This post solves the limitation of JsPlumb graph layout by integrating with Dagre.
First, I assume that you assign an ID (which is supposed to be unique) to each node in your JsPlumb graph and a class "node" and JsPlumb graph are already created and you want to add automatic layout to that graph.
Now you can get all the nodes with jQuery as follows:
Thanks to Yuri Gor for creating a live demo at https://codepen.io/yurigor/pen/vXYomB
First, I assume that you assign an ID (which is supposed to be unique) to each node in your JsPlumb graph and a class "node" and JsPlumb graph are already created and you want to add automatic layout to that graph.
Now you can get all the nodes with jQuery as follows:
var nodes = $(".node");And you can get all edges using your JsPlum instance using:
var edges = inst.getAllConnections();With nodes and edges, you have everything you need to use dagre. Here's the simple code to layout your graph:
// construct dagre graph from JsPlumb graphYou can put the above code in a function (i.e. layout(nodes, jsPlumbInst)) to apply to any jsPlumb graph.
var g = new dagre.graphlib.Graph();
g.setGraph({});
g.setDefaultEdgeLabel(function() { return {}; });
var nodes = $(".node");
for (var i = 0; i < nodes.length; i++) {
var n = nodes[i];
g.setNode(n.id, {width: n.width(), height: n.height()});
}
var edges = inst.getAllConnections();
for (var i = 0; i < edges.length; i++) {
var c = edges[i];
g.setEdge(c.source.id,c.target.id );
}
// calculate the layout (i.e. node positions)
dagre.layout(g);
// Applying the calculated layoutg.nodes().forEach(function(v) {
$("#" + v).css("left", g.node(v).x + "px");
$("#" + v).css("top", g.node(v).y + "px");
})
Thanks to Yuri Gor for creating a live demo at https://codepen.io/yurigor/pen/vXYomB
Hi
ReplyDeleteDoes this require node to have x and y values ?
I want to draw plot where .css("left" and TOp are unknown but I know which is parent and which is child ?
Can this auto Position nodes without such information ?
x & y are being calculated for you by dagre.
DeleteIt will be helpful if you post an example at jsfiddle.net like http://jsfiddle.net/gXuS7/ but with auto positioning , where one doesnot know css top and left that is where to put divs
ReplyDeleteHi, Thanks for this blog - really it helped me to move further. I am also using JSPlumb and Dojo. But I had a query , with above reference I could rearrange the nodes of jsplumb connection. But I could not rearrange the edges. Those remain there itself. Does it need to get dragged along with the rearranged nodes? Or do we need to rearrange edges seperately as done in the last step.
ReplyDeleteHi, Thanks for this blog - really it helped me to move further. I am also using JSPlumb and Dojo. But I had a query , with above reference I could rearrange the nodes of jsplumb connection. But I could not rearrange the edges. Those remain there itself. Does it need to get dragged along with the rearranged nodes? Or do we need to rearrange edges seperately as done in the last step.
ReplyDeleteIf you redraw the node, it redraw the edges in the right positions.
DeleteThis comment has been removed by the author.
ReplyDeleteHi, thanks for this blog.
ReplyDeleteCould anyone please tell how to start the alignment of the elements from the middle instead of left side inside a container (div).
I see this code, is doing the positioning, I thought to give left padding but from centre the elements are not spreading like a tree evenly in left and right direction and are restricting y coordinate and spreading towards right side
g.nodes().forEach(function(v) {
$("#" + v).css("left", g.node(v).x + "px");
$("#" + v).css("top", g.node(v).y + "px");
});
Please suggest
hi can you please help me with your code align blocks as a vertical position and I need align as horizontal position.
ReplyDelete