echarts-动态加载桑吉图数据

先看示意图:
在这里插入图片描述
以某个商场业态数据举例,默认展示第一层级,有多层级品类字体设置了特殊的蓝色,点击展示对应的下一层级,这种设计思路也是防止全部展示导致图表重叠,而且全部展示也无法突出数据重点。
代码是:

  let box = document.querySelector('.box');
  let e = echarts.init(box);
  let colors = ['#FF9656', '#19C09B', '#4387F0', '#9474E2', '#E96E93', '#FFD300'];
  let data1 = {
    firstList: [
      {
        source: 'all',
        target: ['餐饮', '零售', '休闲娱乐', '生活服务', '文化创意'],
        value: [14, 12, 20, 22, 16]
      }
    ],
    otherList: [
      {
        source: '餐饮',
        target: ['餐1', '餐2'],
        value: [15, 20]
      },
      {
        source: '休闲娱乐',
        target: ['乐1', '乐2'],
        value: [18, 21]
      },
      {
        source: '餐1',
        target: ['餐1_1', '餐1_2'],
        value: [12, 20]
      },
      {
        source: '乐1',
        target: ['乐1_1', '乐1_2'],
        value: [30, 15]
      }
    ]
  };

  let allName = [];
  let links = [];
  let labelStatus = {};

  // 添加第一层数据
  addData(data1.firstList, true);

  let option = {
    color: [
      // '#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'
    ],
    tooltip: {
      trigger: 'item',
      // triggerOn: 'mousemove'
    },
    animation: false,
    series: [
      {
        type: 'sankey',
        bottom: 90,
        top: 20,
        right: 20,
        left: 20,
        nodeWidth: 20,
        nodeAlign: 'left',
        draggable: false,
        focusNodeAdjacency: false,
        orient: 'vertical',
        data: allName,
        links: links,
        label: {
          position: 'bottom',
          formatter: function (val) {
            if (val.name === 'all') return '';
            if (labelStatus[val.name]['hasNextStep']) {
              return [
                '{value| '+labelStatus[val.name]['value']+'% }',
                '{hasNextStepName| ' + labelStatus[val.name]['name'] + '}'
              ].join('\n')
            } else {
              return [
                '{value| '+labelStatus[val.name]['value']+'% }',
                '{notNextStepName| ' + labelStatus[val.name]['name'] + '}'
              ].join('\n')
            }
          },
          rich: {
            value: {
              fontSize: 18,
              height: 25,
              align: "center"
            },
            hasNextStepName: {
              fontSize: 14,
              align: "center",
              color: '#4A90E2'
            },
            notNextStepName: {
              fontSize: 14,
              align: "center",
              color: '#000'
            }
          }
        }
      }
    ]
  };

  // resetCharts();

  e.setOption(option);

  e.on('click', function (obj) {

    if (obj.name === 'all') return;

    // 判断是否在图表显示,显示就隐藏
    let hasin = removeList(obj.name, data1.otherList);
    resetCharts();
    if (hasin !== -1) return;

    // 判断有没有下一级
    let status = data1.otherList.findIndex((val, index) => {
      return val.source === obj.name;
    });
    if (status !== -1) {
      // 加入下一级
      addData([data1.otherList[status]], false);

      // 如果点击第二级 计算排它
      let isSecond = data1.firstList[0].target.findIndex((val, index) => {
        return val === obj.name;
      });
      if (isSecond !== -1) {
        data1.firstList[0].target.forEach((v, i) => {
          if (v === obj.name) return;
          removeList(v, data1.otherList);
        });
      }

      box.style.height = '700px';
      resetCharts();
    }

  });

  function unique(points) {
    let result = [];
    let obj = {};
    for (let i = 0; i < points.length; i++) {
      if (!obj[points[i].name]) {
        result.push(points[i]);
        obj[points[i].name] = true;
      }
    }
    return result;
  }

  function removeList(name, otherList) {
    let statusHas = links.findIndex((val, index) => {
      return val.source === name;
    });

    if (statusHas !== -1) {
      links = links.filter((val, index) => {
        return val.source !== name;
      });

      let indexPos = otherList.findIndex((val, index) => {
        return val.source === name;
      });

      allName = allName.filter((val, index) => {
        return otherList[indexPos].target.indexOf(val.name) === -1;
      });

      // 判断子集的子集是否在 links中 有删除
      otherList[indexPos].target.forEach((v, i) => {
        removeList(v, otherList);
      });
    }
    return statusHas;
  }

  function resetCharts() {
    option.series[0].data = allName;
    option.series[0].links = links;
    e.resize();
    e.setOption(option);
  }

  function addData(arr, status) {
    arr.forEach((v, i) => {
      // 首次加载
      if (status) {
        allName.push({
          name: v.source,
          itemStyle: {
            color: '#C1CAE1',
            borderColor: 'transparent'
          }
        });
        labelStatus[v.source] = {
          name: v.source,
          hasNextStep: true,
          value: ''
        };
      }
      v.target.forEach((val, index) => {

        // 判断是否有下一级
        let hasEle = data1.otherList.findIndex((value, ind) => {
          return value.source === val
        });

        if (hasEle === -1) {
          labelStatus[val] = {
            name: val,
            hasNextStep: false,
            value: v.value[index]
          }
        } else {
          labelStatus[val] = {
            name: val,
            hasNextStep: true,
            value: v.value[index]
          }
        }

        allName.push({
          name: val,
          itemStyle: {
            color: colors[index],
            borderColor: 'transparent'
          }
        });
        links.push({
          source: v.source,
          target: val,
          value: v.value[index],
          lineStyle: {
            color: {
              type: 'linear',
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                {
                  offset: 0,
                  color: 'rgba(181, 191, 214, 0.5)' // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: 'rgba(226, 234, 249, 0.3)' // 100% 处的颜色
                }
              ],
              global: false // 缺省为 false
            },
            opacity: 1,
            curveness: 0.5
          }
        });
      })
    });
  }

全部代码都在这了,直接复制到项目中即可看到效果。

猜你喜欢

转载自blog.csdn.net/weixin_44384273/article/details/132992272