1
|
define([
|
2
|
"dojo/_base/declare",
|
3
|
"dojox/charting/action2d/Highlight",
|
4
|
"dojox/charting/action2d/Magnify",
|
5
|
"dojox/charting/action2d/Shake",
|
6
|
"dojox/charting/action2d/Tooltip",
|
7
|
"dojox/charting/Chart2D",
|
8
|
"dojox/charting/widget/Legend",
|
9
|
"dijit/form/HorizontalSlider",
|
10
|
"dijit/form/HorizontalRuleLabels",
|
11
|
"dijit/form/TextBox",
|
12
|
'dojox/charting/Chart',
|
13
|
"dojox/charting/widget/Legend",
|
14
|
'dojox/charting/themes/Tom',
|
15
|
"dojo/date/locale",
|
16
|
'steam2/StatsChartLoader',
|
17
|
'steam2/StatsChartThemes'
|
18
|
], function(declare){
|
19
|
|
20
|
var StatsChart = declare('steam2.StatsChart', dojox.charting.Chart, {
|
21
|
|
22
|
_yaxis: {
|
23
|
vertical: true,
|
24
|
majorTicks: 4,
|
25
|
min: 0,
|
26
|
max: 1 //24*1024*100
|
27
|
},
|
28
|
|
29
|
_xaxis: {
|
30
|
majorTicks: 3
|
31
|
},
|
32
|
|
33
|
markers: true,
|
34
|
|
35
|
// statsURL: '/stabile/stats',
|
36
|
statsURL: '/stabile/systems?action=metrics',
|
37
|
|
38
|
constructor: function(/* DOMNode */node, /* dojox.charting.__ChartCtorArgs? */kwArgs){
|
39
|
dojo.mixin(this, kwArgs);
|
40
|
this.yaxis = dojo.mixin(dojo.mixin({}, this._yaxis), kwArgs.yaxis);
|
41
|
this.xaxis = dojo.mixin(dojo.mixin({}, this._xaxis), kwArgs.xaxis);
|
42
|
this.addAxis('y', this.yaxis);
|
43
|
|
44
|
// add default plot
|
45
|
this.addPlot('default', {
|
46
|
markers: this.markers,
|
47
|
notension: 'S',
|
48
|
lines: true,
|
49
|
nolabelOffset: -30
|
50
|
});
|
51
|
|
52
|
this.addPlot('grid', {type: 'Grid', hMinorLines: false});
|
53
|
|
54
|
// then we can add dynamic stuff to the default plot
|
55
|
new dojox.charting.action2d.Tooltip(this, 'default', {
|
56
|
notext: function(o){
|
57
|
//for (var prop in o.plot._eventSeries)
|
58
|
// console.log(o, prop);
|
59
|
|
60
|
//console.log(o);
|
61
|
var value = o.y;
|
62
|
//var dt = new Date(o.x);
|
63
|
//if(typeof value === 'number'){
|
64
|
// value = value.toFixed(2);
|
65
|
//}
|
66
|
//return dojo.date.locale.format(dt, {datePattern: 'EEE, dd MMM', timePattern: 'HH:mm'}) +
|
67
|
// '<br /><span style="font-weight:bold">' + value + '</span>';
|
68
|
return value;
|
69
|
}
|
70
|
});
|
71
|
|
72
|
// on hover increase marker size.
|
73
|
new dojox.charting.action2d.Magnify(this, 'default', {scale: 1.5});
|
74
|
new steam2.StatsChartLoader(this);
|
75
|
|
76
|
if(this.legend){
|
77
|
var legendNodeWrapper = dojo.create('div', {className: 'legendNodeWrapper'}, node, 'after');
|
78
|
var legendNode = dojo.create('div', null, legendNodeWrapper);
|
79
|
var legend = new dojox.charting.widget.Legend({
|
80
|
chart:this
|
81
|
}, legendNode);
|
82
|
|
83
|
dojo.connect(this, 'render', function(){
|
84
|
legend.refresh();
|
85
|
});
|
86
|
}
|
87
|
|
88
|
this._setTheme();
|
89
|
},
|
90
|
|
91
|
humanSize: function(size, unitOnly){
|
92
|
if (size==null) return null;
|
93
|
var unit;
|
94
|
if(size <= steam2.StatsChart.KB){
|
95
|
unit = 'B/s';
|
96
|
}
|
97
|
else if(size <= steam2.StatsChart.MB){
|
98
|
size = size / steam2.StatsChart.KB;
|
99
|
unit = 'KB/s';
|
100
|
}
|
101
|
else if(size <= steam2.StatsChart.GB){
|
102
|
size = size / steam2.StatsChart.MB; //Math.pow(2,20);
|
103
|
unit = 'MB/s';
|
104
|
}
|
105
|
else{
|
106
|
size = size / steam2.StatsChart.GB;
|
107
|
unit = 'GB/s';
|
108
|
}
|
109
|
if(unitOnly){
|
110
|
return unit;
|
111
|
}
|
112
|
return size.toFixed(0) + ' ' + unit;
|
113
|
},
|
114
|
|
115
|
getTimeLabel: function(timestamp){
|
116
|
if ((new Date()).getDate() > (new Date(timestamp)).getDate()) { // Not today
|
117
|
return dojo.date.locale.format(
|
118
|
new Date(timestamp), {
|
119
|
//selector: "date",
|
120
|
datePattern: 'd/M',
|
121
|
//timePattern: 'HH:mm:ss'
|
122
|
timePattern: 'HH:mm'
|
123
|
});
|
124
|
} else {
|
125
|
return dojo.date.locale.format(
|
126
|
new Date(timestamp), {
|
127
|
selector: "time",
|
128
|
//datePattern: 'd/M',
|
129
|
timePattern: 'HH:mm:ss'
|
130
|
//timePattern: 'HH:mm'
|
131
|
});
|
132
|
}
|
133
|
},
|
134
|
|
135
|
getYLabel: function(value){
|
136
|
if(this.type === 'data'){
|
137
|
return {
|
138
|
value: value,
|
139
|
text: this.humanSize(value)
|
140
|
};
|
141
|
};
|
142
|
return value;
|
143
|
},
|
144
|
|
145
|
loading: function(){
|
146
|
},
|
147
|
|
148
|
noData: function(){
|
149
|
},
|
150
|
|
151
|
show: function(uuid, statfield, name, kwArgs){
|
152
|
this.loading();
|
153
|
|
154
|
var self = this,
|
155
|
from = parseInt(kwArgs.from.getTime() * 0.001, 10),
|
156
|
to = parseInt(kwArgs.to.getTime() * 0.001, 10),
|
157
|
query = {
|
158
|
uuid: uuid,
|
159
|
from: from,
|
160
|
to: to
|
161
|
};
|
162
|
|
163
|
query[statfield] = true;
|
164
|
|
165
|
// when several series are present save the max
|
166
|
this.yaxis.max = null;
|
167
|
|
168
|
function success(dataArray){
|
169
|
for (var i = 0; i < dataArray.length; i++) {
|
170
|
data = dataArray[i];
|
171
|
if(!data || data.timestamps === null){
|
172
|
self.noData();
|
173
|
console.log("No stats data to render");
|
174
|
return;
|
175
|
}
|
176
|
console.log("preparing", data.uuid);
|
177
|
var d = self.prepare(data, statfield, name);
|
178
|
self.addSeries(uuid+name, d.data, {stroke: {width: 1}});
|
179
|
if(self.type === 'data'){
|
180
|
self.addBytesAxis(d.max);
|
181
|
}
|
182
|
else if(self.type === 'ratio'){
|
183
|
self.addRatioAxis(d.max);
|
184
|
};
|
185
|
//console.log(kwArgs.from.getTime()-d.xmin, kwArgs.to.getTime()-d.xmax);
|
186
|
self.addAxis('x', {
|
187
|
minorTicks: false,
|
188
|
//from: kwArgs.from.getTime(),
|
189
|
from:d.xmin,
|
190
|
//to: kwArgs.to.getTime(),
|
191
|
to:d.xmax,
|
192
|
labelFunc: function(def, ts, precision){
|
193
|
return self.getTimeLabel(ts);
|
194
|
},
|
195
|
//majorTickStep: (d.data[d.data.length-1].x - d.data[0].x) / self.xaxis.majorTicks
|
196
|
majorTickStep: (to-from)*1000/6
|
197
|
//majorTickStep: (d.xmax-d.xmin)/6
|
198
|
});
|
199
|
}
|
200
|
self.render();
|
201
|
}
|
202
|
|
203
|
function error(err){
|
204
|
if(err.responseText){
|
205
|
self.noData(err.responseText);
|
206
|
}
|
207
|
else if(err.status === 401){
|
208
|
self.noData("You are not logged in!");
|
209
|
}
|
210
|
else{
|
211
|
self.noData("Couldn't get data from server");
|
212
|
}
|
213
|
}
|
214
|
|
215
|
var def = this.fetch(query);
|
216
|
def.then(success, error);
|
217
|
},
|
218
|
|
219
|
addRatioAxis: function(pmax){
|
220
|
var max = pmax;
|
221
|
var step = null;
|
222
|
if(max > 1){
|
223
|
step = .5;
|
224
|
max = 2;
|
225
|
}
|
226
|
else{
|
227
|
step = .5;
|
228
|
max = 1.05;
|
229
|
}
|
230
|
this.yaxis.majorTickStep = step;
|
231
|
this.yaxis.min = -0.05;
|
232
|
this.yaxis.max = max;
|
233
|
this.yaxis.leftBottom = false;
|
234
|
this.yaxis.vertical = true;
|
235
|
this.addAxis('y', this.yaxis);
|
236
|
},
|
237
|
|
238
|
addBytesAxis: function(pmax){
|
239
|
var max = pmax * 1.1;
|
240
|
|
241
|
if(!this.yaxis.max || this.yaxis.max < max){
|
242
|
this.yaxis.max = max;
|
243
|
this.yaxis.leftBottom = false;
|
244
|
//this.yaxis.majorTickStep = max / 4;
|
245
|
this.yaxis.majorTickStep = Math.round(max / 2);
|
246
|
// go a little bit below 0 so we can see y=0 values
|
247
|
this.yaxis.min = -this.yaxis.majorTickStep * 0.1;
|
248
|
this.yaxis.vertical = true;
|
249
|
|
250
|
var self = this;
|
251
|
this.yaxis.labelFunc = function(def, y, precision){
|
252
|
return self.humanSize(y);
|
253
|
};
|
254
|
this.addAxis('y', this.yaxis);
|
255
|
}
|
256
|
},
|
257
|
|
258
|
fetch: function(query){
|
259
|
return dojo.xhrGet({
|
260
|
content: query,
|
261
|
url: this.statsURL,
|
262
|
handleAs: 'json'
|
263
|
});
|
264
|
},
|
265
|
|
266
|
prepare: function(data, statfield, name){
|
267
|
var prepared = {
|
268
|
min:0,
|
269
|
max:0,
|
270
|
xmax:0,
|
271
|
xmin:0,
|
272
|
data:[]
|
273
|
};
|
274
|
for(var i = 0; i < data.timestamps.length; i++){
|
275
|
var value = data[statfield][i];
|
276
|
if (value || value==0) {
|
277
|
prepared.data.push({
|
278
|
x: data.timestamps[i] * 1000, /* s -> ms */
|
279
|
y: value,
|
280
|
tooltip: name
|
281
|
});
|
282
|
if(value > prepared.max){
|
283
|
prepared.max = value;
|
284
|
}
|
285
|
}
|
286
|
if(data.timestamps[i]*1000 > prepared.xmax || prepared.xmax==0){
|
287
|
prepared.xmax = data.timestamps[i]*1000;
|
288
|
}
|
289
|
if(data.timestamps[i]*1000 < prepared.xmin || prepared.xmin==0){
|
290
|
prepared.xmin = data.timestamps[i]*1000;
|
291
|
}
|
292
|
}
|
293
|
return prepared;
|
294
|
},
|
295
|
|
296
|
_setTheme: function(){
|
297
|
this.setTheme(steam2.StatsChartThemes.blue);
|
298
|
//this.setTheme(dojox.charting.themes.Tom);
|
299
|
}
|
300
|
|
301
|
|
302
|
});
|
303
|
|
304
|
StatsChart.KB = Math.pow(2,10);
|
305
|
StatsChart.MB = Math.pow(2,20);
|
306
|
StatsChart.GB = Math.pow(2,30);
|
307
|
StatsChart.TB = Math.pow(2,40);
|
308
|
|
309
|
});
|
310
|
|