export function useTaskMetrics()

in seatunnel-ui/src/views/task/synchronization-instance/detail/use-task-metrics.ts [31:366]


export function useTaskMetrics() {
  const route = useRoute()
  const { t } = useI18n()
  
  const timeOptions = [
    {
      label: t('project.metrics.last_1_minute'),
      value: '1min',
      getTime: () => [subMinutes(new Date(), 1), new Date()]
    },
    {
      label: t('project.metrics.last_10_minutes'),
      value: '10min',
      getTime: () => [subMinutes(new Date(), 10), new Date()]
    },
    {
      label: t('project.metrics.last_1_hour'),
      value: '1hour',
      getTime: () => [subHours(new Date(), 1), new Date()]
    },
    {
      label: t('project.metrics.last_3_hours'),
      value: '3hours',
      getTime: () => [subHours(new Date(), 3), new Date()]
    },
    {
      label: t('project.metrics.last_1_day'),
      value: '1day',
      getTime: () => [subDays(new Date(), 1), new Date()]
    },
    {
      label: t('project.metrics.last_7_days'),
      value: '7days',
      getTime: () => [subDays(new Date(), 7), new Date()]
    },
    {
      label: t('project.metrics.custom_time'),
      value: 'custom'
    }
  ]

  const variables = reactive({
    readRowCountChartRef: ref(),
    writeRowCountChartRef: ref(),
    readQpsChartRef: ref(),
    writeQpsChartRef: ref(),
    delayChartRef: ref(),
    readRowCountChart: null as echarts.ECharts | null,
    writeRowCountChart: null as echarts.ECharts | null,
    readQpsChart: null as echarts.ECharts | null,
    writeQpsChart: null as echarts.ECharts | null,
    delayChart: null as echarts.ECharts | null,
    metricsData: [] as any[],
    dateRange: null as [number, number] | null,
    selectedTimeOption: '1hour',
    showDatePicker: false,
    timeOptions
  })

  const formatTimeToString = (timestamp: number): string => {
    return format(timestamp, 'yyyy-MM-dd HH:mm:ss')
  }

  const formatTimeData = (data: any[]) => {
    return data.map(item => {
      try {
        const date = new Date(item.createTime)
        return format(date, 'HH:mm:ss')
      } catch (err) {
        console.error('Error formatting time:', err)
        return ''
      }
    })
  }

  const getChartOption = (title: string, data: any[], key: string): EChartsOption => ({
    title: { 
      text: title,
      textStyle: {
        fontSize: 14,
        fontWeight: 'normal'
      },
      left: 'center'
    },
    tooltip: { 
      show: true,
      trigger: 'item',
      axisPointer: {
        type: 'none'
      },
      position: 'top',
      backgroundColor: 'rgba(255, 255, 255, 0.95)',
      borderColor: '#E5E5E5',
      borderWidth: 1,
      padding: [8, 12],
      borderRadius: 4,
      textStyle: {
        color: '#595959',
        fontSize: 13
      },
      formatter: (params: any) => {
        let value = params.value
        if (key.includes('Qps')) {
          value = value.toFixed(2)
        } else if (value >= 10000) {
          value = (value / 10000).toFixed(1) + 'w'
        } else {
          value = Math.round(value)
        }
        
        try {
          const date = new Date(variables.metricsData[params.dataIndex].createTime)
          const fullDateTime = format(date, 'yyyy-MM-dd HH:mm:ss')
          
          return `<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif">
            <div style="color: #8c8c8c; font-size: 12px; margin-bottom: 4px">
              ${fullDateTime}
            </div>
            <div style="display: flex; align-items: center">
              <span style="display: inline-block; width: 6px; height: 6px; border-radius: 50%; background-color: ${params.color}; margin-right: 8px"></span>
              <span style="font-weight: 500">${value}</span>
            </div>
            <div style="font-size: 12px; color: #8c8c8c; margin-top: 4px">
              ${title}
            </div>
          </div>`
        } catch (err) {
          console.error('Error formatting tooltip time:', err)
          return ''
        }
      }
    },
    grid: {
      top: '15%',
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: formatTimeData(data),
      axisLine: {
        lineStyle: {
          color: '#E5E5E5'
        }
      },
      axisLabel: {
        color: '#7F7F7F',
        formatter: (value: string) => {
          return value.substring(value.indexOf(' ') + 1)
        }
      }
    },
    yAxis: { 
      type: 'value',
      splitLine: {
        lineStyle: {
          type: 'dashed',
          color: '#E5E5E5'
        }
      },
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: '#7F7F7F',
        formatter: (value: number) => {
          if (key.includes('Qps')) {
            return value.toFixed(2)
          }
          if (value >= 10000) {
            return (value / 10000).toFixed(1) + 'w'
          }
          return Math.round(value).toString()
        }
      }
    },
    series: [{
      type: 'line',
      data: data.map(item => item[key]),
      smooth: true,
      symbol: 'circle',
      symbolSize: 4,
      showSymbol: true,
      triggerEvent: true,
      emphasis: {
        focus: 'series',
        itemStyle: {
          color: '#1890FF',
          borderWidth: 3,
          borderColor: '#1890FF',
          shadowBlur: 10,
          shadowColor: 'rgba(0, 0, 0, 0.2)'
        }
      },
      itemStyle: {
        color: '#1890FF',
        borderWidth: 1,
        borderColor: '#fff',
        opacity: 0.3
      },
      lineStyle: {
        width: 2
      },
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: 'rgba(24,144,255,0.3)'
          },
          {
            offset: 1,
            color: 'rgba(24,144,255,0.1)'
          }
        ])
      }
    } as LineSeriesOption],
  })

  const initCharts = () => {
    try {
      if (variables.readRowCountChartRef) {
        variables.readRowCountChart?.dispose()
        variables.readRowCountChart = echarts.init(variables.readRowCountChartRef)
      }
      if (variables.writeRowCountChartRef) {
        variables.writeRowCountChart?.dispose()
        variables.writeRowCountChart = echarts.init(variables.writeRowCountChartRef)
      }
      if (variables.readQpsChartRef) {
        variables.readQpsChart?.dispose()
        variables.readQpsChart = echarts.init(variables.readQpsChartRef)
      }
      if (variables.writeQpsChartRef) {
        variables.writeQpsChart?.dispose()
        variables.writeQpsChart = echarts.init(variables.writeQpsChartRef)
      }
      if (variables.delayChartRef) {
        variables.delayChart?.dispose()
        variables.delayChart = echarts.init(variables.delayChartRef)
      }
    } catch (err) {
      console.error('Failed to initialize charts:', err)
    }
  }

  const getChartTitle = (key: string) => {
    return t(`project.task.metrics.${key}`)
  }

  const updateCharts = async () => {
    try {
      const params: any = {
        jobInstanceId: route.query.jobInstanceId as string
      }
      
      if (variables.dateRange) {
        params.startTime = format(variables.dateRange[0], 'yyyy-MM-dd HH:mm:ss')
        params.endTime = format(variables.dateRange[1], 'yyyy-MM-dd HH:mm:ss')
      }

      const res = await queryJobMetricsHistory(params)
      variables.metricsData = res

      if (variables.readRowCountChart) {
        variables.readRowCountChart.setOption(
          getChartOption(getChartTitle('read_row_count'), variables.metricsData, 'readRowCount')
        )
      }
      if (variables.writeRowCountChart) {
        variables.writeRowCountChart.setOption(
          getChartOption(getChartTitle('write_row_count'), variables.metricsData, 'writeRowCount')
        )
      }
      if (variables.readQpsChart) {
        variables.readQpsChart.setOption(
          getChartOption(getChartTitle('read_qps'), variables.metricsData, 'readQps')
        )
      }
      if (variables.writeQpsChart) {
        variables.writeQpsChart.setOption(
          getChartOption(getChartTitle('write_qps'), variables.metricsData, 'writeQps')
        )
      }
      if (variables.delayChart) {
        variables.delayChart.setOption(
          getChartOption(getChartTitle('record_delay'), variables.metricsData, 'recordDelay')
        )
      }
    } catch (err) {
      console.error('Failed to fetch metrics data:', err)
    }
  }

  const handleTimeOptionChange = (value: string) => {
    variables.selectedTimeOption = value
    
    if (value === 'custom') {
      variables.showDatePicker = true
      return
    }
    
    variables.showDatePicker = false
    const option = timeOptions.find(opt => opt.value === value)
    if (option && option.getTime) {
      const [start, end] = option.getTime()
      variables.dateRange = [start.getTime(), end.getTime()]
      updateCharts()
    }
  }

  const handleDateRangeChange = (value: [number, number] | null) => {
    variables.dateRange = value
    variables.selectedTimeOption = 'custom'
    if (value) {
      updateCharts()
    }
  }

  onMounted(() => {
    handleTimeOptionChange('1hour')
  })

  return {
    variables,
    initCharts,
    updateCharts,
    handleDateRangeChange,
    handleTimeOptionChange
  }
}