Search code examples
javascripthtmlcssgraphjsplumb

Force expell library for given div-structure


Given a HTML structure like so:

<div id="canvas">
    <div class="group group-normal" id="1">hello world</div>
    <div class="group group-infiltrated" id="2">whats up dogue</div>
</div>

I currently use jsPlumb to create a graph from that structure:

$(function() {

    jsPlumb.Defaults.Container = $("div#canvas");

    jsPlumb.draggable($("div.group"), {
        containment: $("div#canvas")
    });

    var stateMachineConnector = {               
        connector: "Bezier",
        paintStyle: { lineWidth: 2, strokeStyle: "#056" },
        endpoint: "Blank",
        anchor: "Continuous",
        overlays:[ ["PlainArrow", { location: 1, width: 15, length: 12 } ]]
    };

    jsPlumb.connect({
        source: "1",
        target: "2"
    }, stateMachineConnector);
});

Which already gives me a nice, draggable graph:

Simple-graph

The problem is, that when initialising the graph, all the divs are in the upper left corner of the canvas. I learned that this is due that jsPlumb only provides functionality to layout a graph, but not to position it.

I then went on a scavenger hunt and found many useful libraries that deal with positioning, like springy, sigma and alike. The problem is: Most of the don't operate on divs, but rather on some (for me) instransparent SVG/Canvas object graph.

I like jsPlumb very much and would like to keep using it. The only thing I need from other libraries is the initial positioning of all the elements.

How can I make the elements be positioned more evenly over the space available, maybe even in a way that makes them arrange the same way every time the graph is initialized?


Solution

  • Here is the plugin for positioning DIV's which has connectivity: https://github.com/lndb/jsPlumb_Liviz.js Basically the plugin is derived from graphviz js library.

    You need to pass the connectivity information to the library through a textarea(id=dot-src). So whenever you establish a connection, store the connectivity info in a string and later pass it to the Liviz library for positioning it.

    str='digraph MyGraph {'; // This string will be set to the textarea at the end.
    
    // Whenever connection is created update the string.
    jsPlumb.bind("jsPlumbConnection", function(ci) {
                console.log($('#'+ci.sourceId).data("prop").dn+"->"+$('#'+ci.targetId).data("prop").dn);
                str+=ci.sourceId+"->"+ci.targetId+";";
    });
    
    // At the end set the string and call Liviz function
    $('#dot-src').text(str+"}"); // Set the string
    w_launch(); // call the library to position the DIV's based on connectivity.
    

    You can explore graphviz for different types of options to customise positioning.