这几天一直在学习 D3.js 的使用,并连续总结了两篇相关的入门级文章。今天继续趁热打铁,了解一下折线图的绘制方法。
D3.js 作为一个数据图形化工具,对绘图过程中需要用到的一些功能都提供了相应的方法,而且流程上大同小异。所以从本篇开始,不会再以「由浅入深」的方式来讲解具体绘制过程。需要了解基础使用方法和流程请参考之前的两篇入门级文章:
使用 D3.js 绘制柱形图搭建 D3.js 运行环境并了解如何绘制一个简单的柱形图。
使用 D3.js 绘制饼图从一个基础的饼图开始,了解如何不断扩展相关功能元素,实现一个带图例和交互功能的饼图。
通过以上两篇文章了解了 D3 的「绘图套路」后,接下来就是举一反三,多看多练习的实践,掌握 D3 不是难事。
先来看看本文实践的最终效果:
图表代码如下:
// 定义数据集
var dataset = [2, 10, 35, 60, 70, 100, 90]
// 定义图表画布参数
var width = 800
var height = 400
var padding = 30
var svg = d3.select('svg')
.attr('width', width)
.attr('height', height)
// 定义坐标轴
var xScale = d3.scaleLinear()
.domain([0, dataset.length-1])
.range([0, width-padding*2])
var xAxis = d3.axisBottom(xScale).ticks(dataset.length)
var yScale = d3.scaleLinear()
.domain([0, d3.max(dataset)])
.range([height-padding*2, 0])
var yAxis = d3.axisLeft(yScale)
// 绘制坐标轴
svg.append('g').call(xAxis)
.attr('transform', 'translate(40, '+(height-padding)+')')
svg.append('g').call(yAxis)
.attr('transform', 'translate(40, '+padding+')')
// 绘制折线
var line = svg.append('g')
.attr('transform', 'translate(40, '+padding+')')
line.append('path')
.datum(dataset)
.attr('fill', 'none')
.attr('stroke', 'blue')
.attr('stroke-width', 1)
.attr('d', d3.line().x((v, i) => {
return xScale(i)
}).y((v, i) => {
return yScale(v)
}))
// 绘制数据坐标圆点
line.selectAll('circle').data(dataset).enter()
.append('circle')
.attr('cx', (v, i) => { return xScale(i)})
.attr('cy', (v, i) => { return yScale(v)})
.attr('r', 5)
.attr('fill', 'gold')
.attr('stroke', 'blue')
// 定义鼠标移入事件
.on('mouseover', function (e, v) {
// 放大坐标圆点
d3.select(this).attr('r', 7)
// 在光标上方显示坐标值
var pos = d3.pointer(e)
svg.append('text')
.text(v)
.attr('class', 'tooltip')
.attr('x', pos[0]+50)
.attr('y', pos[1]+20)
.attr('text-anchor', 'end')
})
// 定义鼠标移出事件
.on('mouseout', function () {
// 还原坐标圆点
d3.select(this).attr('r', 5)
// 移除坐标值提示标签
d3.select('.tooltip').remove()
})
代码中的关键位置都有注释,这里就不重复说明了。代码行数看起来虽多,但就像上面说的,如果熟悉了 D3 的用法就会发现,大部分都是一些设置位置和大小的属性操作,没有什么技术难点。