3ENGINE

Programación y otros cachivaches

Etiqueta: chart.js

Tecnologia

Chart.js: grafica de tipo donut con múltiples anillos


En un artículo anterior expliqué cómo añadir texto dentro de una grafica de tipo donut. Hoy te voy a mostrar cómo crear una gráfica tipo donut con múltiples anillos.

Extra! tambien veremos cómo modificar la información que aparece al pasar el ratón por encima de cada uno de los datos de la gŕafica.

Básicamente tenemos que declarar varios conjuntos de datos, donde cada conjunto de datos es un anillo. Hasta aqui todo bien. Si queremos mostrar una etiqueta «personalizada» para cada uno de los datos, tenemos que añadir las etiquetas en cada conjunto de datos y sobreescribir la función encargada de mostrar la información que aparece al pasar el ratón por encima. Ademas, ya de paso, hemos aprovechado para calcular el porcentage.

Código HTML

 <div id="mychart-holder">
    <canvas id="mychart"/>
 </div>

Código Javascript

var data = {
    labels: [],
    datasets: [
        {
            data: [2, 3, 8, 3, 4],
            backgroundColor: ["orange", "red", "green", "violet", "lightgreen"],
            labels: ["naranjas", "mandarinas", "manzanas", "berenjenas", "calabacines"]
        },
        {
            data: [2 + 3 + 8,  3 + 4],
            backgroundColor: ["springgreen", "lightblue"],
            labels: ["frutas", "hortalizas"],
        },
        {
            data: [2 + 3 + 8 + 3 + 4],
            backgroundColor: ["lightgray"],
            labels: ["total"],
        }
    ]
};

var myChart = new Chart(document.getElementById('mychart'), {
    type: 'doughnut',
    data: data,
    options: {
        cutoutPercentage: 20,
        maintainAspectRatio: true,
        responsive: true,
        legend: {
            display: false
        },
        animation: {
            animateScale: true,
            animateRotate: true
        },
        tooltips: {
             /* activa esta funcion si deseas no mostrar alguna de las etiquetas
            filter: function (item, data) {
                if (item.datasetIndex == 1) {
                if (item.index == 1) {
                   return false;
                  }
                }
                return true;
            },
            */            callbacks: {
                label: function(item, data) {
                    // get label and data
                    var labels = data.datasets[item.datasetIndex].labels;
                    var dataset = data.datasets[item.datasetIndex].data;
                    
                    var currentLabel = labels[item.index];
                    var currentValue = dataset[item.index];
                    
                    // calc percentage
                    var total = dataset.reduce(function(previousValue, currentValue, currentIndex, array) {
                        return previousValue + currentValue;
                    });
                    var percentage = ((currentValue/total) * 100);

                    // put label
                    return " " + currentLabel + ": " + currentValue + " (" + percentage.toFixed(1) + "%)";
                     
                }
            }
        },
    }
});

Aqui dejo el jsfiddle




Tecnologia

Chart.js: cómo añadir texto dentro de una grafica de tipo donut


A continuación te muestro cómo añadir texto dentro de una grafica de tipo donut en Chart.js

Chart.js es una libreria open source para crear gráficos en javascript basados en HTML5. Entre la amplia lista de gráficos disponibles de esta fantástica librería tenemos el donut (doughnut). Que básicamente es un gráfico de torta pero con un agujero en el centro … sorprendidos ¿verdad? 😉

Yo lo que quiero es aprovechar ese agujero del centro para añadir información, ya sea un simple texto o el total. Algo asi como los pop dots 😉

cómo añadir texto dentro de una grafica de tipo donut

Básicamente esto se consigue añadiendo un plugin e implementando el evento beforedraw. En mi ejemplo muestro el total pero podeis modificar el código para mostrar otra información.

Código HTML

<div id="mychart-holder">
    <canvas id="mychart"/>
</div>

Código Javascript

var data = {
    labels: ["Error", "Failure", "Success", "Skip", "Unknown"],
    datasets: [
        {
            data: [10, 5, 20, 2, 1],
            backgroundColor: ["red", "orange", "green", "blue", "violet"],
        }
    ]
};

var myChart = new Chart(document.getElementById('mychart'), {
    type: 'doughnut',
    data: data,
    options: {
        //cutoutPercentage: 50,
        maintainAspectRatio: true,
        responsive: true,
        legend: {
            display: false
        },
        animation: {
            animateScale: true,
            animateRotate: true
        },
    },
    plugins: [{
        id: 'total',
        beforeDraw: function(chart) {
            const width = chart.chart.width;
            const height = chart.chart.height;
            const ctx = chart.chart.ctx;
            ctx.restore();
            const fontSize = (height / 114).toFixed(2);
            ctx.font = fontSize + "em sans-serif";
            ctx.textBaseline = 'middle';
            var total = data.datasets[0].data.reduce(function(previousValue, currentValue, currentIndex, array) {
                return previousValue + currentValue;
            });
            const text = total;
            const textX = Math.round((width - ctx.measureText(text).width) / 2);
            const textY = height / 2;
            ctx.fillText(text, textX, textY);
            ctx.save();
        }
    }]
});

Aquí el código en jsfiddle

Si lo que queremos es utilizar el plugin en varias gráficas, entonces podemos registrar el plugin

Código Javascript (2)

var data = {
    labels: ["Error", "Failure", "Success", "Skip", "Unknown"],
    datasets: [
        {
            data: [10, 5, 20, 2, 1],
            backgroundColor: ["red", "orange", "green", "blue", "violet"],
        }
    ]
};

Chart.Chart.pluginService.register({
    beforeDraw: function(chart) {
        const width = chart.chart.width;
        const height = chart.chart.height;
        const ctx = chart.chart.ctx;
        ctx.restore();
        const fontSize = (height / 114).toFixed(2);
        ctx.font = fontSize + "em sans-serif";
        ctx.textBaseline = 'middle';
        var total = chart.data.datasets[0].data.reduce(function(previousValue, currentValue, currentIndex, array) {
                return previousValue + currentValue;
        });
        const text = total;
        const textX = Math.round((width - ctx.measureText(text).width) / 2);
        const textY = height / 2;
        ctx.fillText(text, textX, textY);
        ctx.save();
    },
});

var myChart = new Chart(document.getElementById('mychart'), {
    type: 'doughnut',
    data: data,
    options: {
        //cutoutPercentage: 50,
        maintainAspectRatio: true,
        responsive: true,
        legend: {
            display: false
        },
        animation: {
            animateScale: true,
            animateRotate: true
        },
    }
});

Aquí el código en jsfiddle