echart legend 的使用及离开界面图表全局销毁

 父组件

<template>
  <AbnormalAlarmStatistics ref="abnormalAlarmStatistics" />
</template>
<script setup>
import {
  ref,
  reactive,
  computed,
  onMounted,
  getCurrentInstance,
  watch
} from "vue";

const { proxy } = getCurrentInstance();
const getQualityAnalysisHistory = () => {
  // 异常预警统计
  let warningData = [
    {
      id: 1,
      name: "预警1",
      value: 0,
    },
    {
      id: 2,
      name: "预警2",
      value: 0,
    },
    ...
    {
      id: 40,
      name: "预警40",
      value: 0,
    },
  ];
  proxy.$refs["abnormalAlarmStatistics"].initChart(warningData);
};
onMounted(() => {
  getQualityAnalysisHistory();
});
</script>

子组件

<template>
    <el-card shadow="never" class="statistics">
      <h4>异常报警统计</h4>
      <div ref="chart" class="chart" style="width: 100%; height: 310px;"></div>
    </el-card>
</template>

<script setup>
import { getCurrentInstance, ref } from "vue";
import * as echarts from "echarts";
import { useEcharts } from "@/hooks/useEcharts.js";
/**
 * 初始化值
 */
const { proxy } = getCurrentInstance();
const initChart = (type) => {
  let myChart = echarts.init(proxy.$refs.chart);
  // 图表数据
  const chartData = ref(type);
  //总数
  let sum = chartData.value.reduce((a, b) => {
    return a + b.value;
  }, 0);

  let option = {
    tooltip: {
      trigger: "item",
    },
    legend: [
    {
      icon: "rect",
        top: 20,
        right: '12%',
        itemHeight: 10,
        itemWidth: 10,
        itemGap: 14,
        type: 'scroll',
        orient: "vertical",
        pageIconColor: '#1b9aee', //翻页下一页的三角按钮颜色
        pageIconInactiveColor: '#7f7f7f', //翻页(即翻页到头时)
        data: chartData.value.map((v) => v.name),
        textStyle: {
          rich: {
            uname: {
              color: "#333333",
              fontSize: 14,
              width: 80
            },
            unum: {
              color: "#333333",
              fontWeight: "bold",
              fontSize: 14,
              align: "right",
            },
          },
        },
        formatter(name) {
          let res = chartData.value.filter((v) => v.name == name);
          return `{uname|${name}}{unum|${res[0].value}}`;
        },
      }
    ],
    color: [
      "#0058FF",
      "#D33232",
      "#FFFF02",
      "#FF9402",
      "#00EBFF",
      "#FFC608",
      "#00AF75",
      "#9E46DE",
      "#F06856",
      "#0BB1D0",
    ],
    series: [
      {
        type: "pie",
        radius: [65, 80],
        center: ["30%", "45%"],
        avoidLabelOverlap: false,
        label: {
          normal: {
            show: true,
            position: "center",
            color: "#4c4a4a",
            formatter: "{total|" + sum + "}" + "\n\r" + "{active|报警总数(次)}",
            rich: {
              total: {
                fontSize: 20,
                color: "#333333",
                fontWeight: "bold",
              },
              active: {
                fontSize: 14,
                color: "#333333",
                padding: [7, 0, 0, 0],
              },
            },
          },
          emphasis: {
            //中间文字显示
            show: true,
          },
        },
        labelLine: {
          show: false,
        },
        itemStyle: {
          borderWidth: 0,
          borderColor: "#fff",
        },
        data: chartData.value,
      },
    ],
  };

  useEcharts(myChart, option);
};
defineExpose({ initChart });
</script>
<style lang="scss" scoped>
.statistics {
  height: 364px;
}
</style>

公共方法,用于图表 resize 和 销毁
useEcharts.js

import { onBeforeUnmount, onDeactivated  } from "vue";
// import * as echarts from "echarts";

/**
 * @description 使用 Echarts (只是为了添加图表响应式)
 * @param {Element} myChart Echarts实例 (必传)
 * @param {Object} options 绘制Echarts的参数 (必传)
 * */
// 全局ECharts实例的容器
let globalEChartsInstances = new Set();
export const useEcharts = (myChart, options) => {
  if (options && typeof options === "object") {
    myChart.setOption(options,true);
    globalEChartsInstances.add(myChart);
  }/*  */
  const echartsResize = () => {
    myChart && myChart.resize();
  };

  window.addEventListener("resize", echartsResize);

  // 防止 echarts 页面 keepAlive 时,还在继续监听页面
  onDeactivated(() => {
    window.removeEventListener("resize", echartsResize);
  });
  // onBeforeUnmount(() => {
  //   window.removeEventListener("resize", echartsResize);
  //   myChart.dispose()
  // });
};
// 销毁所有ECharts实例的函数
export const destroyAllECharts = () => {
  globalEChartsInstances.forEach(chart => {
    chart.dispose();
  });
  globalEChartsInstances.clear();
}
//*暴露所有的echarts实例
export default globalEChartsInstances;

全局监听路由变化,销毁图表

router.beforeEach(async (to, from, next) => {
    //*当前路由和跳转路由不一致时,有echarts实例就销毁
    if(to.path !== from.path) {
      if(globalEChartsInstances?.size > 0) destroyAllECharts(); // 当即将离开当前路由时销毁全 
       局ECharts实例
    }
  }
});

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值