繁体   English   中英

节点展开时d3 v4树缩小

[英]d3 v4 tree zoom out when a node expanded

我正在使用d3.tree创建我的树层次结构,对于这个库我还比较陌生,所以我需要一些帮助。

var treeData = {{ data | safe }};
            // Set the dimensions and margins of the diagram
            var margin = {top: 30, right: 90, bottom: 30, left: 150},
                width = $('#tree-container').width(),
                height = $('#tree-container').height();

            // append the svg object to the body of the page
            // appends a 'group' element to 'svg'
            // moves the 'group' element to the top left margin
            var svg = d3.select("#tree-container").append("svg")
                .attr("width", width)
                .attr("height", height)
                .call(d3.zoom().on("zoom", function () {
                    svg.attr("transform", d3.event.transform)
                }))
              .append("g")
                .attr("width", width)
                .attr("height", height)
                .attr("id", "place")
                .attr("transform", "translate("
                      + (width/2) + "," + margin.top + ")");



            var i = 0,
                duration = 750,
                root;

            // declares a tree layout and assigns the size
            var treemap = d3.tree()
                .nodeSize([70, 10]);

            // Assigns parent, children, height, depth
            root = d3.hierarchy(treeData, function(d) { return d.children; });

            root.x0 = 0;
            root.y0 = width / 2;

            // Collapse after the second level
            root.children.forEach(collapse);

            update(root);

            // Collapse the node and all it's children
            function collapse(d) {
              if(d.children) {
                d._children = d.children
                d._children.forEach(collapse)
                d.children = null
              }
            }

            var nodes;

            function update(source) {

              // Assigns the x and y position for the nodes
              var treeData = treemap(root);

              // Compute the new tree layout.
              nodes = treeData.descendants();
                  links = treeData.descendants().slice(1);

              // Normalize for fixed-depth.
              nodes.forEach(function(d){   //HERE
                  d.y = d.depth * 120;
              });

              // ****************** Nodes section ***************************

              // Update the nodes...
              var node = svg.selectAll('g.node')
                  .data(nodes, function(d) {return d.id || (d.id = ++i); });

              // Enter any new modes at the parent's previous position.
              var nodeEnter = node.enter().append('g')
                  .attr('class', 'node')
                  .attr("transform", function(d) {
                    return "translate(" + source.x0 + "," + source.y0 + ")";
                });

              // Add Circle for the nodes
              nodeEnter.append('circle')
                  .attr('class', 'node')
                  .attr('id', function(d) { return "circle-"+d.data.name; })
                  .attr('r', 1e-6)
                  .style("fill", function(d) {
                      return d._children ? "lightsteelblue" : "#fff";// make text color appear read or as data.color
                  }).on('click', click);

              // Add labels for the nodes
              nodeEnter.append('text')
                  .attr("dy", "0.45em")
                  .attr("y", function(d) {
                      return d.children || d._children ? -13 : 13;
                  })
                  .attr("text-anchor", function(d) {
                      return d.children || d._children ? "end" : "start";
                  })
                  .attr("cursor", "pointer")
                  .text(function(d) { return d.data.name; })
                  .on("click", textClick);

              // UPDATE
              var nodeUpdate = nodeEnter.merge(node);

              // Transition to the proper position for the node
              nodeUpdate.transition()
                .duration(duration)
                .attr("transform", function(d) {
                    return "translate(" + d.x + "," + d.y + ")";
                 });

              // Update the node attributes and style
              nodeUpdate.select('circle.node')
                  .attr('r', 10)
                  .style("fill", function(d) { return d._children ? d.data.ncolor : "#fff"; }) // change color of inner circle
                  .style("stroke", function (d) { return d.data.ncolor; })  // changing color of outere circle
                  .attr('cursor', 'pointer');


              // Remove any exiting nodes
              var nodeExit = node.exit().transition()
                  .duration(duration)
                  .attr("transform", function(d) {
                      return "translate(" + source.x + "," + source.y + ")";
                  })
                  .remove();

              // On exit reduce the node circles size to 0
              nodeExit.select('circle')
                .attr('r', 1e-6);

              // On exit reduce the opacity of text labels
              nodeExit.select('text')
                .style('fill-opacity', 1e-6);

              // ****************** links section ***************************

              // Update the links...
              var link = svg.selectAll('path.link')
                  .data(links, function(d) { return d.id; });

              // Enter any new links at the parent's previous position.
              var linkEnter = link.enter().insert('path', "g")
                  .attr("class", "link")
                  .style("stroke", function (d) { return d.data.color; })   // Place where color of previous link changes
                  .attr('d', function(d){
                    var o = {x: source.x0, y: source.y0};
                    return diagonal(o, o)
                  });

              // UPDATE
              var linkUpdate = linkEnter.merge(link);

              // Transition back to the parent element position
              linkUpdate.transition()
                  .duration(duration)
                  .attr('d', function(d){ return diagonal(d, d.parent) });

              // Remove any exiting links
              var linkExit = link.exit().transition()
                  .duration(duration)
                  .attr('d', function(d) {
                    var o = {x: source.x, y: source.y};
                    return diagonal(o, o)
                  })
                  .remove();

              // Store the old positions for transition.
              nodes.forEach(function(d){
                d.x0 = d.x;
                d.y0 = d.y;
              });



              // Creates a curved (diagonal) path from parent to the child nodes
              function diagonal(s, d) {

                  path = "M" + s.x + "," + s.y +
                      "C" + (s.x + d.x) / 2 + " " + s.y + ","
                          + (s.x + d.x) / 2 + " " + d.y + ","
                          + d.x + " " + d.y;


                  return path
              }

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

它实际上有效,但是我要寻找的是将所有内容都放在查看窗口中的方法。 就像如果有人单击节点将其展开,以及子节点溢出(超出窗口)一样,我需要进行缩小,因此它们将可见。 希望有d3绝地大师来回答我:)))

如果没有看到您的实际数据或代码的运行版本,这很难回答,但这是一个建议。 执行此操作时:

var treemap = d3.tree()
    .nodeSize([70, 10]);

您要设置每个节点的大小,而不是整个布局。 另外,根据API

指定节点大小时,根节点始终位于“ 0,0”。

这是一个示例:我只是在Bostock的树示例中进行了设置,设置了nodeSize ,您可以看到节点位于SVG之外: http : //blockbuilder.org/anonymous/7a84944610c7e6b3b9ebf063977955c9

因此,可能的解决方案是使用size而不是nodeSize

var treemap = d3.tree()
    .nodeSize([width, height]);

这是使用size进行比较的原始树示例: http : //blockbuilder.org/mbostock/4339083

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM