Ir al contenido
angel.library

Chart.js

Chart.js dibuja sobre canvas, no sobre SVG: no crea un nodo del DOM por punto, así que aguanta series grandes sin llenar el árbol de elementos. El precio es el otro lado de la misma moneda — lo dibujado no se inspecciona ni se estiliza con CSS, y la accesibilidad hay que resolverla aparte.

Existe desde 2013, licencia MIT, y trae animaciones y tooltips activados por defecto.

Ventana de terminal
pnpm add chart.js

Hace falta un <canvas> cuyo tamaño lo defina el contenedor, y una configuración de tres partes: type, data, options.

<div style="position: relative; height: 320px">
<canvas id="ventas"></canvas>
</div>
import { Chart, registerables } from "chart.js"
Chart.register(...registerables)
const chart = new Chart(document.getElementById("ventas") as HTMLCanvasElement, {
type: "bar",
data: {
labels: ["Ene", "Feb", "Mar", "Abr"],
datasets: [{ label: "Ventas", data: [120, 190, 90, 240] }]
},
options: {
responsive: true,
maintainAspectRatio: false
}
})

responsive: true junto a maintainAspectRatio: false es la combinación que hace que la gráfica siga al contenedor: el alto lo pone el div, no el canvas. Sin eso, o no se adapta o crece sin control.

...registerables registra todos los controladores, escalas y plugins — cómodo, pero anula el tree-shaking. En producción se importan las piezas concretas:

import {
BarController,
BarElement,
CategoryScale,
Chart,
Legend,
LinearScale,
Tooltip
} from "chart.js"
Chart.register(
BarController,
BarElement,
CategoryScale,
LinearScale,
Tooltip,
Legend
)

Si falta una pieza el error lo dice con nombre propio ("bar" is not a registered controller): no es un fallo silencioso.

typePara qué sirve
lineEvolución de una magnitud en el tiempo
barComparar categorías; apilable con stacked
pieComposición de un total, con pocas partes
doughnutIgual que pie, con hueco central para un dato
radarVarias dimensiones de una misma entidad
polarAreaCategorías donde el área comunica la magnitud
scatterRelación entre dos variables numéricas
bubbleComo scatter, con una tercera variable en el radio

Un mismo canvas puede mezclar tipos declarando type dentro de cada dataset: barras más una línea de tendencia, por ejemplo.

options: {
scales: {
y: {
beginAtZero: true,
ticks: {
callback: (valor) => `$${valor}`
}
},
x: {
grid: { display: false }
}
}
}

beginAtZero pesa más de lo que parece en barras: un eje que arranca en 80 exagera diferencias pequeñas.

chart.data.datasets[0].data = [130, 200, 110, 260]
chart.update()

Al desmontar el componente o cambiar de vista, destruye la instancia; si no, el canvas queda con listeners y la siguiente gráfica sobre el mismo elemento falla:

chart.destroy()

Para React (react-chartjs-2), Vue (vue-chartjs) o Svelte hay envoltorios que manejan el ciclo de vida del canvas. Dentro de un framework son la opción recomendada: evitan el destroy manual y el doble render.

Ventana de terminal
pnpm add chart.js react-chartjs-2
  • Lo dibujado en canvas no es texto: un lector de pantalla no lo lee. Acompaña la gráfica con una tabla o un resumen escrito.
  • No hay estilos por CSS: colores, fuentes y bordes se configuran en JavaScript.
  • Las animaciones por defecto están bien en un dashboard y estorban en una impresión o en un test; se apagan con options.animation: false.
  • Con miles de puntos, activa parsing: false y el plugin de decimation antes de culpar al navegador.