points 그래프를 위한 데이터 준비
This commit is contained in:
parent
0f6332c6c2
commit
f67359ba35
@ -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<Options> {}
|
||||
|
||||
@ -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<TimeRange2 | null>(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 (
|
||||
<>
|
||||
<KeyboardPlugin config={uplotConfig} />
|
||||
{cursorSync !== DashboardCursorSync.Off && (
|
||||
<EventBusPlugin config={uplotConfig} eventBus={eventBus} frame={alignedFrame} />
|
||||
)}
|
||||
{options.tooltip.mode !== TooltipDisplayMode.None && (
|
||||
<TooltipPlugin2
|
||||
config={uplotConfig}
|
||||
hoverMode={
|
||||
options.tooltip.mode === TooltipDisplayMode.Single ? TooltipHoverMode.xOne : TooltipHoverMode.xAll
|
||||
}
|
||||
queryZoom={onChangeTimeRange}
|
||||
clientZoom={true}
|
||||
syncMode={cursorSync}
|
||||
syncScope={eventsScope}
|
||||
getDataLinks={(seriesIdx, dataIdx) =>
|
||||
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
|
||||
<TimeSeriesTooltip
|
||||
series={alignedFrame}
|
||||
dataIdxs={dataIdxs}
|
||||
seriesIdx={seriesIdx}
|
||||
mode={viaSync ? TooltipDisplayMode.Multi : options.tooltip.mode}
|
||||
sortOrder={options.tooltip.sort}
|
||||
hideZeros={options.tooltip.hideZeros}
|
||||
isPinned={isPinned}
|
||||
annotate={enableAnnotationCreation ? annotate : undefined}
|
||||
maxHeight={options.tooltip.maxHeight}
|
||||
replaceVariables={replaceVariables}
|
||||
dataLinks={dataLinks}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
maxWidth={options.tooltip.maxWidth}
|
||||
/>
|
||||
)}
|
||||
{!isVerticallyOriented && (
|
||||
<>
|
||||
<AnnotationsPlugin2
|
||||
annotations={data.annotations ?? []}
|
||||
config={uplotConfig}
|
||||
timeZone={timeZone}
|
||||
newRange={newAnnotationRange}
|
||||
setNewRange={setNewAnnotationRange}
|
||||
/>
|
||||
<OutsideRangePlugin config={uplotConfig} onChangeTimeRange={onChangeTimeRange} />
|
||||
{data.annotations && (
|
||||
<ExemplarsPlugin
|
||||
visibleSeries={getVisibleLabels(uplotConfig, frames)}
|
||||
config={uplotConfig}
|
||||
exemplars={data.annotations}
|
||||
timeZone={timeZone}
|
||||
maxHeight={options.tooltip.maxHeight}
|
||||
/>
|
||||
)}
|
||||
{((canEditThresholds && onThresholdsChange) || showThresholds) && (
|
||||
<ThresholdControlsPlugin
|
||||
config={uplotConfig}
|
||||
fieldConfig={fieldConfig}
|
||||
onThresholdsChange={canEditThresholds ? onThresholdsChange : undefined}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return <></>;
|
||||
}}
|
||||
</TimeSeries>
|
||||
);
|
||||
|
||||
180
public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx.bak
Normal file
180
public/app/plugins/panel/timeseries/TimeSeriesPanel.tsx.bak
Normal file
@ -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<Options> {}
|
||||
|
||||
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<TimeRange2 | null>(null);
|
||||
const cursorSync = sync?.() ?? DashboardCursorSync.Off;
|
||||
|
||||
if (!frames || suggestions) {
|
||||
return (
|
||||
<PanelDataErrorView
|
||||
panelId={id}
|
||||
message={suggestions?.message}
|
||||
fieldConfig={fieldConfig}
|
||||
data={data}
|
||||
needsTimeField={true}
|
||||
needsNumberField={true}
|
||||
suggestions={suggestions?.suggestions}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TimeSeries
|
||||
frames={frames}
|
||||
structureRev={data.structureRev}
|
||||
timeRange={timeRange}
|
||||
timeZone={timezones}
|
||||
width={width}
|
||||
height={height}
|
||||
legend={options.legend}
|
||||
options={options}
|
||||
replaceVariables={replaceVariables}
|
||||
dataLinkPostProcessor={dataLinkPostProcessor}
|
||||
cursorSync={cursorSync}
|
||||
>
|
||||
{(uplotConfig, alignedFrame) => {
|
||||
return (
|
||||
<>
|
||||
<KeyboardPlugin config={uplotConfig} />
|
||||
{cursorSync !== DashboardCursorSync.Off && (
|
||||
<EventBusPlugin config={uplotConfig} eventBus={eventBus} frame={alignedFrame} />
|
||||
)}
|
||||
{options.tooltip.mode !== TooltipDisplayMode.None && (
|
||||
<TooltipPlugin2
|
||||
config={uplotConfig}
|
||||
hoverMode={
|
||||
options.tooltip.mode === TooltipDisplayMode.Single ? TooltipHoverMode.xOne : TooltipHoverMode.xAll
|
||||
}
|
||||
queryZoom={onChangeTimeRange}
|
||||
clientZoom={true}
|
||||
syncMode={cursorSync}
|
||||
syncScope={eventsScope}
|
||||
getDataLinks={(seriesIdx, dataIdx) =>
|
||||
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
|
||||
<TimeSeriesTooltip
|
||||
series={alignedFrame}
|
||||
dataIdxs={dataIdxs}
|
||||
seriesIdx={seriesIdx}
|
||||
mode={viaSync ? TooltipDisplayMode.Multi : options.tooltip.mode}
|
||||
sortOrder={options.tooltip.sort}
|
||||
hideZeros={options.tooltip.hideZeros}
|
||||
isPinned={isPinned}
|
||||
annotate={enableAnnotationCreation ? annotate : undefined}
|
||||
maxHeight={options.tooltip.maxHeight}
|
||||
replaceVariables={replaceVariables}
|
||||
dataLinks={dataLinks}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
maxWidth={options.tooltip.maxWidth}
|
||||
/>
|
||||
)}
|
||||
{!isVerticallyOriented && (
|
||||
<>
|
||||
<AnnotationsPlugin2
|
||||
annotations={data.annotations ?? []}
|
||||
config={uplotConfig}
|
||||
timeZone={timeZone}
|
||||
newRange={newAnnotationRange}
|
||||
setNewRange={setNewAnnotationRange}
|
||||
/>
|
||||
<OutsideRangePlugin config={uplotConfig} onChangeTimeRange={onChangeTimeRange} />
|
||||
{data.annotations && (
|
||||
<ExemplarsPlugin
|
||||
visibleSeries={getVisibleLabels(uplotConfig, frames)}
|
||||
config={uplotConfig}
|
||||
exemplars={data.annotations}
|
||||
timeZone={timeZone}
|
||||
maxHeight={options.tooltip.maxHeight}
|
||||
/>
|
||||
)}
|
||||
{((canEditThresholds && onThresholdsChange) || showThresholds) && (
|
||||
<ThresholdControlsPlugin
|
||||
config={uplotConfig}
|
||||
fieldConfig={fieldConfig}
|
||||
onThresholdsChange={canEditThresholds ? onThresholdsChange : undefined}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</TimeSeries>
|
||||
);
|
||||
};
|
||||
@ -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
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user