D3 Collapsible Tree如何使其垂直滚动

时间:2015-10-29 17:48:41

标签: javascript d3.js

我有一个D3可折叠树,问题是单个节点最多可以有4000个叶子。我想使它可滚动或可扩展,即高度应适用于10个叶子节点或几个1000个。

目前我的身高参数是静态的,谁能告诉我如何让它变得动态?

以下是代码:

$(function(){
var m = [20, 120, 20, 120],
    w = 1280 - m[1] - m[3],
    h = 80000 - m[0] - m[2],
    i = 0,
    root;

var tree = d3.layout.tree()
    .size([h, w]);

var diagonal = d3.svg.diagonal()
    .projection(function(d) { return [d.y, d.x]; });

var vis = d3.select("#modelPatterns").append("svg:svg")
    .attr("width", w + m[1] + m[3])
    .attr("height", h + m[0] + m[2])
  .append("svg:g")
    .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

d3.json("./static/data/type1Tree.json", function(json) {
  root = json;
  root.x0 = h / 2;
  root.y0 = 0;

  function toggleAll(d) {
    if (d.children) {
      d.children.forEach(toggleAll);
      toggle(d);
    }
  }

  // Initialize the display to show a few nodes.
  root.children.forEach(toggleAll);
  //toggle(root.children[1]);
  //toggle(root.children[1].children[2]);
  //toggle(root.children[9]);
  //toggle(root.children[9].children[0]);

  update(root);
});

1 个答案:

答案 0 :(得分:0)

您可以根据需要修改更新功能,如下面的代码......

 function update(source) {

 var duration = d3.event && d3.event.altKey ? 5000 : 500;    

 // compute the new height
 var levelWidth = [1];
 var childCount = function(level, n) {
 if(n.children && n.children.length > 0) {
   if(levelWidth.length <= level + 1) levelWidth.push(0);      
   levelWidth[level+1] += n.children.length;
   n.children.forEach(function(d) {`
     childCount(level + 1, d);
   });
 }
 };

 childCount(0, root);  

 newHeight = d3.max(levelWidth) * 60; // 20 pixels per line    

 tree = tree.size([newHeight, width]);

 d3.select("svg").remove();//TO REMOVE THE ALREADY SVG CONTENTS AND RELOAD ON EVERY UPDATE

 svg = d3.select("body").append("svg");

 svg.attr("width", width + margin.right + margin.left)
 .attr("height", newHeight + margin.top + margin.bottom)
 .append("g")
 .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

 // Compute the new tree layout.
 var nodes = tree.nodes(root).reverse(),
 links = tree.links(nodes);

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

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

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

 nodeEnter.append("circle")
   .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

 nodeEnter.append("text")
   .attr("x", function(d) { return d.children || d._children ? -10 : 10; })
   .attr("dy", "-.75em")
   .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
   .text(function(d) { return d.name; })
   .style("fill-opacity", 1e-2);

 nodeEnter.append("text")
   .attr("x", function(d) { return d.children || d._children ? -10 : 10; })
   .attr("dy", "1.00em")
   .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
   .text(function(d) { return d.info1; })
   .style("fill-opacity", 1e-2);

 // Transition nodes to their new position.
 var nodeUpdate = node.transition()
   .duration(duration)
   .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

 nodeUpdate.select("circle")
   .attr("r", 6)
   .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

 nodeUpdate.selectAll("text")
   .style("fill-opacity", 4);

 // Transition exiting nodes to the parent's new position.
 var nodeExit = node.exit().transition()
   .duration(duration)
   .attr("transform", function(d) { return "translate(" + source.y + "," +     source.x + ")"; })
   .remove();

 nodeExit.selectAll("text")
   .style("fill-opacity", 1e-6);

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

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

 // Transition links to their new position.
 link.transition()
   .duration(duration)
   .attr("d", diagonal);

 // Transition exiting nodes to the parent's new position.
 link.exit().transition()
   .duration(duration)
   .attr("d", function(d) {
     var o = {x: source.x, y: source.y};
     return diagonal({source: o, target: o});
   })
   .remove();

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

它将为您提供动态大小树,并为树中的任意数量的节点提供服务。 我希望这能解决你的目的。