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.

107 Responses to JavaScript Graph Library

  1. Robb Shecter says:

    That’s an awesome, simple API. Thanks! If I get it up and running like I’m thinking, I’ll send you a link to it.

  2. Ivan says:

    Hi,
    Thanks for the code!
    What I need more, is to be able to fix the position of all the old nodes when redrawing, and only to add the new nodes with minimal rearrangement of the nearby nodes.
    Please advise. Thanks.

    • Johann Philipp says:

      Currently this is not easily possible, though it is somewhere on my list… check back in a few months!

      • vijay says:

        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.

  3. Tony Kumin says:

    hi there

    thank you for your framework.
    I have been modifying the original version dated 02/03/2010 for the last couple of months for visualization of a debate for my bachelor thesis. of course i will cite you.

    if you feel like having a sneak peek, email me such that I tell you the project page

    cheers,
    Tony Kumin

  4. Brian says:

    There is an error in dracula_graph.js

    nodes should be initialized to {} not [].
    Otherwise you’ll iterate over “forEach” and introduce a spurious node.

  5. Anonymous says:

    Hi,

    with Firefox it works fine, but on Internet Explorer it doesn’t :(

    (I’ve tested it under Internet Explorer 7)

    Will it be cross-browser in the future?

    • Johann Philipp says:

      Yes, cross-browser is on my roadmap. Currently, only modern, standard-conform browsers are supported, like Opera, Safari, Chrome, Konqueror and Mozilla/Firefox should work. I haven’t tested IE yet, since I’m mostly on Linux, but have you tried IE8? I am confident that IE9 will work fine with my library once it is released. I think they actually invested some work in version 9.

      • Nicky says:

        Hi,
        Thanks for the great framework!
        When I run the example on Chrome and Firefox, it works find. But under IE8, there is a javascript error in graph.js(line 216, char 9) and can’t disply the graph.

        Hope can cross-broswer soon, many thx~

        • Johann Philipp says:

          Hi Nicky, unfortunately it doesn’t work on IE9 either (until now). I promise to look into it, once I am on a windows machine again, but from my experience with IE this won’t be an easy fix and I am not sure I want to invest like 60% of my time only to make it work on IE. Microsoft is a big company, they should finally get a decent browser working. My lib works out-of-the-box on Webkit (aka Safari/Chrome), Opera and Mozilla, with only one small adoption I had to fix to make it work. Opera is a tiny company compared to Microsoft, and Webkit on the other hand even started as a hobbyists project. So, if it’s only a few minor fixes, I will do it. Otherwise, as I read somewhere else: The best way to support Internet Explorer is not to support it. A warning message may be an option.

        • Johann Philipp says:

          Ah, by the way: Line 216 Char 9 is a closing bracket as far as I see it… looks like fun tracking this one down :-)

          • Steve Meyfroidt says:

            As a quick and stupid hack, commenting out lines 216 and 217 allows the graph to draw, although it disables dragging.

            Can’t find any way to debug the problem further within IE so maybe it’s enough to disable drag for unfortunate IE users.

          • John Campbell says:

            the solution is to uncomment the “forEach” function these lines use :)
            this works for me!

          • Johann Philipp says:

            Ah, okay, not every JavaScript implementation has “forEach”. I will re-introduce it along with a test for if that function already exists.

  6. Shadow Caster says:

    This is a really good project. Is it possible to put stuff inside the node shapes and on the edges?

  7. Max Floettmann says:

    Hi Johann,
    I’d like to your library for my project. As I am dealing with slightly bigger graphs I’d like to be able to zoom in and out aswell as pan around. Is there a simple way to implement that in Dracula/Raphael?
    Thanks for the great work here!

    • Hi Max,

      While not exactly “zooming” in a sense that you’re using the word, you can very easily implement “zoom in” and “zoom out” buttons that will enlarge the graph, or make it smaller.

      Here’s a very crude implementation of such zoom function. With this “zoom” you’d have to pan around using browser’s own sliders. Which might be just good enough :-)

      (There’s probably a better way to do this with something in Raphael, but I haven’t looked yet.)


      // some initial size
      var depth = 1000;

      function zoom(type) {
      g = getGraph(root);
      document.getElementById('canvas').innerHTML = "";

      // this my experimental Tree layout mode - see https://github.com/grigoryk/dracula-js-fork
      var layouter = new Graph.Layout.Tree(g);
      layouter.layout();

      // scale the size accordingly
      if (type == "out") {
      depth = depth * 0.9;
      } else {
      depth = depth / 0.9;
      }

      // redraw
      var renderer = new Graph.Renderer.Raphael('canvas', g, depth, depth);
      renderer.draw();

      return false;
      }

      I have a pretty good idea of how to implement proper “drag-the-graph” panning, so I’ll be pushing these changes to my github fork of Dracula (https://github.com/grigoryk/dracula-js-fork).

      cheers,
      Grigory.

  8. Joel says:

    Hi Johann,

    My company is about to start work on a project
    involving creating a visualization of our client’s
    employees and the internal workgroups with
    which they are associated. Your graph library
    seems like it would be a good fit for the project.

    Would you be interested in helping with the project?
    If so, send me an email and I can give you more details.

    Sorry to use your comments section for a question
    like this, but I couldn’t find any other way to contact you.

    Thanks.

    – Joel

  9. Hi all,

    Johann – thanks a bunch for putting this framework together!

    I needed a Tree Layout mode to represent large directed graphs, and have implemented it for myself.
    You can get my updated version of Dracula with an experimental Tree Layout mode here: https://github.com/grigoryk/dracula-js-fork

    Maybe Johann will merge it into the main version :-)

    cheers,
    Grigory.

  10. Tanya C says:

    Awesome! Any way to use custom images as the nodes?

  11. Hi Johann,

    I currently looking into using your framework for my final year dissertation to create a entity relationship diagram.

    I am having a problem with the nodes going over the canvas boundaries. Its when I render the nodes as rectangles, below is a link to show the problem:
    http://free-12415f14c3a-124e539428a-12b7bbd740a.sandbox.cs4.force.com/

    Is there a simple fix or will I need to look into changing the code in dracula_graph.js?

    Thanks,

    Peter

    • Johann Philipp says:

      Hi Peter, sorry for the late answer, busy these days… so, you will only have to change two hard coded values. I was going to make the thing more generic to actually consider the dimensions of the boxes, but until now there is one bounding box around where the dragging is coded and somewhere there’s also a radius that makes the nodes have some distance to the frame. Can you post it when you found it? Thanks! :) and good luck!

  12. patembe says:

    Hi Johann,
    nice work, but after I use it for retrive a large data from my database, it look like ugly graph :( how about just show little node from the root, and then show the next node when clicked :D just like http://thejit.org/static/v20/Jit/Examples/Spacetree/example2.html does

    • Johann Philipp says:

      Hi Patembe, hiding nodes is on my list, I have even already started hacking… but will still take some months I think :-)

  13. Marc says:

    Hi Johann,

    Thanks for making this great library.

    I am attempting to use it for a small project for a client, and I am coming across bugs/missing features, such as the inability to adjust the text size for edge labels.

    Are you maintaining this code and accepting patches?

    If so, would it be possible for you to move the main repository to Github, or to otherwise make it easier for users of Git to submit their changes? I see that there is already one fork on Github, for Grigory’s Tree code (https://github.com/grigoryk/dracula-js-fork). I would hazard to guess that many of the users your work has attracted are Github users ;)

    I don’t have time to learn how to use launchpad now…

    • Johann Philipp says:

      Hi Marc, I am thankful for any improvements and patches, of course! Since there seems to be a demand for GitHub users to take part, I’ll soon set up some way to merge Git and Bazaar (used by Launchpad) changes. Others also seem to do it.

      Anyway, Bazaar and Git are almost the same, really! Except that Bazaar uses “branch” instead of “clone”. Okay, so stay tuned, I’ll post a message as soon as I have set up a GitHub mirror of the code… thanks in advance for any improvements.

  14. Dan Brickley says:

    Hi! Great stuff. I found this via the ‘graph’ tab in http://lackoftalent.org/michael/ which uses dracula to display RDF graph data. These have node-edge-node structure where the edges are labelled and directed. Doing this in Dracula seems a bit tricky, unless I’m missing something. My version of that hack is at svn.foaf-project.org/foaftown/2010/ogrdfa/rdfa1.html but buggy and just a workaround; I introduce additional nodes for each edge label, which is a bit awkward.

    All of which is longwinded way to ask: how can I label the edges of a graph? I’m sure it must be possible but haven’t figured it out yet…

  15. Lars says:

    Nice graphing tool. Thanks for making this available and open-source.

    Have you considered integrating edge routing into it as an option?
    See Integrating Edge Routing into Force-Directed Layout.

    This is an important feature for our application. I’m not sure how feasible it is to do in the browser, especially with larger graphs; but JS is getting much more powerful and fast these days, and what used to be server-only tasks can now be done in the browser.

    There are a lot of things that can be done with separation constraints to “allow
    aesthetic requirements—such as placement of nodes below other nodes in
    directed graphs or containment of nodes in clusters—to be integrated into force directed layout.” Not all of them have to be implemented all at once, but if Dracula offered these features, it would be unique among client-side graph layout libraries.

    Thoughts?

    • Johann Philipp says:

      I’d love to see edge routing, but it would take too much time right now… at the end of the year is realistic.

  16. Borja says:

    Hello,

    Nice and great tool, first of all. I’ve been playing with it, and mixing it with my GWT and SmartGWT application. And that’s why I’ve found what I think it might be an important bug..

    Using your library, suddenly some of the mouse event weren’t working well, so I investigated.. Finally I found it.

    On your dracula_graph.js, at your ‘Graph.Renderer.Raphael’ function (line 152) you capture two mouse events (onmousemove and onmouseup), but you are using ‘document.onmousemove’ and ‘document.onmouseup’, and that’s a too wide scope I guess…

    Those definitions were interfering with the behavior of my GWT application. I’ve solved it (quite simple) replacing ‘document’ by the element where the SVG is drawn (as you have it’s id as argument). As follows:

    var d = document.getElementById(element);
    d.onmousemove = function() { (…) }
    d.onmouseup = function() { (…) }

    This way everything works like a charm :)

    • Johann Philipp says:

      Thanks a lot for your fix! Using mouse events on document is definitely evil :-)
      Also, I was thinking of using the hover event as it seems to me easier to handle…

      I will include your fix in the latest sources soon!

  17. AB says:

    I’m using this library right now for a project of mine, I just wanted to say thank you.

  18. Soren says:

    Hi.

    Is there some built-in way to get graphdracula to draw two directed edges in opposite direction without overlapping?

    Eg. I have a graph like:
    g.addEdge(“a”, “b”, {directed:true});
    g.addEdge(“b”, “a”, {directed:true});

    Thanks for a nice library, good for quick stuff :)

    • Vijay Mohan says:

      Any luck on this?
      It crashes for me…..

      • dyl says:

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

        • Luiz Gustavo says:

          Same concern…

          • Michael says:

            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!

          • Michael says:

            Another thing I would like in the framework is, that you could change the width of an edge.

          • Johann Philipp says:

            @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.

    • Johann Philipp says:

      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.

  19. Cosmin Mutu says:

    Hi, great api and great implementation, but IE has some problems.

    For example, on IE 7 or 8 if you do a double click anywhere on “canvas” (here on your demo) and then you do a double click on any graph node a very nasty error will be born … check it out :)

  20. Vijay Mohan says:

    Nice work!
    Does it support bidirectional edges? eg node A connects to node B and node B connects to node A as well. Me thinks it will crash….
    Still this is awesome!

  21. Patrik says:

    Brilliant thanks for sharing mate :)

  22. Dennis-GAO says:

    I am a new user. I try to run the example code at the first page, but it doesn’t work, I get the error message :
    layoutPostX is null in the 379 line of dracula_graph.js

    This is my jsp file:

    chat

    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();

  23. Dennis-GAO says:

    Is it any function can delete an edge?

  24. EddieS says:

    Is there a way to clean the canvas so a different graph can be drawn on it?

    • ayesha says:

      change the Graph.Renderer.Raphael function in main file and return this from it. then you can call its draw method to redraw the graph, you will also need to call the layout method on layouter.

  25. ayesha says:

    How do I disable dragging?

  26. Vaibhav Darji says:

    Hi.
    Nice,simple and useful api.
    but i want more functionality.
    is it possible that we can edit edge or we can drag-drop edge and change node by drag and drop edge?
    Thanks.

  27. Ricardo Henrique says:

    Hi,

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

    • biziclop says:

      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.

  28. shreyas says:

    its simply awesome…

  29. shreyas says:

    hi can u help provide implementation for a binary tree graph

  30. Luis says:

    Thanks. Helped me a lot.

    Check this library working in a final project: directedgraph.co.cc

    Thanks again!

  31. Desperado says:

    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

  32. michael says:

    Getting the following error on IE8:

    layoutPostX is null in the 379 line of dracula_graph.js

  33. Antony says:

    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?

  34. academo says:

    Can the nodes point to himself? lines is not well-drawed, any help please

  35. Sid says:

    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.!!

  36. Lorand says:

    can i save the node structure in xml string ???for example!

    • Johann Philipp says:

      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.

  37. €quiman says:

    How I can customize the connector like a straight of 90 grades instead the sinusoidal form?

    • Johann Philipp says:

      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!

  38. Luiz Gustavo says:

    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!

    • Johann Philipp says:

      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.

  39. Harsha says:

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

  40. Joe says:

    How can I attach an event(onclick, mouseover) to an edge? or a custom object?

  41. Joe says:

    What I meant to say was “How can I attach an event to the text object of an edge?”

  42. areszen says:

    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!

  43. Chris says:

    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.

  44. Great Work, i hope we can embed it in our last data centric project. I love the simplicity a minimal design

  45. Anonymous says:

    Hi,

    do you have a version that produces stable results,
    i mean the same layout with the same data set?

    Thanks.

  46. kim says:

    nice library! is there a way i could export the graph to an image (jpg, png, pdf, etc) in IE7+? how about in mozilla or chrome?

  47. Cheney Tsai says:

    How would you grab the id of a node that you’re dragging.

  48. koushik says:

    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.

  49. Rubens Pinheiro says:

    How can I remove a link between two nodes?

  50. Carrie says:

    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.

  51. Puneet says:

    I have been following this library post for quite a long time now. I wanted to check if the layout algorithm using in this js library avoids collision between edges or tries to reduce the crossing between edges?

  52. ivan says:

    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?

  53. Bob Chen says:

    Hi, Johann
    is there any way to draw a graph like http://www.ryandesign.com/canviz/ ?

  54. JDoe says:

    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.

  55. Anonymous says:

    Nice! Going to give a shot at using this with Apple’s iAd Producer – http://developer.apple.com/iad/iadproducer/ – and RDF data structures (OWL namely) maybe with something like Joseki – will see how that works out…

  56. GregM says:

    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
    }
    };

  57. Kyle Hailey says:

    Awesome stuff. I’d love to use it to diagram SQL interactive graphs in browsers as in http://dboptimizer.com/db-optimizer/. The tool DB Optimizer is a fat desktop client. Would be so nice to web enable it.
    How is the project going. Most of the posts seem to be from last year.
    Best Wishes
    Kyle Hailey

  58. 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!

  59. Anonymous says:

    is it possible to have it as a heirarchical structure and also allow multiple parent nodes ?

  60. ArNo NyHm says:

    It seems it not works on iphone web browser

    iPhone 4
    iOS5

  61. Michel Kogan says:

    How can I draw multigraphs with this ?

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> <pre lang="" line="" escaped="" highlight="">