使用 angular directive 和 json 数据 D3 随着标签 donut chart演示样本

使用angular resource载入中priorityData.json中间json数据,结合D3绘制甜甜圈图。执行index.html其结果见于图。:


priorityData.json中json数据例如以下:

{  
   "priority":{  
      "Blocker":12,
      "Critical":18,
      "Major":5,
      "Minor":30,
      "Trivial":24
   }
}


index.html代码例如以下:

<!DOCTYPE html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-resource.min.js"></script>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body ng-app="myApp" ng-controller=MainCtrl>

		<li ng-repeat="(priority, val) in priorityData">
			<span >{{priority}}</span>
			<span >{{val}}</span>
		</li>
  <priority-graph data="priorityData"></priority-graph>
  
  <script>
var myApp = angular.module('myApp', ['ngResource']);
//define app factory
myApp.factory('DataFac',function($resource){
	return $resource('priorityData.json',{});
});

//define app controller
myApp.controller('MainCtrl',function($scope,DataFac){
	DataFac.get(function(response){
		$scope.priorityData = response.priority;		
	})
});

//define app directive
myApp.directive('priorityGraph', function(){
	  function link(scope, el, attr){
          //set graph width,height and radius
		  var width=960,
		  height=500,
		  radius=Math.min(width,height)/2;
		  //set color range
		  var color=d3.scale.ordinal().range(["rgb(166,60,48)", "rgb(229,144,78)", " rgb(221,226,77)", "rgb(157,211,72)", "rgb(40,106,151)"]);
		  //set outer radius and inner radius for donut chart
		  var arc=d3.svg.arc()
		  .outerRadius(radius-80)
		  .innerRadius(radius-150);
		
		  //watch data change from json
	      scope.$watch('data', function(data){
	      if(!data){ return; }
	      //change json to two arrays for category and count
	      //count array
			var countArr=[];
	      //category array
			var categoryArr=[];
		  //total number of issues
	        var total=0;
		  
			for (key in data){
				if(data.hasOwnProperty(key)){
					categoryArr.push(key);
					countArr.push(data[key]);
					total+=data[key];
				}
			}
	      //get the graph parent element
		   el = el[0];
	      // remove the graph if already exist, in case of repeat
		  d3.select( el ).select( 'svg' ).remove();
	      
	      var pie=d3.layout.pie()
	      .sort(null)
	      .value(function(d){return d});
	      
	      var svg=d3.select(el).append("svg")
	    		  .attr("width",width)
	    		  .attr("height",height)
	    		  .append("g")
	    		  .attr("transform","translate("+width/2+","+height/2+")");
	      
		  var g=svg.selectAll(".arc")
		  .data(pie(countArr))
		  .enter().append("g")
		  .attr("class","arc");
		  
		  //paint the grah
		  g.append("path")
		  .attr("d",arc)
		  .style("fill",function(d,i){return color(i);});
		  
		  //paint the text
		  g.append("text")
		  .attr("transform",function(d){return "translate("+arc.centroid(d)+")";})
		  .attr("dy",".35em")
		  .style("text-anchor","middle")
		  .text(function(d,i){return categoryArr[i]+":"+countArr[i]});
		  
		  //paint total number in the middle of graph
		  g.append("text")
	      .attr("dy", ".35em")
	      .style("text-anchor", "middle")
	      .text(function(d) { return total+" tickets"; });
	    }, true);
	  }
	  return {
	    link: link,
	    restrict: 'E',
	    scope: { data: '=' }
	  };
	});
  </script>
</body>
</html>




原文地址:https://www.cnblogs.com/zfyouxi/p/5047147.html