blob: dcba9c056cc7874a32274888e1d870d1dca0b449 [file] [log] [blame]
vinayakb70b63e22012-02-03 13:13:01 +00001Graphs = {};
2
3Graphs.DAG = function() {
4 this.nodeMap = {};
5 this.edgeMap = {};
6}
7
8Graphs.DAG.prototype.addNode = function(key, attachment) {
9 var node = new Graphs.Node(this, key, attachment);
10 this.nodeMap[key] = node;
11 return node;
12}
13
14Graphs.DAG.prototype.addEdge = function(key, attachment, sNode, sIndex, tNode, tIndex) {
15 var edge = new Graphs.DirectedEdge(this, key, attachment, sNode, sIndex, tNode, tIndex);
16 this.edgeMap[key] = edge;
17 sNode.outEdges[sIndex] = edge;
18 tNode.inEdges[tIndex] = edge;
19 return edge;
20}
21
22Graphs.DAG.prototype.lookupNode = function(key) {
23 return this.nodeMap[key];
24}
25
26Graphs.DAG.prototype.lookupEdge = function(key) {
27 return this.edgeMap[key];
28}
29
30Graphs.DAG.prototype.walkNodes = function(callback) {
31 for ( var nKey in this.nodeMap) {
32 callback(this.nodeMap[nKey]);
33 }
34}
35
36Graphs.DAG.prototype.walkEdges = function(callback) {
37 for ( var eKey in this.edgeMap) {
38 callback(this.edgeMap[eKey]);
39 }
40}
41
42Graphs.DAG.prototype.findRoots = function() {
43 var roots = [];
44 var callback = function(node) {
45 if (node.inEdges.length == 0) {
46 roots.push(node);
47 }
48 }
49 this.walkNodes(callback);
50 return roots;
51}
52
53Graphs.DAG.prototype.findLeaves = function() {
54 var leaves = [];
55 var callback = function(node) {
56 if (node.outEdges.length == 0) {
57 leaves.push(node);
58 }
59 }
60 this.walkNodes(callback);
61 return leaves;
62}
63
64Graphs.DAG.prototype.tsort = function() {
65 var sortedNodes = [];
66 var nodeState = {};
67
68 function visit(node) {
69 if (!nodeState[node.key]) {
70 nodeState[node.key] = true;
71 for ( var i = 0; i < node.inEdges.length; ++i) {
72 visit(node.inEdges[i].sNode);
73 }
74 sortedNodes.push(node);
75 }
76 }
77
78 var roots = this.findLeaves();
79 for ( var i = 0; i < roots.length; ++i) {
80 visit(roots[i]);
81 }
82 return sortedNodes;
83}
84
85Graphs.DAG.prototype.stratify = function() {
86 var sortedNodes = this.tsort();
87 var stratumMap = {};
88 var strata = [];
89 for ( var i = 0; i < sortedNodes.length; ++i) {
90 var node = sortedNodes[i];
91 var maxParentStratum = -1;
92 for ( var j = 0; j < node.inEdges.length; ++j) {
93 var edge = node.inEdges[j];
94 maxParentStratum = Math.max(maxParentStratum, stratumMap[edge.sNode.key]);
95 }
96 var stratum = maxParentStratum + 1;
97 stratumMap[node.key] = stratum;
98 var stratumList = strata[stratum];
99 if (!stratumList) {
100 stratumList = [];
101 strata[stratum] = stratumList;
102 }
103 stratumList.push(node);
104 }
105 return strata;
106}
107
108Graphs.Node = function(dag, key, attachment) {
109 this.dag = dag;
110 this.key = key;
111 this.attachment = attachment;
112 this.inEdges = [];
113 this.outEdges = [];
114}
115
116Graphs.DirectedEdge = function(dag, key, attachment, sNode, sIndex, tNode, tIndex) {
117 this.dag = dag;
118 this.key = key;
119 this.attachment = attachment;
120 this.sNode = sNode;
121 this.sIndex = sIndex;
122 this.tNode = tNode;
123 this.tIndex = tIndex;
124}
125
126Graphs.JsPlumbRenderer = function(dag, element, options) {
127 this.dag = dag;
128 this.element = element;
vinayakb77a67092012-02-05 23:53:54 +0000129 this.options = options || {
130 levelStep : 100
131 };
132}
133
134Graphs.JsPlumbRenderer.prototype.configureDiv = function(div, node, stratum, inStratumIndex, stratumWidth) {
135 div.id = node.key;
136 div.dagNode = node;
137 /*
138 * div.style.position = 'absolute'; div.style.left = (stratum *
139 * this.options.levelStep) + 'px'; div.style.top = (inStratumIndex * 100) +
140 * 'px'; div.style.width = '50px'; div.style.height = '50px';
141 * div.style.border = 'thick solid #000000';
142 */
vinayakb70b63e22012-02-03 13:13:01 +0000143}
144
145Graphs.JsPlumbRenderer.prototype.refresh = function() {
146 var strata = this.dag.stratify();
147
148 while (this.element.hasChildNodes()) {
149 this.element.removeChild(this.element.lastChild);
150 }
151 for ( var i = 0; i < strata.length; ++i) {
152 var stratumList = strata[i];
153 for ( var j = 0; j < stratumList.length; ++j) {
154 var node = stratumList[j];
155 var div = document.createElement('div');
vinayakb77a67092012-02-05 23:53:54 +0000156 this.configureDiv(div, node, i, j, stratumList.length);
vinayakb70b63e22012-02-03 13:13:01 +0000157 this.element.appendChild(div);
158 }
159 }
160}