I am trying to adding a general shape to highlight an area where Y is greater than X in JFreechart.
for that i have defined a general path.
int x3Points[] = {0, (int) Math.max(maxX, maxY), (int) Math.max(maxX, maxY), 0};
int y3Points[] = {0, (int) Math.max(maxX, maxY), (int) maxY, (int) maxY};
GeneralPath filledPolygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, x3Points.length);
filledPolygon.moveTo(x3Points[0], y3Points[0]);
for (int index = 1; index < x3Points.length; index++) {
filledPolygon.lineTo(x3Points[index], y3Points[index]);
}
filledPolygon.lineTo(x3Points[0], y3Points[0]);
filledPolygon.closePath();
Graphics graphics = getGraphics(); // i am not sure if calling getGraphics() method of JFrame is a good idea. but if not how to get Graphics() to draw on chart
Graphics2D g2d = (Graphics2D) graphics;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2d.setPaint(Color.gray);
g2d.fill(filledPolygon);
g2d.dispose();
XYShapeAnnotation xyShapeAnnotation = new XYShapeAnnotation(filledPolygon, new BasicStroke(2.f), Color.black);
renderer.addAnnotation(xyShapeAnnotation, Layer.BACKGROUND);
the shape is added to the chart but it is not filled with black color. i guess the getGraphics() method that i am using is not correct. but how to get graphics of JFreechart.
Don't use getGraphics()
; the returned graphics context will become invalid after subsequent updates. Instead, specify the desired fillPaint
in your XYShapeAnnotation
constructor. Later calls to draw()
will fill()
the Shape
accordingly, as shown in the example below. Note a few common pitfalls:
The desired Layer
should be specified, as shown here.
The shape coordinates must be specified in data space, as shown here.
The winding rule defines the interior for fill()
, as discussed here.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.geom.GeneralPath;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYShapeAnnotation;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.ui.Layer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
/**
* @see https://stackoverflow.com/q/59588078/230513
* @see http://stackoverflow.com/a/35236100/261156
*/
public class AnnotationTest {
private static final BasicStroke STROKE = new BasicStroke(2.0f);
private static final int N = 16;
private static final int W = 1;
private static final int H = W;
public static void main(String[] args) {
EventQueue.invokeLater(new AnnotationTest()::display);
}
private void display() {
XYDataset data = createDataset();
JFreeChart chart = ChartFactory.createXYLineChart("Annotation Test", "X", "Y",
data, PlotOrientation.VERTICAL, true, true, false);
XYPlot plot = chart.getXYPlot();
XYLineAndShapeRenderer renderer
= (XYLineAndShapeRenderer) plot.getRenderer();
renderer.addAnnotation(new XYShapeAnnotation(initPath(4, 4),
STROKE, Color.gray, Color.red), Layer.FOREGROUND);
renderer.addAnnotation(new XYShapeAnnotation(initPath(8, 8),
STROKE, Color.gray, Color.blue), Layer.FOREGROUND);
renderer.addAnnotation(new XYShapeAnnotation(initPath(12, 12),
STROKE, Color.gray, Color.green), Layer.FOREGROUND);
ChartFrame frame = new ChartFrame("Annotation Test", chart);
frame.pack();
frame.setSize(640, 480);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private GeneralPath initPath(int x, int y) {
GeneralPath path = new GeneralPath();
path.moveTo(x, y);
path.lineTo(x - W, y - H);
path.lineTo(x + W, y - H);
path.lineTo(x - W, y + H);
path.lineTo(x + W, y + H);
path.lineTo(x, y);
return path;
}
private static XYDataset createDataset() {
XYSeriesCollection result = new XYSeriesCollection();
XYSeries series = new XYSeries("Test");
for (int i = 0; i < N; i++) {
series.add(i, i);
}
result.addSeries(series);
return result;
}
}