Charts with JFreeChart 1
JFreeChart is a free Java chart library that can be used to display charts from Java applications. It features:
  • A wide range of chart types
  • support for many output types, including Swing components, image files (including PNG and JPEG), and vector graphics file formats (including PDF, EPS and SVG);
  • It is distributed under the terms of the LGPL, which permits use in proprietary applications.
In this post, I will describe how to use JFreeChart to display a comparative barchart, with data that contains multiple series which have to be grouped (G1, G2) per date. This effectively gives three levels of information (series, group and date). In order to display this data in a chart, we can use a StackedBarChart from JFreeChart. Please note that this is a result of my playing around with JFreeChart, and is not from the official documentation, which means that some of my assumptions may not be accurate. Follow these steps to run the example
  1. Download JFreeChart from here.
  2. Create the DataSet: The StakedBarChart takes a CategoryDataset as input. The following piece of code shows how to add data to the CategoryDataset.
      DefaultCategoryDataset dataSet = new DefaultCategoryDataset();

    dataSet.addValue(100, "Series1 G1", "Jan 04");
    dataSet.addValue(150, "Series1 G2", "Jan 04");
    It is important to note that the order in which you add data to the Dataset, as this would affect how you assign colors to the different series.
  3. Create the renderer and assign series colors:
      GroupedStackedBarRenderer renderer = new GroupedStackedBarRenderer();
    renderer.setItemMargin(0.01);
    renderer.setDrawBarOutline(false);

    renderer.setSeriesPaint(0, Color.blue);
    renderer.setSeriesPaint(1, Color.blue);
    The order of the series in the Dataset, will dictate series number when assigning colors. You will see this in the full code shown below.
  4. Map series to groups: This is done using the KeyToGroupMap.
      KeyToGroupMap keytogroupmap = new KeyToGroupMap("G1");
    keytogroupmap.mapKeyToGroup("Series1 G1", "G1");
    keytogroupmap.mapKeyToGroup("Series2 G1", "G1");
  5. Create the Legend: Since I wanted to give same color to a given series in different groups, I had to add a legend collection that maps colors to the series
     private static LegendItemCollection createLegendItems() {
    LegendItemCollection legenditemcollection = new LegendItemCollection();
    LegendItem legenditem = new LegendItem("Series1", "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, Color.blue);
    LegendItem legenditem1 = new LegendItem("Series2", "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, Color.cyan);
    LegendItem legenditem2 = new LegendItem("Series3", "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, Color.green);
    LegendItem legenditem3 = new LegendItem("Series4", "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, Color.yellow);
    legenditemcollection.add(legenditem);
    legenditemcollection.add(legenditem1);
    legenditemcollection.add(legenditem2);
    legenditemcollection.add(legenditem3);
    return legenditemcollection;
    }
  6. The code
    package chart;

    import java.awt.Color;

    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartFrame;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.LegendItem;
    import org.jfree.chart.LegendItemCollection;
    import org.jfree.chart.axis.SubCategoryAxis;
    import org.jfree.chart.plot.CategoryPlot;
    import org.jfree.chart.plot.Plot;
    import org.jfree.chart.plot.PlotOrientation;
    import org.jfree.chart.renderer.category.GroupedStackedBarRenderer;
    import org.jfree.data.KeyToGroupMap;
    import org.jfree.data.category.CategoryDataset;
    import org.jfree.data.category.DefaultCategoryDataset;

    public class StackedBarChartTest {

    private static CategoryDataset getData() {
    DefaultCategoryDataset dataSet = new DefaultCategoryDataset();

    dataSet.addValue(100, "Series1 G1", "Jan 04");
    dataSet.addValue(150, "Series1 G2", "Jan 04");

    dataSet.addValue(60, "Series2 G1", "Feb 04");
    dataSet.addValue(90, "Series2 G2", "Feb 04");

    dataSet.addValue(70, "Series3 G2", "Feb 04");
    dataSet.addValue(99, "Series3 G1", "Feb 04");

    dataSet.addValue(100, "Series4 G1", "Feb 04");
    dataSet.addValue(80, "Series4 G2", "Feb 04");

    dataSet.addValue(20, "Series1 G1", "Feb 04");
    dataSet.addValue(50, "Series1 G2", "Feb 04");

    dataSet.addValue(10, "Series2 G1", "Jan 04");
    dataSet.addValue(40, "Series2 G2", "Jan 04");

    dataSet.addValue(10, "Series3 G2", "Jan 04");
    dataSet.addValue(50, "Series3 G1", "Jan 04");

    dataSet.addValue(10, "Series4 G1", "Jan 04");
    dataSet.addValue(60, "Series4 G2", "Jan 04");

    // dataSet.addValue(100, "Series1 G1", "Jan 04");
    // dataSet.addValue(20, "Series1 G1", "Feb 04");
    // dataSet.addValue(10, "Series2 G1", "Jan 04");
    // dataSet.addValue(60, "Series2 G1", "Feb 04");
    // dataSet.addValue(99, "Series3 G1", "Feb 04");
    // dataSet.addValue(50, "Series3 G1", "Jan 04");
    // dataSet.addValue(100, "Series4 G1", "Feb 04");
    // dataSet.addValue(10, "Series4 G1", "Jan 04");
    //
    //
    // dataSet.addValue(150, "Series1 G2", "Jan 04");
    // dataSet.addValue(50, "Series1 G2", "Feb 04");
    // dataSet.addValue(40, "Series2 G2", "Jan 04");
    // dataSet.addValue(90, "Series2 G2", "Feb 04");
    // dataSet.addValue(10, "Series3 G2", "Jan 04");
    // dataSet.addValue(70, "Series3 G2", "Feb 04");
    // dataSet.addValue(60, "Series4 G2", "Jan 04");
    // dataSet.addValue(80, "Series4 G2", "Feb 04");

    return dataSet;
    }

    private static JFreeChart createChart(CategoryDataset categorydataset) {
    JFreeChart jfreechart = ChartFactory.createStackedBarChart("Sample", null, "value", categorydataset, PlotOrientation.VERTICAL, true, true, false);
    GroupedStackedBarRenderer renderer = new GroupedStackedBarRenderer();
    renderer.setItemMargin(0.01);
    renderer.setDrawBarOutline(false);

    renderer.setSeriesPaint(0, Color.blue);
    renderer.setSeriesPaint(1, Color.blue);

    renderer.setSeriesPaint(2, Color.cyan);
    renderer.setSeriesPaint(3, Color.cyan);

    renderer.setSeriesPaint(4, Color.green);
    renderer.setSeriesPaint(5, Color.green);

    renderer.setSeriesPaint(6, Color.yellow);
    renderer.setSeriesPaint(7, Color.yellow);

    // renderer.setSeriesPaint(0, Color.blue);
    // renderer.setSeriesPaint(4, Color.blue);
    //
    // renderer.setSeriesPaint(1, Color.cyan);
    // renderer.setSeriesPaint(5, Color.cyan);
    //
    // renderer.setSeriesPaint(2, Color.green);
    // renderer.setSeriesPaint(6, Color.green);
    //
    // renderer.setSeriesPaint(3, Color.yellow);
    // renderer.setSeriesPaint(7, Color.yellow);

    KeyToGroupMap keytogroupmap = new KeyToGroupMap("G1");
    keytogroupmap.mapKeyToGroup("Series1 G1", "G1");
    keytogroupmap.mapKeyToGroup("Series2 G1", "G1");
    keytogroupmap.mapKeyToGroup("Series3 G1", "G1");
    keytogroupmap.mapKeyToGroup("Series4 G1", "G1");

    keytogroupmap.mapKeyToGroup("Series1 G2", "G2");
    keytogroupmap.mapKeyToGroup("Series2 G2", "G2");
    keytogroupmap.mapKeyToGroup("Series3 G2", "G2");
    keytogroupmap.mapKeyToGroup("Series4 G2", "G2");

    renderer.setSeriesToGroupMap(keytogroupmap);
    SubCategoryAxis subcategoryaxis = new SubCategoryAxis("Series/Month");
    subcategoryaxis.setCategoryMargin(0.03);
    subcategoryaxis.addSubCategory("G1");
    subcategoryaxis.addSubCategory("G2");

    CategoryPlot categoryplot = (CategoryPlot) jfreechart.getPlot();
    categoryplot.setDomainAxis(subcategoryaxis);
    categoryplot.setRenderer(renderer);
    categoryplot.setFixedLegendItems(createLegendItems());

    return jfreechart;
    }

    private static LegendItemCollection createLegendItems() {
    LegendItemCollection legenditemcollection = new LegendItemCollection();
    LegendItem legenditem = new LegendItem("Series1", "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, Color.blue);
    LegendItem legenditem1 = new LegendItem("Series2", "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, Color.cyan);
    LegendItem legenditem2 = new LegendItem("Series3", "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, Color.green);
    LegendItem legenditem3 = new LegendItem("Series4", "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, Color.yellow);
    legenditemcollection.add(legenditem);
    legenditemcollection.add(legenditem1);
    legenditemcollection.add(legenditem2);
    legenditemcollection.add(legenditem3);
    return legenditemcollection;
    }

    public static void main(String args[]) {

    StackedBarChartTest demo = new StackedBarChartTest();

    ChartFrame frame = new ChartFrame("First", demo.createChart(demo.getData()));
    frame.pack();
    frame.setVisible(true);
    }
    }
    Note:
    • The SubCategoryAxis is used to assign labels to Category Axis' subcategories (i.e. groups).
    • The ChartFrame is used to display the results. The results could also be written to an output stream using the ChartUtilities.writeChartAsJPEG or ChartUtilities.writeChartAsPNG methods.
    • The commented lines show how the series color is affected by the order in which the data is entered into the Dataset.

11 comments:

Abhisek said...

Hi.. Abhi...

Can u help me regarding the way of running the Jfreechart code??? It will be very much helpful for me if u can help me out.. I am stuck with it for many days.. My email id is : abh.kol@gmail.com. . .

With regards,
Abhisek

PraDz said...

hi Abhi

i am a new user of JFreechart and i wud like to create an Image Map for the Horizontal Stacked Bar chart.
i did that too. but mapping was a problem. how to set the tooltip, etc...

harmeet said...

bablu

hi abhi
can u tell me how to create the
legends in square/circle shape in pie
and bar charts. Its very urgent.
Bye

Suvoraj Biswas said...

I want my bar to be clickable like each different bar can point to some different url. Would you plz tell me how to do that?Any help/hint or resource reference from you would be appreciated.
Thanks,
Suvoraj

pankaj said...

hi Abhi
Can you please send me the jar that have org.jfree.chart.renderer.category

Thanks
With Regards
Pankaj Bansal
pankaj.bansal@sdgc.com

mayank said...

hi abhi ,

i am not able to run the javachart it is giving me the error package org.jfree.util does not exit.

ravi said...

Hi.. Abhi...

Can u help me regarding the way of running the Jfreechart code??? It will be very much helpful for me if u can help me out.. I am stuck with it for many days.. My email id is ravi.k.choudhari@gmail.com

thnks.

Mohit said...

Hi Abhi

It would be of great help if you could pls tell me how to assign the series color based on some field value which is being queried from database. I am using JasperReports for the same.

Naveen said...

Hi Abhi,

Is there a way to change the orientation of the SubCategroyAxis, for rg: In your case change the orientation of G1 , G2 label by 90 degrees.

Regards
Naveen

vardhan rao said...

Hi Abhi....

I need some hlep regarding charts, please help me i need financial charts like line charts,candlestick charts and like that

With Regards,
Dhanavardhan

rajnesh said...

Hi Abhi,

i'm working on bar chart using JFREEChart.
i'm able to get dynamic data but i'm unable to run on browser if i'm runing on browser its giving default image.Help me out
my mail id is rajnesh.thakore@gmail.com