index.vue 6.9 KB
<script lang="ts" setup>
  import { EChartsOption, ECharts, init } from 'echarts';
  import { unref, ref, onMounted, computed, nextTick } from 'vue';
  import { useMultipleDataFetch } from '../../../hook/useSocket';
  import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type';
  import { option } from './config';
  import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime';
  // import { useIntervalFn } from '@vueuse/core';
  import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  import { useComponentScale } from '/@/views/visual/packages/hook/useComponentScale';

  const props = defineProps<{
    config: ComponentPropsConfigType<typeof option>;
  }>();

  const chartRefEl = ref<Nullable<HTMLElement>>(null);

  const chartInstance = ref<Nullable<ECharts>>(null);

  const time = ref<Nullable<number>>(null);

  const getDesign = computed(() => {
    const { option, persetOption } = props.config;
    const { componentInfo, attribute, attributeRename } = option;
    const {
      fontColor: presetFontColor,
      unit: presetUnit,
      pointerColor: presetPointerColor,
      instrumentPanelColor: presetInstrumentPanelColor,
      progressBarCircle: presetProgressBarCircle,
      gradientInfo: presetGradientInfo,
    } = persetOption || {};
    const { unit, fontColor, pointerColor, gradientInfo, progressBarCircle, instrumentPanelColor } =
      componentInfo || {};
    return {
      unit: unit ?? presetUnit,
      fontColor: fontColor ?? presetFontColor,
      attribute: attributeRename || attribute,
      pointerColor: pointerColor ?? presetPointerColor,
      instrumentPanelColor: instrumentPanelColor ?? presetInstrumentPanelColor,
      progressBarCircle: progressBarCircle ?? presetProgressBarCircle,
      gradientInfo: gradientInfo ?? presetGradientInfo,
    };
  });

  const gaugeData = [
    {
      value: 30,
      name: '',
      title: {
        offsetCenter: ['0%', '-35%'],
      },
      detail: {
        valueAnimation: true,
        offsetCenter: ['0%', '-20%'],
      },
    },
    {
      value: 40,
      name: '',
      title: {
        offsetCenter: ['0%', '0%'],
      },
      detail: {
        valueAnimation: true,
        offsetCenter: ['0%', '15%'],
      },
    },
  ];

  const options = (): EChartsOption => {
    const { fontColor } = unref(getDesign);
    return {
      color: ['#ED6C0D', '#D3DB00', '#00F0F0'],
      series: [
        {
          type: 'gauge',
          startAngle: 90,
          endAngle: -270,
          pointer: {
            show: false,
          },
          progress: {
            show: true,
            overlap: false,
            roundCap: true,
            clip: false,
            itemStyle: {
              // borderWidth: 1,
              // borderColor: '#464646',
            },
          },
          axisLine: {
            lineStyle: {
              width: unref(getRatio) ? 25 * unref(getRatio) : 18,
            },
          },
          splitLine: {
            show: false,
            distance: 0,
            length: 10,
          },
          axisTick: {
            show: false,
          },
          axisLabel: {
            show: false,
            distance: 50,
          },
          data: gaugeData,
          title: {
            fontSize: unref(getRatio) ? 14 * unref(getRatio) : 14,
          },
          detail: {
            width: 50,
            height: 16,
            fontSize: unref(getRatio) ? 12 * unref(getRatio) : 12,
            color: fontColor || 'inherit',
            // formatter: `{value} ${unit ?? ''}`,
          },
        },
      ],
    };
  };

  const initial = () => {
    chartInstance.value = init(unref(chartRefEl)! as HTMLElement);
    chartInstance.value.setOption(options());
  };

  // const randomFn = () => {
  //   gaugeData[0].value = +(Math.random() * 100).toFixed(2);
  //   gaugeData[1].value = +(Math.random() * 100).toFixed(2);
  //   useIntervalFn(() => {
  //     unref(chartInstance)?.setOption({
  //       series: [
  //         {
  //           data: gaugeData,
  //           pointer: {
  //             show: false,
  //           },
  //         },
  //       ],
  //     });
  //   }, 3000);
  // };
  const list = ref<any>([]);
  const updateFn: MultipleDataFetchUpdateFn = (message) => {
    const { data = {} } = message;
    const { dataSource } = props.config.option;
    // const dataList = Object.keys(data);
    const dataList = dataSource?.map((item) => item.attribute);
    list.value = dataList?.map((item, index) => {
      return {
        value: data[item][0][1],
        name: item,
        title: {
          color: index == 0 ? '#ED6C0D' : index == 1 ? '#D3DB00' : '#00F0F0',
          offsetCenter: index == 0 ? ['0%', '-35%'] : index == 1 ? ['0%', '0%'] : ['0%', '35%'],
        },
        detail: {
          valueAnimation: true,
          color: index == 0 ? '#ED6C0D' : index == 1 ? '#D3DB00' : '#00F0F0',
          offsetCenter: index == 0 ? ['0%', '-20%'] : index == 1 ? ['0%', '18%'] : ['0%', '50%'],
        },
      };
    });
    dataSource?.forEach((item, index) => {
      list.value.forEach((item1, index1) => {
        if (index == index1) {
          // item1.value = item1.value + item.componentInfo.unit;
          item1.name = item.attributeRename;
          item1.title.color = item.componentInfo.fontColor;
          item1.detail.color = item.componentInfo.fontColor;
          item1.detail.formatter = `{value} ${item.componentInfo.unit ?? ''}`;
        }
      });
    });
    // console.log(message, 'message', dataSource, 'dataSource', list, 'list');
    unref(chartInstance)?.setOption({
      series: [{ data: unref(list), pointer: { show: false } }],
      color: unref(list).map((item) => item.title.color),
    } as EChartsOption);

    // updateChart(isNaN(value as unknown as number) ? 0 : Number(value));
  };

  useMultipleDataFetch(props, updateFn);

  onMounted(() => {
    initial();
    // !props.config.option.uuid && randomFn();
    !props.config.option.uuid;
  });

  const resize = async () => {
    await nextTick();

    // 修改echarts大小
    unref(chartInstance)?.setOption({
      series: [
        {
          title: {
            fontSize: 14 * unref(getRatio),
          },
          detail: {
            fontSize: 14 * unref(getRatio),
          },
          axisLine: {
            lineStyle: {
              width: 25 * unref(getRatio),
            },
          },
        },
      ],
      title: {
        textStyle: {
          fontSize: 12 * unref(getRatio),
        },
      },
    });
    unref(chartInstance)?.resize();
  };

  const { getRatio } = useComponentScale(props, resize);
</script>

<template>
  <main class="w-full h-full flex flex-col justify-center items-center">
    <DeviceName :config="config" />
    <div ref="chartRefEl" class="flex-1 w-full h-full"> </div>
    <div class="text-gray-500 text-xs text-center truncate">{{
      getDesign.attribute || '湿度'
    }}</div>
    <UpdateTime :time="time" />
  </main>
</template>