index.vue 2.41 KB
<script lang="ts" setup>
import { computed, onMounted, ref, unref } from 'vue'
import { init } from 'echarts'
import type { ECharts, EChartsOption } from 'echarts'
import { getDefaultOption } from './index.config'
import type { CreateComponentType, RenderComponentExposeType } from '@/core/Library/types'
import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue'
import { useOnMessage } from '@/core/Library/hook/useOnMessage'
import type { CommandSource } from '@/core/websocket/processor'
import type { NodeDataDataSourceJsonType } from '@/api/node/model'
import type { SubscriptionUpdateMsg } from '@/core/websocket/type/message'
import { useContentDataStore } from '@/store/modules/contentData'
import { useProductsStore } from '@/store/modules/products'

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>>()

const contentDataStore = useContentDataStore()

const productsStore = useProductsStore()

function initChartInstance() {
  chartInstance.value = init(unref(chartElRef))
  const currentNodeData = unref(contentDataStore.getCurrentNodeDataById(props.config))

  chartInstance.value.setOption(getDefaultOption(currentNodeData?.dataSourceJson.chartOption?.unit))
}

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

const onReceiveDataSourceMessage = (commandSource: CommandSource, message: SubscriptionUpdateMsg) => {
  const { data } = commandSource
  const { attr, deviceName, deviceProfileId } = data as NodeDataDataSourceJsonType
  const { functionName } = productsStore.getObjectModelByIdWithIdentifier(deviceProfileId, (attr) as string) || {}
  const { latestValue } = useLatestMessageValue(message.data, (attr as string))
  unref(chartInstance)?.setOption({
    series: [{
      data: [{ value: latestValue ?? 0 }],

    }],
    title: {
      text: `${deviceName || ''}- ${functionName || ''} `,
    },
  } as EChartsOption)
}

const { onMessage } = useOnMessage({ onReceiveDataSourceMessage })

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>