D3 force layout: Straight line instead of curve for links (but only for some links)

爱⌒轻易说出口 提交于 2019-12-19 21:25:07

问题


I have this D3 jsfiddle that produces following diagram:

The only thing that bothers me about this diagram is that if there is only one link between two nodes, it is drawn as a curve. I think it would be much better if such links were just straight lines (arrow would be fine). Let's say between Microsoft and Amazon should be just a straight line (with arrow). The same between Oracle and Google, Sony and LG, etc.

How to achieve this?


回答1:


It's very easy. In your linkArc(d) method, just set the dr parameter to 0 if there is only 1 child, or the default one, if there are more. This way there won't be any curve between the nodes.

The first step though, will be to determine how many neighbours there are. A simple way would be like the following just after you define the nodes from the links, though it is not optimal.

links.forEach(function(d) {
    if (nodes[d.source.name].children==undefined) {
        nodes[d.source.name].children=0;
    }
    nodes[d.source.name].children++
});

Once you do that, you can adjust the curve of the line as follows:

function linkArc(d) {
  var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y,
      dr = (nodes[d.target.name].children>1 & nodes[d.source.name].children>1)?Math.sqrt(dx * dx + dy * dy):0;
  return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

The result will be like this:

I am sure that there are much better ways to tackle this, but it is a start. Hope this helps.




回答2:


This is based on @Nikos answer:

links.forEach(function(d) {
    d.straight = 1;
    links.forEach(function(d1) {
        if ((d.source == d1.target) && (d1.source == d.target))
            d.straight = 0;
    });
});

and

function linkArc(d) {
  var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y,
      dr = (d.straight == 0)?Math.sqrt(dx * dx + dy * dy):0;
  return "M" + d.source.x + "," + d.source.y +
      "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

yield to correct diagram: (with respect to straightness of connections)

jsfiddle



来源:https://stackoverflow.com/questions/28098879/d3-force-layout-straight-line-instead-of-curve-for-links-but-only-for-some-lin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!