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