@grafana/ui
Version:
Grafana Components Library
1 lines • 17.7 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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"}