lunes, noviembre 03, 2008

Gráficos dinámicos con Open Flash Chart en ASP.NET y UpdatePanels

Todos los códigos de este post os los podéis descargar desde aquí. Todo el proyecto ha sido realizado con Visual Web Developer 2005 Express Edition.

Buenas, hace tiempo que tenía ganas de escribir este artículo sobre la creación de gráficos sobre ASP.NET utilizando la librería flash OpenFlashChart. Este componente flash nos permite crear gráficos muy versátiles, de muy diversos tipos y totalmente customizables en estilo. Además, es código abierto y libre tanto para uso personal como comercial. Aunque ya ha sido liberada la versión 2 (con cambios sustanciales en la forma de pasar los datos), este artículo está basado en la versión 1.9.7 que fue la que inicialmente me descargué en su momento y con la que trabajé.

Introducción del por qué y el cómo
En la página de OFC podéis encontrar multitud de ejemplos, tutoriales, foros, etc. por lo que no voy a explicar aquí los diferentes tipos de gráficos y las funcionalidades de las que dispone OFC.

Después de leer la documentación y de probar con la librería, me surgió un problema, la necesidad de pasarle datos dinámicamente desde código al gráfico y que se refrescará utilizando UpdatePanels de ASP.net. Es decir, poder generar, actualizar, cambiar el tipo de gráfico, todo ello desde código (entiéndase base de datos) y utilizando el AJAX de ASP.NET. Para conseguir tal propósito, me he apoyado en la librería .NET que viene con la descarga de OFC llamada "OpenFlashChartLibrary.dll". Esta librería trae un control de servidor para renderizar el gráfico, pero en este proyecto no se utiliza, sólo utilizaremos las clases que nos permiten generar el código de los gráficos que entiende el componente flash.

¿Qué es lo que queremos conseguir?
Puedes acceder a las páginas de demo pulsando aquí

Si véis en las páginas de demo, lo que queremos conseguir es un entorno basado en AJAX (UpdatePanels) para la generación y actualización de gráficos. En el ejemplo hay dos páginas:
  • La primera (Ejemplo de gráfico dinámico): permite generar un gráfico dinámicamente y anexarle dos series más. Además podemos elegir si cada serie la queremos en forma de barras o líneas. Si elegimos el gráfico como tarta sólo se renderiza la primera serie. Además el gráfico recalcula automáticamente los márgenes de valores máximos a mostrar en base a los datos introducidos (hay un error en la demo, sólo recalcula para la primera serie, lo siente).















  • La segunda (Ejemplo de varios gráficos): nos permite generar dos gráficos simultáneamente y actualizarlos de forma independiente, cada uno con sus controles de tipo de gráfico y la serie a mostrar.

















¿Cómo lo hacemos?
Todo el tema se basa en la clase RenderizadorGrafico.cs que se encuentra en la carpeta App_Code del proyecto. Dicha clase se apoya en la libreria OpenFlasChartLibrary para la generación del código del gráfico. El funcionamiento general es el siguiente:
  1. Le pasamos a la clase la primera serie a pintar junto con varios valores generales (título del gráfico, posiciones decimales, etc)
  2. Si tenemos más series le vamos pasando cada una de las series restantes (debe coincidir el número de valores de la serie con los del eje X), con su nombre.
  3. Llamamos al método RenderizarGrafico pasándole el código del gráfico (devuelto por los métodos anteriores), la ubicación del componente flash OFC, el div donde queremos que se coloque el gráfico y la página en la que estamos. Este método se encargará de generar el código javascript necesario para mostrar el gráfico y lo inyectará en la página.
La clase RenderizadorGrafico.cs en detalle
La clase RenderizadorGrafico.cs es la encargada de generar el código que entiende el componente OFC para la generación de los gráficos. Esta clase se apoya en la librería OpenFlashChartLibrary.dll que viene con OFC y que simplifica la generación del código. Los métodos de los que dispone la clase son:
  • RenderizarGrafico: se le pasa el código del gráfico (obtenido con los otros métodos), la ruta del componente OFC, el div donde colocar el gráfico (uno por cada gráfico) y la página que llama al método. Este método tiene una sobrecarga para cuando tenemos varios gráficos en pantalla en la que le pasamos arrays con los diferentes códigos y los divs donde colocar cada gráfico.
  • GenerarCodigoGrafico: este método se encarga de generar el código del gráfico que le pasaremos al método RenderizarGrafico. A este método le pasaremos la serie tanto para el eje X como para el eje Y y diferentes parámetros de visualización. Este método dispone de una sobrecarga para la representación de gráficos en forma de tarta que se manejan de forma diferente. En esta sobrecarga se le pasan los valores en formato Object[,], pasando en la primera dimensión el valor y en la segunda la etiqueta.
  • AnexarGrafico: este método permite anexarle más series a un gráfico.
La clase define al inicio el estilo que se va a aplicar para los gráficos, teniendo varios struct y constantes que se van utilizando a lo largo de los métodos. En cualquier momento se puede modificar dichos valores para cambiar el aspecto de nuestros gráficos.













La clase dispone, al final de un par de métodos que se utilizan para corregir ciertos fallos que me encontré en la librería .net en la generación de gráficos del tipo tarta.

¿Cómo genera la clase el gráfico?
La clase, en el método RenderizarGráfico, genera el código javascript necesario para renderizar el gráfico en pantalla. Utiliza el fichero swfobject.js para la incrustación de elementos flash en páginas web y lo inyecta en la página. Para inyectar el código hace uso del elemento ScriptManager del AJAX de ASP.net.














¿Cómo le pasamos los datos?
Tenemos dos formas de pasarle los datos a la clase dependiendo del tipo de gráfico que vamos a realizar. Si vamos a crear un gráfico que no sea del tipo tarta tendremos que crearnos lo siguiente:
  • Array de strings con los valores del eje X
  • Array de doubles con los valores del eje Y
  • Float con el valor máximo de la gráfica
  • Float con el valor mínimo
Si vamos a generar un gráfico del tipo tarta tendremos que crearnos lo siguiente:
  • Array de objects de dos dimensiones (object[2,numero elementos]) que tenga en la dimensión 0 el valor y en la dimensión 1 la etiqueta para ese valor. El componente se encargará de pintarlos en el orden correcto.
Lo último, ¿qué código ponemos en el aspx?
Finalmente, para que nuestro gráfico se vea correctamente tendremos que crearnos en la página un div donde vaya a ser colocado. Para utilizar AJAX en los refrescos del gráfico, pondremos dicho div dentro de una estructura UpdatePanel y le pondremos los triggers pertinentes.


















Final
Espero que os haya gustado este artículo y que os pueda servir. Personalmente, esta solución se encuentra en entornos de producción y funciona perfectamente. Como siempre, agradeceré cualquier comentario.