dagrejs / dagre-d3

A D3-based renderer for Dagre
MIT License
2.85k stars 587 forks source link

Multiple labels on edges #44

Open braibant opened 10 years ago

braibant commented 10 years ago

Is it possible to have multiple labels per edges (or to customize the way labels are printed?) If it is the case, it would be nice to have an example of use.

cpettitt commented 10 years ago

Do you mean something like this? http://cpettitt.github.io/project/dagre-d3/latest/demo/interactive-demo.html?graph=digraph%20%7B%0A%20%20A%20-%3E%20B%20%5Blabel%3D%22label1%5Cnlabel2%5Cnlabel3%22%5D%0A%7D

Or something like this? http://cpettitt.github.io/project/dagre-d3/latest/demo/interactive-demo.html?graph=digraph%20%7B%0A%20%20A%20-%3E%20B%20%5Blabel%3D%22%3Col%3E%3Cli%3Elabel%201%3Cli%3Elabel%202%3Cli%3Elabel%203%22%5D%0A%7D

Or something else?

braibant commented 10 years ago

I could do with both. So, the preferred way to have multiple labels is to tweak the label string, right?

cpettitt commented 10 years ago

If you want multiple labels on the same edge, you'd tweak the label string. If you can use multiple edges between the same nodes, you could also do something like this: http://cpettitt.github.io/project/dagre-d3/latest/demo/interactive-demo.html?graph=digraph%20%7B%0AA%20-%3E%20B%20%5Blabel%3D%22label1%22%5D%0AA%20-%3E%20B%20%5Blabel%3D%22label2%22%5D%0AA%20-%3E%20B%20%5Blabel%3D%22label3%22%5D%0A%7D.

braibant commented 10 years ago

Yes, my first solution was to use several edges between the nodes (I am pretty printing the source of the graph from another language). Problem is that I have ~20 edges in some of my graphs, which does not make nice graphs. Thanks for the help (but I believe that it could be interesting to add your examples in the doc)

braibant commented 10 years ago

A bit of topic, but still related to my seminal question: I have big graphs and I wonder if it is possible to scale them automatically to fit a given rendering box (by that, I mean an svg div).

cpettitt commented 10 years ago

The output graph has width and height attributes, so you could override postLayout in the renderer to set a scale transform based on the desired dimensions.

braibant commented 10 years ago

Thanks again for your answers. Coming back on the main subject, I have a kind of pie-in-the-sky wish. I can choose to use \n to order my labels vertically on a given edge, or I can choose to use a blank to separate them in an horizontal manner. I wonder if it could be possible to have a kind of formatting box that would ask the renderer to choose between these two options on a case by case basis, to optimize the layout. I am referring to the following kind of boxes, http://caml.inria.fr/resources/doc/guides/format.en.html but I do not know to what extent your layout algorithms can be tuned to exploit this extra level of freedom (or if one would find it desirable).

sguidos commented 9 years ago

For those who may have a similar question and find this page, I wanted to add what I learned on this topic. I was trying to create multiple edges between the same 2 nodes, which is a little different than creating multiple edge labels for the same edge.

By default, graphs in GRAPHLIB can only have one edge between two given nodes. Also, the GRAPHLIB documentation states that the method graph.setEdge(v, w, label) will create OR UPDATE the label for edge(v,w). This is why, when you call graph.setEdge('Parent', 'Child', 'Label') a second time, instead of add a new edge (like I expected) the method instead updates the label of the existing edge between these 2 nodes.

To have more than one edge between the same 2 nodes, you must first specify the graph type as "multigraph" when you create the graph object: var g = new dagreD3.graphlib.Graph({ multigraph: true });

Now, when you add edges, each edge must also have a unique "name" to differentiate them within the multigraph. You do this by including the unique name as the optional 4th parameter in the setEdge method: graph.setEdge('Parent', 'Child', 'Label', 'edge1'). To manipulate your multigraph, the other "edge" related methods will also require this optional "name" parameter to identify a particular edge: removeEdge(), hasEdge(), edge(), etc.