【问题标题】:D3 Collapsible Tree how to make it vertically scrollableD3 Collapsible Tree如何使其垂直滚动
【发布时间】:2021-09-15 04:55:24
【问题描述】:

我有一个 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);
});

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    如果它对某人有帮助,我使用了启用平移和缩放的缩放功能。这可能足以满足您在尝试使图形可滚动时所寻找的内容。

     D3.select('svg')
          .call(D3.zoom()
            .scaleExtent([-5, 8])
            .extent([[0, 0], [300, 300]])
            .on('zoom', () => {
              D3.selectAll('g')
                .attr('transform', D3.event.transform);
    
    
              if (has('root.children', this) && this.root.children.length > 50) {
                this.updateAfterInit(this.root);
              } else {
                this.update(this.root);
              }
    
              // this.centerNode(this.root);
            })
            .filter(() => {
    
              const foundNode = this.N.findNodeByID(D3.event.srcElement.id.split('_')[1])
              if ( !!foundNode && D3.event.type === 'dblclick' && foundNode.data.type === 'SearchRelationspec') {
                return false;
              } else {
                return !D3.event.target.classList.contains('drawarea') && D3.event.type === 'dblclick';
              }
            })
    

    【讨论】:

      【解决方案2】:

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

       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;
       });
      

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

      【讨论】:

      • 万一有人像我一样在这个问题上留了根。对角函数可以如下所示 // 创建从父节点到子节点的弯曲(对角线)路径对角线(s,d){ return M ${s.y} ${s.x} C ${(s.y + d.y) / 2} ${s.x}, ${(s.y + d.y) / 2} ${d.x}, ${d.y} ${d.x}; } source 来自根 ndoe,持续时间是毫秒数
      猜你喜欢
      • 2014-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-13
      • 2013-09-27
      • 2012-06-24
      • 2013-10-26
      相关资源
      最近更新 更多