折线图是数据统计中经常会用到的图表,用于二维数据的展示,本文将使用D3上手制作一个简单的折线图
确定数据
表格数据是一家店铺一年的销售量
月份 |
销售量(件) |
1月 |
454 |
2月 |
628 |
3月 |
756 |
4月 |
632 |
5月 |
582 |
6月 |
704 |
7月 |
766 |
8月 |
804 |
9月 |
884 |
10月 |
960 |
11月 |
1095 |
12月 |
1250 |
1 2
| var dataset = [[1, 224], [2, 528], [3, 756], [4, 632], [5, 582], [6, 704], [7, 766], [8, 804], [9, 884], [10, 960], [11, 1095], [12, 1250]];
|
要找出最大值和最小值,需要用到D3的数组方法
d3.min(array[,accessor])
返回数组中的最小值
d3.max(array[,accessor])
返回数组中的最大值
accessor是一个执行min或max函数前调用的方法,因为dataset是一个二维数组,因此需要在每一项数组拿出来后返回子数组中的第二个数值,可以取得1至12月份销售量的最大值和最小值
1 2 3 4 5 6
| var min = d3.min(dataset, function(d) { return d[1]; }) var max = d3.max(dataset, function(d) { return d[1]; })
|
还需要一些画图的基础数据
1 2 3 4 5
| var width = 600; var height = 600; var padding = { top: 50, right: 50, bottom: 50, left: 50 };
|
设置比例尺
由于画布的大小有限,数据值很大,所以折线图通常要用到线性比例尺,用画布上的距离来代表图表中量化的数值
d3.scaleLinear()
设置一个线性比例尺
quantize.domain([domain])
取得或设置比例尺的定义域
quantize.range([range])
取得或设置比例尺的值域
在x轴方向,数据从1月份到12月份,画布上的对应距离为画布宽度减去左右空隙,在y轴方向同理,不过y轴的值域是颠倒的,因为y轴的零点在最下面,刻度从下往上的递增
1 2 3 4 5 6 7
| var xScale = d3.scaleLinear() .domain([1, 12]) .range([0, width - padding.left - padding.right]); var yScale = d3.scaleLinear() .domain([0, max]) .range([height - padding.top - padding.bottom, 0]);
|
绘制轴线
d3.axisBottom(scale)
创建一个新的轴生成器
d3.axisBottom(scale).scale([scale])
设置或者取得比例尺
有了比例尺就可以绘制轴线了,创建比例尺,并调用刚才设置的比例尺
1 2 3 4 5 6 7 8
| var svg = d3.select('body') .append('svg') .attr('width', width + 'px') .attr('height', height + 'px'); var xAxis = d3.axisBottom() .scale(xScale); var yAxis = d3.axisLeft() .scale(yScale);
|
在svg中需要一个容器来装轴线,就是装载群组的g标签,在g标签中调用轴生成器,生成例如path、line、text等svg标签组成的轴线
1 2 3 4 5 6 7 8
| svg.append('g') .attr('class', 'axis') .attr('transform', 'translate(' + padding.left + ',' + (height - padding.bottom) + ')') .call(xAxis); svg.append('g') .attr('class', 'axis') .attr('transform', 'translate(' + padding.left + ',' + padding.top + ')') .call(yAxis);
|
绘制的轴线图如下所示
绘制曲线
d3.line()
新建一个线生成器
line.x([x])
设置或获取x-坐标访问器
line.y([y])
设置或获取y-坐标访问器
D3为了生成各种线段、形状、图形,内置了路径生成器,这里需要用到线段生成器,并指定二维的访问器,调用刚才设置的比例尺
1 2 3
| var linePath = d3.line() .x(function(d){ return xScale(d[0]) }) .y(function(d){ return yScale(d[1]) });
|
1 2 3 4 5 6 7 8
| svg.append('g') .append('path') .attr('class', 'line-path') .attr('transform', 'translate(' + padding.left + ',' + padding.top + ')') .attr('d', linePath(dataset)) .attr('fill', 'none') .attr('stroke-width', 3) .attr('stroke', 'green');
|
1 2 3 4 5 6 7 8 9 10
| svg.append('g') .selectAll('circle') .data(dataset) .enter() .append('circle') .attr('r', 5) .attr('transform', function(d){ return 'translate(' + (xScale(d[0]) + padding.left) + ',' + (yScale(d[1]) + padding.top) + ')' }) .attr('fill', 'green');
|
最终绘制的轴线图如下所示
查看完整示例代码