Is it possible to have single stable dagre layout in cytoscape.js - javascript

cytoscape.js dagre layout works really well.
However there is no single stable layout given particular graph.
The layout algorithm seems to be using some random number generator to calculate node positions. It leads to annoying situation when the same graph sometimes rendered differently on the screen.
Is any simple way to fix that? Usually random seed value could be set to some user-defined number. I was unable to find suggestion on how to do that in cytoscape.js docs.

I have seen similar issue with Dagre as well. After digging a little bit into the source code, the reason might be with the ranking algorithm that's used:
Link
AFAIK, network simplex algorithm chooses a random starting to find the optimum, and in case where multiple optima exist, it doesn't guarantee that the same solution will be reached every time.

Related

Class diagram - optimal node positioning

I am trying to build a class diagram model viewer using d3.js and d3.dag
A most crucial part of this viewer is that it should be able to optimally position nodes so that we won't have link crossing (whenever possible) and plus should be able to clearly see what's connected to what
We know:
Width of each node
Height of each node
Links starting coordinate
Links ending coordinate
Links all corner coordinates
We want:
To see connections ending (Can be achieved manually moving nodes).
To minimize links crossing (If it's possible)
What I need is kinda theoretical.
Is there any known algorithm which can solve the problem above (Language does not matter, I just need theoretical reference)
Putting examples below
What's the current situation
What can I achieve by myself
What would be perfect
Example 1.
Current
Achievable
Perfect
Example 2.
Current
Achievable
Perfect
Example 3.
Current
Achievable And Perfect
Example 4.
Current
Achievable
Perfect
Example 5.
Current
Achievable
Perfect
Example 6.
Current
Perfect
Update
Traditional (node to node link ) crossing is already minimized in this case (thanks to d3-dag). The issue is that we don't have the only node to node relationship, we also have a node row to row relationship and in this case, d3-dag fails
I used d3-dag to topologically sort nodes, and then repositioned them vertically, top if odd and bottom if even
Although it's not an algorithm I was looking for, it improved the visual look of components dramatically and made much more readable
Old
New
Old
New
Old
New
I'm not sure this is still a problem, but if so, could you elaborate on what "row -> row" relationships are? Is that a strict definition on which nodes belong on which row? More recent versions of d3-dag support a rank criterion for nodes which specified relative ordering an equality constraints for a nodes row, but that may not be what you're looking for.
If you want to reposition just the edges, there may be way to pull out d3-dag's internals to just do the crossing minimization. Essentially d3 does what most layered layouts do, break an edge up to sections, and change the order of each edge in each row. After the ordering is set, it's easy to assign coordinates. If you can phrase your problem like that, you should be able to use code like this to phrase it as an integer linear program and find the optimal edge layout.

how much can d3 js scale

I am trying to build a network graph (like a network for brain) to display millions of nodes. I would like to know to what extent I can push the d3 js to in terms of adding more network nodes on one graph?
Like for example, http://linkedjazz.org/network/ and http://fatiherikli.github.io/programming-language-network/#foundation:Cappuccino
I am not that familiar with d3.js (though I am a JS dev), I just want to know if d3.js is the right tool to build a massive network visualization (one million nodes +) before I start looking at some other tools.
My requirements are simply: build a interactive web based network visualization that can scale
Doing a little searching myself, I found the following D3 Performance Test.
Be Careful, I locked up a few of my browser tabs trying to push this to the limit.
Some further searching led me to a possible solution where you can pre-render the d3.js charts server side, but I'm not sure this will help depending on your level of interaction desired.
That can be found here.
"Scaling" is not really an abstract question, it's all about how much you want to do and what kind of hardware you have available. You've defined one variable: "millions of nodes". So, the next question is what kind of hardware will this run on? If the answer is "anything that hits my website", the answer is "no, it will not scale". Not with d3 and probably not with anything. Low cost smartphones will not handle millions of nodes. If the answer is "high end workstations" the answer is "maybe".
The only way to know for sure is to take the lowest-end hardware profile you plan to support and test it. Can you guarantee users have access to a 64GB 16 core workstation? An 8GB 2 core laptop? Whatever it is, load up a page with whatever the maximum number of nodes is and sketch in something to simulate the demands of the type of interaction you want and see if it works.
How much d3 scales is very dependent on how you go about using it.
If you use d3 to render lots of svg elements, browsers will start to have performance issues in the upper thousands of elements. You can render up to about 100k elements before the browser crashes, but at that point user interaction is basically useless.
It is possible, however, to render lots and lots of lines or circles with a canvas. In canvas, everything is rendered in a single image file. Rather than creating a new element for each node or line, you draw a line in the image file for it. The downside of this is that animation is a bit more difficult, since you can't move elements in a canvas, only draw on top of a canvas or redraw the whole thing. This isn't impossible, but would be computationally expensive with a million nodes.
Since canvas doesn't have nodes, if you want to use the enter/exit/update paradigm with it, you have to put placeholder elements in the DOM. Here's a good example of how to do that: DOM-to-canvas with D3.
Since the memory costs of canvas don't scale with the number of nodes, it makes for a very scalable solution for large visualizations, but workarounds are required to get it to be interactive.

Javascript big-data visualisation

I'm about to develop a UI for medical research application. I need to make a time series line graph. Main issue is the amount of data:
5,000 points per graph, with a few of them displayed simultaneity. I’m expecting 50,000 points processed all together.
The question is what presentation library?
The main features I’m looking for are: Handles huge data sets, Zoom, annotations, live update.
I’m already looking into http://dygraphs.com/ and http://meteorcharts.com/
I wouldn't want any library that renders the data as DOM elements, or that uses SVG (from performance perspective)
Well, I think I'll give everyone my own answer to my question:
Dygraphs (http://dygraphs.com/) seems to be on the spot. The documentation, although a lot of apparent efforts, leaves a lot to be desired. But from performance, features and flexibility, it's the best I've seen. At least for my current project needs.
Way to go, Dygraphs!
Have you checked out D3? I'm using that for a lot of graph visualization. It looks like this example renders to svg.
My stuff renders to a SVG for force graph visualizations too, but it looks like D3 might be able to use either a canvas or SVG, but I'm not positive about what all can be rendered to which. Honestly, I'd give D3 a try even with SVG, it might be fast enough. I remember reading something about someone simulating thousands of particles using D3's force graph visualizations without issues. It's SUPER easy to get your data into the right format for it to use.
Good luck!
I am developing a very similar application.
I am currently using Flot for the chart rendering. It handles annotations and zoom, take a look at their plugin library.
I recommend this downsampling plugin which will speed up graph rendering. Rendering 5000 points on your graph is useless: you have less vertical pixels on your screen than that! so this library will only render those that actually have a visual importance.
This only gives you the graph. You may want some kind of dashboard to present all that... I am currently looking at Grafana, which is used for a totally different purpose but makes awesome dashboards. It may be possible to "rip out" their dashboarding features (it uses Flot as well).
Another option is Hightcharts, but that's not free.
Check raphael js Library
Raphaël is a small JavaScript library that should simplify your work with vector graphics on the web. If you want to create your own specific chart or image crop and rotate widget, for example, you can achieve it simply and easily with this library.

Graphing Algorithm for many nodes

I have been trying to develop a web based application to help in the graphing of nodes and their interactions.
I have attempted to use the Sigma.Js with the Force Atlas extension.
For my simple tests (few nodes) the results are quite good-looking, however with an additional thousand nodes the result becomes quite a mess.
Is there any such way to make the result more view able? (easier on the eyes/not just 1 big blob) How would I go about doing this? Are there any algorithms already written(that I may implement?)
You can try the Fruchterman-Reingold force layout (for which there is a sigma plugin). It specifically minimises the number of links that cross each other, so it is in general more suitable for large graphs (unless all the nodes have lots of connections).
In addition, the fisheye plugin may help to make more sense of the graph after it has been drawn.
sigma.layout.forceAtlas2 scales much better, however it won't do miracles if the graph has a strong density of connections.

Directed acyclic graph using d3.js without DOT

I am trying to draw directed acyclic graph using d3.js. While searching for the layout, I came across Dagre but it seems to be of less use as I do not want to use DOT based code anywhere. If anyone knows about pure Javascript solution for this or plugin/custom layout for DAG, please let me know. Thanks in advance.
Dagre author here. Dagre doesn't include any of the graphviz code - it is pure JavaScript. It is based on similar layout techniques though; both are based on techniques from the Sugiyama paper.
You can find some examples of dagre here:
http://cpettitt.github.io/project/dagre-d3/latest/demo/interactive-demo.html
http://cpettitt.github.io/project/dagre-d3/latest/demo/sentence-tokenization.html
http://cpettitt.github.io/project/dagre-d3/latest/demo/tcp-state-diagram.html
The minified source can be found here: http://cpettitt.github.io/project/dagre-d3/latest/dagre-d3.min.js. It clocks in at about 44K.
Rendering directed acyclic graphs (and actually highlighting the directedness property) is a domain of the Sugiyama layout algorithms.
They basically assign layers (through a topological sorting) to the nodes and then calculate a sequencing for the nodes in the layers. Using a simple heuristic to reverse cycles first, this works well for cyclic graphs as well. Graphviz DOT has an implementation of this layout called dot, which is also the name of the file format it uses, so there sometimes is a bit confusion when DOT is mentioned.
Of course there are other implementations of the algorithm, even a cross-compiled Javascript version of dot is available. The probably most feature-complete solution available for Javascript is the commercial implementation of the algorithm in the yFiles library. So if this is in a commercial scenario, you might want to take a look at the corresponding live demo. Note that although yFiles comes with its own rendering and editor implementation, you could still plug the code into d3.js, since the layout algorithms can be used as standalone implementations to "just" calculate the coordinates of the nodes, the edge connection points, the bends, and the labels. This specific implementation supports a great number of additional constraints, like "Port Constraints" (to restrict the direction of the outgoing and incoming edges as well as their exact locations at the nodes), hierarchically grouped nodes (where each node can have a parent node and the parent node "contains" all of its child nodes), layer and sequence constraints, edge labeling constraints, different edge routing styles, bus-routing, and more.
Disclosure: I work for the company that creates said library, however on SO I do not represent my employer.

Categories