1、简介
本文是介绍怎么用简单的方法利用D3.js画出条形图,为了方便操作,本文选取的是vue组件。先放上最简单的代码:
上边的代码做了两个事情,首先在html页面中添加了一个
标签,然后在js中调用d3相关代码,获取到html中的对象,然后为其添加了“Hello world”的文字。效果如下:(没有调style,所以偏向一边……)
作为一个非职业前端开发,其实一开始我对D3 的概念是非常模糊的,知识知道是一个数据可视化(画图)的包。那么究竟什么是D3呢?
我的理解是:用代码来画图的工具。
2、用D3画简单的条形图
还是先放上效果:
代码如下:
超简易条形图
代码逻辑:
1.标签
首先在html部分中定义标题和svg标签,也就是下边两行:
超简易条形图
再套一层div是因为vue规定一个中只有一个标签,其他的都要套在里边。
2.js部分
js包含了四个部分:定义范围,缩放,画图,添加文字。
定义范围
就是定义图画的大小。对应的代码是这几行:
let barWidth = (this.svgWidth / this.dataset.length)
let svg = d3.select('svg')
.attr('width', this.svgWidth)
.attr('height', this.svgHeight)
注意的是,this开头的都是在data中定义好的数据。这里定义了条形图中“条”的宽度,以及svg的画布大小(也就是整个图形的大小)。
缩放
就是对数据的缩放,主要的作用就是放大数据的特征。对应的代码是以下几行:
let yScale = d3.scaleLinear()
.domain([0, d3.max(this.dataset)])
.range([0, this.svgHeight - 20])
这里用到的是d3的线性缩放函数:scaleLinear()。使用这个函数需要设定两个值,一个是domain,一个是range。分别对应的是传入的数据的范围,这里用的是0到数据的最大值(用d3的max函数获取),也可以用数据值的最小值到最大值(如下图),但是这种做法不使用于条形图,所以我没有采用。
range对应的是说上边domain中设定的范围对应图形的是什么范围,这里用的是0到最大高度减去20(为了美观,留了一点距离)
画图
由于上边的第一步就设定了一个svg对象(通过d3的选择其获取到html中的svg标签的来,这种操作和jquery比较类似,毕竟d3也是那个年代的产物),所以这里就直接操作svg对象。
let barChart = svg.selectAll('rect') // 获取rect对象
.data(this.dataset) // 设置数据
.enter() // 进入数据
.append('rect') // 增加rect
.attr('y', d => this.svgHeight - yScale(d)) // 增加一个参数y
.attr('height', d => yScale(d)) // 设置高度
.attr('width', barWidth - this.barPadding) // 设置宽度
.attr('transform', (d, i) => { // 设置transform
let translate = [ barWidth * i, 0 ] // 这里是一个函数
return 'translate(' + translate + ')'
})
.attr('fill', '#566fde') // 填充的颜色
这里有一个比较奇怪的参数——transform。这个是svg的一个属性,主要用于坐标轴的偏移。简单来说,就是画完一个柱子之后,下一个柱子在哪里画,如果这里设置了一个固定的值,那么所有的柱子就会重叠到一起:
添加文字
从上图可以看到,在条形图在出现问题重叠的时候,上边的文字是不会重叠。这是因为文字和图是分开画的,添加文字的代码如下:
let text = svg.selectAll('text')
.data(this.dataset)
.enter()
.append('text')
.text(d => d)
.attr('y', (d, i) => this.svgHeight - yScale(d) - 2)
.attr('x', (d, i) => barWidth * i)
.attr('fill', '#000000')
这段代码里边并没有设置translate属性,但是文字也没有重叠,原因是因为其用了x属性。