节点溢出D3js

问题描述

在闪电中,我们正在使用 D3js 库在圆形树中显示放射状树。 当我们有大约 15个节点时,它看起来不错。

当我们尝试显示15条以上的记录时,节点相互碰撞

我需要在圆上显示40个以上的节点,并且节点之间要有足够的空间。

在这里分享了我的代码和屏幕截图

drawTree : function(component,event,helper,treeData) {


  var textMaxLength = 0,radius = 50,circleTextLen = 0;
  // Properly formatted treeData,if it's flat data,use stratify
  console.log('treeData',treeData);
  


  var margin = { top: 10,right: 10,bottom: 10,left: 10 },width = 1200,height = 1000;

  // Prepare container

  var svg = d3.select("body")
      .append("svg")
      .attr("width",width)
      .attr("height",height),g = svg.append("g")
      .attr("transform","translate(" + 450 + "," + 400 + ") scale(1) ");

  var i = 0,// duration = 750,cluster_size = 800,root;

  // Define cluster

  var cluster = d3.cluster()
    .size([cluster_size,cluster_size]);

  // Get the root

  root = d3.hierarchy(treeData,function(d) {
    return d.children;
  });
  // Collapse all children
  if(typeof collapse === 'undefined') {
    root.children.forEach(collapse);
  }


  root.x0 = 0;
  root.y0 = 0;

  // Start drawing
  draw(root);

  function draw(source) {

    var treeData = cluster(root);

    var nodes = treeData.descendants(),links = treeData.descendants()
        .slice(1);

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

    // Enter the node,draw it at source,so that we can animate later from
    // source

    var nodeEnter = node
      .enter()
      .append('g')
      .attr('class','node')
      .attr("transform",function(d) {
        return "translate(" + project(source,source.x0,source.y0) + ")";
      })
      .on('click',d => {
        // d3.event.preventDefault();
        if(d.data.level == 'subnode') {
          component.set("v.nodeName",d.data.name);
        }
      })
      .on("dblclick",click);

    // Draw a circle with zero radius

    nodeEnter.append('circle')
      .attr('class','node')
      .attr('r',20)
      .attr('stroke','steelblue')
      .attr('fill','white')
      .attr('stroke-width','1.5px')
      .attr('display',function(d) {
        if(d.data.level == 'subnode' || d.data.level != 'node') {
          return 'block';
        } else {
          return 'none';
        }
      });


    //Draw text
    nodeEnter.append("text")
      //  .attr("class","wrap")
      .attr("dy",function(d) {
        if(d.data.level == 'node') {
          return '0.5em';
        } else {
          return '0.5em';
        }
      })

      .style("text-anchor",'middle')
      .text(function(d) {
        if(textMaxLength < (d.data.name).length) {
          textMaxLength = (d.data.name).length;
        }
        return d.data.name;
      })
      //  .style("font-size","1px")
      .call(wrap,100)
      .each(getSize)
      .style('fill',function(d) {
       
          return "white";
        

      })
      .style("font-size",function(d) {
          return (d.scale + 10 + "px");
        
      });


    var nodeUpdate = nodeEnter.merge(node);

    // When we enter the update phase,change the coordinate of each node using a 
    // transition,so that we can animate

    nodeUpdate.transition()
      .duration(duration)
      .attr("transform",function(d) {
        return "translate(" + project(d,d.x,d.y) + ")";
      });

    // Add color to circle

    
    // Handle exit node,show a transition

    var nodeExit = node.exit()
      .transition()
      .duration(duration)
      .attr("transform",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);

    var link = g.selectAll('path.link')
      .data(links,function(d) {
        return d.id || (d.id = i);
      });
    // We need animation for links also,so we first draw paths whose start and origin is 
    // same
    var linkEnter = link.enter()
      .insert('path',"g")
      .attr("class","link")
      .attr("stroke","rgb(65,136,229)")
      .attr("stroke-width","1px")

      .attr("d",function(d) {
        return "M" + project(source,source.y0)
          + "L" + project(source,source.y0);
      });

    var linkUpdate = linkEnter.merge(link);

    // Now animate the links

    linkUpdate.transition()
      .duration(duration)
      .attr("d",function(d) {
        return "M" + project(d,d.y)
          + "L" + project(d.parent,d.parent.x,d.parent.y);
      });

    // Remove any exiting links
    var linkExit = link.exit()
      .transition()
      .duration(duration)
      .attr("d",source.y)
          + "L" + project(source,source.y);
      })
      .remove();

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

  }

  function project(d,x,y) {
    // Calculate angle,and adjust radius so that links are not too long.
    // Start playing with radius and cluster_size.
    var angle = (x - (cluster_size / 4)) / (cluster_size / 2) * Math.PI,radius = y * 0.5;
    var cors = [radius * Math.cos(angle),radius * Math.sin(angle)];
    return cors;
  }

  function collapse(d) {
    if(d.children) {
      d._children = d.children;
      d._children.forEach(collapse);
      d.children = null;
    }
  }

  // We use this function,so that all nodes won't be drawn at same time.
  // Play around with this and check it changes the output
  // If you increase the "value",animation will be slower

  function duration(d) {
    var value = 300 + (d.id * 5);
    // var value = 500+(d.id*5);
    // var value = 1500+(d.id*5);

    return value;
  }

  

  
}

This is image of colliding with existing nodes,and also out of the svg

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)