title: Nodes Overflow D3js
body: <p>In lightning We are Using <strong>D3js</strong> library to display an radial tree in a circular tree.
  Its looks good when we have around <strong>15 nodes</strong>.</p>
  <p>When we try  to display morethan 15 records, <strong>node are collide with each other</strong>.</p>
  <p>I need to <strong>display more than 40 nodes around the circle</strong> with good space between the nodes.</p>
  <p>Here I have shared my code and screenshots</p>
  <pre class="lang-js prettyprint-override"><code>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(&quot;body&quot;)
        .append(&quot;svg&quot;)
        .attr(&quot;width&quot;, width)
        .attr(&quot;height&quot;, height),
      g = svg.append(&quot;g&quot;)
        .attr(&quot;transform&quot;,
          &quot;translate(&quot; + 450 + &quot;,&quot; + 400 + &quot;) scale(1) &quot;);
  
    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(&quot;transform&quot;, function(d) {
          return &quot;translate(&quot; + project(source, source.x0, source.y0) + &quot;)&quot;;
        })
        .on('click', d =&gt; {
          // d3.event.preventDefault();
          if(d.data.level == 'subnode') {
            component.set(&quot;v.nodeName&quot;, d.data.name);
          }
        })
        .on(&quot;dblclick&quot;, 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(&quot;text&quot;)
        //  .attr(&quot;class&quot;,&quot;wrap&quot;)
        .attr(&quot;dy&quot;, function(d) {
          if(d.data.level == 'node') {
            return '0.5em';
          } else {
            return '0.5em';
          }
        })
  
        .style(&quot;text-anchor&quot;, 'middle')
        .text(function(d) {
          if(textMaxLength &lt; (d.data.name).length) {
            textMaxLength = (d.data.name).length;
          }
          return d.data.name;
        })
        //  .style(&quot;font-size&quot;, &quot;1px&quot;)
        .call(wrap, 100)
        .each(getSize)
        .style('fill', function(d) {
         
            return &quot;white&quot;;
          
  
        })
        .style(&quot;font-size&quot;, function(d) {
            return (d.scale + 10 + &quot;px&quot;);
          
        });
  
  
      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(&quot;transform&quot;, function(d) {
          return &quot;translate(&quot; + project(d, d.x, d.y) + &quot;)&quot;;
        });
  
      // Add color to circle
  
      
      // Handle exit node, show a transition
  
      var nodeExit = node.exit()
        .transition()
        .duration(duration)
        .attr(&quot;transform&quot;, function(d) {
          return &quot;translate(&quot; + project(source, source.x, source.y) + &quot;)&quot;;
        })
        .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', &quot;g&quot;)
        .attr(&quot;class&quot;, &quot;link&quot;)
        .attr(&quot;stroke&quot;, &quot;rgb(65, 136, 229)&quot;)
        .attr(&quot;stroke-width&quot;, &quot;1px&quot;)
  
        .attr(&quot;d&quot;, function(d) {
          return &quot;M&quot; + project(source, source.x0, source.y0)
            + &quot;L&quot; + project(source, source.x0, source.y0);
        });
  
      var linkUpdate = linkEnter.merge(link);
  
      // Now animate the links
  
      linkUpdate.transition()
        .duration(duration)
        .attr(&quot;d&quot;, function(d) {
          return &quot;M&quot; + project(d, d.x, d.y)
            + &quot;L&quot; + project(d.parent, d.parent.x, d.parent.y);
        });
  
      // Remove any exiting links
      var linkExit = link.exit()
        .transition()
        .duration(duration)
        .attr(&quot;d&quot;, function(d) {
          return &quot;M&quot; + project(source, source.x, source.y)
            + &quot;L&quot; + project(source, source.x, 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 &quot;value&quot;, 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;
    }
  
    
  
    
  }
  </code></pre>
  <p><a href="https://i.stack.imgur.com/3k6AV.png" rel="nofollow noreferrer">This is image of colliding with existing nodes,and also out of the svg</a></p>