How to increase the length of a link in D3 force layout

11,021

Solution 1

For the link distance, you can use link.distance.

Here is what the doc currently says about this function:

If distance is specified, sets the distance accessor to the specified number or function, re-evaluates the distance accessor for each link, and returns this force. If distance is not specified, returns the current distance accessor, which defaults to:

function distance() {
    return 30;
}

The distance accessor is invoked for each link, being passed the link and its zero-based index. The resulting number is then stored internally, such that the distance of each link is only recomputed when the force is initialized or when this method is called with a new distance, and not on every application of the force.

For the labels, please ask another question.

Solution 2

Here you can use .distance to set the disance or length of a link.

var forceLink = d3
    .forceLink().id(function (d) {
        return d.id;
    })
    .distance(function (d) {
        return GetNodeDefaults(d.label).linkDistance;
    })
    .strength(0.1);

var simulation = d3.forceSimulation()
    .force("link", forceLink)
    .force("charge", d3.forceManyBody().strength(function (d, i) {
        var a = i == 0 ? -2000 : -1000;
        return a;
    }).distanceMin(200).distanceMax(1000))
    .force("center", d3.forceCenter(width / 2, height / 2))
    .force("y", d3.forceY(0.01))
    .force("x", d3.forceX(0.01))
    .on("tick", ticked);

Ref Link: https://github.com/d3/d3-force/blob/master/README.md#link_distance

Share:
11,021
Prasad27
Author by

Prasad27

Updated on June 13, 2022

Comments

  • Prasad27
    Prasad27 almost 2 years

    How can I increase the link length of a force graph. My code is written below. What should i change?

    Also I want to label the "only child nodes" on mouse-over and the parent node has their label.

    <!DOCTYPE html>
    <html>
      <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>Force</title>
        <style type="text/css">
    
    circle.node {
      cursor: pointer;
      stroke: #3182bd;
      stroke-width: 1.5px;
    }
    
    line.link {
      fill: none;
      stroke: #9ecae1;
      stroke-width: 1.5px;
    }
    
        </style>
      </head>
      <body>
        <div id="chart"></div>
        <script src="../d3/d3.v3.min.js"></script>
        <script type="text/javascript">
    
    var w = 960,
        h = 500,
        node,
        link,
        root;
    
    var force = d3.layout.force()
        .on("tick", tick)
        .size([w*2, h*2]);
    
    var vis = d3.select("#chart").append("svg:svg")
        .attr("width", w*2)
        .attr("height", h*2);
    
    var diagonal = d3.svg.diagonal.radial()
        .projection(function(d) { return [d.y, d.x / (180) * Math.PI]; });
    d3.json("try.json", function(json) {
      root = json;
      update();
    });
    
    function update() {
      var nodes = flatten(root),
          links = d3.layout.tree().links(nodes);
    
      // Restart the force layout.
      root.fixed=true;
      root.x=900;
      root.y=500;
      force
          .nodes(nodes)
          .links(links)
          .start();
    
      // Update the links…
      link = vis.selectAll("line.link")
          .data(links, function(d) { return d.target.id; });
    
      // Enter any new links.
      link.enter().insert("svg:line", ".node")
          .attr("class", "link")
          .attr("x1", function(d) { return d.source.x+100; })
          .attr("y1", function(d) { return d.source.y+100; })
          .attr("x2", function(d) { return d.target.x+100; })
          .attr("y2", function(d) { return d.target.y+100; });
    
      // Exit any old links.
      link.exit().remove();
    
      // Update the nodes…
      node = vis.selectAll("circle.node")
          .data(nodes, function(d) { return d.id; })
          .style("fill", color);
    
      // Enter any new nodes.
      node.enter().append("svg:circle")
          .attr("class", "node")
          .attr("cx", function(d) { return d.x; })
          .attr("cy", function(d) { return d.y; })
          .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 25; })
          .style("fill", color)
          .on("click", click)
          .call(force.drag);
    
      // Exit any old nodes.
      node.exit().remove();
    }
    
    function tick() {
      link.attr("x1", function(d) { return d.source.x-100; })
          .attr("y1", function(d) { return d.source.y; })
          .attr("x2", function(d) { return d.target.x-100; })
          .attr("y2", function(d) { return d.target.y; });
    
      node.attr("cx", function(d) { return d.x-100; })
          .attr("cy", function(d) { return d.y; });
    }
    
    // Color leaf nodes orange, and packages white or blue.
    function color(d) {
      return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
    }
    
    // Toggle children on click.
    function click(d) {
      if (d.children) {
        d._children = d.children;
        d.children = null;
      } else {
        d.children = d._children;
        d._children = null;
      }
      update();
    }
    
    // Returns a list of all nodes under the root.
    function flatten(root) {
      var nodes = [], i = 0;
    
      function recurse(node) {
        if (node.children) node.children.forEach(recurse);
        if (!node.id) node.id = ++i;
        nodes.push(node);
      }
    
      recurse(root);
      return nodes;
    }
    
        </script>
      </body>
    </html>   
    
    • Christopher Chiche
      Christopher Chiche almost 11 years
      Welcome on StackOverflow, have a look at the how to ask section in order to know more about how to ask a question. Mainly here it would be interesting to know what you have tried and to provide a working example of what you have for now (a jsFiddle for example). Also, please do not ask a second unrelated questions inside of your question, ask another question. The goal of this website is for other users to find existing answers after you got your answer.
  • Santiago Martí Olbrich
    Santiago Martí Olbrich over 5 years
    You should've provided an explanation and not only a link, which no longer works BTW.
  • Christopher Chiche
    Christopher Chiche over 5 years
    @SantiagoMartíOlbrich thanks for your comment. This answer is now 5 years old so the links and the library changed indeed. Thanks for pointing this out.