【问题标题】:Add GeneralPath shape in XYShapeAnnotation of JFreechart在 JFreechart 的 XYShapeAnnotation 中添加 GeneralPath 形状
【发布时间】:2020-01-04 05:10:45
【问题描述】:

我正在尝试添加一个通用形状以突出显示 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()addAnnotation(),对于example,应该足够了;还要检查你的缠绕规则,example
  • 就我而言,我正在设置 GeneralPath.WIND_EVEN_ODD 。当我删除getGraphics() 并简单地使用addAnnotation() 形状未填充时,它仅显示形状的边框

标签: java jfreechart


【解决方案1】:

不要使用getGraphics();后续更新后,返回的图形上下文将变为invalid。相反,请在 XYShapeAnnotation 构造函数中指定所需的 fillPaint。稍后对draw() 的调用将相应地fill() Shape,如下例所示。注意几个常见的陷阱:

  • 应指定所需的Layer,如here所示。

  • 形状坐标必须在数据空间中指定,如图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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多