From dbda8ee613ea40f6a96073b81d498ac592752721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D0=BE=D0=B2=20=D0=90=D1=80=D1=82?= =?UTF-8?q?=D0=B5=D0=BC?= Date: Fri, 19 Jun 2026 09:05:58 +0300 Subject: [PATCH] history minor changes. autorefresh not interrupt zoom. --- src/components/HistoryChart.tsx | 48 ++++++++++++++++++++++++++++++--- src/pages/EdgeDetailPage.tsx | 3 ++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/components/HistoryChart.tsx b/src/components/HistoryChart.tsx index 13ad13a..6e3f78b 100644 --- a/src/components/HistoryChart.tsx +++ b/src/components/HistoryChart.tsx @@ -9,6 +9,7 @@ import * as echarts from 'echarts/core'; import { CanvasRenderer } from 'echarts/renderers'; import ReactEChartsCore from 'echarts-for-react/esm/core.js'; import type { EChartsOption, SeriesOption } from 'echarts'; +import { useMemo, useRef } from 'react'; import type { HistoryResponse } from '../api/cloud'; echarts.use([ @@ -48,6 +49,17 @@ type TooltipParam = { value?: unknown; }; +type DataZoomState = { + start?: number; + end?: number; + startValue?: number; + endValue?: number; +}; + +type DataZoomEventBatch = DataZoomState & { + batch?: DataZoomState[]; +}; + /** Подбирает подпись оси времени под текущий масштаб графика. */ function formatAxisDate(value: number, spanMs?: number): string { const date = new Date(value); @@ -206,12 +218,17 @@ function createSeriesOptions( /** Рисует исторические ряды: avg соединяется линией, min/max показываются точками и вертикальным диапазоном. */ export function HistoryChart({ data, loading, from, to, tagLabels = {} }: HistoryChartProps) { + const dataZoomRef = useRef(null); const xMin = from ? new Date(from).getTime() : undefined; const xMax = to ? new Date(to).getTime() : undefined; const xSpan = Number.isFinite(xMin) && Number.isFinite(xMax) ? Number(xMax) - Number(xMin) : undefined; - const legendData = data?.series.map((series) => tagLabels[series.tag] ?? series.tag) ?? []; + const legendData = useMemo( + () => data?.series.map((series) => tagLabels[series.tag] ?? series.tag) ?? [], + [data?.series, tagLabels], + ); + const dataZoomState = dataZoomRef.current ?? {}; - const option: EChartsOption = { + const option: EChartsOption = useMemo(() => ({ color: SERIES_COLORS, animation: false, backgroundColor: 'transparent', @@ -260,6 +277,10 @@ export function HistoryChart({ data, loading, from, to, tagLabels = {} }: Histor { type: 'inside', throttle: 80, + start: dataZoomState.start, + end: dataZoomState.end, + startValue: dataZoomState.startValue, + endValue: dataZoomState.endValue, }, { type: 'slider', @@ -272,13 +293,32 @@ export function HistoryChart({ data, loading, from, to, tagLabels = {} }: Histor borderColor: '#e8c9a0', }, textStyle: { color: '#94a3b8' }, + start: dataZoomState.start, + end: dataZoomState.end, + startValue: dataZoomState.startValue, + endValue: dataZoomState.endValue, }, ], series: data?.series.flatMap((series, index) => createSeriesOptions(series, index, tagLabels[series.tag] ?? series.tag), ) ?? [], - }; + }), [data?.series, dataZoomState.end, dataZoomState.endValue, dataZoomState.start, dataZoomState.startValue, legendData, tagLabels, xMax, xMin, xSpan]); + + const onChartEvents = useMemo( + () => ({ + datazoom: (event: DataZoomEventBatch) => { + const state = event.batch?.[0] ?? event; + dataZoomRef.current = { + start: state.start, + end: state.end, + startValue: state.startValue, + endValue: state.endValue, + }; + }, + }), + [], + ); if (loading) { return
Загрузка графика...
; @@ -288,5 +328,5 @@ export function HistoryChart({ data, loading, from, to, tagLabels = {} }: Histor return
Нет данных для выбранного диапазона
; } - return ; + return ; } diff --git a/src/pages/EdgeDetailPage.tsx b/src/pages/EdgeDetailPage.tsx index bfd1178..9220190 100644 --- a/src/pages/EdgeDetailPage.tsx +++ b/src/pages/EdgeDetailPage.tsx @@ -157,7 +157,7 @@ export function EdgeDetailPage({ view }: EdgeDetailPageProps) { targetPoints: 1600, }), enabled: Boolean(edgeId && selectedTags.length), - refetchInterval: 5_000, + refetchInterval: false, }); /** Переключает выбранный тег для отображения на историческом графике. */ @@ -556,6 +556,7 @@ function ArchiveView({ {selectedTags.length ? (