@grafana/ui
Version:
Grafana Components Library
1 lines • 12.6 kB
Source Map (JSON)
{"version":3,"file":"cellUtils.mjs","sources":["../../../../src/components/Table/cellUtils.ts"],"sourcesContent":["import { type Property } from 'csstype';\nimport tinycolor from 'tinycolor2';\n\nimport {\n type ActionModel,\n type DisplayValue,\n type DisplayValueAlignmentFactors,\n type Field,\n FieldType,\n formattedValueToString,\n type GrafanaTheme2,\n type LinkModel,\n} from '@grafana/data';\nimport {\n BarGaugeDisplayMode,\n type TableAutoCellOptions,\n TableCellBackgroundDisplayMode,\n TableCellDisplayMode,\n} from '@grafana/schema';\n\nimport { getTextColorForAlphaBackground } from '../../utils/colors';\n\nimport { type CellColors, type TableCellOptions, type TableFieldOptions } from './types';\n\nexport function getTextAlign(field?: Field): Property.JustifyContent {\n if (!field) {\n return 'flex-start';\n }\n\n if (field.config.custom) {\n const custom: TableFieldOptions = field.config.custom;\n\n switch (custom.align) {\n case 'right':\n return 'flex-end';\n case 'left':\n return 'flex-start';\n case 'center':\n return 'center';\n }\n }\n\n if (field.type === FieldType.number) {\n return 'flex-end';\n }\n\n return 'flex-start';\n}\n\nconst defaultCellOptions: TableAutoCellOptions = { type: TableCellDisplayMode.Auto };\n\nexport function getCellOptions(field: Field): TableCellOptions {\n if (field.config.custom?.displayMode) {\n return migrateTableDisplayModeToCellOptions(field.config.custom?.displayMode);\n }\n\n if (!field.config.custom?.cellOptions) {\n return defaultCellOptions;\n }\n\n return field.config.custom.cellOptions;\n}\n\n/**\n * Migrates table cell display mode to new object format.\n *\n * @param displayMode The display mode of the cell\n * @returns TableCellOptions object in the correct format\n * relative to the old display mode.\n */\nexport function migrateTableDisplayModeToCellOptions(displayMode: TableCellDisplayMode): TableCellOptions {\n switch (displayMode) {\n // In the case of the gauge we move to a different option\n case 'basic':\n case 'gradient-gauge':\n case 'lcd-gauge':\n let gaugeMode = BarGaugeDisplayMode.Basic;\n\n if (displayMode === 'gradient-gauge') {\n gaugeMode = BarGaugeDisplayMode.Gradient;\n } else if (displayMode === 'lcd-gauge') {\n gaugeMode = BarGaugeDisplayMode.Lcd;\n }\n\n return {\n type: TableCellDisplayMode.Gauge,\n mode: gaugeMode,\n };\n // Also true in the case of the color background\n case 'color-background':\n case 'color-background-solid':\n let mode = TableCellBackgroundDisplayMode.Basic;\n\n // Set the new mode field, somewhat confusingly the\n // color-background mode is for gradient display\n if (displayMode === 'color-background') {\n mode = TableCellBackgroundDisplayMode.Gradient;\n }\n\n return {\n type: TableCellDisplayMode.ColorBackground,\n mode: mode,\n };\n default:\n // @ts-ignore TSGO / TS7\n return {\n // @ts-ignore TS5 / TS6\n type: displayMode,\n };\n }\n}\n\n/**\n * Getting gauge or sparkline values to align is very tricky without looking at all values and passing them through display processor.\n * For very large tables that could pretty expensive. So this is kind of a compromise. We look at the first 1000 rows and cache the longest value.\n * If we have a cached value we just check if the current value is longer and update the alignmentFactor. This can obviously still lead to\n * unaligned gauges but it should a lot less common.\n **/\nexport function getAlignmentFactor(\n field: Field,\n displayValue: DisplayValue,\n rowIndex: number\n): DisplayValueAlignmentFactors {\n let alignmentFactor = field.state?.alignmentFactors;\n\n if (alignmentFactor) {\n // check if current alignmentFactor is still the longest\n if (formattedValueToString(alignmentFactor).length < formattedValueToString(displayValue).length) {\n alignmentFactor = { ...displayValue };\n field.state!.alignmentFactors = alignmentFactor;\n }\n return alignmentFactor;\n } else {\n // look at the next 1000 rows\n alignmentFactor = { ...displayValue };\n const maxIndex = Math.min(field.values.length, rowIndex + 1000);\n\n for (let i = rowIndex + 1; i < maxIndex; i++) {\n const nextDisplayValue = field.display!(field.values[i]);\n if (formattedValueToString(alignmentFactor).length > formattedValueToString(nextDisplayValue).length) {\n alignmentFactor.text = displayValue.text;\n }\n }\n\n if (field.state) {\n field.state.alignmentFactors = alignmentFactor;\n } else {\n field.state = { alignmentFactors: alignmentFactor };\n }\n\n return alignmentFactor;\n }\n}\n\n/**\n * Retrieve colors for a table cell (or table row).\n *\n * @param tableStyles\n * Styles for the table\n * @param cellOptions\n * Table cell configuration options\n * @param displayValue\n * The value that will be displayed\n * @returns CellColors\n */\nexport function getCellColors(\n theme: GrafanaTheme2,\n cellOptions: TableCellOptions,\n displayValue: DisplayValue\n): CellColors {\n // How much to darken elements depends upon if we're in dark mode\n const darkeningFactor = theme.isDark ? 1 : -0.7;\n\n // Setup color variables\n let textColor: string | undefined = undefined;\n let bgColor: string | undefined = undefined;\n let bgHoverColor: string | undefined = undefined;\n\n if (cellOptions.type === TableCellDisplayMode.ColorText) {\n textColor = displayValue.color;\n } else if (cellOptions.type === TableCellDisplayMode.ColorBackground) {\n const mode = cellOptions.mode ?? TableCellBackgroundDisplayMode.Gradient;\n\n if (mode === TableCellBackgroundDisplayMode.Basic) {\n textColor = getTextColorForAlphaBackground(displayValue.color!, theme.isDark);\n bgColor = tinycolor(displayValue.color).toRgbString();\n bgHoverColor = tinycolor(displayValue.color).setAlpha(1).toRgbString();\n } else if (mode === TableCellBackgroundDisplayMode.Gradient) {\n const hoverColor = tinycolor(displayValue.color).setAlpha(1).toRgbString();\n const bgColor2 = tinycolor(displayValue.color)\n .darken(10 * darkeningFactor)\n .spin(5);\n textColor = getTextColorForAlphaBackground(displayValue.color!, theme.isDark);\n bgColor = `linear-gradient(120deg, ${bgColor2.toRgbString()}, ${displayValue.color})`;\n bgHoverColor = `linear-gradient(120deg, ${bgColor2.setAlpha(1).toRgbString()}, ${hoverColor})`;\n }\n }\n\n return { textColor, bgColor, bgHoverColor };\n}\n\nexport interface DataLinksActionsTooltipState {\n coords: DataLinksActionsTooltipCoords;\n links?: LinkModel[];\n actions?: ActionModel[];\n}\n\nexport interface DataLinksActionsTooltipCoords {\n clientX: number;\n clientY: number;\n}\n\nexport const getDataLinksActionsTooltipUtils = (links: LinkModel[], actions?: ActionModel[]) => {\n const hasMultipleLinksOrActions = links.length > 1 || Boolean(actions?.length);\n const shouldShowLink = links.length === 1 && !Boolean(actions?.length);\n\n return { shouldShowLink, hasMultipleLinksOrActions };\n};\n\nconst shouldTriggerTooltip = (event: React.MouseEvent<HTMLElement>): boolean => {\n return event.target === event.currentTarget;\n};\n\n/**\n * Creates an onClick handler for table cells that only triggers tooltip when clicking directly on the cell\n * @param setTooltipCoords - function to set tooltip coordinates\n * @returns onClick handler\n */\nexport const tooltipOnClickHandler = (setTooltipCoords: (coords: DataLinksActionsTooltipCoords) => void) => {\n return (event: React.MouseEvent<HTMLElement>) => {\n if (shouldTriggerTooltip(event)) {\n const { clientX, clientY } = event;\n setTooltipCoords({ clientX, clientY });\n }\n };\n};\n"],"names":[],"mappings":"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"}