Added local jquery-1.8.1-min.js so internet isn't needed
[p5sagit/Devel-Size.git] / static / public / tm.js
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
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
47
48 function request_jit_tree(nodeId, level, depth, onComplete){
49     var params = { logarea: 1 };
50     jQuery.getJSON('jit_tree/'+nodeId+'/'+depth, params, onComplete);
51 }
52
53
54 function init(){
55   var levelsToShow = 2;
56   //init TreeMap
57   var tm = new $jit.TM.Squarified({
58     //where to inject the visualization
59     injectInto: 'infovis',
60     //show only one tree level
61     levelsToShow: levelsToShow,
62     //parent box title heights
63     titleHeight: 11,
64     //enable animations
65     animate: animate,
66     //box offsets
67     offset: 1,
68     //use canvas text
69     Label: {
70       type: labelType,
71       size: 9,
72       family: 'Tahoma, Verdana, Arial'
73     },
74     //enable specific canvas styles
75     //when rendering nodes
76     Node: {
77       CanvasStyles: {
78         shadowBlur: 0,
79         shadowColor: '#000'
80       }
81     },
82     //Attach left and right click events
83     Events: {
84       enable: true,
85       onClick: function(node) {
86         if(node) tm.enter(node);
87       },
88       onRightClick: function() {
89         tm.out();
90       },
91       //change node styles and canvas styles
92       //when hovering a node
93       onMouseEnter: function(node, eventInfo) {
94         if(node) {
95           //add node selected styles and replot node
96           node.setCanvasStyle('shadowBlur', 7);
97           node.setData('color', '#888');
98           tm.fx.plotNode(node, tm.canvas);
99           tm.labels.plotLabel(tm.canvas, node);
100         }
101       },
102       onMouseLeave: function(node) {
103         if(node) {
104           node.removeData('color');
105           node.removeCanvasStyle('shadowBlur');
106           tm.plot();
107         }
108       }
109     },
110     //duration of the animations
111     duration: 500,
112     //Enable tips
113     Tips: {
114       enable: true,
115       type: 'Native',
116       //add positioning offsets
117       offsetX: 20,
118       offsetY: 20,
119       //implement the onShow method to
120       //add content to the tooltip when a node
121       //is hovered
122       onShow: function(tip, node, isLeaf, domElement) {
123         var data = node.data;
124         var html = "<div class=\"tip-title\">"
125           + (data.title ? data.title : "")
126           + " " + data.name
127           + "</div><div class=\"tip-text\">";
128
129         html += "<br />";
130         html += sprintf("Size: %d (%d + %d)<br />", data.self_size+data.kids_size, data.self_size, data.kids_size);
131
132         if (data.self_size) {
133             html += sprintf("Memory usage:<br />");
134             bySortedValue(data.leaves,
135                 function(a, b) { return a[1] - b[1] },
136                 function(k, v) { html += sprintf(" %10s: %5d<br />", k, v);
137             });
138             html += "<br />";
139         }
140
141
142         html += sprintf("Attributes:<br />");
143         bySortedValue(data.attr,
144             function(a, b) { return a[0] > b[0] ? 1 : a[0] < b[0] ? -1 : 0 },
145             function(k, v) { html += sprintf(" %10s: %5d<br />", k, v);
146         });
147         html += "<br />";
148
149         if (data.child_count) {
150             html += sprintf("Children: %d of %d<br />", data.child_count, data.kids_node_count);
151         }
152         html += sprintf("Id: %s%s<br />", node.id, data._ids_merged ? data._ids_merged : "");
153         html += sprintf("Depth: %d<br />", data.depth);
154         html += sprintf("Parent: %d<br />", data.parent_id);
155
156         html += JSON.stringify(data.attr, undefined, 4);
157         //html += JSON.stringify(data, undefined, 4);
158
159         tip.innerHTML =  html; 
160       }  
161     },
162     //Implement this method for retrieving a requested  
163     //subtree that has as root a node with id = nodeId,  
164     //and level as depth. This method could also make a server-side  
165     //call for the requested subtree. When completed, the onComplete   
166     //callback method should be called.  
167     request: function(nodeId, level, onComplete){  
168             request_jit_tree(nodeId, level, levelsToShow, function(data) {
169                 console.log("Fetched node "+nodeId);
170                 console.log(data);
171                 onComplete.onComplete(nodeId, data);  
172             });
173     },
174     //Add the name of the node in the corresponding label
175     //This method is called once, on label creation and only for DOM labels.
176     onCreateLabel: function(domElement, node){
177         domElement.innerHTML = node.name;
178     }
179   });
180
181   request_jit_tree(1, 0, levelsToShow, function(data) {
182         console.log(data);
183         tm.loadJSON(data);
184         tm.refresh();
185     });
186
187     //add event to buttons
188     $jit.util.addEvent($jit.id('back'), 'click', function() { tm.out() });
189     $jit.util.addEvent($jit.id('logarea'), 'onchange', function() { tm.refresh() });
190
191 }
192
193