1. 程式人生 > >【echarts】用地圖模組做動態流程圖2.0(根據後臺資料自動均勻排布,且實時更新節點狀態)

【echarts】用地圖模組做動態流程圖2.0(根據後臺資料自動均勻排布,且實時更新節點狀態)

1.效果

0

2.說明

  • 這個升級版幾乎就是我們公司用的這個功能了,設計到的功能就是可以根據後臺資料重新進行位置排布,且實時重新整理節點的資料。用ec寫出這個效果不難,參考demo1
  • 這個主要是設計到如何根據資料進行重新排布,實時刷資料,這些都是ec外掛沒有的,需要我們去苦逼手寫的。

3.程式碼:

3.1要知道的:

  • 其實在敲程式碼前,就應該意識到和後臺要的資料是什麼樣的,要知道我們是用地圖模組實現的,所以節點的定位就要設計到座標,而這個座標是後臺不會給我們的,他只會給我們這些個節點的基本資訊,狀態,來自哪個節點,要去哪個節點。換句話說,就是這個節點的定位是需要我們算的。
  • OK,既然是我們算,就要知道,我們算的這個地圖的模組的邊界大小和起始點。這裡我用的世界地圖,沒有用中國地圖,是有原因的。這就是說到我們的邊界和起始點。世界地圖的邊界和起始點比較好設定和計算,都是整數,而中國地圖首先得合理的把中國地圖放大,找到起始點座標和邊界大小,雖然說後面的計算方法和世界地圖的計算是一樣的,但是找起始點就噁心的很,所以強烈建議用世界地圖。
  • 世界地圖的起始點和邊界:

aa

  • 資料也不難找 中心點座標是[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],
                    ]
                  });
                }

              }



            });
          }
        },
  • 說下我和後臺要的資料格式 ,注意這裡寫的我和後臺要,意思就是後臺給我的資料格式是我前端定的,我和他約定要什麼格式,他就得按照這個格式來。不然沒法配合。對吧?
  • 最後就是設定定時刷了,核心就是遞迴加定時器,保證資料在上一次沒有請求完成不會發出下次請求,唉,我們的老業務場景了。