<!-- 最初版本的波形图验证，推送的数据一直追加,服务端使用本目录下的lineChart1Server.js -->
<template>
  <el-card class="mb-20px" shadow="hover">
    <el-skeleton :loading="loading" :rows="4" animated>
      <Echart :height="350" :options="lineOptionsData" />
    </el-skeleton>
  </el-card>
</template>
<script lang="ts" setup>
import { set } from 'lodash-es'
import { EChartsOption } from 'echarts'
import 'echarts/lib/component/dataZoom'

import { lineOptions } from './echarts-data'

defineOptions({ name: 'Home2' })

const { t } = useI18n()
const loading = ref(true)

const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
let data: any[] = [] // 波形图数据

// 初始数据
const getLineData = async () => {
  // data = createData(1000000, 1)
  set(
    lineOptionsData,
    'xAxis.data',
    data.map((v) => t(v.name))
  )
  set(lineOptionsData, 'series', [
    {
      name: 'data1',
      smooth: false, // 是否平滑曲线
      type: 'line',
      showSymbol: false, // 不显示数据点
      progressive: 1000, // 每次增量渲染的数据量
      progressiveThreshold: 5000, // 总数据量超过此值触发增量渲染
      lineStyle: {
        width: 1 // 细线
      },
      sampling: 'lttb', // 使用 LTTB 采样算法降低数据量
      // samplingThreshold: 10000, // 采样阈值，超过此值将进行采样
      animation: false, // 动画
      animationDuration: 1000, // 动画持续时间
      animationEasing: 'linear', // 动画缓动效果
      data: data.map((v) => v.data1)
    }
    // {
    //   name: 'data2',
    //   smooth: false, // 是否平滑曲线
    //   type: 'line',
    //   showSymbol: false, // 不显示数据点
    //   progressive: 1000, // 每次增量渲染的数据量
    //   progressiveThreshold: 5000, // 总数据量超过此值触发增量渲染
    //   animation: false, // 关闭动画
    //   lineStyle: {
    //     width: 0.5 // 细线
    //   },
    //   sampling: 'lttb', // 使用 LTTB 采样算法
    //   samplingThreshold: 10000, // 采样阈值，超过此值将进行采样
    //   data: data.map((v) => v.data2)
    // }
  ])
}

const connect = () => {
  // 连接到 WebSocket 服务器
  const socket = new WebSocket('ws://localhost:8080')

  // 监听连接成功
  socket.addEventListener('open', (event) => {
    console.log('WebSocket 连接成功')
  })

  // 接收服务器消息
  socket.addEventListener('message', (event) => {
    const newData = JSON.parse(event.data)

    // 更新图表数据
    const newXAxisData = [...lineOptionsData!.xAxis!.data, ...newData.map((item) => item.name)]
    console.log(newXAxisData.length)
    set(lineOptionsData, 'xAxis.data', newXAxisData)
    set(lineOptionsData, 'series', [
      {
        name: 'data1',
        smooth: false,
        type: 'line',
        // 启用大数据优化
        progressive: 1000,
        progressiveThreshold: 5000,
        showSymbol: false, // 不显示数据点
        lineStyle: {
          width: 0.5 // 细线
        },
        sampling: 'lttb', // 使用 LTTB 采样算法
        animation: false, // 动画
        animationDuration: 1000, // 动画持续时间
        animationEasing: 'linear', // 动画缓动效果
        data: [...lineOptionsData!.series![0].data, ...newData.map((item) => item.data1)]
      }
      // {
      //   name: 'data2',
      //   smooth: false,
      //   type: 'line',
      //   itemStyle: {},
      //   // 启用大数据优化
      //   progressive: 1000,
      //   progressiveThreshold: 5000,
      //   lineStyle: {
      //     width: 0.5 // 细线
      //   },
      //   data: [...lineOptionsData.series[1].data, ...newData.map((item) => item.data2)]
      // }
    ])
  })
}

const getAllApi = async () => {
  await getLineData()
  loading.value = false
  connect()
}

getAllApi()

interface DataItem {
  [key: string]: number | string
  name: string
}

function formatDate(date: Date, format: string): string {
  const pad = (num: number) => num.toString().padStart(2, '0')
  return format
    .replace('HH', pad(date.getHours()))
    .replace('mm', pad(date.getMinutes()))
    .replace('ss', pad(date.getSeconds()))
}

function createData(
  count: number,
  dataCount: 1 | 2 | 3 = 2,
  minValue: number = 50,
  maxValue: number = 250
): DataItem[] {
  const result: DataItem[] = []
  const now = new Date()

  // 生成时间点（从当前时间往前递减）
  const timeStamps: Date[] = []
  for (let i = count - 1; i >= 0; i--) {
    const time = new Date(now.getTime() - i * 1000)
    timeStamps.push(time)
  }

  // 初始化各数据项的值和方向
  const dataValues: Record<string, number> = {}
  const dataDirections: Record<string, number> = {}

  for (let i = 1; i <= dataCount; i++) {
    const key = `data${i}`
    dataValues[key] = minValue + Math.random() * (maxValue - minValue) // 初始随机值
    dataDirections[key] = Math.random() > 0.5 ? 1 : -1 // 随机初始方向
  }

  for (let i = 0; i < count; i++) {
    const item: DataItem = { name: formatDate(timeStamps[i], 'HH:mm:ss') }

    // 为每个数据项生成波形数据
    for (let j = 1; j <= dataCount; j++) {
      const key = `data${j}`
      const change = 10 + Math.random() * 30 // 变化幅度10~40（可调整）

      // 随机决定是否改变方向（更自然的波动）
      if (Math.random() < 0.2) {
        // 20%概率改变方向
        dataDirections[key] *= -1
      }

      dataValues[key] += dataDirections[key] * change

      // 限制在合理范围内（但不强制反转）
      dataValues[key] = Math.max(
        minValue * 0.9, // 允许稍微低于最小值（避免卡边界）
        Math.min(maxValue * 1.1, dataValues[key]) // 允许稍微高于最大值
      )

      item[key] = Math.round(dataValues[key])
    }

    result.push(item)
  }

  return result
}
</script>

<style lang="scss" scoped></style>
