views:

682

answers:

2

Hi, I am new to using JFreeChart and I'm sure there is a simple solution to my problem . .

PROBLEM:
I have a chart that shows multiple "events types" along the date X axis. The Y axis shows the "event category". My problem is that only the latest date of an event type is shown for each category.

In the example below The chart shows data points for Event Type 1 at June 20th(Category 1) and at June 10th (Category 2). I had also added a data point for June 10th, Category 1 but the June 20th point erases it.

I think I am misunderstanding how the CategoryPlot is working. Am I using the wrong type of chart? I thought a scatter chart would be the ticket but it only accepts numerical values. I need to have discrete string categories on my Y-axis.

If anyone can point me in the right direction, you would really make my day. Thanks for reading!

-Christine

(The code below works as-is. It is as simple as I could make it)

import java.awt.Dimension;

import javax.swing.JPanel;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.time.Day;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class EventFrequencyDemo1 extends ApplicationFrame   
{   
    public EventFrequencyDemo1(String s)   
    {   
        super(s);   
        CategoryDataset categorydataset = createDataset();   
        JFreeChart jfreechart = createChart(categorydataset);   
        ChartPanel chartpanel = new ChartPanel(jfreechart);   
        chartpanel.setPreferredSize(new Dimension(500, 270));   
        setContentPane(chartpanel);   
    }   

    private static JFreeChart createChart(CategoryDataset categorydataset)   
    {   
        CategoryPlot categoryplot = new CategoryPlot(categorydataset, new CategoryAxis("Category"), new DateAxis("Date"), new LineAndShapeRenderer(false, true));
        categoryplot.setOrientation(PlotOrientation.HORIZONTAL);
        categoryplot.setDomainGridlinesVisible(true);
        return new JFreeChart(categoryplot);   
    }   

    private static CategoryDataset createDataset()   
    {   
        DefaultCategoryDataset defaultcategorydataset = new DefaultCategoryDataset();   
        Day june10 = new Day(10, 6, 2002);   
        Day june20 = new Day(20, 6, 2002);
        // This event is overwritten by June20th
        defaultcategorydataset.setValue(new Long(june10.getMiddleMillisecond()), "Event Type 1", "Category 1");   
        defaultcategorydataset.setValue(new Long(june10.getMiddleMillisecond()), "Event Type 1", "Category 2");   
        // Overwrites the previous June10th event
        defaultcategorydataset.setValue(new Long(june20.getMiddleMillisecond()), "Event Type 1", "Category 1");   
        defaultcategorydataset.setValue(new Long(june20.getMiddleMillisecond()), "Event Type 2", "Category 2");   
        return defaultcategorydataset;   
    }   

    public static JPanel createDemoPanel()   
    {   
        JFreeChart jfreechart = createChart(createDataset());   
        return new ChartPanel(jfreechart);   
    }   

    public static void main(String args[])   
    {   
        EventFrequencyDemo1 eventfrequencydemo1 = new EventFrequencyDemo1("Event Frequency Demo");   
        eventfrequencydemo1.pack();   
        RefineryUtilities.centerFrameOnScreen(eventfrequencydemo1);   
        eventfrequencydemo1.setVisible(true);   
    }   
}  
+1  A: 

I think you are using the wrong type of dataset and chart here. It appears you are trying to create a scatter plot, so you should be using the scatter plot instead of a category plot. In the category plot, because each row/column pair only gets a single value. So, in the first call, you're saying the event1/category1 pair has a value of june10.getMiddleMillisecond then you're changing its value to june20.getMiddleMillisecond. You might also want to look at the time series plots as well.

Jeff Storey
Thanks Jeff, I was starting to get the feeling that was what the problem was. I had looked into the scatter plot but as far as I can tell, I can only use float[][] for the dataset. How can I use Strings (categories) instead of floats to plot the y-axis?If there is no plot that can do what I am looking for, maybe I need to write my own custom class? If that's the case, does anyone have suggestions for a good place to start learning about this?Thanks!-Christine
Christine
You may be able to use a CategoryTableXYDataset. I know it takes x, y values, but you could write a custom axis renderer (and a custom legend if needed0 such that the underlying values on the axis are numbers, but they render as strings. For example, the y-axis might have values 1, 2 and 3, but the renderer would render them as june 1, june 2, june 3. It's not an ideal solution but the type of chart you're trying to create doesn't really fit in with the existing JFreeChart plots and is probably easier than writing your own plot.
Jeff Storey
A: 

In addition to @Jeff Storey's suggestions, you may get some inspiration from the JFreeChart Samples, and don't overlook the Demo application, available via Java Web Start. I'm not sure I follow your requirements, but DefaultMultiValueCategoryDataset is described as "A category dataset that defines multiple values for each item."

Addendum: If you want to stick with LineAndShapeRenderer, both LineAndShapeRenderer(false, true) and setBaseLinesVisible() can preclude line drawing.

trashgod
Thank you! Using the DefaultMultiValueCategoryDataset got me half way there. The other thing I had to do was use a ScatterRenderer instead of a LineAndShapeRenderer. I'm now having problems with the autorange being too narrow but I'll have to look further into that. Thank you both again for your wonderful help! :)-Christine
Christine
Excellent! I haven't used `ScatterRenderer`, but I've commented on `LineAndShapeRenderer` above. See also http://stackoverflow.com/questions/2081676/looking-for-open-source-tool-for-drawing-charts-in-java/2082297#2082297
trashgod