mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 16:15:42 -06:00
VizTooltips: Don't use y scales for sync, since they rarely match (#81031)
This commit is contained in:
parent
2a53ae637e
commit
391f3ca615
@ -13,6 +13,7 @@ import { CloseButton } from './CloseButton';
|
|||||||
|
|
||||||
export const DEFAULT_TOOLTIP_WIDTH = 300;
|
export const DEFAULT_TOOLTIP_WIDTH = 300;
|
||||||
export const DEFAULT_TOOLTIP_HEIGHT = 600;
|
export const DEFAULT_TOOLTIP_HEIGHT = 600;
|
||||||
|
export const TOOLTIP_OFFSET = 10;
|
||||||
|
|
||||||
// todo: barchart? histogram?
|
// todo: barchart? histogram?
|
||||||
export const enum TooltipHoverMode {
|
export const enum TooltipHoverMode {
|
||||||
@ -40,7 +41,8 @@ interface TooltipPlugin2Props {
|
|||||||
isPinned: boolean,
|
isPinned: boolean,
|
||||||
dismiss: () => void,
|
dismiss: () => void,
|
||||||
// selected time range (for annotation triggering)
|
// selected time range (for annotation triggering)
|
||||||
timeRange: TimeRange2 | null
|
timeRange: TimeRange2 | null,
|
||||||
|
viaSync: boolean
|
||||||
) => React.ReactNode;
|
) => React.ReactNode;
|
||||||
|
|
||||||
maxWidth?: number;
|
maxWidth?: number;
|
||||||
@ -155,13 +157,14 @@ export const TooltipPlugin2 = ({
|
|||||||
let winHeight = htmlEl.clientHeight - 16;
|
let winHeight = htmlEl.clientHeight - 16;
|
||||||
|
|
||||||
window.addEventListener('resize', (e) => {
|
window.addEventListener('resize', (e) => {
|
||||||
winWidth = htmlEl.clientWidth - 5;
|
winWidth = htmlEl.clientWidth - 16;
|
||||||
winHeight = htmlEl.clientHeight - 5;
|
winHeight = htmlEl.clientHeight - 16;
|
||||||
});
|
});
|
||||||
|
|
||||||
let selectedRange: TimeRange2 | null = null;
|
let selectedRange: TimeRange2 | null = null;
|
||||||
let seriesIdxs: Array<number | null> = plot?.cursor.idxs!.slice()!;
|
let seriesIdxs: Array<number | null> = plot?.cursor.idxs!.slice()!;
|
||||||
let closestSeriesIdx: number | null = null;
|
let closestSeriesIdx: number | null = null;
|
||||||
|
let viaSync = false;
|
||||||
|
|
||||||
let pendingRender = false;
|
let pendingRender = false;
|
||||||
let pendingPinned = false;
|
let pendingPinned = false;
|
||||||
@ -217,7 +220,7 @@ export const TooltipPlugin2 = ({
|
|||||||
isHovering: _isHovering,
|
isHovering: _isHovering,
|
||||||
contents:
|
contents:
|
||||||
_isHovering || selectedRange != null
|
_isHovering || selectedRange != null
|
||||||
? renderRef.current(_plot!, seriesIdxs, closestSeriesIdx, _isPinned, dismiss, selectedRange)
|
? renderRef.current(_plot!, seriesIdxs, closestSeriesIdx, _isPinned, dismiss, selectedRange, viaSync)
|
||||||
: null,
|
: null,
|
||||||
dismiss,
|
dismiss,
|
||||||
};
|
};
|
||||||
@ -225,6 +228,7 @@ export const TooltipPlugin2 = ({
|
|||||||
setState(state);
|
setState(state);
|
||||||
|
|
||||||
selectedRange = null;
|
selectedRange = null;
|
||||||
|
viaSync = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const dismiss = () => {
|
const dismiss = () => {
|
||||||
@ -410,46 +414,62 @@ export const TooltipPlugin2 = ({
|
|||||||
|
|
||||||
// fires on mousemoves
|
// fires on mousemoves
|
||||||
config.addHook('setCursor', (u) => {
|
config.addHook('setCursor', (u) => {
|
||||||
let { left = -10, top = -10 } = u.cursor;
|
let { left = -10, top = -10, event } = u.cursor;
|
||||||
|
|
||||||
if (left >= 0 || top >= 0) {
|
if (left >= 0 || top >= 0) {
|
||||||
let { width, height } = sizeRef.current!;
|
viaSync = event == null;
|
||||||
|
|
||||||
let clientX = u.rect.left + left;
|
let transform = '';
|
||||||
let clientY = u.rect.top + top;
|
|
||||||
|
|
||||||
if (offsetY) {
|
// this means it's a synthetic event from uPlot's sync
|
||||||
if (clientY + height < winHeight || clientY - height < 0) {
|
if (viaSync) {
|
||||||
offsetY = 0;
|
// TODO: smarter positioning here to avoid viewport clipping?
|
||||||
} else if (offsetY !== -height) {
|
transform = `translateX(${left}px) translateY(${u.rect.height / 2}px) translateY(-50%)`;
|
||||||
offsetY = -height;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (clientY + height > winHeight && clientY - height >= 0) {
|
let { width, height } = sizeRef.current!;
|
||||||
offsetY = -height;
|
|
||||||
|
width += TOOLTIP_OFFSET;
|
||||||
|
height += TOOLTIP_OFFSET;
|
||||||
|
|
||||||
|
let clientX = u.rect.left + left;
|
||||||
|
let clientY = u.rect.top + top;
|
||||||
|
|
||||||
|
if (offsetY !== 0) {
|
||||||
|
if (clientY + height < winHeight || clientY - height < 0) {
|
||||||
|
offsetY = 0;
|
||||||
|
} else if (offsetY !== -height) {
|
||||||
|
offsetY = -height;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (clientY + height > winHeight && clientY - height >= 0) {
|
||||||
|
offsetY = -height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (offsetX !== 0) {
|
||||||
|
if (clientX + width < winWidth || clientX - width < 0) {
|
||||||
|
offsetX = 0;
|
||||||
|
} else if (offsetX !== -width) {
|
||||||
|
offsetX = -width;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (clientX + width > winWidth && clientX - width >= 0) {
|
||||||
|
offsetX = -width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shiftX = left + (offsetX === 0 ? TOOLTIP_OFFSET : -TOOLTIP_OFFSET);
|
||||||
|
const shiftY = top + (offsetY === 0 ? TOOLTIP_OFFSET : -TOOLTIP_OFFSET);
|
||||||
|
|
||||||
|
const reflectX = offsetX === 0 ? '' : 'translateX(-100%)';
|
||||||
|
const reflectY = offsetY === 0 ? '' : 'translateY(-100%)';
|
||||||
|
|
||||||
|
// TODO: to a transition only when switching sides
|
||||||
|
// transition: transform 100ms;
|
||||||
|
|
||||||
|
transform = `translateX(${shiftX}px) ${reflectX} translateY(${shiftY}px) ${reflectY}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offsetX) {
|
|
||||||
if (clientX + width < winWidth || clientX - width < 0) {
|
|
||||||
offsetX = 0;
|
|
||||||
} else if (offsetX !== -width) {
|
|
||||||
offsetX = -width;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (clientX + width > winWidth && clientX - width >= 0) {
|
|
||||||
offsetX = -width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const shiftX = offsetX !== 0 ? 'translateX(-100%)' : '';
|
|
||||||
const shiftY = offsetY !== 0 ? 'translateY(-100%)' : '';
|
|
||||||
|
|
||||||
// TODO: to a transition only when switching sides
|
|
||||||
// transition: transform 100ms;
|
|
||||||
|
|
||||||
const transform = `${shiftX} translateX(${left}px) ${shiftY} translateY(${top}px)`;
|
|
||||||
|
|
||||||
if (_isHovering) {
|
if (_isHovering) {
|
||||||
if (domRef.current != null) {
|
if (domRef.current != null) {
|
||||||
domRef.current.style.transform = transform;
|
domRef.current.style.transform = transform;
|
||||||
|
@ -81,7 +81,7 @@ exports[`GraphNG utils preparePlotConfigBuilder 1`] = `
|
|||||||
"key": "__global_",
|
"key": "__global_",
|
||||||
"scales": [
|
"scales": [
|
||||||
"x",
|
"x",
|
||||||
"__fixed/na-na/na-na/auto/linear/na/number",
|
null,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -643,8 +643,8 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
scales: [xScaleKey, yScaleKey],
|
scales: [xScaleKey, null],
|
||||||
// match: [() => true, (a, b) => a === b],
|
// match: [() => true, () => false],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ export const CandlestickPanel = ({
|
|||||||
|
|
||||||
const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations());
|
const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations());
|
||||||
const showNewVizTooltips =
|
const showNewVizTooltips =
|
||||||
config.featureToggles.newVizTooltips && (sync == null || sync() === DashboardCursorSync.Off);
|
config.featureToggles.newVizTooltips && (sync == null || sync() !== DashboardCursorSync.Tooltip);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TimeSeries
|
<TimeSeries
|
||||||
@ -269,7 +269,11 @@ export const CandlestickPanel = ({
|
|||||||
hoverMode={TooltipHoverMode.xAll}
|
hoverMode={TooltipHoverMode.xAll}
|
||||||
queryZoom={onChangeTimeRange}
|
queryZoom={onChangeTimeRange}
|
||||||
clientZoom={true}
|
clientZoom={true}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2) => {
|
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2, viaSync) => {
|
||||||
|
if (viaSync) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (timeRange2 != null) {
|
if (timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
|
@ -160,7 +160,7 @@ export const HeatmapPanel = ({
|
|||||||
const dataRef = useRef(info);
|
const dataRef = useRef(info);
|
||||||
dataRef.current = info;
|
dataRef.current = info;
|
||||||
const showNewVizTooltips =
|
const showNewVizTooltips =
|
||||||
config.featureToggles.newVizTooltips && (sync == null || sync() === DashboardCursorSync.Off);
|
config.featureToggles.newVizTooltips && (sync == null || sync() !== DashboardCursorSync.Tooltip);
|
||||||
|
|
||||||
const builder = useMemo(() => {
|
const builder = useMemo(() => {
|
||||||
const scaleConfig: ScaleDistributionConfig = dataRef.current?.heatmap?.fields[1].config?.custom?.scaleDistribution;
|
const scaleConfig: ScaleDistributionConfig = dataRef.current?.heatmap?.fields[1].config?.custom?.scaleDistribution;
|
||||||
@ -243,7 +243,11 @@ export const HeatmapPanel = ({
|
|||||||
config={builder}
|
config={builder}
|
||||||
hoverMode={TooltipHoverMode.xyOne}
|
hoverMode={TooltipHoverMode.xyOne}
|
||||||
queryZoom={onChangeTimeRange}
|
queryZoom={onChangeTimeRange}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2) => {
|
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2, viaSync) => {
|
||||||
|
if (viaSync) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (timeRange2 != null) {
|
if (timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
|
@ -603,7 +603,7 @@ export function prepConfig(opts: PrepConfigOpts) {
|
|||||||
if (sync && sync() !== DashboardCursorSync.Off) {
|
if (sync && sync() !== DashboardCursorSync.Off) {
|
||||||
cursor.sync = {
|
cursor.sync = {
|
||||||
key: eventsScope,
|
key: eventsScope,
|
||||||
scales: [xScaleKey, yScaleKey],
|
scales: [xScaleKey, null],
|
||||||
filters: {
|
filters: {
|
||||||
pub: (type: string, src: uPlot, x: number, y: number, w: number, h: number, dataIdx: number) => {
|
pub: (type: string, src: uPlot, x: number, y: number, w: number, h: number, dataIdx: number) => {
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
|
@ -167,7 +167,7 @@ export const StateTimelinePanel = ({
|
|||||||
}
|
}
|
||||||
const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations());
|
const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations());
|
||||||
const showNewVizTooltips =
|
const showNewVizTooltips =
|
||||||
config.featureToggles.newVizTooltips && (sync == null || sync() === DashboardCursorSync.Off);
|
config.featureToggles.newVizTooltips && (sync == null || sync() !== DashboardCursorSync.Tooltip);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TimelineChart
|
<TimelineChart
|
||||||
@ -207,7 +207,11 @@ export const StateTimelinePanel = ({
|
|||||||
config={builder}
|
config={builder}
|
||||||
hoverMode={TooltipHoverMode.xOne}
|
hoverMode={TooltipHoverMode.xOne}
|
||||||
queryZoom={onChangeTimeRange}
|
queryZoom={onChangeTimeRange}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2) => {
|
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2, viaSync) => {
|
||||||
|
if (viaSync) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (timeRange2 != null) {
|
if (timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
|
@ -196,7 +196,7 @@ export const StatusHistoryPanel = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const showNewVizTooltips =
|
const showNewVizTooltips =
|
||||||
config.featureToggles.newVizTooltips && (sync == null || sync() === DashboardCursorSync.Off);
|
config.featureToggles.newVizTooltips && (sync == null || sync() !== DashboardCursorSync.Tooltip);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TimelineChart
|
<TimelineChart
|
||||||
@ -235,7 +235,11 @@ export const StatusHistoryPanel = ({
|
|||||||
config={builder}
|
config={builder}
|
||||||
hoverMode={TooltipHoverMode.xyOne}
|
hoverMode={TooltipHoverMode.xyOne}
|
||||||
queryZoom={onChangeTimeRange}
|
queryZoom={onChangeTimeRange}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2) => {
|
render={(u, dataIdxs, seriesIdx, isPinned, dismiss, timeRange2, viaSync) => {
|
||||||
|
if (viaSync) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (timeRange2 != null) {
|
if (timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
|
@ -52,7 +52,7 @@ export const TimeSeriesPanel = ({
|
|||||||
|
|
||||||
const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations());
|
const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations());
|
||||||
const showNewVizTooltips =
|
const showNewVizTooltips =
|
||||||
config.featureToggles.newVizTooltips && (sync == null || sync() === DashboardCursorSync.Off);
|
config.featureToggles.newVizTooltips && (sync == null || sync() !== DashboardCursorSync.Tooltip);
|
||||||
// temp range set for adding new annotation set by TooltipPlugin2, consumed by AnnotationPlugin2
|
// temp range set for adding new annotation set by TooltipPlugin2, consumed by AnnotationPlugin2
|
||||||
const [newAnnotationRange, setNewAnnotationRange] = useState<TimeRange2 | null>(null);
|
const [newAnnotationRange, setNewAnnotationRange] = useState<TimeRange2 | null>(null);
|
||||||
|
|
||||||
@ -113,7 +113,11 @@ export const TimeSeriesPanel = ({
|
|||||||
}
|
}
|
||||||
queryZoom={onChangeTimeRange}
|
queryZoom={onChangeTimeRange}
|
||||||
clientZoom={true}
|
clientZoom={true}
|
||||||
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2) => {
|
render={(u, dataIdxs, seriesIdx, isPinned = false, dismiss, timeRange2, viaSync) => {
|
||||||
|
if (viaSync) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (timeRange2 != null) {
|
if (timeRange2 != null) {
|
||||||
setNewAnnotationRange(timeRange2);
|
setNewAnnotationRange(timeRange2);
|
||||||
dismiss();
|
dismiss();
|
||||||
|
Loading…
Reference in New Issue
Block a user