问题描述
尽管围绕这个话题已经有很多问题,但我仍然无法回答。
我正在绘制这样的圆环图:
const svg = d3.select(svgRef.current);
const size = 500;
const radius = size / 2;
;
svg.attr("viewBox",[-size / 2,-size / 2,size,size]);
const pie = d3.pie()
.padAngle(0.02)
.sort(null)
.value(d => d.value);
const arc = d3.arc()
.innerRadius(radius * 0.67)
.outerRadius(radius - 1);
const color = d3.scaleOrdinal()
.domain(data.map(d => d.name))
.range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1),data.length).reverse());
const arcs = pie(data);
svg.selectAll("path")
.data(arcs)
.join("path")
.attr("fill",d => color(d.data.name))
.transition()
.delay((_,i) => i * 500)
.duration(500)
.attrTween('d',(d) => {
const i = d3.interpolate(d.startAngle+0.1,d.endAngle);
return (t) => {
d.endAngle = i(t);
return arc(d)
}
});
图表按预期进行动画处理。问题是:我希望细分在悬停时扩展一点。我该怎么做?
.on('mouSEOver',...)
到底去哪儿了?我知道我需要另一个 attrTween,但我不知道如何。
非常感谢!
编辑:
我现在找到了一种方法,但我仍然想知道是否有更好的方法来做到这一点?
const svg = d3.select(svgRef.current);
const size = 500;
const radius = size / 2;
;
svg.attr("viewBox",size]);
const pie = d3.pie()
.padAngle(0.02)
.sort(null)
.value(d => d.value);
const initialArc = d3.arc()
.innerRadius(radius * 0.67)
.outerRadius(radius - 20);
const transformedArc = d3.arc().innerRadius(radius * 0.67);
const color = d3.scaleOrdinal()
.domain(data.map(d => d.name))
.range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1),data.length).reverse());
const arcs = pie(data);
function arcTween(nextOuterRadius,currentOuterRadius) {
return function() {
d3.select(this).transition().duration(500).attrTween("d",function(d) {
const i = d3.interpolate(currentOuterRadius,nextOuterRadius);
return (t) => { d.outerRadius = i(t); return transformedArc(d); };
});
};
}
svg.selectAll("path")
.data(arcs)
.join("path")
.attr("fill",d => color(d.data.name))
.on("mouSEOver",arcTween(radius,radius - 20))
.on('mouSEOut',arcTween(radius - 20,radius))
.transition()
.delay((_,d.endAngle);
return (t) => {
d.endAngle = i(t);
return initialArc(d)
}
});
解决方法
如果您尝试将效果添加到所有 path
元素,您可以将其放置在 transition
之前或将选择保存到一个变量并分别附加过渡和鼠标悬停事件。
svg.selectAll("path")
... // Your existing code
.on('mouseover',function () {
svg.selectAll('[YOUR_ELEMENTS]')
.transition()
});
.transition()
... // initial transition
或
let pies = svg.selectAll("path")
... // Your existing code
.on('mouseover',function () {
svg.selectAll('[YOUR_ELEMENTS]')
.transition()
});
pies.transition()
... // initial transition
pies.on('mouseover',function () {
svg.selectAll('[YOUR_ELEMENTS]')
.transition()
});