为了账号安全,请及时绑定邮箱和手机立即绑定

D3 v4 更改 kontext 相关节点的不透明度

D3 v4 更改 kontext 相关节点的不透明度

函数式编程 2023-11-11 16:15:11
我对 D3 完全陌生,正在尝试解决以下场景。我有几个与上下文相关的节点。所有这些都按照我想要的方式显示得很好,此外我想添加一个 HTML 选择器按钮,它可以更改所有未选择的节点的颜色和不透明度。目标是通过更改未选定节点的颜色和不透明度来突出显示选择。我不想像这里那样完全删除它们,因为某些节点将来将成为多个上下文的成员。我认为我们社区的群体智能可能会想到一个主意。提前致谢。
查看完整描述

1 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

您将希望选择菜单具有代表每个上下文的值:


  <select>

    <option value="Jira">01 - Jira</option>

    <option value="Ivis">02 - Ivis</option>

    <option value="All" selected>Whatever</option>

  </select>

然后你会想听听这种情况的改变。当它发生变化时,您会将所有节点恢复为正常状态,并过滤那些具有与所选节点匹配的上下文的节点。


由于您有两个不同的子元素,因此您可能想要以不同的方式更改颜色和不透明度。下面我首先更改了标签和圆的不透明度,然后选择每个节点的圆并更改填充:


d3.select("select").on("change", function() {

  var value = this.value;

  

 // Reset every node:

  node.style("opacity", 1) // change opacity back for every node

      .select("circle")    // select the circle to alter its color

      .style("fill", function(d) { return color(d.group); });

      

  // If "All" isn't selected, filter for the selected value:

  if(value != "All") {

    node.filter(function(d) { return d.kontext != value; })

        .style("opacity", 0.5) // Change the opacity of text and circle for filtered items

        .select("circle")      // select the circle to alter its color

        .style("fill","#aaa");

  }

})

综合起来我们得到:

var graph = {

    nodes:[

        {id: "0001", name: "s02vmware", kontext: "Jira", group: 1},

        {id: "0002", name: "v133atlas", kontext: "Jira", group: 2},

        {id: "0003", name: "Linux", kontext: "Jira", group: 2},

        {id: "0004", name: "PostgreSQL", kontext: "Jira", group: 2},

        {id: "0005", name: "OpenSSH", kontext: "Jira", group: 2},

        {id: "0006", name: "Nginx", kontext: "Jira", group: 2},

        {id: "0007", name: "Confluence", kontext: "Jira", group: 3},

        {id: "0008", name: "Tomcat", kontext: "Jira", group: 3},

        {id: "0009", name: "Java", kontext: "Jira", group: 3},


        {id: "0010", name: "Test1", kontext: "Ivis", group: 1},

        {id: "0011", name: "Test2", kontext: "Ivis", group: 2},

        {id: "0012", name: "Test3", kontext: "Ivis", group: 2},

    ],

    links:[

        {source: "0001", target: "0002"},

        {source: "0002", target: "0003"},

        {source: "0004", target: "0003"},

        {source: "0005", target: "0003"},

        {source: "0006", target: "0003"},

        {source: "0007", target: "0003"},

        {source: "0008", target: "0007"},

        {source: "0009", target: "0007"},


        {source: "0010", target: "0012"},

        {source: "0011", target: "0010"},

        {source: "0012", target: "0011"},

    ]

};



var svg = d3.select("svg"),

    width = 500,

    height = 300;


var color = d3.scaleOrdinal(d3.schemeCategory20);


var simulation = d3.forceSimulation()

 .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(100))

 .force("charge", d3.forceManyBody())

 .force("center", d3.forceCenter(width / 2, height / 2))

 .force("attraceForce",d3.forceManyBody().strength(10));


var link = svg.append("g")

    .attr("class", "links")

    .selectAll("line")

    .data(graph.links)

    .enter().append("line")

    .attr("stroke-width", 2);


var node = svg.selectAll(".node")

            .data(graph.nodes)

            .enter().append("g")

            .attr("class", "node")

            .on("mouseover", mouseover)

            .on("mouseout", mouseout)

            /*

            .on("click", function(d) {      

                div.transition()        

                    .duration(200)      

                    .style("opacity", 0.9);     

                div .html((d.name) + "<br/>"  + d.close)    

                    .style("left", (d3.event.pageX) + "px")     

                    .style("top", (d3.event.pageY - 28) + "px")*/

            .call(d3.drag()

                .on("start", dragstarted)

                .on("drag", dragged)

                .on("end", dragended));


node.append("circle")

  .attr("r", 15)

  .attr("fill", function(d) { return color(d.group); });


node.append("text")

    .attr("dy", -20)

    .text(function(d) { return d.name; });


simulation

   .nodes(graph.nodes)

   .on("tick", ticked);


simulation.force("link")

   .links(graph.links);


function ticked() {

   link

    .attr("x1", function(d) { return d.source.x; })

    .attr("y1", function(d) { return d.source.y; })

    .attr("x2", function(d) { return d.target.x; })

    .attr("y2", function(d) { return d.target.y; });


    node.attr("transform", function(d) {

        return "translate(" + d.x + "," + d.y + ")";

   });

}


function dragstarted(d) {

  if (!d3.event.active) simulation.alphaTarget(0.3).restart();

  d.fx = d.x;

  d.fy = d.y;

}


function dragged(d) {

   d.fx = d3.event.x;

   d.fy = d3.event.y;

}


function dragended(d) {

    if (!d3.event.active) simulation.alphaTarget(0);

    d.fx = null;

    d.fy = null;

}


function mouseover() {

    d3.select(this).select("circle").transition()

        .duration(100)

        .attr("r", 20);

}


function mouseout() {

    d3.select(this).select("circle").transition()

        .duration(500)

        .attr("r", 15);

}


d3.select("select").on("change", function() {

  var value = this.value;

  

 // Reset every node:

  node.style("opacity", 1) // change opacity back for every node

      .select("circle")    // select the circle to alter its color

      .style("fill", function(d) { return color(d.group); });

      

  // If "All" isn't selected, filter for the selected value:

  if(value != "All") {

    node.filter(function(d) { return d.kontext != value; })

        .style("opacity", 0.5) // Change the opacity of text and circle for filtered items

        .select("circle")      // select the circle to alter its color

        .style("fill","#aaa");

  }

})

/* todo: add styles */

.vertical-grid{

    stroke:#ccc;

    

  }

  

  .ordinate-text{

    font-size:10px;

    transform:translateY(10px);

  }

  

  div.tooltip {

    position: absolute;

    text-align: center;

    width: auto;

    height: auto;

    padding: 2px;

    font: 12px sans-serif;

    background: lightsteelblue;

    border: 0px;

    border-radius: 8px;

    pointer-events: none;

    opacity:0;

    padding:5px;

  }

  

  .right-align{

    position:absolute;

    right:100px;

    

  }

  .box,

  .label{

      display:inline-block;

  }

  

  .box{

    width:10px;

    height:10px;

    margin:0px 10px;

  }

<!DOCTYPE html>


    <head>


        <meta charset = "utf-8">

        <link rel="stylesheet" type="text/css" href="style.css">

       

        <title>Ideal iDEP on D3.js</title>

        

   </head>



   <body>

      <!-- Kontext Option Button -->

      <select>

        <option value="Jira">01 - Jira</option>

        <option value="Ivis">02 - Ivis</option>

        <option value="All" selected>Whatever</option>

      </select>

      

      <!-- SVG as a canvas area -->

      <svg width="500" height="300"></svg>

      <!--<svg id="canvas" width="100%" height="100%"></svg> -->

      <!-- import d3.js library -->

      <script src="https://d3js.org/d3.v4.js"></script> 

      <!-- where the magic is happening -->    

      <script type="" src="appv4.js"></script>


   </body>


</html>

如果节点可以是多个上下文的一部分:

{id: "0002", name: "name1", kontext: ["ContextA"], group: 2},
{id: "0003", name: "name2", kontext: ["ContextA","ContextB"] , group: 2},

您需要检查所选上下文是否在 kontext 数组中,如果所有 kontext 属性都是数组(而不是某些字符串和数组),这也会更容易。如果 kontext 是一个数组,你会得到类似的东西:

 node.filter(function(d) { return d.kontext.indexOf(value) == -1; })


查看完整回答
反对 回复 2023-11-11
  • 1 回答
  • 0 关注
  • 125 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信