miércoles, 27 de marzo de 2019

Crear un gráfico en SAPUI5 (IV) - Usar eventos de interacción

Ya hemos aprendido unas cuantas cosas relacionadas con los gráficos en SAPUI5, como han sido:


Ahora vamos a ver una opción adicional con los elementos del gráfico, y es que podemos realizar acciones cuando se seleccione uno de ellos, sin necesidad de mostrar un tooltip.

Para ello usaremos una propiedad de los Vizframe, la propiedad interaction.decorations, que nos permite ejecutar una función callback cuando se muestra el tooltip (al seleccionar) y cuando se oculta (al deseleccionar).

Podemos encontrar la ayuda en la documentación específica de Vizframes, buscando en el apartado de Propiedades.

Aunque esta propiedad nos la proponen para crear nuestros propios tooltips, ya que con las funciones callback podemos recuperar el elemento seleccionado y la posición (x e y), vamos a utilizarla para otro propósito: Para mostrar un panel informativo con los puntos seleccionados y la probabilidad. No lo haremos en un tooltip, sino en un panel desplegable, y obtendremos algo como lo siguiente:


Y los pasos que seguiremos serán:


  • Crear un modelo de datos para guardar los elementos seleccionados (un string concatenado) y el total de probabilidad.
  • Añadir una propiedad al gráfico (interaction.decorations), a la que podemos asignar dos valores: showDetail, para indicar una función callback que se ejecutará al seleccionar un elemento; y hideDetail, que se ejecutará cuando se deseleccione un elemento.
  • Definir las dos funciones que se llaman desde showDetail y hideDetail, para modificar el contenido del modelo de datos.
  • Añadir a la vista XML un panel expansible para mostrar los datos que hemos seleccionado, enlazándolo con el modelo de datos.

Al final del artículo, tenemos el enlace para descargar el ejemplo en GitHub.

Crear el modelo de datos


Lo primero que vamos a hacer es crear un modelo de datos para mostrar, en pantalla, dos tipos de valores: Selección y total. Esto lo enlazaremos al final a un control de tipo sap.m.List.

Lo definiremos como un JSON con un array de dos valores: key para el título y value para el valor.
Ese valor lo asignaremos a una variable this.oInfo para poder recuperarlo en las funciones de la propiedad decorations (por no estar haciendo el getModel("selection")).

El modelo será un array de dos entradas: Selección y Total.

Todo esto lo vamos a definir al inicio del onInit, para facilitar la labor, en lugar de hacerlo en un fichero aparte. Estamos practicando otras cosas...

Hemos creado un JSON con dos entradas, Selección y Total,
y lo volcamos sobre un modelo que hemos llamado selection.

Definir las propiedades del VizFrame


Ahora vamos a definir las propiedades del VizFrame. Tambíen lo hacemos en el onInit, usando el método setVizProperties.

Vamos a crearlo como vimos en el artículo de añadir un tooltip (con behaviorType = null), pero con una propiedad adicional, interaction.decorations. En dicha propiedad, vamos a definir dos propiedades:

  • showDetail, que llamará a una función callback cuando seleccionemos un elemento.
  • hideDetail, que llamará a una función callback cuando se deseleccione un elemento.

El formato sería:

"decorations : [{
     "name" : "showDetail",
     "fn"       : funcion_callback_al_seleccionar_elemento
    },
     "name" : "hideDetail",
     "fn"       : funcion_callback_al_deseleccionar_elemento
    }]
}


Al hacer esto, ya nos estamos cepillando el tooltip estándar, nos dejará de salir. Bueno, nos da igual, nos iba a ser tan útil como Jar Jar Binks, así que nos lo podemos cargar.

Definir las funciones para hacer los cálculos


Ahora definimos las funciones. Como estamos haciendo un bind(this) al definir las propiedades  del VizFrame, (this.showTooltip.bind(this)), el this que recibimos dentro de la función es el de la vista. Gracias a eso, podemos recuperar el modelo con this.oInfo.

Primero creamos la función que se llama con showDetail, que hemos declarado como showToolTip. La usaremos para calcular el contenido del panel.

En el post anterior, asignábamos el contenido al texto directamente con el método setText. Esta vez no vamos a modificar un control directamente, sino el modelo de datos, mediante setProperty. Como sólo tenemos un array de dos elementos, podemos tratarlos con /Section/0/value para la selección y /Section/1/value para el total.

En esta función modificamos el contenido del panel a través del modelo



Después, creamos el método que se llama con hideDetail, que es hideTooltip, y lo usamos para resetear los valores cuando deseleccionemos las entradas. Tiene un efecto colateral, y es que al redimensionar también borra :( , pero bueno, no podría ser todo perfecto.

Recordemos que los elementos seleccionados los recuperábamos con vizSelection(), como vimos en el artículo Tooltip a medida.


Si no hay elementos, borramos el contenido.
Tenemos que comprobar también si aDatos vale algo, porque nos llegará como null al inicio de la ejecución

Modificar la vista


¿Y cómo llevamos esto a la pantalla? Pues para ello accedemos a la vista y creamos un elemento para mostrar los datos. En este ejemplo, nos creamos un sap.m.Panel expandible que incorpora una lista (sap.m.List) donde volcamos el modelo de datos (en la agregación items). Y con eso ya tenemos los datos actualizados en pantalla, para cada vez que seleccionemos algo.

En el List asignamos la agregación items y asignamos nuestro modelo de datos selection
¡Y eso se convierte en magia!

Código resumen


Así que tendremos el siguiente código en nuestra aplicación (no os preocupéis porque venga como imagen, porque más adelante hay un enlace a GitHub para descargárselo).

El controlador (con algunos bloques minimizados para que se vea el esquema general de la aplicación, debemos fijarnos en el número de línea):


Y la vista que tenemos es la siguiente:


Y eso es todo


Hala, ya hemos aprendido a usar otra propiedad de los VizFrames que nos puede resultar interesante.

Ojo, que la hemos usado un poco para lo que nos ha dado la gana, pero la función callback para showDetail recibe un parámetro con información del evento que hace la llamada (evt en nuestro código), gracias al cual podemos recuperar el último elemento seleccionado (en data) y la posición del elemento (position.x y position.y). Mi intención inicial era poner un elemento en dicha coordenada, pero tras pelearme un rato con ella y ver que lo realmente interesante era aprovechar la llamada a la función, decidí no seguir investigando por esa parte. Quizá alguien se anime a hacerlo ;).

Esto es lo que nos trae el parámetro del showDetail

Si te interesa el ejemplo, te lo puedes descargar de GitHub desde aquí. Ojo, que si no te gusta también te lo puedes descargar de ahí, no es que el enlace sólo funcione si te gusta, pero entiendo que en tal caso no lo harás :P.

No hay comentarios:

Publicar un comentario