Crear gráficos con JavaScript y RoughViz

Con este sencillo tutorial, aprenderás a crear gráficos con una estética única con JavaScript y la librería RoughViz.

https://github.com/jwilber/roughViz “RoughViz.js is a reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser, based on D3v5, roughjs, and handy.” 

Éste artículo contiene un ejercicio práctico para ver cómo implementar la librería. Haz click en la siguiente imagen para ver el resultado final en una ventana nueva:

Ejercicio con Roughviz
Haz click sobre la imagen para abrir el ejercicio en una ventana nueva. Crea gráficos con JavaScript y RoughViz

¿Quieres aprender a hacer este ejercicio? Saltar directamente al tutorial

JavaScript al servicio de la visualización de datos

Diariamente, muchos desarrolladores, utilizan JavaScript como una herramienta esencial para solventar necesidades de visualización de datos. La visualización de datos, consiste principalmente, en recuperar y representar datos, de forma relevante y entendible.

En cierto modo, es comprensible que JavaScript esté tan al servicio de este interesante, y extenso, campo de desarrollo. Principalmente, por la posibilidad que ofrece de representar gráficos dinámicos e interactivos, en forma de SVG directamente en el navegador. Por eso, muchas empresas, buscan integrar librerías JavaScript de este tipo, en sus aplicaciones cloud.

Existen muchísimas librerías que dan solución a necesidades de creación de gráficos de todo tipo. Por mencionar algunos, D3 o ChartJs son de las más relevantes. Por supuesto, en su debido momento, les daremos un vistazo a cada una de estas.

Sin embargo, hoy veremos una librería de representación de datos, un tanto peculiar. RoughViz, nos llama la atención por su estética. A diferencia de las otras librerías, RoughViz permite “pintar” gráficos como si estuvieran hechos a mano. Dando como resultado, un aspecto de boceto muy característico.

ejemplos de RoughViz
Ejemplos con RoughViz

La justificación que se da del porqué de la existencia de este recurso, en el repositorio de Github, no podría ser más acertada. El objetivo de estas representaciones, es el de dar una idea aproximada, y no de absoluta precisión. O sencillamente, porque se ven graciosos y peculiares.

¿Qué ofrece esta herramienta?

RoughViz, tiene 6.2k estrellas en Github, sólo ocupa 352kb en su versión comprimida, y se puede instalar a través del comando “npm install rough-viz”.

Adicionalmente, ofrece “wrappers” para frameworks y lenguajes más populares. Concretamente para React, Vue y Python.

Su API expone hasta 7 tipos de gráficos distintos. De barras verticales, horizontales y apiladas. De líneas, de donuts y quesos. Y hasta de nube de puntos.

Cada uno de estos tipos, se importa como una clase independiente. Que posteriormente se instancia, pasando un objeto de propiedades. Por supuesto las propiedades pueden variar en función del gráfico a representar, para ajustarse a sus características.

Sea como sea, todas las clases van a necesitar dos propiedades obligatorias. Una propiedad “element” que actúa como selector del contenedor en el DOM. Y otra “data”, con los datos que se van a representar.

Un sencillo ejercicio para crear gráficos con JavaScript y RoughViz

Su API es extremadamente sencilla, pero, como siempre, la mejor forma de aprender, es haciendo un ejercicio desde cero.

En este ejercicio vamos a crear un conjunto de 4 gráficos con estética de boceto. En ellos representaremos datos extraídos de una API pública.

Inicialmente, prepararemos un sencillo “layout” con HTML. En él definiremos cuatro áreas donde posteriormente acomodaremos los gráficos. A cada una de las “divs” les daremos un identificador único, y una clase común.

<div>
      <div id="viz-bar-container" class="viz-container"></div>
      <div id="viz-donut-container" class="viz-container"></div>
      <div id="viz-scatter-container" class="viz-container"></div>
      <div id="viz-pie-container" class="viz-container"></div>
</div>

Para darle un poco de diseño a la página, utilizaremos SCSS. Mediante los selectores CSS, aplicaremos distintos estilos a los elementos del DOM. Al “body”, le vamos a añadir una imagen de fondo que simule un papel de libreta. Muy adecuado para el estilo que nos va a ofrecer RoughViz. Ese patrón de libreta, lo vamos a extraer de la página http://subtlepatterns.com/. Una web que recoge todo tipo de imágenes de patrones geniales.

body {
  margin: 0;
  padding: 20px 0 20px 0;
  background-image: url("../assets/images/hip-square.png");
  & > div {
    display: flex;
    flex-wrap: wrap;
    .viz-container {
      width: 50%;
      min-width: 400px;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      svg {
        display: block;
      }
    }
  }
}

Finalmente, vamos a programar el script para crear gráficos con JavaScript y RoughViz. Para que no resulte muy monótono, previamente instalaremos la librería “tinycolor2”. Con esta herramienta, podremos aplicar colores aleatorios a nuestros gráficos. Si te interesa conocer más a fondo lo que ofrece esta librería, puedes pasarte por el artículo que le dedicamos.

Para crear el script, el primer paso será importar las librerías y estilos.

import { Donut, Bar, Scatter, Pie } from "rough-viz/dist/roughviz.min.js";
import tinyColor from "tinycolor2";
import "./SCSS/index.scss";

A continuación, preparamos una función llamada fetchData. Al llamar a esta función, realizaremos una petición asíncrona a una API abierta. Esta API es https://fakerapi.it, un recurso online muy útil, que entrega datos falsos para realizar pruebas.

const fetchData = async (quantity = 3) => {
  try {
    const response = await fetch(
      `https://fakerapi.it/api/v1/products?_quantity=${quantity}&_price_min=10&_price_max=100`
    );
    const data = await response.json();
    return data;
  } catch (err) {
    console.log(err);
  }
};

La siguiente función que vamos a preparar es getRandomColor. Tal como su nombre sugiere, nos retornará un color aleatorio, en forma de cadena de texto. Por supuesto, para realizar esta función nos apoyaremos en la API de tinyColor.

const getRandomColor = () => {
  const color = new tinyColor(tinyColor.random());
  return color.saturate(100).toHexString();
};

Con esto, ya estamos en disposición de crear las funciones para la generación de gráficos. Todas las funciones serán muy similares. Recibirán datos como argumento, y crearán una instancia de una de las clases de la librería.

Empezaremos por crear la función “createBar”. CreateBar creará un gráfico de barras, por eso, vamos a instanciar la clase “Bar”. Entre las propiedades de la instancia definimos obligatoriamente “element” y “data”. El primero haciendo referencia al id del contenedor en el HTML. Y el segundo, adaptando los datos recibidos al formato necesario. En ese caso, un objeto con “labels” y “values”.

El resto de propiedades son opcionales. Sin embargo, es interesante mencionar algunos. “Roughness” determina cómo de caótico va a ser el trazo. Y la propiedad color define el color de las barras. Por supuesto, a través de la función “getRandomColor”, aplicaremos un color aleatorio.

const createBar = (data) => {
  return new Bar({
    element: "#viz-bar-container",
    data: {
      labels: data.map((product) => {
        return product.name;
      }),
      values: data.map((product) => {
        return product.net_price;
      }),
    },
    title: "Barras",
    roughness: 2,
    color: getRandomColor(),
    stroke: "black",
    strokeWidth: 1,
    fillStyle: "zigzag",
    fillWeight: 0.5,
  });
};

El resto de funciones para crear gráficos, siguen un esquema muy parecido.

Para la clase Donut, creamos la función createDonut.

const createDonut = (data) => {
  return new Donut({
    element: "#viz-donut-container",
    data: {
      labels: data.map((product) => {
        return product.name;
      }),
      values: data.map((product) => {
        return product.net_price;
      }),
    },
    title: "Donut",
    roughness: 4,
    colors: [getRandomColor(), getRandomColor(), getRandomColor()],
    stroke: "black",
    strokeWidth: 1,
    fillStyle: "cross-hatch",
    fillWeight: 0.5,
  });
};

En createScatter, instanciamos la clase Scatter.

const createScatter = (data) => {
  return new Scatter({
    element: "#viz-scatter-container",
    data: {
      x: data.map((product, i) => {
        return i;
      }),
      y: data.map((product) => {
        return product.net_price;
      }),
    },
    title: "Scatter",
    roughness: 2,
    radius: 30,
    stroke: "black",
    strokeWidth: 1,
    fillStyle: "solid",
    fillWeight: 0.5,
  });
};

También definimos createPie, para construir un gráfico de tipo Queso con la clase Pie.

const createPie = (data) => {
  return new Pie({
    element: "#viz-pie-container",
    data: {
      labels: data.map((product) => {
        return product.name;
      }),
      values: data.map((product) => {
        return product.net_price;
      }),
    },
    title: "Queso",
    roughness: 4,
    colors: [
      getRandomColor(),
      getRandomColor(),
      getRandomColor(),
      getRandomColor(),
    ],
    stroke: "black",
    strokeWidth: 3,
    fillStyle: "zigzag-line",
    fillWeight: 0.5,
  });
};

Finalmente, añadimos un “listener” para saber si la ventana del navegador está lista, y ejecutamos las instrucciones en el orden adecuado.

window.addEventListener("load", async () => {
  let data = await fetchData(5);
  createBar(data.data);
  data = await fetchData(3);
  createDonut(data.data);
  data = await fetchData(10);
  createScatter(data.data);
  data = await fetchData(4);
  createPie(data.data);
});

Con esto, ya hemos visto como crear gráficos con JavaScript y RoughViz.

RoughViz, la propuesta espontánea

Resulta complicado encontrar aplicaciones prácticas para RoughViz. Es evidente que, para abordar un proyecto de representación de datos, existen alternativas mucho mejores. 

Sin embargo, la propuesta que plantea, es interesante para proyectos desenfadados. Proyectos que quieran transmitir la idea de espontaneidad.

Este ha sido un pequeño vistazo a la librería RoughViz. A continuación os dejo enlaces a más recursos, así como el ejercicio subido al repositorio de Github de “Librerías Js”:

Nos vemos pronto, un abrazo desarrolladores!

Deja un comentario