Commit | Line | Data |
b2fc39a5 |
1 | var 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 | |
18 | var 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 |
29 | function 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 | |
e8f4c506 |
48 | function request_jit_tree(nodeId, level, onComplete){ |
49 | var params = { logarea: 1 }; |
50 | jQuery.getJSON('jit_tree/'+nodeId+'/1', params, onComplete); |
51 | } |
52 | |
53 | |
b2fc39a5 |
54 | function init(){ |
55 | //init data |
56 | //end |
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 |
5a78486c |
62 | levelsToShow: 1, |
b2fc39a5 |
63 | //parent box title heights |
5a78486c |
64 | titleHeight: 11, |
b2fc39a5 |
65 | //enable animations |
66 | animate: animate, |
67 | //box offsets |
68 | offset: 1, |
69 | //use canvas text |
70 | Label: { |
71 | type: labelType, |
72 | size: 9, |
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 |
5a78486c |
112 | duration: 500, |
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){ |
e8f4c506 |
169 | request_jit_tree(nodeId, level, function(data) { |
170 | console.log("Fetched node "+nodeId); |
f9d8678b |
171 | console.log(data); |
b2fc39a5 |
172 | onComplete.onComplete(nodeId, data); |
173 | }); |
b2fc39a5 |
174 | }, |
175 | //Add the name of the node in the corresponding label |
176 | //This method is called once, on label creation and only for DOM labels. |
177 | onCreateLabel: function(domElement, node){ |
178 | domElement.innerHTML = node.name; |
179 | } |
180 | }); |
e8f4c506 |
181 | |
182 | request_jit_tree(1, 0, function(data) { |
f9d8678b |
183 | console.log(data); |
b2fc39a5 |
184 | tm.loadJSON(data); |
185 | tm.refresh(); |
186 | }); |
b2fc39a5 |
187 | |
e8f4c506 |
188 | //add event to buttons |
189 | $jit.util.addEvent($jit.id('back'), 'click', function() { tm.out() }); |
190 | $jit.util.addEvent($jit.id('logarea'), 'onchange', function() { tm.refresh() }); |
191 | |
b2fc39a5 |
192 | } |
e8f4c506 |
193 | |
194 | |