Estimad@s,
esta vez escribo para compartir con ustedes algunos experimentos con Pentaho Reporting (PRD).
El caso es que viendo los ejemplos avanzados de PRD y tratando de mejorarlos en algunos casos, salen cosas como lo que les voy a contar en este post. Se trata de un método para expandir y colapsar cabeceras de grupo y detalles de forma muy sencilla.
Este ejemplo tiene como idea inicial, la propuesta por el ejemplo "HTML Actions.prpt", ejemplo que pueden encontrar si seleccionan del menú principal:
Help / Sample Reports / Advanced / HTML Actions
En el editor se ve así:
Ejecutándose en vista HTML así:
La verdad, muy bueno!, les recomiendo que lo vean.
Es la posibilidad de ocultar partes de la jerarquía lo que me llamó la atención y en lo que me puse a experimentar. De los experimentos salió una pequeña serie de funciones javascript genéricas que permiten trabajar con hasta 9 niveles jerárquicos siguiendo dos simples pasos por cabecera de grupo. En este post explicaré en detalle como hacerlo. Ahora veamos el resultado final:
Bien, aquellos que tengan un poco de curiosidad sigan adelante, el resto puede obviar de aquí en adelante.
Partimos de un reporte inicial que tiene muy poco, solo la fuente de datos (se trata de una tabla estática embebida en el reporte) y las librerías javascript necesarias ya embebidas, explicaré en que lugar y como hacerlo. Al reporte inicial lo pueden descargar desde aquí.
Para este caso he utilizado la versión experimental de PRD 4, la pueden descargar desde aquí, aunque se puede hacer sin problema con versiones anteriores (no se con exactitud a partir de cual).
Así se ve el reporte inicial en PRD:
Como pueden ver he ocultado todas las bandas que no son necesarias en el reporte.
Los datos que contiene la tabla forman una jerarquía que puede verse en la imagen anterior y que reproduzco a continuación:
Zona
Año
( Cliente | Importe )
Una Zona tiene varios Años y en un Año por Zona pueden existir varios hechos, cada hecho es un importe de venta a un cliente determinado. La cardinalidad es uno a muchos de zona hacia año y de uno a muchos de zona/año hacia los hechos. Los datos están ordenados con el criterio de agrupamiento, esto es: Zona+Año, se puede agregar el cliente y/o el importe, aunque esto último es anecdótico.
La siguiente es una captura de la tabla:
Luego tenemos las librerías javascript requeridas, a estas librerías y/o reglas de estilo CSS, las agregamos en el header del documento principal, a esto lo hacemos editando el atributo append-header de Master Report. Lo anterior se traduce en algo tan sencillo como que se agregará ese snippet al header del documento HTML cuando el reporte se exporte a ese formato.
Respecto a JQuery, solo descarguen la versión mínima, la abren con un editor de textos, seleccionan todo, copian y lo pegan en esta sección (debe ser lo primero) rodeado de tags < script >
A continuación una captura de como acceder a esta característica en el reporte:
Impresionante las posibilidades que brinda PRD no?
No entraré en detalle de las funciones que he creado, si algun@ está interesad@, solo debe hacer el comentario pertinente. Sin duda que valoraré cualquier aporte o mejora al código.
Teniendo en claro esto, manos a la obra, ahora la parte más sencilla, desarrollar el reporte.
Luego completar los datos del grupo.
Debemos definir ahora el grupo principal, para hacerlo debemos:
Luego completamos los datos:
Hasta aquí, la estructura del reporte debería quedar así:
Ahora coloquemos los elementos en el reporte.
El Detalle:
Primero un rectángulo, le damos el color (pueden usar el selector de combinación de color que está en la barra de herramientas) y las dimensiones. Luego arrastramos el campo cliente y el campo importe al detalle dentro del rectángulo. Será necesario darle una combinación de colores a los campos también. Pueden ver los detalles en la siguiente figura:
Los Grupos:
Como en el caso anterior, primero arrastramos un rectángulo en cada uno de las cabeceras de grupo. La cabecera de grupo que se encuentra en la parte superior pertenece al grupo de mayor jerarquía, en este caso se trata de zona. Luego de colocarlos en su lugar, habrá que asignar un color a cada rectángulo.
Procedemos ahora a colocar sobre los rectángulos los elementos que aportarán los datos, arrastraremos dos elementos Message, uno sobre cada rectángulo, le asignamos la combinación de color y establecemos el atributo value para cada uno.
Valores de value para:
zona: - Zona $(zona)
año: - Año $(año)
Bueno, hasta aquí nada nuevo bajo el sol, verdad?
Es una de las cosas que más me gusta de esto, la simpleza.
Lo que sigue es lo que le da dinamismo al reporte y permite u otorga la posibilidad de expandir/colapsar datos.
Implementación de la funcionalidad de expandir/colapsar:
Solo tres atributos hay que configurar por grupo, dos de los cuales implementan la funcionalidad, el tercero es solo adorno visual.
El primer atributo que configuraremos será xml-id, este atributo se transforma luego en un atributo id para el elemento HTML que renderiza el elemento Message, particularmente se trata de un elemento td.
Veamos en una imagen como hacerlo y que valor colocar para el grupo año.
El valor del atributo xml-id para este caso es =CONCATENATE("j2_";[zona];"_";[año]), esta expresión data como resultado para la zona Este y el año 2012 "j2_Este_2012", esto generará un valor único para cada grupo, muy importante comprender el concepto.
La primera parte de la cadena "j2_" es parte de la implementación, 2 significa que el grupo está 2do en la jerarquía, en este caso el 1ero será el grupo zona.
El render HTML generará algo así:
< td id="j2_Este_2010" colspan="3" > - Año: 2012 < / td >
Si se comprendió lo anterior, se puede deducir el valor para el atributo xml-id de zona: =CONCATENATE("j1_";[zona])
Bien, si hasta aquí se comprendió, ya está, lo que resta es mecánico y muy simple.
Vamos a establecer el valor al atributo on-click de los elementos Message que representan los grupos.
En este caso, en la figura anterior, se muestra como establecer el valor para el grupo zona. El valor asignado es: ="expandCollapse(this, true)", esto es siempre igual, solo vale la pena aclarar que el segundo parámetro (valor true) implica que los valores de los grupos contienen como primer caracter un "+", esto será cambiado automáticamente por un "-" al expandir y vuelta al "+" al colapsar (and so on...).
Recuerden asignar el mismo valor al grupo año.
[Nota mental: estaría muy bueno poder enviar como parámetro el nombre de las clases CSS que deben ser asignadas al grupo cuando está colapsado y cuando está expandido. ¿Alguien se anima a aportar esta característica?]
El reporte ya posee la característica de expandir/colapsar en render HTML. Solo resta mejorar la apariencia en la interacción, hablo de que cuando el usuario pase el mouse por encima del grupo vea un cursor más acorde a lo que el grupo permite hacer. Lo haremos usando una clase CSS que ya está entre los snippets de los que hablamos al inicio. La clase se llama mouse y el código CSS es el siguiente:
.mouse { cursor: pointer; }
Bien, ahora solo debemos establecer la clase mouse a los elementos Message que representan los grupos del reporte. Veamos esto en una figura para el grupo año:
Repetir esto con el grupo zona y listo!
Para probarlo solo debemos seleccionar la vista previa en HTML:
Bien, hemos finalizado, espero que les sea de utilidad.
Pueden descargar la versión final desde aquí.
Saludos
Mariano