]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/web/download_status_timeline.js
f7b3e45a33b12db24d1435b8947f157199a4ab72
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / web / download_status_timeline.js
1
2 $(function() {
3
4       function onDataReceived(data) {
5           var bounds = { min: data.bounds.min,
6                          max: data.bounds.max
7                        };
8           //bounds.max = data.dyhb[data.dyhb.length-1].finish_time;
9           var duration = bounds.max - bounds.min;
10           var WIDTH = 600;
11           var vis = new pv.Panel().canvas("timeline").margin(30);
12
13           var dyhb_top = 0;
14           var read_top = dyhb_top + 30*data.dyhb[data.dyhb.length-1].row+60;
15           var segment_top = read_top + 30*data.read[data.read.length-1].row+60;
16           var block_top = segment_top + 30*data.segment[data.segment.length-1].row+60;
17           var block_row_to_y = {};
18           var row_y=0;
19           for (var group=0; group < data.block_rownums.length; group++) {
20               for (var row=0; row < data.block_rownums[group]; row++) {
21                   block_row_to_y[group+"-"+row] = row_y;
22                   row_y += 10;
23               }
24               row_y += 5;
25           }
26
27           var height = block_top + row_y;
28           var kx = bounds.min;
29           var ky = 1;
30           var x = pv.Scale.linear(bounds.min, bounds.max).range(0, WIDTH-40);
31           var relx = pv.Scale.linear(0, duration).range(0, WIDTH-40);
32           //var y = pv.Scale.linear(-ky,ky).range(0, height);
33           //x.nice(); relx.nice();
34
35           /* add the invisible panel now, at the bottom of the stack, so that
36           it won't steal mouseover events and prevent tooltips from
37           working. */
38           var zoomer = vis.add(pv.Panel)
39               .events("all")
40               .event("mousedown", pv.Behavior.pan())
41               .event("mousewheel", pv.Behavior.zoom())
42               .event("pan", transform)
43               .event("zoom", transform)
44           ;
45
46           vis.anchor("top").top(-20).add(pv.Label).text("DYHB Requests");
47
48           vis.add(pv.Bar)
49               .data(data.dyhb)
50               .height(20)
51               .top(function (d) {return 30*d.row;})
52               .left(function(d){return x(d.start_time);})
53               .width(function(d){return x(d.finish_time)-x(d.start_time);})
54               .title(function(d){return "shnums: "+d.response_shnums;})
55               .fillStyle(function(d){return data.server_info[d.serverid].color;})
56               .strokeStyle("black").lineWidth(1);
57
58           vis.add(pv.Rule)
59               .data(data.dyhb)
60               .top(function(d){return 30*d.row + 20/2;})
61               .left(0).width(0)
62               .strokeStyle("#888")
63               .anchor("left").add(pv.Label)
64               .text(function(d){return d.serverid.slice(0,4);});
65
66           /* we use a function for data=relx.ticks() here instead of
67            simply .data(relx.ticks()) so that it will be recalculated when
68            the scales change (by pan/zoom) */
69           var xaxis = vis.add(pv.Rule)
70               .data(function() {return relx.ticks();})
71               .strokeStyle("#ccc")
72               .left(relx)
73               .anchor("bottom").add(pv.Label)
74               .text(function(d){return relx.tickFormat(d)+"s";});
75
76           var read = vis.add(pv.Panel).top(read_top);
77           read.anchor("top").top(-20).add(pv.Label).text("read() requests");
78
79           read.add(pv.Bar)
80               .data(data.read)
81               .height(20)
82               .top(function (d) {return 30*d.row;})
83               .left(function(d){return x(d.start_time);})
84               .width(function(d){return x(d.finish_time)-x(d.start_time);})
85               .title(function(d){return "read(start="+d.start+", len="+d.length+") -> "+d.bytes_returned+" bytes";})
86               .fillStyle("red")
87               .strokeStyle("black").lineWidth(1);
88
89           var segment = vis.add(pv.Panel).top(segment_top);
90           segment.anchor("top").top(-20).add(pv.Label).text("segment() requests");
91
92           segment.add(pv.Bar)
93               .data(data.segment)
94               .height(20)
95               .top(function (d) {return 30*d.row;})
96               .left(function(d){return x(d.start_time);})
97               .width(function(d){return x(d.finish_time)-x(d.start_time);})
98               .title(function(d){return "seg"+d.segment_number+" ["+d.segment_start+":+"+d.segment_length+"] (took "+(d.finish_time-d.start_time)+")";})
99               .fillStyle(function(d){if (d.success) return "#c0ffc0";
100                                     else return "#ffc0c0";})
101               .strokeStyle("black").lineWidth(1);
102
103           var block = vis.add(pv.Panel).top(block_top);
104           block.anchor("top").top(-20).add(pv.Label).text("block() requests");
105
106           var shnum_colors = pv.Colors.category10();
107           block.add(pv.Bar)
108               .data(data.block)
109               .height(10)
110               .top(function (d) {return block_row_to_y[d.row[0]+"-"+d.row[1]];})
111               .left(function(d){return x(d.start_time);})
112               .width(function(d){return x(d.finish_time)-x(d.start_time);})
113               .title(function(d){return "sh"+d.shnum+"-on-"+d.serverid.slice(0,4)+" ["+d.start+":+"+d.length+"] -> "+d.response_length;})
114               .fillStyle(function(d){return data.server_info[d.serverid].color;})
115               .strokeStyle(function(d){return shnum_colors(d.shnum).color;})
116               .lineWidth(function(d)
117                          {if (d.response_length > 100) return 3;
118                          else return 1;
119                           })
120           ;
121
122
123           vis.height(height);
124
125           function zoomin() {
126               var t = zoomer.transform().invert();
127               t.k = t.k/1.5;
128               zoomer.transform(t.invert());
129               zoompan(t);
130           }
131
132           function zoomout() {
133               var t = zoomer.transform().invert();
134               t.k = t.k*1.5;
135               zoomer.transform(t.invert());
136               zoompan(t);
137           }
138
139           function transform() {
140               var t = this.transform().invert();
141               zoompan(t);
142           }
143           function zoompan(t) {
144               // when t.x=0 and t.k=1.0, left should be bounds.min
145               x.domain(bounds.min + (t.x/WIDTH)*duration,
146                        bounds.min + t.k*duration + (t.x/WIDTH)*duration);
147               relx.domain(0 + t.x/WIDTH*duration,
148                           t.k*duration + (t.x/WIDTH)*duration);
149               vis.render();
150           }
151
152           vis.render();
153           $("#zoomin").click(zoomin);
154           $("#zoomout").click(zoomout);
155       }
156
157       $.ajax({url: "event_json",
158               method: 'GET',
159               dataType: 'json',
160               success: onDataReceived });
161 });
162