diff --git a/packages/grafana-ui/src/components/uPlot/config/addTooltipSupport.ts b/packages/grafana-ui/src/components/uPlot/config/addTooltipSupport.ts index b0d47ac643a..4d27d14166f 100644 --- a/packages/grafana-ui/src/components/uPlot/config/addTooltipSupport.ts +++ b/packages/grafana-ui/src/components/uPlot/config/addTooltipSupport.ts @@ -1,6 +1,6 @@ import { Dispatch, MutableRefObject, SetStateAction } from 'react'; -import { CartesianCoords2D } from '@grafana/data'; +import { CartesianCoords2D, DashboardCursorSync } from '@grafana/data'; import { positionTooltip } from '../plugins/TooltipPlugin'; @@ -21,6 +21,9 @@ type SetupConfigParams = { setCoords: Dispatch>; setHover: Dispatch>; isToolTipOpen: MutableRefObject; + isActive: boolean; + setIsActive: Dispatch>; + sync?: (() => DashboardCursorSync) | undefined; }; // This applies config hooks to setup tooltip listener. Ideally this could happen in the same `prepConfig` function @@ -33,13 +36,26 @@ export const addTooltipSupport = ({ setCoords, setHover, isToolTipOpen, + isActive, + setIsActive, + sync, }: SetupConfigParams): UPlotConfigBuilder => { // Ensure tooltip is closed on config changes isToolTipOpen.current = false; + const onMouseEnter = () => { + if (setIsActive) { + setIsActive(true); + } + }; + const onMouseLeave = () => { if (!isToolTipOpen.current) { setCoords(null); + + if (setIsActive) { + setIsActive(false); + } } }; @@ -50,6 +66,11 @@ export const addTooltipSupport = ({ ref_over = u.over; ref_parent?.addEventListener('click', onUPlotClick); ref_over.addEventListener('mouseleave', onMouseLeave); + ref_over.addEventListener('mouseenter', onMouseEnter); + + if (sync && sync() === DashboardCursorSync.Crosshair) { + u.root.classList.add('shared-crosshair'); + } }); const clearPopupIfOpened = () => { @@ -64,6 +85,7 @@ export const addTooltipSupport = ({ config.addHook('destroy', () => { ref_parent?.removeEventListener('click', onUPlotClick); ref_over?.removeEventListener('mouseleave', onMouseLeave); + ref_over?.removeEventListener('mouseenter', onMouseEnter); clearPopupIfOpened(); }); @@ -84,7 +106,7 @@ export const addTooltipSupport = ({ setFocusedSeriesIdx, setFocusedPointIdx, (clear) => { - if (clear) { + if (clear && isActive) { setCoords(null); return; } @@ -104,7 +126,7 @@ export const addTooltipSupport = ({ } config.addHook('setLegend', (u) => { - if (!isToolTipOpen.current && !tooltipInterpolator) { + if (!isToolTipOpen.current) { setFocusedPointIdx(u.legend.idx!); } if (u.cursor.idxs != null) { diff --git a/public/app/plugins/panel/barchart/BarChartPanel.tsx b/public/app/plugins/panel/barchart/BarChartPanel.tsx index e0533c4439a..8655e3609bd 100644 --- a/public/app/plugins/panel/barchart/BarChartPanel.tsx +++ b/public/app/plugins/panel/barchart/BarChartPanel.tsx @@ -82,6 +82,7 @@ export const BarChartPanel: React.FunctionComponent = ({ const [coords, setCoords] = useState<{ viewport: CartesianCoords2D; canvas: CartesianCoords2D } | null>(null); const [focusedSeriesIdx, setFocusedSeriesIdx] = useState(null); const [focusedPointIdx, setFocusedPointIdx] = useState(null); + const [isActive, setIsActive] = useState(false); const [shouldDisplayCloseButton, setShouldDisplayCloseButton] = useState(false); const onCloseToolTip = () => { @@ -298,6 +299,8 @@ export const BarChartPanel: React.FunctionComponent = ({ setCoords, setHover, isToolTipOpen, + isActive, + setIsActive, }); } @@ -307,7 +310,7 @@ export const BarChartPanel: React.FunctionComponent = ({ return ( - {hover && coords && ( + {hover && coords && focusedSeriesIdx && ( = ({ const [coords, setCoords] = useState<{ viewport: CartesianCoords2D; canvas: CartesianCoords2D } | null>(null); const [focusedSeriesIdx, setFocusedSeriesIdx] = useState(null); const [focusedPointIdx, setFocusedPointIdx] = useState(null); + const [isActive, setIsActive] = useState(false); const [shouldDisplayCloseButton, setShouldDisplayCloseButton] = useState(false); - const { canAddAnnotations } = usePanelContext(); + const { sync, canAddAnnotations } = usePanelContext(); const onCloseToolTip = () => { isToolTipOpen.current = false; @@ -178,6 +179,9 @@ export const StateTimelinePanel: React.FC = ({ setCoords, setHover, isToolTipOpen, + isActive, + setIsActive, + sync, }); } @@ -198,9 +202,13 @@ export const StateTimelinePanel: React.FC = ({ return null; } + if (focusedPointIdx === null || (!isActive && sync && sync() === DashboardCursorSync.Crosshair)) { + return null; + } + return ( - {hover && coords && ( + {hover && coords && focusedSeriesIdx && ( = ({ const [coords, setCoords] = useState<{ viewport: CartesianCoords2D; canvas: CartesianCoords2D } | null>(null); const [focusedSeriesIdx, setFocusedSeriesIdx] = useState(null); const [focusedPointIdx, setFocusedPointIdx] = useState(null); + const [isActive, setIsActive] = useState(false); const [shouldDisplayCloseButton, setShouldDisplayCloseButton] = useState(false); + const { sync } = usePanelContext(); const onCloseToolTip = () => { isToolTipOpen.current = false; @@ -179,6 +182,8 @@ export const StatusHistoryPanel: React.FC = ({ setCoords, setHover, isToolTipOpen, + isActive, + setIsActive, }); } @@ -186,11 +191,15 @@ export const StatusHistoryPanel: React.FC = ({ return null; } + if (focusedPointIdx === null || (!isActive && sync && sync() === DashboardCursorSync.Crosshair)) { + return null; + } + return ( <> - {hover && coords && ( + {hover && coords && focusedSeriesIdx && (