From f67359ba35335aab6c4cb578f939e79b19dc93da Mon Sep 17 00:00:00 2001 From: devhong Date: Tue, 1 Apr 2025 18:12:40 +0900 Subject: [PATCH] =?UTF-8?q?points=20=EA=B7=B8=EB=9E=98=ED=94=84=EB=A5=BC?= =?UTF-8?q?=20=EC=9C=84=ED=95=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A4=80?= =?UTF-8?q?=EB=B9=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../panel/timeseries/TimeSeriesPanel.tsx | 120 ++---------- .../panel/timeseries/TimeSeriesPanel.tsx.bak | 180 ++++++++++++++++++ public/app/plugins/panel/timeseries/utils.ts | 10 + 3 files changed, 203 insertions(+), 107 deletions(-) create mode 100644 public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx.bak diff --git a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx index e4124886..2e2d471e 100644 --- a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx +++ b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx @@ -1,21 +1,14 @@ -import { useMemo, useState } from 'react'; +import { useMemo } from 'react'; import { PanelProps, DataFrameType, DashboardCursorSync } from '@grafana/data'; import { PanelDataErrorView } from '@grafana/runtime'; -import { TooltipDisplayMode, VizOrientation } from '@grafana/schema'; -import { EventBusPlugin, KeyboardPlugin, TooltipPlugin2, usePanelContext } from '@grafana/ui'; -import { TimeRange2, TooltipHoverMode } from '@grafana/ui/src/components/uPlot/plugins/TooltipPlugin2'; +import { DrawStyle, usePanelContext } from '@grafana/ui'; import { TimeSeries } from 'app/core/components/TimeSeries/TimeSeries'; import { config } from 'app/core/config'; -import { TimeSeriesTooltip } from './TimeSeriesTooltip'; import { Options } from './panelcfg.gen'; -import { AnnotationsPlugin2 } from './plugins/AnnotationsPlugin2'; -import { ExemplarsPlugin, getVisibleLabels } from './plugins/ExemplarsPlugin'; -import { OutsideRangePlugin } from './plugins/OutsideRangePlugin'; -import { ThresholdControlsPlugin } from './plugins/ThresholdControlsPlugin'; import { getPrepareTimeseriesSuggestion } from './suggestions'; -import { getTimezones, prepareGraphableFields } from './utils'; +import { getTimezones, prepareGraphableFields, preparePlotFramePoints } from './utils'; interface TimeSeriesPanelProps extends PanelProps {} @@ -27,23 +20,19 @@ export const TimeSeriesPanel = ({ height, options, fieldConfig, - onChangeTimeRange, replaceVariables, id, }: TimeSeriesPanelProps) => { - const { - sync, - eventsScope, - canAddAnnotations, - onThresholdsChange, - canEditThresholds, - showThresholds, - dataLinkPostProcessor, - eventBus, - } = usePanelContext(); + const { sync, dataLinkPostProcessor } = usePanelContext(); + + const preparePlotFrame = + fieldConfig.defaults.custom.drawStyle === DrawStyle.Points ? preparePlotFramePoints : undefined; + if (fieldConfig.defaults.custom.drawStyle === DrawStyle.Points) { + console.log('points'); + } + // Vertical orientation is not available for users through config. // It is simplified version of horizontal time series panel and it does not support all plugins. - const isVerticallyOriented = options.orientation === VizOrientation.Vertical; const frames = useMemo(() => prepareGraphableFields(data.series, config.theme2, timeRange), [data.series, timeRange]); const timezones = useMemo(() => getTimezones(options.timezone, timeZone), [options.timezone, timeZone]); const suggestions = useMemo(() => { @@ -57,8 +46,6 @@ export const TimeSeriesPanel = ({ return undefined; }, [frames, id]); - const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations()); - const [newAnnotationRange, setNewAnnotationRange] = useState(null); const cursorSync = sync?.() ?? DashboardCursorSync.Off; if (!frames || suggestions) { @@ -88,91 +75,10 @@ export const TimeSeriesPanel = ({ replaceVariables={replaceVariables} dataLinkPostProcessor={dataLinkPostProcessor} cursorSync={cursorSync} + preparePlotFrame={preparePlotFrame} > {(uplotConfig, alignedFrame) => { - return ( - <> - - {cursorSync !== DashboardCursorSync.Off && ( - - )} - {options.tooltip.mode !== TooltipDisplayMode.None && ( - - alignedFrame.fields[seriesIdx].getLinks?.({ valueRowIndex: dataIdx }) ?? [] - } - render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2, viaSync, dataLinks) => { - if (enableAnnotationCreation && timeRange2 != null) { - setNewAnnotationRange(timeRange2); - dismiss(); - return; - } - - const annotate = () => { - let xVal = u.posToVal(u.cursor.left!, 'x'); - - setNewAnnotationRange({ from: xVal, to: xVal }); - dismiss(); - }; - - return ( - // not sure it header time here works for annotations, since it's taken from nearest datapoint index - - ); - }} - maxWidth={options.tooltip.maxWidth} - /> - )} - {!isVerticallyOriented && ( - <> - - - {data.annotations && ( - - )} - {((canEditThresholds && onThresholdsChange) || showThresholds) && ( - - )} - - )} - - ); + return <>; }} ); diff --git a/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx.bak b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx.bak new file mode 100644 index 00000000..59d7a5ab --- /dev/null +++ b/public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx.bak @@ -0,0 +1,180 @@ +import { useMemo, useState } from 'react'; + +import { PanelProps, DataFrameType, DashboardCursorSync } from '@grafana/data'; +import { PanelDataErrorView } from '@grafana/runtime'; +import { TooltipDisplayMode, VizOrientation } from '@grafana/schema'; +import { EventBusPlugin, KeyboardPlugin, TooltipPlugin2, usePanelContext } from '@grafana/ui'; +import { TimeRange2, TooltipHoverMode } from '@grafana/ui/src/components/uPlot/plugins/TooltipPlugin2'; +import { TimeSeries } from 'app/core/components/TimeSeries/TimeSeries'; +import { config } from 'app/core/config'; + +import { TimeSeriesTooltip } from './TimeSeriesTooltip'; +import { Options } from './panelcfg.gen'; +import { AnnotationsPlugin2 } from './plugins/AnnotationsPlugin2'; +import { ExemplarsPlugin, getVisibleLabels } from './plugins/ExemplarsPlugin'; +import { OutsideRangePlugin } from './plugins/OutsideRangePlugin'; +import { ThresholdControlsPlugin } from './plugins/ThresholdControlsPlugin'; +import { getPrepareTimeseriesSuggestion } from './suggestions'; +import { getTimezones, prepareGraphableFields } from './utils'; + +interface TimeSeriesPanelProps extends PanelProps {} + +export const TimeSeriesPanel = ({ + data, + timeRange, + timeZone, + width, + height, + options, + fieldConfig, + onChangeTimeRange, + replaceVariables, + id, +}: TimeSeriesPanelProps) => { + const { + sync, + eventsScope, + canAddAnnotations, + onThresholdsChange, + canEditThresholds, + showThresholds, + dataLinkPostProcessor, + eventBus, + } = usePanelContext(); + + // Vertical orientation is not available for users through config. + // It is simplified version of horizontal time series panel and it does not support all plugins. + const isVerticallyOriented = options.orientation === VizOrientation.Vertical; + const frames = useMemo(() => prepareGraphableFields(data.series, config.theme2, timeRange), [data.series, timeRange]); + const timezones = useMemo(() => getTimezones(options.timezone, timeZone), [options.timezone, timeZone]); + const suggestions = useMemo(() => { + if (frames?.length && frames.every((df) => df.meta?.type === DataFrameType.TimeSeriesLong)) { + const s = getPrepareTimeseriesSuggestion(id); + return { + message: 'Long data must be converted to wide', + suggestions: s ? [s] : undefined, + }; + } + return undefined; + }, [frames, id]); + + const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations()); + const [newAnnotationRange, setNewAnnotationRange] = useState(null); + const cursorSync = sync?.() ?? DashboardCursorSync.Off; + + if (!frames || suggestions) { + return ( + + ); + } + + return ( + + {(uplotConfig, alignedFrame) => { + return ( + <> + + {cursorSync !== DashboardCursorSync.Off && ( + + )} + {options.tooltip.mode !== TooltipDisplayMode.None && ( + + alignedFrame.fields[seriesIdx].getLinks?.({ valueRowIndex: dataIdx }) ?? [] + } + render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2, viaSync, dataLinks) => { + if (enableAnnotationCreation && timeRange2 != null) { + setNewAnnotationRange(timeRange2); + dismiss(); + return; + } + + const annotate = () => { + let xVal = u.posToVal(u.cursor.left!, 'x'); + + setNewAnnotationRange({ from: xVal, to: xVal }); + dismiss(); + }; + + return ( + // not sure it header time here works for annotations, since it's taken from nearest datapoint index + + ); + }} + maxWidth={options.tooltip.maxWidth} + /> + )} + {!isVerticallyOriented && ( + <> + + + {data.annotations && ( + + )} + {((canEditThresholds && onThresholdsChange) || showThresholds) && ( + + )} + + )} + + ); + }} + + ); +}; diff --git a/public/app/plugins/panel/timeseries/utils.ts b/public/app/plugins/panel/timeseries/utils.ts index fb5ca669..4d019f8e 100644 --- a/public/app/plugins/panel/timeseries/utils.ts +++ b/public/app/plugins/panel/timeseries/utils.ts @@ -13,6 +13,7 @@ import { applyNullInsertThreshold } from '@grafana/data/src/transformations/tran import { nullToValue } from '@grafana/data/src/transformations/transformers/nulls/nullToValue'; import { GraphFieldConfig, LineInterpolation, TooltipDisplayMode, VizTooltipOptions } from '@grafana/schema'; import { buildScaleKey } from '@grafana/ui/src/components/uPlot/internal'; +import { XYFieldMatchers } from 'app/core/components/GraphNG/types'; import { HeatmapTooltip } from '../heatmap/panelcfg.gen'; @@ -67,6 +68,15 @@ function reEnumFields(frames: DataFrame[]): DataFrame[] { return frames2; } +export function preparePlotFramePoints(frames: DataFrame[], dimFields: XYFieldMatchers, timeRange?: TimeRange | null) { + const dataFrame: DataFrame = { + ...frames[0], + fields: frames[0].fields.filter((f) => f.type === FieldType.number), + }; + console.log(dataFrame); + return dataFrame; +} + /** * Returns null if there are no graphable fields */