d3.js 过滤节点和链接而不更改不透明度d3js

3ks5zfa0  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(139)

有人能帮我尝试过滤这个数据(节点和链接)通过复选框类型,而不触及不透明度,但做一个更新,每次对节点和链接s'请我已经尝试了几种方法,但不能改变任何东西?在这段代码中,我设法过滤他们通过改变不透明度,但我想要的是删除他们,每次添加他们,而不改变节点和链接的颜色。

这是我的HTML/CSS/JS文件:

<style>

.link {
  stroke: #ccc;
  stroke-width: 1.5px;
  fill:transparent;
}

</style>
<body>
      <div>
          <input type="checkbox" value="Application Server" id="applicationServer" name="check" checked>
          <label for="applicationServer">Application Server</label>
      </div>
      <div>
          <input type="checkbox" value="Access Switch" id="acessSwitch" name="check" checked>
          <label for="acessSwitch">Access Switch</label>
      </div>
      <div>
          <input type="checkbox" value="Distribution Switch" id="distSwitch" name="check" checked>
          <label for="distSwitch">Distribution Switch</label>
      </div>

<script src="//d3js.org/d3.v3.min.js"></script>
<script>

var width = 1060,
    height = 500

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var color = d3.scale.category20();

var force = d3.layout.force()
    .gravity(0.05)
    .distance(60)
    .charge(-100)
    .size([width, height]);

d3.json("data2.json", function(error, json) {
  if (error) throw error;

  force
      .nodes(json.nodes)
      .links(json.links)
      .start();

  var link = svg.selectAll(".link")
      .data(json.links)
    .enter().append("line")
      .attr("class", "link");

  var node = svg.selectAll(".node")
      .data(json.nodes)
    .enter().append("g")
      .attr("class", "node")
      .call(force.drag);

  var circles = node.append("circle")
    .attr("r", 8)
    .attr("fill", function(d) { return color(d.group); });

      d3.selectAll("input[name=check]").on("change", function() {
  function getCheckedBoxes(chkboxName) {
          var checkboxes = document.getElementsByName(chkboxName);
          var checkboxesChecked = [];
          for (var i=0; i<checkboxes.length; i++) {
             if (checkboxes[i].checked) {
                checkboxesChecked.push(checkboxes[i].defaultValue);
             }
          }
          return checkboxesChecked.length > 0 ? checkboxesChecked : " ";
        }

        var checkedBoxes = getCheckedBoxes("check");

    node.style("opacity", 1);
    link.style("opacity", 1);

      node.filter(function(d) {
          return checkedBoxes.indexOf(d.role) === -1;
        })
        .style("opacity", "0");

    link.filter(function(d) {
          return checkedBoxes.indexOf(d.source.type) === -1 && 
          checkedBoxes.indexOf(d.target.type) === -1;
        })
        .style("opacity", "0.2");

      link.filter(function(d) {
          return checkedBoxes.indexOf(d.source.type) > -1 && 
          checkedBoxes.indexOf(d.target.type) > -1;
        })
        .style("opacity", "0.2");

  });

  force.on("tick", function() {
    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 + ")"; });
  });
});

</script>

以下是json文件“data2.json”:

{"nodes": [
        {"id": 1, "name": "Beric", "role": "Application Server", "group": 2}, 
        {"id": 2, "name": "dmi01-stamford-sw01", "role": "Access Switch", "group": 5}, 
        {"id": 4, "name": "ncsu118-distswitch1", "role": "Distribution Switch", "group": 6}, 
        {"id": 8, "name": "ncsu128-distswitch1", "role": "Distribution Switch", "group": 6}
    ],
         "links": [
             {"source": 1, "target": 2}, 
            {"source": 4, "target": 8}, {"source": 4, "target": 2}
            ]}

请帮帮忙!!!

gdrx4gfi

gdrx4gfi1#

每次更新复选框时,您可以计算每个节点的布尔值,以根据其角色和活动复选框确定该节点是否应处于活动状态:

document.getElementsByName("check").forEach(checkbox => {
    data.nodes.filter(n => n.role === checkbox.value).forEach(n => n.active = checkbox.checked);
});

然后根据此 active 属性过滤节点和链接:

var activeNodes = data.nodes.filter(n => n.active);
var activeLinks = data.links.filter(l => activeNodes.includes(l.source) && activeNodes.includes(l.target));

然后,使用d3和一般更新模式更新图表。
您可以在此处找到一个工作示例:https://codepen.io/ccasenove/pen/YzLJEmK
当你收到数据时,你应该修改链接,使它们指向真实的的节点对象而不是它们的id,因为力布局需要它。之后,你可以更新图形,就像你在复选框被更改时所做的那样:

d3.json("data2.json", function (error, json) {
        if (error) throw error;

        data = json;

        data.links.forEach(l => {
            l.source = data.nodes.find(n => n.id == l.source);
            l.target = data.nodes.find(n => n.id == l.target);
        });

        updateGraph();
    });

相关问题