aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/bower_components/morris.js/lib/morris.bar.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'public/bower_components/morris.js/lib/morris.bar.coffee')
-rw-r--r--public/bower_components/morris.js/lib/morris.bar.coffee208
1 files changed, 208 insertions, 0 deletions
diff --git a/public/bower_components/morris.js/lib/morris.bar.coffee b/public/bower_components/morris.js/lib/morris.bar.coffee
new file mode 100644
index 0000000..86fb32b
--- /dev/null
+++ b/public/bower_components/morris.js/lib/morris.bar.coffee
@@ -0,0 +1,208 @@
+class Morris.Bar extends Morris.Grid
+ constructor: (options) ->
+ return new Morris.Bar(options) unless (@ instanceof Morris.Bar)
+ super($.extend {}, options, parseTime: false)
+
+ init: ->
+ @cumulative = @options.stacked
+
+ if @options.hideHover isnt 'always'
+ @hover = new Morris.Hover(parent: @el)
+ @on('hovermove', @onHoverMove)
+ @on('hoverout', @onHoverOut)
+ @on('gridclick', @onGridClick)
+
+ # Default configuration
+ #
+ defaults:
+ barSizeRatio: 0.75
+ barGap: 3
+ barColors: [
+ '#0b62a4'
+ '#7a92a3'
+ '#4da74d'
+ '#afd8f8'
+ '#edc240'
+ '#cb4b4b'
+ '#9440ed'
+ ],
+ barOpacity: 1.0
+ barRadius: [0, 0, 0, 0]
+ xLabelMargin: 50
+
+ # Do any size-related calculations
+ #
+ # @private
+ calc: ->
+ @calcBars()
+ if @options.hideHover is false
+ @hover.update(@hoverContentForRow(@data.length - 1)...)
+
+ # calculate series data bars coordinates and sizes
+ #
+ # @private
+ calcBars: ->
+ for row, idx in @data
+ row._x = @left + @width * (idx + 0.5) / @data.length
+ row._y = for y in row.y
+ if y? then @transY(y) else null
+
+ # Draws the bar chart.
+ #
+ draw: ->
+ @drawXAxis() if @options.axes in [true, 'both', 'x']
+ @drawSeries()
+
+ # draw the x-axis labels
+ #
+ # @private
+ drawXAxis: ->
+ # draw x axis labels
+ ypos = @bottom + (@options.xAxisLabelTopPadding || @options.padding / 2)
+ prevLabelMargin = null
+ prevAngleMargin = null
+ for i in [0...@data.length]
+ row = @data[@data.length - 1 - i]
+ label = @drawXAxisLabel(row._x, ypos, row.label)
+ textBox = label.getBBox()
+ label.transform("r#{-@options.xLabelAngle}")
+ labelBox = label.getBBox()
+ label.transform("t0,#{labelBox.height / 2}...")
+ if @options.xLabelAngle != 0
+ offset = -0.5 * textBox.width *
+ Math.cos(@options.xLabelAngle * Math.PI / 180.0)
+ label.transform("t#{offset},0...")
+ # try to avoid overlaps
+ if (not prevLabelMargin? or
+ prevLabelMargin >= labelBox.x + labelBox.width or
+ prevAngleMargin? and prevAngleMargin >= labelBox.x) and
+ labelBox.x >= 0 and (labelBox.x + labelBox.width) < @el.width()
+ if @options.xLabelAngle != 0
+ margin = 1.25 * @options.gridTextSize /
+ Math.sin(@options.xLabelAngle * Math.PI / 180.0)
+ prevAngleMargin = labelBox.x - margin
+ prevLabelMargin = labelBox.x - @options.xLabelMargin
+ else
+ label.remove()
+
+ # draw the data series
+ #
+ # @private
+ drawSeries: ->
+ groupWidth = @width / @options.data.length
+ numBars = if @options.stacked then 1 else @options.ykeys.length
+ barWidth = (groupWidth * @options.barSizeRatio - @options.barGap * (numBars - 1)) / numBars
+ barWidth = Math.min(barWidth, @options.barSize) if @options.barSize
+ spaceLeft = groupWidth - barWidth * numBars - @options.barGap * (numBars - 1)
+ leftPadding = spaceLeft / 2
+ zeroPos = if @ymin <= 0 and @ymax >= 0 then @transY(0) else null
+ @bars = for row, idx in @data
+ lastTop = 0
+ for ypos, sidx in row._y
+ if ypos != null
+ if zeroPos
+ top = Math.min(ypos, zeroPos)
+ bottom = Math.max(ypos, zeroPos)
+ else
+ top = ypos
+ bottom = @bottom
+
+ left = @left + idx * groupWidth + leftPadding
+ left += sidx * (barWidth + @options.barGap) unless @options.stacked
+ size = bottom - top
+
+ if @options.verticalGridCondition and @options.verticalGridCondition(row.x)
+ @drawBar(@left + idx * groupWidth, @top, groupWidth, Math.abs(@top - @bottom), @options.verticalGridColor, @options.verticalGridOpacity, @options.barRadius)
+
+ top -= lastTop if @options.stacked
+ @drawBar(left, top, barWidth, size, @colorFor(row, sidx, 'bar'),
+ @options.barOpacity, @options.barRadius)
+
+ lastTop += size
+ else
+ null
+
+ # @private
+ #
+ # @param row [Object] row data
+ # @param sidx [Number] series index
+ # @param type [String] "bar", "hover" or "label"
+ colorFor: (row, sidx, type) ->
+ if typeof @options.barColors is 'function'
+ r = { x: row.x, y: row.y[sidx], label: row.label }
+ s = { index: sidx, key: @options.ykeys[sidx], label: @options.labels[sidx] }
+ @options.barColors.call(@, r, s, type)
+ else
+ @options.barColors[sidx % @options.barColors.length]
+
+ # hit test - returns the index of the row at the given x-coordinate
+ #
+ hitTest: (x) ->
+ return null if @data.length == 0
+ x = Math.max(Math.min(x, @right), @left)
+ Math.min(@data.length - 1,
+ Math.floor((x - @left) / (@width / @data.length)))
+
+ # click on grid event handler
+ #
+ # @private
+ onGridClick: (x, y) =>
+ index = @hitTest(x)
+ @fire 'click', index, @data[index].src, x, y
+
+ # hover movement event handler
+ #
+ # @private
+ onHoverMove: (x, y) =>
+ index = @hitTest(x)
+ @hover.update(@hoverContentForRow(index)...)
+
+ # hover out event handler
+ #
+ # @private
+ onHoverOut: =>
+ if @options.hideHover isnt false
+ @hover.hide()
+
+ # hover content for a point
+ #
+ # @private
+ hoverContentForRow: (index) ->
+ row = @data[index]
+ content = "<div class='morris-hover-row-label'>#{row.label}</div>"
+ for y, j in row.y
+ content += """
+ <div class='morris-hover-point' style='color: #{@colorFor(row, j, 'label')}'>
+ #{@options.labels[j]}:
+ #{@yLabelFormat(y)}
+ </div>
+ """
+ if typeof @options.hoverCallback is 'function'
+ content = @options.hoverCallback(index, @options, content, row.src)
+ x = @left + (index + 0.5) * @width / @data.length
+ [content, x]
+
+ drawXAxisLabel: (xPos, yPos, text) ->
+ label = @raphael.text(xPos, yPos, text)
+ .attr('font-size', @options.gridTextSize)
+ .attr('font-family', @options.gridTextFamily)
+ .attr('font-weight', @options.gridTextWeight)
+ .attr('fill', @options.gridTextColor)
+
+ drawBar: (xPos, yPos, width, height, barColor, opacity, radiusArray) ->
+ maxRadius = Math.max(radiusArray...)
+ if maxRadius == 0 or maxRadius > height
+ path = @raphael.rect(xPos, yPos, width, height)
+ else
+ path = @raphael.path @roundedRect(xPos, yPos, width, height, radiusArray)
+ path
+ .attr('fill', barColor)
+ .attr('fill-opacity', opacity)
+ .attr('stroke', 'none')
+
+ roundedRect: (x, y, w, h, r = [0,0,0,0]) ->
+ [ "M", x, r[0] + y, "Q", x, y, x + r[0], y,
+ "L", x + w - r[1], y, "Q", x + w, y, x + w, y + r[1],
+ "L", x + w, y + h - r[2], "Q", x + w, y + h, x + w - r[2], y + h,
+ "L", x + r[3], y + h, "Q", x, y + h, x, y + h - r[3], "Z" ]
+