在JFreechart的XYShapeAnnotation中添加GeneralPath形状 [英] Add GeneralPath shape in XYShapeAnnotation of JFreechart

查看:76
本文介绍了在JFreechart的XYShapeAnnotation中添加GeneralPath形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加一个通用形状以突出显示JFreechart中Y大于X的区域.

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

形状已添加到图表中,但未填充黑色.我猜我正在使用的getGraphics()方法不正确.但是如何获取JFreechart的图形.

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.

推荐答案

请勿使用getGraphics();在后续更新之后,返回的图形上下文将无效.而是在中指定所需的fillPaint XYShapeAnnotation 构造函数.以后调用 draw() fill() Shape相应,如下例所示.请注意一些常见的陷阱:

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:

  • 应指定所需的Layer,如此处所示.

必须在数据空间中指定形状坐标,如此处所示.

The shape coordinates must be specified in data space, as shown 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;
    }
}

这篇关于在JFreechart的XYShapeAnnotation中添加GeneralPath形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆