├── .gitignore
├── README.md
├── example.png
├── example
├── example.jsx
└── index.html
├── index.js
├── index.jsx
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | dagre-react is a JavaScript library which provides a Graph React component and does automatic layout,
2 | so you can render directed graphs just from vertex and edge data:
3 |
4 | ``` .javascript
5 | var Example = React.createClass({
6 | render: function() {
7 | var toVertex = function(name) {
8 | return (
9 |
11 |
12 |
13 | {name}
14 |
15 |
16 | );
17 | };
18 |
19 | var arrow = " \
21 | \
22 | ";
23 |
24 | return (
25 |
43 | );
44 | }
45 | });
46 | ```
47 |
48 | produces something like this (with styles):
49 |
50 |
51 |
52 | You can make the vertices' children arbitrary React components;
53 | at the moment, edges are just SVG paths.
54 |
55 | It uses the dagre library to lay out your graph.
56 |
57 | Make sure you compile JSX files back to JS if you change them.
58 |
--------------------------------------------------------------------------------
/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osnr/dagre-react/7e0eaff7939f43376a2cd41ac917710d06d0cd4d/example.png
--------------------------------------------------------------------------------
/example/example.jsx:
--------------------------------------------------------------------------------
1 | var Graph = DagreReact.Graph;
2 | var Vertex = DagreReact.Vertex;
3 | var Edge = DagreReact.Edge;
4 |
5 | var Example = React.createClass({
6 | render: function() {
7 | var toVertex = function(name) {
8 | return (
9 |
11 |
12 |
13 | {name}
14 |
15 |
16 | );
17 | };
18 |
19 | var arrow = " \
21 | \
22 | ";
23 |
24 | return (
25 |
43 | );
44 | }
45 | });
46 |
47 | React.render(
48 | ,
49 | document.getElementById('dagre-graph-example')
50 | );
51 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Dagre React Example
6 |
7 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | (function(root, modules, factory) {
2 | if (typeof define === 'function' && define.amd) {
3 | // AMD.
4 | var carry = function(React, dagre) {
5 | return factory(root, React, dagre);
6 | };
7 | define(['react', 'dagre'], carry);
8 | } else {
9 | // Browser globals
10 | root.DagreReact = factory(root, modules[0], modules[1]);
11 | }
12 | })(this,
13 | (typeof require === 'function' ?
14 | [require('react'), require('dagre')] :
15 | [React, dagre]
16 | ),
17 | function(window, React, dagre) {
18 | 'use strict';
19 |
20 | var Graph = React.createClass({displayName: 'Graph',
21 | render: function() {
22 | // construct a new graph from scratch
23 | // because dagre mutates g for the layout
24 | var g = new dagre.graphlib.Graph();
25 |
26 | g.setGraph({});
27 |
28 | React.Children.forEach(this.props.children, function(child) {
29 | if (child.type === Vertex) {
30 | g.setNode(child.key, { label: child, width: child.props.width, height: child.props.height });
31 |
32 | } else if (child.type === Edge) {
33 | g.setEdge(child.props.source, child.props.target, { label: child });
34 | }
35 | });
36 |
37 | dagre.layout(g);
38 |
39 | // now render
40 | // node svg elements
41 | var nodes = g.nodes().map(function(v) {
42 | var node = g.node(v);
43 | return React.cloneElement(node.label, {
44 | x: node.x,
45 | y: node.y
46 | });
47 |
48 | });
49 | var edges = g.edges().map(function(e) {
50 | var edge = g.edge(e);
51 | return React.cloneElement(edge.label, {
52 | points: edge.points
53 | });
54 | });
55 |
56 | return (
57 | React.createElement("g", React.__spread({}, this.props),
58 | nodes,
59 | edges
60 | )
61 | );
62 | }
63 | });
64 |
65 | var Vertex = React.createClass({displayName: 'Vertex',
66 | render: function() {
67 | return (
68 | React.createElement("g", React.__spread({transform: "translate("+
69 | (this.props.x-(this.props.width/2))+","+
70 | (this.props.y-(this.props.height/2))+")"},
71 | this.props),
72 |
73 | this.props.children
74 | )
75 | );
76 | }
77 | });
78 |
79 | var Edge = React.createClass({displayName: 'Edge',
80 | render: function() {
81 | var points = this.props.points;
82 |
83 | var path = "M" + points[0].x + " " + points[0].y + " ";
84 | for (var i = 1; i < points.length; i++) {
85 | path += "L" + points[i].x + " " + points[i].y + " ";
86 | }
87 |
88 | return React.createElement("path", React.__spread({}, this.props, {d: path}));
89 | }
90 | });
91 |
92 | var exports = {
93 | Graph: Graph,
94 | Vertex: Vertex,
95 | Edge: Edge
96 | };
97 |
98 | if (typeof module === 'undefined') {
99 | window.DagreReact = exports;
100 | } else {
101 | module.exports = exports;
102 | }
103 |
104 | return exports;
105 | });
106 |
--------------------------------------------------------------------------------
/index.jsx:
--------------------------------------------------------------------------------
1 | (function(root, modules, factory) {
2 | if (typeof define === 'function' && define.amd) {
3 | // AMD.
4 | var carry = function(React, dagre) {
5 | return factory(root, React, dagre);
6 | };
7 | define(['react', 'dagre'], carry);
8 | } else {
9 | // Browser globals
10 | root.DagreReact = factory(root, modules[0], modules[1]);
11 | }
12 | })(this,
13 | (typeof require === 'function' ?
14 | [require('react'), require('dagre')] :
15 | [React, dagre]
16 | ),
17 | function(window, React, dagre) {
18 | 'use strict';
19 |
20 | var Graph = React.createClass({
21 | render: function() {
22 | // construct a new graph from scratch
23 | // because dagre mutates g for the layout
24 | var g = new dagre.graphlib.Graph();
25 |
26 | g.setGraph({});
27 |
28 | React.Children.forEach(this.props.children, function(child) {
29 | if (child.type === Vertex) {
30 | g.setNode(child.key, { label: child, width: child.props.width, height: child.props.height });
31 |
32 | } else if (child.type === Edge) {
33 | g.setEdge(child.props.source, child.props.target, { label: child });
34 | }
35 | });
36 |
37 | dagre.layout(g);
38 |
39 | // now render
40 | // node svg elements
41 | var nodes = g.nodes().map(function(v) {
42 | var node = g.node(v);
43 | return React.cloneElement(node.label, {
44 | x: node.x,
45 | y: node.y
46 | });
47 |
48 | });
49 | var edges = g.edges().map(function(e) {
50 | var edge = g.edge(e);
51 | return React.cloneElement(edge.label, {
52 | points: edge.points
53 | });
54 | });
55 |
56 | return (
57 |
58 | {nodes}
59 | {edges}
60 |
61 | );
62 | }
63 | });
64 |
65 | var Vertex = React.createClass({
66 | render: function() {
67 | return (
68 |
72 |
73 | {this.props.children}
74 |
75 | );
76 | }
77 | });
78 |
79 | var Edge = React.createClass({
80 | render: function() {
81 | var points = this.props.points;
82 |
83 | var path = "M" + points[0].x + " " + points[0].y + " ";
84 | for (var i = 1; i < points.length; i++) {
85 | path += "L" + points[i].x + " " + points[i].y + " ";
86 | }
87 |
88 | return ;
89 | }
90 | });
91 |
92 | var exports = {
93 | Graph: Graph,
94 | Vertex: Vertex,
95 | Edge: Edge
96 | };
97 |
98 | if (typeof module === 'undefined') {
99 | window.DagreReact = exports;
100 | } else {
101 | module.exports = exports;
102 | }
103 |
104 | return exports;
105 | });
106 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dagre-react",
3 | "version": "0.0.1",
4 | "description": "React component that renders directed graphs.",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "Omar Rizwan",
10 | "license": "MIT",
11 | "dependencies": {
12 | "dagre": "^0.7.1",
13 | "react": "^0.13.2"
14 | },
15 | "devDependencies": {
16 | "react-tools": "^0.13.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------