multiple axes and visual cues

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

multiple axes and visual cues

Post by Todd » Tue Jun 28, 2005 2:54 am

Is there any way to draw small square shapes under a range axis with colors of series that use that axis?

I am migrating to jFreeChart's XYPlot to chart multiple series, which have the same unit of measure and therefore need to share the same axis. On the same XYPlot I need to plot other multiple series that share axis 2. Same for axis 3 and 4. I read the following in the Developer's Guide:

"12.3 Hints and Tips
When using multiple axes, you need to provide some visual cue to readers to indicate which axis applies to a particular series. In the MultipleAxisDemo1.java application, the color of the axis label text has been changed to match the series color."

When I was doing all of the laborious line drawing and creating the axis myself before jFreeChart, I would draw these small square shapes with the color of the line series next to the axis as the visual cue to readers. So, for example, an axis might have red, green, blue and orange squares under it if there were 4 series using the same axis.

However, there are no NumberAxis methods that do this. There is only the setLabelPaint method, which is good for only one series on an axis. For my application I can't have all series on an axis be the same color but with different symbols. Neither this class or any other class seems to provide methods that will give me the x,y coordinates of the axis so that I could resort to drawing the square shape outside of JFreeChart's facilities.

Todd

a solution

Post by Todd » Tue Jun 28, 2005 11:56 pm

The solution that I've come up with is to use a super class to NumberAxis and draw the visual cues for series from an overloaded drawAxisLine() method. If anyone has an easier way, please let me know.

public class ViewerNumberAxis extends NumberAxis {


/**
* Default constructor.
*/
public ViewerNumberAxis() {
this(null);
}

/**
* Constructs a Viewer number axis, using default values where necessary.
*
* @param label the axis label (<code>null</code> permitted).
*/
public ViewerNumberAxis(String label) {
super(label);
}

/**
* Returns a clone of the axis.
*
* @return A clone
*
* @throws CloneNotSupportedException if some component of the axis does
* not support cloning.
*/
public Object clone() throws CloneNotSupportedException {
ViewerNumberAxis clone = (ViewerNumberAxis) super.clone();
return clone;
}

/**
* Draws an axis line at the current cursor position and edge.
* Adds a visual series cue
*
* @param g2 the graphics device.
* @param cursor the cursor position.
* @param dataArea the data area.
* @param edge the edge.
*/
protected void drawAxisLine(Graphics2D g2, double cursor,
Rectangle2D dataArea, RectangleEdge edge) {

double xPos = 0.0;
double xPosOffset = 0.0;
if (edge == RectangleEdge.LEFT) {
xPos = cursor;
xPosOffset = 50;
}
else if (edge == RectangleEdge.RIGHT) {
xPos = cursor;
xPosOffset = -50;
}

XYPlot plot = (XYPlot) getPlot();
int axisIndex = 0;
for ( int i = 0; i < plot.getRangeAxisCount(); i ++ ){
ValueAxis a = plot.getRangeAxis( i );
if( a == (ValueAxis) this ){
axisIndex = i;
break;
}
}

XYSeriesCollection dataset = (XYSeriesCollection) plot.getDataset( axisIndex );
XYLineAndShapeRenderer render = (XYLineAndShapeRenderer) plot.getRenderer( axisIndex );
Color colorSav = g2.getColor();
int yPos = 5;
HashMap map = new HashMap();
for( int i = 0; i < dataset.getSeriesCount(); i++ ){
Color c = (Color) render.getSeriesPaint( i );
Object o = map.get( c );
if( o == null ){
g2.setColor( c );
g2.fillRect( (int) ( xPos - xPosOffset ), yPos, 5, 5 );
map.put( c, "1" );
}
yPos += 7;
}
g2.setColor( colorSav );
super.drawAxisLine( g2, cursor, dataArea, edge);
}
}

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Post by david.gilbert » Wed Jun 29, 2005 2:33 pm

I think this is a feature that is needed, so I've added an RFE (1229701) to the database at SourceForge so I don't forget about it.

Another approach that you can use (probably only useful for two y-axes) is to have two legends, one on the left and one on the right. See DualAxisDemo1.java for an example.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

Arkkimaagi
Posts: 25
Joined: Wed Jun 09, 2004 6:15 am
Location: Helsinki, Finland
Contact:

Post by Arkkimaagi » Fri Jul 01, 2005 8:06 am

Another way to show this could be organizing the legend so that there can be multiple groups each with the same title as the axis has.

This way you'd be able to see on what axis each value is supposed to be.

I really need a feature to show on what axis a series of data is on.
~ Arkkimaagi ~
Experto Credite

Locked