From e8c6ba89c8197f6f0ba76aa79efb239393f04631 Mon Sep 17 00:00:00 2001 From: Olly Smith Date: Tue, 4 Dec 2012 19:12:34 +0000 Subject: [PATCH] WIP: re-organising. --- lib/morris.bar.coffee | 12 +- lib/morris.coffee | 101 +----- lib/morris.grid.coffee | 118 ++++++- lib/morris.hover.coffee | 125 +------- lib/morris.line.coffee | 89 +++++- morris.js | 691 ++++++++++++++++++++-------------------- morris.min.js | 2 +- 7 files changed, 573 insertions(+), 565 deletions(-) diff --git a/lib/morris.bar.coffee b/lib/morris.bar.coffee index 8622916..4c0b99b 100644 --- a/lib/morris.bar.coffee +++ b/lib/morris.bar.coffee @@ -1,11 +1,4 @@ class Morris.Bar extends Morris.Grid - @include Morris.Hover - - # override hoverCalculatePosition - hoverGetPosition: (index) -> - [x, y] = Morris.Hover.hoverGetPosition.call(this, index) - [x, (@top + @bottom)/2 - @hoverHeight/2] - constructor: (options) -> return new Morris.Bar(options) unless (@ instanceof Morris.Bar) super($.extend {}, options, parseTime: false) @@ -121,3 +114,8 @@ class Morris.Bar extends Morris.Grid @options.barColors.call(@, r, s, type) else @options.barColors[sidx % @options.barColors.length] + + hoverGetPosition: (index) -> + [x, y] = super(index) + [x, (@top + @bottom)/2 - @hoverHeight/2] + diff --git a/lib/morris.coffee b/lib/morris.coffee index 8cac223..87f4d52 100644 --- a/lib/morris.coffee +++ b/lib/morris.coffee @@ -2,27 +2,10 @@ Morris = window.Morris = {} $ = jQuery -# Very simple multiple-inheritance implementation. -# -# @private -class Morris.Module - @extend: (obj) -> - for key, value of obj when key not in ['extended', 'included'] - @[key] = value - - obj.extended?.apply(@) - this - - @include: (obj) -> - for key, value of obj when key not in ['extended', 'included'] - @::[key] = value - - obj.included?.apply(@) - # Very simple event-emitter class. # # @private -class Morris.EventEmitter extends Morris.Module +class Morris.EventEmitter on: (name, handler) -> unless @handlers? @handlers = {} @@ -57,85 +40,3 @@ Morris.commas = (num) -> # @example # Morris.pad2(1) -> '01' Morris.pad2 = (number) -> (if number < 10 then '0' else '') + number - -# generate a series of label, timestamp pairs for x-axis labels -# -# @private -Morris.labelSeries = (dmin, dmax, pxwidth, specName, xLabelFormat) -> - ddensity = 200 * (dmax - dmin) / pxwidth # seconds per `margin` pixels - d0 = new Date(dmin) - spec = Morris.LABEL_SPECS[specName] - # if the spec doesn't exist, search for the closest one in the list - if spec is undefined - for name in Morris.AUTO_LABEL_ORDER - s = Morris.LABEL_SPECS[name] - if ddensity >= s.span - spec = s - break - # if we run out of options, use second-intervals - if spec is undefined - spec = Morris.LABEL_SPECS["second"] - # check if there's a user-defined formatting function - if xLabelFormat - spec = $.extend({}, spec, {fmt: xLabelFormat}) - # calculate labels - d = spec.start(d0) - ret = [] - while (t = d.getTime()) <= dmax - if t >= dmin - ret.push [spec.fmt(d), t] - spec.incr(d) - return ret - -# @private -minutesSpecHelper = (interval) -> - span: interval * 60 * 1000 - start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours()) - fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}" - incr: (d) -> d.setMinutes(d.getMinutes() + interval) - -# @private -secondsSpecHelper = (interval) -> - span: interval * 1000 - start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes()) - fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}:#{Morris.pad2(d.getSeconds())}" - incr: (d) -> d.setSeconds(d.getSeconds() + interval) - -Morris.LABEL_SPECS = - "decade": - span: 172800000000 # 10 * 365 * 24 * 60 * 60 * 1000 - start: (d) -> new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1) - fmt: (d) -> "#{d.getFullYear()}" - incr: (d) -> d.setFullYear(d.getFullYear() + 10) - "year": - span: 17280000000 # 365 * 24 * 60 * 60 * 1000 - start: (d) -> new Date(d.getFullYear(), 0, 1) - fmt: (d) -> "#{d.getFullYear()}" - incr: (d) -> d.setFullYear(d.getFullYear() + 1) - "month": - span: 2419200000 # 28 * 24 * 60 * 60 * 1000 - start: (d) -> new Date(d.getFullYear(), d.getMonth(), 1) - fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}" - incr: (d) -> d.setMonth(d.getMonth() + 1) - "day": - span: 86400000 # 24 * 60 * 60 * 1000 - start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate()) - fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}-#{Morris.pad2(d.getDate())}" - incr: (d) -> d.setDate(d.getDate() + 1) - "hour": minutesSpecHelper(60) - "30min": minutesSpecHelper(30) - "15min": minutesSpecHelper(15) - "10min": minutesSpecHelper(10) - "5min": minutesSpecHelper(5) - "minute": minutesSpecHelper(1) - "30sec": secondsSpecHelper(30) - "15sec": secondsSpecHelper(15) - "10sec": secondsSpecHelper(10) - "5sec": secondsSpecHelper(5) - "second": secondsSpecHelper(1) - -Morris.AUTO_LABEL_ORDER = [ - "decade", "year", "month", "day", "hour", - "30min", "15min", "10min", "5min", "minute", - "30sec", "15sec", "10sec", "5sec", "second" -] \ No newline at end of file diff --git a/lib/morris.grid.coffee b/lib/morris.grid.coffee index 84af2eb..4f912d7 100644 --- a/lib/morris.grid.coffee +++ b/lib/morris.grid.coffee @@ -35,7 +35,7 @@ class Morris.Grid extends Morris.EventEmitter # load data @setData @options.data - + @postInit() if @postInit # Default options @@ -258,6 +258,122 @@ class Morris.Grid extends Morris.EventEmitter yLabelFormat: (label) -> "#{@options.preUnits}#{Morris.commas(label)}#{@options.postUnits}" + # Hover stuff + # + # + hoverConfigure: (options) -> + @hoverOptions = $.extend {}, @hoverDefaults, options ? {} + + hoverInit: -> + if @hoverOptions.enableHover + @hover = @hoverBuild() + @hoverBindEvents() + @hoverShow(if @hoverOptions.hideHover then null else @data.length - 1) + + hoverDefaults: + enableHover: true + popupClass: "morris-popup" + hideHover: false + allowOverflow: false + pointMargin: 10 + hoverFill: (index, row) -> @hoverFill(index, row) + + hoverBindEvents: -> + @el.mousemove (evt) => + @hoverUpdate evt.pageX + if @hoverOptions.hideHover + @el.mouseout (evt) => + @hoverShow null + touchHandler = (evt) => + touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0] + @hoverUpdate touch.pageX + return touch + @el.bind 'touchstart', touchHandler + @el.bind 'touchmove', touchHandler + @el.bind 'touchend', touchHandler + + @hover.mousemove (evt) -> evt.stopPropagation() + @hover.mouseout (evt) -> evt.stopPropagation() + @hover.bind 'touchstart', (evt) -> evt.stopPropagation() + @hover.bind 'touchmove', (evt) -> evt.stopPropagation() + @hover.bind 'touchend', (evt) -> evt.stopPropagation() + + hoverCalculateMargins: -> + @hoverMargins = for i in [1...@data.length] + @left + i * @width / @data.length + + hoverBuild: -> + hover = $ "
" + hover.addClass "#{@hoverOptions.popupClass} js-morris-popup" + hover.appendTo @el + hover.hide() + hover + + hoverUpdate: (x) -> + x -= @el.offset().left + for hoverIndex in [0...@hoverMargins.length] + break if @hoverMargins[hoverIndex] > x + @hoverShow hoverIndex + + hoverShow: (index) -> + if index isnt null + @hover.html("") + @hoverOptions.hoverFill.call(@, index, @data[index]) + @hoverPosition(index) + @fire "hover.show", index + @hover.show() + if not index? + @hoverHide() + + hoverHide: -> + @hover.hide() + + colorFor: (row, i, type) -> "inherit" + yLabelFormat: (label) -> Morris.commas(label) + + hoverPosition: (index) -> + [x, y] = @hoverGetPosition index + + @hover.css + top: "#{@el.offset().top + y}px" + left: "#{@el.offset().left + x}px" + + hoverGetPosition: (index) -> + row = @data[index] + + @hoverWidth = @hover.outerWidth(true) + @hoverHeight = @hover.outerHeight(true) + + miny = y = Math.min.apply(null, (y for y in row._y when y isnt null).concat(@bottom)) + + x = row._x - @hoverWidth/2 + y = miny + y = y - @hoverHeight - @hoverOptions.pointMargin + + unless @hoverOptions.allowOverflow + if x < @left + x = row._x + @hoverOptions.pointMargin + else if x > @right - @hoverWidth + x = row._x - @hoverWidth - @hoverOptions.pointMargin + + y = Math.max y, @top + y = Math.min y, (@bottom - @hoverHeight - @hoverOptions.pointMargin) + + if y - miny < @hoverWidth + @hoverOptions.pointMargin + y = miny + @hoverOptions.pointMargin + + [x, y] + + hoverFill: (index, row) -> + xLabel = $ "

" + xLabel.text row.label + xLabel.appendTo @hover + for y, i in row.y + yLabel = $ "

" + yLabel.css "color", @colorFor(row, i, "hover") + yLabel.text "#{@options.labels[i]}: #{@yLabelFormat(y)}" + yLabel.appendTo @hover + # Parse a date into a javascript timestamp # diff --git a/lib/morris.hover.coffee b/lib/morris.hover.coffee index ab5f58b..85d8482 100644 --- a/lib/morris.hover.coffee +++ b/lib/morris.hover.coffee @@ -1,113 +1,22 @@ -Morris.Hover = - hoverConfigure: (options) -> - @hoverOptions = $.extend {}, @hoverDefaults, options ? {} +class Morris.Hover + # Displays contextual information in a floating HTML div. + # + constructor: (options = {}) -> + @options = $.extend {}, Morris.Hover.defaults, options + @el = $ "

" + @el.hide() - hoverInit: -> - if @hoverOptions.enableHover - @hover = @hoverBuild() - @hoverBindEvents() - @hoverShow(if @hoverOptions.hideHover then null else @data.length - 1) - - hoverDefaults: - enableHover: true - popupClass: "morris-popup" - hideHover: false + @defaults: + class: 'morris-popup' allowOverflow: false - pointMargin: 10 - hoverFill: (index, row) -> @hoverFill(index, row) - - hoverBindEvents: -> - @el.mousemove (evt) => - @hoverUpdate evt.pageX - if @hoverOptions.hideHover - @el.mouseout (evt) => - @hoverShow null - touchHandler = (evt) => - touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0] - @hoverUpdate touch.pageX - return touch - @el.bind 'touchstart', touchHandler - @el.bind 'touchmove', touchHandler - @el.bind 'touchend', touchHandler - - @hover.mousemove (evt) -> evt.stopPropagation() - @hover.mouseout (evt) -> evt.stopPropagation() - @hover.bind 'touchstart', (evt) -> evt.stopPropagation() - @hover.bind 'touchmove', (evt) -> evt.stopPropagation() - @hover.bind 'touchend', (evt) -> evt.stopPropagation() - hoverCalculateMargins: -> - @hoverMargins = for i in [1...@data.length] - @left + i * @width / @data.length + show: (x, y, data) -> + if typeof @options.content is 'function' + @el.html @options.content(data) + else + @el.html @options.content + @el.show() - hoverBuild: -> - hover = $ "
" - hover.addClass "#{@hoverOptions.popupClass} js-morris-popup" - hover.appendTo @el - hover.hide() - hover + hide: -> + @el.hide() - hoverUpdate: (x) -> - x -= @el.offset().left - for hoverIndex in [0...@hoverMargins.length] - break if @hoverMargins[hoverIndex] > x - @hoverShow hoverIndex - - hoverShow: (index) -> - if index isnt null - @hover.html("") - @hoverOptions.hoverFill.call(@, index, @data[index]) - @hoverPosition(index) - @fire "hover.show", index - @hover.show() - if not index? - @hoverHide() - - hoverHide: -> - @hover.hide() - - colorFor: (row, i, type) -> "inherit" - yLabelFormat: (label) -> Morris.commas(label) - - hoverPosition: (index) -> - [x, y] = @hoverGetPosition index - - @hover.css - top: "#{@el.offset().top + y}px" - left: "#{@el.offset().left + x}px" - - hoverGetPosition: (index) -> - row = @data[index] - - @hoverWidth = @hover.outerWidth(true) - @hoverHeight = @hover.outerHeight(true) - - miny = y = Math.min.apply(null, (y for y in row._y when y isnt null).concat(@bottom)) - - x = row._x - @hoverWidth/2 - y = miny - y = y - @hoverHeight - @hoverOptions.pointMargin - - unless @hoverOptions.allowOverflow - if x < @left - x = row._x + @hoverOptions.pointMargin - else if x > @right - @hoverWidth - x = row._x - @hoverWidth - @hoverOptions.pointMargin - - y = Math.max y, @top - y = Math.min y, (@bottom - @hoverHeight - @hoverOptions.pointMargin) - - if y - miny < @hoverWidth + @hoverOptions.pointMargin - y = miny + @hoverOptions.pointMargin - - [x, y] - - hoverFill: (index, row) -> - xLabel = $ "

" - xLabel.text row.label - xLabel.appendTo @hover - for y, i in row.y - yLabel = $ "

" - yLabel.css "color", @colorFor(row, i, "hover") - yLabel.text "#{@options.labels[i]}: #{@yLabelFormat(y)}" - yLabel.appendTo @hover diff --git a/lib/morris.line.coffee b/lib/morris.line.coffee index e4433fe..7557630 100644 --- a/lib/morris.line.coffee +++ b/lib/morris.line.coffee @@ -1,6 +1,4 @@ class Morris.Line extends Morris.Grid - @include Morris.Hover - # Initialise the graph. # constructor: (options) -> @@ -11,9 +9,9 @@ class Morris.Line extends Morris.Grid # Some instance variables for later @pointGrow = Raphael.animation r: @options.pointSize + 3, 25, 'linear' @pointShrink = Raphael.animation r: @options.pointSize, 25, 'linear' - + @hoverConfigure @options.hoverOptions - + # column hilight events if @options.hilight @prevHilight = null @@ -243,3 +241,86 @@ class Morris.Line extends Morris.Grid @options.pointFillColors[sidx % @options.pointFillColors.length] || @options.lineColors[sidx % @options.lineColors.length] else @options.lineColors[sidx % @options.lineColors.length] + + +# generate a series of label, timestamp pairs for x-axis labels +# +# @private +Morris.labelSeries = (dmin, dmax, pxwidth, specName, xLabelFormat) -> + ddensity = 200 * (dmax - dmin) / pxwidth # seconds per `margin` pixels + d0 = new Date(dmin) + spec = Morris.LABEL_SPECS[specName] + # if the spec doesn't exist, search for the closest one in the list + if spec is undefined + for name in Morris.AUTO_LABEL_ORDER + s = Morris.LABEL_SPECS[name] + if ddensity >= s.span + spec = s + break + # if we run out of options, use second-intervals + if spec is undefined + spec = Morris.LABEL_SPECS["second"] + # check if there's a user-defined formatting function + if xLabelFormat + spec = $.extend({}, spec, {fmt: xLabelFormat}) + # calculate labels + d = spec.start(d0) + ret = [] + while (t = d.getTime()) <= dmax + if t >= dmin + ret.push [spec.fmt(d), t] + spec.incr(d) + return ret + +# @private +minutesSpecHelper = (interval) -> + span: interval * 60 * 1000 + start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours()) + fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}" + incr: (d) -> d.setMinutes(d.getMinutes() + interval) + +# @private +secondsSpecHelper = (interval) -> + span: interval * 1000 + start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes()) + fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}:#{Morris.pad2(d.getSeconds())}" + incr: (d) -> d.setSeconds(d.getSeconds() + interval) + +Morris.LABEL_SPECS = + "decade": + span: 172800000000 # 10 * 365 * 24 * 60 * 60 * 1000 + start: (d) -> new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1) + fmt: (d) -> "#{d.getFullYear()}" + incr: (d) -> d.setFullYear(d.getFullYear() + 10) + "year": + span: 17280000000 # 365 * 24 * 60 * 60 * 1000 + start: (d) -> new Date(d.getFullYear(), 0, 1) + fmt: (d) -> "#{d.getFullYear()}" + incr: (d) -> d.setFullYear(d.getFullYear() + 1) + "month": + span: 2419200000 # 28 * 24 * 60 * 60 * 1000 + start: (d) -> new Date(d.getFullYear(), d.getMonth(), 1) + fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}" + incr: (d) -> d.setMonth(d.getMonth() + 1) + "day": + span: 86400000 # 24 * 60 * 60 * 1000 + start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate()) + fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}-#{Morris.pad2(d.getDate())}" + incr: (d) -> d.setDate(d.getDate() + 1) + "hour": minutesSpecHelper(60) + "30min": minutesSpecHelper(30) + "15min": minutesSpecHelper(15) + "10min": minutesSpecHelper(10) + "5min": minutesSpecHelper(5) + "minute": minutesSpecHelper(1) + "30sec": secondsSpecHelper(30) + "15sec": secondsSpecHelper(15) + "10sec": secondsSpecHelper(10) + "5sec": secondsSpecHelper(5) + "second": secondsSpecHelper(1) + +Morris.AUTO_LABEL_ORDER = [ + "decade", "year", "month", "day", "hour", + "30min", "15min", "10min", "5min", "minute", + "30sec", "15sec", "10sec", "5sec", "second" +] diff --git a/morris.js b/morris.js index 5219469..ff1c7a4 100644 --- a/morris.js +++ b/morris.js @@ -1,8 +1,8 @@ (function() { var $, Morris, minutesSpecHelper, secondsSpecHelper, + __slice = [].slice, __hasProp = {}.hasOwnProperty, __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; }, - __slice = [].slice, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __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; }; @@ -10,46 +10,9 @@ $ = jQuery; - Morris.Module = (function() { + Morris.EventEmitter = (function() { - function Module() {} - - Module.extend = function(obj) { - var key, value, _ref; - for (key in obj) { - value = obj[key]; - if (key !== 'extended' && key !== 'included') { - this[key] = value; - } - } - if ((_ref = obj.extended) != null) { - _ref.apply(this); - } - return this; - }; - - Module.include = function(obj) { - var key, value, _ref; - for (key in obj) { - value = obj[key]; - if (key !== 'extended' && key !== 'included') { - this.prototype[key] = value; - } - } - return (_ref = obj.included) != null ? _ref.apply(this) : void 0; - }; - - return Module; - - })(); - - Morris.EventEmitter = (function(_super) { - - __extends(EventEmitter, _super); - - function EventEmitter() { - return EventEmitter.__super__.constructor.apply(this, arguments); - } + function EventEmitter() {} EventEmitter.prototype.on = function(name, handler) { if (this.handlers == null) { @@ -77,7 +40,7 @@ return EventEmitter; - })(Morris.Module); + })(); Morris.commas = function(num) { var absnum, intnum, ret, strabsnum; @@ -100,135 +63,6 @@ return (number < 10 ? '0' : '') + number; }; - Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) { - var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref; - ddensity = 200 * (dmax - dmin) / pxwidth; - d0 = new Date(dmin); - spec = Morris.LABEL_SPECS[specName]; - if (spec === void 0) { - _ref = Morris.AUTO_LABEL_ORDER; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - s = Morris.LABEL_SPECS[name]; - if (ddensity >= s.span) { - spec = s; - break; - } - } - } - if (spec === void 0) { - spec = Morris.LABEL_SPECS["second"]; - } - if (xLabelFormat) { - spec = $.extend({}, spec, { - fmt: xLabelFormat - }); - } - d = spec.start(d0); - ret = []; - while ((t = d.getTime()) <= dmax) { - if (t >= dmin) { - ret.push([spec.fmt(d), t]); - } - spec.incr(d); - } - return ret; - }; - - minutesSpecHelper = function(interval) { - return { - span: interval * 60 * 1000, - start: function(d) { - return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours()); - }, - fmt: function(d) { - return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())); - }, - incr: function(d) { - return d.setMinutes(d.getMinutes() + interval); - } - }; - }; - - secondsSpecHelper = function(interval) { - return { - span: interval * 1000, - start: function(d) { - return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes()); - }, - fmt: function(d) { - return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())) + ":" + (Morris.pad2(d.getSeconds())); - }, - incr: function(d) { - return d.setSeconds(d.getSeconds() + interval); - } - }; - }; - - Morris.LABEL_SPECS = { - "decade": { - span: 172800000000, - start: function(d) { - return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1); - }, - fmt: function(d) { - return "" + (d.getFullYear()); - }, - incr: function(d) { - return d.setFullYear(d.getFullYear() + 10); - } - }, - "year": { - span: 17280000000, - start: function(d) { - return new Date(d.getFullYear(), 0, 1); - }, - fmt: function(d) { - return "" + (d.getFullYear()); - }, - incr: function(d) { - return d.setFullYear(d.getFullYear() + 1); - } - }, - "month": { - span: 2419200000, - start: function(d) { - return new Date(d.getFullYear(), d.getMonth(), 1); - }, - fmt: function(d) { - return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)); - }, - incr: function(d) { - return d.setMonth(d.getMonth() + 1); - } - }, - "day": { - span: 86400000, - start: function(d) { - return new Date(d.getFullYear(), d.getMonth(), d.getDate()); - }, - fmt: function(d) { - return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)) + "-" + (Morris.pad2(d.getDate())); - }, - incr: function(d) { - return d.setDate(d.getDate() + 1); - } - }, - "hour": minutesSpecHelper(60), - "30min": minutesSpecHelper(30), - "15min": minutesSpecHelper(15), - "10min": minutesSpecHelper(10), - "5min": minutesSpecHelper(5), - "minute": minutesSpecHelper(1), - "30sec": secondsSpecHelper(30), - "15sec": secondsSpecHelper(15), - "10sec": secondsSpecHelper(10), - "5sec": secondsSpecHelper(5), - "second": secondsSpecHelper(1) - }; - - Morris.AUTO_LABEL_ORDER = ["decade", "year", "month", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"]; - Morris.Grid = (function(_super) { __extends(Grid, _super); @@ -528,6 +362,184 @@ return "" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits; }; + Grid.prototype.hoverConfigure = function(options) { + return this.hoverOptions = $.extend({}, this.hoverDefaults, options != null ? options : {}); + }; + + Grid.prototype.hoverInit = function() { + if (this.hoverOptions.enableHover) { + this.hover = this.hoverBuild(); + this.hoverBindEvents(); + return this.hoverShow(this.hoverOptions.hideHover ? null : this.data.length - 1); + } + }; + + Grid.prototype.hoverDefaults = { + enableHover: true, + popupClass: "morris-popup", + hideHover: false, + allowOverflow: false, + pointMargin: 10, + hoverFill: function(index, row) { + return this.hoverFill(index, row); + } + }; + + Grid.prototype.hoverBindEvents = function() { + var touchHandler, + _this = this; + this.el.mousemove(function(evt) { + return _this.hoverUpdate(evt.pageX); + }); + if (this.hoverOptions.hideHover) { + this.el.mouseout(function(evt) { + return _this.hoverShow(null); + }); + } + touchHandler = function(evt) { + var touch; + touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0]; + _this.hoverUpdate(touch.pageX); + return touch; + }; + this.el.bind('touchstart', touchHandler); + this.el.bind('touchmove', touchHandler); + this.el.bind('touchend', touchHandler); + this.hover.mousemove(function(evt) { + return evt.stopPropagation(); + }); + this.hover.mouseout(function(evt) { + return evt.stopPropagation(); + }); + this.hover.bind('touchstart', function(evt) { + return evt.stopPropagation(); + }); + this.hover.bind('touchmove', function(evt) { + return evt.stopPropagation(); + }); + return this.hover.bind('touchend', function(evt) { + return evt.stopPropagation(); + }); + }; + + Grid.prototype.hoverCalculateMargins = function() { + var i; + return this.hoverMargins = (function() { + var _i, _ref, _results; + _results = []; + for (i = _i = 1, _ref = this.data.length; 1 <= _ref ? _i < _ref : _i > _ref; i = 1 <= _ref ? ++_i : --_i) { + _results.push(this.left + i * this.width / this.data.length); + } + return _results; + }).call(this); + }; + + Grid.prototype.hoverBuild = function() { + var hover; + hover = $("

"); + hover.addClass("" + this.hoverOptions.popupClass + " js-morris-popup"); + hover.appendTo(this.el); + hover.hide(); + return hover; + }; + + Grid.prototype.hoverUpdate = function(x) { + var hoverIndex, _i, _ref; + x -= this.el.offset().left; + for (hoverIndex = _i = 0, _ref = this.hoverMargins.length; 0 <= _ref ? _i < _ref : _i > _ref; hoverIndex = 0 <= _ref ? ++_i : --_i) { + if (this.hoverMargins[hoverIndex] > x) { + break; + } + } + return this.hoverShow(hoverIndex); + }; + + Grid.prototype.hoverShow = function(index) { + if (index !== null) { + this.hover.html(""); + this.hoverOptions.hoverFill.call(this, index, this.data[index]); + this.hoverPosition(index); + this.fire("hover.show", index); + this.hover.show(); + } + if (!(index != null)) { + return this.hoverHide(); + } + }; + + Grid.prototype.hoverHide = function() { + return this.hover.hide(); + }; + + Grid.prototype.colorFor = function(row, i, type) { + return "inherit"; + }; + + Grid.prototype.yLabelFormat = function(label) { + return Morris.commas(label); + }; + + Grid.prototype.hoverPosition = function(index) { + var x, y, _ref; + _ref = this.hoverGetPosition(index), x = _ref[0], y = _ref[1]; + return this.hover.css({ + top: "" + (this.el.offset().top + y) + "px", + left: "" + (this.el.offset().left + x) + "px" + }); + }; + + Grid.prototype.hoverGetPosition = function(index) { + var miny, row, x, y; + row = this.data[index]; + this.hoverWidth = this.hover.outerWidth(true); + this.hoverHeight = this.hover.outerHeight(true); + miny = y = Math.min.apply(null, ((function() { + var _i, _len, _ref, _results; + _ref = row._y; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + y = _ref[_i]; + if (y !== null) { + _results.push(y); + } + } + return _results; + })()).concat(this.bottom)); + x = row._x - this.hoverWidth / 2; + y = miny; + y = y - this.hoverHeight - this.hoverOptions.pointMargin; + if (!this.hoverOptions.allowOverflow) { + if (x < this.left) { + x = row._x + this.hoverOptions.pointMargin; + } else if (x > this.right - this.hoverWidth) { + x = row._x - this.hoverWidth - this.hoverOptions.pointMargin; + } + y = Math.max(y, this.top); + y = Math.min(y, this.bottom - this.hoverHeight - this.hoverOptions.pointMargin); + if (y - miny < this.hoverWidth + this.hoverOptions.pointMargin) { + y = miny + this.hoverOptions.pointMargin; + } + } + return [x, y]; + }; + + Grid.prototype.hoverFill = function(index, row) { + var i, xLabel, y, yLabel, _i, _len, _ref, _results; + xLabel = $("

"); + xLabel.text(row.label); + xLabel.appendTo(this.hover); + _ref = row.y; + _results = []; + for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { + y = _ref[i]; + yLabel = $("

"); + yLabel.css("color", this.colorFor(row, i, "hover")); + yLabel.text("" + this.options.labels[i] + ": " + (this.yLabelFormat(y))); + _results.push(yLabel.appendTo(this.hover)); + } + return _results; + }; + return Grid; })(Morris.EventEmitter); @@ -589,179 +601,43 @@ } }; - Morris.Hover = { - hoverConfigure: function(options) { - return this.hoverOptions = $.extend({}, this.hoverDefaults, options != null ? options : {}); - }, - hoverInit: function() { - if (this.hoverOptions.enableHover) { - this.hover = this.hoverBuild(); - this.hoverBindEvents(); - return this.hoverShow(this.hoverOptions.hideHover ? null : this.data.length - 1); + Morris.Hover = (function() { + + function Hover(options) { + if (options == null) { + options = {}; } - }, - hoverDefaults: { - enableHover: true, - popupClass: "morris-popup", - hideHover: false, - allowOverflow: false, - pointMargin: 10, - hoverFill: function(index, row) { - return this.hoverFill(index, row); - } - }, - hoverBindEvents: function() { - var touchHandler, - _this = this; - this.el.mousemove(function(evt) { - return _this.hoverUpdate(evt.pageX); - }); - if (this.hoverOptions.hideHover) { - this.el.mouseout(function(evt) { - return _this.hoverShow(null); - }); - } - touchHandler = function(evt) { - var touch; - touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0]; - _this.hoverUpdate(touch.pageX); - return touch; - }; - this.el.bind('touchstart', touchHandler); - this.el.bind('touchmove', touchHandler); - this.el.bind('touchend', touchHandler); - this.hover.mousemove(function(evt) { - return evt.stopPropagation(); - }); - this.hover.mouseout(function(evt) { - return evt.stopPropagation(); - }); - this.hover.bind('touchstart', function(evt) { - return evt.stopPropagation(); - }); - this.hover.bind('touchmove', function(evt) { - return evt.stopPropagation(); - }); - return this.hover.bind('touchend', function(evt) { - return evt.stopPropagation(); - }); - }, - hoverCalculateMargins: function() { - var i; - return this.hoverMargins = (function() { - var _i, _ref, _results; - _results = []; - for (i = _i = 1, _ref = this.data.length; 1 <= _ref ? _i < _ref : _i > _ref; i = 1 <= _ref ? ++_i : --_i) { - _results.push(this.left + i * this.width / this.data.length); - } - return _results; - }).call(this); - }, - hoverBuild: function() { - var hover; - hover = $("

"); - hover.addClass("" + this.hoverOptions.popupClass + " js-morris-popup"); - hover.appendTo(this.el); - hover.hide(); - return hover; - }, - hoverUpdate: function(x) { - var hoverIndex, _i, _ref; - x -= this.el.offset().left; - for (hoverIndex = _i = 0, _ref = this.hoverMargins.length; 0 <= _ref ? _i < _ref : _i > _ref; hoverIndex = 0 <= _ref ? ++_i : --_i) { - if (this.hoverMargins[hoverIndex] > x) { - break; - } - } - return this.hoverShow(hoverIndex); - }, - hoverShow: function(index) { - if (index !== null) { - this.hover.html(""); - this.hoverOptions.hoverFill.call(this, index, this.data[index]); - this.hoverPosition(index); - this.fire("hover.show", index); - this.hover.show(); - } - if (!(index != null)) { - return this.hoverHide(); - } - }, - hoverHide: function() { - return this.hover.hide(); - }, - colorFor: function(row, i, type) { - return "inherit"; - }, - yLabelFormat: function(label) { - return Morris.commas(label); - }, - hoverPosition: function(index) { - var x, y, _ref; - _ref = this.hoverGetPosition(index), x = _ref[0], y = _ref[1]; - return this.hover.css({ - top: "" + (this.el.offset().top + y) + "px", - left: "" + (this.el.offset().left + x) + "px" - }); - }, - hoverGetPosition: function(index) { - var miny, row, x, y; - row = this.data[index]; - this.hoverWidth = this.hover.outerWidth(true); - this.hoverHeight = this.hover.outerHeight(true); - miny = y = Math.min.apply(null, ((function() { - var _i, _len, _ref, _results; - _ref = row._y; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - y = _ref[_i]; - if (y !== null) { - _results.push(y); - } - } - return _results; - })()).concat(this.bottom)); - x = row._x - this.hoverWidth / 2; - y = miny; - y = y - this.hoverHeight - this.hoverOptions.pointMargin; - if (!this.hoverOptions.allowOverflow) { - if (x < this.left) { - x = row._x + this.hoverOptions.pointMargin; - } else if (x > this.right - this.hoverWidth) { - x = row._x - this.hoverWidth - this.hoverOptions.pointMargin; - } - y = Math.max(y, this.top); - y = Math.min(y, this.bottom - this.hoverHeight - this.hoverOptions.pointMargin); - if (y - miny < this.hoverWidth + this.hoverOptions.pointMargin) { - y = miny + this.hoverOptions.pointMargin; - } - } - return [x, y]; - }, - hoverFill: function(index, row) { - var i, xLabel, y, yLabel, _i, _len, _ref, _results; - xLabel = $("

"); - xLabel.text(row.label); - xLabel.appendTo(this.hover); - _ref = row.y; - _results = []; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - y = _ref[i]; - yLabel = $("

"); - yLabel.css("color", this.colorFor(row, i, "hover")); - yLabel.text("" + this.options.labels[i] + ": " + (this.yLabelFormat(y))); - _results.push(yLabel.appendTo(this.hover)); - } - return _results; + this.options = $.extend({}, Morris.Hover.defaults, options); + this.el = $("

"); + this.el.hide(); } - }; + + Hover.defaults = { + "class": 'morris-popup', + allowOverflow: false + }; + + Hover.prototype.show = function(x, y, data) { + if (typeof this.options.content === 'function') { + this.el.html(this.options.content(data)); + } else { + this.el.html(this.options.content); + } + return this.el.show(); + }; + + Hover.prototype.hide = function() { + return this.el.hide(); + }; + + return Hover; + + })(); Morris.Line = (function(_super) { __extends(Line, _super); - Line.include(Morris.Hover); - function Line(options) { this.updateHilight = __bind(this.updateHilight, this); @@ -1135,6 +1011,135 @@ })(Morris.Grid); + Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) { + var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref; + ddensity = 200 * (dmax - dmin) / pxwidth; + d0 = new Date(dmin); + spec = Morris.LABEL_SPECS[specName]; + if (spec === void 0) { + _ref = Morris.AUTO_LABEL_ORDER; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + name = _ref[_i]; + s = Morris.LABEL_SPECS[name]; + if (ddensity >= s.span) { + spec = s; + break; + } + } + } + if (spec === void 0) { + spec = Morris.LABEL_SPECS["second"]; + } + if (xLabelFormat) { + spec = $.extend({}, spec, { + fmt: xLabelFormat + }); + } + d = spec.start(d0); + ret = []; + while ((t = d.getTime()) <= dmax) { + if (t >= dmin) { + ret.push([spec.fmt(d), t]); + } + spec.incr(d); + } + return ret; + }; + + minutesSpecHelper = function(interval) { + return { + span: interval * 60 * 1000, + start: function(d) { + return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours()); + }, + fmt: function(d) { + return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())); + }, + incr: function(d) { + return d.setMinutes(d.getMinutes() + interval); + } + }; + }; + + secondsSpecHelper = function(interval) { + return { + span: interval * 1000, + start: function(d) { + return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes()); + }, + fmt: function(d) { + return "" + (Morris.pad2(d.getHours())) + ":" + (Morris.pad2(d.getMinutes())) + ":" + (Morris.pad2(d.getSeconds())); + }, + incr: function(d) { + return d.setSeconds(d.getSeconds() + interval); + } + }; + }; + + Morris.LABEL_SPECS = { + "decade": { + span: 172800000000, + start: function(d) { + return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1); + }, + fmt: function(d) { + return "" + (d.getFullYear()); + }, + incr: function(d) { + return d.setFullYear(d.getFullYear() + 10); + } + }, + "year": { + span: 17280000000, + start: function(d) { + return new Date(d.getFullYear(), 0, 1); + }, + fmt: function(d) { + return "" + (d.getFullYear()); + }, + incr: function(d) { + return d.setFullYear(d.getFullYear() + 1); + } + }, + "month": { + span: 2419200000, + start: function(d) { + return new Date(d.getFullYear(), d.getMonth(), 1); + }, + fmt: function(d) { + return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)); + }, + incr: function(d) { + return d.setMonth(d.getMonth() + 1); + } + }, + "day": { + span: 86400000, + start: function(d) { + return new Date(d.getFullYear(), d.getMonth(), d.getDate()); + }, + fmt: function(d) { + return "" + (d.getFullYear()) + "-" + (Morris.pad2(d.getMonth() + 1)) + "-" + (Morris.pad2(d.getDate())); + }, + incr: function(d) { + return d.setDate(d.getDate() + 1); + } + }, + "hour": minutesSpecHelper(60), + "30min": minutesSpecHelper(30), + "15min": minutesSpecHelper(15), + "10min": minutesSpecHelper(10), + "5min": minutesSpecHelper(5), + "minute": minutesSpecHelper(1), + "30sec": secondsSpecHelper(30), + "15sec": secondsSpecHelper(15), + "10sec": secondsSpecHelper(10), + "5sec": secondsSpecHelper(5), + "second": secondsSpecHelper(1) + }; + + Morris.AUTO_LABEL_ORDER = ["decade", "year", "month", "day", "hour", "30min", "15min", "10min", "5min", "minute", "30sec", "15sec", "10sec", "5sec", "second"]; + Morris.Area = (function(_super) { __extends(Area, _super); @@ -1196,14 +1201,6 @@ __extends(Bar, _super); - Bar.include(Morris.Hover); - - Bar.prototype.hoverGetPosition = function(index) { - var x, y, _ref; - _ref = Morris.Hover.hoverGetPosition.call(this, index), x = _ref[0], y = _ref[1]; - return [x, (this.top + this.bottom) / 2 - this.hoverHeight / 2]; - }; - function Bar(options) { if (!(this instanceof Morris.Bar)) { return new Morris.Bar(options); @@ -1350,6 +1347,12 @@ } }; + Bar.prototype.hoverGetPosition = function(index) { + var x, y, _ref; + _ref = Bar.__super__.hoverGetPosition.call(this, index), x = _ref[0], y = _ref[1]; + return [x, (this.top + this.bottom) / 2 - this.hoverHeight / 2]; + }; + return Bar; })(Morris.Grid); diff --git a/morris.min.js b/morris.min.js index 2ac6b49..074b975 100644 --- a/morris.min.js +++ b/morris.min.js @@ -1 +1 @@ -(function(){var e,t,n,r,i={}.hasOwnProperty,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e},o=[].slice,u=function(e,t){return function(){return e.apply(t,arguments)}},a=[].indexOf||function(e){for(var t=0,n=this.length;tn.length&&(r+=i.slice(n.length)),r):"-"},t.pad2=function(e){return(e<10?"0":"")+e},t.labelSeries=function(n,r,i,s,o){var u,a,f,l,c,h,p,d,v,m,g;f=200*(r-n)/i,a=new Date(n),p=t.LABEL_SPECS[s];if(p===void 0){g=t.AUTO_LABEL_ORDER;for(v=0,m=g.length;v=h.span){p=h;break}}}p===void 0&&(p=t.LABEL_SPECS.second),o&&(p=e.extend({},p,{fmt:o})),u=p.start(a),c=[];while((d=u.getTime())<=r)d>=n&&c.push([p.fmt(u),d]),p.incr(u);return c},n=function(e){return{span:e*60*1e3,start:function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours())},fmt:function(e){return""+t.pad2(e.getHours())+":"+t.pad2(e.getMinutes())},incr:function(t){return t.setMinutes(t.getMinutes()+e)}}},r=function(e){return{span:e*1e3,start:function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes())},fmt:function(e){return""+t.pad2(e.getHours())+":"+t.pad2(e.getMinutes())+":"+t.pad2(e.getSeconds())},incr:function(t){return t.setSeconds(t.getSeconds()+e)}}},t.LABEL_SPECS={decade:{span:1728e8,start:function(e){return new Date(e.getFullYear()-e.getFullYear()%10,0,1)},fmt:function(e){return""+e.getFullYear()},incr:function(e){return e.setFullYear(e.getFullYear()+10)}},year:{span:1728e7,start:function(e){return new Date(e.getFullYear(),0,1)},fmt:function(e){return""+e.getFullYear()},incr:function(e){return e.setFullYear(e.getFullYear()+1)}},month:{span:24192e5,start:function(e){return new Date(e.getFullYear(),e.getMonth(),1)},fmt:function(e){return""+e.getFullYear()+"-"+t.pad2(e.getMonth()+1)},incr:function(e){return e.setMonth(e.getMonth()+1)}},day:{span:864e5,start:function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate())},fmt:function(e){return""+e.getFullYear()+"-"+t.pad2(e.getMonth()+1)+"-"+t.pad2(e.getDate())},incr:function(e){return e.setDate(e.getDate()+1)}},hour:n(60),"30min":n(30),"15min":n(15),"10min":n(10),"5min":n(5),minute:n(1),"30sec":r(30),"15sec":r(15),"10sec":r(10),"5sec":r(5),second:r(1)},t.AUTO_LABEL_ORDER=["decade","year","month","day","hour","30min","15min","10min","5min","minute","30sec","15sec","10sec","5sec","second"],t.Grid=function(n){function r(t){typeof t.element=="string"?this.el=e(document.getElementById(t.element)):this.el=e(t.element);if(this.el==null||this.el.length===0)throw new Error("Graph container element not found");this.options=e.extend({},this.gridDefaults,this.defaults||{},t);if(this.options.data===void 0||this.options.data.length===0)return;typeof this.options.units=="string"&&(this.options.postUnits=t.units),this.r=new Raphael(this.el[0]),this.elementWidth=null,this.elementHeight=null,this.dirty=!1,this.init&&this.init(),this.setData(this.options.data),this.postInit&&this.postInit()}return s(r,n),r.prototype.gridDefaults={dateFormat:null,gridLineColor:"#aaa",gridStrokeWidth:.5,gridTextColor:"#888",gridTextSize:12,numLines:5,padding:25,parseTime:!0,postUnits:"",preUnits:"",ymax:"auto",ymin:"auto 0",goals:[],goalStrokeWidth:1,goalLineColors:["#666633","#999966","#cc6666","#663333"],events:[],eventStrokeWidth:1,eventLineColors:["#005a04","#ccffbb","#3a5f0b","#005502"]},r.prototype.setData=function(e,n){var r,i,s,o,u,a,f,l,c,h,p,d;n==null&&(n=!0),h=this.cumulative?0:null,p=this.cumulative?0:null,this.options.goals.length>0&&(u=Math.min.apply(null,this.options.goals),o=Math.max.apply(null,this.options.goals),p=p!=null?Math.min(p,u):u,h=h!=null?Math.max(h,o):o),this.data=function(){var n,r,o;o=[];for(s=n=0,r=e.length;nt.x)-(t.x>e.x)})),this.xmin=this.data[0].x,this.xmax=this.data[this.data.length-1].x,this.events=[],this.options.parseTime&&this.options.events.length>0&&(this.events=function(){var e,n,i,s;i=this.options.events,s=[];for(e=0,n=i.length;e5?(this.ymax=parseInt(this.options.ymax.slice(5),10),h!=null&&(this.ymax=Math.max(h,this.ymax))):this.ymax=h!=null?h:0:this.ymax=parseInt(this.options.ymax,10):this.ymax=this.options.ymax,typeof this.options.ymin=="string"?this.options.ymin.slice(0,4)==="auto"?this.options.ymin.length>5?(this.ymin=parseInt(this.options.ymin.slice(5),10),p!=null&&(this.ymin=Math.min(p,this.ymin))):this.ymin=p!==null?p:0:this.ymin=parseInt(this.options.ymin,10):this.ymin=this.options.ymin,this.ymin===this.ymax&&(p&&(this.ymin-=1),this.ymax+=1),this.yInterval=(this.ymax-this.ymin)/(this.options.numLines-1),this.yInterval>0&&this.yInterval<1?this.precision=-Math.floor(Math.log(this.yInterval)/Math.log(10)):this.precision=0,this.dirty=!0;if(n)return this.redraw()},r.prototype._calc=function(){var e,t,n;n=this.el.width(),e=this.el.height();if(this.elementWidth!==n||this.elementHeight!==e||this.dirty){this.elementWidth=n,this.elementHeight=e,this.dirty=!1,t=Math.max(this.measureText(this.yAxisFormat(this.ymin),this.options.gridTextSize).width,this.measureText(this.yAxisFormat(this.ymax),this.options.gridTextSize).width),this.left=t+this.options.padding,this.right=this.elementWidth-this.options.padding,this.top=this.options.padding,this.bottom=this.elementHeight-this.options.padding-1.5*this.options.gridTextSize,this.width=this.right-this.left,this.height=this.bottom-this.top,this.dx=this.width/(this.xmax-this.xmin),this.dy=this.height/(this.ymax-this.ymin);if(this.calc)return this.calc()}},r.prototype.transY=function(e){return this.bottom-(e-this.ymin)*this.dy},r.prototype.transX=function(e){return this.data.length===1?(this.left+this.right)/2:this.left+(e-this.xmin)*this.dx},r.prototype.redraw=function(){this.r.clear(),this._calc(),this.drawGrid(),this.drawGoals(),this.drawEvents();if(this.draw)return this.draw()},r.prototype.drawGoals=function(){var e,t,n,r,i,s;i=this.options.goals,s=[];for(t=n=0,r=i.length;n=t;n=s+=o)r=parseFloat(n.toFixed(this.precision)),i=this.transY(r),this.r.text(this.left-this.options.padding/2,i,this.yAxisFormat(r)).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),u.push(this.r.path("M"+this.left+","+i+"H"+(this.left+this.width)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth));return u},r.prototype.measureText=function(e,t){var n,r;return t==null&&(t=12),r=this.r.text(100,100,e).attr("font-size",t),n=r.getBBox(),r.remove(),n},r.prototype.yAxisFormat=function(e){return this.yLabelFormat(e)},r.prototype.yLabelFormat=function(e){return""+this.options.preUnits+t.commas(e)+this.options.postUnits},r}(t.EventEmitter),t.parseDate=function(e){var t,n,r,i,s,o,u,a,f,l,c;return typeof e=="number"?e:(n=e.match(/^(\d+) Q(\d)$/),i=e.match(/^(\d+)-(\d+)$/),s=e.match(/^(\d+)-(\d+)-(\d+)$/),u=e.match(/^(\d+) W(\d+)$/),a=e.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/),f=e.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/),n?(new Date(parseInt(n[1],10),parseInt(n[2],10)*3-1,1)).getTime():i?(new Date(parseInt(i[1],10),parseInt(i[2],10)-1,1)).getTime():s?(new Date(parseInt(s[1],10),parseInt(s[2],10)-1,parseInt(s[3],10))).getTime():u?(l=new Date(parseInt(u[1],10),0,1),l.getDay()!==4&&l.setMonth(0,1+(4-l.getDay()+7)%7),l.getTime()+parseInt(u[2],10)*6048e5):a?a[6]?(o=0,a[6]!=="Z"&&(o=parseInt(a[8],10)*60+parseInt(a[9],10),a[7]==="+"&&(o=0-o)),Date.UTC(parseInt(a[1],10),parseInt(a[2],10)-1,parseInt(a[3],10),parseInt(a[4],10),parseInt(a[5],10)+o)):(new Date(parseInt(a[1],10),parseInt(a[2],10)-1,parseInt(a[3],10),parseInt(a[4],10),parseInt(a[5],10))).getTime():f?(c=parseFloat(f[6]),t=Math.floor(c),r=Math.round((c-t)*1e3),f[8]?(o=0,f[8]!=="Z"&&(o=parseInt(f[10],10)*60+parseInt(f[11],10),f[9]==="+"&&(o=0-o)),Date.UTC(parseInt(f[1],10),parseInt(f[2],10)-1,parseInt(f[3],10),parseInt(f[4],10),parseInt(f[5],10)+o,t,r)):(new Date(parseInt(f[1],10),parseInt(f[2],10)-1,parseInt(f[3],10),parseInt(f[4],10),parseInt(f[5],10),t,r)).getTime()):(new Date(parseInt(e,10),0,1)).getTime())},t.Hover={hoverConfigure:function(t){return this.hoverOptions=e.extend({},this.hoverDefaults,t!=null?t:{})},hoverInit:function(){if(this.hoverOptions.enableHover)return this.hover=this.hoverBuild(),this.hoverBindEvents(),this.hoverShow(this.hoverOptions.hideHover?null:this.data.length-1)},hoverDefaults:{enableHover:!0,popupClass:"morris-popup",hideHover:!1,allowOverflow:!1,pointMargin:10,hoverFill:function(e,t){return this.hoverFill(e,t)}},hoverBindEvents:function(){var e,t=this;return this.el.mousemove(function(e){return t.hoverUpdate(e.pageX)}),this.hoverOptions.hideHover&&this.el.mouseout(function(e){return t.hoverShow(null)}),e=function(e){var n;return n=e.originalEvent.touches[0]||e.originalEvent.changedTouches[0],t.hoverUpdate(n.pageX),n},this.el.bind("touchstart",e),this.el.bind("touchmove",e),this.el.bind("touchend",e),this.hover.mousemove(function(e){return e.stopPropagation()}),this.hover.mouseout(function(e){return e.stopPropagation()}),this.hover.bind("touchstart",function(e){return e.stopPropagation()}),this.hover.bind("touchmove",function(e){return e.stopPropagation()}),this.hover.bind("touchend",function(e){return e.stopPropagation()})},hoverCalculateMargins:function(){var e;return this.hoverMargins=function(){var t,n,r;r=[];for(e=t=1,n=this.data.length;1<=n?tn;e=1<=n?++t:--t)r.push(this.left+e*this.width/this.data.length);return r}.call(this)},hoverBuild:function(){var t;return t=e("
"),t.addClass(""+this.hoverOptions.popupClass+" js-morris-popup"),t.appendTo(this.el),t.hide(),t},hoverUpdate:function(e){var t,n,r;e-=this.el.offset().left;for(t=n=0,r=this.hoverMargins.length;0<=r?nr;t=0<=r?++n:--n)if(this.hoverMargins[t]>e)break;return this.hoverShow(t)},hoverShow:function(e){e!==null&&(this.hover.html(""),this.hoverOptions.hoverFill.call(this,e,this.data[e]),this.hoverPosition(e),this.fire("hover.show",e),this.hover.show());if(e==null)return this.hoverHide()},hoverHide:function(){return this.hover.hide()},colorFor:function(e,t,n){return"inherit"},yLabelFormat:function(e){return t.commas(e)},hoverPosition:function(e){var t,n,r;return r=this.hoverGetPosition(e),t=r[0],n=r[1],this.hover.css({top:""+(this.el.offset().top+n)+"px",left:""+(this.el.offset().left+t)+"px"})},hoverGetPosition:function(e){var t,n,r,i;return n=this.data[e],this.hoverWidth=this.hover.outerWidth(!0),this.hoverHeight=this.hover.outerHeight(!0),t=i=Math.min.apply(null,function(){var e,t,r,s;r=n._y,s=[];for(e=0,t=r.length;ethis.right-this.hoverWidth&&(r=n._x-this.hoverWidth-this.hoverOptions.pointMargin),i=Math.max(i,this.top),i=Math.min(i,this.bottom-this.hoverHeight-this.hoverOptions.pointMargin),i-t"),i.text(n.label),i.appendTo(this.hover),f=n.y,l=[];for(r=u=0,a=f.length;u"),o.css("color",this.colorFor(n,r,"hover")),o.text(""+this.options.labels[r]+": "+this.yLabelFormat(s)),l.push(o.appendTo(this.hover));return l}},t.Line=function(e){function n(e){this.updateHilight=u(this.updateHilight,this),this.hilight=u(this.hilight,this);if(!(this instanceof t.Line))return new t.Line(e);n.__super__.constructor.call(this,e)}return s(n,e),n.include(t.Hover),n.prototype.init=function(){var e,t=this;this.pointGrow=Raphael.animation({r:this.options.pointSize+3},25,"linear"),this.pointShrink=Raphael.animation({r:this.options.pointSize},25,"linear"),this.hoverConfigure(this.options.hoverOptions);if(this.options.hilight)return this.prevHilight=null,this.el.mousemove(function(e){return t.updateHilight(e.pageX)}),this.options.hilightAutoHide&&this.el.mouseout(function(e){return t.hilight(null)}),e=function(e){var n;return n=e.originalEvent.touches[0]||e.originalEvent.changedTouches[0],t.updateHilight(n.pageX),n},this.el.bind("touchstart",e),this.el.bind("touchmove",e),this.el.bind("touchend",e)},n.prototype.postInit=function(){return this.hoverInit()},n.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],pointWidths:[1],pointStrokeColors:["#ffffff"],pointFillColors:[],smooth:!0,hilight:!0,hilightAutoHide:!1,xLabels:"auto",xLabelFormat:null,continuousLine:!0},n.prototype.calc=function(){return this.calcPoints(),this.hoverCalculateMargins(),this.generatePaths(),this.calcHilightMargins()},n.prototype.calcPoints=function(){var e,t,n,r,i,s;i=this.data,s=[];for(n=0,r=i.length;nu;r=0<=u?++o:--o)s=this.options.smooth===!0||(f=this.options.ykeys[r],a.call(this.options.smooth,f)>=0),n=function(){var e,t,n,s;n=this.data,s=[];for(e=0,t=n.length;e1?l.push(t.Line.createPath(n,s,this.bottom)):l.push(null);return l}.call(this)},n.prototype.draw=function(){this.drawXAxis(),this.drawSeries();if(this.options.hilight)return this.hilight(this.options.hilightAutoHide?null:this.data.length-1)},n.prototype.drawXAxis=function(){var e,n,r,i,s,o,u,a,f,l,c=this;u=this.bottom+this.options.gridTextSize*1.25,o=50,i=null,e=function(e,t){var n,r;return n=c.r.text(c.transX(t),u,e).attr("font-size",c.options.gridTextSize).attr("fill",c.options.gridTextColor),r=n.getBBox(),(i==null||i>=r.x+r.width)&&r.x>=0&&r.x+r.width=0;t=o<=0?++i:--i)n=this.paths[t],n!==null&&this.r.path(n).attr("stroke",this.colorFor(r,t,"line")).attr("stroke-width",this.options.lineWidth);this.seriesPoints=function(){var e,n,r;r=[];for(t=e=0,n=this.options.ykeys.length;0<=n?en;t=0<=n?++e:--e)r.push([]);return r}.call(this),a=[];for(t=s=u=this.options.ykeys.length-1;u<=0?s<=0:s>=0;t=u<=0?++s:--s)a.push(function(){var n,i,s,o;s=this.data,o=[];for(n=0,i=s.length;n=i;t=0<=i?++n:--n)this.seriesPoints[t][this.prevHilight]&&this.seriesPoints[t][this.prevHilight].animate(this.pointShrink);if(e!==null&&this.prevHilight!==e)for(t=r=0,s=this.seriesPoints.length-1;0<=s?r<=s:r>=s;t=0<=s?++r:--r)this.seriesPoints[t][e]&&this.seriesPoints[t][e].animate(this.pointGrow);return this.prevHilight=e},n.prototype.updateHilight=function(e){var t,n,r;e-=this.el.offset().left;for(t=n=0,r=this.hilightMargins.length;0<=r?nr;t=0<=r?++n:--n)if(this.hilightMargins[t]>e)break;return this.hilight(t)},n.prototype.strokeWidthForSeries=function(e){return this.options.pointWidths[e%this.options.pointWidths.length]},n.prototype.strokeForSeries=function(e){return this.options.pointStrokeColors[e%this.options.pointStrokeColors.length]},n.prototype.colorFor=function(e,t,n){return typeof this.options.lineColors=="function"?this.options.lineColors.call(this,e,t,n):n==="point"?this.options.pointFillColors[t%this.options.pointFillColors.length]||this.options.lineColors[t%this.options.lineColors.length]:this.options.lineColors[t%this.options.lineColors.length]},n}(t.Grid),t.Area=function(e){function n(e){if(!(this instanceof t.Area))return new t.Area(e);this.cumulative=!0,n.__super__.constructor.call(this,e)}return s(n,e),n.prototype.calcPoints=function(){var e,t,n,r,i,s,o;s=this.data,o=[];for(r=0,i=s.length;r=0;e=i<=0?++r:--r)t=this.paths[e],t!==null&&(t+="L"+this.transX(this.xmax)+","+this.bottom+"L"+this.transX(this.xmin)+","+this.bottom+"Z",this.r.path(t).attr("fill",this.fillForSeries(e)).attr("stroke-width",0));return n.__super__.drawSeries.call(this)},n.prototype.fillForSeries=function(e){var t;return t=Raphael.rgb2hsl(this.colorFor(this.data[e],e,"line")),Raphael.hsl(t.h,Math.min(255,t.s*.75),Math.min(255,t.l*1.25))},n}(t.Line),t.Bar=function(n){function r(n){if(!(this instanceof t.Bar))return new t.Bar(n);r.__super__.constructor.call(this,e.extend({},n,{parseTime:!1}))}return s(r,n),r.include(t.Hover),r.prototype.hoverGetPosition=function(e){var n,r,i;return i=t.Hover.hoverGetPosition.call(this,e),n=i[0],r=i[1],[n,(this.top+this.bottom)/2-this.hoverHeight/2]},r.prototype.init=function(){return this.cumulative=this.options.stacked,this.hoverConfigure(this.options.hoverOptions)},r.prototype.postInit=function(){return this.hoverInit()},r.prototype.defaults={barSizeRatio:.75,barGap:3,barColors:["#0b62a4","#7a92a3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"]},r.prototype.calc=function(){return this.calcBars(),this.hoverCalculateMargins()},r.prototype.calcBars=function(){var e,t,n,r,i,s,o;s=this.data,o=[];for(e=r=0,i=s.length;ra;e=0<=a?++u:--u)i=this.data[this.data.length-1-e],t=this.r.text(i._x,o,i.label).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),n=t.getBBox(),(r==null||r>=n.x+n.width)&&n.x>=0&&n.x+n.width=0?this.transY(0):null,this.bars=function(){var u,d,v,m;v=this.data,m=[];for(r=u=0,d=v.length;uMath.PI?1:0,this.path=this.calcSegment(this.inner+3,this.inner+this.outer-5),this.selectedPath=this.calcSegment(this.inner+3,this.inner+this.outer),this.hilight=this.calcArc(this.inner)}return s(t,e),t.prototype.calcArcPoints=function(e){return[this.cx+e*this.sin_p0,this.cy+e*this.cos_p0,this.cx+e*this.sin_p1,this.cy+e*this.cos_p1]},t.prototype.calcSegment=function(e,t){var n,r,i,s,o,u,a,f,l,c;return l=this.calcArcPoints(e),n=l[0],i=l[1],r=l[2],s=l[3],c=this.calcArcPoints(t),o=c[0],a=c[1],u=c[2],f=c[3],"M"+n+","+i+("A"+e+","+e+",0,"+this.long+",0,"+r+","+s)+("L"+u+","+f)+("A"+t+","+t+",0,"+this.long+",1,"+o+","+a)+"Z"},t.prototype.calcArc=function(e){var t,n,r,i,s;return s=this.calcArcPoints(e),t=s[0],r=s[1],n=s[2],i=s[3],"M"+t+","+r+("A"+e+","+e+",0,"+this.long+",0,"+n+","+i)},t.prototype.render=function(e){var t=this;return this.arc=e.path(this.hilight).attr({stroke:this.color,"stroke-width":2,opacity:0}),this.seg=e.path(this.path).attr({fill:this.color,stroke:"white","stroke-width":3}).hover(function(){return t.fire("hover",t)})},t.prototype.select=function(){if(!this.selected)return this.seg.animate({path:this.selectedPath},150,"<>"),this.arc.animate({opacity:1},150,"<>"),this.selected=!0},t.prototype.deselect=function(){if(this.selected)return this.seg.animate({path:this.path},150,"<>"),this.arc.animate({opacity:0},150,"<>"),this.selected=!1},t}(t.EventEmitter)}).call(this); \ No newline at end of file +(function(){var e,t,n,r,i=[].slice,s={}.hasOwnProperty,o=function(e,t){function r(){this.constructor=e}for(var n in t)s.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e},u=function(e,t){return function(){return e.apply(t,arguments)}},a=[].indexOf||function(e){for(var t=0,n=this.length;tn.length&&(r+=i.slice(n.length)),r):"-"},t.pad2=function(e){return(e<10?"0":"")+e},t.Grid=function(n){function r(t){typeof t.element=="string"?this.el=e(document.getElementById(t.element)):this.el=e(t.element);if(this.el==null||this.el.length===0)throw new Error("Graph container element not found");this.options=e.extend({},this.gridDefaults,this.defaults||{},t);if(this.options.data===void 0||this.options.data.length===0)return;typeof this.options.units=="string"&&(this.options.postUnits=t.units),this.r=new Raphael(this.el[0]),this.elementWidth=null,this.elementHeight=null,this.dirty=!1,this.init&&this.init(),this.setData(this.options.data),this.postInit&&this.postInit()}return o(r,n),r.prototype.gridDefaults={dateFormat:null,gridLineColor:"#aaa",gridStrokeWidth:.5,gridTextColor:"#888",gridTextSize:12,numLines:5,padding:25,parseTime:!0,postUnits:"",preUnits:"",ymax:"auto",ymin:"auto 0",goals:[],goalStrokeWidth:1,goalLineColors:["#666633","#999966","#cc6666","#663333"],events:[],eventStrokeWidth:1,eventLineColors:["#005a04","#ccffbb","#3a5f0b","#005502"]},r.prototype.setData=function(e,n){var r,i,s,o,u,a,f,l,c,h,p,d;n==null&&(n=!0),h=this.cumulative?0:null,p=this.cumulative?0:null,this.options.goals.length>0&&(u=Math.min.apply(null,this.options.goals),o=Math.max.apply(null,this.options.goals),p=p!=null?Math.min(p,u):u,h=h!=null?Math.max(h,o):o),this.data=function(){var n,r,o;o=[];for(s=n=0,r=e.length;nt.x)-(t.x>e.x)})),this.xmin=this.data[0].x,this.xmax=this.data[this.data.length-1].x,this.events=[],this.options.parseTime&&this.options.events.length>0&&(this.events=function(){var e,n,i,s;i=this.options.events,s=[];for(e=0,n=i.length;e5?(this.ymax=parseInt(this.options.ymax.slice(5),10),h!=null&&(this.ymax=Math.max(h,this.ymax))):this.ymax=h!=null?h:0:this.ymax=parseInt(this.options.ymax,10):this.ymax=this.options.ymax,typeof this.options.ymin=="string"?this.options.ymin.slice(0,4)==="auto"?this.options.ymin.length>5?(this.ymin=parseInt(this.options.ymin.slice(5),10),p!=null&&(this.ymin=Math.min(p,this.ymin))):this.ymin=p!==null?p:0:this.ymin=parseInt(this.options.ymin,10):this.ymin=this.options.ymin,this.ymin===this.ymax&&(p&&(this.ymin-=1),this.ymax+=1),this.yInterval=(this.ymax-this.ymin)/(this.options.numLines-1),this.yInterval>0&&this.yInterval<1?this.precision=-Math.floor(Math.log(this.yInterval)/Math.log(10)):this.precision=0,this.dirty=!0;if(n)return this.redraw()},r.prototype._calc=function(){var e,t,n;n=this.el.width(),e=this.el.height();if(this.elementWidth!==n||this.elementHeight!==e||this.dirty){this.elementWidth=n,this.elementHeight=e,this.dirty=!1,t=Math.max(this.measureText(this.yAxisFormat(this.ymin),this.options.gridTextSize).width,this.measureText(this.yAxisFormat(this.ymax),this.options.gridTextSize).width),this.left=t+this.options.padding,this.right=this.elementWidth-this.options.padding,this.top=this.options.padding,this.bottom=this.elementHeight-this.options.padding-1.5*this.options.gridTextSize,this.width=this.right-this.left,this.height=this.bottom-this.top,this.dx=this.width/(this.xmax-this.xmin),this.dy=this.height/(this.ymax-this.ymin);if(this.calc)return this.calc()}},r.prototype.transY=function(e){return this.bottom-(e-this.ymin)*this.dy},r.prototype.transX=function(e){return this.data.length===1?(this.left+this.right)/2:this.left+(e-this.xmin)*this.dx},r.prototype.redraw=function(){this.r.clear(),this._calc(),this.drawGrid(),this.drawGoals(),this.drawEvents();if(this.draw)return this.draw()},r.prototype.drawGoals=function(){var e,t,n,r,i,s;i=this.options.goals,s=[];for(t=n=0,r=i.length;n=t;n=s+=o)r=parseFloat(n.toFixed(this.precision)),i=this.transY(r),this.r.text(this.left-this.options.padding/2,i,this.yAxisFormat(r)).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor).attr("text-anchor","end"),u.push(this.r.path("M"+this.left+","+i+"H"+(this.left+this.width)).attr("stroke",this.options.gridLineColor).attr("stroke-width",this.options.gridStrokeWidth));return u},r.prototype.measureText=function(e,t){var n,r;return t==null&&(t=12),r=this.r.text(100,100,e).attr("font-size",t),n=r.getBBox(),r.remove(),n},r.prototype.yAxisFormat=function(e){return this.yLabelFormat(e)},r.prototype.yLabelFormat=function(e){return""+this.options.preUnits+t.commas(e)+this.options.postUnits},r.prototype.hoverConfigure=function(t){return this.hoverOptions=e.extend({},this.hoverDefaults,t!=null?t:{})},r.prototype.hoverInit=function(){if(this.hoverOptions.enableHover)return this.hover=this.hoverBuild(),this.hoverBindEvents(),this.hoverShow(this.hoverOptions.hideHover?null:this.data.length-1)},r.prototype.hoverDefaults={enableHover:!0,popupClass:"morris-popup",hideHover:!1,allowOverflow:!1,pointMargin:10,hoverFill:function(e,t){return this.hoverFill(e,t)}},r.prototype.hoverBindEvents=function(){var e,t=this;return this.el.mousemove(function(e){return t.hoverUpdate(e.pageX)}),this.hoverOptions.hideHover&&this.el.mouseout(function(e){return t.hoverShow(null)}),e=function(e){var n;return n=e.originalEvent.touches[0]||e.originalEvent.changedTouches[0],t.hoverUpdate(n.pageX),n},this.el.bind("touchstart",e),this.el.bind("touchmove",e),this.el.bind("touchend",e),this.hover.mousemove(function(e){return e.stopPropagation()}),this.hover.mouseout(function(e){return e.stopPropagation()}),this.hover.bind("touchstart",function(e){return e.stopPropagation()}),this.hover.bind("touchmove",function(e){return e.stopPropagation()}),this.hover.bind("touchend",function(e){return e.stopPropagation()})},r.prototype.hoverCalculateMargins=function(){var e;return this.hoverMargins=function(){var t,n,r;r=[];for(e=t=1,n=this.data.length;1<=n?tn;e=1<=n?++t:--t)r.push(this.left+e*this.width/this.data.length);return r}.call(this)},r.prototype.hoverBuild=function(){var t;return t=e("
"),t.addClass(""+this.hoverOptions.popupClass+" js-morris-popup"),t.appendTo(this.el),t.hide(),t},r.prototype.hoverUpdate=function(e){var t,n,r;e-=this.el.offset().left;for(t=n=0,r=this.hoverMargins.length;0<=r?nr;t=0<=r?++n:--n)if(this.hoverMargins[t]>e)break;return this.hoverShow(t)},r.prototype.hoverShow=function(e){e!==null&&(this.hover.html(""),this.hoverOptions.hoverFill.call(this,e,this.data[e]),this.hoverPosition(e),this.fire("hover.show",e),this.hover.show());if(e==null)return this.hoverHide()},r.prototype.hoverHide=function(){return this.hover.hide()},r.prototype.colorFor=function(e,t,n){return"inherit"},r.prototype.yLabelFormat=function(e){return t.commas(e)},r.prototype.hoverPosition=function(e){var t,n,r;return r=this.hoverGetPosition(e),t=r[0],n=r[1],this.hover.css({top:""+(this.el.offset().top+n)+"px",left:""+(this.el.offset().left+t)+"px"})},r.prototype.hoverGetPosition=function(e){var t,n,r,i;return n=this.data[e],this.hoverWidth=this.hover.outerWidth(!0),this.hoverHeight=this.hover.outerHeight(!0),t=i=Math.min.apply(null,function(){var e,t,r,s;r=n._y,s=[];for(e=0,t=r.length;ethis.right-this.hoverWidth&&(r=n._x-this.hoverWidth-this.hoverOptions.pointMargin),i=Math.max(i,this.top),i=Math.min(i,this.bottom-this.hoverHeight-this.hoverOptions.pointMargin),i-t"),i.text(n.label),i.appendTo(this.hover),f=n.y,l=[];for(r=u=0,a=f.length;u"),o.css("color",this.colorFor(n,r,"hover")),o.text(""+this.options.labels[r]+": "+this.yLabelFormat(s)),l.push(o.appendTo(this.hover));return l},r}(t.EventEmitter),t.parseDate=function(e){var t,n,r,i,s,o,u,a,f,l,c;return typeof e=="number"?e:(n=e.match(/^(\d+) Q(\d)$/),i=e.match(/^(\d+)-(\d+)$/),s=e.match(/^(\d+)-(\d+)-(\d+)$/),u=e.match(/^(\d+) W(\d+)$/),a=e.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/),f=e.match(/^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/),n?(new Date(parseInt(n[1],10),parseInt(n[2],10)*3-1,1)).getTime():i?(new Date(parseInt(i[1],10),parseInt(i[2],10)-1,1)).getTime():s?(new Date(parseInt(s[1],10),parseInt(s[2],10)-1,parseInt(s[3],10))).getTime():u?(l=new Date(parseInt(u[1],10),0,1),l.getDay()!==4&&l.setMonth(0,1+(4-l.getDay()+7)%7),l.getTime()+parseInt(u[2],10)*6048e5):a?a[6]?(o=0,a[6]!=="Z"&&(o=parseInt(a[8],10)*60+parseInt(a[9],10),a[7]==="+"&&(o=0-o)),Date.UTC(parseInt(a[1],10),parseInt(a[2],10)-1,parseInt(a[3],10),parseInt(a[4],10),parseInt(a[5],10)+o)):(new Date(parseInt(a[1],10),parseInt(a[2],10)-1,parseInt(a[3],10),parseInt(a[4],10),parseInt(a[5],10))).getTime():f?(c=parseFloat(f[6]),t=Math.floor(c),r=Math.round((c-t)*1e3),f[8]?(o=0,f[8]!=="Z"&&(o=parseInt(f[10],10)*60+parseInt(f[11],10),f[9]==="+"&&(o=0-o)),Date.UTC(parseInt(f[1],10),parseInt(f[2],10)-1,parseInt(f[3],10),parseInt(f[4],10),parseInt(f[5],10)+o,t,r)):(new Date(parseInt(f[1],10),parseInt(f[2],10)-1,parseInt(f[3],10),parseInt(f[4],10),parseInt(f[5],10),t,r)).getTime()):(new Date(parseInt(e,10),0,1)).getTime())},t.Hover=function(){function n(n){n==null&&(n={}),this.options=e.extend({},t.Hover.defaults,n),this.el=e("
"),this.el.hide()}return n.defaults={"class":"morris-popup",allowOverflow:!1},n.prototype.show=function(e,t,n){return typeof this.options.content=="function"?this.el.html(this.options.content(n)):this.el.html(this.options.content),this.el.show()},n.prototype.hide=function(){return this.el.hide()},n}(),t.Line=function(e){function n(e){this.updateHilight=u(this.updateHilight,this),this.hilight=u(this.hilight,this);if(!(this instanceof t.Line))return new t.Line(e);n.__super__.constructor.call(this,e)}return o(n,e),n.prototype.init=function(){var e,t=this;this.pointGrow=Raphael.animation({r:this.options.pointSize+3},25,"linear"),this.pointShrink=Raphael.animation({r:this.options.pointSize},25,"linear"),this.hoverConfigure(this.options.hoverOptions);if(this.options.hilight)return this.prevHilight=null,this.el.mousemove(function(e){return t.updateHilight(e.pageX)}),this.options.hilightAutoHide&&this.el.mouseout(function(e){return t.hilight(null)}),e=function(e){var n;return n=e.originalEvent.touches[0]||e.originalEvent.changedTouches[0],t.updateHilight(n.pageX),n},this.el.bind("touchstart",e),this.el.bind("touchmove",e),this.el.bind("touchend",e)},n.prototype.postInit=function(){return this.hoverInit()},n.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],pointWidths:[1],pointStrokeColors:["#ffffff"],pointFillColors:[],smooth:!0,hilight:!0,hilightAutoHide:!1,xLabels:"auto",xLabelFormat:null,continuousLine:!0},n.prototype.calc=function(){return this.calcPoints(),this.hoverCalculateMargins(),this.generatePaths(),this.calcHilightMargins()},n.prototype.calcPoints=function(){var e,t,n,r,i,s;i=this.data,s=[];for(n=0,r=i.length;nu;r=0<=u?++o:--o)s=this.options.smooth===!0||(f=this.options.ykeys[r],a.call(this.options.smooth,f)>=0),n=function(){var e,t,n,s;n=this.data,s=[];for(e=0,t=n.length;e1?l.push(t.Line.createPath(n,s,this.bottom)):l.push(null);return l}.call(this)},n.prototype.draw=function(){this.drawXAxis(),this.drawSeries();if(this.options.hilight)return this.hilight(this.options.hilightAutoHide?null:this.data.length-1)},n.prototype.drawXAxis=function(){var e,n,r,i,s,o,u,a,f,l,c=this;u=this.bottom+this.options.gridTextSize*1.25,o=50,i=null,e=function(e,t){var n,r;return n=c.r.text(c.transX(t),u,e).attr("font-size",c.options.gridTextSize).attr("fill",c.options.gridTextColor),r=n.getBBox(),(i==null||i>=r.x+r.width)&&r.x>=0&&r.x+r.width=0;t=o<=0?++i:--i)n=this.paths[t],n!==null&&this.r.path(n).attr("stroke",this.colorFor(r,t,"line")).attr("stroke-width",this.options.lineWidth);this.seriesPoints=function(){var e,n,r;r=[];for(t=e=0,n=this.options.ykeys.length;0<=n?en;t=0<=n?++e:--e)r.push([]);return r}.call(this),a=[];for(t=s=u=this.options.ykeys.length-1;u<=0?s<=0:s>=0;t=u<=0?++s:--s)a.push(function(){var n,i,s,o;s=this.data,o=[];for(n=0,i=s.length;n=i;t=0<=i?++n:--n)this.seriesPoints[t][this.prevHilight]&&this.seriesPoints[t][this.prevHilight].animate(this.pointShrink);if(e!==null&&this.prevHilight!==e)for(t=r=0,s=this.seriesPoints.length-1;0<=s?r<=s:r>=s;t=0<=s?++r:--r)this.seriesPoints[t][e]&&this.seriesPoints[t][e].animate(this.pointGrow);return this.prevHilight=e},n.prototype.updateHilight=function(e){var t,n,r;e-=this.el.offset().left;for(t=n=0,r=this.hilightMargins.length;0<=r?nr;t=0<=r?++n:--n)if(this.hilightMargins[t]>e)break;return this.hilight(t)},n.prototype.strokeWidthForSeries=function(e){return this.options.pointWidths[e%this.options.pointWidths.length]},n.prototype.strokeForSeries=function(e){return this.options.pointStrokeColors[e%this.options.pointStrokeColors.length]},n.prototype.colorFor=function(e,t,n){return typeof this.options.lineColors=="function"?this.options.lineColors.call(this,e,t,n):n==="point"?this.options.pointFillColors[t%this.options.pointFillColors.length]||this.options.lineColors[t%this.options.lineColors.length]:this.options.lineColors[t%this.options.lineColors.length]},n}(t.Grid),t.labelSeries=function(n,r,i,s,o){var u,a,f,l,c,h,p,d,v,m,g;f=200*(r-n)/i,a=new Date(n),p=t.LABEL_SPECS[s];if(p===void 0){g=t.AUTO_LABEL_ORDER;for(v=0,m=g.length;v=h.span){p=h;break}}}p===void 0&&(p=t.LABEL_SPECS.second),o&&(p=e.extend({},p,{fmt:o})),u=p.start(a),c=[];while((d=u.getTime())<=r)d>=n&&c.push([p.fmt(u),d]),p.incr(u);return c},n=function(e){return{span:e*60*1e3,start:function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours())},fmt:function(e){return""+t.pad2(e.getHours())+":"+t.pad2(e.getMinutes())},incr:function(t){return t.setMinutes(t.getMinutes()+e)}}},r=function(e){return{span:e*1e3,start:function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes())},fmt:function(e){return""+t.pad2(e.getHours())+":"+t.pad2(e.getMinutes())+":"+t.pad2(e.getSeconds())},incr:function(t){return t.setSeconds(t.getSeconds()+e)}}},t.LABEL_SPECS={decade:{span:1728e8,start:function(e){return new Date(e.getFullYear()-e.getFullYear()%10,0,1)},fmt:function(e){return""+e.getFullYear()},incr:function(e){return e.setFullYear(e.getFullYear()+10)}},year:{span:1728e7,start:function(e){return new Date(e.getFullYear(),0,1)},fmt:function(e){return""+e.getFullYear()},incr:function(e){return e.setFullYear(e.getFullYear()+1)}},month:{span:24192e5,start:function(e){return new Date(e.getFullYear(),e.getMonth(),1)},fmt:function(e){return""+e.getFullYear()+"-"+t.pad2(e.getMonth()+1)},incr:function(e){return e.setMonth(e.getMonth()+1)}},day:{span:864e5,start:function(e){return new Date(e.getFullYear(),e.getMonth(),e.getDate())},fmt:function(e){return""+e.getFullYear()+"-"+t.pad2(e.getMonth()+1)+"-"+t.pad2(e.getDate())},incr:function(e){return e.setDate(e.getDate()+1)}},hour:n(60),"30min":n(30),"15min":n(15),"10min":n(10),"5min":n(5),minute:n(1),"30sec":r(30),"15sec":r(15),"10sec":r(10),"5sec":r(5),second:r(1)},t.AUTO_LABEL_ORDER=["decade","year","month","day","hour","30min","15min","10min","5min","minute","30sec","15sec","10sec","5sec","second"],t.Area=function(e){function n(e){if(!(this instanceof t.Area))return new t.Area(e);this.cumulative=!0,n.__super__.constructor.call(this,e)}return o(n,e),n.prototype.calcPoints=function(){var e,t,n,r,i,s,o;s=this.data,o=[];for(r=0,i=s.length;r=0;e=i<=0?++r:--r)t=this.paths[e],t!==null&&(t+="L"+this.transX(this.xmax)+","+this.bottom+"L"+this.transX(this.xmin)+","+this.bottom+"Z",this.r.path(t).attr("fill",this.fillForSeries(e)).attr("stroke-width",0));return n.__super__.drawSeries.call(this)},n.prototype.fillForSeries=function(e){var t;return t=Raphael.rgb2hsl(this.colorFor(this.data[e],e,"line")),Raphael.hsl(t.h,Math.min(255,t.s*.75),Math.min(255,t.l*1.25))},n}(t.Line),t.Bar=function(n){function r(n){if(!(this instanceof t.Bar))return new t.Bar(n);r.__super__.constructor.call(this,e.extend({},n,{parseTime:!1}))}return o(r,n),r.prototype.init=function(){return this.cumulative=this.options.stacked,this.hoverConfigure(this.options.hoverOptions)},r.prototype.postInit=function(){return this.hoverInit()},r.prototype.defaults={barSizeRatio:.75,barGap:3,barColors:["#0b62a4","#7a92a3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"]},r.prototype.calc=function(){return this.calcBars(),this.hoverCalculateMargins()},r.prototype.calcBars=function(){var e,t,n,r,i,s,o;s=this.data,o=[];for(e=r=0,i=s.length;ra;e=0<=a?++u:--u)i=this.data[this.data.length-1-e],t=this.r.text(i._x,o,i.label).attr("font-size",this.options.gridTextSize).attr("fill",this.options.gridTextColor),n=t.getBBox(),(r==null||r>=n.x+n.width)&&n.x>=0&&n.x+n.width=0?this.transY(0):null,this.bars=function(){var u,d,v,m;v=this.data,m=[];for(r=u=0,d=v.length;uMath.PI?1:0,this.path=this.calcSegment(this.inner+3,this.inner+this.outer-5),this.selectedPath=this.calcSegment(this.inner+3,this.inner+this.outer),this.hilight=this.calcArc(this.inner)}return o(t,e),t.prototype.calcArcPoints=function(e){return[this.cx+e*this.sin_p0,this.cy+e*this.cos_p0,this.cx+e*this.sin_p1,this.cy+e*this.cos_p1]},t.prototype.calcSegment=function(e,t){var n,r,i,s,o,u,a,f,l,c;return l=this.calcArcPoints(e),n=l[0],i=l[1],r=l[2],s=l[3],c=this.calcArcPoints(t),o=c[0],a=c[1],u=c[2],f=c[3],"M"+n+","+i+("A"+e+","+e+",0,"+this.long+",0,"+r+","+s)+("L"+u+","+f)+("A"+t+","+t+",0,"+this.long+",1,"+o+","+a)+"Z"},t.prototype.calcArc=function(e){var t,n,r,i,s;return s=this.calcArcPoints(e),t=s[0],r=s[1],n=s[2],i=s[3],"M"+t+","+r+("A"+e+","+e+",0,"+this.long+",0,"+n+","+i)},t.prototype.render=function(e){var t=this;return this.arc=e.path(this.hilight).attr({stroke:this.color,"stroke-width":2,opacity:0}),this.seg=e.path(this.path).attr({fill:this.color,stroke:"white","stroke-width":3}).hover(function(){return t.fire("hover",t)})},t.prototype.select=function(){if(!this.selected)return this.seg.animate({path:this.selectedPath},150,"<>"),this.arc.animate({opacity:1},150,"<>"),this.selected=!0},t.prototype.deselect=function(){if(this.selected)return this.seg.animate({path:this.path},150,"<>"),this.arc.animate({opacity:0},150,"<>"),this.selected=!1},t}(t.EventEmitter)}).call(this); \ No newline at end of file