DashBoardComponent.vue 5.25 KB
<script lang="ts" setup>
  import type { ECharts, EChartsOption } from 'echarts';
  import { PropType, watch } from 'vue';
  import { nextTick, onMounted, onUnmounted, ref, unref, computed } from 'vue';
  import { init } from 'echarts';
  import {
    DashboardComponentLayout,
    DashBoardValue,
    instrumentComponent1,
    InstrumentComponentType,
    update_instrument_1_font,
    update_instrument_2_font,
    update_instrument_1_value,
    update_instrument_2_value,
  } from './dashBoardComponent.config';
  import { dateUtil } from '/@/utils/dateUtil';
  import {
    DEFAULT_RADIO_RECORD,
    RadioRecord,
    DEFAULT_DATE_FORMAT,
    fontSize,
  } from '../../detail/config/util';
  import { Tooltip } from 'ant-design-vue';
  import { useThrottleFn } from '@vueuse/shared';

  const props = defineProps({
    add: {
      type: Function,
    },
    layout: {
      type: Object as PropType<DashboardComponentLayout>,
      default: () => ({}),
    },
    value: {
      type: Object as PropType<DashBoardValue>,
      default: () => ({}),
    },
    radio: {
      type: Object as PropType<RadioRecord>,
      default: () => DEFAULT_RADIO_RECORD,
    },
    random: {
      type: Boolean,
      default: true,
    },
  });

  const getControlsWidgetId = () => `widget-chart-${props.value.id}`;

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

  function initChart() {
    const chartDom = document.getElementById(getControlsWidgetId())!;
    chartRef.value = init(chartDom);
    const option: EChartsOption = props.layout.chartOption || instrumentComponent1();

    nextTick(() => {
      option && unref(chartRef)?.setOption(option);
    });
  }

  const getRadio = computed(() => {
    const { radio } = props.radio;
    return radio;
  });

  const beforeUpdateFn = (componentType: InstrumentComponentType) => {
    if (componentType === 'instrument-component-1') return update_instrument_1_font;
    if (componentType === 'instrument-component-2') return update_instrument_2_font;
    return (_radio: number) => {};
  };

  function update() {
    const option = beforeUpdateFn(props.layout.componentType);
    unref(chartRef)?.setOption((option(unref(getRadio)) as unknown as EChartsOption) || {});
    unref(chartRef)?.resize();
  }

  const getUpdateValueFn = (componentType: InstrumentComponentType) => {
    if (componentType === 'instrument-component-1') return update_instrument_1_value;
    if (componentType === 'instrument-component-2') return update_instrument_2_value;
    return (_radio: DashBoardValue) => {};
  };

  const updateChartValue = useThrottleFn(() => {
    const updateFn = getUpdateValueFn(props.layout.componentType);
    unref(chartRef)?.setOption((updateFn(props.value) as unknown as EChartsOption) || {});
  }, 500);

  watch(() => props.value, updateChartValue);

  // watch(
  //   () => [props.value.gradientInfo, props.value.unit, props.value.valueColor, props.value.name],
  //   updateChartValue
  // );

  const updateChartFont = useThrottleFn(() => {
    const option = beforeUpdateFn(props.layout.componentType);
    setTimeout(() => {
      unref(chartRef)?.setOption((option(unref(getRadio)) as unknown as EChartsOption) || {});
    });
  }, 500);

  watch(() => props.radio, updateChartFont);

  const updateChartType = useThrottleFn(() => {
    unref(chartRef)?.clear();
    unref(chartRef)?.setOption(props?.layout?.chartOption || {});
  }, 500);

  watch(() => props.layout.componentType, updateChartType);

  // watch(() => props.value.gradientInfo, updateChartType);

  let timeout: Nullable<number> = null;

  function handleRandomValue() {
    const newValue = Math.floor(Math.random() * 100);
    const updateFn = getUpdateValueFn(props.layout.componentType);
    unref(chartRef)?.setOption(
      (updateFn({ ...props.value, value: newValue }) as unknown as EChartsOption) || {}
    );
  }

  onMounted(() => {
    initChart();
    props.add && props.add(props.value.id, update);
    if (props.random) timeout = setInterval(handleRandomValue, 2000) as unknown as number;
  });

  onUnmounted(() => {
    unref(chartRef)?.clear();
    clearInterval(timeout as number);
    timeout = null;
  });

  defineExpose({ update });
</script>

<template>
  <div class="flex flex-col w-full h-full min-w-3 min-h-3">
    <div :id="getControlsWidgetId()" class="widget-charts w-full h-full flex-auto"></div>
    <div>
      <div
        class="text-center"
        :style="{ fontSize: fontSize({ radio: getRadio, basic: 16, max: 18 }), color: '#666' }"
      >
        {{ props.value.name }}
      </div>
      <Tooltip
        placement="top"
        :title="
          props.value?.updateTime
            ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT)
            : '暂无更新时间'
        "
      >
        <div
          class="text-xs text-center truncate p-5"
          :style="{ fontSize: fontSize({ radio: getRadio, basic: 12, max: 12 }), color: '#999' }"
        >
          <span class="mr-2">更新时间:</span>
          <span>
            {{
              props.value?.updateTime
                ? dateUtil(props?.value?.updateTime).format(DEFAULT_DATE_FORMAT)
                : '暂无更新时间'
            }}
          </span>
        </div>
      </Tooltip>
    </div>
  </div>
</template>

<style scoped>
  .widget-charts > div {
    width: 100%;
    height: 100%;
  }
</style>