Animaciones en tus gráficos de Chart.js

0
3259

Índice de contenidos

    1. Entorno
    2. Introducción
    3. Animaciones
    4. Ejemplos
    5. Conclusiones

1. Entorno

    • Hardware: Portátil MacBook Pro 15 pulgadas (2,5 GHz Intel Core i7, 16GB RAM)
    • Sistema Operativo: MacOS Monterey 12.4
    • Bootstrap 5
    • Chart.js v3.8.0

2. Introducción

Chart.js es una librería javascript open-source para el uso de gráficos en tu página web. En el tutorial anterior introducía esta librería contando los conceptos básicos y explicando algunos ejemplos, si no has leído ese tutorial te recomiendo que lo hagas antes de empezar con este: Cómo añadir gráficos en tu web con Chart.js

En este tutorial nos centraremos más en características propias de la librería, como son las animaciones en los gráficos, que nos permiten que nuestros gráficos tengan todavía un mejor aspecto.

3. Animaciones

Chart.js tiene por defecto una pequeña animación ya integrada, al cargar los datos o eliminar algún conjunto de datasets se recarga el gráfico con una pequeña transición.

Es posible añadir más animaciones a los gráficos que pueden ser de diferentes tipos y que afecten a diferentes propiedades. Como por ejemplo animación en bucle, progresiva, al inicio… que afecte al color, grosor de los bordes, tensión, puntos…, e incluso es posible solo configurar la animación para un conjunto de datos en caso de que el gráfico tuviera más de uno.

A continuación explicaré la estructura y conceptos básicos de las animaciones y algunos ejemplos posibles.
La estructura básica de las animaciones está dentro de la etiqueta animations, que formara parte de la etiqueta options, dataset o tooltip dependiendo donde queramos la animación

    • animations:
      • animation: elemento que queremos animar puede ser tension, borderWidth. La palabra animation deberá ser sustituida por el elemento que queramos animar.
        • duration: duración de la animación en ms
        • type: number o color (por defecto es number). Esto depende del elemento que se quiera animar, hay elementos numéricos como grosor, tensión o elementos de color como fondo, color del borde…
        • easing: función movimiento (tipos)
        • to: valor final de la animación (color o número)
        • from: valor inicial para la animación (color o número)
        • loop: repetición en bucle de las animaciones (boolean)

4. Ejemplos

Hay diferentes tipos de animaciones como pueden ser:

  • Loop: animaciones que se repiten en bucle
  • Delay: animaciones donde se muestran los datos con una pequeña demora
  • Drop: animaciones donde se muestran los datos en forma de caída
  • Proggresive Line: gráfico donde se muestra las líneas de forma progresiva

A continuación mostraré alguno de los ejemplos con estas animaciones.
Los gráficos los crearemos de la misma manera que el primer tutorial de Chart.js, si todavía no lo has leído: Cómo añadir gráficos en tu web con Chart.js

Ejemplos Animación Loop

Para que nuestra animación se ejecute en bucle debemos establecer la propiedad loop como true. Establecemos el elemento que queremos animar, en nuestro caso será el primer ejemplo tension para animar la tensión de las líneas y el segundo ejemplo backgroundColor para animar el color de las barras del gráfico.

Hay que decir los valores de inicio y final de animación dependiendo si nuestra animación es de un elemento numérico como el caso de tensión o un elemento de color como el caso de backgroundColor.

Gráfico líneas con animación en la tensión de la línea

const config = {
    type: 'line',
    data: data,
    options: {
        animations: {
            tension: {
                duration: 1000,
                easing: 'linear',
                from: 1,
                to: 0,
                loop: true
            }
        },
        scales: {
            y: {
                min: 0,
                max: 100
            }
        }
    }
};

Puedes ver la demostración y código completo aquí: Ejemplo gráfico líneas

Gráfico de barras con animación en el color de fondo

const config = {
    type: 'bar',
    data: data,
    options: {
        animations: {
            backgroundColor: {
                type: 'color',
                duration: 2000,
                easing: 'linear',
                from: 'blue',
                to: 'red',
                loop: true
            }
        },
        plugins: {
            legend:{
                display:false
            }
        }
    },

};

Puedes ver la demostración y código completo aquí: Ejemplo gráfico barras color de fondo

Ejemplos Animación Delay

Este tipo de animación es cuando no queremos que los datos aparezcan desde el inicio, queremos que aparezcan con una demora, permitiendo así mostrar los datos del gráfico de manera escalonada.

Para ello será necesario configurar la etiqueta delay con la demora que queramos, donde normalmente suele ser un cálculo aumentando el tiempo de demora para cada dato:

const config = {
    type: 'bar',
    data: data,
    options: {
        animation: {
            delay: (context) => {
                let delay = 0;
                if (context.type === 'data') {
                    delay = context.dataIndex * 300 + context.datasetIndex * 100;
                }
                return delay;
            },
        },
        scales: {
            x: {
                stacked: true,
            },
            y: {
                stacked: true
            }
        }
    }
};

Puedes ver la demostración y código completo aquí: Ejemplo gráfico barras

Ejemplo Animación Progressive Line

Este tipo es muy similar al anterior de demora, e incluso se configura de una manera muy similar, pero Chart.js lo separa como otro tipo de animación en concreto para los gráficos de líneas, que permite que se vaya dibujando la línea de datos de forma escalonada.

Esta configuración es un poco más difícil de entender, Chartjs nos da un ejemplo con todo lo necesario para mostrar este gráfico, pero no indaga mucho en la explicación.
Se necesita configurar el tiempo para mostrar los datos de ambos ejes, aumentando este tiempo con los datos a mostrar. El eje Y se tomará como punto inicial el punto anterior que se irá calculando

const totalDuration = 10000;
const delayBetweenPoints = totalDuration / data.length;
const previousY = (ctx) => ctx.index === 0 ? ctx.chart.scales.y.getPixelForValue(100) : ctx.chart.getDatasetMeta(ctx.datasetIndex).data[ctx.index - 1].getProps(['y'], true).y;
const animation = {
    x: {
        type: 'number',
        easing: 'linear',
        duration: delayBetweenPoints,
        from: NaN, // the point is initially skipped
        delay(ctx) {
            if (ctx.type !== 'data' || ctx.xStarted) {
                return 0;
            }
            ctx.xStarted = true;
            return ctx.index * delayBetweenPoints;
        }
    },
    y: {
        type: 'number',
        easing: 'linear',
        duration: delayBetweenPoints,
        from: previousY,
        delay(ctx) {
            if (ctx.type !== 'data' || ctx.yStarted) {
                return 0;
            }
            ctx.yStarted = true;
            return ctx.index * delayBetweenPoints;
        }
    }
};

Puedes ver la demostración y código completo aquí: Ejemplo progressive line

Ejemplo Animación solo en un dataset

Como he comentado antes, es posible configurar una animación para que solo afecte a una parte del gráfico, mostrándose así solo uno de los conjuntos de datos animado.
De esta forma se deberá cambiar el lugar de configuración de la etiqueta animations y se incorporará dentro de las características del dataset que queramos animar. Recordar que antes estaba dentro de la etiqueta options de configuración.
No es necesario que ambos datasets sean del mismo tipo, puede configurarse, como es este caso, en un gráfico que sea de líneas y barras.

const data = {
    labels: labels,
    datasets: [
        {
            label: "Dataset 1",
            data: [50, 20, 40, 60, 80, 100],
            borderColor: 'rgba(248, 37, 37, 0.8)',
            backgroundColor: 'rgba(255,0,0,0.29)',
            order:1,
            animations: {
                borderWidth: {
                    duration: 1000,
                    easing: 'linear',
                    from: 10,
                    to: 1,
                    loop: true
                }
            }
        },
        {
            label: "Dataset 2",
            data: [80, 90, 40, 50, 70, 90],
            borderColor: 'rgba(69,200,248,0.8)',
            backgroundColor: 'rgba(0,255,234,0.31)',
            type: 'line',
            order:0
        }
    ]
};

const config = {
    type: 'bar',
    data: data,
};

Puedes ver la demostración y código completo aquí: Ejemplo Gráfica de barras y líneas

Esto son solo algunos ejemplos, siempre se puede jugar más con las opciones y configurar la animación y el gráfico concreto para nuestro caso en particular.

Para ver la demostración de todos los gráficos y el código completo de todos los ejemplos anteriores e incluso alguno más en Github o en https://laura-cercas.github.io/chartjs-animations-tutorial/

Para leer más información acerca de estas animaciones se puede consultar la documentación oficial, e incluso Chart.js nos facilita algunos ejemplos de pruebas de diferentes animaciones: Ejemplos Animaciones

5. Conclusiones

Al igual que dije en el primer tutorial, la mayor ventaja de esta librería es que es una librería muy sencilla, no requiere mucha experiencia con html ni javascript, y se puede adaptar a las necesidades de cada página web. Tenemos la suerte de que Chart.js tiene varios ejemplos con todo lo necesario para poder replicarlos y tiene una gran comunidad que usa y apoya esta librería, por lo que no es difícil encontrar soluciones y explicaciones a lo que nos ofrece Chart.js

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad