UNPKG

@grafana/ui

Version:
1 lines • 32.8 kB
{"version":3,"file":"utils.cjs","sources":["../../../../src/components/Table/utils.ts"],"sourcesContent":["import { clone, sampleSize } from 'lodash';\nimport memoize from 'micro-memoize';\nimport { type HeaderGroup, type Row } from 'react-table';\n\nimport {\n type DataFrame,\n type Field,\n type FieldConfigSource,\n fieldReducers,\n FieldType,\n formattedValueToString,\n getDisplayProcessor,\n getFieldDisplayName,\n type GrafanaTheme2,\n isDataFrame,\n isDataFrameWithValue,\n isTimeSeriesFrame,\n reduceField,\n type SelectableValue,\n} from '@grafana/data';\nimport { TableCellDisplayMode } from '@grafana/schema';\n\nimport { ActionsCell } from './ActionsCell';\nimport { BarGaugeCell } from './Cells/BarGaugeCell';\nimport { DataLinksCell } from './Cells/DataLinksCell';\nimport { DefaultCell } from './Cells/DefaultCell';\nimport { GeoCell } from './Cells/GeoCell';\nimport { ImageCell } from './Cells/ImageCell';\nimport { JSONViewCell } from './Cells/JSONViewCell';\nimport { SparklineCell } from './Cells/SparklineCell';\nimport { getFooterValue } from './TableRT/FooterRow';\nimport { RowExpander } from './TableRT/RowExpander';\nimport { getTextAlign } from './cellUtils';\nimport {\n type CellComponent,\n type FooterItem,\n type GrafanaTableColumn,\n type TableFieldOptions,\n type TableFooterCalc,\n} from './types';\n\nexport const EXPANDER_WIDTH = 50;\n\nexport function getColumns(\n data: DataFrame,\n availableWidth: number,\n columnMinWidth: number,\n expander: boolean,\n footerValues?: FooterItem[],\n isCountRowsSet?: boolean\n): GrafanaTableColumn[] {\n const columns: GrafanaTableColumn[] = [];\n let fieldCountWithoutWidth = 0;\n\n if (expander) {\n columns.push({\n // Make an expander cell\n Header: () => null, // No header\n id: 'expander', // It needs an ID\n // @ts-expect-error\n // TODO fix type error here\n Cell: RowExpander,\n width: EXPANDER_WIDTH,\n minWidth: EXPANDER_WIDTH,\n filter: (_rows: Row[], _id: string, _filterValues?: SelectableValue[]) => {\n return [];\n },\n justifyContent: 'left',\n field: data.fields[0],\n sortType: 'basic',\n });\n\n availableWidth -= EXPANDER_WIDTH;\n }\n\n for (const [fieldIndex, field] of data.fields.entries()) {\n const fieldTableOptions: TableFieldOptions = field.config.custom || {};\n if (\n // @ts-ignore this was the former hidden option; we support it for legacy use cases while TableRT is being sunset.\n fieldTableOptions.hidden ||\n fieldTableOptions.hideFrom?.viz ||\n field.type === FieldType.nestedFrames\n ) {\n continue;\n }\n\n if (fieldTableOptions.width) {\n availableWidth -= fieldTableOptions.width;\n } else {\n fieldCountWithoutWidth++;\n }\n\n const selectSortType = (type: FieldType) => {\n switch (type) {\n case FieldType.number:\n case FieldType.frame:\n return 'number';\n case FieldType.time:\n return 'basic';\n default:\n return 'alphanumeric-insensitive';\n }\n };\n\n const Cell = getCellComponent(fieldTableOptions.cellOptions?.type, field);\n columns.push({\n // @ts-expect-error\n // TODO fix type error here\n Cell,\n id: fieldIndex.toString(),\n field: field,\n Header: fieldTableOptions.hideHeader ? '' : getFieldDisplayName(field, data),\n accessor: (_row, i) => field.values[i],\n sortType: selectSortType(field.type),\n width: fieldTableOptions.width,\n minWidth: fieldTableOptions.minWidth ?? columnMinWidth,\n filter: memoize(filterByValue(field)),\n justifyContent: getTextAlign(field),\n Footer: getFooterValue(fieldIndex, footerValues, isCountRowsSet),\n });\n }\n\n // set columns that are at minimum width\n let sharedWidth = availableWidth / fieldCountWithoutWidth;\n for (let i = fieldCountWithoutWidth; i > 0; i--) {\n for (const column of columns) {\n if (!column.width && column.minWidth > sharedWidth) {\n column.width = column.minWidth;\n availableWidth -= column.width;\n fieldCountWithoutWidth -= 1;\n sharedWidth = availableWidth / fieldCountWithoutWidth;\n }\n }\n }\n\n // divide up the rest of the space\n for (const column of columns) {\n if (!column.width) {\n column.width = sharedWidth;\n }\n column.minWidth = 50;\n }\n\n return columns;\n}\n\nfunction getCellComponent(displayMode: TableCellDisplayMode, field: Field): CellComponent {\n switch (displayMode) {\n case TableCellDisplayMode.Custom:\n case TableCellDisplayMode.ColorText:\n case TableCellDisplayMode.ColorBackground:\n return DefaultCell;\n case TableCellDisplayMode.Image:\n return ImageCell;\n case TableCellDisplayMode.Gauge:\n return BarGaugeCell;\n case TableCellDisplayMode.Sparkline:\n return SparklineCell;\n case TableCellDisplayMode.JSONView:\n return JSONViewCell;\n case TableCellDisplayMode.DataLinks:\n return DataLinksCell;\n case TableCellDisplayMode.Actions:\n return ActionsCell;\n case TableCellDisplayMode.Pill:\n return DefaultCell; // Legacy table doesn't support pill cells, fallback to default\n }\n\n if (field.type === FieldType.geo) {\n return GeoCell;\n }\n\n if (field.type === FieldType.frame) {\n const firstValue = field.values[0];\n if (isDataFrame(firstValue) && isTimeSeriesFrame(firstValue)) {\n return SparklineCell;\n }\n\n return JSONViewCell;\n }\n\n // Default or Auto\n if (field.type === FieldType.other) {\n return JSONViewCell;\n }\n\n return DefaultCell;\n}\n\nexport function filterByValue(field?: Field) {\n return function (rows: Row[], id: string, filterValues?: SelectableValue[]) {\n if (rows.length === 0) {\n return rows;\n }\n\n if (!filterValues) {\n return rows;\n }\n\n if (!field) {\n return rows;\n }\n\n return rows.filter((row) => {\n if (!row.values.hasOwnProperty(id)) {\n return false;\n }\n const value = rowToFieldValue(row, field);\n return filterValues.find((filter) => filter.value === value) !== undefined;\n });\n };\n}\n\nexport function calculateUniqueFieldValues(rows: any[], field?: Field) {\n if (!field || rows.length === 0) {\n return {};\n }\n\n const set: Record<string, string> = {};\n\n for (let index = 0; index < rows.length; index++) {\n const value = rowToFieldValue(rows[index], field);\n set[value || '(Blanks)'] = value;\n }\n\n return set;\n}\n\nexport function rowToFieldValue(row: any, field?: Field): string {\n if (!field || !row) {\n return '';\n }\n\n const fieldValue = field.values[row.index];\n const displayValue = field.display ? field.display(fieldValue) : fieldValue;\n const value = field.display ? formattedValueToString(displayValue) : displayValue;\n\n return value;\n}\n\nexport function valuesToOptions(unique: Record<string, unknown>): SelectableValue[] {\n return Object.keys(unique)\n .reduce<SelectableValue[]>((all, key) => all.concat({ value: unique[key], label: key }), [])\n .sort(sortOptions);\n}\n\nexport function sortOptions(a: SelectableValue, b: SelectableValue): number {\n if (a.label === undefined && b.label === undefined) {\n return 0;\n }\n\n if (a.label === undefined && b.label !== undefined) {\n return -1;\n }\n\n if (a.label !== undefined && b.label === undefined) {\n return 1;\n }\n\n if (a.label! < b.label!) {\n return -1;\n }\n\n if (a.label! > b.label!) {\n return 1;\n }\n\n return 0;\n}\n\nexport function getFilteredOptions(options: SelectableValue[], filterValues?: SelectableValue[]): SelectableValue[] {\n if (!filterValues) {\n return [];\n }\n\n return options.filter((option) => filterValues.some((filtered) => filtered.value === option.value));\n}\n\nexport function sortCaseInsensitive(a: Row, b: Row, id: string) {\n return String(a.values[id]).localeCompare(String(b.values[id]), undefined, { sensitivity: 'base' });\n}\n\n// sortNumber needs to have great performance as it is called a lot\nexport function sortNumber(rowA: Row, rowB: Row, id: string) {\n const a = toNumber(rowA.values[id]);\n const b = toNumber(rowB.values[id]);\n return a === b ? 0 : a > b ? 1 : -1;\n}\n\nfunction toNumber(value: any): number {\n if (isDataFrameWithValue(value)) {\n return value.value ?? Number.NEGATIVE_INFINITY;\n }\n\n if (value === null || value === undefined || value === '' || isNaN(value)) {\n return Number.NEGATIVE_INFINITY;\n }\n\n if (typeof value === 'number') {\n return value;\n }\n\n return Number(value);\n}\n\nexport function getFooterItems(\n filterFields: Array<{ id: string; field?: Field } | undefined>,\n values: any[number],\n options: TableFooterCalc,\n theme2: GrafanaTheme2\n): FooterItem[] {\n /*\n The FooterItems[] are calculated using both the `headerGroups[0].headers`\n (filterFields) and `rows` (values) destructured from the useTable() hook.\n This cacluation is based on the data from each index in `filterFields`\n array as well as the corresponding index in the `values` array.\n When the user hides a column through an override, the getColumns()\n hook is invoked, removes said hidden column, sends the updated column\n data to the useTable() hook, which then builds `headerGroups[0].headers`\n without the hidden column. However, it doesn't remove the hidden column\n from the `row` data, instead it substututes the hidden column row data\n with an `undefined` value. Therefore, the `row` array length never changes,\n despite the `headerGroups[0].headers` length changing at every column removal.\n This makes all footer reduce calculations AFTER the first hidden column\n in the `headerGroups[0].headers` break, since the indexing of both\n arrays is no longer in parity.\n\n So, here we simply recursively test for the \"hidden\" columns\n from `headerGroups[0].headers`. Each column has an ID property that corresponds\n to its own index, therefore if (`filterField.id` !== `String(index)`),\n we know there is one or more hidden columns; at which point we update\n the index with an ersatz placeholder with just an `id` property.\n */\n addMissingColumnIndex(filterFields);\n\n return filterFields.map((data, i) => {\n // Then test for numerical data - this will filter out placeholder `filterFields` as well.\n if (data?.field?.type !== FieldType.number) {\n // Show the reducer in the first column\n if (i === 0 && options.reducer && options.reducer.length > 0) {\n const reducer = fieldReducers.get(options.reducer[0]);\n return reducer.name;\n }\n // Render an <EmptyCell />.\n return undefined;\n }\n\n let newField = clone(data.field);\n newField.values = values[data.id];\n newField.state = undefined;\n\n data.field = newField;\n\n if (options.fields && options.fields.length > 0) {\n const f = options.fields.find((f) => f === data?.field?.name);\n if (f) {\n return getFormattedValue(data.field, options.reducer, theme2);\n }\n return undefined;\n }\n return getFormattedValue(data.field, options.reducer || [], theme2);\n });\n}\n\nfunction getFormattedValue(field: Field, reducer: string[], theme: GrafanaTheme2) {\n // If we don't have anything to return then we display nothing\n const calc = reducer[0];\n if (calc === undefined) {\n return '';\n }\n\n // Calculate the reduction\n const format = field.display ?? getDisplayProcessor({ field, theme });\n const fieldCalcValue = reduceField({ field, reducers: reducer })[calc];\n\n // If the reducer preserves units then format the\n // end value with the field display processor\n const reducerInfo = fieldReducers.get(calc);\n if (reducerInfo.preservesUnits) {\n return formattedValueToString(format(fieldCalcValue));\n }\n\n // Otherwise we simply return the formatted string\n return formattedValueToString({ text: fieldCalcValue });\n}\n\n// This strips the raw vales from the `rows` object.\nexport function createFooterCalculationValues(rows: Row[]): any[number] {\n const values: any[number] = [];\n\n for (const key in rows) {\n for (const [valKey, val] of Object.entries(rows[key].values)) {\n if (values[valKey] === undefined) {\n values[valKey] = [];\n }\n values[valKey].push(val);\n }\n }\n\n return values;\n}\n\n/**\n * This recurses through an array of `filterFields` (Array<{ id: string; field?: Field } | undefined>)\n * and adds back the missing indecies that are removed due to hiding a column through an panel override.\n * This is necessary to create Array.length parity between the `filterFields` array and the `values` array (any[number]),\n * since the footer value calculations are based on the corresponding index values of both arrays.\n *\n * @remarks\n * This function uses the splice() method, and therefore mutates the array.\n *\n * @param columns - An array of `filterFields` (Array<{ id: string; field?: Field } | undefined>).\n * @returns void; this function returns nothing; it only mutates values as a side effect.\n */\nfunction addMissingColumnIndex(columns: Array<{ id: string; field?: Field } | undefined>): void {\n const missingIndex = columns.findIndex((field, index) => field?.id !== String(index));\n\n // Base case\n if (missingIndex === -1 || columns[missingIndex]?.id === 'expander') {\n return;\n }\n\n // Splice in missing column\n columns.splice(missingIndex, 0, { id: String(missingIndex) });\n\n // Recurse\n addMissingColumnIndex(columns);\n}\n\n// since the conversion from timeseries panel crosshair to time is pixel based, we need\n// to set a threshold where the table row highlights when the crosshair is hovered over a certain point\n// because multiple pixels (converted to times) may represent the same point/row in table\nexport function isPointTimeValAroundTableTimeVal(pointTime: number, rowTime: number, threshold: number) {\n return Math.abs(Math.floor(pointTime) - rowTime) < threshold;\n}\n\n// calculate the threshold for which we consider a point in a chart\n// to match a row in a table based on a time value\nexport function calculateAroundPointThreshold(timeField: Field): number {\n let max = -Number.MAX_VALUE;\n let min = Number.MAX_VALUE;\n\n if (timeField.values.length < 2) {\n return 0;\n }\n\n for (let i = 0; i < timeField.values.length; i++) {\n const value = timeField.values[i];\n if (value > max) {\n max = value;\n }\n if (value < min) {\n min = value;\n }\n }\n\n return (max - min) / timeField.values.length;\n}\n\n/**\n * Calculate an estimated bounding box for a block\n * of text using an offscreen canvas.\n */\nexport function guessTextBoundingBox(\n text: string,\n headerGroup: HeaderGroup,\n osContext: OffscreenCanvasRenderingContext2D | null,\n lineHeight: number,\n defaultRowHeight: number,\n padding = 0\n) {\n const width = Number(headerGroup?.width ?? 300);\n const LINE_SCALE_FACTOR = 1.17;\n const LOW_LINE_PAD = 42;\n const PADDING = padding * 2;\n\n if (osContext !== null && typeof text === 'string') {\n const words = text.split(/\\s/);\n const lines = [];\n let currentLine = '';\n let wordCount = 0;\n let extraLines = 0;\n\n // Let's just wrap the lines and see how well the measurement works\n for (let i = 0; i < words.length; i++) {\n const currentWord = words[i];\n let lineWidth = osContext.measureText(currentLine + ' ' + currentWord).width;\n\n if (lineWidth < width - PADDING) {\n currentLine += ' ' + currentWord;\n wordCount++;\n } else {\n lines.push({\n width: lineWidth,\n line: currentLine,\n });\n\n currentLine = currentWord;\n wordCount = 0;\n }\n }\n\n // We can have extra long strings, for these\n // we estimate if it overshoots the line by\n // at least one other line\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].width > width) {\n let extra = Math.floor(lines[i].width / width) - 1;\n extraLines += extra;\n }\n }\n\n // Estimated height would be lines multiplied\n // by the line height\n let lineNumber = lines.length + extraLines;\n let height = 38;\n if (lineNumber > 5) {\n height = lineNumber * lineHeight * LINE_SCALE_FACTOR;\n } else {\n height = lineNumber * lineHeight + LOW_LINE_PAD;\n }\n height += PADDING;\n\n return { width, height };\n }\n\n return { width, height: defaultRowHeight };\n}\n\n/**\n * A function to guess at which field has the longest text.\n * To do this we either select a single record if there aren't many records\n * or we select records at random and sample their size.\n */\nexport function guessLongestField(fieldConfig: FieldConfigSource, data: DataFrame) {\n let longestField = undefined;\n const SAMPLE_SIZE = 3;\n\n // If the default field option is set to allow text wrapping\n // we determine the field to wrap text with here and then\n // pass it to the RowsList\n if (fieldConfig.defaults.custom?.cellOptions?.wrapText) {\n const stringFields = data.fields.filter((field: Field) => field.type === FieldType.string);\n\n if (stringFields.length >= 1 && stringFields[0].values.length > 0) {\n const numValues = stringFields[0].values.length;\n let longestLength = 0;\n\n // If we have less than 30 values we assume that the first\n // non-null record is representative of the overall data\n if (numValues <= 30) {\n for (const field of stringFields) {\n const fieldLength = field.values.find((v) => v != null)?.length ?? 0;\n if (fieldLength > longestLength) {\n longestLength = fieldLength;\n longestField = field;\n }\n }\n }\n // Otherwise we randomly sample SAMPLE_SIZE values and take\n // the mean length\n else {\n for (const field of stringFields) {\n // This could result in duplicate values but\n // that should be fairly unlikely. This could potentially\n // be improved using a Set datastructure but\n // going to leave that one as an exercise for\n // the reader to contemplate and possibly code\n const vals = sampleSize(field.values, SAMPLE_SIZE);\n const meanLength = (vals[0]?.length + vals[1]?.length + vals[2]?.length) / 3;\n\n if (meanLength > longestLength) {\n longestLength = meanLength;\n longestField = field;\n }\n }\n }\n }\n }\n\n return longestField;\n}\n"],"names":["data","RowExpander","FieldType","getFieldDisplayName","memoize","getTextAlign","getFooterValue","TableCellDisplayMode","DefaultCell","ImageCell","BarGaugeCell","SparklineCell","JSONViewCell","DataLinksCell","ActionsCell","GeoCell","isDataFrame","isTimeSeriesFrame","formattedValueToString","isDataFrameWithValue","fieldReducers","clone","f","_a","getDisplayProcessor","reduceField","sampleSize"],"mappings":"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"}