Let's Make a Bar Chart
2018-04-21 本文已影响0人
雷朝建
选择一个元素
在d3中, 一般使用d3.select选择单个元素. 或者d3.selectAll选择匹配的所有元素.
const body = d3.select('body');
const div = body.append('div');
div.html('Hello world!');
const section = d3.selectAll('section');
const div = section.append('div');
div.html('Hello, world!');
链式方法
类似jQuery, 支持链式写法.
d3.select('body').append('div').html('Hello, world!');
SVG简介
SVG中的<g>元素用来组合对象的容器. 添加到g元素上的变换会应用到其所有的子元素上.
translate(x, y)用来移动对象, x/y分别对应坐标x/y轴.
rect绘制矩形, 需要提供width和height.
text绘制文本, 需要提供x/y坐标位置.
绘制柱状图
整体效果如下:
image.png
这里由四部分组成:
- 柱状图部分(使用rect进行绘制)
- 显示柱状图的值部分(使用text进行绘制)
- x轴部分(使用d3.axisBottom进行绘制)
- y轴部分(使用d3.axisLeft进行绘制)
柱状图部分
d3.select('.chart').attr('width', width + 50).attr('height', height + 50)
.selectAll('rect').data(data)
.enter().append('rect')
.attrs({ x: (d, i) => x(i), y: d => y(d), width: barWidth, height: d => height - y(d) })
.style('fill', 'green');
这里先selectAll所有的rect(还未创建), 赋值其data, 然后通过enter后append(创建)多个rect. 通过设置其属性x, y, width, height进行rect的绘制.
这里x(i), y(i)中的x, y分别为函数, 是从domain向range的转换.
文本部分
d3.select('.chart').selectAll('text').data(data)
.enter().append('text')
.attrs({ x: (d, i) => x(i) + 10, y: d => y(d) })
.text(d => d)
这里只需要简单的设置文本的x,y和text即可.
x/y坐标轴代码
const y = d3.scaleLinear().domain([0, d3.max(data)]).range([height, 0]);
const x = d3.scaleBand().domain(d3.range(20)).range([0, width]);
const gx = d3.select('.chart').append('g').attr('transform', `translate(0,${height})`);
const xAxis = d3.axisBottom(x);
const gy = d3.select('.chart').append('g').attr('transform', `translate(0,0)`);
const yAxis = d3.axisLeft(y);
gx.call(xAxis);
gy.call(yAxis);
- domain向range的转换: domain通常为实际数据的值, 例如区间为0~20, 而range为实际绘图区域的区间, 例如0~960px, 则设置后, 输入20定位到像素960px.
- d3.axisBottom为d3封装的x轴坐标, d3.axisLeft为d3封装的y轴左侧坐标.
源码
https://github.com/leicj/d3/blob/master/src/components/bar.js