41 votes

Comment ajouter des étiquettes dans le plugin Chart.js canvas ?

J'utilise l'excellent plugin Chart.js et j'essaie de trouver le moyen d'afficher les étiquettes dans chaque pourcentage. J'ai donc cherché sur Google, et j'ai trouvé cette tirette : https://github.com/nnnick/Chart.js/pull/35

J'ai fait un simple bidouillage pour le tester, mais ça ne marche pas : http://jsfiddle.net/marianico2/7ktug/1/

Voici le contenu :

HTML

<canvas id="canvas" height="450" width="450"></canvas>

JS

$(document).ready(function () {
    var pieData = [{
        value: 30,
        color: "#F38630",
        label: 'HELLO',
        labelColor: 'black',
        labelFontSize: '16'
    }, {
        value: 50,
        color: "#E0E4CC"
    }, {
        value: 100,
        color: "#69D2E7"
    }];

    var myPie = new Chart(document.getElementById("canvas").getContext("2d")).Pie(pieData, {
        labelAlign: 'center'
    });
});

J'ai bien peur qu'il n'y ait pas d'informations à ce sujet dans l'annuaire de l'entreprise. documentation .

J'aimerais également savoir comment afficher une étiquette pour chaque portion, mais en dehors du graphique. Relié par une ligne. Comme le font les graphiques de highcharts.js .

À propos, je serais heureux si vous me recommandiez une alternative de graphique html5 qui inclut les options que j'ai mentionnées ci-dessus. J'ai entendu parler de la flot mais je crains qu'il ne supporte pas les animations...

Si vous avez besoin de plus d'informations, faites-le moi savoir et je modifierai le message.

32voto

Jack Points 816

Vous devrez ajouter du code à deux endroits. Prenons l'exemple du beignet. Tout d'abord, ajoutez des informations sur les étiquettes aux valeurs par défaut (regardez le code original de Chart.js et comparez avec celui-ci) :

    chart.Doughnut.defaults = {
        segmentShowStroke : true,
        segmentStrokeColor : "#fff",
        segmentStrokeWidth : 2,
        percentageInnerCutout : 50,
        animation : true,
        animationSteps : 100,
        animationEasing : "easeOutBounce",
        animateRotate : true,
        animateScale : false,
        onAnimationComplete : null,
        labelFontFamily : "Arial",
        labelFontStyle : "normal",
        labelFontSize : 24,
        labelFontColor : "#666"
    };

Ensuite, descendez à l'endroit où le Doughnut est dessiné et ajoutez les quatre ctx lignes.

    animationLoop(config,null,drawPieSegments,ctx);

    function drawPieSegments (animationDecimal){
        ctx.font = config.labelFontStyle + " " + config.labelFontSize+"px " + config.labelFontFamily;
        ctx.fillStyle = 'black';
        ctx.textBaseline = 'middle';
        ctx.fillText(data[0].value + "%", width/2 - 20, width/2, 200);

El ctx.fillText placera le texte sur le canevas, de sorte que vous pouvez l'utiliser pour écrire du texte avec des coordonnées x,y. Vous devriez être capable d'utiliser cette méthode pour faire des étiquettes de base. Voici le jsfiddle pour bricoler : http://jsfiddle.net/nCFGL/

Si vous avez besoin de quelque chose de plus sophistiqué, quelqu'un a bifurqué vers une version de Charts.js et y a ajouté des infobulles. Voici la discussion https://github.com/nnnick/Chart.js/pull/35 et vous pourrez trouver le lien vers la version forked dans cette discussion.

7voto

animesh manglik Points 757

Celle-ci a littéralement pris des heures et des heures et j'ai trouvé une solution qui fonctionne.

https://github.com/nnnick/Chart.js/pull/116

C'était mon code final. J'ai essayé d'afficher les pourcentages comme des étiquettes sur les beignets.

Chart.types.Doughnut.extend({
name: "DoughnutAlt",
draw: function() {
    Chart.types.Doughnut.prototype.draw.apply(this, arguments);
    this.chart.ctx.fillStyle = 'black';
    this.chart.ctx.textBaseline = 'middle';
    this.chart.ctx.textAlign = 'start';
    this.chart.ctx.font="18px Verdana";

    var total = 0;
    for (var i = 0; i < this.segments.length; i++) { 
        total += this.segments[i].value;      
    }

    this.chart.ctx.fillText(total , this.chart.width / 2 - 20, this.chart.height / 2, 100);
    for(var i = 0; i < this.segments.length; i++){
        var percentage = ((this.segments[i].value / total) * 100).toFixed(1);
        if( percentage > 3 ){
            var centreAngle = this.segments[i].startAngle + ((this.segments[i].endAngle - this.segments[i].startAngle) / 2),
                rangeFromCentre = (this.segments[i].outerRadius - this.segments[i].innerRadius) / 2 + this.segments[i].innerRadius;
            var x = this.segments[i].x + (Math.cos(centreAngle) * rangeFromCentre);
            var y = this.segments[i].y + (Math.sin(centreAngle) * rangeFromCentre);
            this.chart.ctx.textAlign = 'center';
            this.chart.ctx.textBaseline = 'middle';
            this.chart.ctx.fillStyle = '#fff';
            this.chart.ctx.font = 'normal 10px Helvetica';
            this.chart.ctx.fillText(percentage , x, y);
        }
     }
}
});

3voto

Sareesh Points 21

J'ai trouvé un moyen d'afficher les valeurs de chaque région en dehors du graphique.

J'ai également supprimé la rotation des valeurs et je me suis référé au lien ci-dessous.

https://github.com/nnnick/Chart.js/pull/116

Ajoutez les lignes de code suivantes à l'intérieur de la fonction Doughnut. ( J'ai collé les lignes modifiées du fichier Chart.js).

    var Doughnut = function(data,config,ctx){

    var segmentTotal = 0;

    //In case we have a canvas that is not a square. Minus 10 pixels as padding round the edge.
    var doughnutRadius = Min([height/2,width/2]) - 15;
    var cutoutRadius = doughnutRadius * (config.percentageInnerCutout/100);
    //Modified for setting the label values out side the arc
    var outRadius= doughnutRadius + cutoutRadius/3;
    var outRadiustop= doughnutRadius + cutoutRadius/5;
    ......
    ......
    ......

    function drawPieSegments (animationDecimal){
    :
    :

       if (config.scaleShowValues) {
                ctx.save();                
                ctx.translate(width / 2, height / 2);
                ctx.font = config.scaleFontStyle + ' ' + config.scaleFontSize + 'px ' + config.scaleFontFamily;
                ctx.textBaselne = 'middle';
                var a = (cumulativeAngle + cumulativeAngle + segmentAngle) / 2,
                    w = ctx.measureText(data[i].value).width,
                    b = Math.PI / 2 < a && a < Math.PI * 3 / 2;
                var c  = 0 < a && a < Math.PI;
                if(b){
                    ctx.textAlign = 'right';
                }
                else{
                    ctx.textAlign = 'left';
                }
                if(c){
                    ctx.translate(Math.cos(a) * outRadius +1 , Math.sin(a) * outRadius+1);

                }
                else{
                    ctx.translate(Math.cos(a) * outRadiustop, Math.sin(a) * outRadiustop);      
                }

                ctx.fillStyle = config.scaleFontColor;
                //If the segment angle less than 0.2, then the lables will overlap, so hiding it.
                if(segmentAngle > 0.2){
                    ctx.fillText(data[i].value,0,0);

                }
                ctx.restore();
     }

     ......
     ...... 

Maintenant, les valeurs seront affichées à côté de chaque section et ne seront pas tournées.

3voto

dunckr Points 1

Il existe une version forked, GraphiqueNouveau qui fournit cette fonctionnalité d'emblée.

Si vous devez utiliser ChartJS, vous pouvez utiliser cette version révisée de la solution de @Jack. de la solution de @Jack :

Chart.types.Doughnut.extend({ name: "DoughnutAlt", draw: function() { Chart.types.Doughnut.prototype.draw.apply(this, arguments); this.chart.ctx.fillStyle = 'black'; this.chart.ctx.textBaseline = 'middle'; this.chart.ctx.fillText(this.segments[0].value + "%", this.chart.width / 2 - 20, this.chart.width / 2, 200); } });

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X