仪表盘重做:ECharts 曲线、常驻遥测、路由行直达详情

采集从仪表盘组件挪进模块级单例(web/telemetry.ts),流量曲线和每路
吞吐的历史跨页面留存——跟着组件走的话切一次页面就清零一次。每路吞吐
从 /connections 快照按连接逐条求差再按 inboundName 聚合:先求和再求差
会在连接关闭时算出负数。

图表换 ECharts(按需注册):手写 SVG 折线做不出平滑曲线和时间轴,
颜色在运行时从 CSS 变量取,跟随主题切换重取。

路由列表每行带走势、速率和可选的公网 IP 检测,点击跳路由页并选中
那一路(外壳传 focus 给 RouterPage 消费)。
This commit is contained in:
2026-08-11 22:26:36 +08:00
parent ce181e9ae5
commit eec5b791c8
15 changed files with 1385 additions and 376 deletions
+52
View File
@@ -0,0 +1,52 @@
<script setup lang="ts">
/**
* ECharts 的最小封装:初始化、跟随 option 更新、跟随容器尺寸缩放、卸载时销毁。
*
* 按需注册而不是整包引入:仪表盘只用折线和环形图。调用方传新的 option 对象
* 触发更新(computed 每次重算都是新引用),这里不做深比较。
*/
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts/core'
import { LineChart, PieChart } from 'echarts/charts'
import { GridComponent, TooltipComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import type { EChartsCoreOption } from 'echarts/core'
echarts.use([LineChart, PieChart, GridComponent, TooltipComponent, CanvasRenderer])
const props = defineProps<{ option: EChartsCoreOption }>()
const el = ref<HTMLElement | null>(null)
let chart: echarts.EChartsType | null = null
let observer: ResizeObserver | null = null
onMounted(() => {
if (!el.value) return
chart = echarts.init(el.value)
chart.setOption(props.option)
observer = new ResizeObserver(() => chart?.resize())
observer.observe(el.value)
})
watch(
() => props.option,
(option) => chart?.setOption(option),
)
onBeforeUnmount(() => {
observer?.disconnect()
chart?.dispose()
chart = null
})
</script>
<template>
<div ref="el" class="echart"></div>
</template>
<style scoped>
.echart {
width: 100%;
height: 100%;
}
</style>