web-dev-qa-db-fra.com

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

J'utilise le plugin génial Chart.js , et j'essaie de trouver le moyen d'afficher des étiquettes dans chaque pourcentage. Alors je l'ai googlé, et j'ai trouvé ce pull: https://github.com/nnnick/Chart.js/pull/35

J'ai fait un simple violon pour le tester, mais cela ne fonctionne pas: http://jsfiddle.net/marianico2/7ktug/1/

Ceci est 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'
    });
});

Je crains qu'il n'y ait aucune information à ce sujet dans le documentation .

De plus, j'aimerais savoir comment afficher une étiquette pour chaque partie, mais en dehors du graphique. Relié par une ligne. Comme le font les cartes de highcharts.js .

En passant, je serais heureux si vous me recommandiez une alternative au tableau html5 qui inclut les options que j'ai mentionnées ci-dessus. J'ai entendu parler du plugin flot , mais je crains que cela ne supporte pas les animations ...

Si vous avez besoin de plus d'informations, faites le moi savoir et je vais éditer le post.

41
harrison4

Vous devrez ajouter du code à 2 endroits. Par exemple, prenez le beignet. Commencez par ajouter les informations de libellé aux valeurs par défaut (regardez le code original de Chart.js et comparez-le 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 beignet est dessiné et ajoutez les quatre lignes ctx.

    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);

Le ctx.fillTextappel va mettre le texte sur la toile, vous pouvez donc l'utiliser pour écrire du texte avec des coordonnées x, y. Vous devriez pouvoir utiliser cette méthode pour créer des étiquettes de base. Voici le jsfiddle avec lequel bricoler:

http://jsfiddle.net/nCFGL/ (regardez les lignes 281 et 772 dans la section JavaScript de jsfiddle pour le code susmentionné)

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

32
Jack

Celui-ci a pris littéralement des heures et des heures et j'ai trouvé une solution efficace.

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

C'était mon code final. J'essayais d'afficher des pourcentages sous forme d'étiquettes sur un beignet

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);
        }
     }
}
});
7
animesh manglik

J'ai trouvé un moyen pour que nous puissions afficher les valeurs de chaque région à l'extérieur du graphique.

Aussi j'ai enlevé la rotation des valeurs et je me suis référé à ici

Ajoutez les lignes de code suivantes dans la fonction Donut. (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 à l'extérieur de chaque section et il ne sera pas pivoté.

3
Sareesh

Il existe une version forkée, ChartNew , qui fournit cette fonctionnalité immédiatement.

Si vous devez utiliser ChartJS, vous pouvez utiliser cette version révisée 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);
    }
});
3
dunckr