Los perezosos siempre hablan de lo que piensan hacer, de lo que harán; los que de veras hacen algo no tienen tiempo de hablar ni de lo que hacen.
Johann Wolfgang von Goethe

Generación de Gráficas en JSP

Categoría: Java
Publicado el Lunes 14 de Julio, 2008, a las 15:38:06.
Última modificación hecha el Miércoles 31 de Diciembre, 1969, a las 17:00:00.
Leído 722 veces.
Generación de gráficas en páginas JSP utilizando las librerías libres JFreeChart y Cewolf.



Introducción

 

En muchas aplicaciones se manejan grandes cantidades de información. El uso de gráficas proporciona una forma fácil y sencilla de visualizar estadísticas o resúmenes de dicha información, permitiendo además compararla bajo diferentes parámetros. Las gráficas son un elemento bastante útil para el análisis de la información y la toma de decisiones. Todo esto también aplica para el entorno web, donde el tipo de aplicaciones y la cantidad de información que manejan es muy variada.

 

En este tutorial se explica la generación de gráficas para aplicaciones web basadas en la tecnología estrella para desarrollo web de Java: JSP, usando dos librerías bastante útiles: JFreeChart y Cewolf. JFreeChart una librería para Java gratuita y libre (bajo licencia LGPL) y es el motor detrás de la generación de las gráficas. JFreeChart puede generar diversos tipos de gráficas, como por ejemplo: gráficas de pastel, de barras, de gantt, de área, de líneas, etc. Por su parte, también para Java y bajo licencia LGPL, Cewolf es una librería de etiquetas basada en JFreeChart que permite embeber la gráfica en la página JSP sin necesidad de embeber código Java para lograrlo, únicamente etiquetas (sintaxis XML) que definen las propiedades de la gráfica.

 

Instalación y Configuración

 

Para empezar a trabajar primero es necesario descargar las librerías. En este caso únicamente es necesario descargar la librería de Cewolf puesto que ya contiene los archivos de JFreeChart necesarios. Al momento de escribir este tutorial, la versión estable más reciente de Cewolf es la 1.0, disponible para descargar desde http://sourceforge.net/project/showfiles.php?group_id=57282, que viene siendo el archivo cewolf-1.0-bin-src.zip.

 

Al descomprimir el archivo Zip de la distribución de Cewolf, se nos crean varios directorios. Para que nuestra aplicación web utilice las librerías de Cewolf y JFreeChart es necesario copiar todos los archivos de la carpeta /lib (de la distribución de Cewolf) a la carpeta /WEB-INF/lib de nuestra aplicación web.

 

La gráfica final generada se provee a través de un servlet, por lo que tenemos que agregar su descripción y mapeo al archivo /WEB-INF/web.xml de nuestra aplicación web, agregando las siguientes líneas:

 

<servlet>

    <servlet-name>CewolfServlet</servlet-name>

    <servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>

</servlet>

<servlet-mapping>

    <servlet-name>CewolfServlet</servlet-name>

    <url-pattern>/cewolf/*</url-pattern>

</servlet-mapping>

 

Podríamos agregar al archivo web.xml estas líneas y empezar a trabajar sin ningún problema, pero existen opciones de configuración adicionales que explico brevemente a continuación. El servlet CewolfServlet acepta tres parámetros iniciales opcionales que pueden ser agregados a su declaración del archivo web.xml:

 

Parámetro

Valores

Descripción

Debug

“true” o “false”

Establece si Cewolf mostrará o no información de depuración. Si este parámetro se omite el valor por defecto es “false”.

overliburl

Ruta relativa al archivo overlib.js

Ruta relativa al directorio raíz de la aplicación web donde se encuentra el archivo overlib.js. Este archivo se encarga de la generación de tooltips para ciertos navegadores. Si este parámetro se omite el valor por defecto es “overlib.js”, que considera que el archivo overlib.js se encuentra en el directorio raíz de la aplicación web.

storage

Ruta a la clase que maneja el almacenamiento de las imágenes.

Ruta a la clase que se encarga de manejar la forma en que las imágenes serán almacenadas en el servidor. Si este parámetro se omite el valor por defecto es “de.laures.cewolf.storage.TransientSessionStorage”

 

El archivo overlib.js se encuentra en la carpeta /etc de la distribución de Cewolf y lo puedes colocar en la carpeta de tu aplicación web que creas más conveniente. Recuerda asignar la ruta correcta al parámetro overliburl.

 

<servlet>

    <servlet-name>CewolfServlet</servlet-name>

    <servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>

    <init-param>

        <param-name>overliburl</param-name>

        <param-value>etc/overlib.js</param-name>

    </init-param>

</servlet>

 

En el parámetro storage se especifica la clase que será usada para el manejo del almacenamiento de imágenes. La distribución Cewolf viene con tres clases que realizan este almacenamiento de forma diferente: TransientSessionStorage, LongTermSessionStorage y FileStorage.

 

Si como valor del parámetro storage utilizamos la clase de.laures.cewolf.storage.TransientSessionStorage, las imágenes se almacenarán en objetos de sesión HttpSession, que técnicamente permanecerán en memoria todo el tiempo hasta que expire la sesión.

 

<servlet>

    <servlet-name>CewolfServlet</servlet-name>

    <servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>

    <init-param>

        <param-name>storage</param-name>

        <param-value>de.laures.cewolf.storage.TransientSessionStorage</param-name>

    </init-param>

</servlet>

 

La clase LongTermSessionStorage es básicamente la misma que TransientSessionStorage. También almacena las imágenes en objetos HttpSession, excepto que con LongTermSessionStorage las imágenes expiran de la sesión después de cierto tiempo. Por defecto 300 segundos, pero el tiempo puede ser especificado agregando el atributo timeout=”xxx” en la etiqueta <cewolf:img> que pondremos en la página JSP.

 

<servlet>

    <servlet-name>CewolfServlet</servlet-name>

    <servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>

    <init-param>

        <param-name>storage</param-name>

        <param-value>de.laures.cewolf.storage.LongTermSessionStorage</param-name>

    </init-param>

</servlet>

 

Si como valor para el parámetro storage utilizamos la clase de.laures.cewolf.storage.FileStorage, las imágenes serán guardadas como archivos en el directorio de la aplicación web. Estos archivos serán guardados bajo un nombre de archivo “_chart-*” o “_chart*”, donde el asterisco corresponde al identificador de la imagen. Por defecto, estos archivos nunca serán borrados automáticamente.

 

Sin embargo, cuando se elije usar la clase FileStorage se puede agregar a la definición del servlet CewolfServlet el parámetro FileStorage.deleteOnExit (acepta como valores “true” o “false”) que indica que dichos archivos serán borrados automáticamente cuando la Máquina Virtual Java (JVM) se cierre normalmente (la JVM se cierra normalmente cuando todos los procesos que corrían sobre ella han finalizado normalmente). Si el servidor o la JVM se apagan abruptamente, por ejemplo al cortar el suministro de energía o matar el proceso de la JVM, estos archivos no se borrarán automáticamente.

 

<servlet>

    <servlet-name>CewolfServlet</servlet-name>

    <servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>

    <init-param>

         <param-name>storage</param-name>

         <param-value>de.laures.cewolf.storage.FileStorage</param-name>

    </init-param>

    <init-param>

         <param-name>FileStorage.deleteOnExit</param-name>

         <param-value>true</param-name>

    </init-param>

</servlet>

 

Los chicos de Cewolf aseguran que los objetos de sesión HttpSession donde se almacenan las imágenes ocupan poco espacio, pero debido a que con TransientSessionStorage las imágenes permanecen en memoria hasta que toda la sesión expira, podrías llegar a tener problemas de memoria. Por lo que quizá lo más recomendable sería usar LongTermSessionStorage y especificar el tiempo que durará la imagen en memoria antes de borrarla. Para el caso de FileStorage, los archivos creados pueden ser bastante numerosos y dadas ciertas circunstancias podrían permanecer en el sistema de archivos por mucho tiempo. Recordemos que un servidor no suele ser reiniciado frecuentemente, además bajo algunas circunstancias los archivos podrían nunca ser borrados automáticamente. Aunque siempre puedes hacerlo a mano.

 

Incluso si alguna de estas tres opciones de almacenamiento no te agradan o no son lo que necesitas, siempre puedes escribir tu propia implementación de almacenamiento. Recuerda que Cewolf y JFreeChart son de código abierto (bajo licencia LGPL). Considera las opciones y elije la que se ajuste a tus necesidades.

 

No es totalmente necesario, pero para evitar problemas podemos agregar una etiqueta a la declaración del servlet para asegurarnos que carge al inicio:

 

<load-on-startup>1</load-on-startup>

 

En un servidor de producción y usando la clase FileStorage como opción de almacenamiento, nuestro archivo /WEB-INF/web.xml quedaría así (incluyendo únicamente lo relevante para este tutorial):

 

<servlet>

     <servlet-name>CewolfServlet</servlet-name>

     <servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>

     <init-param>

         <param-name>storage</param-name>

         <param-value>de.laures.cewolf.storage.FileStorage</param-value>

    </init-param>

    <init-param>

        <param-name>FileStorage.deleteOnExit</param-name>

        <param-value>true</param-value>

    </init-param>

    <init-param>

        <param-name>overliburl</param-name>

        <param-value>etc/overlib.js</param-value>

    </init-param>

    <init-param>

        <param-name>debug</param-name>

        <param-value>false</param-value>

    </init-param>

    <load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

    <servlet-name>CewolfServlet</servlet-name>

    <url-pattern>/cewolf/*</url-pattern>

</servlet-mapping>

 

Ahora podemos pasar a probar si el servlet funciona correctamente. Para probar su estado sólo hay que escribir en el navegador “http://direccion:8080/cewolf?state”. El servlet debería responder con el mensaje “Cewolf servlet up and running”, indicando que todo funciona bien.

 

Preparando los Datos a Graficar

 

Una vez que tenemos configurado lo necesario para trabajar con Cewolf y JFreeChart, podemos pasar a explicar lo que se necesita para generar una gráfica.

 

Gracias a Cewolf podemos usar el patrón MVC (Modelo-Vista-Controlador), dejando en la página JSP sólo etiquetas que definan la presentación y dejando el código Java que genera los datos para la gráfica aparte. Usando únicamente JFreeChart, tendríamos que incluir código Java dentro de la página JSP, lo que “contaminaría” la página JSP (aunque existe otra forma de respetar el patrón MVC usando sólo JFreeChart, pero no hablaré de eso en este tutorial).

 

Los datos que serán usados para construir la gráfica son proporcionados por una clase que implementa la interface de.laures.cewolf.DatasetProducer. La interface DatasetProducer presenta tres métodos:

 

  • Object produceDataset(Map params)

    • produceDataset() es el método más importante, pues es en este método donde se obtienen los datos con los que estará construida la gráfica. Normalmente aquí es donde se realizan las consultas necesarias a la base de datos, archivos, web services, etc.

 

  • boolean hasExpired(Map params, Date since)

    • Por medio del método hasExpired() podemos especificar si una gráfica tiene que ser redibujada o no. Si retorna true la gráfica volverá a ser redibujada, mientras que si retorna false se usará la gráfica previa (una especie de caché) incluso si los datos a graficar han cambiado. Por supuesto, la segunda opción tarda menos en presentar la imagen al usuario final. La lógica que le implementemos a este método puede variar dependiendo de nuestras necesidades. Por ejemplo, podemos especificar que una gráfica no sea redibujada sino hasta dentro de x segundos, cuando los parámetros de entrada sean diferentes, o alguna otra condición.

 

  • String getProducerId()

    • El método getProducerId() debe retornar un identificador único para cada DatasetProducer que creemos.

 

Pongamos como ejemplo una clase que implemente la interface DatasetProducer que proporcione datos para una gráfica de barras verticales:

 

import java.util.Date;
import java.util.Map;
import de.laures.cewolf.DatasetProducer;
import org.jfree.data.category.*;


public class AlumnosAprobados implements DatasetProducer {

    private static final long serialVersionUID = 1L;

    public Object produceDataset(Map params)

        {

        final String[] categories = { "A", "B", "C" };

        final String[] seriesNames = { "Aprobados", "Reprobados" };

        final Integer[][] startValues = new Integer[seriesNames.length][categories.length];

        final Integer[][] endValues = new Integer[seriesNames.length][categories.length];

        for (int series = 0; series < seriesNames.length; series++)

            {

            for (int i = 0; i < categories.length; i++)
               

                {
                startValues[series][i] = new Integer(0);
                endValues[series][i] = (int) (Math.random() * 10 + 1);

                }

            }

        DefaultIntervalCategoryDataset ds =

        new DefaultIntervalCategoryDataset(seriesNames, categories, startValues, endValues);

        return ds;

        }

public boolean hasExpired(Map params, Date since)
    {
    return true;
    }


public String getProducerId()
    {
    return "Alumnos DatasetProducer";
    }
}

 

En este ejemplo, produceDataset() genera la información de manera aleatoria. En aplicaciones reales aquí nos conectariamos a la base de datos para extraer la información. Pero lo que deseo que se comprenda es la forma en que se prepara la información, que una vez lista, es pasada al constructor de un dataset, en este caso de la clase DefaultIntervalCategoryDataset.

 

La mayoría de las gráficas necesitan diferentes tipos de información (o la misma pero con diferente representación) para ser dibujadas, por lo que dependiendo del tipo de gráfica que desees hacer variarán las clases de los datasets que utilices y el tratamiento de los datos.

 

Más adelante mostraré breves ejemplos de algunos tipos gráficas adicionales y sus respectivos ejemplos de datasets.

 

Las Etiquetas para las Páginas JSP

 

Pasando ahora al código necesario que debemos poner en la página JSP, dos son las etiquetas principales de Cewolf que definirán la gráfica: chart e img. La etiqueta chart especifica datos de configuración para el dibujado de la gráfica como lo son el tipo de gráfica, los títulos de ejes, el título general de la gráfica, el DatasetProducer que se utilizará, los parámetros para el DatasetProducer, etc.

 

La etiqueta img define, más bien, detalles acerca de su presentación en la página JSP, similares a los de la etiqueta img de HTML (atributos height, width, alt, class, etc.). Y de la misma forma, la colocación de esta etiqueta es importante (a diferencia de chart) pues la posición dentro del código definirá su posición en la página dibujada por el navegador.

 

Pongamos ahora otro ejemplo, esta vez de la página JSP que contiene las etiquetas necesarias:

 

1 <?xml version="1.0" encoding="UTF-8" ?>
2 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
3 <%@ taglib uri='/etc/cewolf.tld' prefix='cewolf' %>
4
5 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6 <html xmlns="http://www.w3.org/1999/xhtml">
7 <head>
8     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
9     <title>Alumnos Aprobados</title>
10 </head>
11 <body>
12
13 <h1>Alumnos Aprobados</h1>
14 <hr />
15
16 <jsp:useBean id="alumnos" class="AlumnosAprobados" />
17 <cewolf:chart id="graficaAlumnos" title="Alumnos" type="verticalBar" xaxislabel="Grupos" yaxislabel="No. Alumnos">
18     <cewolf:data>
19         <cewolf:producer id="alumnos" />
20     </cewolf:data>
21 </cewolf:chart>
22 <p>
23      <cewolf:img chartid="graficaAlumnos" renderer="/cewolf" width="400" height="300"/>
24 </p>
25 </body>
26 </html>

 

En la línea 3 podemos ver la directiva de página taglib en la que especificamos la librería de etiquetas de Cewolf. El archivo cewolf.tld lo podemos encontrar en la carpeta /etc de la distribución de Cewolf y lo podemos ubicar donde nos plazca dentro de nuestra aplicación web. Sólo hay que especificar su ruta en el atributo uri de la directiva taglib.

 

La etiqueta en la línea 16 nos permite crear una instancia de nuestra clase que implementa la interface DatasetProducer (AlumnosAprobados). El valor del atributo id de la etiqueta jsp:useBean será el identificador de esta instancia que nos permitirá referenciarla luego.

 

En la etiqueta cewolf:chart de la línea 17 se especifican algunos parámetros de configuración. El atributo id sirve para identificar las configuraciones de esta etiqueta cewolf:chart, que después será referenciada por la etiqueta cewolf:img para relacionar la imagen y sus configuraciones.

 

El atributo type es el que define qué tipo de gráfica va a ser dibujada. Tenemos que colocar aquí un tipo de gráfica que sea compatible con el dataset que retorna el método produceDataset() o de lo contrario generará un error. En este caso nuestra clase AlumnosAprobados también nos serviría para generar una gráfica de barras horizontales, horizontales 3D y verticales 3D.

 

Los atributos title, xaxislabel y yaxislabel definen el título, y las etiquetas del eje x y y en la gráfica respectivamente.

 

La etiqueta cewolf:producer (anidada en la etiqueta cewolf:data, y ésta a su vez en cewolf:chart) es la que hace referencia, por medio del atributo id, a nuestra clase generadora del dataset instanciada en la línea 16.

 

Y por último la etiqueta cewolf:img de la línea 23 se relaciona con las configuraciones de la etiqueta cewolf:chart por medio del atributo chartid. En el atributo renderer se especifica la ruta del servlet de Cewolf, CewolfServlet, que se encargará de hacer el dibujado de la gráfica. Esta ruta es relativa con relación a la página JSP actual, por lo que si la página se encuentra en un directorio por debajo del directorio raíz, el atributo renderer debería quedar así: renderer=”../cewolf”. Los atributos width y height especifican las dimensiones de la imagen en anchura y altura respectivamente.

 

Existen más atributos para las etiquetas de Cewolf que se describen en su documentación.

 

http://cewolf.sourceforge.net/new/taglib.html

 

Al final, la gráfica de nuestra página de ejemplo debería visualizarse similar a la siguiente:

Gráfica de ejemplo resultante 

Enviar Parámetros a la Clase Generadora del Dataset

 

Si prestaste atención a la definición del método produceDataset() te habrás dado cuenta que acepta un parámetro. El parámetro params de tipo Map (http://java.sun.com/javase/6/docs/api/java/util/Map.html) nos permite enviar parámetros como si de un arreglo se tratase, pues los parámetros están disponibles como pares de índice-valor. Estos parámetros son especificados como etiquetas en la página JSP y pueden ser extraídos en la clase que implementa la interface DatasetProducer.

 

Los parámetros se especifican con la etiqueta cewolf:param, que debe estar anidada en la etiqueta cewolf:chart, y en nuestro ejemplo anterior, en el caso de que fuera necesario enviar parámetros a la clase, su definición sería así:

 

...

<cewolf:chart id="graficaAlumnos" title="Alumnos" type="verticalBar" xaxislabel="Grupos" yaxislabel="No. Alumnos">

    <cewolf:data>

        <cewolf:producer id="alumnos">

            <cewolf:param name=”grado” value=”B” />

        </cewolf:producer>

    </cewolf:data>

</cewolf:chart>

...

 

El atributo name especifica el nombre del índice, mientras que value especifica el valor del parámetro.

 

En la clase, la forma de recuperar el valor del parámetro se haría de la siguiente forma:

 

public Object produceDataset(Map params)

    {

    ...

    String grado = (String)params.get("grado");

    ...

    }

 

El método containsKey() nos permite saber si un parámetro existe:

 

public Object produceDataset(Map params)

    {

    ...

    String grado = null;

    if(params.containsKey("grado"))

        {

        grado = (String)params.get("grado");

        }

    ...

    }

 

Ejemplos de Gráficas Disponibles y Preparación de Datasets

 

La aplicación de ejemplo de Cewolf (http://sourceforge.net/project/showfiles.php?group_id=57282&package_id=55139) presenta varios ejemplos útiles de gráficas y cómo construir sus datasets. Todos los ejemplos a continuación fueron extraídos de esta aplicación de ejemplo (archivo cewolfset_inc.jsp). Simplemente he organizado aquí los DatasetProducer junto con la imagen de la gráfica para que la información de estos ejemplos quede más a la mano. Como había comentado anteriormente, algunas gráficas usan la misma información, por lo que comparten datasets.

 

A) 

public Object produceDataset(Map params) {
    TimeSeries ts = new TimeSeries("Cewolf Release Schedule", Month.class);
    ts.add(new Month(7, 2002), 0.1);
   
ts.add(new Month(8, 2002), 0.4);
   
ts.add(new Month(9, 2002), 0.9);
   
ts.add(new Month(10, 2002), 1.0);
   
return new TimeSeriesCollection(ts);
  
}

Gŕafica de serie de tiempoGráfica vertical de barras XY

B) 

public Object produceDataset(Map params) {
   
XYSeries xys = new XYSeries("Example XY Dataset");
   
double last = 0.0;
   
for (int i = -50; i <= 50; i++)
   
    {
   
    double y = last + ((Math.random() * 100) - 50.0);
   
    xys.add((double) i, y);
   
    last = y;
   
    }
   
return new XYSeriesCollection(xys);
   
}

Gráfica de Área XYGráfica XY

C) 

public Object produceDataset(Map params) {
   
final String[] categories = { "apples", "pies", "bananas", "oranges" };
   
DefaultPieDataset ds = new DefaultPieDataset();
   
for (int i = 0; i < categories.length; i++)
   
    {
   
    int y = (int) (Math.random() * 10 + 1);
   
    ds.setValue(categories[i], new Integer(y));
   
    }
   
return ds;
   
}

Gráfica de Pastel Gráfica de Pastel 3D

 

D) 

public Object produceDataset(Map params) {
   
final String[] categories = { "apples", "pies", "bananas", "oranges" };
   
final String[] seriesNames = { "Peter", "Helga", "Franz", "Olga" };
   
final Integer[][] startValues = new Integer[seriesNames.length][categories.length];
   
final Integer[][] endValues = new Integer[seriesNames.length][categories.length];
   
for (int series = 0; series < seriesNames.length; series++)
   
    {
   
    for (int i = 0; i < categories.length; i++)
   
        {
   
        int y = (int) (Math.random() * 10 + 1);
   
        startValues[series][i] = new Integer(y);
   
        endValues[series][i] = new Integer(y + (int) (Math.random() * 10));
   
        }
   
    }
   
DefaultIntervalCategoryDataset ds =
   
new DefaultIntervalCategoryDataset(seriesNames, categories, startValues, endValues);
   
return ds;
   
}

Gráfica de Área Gráfica de Barras Horizontal Gráfica de Barras Horizontal 3D Gráfica de Líneas Gráfica Apilada Horizontal Gráfica Apilada Vertical Gráfica de Barras Vertical 3D Gráfica de Barras Vertical Gráfica Apilada Vertical 3D Gráfica de Área Apilada

  

E)

final private long now = System.currentTimeMillis();
final private long day = 1000 * 60 * 60 * 24;
final private String[] workflows = { "Analysis", "Design", "Implementation", "Test", "Rollout", "Operations" };
final private String[] person = { "Frank", "Paul", "Daisy", "Chris" };
public Object produceDataset(Map params) {
   
TaskSeriesCollection ds = new TaskSeriesCollection();
    for (int j = 0; j < 4; j++)

   
    {
   
    TaskSeries ser = new TaskSeries(person[j]);
   
    long lastEnd = now + getRandomTime();
   
    for (int i = 0; i < workflows.length; i++)
   
        {
   
        long myEnd = lastEnd + getRandomTime();
   
        Task t = new Task(workflows[i], new SimpleTimePeriod(new Date(lastEnd), new Date(myEnd)));
   
        ser.add(t);
   
        lastEnd = myEnd;
   
        }
   
    ds.add(ser);
   
    }
   
return ds;
   
}

Gráfica de Gantt

 

F)

public Object produceDataset(Map params) {
    int itemCount = 100;
    Date[] dates = new Date[itemCount];
    double[] high = new double[itemCount];
    double[] low = new double[itemCount];
    double[] open = new double[itemCount];
    double[] close = new double[itemCount];
    double[] volume = new double[itemCount];
    Calendar cal = new GregorianCalendar();
    for (int i = 0; i < itemCount; i++)
        {
        cal.roll(Calendar.HOUR, 1);
        dates[i] = cal.getTime();
        high[i] = Math.random() * 100 + 100;
        low[i] = high[i] - (Math.random() * 30);
        open[i] = low[i] + (Math.random() * (high[i] - low[i]));
        close[i] = open[i] + (Math.random() * (high[i] - open[i]));
        volume[i] = Math.random() * 1000;
        }
    OHLCDataset ds =
        new DefaultHighLowDataset("Laures, Inc.", dates, high, low, open, close, volume);
    return ds;
    }

 

 

Conclusión

 

Hasta aquí llega este tutorial de creación de gráficas en JSP con JFreeChart y Cewolf. Como se puede notar, generar gráficas con estas dos librerías es relativamente fácil. Sin embargo, he encontrado que cuestiones más específicas, como la personalización de gráficas, no es del todo fácil. Temas como la selección de los colores, orientación de leyendas, y otros, pueden requerir de un poco de programación para lograr el resultado deseado. Sobretodo con JFreeChart. Cewolf proporciona las etiquetas, pero JFreeChart es quien se encarga del dibujado de gráficas.

 

JFreeChart cuenta con una guía para desarrolladores, pero hay que pagar por ella y no es un gasto que se pueda cubrir en todos los proyectos que piensen usarlo. También está la documentación de sus APIs, pero como en toda documentación javadoc, todo está ahí, pero hay que leer mucho antes de tener la idea completa. Y por supuesto, están disponibles los foros de ayuda tanto de JFreeChart como de Cewolf, por lo que con un poco de trabajo, lograremos el resultado que queremos.

 




Publica un Comentario:

Nombre/Nickname
Email (no será publicado)
Sitio Web (si tienes)
Comentario
Etiquetas permitidas: <a href="" title=""> <b> <code> <em> <i> <strike> <strong>