index.vue 2.52 KB
<script lang="ts" setup>
import { computed, onMounted, onUnmounted, ref, unref } from 'vue'
import { init } from 'echarts'
import type { ECharts, EChartsOption } from 'echarts'
import { defaultOption } from './index.config'
import type { CreateComponentType, RenderComponentExposeType } from '@/core/Library/types'
import { useOnMessage } from '@/core/Library/hook/useOnMessage'
import type { NodeDataDataSourceJsonType } from '@/api/node/model'
import { SocketSubscriberEnum } from '@/enums/datasource'
import type { SubscriptionData } from '@/core/websocket/type/message'
import { formatToDateTime } from '@/utils/dateUtil'
import type { CommandSource } from '@/core/websocket/processor'

const props = defineProps<{
  config: CreateComponentType
}>()

const getCellBounds = computed(() => props.config.cellBounds || { width: 300, height: 300, x: 0, y: 0 })

const chartElRef = ref<Nullable<HTMLDivElement>>()

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

function initChartInstance() {
  chartInstance.value = init(unref(chartElRef))
  chartInstance.value.setOption(defaultOption)
}

const handleHistoryData = (commandSource: CommandSource, message: SubscriptionData) => {
  const { data } = commandSource
  const { attrInfo, deviceInfo, attr } = data as NodeDataDataSourceJsonType
  const { deviceName } = deviceInfo || {}

  const historyData = message[attr]
  const xAxisData: string[] = []
  const seriesData: number[] = []

  for (const item of historyData) {
    const [ts, value] = item
    xAxisData.push(formatToDateTime(ts))
    seriesData.push(value)
  }

  unref(chartInstance)?.setOption({
    title: {
      text: `${deviceName || ''}-${attrInfo.name || ''}`,
    },
    xAxis: { data: xAxisData },
    series: { data: seriesData },
  } as EChartsOption)
}

const { onMessage } = useOnMessage({
  onReceiveDataSourceMessage(commandSource, message) {
    const { data } = commandSource
    const { chartOption } = data as NodeDataDataSourceJsonType
    const { queryType } = chartOption || {}

    if (queryType === SocketSubscriberEnum.HISTORY_CMDS)
      handleHistoryData(commandSource, message.data)
  },
})

onMounted(() => {
  initChartInstance()
})

onUnmounted(() => {
  chartInstance.value?.dispose()
  chartInstance.value = null
})

defineExpose<RenderComponentExposeType>({ onMessage })
</script>

<template>
  <div class="w-full h-full justify-center flex items-center">
    <div
      ref="chartElRef"
      :style="{ width: `${getCellBounds.width}px`, height: `${getCellBounds.height}px` }"
      class="w-full h-full"
    />
  </div>
</template>