HTML5 Canvas pie chart

前端 未结 4 1142
名媛妹妹
名媛妹妹 2020-12-05 07:30

I\'m attempting to create a simple pie chart like shown in the graphic below:

\"enter<

4条回答
  •  无人及你
    2020-12-05 07:43

    I like the previous answer, but I felt it was lacking in code clarity and it didn't really cover how to utilize labels.

    I moved the values into a data object array for easy declaration. Other values, like percentage, I explicitly declared as a property on the data object, or as a separate variable. This, I think, makes it easier to read.

    The refactoring also made it easier to tie the values to input boxes if that's something you're interested in.

    To see what I mean and play with the values check out this CodePen: http://codepen.io/zfrisch/pen/pRbZeb

      var data = [{
        label: "one",
        value: 100,
        color: 'white'
      }, {
        label: "two",
        value: 100,
        color: 'skyBlue'
      }, {
        label: "three",
        value: 100,
        color: 'yellow'
      }];
    
      var total = 0;
      for (obj of data) {
        total += obj.value;
      }
    
      var canvas = document.getElementById('myCanvas');
      var ctx = canvas.getContext('2d');
      var previousRadian;
      var middle = {
        x: canvas.width / 2,
        y: canvas.height / 2,
        radius: canvas.height / 2,
      };
      
       //background
      ctx.beginPath();
      ctx.arc(middle.x, middle.y, middle.radius, 0, 2 * Math.PI);
      ctx.closePath();
      ctx.stroke();
      ctx.fillStyle = "black";
      ctx.fill();
       //end of background
    
      for (obj of data) {
        previousRadian = previousRadian || 0;
        obj.percentage = parseInt((obj.value / total) * 100)
        
        ctx.beginPath();
        ctx.fillStyle = obj.color;
        obj.radian = (Math.PI * 2) * (obj.value / total);
        ctx.moveTo(middle.x, middle.y);
        //middle.radius - 2 is to add border between the background and the pie chart
        ctx.arc(middle.x, middle.y, middle.radius - 2, previousRadian, previousRadian + obj.radian, false);
        ctx.closePath();
        ctx.fill();
        ctx.save();
        ctx.translate(middle.x, middle.y);
        ctx.fillStyle = "black";
        ctx.font = middle.radius / 10 + "px Arial";
        ctx.rotate(previousRadian + obj.radian);
        var labelText = "'" + obj.label + "' " + obj.percentage  + "%";
        ctx.fillText(labelText, ctx.measureText(labelText).width / 2, 0);
        ctx.restore();
    
        previousRadian += obj.radian;
      }

提交回复
热议问题