Enlgish version is here.

Después de la primera no-inmersión en la API, vamos a empezar a meternos en faena con algo relativamente sencillo:

  • Incluir una visualización que se actualice “sola”.

Para después complicarlo un poco permitiendo que el usuario seleccione el intervalo de actualización desde la visualización.

Estructura:

Ejemplos

Busca un aviso de seguridad y permite la carga de "unsafe scripts"

Visualización incrustada diseñada por Rusell Christopher que se actualiza cada 5 segundos (¡fíjate en el reloj! –haz click aquí si no carga la visualización y no quieres permitir los scripts “inseguros”).

Visualización incrustada que permite cambiar el tiempo de actualización interaccionando con la visualización misma (haz click aquí si no se carga). Los cuadrados de colores (¡marcas de Tableau dentro de la visualización!) permiten modificar el tiempo de recarga. Hay, pues una comunicación bidireccional: la página web recarga la vista, interaccionando con la vista se cambia la variable/parámetro de la página que controla el tiempo de actualización.

Material de referencia

  1. Tableau: Gratísima sorpresa con la calidad y simplicidad del material desarrollado por Tableau. Partiendo de la base de que soy un lego en Javascript, me han parecido sumamente didácticos y asequibles tanto el manual, como los ejemplos interactivos y, muy especialmente los vídeos ejemplos que tienen tanto en github como en youtube.
  2. Russell Christopher: el primer ejemplo (básico, actualización cada 5 s) y la idea y dashboard del reloj son enteramente suyos.
  3. Tamas Foldi es un genio y tiene material muy variado que puede servir de inspiración.
  4. GitHub: he compilado aquí todo el material que he ido usando en este proyecto.

Paso a Paso

Actualización automática

El concepto es muy sencillo: vamos a tener una página web “minimalista” con un único objeto en el cual vamos a cargar la visualización usando la JS API de Tableau.

Después, usaremos Javascript en la página para que recargue la vista.

 

HTML

<div>API embed - Autorefresh every 5 seconds</div>
<div id="myViz"></div>
Éste es todo el cuerpo de la página: Una breve descripción seguida de un elemento “div” al que he llamado “myViz” que, inicialmente, está vacío. El onload=”initialize();” es la orden para que, cuando cargue el cuerpo de la página, lance una función llamada “initialize” que veremos a continuación.

JAVASCRIPT

Lo primero que hace falta es llamar a la API, cosa que, en mi caso, hago usando la de Tableau Public:

<br /><!-- Importing Tableau API --><br /><script type="text/javascript" src="https://public.tableau.com/javascripts/api/tableau-2.js"></script><br />

Esto nos permite ahora usar sus métodos en nuestro script. En el cuerpo de la página llamamos a la función “initalize” que es la que coloca la visualización en el elemento  adecuado (“myViz”). Para ello, hemos de pasarle a la función la url de la viz que queremos incluir así como los distintos parámetros para configurar la visualización (tamaño, con o sin barra de herramientas, etc.).

<br />function initialize() {<br />var placeholderDiv = document.getElementById("myViz");<br />var url = "http://public.tableau.com/views/TheTime/Dashboard1?";<br />var options = {<br />width: 900,<br />height: 600,<br />hideTabs: true,<br />hideToolbar: true<br />}<br />viz = new tableau.Viz(placeholderDiv, url, options);<br />}<br />

Si nos fijamos en la última línea:

viz = new tableau.Viz(placeholderDiv, url, options);

Estamos creando un “new” tableau.Viz, esto es, un objeto Viz que pertenece al módulo “tableau” (o sea, a la API que hemos iniciado al principio) y lo guardamos en la variable “viz” (que no está definida en esta función sino que, veremos, la definimos en el espacio inicial).

La función tableau.Viz recibe tres parámetros:

  1. El elemento HTML en el que colocar la viz.
  2. La url de la visualización original.
  3. Un listado de opciones.

Cada uno de esos parámetros los hemos inicializado dentro de la función “intialize” creando las distintas variables placeholderDiv, url & options.

PÁGINA BÁSICA

Si combinamos la sección de HTML con la de Javascript, y completamos la estructura de la página con un título, la sección de “script” dentro de la cual tiene que ir el JS, la definición de la variable viz y los tags de “html”…tenemos una página básica en la que, al cargarla, aparace la visualización incrustada. Sin ninguna funcionalidad adicional. Es el paso de partida para incluir a continuación el código para que se auto-recargue.
<!DOCTYPE html>
<html>
<title>API autorefresh</title>
<!-- Importing Tableau API -->
<script type="text/javascript" src="https://public.tableau.com/javascripts/api/tableau-2.js"></script>

    
<body onload="initialize();">
       
    <div>API embed - Autorefresh every 5 seconds</div>
    
    <div id="myViz"></div>


</body>
<script>

    var viz;
    
    function initialize() {

        var placeholderDiv = document.getElementById("myViz");
        var url = "http://public.tableau.com/views/TheTime/Dashboard1?";
        var options = {
            width: 900,
            height: 600,
            hideTabs: true,
            hideToolbar: true
            }
        viz = new tableau.Viz(placeholderDiv, url, options);
        }
    
</script>


</html>

AUTORECARGA

Con la página básica ya creada, el paso adicional para incluir una recarga automática es mínimo. Basta con un par de líneas adicionales:
  1. Una para crear una función que dispare la recarga de la visualización.
    function refreshView(){
    viz.refreshDataAsync();
    }
    
  2. Otra para llamar a esa función en un intervalo determinado de tiempo.
 setInterval(refreshView,5000);
La función “refreshView” llama a una propiedad/método de la clase viz: “refreshDataAsync()” que es equivalente a pulsar el botón de actualizar en la barra de herramientas. La función “setInterval()” permite llamar a otra función transcurrido un número determinado de milisegundos. El resultado final está aquí y puedes ver el código en GitHub.

Actualización automática controlando el intervalo de actualización

Partiendo de la visualización y página anterior, el objetivo ahora consiste en permitir seleccionar el intervalo de actualización a partir de elementos de la visualización.

Es decir: la página/elemento web controla la frecuencia de actualizción, tras interaccionar con la visualización, se pasa un valor de la visualización a la página web que la usa como nueva frecuencia.

La interacción con la visualización cambia los valores guardados en la página web
Comunicacíión de doble sentido entre la página web y la visualización

HTML, JAVASCRIPT y un poco de CSS

Además de permitir la selección del intervalo, he incluido un contador que permite seguir el tiempo transcurrido y cómo cambian los valores tras la interacción. Esto se consigue con una línea de HTML:

</p><div>API embed - Autorefresh every N seconds</div><div id="countdown" class="circle"> </div><div id="myViz"> </div><p><!-- Remove this to see info about the selected marks</p>
<div id="markDetails">Information about selected marks displays here.</div>
<p>-->

es un div vacío, sin contenido al empezar, pero con un poco de Javascript podemos pasar el valor en segundos del intervalo de refresco:

<br />var timeleft = ourInterval/1000;</p><p>function countdownDownloadTimer() {<br />document.getElementById("countdown").innerHTML = timeleft + " ";<br />timeleft -= 1;<br />if(timeleft &lt;= 0){<br />timeleft = ourInterval/1000;<br />document.getElementById("countdown").innerHTML = timeleft + " ";<br />var div = document.getElementById("countdown");<br />div.style.background = '#000000';<br />}<br />

que se adereza con un poco de css (fusilado de otra parte)

.countdown {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  font-size: 50px;
  color: #fff;
  line-height: 500px;
  text-align: center;
  background: #ff00ff;
}
    
.circle {
    position: relative;
    top: 50%;
    left: 50%;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  font-size: 20px;
  color: #fff;
  line-height: 100px;
  text-align: center;
  background: #ff00ff;
    
}

El meollo viene ahora en el javascript, aunque es, fundamentalmente, un derivado del usado en la página anterior.
var viz;
var ourInterval = 10000;
function refreshView(){
viz.refreshDataAsync();
}

function initialize() {
var placeholderDiv = document.getElementById("myViz");
var url = "https://public.tableau.com/views/TheTime_0/withboxes?";
var options = {
width: 1200,
height: 600,
hideTabs: true,
hideToolbar: true,
onFirstInteractive: function(){
listenToMarksSelection();
}
}
viz = new tableau.Viz(placeholderDiv, url, options);
}

var refreshInterval = setInterval(refreshView,ourInterval);

Es muy parecido al anterior. Se inicializa la variable “viz”, se define la función “refreshView”, se inicializa la visualización y se crea un intervalo para llamar a la función de actualización. ¿Principales diferencias?
  1. El período del intervalo se guarda ahora en una variable “ourInterval”, lo que permitirá modificarlo después.
  2. Dentro de la función que inicializa la visualización se llama ahora a una nueva función “listenToMarksSelection()” que describiré después y que, importante, se llama después de “onFirstInteractive” que, según Tableau “Callback function that is invoked when the Viz object first becomes interactive. This is only called once, but it’s guaranteed to be called. If the Viz object is already interactive, it will be called immediately, but on a separate ‘thread.‘”
  3. Por úlitmo, no sólo el período del intervalo, sino el intervalo en sí se almacena en una variable “refreshInterval”, lo que permitirá eliminarlo y recrearlo después.

La segunda, y jugosa, parte viene ahora. ¿Cómo pasamos el valor seleccionado en la visualización a la variable “ourInterval” para cambiar el período de actualización de la visualización?

El código es el siguiente:

Parece complejo, pero se puede subdividir en elementos más accesibles:
  1. La primera parte, “listenToMarksSelection” indica al navegador que esté atento y que, tras las selección de alguna marca en Tableau, llame a la segunda función “onMarksSelection”.
  2. Ésta, a su vez, captura todos los valores seleccionados y lanza la tercera parte “reportSelectedMarks”.
  3. En principio, se podrían seleccionar múltiples marcas, aunque este ejemplo esté pensado para una sola. La parte de “reportSelectedMarks”…
    1. navega por todos los pares de “medida & valor” seleccionados y, si la medida se llama “Value”
    2. recoge el valor, lo multiplica por 1000 (el intervalo en JS es en milisegundos),
    3. resetea el tiempo restante para sincronizar el reloj
    4. destruye el intervalo de actualización anterior
    5. y lo reemplaza por uno nuevo con el nuevo intervalo.
El resultado final está aquí y puedes ver el código en github

Gracias por llegar hasta aquí. En el próximo post usaré la API para lanzar alertas en función de cómo cambien los datos. Fácil.

Deja aquí cualquier comentario o contacta a través de alguna de las redes sociales.