Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
21627 kshitij.so 1
class Morris.Bar extends Morris.Grid
2
  constructor: (options) ->
3
    return new Morris.Bar(options) unless (@ instanceof Morris.Bar)
4
    super($.extend {}, options, parseTime: false)
5
 
6
  init: ->
7
    @cumulative = @options.stacked
8
 
9
    if @options.hideHover isnt 'always'
10
      @hover = new Morris.Hover(parent: @el)
11
      @on('hovermove', @onHoverMove)
12
      @on('hoverout', @onHoverOut)
13
      @on('gridclick', @onGridClick)
14
 
15
  # Default configuration
16
  #
17
  defaults:
18
    barSizeRatio: 0.75
19
    barGap: 3
20
    barColors: [
21
      '#0b62a4'
22
      '#7a92a3'
23
      '#4da74d'
24
      '#afd8f8'
25
      '#edc240'
26
      '#cb4b4b'
27
      '#9440ed'
28
    ]
29
    xLabelMargin: 50
30
 
31
  # Do any size-related calculations
32
  #
33
  # @private
34
  calc: ->
35
    @calcBars()
36
    if @options.hideHover is false
37
      @hover.update(@hoverContentForRow(@data.length - 1)...)
38
 
39
  # calculate series data bars coordinates and sizes
40
  #
41
  # @private
42
  calcBars: ->
43
    for row, idx in @data
44
      row._x = @left + @width * (idx + 0.5) / @data.length
45
      row._y = for y in row.y
46
        if y? then @transY(y) else null
47
 
48
  # Draws the bar chart.
49
  #
50
  draw: ->
51
    @drawXAxis() if @options.axes
52
    @drawSeries()
53
 
54
  # draw the x-axis labels
55
  #
56
  # @private
57
  drawXAxis: ->
58
    # draw x axis labels
59
    ypos = @bottom + @options.padding / 2
60
    prevLabelMargin = null
61
    prevAngleMargin = null
62
    for i in [0...@data.length]
63
      row = @data[@data.length - 1 - i]
64
      label = @drawXAxisLabel(row._x, ypos, row.label)
65
      textBox = label.getBBox()
66
      label.transform("r#{-@options.xLabelAngle}")
67
      labelBox = label.getBBox()
68
      label.transform("t0,#{labelBox.height / 2}...")
69
      if @options.xLabelAngle != 0
70
        offset = -0.5 * textBox.width *
71
          Math.cos(@options.xLabelAngle * Math.PI / 180.0)
72
        label.transform("t#{offset},0...")
73
      # try to avoid overlaps
74
      if (not prevLabelMargin? or
75
          prevLabelMargin >= labelBox.x + labelBox.width or
76
          prevAngleMargin? and prevAngleMargin >= labelBox.x) and
77
         labelBox.x >= 0 and (labelBox.x + labelBox.width) < @el.width()
78
        if @options.xLabelAngle != 0
79
          margin = 1.25 * @options.gridTextSize /
80
            Math.sin(@options.xLabelAngle * Math.PI / 180.0)
81
          prevAngleMargin = labelBox.x - margin
82
        prevLabelMargin = labelBox.x - @options.xLabelMargin
83
      else
84
        label.remove()
85
 
86
  # draw the data series
87
  #
88
  # @private
89
  drawSeries: ->
90
    groupWidth = @width / @options.data.length
91
    numBars = if @options.stacked? then 1 else @options.ykeys.length
92
    barWidth = (groupWidth * @options.barSizeRatio - @options.barGap * (numBars - 1)) / numBars
93
    leftPadding = groupWidth * (1 - @options.barSizeRatio) / 2
94
    zeroPos = if @ymin <= 0 and @ymax >= 0 then @transY(0) else null
95
    @bars = for row, idx in @data
96
      lastTop = 0
97
      for ypos, sidx in row._y
98
        if ypos != null
99
          if zeroPos
100
            top = Math.min(ypos, zeroPos)
101
            bottom = Math.max(ypos, zeroPos)
102
          else
103
            top = ypos
104
            bottom = @bottom
105
 
106
          left = @left + idx * groupWidth + leftPadding
107
          left += sidx * (barWidth + @options.barGap) unless @options.stacked
108
          size = bottom - top
109
 
110
          top -= lastTop if @options.stacked
111
          @drawBar(left, top, barWidth, size, @colorFor(row, sidx, 'bar'))
112
 
113
          lastTop += size
114
        else
115
          null
116
 
117
  # @private
118
  #
119
  # @param row  [Object] row data
120
  # @param sidx [Number] series index
121
  # @param type [String] "bar", "hover" or "label"
122
  colorFor: (row, sidx, type) ->
123
    if typeof @options.barColors is 'function'
124
      r = { x: row.x, y: row.y[sidx], label: row.label }
125
      s = { index: sidx, key: @options.ykeys[sidx], label: @options.labels[sidx] }
126
      @options.barColors.call(@, r, s, type)
127
    else
128
      @options.barColors[sidx % @options.barColors.length]
129
 
130
  # hit test - returns the index of the row beneath the given coordinate
131
  #
132
  hitTest: (x, y) ->
133
    return null if @data.length == 0
134
    x = Math.max(Math.min(x, @right), @left)
135
    Math.min(@data.length - 1,
136
      Math.floor((x - @left) / (@width / @data.length)))
137
 
138
  # click on grid event handler
139
  #
140
  # @private
141
  onGridClick: (x, y) =>
142
    index = @hitTest(x, y)
143
    @fire 'click', index, @options.data[index], x, y
144
 
145
  # hover movement event handler
146
  #
147
  # @private
148
  onHoverMove: (x, y) =>
149
    index = @hitTest(x, y)
150
    @hover.update(@hoverContentForRow(index)...)
151
 
152
  # hover out event handler
153
  #
154
  # @private
155
  onHoverOut: =>
156
    if @options.hideHover isnt false
157
      @hover.hide()
158
 
159
  # hover content for a point
160
  #
161
  # @private
162
  hoverContentForRow: (index) ->
163
    row = @data[index]
164
    content = "<div class='morris-hover-row-label'>#{row.label}</div>"
165
    for y, j in row.y
166
      content += """
167
        <div class='morris-hover-point' style='color: #{@colorFor(row, j, 'label')}'>
168
          #{@options.labels[j]}:
169
          #{@yLabelFormat(y)}
170
        </div>
171
      """
172
    if typeof @options.hoverCallback is 'function'
173
      content = @options.hoverCallback(index, @options, content)
174
    x = @left + (index + 0.5) * @width / @data.length
175
    [content, x]
176
 
177
  drawXAxisLabel: (xPos, yPos, text) ->
178
    label = @raphael.text(xPos, yPos, text)
179
      .attr('font-size', @options.gridTextSize)
180
      .attr('font-family', @options.gridTextFamily)
181
      .attr('font-weight', @options.gridTextWeight)
182
      .attr('fill', @options.gridTextColor)
183
 
184
  drawBar: (xPos, yPos, width, height, barColor) ->
185
    @raphael.rect(xPos, yPos, width, height)
186
      .attr('fill', barColor)
187
      .attr('stroke-width', 0)