前言
今天要在WebGIS中加入一些資訊圖表,利用D3.js來實作圖表並與地圖互動,D3.js非常具有彈性且多樣,能與地圖結合有錦上添花的感覺,let’s go!
本文是參加鐵人賽的文章,同步發表於 “2018鐵人賽-30天打造我的WebGIS系列”
D3.js
D3.js是資料視覺化的利器,光從官方網站範例就琳瑯滿目,例如我們要畫一個bar chart
1 | //設定畫布及x,y軸比例尺等 |
在地圖中增加互動
WebGIS的圖表當然就是圖層的屬性,在讀入geojson後,我們會需要把資料做些轉換,去產生圖表需要的資訊。
例如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32$.getJSON("./dist/assets/data/map.geojson", function (data) {
featchdata(data);
});
function featchdata(d) {
//資料
var data = [];
var tmp_type;
var tmp_count = 0;
$.each(d.features, function (k, v) {
if (k == 0) {
tmp_type = v.properties.surface;
tmp_count++;
}
else if (k == d.length - 1) {
tmp_count++;
data.push({ "letter": tmp_type, "frequency": tmp_count })
}
else {
if (tmp_type == v.properties.surface) {
tmp_count++;
} else {
data.push({ "letter": tmp_type, "frequency": tmp_count })
tmp_count = 1;
tmp_type = v.properties.surface;
}
}
});
上面圖表串接,我們加入一些地圖事件讓圖表動起來,圖表會跟著地圖實際涵蓋的範圍做變化
首先,加入地圖事件:1
2
3
4
5
6
7
8
9map.on('zoomend', function () {
var d = pois.toGeoJSON();
featchdata(d);
});
map.on('dragend', function () {
var d = pois.toGeoJSON();
featchdata(d);
});
接著,在前面的featchdata加入bounds判斷,讓圖表會根據bounds範圍呈現資料
使用的函式為turf.booleanPointInPolygon(point,polygon)
如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51function featchdata(d0) {
var ext = map.getBounds()
//資料
var poly = turf.polygon([[
[ext.getSouthWest().lng, ext.getSouthWest().lat],
[ext.getNorthWest().lng, ext.getNorthWest().lat],
[ext.getNorthEast().lng, ext.getNorthEast().lat],
[ext.getSouthEast().lng, ext.getSouthEast().lat],
[ext.getSouthWest().lng, ext.getSouthWest().lat]
]]);
console.log(poly);
var d = [];
$.each(d0.features, function (k, v) {
var pt = turf.point([v.geometry.coordinates[0], v.geometry.coordinates[1]]);
if (turf.booleanPointInPolygon(pt, poly)) {
d.push(v);
}
});
var data = [];
var tmp_type;
var tmp_count = 0;
$.each(d, function (k, v) {
if (k == 0) {
tmp_type = v.properties.surface;
tmp_count++;
}
else if (k == d.length - 1) {
tmp_count++;
data.push({ "letter": tmp_type, "frequency": tmp_count })
}
else {
if (tmp_type == v.properties.surface) {
tmp_count++;
} else {
data.push({ "letter": tmp_type, "frequency": tmp_count })
tmp_count = 1;
tmp_type = v.properties.surface;
}
}
});
...
...
省略
}
成果略圖
後記
在D3.js我們還加入一些click事件及css調整,可以直接看程式碼喔~,另外,除了D3.js以外,也可以使用單純圖表的C3.js或是highchart等較直覺的工具喔。