5
respostas

Chart.js - Texto dinâmico no meio do gráfico

Boa Tarde,

Estou usando o Chart.js para fazer gráficos de dounagth, porém, para colocar o valor no meio do gráfico tive de utilizar um plug-in. No entanto, quando as opções de Label são desmarcadas, o valor no meio do gráfico não muda.

Por exemplo, Tenho 3 labels ( A=100, B= 100, C= 300)

O valor que aparece no centro é 500 que é o total, mas quando desmarco qualquer um dos labels, o valor continua em 500, ele não retira o valor desmarcado.

Alguém saberia me ajudar??

Segue o código:

-------JS------

Chart.pluginService.register({ beforeDraw: function (chart) { if (chart.config.options.elements.center) { //Get ctx from string var ctx = chart.chart.ctx;

        //Get options from the center object in options
var centerConfig = chart.config.options.elements.center;
  var fontStyle = centerConfig.fontStyle || 'Arial';
        var txt = centerConfig.text;
var color = centerConfig.color || '#000';
var sidePadding = centerConfig.sidePadding || 20;
var sidePaddingCalculated = (sidePadding/100) * (chart.innerRadius * 2)
//Start with a base font of 30px
ctx.font = "30px " + fontStyle;

        //Get the width of the string and also the width of the element minus 10 to give it 5px side padding
var stringWidth = ctx.measureText(txt).width;
var elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated;

// Find out how much the font can grow in width.
var widthRatio = elementWidth / stringWidth;
var newFontSize = Math.floor(30 * widthRatio);
var elementHeight = (chart.innerRadius * 2);

// Pick a new font size so it will not be larger than the height of label.
var fontSizeToUse = Math.min(newFontSize, elementHeight);

        //Set font settings to draw it correctly.
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
ctx.font = fontSizeToUse+"px " + fontStyle;
ctx.fillStyle = color;

//Draw text in center
ctx.fillText(txt, centerX, centerY);
    }
}

});

var config = {
    type: 'doughnut',
    data: {
        labels: [
          "Red",
          "Green",
          "Yellow"
        ],
        datasets: [{
            data: [300, 50, 100],
            backgroundColor: [
              "#FF6384",
              "#36A2EB",
              "#FFCE56"
            ],
            hoverBackgroundColor: [
              "#FF6384",
              "#36A2EB",
              "#FFCE56"
            ]
        }]
    },
options: {
    elements: {
        center: {
            text: '90,0 bi',
  color: '#FF6384', // Default is #000000
  fontStyle: 'Arial', // Default is Arial
  sidePadding: 20 // Defualt is 20 (as a percentage)
        }
    }
}

}; var dnt1 = document.getElementById("dnt-1").getContext("d2");

var myChart = new Chart(dnt1, config);

-----HTML-----

<canvas id="myChart" width="900" height="550"></canvas>  

Fonte do plug in: http://jsfiddle.net/nkzyx50o/

5 respostas

Fala ai William, tudo bem? Dei uma olhada no seu exemplo e obrigado por compartilhar o projeto, isso ajuda muito.

O problema é que o valor do centro, ou seja, os 90% são definidos de forma fixa:

options: {
            elements: {
                center: {
                    text: '90%',
          color: '#FF6384', // Default is #000000
          fontStyle: 'Arial', // Default is Arial
          sidePadding: 20 // Defualt is 20 (as a percentage)
                }
            }
        }

Para que o valor seja atualizado dinamicamente, você precisaria fazer esse ajuste com JavaScript e adicionar alguns listeners.

Ou seja, quando clicar em alguma label ou filtro, você precisaria atualizar esse valor.

Espero ter ajudado.

Então,

Acho que não me expliquei direito então. Eu sei que está fixo em text: '90%',

O que quero saber é como deixar esse valor dinâmico junto com as seleções do gráfico.

No gráfico você pode escolher entre 3 cores para aparecerem, no entanto, quando tiro a seleção de uma das cores, como faria para o valor mudar?

Esse é o problema.

Exemplo,

https://drive.google.com/file/d/1u95s4H2y0G4qa6ELttGVoQRGQ1cVmhl4/view?usp=sharing

Quero uma forma que o valor acompanhe os valores das legendas que aparecem, e não somente o total: https://drive.google.com/file/d/13H6hrVy7kpagY4WJTecjFB0OX9-TAIec/view?usp=sharing

Tentei adicionar os "listeners" e não consegui, Alguma ideia?

Fala ai William, tudo bem? Dá uma olhada nesse exemplo:

https://jsfiddle.net/mahenrique94/0gxoqktd/

Repare que ao clicar no botão o título do gráfico e seus conteúdos são atualizados, a ideia seria algo mais ou menos nesse caminho.

Espero ter ajudado.