一直對數據可視化比較感興趣,當年 Alibaba 年報晚會上的大屏顯示可謂是技驚四座,夠震撼,將數據之美展現得淋漓盡致。
國內的前端數據可視化插件中,echart.js 算是熱度很高的,也容易上手,算是新手福利吧;D3.js 源於國外,長於定制,看評價多是傾向於這個方面的。先不管這些,先入手 echart.js。
一、安裝
大致分兩類:
1.<script> 直接引入本地或者cdn上的 echart(.min).js 文件,是本文中使用的方法;
2. npm 獲取,詳見 點擊comb! ;
二、基本使用
1.首先在 body 中准備一個容器:
<!-- 為 ECharts 准備一個具備大小(寬高)的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
2.引入 echart.js 文件: <script> 標簽引入
3.基本結構(貼個小demo):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js -->
<script src="echarts.min.js"></script>
</head>
<body>
<!-- 為ECharts准備一個具備大小(寬高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基於准備好的dom,初始化echarts實例
var myChart = echarts.init(document.getElementById('main'));
// 指定圖表的配置項和數據
var option = {
title: {
text: 'ECharts 入門示例'
},
tooltip: {},
legend: {
data:['銷量']
},
xAxis: {
data: ["襯衫","羊毛衫","雪紡衫","褲子","高跟鞋","襪子"]
},
yAxis: {},
series: [{
name: '銷量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
};
// 使用剛指定的配置項和數據顯示圖表。
myChart.setOption(option);
</script>
</body>
三、異步加載數據和更新
1.異步加載也比較簡單,通過 ajax 請求數據,並將數據和配置填入 setOption 即可。
var myChart = echarts.init(document.getElementById('main'));
// 顯示標題,圖例和空的坐標軸
myChart.setOption({
title: {
text: '異步數據加載示例'
},
tooltip: {},
legend: {
data:['銷量']
},
xAxis: { // 先聲明
data: []
},
yAxis: {},
series: [{
name: '銷量',
type: 'bar',
data: []
}]
});
// 異步加載數據
$.get('data.json').done(function (data) {
// 填入數據
myChart.setOption({
xAxis: {
data: data.categories
},
series: [{
// 根據名字對應到相應的系列
name: '銷量',
data: data.data
}]
});
});
上面的思路是先將空的坐標系畫出來,獲取數據后在填入進去,另外一條思路是先獲取數據,在配置各項目,代碼層面是將 setOption 全部寫在 ajax 邏輯內部,但這樣很容易造成頁面的區域性空白,故不推薦這種思路。
注意:在數據的更新時需要通過 name 屬性對應到相應的系列,更推薦在配置時加上 series 中的 name 。
2.對於加載過程的優化:
數據加載過程中往往出現各種問題導致加載過程變長,這就很容易產生用戶體驗問題,echart.js中內置了一個簡單加載過渡動畫的 api:
請求數據前調用 showLoading 方法,數據加載完成后調用 hideLoading 方法隱藏加載動畫即可。
// 調用 showLoading 方法
myChart.showLoading();
$.get('data.json').done(function (data) {
// 調用 hideLoading 方法
myChart.hideLoading();
myChart.setOption(...);
});
3.數據的動態更新
使用定時器(setInterval)定時請求數據並更新 setOption 即可。 動態更新實例
四、dataset 管理數據
Echart 4 以前,數據需要在各個 series 中聲明,這中方式直觀易理解,但是缺點是不利於多個系列共享等。
而從 4 開始,提供數據集(dataset)來聲明數據,可以完成諸如:共享、分割數據等操作。
官方的入門例子:
option = {
legend: {},
tooltip: {},
dataset: {
// 提供一份數據,此處是二維數組。
source: [
['product', '2015', '2016', '2017'],
['Matcha Latte', 43.3, 85.8, 93.7],
['Milk Tea', 83.1, 73.4, 55.1],
['Cheese Cocoa', 86.4, 65.2, 82.5],
['Walnut Brownie', 72.4, 53.9, 39.1]
]
},
// 聲明一個 X 軸,類目軸(category)。默認情況下,類目軸對應到 dataset 第一列。
xAxis: {type: 'category'},
// 聲明一個 Y 軸,數值軸。
yAxis: {},
// 聲明多個 bar 系列,默認情況下,每個系列會自動對應到 dataset 的每一列。
series: [
{type: 'bar'},
{type: 'bar'},
{type: 'bar'}
]
}
或者:
option = {
legend: {},
tooltip: {},
dataset: {
// 這里指定了維度名的順序,從而可以利用默認的維度到坐標軸的映射。
// 如果不指定 dimensions,也可以通過指定 series.encode 完成映射,參見后文。
dimensions: ['product', '2015', '2016', '2017'],
source: [
{product: 'Matcha Latte', '2015': 43.3, '2016': 85.8, '2017': 93.7},
{product: 'Milk Tea', '2015': 83.1, '2016': 73.4, '2017': 55.1},
{product: 'Cheese Cocoa', '2015': 86.4, '2016': 65.2, '2017': 82.5},
{product: 'Walnut Brownie', '2015': 72.4, '2016': 53.9, '2017': 39.1}
]
},
xAxis: {type: 'category'},
yAxis: {},
series: [
{type: 'bar'},
{type: 'bar'},
{type: 'bar'}
]
};
建議: dataset 中 source 是數組,建議將數據模擬成 二維 排列,這樣在整個 dataset 的學習過程中比較容易理解。
行、列映射
dataset 的 source 中數據可以大致看成是一個二維排列的數組,那是怎么將數組中的數據與圖表對應的呢?
用戶可以使用 seriesLayoutBy 配置項,改變圖表對於行列的理解。seriesLayoutBy 可取值:
'column': 默認值。系列被安放到 dataset 的列上面。
'row': 系列被安放到 dataset 的行上面。
官方栗子:
option = {
legend: {},
tooltip: {},
dataset: {
source: [
['product', '2012', '2013', '2014', '2015'],
['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
['Milk Tea', 86.5, 92.1, 85.7, 83.1],
['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
]
},
xAxis: [
{type: 'category', gridIndex: 0}, // 坐標系1
{type: 'category', gridIndex: 1} // 坐標系2
],
yAxis: [
{gridIndex: 0}, // 坐標系1
{gridIndex: 1} // 坐標系2
],
grid: [
{bottom: '55%'}, // 坐標系1 距離底部距離
{top: '55%'} // 坐標系2 距離頂部距離
],
series: [
// 這幾個系列會在第一個直角坐標系中,每個系列對應到 dataset 的每一行,即將 source 中的行作為 x 軸。
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
{type: 'bar', seriesLayoutBy: 'row'},
// 這幾個系列會在第二個直角坐標系中,每個系列對應到 dataset 的每一列。
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
{type: 'bar', xAxisIndex: 1, yAxisIndex: 1}
]
}

數據映射到圖形(encode)
官方栗子:
var option = {
dataset: {
source: [
['score', 'amount', 'product'],
[89.3, 58212, 'Matcha Latte'],
[57.1, 78254, 'Milk Tea'],
[74.4, 41032, 'Cheese Cocoa'],
[50.1, 12755, 'Cheese Brownie'],
[89.7, 20145, 'Matcha Cocoa'],
[68.1, 79146, 'Tea'],
[19.6, 91852, 'Orange Juice'],
[10.6, 101852, 'Lemon Juice'],
[32.7, 20112, 'Walnut Brownie']
]
},
// 注意下面兩行的寫法;
xAxis: {},
yAxis: {type: 'category'},
series: [
{
type: 'bar',
encode: {
// 將 "amount" 列映射到 X 軸。
x: 'amount',
// 將 "product" 列映射到 Y 軸。
y: 'product'
}
}
]
};

放一個官網實例(數據量巨大): 數據圖 ;
encode 的具體配置以及值:
// 例如在直角坐標系(grid/cartesian)中:
encode: {
// 把 “維度1”、“維度5”、“名為 score 的維度” 映射到 X 軸:
x: [1, 5, 'score'],
// 把“維度0”映射到 Y 軸。
y: 0,
// 使用 “名為 product 的維度” 和 “名為 score 的維度” 的值在 tooltip 中顯示
tooltip: ['product', 'score']
// 使用 “維度 3” 的維度名作為系列名。(有時候名字比較長,這可以避免在 series.name 重復輸入這些名字)
seriesName: 3,
// 表示使用 “維度2” 中的值作為 id。這在使用 setOption 動態更新數據時有用處,可以使新老數據用 id 對應起來,從而能夠產生合適的數據更新動畫。
itemId: 2,
// 指定數據項的名稱使用 “維度3” 在餅圖等圖表中有用,可以使這個名字顯示在圖例(legend)中。
itemName: 3
}
// 對於極坐標系,可以是:
encode: {
radius: 3,
angle: 2,
...
}
// 對於地理坐標系,可以是:
encode: {
lng: 3,
lat: 2
}
// 對於一些沒有坐標系的圖表,例如餅圖、漏斗圖等,可以是:
encode: {
value: 3
}
實例:
1.南丁格爾(餅)圖:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>echart-coxcomb</title>
</head>
<body>
<p>南丁格爾圖是餅圖的一種</p>
<div id="main" style="width: 600px;height: 400px;"></div>
<script type="text/javascript" src="../../jslib/echarts.js"></script>
<script type="text/javascript">
// 初始化 echart 實例
var myChart = echarts.init(document.getElementById('main'));
// 指定圖表的配置項和數據
var option = {
// 設置全局背景色,注意與下面陰影的關系
backgroundColor: '#2c343c',
// 將數據映射到扇形的明暗程度上
visualMap: {
show: false,
min: 80,
max: 600,
inRange: {
colorLightness: [0, 1]
}
},
series: [
{
name: '訪問來源',
type: 'pie', // 通過 type 來控制圖表種類
radius: '75%', // 圖表大小
data: [
{value: 235, name: '視頻廣告'},
{value: 274, name: '聯盟廣告'},
{value: 310, name: '郵件營銷'},
{value: 335, name: '直接訪問'},
{value: 400, name: '搜索引擎'}
],
roseType: 'angle', // 將餅圖以南丁格爾圖形式展示
itemStyle: {
normal: {
// 餅圖扇形的顏色
color: '#c23531',
// 設置陰影大小
shadowBlur: 100,
// 設置陰影顏色
shadowColor: 'rgba(0,0,0,0.5)'
}
},
label: {
normal: {
// 文本標簽的字體顏色
color: 'rgba(255, 255, 255, 0.3)'
}
},
labelLine: {
normal: {
// 文本標簽的視覺引導線顏色
lineStyle: {
color: 'rgba(255, 255, 255, 0.3)'
}
}
}
}
]
};
// 使用配置項並顯示圖像
myChart.setOption(option);
</script>
</body>
</html>
更多關於餅圖的配置項詳參: echart.js - pie configure ;
