Pie chart progress bar in AngularJS

Based on: Simple pie chart progress bar in canvas element

HTML:

<style>
.chart {
  position:relative;
  margin:80px;
  width:220px;
  height:220px;
}
.chart > canvas {
  display:block;
  position:absolute;
  top:0;
  left:0;
}
.chart > span {
  color:#555;
  display:block;
  line-height:220px;
  text-align:center;
  width:220px;
  font-family:sans-serif;
  font-size:40px;
  font-weight:100;
  margin-left:5px;
}
</style>

<body ng-controller="MainCtrl">
  <div class="chart" pie-chart-progress-bar="Percent"></div>
</body>

AngularJS controller and directive:

app.controller('MainCtrl', function($scope, $timeout) {
  $scope.Percent = 0;
  var Count = function() {
      $scope.Percent++;
      
      if($scope.Percent < 100) {
          $timeout(Count, 10);
      }
  };
  Count();
});


app.directive('pieChartProgressBar', function() {
  return {
    restrict: 'A',
    scope: {
        percent: "=pieChartProgressBar"
    },
    link: function (scope, elem, attr, ctrl) {
      var el = elem[0];
      var options = {
        size: 220,
        lineWidth: 15,
        rotate: 0
      };

      var canvas = document.createElement('canvas');
      var span = document.createElement('span');

      if (typeof(G_vmlCanvasManager) !== 'undefined') {
        G_vmlCanvasManager.initElement(canvas);
      }

      var ctx = canvas.getContext('2d');
      canvas.width = canvas.height = options.size;

      el.appendChild(span);
      el.appendChild(canvas);

      ctx.translate(options.size / 2, options.size / 2);
      ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);

      var radius = (options.size - options.lineWidth) / 2;

      var drawCircle = function(color, lineWidth, percent) {
        percent = Math.min(Math.max(0, percent || 1), 1);
        ctx.beginPath();
        ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
        ctx.strokeStyle = color;
        ctx.lineCap = 'round'; // butt, round or square
        ctx.lineWidth = lineWidth;
        ctx.stroke();
      };

      drawCircle('#efefef', options.lineWidth, 100 / 100);

      scope.$watch('percent', function(value) {
        span.innerText = value + '%';
        drawCircle('#555555', options.lineWidth, value / 100);
      });
  
    }
  }
});

live preview

Advertisements