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