viernes, 1 de junio de 2012

Graficos Estadisicos (JFreeChart)

JFreeChart

JFreeChart es una librería la cual nos permite hacer gráficos de una forma muy sencilla, esta librería posee todo tipo de gráficos, desde tortas, líneas, barras, etc.
Añadir librerías a NetBeans

Para hacer uso de esta clase antes que nada debemos descargarnos el JFreeChart, a continuación dejo el link de descarga directa:

http://sourceforge.net/projects/jfreechart/files/latest/download?source=files

Una vez descargada la librería, deberán desomprimir el rar, se descomprime una carpeta llamada “jfreechart – 1.0.XX”, dentro de esta se encuentra otra carpeta llamada “lib”, que es la que contiene los .jar para agregar al netbeans (jcommon-1.0.XX.jar y jfreecahrt-1.0.XX.jar).
Para agregar estas 2 librerias a nuestro IDE NetBeans, tenemos que dirijirno a:

barra de menú à Tools àLibrariesà(1) New Library à Le ponen JFreeChart de nombre y tipo Class Libraries à Una vez creada tocan el botón Add JAR/Folder à Buscan dentro de la carpeta “lib” el jar del JFreeChart y lo agregan. à Repiten los pasos desde (1) New Library cámbienle el nombre por JCommon, y al buscar el jar en este caso va a ser el de JCommon.


Una vez hecho esto, en nuestro proyecto de netbeans que vayamos a necesitar de estas librerías, buscamos la carpetita Libraries clic derecho y presionamos Add Library, y buscamos nuestras librerías creadas y las agregamos.

Ya con todo esto podemos empezar a sacarle jugo a nuestra nueva librería JFreeChart

Uso de JFreeChart
Grafico de torta
En el siguiente ejemplo vamos a ver el uso de JFreeChart para crear un grafico de torta:
Este va a ser nuestro diseño: un JFrame, un JPanel(general), un JButton, un JPanel-PanelGraficoTorta-(donde se va a mostrar el grafico), y un JLabel-lblTorta-(dentro de panel donde se va a mostrar el grafico, le borramos el texto y lo dejamos asi).


 Lo que necesitamos importar en nuestro código son las siguientes librerías:

import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;


Dentro del ActionPerformed de nuestro botón vamos a ingresar el siguiente código:

       DefaultPieDataset porciones;
       JFreeChart torta;

        porciones=new DefaultPieDataset();

        porciones.setValue("A", 4550);
        porciones.setValue("B", 4000);
        porciones.setValue("C", 3000);
        porciones.setValue("D", 3500);
        torta=ChartFactory.createPieChart3D("Ejemplo",porciones,true,true,false);
        BufferedImage graficoTorta = torta.createBufferedImage(panelGraficoTorta.getWidth(), panelGraficoTorta.getHeight());       
        lblTorta.setSize(panelGraficoTorta.getSize());
        lblTorta.setIcon(new ImageIcon(graficoTorta));    
        panelGraficoTorta.updateUI();


El código nos muestra que para porciones, por decirlo de alguna manera, se indican con la clase DefaultPieDataset con ella le indicamos cuantas porciones van a haber y de cuanto van a hacer.
Luego creamos un gráfico de torta con la clase ChartFactory, esta clase tiene una gran cantidad de métodos estáticos para la creación de varios tipos de gráficos y entre esos esta el gráfico de torta o pie. Con el método createPieChart3D, este método recibe el titulo del gráfico, las porciones y tres booleanos que indican si queremos mostrar la leyenda, mostrar información y generar urls.
Un método del JFreeChart es el createBufferedImage() que nos devuelve nuestro grafico en una imagen. Esta imagen luego se la asignamos a nuestra etiqueta mediante el método setIcon() e instanciando dentro un ImageIcon que como parámetro recibe nuestra imagen.
Por ultimo actualizamos/refrescamos nuestro panel para que muestre los cambios.

El resultado es el siguiente:


Grafico de barras

Basándonos en el ejemplo anterior vamos a hacerlo un poco mas interactivo, vamos a agregar 3 JTextField-txtval1,txtval2,txtval3- que van a tomar los valores con los que se debe hacer el grafico.




Las librerías que vamos a importar son:

import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;


Y el código del ActionPerformed de nuestro botón va a ser el siguiente:

        JFreeChart barra = null;
        DefaultCategoryDataset datos;
        datos = new DefaultCategoryDataset();
        datos.setValue(Integer.parseInt(txtval1.getText()), "A", "");
        datos.setValue(Integer.parseInt(txtval2.getText()), "B", "");
        datos.setValue(Integer.parseInt(txtval3.getText()), "C", "");       
            barra = ChartFactory.createBarChart3D("Ejemplo Barras", "Trimestres","Ventas",datos,PlotOrientation.VERTICAL,true,true,true);
        BufferedImage graficoBarra=barra.createBufferedImage(panelGraficoTorta.getWidth(), panelGraficoTorta.getHeight());

        lblTorta.setSize(panelGraficoTorta.getSize());
        lblTorta.setIcon(new ImageIcon(graficoBarra));

        panelGraficoTorta.updateUI();


El codigo es muy parecido al de grafico de tortas con la diferencia de que ahora estamos usando la clase DefaultCategoryDataset en donde se indica el valor de la barra y su nombre. Además con el método estático createBarChart3D de la clase ChartFactory creamos el gráfico de barras con la cual se le indica el nombre del grafico, el nombre de la barra, el nombre de la columna, los datos, la orientación del grafico(en este caso Vertical) y los últimos 3 parámetros iguales que los de la torta. Luego capturamos la imagen de la barra y se la mandamos a un JLabel para mostrarla.

El resultado sera el siguiente:



Grafico de línea


Nos basamos en el ejemplo anterior pero esta vez solo vamos a tener un solo JTextField-txtvalor-






Las librerías que vamos a importar son:

import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

Y el codigo del ActionPerformed de nuestro boton es el siguiente:

        XYSeries series = null;
        XYDataset datos;
        JFreeChart linea = null;
         int x=0;

        series= new XYSeries("Popularidad de Blog");
    
        series.add(0,x);
        x++;
        //series.add(5,x);
        //x++;
        // series.add(10,x);
        //x++;
     
        series.add(Integer.parseInt(txtval.getText()),x);
        x++;
       
        datos = new XYSeriesCollection(series);
        linea = ChartFactory.createXYLineChart("Ejemplo Grafico de Linea","Popularidad","Meses",datos,PlotOrientation.HORIZONTAL,true,true,true);
       
        BufferedImage graficoLinea=linea.createBufferedImage(panelGraficoTorta.getWidth(), panelGraficoTorta.getHeight());
       
        lblTorta.setSize(panelGraficoTorta.getSize());
        lblTorta.setIcon(new ImageIcon(graficoLinea));
      
        panelGraficoTorta.updateUI();

El código ya cambia en este tipo de grafico, utilizamos las clases XYSeries y un XYDataset, el XYSeries es para indicar los puntos en donde va a pasar la linea, esta clase recibe los puntos de X y Y con el método add(int x, int y). Luego este objeto se lo mandamos como parámetro de una XYSeriesCollection a la clase XYDataset, y por ultimo con el método estático createXYLineChart de la clase ChartFactory creamos el gráfico de línea. Por ultimo como ya suponen capturamos la imagen del gráfico y se la mandamos al JLabel para mostrarlo en pantalla.
Aclaracion: Si ejecutan el programa con el código asi como lo puse les va a salir el primer grafico, si ustedes descomentarizan las 4 lineas que están como comentario se vera el segundo grafico.

El resultado es el siguiente:




Como guardar un grafico en archivo JPG


Para guardar un grafico en un archivo utilizaremos la clase ChartUtilities, por lo cual debemos importar la siguiente librería:

import org.jfree.chart.ChartUtilities;

ChartUtilities tiene un método llamado saveChartAsJPEG(), que se le debe pasar los siguiente parámetros:un File, un Grafico y las medidas.

Un ejemplo bueno seria si quisiéramos guardar alguno de nuestros gráficos para tenerlos a mano si deseamos imprimirlos o verlos sin necesidad de ejecutar nuestro programa. En el código siguiente se ve como hacer esto:



try {
            ChartUtilities.saveChartAsJPEG(new File("ImagenGuardada.jpg"), linea, graficoLinea.getWidth(), graficoLinea.getHeight());
        } catch (IOException ex) {
          JOptionPane.showMessageDialog(this, "Se ha producido un error al intentar guardar","Error",JOptionPane.ERROR_MESSAGE);
        }

En este caso se va a guardar en la carpeta raíz, el grafico de líneas anterior.

13 comentarios:

  1. Oye, pues muchas gracias, porque hacía un montón de horas que me peleaba con las librerías y como hacer que me las reconociese.
    Es que los que somos nuevos en esto, no sabemos por donde ir todavía.
    Esta página me la pongo como favorita, para ir estudiándolo todo.

    ResponderEliminar
  2. muy pero muy buen aporte hermano pero me gustaria aun mas si t hicieras uno con jsp

    ResponderEliminar
  3. me sacaron de apuros en clase de matemáticas avanzadas para una serie de graficas utilizando el método runge kuta, eres grande

    ResponderEliminar
  4. buen tuto gracias ciberAmigo.. solo un problema con la grafica de lineas...cuando pones valores donde hay bajas y altas (no solo altas) te las grafica mal.. :(

    ResponderEliminar
  5. muy bueno, pero alguien sabe porque cuando genero el grafico, se me corre el panel, y se desajusta el tamaño?

    ResponderEliminar
  6. hola, como puedo graficar con datos de una base de datos estoy trabajando con netbeans y mysql

    ResponderEliminar
    Respuestas
    1. Connection conn = Access.getConnection();
      Statement st = conn.createStatement();
      ResultSet rs = st.executeQuery("SELECT Mid (N_HC, 3, 4 ) AS HC, COUNT(*) TOTAL FROM TB_HISTORIA_CLINICA GROUP BY Mid (N_HC, 3, 4)");

      DefaultCategoryDataset datos;
      datos = new DefaultCategoryDataset();
      while (rs.next()) {
      String n_hc = rs.getString("HC");
      Integer total = rs.getInt("TOTAL");
      datos.setValue(total, "Año", n_hc);
      }
      Grafico = ChartFactory.createBarChart(
      "APERTURA DE H.C POR AÑOS", "", "CANTIDAD DE APERTURAS", datos, PlotOrientation.VERTICAL, true, true, false);

      LineAndShapeRenderer renderer = new LineAndShapeRenderer(true, true);
      Grafico.getCategoryPlot().setRenderer(renderer);
      renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getNumberInstance()));
      renderer.setBaseItemLabelsVisible(true);

      StatisticalLineAndShapeRenderer statisticalRenderer = new StatisticalLineAndShapeRenderer(true, false);

      statisticalRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}", NumberFormat.getNumberInstance()));
      statisticalRenderer.setBaseItemLabelsVisible(true);

      ChartPanel panel = new ChartPanel(Grafico);

      jPanel1.setLayout(new java.awt.BorderLayout());
      panel.setSize(jPanel1.getSize());
      jPanel1.add(panel);

      Eliminar
  7. hola, como puedo graficar con datos de una base de datos estoy trabajando con netbeans y mysql

    ResponderEliminar
  8. Hola si quiero solo guardar la grafica como imagen, mecesito meterla a un label o al panel?

    ResponderEliminar
  9. Gracias por tu aporte.... Fue de gran ayuda...
    Me sirvió mucho.. :)

    ResponderEliminar
  10. holaaa.
    a mi me deja importar todas las clases menos
    ChartUtilities

    ResponderEliminar