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.

14 comentarios:

Nacho Foche dijo...

Hace poco me hablaron de Flex, yo la verdad es que no lo conocía. ¿Le has echao un vistazo? Mira esta dirección, igual va en la línea de lo que pones en esta entrada...
http://200.26.70.70/Dashboard/Dashboard-debug/Dashboard.html

Un abrazo

Manuel Cardenas Thorlund dijo...

Llevaba ya un tiempo queriendo ver Flex y el otro día le estuve echando un vistando. Básicamente es un tipo de lenguaje de programación que se traduce al final a un objeto flash. Te ofrece cantidad de controles de presentación y además te ofrecen un plugin completo para Eclipse.

Lo que pones en la dirección es una de las utilidades que se le puede dar a este post. Pero ten en cuenta que la libreria OpenFlashChart es mucho más potente que Flex a nivel de gráficos y puede integrarse con cualquier lenguaje de programación (Java, PHP, Ruby,...).

Unknown dijo...

Saludos,
Estoy tratando de hacer una aplicacion como la tuya pero la verdad es q estoy un poco perdido, primero porque esta en Vb .net 2005 y segundo xq no tngo mucho conocimiento d javascript, x lo q no se si me podrias ayudar con una version no se un poco mas simple d entender, pero en el q se haga un refresh del grafico al igual q lo haces en este.

Muchas gracias y ojala puedas ayudarme.

Manuel Cardenas Thorlund dijo...

Buenas David,
siento mucho no poder ayudarte porque nunca he trabajado con vb.net. Lo único que te puedo decir es que te descargues el proyecto de demo e intentes pasar la clase RenderizadorGrafico.cs a Visual Basic. Con eso sería suficiente porque por el tema de javascript no te tienes que preocupar que todo lo gestiona la clase.

Unknown dijo...

Hola, primero gracias por la clase me fue muy util.
Tengo un pequño inconveniente, como utilizo el eje derecho (yAxisRight).
Tengo que colocar varias variables en diferentes escalas.

Gorefest dijo...

Amigo, tengo una duda trabajo con vs.net (ya se no trabajas con eso) pero el problema es como coloco dos o mas graficos en la misma pantalla ej: form id="form1" runat="server"
div id="OldChart"
<ofc:Chart ID="OldChart" Url="OldChart.aspx" Height="200" Width="500" runat="server"
/div

div id="NewChart"
ofc:Chart ID="NewChart" Url="NewChart.aspx" Height="200" Width="500" runat="server" /
/div
/form
de ante mano gracias

Manuel Cardenas Thorlund dijo...

Buenas Gorefest,
hice pruebas con el control ofc pero me daba problemas así que opté por implementar las clases descritas en el ejemplo y de las que tienes el código. Con ellas no tienes problema para poner tantos gráficos como quieras en la pantalla.

Siento no poder ayudarte.

Gorefest dijo...

No man, al contrario gracias por la pista así puedo solucionar el problema...

Unknown dijo...
Este comentario ha sido eliminado por el autor.
Unknown dijo...
Este comentario ha sido eliminado por el autor.
Unknown dijo...

Hola, modificando un poco el codigo ... todo funciona perfectamente. Salvo una cosa que no he podido solucionar en el tipo de grafico Pie (Tarta), y es que no puedo darle formato a los datos, cosa que si se puede hacer sin problemas en los graficos de Barras y Lineas.
Por ejemplo, tengo el dato: 1000,457 y quiero darle el formato: 1.000,45 pues en el grafico Pie lo mas he podido hacer es controlar los decimales, PERO al final en pantalla se muestra: 1000.45 (con el punto y no con la coma y sin el formato que quiero).
Espero puedas ayudarme.
GRACIAS

Grupo 8 dijo...

Excelente, es exactamente lo que estaba buscando, gracias por darme la idea para crear mi clase generica de Gráficas para ASP.NET.

Anónimo dijo...

HOLA MANUEL:
ES MUY ÚTIL TU PUBLICACIÓN. PERO TENGO UN PROBLEMA QUE ME GUSTARÍA CONSULTARTE. ¿CÓMO HAGO PARA PONER EL DATO DE LA SERIE (el valor de ejeY[i]) ENCIMA DE LA BARRAS O LÍNEAS GENERADAS? NO ENCUENTRO NINGUNA PROPIEDAD PARA SETEAR DICHO VALOR. GRACIAS DE ANTEMANO.

Manuel Cardenas Thorlund dijo...

Buenas,
en principio creo que no se puede, de todas formas, mira la página oficial, http://teethgrinder.co.uk/open-flash-chart.