Hi,
I am using the latest JFreeChart. In my line graph, I want each line to start and end with some shape. I did some research in the news group and I found that I have to implement my own renderer to do this.
So, My questions are:
1) How would I start about doing this?
2)I already noticed that Jfreechart puts different shapes on the lines.Where does Jfreechart get these shapes?
How to use different shapes to distinguish lines
-
- Posts: 11
- Joined: Fri Feb 03, 2006 9:27 pm
2.
Code: Select all
org.jfree.chart.plot.DefaultDrawingSupplier
-
- Posts: 11
- Joined: Fri Feb 03, 2006 9:27 pm
Solved the problem
Thanks skunk for your reply.
Basically, what I did was that I implemented my renderer that extends XYLineAndShapeRenderer. I overrode drawSecondPass ( a protected method which is responsibly for drawing shapes) and I put my logic in that method.
The code is:
Basically, what I did was that I implemented my renderer that extends XYLineAndShapeRenderer. I overrode drawSecondPass ( a protected method which is responsibly for drawing shapes) and I put my logic in that method.
The code is:
Code: Select all
package com.telus.insight.graph;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.plot.CrosshairState;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.PublicCloneable;
import org.jfree.util.ShapeUtilities;
public class CustomXYLineAndShapeRenderer extends XYLineAndShapeRenderer
implements PublicCloneable,Serializable,Cloneable,XYItemRenderer {
private HashMap markedPointsPerSeries;
private ArrayList shapes;
CustomXYLineAndShapeRenderer(HashMap markedPointsPerSeries, ArrayList shapes) {
super();
this.markedPointsPerSeries = markedPointsPerSeries;
this.shapes = shapes;
}
private boolean markItem (int series, int item) {
//System.err.println("Entering markItem, series is " + series);
ArrayList pointsToBeMarked =
(ArrayList)markedPointsPerSeries.get(new Integer(series));
if (pointsToBeMarked != null) {
int firstItem = ((Integer)pointsToBeMarked.get(0)).intValue();
int secondItem = ((Integer)pointsToBeMarked.get(1)).intValue();
//System.err.println("firstItem is "+ firstItem);
//System.err.println("secondItem is " + secondItem);
if (item == firstItem || item == secondItem)
return true;
}
//System.err.println("Exiting markItem");
return false;
}
protected void drawSecondaryPass
(Graphics2D g2, XYPlot plot,XYDataset dataset,int pass, int series, int item,
ValueAxis domainAxis,Rectangle2D dataArea,ValueAxis rangeAxis,CrosshairState crosshairState,
EntityCollection entities) {
Shape entityArea = null;
boolean drawShape = markItem(series,item);
// get the data point...
double x1 = dataset.getXValue(series, item);
double y1 = dataset.getYValue(series, item);
if (Double.isNaN(y1) || Double.isNaN(x1)) {
return;
}
PlotOrientation orientation = plot.getOrientation();
RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);
double dataAreaX = dataArea.getX();
double dataAreaY = dataArea.getY();
if (drawShape) {
System.err.println("Series is " + series + " item is " + item);
System.err.println("transX1 is " + transX1 + " transY1 is " + transY1);
System.err.println("dataAreaX is " + dataAreaX + " dataAreaY is " + dataAreaY);
Shape shape = (Shape)shapes.get(series);
if (orientation == PlotOrientation.HORIZONTAL) {
shape = ShapeUtilities.createTranslatedShape(shape, transY1, transX1);
}
else if (orientation == PlotOrientation.VERTICAL) {
shape = ShapeUtilities.createTranslatedShape(shape, transX1, transY1);
}
entityArea = shape;
if (shape.intersects(dataArea)) {
if (getItemShapeFilled(series, item)) {
if (super.getUseFillPaint()) {
g2.setPaint(getItemFillPaint(series, item));
}
else {
g2.setPaint(getItemPaint(series, item));
}
g2.fill(shape);
}
if (super.getDrawOutlines()) {
if (getUseOutlinePaint()) {
g2.setPaint(getItemOutlinePaint(series, item));
}
else {
g2.setPaint(getItemPaint(series, item));
}
g2.setStroke(getItemOutlineStroke(series, item));
g2.draw(shape);
}
}
}
// draw the item label if there is one...
if (isItemLabelVisible(series, item)) {
double xx = transX1;
double yy = transY1;
if (orientation == PlotOrientation.HORIZONTAL) {
xx = transY1;
yy = transX1;
}
drawItemLabel(g2, orientation, dataset, series, item, xx, yy,(y1 < 0.0));
}
updateCrosshairValues
(crosshairState, x1, y1, transX1, transY1, plot.getOrientation());
// add an entity for the item...
if (entities != null) {
addEntity(entities, entityArea, dataset, series, item, transX1, transY1);
}
}
}