echarts堆叠柱状图Y轴动态适应-vue3

141 阅读1分钟

一、前言

echarts堆叠柱状图点了图例后,Y轴的数值,没有动态更新~,具体现象如下:⬇️

image.png

点击图例后⬇️

image.png

二、解决办法

用echarts官方提供的切换图例选中状态后的事件,图例切换后,前端通过总数数值计算,重新绘制图形~

三、代码

3.1 原代码

<template>
    <div class="chart" id="distributionChart" :style="{ width: '100%', height: '300px' }"></div>
</template>

defineOptions({
  name: 'GraphAlertDistribution'
});

const props = defineProps({
  alertEventId: {
    type: [String, Number]
  }
});

const chart = ref(null);
const chartData = ref([]);

onMounted(() => {
  nextTick(() => {
    drawAppChart(true);
  });
});

const getOptions = (data = []) => {
  let dates = [];
  let alertNums = [];
  let critNums = [];
  let highNums = [];
  let noticeNums = [];
  let warnNums = [];
  // 处理后端返回的数据
  data.forEach((item) => {
    dates.push(item.date);
    alertNums.push(item.alertNum);
    critNums.push(item.critNum);
    highNums.push(item.highNum);
    noticeNums.push(item.noticeNum);
    warnNums.push(item.warnNum);
  });
  // 堆叠柱状图配置
  const options = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      },
      formatter: function (params) {
        const item = chartData.value[params[0].dataIndex];
        return `<p>${item.date}</p><p>总数:${item.alertNum}</p><p>crit:${item.critNum}</p><p>high:${item.highNum}</p><p>warn:${item.warnNum}</p><p>notice:${item.noticeNum}</p>`;
      }
    },
    legend: {
      data: ['crit', 'high', 'warn', 'notice']
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
      {
        type: 'category',
        data: dates,
        axisLabel: {
          interval: 0,
          rotate: 40
        }
      }
    ],
    yAxis: [
      {
        type: 'value'
      }
    ],
    series: [
      {
        name: 'crit',
        type: 'bar',
        stack: 'Ad',
        emphasis: {
          focus: 'series'
        },
        data: critNums,
        itemStyle: {
          color: '#ee6666'
        }
      },
      {
        name: 'high',
        type: 'bar',
        stack: 'Ad',
        emphasis: {
          focus: 'series'
        },
        data: highNums,
        itemStyle: {
          color: '#fac858'
        }
      },
      {
        name: 'warn',
        type: 'bar',
        stack: 'Ad',
        emphasis: {
          focus: 'series'
        },
        data: warnNums,
        itemStyle: {
          color: '#5470c6'
        }
      },
      {
        name: 'notice',
        type: 'bar',
        stack: 'Ad',
        emphasis: {
          focus: 'series'
        },
        data: noticeNums,
        itemStyle: {
          color: '#91cc75'
        }
      },
      {
        name: '总计',
        type: 'bar',
        stack: '',
        data: alertNums,
        label: {
          show: true,
          position: 'top',
          color: '#000'
        },
        z: -1,
        barGap: '-100%',
        itemStyle: {
          color: '#fff'
        }
      }
    ]
  };
  return options;
};

const drawAppChart = async () => {
  // 发接口拿数据
  const { content = [] } = await api.XXXXXX();
  chartData.value = content;
  chart.value = initChart(content);
};

const initChart = (data) => {
  let chart = echarts.init(document.getElementById('distributionChart'));
  // 把配置和数据放这里
  const options = getOptions(data);
  chart.setOption(options);
  window.onresize = function () {
    //自适应大小
    chart.resize();
  };

  return chart;
};
</script>
<style lang="scss" scoped>
.chart {
  margin-top: 10px;
}
</style>

3.2添加legendselectchanged事件后的代码:


const initChart = (data) => {
  let originalData = [...chartData.value]; // 保存原始数据
  let chart = echarts.init(document.getElementById('distributionChart'));
  // 把配置和数据放这里
  const options = getOptions(data);
  chart.setOption(options);
  window.onresize = function () {
    //自适应大小
    chart.resize();
  };
   
  // 图例组件用户切换图例开关会触发该事件
  chart.on('legendselectchanged', (obj) => {
    // 根据图例情况计算alertNum
    let updatedData = originalData.map((item) => {
      let newAlertNum =
        item.critNum * obj.selected.crit +
        item.highNum * obj.selected.high +
        item.noticeNum * obj.selected.notice +
        item.warnNum * obj.selected.warn;
      return {
        ...item,
        alertNum: newAlertNum
      };
    });
    // 重新渲染柱状图
    const newOptions = getOptions(updatedData);
    chart.setOption(newOptions);
  });

  return chart;
};

四、效果

image.png

image.png

image.png