22/4/10

Graficas con java y JFreeChart


En esta ocasion les presento un codigo para crear graficas en java con la libreria OpenSource jFreeChart, esta libreria nos permite crear todo tipo de graficas como se puede ver en la imagen de abajo
Puedes descargarte la libreria desde la pagina del proyecto http://www.jfree.org/jfreechart/,

INSTALACION
1. Una vez que descargaste el archivo ZIP, debes descomprimirlo en algun lugar del disco duro, por ejemplo en c:/java/librerias/jfreechart-1.0.13
2. Con netbeans abierto, dirigete a TOOLS - LIBRARIES o a HERRAMIENTAS - LIBRERIAS.
3. En la ventana que aparece le das a "new library.." y te mostrara una pequeña ventana, en esa ventana le das un nombre a la libreria para poder reconocerla despues, yo le puse "graficos", tu puedes colocar el nombre que desees.
4. Presionas el boton AÑADIR JAR y buscas los siguientes archivos jfreechart-1.0.13 y jcommon-1.0.16 y los añades uno por uno, despues presionas OK y listo

EL PROYECTO EN NETBEANS
1. Crea un nuevo proyecto en netbeans llamalo "graficas", luego debes añadir las librerias al proyecto, clic derecho sobre la carpeta "libraries" como se ve en la imagen y escoges Add Library, en la ventana que aparece, busca la libreria, en mi caso la llame GRAFICAS, asi que busco ese nombre y le digo Add Library
Si seguiste todos los pasos, debes tener algo como la imagen de abajo:
2. Ahora crea un nuevo JFrame en el proyecto, añade un JPanel: CONTENEDOR, dos JButton CREAR Y GUARDAR y situalos como se ve en la imagen:

3. Crea una nueva clase, "Grafico.java" y añade el siguiente codigo:


import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.*;
import java.io.*;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import org.jfree.chart.ChartUtilities;
import org.jfree.data.category.DefaultCategoryDataset;
/**
 * @web http://jc-mouse.blogspot.com/
 * @author Mouse
 */
public class grafico {
    
    private BufferedImage _image ;//para la imagen en memoria
    private JFreeChart grafico ;// el grafico
    private Dimension d;//dimension del grafico
    
    public grafico(){
    }
    /* Crea el grafico */
    public void crear_grafico_de_barras(Dimension d, int[] v, String[] arg1, String arg2[],String[] data){
        this.d= d;          
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        //se llenan los datos
        for(int i=0; i<=v.length-1;i++){
            dataset.setValue(v[i], arg1[i], arg2[i]);
        }      
        //se crea el grafico
        grafico = ChartFactory.createBarChart3D(data[0], data[1], data[2], dataset, PlotOrientation.HORIZONTAL , true, false, true);
        //se coloca el grafico en memoria
        _image = grafico.createBufferedImage(this.d.width,this.d.height);
        System.err.println("grafico creado");     
    }
    
    /* carga la imagen que esta en memoria en el objeto jLabel */
    public void cargar_grafico(JLabel lb){
        ImageIcon imagenFondo = new ImageIcon(_image);  
        lb.setIcon(imagenFondo);
        lb.repaint();
    }  
    /* presenta la ventana de dialogo "guardar" y salva el grafico generado en JPG */
     public void Guardar(){
       JFileChooser fileChooser = new JFileChooser();
       int result = fileChooser.showSaveDialog(null);
       if ( result == JFileChooser.APPROVE_OPTION ){ 
            try {
                //se obtiene la direccion donde se guardara la imagen
                String url = fileChooser.getSelectedFile().toString();
                //Se guarda la imagen
                ChartUtilities.saveChartAsJPEG(new File(url + ".jpg"), grafico, d.width, d.height);
            } catch (IOException ex) {
                Logger.getLogger(grafico.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
   }   
}


4. Como siguiente paso, debes implementar esta clase en el JFrame, el codigo para los JButton es el siguiente


private void CREARActionPerformed(java.awt.event.ActionEvent evt) {
        //tamaño del grafico
        Dimension d = CONTENEDOR.getSize();//toma el tamaño del contenedor
        //se crean los datos
        int[] valores = {1000,2011,3030,1569,2688,4587}; 
        String[] arg1 = {"Enero","Febrero","Marzo","Enero","Febrero","Marzo"};
        String[] arg2 = {"Visitas","Visitas","Visitas","Hits","Hits","Hits"};
        //titulo, lateral 1, lateral 2
        String[] data = {"Blog de Mouse","Primer Trimestre","Visitas"};
        //se crea el grafico
        migrafico.crear_grafico_de_barras(d, valores, arg2, arg1, data);
        //se crea un jlabel para colocar el grafico
        JLabel j = new JLabel();
        j.setBounds(0, 0, d.width, d.height);
        //se carga el grafico de memoria
        migrafico.cargar_grafico(j);
        //se añade al contenedor
        CONTENEDOR.add(j);
        this.repaint();
}

private void GUARDARActionPerformed(java.awt.event.ActionEvent evt) {
       migrafico.Guardar();
}

/**
 * @param args the command line arguments
*/
grafico migrafico = new grafico();


La forma en que se pasa los parametros a la clase "graficos.java", es mediante el uso de Array, se utilizan 4 array, un array de enteros para pasar los valores numericos, otros dos array de tipo String arg1 y arg2, donde se coloca los valores sobre los cuales se llevara a cabo la comparacion y agrupacion de datos, estos tres primeros array, deben tener la misma longitud, por ultimo un array de tipo String de  3 elementos en el cual se coloca, primero el titulo, seguidos del texto que se coloca en los lateras del grafico; por ejemplo, 
int[] valores = {1000,2011,3030,1569,2688,4587};, se le esta pasando un array con 6 elementos, entonces los arrays arg1 y arg2 , deben tener tambien seis elementos.

En el ejemplo de abajo, tenemos el mismo grafico, con los mismos datos, pero con diferente agrupacion, el primero agrupado entre "visitas y hits"  y el segundo entre "meses", esto solamente se hizo, inviertiendo "arg1"  y "arg2" en la llamada al metodo crear_grafico_de_barras();

13 comentarios:

  1. muchas gracias amigo por el aporte.. en realidad lo estaba necesitando mucho. yo tengo que graficar los datos de unos sensores que arrojan varios datos, los cuales estoy almacenando en una base de datos, espero que con esto lo pueda hacer.
    gracias...

    ResponderEliminar
  2. te agradeceria que pongas la fuente de este ejemplo

    ResponderEliminar
  3. Exelente...tus proyectos son muy utiles....

    ResponderEliminar
  4. excelente , me funciono genial

    muchas gracuas1!!

    esperamos mas tutoriales :D

    ResponderEliminar
  5. Esta interesante, pero me surguio un problema al momento de crear la grafica me marca muchos errores.... estos, espeor que me puedan ayudar.


    Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1016)
    at java.awt.image.BufferedImage.(BufferedImage.java:338)
    at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1407)
    at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1389)
    at org.jfree.chart.JFreeChart.createBufferedImage(JFreeChart.java:1374)
    at graficas.grafico.crear_grafico_de_barras(grafico.java:48)
    at graficas.frame.jButton1ActionPerformed(frame.java:102)
    at graficas.frame.access$000(frame.java:20)
    at graficas.frame$1.actionPerformed(frame.java:58)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2012)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2335)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:404)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:253)
    at java.awt.Component.processMouseEvent(Component.java:6108)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
    at java.awt.Component.processEvent(Component.java:5873)
    at java.awt.Container.processEvent(Container.java:2105)
    at java.awt.Component.dispatchEventImpl(Component.java:4469)
    at java.awt.Container.dispatchEventImpl(Container.java:2163)
    at java.awt.Component.dispatchEvent(Component.java:4295)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4461)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4125)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4055)
    at java.awt.Container.dispatchEventImpl(Container.java:2149)
    at java.awt.Window.dispatchEventImpl(Window.java:2478)
    at java.awt.Component.dispatchEvent(Component.java:4295)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:604)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

    ResponderEliminar
  6. muchas gracias por el ejemplo pero me sale un error en la clase jframe Contenedor no lo encuentra!!! me puedes ayudar gracias

    ResponderEliminar
  7. Hermano, Muchas gracias por su tiempo!

    ResponderEliminar
  8. Gracias por tu aporte =D me sirvio de mucho

    ResponderEliminar
  9. Muchisimas Grcias por tu Ejemplo y explicación, fueron de gran ayuda.
    :D ;P

    ResponderEliminar
  10. gracias hermano excelente todos los proyectos uffff elegantes y te agradezco si pones el fuente de este proyecto para estudiarlo y entenderlo mejor muchas gracias hermano

    ResponderEliminar
  11. bro. muy buena la ixplicacion,

    bueno mi duda es como obtendría el total de ventas que hubo durante los últimos 5 meses y lo muestro en la grafica..

    Ayudaaaaaaa

    ResponderEliminar