I was getting some comments on a previous post asking about building stacked bar charts in JRuby using JFreeChart, so here’s another example:
# Mostly inspired by # http://left.subtree.org/2007/01/15/creating-sparklines-with-jfreechart/ # have JFreeChart in your classpath, obviously, as well as jcommon.jar require 'java' module Graph class StackedBar include_class 'java.io.File' include_class 'org.jfree.chart.ChartUtilities' include_class 'org.jfree.chart.JFreeChart' include_class 'org.jfree.data.category.DefaultCategoryDataset' include_class 'org.jfree.chart.ChartFactory' include_class 'org.jfree.chart.plot.PlotOrientation' def initialize(width=600, height=400, data=[]) @width = width @height = height dataset = create_sample_data() if data.empty? @chart = create_chart(dataset) end def render_to_file(filename, format="png") puts "Rendering graph to #{filename}" javafile = java.io.File.new(filename) ChartUtilities.saveChartAsPNG(javafile, @chart, @width, @height) end private def create_sample_data dataset = DefaultCategoryDataset.new dataset.addValue(1, "Submitted", "A") dataset.addValue(1, "Assigned", "A") dataset.addValue(3, "In-work", "A") dataset.addValue(1, "InVerfication", "A") dataset.addValue(2, "Delivered", "A") dataset.addValue(2, "Submitted", "B") dataset.addValue(1, "Rejected", "B") dataset.addValue(1, "Closed", "B") dataset.addValue(1, "Submitted", "C") dataset.addValue(1, "Assigned", "C") dataset.addValue(3, "In-work", "C") dataset.addValue(2, "On-hold", "C") return dataset end def create_chart(dataset) chart = ChartFactory.createStackedBarChart("XYZ's Development Projects", "Project Name", "Hours", dataset, PlotOrientation::VERTICAL, true, true, false) return chart end end # class StackedBar end # class Graph sb = Graph::StackedBar.new sb.render_to_file("stacked_bar.png")
Here’s the output:
Code here: http://kfahlgren.com/code/stacked_bar.jrb

I updated your blog entry code snippet to use the new more endorsed
Java integration methods:
1. Include Java
2. Import instead of include_class
In addition, I decided to play with the addValue method and see what I
could come up with besides raw arrays (which is actually probably the
best way of loading raw datasets) if you were handcoding a graph.
I would be fun if we could get some threads going on list to discuss
good rubification of Java API techniques…
-Tom
—– jfree.rb —-
include Java
import org.jfree.data.category.DefaultCategoryDataset
class DefaultCategoryDataset
class Inner
def initialize(dataset, row)
@dataset, @row = dataset, row.to_s
end
# a value of nil can call ‘removeValue’
def []=(column, value)
@dataset.addValue value, @row, column.to_s
end
def populate(hash)
hash.each_with_pair do |column, value|
@dataset.addValue value, @row, column.to_s
end
end
end
def [](row)
Inner.new self, row
end
end
module Graph
class StackedBar
import org.jfree.chart.ChartUtilities
import org.jfree.chart.JFreeChart
import org.jfree.chart.ChartFactory
import org.jfree.chart.plot.PlotOrientation
def initialize(width=600, height=400, dataset=create_sample_data)
@height, @width, @chart = height, width, create_chart(dataset)
end
def render_to_file(filename, format=”png”)
puts “Rendering graph to #{filename}”
javafile = java.io.File.new(filename)
ChartUtilities.saveChartAsPNG(javafile, @chart, @width, @height)
end
private
def create_sample_data
# I thought about method_missing for dataset.submitted but since these
# can be arbitrary strings with method-name unfriendly chars in it I
# decided against it.
# This also allows symbols as well as strings
dataset = DefaultCategoryDataset.new
dataset[:Submitted].populate(:A => 1, :B => 2, :C => 3)
dataset[:Assigned].populate(:A => 1, :C => 1)
dataset["In-work"].populate(:A => 3, :C => 3)
dataset[:InVerfication][:A] = 1
dataset[:Delivered][:A] = 2
dataset[:Rejected][:B] = 1
dataset[:Closed][:B] = 1
dataset["On-hold"][:C] = 2
dataset
end
def create_chart(dataset)
ChartFactory.createStackedBarChart(“XYZ’s Development Projects”,
“Project Name”,
“Hours”,
dataset,
PlotOrientation::VERTICAL,
true,
true,
false)
end
end # class StackedBar
end # class Graph
sb = Graph::StackedBar.new
sb.render_to_file(“stacked_bar.png”)