【发布时间】:2016-03-22 23:07:14
【问题描述】:
小提琴:https://jsfiddle.net/vpkarep8/
我有三个饼图在更新新数据时会显示动画,但我似乎无法正确更新标签。上面附有小提琴。
要更改文本,我不得不对文本进行另一个数据连接(第 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();
【问题讨论】:
-
这与您链接到的第二个问题完全相同。您没有更新绑定到
text元素的数据。
标签: javascript d3.js charts