Fecha publicación: 3 may 2021

D3js creando un gráfico de tarta

Vamos a crear el mínimo para tener una gráfica de tarta, verás que el proceso es muy directo, donde se nos va a ir el tiempo será personalizando la gráfica y añadiendo detalles, ésto lo veremos más adelante.

Manos a la obra

De cara a poder entender mejor estos ejemplos vamos a nombrar las variables y funciones en español, de esta manera podemos ver claro que partes del código vienen de usar la librería d3js, y que partes del código son propias. En un proyecto real lo normal es que siempre nombres variables y funciones en inglés.

Lo primero, vamos a inventarnos unos datos de ventas de un trimestre:

interface Ventas {
  mes: string;
  ventas: number;
}

const ventas: Ventas[] = [
  { mes: "Enero", ventas: 5000 },
  { mes: "Febrero", ventas: 2500 },
  { mes: "Marzo", ventas: 3000 },
];

Y vamos a darle una escala de colores, podemos o bien usar una escala predefinida, o podemos darle una propia. Para crear la escala personalizada hacemos un mapping entre los nombres de los meses y una lista de colores.

Aquí tenéis la predefinida

const nombresMeses = ventas.map((venta) => venta.mes);

const color = d3
  .scaleOrdinal<string, string>()
  .domain(nombresMeses)
  .range(d3.schemeSet2);

Una propia sería de la siguiente manera:

const nombresMeses = ventas.map((venta) => venta.mes);

const color = d3
  .scaleOrdinal<string, string>()
  .domain(nombresMeses)
  .range(["#006A7B", "#008D54", "#659B91", "#00BC9F", "#006B5F"]);

En este caso hemos puesto más de 3 entradas por si en un futuro quisieramos añadir más datos

Un gráfico de tarta no deja de ser un círculo, toca ahora sacarle partido a las mates que los más viejos aprendimos en las EGB y los más jovenes aprendistéis en la ESO:

Vamos a crear un elemento grupo g (es un elemento parecido a un div de HTML pero aplicado a SVG), y vamos a ponernos justo en el centro de la circunferencia para poder pintarla (añadimos esto al final de nuestro fichero index.ts)

const centroGrafica = {
  x: margin.left + chartDimensions.height / 2,
  y: margin.top + chartDimensions.width / 2,
};

const grupoGrafica = svg
  .append("g")
  .attr("width", chartDimensions.width)
  .attr("height", chartDimensions.height)
  .attr("transform", `translate(${centroGrafica.x}, ${centroGrafica.y})`);

Siguiente paso, vamos a usar el pie layout de d3js para que nos calcule los arcos de cada trozo de tarta ¿Por qué hay que usar este layout en vez de empezar a pintar del tirón? El pie layout me calcula arcos, estos arcos lo puedes aplicar a lo que tu quieras: una gráfica de tarta, un gráfica de tipo donut, una de semi arco...

Lo primero que hacemos es indicar que vamos a usar este layout, y decirle de cada dato de donde puede sacar el valor númerico a mostrar.

const pieLayout = d3.pie<Ventas>().value((d) => d.ventas);

const datosArcos = pieLayout(ventas);

Queremos que la gráfica se ajuste al espacio que tenemos disponible, para ello:

  • Sabemos que el radio es la mitad del diámetro de la circunferencia.
  • Lo ajustamos para que esté en el centro del área de dibujo que hemos definido.
var datosArcos = pieLayout(ventas);

+ const radio = Math.min(chartDimensions.width, chartDimensions.height) / 2;

Vamos a crear una función que nos permita generar las porciones de nuestra gráfica. Ya que vamos a crear una de tarta, le indicamos que el radio interno es 0, y el exterior sea el máximo que tenga disponible (si quisieramos por ejemplo pintar una gráfica de tipo donut tocaríamos el valor de innerRadius)

const constructorDePath = d3.arc().innerRadius(0).outerRadius(radio);

Es hora de pintar la gráfica, que hacemos

  • Tomamos como punto de partida el grupo que creamos anteriormente (el que incluye los márgenes).
  • Agrupamos en una selección los elementos que vamos a crear, de esta manera más adelante podríamos realizar actualizaciones si fuera necesario.
  • Le pasamos los arcos que previamente calculamos con el pie layout.
  • Le indicamos a d3js que vamos a insertar elementos.
  • Añadimos un Path por cada arco (un path es una primitiva de SVG representa un polígono que puede ser abierto o cerrado).
  • Lo rellenamos con el color que toque en base a la escala que hemos definido antes.
grupoGrafica
  .selectAll("slice")
  .data(datosArcos)
  .enter()
  .append("path")
  .attr("d", <any>constructorDePath)
  .attr("fill", (d) => color(d.data.mes));

Con esto podemos ver nuestra gráfica de tarta recien montado.

Referencias

Este ejemplo está basado en el ejemplo descrito en este enlace: https://www.d3-graph-gallery.com/graph/pie_basic.html

¿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.