Wednesday, December 5, 2012

Using JFreeChart in your RCP

JFreeChart is a charting library available under LGPL. Designed for AWT/Swing it takes some (minor) effort to make it work with SWT. There is a tutorial available from Lars Vogel which shows how to use this with swing, so I will focus on how to integrate this into your own plug-ins.

Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online.External libraries needed for this tutorial are not provided on my github site!

Step 1: Create the JFreeChart plug-in

We will put all required libraries into a separate plug-in. First we need to download JFreeChart. Unzip the archive and switch back to Eclipse.

Create a new Plug-in from Existing JAR Archives. On the Jar selection page add jfreechart-1.0.19.jar, jfreechart-1.0.19-swt.jar and jcommon-1.0.23.jar from jfreechart/lib folder. You can do this by using the Add External... button.

On the next page set the Project name to org.jfree.chart and uncheck Unzip the JAR archives into the project. Then finish the wizard.

The manifest file is automatically opened. Switch to the Dependencies tab and add a dependency to org.eclipse.swt.

Step 2: Create a sample chart

For the view I created a separate plug-in. Add org.jfree.chart as a dependency and define a new view. The source code is pretty straight forward and mostly taken from Lars' tutorial.
package com.codeandme.jfreechart;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.experimental.chart.swt.ChartComposite;
import org.jfree.util.Rotation;

public class DemoView extends ViewPart {

 @Override
 public void createPartControl(Composite parent) {
  final PieDataset dataset = createDataset();
  final JFreeChart chart = createChart(dataset, "Operating Systems");

  new ChartComposite(parent, SWT.NONE, chart, true);
 }

 private PieDataset createDataset() {
  final DefaultPieDataset result = new DefaultPieDataset();
  result.setValue("Linux", 29);
  result.setValue("Mac", 20);
  result.setValue("Windows", 51);
  return result;
 }

 private org.jfree.chart.JFreeChart createChart(final PieDataset dataset, final String title) {
  final JFreeChart chart = ChartFactory.createPieChart3D(title, dataset, true, true, false);
  final PiePlot3D plot = (PiePlot3D) chart.getPlot();
  plot.setStartAngle(290);
  plot.setDirection(Rotation.CLOCKWISE);
  plot.setForegroundAlpha(0.5f);
  return chart;
 }

 @Override
 public void setFocus() {
 }
}

To use JFreeChart under SWT you create a chart the same way as for Swing and display it using a ChartComposite (see line 21).

Your view should look like this:


If you use JFreeChart in your own products remember that it is licensed under LGPL. Consider buying the developers guide to support this great library.

7 comments:

  1. Eclipse BIRT project is already providing a rich and powerfull chart engine that runs with Swing, SWT and more...
    http://www.eclipse.org/projects/project.php?id=birt
    Tutorial here : http://www.eclipse.org/articles/article.php?file=Article-BIRTChartEngine/index.html

    ReplyDelete
  2. Do you know if JFreeChart is still being developed? I had noted an issue with the SWT ChartComposite, and had to use a back-leveled library (version 1.0.13) to get around it. Since I found this one fairly quickly, I was concerned that there were more issues I was going to run into.

    I found the API very easy to use, and was hopeful that I could use this to do some charting in my Eclipse RCP application...but since it seems to be languishing on the development side, I've dropped the idea for now.

    ReplyDelete
    Replies
    1. Seems there is some renovation ongoing with the library. Checking the commits on github (https://github.com/jfree/jfreechart-fse/commits/master) it seems development is still ongoing. Still SWT seems abandoned (http://sourceforge.net/mailarchive/message.php?msg_id=24569902).

      Delete
  3. I was using dynamic time chart.
    Timeseries chart when the mouse is clicked I want to get the time value.
    But the method I used was able to get the y-axis value.
    How can I get the x-axis time?
    Please help me.

    =========================================================
    chartComposite.addChartMouseListener(new ChartMouseListener() {

    @Override
    public void chartMouseMoved(ChartMouseEvent arg0) {

    }

    @Override
    public void chartMouseClicked(ChartMouseEvent event) {

    XYItemEntity entity = (XYItemEntity)event.getEntity();
    XYDataset dataset = entity.getDataset();

    int series = entity.getSeriesIndex();
    int item = entity.getItem();
    Comparable seriesKey = dataset.getSeriesKey(series);

    System.out.println(series + " " + item + " " + seriesKey);
    }
    });
    ===========================================================

    ReplyDelete
    Replies
    1. Here is a piece of code that is displaying X/Y coordinates for an XY plot:

      chartComposite.addChartMouseListener(new ChartMouseListener() {
      @Override
      public void chartMouseClicked(final ChartMouseEvent arg0) {
      ChartEntity entity = arg0.getEntity();

      if ((entity != null) && (entity instanceof XYItemEntity)) {
      XYItemEntity ent = (XYItemEntity) entity;

      int sindex = ent.getSeriesIndex();
      int iindex = ent.getItem();

      // TODO implement switch to MacroPlayer
      System.out.println("x = " + ent.getDataset().getXValue(sindex, iindex));
      System.out.println("y = " + ent.getDataset().getYValue(sindex, iindex));
      }

      }

      @Override
      public void chartMouseMoved(final ChartMouseEvent arg0) {
      // nothing to do
      }
      });

      HTH

      Delete
  4. Worked well (including label rendering) with jfreechart 1.0.19 ! Thanks.

    ReplyDelete