Trying to figure out overlaid chart

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
Neil Aggarwal

Trying to figure out overlaid chart

Post by Neil Aggarwal » Tue Mar 26, 2002 5:53 am

Hello:

I am trying to figure out how to work with the overload chart, but I
am having trouble.

I want a graph with a vertical axis that goes from 0 to 5. I dont
want the axis to have values displayed on it.

I want a horizontal axis that goes from 1100 to 2500. It should
have a label of "Daily Caloric Intake"

I want these items displayed on the chart:
1. A horizontal line from (1200,1) to (1500,1) with a label
of "Advisory Range"
2. A marker at the point (2100,2) with a label of "Recommended"
3. A marker at the point (2400,3) with a label of "Current"
4. A horizontal line from (2000,4) to (2300,4) with a label of
"Normal Range"
If the lines can have markers at their endpoints, that would be nice as
well.

Here is my code so far after looking at the demos:
// Create a common x axis
NumberAxis xAxis = new HorizontalNumberAxis("Daily Caloric Intake");
xAxis.setTickMarksVisible(true);
xAxis.setCrosshairVisible(false);
xAxis.setAutoRangeIncludesZero(false);
xAxis.setMinimumAxisValue(1100);
xAxis.setMaximumAxisValue(2500);

// make one vertical axis for each (vertical) chart
NumberAxis yAxis = new VerticalNumberAxis();
yAxis.setTickMarksVisible(false);
yAxis.setCrosshairVisible(false);
yAxis.setMinimumAxisValue(0);
yAxis.setMaximumAxisValue(5);

OverlaidPlot overlaidPlot = new OverlaidPlot(xAxis, yAxis);

XYSeriesCollection dataSet = new XYSeriesCollection();
XYSeries data = new XYSeries("Advisory Range");
try {
data.add(new Integer(1200),new Integer(1));
data.add(new Integer(1500),new Integer(1));
} catch( SeriesException e ) {
handleException(e,request,response);
return;
}
dataSet.addSeries(data);
overlaidPlot.add(ChartFactory.createCombinableXYChart(xAxis, yAxis, dataSet));

dataSet = new XYSeriesCollection();
data = new XYSeries("Normal Range");
try {
data.add(new Integer(2000),new Integer(4));
data.add(new Integer(2300),new Integer(4));
} catch( SeriesException e ) {
handleException(e,request,response);
return;
}
dataSet.addSeries(data);
overlaidPlot.add(ChartFactory.createCombinableXYChart(xAxis, yAxis, dataSet));

JFreeChart chart = new JFreeChart(dataSet, overlaidPlot, "Daily Caloric Intake", JFreeChart.DEFAULT_TITLE_FONT, true);

// Set the background paint
....

// Output the image
....

You can see my current output at this page:
http://dev.jammconsulting.com/burnrated ... tSession=1

Obviously, the output is not what I anticipated:
There is no label for "Advisory Range"
The ranges are not what I thought they would be.
There is a glitch in the graph on the bottom left corner.

I am also trying to figure out how to put the markers on the plot.

Any suggestions?

Thanks,
Neil

David Gilbert

Re: Trying to figure out overlaid chart

Post by David Gilbert » Tue Mar 26, 2002 6:30 pm

Hi Neil,

I'm not sure if you need to use the combined plot...although I might not be understanding your requirement fully. You ought to be able to use several series on one XYPlot to get close to what you want. I'll put together a small example tonight if I get a chance...

Regards,

DG.

Neil Aggarwal

Re: Trying to figure out overlaid chart

Post by Neil Aggarwal » Tue Mar 26, 2002 8:47 pm

I understand how to add multiple series to an XY plot, but I want markers on the single points (And hopefully on the ends of the lines). Is this possible on an XY chart?

Neil Aggarwal

Re: Trying to figure out overlaid chart

Post by Neil Aggarwal » Tue Mar 26, 2002 9:12 pm

I tried to do it with an XY chart with multiple series.

You can see my result at:
http://dev.JAMMConsulting.com/burnrated ... rtTest.jsp

The problem is that the single points disappear.

Here is my code:
// Create a data set for the graph
XYSeriesCollection dataSet = new XYSeriesCollection();

XYSeries data = new XYSeries("Advisory Range");
data.add(new Integer(1200),new Integer(1));
data.add(new Integer(1500),new Integer(1));
dataSet.addSeries(data);

data = new XYSeries("Recommended");
data.add(new Integer(2100),new Integer(2));
dataSet.addSeries(data);

data = new XYSeries("Current");
data.add(new Integer(2400),new Integer(3));
dataSet.addSeries(data);

data = new XYSeries("Average Range");
data.add(new Integer(2000),new Integer(4));
data.add(new Integer(2300),new Integer(4));
dataSet.addSeries(data);

JFreeChart chart = ChartFactory.createXYChart("Caloric Intake Chart",
"Daily Caloric Intake",
null,
dataSet, true);

NumberAxis y_axis = (NumberAxis)chart.getPlot().getAxis(Axis.VERTICAL);
y_axis.setMinimumAxisValue(0);
y_axis.setMaximumAxisValue(5);

// Set the background and output the image
....

David Gilbert

Re: Trying to figure out overlaid chart

Post by David Gilbert » Tue Mar 26, 2002 11:00 pm

Near the end just after you create your chart, add the following:

XYItemRenderer renderer = new StandardXYItemRenderer(StandardXYItemRenderer.SHAPES_AND_LINES);
XYPlot plot = (XYPlot)chart.getPlot();
plot.setXYItemRenderer(renderer);

The renderer will call the getShape(...) method in the Plot class to get a shape for each series...at the moment that method just returns a circle every time, it needs work!

Also, I had to change the SeriesException class to extend RuntimeException so I wouldn't need to wrap the data.add(...) methods in try/catch code.

Hope that helps,

DG.

Neil Aggarwal

Re: Trying to figure out overlaid chart

Post by Neil Aggarwal » Wed Mar 27, 2002 12:10 am

David:

You can take a look at my final chart at:
http://dsl.jammconsulting.com/burnrated ... rtTest.jsp

I think it looks very good, except as you said, it would be nice
to have different symbols for each of the series. That is not a big
problem for now.

I would like to express my appreciation for all of the efforts that you
and the other developers have put in. This is a very functional package
and one that I hope to contribute to in the near future.

Thanks,
Neil

David Gilbert

Re: Trying to figure out overlaid chart

Post by David Gilbert » Wed Mar 27, 2002 9:47 am

Hi Neil,

A simple, but not very flexible, way to change the shapes is to modify the getShapes(...) method in the Plot class like this:

public Shape getShape(int series, int item, double x, double y, double scale) {

if (series==0) {
return new Rectangle2D.Double(x-0.5*scale, y-0.5*scale, scale, scale);
}
else {
return new Ellipse2D.Double(x-0.5*scale, y-0.5*scale, scale, scale);
}

}

What I plan to do is write a ShapeGenerator interface, and then have a setShapeGenerator(...) method in the plot class so that you can plug in your own shape generator and have full control over the shapes being returned (without having to modify the JFreeChart source code).

Regards,

DG.

P.S. Thanks for your comments about JFreeChart, a little bit of encouragement goes a long way!

Locked