diff --git a/examples/bar.html b/examples/bar.html
new file mode 100644
index 00000000..eba7186a
--- /dev/null
+++ b/examples/bar.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+Bar charts
+
+
+// Use Morris.Bar
+Morris.Bar({
+ element: 'graph',
+ data: [
+ {x: '2011 Q1', y: 3, z: 2, a: 3},
+ {x: '2011 Q2', y: 2, z: 1, a: 1},
+ {x: '2011 Q3', y: 0, z: 2, a: 4},
+ {x: '2011 Q4', y: 4, z: 4, a: 3}
+ ],
+ xkey: 'x',
+ ykeys: ['y', 'z', 'a'],
+ labels: ['Y', 'Z', 'A']
+});
+
+
\ No newline at end of file
diff --git a/grunt.js b/grunt.js
index 330fd37b..8bee7a46 100644
--- a/grunt.js
+++ b/grunt.js
@@ -18,6 +18,7 @@ module.exports = function (grunt) {
'lib/morris.grid.coffee',
'lib/morris.line.coffee',
'lib/morris.area.coffee',
+ 'lib/morris.bar.coffee',
'lib/morris.donut.coffee'
],
'build/spec.coffee': ['spec/support/**/*.coffee', 'spec/lib/**/*.coffee']
diff --git a/lib/morris.bar.coffee b/lib/morris.bar.coffee
new file mode 100644
index 00000000..afd0479b
--- /dev/null
+++ b/lib/morris.bar.coffee
@@ -0,0 +1,315 @@
+class Morris.Bar extends Morris.Grid
+ # Initialise the graph.
+ #
+ constructor: (options) ->
+ return new Morris.Bar(options) unless (@ instanceof Morris.Bar)
+ super(options)
+
+ init: ->
+ # Some instance variables for later
+ @barFace = Raphael.animation opacity: @options.barHoverOpacity, 25, 'linear'
+ @barDeface = Raphael.animation opacity: 1.0, 25, 'linear'
+ # data hilight events
+ @prevHilight = null
+ @el.mousemove (evt) =>
+ @updateHilight evt.pageX
+ if @options.hideHover
+ @el.mouseout (evt) =>
+ @hilight null
+ touchHandler = (evt) =>
+ touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0]
+ @updateHilight touch.pageX
+ return touch
+ @el.bind 'touchstart', touchHandler
+ @el.bind 'touchmove', touchHandler
+ @el.bind 'touchend', touchHandler
+
+ # Default configuration
+ #
+ defaults:
+ barSizeRatio: 0.5
+ barGap: 3
+ barStrokeWidths: [0]
+ barStrokeColors: ['#ffffff']
+ barFillColors: [
+ '#0b62a4'
+ '#7a92a3'
+ '#4da74d'
+ '#afd8f8'
+ '#edc240'
+ '#cb4b4b'
+ '#9440ed'
+ ]
+ barHoverOpacity: 0.95
+ hoverPaddingX: 10
+ hoverPaddingY: 5
+ hoverMargin: 10
+ hoverFillColor: '#fff'
+ hoverBorderColor: '#ccc'
+ hoverBorderWidth: 2
+ hoverOpacity: 0.95
+ hoverLabelColor: '#444'
+ hoverFontSize: 12
+ hideHover: false
+ xLabels: 'auto'
+ xLabelFormat: null
+
+ # Override padding
+ #
+ # @private
+ overridePadding: ->
+ maxYLabelWidth = Math.max(
+ @measureText(@yAxisFormat(@ymin), @options.gridTextSize).width,
+ @measureText(@yAxisFormat(@ymax), @options.gridTextSize).width)
+ @left = maxYLabelWidth + @paddingLeft
+ @right = @elementWidth - @paddingRight
+ @width = @right - @left
+
+ xgap = @width / @data.length
+ @barsoffset = @options.barSizeRatio * xgap / 2.0;
+ @barwidth = (@options.barSizeRatio * xgap - ( @options.ykeys.length - 1 ) * @options.barGap ) / @options.ykeys.length
+ @halfBarsWidth = Math.round( @options.ykeys.length / 2 ) * ( @barwidth + @options.barGap )
+
+ @paddingLeft += @halfBarsWidth
+ @paddingRight += @halfBarsWidth
+
+ # Do any size-related calculations
+ #
+ # @private
+ calc: ->
+ @calcBars()
+ @generateBars()
+ @calcHoverMargins()
+
+ # calculate series data bars coordinates and sizes
+ #
+ # @private
+ calcBars: ->
+ for row in @data
+ row._x = @transX(row.x)
+ row._y = for y in row.y
+ if y is null
+ null
+ else
+ @transY(y)
+
+ # calculate hover margins
+ #
+ # @private
+ calcHoverMargins: ->
+ @hoverMargins = $.map @data.slice(1), (r, i) => (r._x + @data[i]._x) / 2
+
+ # generate bars for series
+ #
+ # @private
+ generateBars: ->
+ @bars = for i in [0..@options.ykeys.length]
+ coords = ({x: r._x - @barsoffset + i * (@options.barGap + @barwidth) , y: r._y[i], v: r.y[i] } for r in @data when r._y[i] isnt null)
+ if coords.length > 1
+ @createBars i, coords, @barwidth
+ else
+ null
+
+ # Draws the bar chart.
+ #
+ draw: ->
+ @drawXAxis()
+ @drawSeries()
+ @drawHover()
+ @hilight(if @options.hideHover then null else @data.length - 1)
+
+ # draw the x-axis labels
+ #
+ # @private
+ drawXAxis: ->
+ # draw x axis labels
+ ypos = @bottom + @options.gridTextSize * 1.25
+ xLabelMargin = 50 # make this an option?
+ prevLabelMargin = null
+ drawLabel = (labelText, xpos) =>
+ label = @r.text(@transX(xpos), ypos, labelText)
+ .attr('font-size', @options.gridTextSize)
+ .attr('fill', @options.gridTextColor)
+ labelBox = label.getBBox()
+ # ensure a minimum of `xLabelMargin` pixels between labels, and ensure
+ # labels don't overflow the container
+ if (prevLabelMargin is null or prevLabelMargin >= labelBox.x + labelBox.width) and
+ labelBox.x >= 0 and (labelBox.x + labelBox.width) < @el.width()
+ prevLabelMargin = labelBox.x - xLabelMargin
+ else
+ label.remove()
+ if @options.parseTime
+ if @data.length == 1 and @options.xLabels == 'auto'
+ # where there's only one value in the series, we can't make a
+ # sensible guess for an x labelling scheme, so just use the original
+ # column label
+ labels = [[@data[0].label, @data[0].x]]
+ else
+ labels = Morris.labelSeries(@xmin, @xmax, @width, @options.xLabels, @options.xLabelFormat)
+ else
+ labels = ([row.label, row.x] for row in @data)
+ labels.reverse()
+ for l in labels
+ drawLabel(l[0], l[1])
+
+ # draw the data series
+ #
+ # @private
+ drawSeries: ->
+ @seriesBars = ([] for i in [0...@options.ykeys.length])
+ for i in [@options.ykeys.length-1..0]
+ bars = @bars[i]
+ if bars.length > 0
+ for bar in bars
+ if bar isnt null
+ rect = @r.rect(bar.x, bar.y, bar.width, bar.height)
+ .attr('fill', bar.fill)
+ .attr('stroke', @strokeForSeries(i))
+ .attr('stroke-width', @strokeWidthForSeries(i))
+ else
+ rect = null
+ @seriesBars[i].push(rect)
+
+ # create bars for a data series
+ #
+ # @private
+ createBars: (index, coords, barwidth) ->
+ bars = []
+ for coord in coords
+ bars.push(
+ x: coord.x
+ y: coord.y
+ width: barwidth
+ height: @bottom - coord.y
+ fill: @colorForSeriesAndValue(index, coord.v)
+ )
+
+ return bars
+
+ # draw the hover tooltip
+ #
+ # @private
+ drawHover: ->
+ # hover labels
+ @hoverHeight = @options.hoverFontSize * 1.5 * (@options.ykeys.length + 1)
+ @hover = @r.rect(-10, -@hoverHeight / 2 - @options.hoverPaddingY, 20, @hoverHeight + @options.hoverPaddingY * 2, 10)
+ .attr('fill', @options.hoverFillColor)
+ .attr('stroke', @options.hoverBorderColor)
+ .attr('stroke-width', @options.hoverBorderWidth)
+ .attr('opacity', @options.hoverOpacity)
+ @xLabel = @r.text(0, (@options.hoverFontSize * 0.75) - @hoverHeight / 2, '')
+ .attr('fill', @options.hoverLabelColor)
+ .attr('font-weight', 'bold')
+ .attr('font-size', @options.hoverFontSize)
+ @hoverSet = @r.set()
+ @hoverSet.push(@hover)
+ @hoverSet.push(@xLabel)
+ @yLabels = []
+ for i in [0...@options.ykeys.length]
+ idx = if @cumulative then (@options.ykeys.length - i - 1) else i
+ yLabel = @r.text(0, @options.hoverFontSize * 1.5 * (idx + 1.5) - @hoverHeight / 2, '')
+ .attr('font-size', @options.hoverFontSize)
+ @yLabels.push(yLabel)
+ @hoverSet.push(yLabel)
+
+ # @private
+ updateHover: (index) =>
+ @hoverSet.show()
+ row = @data[index]
+ @xLabel.attr('text', row.label)
+ for y, i in row.y
+ @yLabels[i].attr('fill', @hoverColorForSeriesAndValue(i, y))
+ @yLabels[i].attr('text', "#{@options.labels[i]}: #{@yLabelFormat(y)}")
+ # recalculate hover box width
+ maxLabelWidth = Math.max.apply null, $.map @yLabels, (l) ->
+ l.getBBox().width
+ maxLabelWidth = Math.max maxLabelWidth, @xLabel.getBBox().width
+ @hover.attr 'width', maxLabelWidth + @options.hoverPaddingX * 2
+ @hover.attr 'x', -@options.hoverPaddingX - maxLabelWidth / 2
+ # move to y pos
+ yloc = Math.min.apply null, (y for y in row._y when y isnt null).concat(@bottom)
+ if yloc > @hoverHeight + @options.hoverPaddingY * 2 + @options.hoverMargin + @top
+ yloc = yloc - @hoverHeight / 2 - @options.hoverPaddingY - @options.hoverMargin
+ else
+ yloc = yloc + @hoverHeight / 2 + @options.hoverPaddingY + @options.hoverMargin
+ yloc = Math.max @top + @hoverHeight / 2 + @options.hoverPaddingY, yloc
+ yloc = Math.min @bottom - @hoverHeight / 2 - @options.hoverPaddingY, yloc
+ xloc = Math.min @right - maxLabelWidth / 2 - @options.hoverPaddingX, @data[index]._x
+ xloc = Math.max @left + maxLabelWidth / 2 + @options.hoverPaddingX, xloc
+ @hoverSet.attr 'transform', "t#{xloc},#{yloc}"
+
+ # @private
+ hideHover: ->
+ @hoverSet.hide()
+
+ # @private
+ hilight: (index) =>
+ if @prevHilight isnt null and @prevHilight isnt index
+ for i in [0..@seriesBars.length-1]
+ if @seriesBars[i][@prevHilight]
+ @seriesBars[i][@prevHilight].animate @barDeface
+ if index isnt null and @prevHilight isnt index
+ for i in [0..@seriesBars.length-1]
+ if @seriesBars[i][index]
+ @seriesBars[i][index].animate @barFace
+ @updateHover index
+ @prevHilight = index
+ if index is null
+ @hideHover()
+
+ # @private
+ updateHilight: (x) =>
+ x -= @el.offset().left
+ for hoverIndex in [0...@hoverMargins.length]
+ break if @hoverMargins[hoverIndex] > x
+ @hilight hoverIndex
+
+ # @private
+ strokeWidthForSeries: (index) ->
+ @options.barStrokeWidths[index % @options.barStrokeWidths.length]
+
+ # @private
+ strokeForSeries: (index) ->
+ @options.barStrokeColors[index % @options.barStrokeColors.length]
+
+ # @private
+ hoverColorForSeriesAndValue: (index, value) =>
+ colorOrGradient = @colorForSeriesAndValue index, value
+ if typeof colorOrGradient is 'string'
+ return colorOrGradient.split('-').pop()
+
+ return colorOrGradient
+
+ # @private
+ colorForSeriesAndValue: (index, value) =>
+ color = @options.barFillColors[index % @options.barFillColors.length]
+ if color.indexOf(' ') is -1
+ return color
+
+ color = color.split(/\s/)
+
+ colorAt = (top, bottom, relPos) ->
+ chan = (a, b) -> a + Math.round((b-a)*relPos)
+ newColor =
+ r: chan(top.r, bottom.r)
+ g: chan(top.g, bottom.g)
+ b: chan(top.b, bottom.b)
+ return Raphael.color("rgb(#{newColor.r},#{newColor.g},#{newColor.b})")
+
+ position = 1.0 - (value - @ymin) / (@ymax - @ymin)
+ top = Raphael.color(color[0])
+ bottom = Raphael.color(color[1])
+
+ if color.length is 3
+ bottom = Raphael.color(color[2])
+ middle = Raphael.color(color[1])
+ if position > 0.5
+ start = colorAt(middle, bottom, 2 * (position - 0.5))
+ return "90-#{bottom.hex}-#{start.hex}"
+ else
+ start = colorAt(top, middle, position * 2)
+ middlepos = 100 - Math.round(100 * (0.5 - position) / (1.0 - position))
+ return "90-#{bottom.hex}-#{middle.hex}:#{middlepos}-#{start.hex}"
+
+ start = colorAt(top, bottom, position)
+ return "90-#{bottom.hex}-#{start.hex}"
\ No newline at end of file
diff --git a/lib/morris.grid.coffee b/lib/morris.grid.coffee
index f8462ace..67439d70 100644
--- a/lib/morris.grid.coffee
+++ b/lib/morris.grid.coffee
@@ -147,11 +147,35 @@ class Morris.Grid extends Morris.EventEmitter
maxYLabelWidth = Math.max(
@measureText(@yAxisFormat(@ymin), @options.gridTextSize).width,
@measureText(@yAxisFormat(@ymax), @options.gridTextSize).width)
- @left = maxYLabelWidth + @options.padding
- @right = @elementWidth - @options.padding
- @top = @options.padding
- @bottom = @elementHeight - @options.padding - 1.5 * @options.gridTextSize
+ # calculate paddings
+ if typeof @options.padding is 'string'
+ padding = @options.padding.split(/\s+/)
+ if padding.length == 2
+ @paddingLeft = @paddingRight = padding[1]
+ @paddingTop = @paddingBottom = padding[0]
+ else if padding.length == 3
+ @paddingLeft = @paddingRight = padding[1]
+ @paddingTop = padding[0]
+ @paddingBottom = padding[2]
+ else if padding.length == 4
+ @paddingTop = padding[0]
+ @paddingRight = padding[1]
+ @paddingBottom = padding[2]
+ @paddingLeft = padding[3]
+ else
+ @paddingTop = @paddingBottom = @options.padding
+ @paddingLeft = @paddingRight = @options.padding
+ @gridPaddingRight = @paddingRight
+ @gridPaddingLeft = @paddingLeft
+ @overridePadding() if @overridePadding
+ @left = maxYLabelWidth + @paddingLeft
+ @gridLeft = maxYLabelWidth + @gridPaddingLeft
+ @right = @elementWidth - @paddingRight
+ @gridRight = @elementWidth - @gridPaddingRight
+ @top = @paddingTop
+ @bottom = @elementHeight - @paddingBottom - 1.5 * @options.gridTextSize
@width = @right - @left
+ @gridWidth = @gridRight - @gridLeft
@height = @bottom - @top
@dx = @width / (@xmax - @xmin)
@dy = @height / (@ymax - @ymin)
@@ -184,11 +208,11 @@ class Morris.Grid extends Morris.EventEmitter
for lineY in [firstY..lastY] by @yInterval
v = parseFloat(lineY.toFixed(@precision))
y = @transY(v)
- @r.text(@left - @options.padding / 2, y, @yAxisFormat(v))
+ @r.text(@gridLeft - @gridPaddingLeft / 2, y, @yAxisFormat(v))
.attr('font-size', @options.gridTextSize)
.attr('fill', @options.gridTextColor)
.attr('text-anchor', 'end')
- @r.path("M#{@left},#{y}H#{@left + @width}")
+ @r.path("M#{@gridLeft},#{y}H#{@gridLeft + @gridWidth}")
.attr('stroke', @options.gridLineColor)
.attr('stroke-width', @options.gridStrokeWidth)
diff --git a/morris.js b/morris.js
index f99c016d..3485ea38 100644
--- a/morris.js
+++ b/morris.js
@@ -228,7 +228,7 @@
};
Grid.prototype._calc = function() {
- var h, maxYLabelWidth, w;
+ var h, maxYLabelWidth, padding, w;
w = this.el.width();
h = this.el.height();
if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) {
@@ -236,11 +236,38 @@
this.elementHeight = h;
this.dirty = false;
maxYLabelWidth = Math.max(this.measureText(this.yAxisFormat(this.ymin), this.options.gridTextSize).width, this.measureText(this.yAxisFormat(this.ymax), this.options.gridTextSize).width);
- this.left = maxYLabelWidth + 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;
+ if (typeof this.options.padding === 'string') {
+ padding = this.options.padding.split(/\s+/);
+ if (padding.length === 2) {
+ this.paddingLeft = this.paddingRight = padding[1];
+ this.paddingTop = this.paddingBottom = padding[0];
+ } else if (padding.length === 3) {
+ this.paddingLeft = this.paddingRight = padding[1];
+ this.paddingTop = padding[0];
+ this.paddingBottom = padding[2];
+ } else if (padding.length === 4) {
+ this.paddingTop = padding[0];
+ this.paddingRight = padding[1];
+ this.paddingBottom = padding[2];
+ this.paddingLeft = padding[3];
+ }
+ } else {
+ this.paddingTop = this.paddingBottom = this.options.padding;
+ this.paddingLeft = this.paddingRight = this.options.padding;
+ }
+ this.gridPaddingRight = this.paddingRight;
+ this.gridPaddingLeft = this.paddingLeft;
+ if (this.overridePadding) {
+ this.overridePadding();
+ }
+ this.left = maxYLabelWidth + this.paddingLeft;
+ this.gridLeft = maxYLabelWidth + this.gridPaddingLeft;
+ this.right = this.elementWidth - this.paddingRight;
+ this.gridRight = this.elementWidth - this.gridPaddingRight;
+ this.top = this.paddingTop;
+ this.bottom = this.elementHeight - this.paddingBottom - 1.5 * this.options.gridTextSize;
this.width = this.right - this.left;
+ this.gridWidth = this.gridRight - this.gridLeft;
this.height = this.bottom - this.top;
this.dx = this.width / (this.xmax - this.xmin);
this.dy = this.height / (this.ymax - this.ymin);
@@ -279,8 +306,8 @@
for (lineY = _i = firstY, _ref = this.yInterval; firstY <= lastY ? _i <= lastY : _i >= lastY; lineY = _i += _ref) {
v = parseFloat(lineY.toFixed(this.precision));
y = this.transY(v);
- this.r.text(this.left - this.options.padding / 2, y, this.yAxisFormat(v)).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
- _results.push(this.r.path("M" + this.left + "," + y + "H" + (this.left + this.width)).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth));
+ this.r.text(this.gridLeft - this.gridPaddingLeft / 2, y, this.yAxisFormat(v)).attr('font-size', this.options.gridTextSize).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');
+ _results.push(this.r.path("M" + this.gridLeft + "," + y + "H" + (this.gridLeft + this.gridWidth)).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth));
}
return _results;
};
@@ -921,6 +948,418 @@
})(Morris.Line);
+ Morris.Bar = (function(_super) {
+
+ __extends(Bar, _super);
+
+ function Bar(options) {
+ this.colorForSeriesAndValue = __bind(this.colorForSeriesAndValue, this);
+
+ this.hoverColorForSeriesAndValue = __bind(this.hoverColorForSeriesAndValue, this);
+
+ this.updateHilight = __bind(this.updateHilight, this);
+
+ this.hilight = __bind(this.hilight, this);
+
+ this.updateHover = __bind(this.updateHover, this);
+ if (!(this instanceof Morris.Bar)) {
+ return new Morris.Bar(options);
+ }
+ Bar.__super__.constructor.call(this, options);
+ }
+
+ Bar.prototype.init = function() {
+ var touchHandler,
+ _this = this;
+ this.barFace = Raphael.animation({
+ opacity: this.options.barHoverOpacity
+ }, 25, 'linear');
+ this.barDeface = Raphael.animation({
+ opacity: 1.0
+ }, 25, 'linear');
+ this.prevHilight = null;
+ this.el.mousemove(function(evt) {
+ return _this.updateHilight(evt.pageX);
+ });
+ if (this.options.hideHover) {
+ this.el.mouseout(function(evt) {
+ return _this.hilight(null);
+ });
+ }
+ touchHandler = function(evt) {
+ var touch;
+ touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0];
+ _this.updateHilight(touch.pageX);
+ return touch;
+ };
+ this.el.bind('touchstart', touchHandler);
+ this.el.bind('touchmove', touchHandler);
+ return this.el.bind('touchend', touchHandler);
+ };
+
+ Bar.prototype.defaults = {
+ barSizeRatio: 0.5,
+ barGap: 3,
+ barStrokeWidths: [0],
+ barStrokeColors: ['#ffffff'],
+ barFillColors: ['#0b62a4', '#7a92a3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],
+ barHoverOpacity: 0.95,
+ hoverPaddingX: 10,
+ hoverPaddingY: 5,
+ hoverMargin: 10,
+ hoverFillColor: '#fff',
+ hoverBorderColor: '#ccc',
+ hoverBorderWidth: 2,
+ hoverOpacity: 0.95,
+ hoverLabelColor: '#444',
+ hoverFontSize: 12,
+ hideHover: false,
+ xLabels: 'auto',
+ xLabelFormat: null
+ };
+
+ Bar.prototype.overridePadding = function() {
+ var maxYLabelWidth, xgap;
+ maxYLabelWidth = Math.max(this.measureText(this.yAxisFormat(this.ymin), this.options.gridTextSize).width, this.measureText(this.yAxisFormat(this.ymax), this.options.gridTextSize).width);
+ this.left = maxYLabelWidth + this.paddingLeft;
+ this.right = this.elementWidth - this.paddingRight;
+ this.width = this.right - this.left;
+ xgap = this.width / this.data.length;
+ this.barsoffset = this.options.barSizeRatio * xgap / 2.0;
+ this.barwidth = (this.options.barSizeRatio * xgap - (this.options.ykeys.length - 1) * this.options.barGap) / this.options.ykeys.length;
+ this.halfBarsWidth = Math.round(this.options.ykeys.length / 2) * (this.barwidth + this.options.barGap);
+ this.paddingLeft += this.halfBarsWidth;
+ return this.paddingRight += this.halfBarsWidth;
+ };
+
+ Bar.prototype.calc = function() {
+ this.calcBars();
+ this.generateBars();
+ return this.calcHoverMargins();
+ };
+
+ Bar.prototype.calcBars = function() {
+ var row, y, _i, _len, _ref, _results;
+ _ref = this.data;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ row = _ref[_i];
+ row._x = this.transX(row.x);
+ _results.push(row._y = (function() {
+ var _j, _len1, _ref1, _results1;
+ _ref1 = row.y;
+ _results1 = [];
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ y = _ref1[_j];
+ if (y === null) {
+ _results1.push(null);
+ } else {
+ _results1.push(this.transY(y));
+ }
+ }
+ return _results1;
+ }).call(this));
+ }
+ return _results;
+ };
+
+ Bar.prototype.calcHoverMargins = function() {
+ var _this = this;
+ return this.hoverMargins = $.map(this.data.slice(1), function(r, i) {
+ return (r._x + _this.data[i]._x) / 2;
+ });
+ };
+
+ Bar.prototype.generateBars = function() {
+ var coords, i, r;
+ return this.bars = (function() {
+ var _i, _ref, _results;
+ _results = [];
+ for (i = _i = 0, _ref = this.options.ykeys.length; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ coords = (function() {
+ var _j, _len, _ref1, _results1;
+ _ref1 = this.data;
+ _results1 = [];
+ for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
+ r = _ref1[_j];
+ if (r._y[i] !== null) {
+ _results1.push({
+ x: r._x - this.barsoffset + i * (this.options.barGap + this.barwidth),
+ y: r._y[i],
+ v: r.y[i]
+ });
+ }
+ }
+ return _results1;
+ }).call(this);
+ if (coords.length > 1) {
+ _results.push(this.createBars(i, coords, this.barwidth));
+ } else {
+ _results.push(null);
+ }
+ }
+ return _results;
+ }).call(this);
+ };
+
+ Bar.prototype.draw = function() {
+ this.drawXAxis();
+ this.drawSeries();
+ this.drawHover();
+ return this.hilight(this.options.hideHover ? null : this.data.length - 1);
+ };
+
+ Bar.prototype.drawXAxis = function() {
+ var drawLabel, l, labels, prevLabelMargin, row, xLabelMargin, ypos, _i, _len, _results,
+ _this = this;
+ ypos = this.bottom + this.options.gridTextSize * 1.25;
+ xLabelMargin = 50;
+ prevLabelMargin = null;
+ drawLabel = function(labelText, xpos) {
+ var label, labelBox;
+ label = _this.r.text(_this.transX(xpos), ypos, labelText).attr('font-size', _this.options.gridTextSize).attr('fill', _this.options.gridTextColor);
+ labelBox = label.getBBox();
+ if ((prevLabelMargin === null || prevLabelMargin >= labelBox.x + labelBox.width) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {
+ return prevLabelMargin = labelBox.x - xLabelMargin;
+ } else {
+ return label.remove();
+ }
+ };
+ if (this.options.parseTime) {
+ if (this.data.length === 1 && this.options.xLabels === 'auto') {
+ labels = [[this.data[0].label, this.data[0].x]];
+ } else {
+ labels = Morris.labelSeries(this.xmin, this.xmax, this.width, this.options.xLabels, this.options.xLabelFormat);
+ }
+ } else {
+ labels = (function() {
+ var _i, _len, _ref, _results;
+ _ref = this.data;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ row = _ref[_i];
+ _results.push([row.label, row.x]);
+ }
+ return _results;
+ }).call(this);
+ }
+ labels.reverse();
+ _results = [];
+ for (_i = 0, _len = labels.length; _i < _len; _i++) {
+ l = labels[_i];
+ _results.push(drawLabel(l[0], l[1]));
+ }
+ return _results;
+ };
+
+ Bar.prototype.drawSeries = function() {
+ var bar, bars, i, rect, _i, _ref, _results;
+ this.seriesBars = (function() {
+ var _i, _ref, _results;
+ _results = [];
+ for (i = _i = 0, _ref = this.options.ykeys.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+ _results.push([]);
+ }
+ return _results;
+ }).call(this);
+ _results = [];
+ for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {
+ bars = this.bars[i];
+ if (bars.length > 0) {
+ _results.push((function() {
+ var _j, _len, _results1;
+ _results1 = [];
+ for (_j = 0, _len = bars.length; _j < _len; _j++) {
+ bar = bars[_j];
+ if (bar !== null) {
+ rect = this.r.rect(bar.x, bar.y, bar.width, bar.height).attr('fill', bar.fill).attr('stroke', this.strokeForSeries(i)).attr('stroke-width', this.strokeWidthForSeries(i));
+ } else {
+ rect = null;
+ }
+ _results1.push(this.seriesBars[i].push(rect));
+ }
+ return _results1;
+ }).call(this));
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ };
+
+ Bar.prototype.createBars = function(index, coords, barwidth) {
+ var bars, coord, _i, _len;
+ bars = [];
+ for (_i = 0, _len = coords.length; _i < _len; _i++) {
+ coord = coords[_i];
+ bars.push({
+ x: coord.x,
+ y: coord.y,
+ width: barwidth,
+ height: this.bottom - coord.y,
+ fill: this.colorForSeriesAndValue(index, coord.v)
+ });
+ }
+ return bars;
+ };
+
+ Bar.prototype.drawHover = function() {
+ var i, idx, yLabel, _i, _ref, _results;
+ this.hoverHeight = this.options.hoverFontSize * 1.5 * (this.options.ykeys.length + 1);
+ this.hover = this.r.rect(-10, -this.hoverHeight / 2 - this.options.hoverPaddingY, 20, this.hoverHeight + this.options.hoverPaddingY * 2, 10).attr('fill', this.options.hoverFillColor).attr('stroke', this.options.hoverBorderColor).attr('stroke-width', this.options.hoverBorderWidth).attr('opacity', this.options.hoverOpacity);
+ this.xLabel = this.r.text(0, (this.options.hoverFontSize * 0.75) - this.hoverHeight / 2, '').attr('fill', this.options.hoverLabelColor).attr('font-weight', 'bold').attr('font-size', this.options.hoverFontSize);
+ this.hoverSet = this.r.set();
+ this.hoverSet.push(this.hover);
+ this.hoverSet.push(this.xLabel);
+ this.yLabels = [];
+ _results = [];
+ for (i = _i = 0, _ref = this.options.ykeys.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+ idx = this.cumulative ? this.options.ykeys.length - i - 1 : i;
+ yLabel = this.r.text(0, this.options.hoverFontSize * 1.5 * (idx + 1.5) - this.hoverHeight / 2, '').attr('font-size', this.options.hoverFontSize);
+ this.yLabels.push(yLabel);
+ _results.push(this.hoverSet.push(yLabel));
+ }
+ return _results;
+ };
+
+ Bar.prototype.updateHover = function(index) {
+ var i, maxLabelWidth, row, xloc, y, yloc, _i, _len, _ref;
+ this.hoverSet.show();
+ row = this.data[index];
+ this.xLabel.attr('text', row.label);
+ _ref = row.y;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+ y = _ref[i];
+ this.yLabels[i].attr('fill', this.hoverColorForSeriesAndValue(i, y));
+ this.yLabels[i].attr('text', "" + this.options.labels[i] + ": " + (this.yLabelFormat(y)));
+ }
+ maxLabelWidth = Math.max.apply(null, $.map(this.yLabels, function(l) {
+ return l.getBBox().width;
+ }));
+ maxLabelWidth = Math.max(maxLabelWidth, this.xLabel.getBBox().width);
+ this.hover.attr('width', maxLabelWidth + this.options.hoverPaddingX * 2);
+ this.hover.attr('x', -this.options.hoverPaddingX - maxLabelWidth / 2);
+ yloc = Math.min.apply(null, ((function() {
+ var _j, _len1, _ref1, _results;
+ _ref1 = row._y;
+ _results = [];
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ y = _ref1[_j];
+ if (y !== null) {
+ _results.push(y);
+ }
+ }
+ return _results;
+ })()).concat(this.bottom));
+ if (yloc > this.hoverHeight + this.options.hoverPaddingY * 2 + this.options.hoverMargin + this.top) {
+ yloc = yloc - this.hoverHeight / 2 - this.options.hoverPaddingY - this.options.hoverMargin;
+ } else {
+ yloc = yloc + this.hoverHeight / 2 + this.options.hoverPaddingY + this.options.hoverMargin;
+ }
+ yloc = Math.max(this.top + this.hoverHeight / 2 + this.options.hoverPaddingY, yloc);
+ yloc = Math.min(this.bottom - this.hoverHeight / 2 - this.options.hoverPaddingY, yloc);
+ xloc = Math.min(this.right - maxLabelWidth / 2 - this.options.hoverPaddingX, this.data[index]._x);
+ xloc = Math.max(this.left + maxLabelWidth / 2 + this.options.hoverPaddingX, xloc);
+ return this.hoverSet.attr('transform', "t" + xloc + "," + yloc);
+ };
+
+ Bar.prototype.hideHover = function() {
+ return this.hoverSet.hide();
+ };
+
+ Bar.prototype.hilight = function(index) {
+ var i, _i, _j, _ref, _ref1;
+ if (this.prevHilight !== null && this.prevHilight !== index) {
+ for (i = _i = 0, _ref = this.seriesBars.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ if (this.seriesBars[i][this.prevHilight]) {
+ this.seriesBars[i][this.prevHilight].animate(this.barDeface);
+ }
+ }
+ }
+ if (index !== null && this.prevHilight !== index) {
+ for (i = _j = 0, _ref1 = this.seriesBars.length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
+ if (this.seriesBars[i][index]) {
+ this.seriesBars[i][index].animate(this.barFace);
+ }
+ }
+ this.updateHover(index);
+ }
+ this.prevHilight = index;
+ if (index === null) {
+ return this.hideHover();
+ }
+ };
+
+ Bar.prototype.updateHilight = 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.hilight(hoverIndex);
+ };
+
+ Bar.prototype.strokeWidthForSeries = function(index) {
+ return this.options.barStrokeWidths[index % this.options.barStrokeWidths.length];
+ };
+
+ Bar.prototype.strokeForSeries = function(index) {
+ return this.options.barStrokeColors[index % this.options.barStrokeColors.length];
+ };
+
+ Bar.prototype.hoverColorForSeriesAndValue = function(index, value) {
+ var colorOrGradient;
+ colorOrGradient = this.colorForSeriesAndValue(index, value);
+ if (typeof colorOrGradient === 'string') {
+ return colorOrGradient.split('-').pop();
+ }
+ return colorOrGradient;
+ };
+
+ Bar.prototype.colorForSeriesAndValue = function(index, value) {
+ var bottom, color, colorAt, middle, middlepos, position, start, top;
+ color = this.options.barFillColors[index % this.options.barFillColors.length];
+ if (color.indexOf(' ') === -1) {
+ return color;
+ }
+ color = color.split(/\s/);
+ colorAt = function(top, bottom, relPos) {
+ var chan, newColor;
+ chan = function(a, b) {
+ return a + Math.round((b - a) * relPos);
+ };
+ newColor = {
+ r: chan(top.r, bottom.r),
+ g: chan(top.g, bottom.g),
+ b: chan(top.b, bottom.b)
+ };
+ return Raphael.color("rgb(" + newColor.r + "," + newColor.g + "," + newColor.b + ")");
+ };
+ position = 1.0 - (value - this.ymin) / (this.ymax - this.ymin);
+ top = Raphael.color(color[0]);
+ bottom = Raphael.color(color[1]);
+ if (color.length === 3) {
+ bottom = Raphael.color(color[2]);
+ middle = Raphael.color(color[1]);
+ if (position > 0.5) {
+ start = colorAt(middle, bottom, 2 * (position - 0.5));
+ return "90-" + bottom.hex + "-" + start.hex;
+ } else {
+ start = colorAt(top, middle, position * 2);
+ middlepos = 100 - Math.round(100 * (0.5 - position) / (1.0 - position));
+ return "90-" + bottom.hex + "-" + middle.hex + ":" + middlepos + "-" + start.hex;
+ }
+ }
+ start = colorAt(top, bottom, position);
+ return "90-" + bottom.hex + "-" + start.hex;
+ };
+
+ return Bar;
+
+ })(Morris.Grid);
+
Morris.Donut = (function() {
Donut.prototype.defaults = {
diff --git a/morris.min.js b/morris.min.js
index 2228e5a9..e17c8029 100644
--- a/morris.min.js
+++ b/morris.min.js
@@ -1 +1 @@
-(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)}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"},r.prototype.setData=function(n,r){var i,s,o=this;r==null&&(r=!0),i=this.cumulative?0:null,s=this.cumulative?0:null,this.data=e.map(n,function(e,n){var r,u,a,f,l;return u={},u.label=e[o.options.xkey],o.options.parseTime?(u.x=t.parseDate(u.label),o.options.dateFormat?u.label=o.options.dateFormat(u.x):typeof u.label=="number"&&(u.label=(new Date(u.label)).toString())):u.x=n,a=0,u.y=function(){var t,n,o,u;o=this.options.ykeys,u=[];for(r=t=0,n=o.length;tt.x)-(t.x>e.x)})),this.xmin=this.data[0].x,this.xmax=this.data[this.data.length-1].x,this.xmin===this.xmax&&(this.xmin-=1,this.xmax+=1),typeof this.options.ymax=="string"?this.options.ymax.slice(0,4)==="auto"?this.options.ymax.length>5?(this.ymax=parseInt(this.options.ymax.slice(5),10),i!==null&&(this.ymax=Math.max(i,this.ymax))):this.ymax=i!==null?i: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),s!==null&&(this.ymin=Math.min(s,this.ymin))):this.ymin=s!==null?s:0:this.ymin=parseInt(this.options.ymin,10):this.ymin=this.options.ymin,this.ymin===this.ymax&&(s&&(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(r)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();if(this.draw)return this.draw()},r.prototype.drawGrid=function(){var e,t,n,r,i,s,o,u;e=this.ymin,t=this.ymax,u=[];for(n=s=e,o=this.yInterval;e<=t?s<=t:s>=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.Line=function(n){function r(e){this.updateHilight=u(this.updateHilight,this),this.hilight=u(this.hilight,this),this.updateHover=u(this.updateHover,this);if(!(this instanceof t.Line))return new t.Line(e);r.__super__.constructor.call(this,e)}return o(r,n),r.prototype.init=function(){var e,t=this;return this.pointGrow=Raphael.animation({r:this.options.pointSize+3},25,"linear"),this.pointShrink=Raphael.animation({r:this.options.pointSize},25,"linear"),this.prevHilight=null,this.el.mousemove(function(e){return t.updateHilight(e.pageX)}),this.options.hideHover&&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)},r.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],pointWidths:[1],pointStrokeColors:["#ffffff"],pointFillColors:[],hoverPaddingX:10,hoverPaddingY:5,hoverMargin:10,hoverFillColor:"#fff",hoverBorderColor:"#ccc",hoverBorderWidth:2,hoverOpacity:.95,hoverLabelColor:"#444",hoverFontSize:12,smooth:!0,hideHover:!1,xLabels:"auto",xLabelFormat:null},r.prototype.calc=function(){return this.calcPoints(),this.generatePaths(),this.calcHoverMargins()},r.prototype.calcPoints=function(){var e,t,n,r,i,s;i=this.data,s=[];for(n=0,r=i.length;ns;t=0<=s?++i:--i)r=this.options.smooth===!0||(o=this.options.ykeys[t],a.call(this.options.smooth,o)>=0),e=function(){var e,r,i,s;i=this.data,s=[];for(e=0,r=i.length;e1?u.push(this.createPath(e,r)):u.push(null);return u}.call(this)},r.prototype.draw=function(){return this.drawXAxis(),this.drawSeries(),this.drawHover(),this.hilight(this.options.hideHover?null:this.data.length-1)},r.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.colorForSeries(t)).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=m;o=0<=m?++v:--v)r=t[o],o===0?l+="M"+r.x+","+r.y:(i=s[o],a=t[o-1],f=s[o-1],u=(r.x-a.x)/4,c=a.x+u,p=Math.min(this.bottom,a.y+u*f),h=r.x-u,d=Math.min(this.bottom,r.y-u*i),l+="C"+c+","+p+","+h+","+d+","+r.x+","+r.y)}else l="M"+e.map(t,function(e){return""+e.x+","+e.y}).join("L");return l},r.prototype.gradients=function(t){return e.map(t,function(e,n){return n===0?(t[1].y-e.y)/(t[1].x-e.x):n===t.length-1?(e.y-t[n-1].y)/(e.x-t[n-1].x):(t[n+1].y-t[n-1].y)/(t[n+1].x-t[n-1].x)})},r.prototype.drawHover=function(){var e,t,n,r,i,s;this.hoverHeight=this.options.hoverFontSize*1.5*(this.options.ykeys.length+1),this.hover=this.r.rect(-10,-this.hoverHeight/2-this.options.hoverPaddingY,20,this.hoverHeight+this.options.hoverPaddingY*2,10).attr("fill",this.options.hoverFillColor).attr("stroke",this.options.hoverBorderColor).attr("stroke-width",this.options.hoverBorderWidth).attr("opacity",this.options.hoverOpacity),this.xLabel=this.r.text(0,this.options.hoverFontSize*.75-this.hoverHeight/2,"").attr("fill",this.options.hoverLabelColor).attr("font-weight","bold").attr("font-size",this.options.hoverFontSize),this.hoverSet=this.r.set(),this.hoverSet.push(this.hover),this.hoverSet.push(this.xLabel),this.yLabels=[],s=[];for(e=r=0,i=this.options.ykeys.length;0<=i?ri;e=0<=i?++r:--r)t=this.cumulative?this.options.ykeys.length-e-1:e,n=this.r.text(0,this.options.hoverFontSize*1.5*(t+1.5)-this.hoverHeight/2,"").attr("fill",this.colorForSeries(e)).attr("font-size",this.options.hoverFontSize),this.yLabels.push(n),s.push(this.hoverSet.push(n));return s},r.prototype.updateHover=function(t){var n,r,i,s,o,u,a,f,l;this.hoverSet.show(),i=this.data[t],this.xLabel.attr("text",i.label),l=i.y;for(n=a=0,f=l.length;athis.hoverHeight+this.options.hoverPaddingY*2+this.options.hoverMargin+this.top?u=u-this.hoverHeight/2-this.options.hoverPaddingY-this.options.hoverMargin:u=u+this.hoverHeight/2+this.options.hoverPaddingY+this.options.hoverMargin,u=Math.max(this.top+this.hoverHeight/2+this.options.hoverPaddingY,u),u=Math.min(this.bottom-this.hoverHeight/2-this.options.hoverPaddingY,u),s=Math.min(this.right-r/2-this.options.hoverPaddingX,this.data[t]._x),s=Math.max(this.left+r/2+this.options.hoverPaddingX,s),this.hoverSet.attr("transform","t"+s+","+u)},r.prototype.hideHover=function(){return this.hoverSet.hide()},r.prototype.hilight=function(e){var t,n,r,i,s;if(this.prevHilight!==null&&this.prevHilight!==e)for(t=n=0,i=this.seriesPoints.length-1;0<=i?n<=i: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);this.updateHover(e)}this.prevHilight=e;if(e===null)return this.hideHover()},r.prototype.updateHilight=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.hilight(t)},r.prototype.colorForSeries=function(e){return this.options.lineColors[e%this.options.lineColors.length]},r.prototype.strokeWidthForSeries=function(e){return this.options.pointWidths[e%this.options.pointWidths.length]},r.prototype.strokeForSeries=function(e){return this.options.pointStrokeColors[e%this.options.pointStrokeColors.length]},r.prototype.pointFillColorForSeries=function(e){return this.options.pointFillColors[e%this.options.pointFillColors.length]},r}(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={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=["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.colorForSeries(e)),Raphael.hsl(t.h,Math.min(255,t.s*.75),Math.min(255,t.l*1.25))},n}(t.Line),t.Donut=function(){function n(n){this.select=u(this.select,this);if(!(this instanceof t.Donut))return new t.Donut(n);typeof n.element=="string"?this.el=e(document.getElementById(n.element)):this.el=e(n.element),this.options=e.extend({},this.defaults,n);if(this.el===null||this.el.length===0)throw new Error("Graph placeholder not found.");if(n.data===void 0||n.data.length===0)return;this.data=n.data,this.el.addClass("graph-initialised"),this.redraw()}return n.prototype.defaults={colors:["#0B62A4","#3980B5","#679DC6","#95BBD7","#B0CCE1","#095791","#095085","#083E67","#052C48","#042135"],formatter:t.commas},n.prototype.redraw=function(){var e,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S,x;this.el.empty(),this.r=new Raphael(this.el[0]),n=this.el.width()/2,r=this.el.height()/2,h=(Math.min(n,r)-10)/3,c=0,w=this.data;for(d=0,g=w.length;dMath.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
+(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)}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"},r.prototype.setData=function(n,r){var i,s,o=this;r==null&&(r=!0),i=this.cumulative?0:null,s=this.cumulative?0:null,this.data=e.map(n,function(e,n){var r,u,a,f,l;return u={},u.label=e[o.options.xkey],o.options.parseTime?(u.x=t.parseDate(u.label),o.options.dateFormat?u.label=o.options.dateFormat(u.x):typeof u.label=="number"&&(u.label=(new Date(u.label)).toString())):u.x=n,a=0,u.y=function(){var t,n,o,u;o=this.options.ykeys,u=[];for(r=t=0,n=o.length;tt.x)-(t.x>e.x)})),this.xmin=this.data[0].x,this.xmax=this.data[this.data.length-1].x,this.xmin===this.xmax&&(this.xmin-=1,this.xmax+=1),typeof this.options.ymax=="string"?this.options.ymax.slice(0,4)==="auto"?this.options.ymax.length>5?(this.ymax=parseInt(this.options.ymax.slice(5),10),i!==null&&(this.ymax=Math.max(i,this.ymax))):this.ymax=i!==null?i: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),s!==null&&(this.ymin=Math.min(s,this.ymin))):this.ymin=s!==null?s:0:this.ymin=parseInt(this.options.ymin,10):this.ymin=this.options.ymin,this.ymin===this.ymax&&(s&&(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(r)return this.redraw()},r.prototype._calc=function(){var e,t,n,r;r=this.el.width(),e=this.el.height();if(this.elementWidth!==r||this.elementHeight!==e||this.dirty){this.elementWidth=r,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),typeof this.options.padding=="string"?(n=this.options.padding.split(/\s+/),n.length===2?(this.paddingLeft=this.paddingRight=n[1],this.paddingTop=this.paddingBottom=n[0]):n.length===3?(this.paddingLeft=this.paddingRight=n[1],this.paddingTop=n[0],this.paddingBottom=n[2]):n.length===4&&(this.paddingTop=n[0],this.paddingRight=n[1],this.paddingBottom=n[2],this.paddingLeft=n[3])):(this.paddingTop=this.paddingBottom=this.options.padding,this.paddingLeft=this.paddingRight=this.options.padding),this.gridPaddingRight=this.paddingRight,this.gridPaddingLeft=this.paddingLeft,this.overridePadding&&this.overridePadding(),this.left=t+this.paddingLeft,this.gridLeft=t+this.gridPaddingLeft,this.right=this.elementWidth-this.paddingRight,this.gridRight=this.elementWidth-this.gridPaddingRight,this.top=this.paddingTop,this.bottom=this.elementHeight-this.paddingBottom-1.5*this.options.gridTextSize,this.width=this.right-this.left,this.gridWidth=this.gridRight-this.gridLeft,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();if(this.draw)return this.draw()},r.prototype.drawGrid=function(){var e,t,n,r,i,s,o,u;e=this.ymin,t=this.ymax,u=[];for(n=s=e,o=this.yInterval;e<=t?s<=t:s>=t;n=s+=o)r=parseFloat(n.toFixed(this.precision)),i=this.transY(r),this.r.text(this.gridLeft-this.gridPaddingLeft/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.gridLeft+","+i+"H"+(this.gridLeft+this.gridWidth)).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.Line=function(n){function r(e){this.updateHilight=u(this.updateHilight,this),this.hilight=u(this.hilight,this),this.updateHover=u(this.updateHover,this);if(!(this instanceof t.Line))return new t.Line(e);r.__super__.constructor.call(this,e)}return o(r,n),r.prototype.init=function(){var e,t=this;return this.pointGrow=Raphael.animation({r:this.options.pointSize+3},25,"linear"),this.pointShrink=Raphael.animation({r:this.options.pointSize},25,"linear"),this.prevHilight=null,this.el.mousemove(function(e){return t.updateHilight(e.pageX)}),this.options.hideHover&&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)},r.prototype.defaults={lineWidth:3,pointSize:4,lineColors:["#0b62a4","#7A92A3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],pointWidths:[1],pointStrokeColors:["#ffffff"],pointFillColors:[],hoverPaddingX:10,hoverPaddingY:5,hoverMargin:10,hoverFillColor:"#fff",hoverBorderColor:"#ccc",hoverBorderWidth:2,hoverOpacity:.95,hoverLabelColor:"#444",hoverFontSize:12,smooth:!0,hideHover:!1,xLabels:"auto",xLabelFormat:null},r.prototype.calc=function(){return this.calcPoints(),this.generatePaths(),this.calcHoverMargins()},r.prototype.calcPoints=function(){var e,t,n,r,i,s;i=this.data,s=[];for(n=0,r=i.length;ns;t=0<=s?++i:--i)r=this.options.smooth===!0||(o=this.options.ykeys[t],a.call(this.options.smooth,o)>=0),e=function(){var e,r,i,s;i=this.data,s=[];for(e=0,r=i.length;e1?u.push(this.createPath(e,r)):u.push(null);return u}.call(this)},r.prototype.draw=function(){return this.drawXAxis(),this.drawSeries(),this.drawHover(),this.hilight(this.options.hideHover?null:this.data.length-1)},r.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.colorForSeries(t)).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=m;o=0<=m?++v:--v)r=t[o],o===0?l+="M"+r.x+","+r.y:(i=s[o],a=t[o-1],f=s[o-1],u=(r.x-a.x)/4,c=a.x+u,p=Math.min(this.bottom,a.y+u*f),h=r.x-u,d=Math.min(this.bottom,r.y-u*i),l+="C"+c+","+p+","+h+","+d+","+r.x+","+r.y)}else l="M"+e.map(t,function(e){return""+e.x+","+e.y}).join("L");return l},r.prototype.gradients=function(t){return e.map(t,function(e,n){return n===0?(t[1].y-e.y)/(t[1].x-e.x):n===t.length-1?(e.y-t[n-1].y)/(e.x-t[n-1].x):(t[n+1].y-t[n-1].y)/(t[n+1].x-t[n-1].x)})},r.prototype.drawHover=function(){var e,t,n,r,i,s;this.hoverHeight=this.options.hoverFontSize*1.5*(this.options.ykeys.length+1),this.hover=this.r.rect(-10,-this.hoverHeight/2-this.options.hoverPaddingY,20,this.hoverHeight+this.options.hoverPaddingY*2,10).attr("fill",this.options.hoverFillColor).attr("stroke",this.options.hoverBorderColor).attr("stroke-width",this.options.hoverBorderWidth).attr("opacity",this.options.hoverOpacity),this.xLabel=this.r.text(0,this.options.hoverFontSize*.75-this.hoverHeight/2,"").attr("fill",this.options.hoverLabelColor).attr("font-weight","bold").attr("font-size",this.options.hoverFontSize),this.hoverSet=this.r.set(),this.hoverSet.push(this.hover),this.hoverSet.push(this.xLabel),this.yLabels=[],s=[];for(e=r=0,i=this.options.ykeys.length;0<=i?ri;e=0<=i?++r:--r)t=this.cumulative?this.options.ykeys.length-e-1:e,n=this.r.text(0,this.options.hoverFontSize*1.5*(t+1.5)-this.hoverHeight/2,"").attr("fill",this.colorForSeries(e)).attr("font-size",this.options.hoverFontSize),this.yLabels.push(n),s.push(this.hoverSet.push(n));return s},r.prototype.updateHover=function(t){var n,r,i,s,o,u,a,f,l;this.hoverSet.show(),i=this.data[t],this.xLabel.attr("text",i.label),l=i.y;for(n=a=0,f=l.length;athis.hoverHeight+this.options.hoverPaddingY*2+this.options.hoverMargin+this.top?u=u-this.hoverHeight/2-this.options.hoverPaddingY-this.options.hoverMargin:u=u+this.hoverHeight/2+this.options.hoverPaddingY+this.options.hoverMargin,u=Math.max(this.top+this.hoverHeight/2+this.options.hoverPaddingY,u),u=Math.min(this.bottom-this.hoverHeight/2-this.options.hoverPaddingY,u),s=Math.min(this.right-r/2-this.options.hoverPaddingX,this.data[t]._x),s=Math.max(this.left+r/2+this.options.hoverPaddingX,s),this.hoverSet.attr("transform","t"+s+","+u)},r.prototype.hideHover=function(){return this.hoverSet.hide()},r.prototype.hilight=function(e){var t,n,r,i,s;if(this.prevHilight!==null&&this.prevHilight!==e)for(t=n=0,i=this.seriesPoints.length-1;0<=i?n<=i: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);this.updateHover(e)}this.prevHilight=e;if(e===null)return this.hideHover()},r.prototype.updateHilight=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.hilight(t)},r.prototype.colorForSeries=function(e){return this.options.lineColors[e%this.options.lineColors.length]},r.prototype.strokeWidthForSeries=function(e){return this.options.pointWidths[e%this.options.pointWidths.length]},r.prototype.strokeForSeries=function(e){return this.options.pointStrokeColors[e%this.options.pointStrokeColors.length]},r.prototype.pointFillColorForSeries=function(e){return this.options.pointFillColors[e%this.options.pointFillColors.length]},r}(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={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=["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.colorForSeries(e)),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(e){this.colorForSeriesAndValue=u(this.colorForSeriesAndValue,this),this.hoverColorForSeriesAndValue=u(this.hoverColorForSeriesAndValue,this),this.updateHilight=u(this.updateHilight,this),this.hilight=u(this.hilight,this),this.updateHover=u(this.updateHover,this);if(!(this instanceof t.Bar))return new t.Bar(e);r.__super__.constructor.call(this,e)}return o(r,n),r.prototype.init=function(){var e,t=this;return this.barFace=Raphael.animation({opacity:this.options.barHoverOpacity},25,"linear"),this.barDeface=Raphael.animation({opacity:1},25,"linear"),this.prevHilight=null,this.el.mousemove(function(e){return t.updateHilight(e.pageX)}),this.options.hideHover&&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)},r.prototype.defaults={barSizeRatio:.5,barGap:3,barStrokeWidths:[0],barStrokeColors:["#ffffff"],barFillColors:["#0b62a4","#7a92a3","#4da74d","#afd8f8","#edc240","#cb4b4b","#9440ed"],barHoverOpacity:.95,hoverPaddingX:10,hoverPaddingY:5,hoverMargin:10,hoverFillColor:"#fff",hoverBorderColor:"#ccc",hoverBorderWidth:2,hoverOpacity:.95,hoverLabelColor:"#444",hoverFontSize:12,hideHover:!1,xLabels:"auto",xLabelFormat:null},r.prototype.overridePadding=function(){var e,t;return e=Math.max(this.measureText(this.yAxisFormat(this.ymin),this.options.gridTextSize).width,this.measureText(this.yAxisFormat(this.ymax),this.options.gridTextSize).width),this.left=e+this.paddingLeft,this.right=this.elementWidth-this.paddingRight,this.width=this.right-this.left,t=this.width/this.data.length,this.barsoffset=this.options.barSizeRatio*t/2,this.barwidth=(this.options.barSizeRatio*t-(this.options.ykeys.length-1)*this.options.barGap)/this.options.ykeys.length,this.halfBarsWidth=Math.round(this.options.ykeys.length/2)*(this.barwidth+this.options.barGap),this.paddingLeft+=this.halfBarsWidth,this.paddingRight+=this.halfBarsWidth},r.prototype.calc=function(){return this.calcBars(),this.generateBars(),this.calcHoverMargins()},r.prototype.calcBars=function(){var e,t,n,r,i,s;i=this.data,s=[];for(n=0,r=i.length;n=i;t=0<=i?++r:--r)e=function(){var e,r,i,s;i=this.data,s=[];for(e=0,r=i.length;e1?s.push(this.createBars(t,e,this.barwidth)):s.push(null);return s}.call(this)},r.prototype.draw=function(){return this.drawXAxis(),this.drawSeries(),this.drawHover(),this.hilight(this.options.hideHover?null:this.data.length-1)},r.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.widtht;n=0<=t?++e:--e)r.push([]);return r}.call(this),o=[];for(n=i=s=this.options.ykeys.length-1;s<=0?i<=0:i>=0;n=s<=0?++i:--i)t=this.bars[n],t.length>0?o.push(function(){var i,s,o;o=[];for(i=0,s=t.length;ii;e=0<=i?++r:--r)t=this.cumulative?this.options.ykeys.length-e-1:e,n=this.r.text(0,this.options.hoverFontSize*1.5*(t+1.5)-this.hoverHeight/2,"").attr("font-size",this.options.hoverFontSize),this.yLabels.push(n),s.push(this.hoverSet.push(n));return s},r.prototype.updateHover=function(t){var n,r,i,s,o,u,a,f,l;this.hoverSet.show(),i=this.data[t],this.xLabel.attr("text",i.label),l=i.y;for(n=a=0,f=l.length;athis.hoverHeight+this.options.hoverPaddingY*2+this.options.hoverMargin+this.top?u=u-this.hoverHeight/2-this.options.hoverPaddingY-this.options.hoverMargin:u=u+this.hoverHeight/2+this.options.hoverPaddingY+this.options.hoverMargin,u=Math.max(this.top+this.hoverHeight/2+this.options.hoverPaddingY,u),u=Math.min(this.bottom-this.hoverHeight/2-this.options.hoverPaddingY,u),s=Math.min(this.right-r/2-this.options.hoverPaddingX,this.data[t]._x),s=Math.max(this.left+r/2+this.options.hoverPaddingX,s),this.hoverSet.attr("transform","t"+s+","+u)},r.prototype.hideHover=function(){return this.hoverSet.hide()},r.prototype.hilight=function(e){var t,n,r,i,s;if(this.prevHilight!==null&&this.prevHilight!==e)for(t=n=0,i=this.seriesBars.length-1;0<=i?n<=i:n>=i;t=0<=i?++n:--n)this.seriesBars[t][this.prevHilight]&&this.seriesBars[t][this.prevHilight].animate(this.barDeface);if(e!==null&&this.prevHilight!==e){for(t=r=0,s=this.seriesBars.length-1;0<=s?r<=s:r>=s;t=0<=s?++r:--r)this.seriesBars[t][e]&&this.seriesBars[t][e].animate(this.barFace);this.updateHover(e)}this.prevHilight=e;if(e===null)return this.hideHover()},r.prototype.updateHilight=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.hilight(t)},r.prototype.strokeWidthForSeries=function(e){return this.options.barStrokeWidths[e%this.options.barStrokeWidths.length]},r.prototype.strokeForSeries=function(e){return this.options.barStrokeColors[e%this.options.barStrokeColors.length]},r.prototype.hoverColorForSeriesAndValue=function(e,t){var n;return n=this.colorForSeriesAndValue(e,t),typeof n=="string"?n.split("-").pop():n},r.prototype.colorForSeriesAndValue=function(e,t){var n,r,i,s,o,u,a,f;return r=this.options.barFillColors[e%this.options.barFillColors.length],r.indexOf(" ")===-1?r:(r=r.split(/\s/),i=function(e,t,n){var r,i;return r=function(e,t){return e+Math.round((t-e)*n)},i={r:r(e.r,t.r),g:r(e.g,t.g),b:r(e.b,t.b)},Raphael.color("rgb("+i.r+","+i.g+","+i.b+")")},u=1-(t-this.ymin)/(this.ymax-this.ymin),f=Raphael.color(r[0]),n=Raphael.color(r[1]),r.length===3?(n=Raphael.color(r[2]),s=Raphael.color(r[1]),u>.5?(a=i(s,n,2*(u-.5)),"90-"+n.hex+"-"+a.hex):(a=i(f,s,u*2),o=100-Math.round(100*(.5-u)/(1-u)),"90-"+n.hex+"-"+s.hex+":"+o+"-"+a.hex)):(a=i(f,n,u),"90-"+n.hex+"-"+a.hex))},r}(t.Grid),t.Donut=function(){function n(n){this.select=u(this.select,this);if(!(this instanceof t.Donut))return new t.Donut(n);typeof n.element=="string"?this.el=e(document.getElementById(n.element)):this.el=e(n.element),this.options=e.extend({},this.defaults,n);if(this.el===null||this.el.length===0)throw new Error("Graph placeholder not found.");if(n.data===void 0||n.data.length===0)return;this.data=n.data,this.el.addClass("graph-initialised"),this.redraw()}return n.prototype.defaults={colors:["#0B62A4","#3980B5","#679DC6","#95BBD7","#B0CCE1","#095791","#095085","#083E67","#052C48","#042135"],formatter:t.commas},n.prototype.redraw=function(){var e,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S,x;this.el.empty(),this.r=new Raphael(this.el[0]),n=this.el.width()/2,r=this.el.height()/2,h=(Math.min(n,r)-10)/3,c=0,w=this.data;for(d=0,g=w.length;dMath.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