module CssGraphs VERSION='0.1.0' # Makes a vertical bar graph. # # bar_graph [["Stout", 10], ["IPA", 80], ["Pale Ale", 50], ["Milkshake", 30]] # # NOTE: Updated to take an array instead of forcing you to use *array. # NOTE: Normalizes data to fit in the viewable area instead of being fixed to 100. def bar_graph(data=[]) width = 378 height = 150 colors = %w(#ce494a #efba29 #efe708 #5a7dd6 #73a25a) floor_cutoff = 24 # Pixels beneath which values will not be drawn in graph data_max = data.inject(0) { |memo, array| array.last > memo ? array.last : memo } html = <<-"HTML"
HTML data.each_with_index do |d, index| scaled_value = scale_graph_value(d.last, data_max, 100) html += <<-"HTML"
#{d[0].to_s.humanize}
#{scaled_value < floor_cutoff ? '' : d.last} HTML end html += <<-"HTML"
HTML html end # 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,{:width => 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 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"
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"
#{d[0].to_s}
HTML end @url = url_creator.call(index,dimension) if !url_creator.nil? html += <<-"HTML"
#{bar_text}
HTML end end html += <<-"HTML"
HTML html end # Make a horizontal graph that only shows percentages. # # The label will be set as the title of the bar element. # # horizontal_bar_graph [["Stout", 10], ["IPA", 80], ["Pale Ale", 50], ["Milkshake", 30]] # # NOTE: Updated to take an array instead of forcing you to use *array. # NOTE: Does not normalize data yet...TODO def horizontal_bar_graph(data) html = <<-"HTML" HTML data.each do |d| html += <<-"HTML"
#{d[1]}%
HTML end return html end # Makes a multi-colored bar graph with a bar down the middle, representing the value. # # complex_bar_graph [["Stout", 10], ["IPA", 80], ["Pale Ale", 50], ["Milkshake", 30]] # # NOTE: Updated to take an array instead of forcing you to use *array. # NOTE: Does not normalize data yet...TODO def complex_bar_graph(data) html = <<-"HTML"
HTML data.each do |d| html += <<-"HTML"
#{d[0].to_s.humanize}
#{d[1]}%
HTML end html += "
\n
" return html end ## # Scale values within a +max+. The +max+ will usually be the height of the graph. def scale_graph_value(data_value, data_max, max) ((data_value.to_f / data_max.to_f) * max).round end end