1 //Class c.infovis.SpaceTree : Chart 2 //This is the custom wrapper class for protovis bar charts 3 4 //Constructor 5 wso2vis.s.chart.infovis.SpaceTree = function(divElementLog, canvas, chartTitle, chartDesc) { 6 wso2vis.s.chart.Chart.call(this, canvas, chartTitle, chartDesc); 7 8 /* @private */ 9 this.divElementLog = divElementLog; 10 this.canvas = canvas; 11 this.st = null; 12 this.y = null; 13 this.x = null; 14 this.tip = new wso2vis.c.Tooltip(); 15 this.testLabel = null; 16 this.edgeLabelArray = null; 17 }; 18 19 //this makes c.infovis.SpaceTree.prototype inherits 20 //from Chart.prototype 21 wso2vis.extend(wso2vis.s.chart.infovis.SpaceTree, wso2vis.s.chart.Chart); 22 23 wso2vis.s.chart.infovis.SpaceTree.prototype 24 .property("dataField") 25 .property("dataValue") 26 .property("dataLabel") 27 .property("ySuffix") 28 .property("xSuffix"); 29 30 31 ST.Plot.EdgeTypes.implement({ 32 'custom-line': function(adj, canvas) { 33 //plot arrow edge 34 this.edgeTypes.arrow.call(this, adj, canvas); 35 //get nodes cartesian coordinates 36 var pos = adj.nodeFrom.pos.getc(true); 37 var posChild = adj.nodeTo.pos.getc(true); 38 //check for edge label in data 39 var data = adj.nodeTo.data; 40 if(data.labelid && data.labeltext) { 41 var domlabel = document.getElementById(data.labelid); 42 //if the label doesn't exist create it and append it 43 //to the label container 44 if(!domlabel) { 45 var domlabel= document.createElement('div'); 46 domlabel.id = data.labelid; 47 domlabel.innerHTML = data.labeltext; 48 //add some custom style 49 var style = domlabel.style; 50 style.position = 'absolute'; 51 style.color = '#00f'; 52 style.fontSize = '9px'; 53 //append the label to the labelcontainer 54 this.getLabelContainer().appendChild(domlabel); 55 56 } 57 58 //now adjust the label placement 59 var radius = this.viz.canvas.getSize(); 60 domlabel.style.left = parseInt((pos.x + posChild.x + radius.width - domlabel.offsetWidth) /2) + 'px'; 61 domlabel.style.top = parseInt((pos.y + posChild.y + radius.height) /2) + 'px'; 62 } 63 } 64 }); 65 66 67 //Public function loadChart 68 //Loads the chart inside the given HTML element 69 wso2vis.s.chart.infovis.SpaceTree.prototype.load = function (w, h) { 70 71 if (w !== undefined) { 72 this.width(w); 73 } 74 if (h !== undefined) { 75 this.height(h); 76 } 77 78 that = this; 79 var Log = { 80 elem: false, 81 write: function(text){ 82 if (!this.elem) 83 this.elem = that.divElementLog; 84 this.elem.innerHTML = text; 85 this.elem.style.left = (500 - this.elem.offsetWidth / 2) + 'px'; 86 } 87 }; 88 //init canvas 89 //Create a new canvas instance. 90 var canvas = new Canvas('mycanvas', { 91 'injectInto': that.canvas, 92 'width': that.width(), 93 'height': that.height(), 94 'backgroundColor': '#1a1a1a' 95 }); 96 //end 97 98 //init st 99 //Create a new ST instance 100 this.st = new ST(canvas, { 101 //set duration for the animation 102 orientation: "top", 103 duration: 400, 104 //set animation transition type 105 transition: Trans.Quart.easeInOut, 106 //set distance between node and its children 107 levelDistance: 60, 108 //set node and edge styles 109 //set overridable=true for styling individual 110 //nodes or edges 111 Node: { 112 width:20, 113 type: 'none', 114 color: '#aaa', 115 overridable: true 116 }, 117 118 Edge: { 119 type: 'arrow', 120 overridable: true 121 122 123 }, 124 125 onBeforeCompute: function(node){ 126 127 // Log.write("loading " + node.name); 128 }, 129 130 onAfterCompute: function(){ 131 //Log.write("done"); 132 }, 133 134 //This method is called on DOM label creation. 135 //Use this method to add event handlers and styles to 136 //your node. 137 onCreateLabel: function(label, node){ 138 label.id = node.id; 139 label.innerHTML = node.name; 140 label.onclick = function(){ 141 that.st.onClick(node.id); 142 143 // Log.write("Done"); 144 }; 145 label.onmouseover = function(e){ 146 that.tip.show(e.pageX, e.pageY, node.name); 147 // Log.write("mouse is over the" + node.name + "label, triggering mouse event : " + e.toString()); 148 }; 149 label.onmouseout = function () { 150 that.tip.hide(); 151 }; 152 //set label styles 153 var style = label.style; 154 style.width = 10 + 'px'; 155 style.height = 17 + 'px'; 156 style.cursor = 'pointer'; 157 style.color = '#333'; 158 style.fontSize = '0.8em'; 159 style.textAlign= 'center'; 160 style.paddingTop = '4px'; 161 style.paddingLeft = '3px'; 162 }, 163 164 //This method is called right before plotting 165 //a node. It's useful for changing an individual node 166 //style properties before plotting it. 167 //The data properties prefixed with a dollar 168 //sign will override the global node style properties. 169 onBeforePlotNode: function(node){ 170 //add some color to the nodes in the path between the 171 //root node and the selected node. 172 173 if (node.selected) { 174 node.data.$color = "#ff7"; 175 } 176 else { 177 delete node.data.$color; 178 var GUtil = Graph.Util; 179 //if the node belongs to the last plotted level 180 if(!GUtil.anySubnode(node, "exist")) { 181 //count children number 182 var count = 0; 183 GUtil.eachSubnode(node, function(n) { count++; }); 184 //assign a node color based on 185 //how many children it has 186 node.data.$color = ['#aaa', '#baa', '#caa', '#daa', '#eaa', '#faa'][count]; 187 } 188 } 189 }, 190 191 //This method is called right before plotting 192 //an edge. It's useful for changing an individual edge 193 //style properties before plotting it. 194 //Edge data proprties prefixed with a dollar sign will 195 //override the Edge global style properties. 196 onBeforePlotLine: function(adj){ 197 if (adj.nodeFrom.selected && adj.nodeTo.selected) { 198 adj.data.$color = "#eed"; 199 adj.data.$lineWidth = 3; 200 } 201 else { 202 delete adj.data.$color; 203 delete adj.data.$lineWidth; 204 } 205 } 206 }); 207 208 }; 209 210 211 wso2vis.s.chart.infovis.SpaceTree.prototype.populateData = function (thisObject) { 212 // Space Tree can only be drawn with a JSON Tree i.e. with JSON nodes 213 var _dataField = thisObject.traverseToDataField(thisObject.data, thisObject.dataField()); 214 if ((_dataField instanceof Array) && (_dataField.length < 1)) { 215 return false; 216 } 217 var st = thisObject.st; 218 var lbs = st.fx.labels; 219 220 for (label in lbs) { 221 if (lbs[label]) { 222 lbs[label].parentNode.removeChild(lbs[label]); 223 } 224 } 225 // for (edge in edges) { 226 // if (edges(edge)) { 227 // edges[edge] 228 // } 229 st.fx.labels = {}; 230 // thisObject.adjustWidth(_dataField[0]); 231 thisObject.st.loadJSON(_dataField[0]); 232 return true; 233 234 }; 235 236 wso2vis.s.chart.infovis.SpaceTree.prototype.trim = function (txt) { 237 if (txt.length > 20) { 238 var str = txt.substr(0,18); 239 str += "..."; 240 } else { 241 var str = txt; 242 } 243 return str; 244 } 245 246 247 wso2vis.s.chart.infovis.SpaceTree.prototype.getNodeDiv = function () { 248 if (this.testLabel == null) { 249 250 var testLabel = this.testLabel = document.createElement('div'); 251 testLabel.id = "mytestlabel"; 252 testLabel.style.visibility = "hidden"; 253 testLabel.style.position = "absolute"; 254 testLabel.style.height = 20 + 'px'; 255 document.body.appendChild(testLabel); 256 return this.testLabel; 257 } 258 } 259 260 261 262 wso2vis.s.chart.infovis.SpaceTree.prototype.adjustWidth = function(tree) { 263 var elem = this.getNodeDiv(); 264 TreeUtil.each(tree, function(node) { 265 elem.innerHTML = that.trim(node.name); 266 node.data.$width = elem.offsetWidth; 267 }); 268 } 269 270 wso2vis.s.chart.infovis.SpaceTree.prototype.update = function () { 271 var st = this.st; 272 if (this.populateData(this)) { 273 //compute node positions and layout 274 st.compute(); 275 //optional: make a translation of the tree 276 st.geom.translate(new Complex(-200, 0), "startPos"); 277 //emulate a click on the root node. 278 st.onClick(st.root); 279 280 if(this.tooltip() === true) { 281 tooltip.init(); 282 } 283 } 284 }; 285