Как я могу поместить ось в файл.png в Java?
У меня есть файл chart.png с данными, которые я хотел бы поместить на простой оси X - Y с некоторой маркировкой. Я также хотел бы попытаться не использовать любое внешнее программное обеспечение, которое не идет с Java. Мне разрешено использовать jfreechart, но если есть способ, чтобы он выглядел красиво, просто используя некоторый план Java-кода, это было бы лучше. У кого-нибудь есть хорошая идея о том, как делать такие вещи?
Обновление: что-то вроде этого, но данные будут иметь цветовую кодировку со значениями RGB и, конечно, не будет никакой оси / маркировки.
http://www.goldb.org/goldblog/cmg_images/pylot_latency_sample.png
Этот график - просто пример, он не похож на то, как выглядят мои настоящие графики... В моих реальных графиках может быть любое значение цвета rgb. Я знаю, как создать сюжет, я просто не знаю, как разместить ось / маркировку на BufferImage
что я создал
4 ответа
Я не думаю, что изменение статического изображения будет работать очень хорошо, так как это неизбежно приведет к ошибкам регистрации и несоответствующим стилям. Вместо этого интегрируйте любой рендеринг в создание диаграммы. Используя подход, изложенный здесь, ниже показан пример, показывающий несколько способов настройки визуализированных форм, цветов и осей по желанию.
Приложение: Чтобы раскрасить отдельные элементы, 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://stackru.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();
}
});
}
}
Я думаю, что библиотека 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
Я прочитал бы изображение в BufferedImage
а затем использовать drawXxxx()
методы на изображении Graphics
пример.
Затем либо запишите это изображение обратно в файл, либо отобразите его в каком-нибудь графическом интерфейсе.
Насколько я могу понять, это было бы очень сложно. Когда ваше изображение готово, вы можете нарисовать что-нибудь еще поверх него, но как рассчитать единицу, чтобы сделать его пропорциональным изображению? Как сделать макет всего изображения позже? С помощью инструмента построения диаграмм, такого как jfreechart, вы получаете большую свободу действий с метками, осями и единицами. Но когда дело доходит до их рисования после того, как диаграмма действительно создана, все будет намного сложнее. Я понятия не имею, почему вы хотите нарисовать ось самостоятельно или собираетесь показывать эти графики в Интернете. Я обнаружил, что графики, сгенерированные с помощью jfreechart, иногда выглядят не очень хорошо на веб-страницах - текст выглядит размытым, а цвет шрифта не соответствует другому тексту на той же странице.
Если вы собираетесь разместить их на веб-страницах, другим вариантом будет использование Javascript для извлечения данных с сервера и рисования диаграммы на лету на стороне клиента.