折線圖是資料統計中經常會用到的圖表,用於二維資料的展示,本文將使用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 |
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月份銷售量的最大值和最小值
var min = d3.min(dataset, function(d) {
return d[1];
})
var max = d3.max(dataset, function(d) {
return d[1];
})
複製程式碼
還需要一些畫圖的基礎資料
// 圖表的寬度和高度
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軸的零點在最下面,刻度從下往上的遞增
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]) 設定或者取得比例尺
有了比例尺就可以繪製軸線了,建立比例尺,並呼叫剛才設定的比例尺
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標籤組成的軸線
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為了生成各種線段、形狀、圖形,內建了路徑生成器,這裡需要用到線段生成器,並指定二維的訪問器,呼叫剛才設定的比例尺
var linePath = d3.line()
.x(function(d){ return xScale(d[0]) })
.y(function(d){ return yScale(d[1]) });
複製程式碼
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');
複製程式碼
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');
複製程式碼
最終繪製的軸線圖如下所示