我试图将工作的饼图代码从简单的单个HTML文件复制到角度指令。 使用我的指令加载图表有效,但图表被截断。
代码有点长,所以附上codepen demonstration
JS代码:
var app = angular.module('chartApp', []);
app.controller('SalesController', ['$scope', function($scope){
$scope.salesData=[
{label: 'aa',value: 54},
{label: 'bb',value: 26},
{label: 'cc',value: 20}
];
}]);
app.directive('pieChart', function ($window) {
return {
restrict: 'EA',
template: "<svg></svg>",
link: function (scope, element, attr, ctrl) {
// render graph only when data avaliable
var data = scope[attr.chartData];
var w = 300,
h = 300 ;
var r = 150;
var d3 = $window.d3;
var color = d3.scale.category20(); //builtin range of colors
var svg = d3.select(element.find('svg')[0]);
svg.data([data])
.append('svg') //associate our data with the document
.attr("width", w) //set the width and height of our visualization (these will be attributes of the <svg> tag
.attr("height", h)
.append("svg:g")
//make a group to hold our pie chart
.attr("transform", "translate(" + r + "," + r + ")"); //move the center of the pie chart from 0, 0 to radius, radius
var arc = d3.svg.arc() //this will create <path> elements for us using arc data
.outerRadius(r);
var pie = d3.layout.pie() //this will create arc data for us given a list of values
.value(function(d) { return d.value; }); //we must tell it out to access the value of each element in our data array
var arcs = svg.selectAll("g.slice") //this selects all <g> elements with class slice (there aren't any yet)
.data(pie) //associate the generated pie data (an array of arcs, each having startAngle, endAngle and value properties)
.enter() //this will create <g> elements for every "extra" data element that should be associated with a selection. The result is creating a <g> for every object in the data array
.append("svg:g") //create a group to hold each slice (we will have a <path> and a <text> element associated with each slice)
.attr("class", "slice"); //allow us to style things in the slices (like text)
arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); } ) //set the color for each slice to be chosen from the color function defined above
.attr("d", arc); //this creates the actual SVG path using the associated data (pie) with the arc drawing function
arcs.append("svg:text") //add a label to each slice
.attr("transform", function(d) { //set the label's origin to the center of the arc
// we have to make sure to set these before calling arc.centroid
d.innerRadius = 0;
d.outerRadius = r;
return "translate(" + arc.centroid(d) + ")"; //this gives us a pair of coordinates like [50, 50]
})
.attr("text-anchor", "middle")
.style("font-size","20px")//center the text on it's origin
.text(function(d, i) { return data[i].label; }); //get the label from our original data array
}
};
});
HTML:
<div ng-app="chartApp" ng-controller="SalesController">
<h1>Chart</h1>
<div pie-chart chart-data="salesData"></div>
</div>
我已尝试添加填充和保证金,如here所示,但问题仍然存在。
有什么想法吗?
答案 0 :(得分:2)
您的代码存在以下问题:
请勿使用template: <svg></svg>
,因为稍后您会在其中插入另一个svg。简单地删除该行,以便将饼图插入当前div中。
您删除了第一个svg
元素后,将选择器从var svg = d3.select(element.find('svg')[0])
更改为var svg = d3.select(element[0])
。
最后,您需要将svg
定义链接起来,以便它将指向已包含已翻译g
的对象。现在定义svg
。然后,您附加了g
元素,稍后您附加了另一个g.slice
元素,该元素未放置在第一个g
内。
第3点的变化如下:
// From
var svg = d3.select(element[0]);
svg.data([data]) ...
// To
var svg = d3.select(element[0])
.data([data])
.append('svg') ...
以下是您codepen的一个分支,其中有一个工作示例。
祝你好运!