JRuby + JFreeChart = Sparklines

Inspired by how easy it was to get JFreeChart working and some code from former colleague Andrew Bruno, I thought it’d be nice to write some JRuby to generate Edward Tufte’s Sparklines.

Here’s some simple example code on a semi-random dataset:

# 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 Sparkline
    include_class 'java.io.File'
    include_class 'org.jfree.chart.ChartUtilities'
    include_class 'org.jfree.chart.JFreeChart'
    include_class 'org.jfree.chart.axis.NumberAxis'
    include_class 'org.jfree.chart.plot.XYPlot'
    include_class 'org.jfree.chart.renderer.xy.StandardXYItemRenderer'
    include_class 'org.jfree.data.xy.XYSeries'
    include_class 'org.jfree.data.xy.XYSeriesCollection'
    include_class 'org.jfree.chart.plot.PlotOrientation'

    def initialize(width=200, height=80, data=[])
      @width = width
      @height = height
      dataset = create_sample_data() if data.empty?
      @chart = create_chart(dataset)
    end

    def render_to_file(filename, format="png")
      javafile = java.io.File.new(filename)
      ChartUtilities.saveChartAsPNG(javafile, @chart, @width, @height)
    end

    private
    def create_sample_data
       series = XYSeries.new("Sparkline")
      data = [20]
      (1..99).each {|x|
        y = (data.last + (rand(x) + 1)) / 2
        data << y
        series.add(x, y)
      }

      dataset = XYSeriesCollection.new
      dataset.addSeries(series)
      return dataset
    end

    def create_chart(dataset)
      x = NumberAxis.new
      x.setTickLabelsVisible(false)
      x.setTickMarksVisible(false)
      x.setAxisLineVisible(false)
      x.setNegativeArrowVisible(false)
      x.setPositiveArrowVisible(false)
      x.setVisible(false)

      y = NumberAxis.new
      y.setTickLabelsVisible(false)
      y.setTickMarksVisible(false)
      y.setAxisLineVisible(false)
      y.setNegativeArrowVisible(false)
      y.setPositiveArrowVisible(false)
      y.setVisible(false)

      plot = XYPlot.new
      plot.setDataset(dataset)
      plot.setDomainAxis(x)
      plot.setDomainGridlinesVisible(false)
      plot.setDomainCrosshairVisible(false)
      plot.setRangeGridlinesVisible(false)
      plot.setRangeCrosshairVisible(false)
      plot.setRangeAxis(y)
      plot.setOutlinePaint(nil)
      plot.setRenderer(StandardXYItemRenderer.new(StandardXYItemRenderer::LINES))

      chart = JFreeChart.new(nil, JFreeChart::DEFAULT_TITLE_FONT, plot, false)
      chart.setBorderVisible(false);
      return chart
    end

  end # class Sparkline  
end # class Graph

sp = Graph::Sparkline.new
puts "Rendering sparkline"
sp.render_to_file("sparkline.png")

And the resulting sparkline chart:
An Example Sparkline Chart

Code: http://kfahlgren.com/code/sparkline.jrb

UPDATE: Removed some of the useless sample generation code

6 Responses to “JRuby + JFreeChart = Sparklines”

  1. mdweezer says:

    Have you done anything with DefaultCategoryDatasets? I’m trying to build some stacked bar charts in JRuby and your code is excellent but I can’t seem to make things work with other types of datasets, grrrrr. But then again, my Ruby isn’t exactly sharp.

    The following chunk of code is what I need to port over…

    DefaultCategoryDataset result = new DefaultCategoryDataset();
    result.addValue(0, “Closed”, “”);
    result.addValue(0, “InVerfication”, “”);
    result.addValue(0, “Delivered”, “”);
    result.addValue(0, “On-hold”, “”);
    result.addValue(0, “In-work”, “”);
    result.addValue(0, “Rejected”, “”);
    result.addValue(0, “Duplicate”, “”);
    result.addValue(0, “Assigned”, “”);
    result.addValue(0, “Submitted”, “”);

  2. Keith says:

    mdweezer:

    I haven’t the foggiest idea what you’re actually trying to do, but:

    # 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 Sparkline
        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=200, height=80, data=[])
          @width = width
          @height = height
          dataset = create_sample_data() if data.empty?
          @chart = create_chart(dataset)
        end
    
        def render_to_file(filename, format="png")
          javafile = java.io.File.new(filename)
          ChartUtilities.saveChartAsPNG(javafile, @chart, @width, @height)
        end
    
        private
        def create_sample_data
          dataset = DefaultCategoryDataset.new
          dataset.addValue(1, "Closed", "")
          dataset.addValue(1, "InVerfication", "")
          dataset.addValue(2, "Delivered", "")
          dataset.addValue(2, "On-hold", "")
          dataset.addValue(3, "In-work", "")
          dataset.addValue(3, "Rejected", "")
          dataset.addValue(3, "Duplicate", "")
          dataset.addValue(3, "Assigned", "")
          dataset.addValue(4, "Submitted", "")
    
          return dataset
        end
    
        def create_chart(dataset)
          chart = ChartFactory.createWaterfallChart("Phase","Name", "", dataset, PlotOrientation::VERTICAL, true, true, false)
          return chart
        end
      end # class Sparkline
    end # class Graph
    
    sp = Graph::Sparkline.new
    puts "Rendering sparkline"
    sp.render_to_file("sparkline.png")
  3. mdweezer says:

    Keith,

    I appreciate the response, I kept getting “addValue” incorrect method errors… I’m building stacked bar charts with the data. I’m using data scraped from a database, I just used those values to figure out how to actually add data to the dataset. Not quite sure what I was doing wrong but I”ll see what I can do. Again, I appreciate it, thanks!

  4. Keith says:

    What’s the actual error you’re getting/can you post more of the code you’re using?

    Hope this helps

  5. slonkak says:

    Would you be so kind as to help our a Ruby/Java noob? Say I just created a default, blank rails app in my jRuby install. I have the jfreechart and jcommon JARs in my classpath. What all do I have to do to get your code to work and start producing charts. I don’t know Ruby (nor the MVC framework), I don’t know Java, and I most certainly don’t know how Java works with jRuby. I would like to learn, but since I learn by example, and most examples on the net are very incomplete, I’m having a hard time. Could you provide any assistance?

  6. punk21 says:

    Hey guys, Having problem while drawing Sparkline Charts then chk this out visifire an amazing charting component which is powered by silverlight offered under open source