Как я могу поместить ось в файл .png в Java? - PullRequest
7 голосов
/ 23 марта 2012

У меня есть файл chart.png с данными, которые я хотел бы поместить в простую ось X - Y с некоторой маркировкой. Я также хотел бы попытаться не использовать любое внешнее программное обеспечение, которое не идет с Java. Мне разрешено использовать jfreechart , но если есть способ сделать так, чтобы он выглядел красиво, просто используя некоторый код плана Java, это было бы лучше. У кого-нибудь есть хорошая идея о том, как делать такие вещи?

Обновление: что-то вроде этого, но данные будут иметь цветовую кодировку со значениями rgb и, конечно, не будет никакой оси / маркировки.

Пример задержки Pyplot http://www.goldb.org/goldblog/cmg_images/pylot_latency_sample.png

Этот график - просто пример, он не похож на то, как выглядят мои настоящие графики ... Мои реальные графики могут иметь каждое значение цвета RGB в них. Я знаю, как создать график, я просто не знаю, как разместить ось / метку на BufferImage, который я создал

Ответы [ 4 ]

15 голосов
/ 26 марта 2012

Я не думаю, что изменение статического изображения будет работать очень хорошо, так как оно неизбежно приведет к ошибкам регистрации и несоответствующим стилям.Вместо этого интегрируйте любой рендеринг в создание диаграммы.Используя подход, обозначенный здесь , sscce ниже иллюстрирует несколько способов настройки визуализированных форм, цветов и осей по желанию.

Добавление: для раскраски отдельныхДля элементов, API рекомендует подход, показанный здесь , в котором пользовательский рендер переопределяет getItemPaint().Color.getHSBColor() используется для создания полного спектра цветов.

Response Time chart

Вот исходный рендерер по умолчанию для сравнения:

Response Time chart

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();
            }
        });
    }
}
3 голосов
/ 27 марта 2012

Я думаю, что библиотека 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

0 голосов
/ 24 марта 2012

Насколько я понимаю, это было бы очень сложно.Когда ваше изображение готово, вы можете нарисовать что-нибудь еще поверх него, но как рассчитать единицу, чтобы сделать его пропорциональным изображению?Как сделать макет всего изображения позже?С помощью инструмента построения диаграмм, такого как jfreechart, вы получаете большую свободу действий с метками, осями и единицами.Но когда дело доходит до их рисования после того, как диаграмма фактически создана, все будет намного сложнее.Я понятия не имею, почему вы хотите нарисовать ось самостоятельно или собираетесь показывать эти графики в Интернете.Я нашел диаграммы, сгенерированные с помощью jfreechart, которые иногда выглядят не очень хорошо на веб-страницах - текст выглядит нечетко, а цвет шрифта не совпадает с другим текстом на той же странице.

Если вы собираетесь разместить их на веб-страницахДругой вариант - использовать Javascript для извлечения данных с сервера и рисовать диаграммы на лету на стороне клиента.

0 голосов
/ 23 марта 2012

Я прочитал бы изображение в BufferedImage, а затем использовал drawXxxx() методы для экземпляра Graphics изображения.

Затем либо запишите это изображение обратно в файл, либо отобразите его в каком-нибудь графическом интерфейсе.

...