仪表盘重做:ECharts 曲线、常驻遥测、路由行直达详情
采集从仪表盘组件挪进模块级单例(web/telemetry.ts),流量曲线和每路 吞吐的历史跨页面留存——跟着组件走的话切一次页面就清零一次。每路吞吐 从 /connections 快照按连接逐条求差再按 inboundName 聚合:先求和再求差 会在连接关闭时算出负数。 图表换 ECharts(按需注册):手写 SVG 折线做不出平滑曲线和时间轴, 颜色在运行时从 CSS 变量取,跟随主题切换重取。 路由列表每行带走势、速率和可选的公网 IP 检测,点击跳路由页并选中 那一路(外壳传 focus 给 RouterPage 消费)。
This commit is contained in:
@@ -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>
|
||||
Reference in New Issue
Block a user