8

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>   
VividD
  • 10,456
  • 6
  • 64
  • 111
Prasad27
  • 105
  • 1
  • 2
  • 6
  • Welcome on StackOverflow, have a look at the [how to ask](http://stackoverflow.com/questions/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. – Christopher Chiche Jun 19 '13 at 06:34

2 Answers2

13

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.

Christopher Chiche
  • 15,075
  • 9
  • 59
  • 98
5

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