PieChartDeviceStatus.vue 4.38 KB
<template>
  <a-row type="flex" justify="space-between" align="middle">
    <a-col
      class="flex items-center"
      v-for="(item, index) in seriesStatusData"
      :key="index"
      :span="8"
    >
      <a-col
        :id="`chartPie${item.key}`"
        style="width: 10rem; height: 12rem; position: relative; top: -0.7rem"
      />
    </a-col>
  </a-row>
</template>
<script lang="ts">
  import {
    defineComponent,
    PropType,
    onMounted,
    toRefs,
    shallowReactive,
    onUnmounted,
    nextTick,
    computed,
    watch,
  } from 'vue';
  import * as echarts from 'echarts';
  import { seriesDataT } from './props';
  import { useAppStore } from '/@/store/modules/app';
  import { useI18n } from '/@/hooks/web/useI18n';

  export default defineComponent({
    props: {
      seriesStatusData: {
        type: Array as PropType<seriesDataT[]>,
        default: () => [],
      },
    },

    setup(props) {
      const appStore = useAppStore();
      const skinName = computed(() => {
        return appStore.getDarkMode === 'light' ? '#ffffff' : '#151515';
      });

      const { t } = useI18n();
      const chartsInstance = shallowReactive<{ [key: string]: echarts.ECharts }>({});

      const { seriesStatusData } = toRefs(props);

      watch(
        () => appStore.getDarkMode,
        (target) => {
          const backgroundColor = target === 'light' ? '#ffffff' : '#151515';
          for (const item of seriesStatusData.value) {
            const { key } = item;
            chartsInstance[key!]?.setOption({ backgroundColor });
          }
        },
        {
          immediate: true,
        }
      );

      const total = seriesStatusData.value
        .map((m) => m.value)
        .reduce((prev, cur) => prev! + cur!, 0);

      nextTick(() => {
        for (const item of seriesStatusData.value) {
          const { key, value } = item;
          //牵引线条颜色
          const labelLine = {
            normal: {
              show: true,
              length: 30,
              length2: 0,
              lineStyle: {
                color: '#808080',
              },
            },
          } as any;
          const legendKey =
            key == 'onLine'
              ? t('home.index.deviceStatus.online')
              : key == 'offLine'
              ? t('home.index.deviceStatus.offline')
              : t('home.index.deviceStatus.inactive');
          chartsInstance[key!] = echarts.init(
            document.getElementById(`chartPie${key}`) as HTMLElement
          );
          const option = {
            backgroundColor: skinName.value,
            tooltip: {
              trigger: 'item',
              formatter: `${legendKey}${t('home.index.device')}${(
                (!value ? 0 : value! / total!) * 100
              ).toFixed(2)}%`,
            },
            graphic: [
              {
                type: 'text',
                left: '42%',
                top: '48%',
                z: 10,
                style: {
                  width: 35,
                  textAlign: 'left',
                  overflow: 'truncate',
                  textVerticalAlign: 'middle',
                  fill: '#1a1a1a',
                  text: value + t('home.index.a'),
                  font: '0.85rem Microsoft YaHei',
                },
              },
            ],
            series: [
              {
                data: [item],
                avoidLabelOverlap: false,
                type: 'pie',
                radius: ['40%', '60%'],
                label: {
                  normal: {
                    show: true,
                    position: 'outer',
                    formatter: `${legendKey}${((!value ? 0 : value! / total!) * 100).toFixed(2)}%`,
                    borderWidth: 5,
                    borderRadius: 0,
                    padding: [90, -30],
                  },
                },
                labelLine,
              },
            ],
          };
          chartsInstance[key!].setOption(option);
        }
      });

      const resize = (flag) => {
        Object.keys(chartsInstance).forEach((key) => {
          const doFuncKey = chartsInstance[key];
          flag === 'r' ? doFuncKey.resize() : doFuncKey.dispose();
        });
      };

      onMounted(() => {
        window.addEventListener('resize', () => resize('r'));
      });

      onUnmounted(() => {
        window.removeEventListener('resize', () => resize('d'));
      });
    },
  });
</script>