使用 Lodash 工具後代碼行數瞬間縮短---

作者:Timor

來源:SegmentFault 思否社區

背景
最近在做報表. 涉及到 echarts 圖表. 多層柱狀圖疊加展示. 然後後端給出來的結構是二維數組. 需要前端自行處理成圖表可用的數據格式. echarts 數據是是動態的。
需求效果圖的樣子:

echarts 相似的官網案例代碼:

option = {
    tooltip: {
        trigger: 'axis',
    },
    legend: {
        data: ['Direct''Mail Ad''Affiliate Ad''Video Ad''Search Engine']
    },
  
    xAxis: {
        type: 'category',
        data: ['Mon''Tue''Wed''Thu''Fri''Sat''Sun']
    },
    yAxis: [
        {
          splitLine: {
            show: false, //去掉網格線
          },
          axisTick: {
            show: true,
            length: 4,
            lineStyle: {
              color: '#D8D8D8',
            },
          },
          axisLabel: {
            show: true,
            color: '#606C7B',
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: '#D8D8D8',
            },
          },
          name: '次數',
          type: 'value',
        },
      ],
    series: [
       
        {
            name: 'A',
            type: 'bar',
            stack: 'total',
            emphasis: {
                focus: 'series'
            },
            data: [320, 302, 301, 334, 390, 330, 320]
        },
        {
            name: 'B',
            type: 'bar',
            stack: 'total',
            emphasis: {
                focus: 'series'
            },
            data: [120, 132, 101, 134, 90, 230, 210]
        },
        {
            name: 'C',
            type: 'bar',
            stack: 'total',
            emphasis: {
                focus: 'series'
            },
            data: [220, 182, 191, 234, 290, 330, 310]
        },
    ]
};

官網的代碼實現示例圖 :

由此可以看到. 需要的 series 裏的數據結構是這樣的:

{
            name: 'C',  //等級名稱
            type: 'bar',
            stack: 'total',
            emphasis: {
                focus: 'series'
            },
            data: [220, 182, 191, 234, 290, 330, 310]  //對應的每一天的值
      },

開始我的數據處理路程

var data = [
  {
    dt: 1,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 1,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 1,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 1,
    priority: "無",
    call_day_cnt: 0,
  },
  {
    dt: 2,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 2,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 2,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 2,
    priority: "無",
    call_day_cnt: 0,
  },
  {
    dt: 3,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 3,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 3,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 3,
    priority: "無",
    call_day_cnt: 0,
  },
  {
    dt: 4,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 4,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 4,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 4,
    priority: "無",
    call_day_cnt: 0,
  },
  {
    dt: 5,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 5,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 5,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 5,
    priority: "無",
    call_day_cnt: 0,
  },
  {
    dt: 6,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 6,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 6,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 6,
    priority: "無",
    call_day_cnt: 0,
  },
  {
    dt: 7,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 7,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 7,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 7,
    priority: "無",
    call_day_cnt: 0,
  },
  {
    dt: 8,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 8,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 8,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 8,
    priority: "無",
    call_day_cnt: 0,
  },
  {
    dt: 9,
    priority: "A級-高潛",
    call_day_cnt: 0,
  },
  {
    dt: 9,
    priority: "B級-普通",
    call_day_cnt: 0,
  },
  {
    dt: 9,
    priority: "V級-重要",
    call_day_cnt: 0,
  },
  {
    dt: 9,
    priority: "無",
    call_day_cnt: 0,
  }]

我的處理思路:

  1. 先拿到所有的等級 (不同的人看到的等級是不同的, 但是每一天的等級會是一致的) 搭建好等級外層數據結構. 一個唯一鍵, 一個等級名稱, 一個等級對應的每天的值 data.
var data =[ key: 'levelList' + index, value: item.priority, data: [] ]
  1. 遍歷成圖表所需的數據格式, 先按照 priority 去分類. 再塞進創建好的等級對應的 data 中.
//用data存一下後端返回的值
    var data = this.reportList || [];
    //創建外層等級殼子
    var level = [];
    data.map((item, index) ={
      if (item.dt == 1) {
        level.push({
          key: 'levelList' + index,
          value: item.priority,
          data: [],
        });
      }
    });
    //分組
    var json = {};
    for (let i = 0; i < data.length; i++) {
      if (!json.hasOwnProperty(data[i].priority))json[data[i].priority] = [];
      level.map(item => item.value === data[i].priority && item.data.push(data[i]));
    }

最後得到的數據結構:

這樣寫是可以拿到, 但是寫法不是很好.

直到同事給我安利了 Lodash 工具... 真的香...

首先項目裏安裝一下:
npm install lodash
然後 js 裏面引用一下:
import _ from 'lodash'
然後就可以使用了:

 //用data存一下後端返回的值
 var data = this.reportList || [];
 //priority是分組字段
 const a = _.groupBy(data,'priority')
 console.log('a--------',a)

結果:

後端應該給出唯一鍵非中文的用來分組的. 如果沒有給的話. 分組後的名字默認就是分組關鍵字. 這時候自己再稍微處理下也可以. 例如 :

 //用data存一下後端返回的值
 var data = this.reportList || [];
//創建外層等級殼子
    var level = [];
    data.map((item, index) ={
      if (item.dt == 1) {
        level.push({
          key: 'levelList' + index,
          value: item.priority,
          data: [],
        });
      }
    });
    //分組
    const groupList = _.groupBy(data,'priority')
    for(var i in groupList){
      level.map(item => item.value === groupList[i].key && item.data.push(data[i]));
    }
    console.log('level-----------',level)

最後結果 :

最後貼出來這個 echarts 圖的整體數據吧

//日均call數
  setDayNumChart=()=>{
    //data保存從後端取回的數據
    var data = this.reportList?.dt_priority_m || [];
    //創建外層等級殼子
    var level = [];
    data.map((item, index) ={
      if (item.dt == 1) {
        level.push({
          key: 'levelList' + index,
          value: item.priority,
          data: [],
        });
      }
    });
    //分組
    const groupList = _.groupBy(data,'priority')
    for(var i in groupList){
      level.map(item => item.value === groupList[i].key && item.data.push(data[i]));
    }
    //抽出series
    var seriesData = [];
    level.map((item) ={
      seriesData.push({
        name: item.value,
        type: 'bar',
        stack: '級別',
        barWidth: '30%',
        emphasis: {
          focus: 'series',
        },
        data: item.data.map((item) => item.call_day_cnt),
      });
    });
   // 提取出X軸的值
    var date = []
    level && level[0].data.map(item ={
      date.push(item.dt)
    })
    // echarts賦值
    this.dayNumChart = {
      title: {
        text: '日均Call數',
        textStyle: {
          show: true,
          color: '#C3C7CC',
          fontSize: 16,
          fontWeight: 400,
        },
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow',
        },
      },
      legend: {
        bottom: 0,
        data: level.map((item) => item.value),
      },
      xAxis: [
        {
          type: 'category',
          axisTick: {
            alignWithLabel: true,
            length: 3,
            lineStyle: {
              color: '#D8D8D8',
            },
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: '#D8D8D8',
            },
          },
          axisLabel: {
            show: true,
            color: '#606C7B',
          },
          data: date,
        },
      ],
      yAxis: [
        {
          splitLine: {
            show: false, //去掉網格線
          },
          axisTick: {
            show: true,
            length: 4,
            lineStyle: {
              color: '#D8D8D8',
            },
          },
          axisLabel: {
            show: true,
            color: '#606C7B',
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: '#D8D8D8',
            },
          },
          name: '次數',
          type: 'value',
        },
      ],
      // 滑動
      dataZoom: [
        {
          show: true, // 是否顯示
          start: 0, // 伸縮條開始位置(1-100),可以隨時更改
          type: 'inside',
          throttle: 40,
          endValue: 5,
        },
      ],
      series: seriesData,
    };
  }
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/gRP6A2Cg6nbyNfUmTJi_dA