Inserting percentage charts.js doughnut

前端 未结 4 636
失恋的感觉
失恋的感觉 2021-02-06 08:39

i\'m, using charts.js librarie and would like to know how could I add some mark to the hole of a doughnut chart (sth like a percentage)-

相关标签:
4条回答
  • 2021-02-06 09:05

    enter image description here

    The donut chart is centered in the canvas, so you can calculate the center of the donut like this:

    // get the canvas element and its context
    var canvas = document.getElementById("myChart");
    var ctx = canvas.getContext("2d");
    
    // calculate the center of the canvas (cx,cy)
    var cx=canvas.width/2;
    var cy=canvas.height/2;
    

    Then you can tell canvas to draw text vertically & horizontally centered around cx,cy like this:

    // horizontally align text around the specified point (cx)
    ctx.textAlign='center';
    
    // vertically align text around the specified point (cy)
    ctx.textBaseline='middle';
    
    // draw the text
    ctx.font='14px verdana';
    ctx.fillStyle='black';
    ctx.fillText("Text Here",cx,cy);
    

    But you must wait for any animations to complete before drawing your centered text.

    To do that you must tell ChartJS that you want a callback function triggered when it completes its animation. You can set the callback by setting the onAnimationComplete property of the chart options:

    var myDoughnutChart = new Chart(ctx).Doughnut(data, {
        responsive : true,
    
        // when ChartJS has completed all animations then call the addText function
        onAnimationComplete: addText
    });
    

    Here's a demo putting it all together:

    var doughnutData = [{
        value: 300,
        color: "#F7464A",
        highlight: "#FF5A5E",
        label: "Red"
      }, {
        value: 50,
        color: "#46BFBD",
        highlight: "#5AD3D1",
        label: "Green"
      }, {
        value: 100,
        color: "#FDB45C",
        highlight: "#FFC870",
        label: "Yellow"
      }, {
        value: 40,
        color: "#949FB1",
        highlight: "#A8B3C5",
        label: "Grey"
      }, {
        value: 120,
        color: "#4D5360",
        highlight: "#616774",
        label: "Dark Grey"
      }
    
    ];
    
    window.onload = function() {
      var canvas = document.getElementById("chart-area");
      var ctx = document.getElementById("chart-area").getContext("2d");
      window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {
        responsive: true,
        onAnimationComplete: addText
      });
    
    };
    
    var myDoughnutChart = new Chart(ctx).Doughnut(data);
    var myDoughnutChart = new Chart(ctx).Doughnut(doughnutData, {
      responsive: true,
      onAnimationComplete: addText
    });
    
    
    function addText() {
    
      var canvas = document.getElementById("chart-area");
      var ctx = document.getElementById("chart-area").getContext("2d");
    
      var cx = canvas.width / 2;
      var cy = canvas.height / 2;
    
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.font = '14px verdana';
      ctx.fillStyle = 'black';
      ctx.fillText("Text Here", cx, cy);
    
    }
    body {
      padding: 10px;
      margin: 0;
    }
    #canvas-holder {
      width: 30%;
    }
    canvas {
      border: 1px solid red;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.1/Chart.min.js"></script>
    <div id="canvas-holder">
      <canvas id="chart-area" width="500" height="500" />
    </div>

    0 讨论(0)
  • 2021-02-06 09:05

    A pure css solution

    .overview-total {
      position: relative;
    
      .overview-num{
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }
    }
    

    Html

    <div class="overview-total">
       <span class="overview-num">140</span>
       <canvas baseChart class="chart-size" width="300" height="180"
                          [plugins]="doughnutChartPluginsSo"
                          [colors]="doughnutChartColorsSo"
                          [data]="doughnutChartDataSo"
                          [labels]="doughnutChartLabelsSo"
                          [chartType]="doughnutChartTypeSo"
                          [options]="doughnutChartOptionsSo"></canvas>
    </div>
    
    0 讨论(0)
  • 2021-02-06 09:06

    Draw method creates the canvas for chart. On hover draw method is called to re-create the chart and show the tool-tip. Text disappears because there is no code to show text inside draw method as we are adding text manually outside of API.

    You can achieve this by extending the chart. Follow Docs here.

    Following is the example of adding total records at the centre of the doughnut chart.

    Chart.defaults.derivedDoughnut = Chart.defaults.doughnut;
    var customDoughnut = Chart.controllers.doughnut.extend({
      draw: function(ease) {
        Chart.controllers.doughnut.prototype.draw.apply(this, [ease]);
        var width = this.chart.chart.width,
          height = this.chart.chart.height;
        var total = this.getMeta().total;
        var fontSize = (height / 114).toFixed(2);
        var ctx = this.chart.chart.ctx;
        ctx.font = fontSize + "em Verdana";
        ctx.textBaseline = "middle";
        var text = total,
          textX = Math.round((width - ctx.measureText(text).width) / 2),
          textY = height / 2;
    
        ctx.fillText(text, textX, textY);
      }
    });
    Chart.controllers.derivedDoughnut = customDoughnut;
    

    Example: jsfiddle

    0 讨论(0)
  • 2021-02-06 09:16

    I think the accepted answer does not work, at least for me. Here is my solution:

    let canvas = document.getElementById('chart-area');
    let ctx = canvas.getContext('2d');
    let perc = 25;
    
    const config = {
        type: 'doughnut',
        data: {
            datasets: [{
                data: [
                    perc,
                    100-perc
                ],
                backgroundColor: [
                    window.chartColors.green,
                    window.chartColors.gray
                ]
            }]
        },
        options: {
            responsive: true,
            animation: {
                animateScale: true,
                animateRotate: true,
                onComplete : function() {
                    var cx = canvas.width / 2;
                    var cy = canvas.height / 2;
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.font = '16px verdana';
                    ctx.fillStyle = 'black';
                    ctx.fillText(perc+"%", cx, cy);
                }
            },
        }
    };
    
    new Chart(ctx, config);
    
    0 讨论(0)
提交回复
热议问题