7

我有chart.png,其中包含数据,我想在其中放置一个简单的X - Y 轴并带有一些标签。我也想尽量不要使用任何不附带 java 的外部软件。我被允许使用jfreechart,但如果有办法让它看起来不错,而只是使用一些计划 java 代码,那就更好了。有没有人对如何做这种事情有一个好主意?

更新:类似这样的东西,但数据将使用 rgb 值进行颜色编码,当然不会有轴/标签。

pyplot 延迟示例
(来源:goldb.org

该图只是一个示例,它看起来与我的实际图完全不同……我的真实图可以包含每个 rgb 颜色值。我知道如何创建情节,我只是不知道如何在我创建的情节上放置轴/BufferImage标签

4

4 回答 4

15

我不认为修改静态图像会很好,因为它不可避免地会导致注册错误和样式不匹配。相反,将任何渲染集成到图表的创建中。使用此处概述的方法,下面的sscce说明了一些根据需要自定义渲染形状、颜色和轴的方法。

附录:要为单个项目着色,API 建议使用此处显示的方法,其中自定义渲染器会覆盖getItemPaint()Color.getHSBColor()用于创建全光谱颜色。

响应时间图表

这是用于比较的原始默认渲染器:

响应时间图表

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/** @see https://stackoverflow.com/q/9843451/230513 */
public class ResponseTime {

    private static final int N = 600;
    private static final String title = "ResponseTime";
    private static final Random random = new Random();
    private static final Shape circle = new Ellipse2D.Double(-3, -3, 6, 6);
    private static final Color line = Color.gray;

    private ChartPanel createPanel() {
        JFreeChart chart = ChartFactory.createXYLineChart(
            title, "Elapsed Time (secs)", "Response Time (secs)",
            createDataset(), PlotOrientation.VERTICAL, true, true, false);
        XYPlot plot = chart.getXYPlot();
        MyRenderer renderer = new MyRenderer(true, true, N);
        plot.setRenderer(renderer);
        renderer.setSeriesShape(0, circle);
        renderer.setSeriesPaint(0, line);
        renderer.setUseFillPaint(true);
        renderer.setSeriesShapesFilled(0, true);
        renderer.setSeriesShapesVisible(0, true);
        renderer.setUseOutlinePaint(true);
        renderer.setSeriesOutlinePaint(0, line);
        ValueAxis range = plot.getRangeAxis();
        range.setLowerBound(0.5);
        return new ChartPanel(chart);
    }

    private static class MyRenderer extends XYLineAndShapeRenderer {

        private List<Color> clut;

        public MyRenderer(boolean lines, boolean shapes, int n) {
            super(lines, shapes);
            clut = new ArrayList<Color>(n);
            for (int i = 0; i < n; i++) {
                clut.add(Color.getHSBColor((float) i / n, 1, 1));
            }
        }

        @Override
        public Paint getItemFillPaint(int row, int column) {
            return clut.get(column);
        }
    }

    private XYDataset createDataset() {
        XYSeriesCollection result = new XYSeriesCollection();
        XYSeries series = new XYSeries("Series 1");
        for (double x = 0; x < N - 1; x++) {
            series.add(x, f(x));
        }
        series.add(25, 1.75); // outlier
        result.addSeries(series);
        return result;
    }

    private double f(double x) {
        double y = 0.004 * x + .75;
        return y + random.nextGaussian() * y / 10;
    }

    private void display() {
        JFrame f = new JFrame(title);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(createPanel());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ResponseTime().display();
            }
        });
    }
}
于 2012-03-26T16:00:12.403 回答
3

我认为 jfreechart 库是实现报告的正确方法。

但是,如果您只是在寻找在图像上绘制一些标签的代码,那就是这里。

public static void main(String[] args)
    throws IOException
{
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setSize(800, 600);

    BufferedImage modifiedImg = ImageIO.read(new File("c:\\test.png"));
    Graphics graphics = modifiedImg.getGraphics();
    graphics.setColor(Color.red);
    graphics.drawString("Label", 100, 100);// draw text
    graphics.drawLine(1, 100, 100, 100);// draw line

    JLabel label = new JLabel();
    label.setIcon(new ImageIcon(modifiedImg));
    frame.getContentPane().add(label, BorderLayout.CENTER);

    frame.setVisible(true);
}

我不使用 jfreechart,我们使用的是 Jide,他们得到了一些可爱的图表库。我喜欢它,除了价格,但老板还是付了钱。你可以在这里看到截图:http ://www.jidesoft.com/products/charts.htm

于 2012-03-27T05:18:35.063 回答
0

我将图像读入 aBufferedImage然后使用drawXxxx()图像Graphics实例上的方法。

然后将该图像写回文件或在某个 gui 中显示。

于 2012-03-23T17:15:53.830 回答
0

据我所知,这将非常困难。准备好图像后,您可以在其上绘制其他任何东西,但是如何计算单位以使其与图像成比例?以后如何布局整个图像?使用像 jfreechart 这样的图表工具,您可以自由地使用标签、轴和单位。但是在实际创建图表后绘制它们时,事情会复杂得多。我不知道您为什么要自己绘制轴,或者您是否要在网络上显示这些图表。我确实发现使用 jfreechart 生成的图表有时在网页上看起来不太好 - 文本看起来很模糊,字体颜色与同一页面上的其他文本不匹配。

如果您要将它们放在网页上,另一种选择是使用 Javascript 从服务器检索数据并在客户端动态绘制图表。

于 2012-03-23T20:17:21.750 回答