ECharts GL (後面統一簡稱 GL)爲 ECharts 補充了豐富的三維可視化組件,這篇文章咱們會簡單介紹如何基於 GL 實現一些常見的三維可視化做品。實際上若是你對 ECharts 有必定了解的話,也能夠很快的上手 GL,GL 的配置項徹底是按照 ECharts 的標準和上手難度來設計的。html
看完文章有個大概的瞭解以後,你能夠繼續前往 官方示例 和 Gallery 去了解更多使用 GL 製做的示例,對於文章中咱們無法解釋到的代碼,也能夠前往 GL 配置項手冊查看具體的配置項使用方法。webpack
爲了避免再增長已經很大了的 ECharts 完整版的體積,咱們將 GL 做爲擴展包的形式提供,和諸如水球圖這樣的擴展相似,若是要使用 GL 裏的各類組件,只須要在引入echarts.min.js
的基礎上再引入一個echarts-gl.min.js
。你能夠從 官網 下載最新版的 GL,而後在頁面中經過標籤引入:web
<script src="lib/echarts.min.js"></scrpt>
<script src="lib/echarts-gl.min.js"></script>
複製代碼
若是你的項目使用 webpack 或者 rollup 來打包代碼的話,也能夠經過 npm 安裝後引入npm
npm install echarts
npm install echarts-gl
複製代碼
經過 ES6 的 import 語法引入 ECharts 和 ECharts GLjson
import echarts from 'echarts';
import 'echarts-gl';
複製代碼
引入 ECharts 和 ECharts GL 後,咱們先來聲明一個基礎的三維笛卡爾座標系用於繪製三維的散點圖,柱狀圖,曲面圖等常見的統計圖。數組
在 ECharts 中咱們有 grid 組件用於提供一個矩形的區域放置一個二維的笛卡爾座標系,以及笛卡爾座標系上上的 x 軸(xAxis)和 y 軸(yAxis)。對於三維的笛卡爾座標系,咱們在 GL 中提供了 grid3D 組件用於劃分一塊三維的笛卡爾空間,以及放置在這個 grid3D 上的 xAxis3D, yAxis3D, zAxis3D。
bash
小提示:在 GL 中咱們對除了 globe 以外全部的三維組件和系列都加了 3D 的後綴用以區分,例如三維的散點圖就是 scatter3D,三維的地圖就是 map3D 等等。
下面這段代碼就聲明瞭一個最簡單的三維笛卡爾座標系echarts
let option = {
// 須要注意的是咱們不能跟 grid 同樣省略 grid3D
grid3D: {},
// 默認狀況下, x, y, z 分別是從 0 到 1 的數值軸
xAxis3D: {},
yAxis3D: {},
zAxis3D: {}
}
複製代碼
效果以下:dom
跟二維的笛卡爾座標系同樣,每一個軸都會有多種類型,默認是數值軸,若是須要是類目軸的話,簡單的設置爲 type: 'category'
就好了。機器學習
聲明好笛卡爾座標系後,咱們先試試用一份程序生成的正態分佈數據在這個三維的笛卡爾座標系中畫散點圖。
下面這段是生成正態分佈數據的代碼,你能夠先不用關心這段代碼是怎麼工做的,只須要知道它生成了一份三維的正態分佈數據放在data
數組中。
function makeGaussian(amplitude, x0, y0, sigmaX, sigmaY) {
return function (amplitude, x0, y0, sigmaX, sigmaY, x, y) {
let exponent = -(
( Math.pow(x - x0, 2) / (2 * Math.pow(sigmaX, 2)))
+ ( Math.pow(y - y0, 2) / (2 * Math.pow(sigmaY, 2)))
)
return amplitude * Math.pow(Math.E, exponent);
}.bind(null, amplitude, x0, y0, sigmaX, sigmaY);
}
// 建立一個高斯分佈函數
const gaussian = makeGaussian(50, 0, 0, 20, 20);
let data = [];
for (var i = 0; i < 1000; i++) {
// x, y 隨機分佈
let x = Math.random() * 100 - 50;
let y = Math.random() * 100 - 50;
let z = gaussian(x, y);
data.push([x, y, z]);
}
複製代碼
生成的正態分佈的數據大概長這樣:
[
[46.74395071259907, -33.88391024738553, 0.7754030099768191],
[-18.45302873809771, 16.88114775416834, 22.87772504105404],
[2.9908128281121336, -0.027699444453467947, 49.44400635911886],
...
]複製代碼
每一項都包含了x
, y
, z
三個值,這三個值會分別被映射到笛卡爾座標系的 x 軸,y 軸和 z 軸上。
而後咱們可使用 GL 提供的 scatter3D 系列類型把這些數據畫成三維空間中正態分佈的點。
let option = {
grid3D: {},
xAxis3D: {},
yAxis3D: {},
zAxis3D: { max: 100 },
series: [{
type: 'scatter3D',
data: data
}]
}
複製代碼
接下來咱們來看一個使用真實多維數據的三維散點圖例子。
開始以前能夠先從 www.echartsjs.com/examples/da… 獲取這份數據。
編輯器裏格式化一下能夠看到這份數據是很傳統轉成 JSON 後的表格格式。第一行是每一列數據的屬性名,能夠從這個屬性名看出來每一列數據的含義,分別是人均收入,人均壽命,人口數量,國家和年份。
[
["Income", "Life Expectancy", "Population", "Country", "Year"],
[815, 34.05, 351014, "Australia", 1800],
[1314, 39, 645526, "Canada", 1800],
[985, 32, 321675013, "China", 1800],
[864, 32.2, 345043, "Cuba", 1800],
[1244, 36.5731262, 977662, "Finland", 1800],
...
]
複製代碼
在 ECharts 4 中咱們可使用 dataset 組件很是方便地引入這份數據。若是對 dataset 還不熟悉的話能夠看dataset使用教程
$.getJSON('data/asset/data/life-expectancy-table.json', function (data) {
myChart.setOption({
grid3D: {},
xAxis3D: {},
yAxis3D: {},
zAxis3D: {},
dataset: {
source: data
},
series: [
{
type: 'scatter3D',
symbolSize: 2.5
}
]
})
});
複製代碼
ECharts 默認會把前三列,也就是收入(Income),人均壽命(Life Expectancy),人口(Population)分別放到 x、 y、 z 軸上。
使用 encode 屬性咱們還能夠將指定列的數據映射到指定的座標軸上,從而省去不少繁瑣的數據轉換代碼。例如咱們將 x 軸換成是國家(Country),y 軸換成年份(Year),z 軸換成收入(Income),能夠看到不一樣國家不一樣年份的人均收入分佈。
myChart.setOption({
grid3D: {},
xAxis3D: {
// 由於 x 軸和 y 軸都是類目數據,因此須要設置 type: 'category' 保證正確顯示數據。
type: 'category'
},
yAxis3D: {
type: 'category'
},
zAxis3D: {},
dataset: {
source: data
},
series: [
{
type: 'scatter3D',
symbolSize: 2.5,
encode: {
// 維度的名字默認就是表頭的屬性名
x: 'Country',
y: 'Year',
z: 'Income',
tooltip: [0, 1, 2, 3, 4]
}
}
]
});
複製代碼
剛纔多維數據的例子中,咱們還有幾個維度(列)沒能表達出來,利用 ECharts 內置的 visualMap 組件咱們能夠繼續將第四個維度編碼成顏色。
myChart.setOption({
grid3D: {
viewControl: {
// 使用正交投影。
projection: 'orthographic'
}
},
xAxis3D: {
// 由於 x 軸和 y 軸都是類目數據,因此須要設置 type: 'category' 保證正確顯示數據。
type: 'category'
},
yAxis3D: {
type: 'log'
},
zAxis3D: {},
visualMap: {
calculable: true,
max: 100,
// 維度的名字默認就是表頭的屬性名
dimension: 'Life Expectancy',
inRange: {
color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
}
},
dataset: {
source: data
},
series: [
{
type: 'scatter3D',
symbolSize: 5,
encode: {
// 維度的名字默認就是表頭的屬性名
x: 'Country',
y: 'Population',
z: 'Income',
tooltip: [0, 1, 2, 3, 4]
}
}
]
})
複製代碼
這段代碼中咱們又在剛纔的例子基礎上加入了 visualMap 組件,將Life Expectancy
這一列數據映射到了不一樣的顏色。
除此以外咱們還把原來默認的透視投影改爲了正交投影。正交投影在某些場景中能夠避免由於近大遠小所形成的表達錯誤。
除了 visualMap 組件,還能夠利用其它的 ECharts 內置組件而且充分利用這些組件的交互效果,好比 legend。也能夠像 三維散點圖和散點矩陣結合使用 這個例子同樣實現二維和三維的系列混搭。
在實現 GL 的時候咱們儘量地把 WebGL 和 Canvas 之間的差別屏蔽了到最小,從而讓 GL 的使用能夠更加方便天然。
除了散點圖,咱們也能夠經過 GL 在三維的笛卡爾座標系上繪製其它類型的三維圖表。好比剛纔例子中將 scatter3D
類型改爲 bar3D
就能夠變成一個三維的柱狀圖。
還有機器學習中會用到的三維曲面圖 surface,三維曲面圖經常使用來表達平面上的數據走勢,剛纔的正態分佈數據咱們也能夠像下面這樣畫成曲面圖。
let data = [];
// 曲面圖要求給入的數據是網格形式按順序分佈。
for (let y = -50; y <= 50; y++) {
for (let x = -50; x <= 50; x++) {
let z = gaussian(x, y);
data.push([x, y, z]);
}
}
option = {
grid3D: {},
xAxis3D: {},
yAxis3D: {},
zAxis3D: { max: 60 },
series: [{
type: 'surface',
data: data
}]
}
複製代碼
最後,咱們常常會被問到如何用 ECharts 畫只有二維數據的立體柱狀圖效果。通常來講咱們是不推薦這麼作的,由於這種沒必要要的立體柱狀圖很容易形成錯誤的表達,具體能夠見咱們 柱狀圖使用指南 中的解釋。
可是若是有一些其餘因素致使必須得畫成立體的柱狀圖的話,用 GL 也能夠實現。丶灬豆奶 和 阿洛兒啊 在 Gallery 已經寫了相似的例子,你們能夠參考。