Method: CssGraphs#multi_bar_graph

Defined in:
lib/css_graphs.rb

#multi_bar_graph(alldata = [], options = {}, &url_creator) ⇒ Object

Makes a vertical bar graph with several sets of bars.

NOTE: Normalizes data to fit in the viewable area instead of being fixed to 100.

Example: <% @data_for_graph = [[[‘January’,10],[‘February’,25],[‘March’,45]],[[‘January’,34],[‘February’,29],[‘March’,80]]] %> <%= bar_graph (@data_for_graph,=> 640,:height => 480) do |index,variable|

  url_for( :action => 'report', :month => index) 
end

%>

alldata should be an array of variables, each one an array itself, of the form:

[['label1',value1],['label2',value2]]

options hash:

  • :display_value_on_bar if set to true, will display the value on top each bar, default behavior is not to show the value

  • :colors is an array of colors in hex format: ‘#EEC2D2’ if you don’t set them, default colors will be used

  • :color_by can be set to ‘dimension’ or ‘index’

  • :width and :height set the dimensions, wich default to 378x150

url_creator_block:

the url_creator_block receives two parameters, index and variable, that are used to build the bars links. 
index is the position for this bar's that in its variable array, while variable is the variable this bar represents


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/css_graphs.rb', line 121

def multi_bar_graph(alldata=[], options={}, &url_creator)
  graph_id = (rand*10000000000000000000).to_i.to_s #we need a unique id for each graph on the page so we can have distinct styles for each of them
  if !options.nil? && options[:width] && options[:height]
    width,height=options[:width].to_i,options[:height].to_i
  else
    width,height = 378,150
  end
  colors = (%w(#ce494a #efba29 #efe708 #5a7dd6 #73a25a))*10 unless colors=options[:colors]
  floor_cutoff = 24 # Pixels beneath which values will not be drawn in graph
  data_max = (alldata.map { |data| data.max{ |a,b| a.last <=> b.last }.last } ).max
  dimensions=alldata.size
  size =  alldata.map{ |data| data.size }.max
  bar_offset = 24 #originally set to 24
  bar_group_width=(width-bar_offset)/size #originally set to 48px
  bar_increment = bar_group_width #originally set to 75
  bar_width=(bar_group_width-bar_offset)/dimensions #originally set to 28px
  bar_image_offset = bar_offset+4 #originally set to 28
  bar_padding = 2

  #p "dimensions = #{dimensions}"
  #p "bar_group_width =#{bar_group_width}"
  #p "bar_width = #{bar_width}"
  #p "bar_increment = #{bar_increment}"

  html = <<-"HTML"
  <style>
    #vertgraph-#{graph_id} {    				
        width: #{width}px; 
        height: #{height}px; 
        position: relative; 
        background-color: #eeeeee;
        border: 4px solid #999999;
        font-family: "Lucida Grande", Verdana, Arial;
    }
  
    #vertgraph-#{graph_id} dl dd {
      position: absolute;
      width: #{bar_width}px;
      height: #{height-50}px;
      bottom: 34px;
      padding: 0 !important;
      margin: 0 !important;
      background-image: url('/images/css_graphs/colorbar.jpg') no-repeat !important;
      text-align: center;
      font-weight: bold;
      color: white;
      line-height: 1.5em;
    }

    #vertgraph-#{graph_id} dl dt {
      position: absolute;
      width: #{bar_group_width}px;
      height: 25px;
      bottom: 0px;
      padding: 0 !important;
      margin: 0 !important;
      text-align: center;
      color: #444444;
      font-size: 0.8em;
    }
  HTML

  alldata.each_with_index do |data,dimension|
#    p "\n drawing dimension #{dimension}"
    data.each_with_index do |d, index|
#        bar_left = bar_offset + (bar_increment * index) 
      bar_group_left = bar_offset + (bar_increment * index) 
      bar_left = bar_group_left + ((bar_width+bar_padding)*dimension)
      #        bar_left = bar_group_left + ( 2*bar_width* (dimension-1))     
#        p "\n bar_left #{bar_left}"
      label_left = bar_group_left - 10
      background_offset = ( bar_image_offset * index ) 
      if options[:color_by]=='index'
        color=colors[index]
      else
        color=colors[dimension]
      end
      html += <<-HTML
        #vertgraph-#{graph_id} dl dd.a#{index.to_s}#{dimension.to_s} { left: #{bar_left}px; background-color: #{color}; background-position: -#{background_offset}px bottom !important; }
        #vertgraph-#{graph_id} dl dt.a#{index.to_s}#{dimension.to_s} { left: #{label_left}px; background-position: -#{background_offset}px bottom !important; }
      HTML
    end
  end  

    html += <<-"HTML"
      </style>
      <div id="vertgraph-#{graph_id}">
        <dl>
    HTML
  alldata.each_with_index do |data,dimension|    
#      data_max = data.inject(0) { |memo, array| array.last > memo ? array.last : memo }
    data.each_with_index do |d, index|
      scaled_value = scale_graph_value(d.last, data_max, height-50)
     if (options[:display_value_on_bar])
       bar_text=(scaled_value < floor_cutoff ? '' : d.last).to_s  #text on top of the bar
     else
        bar_text=''
     end  

   if dimension==0
      html += <<-"HTML"
        <!-- algo -->
        <dt class="a#{index.to_s}#{dimension.to_s}" >#{d[0].to_s}</dt>
      HTML
   end
    @url = url_creator.call(index,dimension) if !url_creator.nil?
    html += <<-"HTML"
    <a href="#{@url}">
      <!-- Tooltip for bar group -->
      <dd class="a#{index.to_s}#{dimension.to_s}" style="height: #{height-50}px;background: none;" title="#{d.last}"></dd>
      <!-- Color bar -->
      <dd class="a#{index.to_s}#{dimension.to_s}" style="height: #{scaled_value}px;" title="#{d.last}">#{bar_text}</dd>
    </a>
   HTML
    end
  end        
  html += <<-"HTML"
      </dl>
    </div>
  HTML
  
  html
end