chore: hide anno lines & regions for multi-lane, pass options into annoPlugin

This commit is contained in:
Galen 2025-09-25 13:31:17 -05:00
parent fa59ef2b86
commit a40444fd23
No known key found for this signature in database
6 changed files with 58 additions and 54 deletions

View File

@ -323,6 +323,7 @@ export const CandlestickPanel = ({
/> />
)} )}
<AnnotationsPlugin2 <AnnotationsPlugin2
annotationsConfig={options.annotations}
annotations={data.annotations ?? []} annotations={data.annotations ?? []}
config={uplotConfig} config={uplotConfig}
timeZone={timeZone} timeZone={timeZone}

View File

@ -235,6 +235,7 @@ export const HeatmapPanel = ({
/> />
)} )}
<AnnotationsPlugin2 <AnnotationsPlugin2
annotationsConfig={options.annotations}
annotations={data.annotations ?? []} annotations={data.annotations ?? []}
config={builder} config={builder}
timeZone={timeZone} timeZone={timeZone}

View File

@ -152,6 +152,7 @@ export const StateTimelinePanel = ({
)} )}
{alignedFrame.fields[0].config.custom?.axisPlacement !== AxisPlacement.Hidden && ( {alignedFrame.fields[0].config.custom?.axisPlacement !== AxisPlacement.Hidden && (
<AnnotationsPlugin2 <AnnotationsPlugin2
annotationsConfig={options.annotations}
annotations={data.annotations ?? []} annotations={data.annotations ?? []}
config={builder} config={builder}
timeZone={timeZone} timeZone={timeZone}

View File

@ -165,6 +165,7 @@ export const StatusHistoryPanel = ({
)} )}
{alignedFrame.fields[0].config.custom?.axisPlacement !== AxisPlacement.Hidden && ( {alignedFrame.fields[0].config.custom?.axisPlacement !== AxisPlacement.Hidden && (
<AnnotationsPlugin2 <AnnotationsPlugin2
annotationsConfig={options.annotations}
annotations={data.annotations ?? []} annotations={data.annotations ?? []}
config={builder} config={builder}
timeZone={timeZone} timeZone={timeZone}

View File

@ -193,6 +193,7 @@ export const TimeSeriesPanel = ({
{!isVerticallyOriented && ( {!isVerticallyOriented && (
<> <>
<AnnotationsPlugin2 <AnnotationsPlugin2
annotationsConfig={options.annotations}
annotations={data.annotations ?? []} annotations={data.annotations ?? []}
config={uplotConfig} config={uplotConfig}
timeZone={timeZone} timeZone={timeZone}

View File

@ -6,7 +6,7 @@ import tinycolor from 'tinycolor2';
import uPlot from 'uplot'; import uPlot from 'uplot';
import { arrayToDataFrame, colorManipulator, DataFrame, DataTopic } from '@grafana/data'; import { arrayToDataFrame, colorManipulator, DataFrame, DataTopic } from '@grafana/data';
import { TimeZone } from '@grafana/schema'; import { TimeZone, VizAnnotations } from '@grafana/schema';
import { DEFAULT_ANNOTATION_COLOR, getPortalContainer, UPlotConfigBuilder, useStyles2, useTheme2 } from '@grafana/ui'; import { DEFAULT_ANNOTATION_COLOR, getPortalContainer, UPlotConfigBuilder, useStyles2, useTheme2 } from '@grafana/ui';
import { AnnotationMarker2 } from './annotations2/AnnotationMarker2'; import { AnnotationMarker2 } from './annotations2/AnnotationMarker2';
@ -25,6 +25,7 @@ interface AnnotationsPluginProps {
newRange: TimeRange2 | null; newRange: TimeRange2 | null;
setNewRange: (newRage: TimeRange2 | null) => void; setNewRange: (newRage: TimeRange2 | null) => void;
canvasRegionRendering?: boolean; canvasRegionRendering?: boolean;
annotationsConfig?: VizAnnotations;
} }
// TODO: batch by color, use Path2D objects // TODO: batch by color, use Path2D objects
@ -58,6 +59,7 @@ function getVals(frame: DataFrame) {
} }
export const AnnotationsPlugin2 = ({ export const AnnotationsPlugin2 = ({
annotationsConfig,
annotations, annotations,
timeZone, timeZone,
config, config,
@ -131,6 +133,8 @@ export const AnnotationsPlugin2 = ({
ctx.rect(u.bbox.left, u.bbox.top, u.bbox.width, u.bbox.height); ctx.rect(u.bbox.left, u.bbox.top, u.bbox.width, u.bbox.height);
ctx.clip(); ctx.clip();
// Multi-lane annotations do not support vertical lines or shaded regions
if (!annotationsConfig?.multiLane) {
annos.forEach((frame) => { annos.forEach((frame) => {
let vals = getVals(frame); let vals = getVals(frame);
@ -165,27 +169,20 @@ export const AnnotationsPlugin2 = ({
ctx.strokeRect(x0, y0, x1 - x0, y1 - y0); ctx.strokeRect(x0, y0, x1 - x0, y1 - y0);
} }
} else { } else {
// if multiple regions, don't shade
// @todo toggle functionality, new annotation config option?
let y0 = u.bbox.top; let y0 = u.bbox.top;
let y1 = y0 + u.bbox.height; let y1 = y0 + u.bbox.height;
ctx.lineWidth = 2; ctx.lineWidth = 2;
ctx.setLineDash([5, 5]); ctx.setLineDash([5, 5]);
// @todo Don't render the vertical lines if multi lane is enabled
//@todo Don't render shaded region if multi-lane is enabled
// skipping this loop should do it
for (let i = 0; i < vals.time.length; i++) { for (let i = 0; i < vals.time.length; i++) {
let color = getColorByName(vals.color?.[i] || DEFAULT_ANNOTATION_COLOR_HEX8); let color = getColorByName(vals.color?.[i] || DEFAULT_ANNOTATION_COLOR_HEX8);
let x0 = u.valToPos(vals.time[i], 'x', true); let x0 = u.valToPos(vals.time[i], 'x', true);
renderLine(ctx, y0, y1, x0, color); renderLine(ctx, y0, y1, x0, color);
// If dataframe does not have end times, let's omit rendering the region for now // If dataframe does not have end times, let's omit rendering the region for now to prevent runtime error in valToPos
// @todo do we want to fix isRegion to render a point when we're missing timeEnd? // @todo do we want to fix isRegion to render a point (or use "to" as timeEnd) when we're missing timeEnd?
if (vals.isRegion?.[i] && vals.timeEnd?.[i]) { if (vals.isRegion?.[i] && vals.timeEnd?.[i]) {
let x1 = u.valToPos(vals.timeEnd[i], 'x', true); let x1 = u.valToPos(vals.timeEnd[i], 'x', true);
renderLine(ctx, y0, y1, x1, color); renderLine(ctx, y0, y1, x1, color);
@ -198,10 +195,11 @@ export const AnnotationsPlugin2 = ({
} }
} }
}); });
}
ctx.restore(); ctx.restore();
}); });
}, [config, canvasRegionRendering, getColorByName]); }, [config, canvasRegionRendering, getColorByName, annotationsConfig]);
// ensure annos are re-drawn whenever they change // ensure annos are re-drawn whenever they change
useEffect(() => { useEffect(() => {
@ -223,7 +221,8 @@ export const AnnotationsPlugin2 = ({
let markers: React.ReactNode[] = []; let markers: React.ReactNode[] = [];
const top = frameIdx * ANNOTATION_LANE_SIZE; // Top offset for multi-lane annotations
const top = annotationsConfig?.multiLane ? frameIdx * ANNOTATION_LANE_SIZE : undefined;
for (let i = 0; i < vals.time.length; i++) { for (let i = 0; i < vals.time.length; i++) {
let color = getColorByName(vals.color?.[i] || DEFAULT_ANNOTATION_COLOR); let color = getColorByName(vals.color?.[i] || DEFAULT_ANNOTATION_COLOR);
let left = Math.round(plot.valToPos(vals.time[i], 'x')) || 0; // handles -0 let left = Math.round(plot.valToPos(vals.time[i], 'x')) || 0; // handles -0