Internacionalización en Dashboard Sofia2

image1

 

En la nueva versión de Sofia2 se han incluido capacidades de internacionalización dentro de los dashboards. Esta característica es configurable desde el menú de edición del propio dashboard.

 

Mediante etiquetas, se pueden internacionalizar los diferentes elementos de texto del dashboard y visualizarlo a través de la configuración de idioma de la propia consola, o bien, a través del parámetro lang de la query, indicando el lenguaje requerido, que debe estar reflejado en el JSON de internacionalización mediante su referencia abreviada (en, es, pt…).

 

image2

image3

 

Este JSON de internacionalización tiene la siguiente estructura


{

"label1": {

"es": "Spanish text 1",

"en": "English text 1",

"pt": "Portuguese text 1"

},

"label1": {

"es": " Spanish text 2",

"en": " English text 2",

"pt": "Portuguese text 2"

},

"label3": {

"es": " Spanish text 3",

"en": " English text 3".

"pt": "Portuguese text 3"

},

….

}

 

Pudiendo tener cualquier número de etiquetas o idiomas reflejados en el mismo. Estas etiquetas habrá que incluirlas dentro de los diferentes elementos de texto con la siguiente sintaxis: #{label1} que será sustituida por el correspondiente valor internacionalizado.

Internacionalización en Dashboard Sofia2

Ejecución de código personalizado en Dashboards

image1

 

Siguiendo con las nuevas capacidades de los Dashboards de Sofia2, otra nueva posibilidad que se nos brinda, es la de ejecutar código javascript propio, para tener un acceso a más bajo nivel en nuestros dashboards, así como incluir nuevas interacciones, como por ejemplo botones que realicen ciertas tareas sobre el mismo o realizar cambios de estilado o la inclusión y eliminación de ciertos elementos.

 

Todo esto se puede programar en la nueva opción habilitada para ello, dentro del menú de dashboard, denominada Custom JS.

image2

 

Como se puede ver, este código tiene la posibilidad de usar jQuery, con lo que podremos acceder a diferentes elementos del dashboard o gadgets gracias a su sencilla sintaxis de selección. También, al igual que el estilado personalizado, este javascript se compartirá entre todas las páginas, por lo que habrá que tener esto en cuenta a la hora de usar esta funcionalidad.

 

A parte de ejecutar cierto código propio, un uso muy interesante es la combinación con el gadget markdown actual. Con este gadget, podemos crear contenido HTML como botones, selectores, checkboxs… combinado con la agilidad de usar bootstrap para ello y referenciar funciones que tengamos definidas en nuestro propio código javascript.

image3

Ejecución de código personalizado en Dashboards

Tutorial desarrollo de un mapa 3D interactivo con Sofia2

image1

En el siguiente tutorial vamos a ver cómo realizar un mapa 3d interactivo en Sofia2. Para ello, vamos a utilizar la potente tecnología de visualización en nodejs CesiumJS.

image2

Usaremos el API JavaScript de Sofia2 para acceder a varias ontologías que representan 3 tipos de puntos en el mapa sobre la geografía de España, con sus datos asociados:

  • Playas: GSMA_PointOfInterest_Beach
  • Museos: GSMA_PointOfInterest_Museum
  • Parkings: GSMA_OffStreetParking_Destino

Las instancias de estas ontologías estarán georreferenciadas por lo que tendrán un atributo de tipo geometry que representará la posición.

El primer paso, será descargarnos e instalarnos NodeJS y CesiumJS que servirá como base para poder empezar a trabajar. Desde los siguientes enlaces, podemos descargarnos ambas herramientas:

Una vez que tenemos el CesiumJS instalado correctamente, podemos arrancarlo con el siguiente comando:


node server.js

Dentro de la carpeta Apps se podrán ver todas las aplicaciones y ejemplos que vienen con CesiumJS. Podremos navegar por las mismas con el servidor arrancado desde nuestro navegador, con lo que podremos acceder a través de la url y el puerto por defecto que tiene: localhost:8080

image3

image4

Con todo lo anterior hecho, vamos a crear un nuevo HTML que alojará el visor 3D DGSMA.html y un subdirectorio para los archivos necesarios “datosGSMA” del mismo. Quedará la siguiente estructura:

image5

Dentro de la carpeta de datosGSMA tendremos varios subdirectorios:

image6

  • Conexión: script en lenguaje javascript para la conexión con Sofia2, donde se alojan los datos de conexión, así como las diferentes queries que se lanzarán a la plataforma para recuperar los datos necesarios del ejemplo.
  • Css: hoja de estilos para el ejemplo
  • Imágenes: archivos de imagen tanto para los iconos como para el fondo

Todo el código e imágenes, lo podéis descargar desde el github de la plataforma https://github.com/Sofia2/Sofia2-3DViewer

Dentro del archivo HTML principal tendremos varias partes interesantes que vamos a explicar a continuación:

image7

Cómo se ve en la imagen, tendremos un contenedor completo que alojará el mapa en el fondo con un identificador “cesiumContainer”. Este elemento, englobará al mapa que estará en el fondo de la página.

También, tenemos otras partes de estructura interesantes, como los paneles lateral e inferior donde alojaremos los gráficos de los parkings, así como un panel overlay que se nos mostrará durante la carga del visor 3D. Como se puede ver en las importaciones de librerías en la parte de la cabecera, los gráficos están construidos en SVG sobre D3 a través de la librería NVD3 http://nvd3.org/.

Otras partes a destacar son la propia carga del visor de CesiumJS:

image8

La función startup se llamará al inicio de la carga del visor con todas las opciones necesarias para el mismo, que se dibujarán en el div completo de fondo con todos los elementos visuales e interactivos que dispone la demo. A la vez que se cargan estos datos se realizará la conexión contra Sofia2, la cual se realiza desde el js de la carpeta conexión conexionAdministrador.js

En este archivo se puede ver la conexión “Join” con la plataforma sofia2

image9

Así como las diferentes queries que se lanzan para recuperar los datos necesarios que se dibujan en el mapa.

image10

Volviendo al código principal, para combinar los datos de Sofia2 con los de CesiumJS tendremos que construir las entidades de visualización de CesiumJS. Estas entidades, son las estructuras que usa CesiumJS para dibujar diferentes elementos tanto interactivos como no en el mapa. Por cada tipo de datos a mostrar (playas, parkings y museos) se rellenarán los datos necesarios desde las instancias recuperadas por el API JS incluida la posición de los mismos en el mapa. En esta parte también se incluran las referencias correspondientes a las imágenes de los marcadores.

image11

Una vez creadas y dadas de alta esas entidades en CesiumJS, el propio motor se encargará de colocar estos elementos en el mapa, así como actuar mostrando un overlay con los datos al hacer clic en cualquiera de los marcadores.

Para poder mostrar y ocultar estos marcadores, poseemos el panel lateral, donde al hacer clic en una capa de datos podremos ponerlos o quitarlos del mapa.

image12

A parte de las interacciones con las diferentes capas (las cuales se actualizarán creando o destruyendo las diferentes entidades en el motor), se realizará un “vuelo” en el mapa a las nuevas localizaciones incluidas o al mapa general (al desmarcar). La clave de esto es la función flyTo de la cámara del viewer que realizará un suave vuelo a la posición pasada por parámetro.

image13

Por último, en la parte de gráficos, como ya hemos comentado se ha usado nvd3 (librería sobre D3) por lo que una vez recuperados los datos necesarios de Sofia2, podremos hacer la llamada a la librería de nvd3 que se encargará de pintar tanto el gráfico de tipo Pie como el gráfico de tipo barra con los datos de los diferentes parkings.

image14

image15

Tutorial desarrollo de un mapa 3D interactivo con Sofia2

Estilado personalizado en Dashboards Sofia2

image3

Una de las nuevas capacidades más importantes de los Dashboards de Sofia2 es la posibilidad de incluir y editar código de la hoja de estilos (css) en los mismos. Con esta característica, podemos estilar los dashboards de manera profesional, incluyendo cambios de imagen, transparencias, colores, animaciones, eliminar u ocultar elementos que no nos interesen… con toda la potencia que nos brinda este lenguaje de marcado.

 

Todo esto, se ha posibilitado gracias al remodelado del menú de edición de estilos, donde ahora, al pulsar en uno de los estilos predeterminados, podemos ver y editar en vivo el css que contiene. Este css será posteriormente inyectado al dashboard con todo nuestro estilado personalizado.

image1image2

Adicionalmente a esto, también es posible incluir uno o varios estilos externos por url. Mediante el nuevo parámetro de query styles se pueden incluir las referencias a archivos css externos separados por comas que se irán incluyendo en orden en el dashboard. Estos estilos sustituirán a los estilos base del dashboard. Hay que tener en cuenta que los propios elementos del dashboard tienen estilados de posiciones o tamaños por lo que es recomendable partir de un css de los dashboards actuales y a partir de ahí mantenerlo como estilo base.

urlDashboard?styles=url1.css,url2.css

Estilado personalizado en Dashboards Sofia2

Inyección de parámetros en Dashboards

image339

 

En la última release de Sofia2 se han mejorado las capacidades de integración de dashboards y gadgets en aplicaciones o webs. Uno de estos cambios, ha sido la posibilidad de pasar parámetros a los gadgets y dashboards de manera dinámica. Esta integración se apoya en los gadgets paramétricos que ya existían en Sofia2.

 

image1

 

Con esta nueva funcionalidad, se pueden integrar tanto gadgets como dashboards desde su url en sitios externos y, desde estos, refrescar el contenido de los mismos mediante parámetros de url.

 

image2

 

Existen dos formas de incluir estos parámetros a los gadgets:

  • Formato directo: sigue el siguiente formato y sustituye tanto en gadgets como dashboards todos los parámetros por nombre indistintamente.

          urlDashboard/Gadget?param1=value1&param2=value2

 

Gadgets:

image3

 

Dashboards:

  • Formato específico: sólo para dashboard. Con este formato podemos elegir que gadgets reciben un determinado parámetro dentro de un dashboard, con lo que podemos tener, por ejemplo, varias instancias del mismo gadget paramétrico y que cada una reciba un parámetro diferente. En este caso, se tiene que enviar una estructura más compleja en formato JSON sobre el parámetro “params” para indicar que gadget recibe un determinado parámetro o parámetros comunes a todos los gadgets. El formato es el siguiente:

image4

          urlDashboard/Gadget?params={‘idGadget1’:[{‘param1’:value1},{‘param2′: value2}],’all’:[{‘comun1’:value3},{‘param1’: value2}]}

 

Con la palabra reservada ‘all’ indicaremos que todos los gadgets recibirán un determinado parámetro. Si este parámetro ya lo tiene el propio gadget entonces tendrá preferencia el del propio gadget. En el caso anterior, si tenemos dos gadgets con IDs idGadget1 y idGadget2, el primero recibirá los parámetros:

  • param1: value1
  • param2: value2
  • comun1: value3

 

El segundo recibirá:

  • comun1:value3
  • param1:value2

image5

 

Los identificadores de Gadgets pueden obtenerse pulsando, en el modo edición del dashboard, las opciones del gadget.

image6

 

Si un gadget tiene más parámetros que los que recibe, entonces se pintará un formulario en su área de dibujado con los parámetros restantes para poder completar la lista.

Inyección de parámetros en Dashboards

Orquestación de notebooks desde motor de flujos: Procesamiento de imágenes con Sofia2

image1

En la nueva versión de Sofia2 se ha añadido un nuevo nodo al motor de flujos capaz de gestionar ejecuciones sobre notebooks de la plataforma.

Con esta nueva característica, se pueden orquestar procesos basados en notebook e incluso paralelizar los mismos distribuyendo la carga de trabajo. Es posible pasar parámetros dinámicos a estos notebooks, pudiendo incluir información fija o generada por un flujo sobre cualquier lenguaje usado en los notebooks y más adelante iniciar una ejecución con los mismos.

Al igual que los parámetros de entrada, se posibilita la salida de los datos generados por uno o varios párrafos de un notebook, incluyendo información generada por un proceso analítico dentro del flujo y tomar decisiones en base al mismo.

Vamos a ver un tutorial de uso del mismo. Tendremos varios elementos de Sofia2 que nos ayudarán a construir y procesar una imagen que el usuario incluirá a través de una web, los cuales son:

  • Proyecto Web: Donde alojaremos la web donde el usuario subirá su imagen y verá los resultados.
  • Binary Repository: Para almacenar y recuperar las diferentes imágenes generadas
  • SSAP: Que nos servirá para comunicarnos entre los diferentes elementos
  • Motor de Flujos (Nodered + nodo Notebook Launcher)
  • Notebooks Sofia2: Usaremos dentro de los mismos Python junto con la librería PIL para procesar imágenes.
  • Gadgets Sofia2: Tendremos un gadget donde se mostrará el histograma de la imagen subida

Lo primero que haremos, será crear un proyecto en Sofia2 que tendrá un domino del motor de flujos y que también tendrá asociada la web.

image2

En la web asociada al proyecto tendremos una interfaz simple que permitirá subir un imagen al binary repository, realizará un POST sobre una URL que iniciará el flujo de procesamiento (al que le pasará los datos de la imagen ya subida) y que mediante el protocolo SSAP se subscribirá a la ontología donde recibirá los resultados de las imágenes ya procesadas.

image3

La url donde se pueden ver los resultados y el código fuente es la siguiente https://sofia2.com/web/imageprocess/imageFlow.html

A continuación, veremos los notebooks necesarios para el procesamiento, así como la configuración necesaria en el motor de flujos. Los notebooks se han construido de manera que cada uno haga una funcionalidad concreta y aislada.

Conversor de RGB a escala de grises: recibe como parámetro una sessionKey válida y el identificador del binary repository (la referencia de la imagen de entrada). Utilizando lenguaje Python y la librería PIL se obtendrá esa imagen del binary repository se convertirá a escala de grises y se volverá a subir al binary repository.

En este notebook podemos comprobar cómo se pueden recibir parámetros en el mismo. Simplemente usando z.input(“nombreParámetro”) crearemos un párrafo que podrá recibir datos dinámicos de forma externa por un formulario, esto no solo es válido para Python, se puede incluir igualmente en otros lenguajes soportados en los notebook como por ejemplo con el interpreter de Spark(scala).

image4

image5

Teniendo ese notebook creado, dentro del motor de flujos podremos añadirlo con el nodo Notebook Launcher:

image6

Al añadir ese nodo, podremos seleccionar cualquiera de los notebooks del usuario en la configuración:

image7

Posteriormente añadiremos el párrafo de entrada (se nos mostrará la lista de los mismos junto con el título y el texto de los mismos):

image8

Al añadir un párrafo con parámetros de entrada, se nos desplegará el formulario correspondiente para configurar cada entrada dinámicamente.

image9

En cuanto a la salida del párrafo (la cual, en este caso, será el nuevo identificador del binary repository de la imagen procesada) la haremos como salida del último párrafo el cuál imprimirá ese identificador. De manera análoga a los parámetros de entrada seleccionaremos un párrafo de salida. Además, se le podrá añadir un tópico para poder distinguir esta salida de otras en nodos posteriores.

image10

Si tuviéramos varios párrafos de salida, podríamos incluir diferentes salidas distinguidas por tópico.

image11

Al enviarlas, podrá ser por array en el mismo puerto (Split Output desactivado) o por diferentes puertos de salida (Split Output activado):

image12

Filtro Blur sobre imagen RGB: similar al notebook anterior salvo que se hará un filtro blur sobre un imagen.

image13image14

Obtención histograma: en este caso se leerá la imagen y se devolverá en el último párrafo el array del histograma

image15

Agrupación de datos: notebook que unificará los datos de los diferentes notebook de procesamiento para conformar una salida única que se enviará posteriormente a la ontología de salida por SSAP a Sofia2.

image16

En este caso, en la configuración del nodo, al tener varios notebooks de entrada tendremos que tener activado el Workflow Mode. Con esta opción, este nodo, se esperará a todos los notebooks de entrada antes de ejecutarse (cada notebook le enviará un parámetro). A parte, al tener varias entradas y no saber el orden de las mismas, tendremos que diferenciar las entradas del nodo por tópico para direccionarlas correctamente. Este direccionamiento se puede hacer de 3 formas:

  • payload: única entrada y se recoge el parámetro el contenido de “payload”
  • payload[n]: múltiples entradas, se recoge la que llega en posición n
  • payload{“topic”:”t1″}: múltiples entradas, se busca la que “topic” sea igual a “t1”

Para este nodo en concreto tendremos:

image17

Ahora, vamos a ver el flujo de procesamiento completo dentro del motor de flujos:

image1

La primera parte del mismo crea un endpoint REST de tipo POST (este será el disparador de todo el flujo). Dentro de este POST se incluirán por JSON los datos de:

  • SessionKey: sessionKey del usuario contra Sofia2. Se usará en todos los acceso al binary repository o al enviar mensajes SSAP
  • BinaryID: id en el binary repository de la imagen inicial

image18

A parte también se incluirá la sessionKey (común para todos los procesos) en el contexto del flow mediante el nodo function.

image19

Más adelante esta información llega a 3 nodos de tipo Notebook Launcher:

image20

Cada uno de estos notebooks recibirá como parámetro el ID del Binario junto con la sessionKey (desde el contexto del flow).

image21

La salida en el caso concreto del conversor a escala de grises va tanto al notebook de agrupación de datos, como a otro notebook idéntico al de filtrado blur.

image22

Aquí, se puede el porqué de la distinción por funcionalidad completa y aislada de los notebooks pudiendo verlos como “cajas negras” reutilizables que procesa con una entrada y una salida. A parte, el nodo notebook launcher crea una instancia de ejecución nueva para cada notebook, por lo que se puede usar varios nodos iguales en paralelo.

Finalmente, se crea un mensaje SSAP que se envía por POST a la ontología destino.

image23

image24

El resultado de todo este proceso, al subir una imagen de este tipo:

image25

Obtendremos al terminar el procesamiento las diferentes imágenes:

  • Imagen con filtro blur
  • Imagen en escala de grises
  • Imagen en escala de grises más filtro blur
  • Histograma en un gadget

image26

El código de los notebook así como la exportación del flujo de nodered puede descargar en el siguiente enlace del github de Sofia2: https://github.com/Sofia2/Sofia2-ImageProcessing

 

Orquestación de notebooks desde motor de flujos: Procesamiento de imágenes con Sofia2

New Notebook Module Version

image1

image2

 

In the new Sofia2 4.0 release, notebook engine has been migrated to the new Apache Zeppelin version, refactorizing the user interface and including new features and capabilities.

 

Some of the new notebooks features are:

 

  • Exporting notebooks is now available as JSON file: there are two ways to do this, from user’s notebook list and from edit notebook interface.

 

image3image4

 

  • Importation of notebook from JSON files, from the user’s notebook list.

 

image5

 

  • Exportation of generated data from different kinds of visualization in TSV/CSV format.

 

image6

 

  • Version control over different repositories like Git, Azure, S3 or ZeppelinHub.

 

image7

 

  • New visualization capabilities granted by Helium Framework throught many frontend plugins that allow create from new chart types to interpreters.

 

image8

 

  • Upgraded to Apache Zeppelin 0.7.1 and Spark 2.1

 

  • Centralizated Visualization in notebook execution information (Jobs)

 

image9

 

  • Notebooks Security improvements
New Notebook Module Version