Code Monkey home page Code Monkey logo

dracula's Introduction

Graph Dracula - a JavaScript Graph Library

Build Status Backers on Open Collective Sponsors on Open Collective

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

Based on JavaScript and SVG.

The code is released under the MIT license, so commercial use is not a problem.

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

  1. install the dependencies:

     npm install --save graphdracula raphael
    

    or jspm install npm:graphdracula

  2. create an html file with a tag having the ID paper.

  3. require graphdracula (via browserify or webpack):

var Dracula = require('graphdracula')

var Graph = Dracula.Graph
var Renderer = Dracula.Renderer.Raphael
var Layout = Dracula.Layout.Spring

var graph = new Graph()

graph.addEdge('Banana', 'Apple')
graph.addEdge('Apple', 'Kiwi')
graph.addEdge('Apple', 'Dragonfruit')
graph.addEdge('Dragonfruit', 'Banana')
graph.addEdge('Kiwi', 'Banana')

var layout = new Layout(graph)
var renderer = new Renderer('#paper', graph, 400, 300)
renderer.draw()

How To Develop

git clone [email protected]:strathausen/dracula.git
cd dracula
npm install
npm start

Point your browser to one of examples in examples/.

Contributors

This project exists thanks to all the people who contribute.

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

dracula's People

Contributors

alfadur avatar dependabot[bot] avatar donatj avatar keeganwitt avatar kingkero avatar kuzeko avatar masklinn avatar monkeywithacupcake avatar monomon avatar ms-ati avatar ptarjan avatar robertleeplummerjr avatar seijikun avatar snyk-bot avatar strathausen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dracula's Issues

How can I delete a node and edge?

I tried to remove the node by delete corresponding component in .node and .nodelist. But the nodes remained the same after I redrawed...

edge styles are not detected during rendering

Case test with last Dracula version :

graph.addEdge('Dragonfruit', 'Banana');
graph.addEdge('Kiwi', 'Banana', { directed : true } );
graph.addEdge('Banana', 'id35',{ stroke : "#f00" , fill : "#56f", label : "test" });

Default renderer doesn't draw arrows or other styles inside {}.

This problem is that function Connection() expects style as third parameter,
but receives always a null var from function drawEdge().

So I changed this original code:

    key: 'addEdge',
    value: function addEdge(source, target) {
    var edgeData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

writing this:

    key: 'addEdge',
    value: function addEdge(source, target) {
    var edgeData = {};
    if(arguments.length > 2 && arguments[2] !== undefined) {edgeData.style = arguments[2];}

In this way works; let me know if it's the best way to fix it.

Regards,
Andrea

No edges between rectangles

When adding edges between nodes with text inside them, if one of the two is a rect the edge won't show up.

I tracked the problem down to the graffle file where getBBox is not working for the set passed as input to the Connection function.

Not sure if it may be due also to a RaphalelJs bug.

The custom rendered I'm using is :

filledRenderer : function(r, n) {
        var frame = {};
        var label = {};
        if(typeof n.round === 'undefined' || !n.round) {
            frame = r.rect(n.point[0], n.point[1], 90, 30);
            label = r.text(n.point[0]+45, n.point[1]+15, n.label);
        } else {
            frame = r.ellipse(n.point[0], n.point[1], 50, 18);
            label = r.text(n.point[0], n.point[1], n.label);
        }
        frame.attr({"fill": "#69c", "stroke-width": 1, r : "5px"});
        var set = r.set()
          .push(frame)
          .push(label);
        return set;
    }

TypeError: this.r.connection is not a function

I can't seem to draw any edge in my javascript.

TypeError: this.r.connection is not a function
edge.connection = this.r.connection(edge.source.shape, edge.target.shape, edge.s...
    dracula_graph.js?body=1 (ligne 306, col. 24)
TypeError: this.r.connection is not a function

On the WEB I see many people using r.connection without any problem... yet the function is not defined. I tried downloading the latest version of Raphael, but it didn't help

Sources in Examples Out of Date

Hi, I would love to further evaluate your project for use in my open source application. A barrier that I am experiencing is that most of the sources are out of date on the examples. Specifically with the classes example, the following are not able to be found. I found valid CDN links for jQuery and for 45 min attempted to find the correct files, but it seems there has been quite a bit of file restructuring since these examples were first developed. Could you help me get classes example up and running, and potentially fix the sources on all examples? I think this might help future users as well. Thank you, great project!

"../vendor/raphael.js"
"../vendor/jquery-1.8.2.js"
"../lib/dracula_graffle.js"
"../lib/dracula_graph.js"

Custom styling of nodes doesn't work

In the documentation, it's apparently possible to be able to add styling to a node like so:

g.addEdge('id35', 'apple', { style: { stroke: '#bfa', fill: '#56f', label: 'Label' } });

However, doing this in practice doesn't work.

Looking through the source, I can see the node.style gets stored, however in the renderer it is never considered, the colour is still chosen randomly by Raphael and the custom labels aren't applied.

click event modification

Hello,
it could be very helpfull to have the possibility to add a click event handler for the nodes.

Thanks

Groups, Expandable Collapsible groups

So, I don't know if this is on your roadmap, but many libraries for graph lack this functionality and in many cases where we have some hierarchy in large graphs such features are a must. Just to explain in more details:

Allow nodes to be assigned to groups, and groups to be assignable to other groups as well to form hierarchies. Allow easy to collapse/expand groups to a single node.

Sorry I can't help with this, but really I am not experienced in js.

Specify sides from which to connect a node

When creating node/edge specify sides on which to allow connections
(e.g. allow only north and south)
This is a bit specific, but it might be useful. It is a small change in graffle, will post a patch soon.
Let me know if you think it fits, though.

option to disable node dragging

I need a way to disable dragging on some nodes.

Case test:
graph.addNode('Banana', { nodrag:true });
I changed the original code at bottom of drawNode():

node.shape.connections = [];
dragify(node.shape);

resulting in:

node.shape.connections = [];
if(!node.nodrag) {dragify(node.shape);}

Is there a better way to do it ?

Regards
Andrea

constant layout

Are there any plans to support a constant layout of a grpah?
e.g. if I give the same edges/nodes the graph looks the same everytime
the API anf features are great, but unfortunately this is currently my showstopper...

Error in hide function

when i call hide function it hides the node, while try to remove edge it gives the following error:
"Uncaught TypeError: Cannot read property 'connection' of undefined "
what seems to be the problem. am I using it properly?

Node labels that aren't IDs

I had an idea for an enhancement. It'd be cool if we could specify a label for nodes that is different than the ID used to connect nodes with edges. For backwards compatibility, if the node label isn't specified, the label could default to the ID.

line break

Is there a way to put a line breaker in node label?

banana

Edges are not rendering

Hi my Edges are not rendering.

The Nodes are displayed fine.

Can you help me to fix this problem?

Dynamically add nodes or edges

Hi, I need to dynamically add stuff to the canvas but all aproaches I try fail.

$('#asd').click(function() {
    ggg.addEdge("A3-1","S1", {  });
});

Also tried to clear the existing canvas and redraw it entirely (failed also)

$('#asd').click(function() {
    $('#canvas').html('');
    ggg.addEdge("A3-1","S1", {  });
    var layouter = new Graph.Layout.Spring(ggg);
    var renderer = new Graph.Renderer.Raphael('canvas', ggg, width, height);
});

The nodes are correct and adding the edge on initialization works fine, is this a bug in dracula?

Three Bugs

Hi, Firebug gets me three Errors:

ReferenceError: Raphael is not defined

Raphael.el.tooltip = function (tp) {

dracula_graph.js (Row 491)

ReferenceError: Raphael is not defined

Raphael.el.tooltip = function (tp) {

dracula_graph.js (Row 491)

TypeError: this.r.connection is not a function

...e.connection = this.r.connection(edge.source.shape, edge.target.shape, edge.styl...
dracula_graph.js (Row 281)

documentation

Could you wright a step by step tutorial on how you got your example? I looked at this project because I wanted a replacement for graphviz in my app. I wanted to just add edges to a graph similar to the manor you add edges in your example on your blog. its very much like graph viz

Issue with new version

Hi,

I am using Dracula for scientific project, and I can see there is new version. I tried to use it in my old code which was using previous version of Dracula, but there are some problems. I don't see any error, but the graph is not looking as it should.
Could you please tell me what changes did you make to code, so I could set it. Also, it is very confusing having examples here on github which are not working with new version.

Renderer for Graphviz graphs?

Is it possible to display Graphviz graphs (xdot renderer) with vivagraph?

Example of Graphviz dot file

digraph G {
0 [label="A"];
1 [label="B"];
2 [label="C"];
3 [label="D"];
4 [label="E"];
0 -> 1 [ ];
0 -> 3 [ ];
1 -> 2 [ ];
1 -> 4 [ ];
2 -> 3 [ ];
3 -> 4 [ ];
}

Algorithms export?

Hi there!

I was wondering why there is no export for Algorithms. I wanted to pass an ordering to the layout, but I noticed that 'graphdracula' modulo exports do not include any of the algorithms, so I need to compute it by hand, while there's a topologicalSort available.

Is this intentional?

Node out of bound

Hi,

I'm trying to use a custom node render, to make larger nodes with this code:

    function nodeRender(r, n) {
      //the Raphael set is obligatory, containing all you want to display
      return r.set()
        .push(r.rect(-30, -13, 130, 60).attr({
          'fill': '#FFF',
          'fill-opacity': 0,
          'stroke-width': 2,
          r: 9
        }))
        .push(r.text(35, 10, n.label).attr({
          opacity: 1,
          'font-size': 16
        }))
    }

But when i do that, some nodes go out of bound of the selected canvas, i think i need to tell dracula the new node size, but i'm not sure how to do that.

I have a full example here: https://jsfiddle.net/tkheyznr/1/
(i hope jsfiddle is ok)

Thanks in advance

Minimal example for NodeJS developer

Hi,

I am a NodeJS developer. Unfortunately, I was not able to make a simple example work. May you provide a step-by-step procedure for me to follow?

Best regards,

Enhancement: distinguish opposite direction paths between two nodes

I have a enhancement suggestion for drawing edges in the graph. It would be nice if opposite direction paths between two nodes can be different. In my use case, I'm labeling the path with weights and currently there is no way to tell if the number displayed is in which direction (they are also displayed right on top of each other). Is there a way to draw a different edge path when there is already one between two nodes?

Publish to Bower

While you have a bower.json (which is half of the battle), it looks like you're not actually published on bower, which would be the other half.

The other other half is knowing.

You can publish to bower via this command:

bower register graphdracula git://github.com/strathausen/dracula.git

It doesn't actually have to be you who does this, I could do it for you. But it seems like something intimate between a developer and his or her code, and I wouldn't want to do it without permission.

Can't draw inside my element. [function Renderer problems with Jquery]

If Jquery (last version) is loaded, the function Renderer is not able to draw inside a wanted element.
This is because jquery returns a wrapper to en element, not the dom element itself.

Test case:
var renderer = new Renderer('#paper', graph, 400, 400);
I have a div element with 'paper' id but the rendering doesn't happen inside it

The original code frangment is:
if (typeof element === "string") {

                    var selector = typeof $ !== "undefined" ? $ : function(q) {
                        return document.querySelector(q)
                    };
                    element = selector(element);
                }

To solve my problem I modified into:

                if (typeof element === "string") {
                	element = (typeof $ !== "undefined")? $(element)[0]: document.querySelector(element);
                }

Regards
Andrea

Better Aesthetics

Added animated hiding/showing, which Raphaeljs already supported. Show/Hide also shows/hides related edges so left over edges are less confusing.

Using Version (0.0.3alpha4)

--- dracula_graph.js 2011-07-13 12:50:27.712185500 -0400
+++ js/dracula_graph.js 2011-07-13 12:41:25.198939600 -0400
@@ -29,8 +29,26 @@
}
AbstractEdge.prototype = {
hide: function() {

  •    this.connection.fg.hide();
    
  •    this.connection.bg && this.bg.connection.hide();
    
  •   this.connection.fg.animate({opacity:0},1000,"backOut",function () {
    
  •       this.hide();
    
  •   });
    
  •   this.connection.bg && this.connection.bg.animate({opacity:0},1000,"backOut",function () {
    
  •       this.hide();
    
  •   });
    
  •   this.connection.label && this.connection.label.animate({opacity:0},1000,"backOut",function () {
    
  •       this.hide();
    
  •   });
    
  • },
  • show: function() {
  •   this.connection.fg.animate({opacity:1},1000,"backIn",function () {
    
  •       this.show();
    
  •   });
    
  •   this.connection.bg && this.connection.bg.animate({opacity:1},1000,"backIn",function () {
    
  •       this.show();
    
  •   });
    
  •   this.connection.label && this.connection.label.animate({opacity:1},1000,"backIn",function () {
    
  •       this.show();
    
  •   });
    
    }
    };
    var EdgeFactory = function() {
    @@ -97,7 +115,7 @@
    */
    },
    removeNode: function(id) {
  •    delete this.nodes[id];
    
  •   delete this.nodes[id];
     for(var i = 0; i < this.edges.length; i++) {
         if (this.edges[i].source.id == id || this.edges[i].target.id == id) {
             this.edges.splice(i, 1);
    
    @@ -115,16 +133,31 @@
    node.id = id;
    node.edges = [];
    node.hide = function() {
  •    this.hidden = true;
    
  •    this.shape.animate({opacity: 0},1000,"backOut",function () {
    
  •   this.hidden = true;
     this.shape && this.shape.hide(); /\* FIXME this is representation specific code and should be elsewhere */
     for(i in this.edges)
         (this.edges[i].source.id == id || this.edges[i].target == id) && this.edges[i].hide && this.edges[i].hide();
    
  •   });
    
  •   for(var i = 0; i < this.edges.length; i++) {
    
  •        if (this.edges[i].source.id == id || this.edges[i].target.id == id) {
    
  •            this.edges[i].hide();
    
  •        }
    
  •    }
    
    };
    node.show = function() {
  •    this.hidden = false;
    
  •    this.shape.animate({opacity: 1},1000,"backIn",function () {
    
  •   this.hidden = false;
     this.shape && this.shape.show();
     for(i in this.edges)
         (this.edges[i].source.id == id || this.edges[i].target == id) && this.edges[i].show && this.edges[i].show();
    
  •   });
    
  •   for(var i = 0; i < this.edges.length; i++) {
    
  •        if (this.edges[i].source.id == id || this.edges[i].target.id == id) {
    
  •            this.edges[i].show();
    
  •        }
    
  •    }
    
    };
    return node;
    };

Vertical Tree Problem

I'm trying to create a basic vertical tree, ie.

 A
 |
 v
 B
 |
 v
 C

Eventually there will be an actual tree (ie. C will go to D, E, etc.) but so far I can't even get the above to work. Even when I use a TournamentTree or OrderedTree, the order I pass doesn't matter; I always get:

 A
 |
 v
 B     --->   C

Well, technically the order does affect what node goes in positions A/B/C, but the point is that I can only make an L-shaped graph, not a vertical one.

Is there any way to tell Dracula to use one vertical level per single-edge pair of nodes (although obviously when there's an actual branch I still want all children of that branch to be on the same vertical level)?

edgeFactory and examples

Thanks for all the work on this library!

It looks like the commit on February 15th to remove edgeFactory broke a couple of the examples (though in my case that's just fine since it helped me dig through things a little deeper to determine alternate ways to accomplish the same behavior)

Error in documentation

The documentation states that the settings of an edge must be passed in an object as the 3rd parameter of the addEdge function. See the example below extracted from the website:

/* a directed connection, using an arrow */
g.addEdge("id34", "cherry", { directed : true } );
 
/* customize the colors of that edge */
g.addEdge("id35", "apple", { stroke : "#bfa" , fill : "#56f", label : "Label" });

I couldn't get this to work. Looking at the source code, I found out that every edge setting is retrieved from the parameter "style", so I changed my approach to the following:

g.addEdge("id34", "cherry", { style: {directed : true} } );
g.addEdge("id35", "apple", { style: {stroke : "#bfa" , fill : "#56f", label : "Label" }});

Now it works fine. It would be great for new users if the docs could be updated.

Image connection

Hi. I tried using image icons in my code but when i try to connect the nodes together using addEdge method, i loose the image icon and revert back to ellipse. Is there any workaround for this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.