引言
想要用d3实现常见的折线绘制动画,找了找没有现成的库可以用。于是,自己结合svg的一些资料和d3的transition想了三种实现方法。总体是两类思路一类是是遮盖折线如用rect遮盖,通过clip-path修改可视区域遮盖,另外一类是通过修改折线的样式实现,如用stroke-dasharray和stroke-dashoffset。完整的demo代码在本文最后的gitHub链接中给出。
效果图如下:
法一、用rect遮蔽
最朴素的思路是利用svg 后一个元素显示位于前一个元素之上的性质,用一个和背景色相同的矩形先遮盖住绘制好的折线,用transition 慢慢移动矩形到坐标轴外。实现视觉上的折线绘制动画
绘制过程:
- 先完全遮住(黑色矩形代表程序中的rect元素)
- 移动遮盖矩形
实现代码:
let num = 20
let dataset = []
let w = 500
let h = 200
let padding = 30
//随机生成初始值
for (let i = 0; i < num; i++) {
let tevalue = Math.random() * 1000
let temp = {
id: i,
value: tevalue
}
dataset.push(temp)
}
var key = function (d) {
return d.id;
};
//x轴就是每个点等宽
let xScale = d3.scaleBand()
.domain(d3.range(num))
.range([padding, w - padding])
.paddingInner(0.05)
//y将实际值转化到整个画布上
let yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, d => d.value)])
.rangeRound([h - padding, padding])
let svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h);
let polyLine = svg.append("path")
//在path后面创建遮蔽用的与背景同色的白色矩形
let rect = svg.append('rect')
.attr("class", "shield_rect")
.attr("x", padding)
.attr("y", 0)
.attr("width", w - padding * 2)
.attr("height", h - padding)
.style("fill", "white")
let line = d3.line()
.x((d, i) => {
return (xScale(i) + xScale.bandwidth() / 2) })
.y(d => yScale(d.value) - 1