2012-03-23 15 views
6

Tengo chart.png con datos en los que me gustaría poner un eje X - Y simple con algunas etiquetas. También me gustaría tratar de no usar ningún software externo que no venga con Java. Puedo usar jfreechart, pero si hay una manera de que se vea bien, mientras uso algún código java plan, eso sería mejor. ¿Alguien tiene una buena idea sobre cómo hacer este tipo de cosas?¿Cómo puedo poner ejes en un archivo .png en java?

Actualización: Algo así, pero los datos estarían codificados por colores con valores de rgb y, por supuesto, no habría ejes/etiquetas.

pyplot latency example http://www.goldb.org/goldblog/cmg_images/pylot_latency_sample.png

Este gráfico es sólo un ejemplo que parece en nada a lo que mis gráficos reales parecen reales ... Mis gráficos pueden tener cada valor de color RGB en ellos. Sé cómo crear la trama, sólo que no sé cómo poner eje/etiquetado en la BufferImage que he creado

+0

¿Puede vincularse al 'png'? ¿Tienes los datos originales? – trashgod

+0

Algo como esto http://www.goldb.org/goldblog/cmg_images/pylot_latency_sample.png pero solo serían los puntos azul y blanco en un png – Grammin

+0

¿Realmente quieres alterar la imagen existente? ¿Los datos existentes son importantes? ¿Por qué no crear un nuevo gráfico que se asemeje a la imagen? – trashgod

Respuesta

14

No creo que modificar una imagen estática funcionará muy bien, ya que inevitablemente conducirá a errores de registro y estilos no coincidentes. En cambio, integre cualquier representación en la creación del gráfico. Utilizando el enfoque descrito here, el sscce a continuación ilustra algunas de las formas de personalizar las formas, colores y ejes representados, según lo desee.

Adición: Para colorear elementos individuales, la API recomienda el enfoque que se muestra here, en el que un procesador personalizado reemplaza getItemPaint(). Color.getHSBColor() se utiliza para crear un espectro completo de colores.

Response Time chart

Aquí es el, procesador predeterminado original para su cotejo:

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(); 
      } 
     }); 
    } 
} 
+0

¡Gracias por el ejemplo de código muy detallado! ¿Cómo haré algo así como: Random rg = new Random(); for (double x = 0; x <600; x ++) {Color randColor = new Color (rg.nextInt (255), rg.nextInt (255), rg.nextInt (255)); randomseries.add (x, f (x), randColor.getRGB());} – Grammin

+0

Supongo que mi problema principal es obtener mis colores correctos en el gráfico? – Grammin

+0

excelente respuesta, realmente – mKorbel

0

que había leído la imagen en un BufferedImage y luego usar los métodos drawXxxx() en la imagen de Graphics instancia.

A continuación, o bien, vuelva a escribir esa imagen en un archivo o muéstrela en algún gui.

+0

Tengo la imagen en una imagen Buffered, pero no sé qué tan difícil va a ser para dibujar etiquetas y líneas de rango/dominio – Grammin

0

Por lo que puedo entender, sería muy difícil. Con su imagen lista, puede dibujar cualquier otra cosa encima, pero ¿cómo calcula la unidad para que sea proporcional a la imagen? ¿Cómo distribuir toda la imagen más tarde? Con una herramienta de gráficos como jfreechart, puedes ver cuánta libertad tienes para jugar con las etiquetas, ejes y unidades. Pero cuando se trata de dibujarlos después de que realmente se haya creado el gráfico, las cosas serán muy complicadas. No tengo idea de por qué quieres dibujar el eje tú mismo o si vas a mostrar esos gráficos en la web. Encontré que los gráficos generados con jfreechart a veces no se ven muy bien en las páginas web: el texto se ve borroso y el color de la fuente no coincide con el de otros textos en la misma página.

Si va a ponerlos en páginas web, otra opción sería usar Javascript para recuperar datos del servidor y dibujar el gráfico sobre la marcha en el lado del cliente.

3

creo que la biblioteca jfreechart es el camino correcto para implementa el informe.

Pero si solo está buscando un código para dibujar alguna etiqueta en una imagen, aquí está.

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

No utilizo el jfreechart, estamos usando Jide, obtienen una bonita biblioteca de gráficos. Me gusta excepto el precio, pero el jefe lo pagó de todos modos. Puede ver la captura de pantalla aquí: http://www.jidesoft.com/products/charts.htm

Cuestiones relacionadas