I'm new to D3. Trying to show "outside" labels with lines, in D3, similar to Bostock's pie chart here http://bl.ocks.org/dbuezas/9306799 I can't get the labels or lines to show up like Bostock's pie. The pie is working well though! Any help with my code, mainly the directive, would be appreciated!
我是D3的新手。试图在D3中显示带有线条的“外部”标签,类似于Bostock的饼图http://bl.ocks.org/dbuezas/9306799我无法获得像Bostock馅饼那样的标签或线条。馅饼虽然运作良好!任何有关我的代码的帮助,主要是指令,将不胜感激!
HTML:
<div ng-controller="myControl">
<d3-pie-dir data="d3Data"></d3-pie-dir>
</div>
CSS:
path.slice{
stroke-width:2px;
}
polyline{
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
Controller:
inAng.controller('myControl', function ( $scope, $http ) {
var stack = [];
$http.get("/getAPIData").
success(function (data, status, headers, config) {
// formatting for easier D3 consumption
for(var i in data)
stack.push(data [i]);
$scope.d3Data = stack;
// looks something like $scope.d3Data = [{ name: 'Bill', score: 25}, { name: 'Pete', score: 50}]
}).
error(function (data, status, headers, config) {
$scope.stack = 'Error!';
});
});
And the problem is in the directive:
问题出在指令中:
inAng.directive('d3PieDir', function () {
return {
restrict: 'E',
scope: {
data: '='
},
link: function (scope, element, attrs) {
scope.$watch('data', function(values) {
if(values) {
console.log('values from directive: ', values);
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.score;
});
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
values.forEach(function(d) {
d.score = +d.score;
});
var g = svg.selectAll(".arc")
.data(pie(values))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.name); });
// **** Below is where it stops working! ****
var key = function(d){ return d.data.name; };
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(values), key);
slice.enter()
.insert("path")
.style("fill", function(d) { return color(d.data.name); })
.attr("class", "slice");
slice
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(values), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.name;
});
function midAngle(d){
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate("+ pos +")";
};
})
.styleTween("text-anchor", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start":"end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(values), key);
polyline.enter()
.append("polyline");
polyline.transition().duration(1000)
.attrTween("points", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline.exit()
.remove();
}
})}
}});
1 个解决方案
#1
1
You have two problems the first one is that you forgot to append these elements to your svg
你有两个问题,第一个是你忘了将这些元素附加到你的svg
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
these are the g elements that d3 draws lines and labels on , so you need to put them after
这些是d3绘制线条和标签的g元素,因此您需要将它们放在后面
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
,, the second issue is that you forgot to define outer arc ,,
,,第二个问题是你忘了定义外弧,
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
which you use in your calculation for creating lines
您在计算中用于创建线条
#1
1
You have two problems the first one is that you forgot to append these elements to your svg
你有两个问题,第一个是你忘了将这些元素附加到你的svg
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
these are the g elements that d3 draws lines and labels on , so you need to put them after
这些是d3绘制线条和标签的g元素,因此您需要将它们放在后面
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
,, the second issue is that you forgot to define outer arc ,,
,,第二个问题是你忘了定义外弧,
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
which you use in your calculation for creating lines
您在计算中用于创建线条