简体   繁体   English

在 JFreechart 的 XYShapeAnnotation 中添加 GeneralPath 形状

[英]Add GeneralPath shape in XYShapeAnnotation of JFreechart

I am trying to adding a general shape to highlight an area where Y is greater than X in JFreechart.我正在尝试添加一个通用形状来突出显示 JFreechart 中 Y 大于 X 的区域。

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.我猜我使用的 getGraphics() 方法不正确。 but how to get graphics of JFreechart.但是如何获取 JFreechart 的图形。

Don't use getGraphics() ;不要使用getGraphics() the returned graphics context will become invalid after subsequent updates.返回的图形上下文在后续更新后将失效 Instead, specify the desired fillPaint in your XYShapeAnnotation constructor.相反,在您的XYShapeAnnotation构造函数中指定所需的fillPaint Later calls to draw() will fill() the Shape accordingly, as shown in the example below.稍后对draw()调用将相应地fill() Shape ,如下面的示例所示。 Note a few common pitfalls:请注意一些常见的陷阱:

  • The desired Layer should be specified, as shown here .所期望的Layer应被指定,如图这里

  • The shape coordinates must be specified in data space, as shown here .形状坐标必须在数据空间中指定,如图这里

  • The winding rule defines the interior for fill() , as discussed here .缠绕规则定义了fill()的内部,如这里所讨论的。

图片

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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM