昨天用了D3的transition
,
今天来试试看attrTween
来让圆饼图长出来!
老样子先来看成果:
今天会先来看一下D3的Interpolate
想看code的请自己跳过喔~
tween就是补间的意思,
另外D3还有一个 interpolate (插入)
可以在两个值中间帮你算出过度的值。
官方文件: https://github.com/d3/d3-interpolate
这边也有详细的解释(https://observablehq.com/@d3/d3-interpolate)
看一下官方的案例:
数字
const i = d3.interpolateNumber(10, 20);//帮我算出10~20中间的补间吧~
i(0.0); // 10
i(0.2); // 12
i(0.5); // 15
i(1.0); // 20
颜色
const i = d3.interpolate({colors: ["red", "blue"]}, {colors: ["white", "black"]});
i(0.0); // {colors: ["rgb(255, 0, 0)", "rgb(0, 0, 255)"]}
i(0.5); // {colors: ["rgb(255, 128, 128)", "rgb(0, 0, 128)"]}
i(1.0); // {colors: ["rgb(255, 255, 255)", "rgb(0, 0, 0)"]}
tween搭配interpolate去做出过度,
而Colors, numbers, 和 transforms
可以直接用d3公式算出来(d3.interpolateTransformCss(a, b) 等等,
其他要客制化的参数,就可用:attrTween、styleTween、tween,官方案例:
transition.attrTween
transition.attrTween("fill", function() {
return d3.interpolateRgb("red", "blue");
});
transition.styleTween
transition.styleTween("fill", function() {
return d3.interpolateRgb("red", "blue");
});
transition.tween
transition.tween("attr.fill", function() {
const i = d3.interpolateRgb(this.getAttribute("fill"), "blue");
return function(t) {
this.setAttribute("fill", i(t));
};
});
将Interpolate & transition结合就可以完成我们的动态啦!
先来做基本设定:
//data
const ethnicGroupsData = [
{ label: 'Black',value:80.7},
{ label: 'Coloured',value:8.8},
{ label: 'White',value:7.9},
{ label: 'Asian',value:2.6}]
//做出颜色比例尺
const color = d3.scaleOrdinal().domain(ethnicGroupsData)
.range(['#f9c74f','#f8961e','#90be6d','#43aa8b']);
//原饼图的半径
const radius = 100;
// Animation
function play(){
//先清空
d3.select('svg').remove();
//svg起手式
const svg = d3.select('.graph2')
.append('svg')
.attr('width',300)
.attr('height',300)
.attr('id','graph2-svg')
.append("g")
.attr("transform", "translate(" + 300 / 2 + "," + 300 / 2 + ")");
// 做饼啦
var pie = d3.pie().value(function(d) {return d.value});
// 画圆饼图制造机,帮每一个data做出扇形
//可以看这一篇:弧的产生器(https://ithelp.ithome.com.tw/articles/10207678)
var arcGenerator =
d3.arc()
.innerRadius(0) //这边如果有数值的话变成甜甜圈形状的
.outerRadius(radius)
// 把data塞进去
var arc = svg.selectAll('arc').data(pie(ethnicGroupsData)).enter()
来画图&做动态罗!
//做底图和动画一块一块啦
arc
.append('path')
.attr('d',arcGenerator)
.attr('fill', function(d, i){
return color(d.data)
})
.transition() //动画起手式!
.duration(3000)
.attrTween("d", function(d) {
//data里面 有startAngle & endAngle
var d3Interpolate = d3.interpolate({startAngle: 0, endAngle: 0}, d);
return function(t) {
// t就是时间间隔回传0-1中间的数值
//d3Interpolate(t) =>各个data在t时间的角度
return arcGenerator(d3Interpolate(t));
};
})
// Label 标签
var label = d3.arc()
.outerRadius(radius*1.5) //让他在圆的更外面
.innerRadius(radius);
var text = arc.append("text")
.text(function(d) { return d.data.label; })
.style("font-family", "arial")
.style("font-size", 15)
.style("fill", "transparent")
.attr("text-anchor", "middle")
.transition()
.delay(2000)//让他晚一点出现
.duration(1000)
.style("fill", "white")
.attr("transform", function(d) {
return "translate(" + label.centroid(d) + ")";
})
// Label标签的线。polyline
var polyline = arc.append("polyline")
.attr("stroke", "white")
.attr("stroke-width", 1)
.attr("fill", "transparent")
.transition()
.delay(3000) //让他晚一点出现
.duration(1000)
.attr("points",function(d){
var outer = label.centroid(d).map((i)=>i*0.9)
return outer+','+ arcGenerator.centroid(d)
})
}
play();
今天的code: 放在这
对於画圆饼图&甜甜圈图有兴趣也可以参考:
Day20-D3 基础图表:圆饼图
Day27-D3 进阶图表:甜甜圈图
<<: 【从实作学习ASP.NET Core】Day30 | 总结与回顾
>>: Day29_ISO27037数位证据处理程序国际标准-2021/10/12
终於,我们要进入 UX/UI 设计中的最後一个流程- 高精度原型 Hi-Fi Prototype,这...
在某个我辅导过的团队,我曾观察到一个现象: RD 在评估工作时数,总是会估出不合理的长时间。是 RD...
相信大家或多或少都有去公家机关办事的经验。去公家机关办事时,如果等待时间拖太久,肯定觉得很烦吧?好不...
Q: 同事说自己的 C++ 能力是世界第一,怎麽样可以让他意识到自己没那麽厉害? A: 实不相瞒,...
OptionMenu就是下拉式选单的概念,可以有不同的设定方法,可以设成有预设选项的,也可以获得选好...