我试图添加一个通用形状以突出显示JFreechart中Y大于X的区域。
为此,我定义了一条通用路径。
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);
形状已添加到图表中,但未填充黑色。我猜我正在使用的getGraphics()方法不正确。但是如何获取JFreechart的图形。
最佳答案
不要使用getGraphics()
;在后续更新之后,返回的图形上下文将变为invalid。而是在fillPaint
构造函数中指定所需的XYShapeAnnotation
。以后对draw()
的调用将相应地fill()
Shape
,如下例所示。请注意一些常见的陷阱:
如here所示,应指定所需的Layer
。
必须在数据空间中指定形状坐标,如here所示。
缠绕规则定义了fill()
的内部,如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;
}
}
关于java - 在JFreechart的XYShapeAnnotation中添加GeneralPath形状,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59588078/