小提琴:https://jsfiddle.net/vpkarep8/D3:在更新重新定位饼图标签
我有三个饼图与新的数据更新时的动画,我似乎无法得到标签正确地更新。上面附上小提琴。
为了让文字发生变化,我不得不对文本进行另一个数据连接(第486-489行),但后来我无法使用arc.centroid()。将其缩小到我如何处理更新,但不知道处理所有这些问题的最佳方法。似乎质心需要d,但更新文本需要d.values。
有什么想法?
试过Label outside arc (Pie chart) d3.js和How to update both the content and location of text labels on a D3 pie chart的答案。
function drawESGraph() {
d3.selectAll('.ES__graph__container svg')
.remove();
d3.selectAll('.ES__buttons button')
.remove();
var $container = $('.ES__graph__container');
var width = $container.width()/3;
var m = 40,
r = width/3,
labelr = r + 20;
var arc = d3.svg.arc()
.outerRadius(r)
.innerRadius(r/2);
var pie = d3.layout.pie()
.value(function(d) {
return +d.val;
})
.sort(null);
var allBrands = d3.set(data.map(function(d) {
return d.brand;
})).values();
var buttons = d3.select('.ES__buttons')
.selectAll('button')
.data(allBrands)
.enter()
.append('button')
.attr('class', function(d) {
return d + ' button';
})
.text(function(d) {
return d;
})
.on('click', function(d) {
updateChart(d);
})
.style('opacity', 0);
buttons.transition().duration(1000)
.style('opacity', 1);
d3.select('.brand1.button')
.attr('class', 'brand1 button active');
function updateChart(brand) {
var brandData = data.filter(function(d) {
return d.brand === brand;
});
var brandDataByYear = d3.nest()
.key(function(d) {
return d.year;
})
.entries(brandData);
var svg = d3.select('.ES__graph__container')
.selectAll('svg')
.data(brandDataByYear)
.enter()
.append('svg')
.style('margin-top', '25px')
.attr('width', (r + m) * 2)
.attr('height', (r + m) * 2)
.attr('id', function(d, i) {
return 'pie' + i;
})
.append('svg:g')
.attr('transform', 'translate(' + (r + m) + ',' + (r + m) + ')');
var pieLabel = svg.append('svg:text')
.attr('dy', '.35em')
.attr('text-anchor', 'middle')
.text(function(d) {
return d.key;
})
.style('fill', 'black')
.style('opacity', 0);
pieLabel.transition().duration(1000)
.style('opacity', 1);
var slice = svg.selectAll('.arc')
.data(function(d) {
return pie(d.values);
})
.enter()
.append('g')
.attr('class', 'arc');
var path = slice.append('svg:path')
.attr('d', arc)
.attr('class', function(d) {
return 'arc ' + d.data.platform;
})
.each(function(d) {
this._current = d;
});
var text = slice.append('text')
.text(function(d) {
if (d.data.val > 0) {
return d.data.val + '%';
}
})
.attr('transform', function(d) {
if (d.data.val > 3) {
return 'translate(' + arc.centroid(d) + ')';
} else {
var c = arc.centroid(d),
x = c[0],
y = c[1],
h = Math.sqrt(x * x + y * y);
return 'translate(' + (x/h * labelr) + ',' + (y/h * labelr) + ')';
}
})
.attr('text-anchor', function(d) {
if (d.data.val < 3) {
return (d.endAngle + d.startAngle)/2 > Math.PI ? 'end' : 'start';
}
})
.attr('dx', function(d) {
return d.data.val > 3 ? -15 : 18;
})
.attr('dy', function(d) {
return d.data.val > 3 ? 5 : 3;
})
.style('fill', function(d) {
return d.data.val > 3 ? 'white' : 'black';
})
.attr('class', 'label');
change();
function change() {
var newdata = brandDataByYear;
for (x in newdata) {
var nslice = d3.select('#pie' + x)
.data(newdata);
var npath = nslice.selectAll('path')
.data(function(d) {
return pie(d.values);
})
.attr('class', function(d) {
return 'arc ' + d.data.platform;
});
npath.transition().duration(1000)
.attrTween('d', arcTween);
npath.exit()
.remove();
var ntext = nslice.selectAll('.label')
.data(function(d) {
return d.values;
})
.style('opacity', 0);
ntext.transition().duration(1000)
.style('opacity', 1)
.text(function(d) {
if (d.val > 0) {
return d.val + '%';
}
})
// .attr("transform", function(d) {
// return "translate(" +
// ((radius - 12) * Math.sin(((d.endAngle - d.startAngle)/2) + d.startAngle)) +
// ", " +
// (-1 * (radius - 12) * Math.cos(((d.endAngle - d.startAngle)/2) + d.startAngle)) +
// ")";
// })
// .style("text-anchor", function(d) {
// var rads = ((d.endAngle - d.startAngle)/2) + d.startAngle;
// if ((rads > 7 * Math.PI/4 && rads < Math.PI/4) || (rads > 3 * Math.PI/4 && rads < 5 * Math.PI/4)) {
// return "middle";
// } else if (rads >= Math.PI/4 && rads <= 3 * Math.PI/4) {
// return "start";
// } else if (rads >= 5 * Math.PI/4 && rads <= 7 * Math.PI/4) {
// return "end";
// } else {
// return "middle";
// }
// })
// ntext.exit()
// .remove();
}
}
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
}
}
}
updateChart('brand1');
}
drawESGraph();
这是完全一样的问题,因为在第二个问题,你'我l签署。你不更新绑定到'text'元素的数据。 –