【echarts】用地圖模組做動態流程圖2.0(根據後臺資料自動均勻排布,且實時更新節點狀態)
阿新 • • 發佈:2019-02-05
1.效果
2.說明
- 這個升級版幾乎就是我們公司用的這個功能了,設計到的功能就是可以根據後臺資料重新進行位置排布,且實時重新整理節點的資料。用ec寫出這個效果不難,參考demo1
- 這個主要是設計到如何根據資料進行重新排布,實時刷資料,這些都是ec外掛沒有的,需要我們去苦逼手寫的。
3.程式碼:
3.1要知道的:
- 其實在敲程式碼前,就應該意識到和後臺要的資料是什麼樣的,要知道我們是用地圖模組實現的,所以節點的定位就要設計到座標,而這個座標是後臺不會給我們的,他只會給我們這些個節點的基本資訊,狀態,來自哪個節點,要去哪個節點。換句話說,就是這個節點的定位是需要我們算的。
- OK,既然是我們算,就要知道,我們算的這個地圖的模組的邊界大小和起始點。這裡我用的世界地圖,沒有用中國地圖,是有原因的。這就是說到我們的邊界和起始點。世界地圖的邊界和起始點比較好設定和計算,都是整數,而中國地圖首先得合理的把中國地圖放大,找到起始點座標和邊界大小,雖然說後面的計算方法和世界地圖的計算是一樣的,但是找起始點就噁心的很,所以強烈建議用世界地圖。
- 世界地圖的起始點和邊界:
- 資料也不難找 中心點座標是[0,0],寬度是東經到西經360,高度不是北緯到南緯180,是北緯80度到南緯50度的樣子,這個也沒有具體是怎麼樣的數值,原因就是地圖會向上偏移點,北緯80度到南緯50度的範圍更合適點。所以可以得出:
me.conf = {
// 起始點
start: [-180, 80],
w: 360,
h: 130,
padding: 5,
// 列寬
_lie_w: 0,
}
3.2主要過程:
- 主要流程:1.確定了起始點和邊界範圍 2.根據資料確定每列資料的寬度;3.初始化節點資料,4.初始化航線資料,5.注入資料 6.設定實時更新
_init: function() { // 起始點確定 me._flow_start_p(); // 確認列寬 me._flow_lie_w(); // me._flow(); }, _flow: function() { // **************************************模擬資料 for (var lie_key in all_data) { all_data[lie_key].forEach(function(ele, index) { ele.id = `${lie_key}_${index+1}`; ele.name = `lie_${lie_key}_${index+1}`; ele.status = (Math.random() > 0.5 ? 0 : 1); }); } // ********************************************** // 初始化節點 me._flow_node(); // **************************************模擬資料 for (var lie_key in all_data) { all_data[lie_key].forEach(function(ele, index) { // console.log(); ele.to = me._flow_lines_to_test(ele.id); }); } // ********************************************** // 初始化線 me._flow_lines(); // 生成資料 me._flow_init(); // setTimeout(function() { // **************************************模擬資料 // for (var lie_key in all_data) { // all_data[lie_key].forEach(function(ele, index) { // // console.log(); // ele.to = me._flow_lines_to_test(ele.id); // }); // } // ********************************************** // me.all_obj.ec.clear(); me.all_obj.pt_p_arr.length = 0; me.all_obj.alarm_p_arr.length = 0; me.all_obj.pt_lines_arr.length = 0; me.all_obj.alarm_lines_arr.length = 0; me._flow(); }, 5000) },
- 認識下資料格式,要知道後臺是不給我們座標的,所以猜下大概的資料格式應該是:id是節點的座標,statu節點的狀態,to就是表示我們這個節點要去哪個節點的座標。這些都是我作為前端想到的。到時候有其他欄位再加就行了。
var all_data = {
1: [
//
{
id: 1,
status: 0,
name: 'lie-1-1',
to:'2_1',
},
//
{
id: 1,
status: 1,
name: 'lie-1-2',
to:'2_1',
},
//
{
id: 1,
status: 1,
name: 'lie-1-3',
to:'2_2',
},
],
2:...
}
- 這裡是5列資料,所以走第一步,先確定列的寬度:(在配置起始座標和邊界時,我同時設定了一個padding值,就是以防我們經理說撐的太滿了要往裡面收下的這個low的要求。)
// 寬度確定
_flow_lie_w: function() {
// 資料處理
var index = 0;
for (var lie in all_data) {
index++;
}
// 初始化列寬
me.conf._lie_w = Math.floor(me.conf.w / index);
},
- 然後就是初始化每一列資料:核心就是要確定每一列第一個節點的經緯度,知道如歌通過遍歷得到同列下面節點的經緯度,這裡要注意的是:1.在最後要收集每個節點的ID和座標的對應關係,因為我們在初始化巡航線的時候要用到這些點的座標。2.根據不同的狀態收集不同的資料,這裡主要是有普通點就是沒有動態效果,報警點有報警效果的區別,我也是擔心經理有這個要求,沒等他說我就直接這樣寫了,如果是報警直接節點顏色變了,沒有動畫效果,就沒必要通過兩個陣列進行收集資料了,因為看ec的API顏色也是可以用個回撥函式進行顏色的設定。
// 初始化節點
_flow_node: function() {
for (var lie in all_data) {
me._flow_node_init(all_data[lie], lie);
}
},
_flow_node_init: function(arr, lie) {
// console.log(arr, lie);
var lie_index = null;
switch (lie) {
case "1":
lie_index = 1;
break;
case "2":
lie_index = 2;
break;
case "3":
lie_index = 3;
break;
case "4":
lie_index = 4;
break;
case "5":
lie_index = 5;
break;
}
// 每一列的專案高
var _item_h = Math.floor(me.conf.h / arr.length);
// 每列起始經度
var lng = me.conf.start[0] + (lie_index - 0.5) * me.conf._lie_w;
// 緯度
var lat = 0;
//
arr.forEach(function(ele, index) {
lat = me.conf.start[1] - (index + 1 - 0.5) * _item_h;
// PT
if (ele.status) {
// 普通點收集
me.all_obj.pt_p_arr.push({
id: ele.id,
name: ele.name,
value: [lng, lat]
});
}
// 報警點收集
else {
me.all_obj.alarm_p_arr.push({
id: ele.id,
name: ele.name,
value: [lng, lat]
});
}
// 生成字典
me.all_obj.p_obj[ele.id] = [lng, lat];
});
},
- 初始化巡航線:就是更加節點資料裡的to欄位。知道我們要去哪個節點的ID,根據前面收集的ID的座標的對應關係,拿到要去的節點的座標。
// 初始化線
_flow_lines: function() {
for (var lie in all_data) {
all_data[lie].forEach(function(ele, index) {
if (ele.to) {
// PT
if (ele.status) {
me.all_obj.pt_lines_arr.push({
"coords": [
me.all_obj.p_obj[ele.id],
me.all_obj.p_obj[ele.to],
]
});
}
// 報警
else {
me.all_obj.alarm_lines_arr.push({
"coords": [
me.all_obj.p_obj[ele.id],
me.all_obj.p_obj[ele.to],
]
});
}
}
});
}
},
- 說下我和後臺要的資料格式 ,注意這裡寫的我和後臺要,意思就是後臺給我的資料格式是我前端定的,我和他約定要什麼格式,他就得按照這個格式來。不然沒法配合。對吧?
- 最後就是設定定時刷了,核心就是遞迴加定時器,保證資料在上一次沒有請求完成不會發出下次請求,唉,我們的老業務場景了。