D3 · 一个散点图
举一个小小的例子——散点图(D3.V4版本开发),来说明如何结合数据,坐标轴,比例尺,过度动画,事件交互
准备数据 & SVG区域
数据
一组圆心坐标,作为散点。
1 | const center = [ |
svg区域
添加一个svg区域,并定义外边框。
padding: 图形与画布的边界距离。
1 | // svg宽高 |
比例尺
定义比例尺,在绘制散点和坐标轴时会用到,其用法如下:
1 | const linear = d3.scaleLinear().domain([0, 500]).range([0, 100]) |
domain() 线性比例尺获取或设置定义域
range() 线性比例尺获取或设置值域
linear(x) 输入定义域的值x,返回值域对应的值
散点图的比例尺:
1 | // xy轴宽度 |
坐标轴

D3提供了坐标轴的制作方法,需要配合比例尺一起使用。 D3所绘制的坐标轴由<path> <line> <text>三种元素组成:
| 元素 | 绘制 |
|---|---|
<path> |
主直线 |
<line> |
刻度 |
<text> |
刻度文字 |
其用法如下(比例尺取上面xScale的值):
1 | let xAxis = d3.axisBottom(xScale).ticks(5) |
ticks() 设定或获取坐标轴上指定的宽度
散点图的坐标轴:
1 | let xAxis = d3.axisBottom(xScale).ticks(5) |
过渡 & 动画
将绘制散点的代码都写进drawCircle()函数里面,其中包含update(更新),enter(添加),exit(删除)三部分的处理方法。
- 添加新点时,从坐标原点过度到目标的位置
- 更新点时,坐标系中的散点过渡到新的位置
- 点被删除时,点先慢慢变成白色,然后删除
1 | const t = d3.transition().duration(700).ease(d3.easeLinear) |
交互
D3的选择集可以通过on来为事件添加监听器。d3.select(this) 改变响应事件的元素,this就是事件被触发的元素。
注意的是:
过渡对象是没有on()的,不能为过渡对象设置监听器。这样写是不正确的:1
2
3svg.select(this)
.transition()
.on('click',function(){})
所以设定监听器要在transtion()之前1
2
3svg.select(this)
.on('click',function(){})
.transition()
散点图里:修改update部分1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17circleEnter.append('circle')
.attr('fill', 'black')
.attr('cx', padding.left)
.attr('cy', height - padding.bottom)
.attr('r', 7)
// 交互事件
// 1.鼠标悬浮在元素 元素变成黄色
.on('mouseover', function() {
d3.select(this).attr('fill', 'yellow')
})
// 2.鼠标离开元素 元素变回原来的黑色
.on('mouseout', function() {
d3.select(this).transition(t).attr('fill', 'black')
})
.transition(t)
.attr('cx', d => padding.left + xScale(d[0]))
.attr('cy', d => height - padding.bottom - yScale(d[1]))
最终演示效果:
See the Pen BrjOde by 何大小成 (@hopkinson) on CodePen.