martes, 22 de noviembre de 2011

JFreeChart. Gráficas en Java

Hace algunos años buscando una librería Java para mi proyecto de fin carrera encontré JFreeChart. Revisando el proyecto veo que ha seguido siempre activo y se sigue utilizando ampliamente entre la comunidad de desarrolladores.

JFreeChart es una librería Java 100% libre creada por David Gilbert. Sirve para la creación de gráficas profesionales en nuestras aplicaciones Java. Para consultar todos los detalles podéis ir a la página del proyecto.

A continuación vamos a utilizar la librería para crear un gráfico de tipo tarta (pie chart) en el que se muestre el número de escaños de cada partido en las Elecciones Generales de 2011. Vamos a utilizar el IDE Eclipse aunque podemos utilizar cualquier otro.

Lo primero que tenemos que hacer es crear un proyecto Java en Eclipse. Le llamamos por ejemplo jfreechart y creamos un paquete de código fuente que se llame es.jpascu.graficos.


Proyecto en Eclipse


Después descargamos las siguientes librerías de la página de descargas del proyecto jfreechart y las añadimos como dependencias a nuestro proyecto. Las podemos meter en una carpeta llamada lib


  • jcommon-1.0.16.jar
  • jfreechart-1.0.13.jar

Para añadir liberías a nuestro proyecto pulsamos con el botón derecho sobre el proyecto y en la pestaña Libraries de la opción Java Build Path le damos al boton Add JARS.




Añadir dependencias a un proyecto Java




Una vez que hemos creado el proyecto y añadido las dependencias creamos la clase que pintará nuestra gráfica. Este código se puede modificar fácilmente para incluirlo en un servlet o JSP. 


El código de nuestra clase quedaría como sigue:





package es.jpascu.graficos;

import javax.swing.JFrame;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.util.Rotation;

public class PieChart extends JFrame {

 private static final long serialVersionUID = 1L;

 public PieChart(String applicationTitle, String chartTitle) {
  super(applicationTitle);
  // Creamos el conjunto de datos con las votaciones
  PieDataset dataset = createDataset();

  JFreeChart chart = createChart(dataset, chartTitle);
  // Ponemos el gráfico en un panel
  ChartPanel chartPanel = new ChartPanel(chart);
  // Dejamos el tamaño por defecto
  chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
  // Lo añadimos a nuestra aplicación (PieChart)
  setContentPane(chartPanel);

 }

 /**
  * Creates a sample dataset
  */

 private PieDataset createDataset() {
  DefaultPieDataset result = new DefaultPieDataset();

  result.setValue("PP", 186);
  result.setValue("PSOE", 110);
  result.setValue("CIU", 16);
  result.setValue("IU-LV", 11);
  result.setValue("AMAIUR", 7);
  result.setValue("UPyD", 5);
  result.setValue("EAJ-PNV", 5);
  result.setValue("ERC", 3);
  result.setValue("BNG", 2);
  return result;

 }

 /**
  * Creates a chart
  */

 private JFreeChart createChart(PieDataset dataset, String title) {

  JFreeChart chart = ChartFactory.createPieChart3D(title, // chart title
    dataset, // data
    true, // include legend
    true, false);

  PiePlot3D plot = (PiePlot3D) chart.getPlot();
  plot.setStartAngle(290);
  plot.setDirection(Rotation.CLOCKWISE);
  plot.setForegroundAlpha(0.5f);
  return chart;

 }

 public static void main(String[] args) {
  PieChart demo = new PieChart("Elecciones Generales 2011",
    "Escaños obtenidos por partido");
  demo.pack();
  demo.setVisible(true);
 }
}


Resultado de la ejecución

Tenemos muchas posibilidades. A continuación os pongo un ejemplo con una gráfica de barras en 3D con la comparación entre las elecciones del 2008 y 20012.


package es.jpascu.graficos;

import javax.swing.JFrame;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

public class BarChart extends JFrame {

 private static final long serialVersionUID = 1L;

 public BarChart(String applicationTitle, String chartTitle) {
  super(applicationTitle);
  // Creamos el conjunto de datos con las votaciones
  DefaultCategoryDataset dataset = createDataset();

  JFreeChart chart = createChart(dataset, chartTitle);
  // Ponemos el gráfico en un panel
  ChartPanel chartPanel = new ChartPanel(chart);
  // Dejamos el tamaño por defecto
  chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
  // Lo añadimos a nuestra aplicación (PieChart)
  setContentPane(chartPanel);

 }

 /**
  * Creates a sample dataset
  */

 private DefaultCategoryDataset createDataset() {
  DefaultCategoryDataset result = new DefaultCategoryDataset();
  
  result.setValue(186, "PP", "2011");
  result.setValue(110, "PSOE", "2011");
  result.setValue(16, "CIU", "2011");
  result.setValue(11, "IU-LV", "2011");
  result.setValue(7, "AMAIUR", "2011");
  result.setValue(5, "UPyD", "2011");
  result.setValue(5, "EAJ-PNV", "2011");
  result.setValue(3, "ERC", "2011");
  result.setValue(2, "BNG", "2011");
  
  result.setValue(154, "PP", "2008");
  result.setValue(169, "PSOE", "2008");
  result.setValue(10, "CIU", "2008");
  result.setValue(2, "IU-LV", "2008");
  result.setValue(0, "AMAIUR", "2008");
  result.setValue(1, "UPyD", "2008");
  result.setValue(6, "EAJ-PNV", "2008");
  result.setValue(3, "ERC", "2008");
  result.setValue(2, "BNG", "2008");
  
  
  
  return result;

 }

 /**
  * Creates a chart
  */

 private JFreeChart createChart(DefaultCategoryDataset dataset, String title) {

  JFreeChart chart = ChartFactory.createBarChart3D(title, "Partido",
    "Escaños", dataset, // data
    PlotOrientation.VERTICAL, true, // include legend
    true, false);
  CategoryPlot plot = (CategoryPlot) chart.getPlot();
  CategoryAxis xAxis = (CategoryAxis) plot.getDomainAxis();
  xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // Inclinamos 45 grados las etiquetas del eje X  
  plot.setBackgroundAlpha(0.5f);
  return chart;

 }

 public static void main(String[] args) {
  BarChart demo = new BarChart("Elecciones Generales 2011",
    "Escaños obtenidos por partido");
  demo.pack();
  demo.setVisible(true);
 }
}

Resultado de la ejecución


Por último, otra cosa que nos será útil será guardar la gráfica en un fichero en disco. Con la clase ChartUtilities podemos guardar las gráficas en formato JPG o PNG.


Cuando hemos creado nuestra gráfica (subclase de JFreeChart) la guardamos en disco con el siguiente código:




...
ChartUtilities.saveChartAsJPEG(new File("c:\\tmp\\grafica.jpg"), chart, 500, 300);
...

Si queremos mostrar la gráfica desde un servlet o JSP, sólo tendremos que incluir una etiqueta HTML img con el atributo src a la ruta donde hayamos guardado la imagen.


Espero que toda esta información os haya sido útil.


Salu2.


Referencias: Vogella

11 comentarios:

  1. Muchas gracias amigo me ayudo mucho

    ResponderEliminar
  2. Hola, estoy trabajando con seam inclui las librerias de jfreechart y common pero cuando creo una anotacion con el codigo para crear la pagina no puede inicializar la anotacion como ago o q tengo q hacer para q pueda graficar un reporte de barras en seam

    ResponderEliminar
  3. no le entiendo pake sirve el package :S ¡¡¡
    ami me marca error según agregué las librerias
    pero me marca error a la hora de declararlas :S

    ResponderEliminar
  4. ey compañero como le haria pa que fueran graficas de linea asi como la bolsa de valores gracias :)

    ResponderEliminar
  5. aa y por favor nesesito ponerlo en un jframeee :(

    ResponderEliminar
  6. Hola jpascu, tengo una grand duda.

    He emepzado hace nada a trabajar ocn el jfreechart pero tengo problemas con saber que módulos tengo que importar para cada tipo de gráfica.

    Sabes algún sistema para saber cuales son esos módulos a importar, dependiendo del tipo de gráfica que quiera hacer???

    Muchas gracias de antemano

    Un saludo

    ResponderEliminar
  7. Estimado.. realiza el ejemplo y en win 7 usando eclipse funciona a la perfeccion pero cuando lo instalo en un servidor que posee linux no corre. no hace nada.. y la aplicacion no llega a esta linea.. si pongo un flag antes de esto. lo ejecuta pero despues de esto no hace nada.. alguien me puede decir que puede estar fallando

    BarChart demo = new BarChart("Elecciones Generales 2011","Escaños obtenidos por partido");

    ResponderEliminar
  8. Hola, los molesto porque estoy intentando cambiar los datos del eje del gráfico, (en mi caso es un grafico de líneas que intento representar las horas trabajadas por mes, pero no logro que la grafica me muestre los meses en los ejes y no días, entonces parece que un empleado trabaja 180 horas por día en vez de 180 horas por mes. alguien me podría ayudar???
    Muchas gracias!!

    ResponderEliminar
  9. Hola gracias por excelente tutorial me ha ayudado mucho, mi pregunta seria hay forma de insertar esa grafica que acabo de crear a un archivo Excel que de igual manera va hacer creado en el momento!!!????

    ResponderEliminar