Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
21627 kshitij.so 1
(function() {
2
  var $, Morris, minutesSpecHelper, secondsSpecHelper,
3
    __slice = [].slice,
4
    __hasProp = {}.hasOwnProperty,
5
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
6
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
7
    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
8
 
9
  Morris = window.Morris = {};
10
 
11
  $ = jQuery;
12
 
13
  Morris.EventEmitter = (function() {
14
 
15
    function EventEmitter() {}
16
 
17
    EventEmitter.prototype.on = function(name, handler) {
18
      if (this.handlers == null) {
19
        this.handlers = {};
20
      }
21
      if (this.handlers[name] == null) {
22
        this.handlers[name] = [];
23
      }
24
      this.handlers[name].push(handler);
25
      return this;
26
    };
27
 
28
    EventEmitter.prototype.fire = function() {
29
      var args, handler, name, _i, _len, _ref, _results;
30
      name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
31
      if ((this.handlers != null) && (this.handlers[name] != null)) {
32
        _ref = this.handlers[name];
33
        _results = [];
34
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
35
          handler = _ref[_i];
36
          _results.push(handler.apply(null, args));
37
        }
38
        return _results;
39
      }
40
    };
41
 
42
    return EventEmitter;
43
 
44
  })();
45
 
46
  Morris.commas = function(num) {
47
    var absnum, intnum, ret, strabsnum;
48
    if (num != null) {
49
      ret = num < 0 ? "-" : "";
50
      absnum = Math.abs(num);
51
      intnum = Math.floor(absnum).toFixed(0);
52
      ret += intnum.replace(/(?=(?:\d{3})+$)(?!^)/g, ',');
53
      strabsnum = absnum.toString();
54
      if (strabsnum.length > intnum.length) {
55
        ret += strabsnum.slice(intnum.length);
56
      }
57
      return ret;
58
    } else {
59
      return '-';
60
    }
61
  };
62
 
63
  Morris.pad2 = function(number) {
64
    return (number < 10 ? '0' : '') + number;
65
  };
66
 
67
  Morris.Grid = (function(_super) {
68
 
69
    __extends(Grid, _super);
70
 
71
    function Grid(options) {
72
      var _this = this;
73
      if (typeof options.element === 'string') {
74
        this.el = $(document.getElementById(options.element));
75
      } else {
76
        this.el = $(options.element);
77
      }
78
      if (!(this.el != null) || this.el.length === 0) {
79
        throw new Error("Graph container element not found");
80
      }
81
      if (this.el.css('position') === 'static') {
82
        this.el.css('position', 'relative');
83
      }
84
      this.options = $.extend({}, this.gridDefaults, this.defaults || {}, options);
85
      if (typeof this.options.units === 'string') {
86
        this.options.postUnits = options.units;
87
      }
88
      this.raphael = new Raphael(this.el[0]);
89
      this.elementWidth = null;
90
      this.elementHeight = null;
91
      this.dirty = false;
92
      if (this.init) {
93
        this.init();
94
      }
95
      this.setData(this.options.data);
96
      this.el.bind('mousemove', function(evt) {
97
        var offset;
98
        offset = _this.el.offset();
99
        return _this.fire('hovermove', evt.pageX - offset.left, evt.pageY - offset.top);
100
      });
101
      this.el.bind('mouseout', function(evt) {
102
        return _this.fire('hoverout');
103
      });
104
      this.el.bind('touchstart touchmove touchend', function(evt) {
105
        var offset, touch;
106
        touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0];
107
        offset = _this.el.offset();
108
        _this.fire('hover', touch.pageX - offset.left, touch.pageY - offset.top);
109
        return touch;
110
      });
111
      this.el.bind('click', function(evt) {
112
        var offset;
113
        offset = _this.el.offset();
114
        return _this.fire('gridclick', evt.pageX - offset.left, evt.pageY - offset.top);
115
      });
116
      if (this.postInit) {
117
        this.postInit();
118
      }
119
    }
120
 
121
    Grid.prototype.gridDefaults = {
122
      dateFormat: null,
123
      axes: true,
124
      grid: true,
125
      gridLineColor: '#aaa',
126
      gridStrokeWidth: 0.5,
127
      gridTextColor: '#888',
128
      gridTextSize: 12,
129
      gridTextFamily: 'sans-serif',
130
      gridTextWeight: 'normal',
131
      hideHover: false,
132
      yLabelFormat: null,
133
      xLabelAngle: 0,
134
      numLines: 5,
135
      padding: 25,
136
      parseTime: true,
137
      postUnits: '',
138
      preUnits: '',
139
      ymax: 'auto',
140
      ymin: 'auto 0',
141
      goals: [],
142
      goalStrokeWidth: 1.0,
143
      goalLineColors: ['#666633', '#999966', '#cc6666', '#663333'],
144
      events: [],
145
      eventStrokeWidth: 1.0,
146
      eventLineColors: ['#005a04', '#ccffbb', '#3a5f0b', '#005502']
147
    };
148
 
149
    Grid.prototype.setData = function(data, redraw) {
150
      var e, idx, index, maxGoal, minGoal, ret, row, step, total, y, ykey, ymax, ymin, yval;
151
      if (redraw == null) {
152
        redraw = true;
153
      }
154
      this.options.data = data;
155
      if (!(data != null) || data.length === 0) {
156
        this.data = [];
157
        this.raphael.clear();
158
        if (this.hover != null) {
159
          this.hover.hide();
160
        }
161
        return;
162
      }
163
      ymax = this.cumulative ? 0 : null;
164
      ymin = this.cumulative ? 0 : null;
165
      if (this.options.goals.length > 0) {
166
        minGoal = Math.min.apply(null, this.options.goals);
167
        maxGoal = Math.max.apply(null, this.options.goals);
168
        ymin = ymin != null ? Math.min(ymin, minGoal) : minGoal;
169
        ymax = ymax != null ? Math.max(ymax, maxGoal) : maxGoal;
170
      }
171
      this.data = (function() {
172
        var _i, _len, _results;
173
        _results = [];
174
        for (index = _i = 0, _len = data.length; _i < _len; index = ++_i) {
175
          row = data[index];
176
          ret = {};
177
          ret.label = row[this.options.xkey];
178
          if (this.options.parseTime) {
179
            ret.x = Morris.parseDate(ret.label);
180
            if (this.options.dateFormat) {
181
              ret.label = this.options.dateFormat(ret.x);
182
            } else if (typeof ret.label === 'number') {
183
              ret.label = new Date(ret.label).toString();
184
            }
185
          } else {
186
            ret.x = index;
187
            if (this.options.xLabelFormat) {
188
              ret.label = this.options.xLabelFormat(ret);
189
            }
190
          }
191
          total = 0;
192
          ret.y = (function() {
193
            var _j, _len1, _ref, _results1;
194
            _ref = this.options.ykeys;
195
            _results1 = [];
196
            for (idx = _j = 0, _len1 = _ref.length; _j < _len1; idx = ++_j) {
197
              ykey = _ref[idx];
198
              yval = row[ykey];
199
              if (typeof yval === 'string') {
200
                yval = parseFloat(yval);
201
              }
202
              if ((yval != null) && typeof yval !== 'number') {
203
                yval = null;
204
              }
205
              if (yval != null) {
206
                if (this.cumulative) {
207
                  total += yval;
208
                } else {
209
                  if (ymax != null) {
210
                    ymax = Math.max(yval, ymax);
211
                    ymin = Math.min(yval, ymin);
212
                  } else {
213
                    ymax = ymin = yval;
214
                  }
215
                }
216
              }
217
              if (this.cumulative && (total != null)) {
218
                ymax = Math.max(total, ymax);
219
                ymin = Math.min(total, ymin);
220
              }
221
              _results1.push(yval);
222
            }
223
            return _results1;
224
          }).call(this);
225
          _results.push(ret);
226
        }
227
        return _results;
228
      }).call(this);
229
      if (this.options.parseTime) {
230
        this.data = this.data.sort(function(a, b) {
231
          return (a.x > b.x) - (b.x > a.x);
232
        });
233
      }
234
      this.xmin = this.data[0].x;
235
      this.xmax = this.data[this.data.length - 1].x;
236
      this.events = [];
237
      if (this.options.parseTime && this.options.events.length > 0) {
238
        this.events = (function() {
239
          var _i, _len, _ref, _results;
240
          _ref = this.options.events;
241
          _results = [];
242
          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
243
            e = _ref[_i];
244
            _results.push(Morris.parseDate(e));
245
          }
246
          return _results;
247
        }).call(this);
248
        this.xmax = Math.max(this.xmax, Math.max.apply(null, this.events));
249
        this.xmin = Math.min(this.xmin, Math.min.apply(null, this.events));
250
      }
251
      if (this.xmin === this.xmax) {
252
        this.xmin -= 1;
253
        this.xmax += 1;
254
      }
255
      this.ymin = this.yboundary('min', ymin);
256
      this.ymax = this.yboundary('max', ymax);
257
      if (this.ymin === this.ymax) {
258
        if (ymin) {
259
          this.ymin -= 1;
260
        }
261
        this.ymax += 1;
262
      }
263
      if (this.options.axes === true || this.options.grid === true) {
264
        if (this.options.ymax === this.gridDefaults.ymax && this.options.ymin === this.gridDefaults.ymin) {
265
          this.grid = this.autoGridLines(this.ymin, this.ymax, this.options.numLines);
266
          this.ymin = Math.min(this.ymin, this.grid[0]);
267
          this.ymax = Math.max(this.ymax, this.grid[this.grid.length - 1]);
268
        } else {
269
          step = (this.ymax - this.ymin) / (this.options.numLines - 1);
270
          this.grid = (function() {
271
            var _i, _ref, _ref1, _results;
272
            _results = [];
273
            for (y = _i = _ref = this.ymin, _ref1 = this.ymax; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; y = _i += step) {
274
              _results.push(y);
275
            }
276
            return _results;
277
          }).call(this);
278
        }
279
      }
280
      this.dirty = true;
281
      if (redraw) {
282
        return this.redraw();
283
      }
284
    };
285
 
286
    Grid.prototype.yboundary = function(boundaryType, currentValue) {
287
      var boundaryOption, suggestedValue;
288
      boundaryOption = this.options["y" + boundaryType];
289
      if (typeof boundaryOption === 'string') {
290
        if (boundaryOption.slice(0, 4) === 'auto') {
291
          if (boundaryOption.length > 5) {
292
            suggestedValue = parseInt(boundaryOption.slice(5), 10);
293
            if (currentValue == null) {
294
              return suggestedValue;
295
            }
296
            return Math[boundaryType](currentValue, suggestedValue);
297
          } else {
298
            if (currentValue != null) {
299
              return currentValue;
300
            } else {
301
              return 0;
302
            }
303
          }
304
        } else {
305
          return parseInt(boundaryOption, 10);
306
        }
307
      } else {
308
        return boundaryOption;
309
      }
310
    };
311
 
312
    Grid.prototype.autoGridLines = function(ymin, ymax, nlines) {
313
      var gmax, gmin, grid, smag, span, step, unit, y, ymag;
314
      span = ymax - ymin;
315
      ymag = Math.floor(Math.log(span) / Math.log(10));
316
      unit = Math.pow(10, ymag);
317
      gmin = Math.floor(ymin / unit) * unit;
318
      gmax = Math.ceil(ymax / unit) * unit;
319
      step = (gmax - gmin) / (nlines - 1);
320
      if (unit === 1 && step > 1 && Math.ceil(step) !== step) {
321
        step = Math.ceil(step);
322
        gmax = gmin + step * (nlines - 1);
323
      }
324
      if (gmin < 0 && gmax > 0) {
325
        gmin = Math.floor(ymin / step) * step;
326
        gmax = Math.ceil(ymax / step) * step;
327
      }
328
      if (step < 1) {
329
        smag = Math.floor(Math.log(step) / Math.log(10));
330
        grid = (function() {
331
          var _i, _results;
332
          _results = [];
333
          for (y = _i = gmin; gmin <= gmax ? _i <= gmax : _i >= gmax; y = _i += step) {
334
            _results.push(parseFloat(y.toFixed(1 - smag)));
335
          }
336
          return _results;
337
        })();
338
      } else {
339
        grid = (function() {
340
          var _i, _results;
341
          _results = [];
342
          for (y = _i = gmin; gmin <= gmax ? _i <= gmax : _i >= gmax; y = _i += step) {
343
            _results.push(y);
344
          }
345
          return _results;
346
        })();
347
      }
348
      return grid;
349
    };
350
 
351
    Grid.prototype._calc = function() {
352
      var bottomOffsets, gridLine, h, i, w, yLabelWidths;
353
      w = this.el.width();
354
      h = this.el.height();
355
      if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) {
356
        this.elementWidth = w;
357
        this.elementHeight = h;
358
        this.dirty = false;
359
        this.left = this.options.padding;
360
        this.right = this.elementWidth - this.options.padding;
361
        this.top = this.options.padding;
362
        this.bottom = this.elementHeight - this.options.padding;
363
        if (this.options.axes) {
364
          yLabelWidths = (function() {
365
            var _i, _len, _ref, _results;
366
            _ref = this.grid;
367
            _results = [];
368
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
369
              gridLine = _ref[_i];
370
              _results.push(this.measureText(this.yAxisFormat(gridLine)).width);
371
            }
372
            return _results;
373
          }).call(this);
374
          this.left += Math.max.apply(Math, yLabelWidths);
375
          bottomOffsets = (function() {
376
            var _i, _ref, _results;
377
            _results = [];
378
            for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
379
              _results.push(this.measureText(this.data[i].text, -this.options.xLabelAngle).height);
380
            }
381
            return _results;
382
          }).call(this);
383
          this.bottom -= Math.max.apply(Math, bottomOffsets);
384
        }
385
        this.width = Math.max(1, this.right - this.left);
386
        this.height = Math.max(1, this.bottom - this.top);
387
        this.dx = this.width / (this.xmax - this.xmin);
388
        this.dy = this.height / (this.ymax - this.ymin);
389
        if (this.calc) {
390
          return this.calc();
391
        }
392
      }
393
    };
394
 
395
    Grid.prototype.transY = function(y) {
396
      return this.bottom - (y - this.ymin) * this.dy;
397
    };
398
 
399
    Grid.prototype.transX = function(x) {
400
      if (this.data.length === 1) {
401
        return (this.left + this.right) / 2;
402
      } else {
403
        return this.left + (x - this.xmin) * this.dx;
404
      }
405
    };
406
 
407
    Grid.prototype.redraw = function() {
408
      this.raphael.clear();
409
      this._calc();
410
      this.drawGrid();
411
      this.drawGoals();
412
      this.drawEvents();
413
      if (this.draw) {
414
        return this.draw();
415
      }
416
    };
417
 
418
    Grid.prototype.measureText = function(text, angle) {
419
      var ret, tt;
420
      if (angle == null) {
421
        angle = 0;
422
      }
423
      tt = this.raphael.text(100, 100, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).rotate(angle);
424
      ret = tt.getBBox();
425
      tt.remove();
426
      return ret;
427
    };
428
 
429
    Grid.prototype.yAxisFormat = function(label) {
430
      return this.yLabelFormat(label);
431
    };
432
 
433
    Grid.prototype.yLabelFormat = function(label) {
434
      if (typeof this.options.yLabelFormat === 'function') {
435
        return this.options.yLabelFormat(label);
436
      } else {
437
        return "" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits;
438
      }
439
    };
440
 
441
    Grid.prototype.updateHover = function(x, y) {
442
      var hit, _ref;
443
      hit = this.hitTest(x, y);
444
      if (hit != null) {
445
        return (_ref = this.hover).update.apply(_ref, hit);
446
      }
447
    };
448
 
449
    Grid.prototype.drawGrid = function() {
450
      var lineY, y, _i, _len, _ref, _results;
451
      if (this.options.grid === false && this.options.axes === false) {
452
        return;
453
      }
454
      _ref = this.grid;
455
      _results = [];
456
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
457
        lineY = _ref[_i];
458
        y = this.transY(lineY);
459
        if (this.options.axes) {
460
          this.drawYAxisLabel(this.left - this.options.padding / 2, y, this.yAxisFormat(lineY));
461
        }
462
        if (this.options.grid) {
463
          _results.push(this.drawGridLine("M" + this.left + "," + y + "H" + (this.left + this.width)));
464
        } else {
465
          _results.push(void 0);
466
        }
467
      }
468
      return _results;
469
    };
470
 
471
    Grid.prototype.drawGoals = function() {
472
      var color, goal, i, _i, _len, _ref, _results;
473
      _ref = this.options.goals;
474
      _results = [];
475
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
476
        goal = _ref[i];
477
        color = this.options.goalLineColors[i % this.options.goalLineColors.length];
478
        _results.push(this.drawGoal(goal, color));
479
      }
480
      return _results;
481
    };
482
 
483
    Grid.prototype.drawEvents = function() {
484
      var color, event, i, _i, _len, _ref, _results;
485
      _ref = this.events;
486
      _results = [];
487
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
488
        event = _ref[i];
489
        color = this.options.eventLineColors[i % this.options.eventLineColors.length];
490
        _results.push(this.drawEvent(event, color));
491
      }
492
      return _results;
493
    };
494
 
495
    Grid.prototype.drawGoal = function(goal, color) {
496
      return this.raphael.path("M" + this.left + "," + (this.transY(goal)) + "H" + this.right).attr('stroke', color).attr('stroke-width', this.options.goalStrokeWidth);
497
    };
498
 
499
    Grid.prototype.drawEvent = function(event, color) {
500
      return this.raphael.path("M" + (this.transX(event)) + "," + this.bottom + "V" + this.top).attr('stroke', color).attr('stroke-width', this.options.eventStrokeWidth);
501
    };
502
 
503
    Grid.prototype.drawYAxisLabel = function(xPos, yPos, text) {
504
      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
505
    };
506
 
507
    Grid.prototype.drawGridLine = function(path) {
508
      return this.raphael.path(path).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);
509
    };
510
 
511
    return Grid;
512
 
513
  })(Morris.EventEmitter);
514
 
515
  Morris.parseDate = function(date) {
516
    var isecs, m, msecs, n, o, offsetmins, p, q, r, ret, secs;
517
    if (typeof date === 'number') {
518
      return date;
519
    }
520
    m = date.match(/^(\d+) Q(\d)$/);
521
    n = date.match(/^(\d+)-(\d+)$/);
522
    o = date.match(/^(\d+)-(\d+)-(\d+)$/);
523
    p = date.match(/^(\d+) W(\d+)$/);
524
    q = date.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/);
525
    r = date.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/);
526
    if (m) {
527
      return new Date(parseInt(m[1], 10), parseInt(m[2], 10) * 3 - 1, 1).getTime();
528
    } else if (n) {
529
      return new Date(parseInt(n[1], 10), parseInt(n[2], 10) - 1, 1).getTime();
530
    } else if (o) {
531
      return new Date(parseInt(o[1], 10), parseInt(o[2], 10) - 1, parseInt(o[3], 10)).getTime();
532
    } else if (p) {
533
      ret = new Date(parseInt(p[1], 10), 0, 1);
534
      if (ret.getDay() !== 4) {
535
        ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);
536
      }
537
      return ret.getTime() + parseInt(p[2], 10) * 604800000;
538
    } else if (q) {
539
      if (!q[6]) {
540
        return new Date(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10)).getTime();
541
      } else {
542
        offsetmins = 0;
543
        if (q[6] !== 'Z') {
544
          offsetmins = parseInt(q[8], 10) * 60 + parseInt(q[9], 10);
545
          if (q[7] === '+') {
546
            offsetmins = 0 - offsetmins;
547
          }
548
        }
549
        return Date.UTC(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10) + offsetmins);
550
      }
551
    } else if (r) {
552
      secs = parseFloat(r[6]);
553
      isecs = Math.floor(secs);
554
      msecs = Math.round((secs - isecs) * 1000);
555
      if (!r[8]) {
556
        return new Date(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10), isecs, msecs).getTime();
557
      } else {
558
        offsetmins = 0;
559
        if (r[8] !== 'Z') {
560
          offsetmins = parseInt(r[10], 10) * 60 + parseInt(r[11], 10);
561
          if (r[9] === '+') {
562
            offsetmins = 0 - offsetmins;
563
          }
564
        }
565
        return Date.UTC(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10) + offsetmins, isecs, msecs);
566
      }
567
    } else {
568
      return new Date(parseInt(date, 10), 0, 1).getTime();
569
    }
570
  };
571
 
572
  Morris.Hover = (function() {
573
 
574
    Hover.defaults = {
575
      "class": 'morris-hover morris-default-style'
576
    };
577
 
578
    function Hover(options) {
579
      if (options == null) {
580
        options = {};
581
      }
582
      this.options = $.extend({}, Morris.Hover.defaults, options);
583
      this.el = $("<div class='" + this.options["class"] + "'></div>");
584
      this.el.hide();
585
      this.options.parent.append(this.el);
586
    }
587
 
588
    Hover.prototype.update = function(html, x, y) {
589
      this.html(html);
590
      this.show();
591
      return this.moveTo(x, y);
592
    };
593
 
594
    Hover.prototype.html = function(content) {
595
      return this.el.html(content);
596
    };
597
 
598
    Hover.prototype.moveTo = function(x, y) {
599
      var hoverHeight, hoverWidth, left, parentHeight, parentWidth, top;
600
      parentWidth = this.options.parent.innerWidth();
601
      parentHeight = this.options.parent.innerHeight();
602
      hoverWidth = this.el.outerWidth();
603
      hoverHeight = this.el.outerHeight();
604
      left = Math.min(Math.max(0, x - hoverWidth / 2), parentWidth - hoverWidth);
605
      if (y != null) {
606
        top = y - hoverHeight - 10;
607
        if (top < 0) {
608
          top = y + 10;
609
          if (top + hoverHeight > parentHeight) {
610
            top = parentHeight / 2 - hoverHeight / 2;
611
          }
612
        }
613
      } else {
614
        top = parentHeight / 2 - hoverHeight / 2;
615
      }
616
      return this.el.css({
617
        left: left + "px",
618
        top: parseInt(top) + "px"
619
      });
620
    };
621
 
622
    Hover.prototype.show = function() {
623
      return this.el.show();
624
    };
625
 
626
    Hover.prototype.hide = function() {
627
      return this.el.hide();
628
    };
629
 
630
    return Hover;
631
 
632
  })();
633
 
634
  Morris.Line = (function(_super) {
635
 
636
    __extends(Line, _super);
637
 
638
    function Line(options) {
639
      this.hilight = __bind(this.hilight, this);
640
 
641
      this.onHoverOut = __bind(this.onHoverOut, this);
642
 
643
      this.onHoverMove = __bind(this.onHoverMove, this);
644
 
645
      this.onGridClick = __bind(this.onGridClick, this);
646
      if (!(this instanceof Morris.Line)) {
647
        return new Morris.Line(options);
648
      }
649
      Line.__super__.constructor.call(this, options);
650
    }
651
 
652
    Line.prototype.init = function() {
653
      this.pointGrow = Raphael.animation({
654
        r: this.options.pointSize + 3
655
      }, 25, 'linear');
656
      this.pointShrink = Raphael.animation({
657
        r: this.options.pointSize
658
      }, 25, 'linear');
659
      if (this.options.hideHover !== 'always') {
660
        this.hover = new Morris.Hover({
661
          parent: this.el
662
        });
663
        this.on('hovermove', this.onHoverMove);
664
        this.on('hoverout', this.onHoverOut);
665
        return this.on('gridclick', this.onGridClick);
666
      }
667
    };
668
 
669
    Line.prototype.defaults = {
670
      lineWidth: 3,
671
      pointSize: 4,
672
      lineColors: ['#0b62a4', '#7A92A3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],
673
      pointWidths: [1],
674
      pointStrokeColors: ['#ffffff'],
675
      pointFillColors: [],
676
      smooth: true,
677
      xLabels: 'auto',
678
      xLabelFormat: null,
679
      xLabelMargin: 24,
680
      continuousLine: true,
681
      hideHover: false
682
    };
683
 
684
    Line.prototype.calc = function() {
685
      this.calcPoints();
686
      return this.generatePaths();
687
    };
688
 
689
    Line.prototype.calcPoints = function() {
690
      var row, y, _i, _len, _ref, _results;
691
      _ref = this.data;
692
      _results = [];
693
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
694
        row = _ref[_i];
695
        row._x = this.transX(row.x);
696
        row._y = (function() {
697
          var _j, _len1, _ref1, _results1;
698
          _ref1 = row.y;
699
          _results1 = [];
700
          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
701
            y = _ref1[_j];
702
            if (y != null) {
703
              _results1.push(this.transY(y));
704
            } else {
705
              _results1.push(y);
706
            }
707
          }
708
          return _results1;
709
        }).call(this);
710
        _results.push(row._ymax = Math.min.apply(null, [this.bottom].concat((function() {
711
          var _j, _len1, _ref1, _results1;
712
          _ref1 = row._y;
713
          _results1 = [];
714
          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
715
            y = _ref1[_j];
716
            if (y != null) {
717
              _results1.push(y);
718
            }
719
          }
720
          return _results1;
721
        })())));
722
      }
723
      return _results;
724
    };
725
 
726
    Line.prototype.hitTest = function(x, y) {
727
      var index, r, _i, _len, _ref;
728
      if (this.data.length === 0) {
729
        return null;
730
      }
731
      _ref = this.data.slice(1);
732
      for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
733
        r = _ref[index];
734
        if (x < (r._x + this.data[index]._x) / 2) {
735
          break;
736
        }
737
      }
738
      return index;
739
    };
740
 
741
    Line.prototype.onGridClick = function(x, y) {
742
      var index;
743
      index = this.hitTest(x, y);
744
      return this.fire('click', index, this.options.data[index], x, y);
745
    };
746
 
747
    Line.prototype.onHoverMove = function(x, y) {
748
      var index;
749
      index = this.hitTest(x, y);
750
      return this.displayHoverForRow(index);
751
    };
752
 
753
    Line.prototype.onHoverOut = function() {
754
      if (this.options.hideHover !== false) {
755
        return this.displayHoverForRow(null);
756
      }
757
    };
758
 
759
    Line.prototype.displayHoverForRow = function(index) {
760
      var _ref;
761
      if (index != null) {
762
        (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));
763
        return this.hilight(index);
764
      } else {
765
        this.hover.hide();
766
        return this.hilight();
767
      }
768
    };
769
 
770
    Line.prototype.hoverContentForRow = function(index) {
771
      var content, j, row, y, _i, _len, _ref;
772
      row = this.data[index];
773
      content = "<div class='morris-hover-row-label'>" + row.label + "</div>";
774
      _ref = row.y;
775
      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {
776
        y = _ref[j];
777
        content += "<div class='morris-hover-point' style='color: " + (this.colorFor(row, j, 'label')) + "'>\n  " + this.options.labels[j] + ":\n  " + (this.yLabelFormat(y)) + "\n</div>";
778
      }
779
      if (typeof this.options.hoverCallback === 'function') {
780
        content = this.options.hoverCallback(index, this.options, content);
781
      }
782
      return [content, row._x, row._ymax];
783
    };
784
 
785
    Line.prototype.generatePaths = function() {
786
      var c, coords, i, r, smooth;
787
      return this.paths = (function() {
788
        var _i, _ref, _ref1, _results;
789
        _results = [];
790
        for (i = _i = 0, _ref = this.options.ykeys.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
791
          smooth = this.options.smooth === true || (_ref1 = this.options.ykeys[i], __indexOf.call(this.options.smooth, _ref1) >= 0);
792
          coords = (function() {
793
            var _j, _len, _ref2, _results1;
794
            _ref2 = this.data;
795
            _results1 = [];
796
            for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
797
              r = _ref2[_j];
798
              if (r._y[i] !== void 0) {
799
                _results1.push({
800
                  x: r._x,
801
                  y: r._y[i]
802
                });
803
              }
804
            }
805
            return _results1;
806
          }).call(this);
807
          if (this.options.continuousLine) {
808
            coords = (function() {
809
              var _j, _len, _results1;
810
              _results1 = [];
811
              for (_j = 0, _len = coords.length; _j < _len; _j++) {
812
                c = coords[_j];
813
                if (c.y !== null) {
814
                  _results1.push(c);
815
                }
816
              }
817
              return _results1;
818
            })();
819
          }
820
          if (coords.length > 1) {
821
            _results.push(Morris.Line.createPath(coords, smooth, this.bottom));
822
          } else {
823
            _results.push(null);
824
          }
825
        }
826
        return _results;
827
      }).call(this);
828
    };
829
 
830
    Line.prototype.draw = function() {
831
      if (this.options.axes) {
832
        this.drawXAxis();
833
      }
834
      this.drawSeries();
835
      if (this.options.hideHover === false) {
836
        return this.displayHoverForRow(this.data.length - 1);
837
      }
838
    };
839
 
840
    Line.prototype.drawXAxis = function() {
841
      var drawLabel, l, labels, prevAngleMargin, prevLabelMargin, row, ypos, _i, _len, _results,
842
        _this = this;
843
      ypos = this.bottom + this.options.padding / 2;
844
      prevLabelMargin = null;
845
      prevAngleMargin = null;
846
      drawLabel = function(labelText, xpos) {
847
        var label, labelBox, margin, offset, textBox;
848
        label = _this.drawXAxisLabel(_this.transX(xpos), ypos, labelText);
849
        textBox = label.getBBox();
850
        label.transform("r" + (-_this.options.xLabelAngle));
851
        labelBox = label.getBBox();
852
        label.transform("t0," + (labelBox.height / 2) + "...");
853
        if (_this.options.xLabelAngle !== 0) {
854
          offset = -0.5 * textBox.width * Math.cos(_this.options.xLabelAngle * Math.PI / 180.0);
855
          label.transform("t" + offset + ",0...");
856
        }
857
        labelBox = label.getBBox();
858
        if ((!(prevLabelMargin != null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {
859
          if (_this.options.xLabelAngle !== 0) {
860
            margin = 1.25 * _this.options.gridTextSize / Math.sin(_this.options.xLabelAngle * Math.PI / 180.0);
861
            prevAngleMargin = labelBox.x - margin;
862
          }
863
          return prevLabelMargin = labelBox.x - _this.options.xLabelMargin;
864
        } else {
865
          return label.remove();
866
        }
867
      };
868
      if (this.options.parseTime) {
869
        if (this.data.length === 1 && this.options.xLabels === 'auto') {
870
          labels = [[this.data[0].label, this.data[0].x]];
871
        } else {
872
          labels = Morris.labelSeries(this.xmin, this.xmax, this.width, this.options.xLabels, this.options.xLabelFormat);
873
        }
874
      } else {
875
        labels = (function() {
876
          var _i, _len, _ref, _results;
877
          _ref = this.data;
878
          _results = [];
879
          for (_i = 0, _len = _ref.length; _i < _len; _i++) {
880
            row = _ref[_i];
881
            _results.push([row.label, row.x]);
882
          }
883
          return _results;
884
        }).call(this);
885
      }
886
      labels.reverse();
887
      _results = [];
888
      for (_i = 0, _len = labels.length; _i < _len; _i++) {
889
        l = labels[_i];
890
        _results.push(drawLabel(l[0], l[1]));
891
      }
892
      return _results;
893
    };
894
 
895
    Line.prototype.drawSeries = function() {
896
      var i, _i, _j, _ref, _ref1, _results;
897
      this.seriesPoints = [];
898
      for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
899
        this._drawLineFor(i);
900
      }
901
      _results = [];
902
      for (i = _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) {
903
        _results.push(this._drawPointFor(i));
904
      }
905
      return _results;
906
    };
907
 
908
    Line.prototype._drawPointFor = function(index) {
909
      var circle, row, _i, _len, _ref, _results;
910
      this.seriesPoints[index] = [];
911
      _ref = this.data;
912
      _results = [];
913
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
914
        row = _ref[_i];
915
        circle = null;
916
        if (row._y[index] != null) {
917
          circle = this.drawLinePoint(row._x, row._y[index], this.options.pointSize, this.colorFor(row, index, 'point'), index);
918
        }
919
        _results.push(this.seriesPoints[index].push(circle));
920
      }
921
      return _results;
922
    };
923
 
924
    Line.prototype._drawLineFor = function(index) {
925
      var path;
926
      path = this.paths[index];
927
      if (path !== null) {
928
        return this.drawLinePath(path, this.colorFor(null, index, 'line'));
929
      }
930
    };
931
 
932
    Line.createPath = function(coords, smooth, bottom) {
933
      var coord, g, grads, i, ix, lg, path, prevCoord, x1, x2, y1, y2, _i, _len;
934
      path = "";
935
      if (smooth) {
936
        grads = Morris.Line.gradients(coords);
937
      }
938
      prevCoord = {
939
        y: null
940
      };
941
      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {
942
        coord = coords[i];
943
        if (coord.y != null) {
944
          if (prevCoord.y != null) {
945
            if (smooth) {
946
              g = grads[i];
947
              lg = grads[i - 1];
948
              ix = (coord.x - prevCoord.x) / 4;
949
              x1 = prevCoord.x + ix;
950
              y1 = Math.min(bottom, prevCoord.y + ix * lg);
951
              x2 = coord.x - ix;
952
              y2 = Math.min(bottom, coord.y - ix * g);
953
              path += "C" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + coord.x + "," + coord.y;
954
            } else {
955
              path += "L" + coord.x + "," + coord.y;
956
            }
957
          } else {
958
            if (!smooth || (grads[i] != null)) {
959
              path += "M" + coord.x + "," + coord.y;
960
            }
961
          }
962
        }
963
        prevCoord = coord;
964
      }
965
      return path;
966
    };
967
 
968
    Line.gradients = function(coords) {
969
      var coord, grad, i, nextCoord, prevCoord, _i, _len, _results;
970
      grad = function(a, b) {
971
        return (a.y - b.y) / (a.x - b.x);
972
      };
973
      _results = [];
974
      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {
975
        coord = coords[i];
976
        if (coord.y != null) {
977
          nextCoord = coords[i + 1] || {
978
            y: null
979
          };
980
          prevCoord = coords[i - 1] || {
981
            y: null
982
          };
983
          if ((prevCoord.y != null) && (nextCoord.y != null)) {
984
            _results.push(grad(prevCoord, nextCoord));
985
          } else if (prevCoord.y != null) {
986
            _results.push(grad(prevCoord, coord));
987
          } else if (nextCoord.y != null) {
988
            _results.push(grad(coord, nextCoord));
989
          } else {
990
            _results.push(null);
991
          }
992
        } else {
993
          _results.push(null);
994
        }
995
      }
996
      return _results;
997
    };
998
 
999
    Line.prototype.hilight = function(index) {
1000
      var i, _i, _j, _ref, _ref1;
1001
      if (this.prevHilight !== null && this.prevHilight !== index) {
1002
        for (i = _i = 0, _ref = this.seriesPoints.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
1003
          if (this.seriesPoints[i][this.prevHilight]) {
1004
            this.seriesPoints[i][this.prevHilight].animate(this.pointShrink);
1005
          }
1006
        }
1007
      }
1008
      if (index !== null && this.prevHilight !== index) {
1009
        for (i = _j = 0, _ref1 = this.seriesPoints.length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
1010
          if (this.seriesPoints[i][index]) {
1011
            this.seriesPoints[i][index].animate(this.pointGrow);
1012
          }
1013
        }
1014
      }
1015
      return this.prevHilight = index;
1016
    };
1017
 
1018
    Line.prototype.colorFor = function(row, sidx, type) {
1019
      if (typeof this.options.lineColors === 'function') {
1020
        return this.options.lineColors.call(this, row, sidx, type);
1021
      } else if (type === 'point') {
1022
        return this.options.pointFillColors[sidx % this.options.pointFillColors.length] || this.options.lineColors[sidx % this.options.lineColors.length];
1023
      } else {
1024
        return this.options.lineColors[sidx % this.options.lineColors.length];
1025
      }
1026
    };
1027
 
1028
    Line.prototype.drawXAxisLabel = function(xPos, yPos, text) {
1029
      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);
1030
    };
1031
 
1032
    Line.prototype.drawLinePath = function(path, lineColor) {
1033
      return this.raphael.path(path).attr('stroke', lineColor).attr('stroke-width', this.options.lineWidth);
1034
    };
1035
 
1036
    Line.prototype.drawLinePoint = function(xPos, yPos, size, pointColor, lineIndex) {
1037
      return this.raphael.circle(xPos, yPos, size).attr('fill', pointColor).attr('stroke-width', this.strokeWidthForSeries(lineIndex)).attr('stroke', this.strokeForSeries(lineIndex));
1038
    };
1039
 
1040
    Line.prototype.strokeWidthForSeries = function(index) {
1041
      return this.options.pointWidths[index % this.options.pointWidths.length];
1042
    };
1043
 
1044
    Line.prototype.strokeForSeries = function(index) {
1045
      return this.options.pointStrokeColors[index % this.options.pointStrokeColors.length];
1046
    };
1047
 
1048
    return Line;
1049
 
1050
  })(Morris.Grid);
1051
 
1052
  Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) {
1053
    var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref;
1054
    ddensity = 200 * (dmax - dmin) / pxwidth;
1055
    d0 = new Date(dmin);
1056
    spec = Morris.LABEL_SPECS[specName];
1057
    if (spec === void 0) {
1058
      _ref = Morris.AUTO_LABEL_ORDER;
1059
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1060
        name = _ref[_i];
1061
        s = Morris.LABEL_SPECS[name];
1062
        if (ddensity >= s.span) {
1063
          spec = s;
1064
          break;
1065
        }
1066
      }
1067
    }
1068
    if (spec === void 0) {
1069
      spec = Morris.LABEL_SPECS["second"];
1070
    }
1071
    if (xLabelFormat) {
1072
      spec = $.extend({}, spec, {
1073
        fmt: xLabelFormat
1074
      });
1075
    }
1076
    d = spec.start(d0);
1077
    ret = [];
1078
    while ((t = d.getTime()) <= dmax) {
1079
      if (t >= dmin) {
1080
        ret.push([spec.fmt(d), t]);
1081
      }
1082
      spec.incr(d);
1083
    }
1084
    return ret;
1085
  };
1086
 
1087
  minutesSpecHelper = function(interval) {
1088
    return {
1089
      span: interval * 60 * 1000,
1090
      start: function(d) {
1091
        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());
1092
      },
1093
      fmt: function(d) {
1094
        return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes()));
1095
      },
1096
      incr: function(d) {
1097
        return d.setUTCMinutes(d.getUTCMinutes() + interval);
1098
      }
1099
    };
1100
  };
1101
 
1102
  secondsSpecHelper = function(interval) {
1103
    return {
1104
      span: interval * 1000,
1105
      start: function(d) {
1106
        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());
1107
      },
1108
      fmt: function(d) {
1109
        return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())) + ":" + (Morris.pad2(d.getSeconds()));
1110
      },
1111
      incr: function(d) {
1112
        return d.setUTCSeconds(d.getUTCSeconds() + interval);
1113
      }
1114
    };
1115
  };
1116
 
1117
  Morris.LABEL_SPECS = {
1118
    "decade": {
1119
      span: 172800000000,
1120
      start: function(d) {
1121
        return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1);
1122
      },
1123
      fmt: function(d) {
1124
        return "" + (d.getFullYear());
1125
      },
1126
      incr: function(d) {
1127
        return d.setFullYear(d.getFullYear() + 10);
1128
      }
1129
    },
1130
    "year": {
1131
      span: 17280000000,
1132
      start: function(d) {
1133
        return new Date(d.getFullYear(), 0, 1);
1134
      },
1135
      fmt: function(d) {
1136
        return "" + (d.getFullYear());
1137
      },
1138
      incr: function(d) {
1139
        return d.setFullYear(d.getFullYear() + 1);
1140
      }
1141
    },
1142
    "month": {
1143
      span: 2419200000,
1144
      start: function(d) {
1145
        return new Date(d.getFullYear(), d.getMonth(), 1);
1146
      },
1147
      fmt: function(d) {
1148
        return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1));
1149
      },
1150
      incr: function(d) {
1151
        return d.setMonth(d.getMonth() + 1);
1152
      }
1153
    },
1154
    "day": {
1155
      span: 86400000,
1156
      start: function(d) {
1157
        return new Date(d.getFullYear(), d.getMonth(), d.getDate());
1158
      },
1159
      fmt: function(d) {
1160
        return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)) + "-" + (Morris.pad2(d.getDate()));
1161
      },
1162
      incr: function(d) {
1163
        return d.setDate(d.getDate() + 1);
1164
      }
1165
    },
1166
    "hour": minutesSpecHelper(60),
1167
    "30min": minutesSpecHelper(30),
1168
    "15min": minutesSpecHelper(15),
1169
    "10min": minutesSpecHelper(10),
1170
    "5min": minutesSpecHelper(5),
1171
    "minute": minutesSpecHelper(1),
1172
    "30sec": secondsSpecHelper(30),
1173
    "15sec": secondsSpecHelper(15),
1174
    "10sec": secondsSpecHelper(10),
1175
    "5sec": secondsSpecHelper(5),
1176
    "second": secondsSpecHelper(1)
1177
  };
1178
 
1179
  Morris.AUTO_LABEL_ORDER = ["decade", "year", "month", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"];
1180
 
1181
  Morris.Area = (function(_super) {
1182
    var areaDefaults;
1183
 
1184
    __extends(Area, _super);
1185
 
1186
    areaDefaults = {
1187
      fillOpacity: 'auto',
1188
      behaveLikeLine: false
1189
    };
1190
 
1191
    function Area(options) {
1192
      var areaOptions;
1193
      if (!(this instanceof Morris.Area)) {
1194
        return new Morris.Area(options);
1195
      }
1196
      areaOptions = $.extend({}, areaDefaults, options);
1197
      this.cumulative = !areaOptions.behaveLikeLine;
1198
      if (areaOptions.fillOpacity === 'auto') {
1199
        areaOptions.fillOpacity = areaOptions.behaveLikeLine ? .8 : 1;
1200
      }
1201
      Area.__super__.constructor.call(this, areaOptions);
1202
    }
1203
 
1204
    Area.prototype.calcPoints = function() {
1205
      var row, total, y, _i, _len, _ref, _results;
1206
      _ref = this.data;
1207
      _results = [];
1208
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1209
        row = _ref[_i];
1210
        row._x = this.transX(row.x);
1211
        total = 0;
1212
        row._y = (function() {
1213
          var _j, _len1, _ref1, _results1;
1214
          _ref1 = row.y;
1215
          _results1 = [];
1216
          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
1217
            y = _ref1[_j];
1218
            if (this.options.behaveLikeLine) {
1219
              _results1.push(this.transY(y));
1220
            } else {
1221
              total += y || 0;
1222
              _results1.push(this.transY(total));
1223
            }
1224
          }
1225
          return _results1;
1226
        }).call(this);
1227
        _results.push(row._ymax = Math.max.apply(Math, row._y));
1228
      }
1229
      return _results;
1230
    };
1231
 
1232
    Area.prototype.drawSeries = function() {
1233
      var i, range, _i, _j, _k, _len, _ref, _ref1, _results, _results1, _results2;
1234
      this.seriesPoints = [];
1235
      if (this.options.behaveLikeLine) {
1236
        range = (function() {
1237
          _results = [];
1238
          for (var _i = 0, _ref = this.options.ykeys.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }
1239
          return _results;
1240
        }).apply(this);
1241
      } else {
1242
        range = (function() {
1243
          _results1 = [];
1244
          for (var _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; _ref1 <= 0 ? _j++ : _j--){ _results1.push(_j); }
1245
          return _results1;
1246
        }).apply(this);
1247
      }
1248
      _results2 = [];
1249
      for (_k = 0, _len = range.length; _k < _len; _k++) {
1250
        i = range[_k];
1251
        this._drawFillFor(i);
1252
        this._drawLineFor(i);
1253
        _results2.push(this._drawPointFor(i));
1254
      }
1255
      return _results2;
1256
    };
1257
 
1258
    Area.prototype._drawFillFor = function(index) {
1259
      var path;
1260
      path = this.paths[index];
1261
      if (path !== null) {
1262
        path = path + ("L" + (this.transX(this.xmax)) + "," + this.bottom + "L" + (this.transX(this.xmin)) + "," + this.bottom + "Z");
1263
        return this.drawFilledPath(path, this.fillForSeries(index));
1264
      }
1265
    };
1266
 
1267
    Area.prototype.fillForSeries = function(i) {
1268
      var color;
1269
      color = Raphael.rgb2hsl(this.colorFor(this.data[i], i, 'line'));
1270
      return Raphael.hsl(color.h, this.options.behaveLikeLine ? color.s * 0.9 : color.s * 0.75, Math.min(0.98, this.options.behaveLikeLine ? color.l * 1.2 : color.l * 1.25));
1271
    };
1272
 
1273
    Area.prototype.drawFilledPath = function(path, fill) {
1274
      return this.raphael.path(path).attr('fill', fill).attr('fill-opacity', this.options.fillOpacity).attr('stroke-width', 0);
1275
    };
1276
 
1277
    return Area;
1278
 
1279
  })(Morris.Line);
1280
 
1281
  Morris.Bar = (function(_super) {
1282
 
1283
    __extends(Bar, _super);
1284
 
1285
    function Bar(options) {
1286
      this.onHoverOut = __bind(this.onHoverOut, this);
1287
 
1288
      this.onHoverMove = __bind(this.onHoverMove, this);
1289
 
1290
      this.onGridClick = __bind(this.onGridClick, this);
1291
      if (!(this instanceof Morris.Bar)) {
1292
        return new Morris.Bar(options);
1293
      }
1294
      Bar.__super__.constructor.call(this, $.extend({}, options, {
1295
        parseTime: false
1296
      }));
1297
    }
1298
 
1299
    Bar.prototype.init = function() {
1300
      this.cumulative = this.options.stacked;
1301
      if (this.options.hideHover !== 'always') {
1302
        this.hover = new Morris.Hover({
1303
          parent: this.el
1304
        });
1305
        this.on('hovermove', this.onHoverMove);
1306
        this.on('hoverout', this.onHoverOut);
1307
        return this.on('gridclick', this.onGridClick);
1308
      }
1309
    };
1310
 
1311
    Bar.prototype.defaults = {
1312
      barSizeRatio: 0.75,
1313
      barGap: 3,
1314
      barColors: ['#0b62a4', '#7a92a3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],
1315
      xLabelMargin: 50
1316
    };
1317
 
1318
    Bar.prototype.calc = function() {
1319
      var _ref;
1320
      this.calcBars();
1321
      if (this.options.hideHover === false) {
1322
        return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(this.data.length - 1));
1323
      }
1324
    };
1325
 
1326
    Bar.prototype.calcBars = function() {
1327
      var idx, row, y, _i, _len, _ref, _results;
1328
      _ref = this.data;
1329
      _results = [];
1330
      for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
1331
        row = _ref[idx];
1332
        row._x = this.left + this.width * (idx + 0.5) / this.data.length;
1333
        _results.push(row._y = (function() {
1334
          var _j, _len1, _ref1, _results1;
1335
          _ref1 = row.y;
1336
          _results1 = [];
1337
          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
1338
            y = _ref1[_j];
1339
            if (y != null) {
1340
              _results1.push(this.transY(y));
1341
            } else {
1342
              _results1.push(null);
1343
            }
1344
          }
1345
          return _results1;
1346
        }).call(this));
1347
      }
1348
      return _results;
1349
    };
1350
 
1351
    Bar.prototype.draw = function() {
1352
      if (this.options.axes) {
1353
        this.drawXAxis();
1354
      }
1355
      return this.drawSeries();
1356
    };
1357
 
1358
    Bar.prototype.drawXAxis = function() {
1359
      var i, label, labelBox, margin, offset, prevAngleMargin, prevLabelMargin, row, textBox, ypos, _i, _ref, _results;
1360
      ypos = this.bottom + this.options.padding / 2;
1361
      prevLabelMargin = null;
1362
      prevAngleMargin = null;
1363
      _results = [];
1364
      for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
1365
        row = this.data[this.data.length - 1 - i];
1366
        label = this.drawXAxisLabel(row._x, ypos, row.label);
1367
        textBox = label.getBBox();
1368
        label.transform("r" + (-this.options.xLabelAngle));
1369
        labelBox = label.getBBox();
1370
        label.transform("t0," + (labelBox.height / 2) + "...");
1371
        if (this.options.xLabelAngle !== 0) {
1372
          offset = -0.5 * textBox.width * Math.cos(this.options.xLabelAngle * Math.PI / 180.0);
1373
          label.transform("t" + offset + ",0...");
1374
        }
1375
        if ((!(prevLabelMargin != null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < this.el.width()) {
1376
          if (this.options.xLabelAngle !== 0) {
1377
            margin = 1.25 * this.options.gridTextSize / Math.sin(this.options.xLabelAngle * Math.PI / 180.0);
1378
            prevAngleMargin = labelBox.x - margin;
1379
          }
1380
          _results.push(prevLabelMargin = labelBox.x - this.options.xLabelMargin);
1381
        } else {
1382
          _results.push(label.remove());
1383
        }
1384
      }
1385
      return _results;
1386
    };
1387
 
1388
    Bar.prototype.drawSeries = function() {
1389
      var barWidth, bottom, groupWidth, idx, lastTop, left, leftPadding, numBars, row, sidx, size, top, ypos, zeroPos;
1390
      groupWidth = this.width / this.options.data.length;
1391
      numBars = this.options.stacked != null ? 1 : this.options.ykeys.length;
1392
      barWidth = (groupWidth * this.options.barSizeRatio - this.options.barGap * (numBars - 1)) / numBars;
1393
      leftPadding = groupWidth * (1 - this.options.barSizeRatio) / 2;
1394
      zeroPos = this.ymin <= 0 && this.ymax >= 0 ? this.transY(0) : null;
1395
      return this.bars = (function() {
1396
        var _i, _len, _ref, _results;
1397
        _ref = this.data;
1398
        _results = [];
1399
        for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
1400
          row = _ref[idx];
1401
          lastTop = 0;
1402
          _results.push((function() {
1403
            var _j, _len1, _ref1, _results1;
1404
            _ref1 = row._y;
1405
            _results1 = [];
1406
            for (sidx = _j = 0, _len1 = _ref1.length; _j < _len1; sidx = ++_j) {
1407
              ypos = _ref1[sidx];
1408
              if (ypos !== null) {
1409
                if (zeroPos) {
1410
                  top = Math.min(ypos, zeroPos);
1411
                  bottom = Math.max(ypos, zeroPos);
1412
                } else {
1413
                  top = ypos;
1414
                  bottom = this.bottom;
1415
                }
1416
                left = this.left + idx * groupWidth + leftPadding;
1417
                if (!this.options.stacked) {
1418
                  left += sidx * (barWidth + this.options.barGap);
1419
                }
1420
                size = bottom - top;
1421
                if (this.options.stacked) {
1422
                  top -= lastTop;
1423
                }
1424
                this.drawBar(left, top, barWidth, size, this.colorFor(row, sidx, 'bar'));
1425
                _results1.push(lastTop += size);
1426
              } else {
1427
                _results1.push(null);
1428
              }
1429
            }
1430
            return _results1;
1431
          }).call(this));
1432
        }
1433
        return _results;
1434
      }).call(this);
1435
    };
1436
 
1437
    Bar.prototype.colorFor = function(row, sidx, type) {
1438
      var r, s;
1439
      if (typeof this.options.barColors === 'function') {
1440
        r = {
1441
          x: row.x,
1442
          y: row.y[sidx],
1443
          label: row.label
1444
        };
1445
        s = {
1446
          index: sidx,
1447
          key: this.options.ykeys[sidx],
1448
          label: this.options.labels[sidx]
1449
        };
1450
        return this.options.barColors.call(this, r, s, type);
1451
      } else {
1452
        return this.options.barColors[sidx % this.options.barColors.length];
1453
      }
1454
    };
1455
 
1456
    Bar.prototype.hitTest = function(x, y) {
1457
      if (this.data.length === 0) {
1458
        return null;
1459
      }
1460
      x = Math.max(Math.min(x, this.right), this.left);
1461
      return Math.min(this.data.length - 1, Math.floor((x - this.left) / (this.width / this.data.length)));
1462
    };
1463
 
1464
    Bar.prototype.onGridClick = function(x, y) {
1465
      var index;
1466
      index = this.hitTest(x, y);
1467
      return this.fire('click', index, this.options.data[index], x, y);
1468
    };
1469
 
1470
    Bar.prototype.onHoverMove = function(x, y) {
1471
      var index, _ref;
1472
      index = this.hitTest(x, y);
1473
      return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));
1474
    };
1475
 
1476
    Bar.prototype.onHoverOut = function() {
1477
      if (this.options.hideHover !== false) {
1478
        return this.hover.hide();
1479
      }
1480
    };
1481
 
1482
    Bar.prototype.hoverContentForRow = function(index) {
1483
      var content, j, row, x, y, _i, _len, _ref;
1484
      row = this.data[index];
1485
      content = "<div class='morris-hover-row-label'>" + row.label + "</div>";
1486
      _ref = row.y;
1487
      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {
1488
        y = _ref[j];
1489
        content += "<div class='morris-hover-point' style='color: " + (this.colorFor(row, j, 'label')) + "'>\n  " + this.options.labels[j] + ":\n  " + (this.yLabelFormat(y)) + "\n</div>";
1490
      }
1491
      if (typeof this.options.hoverCallback === 'function') {
1492
        content = this.options.hoverCallback(index, this.options, content);
1493
      }
1494
      x = this.left + (index + 0.5) * this.width / this.data.length;
1495
      return [content, x];
1496
    };
1497
 
1498
    Bar.prototype.drawXAxisLabel = function(xPos, yPos, text) {
1499
      var label;
1500
      return label = this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);
1501
    };
1502
 
1503
    Bar.prototype.drawBar = function(xPos, yPos, width, height, barColor) {
1504
      return this.raphael.rect(xPos, yPos, width, height).attr('fill', barColor).attr('stroke-width', 0);
1505
    };
1506
 
1507
    return Bar;
1508
 
1509
  })(Morris.Grid);
1510
 
1511
  Morris.Donut = (function(_super) {
1512
 
1513
    __extends(Donut, _super);
1514
 
1515
    Donut.prototype.defaults = {
1516
      colors: ['#0B62A4', '#3980B5', '#679DC6', '#95BBD7', '#B0CCE1', '#095791', '#095085', '#083E67', '#052C48', '#042135'],
1517
      backgroundColor: '#FFFFFF',
1518
      labelColor: '#000000',
1519
      formatter: Morris.commas
1520
    };
1521
 
1522
    function Donut(options) {
1523
      this.select = __bind(this.select, this);
1524
 
1525
      this.click = __bind(this.click, this);
1526
 
1527
      var row;
1528
      if (!(this instanceof Morris.Donut)) {
1529
        return new Morris.Donut(options);
1530
      }
1531
      if (typeof options.element === 'string') {
1532
        this.el = $(document.getElementById(options.element));
1533
      } else {
1534
        this.el = $(options.element);
1535
      }
1536
      this.options = $.extend({}, this.defaults, options);
1537
      if (this.el === null || this.el.length === 0) {
1538
        throw new Error("Graph placeholder not found.");
1539
      }
1540
      if (options.data === void 0 || options.data.length === 0) {
1541
        return;
1542
      }
1543
      this.data = options.data;
1544
      this.values = (function() {
1545
        var _i, _len, _ref, _results;
1546
        _ref = this.data;
1547
        _results = [];
1548
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1549
          row = _ref[_i];
1550
          _results.push(parseFloat(row.value));
1551
        }
1552
        return _results;
1553
      }).call(this);
1554
      this.redraw();
1555
    }
1556
 
1557
    Donut.prototype.redraw = function() {
1558
      var C, cx, cy, i, idx, last, max_value, min, next, seg, total, value, w, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
1559
      this.el.empty();
1560
      this.raphael = new Raphael(this.el[0]);
1561
      cx = this.el.width() / 2;
1562
      cy = this.el.height() / 2;
1563
      w = (Math.min(cx, cy) - 10) / 3;
1564
      total = 0;
1565
      _ref = this.values;
1566
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1567
        value = _ref[_i];
1568
        total += value;
1569
      }
1570
      min = 5 / (2 * w);
1571
      C = 1.9999 * Math.PI - min * this.data.length;
1572
      last = 0;
1573
      idx = 0;
1574
      this.segments = [];
1575
      _ref1 = this.values;
1576
      for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
1577
        value = _ref1[i];
1578
        next = last + min + C * (value / total);
1579
        seg = new Morris.DonutSegment(cx, cy, w * 2, w, last, next, this.options.colors[idx % this.options.colors.length], this.options.backgroundColor, idx, this.raphael);
1580
        seg.render();
1581
        this.segments.push(seg);
1582
        seg.on('hover', this.select);
1583
        seg.on('click', this.click);
1584
        last = next;
1585
        idx += 1;
1586
      }
1587
      this.text1 = this.drawEmptyDonutLabel(cx, cy - 10, this.options.labelColor, 15, 800);
1588
      this.text2 = this.drawEmptyDonutLabel(cx, cy + 10, this.options.labelColor, 14);
1589
      max_value = Math.max.apply(null, (function() {
1590
        var _k, _len2, _ref2, _results;
1591
        _ref2 = this.values;
1592
        _results = [];
1593
        for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
1594
          value = _ref2[_k];
1595
          _results.push(value);
1596
        }
1597
        return _results;
1598
      }).call(this));
1599
      idx = 0;
1600
      _ref2 = this.values;
1601
      _results = [];
1602
      for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
1603
        value = _ref2[_k];
1604
        if (value === max_value) {
1605
          this.select(idx);
1606
          break;
1607
        }
1608
        _results.push(idx += 1);
1609
      }
1610
      return _results;
1611
    };
1612
 
1613
    Donut.prototype.click = function(idx) {
1614
      return this.fire('click', idx, this.data[idx]);
1615
    };
1616
 
1617
    Donut.prototype.select = function(idx) {
1618
      var row, s, segment, _i, _len, _ref;
1619
      _ref = this.segments;
1620
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1621
        s = _ref[_i];
1622
        s.deselect();
1623
      }
1624
      segment = this.segments[idx];
1625
      segment.select();
1626
      row = this.data[idx];
1627
      return this.setLabels(row.label, this.options.formatter(row.value, row));
1628
    };
1629
 
1630
    Donut.prototype.setLabels = function(label1, label2) {
1631
      var inner, maxHeightBottom, maxHeightTop, maxWidth, text1bbox, text1scale, text2bbox, text2scale;
1632
      inner = (Math.min(this.el.width() / 2, this.el.height() / 2) - 10) * 2 / 3;
1633
      maxWidth = 1.8 * inner;
1634
      maxHeightTop = inner / 2;
1635
      maxHeightBottom = inner / 3;
1636
      this.text1.attr({
1637
        text: label1,
1638
        transform: ''
1639
      });
1640
      text1bbox = this.text1.getBBox();
1641
      text1scale = Math.min(maxWidth / text1bbox.width, maxHeightTop / text1bbox.height);
1642
      this.text1.attr({
1643
        transform: "S" + text1scale + "," + text1scale + "," + (text1bbox.x + text1bbox.width / 2) + "," + (text1bbox.y + text1bbox.height)
1644
      });
1645
      this.text2.attr({
1646
        text: label2,
1647
        transform: ''
1648
      });
1649
      text2bbox = this.text2.getBBox();
1650
      text2scale = Math.min(maxWidth / text2bbox.width, maxHeightBottom / text2bbox.height);
1651
      return this.text2.attr({
1652
        transform: "S" + text2scale + "," + text2scale + "," + (text2bbox.x + text2bbox.width / 2) + "," + text2bbox.y
1653
      });
1654
    };
1655
 
1656
    Donut.prototype.drawEmptyDonutLabel = function(xPos, yPos, color, fontSize, fontWeight) {
1657
      var text;
1658
      text = this.raphael.text(xPos, yPos, '').attr('font-size', fontSize).attr('fill', color);
1659
      if (fontWeight != null) {
1660
        text.attr('font-weight', fontWeight);
1661
      }
1662
      return text;
1663
    };
1664
 
1665
    return Donut;
1666
 
1667
  })(Morris.EventEmitter);
1668
 
1669
  Morris.DonutSegment = (function(_super) {
1670
 
1671
    __extends(DonutSegment, _super);
1672
 
1673
    function DonutSegment(cx, cy, inner, outer, p0, p1, color, backgroundColor, index, raphael) {
1674
      this.cx = cx;
1675
      this.cy = cy;
1676
      this.inner = inner;
1677
      this.outer = outer;
1678
      this.color = color;
1679
      this.backgroundColor = backgroundColor;
1680
      this.index = index;
1681
      this.raphael = raphael;
1682
      this.deselect = __bind(this.deselect, this);
1683
 
1684
      this.select = __bind(this.select, this);
1685
 
1686
      this.sin_p0 = Math.sin(p0);
1687
      this.cos_p0 = Math.cos(p0);
1688
      this.sin_p1 = Math.sin(p1);
1689
      this.cos_p1 = Math.cos(p1);
1690
      this.is_long = (p1 - p0) > Math.PI ? 1 : 0;
1691
      this.path = this.calcSegment(this.inner + 3, this.inner + this.outer - 5);
1692
      this.selectedPath = this.calcSegment(this.inner + 3, this.inner + this.outer);
1693
      this.hilight = this.calcArc(this.inner);
1694
    }
1695
 
1696
    DonutSegment.prototype.calcArcPoints = function(r) {
1697
      return [this.cx + r * this.sin_p0, this.cy + r * this.cos_p0, this.cx + r * this.sin_p1, this.cy + r * this.cos_p1];
1698
    };
1699
 
1700
    DonutSegment.prototype.calcSegment = function(r1, r2) {
1701
      var ix0, ix1, iy0, iy1, ox0, ox1, oy0, oy1, _ref, _ref1;
1702
      _ref = this.calcArcPoints(r1), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];
1703
      _ref1 = this.calcArcPoints(r2), ox0 = _ref1[0], oy0 = _ref1[1], ox1 = _ref1[2], oy1 = _ref1[3];
1704
      return ("M" + ix0 + "," + iy0) + ("A" + r1 + "," + r1 + ",0," + this.is_long + ",0," + ix1 + "," + iy1) + ("L" + ox1 + "," + oy1) + ("A" + r2 + "," + r2 + ",0," + this.is_long + ",1," + ox0 + "," + oy0) + "Z";
1705
    };
1706
 
1707
    DonutSegment.prototype.calcArc = function(r) {
1708
      var ix0, ix1, iy0, iy1, _ref;
1709
      _ref = this.calcArcPoints(r), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];
1710
      return ("M" + ix0 + "," + iy0) + ("A" + r + "," + r + ",0," + this.is_long + ",0," + ix1 + "," + iy1);
1711
    };
1712
 
1713
    DonutSegment.prototype.render = function() {
1714
      var _this = this;
1715
      this.arc = this.drawDonutArc(this.hilight, this.color);
1716
      return this.seg = this.drawDonutSegment(this.path, this.color, this.backgroundColor, function() {
1717
        return _this.fire('hover', _this.index);
1718
      }, function() {
1719
        return _this.fire('click', _this.index);
1720
      });
1721
    };
1722
 
1723
    DonutSegment.prototype.drawDonutArc = function(path, color) {
1724
      return this.raphael.path(path).attr({
1725
        stroke: color,
1726
        'stroke-width': 2,
1727
        opacity: 0
1728
      });
1729
    };
1730
 
1731
    DonutSegment.prototype.drawDonutSegment = function(path, fillColor, strokeColor, hoverFunction, clickFunction) {
1732
      return this.raphael.path(path).attr({
1733
        fill: fillColor,
1734
        stroke: strokeColor,
1735
        'stroke-width': 3
1736
      }).hover(hoverFunction).click(clickFunction);
1737
    };
1738
 
1739
    DonutSegment.prototype.select = function() {
1740
      if (!this.selected) {
1741
        this.seg.animate({
1742
          path: this.selectedPath
1743
        }, 150, '<>');
1744
        this.arc.animate({
1745
          opacity: 1
1746
        }, 150, '<>');
1747
        return this.selected = true;
1748
      }
1749
    };
1750
 
1751
    DonutSegment.prototype.deselect = function() {
1752
      if (this.selected) {
1753
        this.seg.animate({
1754
          path: this.path
1755
        }, 150, '<>');
1756
        this.arc.animate({
1757
          opacity: 0
1758
        }, 150, '<>');
1759
        return this.selected = false;
1760
      }
1761
    };
1762
 
1763
    return DonutSegment;
1764
 
1765
  })(Morris.EventEmitter);
1766
 
1767
}).call(this);