Creando un gráfico de barras

La forma más tradicional y, muchas veces, efectiva de mostrar datos es usar una gráfica de barras. Las personas somos muy buenas comparando longitudes, sobre todo si estan una encima de otra. Por otro lado, los cálculos necesarios para determinar la longitud de las barras son relativamente sencillos, por lo que empezaremos por esta opción.

Buscando datos

Como el tema es de interés, hay datos sobre COVID-19 en todos los lugares imaginables, con series temporales, por municipio, etc. En este tutorial nos centraremos en los datos provinciales en España, pues se pueden agrupar por Comunidad Autónoma, lo que da juego como veremos. No usaremos datos temporales.

Los datos los tomamos de esta web. Están por fecha, con código de provincia, etc. por lo que hicimos un pequeño script de python para extraerlos un poco y que el archivo para trabajar fuera de un tamaño aceptable. Como que no es el objeto del tutorial, dejamos el enlace con el código (convert.py) pero no lo comentaremos.

Si prefieres descargarte el fichero json en lugar de ejecutar el script de python lo puedes encontrar en el siguiente enlace.

El archivo creado, ccaa_provincia.json estará en cada caso de estudio y consiste en un array de la forma

[
  {
    "name": "Alicante",
    "cases": 146364,
    "code": "A",
    "ccaa": "Comunitat  Valenciana"
  },
  {
    "name": "Albacete",
    "cases": 27785,
    "code": "AB",
    "ccaa": "Castilla-La Mancha"
  },
  ...
]

Con estos datos se pueden mostrar números, etiquetas y agrupar por provincia o Comunidad Autónoma.

Creando el proyecto

Como punto de partida tenemos un proyecto desarrollado con TypeScript y con las librerías de D3js ya instaladas (si buscas una introducción a esta configuración puedes ver nuestro vídeo instalando d3js).

Vamos a trabajar con este proyecto 00-boiler, nos copiamos el contenido de esa carpeta y ejecutamos npm install.

npm install

Y ya se puede comenzar a trabajar

npm start

Abrimos un navegador con la dirección http://localhost:8080

Añadir los datos

Para añadir los datos desde el fichero JSON, los cargaremos con require y los asignamos a un tipo para que TypeScript detecte los campos:

interface ProvinciaData {
  code: string;
  name: string;
  ccaa: string;
  cases: number;
}
const data: ProvinciaData[] = require("./casos_provincia.json");

Escala

Ahora hay que crear una escala. Es una simple función que, dado un valor en nuestros datos (número de casos), te devuelve la longitud de la barra. Aunque es fácil de calcular por uno mismo, d3 tiene también esta función, lo que permite cambiarla fácilmente a escala logarítmica si hace falta, por ejemplo.

const scale = d3
  .scaleLinear()
  .domain([0, d3.max(data, (d) => d.cases)])
  .range([0, chartDimensions.width - 30]);
  • El domain es el rango que ocupan los datos. En nuestro caso, el mínimo es de 0 (aunque podríamos truncar con un número más grande si quisiéramos mostrar diferencias más pequeñas... ¡y engañar un poco a los lectores!) y el máximo es el número máximo en el dataset. d3 tiene otra vez una función que ayuda en eso, llamada d3.max que funciona similar al map o filter.

  • range es la longitud que queremos de vuelta. En este caso, va de 0 a la anchura del gráfico

Añadir las barras

Ya solo queda añadir las barras. Para hacerlo, usaremos el nodo SVG creado anteriormente y lo usaremos para asociarle los datos:

svg
  .selectAll("rect")
  .data(data)
  .join("rect")
  .attr("x", 0)
  .attr("y", (d, i) => i * 30)
  .attr("height", 25)
  .attr("width", (d) => scale(d.cases))
  .attr("fill", (d, i) => d3.schemeSet3[i % d3.schemeSet3.length]);

Aquí pasan bastantes cosas, pero al estar ordenadas se pueden seguir:

  • Del elemento svg se seleccionan todos los elementos de tipo rect (rectángulo), que serán las barras. Nosotros no tenemos ninguno, pero si ya hubiese, se usarían como barras.

  • La función data es la que determina los datos a asociar a los rectángulos. Cada elemento del array data se asociará a los rectángulos.

  • join es el patrón básico de d3 para asociar datos a elementos. Significa que para cada nuevo dato en data creará un elemento rect. Si se eliminan datos (hay más elementos tipo rect que datos en data), se eliminarán los rectángulos.

  • Ahora, a cada rectángulo se le añaden las propiedades del elemento rect usando la función attr de d3

    • x es la posición izquierda del rectángulo, 0 en nuestro caso
    • y es la posición desde la parte superior del svg. En este caso, cada barra la añadimos 30 píxeles hacia abajo
    • height es la altura del rectángulo, que ponemos en 25 para que no se solapen
    • width es la anchura, que dependerá de los datos. Como que d3 ha asociado los datos ea los elementos, si se le pasa una función, el argumento será de tipo ProvinciaData y podremos usar la escala definida anteriormente
    • Finalmente, las barras son negras a menos que les demos un color con el atributo fill. Para este ejemplo simple, elegimos una escala cualquiera de las que vienen en d3

El resultado empieza a ser atractivo, pero faltan unas cuantas cosas para que se entienda, que veremos en el próximo vídeo.

¿Te apuntas a nuestro máster?

Si te ha gustado este ejemplo y tienes ganas de aprender Front End guiado por un grupo de profesionales ¿Por qué no te apuntas a nuestro Máster Front End Online Lemoncode? Tenemos tanto edición de convocatoria con clases en vivo, como edición continua con mentorización, para que puedas ir a tu ritmo y aprender mucho.