(d3.js)如何将动态力导向图与可折叠力导向图结合起来?

时间:2017-11-09 11:28:10

标签: javascript d3.js graph

我试图合并两个不同的力导向图。

一个是动态力导向图(code from here),我可以在其中设置节点之间线条的粗细(并且数据是内联定义的);另一个是可折叠力导向图(code from a SO answer here, that uses non-tree data),我可以点击节点来隐藏子节点(并且数据是从JSON文件定义的)。

我认为这应该足够清楚,但我一直有问题。 JS控制台说,即使我已经设置了变量,属性force也是未定义的。

以下是Plunker:http://plnkr.co/edit/MtOB9PGnXlNwlNj6P5NY?p=preview

这是可折叠的图形部分(完整代码在Plunker中)

// Combined script //
var root,
    force = d3.layout.force()
    .size([width, height])
    .on("tick", tick);


var link = svg.selectAll(".link"),
    node = svg.selectAll(".node");

    d3.json("data.json", function(json) {
      root = json;
      //Give nodes ids and initialize variables
      for(var i=0; i<root.nodes.length; i++) {
        var node = root.nodes[i];
        node.id = i;
        node.collapsing = 0;
        node.collapsed = false;
      }
      //Give links ids and initialize variables
      for(var i=0; i<root.links.length; i++) {
        var link = root.links[i];
        link.source = root.nodes[link.source];
        link.target = root.nodes[link.target];
        link.id = i;
      }

      update();
    });

    function update() {
      //Keep only the visible nodes
      var nodes = root.nodes.filter(function(d) {
        return d.collapsing == 0;
      });
      var links = root.links;
      //Keep only the visible links
      links = root.links.filter(function(d) {
        return d.source.collapsing == 0 && d.target.collapsing == 0;
      });

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

      // Update the links…
      link = link.data(links, function(d) { return d.id; });

      // Exit any old links.
      link.exit().remove();

      // Enter any new links.
      link.enter().insert("line", ".node")
          .attr("class", "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; })
          .attr("marker-end", "url(#arrow)");

      // Update the nodes…
      node = node.data(nodes, function(d){ return d.id; }).style("fill", color);

      // Exit any old nodes.
      node.exit().remove();

      // Enter any new nodes.
      node.enter().append("circle")
          .attr("class", "node")
          .attr("cx", function(d) { return d.x; })
          .attr("cy", function(d) { return d.y; })
          .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; })
          .style("fill", color)
          .on("click", click)
          .call(force.drag);
    }

    function tick() {
      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("cx", function(d) { return d.x; })
          .attr("cy", function(d) { return d.y; });
    }

    // Toggle children on click.
    function click(d) {
      if (!d3.event.defaultPrevented) {
        //check if link is from this node, and if so, collapse
        root.links.forEach(function(l) {
          if(l.source.id == d.id) {
            if(d.collapsed){
              l.target.collapsing--;
            } else {
              l.target.collapsing++;
            }
          }
        });
        d.collapsed = !d.collapsed;
      }
      update();
    }
// Combined end //

如果没有合并这两个代码,它就可以正常工作,如下所示:https://jsfiddle.net/Lrrepn0c/

有什么想法吗?

0 个答案:

没有答案