@grafana/ui
Version:
Grafana Components Library
1 lines • 17.9 kB
Source Map (JSON)
{"version":3,"file":"TooltipPlugin.mjs","sources":["../../../../../src/graveyard/uPlot/plugins/TooltipPlugin.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { useLayoutEffect, useRef, useState } from 'react';\nimport * as React from 'react';\nimport { useMountedState } from 'react-use';\nimport uPlot from 'uplot';\n\nimport {\n arrayUtils,\n CartesianCoords2D,\n DashboardCursorSync,\n DataFrame,\n FALLBACK_COLOR,\n FieldType,\n formattedValueToString,\n getDisplayProcessor,\n getFieldDisplayName,\n GrafanaTheme2,\n TimeZone,\n} from '@grafana/data';\nimport { TooltipDisplayMode, SortOrder } from '@grafana/schema';\n\nimport { Portal } from '../../../components/Portal/Portal';\nimport { SeriesTable, SeriesTableRowProps } from '../../../components/VizTooltip/SeriesTable';\nimport { UPlotConfigBuilder } from '../../../components/uPlot/config/UPlotConfigBuilder';\nimport { VizTooltipContainer } from '../../../components/VizTooltip/VizTooltipContainer';\nimport { findMidPointYPosition } from '../../../components/uPlot/utils';\nimport { useStyles2, useTheme2 } from '../../../themes/ThemeContext';\n\ninterface TooltipPluginProps {\n timeZone: TimeZone;\n data: DataFrame;\n frames?: DataFrame[];\n config: UPlotConfigBuilder;\n mode?: TooltipDisplayMode;\n sortOrder?: SortOrder;\n sync?: () => DashboardCursorSync;\n // Allows custom tooltip content rendering. Exposes aligned data frame with relevant indexes for data inspection\n // Use field.state.origin indexes from alignedData frame field to get access to original data frame and field index.\n renderTooltip?: (alignedFrame: DataFrame, seriesIdx: number | null, datapointIdx: number | null) => React.ReactNode;\n}\n\nconst TOOLTIP_OFFSET = 10;\n\n/**\n * @alpha\n */\nexport const TooltipPlugin = ({\n mode = TooltipDisplayMode.Single,\n sortOrder = SortOrder.None,\n sync,\n timeZone,\n config,\n renderTooltip,\n ...otherProps\n}: TooltipPluginProps) => {\n const plotInstance = useRef<uPlot>();\n const theme = useTheme2();\n const [focusedSeriesIdx, setFocusedSeriesIdx] = useState<number | null>(null);\n const [focusedPointIdx, setFocusedPointIdx] = useState<number | null>(null);\n const [focusedPointIdxs, setFocusedPointIdxs] = useState<Array<number | null>>([]);\n const [coords, setCoords] = useState<CartesianCoords2D | null>(null);\n const [isActive, setIsActive] = useState<boolean>(false);\n const isMounted = useMountedState();\n let parentWithFocus: HTMLElement | null = null;\n\n const style = useStyles2(getStyles);\n\n // Add uPlot hooks to the config, or re-add when the config changed\n useLayoutEffect(() => {\n let bbox: DOMRect | undefined = undefined;\n\n const plotEnter = () => {\n if (!isMounted()) {\n return;\n }\n setIsActive(true);\n plotInstance.current?.root.classList.add('plot-active');\n };\n\n const plotLeave = () => {\n if (!isMounted()) {\n return;\n }\n setCoords(null);\n setIsActive(false);\n plotInstance.current?.root.classList.remove('plot-active');\n };\n\n // cache uPlot plotting area bounding box\n config.addHook('syncRect', (u, rect) => (bbox = rect));\n\n config.addHook('init', (u) => {\n plotInstance.current = u;\n\n u.over.addEventListener('mouseenter', plotEnter);\n u.over.addEventListener('mouseleave', plotLeave);\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n parentWithFocus = u.root.closest('[tabindex]');\n\n if (parentWithFocus) {\n parentWithFocus.addEventListener('focus', plotEnter);\n parentWithFocus.addEventListener('blur', plotLeave);\n }\n\n if (sync && sync() === DashboardCursorSync.Crosshair) {\n u.root.classList.add('shared-crosshair');\n }\n });\n\n config.addHook('setLegend', (u) => {\n if (!isMounted()) {\n return;\n }\n setFocusedPointIdx(u.legend.idx!);\n setFocusedPointIdxs(u.legend.idxs!.slice());\n });\n\n // default series/datapoint idx retireval\n config.addHook('setCursor', (u) => {\n if (!bbox || !isMounted()) {\n return;\n }\n\n const { x, y } = positionTooltip(u, bbox);\n if (x !== undefined && y !== undefined) {\n setCoords({ x, y });\n } else {\n setCoords(null);\n }\n });\n\n config.addHook('setSeries', (_, idx) => {\n if (!isMounted()) {\n return;\n }\n setFocusedSeriesIdx(idx);\n });\n\n return () => {\n setCoords(null);\n\n if (plotInstance.current) {\n plotInstance.current.over.removeEventListener('mouseleave', plotLeave);\n plotInstance.current.over.removeEventListener('mouseenter', plotEnter);\n\n if (parentWithFocus) {\n parentWithFocus.removeEventListener('focus', plotEnter);\n parentWithFocus.removeEventListener('blur', plotLeave);\n }\n }\n };\n }, [config, setCoords, setIsActive, setFocusedPointIdx, setFocusedPointIdxs]);\n\n if (focusedPointIdx === null || (!isActive && sync && sync() === DashboardCursorSync.Crosshair)) {\n return null;\n }\n\n // GraphNG expects aligned data, let's take field 0 as x field. FTW\n let xField = otherProps.data.fields[0];\n if (!xField) {\n return null;\n }\n const xFieldFmt = xField.display || getDisplayProcessor({ field: xField, timeZone, theme });\n let tooltip: React.ReactNode = null;\n\n let xVal = xFieldFmt(xField!.values[focusedPointIdx]).text;\n\n if (!renderTooltip) {\n // when interacting with a point in single mode\n if (mode === TooltipDisplayMode.Single && focusedSeriesIdx !== null) {\n const field = otherProps.data.fields[focusedSeriesIdx];\n\n if (!field) {\n return null;\n }\n\n const dataIdx = focusedPointIdxs?.[focusedSeriesIdx] ?? focusedPointIdx;\n xVal = xFieldFmt(xField!.values[dataIdx]).text;\n const fieldFmt = field.display || getDisplayProcessor({ field, timeZone, theme });\n const display = fieldFmt(field.values[dataIdx]);\n\n tooltip = (\n <SeriesTable\n series={[\n {\n color: display.color || FALLBACK_COLOR,\n label: getFieldDisplayName(field, otherProps.data, otherProps.frames),\n value: display ? formattedValueToString(display) : null,\n },\n ]}\n timestamp={xVal}\n />\n );\n }\n\n if (mode === TooltipDisplayMode.Multi) {\n let series: SeriesTableRowProps[] = [];\n const frame = otherProps.data;\n const fields = frame.fields;\n const sortIdx: unknown[] = [];\n\n for (let i = 0; i < fields.length; i++) {\n const field = frame.fields[i];\n if (\n !field ||\n field === xField ||\n field.type === FieldType.time ||\n field.type !== FieldType.number ||\n field.config.custom?.hideFrom?.tooltip ||\n field.config.custom?.hideFrom?.viz\n ) {\n continue;\n }\n\n const v = otherProps.data.fields[i].values[focusedPointIdxs[i]!];\n const display = field.display!(v);\n\n sortIdx.push(v);\n series.push({\n color: display.color || FALLBACK_COLOR,\n label: getFieldDisplayName(field, frame, otherProps.frames),\n value: display ? formattedValueToString(display) : null,\n isActive: focusedSeriesIdx === i,\n });\n }\n\n if (sortOrder !== SortOrder.None) {\n // create sort reference series array, as Array.sort() mutates the original array\n const sortRef = [...series];\n const sortFn = arrayUtils.sortValues(sortOrder);\n\n series.sort((a, b) => {\n // get compared values indices to retrieve raw values from sortIdx\n const aIdx = sortRef.indexOf(a);\n const bIdx = sortRef.indexOf(b);\n return sortFn(sortIdx[aIdx], sortIdx[bIdx]);\n });\n }\n\n tooltip = <SeriesTable series={series} timestamp={xVal} />;\n }\n } else {\n tooltip = renderTooltip(otherProps.data, focusedSeriesIdx, focusedPointIdx);\n }\n\n return (\n <Portal className={isActive ? style.tooltipWrapper : undefined}>\n {tooltip && coords && (\n <VizTooltipContainer position={{ x: coords.x, y: coords.y }} offset={{ x: TOOLTIP_OFFSET, y: TOOLTIP_OFFSET }}>\n {tooltip}\n </VizTooltipContainer>\n )}\n </Portal>\n );\n};\n\nfunction isCursorOutsideCanvas({ left, top }: uPlot.Cursor, canvas: DOMRect) {\n if (left === undefined || top === undefined) {\n return false;\n }\n return left < 0 || left > canvas.width || top < 0 || top > canvas.height;\n}\n\n/**\n * Given uPlot cursor position, figure out position of the tooltip withing the canvas bbox\n * Tooltip is positioned relatively to a viewport\n * @internal\n **/\nexport function positionTooltip(u: uPlot, bbox: DOMRect) {\n let x, y;\n const cL = u.cursor.left || 0;\n const cT = u.cursor.top || 0;\n\n if (isCursorOutsideCanvas(u.cursor, bbox)) {\n const idx = u.posToIdx(cL);\n // when cursor outside of uPlot's canvas\n if (cT < 0 || cT > bbox.height) {\n let pos = findMidPointYPosition(u, idx);\n\n if (pos) {\n y = bbox.top + pos;\n if (cL >= 0 && cL <= bbox.width) {\n // find x-scale position for a current cursor left position\n x = bbox.left + u.valToPos(u.data[0][u.posToIdx(cL)], u.series[0].scale!);\n }\n }\n }\n } else {\n x = bbox.left + cL;\n y = bbox.top + cT;\n }\n\n return { x, y };\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n tooltipWrapper: css({\n 'z-index': theme.zIndex.portal + 1 + ' !important',\n }),\n});\n"],"names":["_a"],"mappings":"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"}