Stacked Bar Graph in Rails

By Nick

A while ago, I stumbled upon some nice ccs-graphs that did precisely what I needed at work. I wanted to show the evolution of some stats over time, in stacked-bar format. After some googling, I found a simple rails helper for css graphs. I needed some more stuff, but is was definitely a very good starting point.

The final graph I wanted to have looks something like this:

  • 38
  • 29
  • 36
  • 28
  • 34
  • 27
  • 32
  • 26
  • 30
  • 25
  • 28
  • 24
  • 26
  • 23
  • 24
  • 22
  • 22
  • 21
  • 20
  • 20

It turned out this was actually easy to do:
In my view, I wanted to have a clean and simple helper to call:

  <%= stacked_bar_graph @stats, {:classes => %w(p1 p2),
                                 :series => [:good, :bad],
                                 :width => 40,
                                 :title => :date} %>

The actual helper lives in my application_helper.rb and looks like this:

def stacked_bar_graph(stats, options)
    classes = options[:classes]
    series = options[:series]
    width = options[:width] || 40
    title = options[:title] || ""
    graph_class = options[:graph_class] || "graph"
 
    html = <<-"HTML"
     <ul class="#{graph_class}">
    HTML
    li_items = []
    stats.each_with_index do |stat, index|
      total = 0
      series.each_with_index do |serie, serie_index|
        value = stat.send("#{serie.to_s}")
        total += value
        li = <<-"HTML"
      	<li class="#{classes[serie_index]}" title="#{stat.send(title.to_s)}"
                         style="height: #{total}px; left: #{index*width}px;">#{value}</li>
        HTML
        li_items << li
      end
    end
    html += li_items.reverse.join("\n")
    html += "</ul>"
end

The stylesheet that makes the list come to live is shown below:

.graph {
background:#EEEEEE url(../images/horizontal_line.png) repeat scroll left bottom;
border:4px solid #999999;
font-family:Helvetica,Geneva,sans-serif;
font-size:11px;
font-size-adjust:none;
font-stretch:normal;
font-style:normal;
font-variant:normal;
font-weight:normal;
height:200px;
width: 401px;
line-height:normal;
margin:1em 0pt;
padding:0pt;
position:relative;
}
.graph li {
background:#666666  repeat-y scroll right top;
border-color:#555555 rgb(85, 85, 85) -moz-use-text-color;
border-style:solid solid none;
border-width:1px 1px medium;
bottom:0pt;
color:#FFFFFF;
list-style-image:none;
list-style-position:outside;
list-style-type:none;
margin:0pt;
padding:0pt;
position:absolute;
text-align:center;
width:39px;
}
.graph li.p1{ background-color: green}
.graph li.p2{ background-color: red}

Hope you enjoyed it. In a next post, I’ll explain how I turned this helper into a rails plugin.

Share This

Leave a Reply


Close
E-mail It
Socialized through Gregarious 42