smarten up the tooltip
[p5sagit/Devel-Size.git] / static / public / tm.js
CommitLineData
b2fc39a5 1var labelType, useGradients, nativeTextSupport, animate;
2
3(function() {
4 var ua = navigator.userAgent,
5 iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
6 typeOfCanvas = typeof HTMLCanvasElement,
7 nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
8 textSupport = nativeCanvasSupport
9 && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
10 //I'm setting this based on the fact that ExCanvas provides text support for IE
11 //and that as of today iPhone/iPad current text support is lame
12 labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
13 nativeTextSupport = labelType == 'Native';
14 useGradients = nativeCanvasSupport;
15 animate = !(iStuff || !nativeCanvasSupport);
16})();
17
18var Log = {
19 elem: false,
20 write: function(text){
21 if (!this.elem)
22 this.elem = document.getElementById('log');
23 this.elem.innerHTML = text;
24 this.elem.style.left = (500 - this.elem.offsetWidth / 2) + 'px';
25 }
26};
27
5ab994e6 28// http://stackoverflow.com/questions/5199901/how-to-sort-an-associative-array-by-its-values-in-javascript
29function bySortedValue(obj, comparitor, callback, context) {
30 var tuples = [];
31 for (var key in obj) {
32 if (obj.hasOwnProperty(key)) {
33 tuples.push([key, obj[key]]);
34 }
35 }
36
37 tuples.sort(comparitor);
38
39 if (callback) {
40 var length = tuples.length;
41 while (length--) callback.call(context, tuples[length][0], tuples[length][1]);
42 }
43 return tuples;
44}
45
46
b2fc39a5 47
48function init(){
49 //init data
50 //end
51 //init TreeMap
52 var tm = new $jit.TM.Squarified({
53 //where to inject the visualization
54 injectInto: 'infovis',
55 //show only one tree level
5a78486c 56 levelsToShow: 1,
b2fc39a5 57 //parent box title heights
5a78486c 58 titleHeight: 11,
b2fc39a5 59 //enable animations
60 animate: animate,
61 //box offsets
62 offset: 1,
63 //use canvas text
64 Label: {
65 type: labelType,
66 size: 9,
67 family: 'Tahoma, Verdana, Arial'
68 },
69 //enable specific canvas styles
70 //when rendering nodes
71 Node: {
72 CanvasStyles: {
73 shadowBlur: 0,
74 shadowColor: '#000'
75 }
76 },
77 //Attach left and right click events
78 Events: {
79 enable: true,
80 onClick: function(node) {
81 if(node) tm.enter(node);
82 },
83 onRightClick: function() {
84 tm.out();
85 },
86 //change node styles and canvas styles
87 //when hovering a node
88 onMouseEnter: function(node, eventInfo) {
89 if(node) {
90 //add node selected styles and replot node
91 node.setCanvasStyle('shadowBlur', 7);
92 node.setData('color', '#888');
93 tm.fx.plotNode(node, tm.canvas);
94 tm.labels.plotLabel(tm.canvas, node);
95 }
96 },
97 onMouseLeave: function(node) {
98 if(node) {
99 node.removeData('color');
100 node.removeCanvasStyle('shadowBlur');
101 tm.plot();
102 }
103 }
104 },
105 //duration of the animations
5a78486c 106 duration: 500,
b2fc39a5 107 //Enable tips
108 Tips: {
109 enable: true,
110 type: 'Native',
111 //add positioning offsets
112 offsetX: 20,
113 offsetY: 20,
114 //implement the onShow method to
115 //add content to the tooltip when a node
116 //is hovered
117 onShow: function(tip, node, isLeaf, domElement) {
118 var html = "<div class=\"tip-title\">" + node.name
119 + "</div><div class=\"tip-text\">";
120 var data = node.data;
bb66f8a1 121
5ab994e6 122 html += "<br />";
bb66f8a1 123 html += sprintf("Size: %d (%d + %d)<br />", data.self_size+data.kids_size, data.self_size, data.kids_size);
5ab994e6 124
125 if (data.self_size) {
126 html += sprintf("Memory usage:<br />");
127 bySortedValue(data.leaves,
128 function(a, b) { return a[1] - b[1] },
129 function(k, v) { html += sprintf(" %10s: %5d<br />", k, v);
130 });
131 html += "<br />";
132 }
133
134 html += sprintf("Attributes:<br />");
135 bySortedValue(data.attr,
136 function(a, b) { return a[0] > b[0] ? 1 : a[0] < b[0] ? -1 : 0 },
137 function(k, v) { html += sprintf(" %10s: %5d<br />", k, v);
138 });
139 html += "<br />";
140
bb66f8a1 141 if (data.child_count) {
142 html += sprintf("Children: %d of %d<br />", data.child_count, data.kids_node_count);
b2fc39a5 143 }
5ab994e6 144 html += sprintf("Id: %s%s<br />", node.id, data._ids_merged ? data._ids_merged : "");
5a78486c 145 html += sprintf("Depth: %d<br />", data.depth);
146 html += sprintf("Parent: %d<br />", data.parent_id);
bb66f8a1 147
b2fc39a5 148 tip.innerHTML = html;
149 }
150 },
151 //Implement this method for retrieving a requested
152 //subtree that has as root a node with id = nodeId,
153 //and level as depth. This method could also make a server-side
154 //call for the requested subtree. When completed, the onComplete
155 //callback method should be called.
156 request: function(nodeId, level, onComplete){
157 if (true) {
875c1073 158 jQuery.getJSON('jit_tree/'+nodeId+'/1', function(data) {
f9d8678b 159 console.log("Node "+nodeId);
160 console.log(data);
b2fc39a5 161 onComplete.onComplete(nodeId, data);
162 });
163 }
164 else {
165 var tree = memnodes[0];
166 var subtree = $jit.json.getSubtree(tree, nodeId);
167 $jit.json.prune(subtree, 2);
168 onComplete.onComplete(nodeId, subtree);
169 }
170 },
171 //Add the name of the node in the corresponding label
172 //This method is called once, on label creation and only for DOM labels.
173 onCreateLabel: function(domElement, node){
174 domElement.innerHTML = node.name;
175 }
176 });
177
178if(true) {
875c1073 179 jQuery.getJSON('jit_tree/1/1', function(data) {
f9d8678b 180 console.log(data);
b2fc39a5 181 tm.loadJSON(data);
182 tm.refresh();
183 });
184}
185else {
186 //var pjson = eval('(' + json + ')');
187 var pjson = memnodes[0];
188 $jit.json.prune(pjson, 2);
189 console.log(pjson);
190 tm.loadJSON(pjson);
191 tm.refresh();
192}
193
b2fc39a5 194 //add event to the back button
195 var back = $jit.id('back');
196 $jit.util.addEvent(back, 'click', function() {
197 tm.out();
198 });
199}