1 wso2vis.s.chart.raphael.DependencyTree = function(canvas, chartTitle, chartDesc) {
  2     wso2vis.s.chart.Chart.call(this, canvas, chartTitle, chartDesc);
  3     this.div = canvas;
  4     this.nodelength(50)
  5         .nodeheight(20)
  6         .edgelength(20)
  7         .sx(30) // distance between 2 successive horizontal nodes
  8         .sy(40) // distance between 2 successive vertical nodes
  9         .arrowsize(5)
 10         .arrowpos("mid"); 
 11 }
 12 
 13 //inherits from Chart
 14 wso2vis.extend(wso2vis.s.chart.raphael.DependencyTree, wso2vis.s.chart.Chart);
 15 
 16 wso2vis.s.chart.raphael.DependencyTree.prototype
 17 	.property("dataField")
 18 	.property("dataValue")
 19     .property("nodelength")
 20     .property("nodeheight")
 21     .property("edgelength")
 22     .property("sx")
 23     .property("sy")
 24     .property("arrowsize")
 25     .property("arrowpos");
 26     
 27 
 28 
 29 Raphael.fn.node = function(x, y, width, height, node_label, url) {
 30 	var box = this.rect(x,y , width, height);
 31 	
 32 	var mid_x = (x*2 + width)/2;
 33 	var mid_y = (y*2 + height)/2;
 34 	var box_label = this.text(mid_x, mid_y, node_label).attr({font:"Arial"});
 35 	if (url) {
 36 		box_label.node.onclick = function() {
 37 			window.location = url;
 38 		}
 39 		box_label.node.onmouseover = function() {
 40 //			alert("mouse over");
 41 			box_label.attr({
 42 				fill: "#25B"
 43 				
 44 			});
 45 			box_label.node.style.cursor = "pointer";
 46 		}
 47 		box_label.node.onmouseout = function () {
 48 			box_label.attr({fill: "#000"});
 49 		}
 50 	}
 51 	return [box, box_label];
 52 }
 53 
 54 Raphael.fn.edge = function (x1, y1, x2, y2, size, arrow_position, edge_label) {
 55 	var angle = Math.atan2(y2-y1,x2-x1) * 180 / Math.PI ;
 56 	var arrow_x = x2;
 57 	var arrow_y = y2;
 58 	var mid_x = (x1+x2)/2;
 59 	var mid_y = (y1+y2)/2;
 60 
 61 	if (arrow_position == "start") {
 62 		arrow_x = x1;
 63 		arrow_y = y1;
 64 	} else if (arrow_position == "mid") {
 65 		arrow_x = mid_x;
 66 		arrow_y = mid_y;
 67 	} else if (arrow_position == "end") {
 68 		arrow_x = x2;
 69 		arrow_y = y2;
 70 	}
 71 
 72 	var arrow_path = this.path("M"+arrow_x+" "+arrow_y+"l"+0+" "+-(size/2)+"l"+size+" "+(size/2)+"l"+-size+" "+(size/2) +"z").attr("fill","black").rotate(angle, arrow_x, arrow_y);
 73 	var line_path = this.path("M"+x1+" "+y1+"L"+x2+" "+y2);
 74 	var label;
 75 	if (edge_label) {
 76 		label = this.text(mid_x, mid_y-(size+2), edge_label).rotate(angle, mid_x, mid_y).attr({font: "Arial"});
 77 	}
 78 	return [arrow_path, line_path, label];
 79 }
 80 
 81 
 82 
 83 Raphael.fn.node_edge = function ( x, y, px, py, node_length, node_height, node_label, edge_length, edge_label, size, arrow_position, url) {
 84 	var _node = this.node(x,y - (node_height/2),node_length, node_height, node_label, url);
 85 	_node[0].attr({fill: '#4AE',
 86         stroke: '#3b4449',
 87         'stroke-width': 3,
 88         'stroke-linejoin': 'round'});
 89 	var _edge = null;
 90 	if (px != null || py != null) {
 91 		var _edge = this.edge(px, py, x , y , size, arrow_position, edge_label);
 92 		_edge[0].attr({ stroke: '#3b4449',
 93 	        'stroke-width': 3,
 94 	        'stroke-linejoin': 'round'});
 95 		_edge[1].attr({ stroke: '#3b4449',
 96 	        'stroke-width': 3,
 97 	        'stroke-linejoin': 'round'});
 98 	}
 99 	return [_node, _edge];
100 }
101 
102 //public function 
103 wso2vis.s.chart.raphael.DependencyTree.prototype.load = function (w, h) {
104     if (w !== undefined) {
105         this.width(w);
106     }
107     if (h !== undefined) {
108         this.height(h);
109     }
110     
111     this.paper = Raphael(this.divEl(), this.width(), this.height());  
112     
113 	return this; 
114 };
115 
116 
117 wso2vis.s.chart.raphael.DependencyTree.prototype.draw_tree_node_edge = function (paper, px, py ,x,y, node_label, edge_label, url) {
118 	var node_length = this.nodelength();
119 	var edge_length = this.edgelength();
120 	var node_height = this.nodeheight();
121 	var size = this.arrowsize();
122 	var arrow_position = this.arrowpos();
123 	paper.node_edge(x, y, px, py, node_length, node_height, node_label, edge_length, edge_label, size, arrow_position, url);
124 	return [x + node_length, y];
125 }
126 
127 
128 wso2vis.s.chart.raphael.DependencyTree.prototype.draw_json_node = function (paper, jsonObj, px, py, pid, x, y) {
129 	var edge_label = null;
130 	if (jsonObj.data.edges) {
131 		var edge_array = jsonObj.data.edges;
132 		for (var j = 0;j < edge_array.length; j++) {
133 			var edge_ids = edge_array[j].id.split("-");
134 			if (edge_ids != null && edge_ids.length > 1) {
135 				if (edge_ids[0] == pid && edge_ids[1] == jsonObj.id) {
136 					edge_label = edge_array[j].name;
137 				}
138 			}
139 		}
140 	}
141 	var url = null;
142 	if (jsonObj.data.url) {
143 		url = jsonObj.data.url;
144 	}
145 	return this.draw_tree_node_edge(paper, px, py, x, y, jsonObj.name, edge_label, url );
146 
147 }
148 
149 // Node class
150 function Node (_json) {
151 	this.json = _json;
152 	this.visited;
153 	this.level;
154 	this.px;
155 	this.py;
156 	this.pid;
157 	this.i;
158 	this.scount;
159 	Node.prototype.getChildren = function () {
160 		var childArray = new Array();
161 		var child;
162 		var children = this.json.children;
163 		for (var i = 0; i < children.length; i++) {
164 			childArray.push(new Node(children[i]));
165 		}
166 		return childArray;
167 	}
168 }
169 
170 function coYCalc() {
171 	var sy = 5;
172 	var h = 8;
173 	cy = jNode.py;
174 	cy += -((sCount * h) + (sCount-1) * sy)
175 	//
176 }
177 
178 
179 wso2vis.s.chart.raphael.DependencyTree.prototype.calc_draw_single_node = function (paper, jNode) {
180 	var initX = 10;
181 	var initY = paper.height /2;
182 	var d = 30;
183 	var sx = this.sx();
184 	
185 	var h = 10;
186 	if (jNode.level == 0) {
187 		return this.draw_json_node(paper, jNode.json, null, null, null, initX, initY);
188 	} else {
189 		var sy = this.sy(); //200/(2*jNode.level);
190 		cx = jNode.px + sx; //+ (jNode.pLevel - (json.level + 1)) * (d + sx) ;
191 		var sCount = jNode.sCount;
192 		var addConst = (sCount == 0) ? 0 : (sCount - 1) ;
193 		cy = jNode.py + (h + sy) * (jNode.i - ((sCount-1)/2))/Math.pow(3, jNode.level); //((jNode.i  * (h + sy)) - (((sCount - 1) * (sy + h)) / 2)); 
194 		return this.draw_json_node(paper, jNode.json, jNode.px, jNode.py, jNode.pid, cx, cy);
195 	}
196 	
197 }
198 
199 wso2vis.s.chart.raphael.DependencyTree.prototype.DrawTreeBFS = function (paper, jNode) {
200 	var queue = new Array();
201 	jNode.visited = true;
202 	queue.push(jNode);
203 	var level = 0;
204 	var px, py;
205 	while (queue.length > 0) {
206 		var pNode = queue.shift();
207 		level = pNode.level;
208 		var coArr = this.calc_draw_single_node(paper, pNode);
209 		px = coArr[0];
210 		py = coArr[1];
211 		pid = pNode.json.id;
212 		 //document.write(pNode.level + "," +pNode.json.id+" | ");
213 		var children = pNode.getChildren();
214 		var lInc = false;
215 		for (var i = 0; i < children.length; i++) {
216 			if (i == 0) {
217 				level++;
218 			}
219 			if (!children[i].visited) {
220 				children[i].visited = true;
221 				children[i].level = level;
222 				children[i].pid = pid;
223 				children[i].px = px;
224 				children[i].py = py;
225 				children[i].i = i;
226 				children[i].sCount = children.length;
227 				queue.push(children[i]);
228 				
229 			}
230 		}
231 	}
232 
233 }
234 
235 wso2vis.s.chart.raphael.DependencyTree.prototype.populateData = function (thisObject) {
236 	// Space Tree can only be drawn with a JSON Tree i.e. with JSON nodes
237 	this._dataField = thisObject.traverseToDataField(thisObject.data, thisObject.dataField());
238 	if ((this._dataField instanceof Array) && (this._dataField.length < 1)) {
239 		return false;
240 	}
241 	
242 	return true;
243 
244 };
245 
246 
247 wso2vis.s.chart.raphael.DependencyTree.prototype.update = function () {
248 	if (this.populateData(this)) {
249 		this.paper.clear();
250 		var root = new Node(this._dataField[0]);
251 		root.level = 0;
252 		this.DrawTreeBFS(this.paper, root);
253 	}
254 
255 }
256 
257 
258