如何将图标放在JFReechart Java的图表的一侧

发布于 2025-01-30 15:58:06 字数 860 浏览 3 评论 0 原文

我有以下图表:

”“在此处输入图像描述”

图表是动态的,并且具有放大和缩小的功能。 我想放置一个创建的图标:

BufferedImage triangleIcon = null;
        try {
            triangleIcon = ImageIO.read(getClass().getClassLoader().getResource("Resources/Imagenes/triangulo.png"));
        } catch (IOException e) {
        }

可以将其放置在以下任何点:

xyannotation = new XYImageAnnotation(XValue, YValue, triangleIcon);
this.xyplot.addAnnotation(xyannotation); 

我想将此图标放在任何y值,但始终在图表的左侧旁边,而无需考虑缩放。类似:

“在这里输入图像描述”

是否有可能?

I have the following chart:

enter image description here

The chart is dynamic and has the capability of make zoom in and zoom out.
I want to put an icon that is created as:

BufferedImage triangleIcon = null;
        try {
            triangleIcon = ImageIO.read(getClass().getClassLoader().getResource("Resources/Imagenes/triangulo.png"));
        } catch (IOException e) {
        }

And can be placed in any point as:

xyannotation = new XYImageAnnotation(XValue, YValue, triangleIcon);
this.xyplot.addAnnotation(xyannotation); 

I want to put this icon at any Y value but always next to the left side of the chart, without taking into account the zoom. Something like:

enter image description here

Is it possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

路还长,别太狂 2025-02-06 15:58:06

我看起来您想注释“……图表的一侧,忽略 x 轴的值”。通常,这样的 data 空间中的坐标。一种方法是一种自定义注释,它扩展了抽象父母, AbstractXyAnnotation 。 Override draw()以将垂直 data 坐标转换为相应的屏幕坐标,同时固定水平屏幕坐标到图的 dataarea 。锅和缩放以查看效果。

AffineTransform at = new AffineTransform();
…
@Override
public void draw(…) {
    RectangleEdge rangeEdge = plot.getRangeAxisEdge();
    double y = rangeAxis.valueToJava2D(yValue, dataArea, rangeEdge);
    at.setToIdentity();
    at.translate(dataArea.getX() + 1, y);
    …
}

示例代码:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.AbstractXYAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.ui.RectangleEdge;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * @see https://stackoverflow.com/q/72311226/230513
 * @see https://stackoverflow.com/q/71780485/230513
 */
public class XYShapeTest {

    private static final int N = 18_000;
    private static final int SIZE = 16;
    private final Shape pointer = createPolygon(SIZE);

    private static class AxisAnnotation extends AbstractXYAnnotation {

        private final AffineTransform at = new AffineTransform();
        private final Stroke stroke = new BasicStroke(4f);
        private final Shape shape;
        private final double yValue;

        public AxisAnnotation(Shape shape, double y) {
            this.shape = shape;
            this.yValue = y;
        }

        @Override
        public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea,
            ValueAxis domainAxis, ValueAxis rangeAxis,
            int rendererIndex, PlotRenderingInfo info) {
            RectangleEdge rangeEdge = plot.getRangeAxisEdge();
            double y = rangeAxis.valueToJava2D(yValue, dataArea, rangeEdge);
            at.setToIdentity();
            at.translate(dataArea.getX() + 1, y);
            g2.setStroke(stroke);
            g2.setPaint(Color.BLACK);
            g2.draw(at.createTransformedShape(shape));
        }
    }

    private Shape createPolygon(int size) {
        Polygon p = new Polygon();
        p.addPoint(0, 0);
        p.addPoint(0, 1);
        p.addPoint(2, 0);
        p.addPoint(0, -1);
        AffineTransform at = new AffineTransform();
        at.scale(size, size);
        return at.createTransformedShape(p);
    }

    private XYDataset createDataset() {
        XYSeries series = new XYSeries("Series");
        for (int i = 0; i <= N; i += 1_000) {
            series.add(i / 1_000, i);
        }
        return new XYSeriesCollection(series);
    }

    private JFreeChart createChart(final XYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYLineChart("Test", "X", "Y", dataset);
        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setDomainPannable(true);
        plot.setRangePannable(true);
        plot.addAnnotation(new AxisAnnotation(pointer, 9_000));
        return chart;
    }

    private void display() {
        JFrame f = new JFrame("XYShapeTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new ChartPanel(createChart(createDataset())) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(600, 300);
            }
        });
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new XYShapeTest()::display);
    }
}

I looks like you want to annotate "one side of the…chart, ignoring the value of the X axis". Ordinarily, such annotations specify both coordinates in data space. One approach is a custom annotation that extends the abstract parent, AbstractXYAnnotation. Override draw() to transform the vertical data coordinate to the corresponding screen coordinate, while pinning the horizontal screen coordinate to the dataArea of the plot. Pan and zoom to see the effect.

AffineTransform at = new AffineTransform();
…
@Override
public void draw(…) {
    RectangleEdge rangeEdge = plot.getRangeAxisEdge();
    double y = rangeAxis.valueToJava2D(yValue, dataArea, rangeEdge);
    at.setToIdentity();
    at.translate(dataArea.getX() + 1, y);
    …
}

Annotation

Example code:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.AbstractXYAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.ui.RectangleEdge;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * @see https://stackoverflow.com/q/72311226/230513
 * @see https://stackoverflow.com/q/71780485/230513
 */
public class XYShapeTest {

    private static final int N = 18_000;
    private static final int SIZE = 16;
    private final Shape pointer = createPolygon(SIZE);

    private static class AxisAnnotation extends AbstractXYAnnotation {

        private final AffineTransform at = new AffineTransform();
        private final Stroke stroke = new BasicStroke(4f);
        private final Shape shape;
        private final double yValue;

        public AxisAnnotation(Shape shape, double y) {
            this.shape = shape;
            this.yValue = y;
        }

        @Override
        public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea,
            ValueAxis domainAxis, ValueAxis rangeAxis,
            int rendererIndex, PlotRenderingInfo info) {
            RectangleEdge rangeEdge = plot.getRangeAxisEdge();
            double y = rangeAxis.valueToJava2D(yValue, dataArea, rangeEdge);
            at.setToIdentity();
            at.translate(dataArea.getX() + 1, y);
            g2.setStroke(stroke);
            g2.setPaint(Color.BLACK);
            g2.draw(at.createTransformedShape(shape));
        }
    }

    private Shape createPolygon(int size) {
        Polygon p = new Polygon();
        p.addPoint(0, 0);
        p.addPoint(0, 1);
        p.addPoint(2, 0);
        p.addPoint(0, -1);
        AffineTransform at = new AffineTransform();
        at.scale(size, size);
        return at.createTransformedShape(p);
    }

    private XYDataset createDataset() {
        XYSeries series = new XYSeries("Series");
        for (int i = 0; i <= N; i += 1_000) {
            series.add(i / 1_000, i);
        }
        return new XYSeriesCollection(series);
    }

    private JFreeChart createChart(final XYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYLineChart("Test", "X", "Y", dataset);
        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setDomainPannable(true);
        plot.setRangePannable(true);
        plot.addAnnotation(new AxisAnnotation(pointer, 9_000));
        return chart;
    }

    private void display() {
        JFrame f = new JFrame("XYShapeTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new ChartPanel(createChart(createDataset())) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(600, 300);
            }
        });
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new XYShapeTest()::display);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文