JavaScript Graph Library

Dracula is a set of tools to display and layout interactive graphs, along with various related algorithms.

No Flash, no Java, no plug-ins. Just plain JavaScript and SVG. The code is released under the MIT license, so commercial use is not a problem.

Creating a graph is simple! You also can customize anything easily.

The code:

var g = new Graph();
 
g.addEdge("strawberry", "cherry");
g.addEdge("strawberry", "apple");
g.addEdge("strawberry", "tomato");
 
g.addEdge("tomato", "apple");
g.addEdge("tomato", "kiwi");
 
g.addEdge("cherry", "apple");
g.addEdge("cherry", "kiwi");
 
var layouter = new Graph.Layout.Spring(g);
layouter.layout();
 
var renderer = new Graph.Renderer.Raphael('canvas', g, 400, 300);
renderer.draw();

The result:

Enjoy.

Note: If you are looking for a commercially backed graph drawing software for the browser, take a look at the fantastic library yFiles for HTML! It is the most feature complete graph drawing library available for HTML5 and pleasant to work with.

113 thoughts on “JavaScript Graph Library

  1. Hello,

    Thanks for this awesome library. Really easy to use and looks nice.
    Unfortunately I got an error PopUp in IE8 and IE9 when drawing a complex graph (with many nodes and edges):

    “STOP RUNNING THIS SCRIPT?
    A SCRIPT ON THIS PAGE IS CAUSING YOUR WEB BROWSER TO RUN SLOWLY. IF IT CONTINUES TO RUN, YOUR COMPUTER MIGHT BECOME UNRESPONSIVE”

    Is there any solution for this problem?
    Many thanks!

    B.R.
    c0by

  2. Great man, evergreen framework…. could you please help me, how to connect parent and child nodes..? how to find out the distance between different nodes connected to one parent

    Thanks & Regards
    sri

  3. Hey man,

    I’ve browsed the internet for a js graph library yesterday and came accross yours.
    It is great and so easy to use.

    I am programming a small textadventure framework and you lib is being used to display the adventure steps and their connections. It works great.
    Thanks!

    Can you tell me how I can add mouseover events on the edges and nodes?

  4. Hi, great library! Did you ever implement being able to hard code the positions of the node instead of laying it out dynamically. If no, any pointers on how I could do this with dracula? I am working on a project that requires nodes to be at specific positions.

    1. I also had the same requirement and what i understood is even we set the position in render method its get overwritten in drawNode method in dracula_graph.js. So i commented out the line shape.translate(Math.round(point[0]-(box.x+box.width/2)),Math.round(point[1]-(box.y+box.height/2))) in the method so it keeps the node position.

      NB: I know this is not the right way to approach it, but still may help for basic requirements

      1. I implemented a simple fixed layout class, which worked fine. Just load the following JS and use this class as the layouter.

        /* Fixed layout method
        ===================

        Each node should be created by giving explicit “x” and “y” coordinates, which will be normalized when drawing.

        g.addNode(“N”, { x:4, y:8 });
        */

        Graph.Layout.Fixed = function(graph) {
        this.graph = graph;
        this.layout();
        };
        Graph.Layout.Fixed.prototype = {
        layout: function() {
        this.layoutPrepare();
        this.layoutCalcBounds();
        },

        layoutPrepare: function() {
        for (i in this.graph.nodes) {
        var node = this.graph.nodes[i];
        if (node.x) {
        node.layoutPosX = node.x;
        } else {
        node.layoutPosX = 0;
        }
        if (node.y) {
        node.layoutPosY = node.y;
        } else {
        node.layoutPosY = 0;
        }
        }
        },

        layoutCalcBounds: function() {
        var minx = Infinity, maxx = -Infinity, miny = Infinity, maxy = -Infinity;

        for (i in this.graph.nodes) {
        var x = this.graph.nodes[i].layoutPosX;
        var y = this.graph.nodes[i].layoutPosY;

        if(x > maxx) maxx = x;
        if(x maxy) maxy = y;
        if(y < miny) miny = y;
        }

        this.graph.layoutMinX = minx;
        this.graph.layoutMaxX = maxx;

        this.graph.layoutMinY = miny;
        this.graph.layoutMaxY = maxy;
        }
        };

        1. Hi Marcelo,
          if(x > maxx) maxx = x;
          if(x maxy) maxy = y; // need a correction here!!
          if(y < miny) miny = y;

          thanks in advance

          1. Marcelo and you are my heros!!!
            is exactly I was looking….
            correction:

            if(x > maxx) maxx = x;
            if(y > maxy) maxy = y;
            if(y < miny) miny = y;

            and add a missing:

            if (x<minx)minx=x;

  5. Hi, I find this really useful. Thank you for the work. One problem I am facing is putting a mouse down event for the edges. Is there any way that I can capture a click event on a edge label? I would appreciate any help. Thanks!
    Hrishi

    1. This should be now possible in the latest code on github. I’ve replaced the handlers to use drag instead of mousedown.

  6. Thanks for that. I am currently searching what projects are out there about visualisation. Thats how i found this. Thanks for publishing your work.

    1. Yes, still thinking about it, and have a few new features in the pipeline. Right now I want to fix the IE9 issue but don’t have much time…

  7. I’ve found/fixed a bug related to deleting edges. If the edge has a label, then it will remain painted on the canvas after the edge is deleted. In the dracula_graph.js file, inside of the removeNode function, before the statement this.edges[i].hide, inserting:


    this.edges[i].connection && this.edges[i].connection.label.hide();

    Seems to fix the problem nicely.

  8. Great library and it’s helping me a lot. My graphs display fine but I’m having some trouble with labels though. I think this is the right syntax:

    g.addNode(“Start”, {label:”START”});

    The node is drawn and with the proper edges but no text label in the bubble. Any thoughts about what this could be? Fails with both Safari and Chrome. Version is current as of today (11 Dec).

    Thanks!

  9. What else can you put inside the label-style? such as in the example below?
    I’d like to add a background to the label so the edge line doesn’t get in the way of the label.

    st = { directed: true, label : “Label”,
    “label-style” : {
    “font-size”: 20
    }
    };

  10. Hi i am vijay, I am new to this place.I have a question can we set the distance of nodes based on label values.
    e.g: I have set amount on the label so based on amount can we set the distance less amount less distance great amount great distance

    Thanx a lot.

  11. What sort of graph drawing algorithm do you use? is it forced based? eigen vector based? I’m sorry, I’m sure I could read the source code and figure it out, but hearing from you might be faster.

  12. Hi, thanks for the library! I’m wondering about how to make self-loops show up nicer. Currently, they seem to compress into .. nothingness, and their labels just float over the node. Any idea on how to fix this?

  13. Hello, thanks for this useful library!
    Is it possible to trigger an event (e.g. pop up a dialog box with the node’s label) if I were to select a node and then press a key (e.g. tab) on the keyboard? I couldn’t find a solution in the documentation.

  14. Hi everyone,I am working on project for graph databases.I am trying to display graph in a browser having 2000 nodes and 10,000 edges.I tried something for like 100 nodes and 200 edges using Jquery.but It is taking long time to display all the nodes.Do anyone have a better solution for displaying graph in a browser or for improving my time to load the graph fast.Help meThank you.

  15. I’ve put it on my list – won’t have the time in near-future. You should check out the file “dracula_graffle.js” – there the edge object is being created. Also, in the “dracula_graph.js” around the first lines there is the function that adds the edges… instead of “directed” you could introduce some feature like “dual” and then look for it in the dracula_graffle.js when drawing the arrows.

    1. Thanks for the quick reply!
      I’ll check the sources you mentioned. Is there also lying the solution for setting the width of edges?

      1. Yes, that’s also the place for the width. A generic solution would be nice, so you could set the width when creating the edge.

  16. Very good Library, I was looking at using arbor.js for a graphing project I am working on, but I think your Library might work better. Thanks.

  17. hi!
    Really great library here! I noticed the layout usually renders nodes from right area of the canvas (parent) to left (children) and bottom (parent) to top (children). Is there any way to reverse this? Thanks!

  18. how to insert label inside node ………
    how to draw graphs in table i.e each row as seperate graph
    ….plz help me out

  19. No, not yet. The node structure is somewhat in the Graph class as an JSON object, you could write a simple parser that iterates over this structure and generates XML or vice versa.

  20. Hello, considering a code like this:

    g.addEdge(“apple”, “cherry”);
    g.addEdge(“cherry”, “apple”);

    Is it possible to create an offset between these two generated connectors?

    Thanks in advance!

    1. No that’s not yet easily possible, you’d have to do it in the code. But somewhere in the future I would like to make it possible.

  21. I also have similar concern. Is it possible for a node to have multiple “endpoints” which terminates a edge?

      1. I would also appreciate a way that two directed edges in opposite direction are drawn without overlapping. Is there already a way to do this? Or is it possible to get the path object of Raphael to customize it?
        Thanks in advance!

      2. @Michael: Changing the width is easy. Look at dracula_graffle.js around lines 91-94 where you have the Raphael objects describing the lines. Also, each edge should have the fg and bg properties to work on.

    1. Just go to the graffle file, there the lines are defined, and replace the curve with a straight line or modify the curve that is described there. Don’t forget to check out the RaphaelJS docs on this!

  22. Hi

    Thanks for making this graph tool available. I am using this in
    my project to display the graph of authors with their connected co-authors.
    In the example or documentation the nodes labels and their names are added manually.
    eg) g.addNode(“Strawberry”)..and so on!!
    But what I am looking for is that how could I give the addNode method a list of names which it will get dynamically by a function for which it can draw the nodes and edges between them.

    Does anyone have an idea on how to do this?

    Thanks in advance.!!

  23. Philipp, Grigory does a good job – Tree Layout mode https://github.com/grigoryk/dracula-js-fork but he used an old version of your library. I tried implement his code in your last version but it doesn’t work. The main difference I see in your last code you use nodes = {} but in a Grigory’s code nodes = [] I guess the Tree Layout is a good extension for your library. Something like this http://thejit.org/static/v20/Jit/Examples/Spacetree/example1.html Do you plan add Tree Layout in your project?

  24. Hi, download link doesn’t works… could you fix it or get another one please?
    GitHub get a page with a 404 error for dracula_0.0.3alpha3.tar.gz file…
    Thanks

  25. Hi,

    I have so much edges on my graph and began be unreadable. It is possible create a graph with scrollbar?

    1. I created a small, scrollable container div and into it I put a much larger canvas div. Make sure you set width/height to the actual width/height of your canvas and it will work.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>