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