rickshaw_rails 1.2.0 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -136,7 +136,6 @@
136
136
  position: absolute;
137
137
  top: 0;
138
138
  bottom: -6px;
139
- z-index: -10;
140
139
  }
141
140
  .rickshaw_graph .annotation_range.active {
142
141
  display: block;
@@ -318,4 +317,4 @@
318
317
  .rickshaw_legend li:active {
319
318
  background: rgba(255, 255, 255, 0.2);
320
319
  border-radius: 3px;
321
- }
320
+ }
@@ -1,3 +1,3 @@
1
1
  module RickshawRails
2
- VERSION = "1.2.0"
2
+ VERSION = "1.4.3"
3
3
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rickshaw_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
5
- prerelease:
4
+ version: 1.4.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Han Kang
@@ -10,57 +9,51 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-02-27 00:00:00.000000000 Z
12
+ date: 2013-08-28 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: railties
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: 3.1.0
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - '>='
29
26
  - !ruby/object:Gem::Version
30
27
  version: 3.1.0
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: bundler
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ~>
32
+ - - '>='
37
33
  - !ruby/object:Gem::Version
38
34
  version: 1.0.0
39
35
  type: :development
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ~>
39
+ - - '>='
45
40
  - !ruby/object:Gem::Version
46
41
  version: 1.0.0
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: rails
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ~>
46
+ - - '>='
53
47
  - !ruby/object:Gem::Version
54
48
  version: '3.1'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ~>
53
+ - - '>='
61
54
  - !ruby/object:Gem::Version
62
55
  version: '3.1'
63
- description: ! ' Rickshaw, a javascript graphing library based on d3, for the rails
56
+ description: ' Rickshaw, a javascript graphing library based on d3, for the rails
64
57
  asset pipeline '
65
58
  email:
66
59
  - han@logicallsat.com
@@ -71,33 +64,32 @@ files:
71
64
  - lib/rickshaw_rails/engine.rb
72
65
  - lib/rickshaw_rails/version.rb
73
66
  - lib/rickshaw_rails.rb
74
- - vendor/assets/javascripts/d3.v2.js
75
- - vendor/assets/javascripts/rickshaw.js
76
- - vendor/assets/javascripts/rickshaw_with_d3.js
77
- - vendor/assets/stylesheets/rickshaw.css
67
+ - app/assets/javascripts/d3.v2.js
68
+ - app/assets/javascripts/rickshaw.js
69
+ - app/assets/javascripts/rickshaw_with_d3.js
70
+ - app/assets/stylesheets/rickshaw.css
78
71
  homepage: ''
79
72
  licenses: []
73
+ metadata: {}
80
74
  post_install_message:
81
75
  rdoc_options: []
82
76
  require_paths:
83
77
  - lib
84
- - vendor
78
+ - app
85
79
  required_ruby_version: !ruby/object:Gem::Requirement
86
- none: false
87
80
  requirements:
88
- - - ! '>='
81
+ - - '>='
89
82
  - !ruby/object:Gem::Version
90
83
  version: '0'
91
84
  required_rubygems_version: !ruby/object:Gem::Requirement
92
- none: false
93
85
  requirements:
94
- - - ! '>='
86
+ - - '>='
95
87
  - !ruby/object:Gem::Version
96
88
  version: '0'
97
89
  requirements: []
98
90
  rubyforge_project:
99
- rubygems_version: 1.8.24
91
+ rubygems_version: 2.0.5
100
92
  signing_key:
101
- specification_version: 3
93
+ specification_version: 4
102
94
  summary: Gem installation of javascript framework for data visualization, D3
103
95
  test_files: []
@@ -1,2842 +0,0 @@
1
- var Rickshaw = {
2
-
3
- namespace: function(namespace, obj) {
4
-
5
- var parts = namespace.split('.');
6
-
7
- var parent = Rickshaw;
8
-
9
- for(var i = 1, length = parts.length; i < length; i++) {
10
- var currentPart = parts[i];
11
- parent[currentPart] = parent[currentPart] || {};
12
- parent = parent[currentPart];
13
- }
14
- return parent;
15
- },
16
-
17
- keys: function(obj) {
18
- var keys = [];
19
- for (var key in obj) keys.push(key);
20
- return keys;
21
- },
22
-
23
- extend: function(destination, source) {
24
-
25
- for (var property in source) {
26
- destination[property] = source[property];
27
- }
28
- return destination;
29
- }
30
- };
31
-
32
- if (typeof module !== 'undefined' && module.exports) {
33
- var d3 = require('d3');
34
- module.exports = Rickshaw;
35
- }
36
-
37
- /* Adapted from https://github.com/Jakobo/PTClass */
38
-
39
- /*
40
- Copyright (c) 2005-2010 Sam Stephenson
41
-
42
- Permission is hereby granted, free of charge, to any person obtaining a copy
43
- of this software and associated documentation files (the "Software"), to deal
44
- in the Software without restriction, including without limitation the rights
45
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
- copies of the Software, and to permit persons to whom the Software is
47
- furnished to do so, subject to the following conditions:
48
-
49
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55
- SOFTWARE.
56
- */
57
- /* Based on Alex Arnell's inheritance implementation. */
58
- /** section: Language
59
- * class Class
60
- *
61
- * Manages Prototype's class-based OOP system.
62
- *
63
- * Refer to Prototype's web site for a [tutorial on classes and
64
- * inheritance](http://prototypejs.org/learn/class-inheritance).
65
- **/
66
- (function(globalContext) {
67
- /* ------------------------------------ */
68
- /* Import from object.js */
69
- /* ------------------------------------ */
70
- var _toString = Object.prototype.toString,
71
- NULL_TYPE = 'Null',
72
- UNDEFINED_TYPE = 'Undefined',
73
- BOOLEAN_TYPE = 'Boolean',
74
- NUMBER_TYPE = 'Number',
75
- STRING_TYPE = 'String',
76
- OBJECT_TYPE = 'Object',
77
- FUNCTION_CLASS = '[object Function]';
78
- function isFunction(object) {
79
- return _toString.call(object) === FUNCTION_CLASS;
80
- }
81
- function extend(destination, source) {
82
- for (var property in source) if (source.hasOwnProperty(property)) // modify protect primitive slaughter
83
- destination[property] = source[property];
84
- return destination;
85
- }
86
- function keys(object) {
87
- if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
88
- var results = [];
89
- for (var property in object) {
90
- if (object.hasOwnProperty(property)) {
91
- results.push(property);
92
- }
93
- }
94
- return results;
95
- }
96
- function Type(o) {
97
- switch(o) {
98
- case null: return NULL_TYPE;
99
- case (void 0): return UNDEFINED_TYPE;
100
- }
101
- var type = typeof o;
102
- switch(type) {
103
- case 'boolean': return BOOLEAN_TYPE;
104
- case 'number': return NUMBER_TYPE;
105
- case 'string': return STRING_TYPE;
106
- }
107
- return OBJECT_TYPE;
108
- }
109
- function isUndefined(object) {
110
- return typeof object === "undefined";
111
- }
112
- /* ------------------------------------ */
113
- /* Import from Function.js */
114
- /* ------------------------------------ */
115
- var slice = Array.prototype.slice;
116
- function argumentNames(fn) {
117
- var names = fn.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
118
- .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
119
- .replace(/\s+/g, '').split(',');
120
- return names.length == 1 && !names[0] ? [] : names;
121
- }
122
- function wrap(fn, wrapper) {
123
- var __method = fn;
124
- return function() {
125
- var a = update([bind(__method, this)], arguments);
126
- return wrapper.apply(this, a);
127
- }
128
- }
129
- function update(array, args) {
130
- var arrayLength = array.length, length = args.length;
131
- while (length--) array[arrayLength + length] = args[length];
132
- return array;
133
- }
134
- function merge(array, args) {
135
- array = slice.call(array, 0);
136
- return update(array, args);
137
- }
138
- function bind(fn, context) {
139
- if (arguments.length < 2 && isUndefined(arguments[0])) return this;
140
- var __method = fn, args = slice.call(arguments, 2);
141
- return function() {
142
- var a = merge(args, arguments);
143
- return __method.apply(context, a);
144
- }
145
- }
146
-
147
- /* ------------------------------------ */
148
- /* Import from Prototype.js */
149
- /* ------------------------------------ */
150
- var emptyFunction = function(){};
151
-
152
- var Class = (function() {
153
-
154
- // Some versions of JScript fail to enumerate over properties, names of which
155
- // correspond to non-enumerable properties in the prototype chain
156
- var IS_DONTENUM_BUGGY = (function(){
157
- for (var p in { toString: 1 }) {
158
- // check actual property name, so that it works with augmented Object.prototype
159
- if (p === 'toString') return false;
160
- }
161
- return true;
162
- })();
163
-
164
- function subclass() {};
165
- function create() {
166
- var parent = null, properties = [].slice.apply(arguments);
167
- if (isFunction(properties[0]))
168
- parent = properties.shift();
169
-
170
- function klass() {
171
- this.initialize.apply(this, arguments);
172
- }
173
-
174
- extend(klass, Class.Methods);
175
- klass.superclass = parent;
176
- klass.subclasses = [];
177
-
178
- if (parent) {
179
- subclass.prototype = parent.prototype;
180
- klass.prototype = new subclass;
181
- try { parent.subclasses.push(klass) } catch(e) {}
182
- }
183
-
184
- for (var i = 0, length = properties.length; i < length; i++)
185
- klass.addMethods(properties[i]);
186
-
187
- if (!klass.prototype.initialize)
188
- klass.prototype.initialize = emptyFunction;
189
-
190
- klass.prototype.constructor = klass;
191
- return klass;
192
- }
193
-
194
- function addMethods(source) {
195
- var ancestor = this.superclass && this.superclass.prototype,
196
- properties = keys(source);
197
-
198
- // IE6 doesn't enumerate `toString` and `valueOf` (among other built-in `Object.prototype`) properties,
199
- // Force copy if they're not Object.prototype ones.
200
- // Do not copy other Object.prototype.* for performance reasons
201
- if (IS_DONTENUM_BUGGY) {
202
- if (source.toString != Object.prototype.toString)
203
- properties.push("toString");
204
- if (source.valueOf != Object.prototype.valueOf)
205
- properties.push("valueOf");
206
- }
207
-
208
- for (var i = 0, length = properties.length; i < length; i++) {
209
- var property = properties[i], value = source[property];
210
- if (ancestor && isFunction(value) &&
211
- argumentNames(value)[0] == "$super") {
212
- var method = value;
213
- value = wrap((function(m) {
214
- return function() { return ancestor[m].apply(this, arguments); };
215
- })(property), method);
216
-
217
- value.valueOf = bind(method.valueOf, method);
218
- value.toString = bind(method.toString, method);
219
- }
220
- this.prototype[property] = value;
221
- }
222
-
223
- return this;
224
- }
225
-
226
- return {
227
- create: create,
228
- Methods: {
229
- addMethods: addMethods
230
- }
231
- };
232
- })();
233
-
234
- if (globalContext.exports) {
235
- globalContext.exports.Class = Class;
236
- }
237
- else {
238
- globalContext.Class = Class;
239
- }
240
- })(Rickshaw);
241
- Rickshaw.namespace('Rickshaw.Compat.ClassList');
242
-
243
- Rickshaw.Compat.ClassList = function() {
244
-
245
- /* adapted from http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
246
-
247
- if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
248
-
249
- (function (view) {
250
-
251
- "use strict";
252
-
253
- var
254
- classListProp = "classList"
255
- , protoProp = "prototype"
256
- , elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
257
- , objCtr = Object
258
- , strTrim = String[protoProp].trim || function () {
259
- return this.replace(/^\s+|\s+$/g, "");
260
- }
261
- , arrIndexOf = Array[protoProp].indexOf || function (item) {
262
- var
263
- i = 0
264
- , len = this.length
265
- ;
266
- for (; i < len; i++) {
267
- if (i in this && this[i] === item) {
268
- return i;
269
- }
270
- }
271
- return -1;
272
- }
273
- // Vendors: please allow content code to instantiate DOMExceptions
274
- , DOMEx = function (type, message) {
275
- this.name = type;
276
- this.code = DOMException[type];
277
- this.message = message;
278
- }
279
- , checkTokenAndGetIndex = function (classList, token) {
280
- if (token === "") {
281
- throw new DOMEx(
282
- "SYNTAX_ERR"
283
- , "An invalid or illegal string was specified"
284
- );
285
- }
286
- if (/\s/.test(token)) {
287
- throw new DOMEx(
288
- "INVALID_CHARACTER_ERR"
289
- , "String contains an invalid character"
290
- );
291
- }
292
- return arrIndexOf.call(classList, token);
293
- }
294
- , ClassList = function (elem) {
295
- var
296
- trimmedClasses = strTrim.call(elem.className)
297
- , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
298
- , i = 0
299
- , len = classes.length
300
- ;
301
- for (; i < len; i++) {
302
- this.push(classes[i]);
303
- }
304
- this._updateClassName = function () {
305
- elem.className = this.toString();
306
- };
307
- }
308
- , classListProto = ClassList[protoProp] = []
309
- , classListGetter = function () {
310
- return new ClassList(this);
311
- }
312
- ;
313
- // Most DOMException implementations don't allow calling DOMException's toString()
314
- // on non-DOMExceptions. Error's toString() is sufficient here.
315
- DOMEx[protoProp] = Error[protoProp];
316
- classListProto.item = function (i) {
317
- return this[i] || null;
318
- };
319
- classListProto.contains = function (token) {
320
- token += "";
321
- return checkTokenAndGetIndex(this, token) !== -1;
322
- };
323
- classListProto.add = function (token) {
324
- token += "";
325
- if (checkTokenAndGetIndex(this, token) === -1) {
326
- this.push(token);
327
- this._updateClassName();
328
- }
329
- };
330
- classListProto.remove = function (token) {
331
- token += "";
332
- var index = checkTokenAndGetIndex(this, token);
333
- if (index !== -1) {
334
- this.splice(index, 1);
335
- this._updateClassName();
336
- }
337
- };
338
- classListProto.toggle = function (token) {
339
- token += "";
340
- if (checkTokenAndGetIndex(this, token) === -1) {
341
- this.add(token);
342
- } else {
343
- this.remove(token);
344
- }
345
- };
346
- classListProto.toString = function () {
347
- return this.join(" ");
348
- };
349
-
350
- if (objCtr.defineProperty) {
351
- var classListPropDesc = {
352
- get: classListGetter
353
- , enumerable: true
354
- , configurable: true
355
- };
356
- try {
357
- objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
358
- } catch (ex) { // IE 8 doesn't support enumerable:true
359
- if (ex.number === -0x7FF5EC54) {
360
- classListPropDesc.enumerable = false;
361
- objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
362
- }
363
- }
364
- } else if (objCtr[protoProp].__defineGetter__) {
365
- elemCtrProto.__defineGetter__(classListProp, classListGetter);
366
- }
367
-
368
- }(window));
369
-
370
- }
371
- };
372
-
373
- if ( (typeof RICKSHAW_NO_COMPAT !== "undefined" && !RICKSHAW_NO_COMPAT) || typeof RICKSHAW_NO_COMPAT === "undefined") {
374
- new Rickshaw.Compat.ClassList();
375
- }
376
- Rickshaw.namespace('Rickshaw.Graph');
377
-
378
- Rickshaw.Graph = function(args) {
379
-
380
- if (!args.element) throw "Rickshaw.Graph needs a reference to an element";
381
-
382
- this.element = args.element;
383
- this.series = args.series;
384
-
385
- this.defaults = {
386
- interpolation: 'cardinal',
387
- offset: 'zero',
388
- min: undefined,
389
- max: undefined
390
- };
391
-
392
- Rickshaw.keys(this.defaults).forEach( function(k) {
393
- this[k] = args[k] || this.defaults[k];
394
- }, this );
395
-
396
- this.window = {};
397
-
398
- this.updateCallbacks = [];
399
-
400
- var self = this;
401
-
402
- this.initialize = function(args) {
403
-
404
- this.validateSeries(args.series);
405
-
406
- this.series.active = function() { return self.series.filter( function(s) { return !s.disabled } ) };
407
-
408
- this.setSize({ width: args.width, height: args.height });
409
-
410
- this.element.classList.add('rickshaw_graph');
411
- this.vis = d3.select(this.element)
412
- .append("svg:svg")
413
- .attr('width', this.width)
414
- .attr('height', this.height);
415
-
416
- var renderers = [
417
- Rickshaw.Graph.Renderer.Stack,
418
- Rickshaw.Graph.Renderer.Line,
419
- Rickshaw.Graph.Renderer.Bar,
420
- Rickshaw.Graph.Renderer.Area,
421
- Rickshaw.Graph.Renderer.ScatterPlot
422
- ];
423
-
424
- renderers.forEach( function(r) {
425
- if (!r) return;
426
- self.registerRenderer(new r( { graph: self } ));
427
- } );
428
-
429
- this.setRenderer(args.renderer || 'stack', args);
430
- this.discoverRange();
431
- };
432
-
433
- this.validateSeries = function(series) {
434
-
435
- if (!(series instanceof Array) && !(series instanceof Rickshaw.Series)) {
436
- var seriesSignature = Object.prototype.toString.apply(series);
437
- throw "series is not an array: " + seriesSignature;
438
- }
439
-
440
- var pointsCount;
441
-
442
- series.forEach( function(s) {
443
-
444
- if (!(s instanceof Object)) {
445
- throw "series element is not an object: " + s;
446
- }
447
- if (!(s.data)) {
448
- throw "series has no data: " + JSON.stringify(s);
449
- }
450
- if (!(s.data instanceof Array)) {
451
- throw "series data is not an array: " + JSON.stringify(s.data);
452
- }
453
-
454
- var x = s.data[0].x;
455
- var y = s.data[0].y;
456
-
457
- if (typeof x != 'number' || ( typeof y != 'number' && y !== null ) ) {
458
- throw "x and y properties of points should be numbers instead of " +
459
- (typeof x) + " and " + (typeof y)
460
- }
461
-
462
- }, this );
463
- };
464
-
465
- this.dataDomain = function() {
466
-
467
- // take from the first series
468
- var data = this.series[0].data;
469
-
470
- return [ data[0].x, data.slice(-1).shift().x ];
471
-
472
- };
473
-
474
- this.discoverRange = function() {
475
-
476
- var domain = this.renderer.domain();
477
-
478
- this.x = d3.scale.linear().domain(domain.x).range([0, this.width]);
479
-
480
- this.y = d3.scale.linear().domain(domain.y).range([this.height, 0]);
481
-
482
- this.y.magnitude = d3.scale.linear()
483
- .domain([domain.y[0] - domain.y[0], domain.y[1] - domain.y[0]])
484
- .range([0, this.height]);
485
- };
486
-
487
- this.render = function() {
488
-
489
- var stackedData = this.stackData();
490
- this.discoverRange();
491
-
492
- this.renderer.render();
493
-
494
- this.updateCallbacks.forEach( function(callback) {
495
- callback();
496
- } );
497
- };
498
-
499
- this.update = this.render;
500
-
501
- this.stackData = function() {
502
-
503
- var data = this.series.active()
504
- .map( function(d) { return d.data } )
505
- .map( function(d) { return d.filter( function(d) { return this._slice(d) }, this ) }, this);
506
-
507
- this.stackData.hooks.data.forEach( function(entry) {
508
- data = entry.f.apply(self, [data]);
509
- } );
510
-
511
- var stackedData;
512
-
513
- if (!this.renderer.unstack) {
514
-
515
- this._validateStackable();
516
-
517
- var layout = d3.layout.stack();
518
- layout.offset( self.offset );
519
- stackedData = layout(data);
520
- }
521
-
522
- stackedData = stackedData || data;
523
-
524
- this.stackData.hooks.after.forEach( function(entry) {
525
- stackedData = entry.f.apply(self, [data]);
526
- } );
527
-
528
- var i = 0;
529
- this.series.forEach( function(series) {
530
- if (series.disabled) return;
531
- series.stack = stackedData[i++];
532
- } );
533
-
534
- this.stackedData = stackedData;
535
- return stackedData;
536
- };
537
-
538
- this._validateStackable = function() {
539
-
540
- var series = this.series;
541
- var pointsCount;
542
-
543
- series.forEach( function(s) {
544
-
545
- pointsCount = pointsCount || s.data.length;
546
-
547
- if (pointsCount && s.data.length != pointsCount) {
548
- throw "stacked series cannot have differing numbers of points: " +
549
- pointsCount + " vs " + s.data.length + "; see Rickshaw.Series.fill()";
550
- }
551
-
552
- }, this );
553
- };
554
-
555
- this.stackData.hooks = { data: [], after: [] };
556
-
557
- this._slice = function(d) {
558
-
559
- if (this.window.xMin || this.window.xMax) {
560
-
561
- var isInRange = true;
562
-
563
- if (this.window.xMin && d.x < this.window.xMin) isInRange = false;
564
- if (this.window.xMax && d.x > this.window.xMax) isInRange = false;
565
-
566
- return isInRange;
567
- }
568
-
569
- return true;
570
- };
571
-
572
- this.onUpdate = function(callback) {
573
- this.updateCallbacks.push(callback);
574
- };
575
-
576
- this.registerRenderer = function(renderer) {
577
- this._renderers = this._renderers || {};
578
- this._renderers[renderer.name] = renderer;
579
- };
580
-
581
- this.configure = function(args) {
582
-
583
- if (args.width || args.height) {
584
- this.setSize(args);
585
- }
586
-
587
- Rickshaw.keys(this.defaults).forEach( function(k) {
588
- this[k] = k in args ? args[k]
589
- : k in this ? this[k]
590
- : this.defaults[k];
591
- }, this );
592
-
593
- this.setRenderer(args.renderer || this.renderer.name, args);
594
- };
595
-
596
- this.setRenderer = function(name, args) {
597
-
598
- if (!this._renderers[name]) {
599
- throw "couldn't find renderer " + name;
600
- }
601
- this.renderer = this._renderers[name];
602
-
603
- if (typeof args == 'object') {
604
- this.renderer.configure(args);
605
- }
606
- };
607
-
608
- this.setSize = function(args) {
609
-
610
- args = args || {};
611
-
612
- if (typeof window !== undefined) {
613
- var style = window.getComputedStyle(this.element, null);
614
- var elementWidth = parseInt(style.getPropertyValue('width'));
615
- var elementHeight = parseInt(style.getPropertyValue('height'));
616
- }
617
-
618
- this.width = args.width || elementWidth || 400;
619
- this.height = args.height || elementHeight || 250;
620
-
621
- this.vis && this.vis
622
- .attr('width', this.width)
623
- .attr('height', this.height);
624
- }
625
-
626
- this.initialize(args);
627
- };
628
- Rickshaw.namespace('Rickshaw.Fixtures.Color');
629
-
630
- Rickshaw.Fixtures.Color = function() {
631
-
632
- this.schemes = {};
633
-
634
- this.schemes.spectrum14 = [
635
- '#ecb796',
636
- '#dc8f70',
637
- '#b2a470',
638
- '#92875a',
639
- '#716c49',
640
- '#d2ed82',
641
- '#bbe468',
642
- '#a1d05d',
643
- '#e7cbe6',
644
- '#d8aad6',
645
- '#a888c2',
646
- '#9dc2d3',
647
- '#649eb9',
648
- '#387aa3'
649
- ].reverse();
650
-
651
- this.schemes.spectrum2000 = [
652
- '#57306f',
653
- '#514c76',
654
- '#646583',
655
- '#738394',
656
- '#6b9c7d',
657
- '#84b665',
658
- '#a7ca50',
659
- '#bfe746',
660
- '#e2f528',
661
- '#fff726',
662
- '#ecdd00',
663
- '#d4b11d',
664
- '#de8800',
665
- '#de4800',
666
- '#c91515',
667
- '#9a0000',
668
- '#7b0429',
669
- '#580839',
670
- '#31082b'
671
- ];
672
-
673
- this.schemes.spectrum2001 = [
674
- '#2f243f',
675
- '#3c2c55',
676
- '#4a3768',
677
- '#565270',
678
- '#6b6b7c',
679
- '#72957f',
680
- '#86ad6e',
681
- '#a1bc5e',
682
- '#b8d954',
683
- '#d3e04e',
684
- '#ccad2a',
685
- '#cc8412',
686
- '#c1521d',
687
- '#ad3821',
688
- '#8a1010',
689
- '#681717',
690
- '#531e1e',
691
- '#3d1818',
692
- '#320a1b'
693
- ];
694
-
695
- this.schemes.classic9 = [
696
- '#423d4f',
697
- '#4a6860',
698
- '#848f39',
699
- '#a2b73c',
700
- '#ddcb53',
701
- '#c5a32f',
702
- '#7d5836',
703
- '#963b20',
704
- '#7c2626',
705
- '#491d37',
706
- '#2f254a'
707
- ].reverse();
708
-
709
- this.schemes.httpStatus = {
710
- 503: '#ea5029',
711
- 502: '#d23f14',
712
- 500: '#bf3613',
713
- 410: '#efacea',
714
- 409: '#e291dc',
715
- 403: '#f457e8',
716
- 408: '#e121d2',
717
- 401: '#b92dae',
718
- 405: '#f47ceb',
719
- 404: '#a82a9f',
720
- 400: '#b263c6',
721
- 301: '#6fa024',
722
- 302: '#87c32b',
723
- 307: '#a0d84c',
724
- 304: '#28b55c',
725
- 200: '#1a4f74',
726
- 206: '#27839f',
727
- 201: '#52adc9',
728
- 202: '#7c979f',
729
- 203: '#a5b8bd',
730
- 204: '#c1cdd1'
731
- };
732
-
733
- this.schemes.colorwheel = [
734
- '#b5b6a9',
735
- '#858772',
736
- '#785f43',
737
- '#96557e',
738
- '#4682b4',
739
- '#65b9ac',
740
- '#73c03a',
741
- '#cb513a'
742
- ].reverse();
743
-
744
- this.schemes.cool = [
745
- '#5e9d2f',
746
- '#73c03a',
747
- '#4682b4',
748
- '#7bc3b8',
749
- '#a9884e',
750
- '#c1b266',
751
- '#a47493',
752
- '#c09fb5'
753
- ];
754
-
755
- this.schemes.munin = [
756
- '#00cc00',
757
- '#0066b3',
758
- '#ff8000',
759
- '#ffcc00',
760
- '#330099',
761
- '#990099',
762
- '#ccff00',
763
- '#ff0000',
764
- '#808080',
765
- '#008f00',
766
- '#00487d',
767
- '#b35a00',
768
- '#b38f00',
769
- '#6b006b',
770
- '#8fb300',
771
- '#b30000',
772
- '#bebebe',
773
- '#80ff80',
774
- '#80c9ff',
775
- '#ffc080',
776
- '#ffe680',
777
- '#aa80ff',
778
- '#ee00cc',
779
- '#ff8080',
780
- '#666600',
781
- '#ffbfff',
782
- '#00ffcc',
783
- '#cc6699',
784
- '#999900'
785
- ];
786
- };
787
- Rickshaw.namespace('Rickshaw.Fixtures.RandomData');
788
-
789
- Rickshaw.Fixtures.RandomData = function(timeInterval) {
790
-
791
- var addData;
792
- timeInterval = timeInterval || 1;
793
-
794
- var lastRandomValue = 200;
795
-
796
- var timeBase = Math.floor(new Date().getTime() / 1000);
797
-
798
- this.addData = function(data) {
799
-
800
- var randomValue = Math.random() * 100 + 15 + lastRandomValue;
801
- var index = data[0].length;
802
-
803
- var counter = 1;
804
-
805
- data.forEach( function(series) {
806
- var randomVariance = Math.random() * 20;
807
- var v = randomValue / 25 + counter++
808
- + (Math.cos((index * counter * 11) / 960) + 2) * 15
809
- + (Math.cos(index / 7) + 2) * 7
810
- + (Math.cos(index / 17) + 2) * 1;
811
-
812
- series.push( { x: (index * timeInterval) + timeBase, y: v + randomVariance } );
813
- } );
814
-
815
- lastRandomValue = randomValue * .85;
816
- }
817
- };
818
-
819
- Rickshaw.namespace('Rickshaw.Fixtures.Time');
820
-
821
- Rickshaw.Fixtures.Time = function() {
822
-
823
- var tzOffset = new Date().getTimezoneOffset() * 60;
824
-
825
- var self = this;
826
-
827
- this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
828
-
829
- this.units = [
830
- {
831
- name: 'decade',
832
- seconds: 86400 * 365.25 * 10,
833
- formatter: function(d) { return (parseInt(d.getUTCFullYear() / 10) * 10) }
834
- }, {
835
- name: 'year',
836
- seconds: 86400 * 365.25,
837
- formatter: function(d) { return d.getUTCFullYear() }
838
- }, {
839
- name: 'month',
840
- seconds: 86400 * 30.5,
841
- formatter: function(d) { return self.months[d.getUTCMonth()] }
842
- }, {
843
- name: 'week',
844
- seconds: 86400 * 7,
845
- formatter: function(d) { return self.formatDate(d) }
846
- }, {
847
- name: 'day',
848
- seconds: 86400,
849
- formatter: function(d) { return d.getUTCDate() }
850
- }, {
851
- name: '6 hour',
852
- seconds: 3600 * 6,
853
- formatter: function(d) { return self.formatTime(d) }
854
- }, {
855
- name: 'hour',
856
- seconds: 3600,
857
- formatter: function(d) { return self.formatTime(d) }
858
- }, {
859
- name: '15 minute',
860
- seconds: 60 * 15,
861
- formatter: function(d) { return self.formatTime(d) }
862
- }, {
863
- name: 'minute',
864
- seconds: 60,
865
- formatter: function(d) { return d.getUTCMinutes() }
866
- }, {
867
- name: '15 second',
868
- seconds: 15,
869
- formatter: function(d) { return d.getUTCSeconds() + 's' }
870
- }, {
871
- name: 'second',
872
- seconds: 1,
873
- formatter: function(d) { return d.getUTCSeconds() + 's' }
874
- }
875
- ];
876
-
877
- this.unit = function(unitName) {
878
- return this.units.filter( function(unit) { return unitName == unit.name } ).shift();
879
- };
880
-
881
- this.formatDate = function(d) {
882
- return d.toUTCString().match(/, (\w+ \w+ \w+)/)[1];
883
- };
884
-
885
- this.formatTime = function(d) {
886
- return d.toUTCString().match(/(\d+:\d+):/)[1];
887
- };
888
-
889
- this.ceil = function(time, unit) {
890
-
891
- if (unit.name == 'month') {
892
-
893
- var nearFuture = new Date((time + unit.seconds - 1) * 1000);
894
-
895
- var rounded = new Date(0);
896
- rounded.setUTCFullYear(nearFuture.getUTCFullYear());
897
- rounded.setUTCMonth(nearFuture.getUTCMonth());
898
- rounded.setUTCDate(1);
899
- rounded.setUTCHours(0);
900
- rounded.setUTCMinutes(0);
901
- rounded.setUTCSeconds(0);
902
- rounded.setUTCMilliseconds(0);
903
-
904
- return rounded.getTime() / 1000;
905
- }
906
-
907
- if (unit.name == 'year') {
908
-
909
- var nearFuture = new Date((time + unit.seconds - 1) * 1000);
910
-
911
- var rounded = new Date(0);
912
- rounded.setUTCFullYear(nearFuture.getUTCFullYear());
913
- rounded.setUTCMonth(0);
914
- rounded.setUTCDate(1);
915
- rounded.setUTCHours(0);
916
- rounded.setUTCMinutes(0);
917
- rounded.setUTCSeconds(0);
918
- rounded.setUTCMilliseconds(0);
919
-
920
- return rounded.getTime() / 1000;
921
- }
922
-
923
- return Math.ceil(time / unit.seconds) * unit.seconds;
924
- };
925
- };
926
- Rickshaw.namespace('Rickshaw.Fixtures.Number');
927
-
928
- Rickshaw.Fixtures.Number.formatKMBT = function(y) {
929
- abs_y = Math.abs(y);
930
- if (abs_y >= 1000000000000) { return y / 1000000000000 + "T" }
931
- else if (abs_y >= 1000000000) { return y / 1000000000 + "B" }
932
- else if (abs_y >= 1000000) { return y / 1000000 + "M" }
933
- else if (abs_y >= 1000) { return y / 1000 + "K" }
934
- else if (abs_y < 1 && y > 0) { return y.toFixed(2) }
935
- else if (abs_y == 0) { return '' }
936
- else { return y }
937
- };
938
-
939
- Rickshaw.Fixtures.Number.formatBase1024KMGTP = function(y) {
940
- abs_y = Math.abs(y);
941
- if (abs_y >= 1125899906842624) { return y / 1125899906842624 + "P" }
942
- else if (abs_y >= 1099511627776){ return y / 1099511627776 + "T" }
943
- else if (abs_y >= 1073741824) { return y / 1073741824 + "G" }
944
- else if (abs_y >= 1048576) { return y / 1048576 + "M" }
945
- else if (abs_y >= 1024) { return y / 1024 + "K" }
946
- else if (abs_y < 1 && y > 0) { return y.toFixed(2) }
947
- else if (abs_y == 0) { return '' }
948
- else { return y }
949
- };
950
- Rickshaw.namespace("Rickshaw.Color.Palette");
951
-
952
- Rickshaw.Color.Palette = function(args) {
953
-
954
- var color = new Rickshaw.Fixtures.Color();
955
-
956
- args = args || {};
957
- this.schemes = {};
958
-
959
- this.scheme = color.schemes[args.scheme] || args.scheme || color.schemes.colorwheel;
960
- this.runningIndex = 0;
961
- this.generatorIndex = 0;
962
-
963
- if (args.interpolatedStopCount) {
964
- var schemeCount = this.scheme.length - 1;
965
- var i, j, scheme = [];
966
- for (i = 0; i < schemeCount; i++) {
967
- scheme.push(this.scheme[i]);
968
- var generator = d3.interpolateHsl(this.scheme[i], this.scheme[i + 1]);
969
- for (j = 1; j < args.interpolatedStopCount; j++) {
970
- scheme.push(generator((1 / args.interpolatedStopCount) * j));
971
- }
972
- }
973
- scheme.push(this.scheme[this.scheme.length - 1]);
974
- this.scheme = scheme;
975
- }
976
- this.rotateCount = this.scheme.length;
977
-
978
- this.color = function(key) {
979
- return this.scheme[key] || this.scheme[this.runningIndex++] || this.interpolateColor() || '#808080';
980
- };
981
-
982
- this.interpolateColor = function() {
983
- if (!Array.isArray(this.scheme)) return;
984
- var color;
985
- if (this.generatorIndex == this.rotateCount * 2 - 1) {
986
- color = d3.interpolateHsl(this.scheme[this.generatorIndex], this.scheme[0])(0.5);
987
- this.generatorIndex = 0;
988
- this.rotateCount *= 2;
989
- } else {
990
- color = d3.interpolateHsl(this.scheme[this.generatorIndex], this.scheme[this.generatorIndex + 1])(0.5);
991
- this.generatorIndex++;
992
- }
993
- this.scheme.push(color);
994
- return color;
995
- };
996
-
997
- };
998
- Rickshaw.namespace('Rickshaw.Graph.Ajax');
999
-
1000
- Rickshaw.Graph.Ajax = Rickshaw.Class.create( {
1001
-
1002
- initialize: function(args) {
1003
-
1004
- this.dataURL = args.dataURL;
1005
-
1006
- this.onData = args.onData || function(d) { return d };
1007
- this.onComplete = args.onComplete || function() {};
1008
- this.onError = args.onError || function() {};
1009
-
1010
- this.args = args; // pass through to Rickshaw.Graph
1011
-
1012
- this.request();
1013
- },
1014
-
1015
- request: function() {
1016
-
1017
- $.ajax( {
1018
- url: this.dataURL,
1019
- dataType: 'json',
1020
- success: this.success.bind(this),
1021
- error: this.error.bind(this)
1022
- } );
1023
- },
1024
-
1025
- error: function() {
1026
-
1027
- console.log("error loading dataURL: " + this.dataURL);
1028
- this.onError(this);
1029
- },
1030
-
1031
- success: function(data, status) {
1032
-
1033
- data = this.onData(data);
1034
- this.args.series = this._splice({ data: data, series: this.args.series });
1035
-
1036
- this.graph = this.graph || new Rickshaw.Graph(this.args);
1037
- this.graph.render();
1038
-
1039
- this.onComplete(this);
1040
- },
1041
-
1042
- _splice: function(args) {
1043
-
1044
- var data = args.data;
1045
- var series = args.series;
1046
-
1047
- if (!args.series) return data;
1048
-
1049
- series.forEach( function(s) {
1050
-
1051
- var seriesKey = s.key || s.name;
1052
- if (!seriesKey) throw "series needs a key or a name";
1053
-
1054
- data.forEach( function(d) {
1055
-
1056
- var dataKey = d.key || d.name;
1057
- if (!dataKey) throw "data needs a key or a name";
1058
-
1059
- if (seriesKey == dataKey) {
1060
- var properties = ['color', 'name', 'data'];
1061
- properties.forEach( function(p) {
1062
- if (d[p]) s[p] = d[p];
1063
- } );
1064
- }
1065
- } );
1066
- } );
1067
-
1068
- return series;
1069
- }
1070
- } );
1071
-
1072
- Rickshaw.namespace('Rickshaw.Graph.Annotate');
1073
-
1074
- Rickshaw.Graph.Annotate = function(args) {
1075
-
1076
- var graph = this.graph = args.graph;
1077
- this.elements = { timeline: args.element };
1078
-
1079
- var self = this;
1080
-
1081
- this.data = {};
1082
-
1083
- this.elements.timeline.classList.add('rickshaw_annotation_timeline');
1084
-
1085
- this.add = function(time, content, end_time) {
1086
- self.data[time] = self.data[time] || {'boxes': []};
1087
- self.data[time].boxes.push({content: content, end: end_time});
1088
- };
1089
-
1090
- this.update = function() {
1091
-
1092
- Rickshaw.keys(self.data).forEach( function(time) {
1093
-
1094
- var annotation = self.data[time];
1095
- var left = self.graph.x(time);
1096
-
1097
- if (left < 0 || left > self.graph.x.range()[1]) {
1098
- if (annotation.element) {
1099
- annotation.line.classList.add('offscreen');
1100
- annotation.element.style.display = 'none';
1101
- }
1102
-
1103
- annotation.boxes.forEach( function(box) {
1104
- if ( box.rangeElement ) box.rangeElement.classList.add('offscreen');
1105
- });
1106
-
1107
- return;
1108
- }
1109
-
1110
- if (!annotation.element) {
1111
- var element = annotation.element = document.createElement('div');
1112
- element.classList.add('annotation');
1113
- this.elements.timeline.appendChild(element);
1114
- element.addEventListener('click', function(e) {
1115
- element.classList.toggle('active');
1116
- annotation.line.classList.toggle('active');
1117
- annotation.boxes.forEach( function(box) {
1118
- if ( box.rangeElement ) box.rangeElement.classList.toggle('active');
1119
- });
1120
- }, false);
1121
-
1122
- }
1123
-
1124
- annotation.element.style.left = left + 'px';
1125
- annotation.element.style.display = 'block';
1126
-
1127
- annotation.boxes.forEach( function(box) {
1128
-
1129
-
1130
- var element = box.element;
1131
-
1132
- if (!element) {
1133
- element = box.element = document.createElement('div');
1134
- element.classList.add('content');
1135
- element.innerHTML = box.content;
1136
- annotation.element.appendChild(element);
1137
-
1138
- annotation.line = document.createElement('div');
1139
- annotation.line.classList.add('annotation_line');
1140
- self.graph.element.appendChild(annotation.line);
1141
-
1142
- if ( box.end ) {
1143
- box.rangeElement = document.createElement('div');
1144
- box.rangeElement.classList.add('annotation_range');
1145
- self.graph.element.appendChild(box.rangeElement);
1146
- }
1147
-
1148
- }
1149
-
1150
- if ( box.end ) {
1151
-
1152
- var annotationRangeStart = left;
1153
- var annotationRangeEnd = Math.min( self.graph.x(box.end), self.graph.x.range()[1] );
1154
-
1155
- // annotation makes more sense at end
1156
- if ( annotationRangeStart > annotationRangeEnd ) {
1157
- annotationRangeEnd = left;
1158
- annotationRangeStart = Math.max( self.graph.x(box.end), self.graph.x.range()[0] );
1159
- }
1160
-
1161
- var annotationRangeWidth = annotationRangeEnd - annotationRangeStart;
1162
-
1163
- box.rangeElement.style.left = annotationRangeStart + 'px';
1164
- box.rangeElement.style.width = annotationRangeWidth + 'px'
1165
-
1166
- box.rangeElement.classList.remove('offscreen');
1167
- }
1168
-
1169
- annotation.line.classList.remove('offscreen');
1170
- annotation.line.style.left = left + 'px';
1171
- } );
1172
- }, this );
1173
- };
1174
-
1175
- this.graph.onUpdate( function() { self.update() } );
1176
- };
1177
- Rickshaw.namespace('Rickshaw.Graph.Axis.Time');
1178
-
1179
- Rickshaw.Graph.Axis.Time = function(args) {
1180
-
1181
- var self = this;
1182
-
1183
- this.graph = args.graph;
1184
- this.elements = [];
1185
- this.ticksTreatment = args.ticksTreatment || 'plain';
1186
- this.fixedTimeUnit = args.timeUnit;
1187
-
1188
- var time = new Rickshaw.Fixtures.Time();
1189
-
1190
- this.appropriateTimeUnit = function() {
1191
-
1192
- var unit;
1193
- var units = time.units;
1194
-
1195
- var domain = this.graph.x.domain();
1196
- var rangeSeconds = domain[1] - domain[0];
1197
-
1198
- units.forEach( function(u) {
1199
- if (Math.floor(rangeSeconds / u.seconds) >= 2) {
1200
- unit = unit || u;
1201
- }
1202
- } );
1203
-
1204
- return (unit || time.units[time.units.length - 1]);
1205
- };
1206
-
1207
- this.tickOffsets = function() {
1208
-
1209
- var domain = this.graph.x.domain();
1210
-
1211
- var unit = this.fixedTimeUnit || this.appropriateTimeUnit();
1212
- var count = Math.ceil((domain[1] - domain[0]) / unit.seconds);
1213
-
1214
- var runningTick = domain[0];
1215
-
1216
- var offsets = [];
1217
-
1218
- for (var i = 0; i < count; i++) {
1219
-
1220
- var tickValue = time.ceil(runningTick, unit);
1221
- runningTick = tickValue + unit.seconds / 2;
1222
-
1223
- offsets.push( { value: tickValue, unit: unit } );
1224
- }
1225
-
1226
- return offsets;
1227
- };
1228
-
1229
- this.render = function() {
1230
-
1231
- this.elements.forEach( function(e) {
1232
- e.parentNode.removeChild(e);
1233
- } );
1234
-
1235
- this.elements = [];
1236
-
1237
- var offsets = this.tickOffsets();
1238
-
1239
- offsets.forEach( function(o) {
1240
-
1241
- if (self.graph.x(o.value) > self.graph.x.range()[1]) return;
1242
-
1243
- var element = document.createElement('div');
1244
- element.style.left = self.graph.x(o.value) + 'px';
1245
- element.classList.add('x_tick');
1246
- element.classList.add(self.ticksTreatment);
1247
-
1248
- var title = document.createElement('div');
1249
- title.classList.add('title');
1250
- title.innerHTML = o.unit.formatter(new Date(o.value * 1000));
1251
- element.appendChild(title);
1252
-
1253
- self.graph.element.appendChild(element);
1254
- self.elements.push(element);
1255
-
1256
- } );
1257
- };
1258
-
1259
- this.graph.onUpdate( function() { self.render() } );
1260
- };
1261
-
1262
- Rickshaw.namespace('Rickshaw.Graph.Axis.X');
1263
-
1264
- Rickshaw.Graph.Axis.X = function(args) {
1265
-
1266
- var self = this;
1267
- var berthRate = 0.10;
1268
-
1269
- this.initialize = function(args) {
1270
-
1271
- this.graph = args.graph;
1272
- this.orientation = args.orientation || 'top';
1273
-
1274
- var pixelsPerTick = args.pixelsPerTick || 75;
1275
- this.ticks = args.ticks || Math.floor(this.graph.width / pixelsPerTick);
1276
- this.tickSize = args.tickSize || 4;
1277
- this.ticksTreatment = args.ticksTreatment || 'plain';
1278
-
1279
- if (args.element) {
1280
-
1281
- this.element = args.element;
1282
- this._discoverSize(args.element, args);
1283
-
1284
- this.vis = d3.select(args.element)
1285
- .append("svg:svg")
1286
- .attr('height', this.height)
1287
- .attr('width', this.width)
1288
- .attr('class', 'rickshaw_graph x_axis_d3');
1289
-
1290
- this.element = this.vis[0][0];
1291
- this.element.style.position = 'relative';
1292
-
1293
- this.setSize({ width: args.width, height: args.height });
1294
-
1295
- } else {
1296
- this.vis = this.graph.vis;
1297
- }
1298
-
1299
- this.graph.onUpdate( function() { self.render() } );
1300
- };
1301
-
1302
- this.setSize = function(args) {
1303
-
1304
- args = args || {};
1305
- if (!this.element) return;
1306
-
1307
- this._discoverSize(this.element.parentNode, args);
1308
-
1309
- this.vis
1310
- .attr('height', this.height)
1311
- .attr('width', this.width * (1 + berthRate));
1312
-
1313
- var berth = Math.floor(this.width * berthRate / 2);
1314
- this.element.style.left = -1 * berth + 'px';
1315
- };
1316
-
1317
- this.render = function() {
1318
-
1319
- if (this.graph.width !== this._renderWidth) this.setSize({ auto: true });
1320
-
1321
- var axis = d3.svg.axis().scale(this.graph.x).orient(this.orientation);
1322
- axis.tickFormat( args.tickFormat || function(x) { return x } );
1323
-
1324
- var berth = Math.floor(this.width * berthRate / 2) || 0;
1325
-
1326
- if (this.orientation == 'top') {
1327
- var yOffset = this.height || this.graph.height;
1328
- var transform = 'translate(' + berth + ',' + yOffset + ')';
1329
- } else {
1330
- var transform = 'translate(' + berth + ', 0)';
1331
- }
1332
-
1333
- if (this.element) {
1334
- this.vis.selectAll('*').remove();
1335
- }
1336
-
1337
- this.vis
1338
- .append("svg:g")
1339
- .attr("class", ["x_ticks_d3", this.ticksTreatment].join(" "))
1340
- .attr("transform", transform)
1341
- .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));
1342
-
1343
- var gridSize = (this.orientation == 'bottom' ? 1 : -1) * this.graph.height;
1344
-
1345
- this.graph.vis
1346
- .append("svg:g")
1347
- .attr("class", "x_grid_d3")
1348
- .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize));
1349
-
1350
- this._renderHeight = this.graph.height;
1351
- };
1352
-
1353
- this._discoverSize = function(element, args) {
1354
-
1355
- if (typeof window !== 'undefined') {
1356
-
1357
- var style = window.getComputedStyle(element, null);
1358
- var elementHeight = parseInt(style.getPropertyValue('height'));
1359
-
1360
- if (!args.auto) {
1361
- var elementWidth = parseInt(style.getPropertyValue('width'));
1362
- }
1363
- }
1364
-
1365
- this.width = (args.width || elementWidth || this.graph.width) * (1 + berthRate);
1366
- this.height = args.height || elementHeight || 40;
1367
- };
1368
-
1369
- this.initialize(args);
1370
- };
1371
-
1372
- Rickshaw.namespace('Rickshaw.Graph.Axis.Y');
1373
-
1374
- Rickshaw.Graph.Axis.Y = function(args) {
1375
-
1376
- var self = this;
1377
- var berthRate = 0.10;
1378
-
1379
- this.initialize = function(args) {
1380
-
1381
- this.graph = args.graph;
1382
- this.orientation = args.orientation || 'right';
1383
-
1384
- var pixelsPerTick = args.pixelsPerTick || 75;
1385
- this.ticks = args.ticks || Math.floor(this.graph.height / pixelsPerTick);
1386
- this.tickSize = args.tickSize || 4;
1387
- this.ticksTreatment = args.ticksTreatment || 'plain';
1388
-
1389
- if (args.element) {
1390
-
1391
- this.element = args.element;
1392
- this.vis = d3.select(args.element)
1393
- .append("svg:svg")
1394
- .attr('class', 'rickshaw_graph y_axis');
1395
-
1396
- this.element = this.vis[0][0];
1397
- this.element.style.position = 'relative';
1398
-
1399
- this.setSize({ width: args.width, height: args.height });
1400
-
1401
- } else {
1402
- this.vis = this.graph.vis;
1403
- }
1404
-
1405
- this.graph.onUpdate( function() { self.render() } );
1406
- };
1407
-
1408
- this.setSize = function(args) {
1409
-
1410
- args = args || {};
1411
-
1412
- if (!this.element) return;
1413
-
1414
- if (typeof window !== 'undefined') {
1415
-
1416
- var style = window.getComputedStyle(this.element.parentNode, null);
1417
- var elementWidth = parseInt(style.getPropertyValue('width'));
1418
-
1419
- if (!args.auto) {
1420
- var elementHeight = parseInt(style.getPropertyValue('height'));
1421
- }
1422
- }
1423
-
1424
- this.width = args.width || elementWidth || this.graph.width * berthRate;
1425
- this.height = args.height || elementHeight || this.graph.height;
1426
-
1427
- this.vis
1428
- .attr('width', this.width)
1429
- .attr('height', this.height * (1 + berthRate));
1430
-
1431
- var berth = this.height * berthRate;
1432
- this.element.style.top = -1 * berth + 'px';
1433
- };
1434
-
1435
- this.render = function() {
1436
-
1437
- if (this.graph.height !== this._renderHeight) this.setSize({ auto: true });
1438
-
1439
- var axis = d3.svg.axis().scale(this.graph.y).orient(this.orientation);
1440
- axis.tickFormat( args.tickFormat || function(y) { return y } );
1441
-
1442
- if (this.orientation == 'left') {
1443
- var berth = this.height * berthRate;
1444
- var transform = 'translate(' + this.width + ', ' + berth + ')';
1445
- }
1446
-
1447
- if (this.element) {
1448
- this.vis.selectAll('*').remove();
1449
- }
1450
-
1451
- this.vis
1452
- .append("svg:g")
1453
- .attr("class", ["y_ticks", this.ticksTreatment].join(" "))
1454
- .attr("transform", transform)
1455
- .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize))
1456
-
1457
- var gridSize = (this.orientation == 'right' ? 1 : -1) * this.graph.width;
1458
-
1459
- this.graph.vis
1460
- .append("svg:g")
1461
- .attr("class", "y_grid")
1462
- .call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize));
1463
-
1464
- this._renderHeight = this.graph.height;
1465
- };
1466
-
1467
- this.initialize(args);
1468
- };
1469
-
1470
- Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Highlight');
1471
-
1472
- Rickshaw.Graph.Behavior.Series.Highlight = function(args) {
1473
-
1474
- this.graph = args.graph;
1475
- this.legend = args.legend;
1476
-
1477
- var self = this;
1478
-
1479
- var colorSafe = {};
1480
- var activeLine = null;
1481
-
1482
- this.addHighlightEvents = function (l) {
1483
-
1484
- l.element.addEventListener( 'mouseover', function(e) {
1485
-
1486
- if (activeLine) return;
1487
- else activeLine = l;
1488
-
1489
- self.legend.lines.forEach( function(line, index) {
1490
-
1491
- if (l === line) {
1492
-
1493
- // if we're not in a stacked renderer bring active line to the top
1494
- if (index > 0 && self.graph.renderer.unstack) {
1495
-
1496
- var seriesIndex = self.graph.series.length - index - 1;
1497
- line.originalIndex = seriesIndex;
1498
-
1499
- var series = self.graph.series.splice(seriesIndex, 1)[0];
1500
- self.graph.series.push(series);
1501
- }
1502
- return;
1503
- }
1504
-
1505
- colorSafe[line.series.name] = colorSafe[line.series.name] || line.series.color;
1506
- line.series.color = d3.interpolateRgb(line.series.color, d3.rgb('#d8d8d8'))(0.8).toString();
1507
- } );
1508
-
1509
- self.graph.update();
1510
-
1511
- }, false );
1512
-
1513
- l.element.addEventListener( 'mouseout', function(e) {
1514
-
1515
- if (!activeLine) return;
1516
- else activeLine = null;
1517
-
1518
- self.legend.lines.forEach( function(line) {
1519
-
1520
- // return reordered series to its original place
1521
- if (l === line && line.hasOwnProperty('originalIndex')) {
1522
-
1523
- var series = self.graph.series.pop();
1524
- self.graph.series.splice(line.originalIndex, 0, series);
1525
- delete line['originalIndex'];
1526
- }
1527
-
1528
- if (colorSafe[line.series.name]) {
1529
- line.series.color = colorSafe[line.series.name];
1530
- }
1531
- } );
1532
-
1533
- self.graph.update();
1534
-
1535
- }, false );
1536
- };
1537
-
1538
- if (this.legend) {
1539
- this.legend.lines.forEach( function(l) {
1540
- self.addHighlightEvents(l);
1541
- } );
1542
- }
1543
-
1544
- };
1545
- Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Order');
1546
-
1547
- Rickshaw.Graph.Behavior.Series.Order = function(args) {
1548
-
1549
- this.graph = args.graph;
1550
- this.legend = args.legend;
1551
-
1552
- var self = this;
1553
-
1554
- $(function() {
1555
- $(self.legend.list).sortable( {
1556
- containment: 'parent',
1557
- tolerance: 'pointer',
1558
- update: function( event, ui ) {
1559
- var series = [];
1560
- $(self.legend.list).find('li').each( function(index, item) {
1561
- if (!item.series) return;
1562
- series.push(item.series);
1563
- } );
1564
-
1565
- for (var i = self.graph.series.length - 1; i >= 0; i--) {
1566
- self.graph.series[i] = series.shift();
1567
- }
1568
-
1569
- self.graph.update();
1570
- }
1571
- } );
1572
- $(self.legend.list).disableSelection();
1573
- });
1574
-
1575
- //hack to make jquery-ui sortable behave
1576
- this.graph.onUpdate( function() {
1577
- var h = window.getComputedStyle(self.legend.element).height;
1578
- self.legend.element.style.height = h;
1579
- } );
1580
- };
1581
- Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Toggle');
1582
-
1583
- Rickshaw.Graph.Behavior.Series.Toggle = function(args) {
1584
-
1585
- this.graph = args.graph;
1586
- this.legend = args.legend;
1587
-
1588
- var self = this;
1589
-
1590
- this.addAnchor = function(line) {
1591
- var anchor = document.createElement('a');
1592
- anchor.innerHTML = '&#10004;';
1593
- anchor.classList.add('action');
1594
- line.element.insertBefore(anchor, line.element.firstChild);
1595
-
1596
- anchor.onclick = function(e) {
1597
- if (line.series.disabled) {
1598
- line.series.enable();
1599
- line.element.classList.remove('disabled');
1600
- } else {
1601
- line.series.disable();
1602
- line.element.classList.add('disabled');
1603
- }
1604
- }
1605
-
1606
- var label = line.element.getElementsByTagName('span')[0];
1607
- label.onclick = function(e){
1608
-
1609
- var disableAllOtherLines = line.series.disabled;
1610
- if ( ! disableAllOtherLines ) {
1611
- for ( var i = 0; i < self.legend.lines.length; i++ ) {
1612
- var l = self.legend.lines[i];
1613
- if ( line.series === l.series ) {
1614
- // noop
1615
- } else if ( l.series.disabled ) {
1616
- // noop
1617
- } else {
1618
- disableAllOtherLines = true;
1619
- break;
1620
- }
1621
- }
1622
- }
1623
-
1624
- // show all or none
1625
- if ( disableAllOtherLines ) {
1626
-
1627
- // these must happen first or else we try ( and probably fail ) to make a no line graph
1628
- line.series.enable();
1629
- line.element.classList.remove('disabled');
1630
-
1631
- self.legend.lines.forEach(function(l){
1632
- if ( line.series === l.series ) {
1633
- // noop
1634
- } else {
1635
- l.series.disable();
1636
- l.element.classList.add('disabled');
1637
- }
1638
- });
1639
-
1640
- } else {
1641
-
1642
- self.legend.lines.forEach(function(l){
1643
- l.series.enable();
1644
- l.element.classList.remove('disabled');
1645
- });
1646
-
1647
- }
1648
-
1649
- };
1650
-
1651
- };
1652
-
1653
- if (this.legend) {
1654
-
1655
- $(this.legend.list).sortable( {
1656
- start: function(event, ui) {
1657
- ui.item.bind('no.onclick',
1658
- function(event) {
1659
- event.preventDefault();
1660
- }
1661
- );
1662
- },
1663
- stop: function(event, ui) {
1664
- setTimeout(function(){
1665
- ui.item.unbind('no.onclick');
1666
- }, 250);
1667
- }
1668
- })
1669
-
1670
- this.legend.lines.forEach( function(l) {
1671
- self.addAnchor(l);
1672
- } );
1673
- }
1674
-
1675
- this._addBehavior = function() {
1676
-
1677
- this.graph.series.forEach( function(s) {
1678
-
1679
- s.disable = function() {
1680
-
1681
- if (self.graph.series.length <= 1) {
1682
- throw('only one series left');
1683
- }
1684
-
1685
- s.disabled = true;
1686
- self.graph.update();
1687
- };
1688
-
1689
- s.enable = function() {
1690
- s.disabled = false;
1691
- self.graph.update();
1692
- };
1693
- } );
1694
- };
1695
- this._addBehavior();
1696
-
1697
- this.updateBehaviour = function () { this._addBehavior() };
1698
-
1699
- };
1700
- Rickshaw.namespace('Rickshaw.Graph.HoverDetail');
1701
-
1702
- Rickshaw.Graph.HoverDetail = Rickshaw.Class.create({
1703
-
1704
- initialize: function(args) {
1705
-
1706
- var graph = this.graph = args.graph;
1707
-
1708
- this.xFormatter = args.xFormatter || function(x) {
1709
- return new Date( x * 1000 ).toUTCString();
1710
- };
1711
-
1712
- this.yFormatter = args.yFormatter || function(y) {
1713
- return y === null ? y : y.toFixed(2);
1714
- };
1715
-
1716
- var element = this.element = document.createElement('div');
1717
- element.className = 'detail';
1718
-
1719
- this.visible = true;
1720
- graph.element.appendChild(element);
1721
-
1722
- this.lastEvent = null;
1723
- this._addListeners();
1724
-
1725
- this.onShow = args.onShow;
1726
- this.onHide = args.onHide;
1727
- this.onRender = args.onRender;
1728
-
1729
- this.formatter = args.formatter || this.formatter;
1730
-
1731
- },
1732
-
1733
- formatter: function(series, x, y, formattedX, formattedY, d) {
1734
- return series.name + ':&nbsp;' + formattedY;
1735
- },
1736
-
1737
- update: function(e) {
1738
-
1739
- e = e || this.lastEvent;
1740
- if (!e) return;
1741
- this.lastEvent = e;
1742
-
1743
- if (!e.target.nodeName.match(/^(path|svg|rect)$/)) return;
1744
-
1745
- var graph = this.graph;
1746
-
1747
- var eventX = e.offsetX || e.layerX;
1748
- var eventY = e.offsetY || e.layerY;
1749
-
1750
- var j = 0;
1751
- var points = [];
1752
- var nearestPoint;
1753
-
1754
- this.graph.series.active().forEach( function(series) {
1755
-
1756
- var data = this.graph.stackedData[j++];
1757
-
1758
- var domainX = graph.x.invert(eventX);
1759
-
1760
- var domainIndexScale = d3.scale.linear()
1761
- .domain([data[0].x, data.slice(-1)[0].x])
1762
- .range([0, data.length]);
1763
-
1764
- var approximateIndex = Math.floor(domainIndexScale(domainX));
1765
- var dataIndex = Math.min(approximateIndex || 0, data.length - 1);
1766
-
1767
- for (var i = approximateIndex; i < data.length - 1;) {
1768
-
1769
- if (!data[i] || !data[i + 1]) break;
1770
- if (data[i].x <= domainX && data[i + 1].x > domainX) { dataIndex = i; break }
1771
-
1772
- if (data[i + 1].x <= domainX) { i++ } else { i-- }
1773
- }
1774
-
1775
- var value = data[dataIndex];
1776
-
1777
- var distance = Math.sqrt(
1778
- Math.pow(Math.abs(graph.x(value.x) - eventX), 2) +
1779
- Math.pow(Math.abs(graph.y(value.y + value.y0) - eventY), 2)
1780
- );
1781
-
1782
- var xFormatter = series.xFormatter || this.xFormatter;
1783
- var yFormatter = series.yFormatter || this.yFormatter;
1784
-
1785
- var point = {
1786
- formattedXValue: xFormatter(value.x),
1787
- formattedYValue: yFormatter(value.y),
1788
- series: series,
1789
- value: value,
1790
- distance: distance,
1791
- order: j,
1792
- name: series.name
1793
- };
1794
-
1795
- if (!nearestPoint || distance < nearestPoint.distance) {
1796
- nearestPoint = point;
1797
- }
1798
-
1799
- points.push(point);
1800
-
1801
- }, this );
1802
-
1803
-
1804
- nearestPoint.active = true;
1805
-
1806
- var domainX = nearestPoint.value.x;
1807
- var formattedXValue = nearestPoint.formattedXValue;
1808
-
1809
- this.element.innerHTML = '';
1810
- this.element.style.left = graph.x(domainX) + 'px';
1811
-
1812
- this.visible && this.render( {
1813
- points: points,
1814
- detail: points, // for backwards compatibility
1815
- mouseX: eventX,
1816
- mouseY: eventY,
1817
- formattedXValue: formattedXValue,
1818
- domainX: domainX
1819
- } );
1820
- },
1821
-
1822
- hide: function() {
1823
- this.visible = false;
1824
- this.element.classList.add('inactive');
1825
-
1826
- if (typeof this.onHide == 'function') {
1827
- this.onHide();
1828
- }
1829
- },
1830
-
1831
- show: function() {
1832
- this.visible = true;
1833
- this.element.classList.remove('inactive');
1834
-
1835
- if (typeof this.onShow == 'function') {
1836
- this.onShow();
1837
- }
1838
- },
1839
-
1840
- render: function(args) {
1841
-
1842
- var graph = this.graph;
1843
- var points = args.points;
1844
- var point = points.filter( function(p) { return p.active } ).shift();
1845
-
1846
- if (point.value.y === null) return;
1847
-
1848
- var formattedXValue = this.xFormatter(point.value.x);
1849
- var formattedYValue = this.yFormatter(point.value.y);
1850
-
1851
- this.element.innerHTML = '';
1852
- this.element.style.left = graph.x(point.value.x) + 'px';
1853
-
1854
- var xLabel = document.createElement('div');
1855
-
1856
- xLabel.className = 'x_label';
1857
- xLabel.innerHTML = formattedXValue;
1858
- this.element.appendChild(xLabel);
1859
-
1860
- var item = document.createElement('div');
1861
-
1862
- item.className = 'item';
1863
- item.innerHTML = this.formatter(point.series, point.value.x, point.value.y, formattedXValue, formattedYValue, point);
1864
- item.style.top = this.graph.y(point.value.y0 + point.value.y) + 'px';
1865
-
1866
- this.element.appendChild(item);
1867
-
1868
- var dot = document.createElement('div');
1869
-
1870
- dot.className = 'dot';
1871
- dot.style.top = item.style.top;
1872
- dot.style.borderColor = point.series.color;
1873
-
1874
- this.element.appendChild(dot);
1875
-
1876
- if (point.active) {
1877
- item.className = 'item active';
1878
- dot.className = 'dot active';
1879
- }
1880
-
1881
- this.show();
1882
-
1883
- if (typeof this.onRender == 'function') {
1884
- this.onRender(args);
1885
- }
1886
- },
1887
-
1888
- _addListeners: function() {
1889
-
1890
- this.graph.element.addEventListener(
1891
- 'mousemove',
1892
- function(e) {
1893
- this.visible = true;
1894
- this.update(e)
1895
- }.bind(this),
1896
- false
1897
- );
1898
-
1899
- this.graph.onUpdate( function() { this.update() }.bind(this) );
1900
-
1901
- this.graph.element.addEventListener(
1902
- 'mouseout',
1903
- function(e) {
1904
- if (e.relatedTarget && !(e.relatedTarget.compareDocumentPosition(this.graph.element) & Node.DOCUMENT_POSITION_CONTAINS)) {
1905
- this.hide();
1906
- }
1907
- }.bind(this),
1908
- false
1909
- );
1910
- }
1911
- });
1912
-
1913
- Rickshaw.namespace('Rickshaw.Graph.JSONP');
1914
-
1915
- Rickshaw.Graph.JSONP = Rickshaw.Class.create( Rickshaw.Graph.Ajax, {
1916
-
1917
- request: function() {
1918
-
1919
- $.ajax( {
1920
- url: this.dataURL,
1921
- dataType: 'jsonp',
1922
- success: this.success.bind(this),
1923
- error: this.error.bind(this)
1924
- } );
1925
- }
1926
- } );
1927
- Rickshaw.namespace('Rickshaw.Graph.Legend');
1928
-
1929
- Rickshaw.Graph.Legend = function(args) {
1930
-
1931
- var element = this.element = args.element;
1932
- var graph = this.graph = args.graph;
1933
-
1934
- var self = this;
1935
-
1936
- element.classList.add('rickshaw_legend');
1937
-
1938
- var list = this.list = document.createElement('ul');
1939
- element.appendChild(list);
1940
-
1941
- var series = graph.series
1942
- .map( function(s) { return s } )
1943
-
1944
- if (!args.naturalOrder) {
1945
- series = series.reverse();
1946
- }
1947
-
1948
- this.lines = [];
1949
-
1950
- this.addLine = function (series) {
1951
- var line = document.createElement('li');
1952
- line.className = 'line';
1953
-
1954
- var swatch = document.createElement('div');
1955
- swatch.className = 'swatch';
1956
- swatch.style.backgroundColor = series.color;
1957
-
1958
- line.appendChild(swatch);
1959
-
1960
- var label = document.createElement('span');
1961
- label.className = 'label';
1962
- label.innerHTML = series.name;
1963
-
1964
- line.appendChild(label);
1965
- list.appendChild(line);
1966
-
1967
- line.series = series;
1968
-
1969
- if (series.noLegend) {
1970
- line.style.display = 'none';
1971
- }
1972
-
1973
- var _line = { element: line, series: series };
1974
- if (self.shelving) {
1975
- self.shelving.addAnchor(_line);
1976
- self.shelving.updateBehaviour();
1977
- }
1978
- if (self.highlighter) {
1979
- self.highlighter.addHighlightEvents(_line);
1980
- }
1981
- self.lines.push(_line);
1982
- };
1983
-
1984
- series.forEach( function(s) {
1985
- self.addLine(s);
1986
- } );
1987
-
1988
- graph.onUpdate( function() {} );
1989
- };
1990
- Rickshaw.namespace('Rickshaw.Graph.RangeSlider');
1991
-
1992
- Rickshaw.Graph.RangeSlider = function(args) {
1993
-
1994
- var element = this.element = args.element;
1995
- var graph = this.graph = args.graph;
1996
-
1997
- $( function() {
1998
- $(element).slider( {
1999
-
2000
- range: true,
2001
- min: graph.dataDomain()[0],
2002
- max: graph.dataDomain()[1],
2003
- values: [
2004
- graph.dataDomain()[0],
2005
- graph.dataDomain()[1]
2006
- ],
2007
- slide: function( event, ui ) {
2008
-
2009
- graph.window.xMin = ui.values[0];
2010
- graph.window.xMax = ui.values[1];
2011
- graph.update();
2012
-
2013
- // if we're at an extreme, stick there
2014
- if (graph.dataDomain()[0] == ui.values[0]) {
2015
- graph.window.xMin = undefined;
2016
- }
2017
- if (graph.dataDomain()[1] == ui.values[1]) {
2018
- graph.window.xMax = undefined;
2019
- }
2020
- }
2021
- } );
2022
- } );
2023
-
2024
- element[0].style.width = graph.width + 'px';
2025
-
2026
- graph.onUpdate( function() {
2027
-
2028
- var values = $(element).slider('option', 'values');
2029
-
2030
- $(element).slider('option', 'min', graph.dataDomain()[0]);
2031
- $(element).slider('option', 'max', graph.dataDomain()[1]);
2032
-
2033
- if (graph.window.xMin == undefined) {
2034
- values[0] = graph.dataDomain()[0];
2035
- }
2036
- if (graph.window.xMax == undefined) {
2037
- values[1] = graph.dataDomain()[1];
2038
- }
2039
-
2040
- $(element).slider('option', 'values', values);
2041
-
2042
- } );
2043
- };
2044
-
2045
- Rickshaw.namespace("Rickshaw.Graph.Renderer");
2046
-
2047
- Rickshaw.Graph.Renderer = Rickshaw.Class.create( {
2048
-
2049
- initialize: function(args) {
2050
- this.graph = args.graph;
2051
- this.tension = args.tension || this.tension;
2052
- this.graph.unstacker = this.graph.unstacker || new Rickshaw.Graph.Unstacker( { graph: this.graph } );
2053
- this.configure(args);
2054
- },
2055
-
2056
- seriesPathFactory: function() {
2057
- //implement in subclass
2058
- },
2059
-
2060
- seriesStrokeFactory: function() {
2061
- // implement in subclass
2062
- },
2063
-
2064
- defaults: function() {
2065
- return {
2066
- tension: 0.8,
2067
- strokeWidth: 2,
2068
- unstack: true,
2069
- padding: { top: 0.01, right: 0, bottom: 0.01, left: 0 },
2070
- stroke: false,
2071
- fill: false
2072
- };
2073
- },
2074
-
2075
- domain: function() {
2076
-
2077
- var values = { xMin: [], xMax: [], y: [] };
2078
-
2079
- var stackedData = this.graph.stackedData || this.graph.stackData();
2080
- var firstPoint = stackedData[0][0];
2081
-
2082
- var xMin = firstPoint.x;
2083
- var xMax = firstPoint.x
2084
-
2085
- var yMin = firstPoint.y + firstPoint.y0;
2086
- var yMax = firstPoint.y + firstPoint.y0;
2087
-
2088
- stackedData.forEach( function(series) {
2089
-
2090
- series.forEach( function(d) {
2091
-
2092
- var y = d.y + d.y0;
2093
-
2094
- if (y < yMin) yMin = y;
2095
- if (y > yMax) yMax = y;
2096
- } );
2097
-
2098
- if (series[0].x < xMin) xMin = series[0].x;
2099
- if (series[series.length - 1].x > xMax) xMax = series[series.length - 1].x;
2100
- } );
2101
-
2102
- xMin -= (xMax - xMin) * this.padding.left;
2103
- xMax += (xMax - xMin) * this.padding.right;
2104
-
2105
- yMin = this.graph.min === 'auto' ? yMin : this.graph.min || 0;
2106
- yMax = this.graph.max || yMax;
2107
-
2108
- if (this.graph.min === 'auto' || yMin < 0) {
2109
- yMin -= (yMax - yMin) * this.padding.bottom;
2110
- }
2111
-
2112
- if (this.graph.max === undefined) {
2113
- yMax += (yMax - yMin) * this.padding.top;
2114
- }
2115
-
2116
- return { x: [xMin, xMax], y: [yMin, yMax] };
2117
- },
2118
-
2119
- render: function() {
2120
-
2121
- var graph = this.graph;
2122
-
2123
- graph.vis.selectAll('*').remove();
2124
-
2125
- var nodes = graph.vis.selectAll("path")
2126
- .data(this.graph.stackedData)
2127
- .enter().append("svg:path")
2128
- .attr("d", this.seriesPathFactory());
2129
-
2130
- var i = 0;
2131
- graph.series.forEach( function(series) {
2132
- if (series.disabled) return;
2133
- series.path = nodes[0][i++];
2134
- this._styleSeries(series);
2135
- }, this );
2136
- },
2137
-
2138
- _styleSeries: function(series) {
2139
-
2140
- var fill = this.fill ? series.color : 'none';
2141
- var stroke = this.stroke ? series.color : 'none';
2142
-
2143
- series.path.setAttribute('fill', fill);
2144
- series.path.setAttribute('stroke', stroke);
2145
- series.path.setAttribute('stroke-width', this.strokeWidth);
2146
- series.path.setAttribute('class', series.className);
2147
- },
2148
-
2149
- configure: function(args) {
2150
-
2151
- args = args || {};
2152
-
2153
- Rickshaw.keys(this.defaults()).forEach( function(key) {
2154
-
2155
- if (!args.hasOwnProperty(key)) {
2156
- this[key] = this[key] || this.graph[key] || this.defaults()[key];
2157
- return;
2158
- }
2159
-
2160
- if (typeof this.defaults()[key] == 'object') {
2161
-
2162
- Rickshaw.keys(this.defaults()[key]).forEach( function(k) {
2163
-
2164
- this[key][k] =
2165
- args[key][k] !== undefined ? args[key][k] :
2166
- this[key][k] !== undefined ? this[key][k] :
2167
- this.defaults()[key][k];
2168
- }, this );
2169
-
2170
- } else {
2171
- this[key] =
2172
- args[key] !== undefined ? args[key] :
2173
- this[key] !== undefined ? this[key] :
2174
- this.graph[key] !== undefined ? this.graph[key] :
2175
- this.defaults()[key];
2176
- }
2177
-
2178
- }, this );
2179
- },
2180
-
2181
- setStrokeWidth: function(strokeWidth) {
2182
- if (strokeWidth !== undefined) {
2183
- this.strokeWidth = strokeWidth;
2184
- }
2185
- },
2186
-
2187
- setTension: function(tension) {
2188
- if (tension !== undefined) {
2189
- this.tension = tension;
2190
- }
2191
- }
2192
- } );
2193
-
2194
- Rickshaw.namespace('Rickshaw.Graph.Renderer.Line');
2195
-
2196
- Rickshaw.Graph.Renderer.Line = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
2197
-
2198
- name: 'line',
2199
-
2200
- defaults: function($super) {
2201
-
2202
- return Rickshaw.extend( $super(), {
2203
- unstack: true,
2204
- fill: false,
2205
- stroke: true
2206
- } );
2207
- },
2208
-
2209
- seriesPathFactory: function() {
2210
-
2211
- var graph = this.graph;
2212
-
2213
- var factory = d3.svg.line()
2214
- .x( function(d) { return graph.x(d.x) } )
2215
- .y( function(d) { return graph.y(d.y) } )
2216
- .interpolate(this.graph.interpolation).tension(this.tension)
2217
-
2218
- factory.defined && factory.defined( function(d) { return d.y !== null } );
2219
- return factory;
2220
- }
2221
- } );
2222
-
2223
- Rickshaw.namespace('Rickshaw.Graph.Renderer.Stack');
2224
-
2225
- Rickshaw.Graph.Renderer.Stack = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
2226
-
2227
- name: 'stack',
2228
-
2229
- defaults: function($super) {
2230
-
2231
- return Rickshaw.extend( $super(), {
2232
- fill: true,
2233
- stroke: false,
2234
- unstack: false
2235
- } );
2236
- },
2237
-
2238
- seriesPathFactory: function() {
2239
-
2240
- var graph = this.graph;
2241
-
2242
- var factory = d3.svg.area()
2243
- .x( function(d) { return graph.x(d.x) } )
2244
- .y0( function(d) { return graph.y(d.y0) } )
2245
- .y1( function(d) { return graph.y(d.y + d.y0) } )
2246
- .interpolate(this.graph.interpolation).tension(this.tension);
2247
-
2248
- factory.defined && factory.defined( function(d) { return d.y !== null } );
2249
- return factory;
2250
- }
2251
- } );
2252
-
2253
- Rickshaw.namespace('Rickshaw.Graph.Renderer.Bar');
2254
-
2255
- Rickshaw.Graph.Renderer.Bar = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
2256
-
2257
- name: 'bar',
2258
-
2259
- defaults: function($super) {
2260
-
2261
- var defaults = Rickshaw.extend( $super(), {
2262
- gapSize: 0.05,
2263
- unstack: false
2264
- } );
2265
-
2266
- delete defaults.tension;
2267
- return defaults;
2268
- },
2269
-
2270
- initialize: function($super, args) {
2271
- args = args || {};
2272
- this.gapSize = args.gapSize || this.gapSize;
2273
- $super(args);
2274
- },
2275
-
2276
- domain: function($super) {
2277
-
2278
- var domain = $super();
2279
-
2280
- var frequentInterval = this._frequentInterval();
2281
- domain.x[1] += parseInt(frequentInterval.magnitude);
2282
-
2283
- return domain;
2284
- },
2285
-
2286
- barWidth: function() {
2287
-
2288
- var stackedData = this.graph.stackedData || this.graph.stackData();
2289
- var data = stackedData.slice(-1).shift();
2290
-
2291
- var frequentInterval = this._frequentInterval();
2292
- var barWidth = this.graph.x(data[0].x + frequentInterval.magnitude * (1 - this.gapSize));
2293
-
2294
- return barWidth;
2295
- },
2296
-
2297
- render: function() {
2298
-
2299
- var graph = this.graph;
2300
-
2301
- graph.vis.selectAll('*').remove();
2302
-
2303
- var barWidth = this.barWidth();
2304
- var barXOffset = 0;
2305
-
2306
- var activeSeriesCount = graph.series.filter( function(s) { return !s.disabled; } ).length;
2307
- var seriesBarWidth = this.unstack ? barWidth / activeSeriesCount : barWidth;
2308
-
2309
- var transform = function(d) {
2310
- // add a matrix transform for negative values
2311
- var matrix = [ 1, 0, 0, (d.y < 0 ? -1 : 1), 0, (d.y < 0 ? graph.y.magnitude(Math.abs(d.y)) * 2 : 0) ];
2312
- return "matrix(" + matrix.join(',') + ")";
2313
- };
2314
-
2315
- graph.series.forEach( function(series) {
2316
-
2317
- if (series.disabled) return;
2318
-
2319
- var nodes = graph.vis.selectAll("path")
2320
- .data(series.stack.filter( function(d) { return d.y !== null } ))
2321
- .enter().append("svg:rect")
2322
- .attr("x", function(d) { return graph.x(d.x) + barXOffset })
2323
- .attr("y", function(d) { return (graph.y(d.y0 + Math.abs(d.y))) * (d.y < 0 ? -1 : 1 ) })
2324
- .attr("width", seriesBarWidth)
2325
- .attr("height", function(d) { return graph.y.magnitude(Math.abs(d.y)) })
2326
- .attr("transform", transform);
2327
-
2328
- Array.prototype.forEach.call(nodes[0], function(n) {
2329
- n.setAttribute('fill', series.color);
2330
- } );
2331
-
2332
- if (this.unstack) barXOffset += seriesBarWidth;
2333
-
2334
- }, this );
2335
- },
2336
-
2337
- _frequentInterval: function() {
2338
-
2339
- var stackedData = this.graph.stackedData || this.graph.stackData();
2340
- var data = stackedData.slice(-1).shift();
2341
-
2342
- var intervalCounts = {};
2343
-
2344
- for (var i = 0; i < data.length - 1; i++) {
2345
- var interval = data[i + 1].x - data[i].x;
2346
- intervalCounts[interval] = intervalCounts[interval] || 0;
2347
- intervalCounts[interval]++;
2348
- }
2349
-
2350
- var frequentInterval = { count: 0 };
2351
-
2352
- Rickshaw.keys(intervalCounts).forEach( function(i) {
2353
- if (frequentInterval.count < intervalCounts[i]) {
2354
-
2355
- frequentInterval = {
2356
- count: intervalCounts[i],
2357
- magnitude: i
2358
- };
2359
- }
2360
- } );
2361
-
2362
- this._frequentInterval = function() { return frequentInterval };
2363
-
2364
- return frequentInterval;
2365
- }
2366
- } );
2367
-
2368
- Rickshaw.namespace('Rickshaw.Graph.Renderer.Area');
2369
-
2370
- Rickshaw.Graph.Renderer.Area = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
2371
-
2372
- name: 'area',
2373
-
2374
- defaults: function($super) {
2375
-
2376
- return Rickshaw.extend( $super(), {
2377
- unstack: false,
2378
- fill: false,
2379
- stroke: false
2380
- } );
2381
- },
2382
-
2383
- seriesPathFactory: function() {
2384
-
2385
- var graph = this.graph;
2386
-
2387
- var factory = d3.svg.area()
2388
- .x( function(d) { return graph.x(d.x) } )
2389
- .y0( function(d) { return graph.y(d.y0) } )
2390
- .y1( function(d) { return graph.y(d.y + d.y0) } )
2391
- .interpolate(graph.interpolation).tension(this.tension)
2392
-
2393
- factory.defined && factory.defined( function(d) { return d.y !== null } );
2394
- return factory;
2395
- },
2396
-
2397
- seriesStrokeFactory: function() {
2398
-
2399
- var graph = this.graph;
2400
-
2401
- var factory = d3.svg.line()
2402
- .x( function(d) { return graph.x(d.x) } )
2403
- .y( function(d) { return graph.y(d.y + d.y0) } )
2404
- .interpolate(graph.interpolation).tension(this.tension)
2405
-
2406
- factory.defined && factory.defined( function(d) { return d.y !== null } );
2407
- return factory;
2408
- },
2409
-
2410
- render: function() {
2411
-
2412
- var graph = this.graph;
2413
-
2414
- graph.vis.selectAll('*').remove();
2415
-
2416
- // insert or stacked areas so strokes lay on top of areas
2417
- var method = this.unstack ? 'append' : 'insert';
2418
-
2419
- var nodes = graph.vis.selectAll("path")
2420
- .data(this.graph.stackedData)
2421
- .enter()[method]("svg:g", 'g');
2422
-
2423
- nodes.append("svg:path")
2424
- .attr("d", this.seriesPathFactory())
2425
- .attr("class", 'area');
2426
-
2427
- if (this.stroke) {
2428
- nodes.append("svg:path")
2429
- .attr("d", this.seriesStrokeFactory())
2430
- .attr("class", 'line');
2431
- }
2432
-
2433
- var i = 0;
2434
- graph.series.forEach( function(series) {
2435
- if (series.disabled) return;
2436
- series.path = nodes[0][i++];
2437
- this._styleSeries(series);
2438
- }, this );
2439
- },
2440
-
2441
- _styleSeries: function(series) {
2442
-
2443
- if (!series.path) return;
2444
-
2445
- d3.select(series.path).select('.area')
2446
- .attr('fill', series.color);
2447
-
2448
- if (this.stroke) {
2449
- d3.select(series.path).select('.line')
2450
- .attr('fill', 'none')
2451
- .attr('stroke', series.stroke || d3.interpolateRgb(series.color, 'black')(0.125))
2452
- .attr('stroke-width', this.strokeWidth);
2453
- }
2454
-
2455
- if (series.className) {
2456
- series.path.setAttribute('class', series.className);
2457
- }
2458
- }
2459
- } );
2460
-
2461
- Rickshaw.namespace('Rickshaw.Graph.Renderer.ScatterPlot');
2462
-
2463
- Rickshaw.Graph.Renderer.ScatterPlot = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
2464
-
2465
- name: 'scatterplot',
2466
-
2467
- defaults: function($super) {
2468
-
2469
- return Rickshaw.extend( $super(), {
2470
- unstack: true,
2471
- fill: true,
2472
- stroke: false,
2473
- padding:{ top: 0.01, right: 0.01, bottom: 0.01, left: 0.01 },
2474
- dotSize: 4
2475
- } );
2476
- },
2477
-
2478
- initialize: function($super, args) {
2479
- $super(args);
2480
- },
2481
-
2482
- render: function() {
2483
-
2484
- var graph = this.graph;
2485
-
2486
- graph.vis.selectAll('*').remove();
2487
-
2488
- graph.series.forEach( function(series) {
2489
-
2490
- if (series.disabled) return;
2491
-
2492
- var nodes = graph.vis.selectAll("path")
2493
- .data(series.stack.filter( function(d) { return d.y !== null } ))
2494
- .enter().append("svg:circle")
2495
- .attr("cx", function(d) { return graph.x(d.x) })
2496
- .attr("cy", function(d) { return graph.y(d.y) })
2497
- .attr("r", function(d) { return ("r" in d) ? d.r : graph.renderer.dotSize});
2498
-
2499
- Array.prototype.forEach.call(nodes[0], function(n) {
2500
- n.setAttribute('fill', series.color);
2501
- } );
2502
-
2503
- }, this );
2504
- }
2505
- } );
2506
- Rickshaw.namespace('Rickshaw.Graph.Smoother');
2507
-
2508
- Rickshaw.Graph.Smoother = function(args) {
2509
-
2510
- this.graph = args.graph;
2511
- this.element = args.element;
2512
-
2513
- var self = this;
2514
-
2515
- this.aggregationScale = 1;
2516
-
2517
- if (this.element) {
2518
-
2519
- $( function() {
2520
- $(self.element).slider( {
2521
- min: 1,
2522
- max: 100,
2523
- slide: function( event, ui ) {
2524
- self.setScale(ui.value);
2525
- self.graph.update();
2526
- }
2527
- } );
2528
- } );
2529
- }
2530
-
2531
- self.graph.stackData.hooks.data.push( {
2532
- name: 'smoother',
2533
- orderPosition: 50,
2534
- f: function(data) {
2535
-
2536
- if (self.aggregationScale == 1) return data;
2537
-
2538
- var aggregatedData = [];
2539
-
2540
- data.forEach( function(seriesData) {
2541
-
2542
- var aggregatedSeriesData = [];
2543
-
2544
- while (seriesData.length) {
2545
-
2546
- var avgX = 0, avgY = 0;
2547
- var slice = seriesData.splice(0, self.aggregationScale);
2548
-
2549
- slice.forEach( function(d) {
2550
- avgX += d.x / slice.length;
2551
- avgY += d.y / slice.length;
2552
- } );
2553
-
2554
- aggregatedSeriesData.push( { x: avgX, y: avgY } );
2555
- }
2556
-
2557
- aggregatedData.push(aggregatedSeriesData);
2558
- } );
2559
-
2560
- return aggregatedData;
2561
- }
2562
- } );
2563
-
2564
- this.setScale = function(scale) {
2565
-
2566
- if (scale < 1) {
2567
- throw "scale out of range: " + scale;
2568
- }
2569
-
2570
- this.aggregationScale = scale;
2571
- this.graph.update();
2572
- }
2573
- };
2574
-
2575
- Rickshaw.namespace('Rickshaw.Graph.Unstacker');
2576
-
2577
- Rickshaw.Graph.Unstacker = function(args) {
2578
-
2579
- this.graph = args.graph;
2580
- var self = this;
2581
-
2582
- this.graph.stackData.hooks.after.push( {
2583
- name: 'unstacker',
2584
- f: function(data) {
2585
-
2586
- if (!self.graph.renderer.unstack) return data;
2587
-
2588
- data.forEach( function(seriesData) {
2589
- seriesData.forEach( function(d) {
2590
- d.y0 = 0;
2591
- } );
2592
- } );
2593
-
2594
- return data;
2595
- }
2596
- } );
2597
- };
2598
-
2599
- Rickshaw.namespace('Rickshaw.Series');
2600
-
2601
- Rickshaw.Series = Rickshaw.Class.create( Array, {
2602
-
2603
- initialize: function (data, palette, options) {
2604
-
2605
- options = options || {}
2606
-
2607
- this.palette = new Rickshaw.Color.Palette(palette);
2608
-
2609
- this.timeBase = typeof(options.timeBase) === 'undefined' ?
2610
- Math.floor(new Date().getTime() / 1000) :
2611
- options.timeBase;
2612
-
2613
- var timeInterval = typeof(options.timeInterval) == 'undefined' ?
2614
- 1000 :
2615
- options.timeInterval;
2616
-
2617
- this.setTimeInterval(timeInterval);
2618
-
2619
- if (data && (typeof(data) == "object") && (data instanceof Array)) {
2620
- data.forEach( function(item) { this.addItem(item) }, this );
2621
- }
2622
- },
2623
-
2624
- addItem: function(item) {
2625
-
2626
- if (typeof(item.name) === 'undefined') {
2627
- throw('addItem() needs a name');
2628
- }
2629
-
2630
- item.color = (item.color || this.palette.color(item.name));
2631
- item.data = (item.data || []);
2632
-
2633
- // backfill, if necessary
2634
- if ((item.data.length == 0) && this.length && (this.getIndex() > 0)) {
2635
- this[0].data.forEach( function(plot) {
2636
- item.data.push({ x: plot.x, y: 0 });
2637
- } );
2638
- } else if (item.data.length == 0) {
2639
- item.data.push({ x: this.timeBase - (this.timeInterval || 0), y: 0 });
2640
- }
2641
-
2642
- this.push(item);
2643
-
2644
- if (this.legend) {
2645
- this.legend.addLine(this.itemByName(item.name));
2646
- }
2647
- },
2648
-
2649
- addData: function(data) {
2650
-
2651
- var index = this.getIndex();
2652
-
2653
- Rickshaw.keys(data).forEach( function(name) {
2654
- if (! this.itemByName(name)) {
2655
- this.addItem({ name: name });
2656
- }
2657
- }, this );
2658
-
2659
- this.forEach( function(item) {
2660
- item.data.push({
2661
- x: (index * this.timeInterval || 1) + this.timeBase,
2662
- y: (data[item.name] || 0)
2663
- });
2664
- }, this );
2665
- },
2666
-
2667
- getIndex: function () {
2668
- return (this[0] && this[0].data && this[0].data.length) ? this[0].data.length : 0;
2669
- },
2670
-
2671
- itemByName: function(name) {
2672
-
2673
- for (var i = 0; i < this.length; i++) {
2674
- if (this[i].name == name)
2675
- return this[i];
2676
- }
2677
- },
2678
-
2679
- setTimeInterval: function(iv) {
2680
- this.timeInterval = iv / 1000;
2681
- },
2682
-
2683
- setTimeBase: function (t) {
2684
- this.timeBase = t;
2685
- },
2686
-
2687
- dump: function() {
2688
-
2689
- var data = {
2690
- timeBase: this.timeBase,
2691
- timeInterval: this.timeInterval,
2692
- items: []
2693
- };
2694
-
2695
- this.forEach( function(item) {
2696
-
2697
- var newItem = {
2698
- color: item.color,
2699
- name: item.name,
2700
- data: []
2701
- };
2702
-
2703
- item.data.forEach( function(plot) {
2704
- newItem.data.push({ x: plot.x, y: plot.y });
2705
- } );
2706
-
2707
- data.items.push(newItem);
2708
- } );
2709
-
2710
- return data;
2711
- },
2712
-
2713
- load: function(data) {
2714
-
2715
- if (data.timeInterval) {
2716
- this.timeInterval = data.timeInterval;
2717
- }
2718
-
2719
- if (data.timeBase) {
2720
- this.timeBase = data.timeBase;
2721
- }
2722
-
2723
- if (data.items) {
2724
- data.items.forEach( function(item) {
2725
- this.push(item);
2726
- if (this.legend) {
2727
- this.legend.addLine(this.itemByName(item.name));
2728
- }
2729
-
2730
- }, this );
2731
- }
2732
- }
2733
- } );
2734
-
2735
- Rickshaw.Series.zeroFill = function(series) {
2736
- Rickshaw.Series.fill(series, 0);
2737
- };
2738
-
2739
- Rickshaw.Series.fill = function(series, fill) {
2740
-
2741
- var x;
2742
- var i = 0;
2743
-
2744
- var data = series.map( function(s) { return s.data } );
2745
-
2746
- while ( i < Math.max.apply(null, data.map( function(d) { return d.length } )) ) {
2747
-
2748
- x = Math.min.apply( null,
2749
- data
2750
- .filter(function(d) { return d[i] })
2751
- .map(function(d) { return d[i].x })
2752
- );
2753
-
2754
- data.forEach( function(d) {
2755
- if (!d[i] || d[i].x != x) {
2756
- d.splice(i, 0, { x: x, y: fill });
2757
- }
2758
- } );
2759
-
2760
- i++;
2761
- }
2762
- };
2763
-
2764
- Rickshaw.namespace('Rickshaw.Series.FixedDuration');
2765
-
2766
- Rickshaw.Series.FixedDuration = Rickshaw.Class.create(Rickshaw.Series, {
2767
-
2768
- initialize: function (data, palette, options) {
2769
-
2770
- var options = options || {}
2771
-
2772
- if (typeof(options.timeInterval) === 'undefined') {
2773
- throw new Error('FixedDuration series requires timeInterval');
2774
- }
2775
-
2776
- if (typeof(options.maxDataPoints) === 'undefined') {
2777
- throw new Error('FixedDuration series requires maxDataPoints');
2778
- }
2779
-
2780
- this.palette = new Rickshaw.Color.Palette(palette);
2781
- this.timeBase = typeof(options.timeBase) === 'undefined' ? Math.floor(new Date().getTime() / 1000) : options.timeBase;
2782
- this.setTimeInterval(options.timeInterval);
2783
-
2784
- if (this[0] && this[0].data && this[0].data.length) {
2785
- this.currentSize = this[0].data.length;
2786
- this.currentIndex = this[0].data.length;
2787
- } else {
2788
- this.currentSize = 0;
2789
- this.currentIndex = 0;
2790
- }
2791
-
2792
- this.maxDataPoints = options.maxDataPoints;
2793
-
2794
-
2795
- if (data && (typeof(data) == "object") && (data instanceof Array)) {
2796
- data.forEach( function (item) { this.addItem(item) }, this );
2797
- this.currentSize += 1;
2798
- this.currentIndex += 1;
2799
- }
2800
-
2801
- // reset timeBase for zero-filled values if needed
2802
- this.timeBase -= (this.maxDataPoints - this.currentSize) * this.timeInterval;
2803
-
2804
- // zero-fill up to maxDataPoints size if we don't have that much data yet
2805
- if ((typeof(this.maxDataPoints) !== 'undefined') && (this.currentSize < this.maxDataPoints)) {
2806
- for (var i = this.maxDataPoints - this.currentSize - 1; i > 0; i--) {
2807
- this.currentSize += 1;
2808
- this.currentIndex += 1;
2809
- this.forEach( function (item) {
2810
- item.data.unshift({ x: ((i-1) * this.timeInterval || 1) + this.timeBase, y: 0, i: i });
2811
- }, this );
2812
- }
2813
- }
2814
- },
2815
-
2816
- addData: function($super, data) {
2817
-
2818
- $super(data)
2819
-
2820
- this.currentSize += 1;
2821
- this.currentIndex += 1;
2822
-
2823
- if (this.maxDataPoints !== undefined) {
2824
- while (this.currentSize > this.maxDataPoints) {
2825
- this.dropData();
2826
- }
2827
- }
2828
- },
2829
-
2830
- dropData: function() {
2831
-
2832
- this.forEach(function(item) {
2833
- item.data.splice(0, 1);
2834
- } );
2835
-
2836
- this.currentSize -= 1;
2837
- },
2838
-
2839
- getIndex: function () {
2840
- return this.currentIndex;
2841
- }
2842
- } );