index.vue 9.25 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';
  import { SeriesOption } from 'echarts/types/dist/shared';

  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 { dataSource = [] } = option || {};
    const {
      fontColor: persetFontColor,
      unit: persetUnit,
      showDeviceName: persetShowDeviceName,
    } = persetOption || {};
    return {
      dataSource: dataSource.map((item) => {
        const { unit, fontColor, showDeviceName } = item.componentInfo || {};
        const { deviceName, deviceRename, attribute } = item;
        return {
          unit: unit ?? persetUnit,
          fontColor: fontColor ?? persetFontColor,
          showDeviceName: showDeviceName ?? persetShowDeviceName,
          attribute,
          deviceName,
          deviceRename,
        };
      }),
    };

    // 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%'],
        // formatter: `{value} ℃`,
      },
    },
    {
      value: 40,
      name: '',
      title: {
        offsetCenter: ['0%', '0%'],
      },
      detail: {
        valueAnimation: true,
        offsetCenter: ['0%', '15%'],
        // formatter: `{value} ℃`,
      },
    },
  ];

  const options = (): EChartsOption => {
    // const { fontColor } = unref(getDesign);
    const { fontColor } = unref(getDesign).dataSource[0] || [];
    return {
      color: ['#377DFF', '#FD666D', '#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) ? 10 * unref(getRatio) : 10,
          },
          detail: {
            width: 50,
            height: 16,
            fontSize: unref(getRatio) ? 10 * unref(getRatio) : 10,
            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 = 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) => {
    //     console.log(item, 'item');
    //     if (index == index1) {
    //       // item1.value = item1.value + item.componentInfo.unit;
    //       item1.name = item.componentInfo.showDeviceName
    //         ? item.deviceRename
    //           ? item.deviceRename
    //           : item.deviceName
    //         : '';
    //       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);

    const { dataSource } = unref(getDesign);
    const series = dataSource.map((item, index) => {
      const { unit, fontColor, showDeviceName, attribute, deviceName, deviceRename } = item;
      const [latest] = data[attribute] || [];
      const [_timespan, value] = latest || [];
      return {
        value,
        name: showDeviceName ? (deviceRename ? deviceRename : deviceName) : '',
        title: {
          color: fontColor,
          offsetCenter: index == 0 ? ['0%', '-35%'] : index == 1 ? ['0%', '0%'] : ['0%', '35%'],
        },
        detail: {
          color: fontColor,
          valueAnimation: true,
          offsetCenter: index == 0 ? ['0%', '-20%'] : index == 1 ? ['0%', '18%'] : ['0%', '50%'],
          formatter: `{value} ${unit ?? ''}`,
        },
      } as SeriesOption['data'];
    });
    // console.log(series, 'series');
    const xAxisData = unref(getDesign).dataSource.map((item: any) => item.fontColor as any);
    unref(chartInstance)?.setOption({
      series: [{ data: series, pointer: { show: false } }],
      color: xAxisData as any,
    });
    // updateChart(series, xAxisData);
  };

  // const updateChart = (data: SeriesOption['data'], xAxisData) => {
  //   unref(chartInstance)?.setOption({
  //     series: [{ data }],
  //     xAxis: { data: xAxisData },
  //   });
  // };

  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: 10 * unref(getRatio),
          },
          detail: {
            fontSize: 10 * 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>