使用echarts快速實現模擬遷徙圖功能
來自專欄前端筆錄
現在我要實現一個監控功能,其效果如下圖:
圖為雲南省下面的各個市州向昆明市上報一些數據,要達到這種效果其實還是很方便的。具體實現過程如下:
定義繪圖區域
這一步很簡單,只需要一個canvas繪圖區即可。
<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8"> <title>數據交換監控</title> <style type="text/css"> body { margin: auto } </style></head><script src="source/jquery-1.7.2.js"></script><body><div id="map" style="width:600px;height:600px;margin: auto"></div><script src="source/echarts.js"></script><script src="source/data.js"></script><script src="source/hashmap.js"></script><script src="map.js"></script></body></html>
需要注意的是,map這個div的尺寸要設置成等邊的。否則最終顯示的地圖會被擠壓。原因是canvas的尺寸就是這個DIV樣式的高度和寬度。
引入相關庫
在上面文件里引入了相關的庫:jquery,echarts。hashmap.js為js的版本的HashMap實現。map.js為我們的數據展示邏輯代碼。data.js為數據上報展示效果的數據源,其結構如下:
//上報數據的城市,其name對應geo地圖數據中的properties數組元素的namevar dataSource = [{ dataSourceId: 2018, data: [ { name: 文山壯族苗族自治州, value: 10 }, { name: 怒江傈僳族自治州, value: 20 }, { name: 西雙版納傣族自治州, value: 20 }, { name: 大理白族自治州, value: 10 }, { name: 楚雄彝族自治州, value: 20 }, { name: 曲靖市, value: 1 }]}, { dataSourceId: 2017, data: [ { name: 文山壯族苗族自治州, value: 90 } ] }];//中心匯入點城市var center = 昆明市;
初始化echarts
我們採用require來按需載入echarts所需的圖標組件,具體的代碼在map.js:
/** * 模擬遷徙圖功能實現 */require.config({ paths: { echarts: ./source }});var ecConfig;require( [ echarts, echarts/chart/map ], function (ec) { ecConfig = require(echarts/config); myChart = ec.init(document.getElementById(map)); initData(); loadAll(2018, 數據交換監控); });var myChart;option = { backgroundColor: #1b1b1b, color: [gold, aqua, lime], title: { show: true, text: , x: center, textStyle: { color: #fff } }, tooltip: { trigger: item, formatter: function (params, ticket, callback) { /*$.get(detail?name= + params.name, function (content) { callback(ticket, toHTML(content)); });*/ var tips = <ul stylex="list-style: none">; tips += <li>行政區劃: + params.name + </li>; tips += <li>歷史已報件:1000個</li>; tips += <li>最近上報時間: + new Date().toLocaleTimeString() + </li>; tips += </ul>; return tips; } }, legend: { show: true, orient: vertical, x: left, data: [玉溪 Top10, 大理 Top10, 保山 Top10], selectedMode: single, selected: { 保山 Top10: false, 大理 Top10: false }, textStyle: { color: #fff } }, toolbox: { show: true, orient: vertical, x: right, y: center, feature: { mark: {show: true}, dataView: {show: true, readOnly: false}, restore: {show: true}, saveAsImage: {show: true} } }, dataRange: { min: 0, max: 100, calculable: true, color: [#ff3333, orange, yellow, lime, aqua], textStyle: { color: #fff } }, series: [ { name: 雲南, type: map, roam: true, hoverable: false, mapType: 雲南, itemStyle: { normal: { color: #28363E, borderColor: rgba(100,149,237,1), borderWidth: 1, areaStyle: { color: #1b1b1b }, label: { show: true, textStyle: { fontSize: 12, color: white } } } }, data: [], markLine: { smooth: true, symbol: [none, circle], symbolSize: 1, itemStyle: { normal: { color: #fff, borderWidth: 1, borderColor: rgba(30,144,255,0.5) } }, data: [], }, geoCoord: { 普洱市: [100.7446, 23.4229], 紅河哈尼族彝族自治州: [103.0408, 23.6041], 文山壯族苗族自治州: [104.8865, 23.5712], 曲靖市: [103.9417, 25.7025], 楚雄彝族自治州: [101.6016, 25.3619], 大理白族自治州: [99.9536, 25.6805], 臨滄市: [99.613, 24.0546], 迪慶藏族自治州: [99.4592, 27.9327], 昭通市: [104.0955, 27.6031], 昆明市: [102.9199, 25.4663], 麗江市: [100.448, 26.955], 西雙版納傣族自治州: [100.8984, 21.8628], 保山市: [99.0637, 24.9884], 玉溪市: [101.9312, 23.8898], 怒江傈僳族自治州: [99.1516, 26.5594], 德宏傣族景頗族自治州: [98.1299, 24.5874], } }, { name: 昆明市, type: map, mapType: 雲南, data: [], markLine: { smooth: true, effect: { show: true, scaleSize: 2, period: 30, color: #fff, shadowBlur: 10 }, itemStyle: { normal: { borderWidth: 1, lineStyle: { type: solid, shadowBlur: 10 } } } }, markPoint: { symbol: emptyCircle, symbolSize: function (v) { return 10 + v / 10 }, effect: { show: true, shadowBlur: 0 }, itemStyle: { normal: { label: {show: false} }, emphasis: { label: {position: top} } } } } ]};function changeDataSource() { var dataSourceId = parseInt($("#dataSourceId").val()); loadAll(dataSourceId, 數據交換監控);}/** * 載入數據源,構造需要加入遷徙圖的數據和連線信息 * @param dataSourceId 數據源 data.js中定義的對象 * @param title 標題 */function loadAll(dataSourceId, title) { myChart.clear(); var data = h2.get(dataSourceId); option.series[1].markLine.data = []; //各市州到中心的連線數據 for (var i = 0; i < data.length; i++) { var obj = new Object(); obj.name = data[i].name; var obj1 = new Object(); obj1.name = center; var arr = new Array(); arr.push(obj); arr.push(obj1); option.series[1].markLine.data.push(arr); } //流向數據 option.series[1].markPoint.data = data; option.title.text = title; myChart.setOption(option);}var h2 = new HashMap();function initData() { for (var i = 0; i < dataSource.length; i++) { h2.put(dataSource[i].dataSourceId, dataSource[i].data); }}window.onresize = function () { myChart.resize();}
option屬性的配置是關鍵。
- 我們需要展示的是雲南省的地圖,其地圖geojson的數據在source/chart/map.js作為一個amd模塊已經定義好。
mapType指定為雲南,這個是在map模塊里定義個一個省級地圖數據:
geoCoord設置為每個市的中心坐標:
載入數據源
我們需要的數據有兩部分:連線數據和起點數據:
/** * 載入數據源,構造需要加入遷徙圖的數據和連線信息 * @param dataSourceId 數據源 data.js中定義的對象 * @param title 標題 */function loadAll(dataSourceId, title) { myChart.clear(); var data = h2.get(dataSourceId); option.series[1].markLine.data = []; //各市州到中心的連線數據 for (var i = 0; i < data.length; i++) { var obj = new Object(); obj.name = data[i].name; var obj1 = new Object(); obj1.name = center; var arr = new Array(); arr.push(obj); arr.push(obj1); option.series[1].markLine.data.push(arr); } //流向數據 option.series[1].markPoint.data = data; option.title.text = title; myChart.setOption(option);}
markLine的data屬性為一個數組,其元素是{{name:楚雄彝族自治州},{name:昆明市}這種結構。
最後調用myChart.setOption(option);即可展示文章開頭部分的效果了。
end
思考:本文實現的是數據從多個城市上報到中心城市的效果。讀者可自行做一個數據分發的效果,也就是數據從一個中心城市流出到多個城市。效果如下:
推薦閱讀:
※八卦和六十四卦圖表
※雙層圖表 這個真好
※五運六氣( 內經古典理論圖表 - 遺篇 )
※Tableau Deepin - 使用Tableau創建直方圖
※PPT小白如何快速做出既有邏輯又好看的圖表!