Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graph 具有定向路径的D3js可折叠力布局?_Graph_Svg_D3.js - Fatal编程技术网

Graph 具有定向路径的D3js可折叠力布局?

Graph 具有定向路径的D3js可折叠力布局?,graph,svg,d3.js,Graph,Svg,D3.js,我正在尝试做一个力定向布局,其中链接是指向节点的箭头(如和中所示),并且具有子节点的节点是可折叠的(如Mike Bostock的示例:或中所示) 到目前为止,折叠节点工作正常,但我很难理解箭头是如何包含在路径中的。以下是基于上述示例的部分代码: force.nodes(nodes) .links(links) .gravity(0.05) .charge(-1500) .linkDistance(100) .friction(0.5) .linkS

我正在尝试做一个力定向布局,其中链接是指向节点的箭头(如和中所示),并且具有子节点的节点是可折叠的(如Mike Bostock的示例:或中所示)

到目前为止,折叠节点工作正常,但我很难理解箭头是如何包含在路径中的。以下是基于上述示例的部分代码:

force.nodes(nodes)
    .links(links)
    .gravity(0.05)
    .charge(-1500)
    .linkDistance(100)
    .friction(0.5)
    .linkStrength(function(l, i) {return 1 })
    .size([w, h])
    .start();

 // Append markers
 vis.append("svg:defs").selectAll("marker")
    .data(["end"])
  .enter().append("svg:marker")
    .attr("id", String)
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 15)
    .attr("refY", -1.5)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
 //.append("svg:path")      // <-- I not sure what this does
  //.attr("d", "M0,-5L10,0L0,5");


var path = vis.selectAll("path")
    .data(force.links());


// Enter new paths
path.enter().insert("svg:path")
    .attr("class", "link")
    .attr("marker-end", "url(#end)")
    .style("stroke", "#ccc");


// Exit any old paths.
path.exit().remove();


// Update the nodes…
var node = vis.selectAll("g.node")
    .data(nodes, function(d) { return d.id; })

node.select("circle")
    .style("fill", color);

// Enter any new nodes.
var nodeEnter = node.enter().append("svg:g")
    .attr("class", "node")
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
    .on("click", click)
    .call(force.drag);


//Add an immage to the node
nodeEnter.append("svg:image")
      .attr("xlink:href",  function(d) { return d.image;})
      .attr("x", function(d) { return (0 - Math.sqrt(d.size)) / 10 || 4.5;})
      .attr("y", function(d) { return (0 - Math.sqrt(d.size)) / 10 || 4.5;})
      .attr("height", 16)
      .attr("width", 16);


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

// Re-select for update.
node = vis.selectAll("g.node");
path = vis.selectAll("path")

force.on("tick", function() {
     // Draw curved links
     path.attr("d", function(d) {
    var dx = d.target.x - d.source.x,
        dy = d.target.y - d.source.y,
        dr = Math.sqrt(dx * dx + dy * dy);
    return "M" + d.source.x + "," 
            + d.source.y 
            + "A" + dr + "," 
            + dr + " 0 0,1 " 
            + d.target.x + "," 
            + d.target.y;
     });

     node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
然后,在输入路径时(即
.attr(“标记结束”,“url(#结束)”);
)会引用该路径

但我可能遗漏了一些东西,因为在我的图表中显示的是路径,而不是箭头


谢谢你的帮助

我找到了一个“几乎”奏效的解决方案。下面是完整的代码,并简要解释了底部仍然存在的问题:

    var w = 1280,
        h = 800,
        root,
                    vis;

    var force = d3.layout.force()
                .gravity(200)
                .charge(-1500)
                .linkDistance(100)
                .friction(0.01)
                .size([w, h])
                ;


    $(document).ready(function() {

        var newHeight = '100%';

        $("#svgdiv").html("<svg id='graph' xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'></svg>");

        vis = d3.select("svg");

        d3.json("../json/flare.json", function(json) {
            root = json;
            root.fixed = true;
            root.x = w / 2;
            root.y = h / 2;


        // Build the arrow
        var defs = vis.insert("svg:defs").selectAll("marker")
            .data(["end"]);

          defs.enter().append("svg:marker")
            .attr("id", String)
            .attr("viewBox", "0 -5 15 15")
            .attr("refX", 15)
            .attr("refY", -1.5)
            .attr("markerWidth", 6)
            .attr("markerHeight", 6)
            .attr("orient", "auto")
          .append("svg:path")
            .attr("d", "M0,-5L10,0L0,5");       

            update();
        });
    });



    /**
     * 
     */
    function update() {
      var nodes = flatten(root),
          links = d3.layout.tree().links(nodes);

      // Restart the force layout.
      force.nodes(nodes)
            .links(links)
            .gravity(0.05)
            .charge(-1500)
            .linkDistance(100)
            .friction(0.5)
            .linkStrength(function(l, i) {return 1 })
            .size([w, h])
            .start();


        var path = vis.selectAll("path.link") // <-- THIS WAS CHANGED TO "path.links"
            .data(links, function(d) { return d.target.id; });

          path.enter().insert("svg:path")
            .attr("class", "link")
            .attr("marker-end", "url(#end)")
            .style("stroke", "#ccc");


      // Exit any old paths.
      path.exit().remove();


      // Update the nodes…
      var node = vis.selectAll("g.node")
          .data(nodes, function(d) { return d.id; });

      // Enter any new nodes.
      var nodeEnter = node.enter().insert("svg:g")
          .attr("class", "node")
          .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
          .on("click", click)
          .call(force.drag);


        node.select("circle")
          .style("fill", color);


      nodeEnter.append("svg:circle")
          .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; })
          .style("fill", color);

      // Add text to the node (as defined by the json file) 
      nodeEnter.append("svg:text")
          .attr("text-anchor", "middle")
          .attr("dx", function(d) { return Math.sqrt(d.size) / 10 || 4.5; })
          .attr("dy", ".35em")
          .text(function(d) { return d.name; });
      /* */

      //Add an image to the node
      nodeEnter.append("svg:image")
              .attr("xlink:href",  function(d) { return d.logo;})
              .attr("x", function(d) { return (0 - Math.sqrt(d.size)) / 10 || 4.5;})
              .attr("y", function(d) { return (0 - Math.sqrt(d.size)) / 10 || 4.5;})
              .attr("height", 16)
              .attr("width", 16);
       /* */    


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

      // Re-select for update.
      node = vis.selectAll("g.node");
      path = vis.selectAll("path.link");   // <-- THIS WAS CHANGED TO "path.link"


      force.on("tick", function() {


        path.attr("d", function(d) {
            var dx = d.target.x - d.source.x,
                dy = d.target.y - d.source.y,
                dr = Math.sqrt(dx * dx + dy * dy); 
            return  "M" + d.source.x + "," 
                        + d.source.y 
                        + "A" + dr + "," 
                        + dr + " 0 0,1 " 
                        + d.target.x + "," 
                        + d.target.y;
        });


        node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

      });

    }


    // Color leaf nodes orange, and packages white or blue.
    function color(d) {
      return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
    }

    // Toggle children on click.
    function click(d) {
      if (d.children) {
        d._children = d.children;
        d.children = null;
      } else {
        d.children = d._children;
        d._children = null;
      }

      update();
    }



    // Returns a list of all nodes under the root.
    function flatten(root) {
      var nodes = []; 
      var i = 0;

      function recurse(node) {
        if (node.children) 
            node.children.forEach(recurse);
        if (!node.id) 
            node.id = ++i;
        nodes.push(node);
      }

      recurse(root);
      return nodes;
    }
它应该在哪里:

  var path = vis.selectAll("path.link").)
然后我还发现箭头标记的def应该在update()函数之外定义,该函数在折叠和展开节点时调用。否则,每次单击节点时都会将其附加到svg,这不是很有效

因此,现在节点在单击时折叠并绘制箭头(尽管它们很难看)。然而,还有一个问题让我非常困惑:过了一段时间,没有任何明显的时间间隔或点击模式,图形冻结,在浏览器中调试说,
无法读取未定义的
的属性“target”。此错误在“勾号”功能上触发,其中定义了弯曲路径:

    path.attr("d", function(d) {
        var dx = d.target.x - d.source.x,
            dy = d.target.y - d.source.y,
            dr = Math.sqrt(dx * dx + dy * dy); 
        return  "M" + d.source.x + "," 
                    + d.source.y 
                    + "A" + dr + "," 
                    + dr + " 0 0,1 " 
                    + d.target.x + "," 
                    + d.target.y;
    });
它找不到
d.target
,因为在输入
force.on(“tick”,function()…
之前,路径变量被重新初始化(如
path=vis.selectAll(“path.link”);

奇怪的是,它在一开始就可以工作,但在一段随机时间后可能会突然停止工作! 那么有没有人知道会发生什么事

编辑:


我现在知道是怎么回事了。出于某种原因,我使用了我在某处找到的脚本d3.layout.js,我认为这是折叠树所需要的。我删除了该库并使用了正常的d3.v3.js,一切都正常工作……只是箭头很难看。因此,上面的脚本应该可以工作,具有可折叠的节点和定向路径。

问得好!天哪,我一直在努力对付那些箭头。我期待着看到这里出现了什么。SVG标记定义中附加的
路径负责绘制实际的箭头。您是否在运行代码时注释掉了这些箭头(第一个代码块)?谢谢@LarsKotthoff,我在发布问题后就发现了这一点。它在未注释之前不起作用,因为我不理解它的作用,所以我对它进行了注释。编写
path.link
几乎修复了它。我将我的答案放在下面。但是,仍然有一点东西阻止它完全正常工作……我创建了一个要点以显示一个实例:
  var path = vis.selectAll("path.link").)
    path.attr("d", function(d) {
        var dx = d.target.x - d.source.x,
            dy = d.target.y - d.source.y,
            dr = Math.sqrt(dx * dx + dy * dy); 
        return  "M" + d.source.x + "," 
                    + d.source.y 
                    + "A" + dr + "," 
                    + dr + " 0 0,1 " 
                    + d.target.x + "," 
                    + d.target.y;
    });