Captura realizada de SlideModel.com

Cómo usar D3 con WebComponents

Crea potentes gráficas con Stencil y WebComponents

Ruben Triviño
Published in
5 min readApr 18, 2020

--

D3 es una fantástica biblioteca opensource para la visualización de datos desarrollada originariamente por Mike Bostock. La gran variedad de herramientas que ofrece, permite crear gráficas únicas y con vida propia desde cero, o utilizando algunas construcciones predefinidas. Las posibilidades que ofrece D3 son ilimitadas, solo hay que echar un vistazo a la galería que tiene en GitHub.

https://cdn-images-1.medium.com/max/1600/1*pJBsduCvTEHNwCiOEu17Yg.png
Imagen obtenida de D3js

Si ya has trabajado con D3 sabrás que, además de conseguir gráficas realmente impactantes, acabas acumulando un buen puñado de scripts para dar formato a los datos, iterar sobre los elementos SVG, interfaces de comunicación con el servidor, modelos, etc.. Todo esto, probablemente, en medio de un proyecto que poco tendrá que ver con las gráficas en sí. Resumiendo, un engorro.

Por suerte, el mundo de los Web Components cada vez está más accesible y es la herramienta perfecta para crear tu propio hub de graficación, bien encapsulado y reutilizable. En Custom Elements Everywhere puedes comprobar si los webcomponents son compatibles con tu framework de desarrollo web favorito.

StencilJS

Stencil es un compilador de Web Components, o más específicamente, Custom Elements, que utiliza las funcionalidades principales de los frameworks más utilizados.

Esta herramienta fue desarrollada por el equipo de IonicFramework para facilitar la creación de componentes que fueran compatibles con los frameworks principales.

Por tanto, utilizar D3 en un proyecto basado en las especificaciones de Web Components empleando StencilJS es una solución elegante y fácil de llevar acabo si quieres hacer un único proyecto de graficación reutilizable.

Paso 1: Crear un proyecto en Stencil

En primer lugar, descarga la última versión de Stencil utilizando npm desde la consola e inicializa un proyecto base:

npm install @stencil/core@latest --save-exactnpm init stencil

Elige la opción component con las flechas del teclado y un nombre para el proyecto. El CLI de Stencil creará una carpeta base dentro de la cual encontrarás la carpeta src con el primer componente creado por defecto: my-component. El archivo .tsx del componente es el que almacena la lógica inicial del componente.

https://cdn-images-1.medium.com/max/1600/1*d7EvOVpN4wzeBYICNU2Wcg.png
Estructura de directorios de my-component

Para comprobar que todo funciona correctamente lanza el comando start desde la raíz del proyecto.

npm run start

Una nueva ventana del navegador debería abrirse, con la aplicación HelloWorld! de Stencil, bastante seco la verdad.

Paso 2: Importar D3 y crear un gráfico

Una vez iniciado el proyecto en Stencil solo tenemos que incluir en las dependencias la librería D3:

npm install d3 --save

Para trabajar con D3 en un código JavaScript lo habitual es importar todas las referencias de la biblioteca y definir el alias d3, pero desde la última versión tendremos que importar los distintos módulos por separado. Es algo más tedioso pero que nos ayudará a reducir el peso/tamaño de la aplicación. En este caso, vamos a hacer una gráfica circular y utilizaremos los siguientes módulos:

import { select } from 'd3-selection'
import { pie, arc } from 'd3-shape';
import { scaleOrdinal } from 'd3-scale';
import { quantize } from 'd3-interpolate';
import { interpolateCool } from 'd3-scale-chromatic';
  • El operador select permite localizar los elementos html con los que deseamos operar y/o modificar.
  • El operador pie es el encargado de generar una estructura de datos y arc es la herramienta que nos permite generar los ángulos, radio, etc. para crear los elementos visuales del gráfico.
  • Los operadores scaleOrdinal, quantize e interpolateCool nos ayudan a generar una gama de colores en función del valor a graficar.

Ya está todo dispuesto, solo necesitamos saber dónde ubicar nuestro código D3. La estructura básica del componente gráfico será algo así:

La API de Stencil nos ofrece una serie de etiquetas y métodos que nos permiten operar con el componente y su ciclo de vida:

Prop()

Esta etiqueta permite la entrada de información externa, como por ejemplo los datos a graficar. Estos datos serán facilitados en el momento de usar la etiqueta html de nuestro webcomponent.

Si observamos en los documentos del proyecto, el archivo src -> index.html contiene los elementos generados (en este caso solo uno) y vemos que la invocación del elemento es la siguiente, donde myData representa los datos que será utilizados para mostrar en la gráfica:

<my-component data='myData'></my-component> 

render()

Esta función es invocada tras la instanciación del componente y es la responsable de generar los elementos visuales en html. Aquí, generamos el esquema html base de nuestro componente, en el que incluimos el elemento SVG que utilizaremos para generar todos los componentes de la gráfica.

componentDidLoad()

Este método es invocado una vez los elementos hayan sido cargados completamente, evitando así obtener referencias vacías de los elementos html del componente.

La lógica asociada a D3, para la generación de nuevos elementos gráficos, debe ser invocada dentro de este método para garantizar que podamos operar sobre el html definitivo.

Element()

Esta etiqueta nos permite acceder a la referencia propia del componente y poder así iterar sobre los elementos html hijos. En concreto, esta es la referencia que utilizaremos para utilizar la función select de D3 y obtener así el SVG donde inflaremos el gráfico. Debido a la encapsulación que se realiza del componente tenemos que acceder a través de shadowRoot:

select(this.element.shadowRoot.querySelectorAll(".chart")[0]);
https://cdn-images-1.medium.com/max/1600/1*wpku_twGg_gu2XnaLpj1sg.png
Encapsulación del componente para conseguir un contexto aislado

Una vez conseguimos la referencia del elemento SVG, nos olvidamos de Stencil y operamos pensando exclusivamente en D3.

Añadimos el código para generar una gráfica circular o cualquier otra que queramos y ya tendríamos nuestro webcomponent listo:

Con el código anterior obtendríamos una gráfica circular como esta:

https://cdn-images-1.medium.com/max/1600/1*1Wjg2jGDmdrL3rPwcQ7_OQ.gif
Gráfico Circular. Fuente Propia

Paso 3: Exporta y utilízalo donde quieras

Una vez tenemos el gráfico listo, solo queda exportarlo para poder utilizarlo en cualquier otro proyecto que tengamos. Afortunadamente este proceso es tan simple como revisar el archivo package.json para poner la versión del proyecto, descripción, licencia, etc.. y lanzar el comando build.

npm run build

Esto genera el Web Component listo para distribuir en la carpeta www -> build. Para instalarlo en cualquier proyecto, no hay más que publicarlo en tu cuenta de npm y disfrutar de todas sus ventajas:

npm login
npm publish

Conclusión

Stencil permite crear un entorno de trabajo modular, exportable y accesible por los principales frameworks de desarrollo web. Esto es una gran ventaja para unir elementos visuales de varios proyectos y estandarizar su uso, reciclar código, html, css, etc..

Si trabajas en un equipo de desarrollo que está en contacto con continuo con el departamento de UX/UI, Stencil es el sitio perfecto para desarrollar un Design System sostenible y que facilite el trabajo de ambas partes.

--

--