Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
489 views
in Technique[技术] by (71.8m points)

javascript - D3.js force directed graph, reduce edge crossings by making edges repel each other

So i have a page already which draws a force directed graph, like the one shown here.

And that works fine. I'm using the JS from here, with a few tweaks to spread out the nodes slightly nicer.

These are more or less the only differences:

d3.json("force.json", function(json) {
  var force = d3.layout.force()
      .gravity(0.1)
      .charge(-2000)
      .linkDistance(1)
      .linkStrength(0.1)
      .nodes(json.nodes)
      .links(json.links)
      .size([w, h])
      .start();

Where reducing the link strength seems to make the links more like springs, so it becomes similar to the Fruchterman & Reingold technique often used. This works reasonably well, but only for fairly small graphs. With larger graphs the number of crossings just goes up - as one would expect, but the solution it lands on is normally far from optimal. I'm not looking for a method to get the optimal solution, I know that's very difficult. I would just like it to have some crude addition that tries to force the lines apart as well as the nodes.

Is there a way to add a repulsion between in links, as well as between the nodes? I'm not familiar with the way D3 force works, and i can't seem to find anything that says this is possible...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Unfortunately, the answer to your question does not exist.

There is no built-in mechanism in D3 that repels edges or minimizes edge crossings. You would think it wouldn't be that hard to implement a charge on an edge, but here we are.

Furthermore, there doesn't seem to be any mechanism anywhere that reduces edge crossings in general. I've looked through dozens of visualization libraries and layout algorithms, and none of them deal with reducing edge crossings on a generic undirected graph.

There are a number of algorithms that work well for planar graphs, or 2-level graphs, or other simplifications. dagre works well in theory for 2-level graphs, although the utter lack of documentation makes it almost impossible to work with.

Part of the reason for this is that laying out graphs is hard. In particular, minimizing edge crossings is NP-hard, so I suspect that most layout designers hit that problem, bang their head against the keyboard a few times, and give up.

If anyone does come up with a good library for this, please publish it for the rest of us :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...