@grafana/ui
Version:
Grafana Components Library
1 lines • 13.8 kB
Source Map (JSON)
{"version":3,"file":"utils.mjs","sources":["../../../../src/components/Sparkline/utils.ts"],"sourcesContent":["import { type Range } from 'uplot';\n\nimport {\n applyNullInsertThreshold,\n // colorManipulator,\n type DataFrame,\n type FieldConfig,\n type FieldSparkline,\n FieldType,\n getFieldColorModeForField,\n type GrafanaTheme2,\n guessDecimals,\n isLikelyAscendingVector,\n nullToValue,\n roundDecimals,\n sortDataFrame,\n} from '@grafana/data';\nimport { t } from '@grafana/i18n';\nimport {\n AxisPlacement,\n GraphDrawStyle,\n type GraphFieldConfig,\n VisibilityMode,\n ScaleDirection,\n ScaleOrientation,\n // FieldColorModeId,\n} from '@grafana/schema';\n\nimport { UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder';\n\n/** @internal\n * Given a sparkline config returns a DataFrame ready to be turned into Plot data set\n **/\nexport function preparePlotFrame(sparkline: FieldSparkline, config?: FieldConfig<GraphFieldConfig>): DataFrame {\n const length = sparkline.y.values.length;\n const yFieldConfig = {\n ...sparkline.y.config,\n ...config,\n };\n\n const xField = sparkline.x ?? {\n name: '',\n values: [...Array(length).keys()],\n type: FieldType.number,\n config: {},\n };\n\n let frame: DataFrame = {\n refId: 'sparkline',\n fields: [\n xField,\n {\n ...sparkline.y,\n config: yFieldConfig,\n },\n ],\n length,\n };\n\n if (!isLikelyAscendingVector(xField.values)) {\n frame = sortDataFrame(frame, 0);\n }\n\n return applyNullInsertThreshold({\n frame,\n refFieldPseudoMin: sparkline.timeRange?.from.valueOf(),\n refFieldPseudoMax: sparkline.timeRange?.to.valueOf(),\n });\n}\n\n/**\n * apply configuration defaults and ensure that the range is never two equal values.\n */\nexport function getYRange(alignedFrame: DataFrame): Range.MinMax {\n const field = alignedFrame.fields[1];\n let { min, max } = field.state?.range!;\n\n // enure that the min/max from the field config are respected.\n min = Math.min(min!, field.config.min ?? Infinity);\n max = Math.max(max!, field.config.max ?? -Infinity);\n\n // if noValue is set, ensure that it is included in the range as well\n const noValue = +field.config?.noValue!;\n if (!Number.isNaN(noValue)) {\n min = Math.min(min, noValue);\n max = Math.max(max, noValue);\n }\n\n const decimals = field.config.decimals ?? Math.max(guessDecimals(min), guessDecimals(max));\n\n // call roundDecimals to mirror what is going to eventually happen in uplot\n let roundedMin = roundDecimals(min, decimals);\n let roundedMax = roundDecimals(max, decimals);\n\n // if the rounded min and max are different,\n // we can return the real min and max.\n if (roundedMin !== roundedMax) {\n return [min, max];\n }\n\n // we are forced to tweak the min and max since they\n // will be treated as equal after rounding by uPlot.\n if (roundedMin === 0) {\n // both are zero\n roundedMax = 1;\n } else if (roundedMin < 0) {\n // both are negative\n roundedMin *= 2;\n } else {\n // both are positive\n roundedMax *= 2;\n }\n\n return [roundedMin, roundedMax];\n}\n\nconst HIGHLIGHT_IDX_POINT_SIZE = 6;\n\nconst defaultConfig: GraphFieldConfig = {\n drawStyle: GraphDrawStyle.Line,\n showPoints: VisibilityMode.Auto,\n axisPlacement: AxisPlacement.Hidden,\n pointSize: 0,\n};\n\nexport const prepareSeries = (\n sparkline: FieldSparkline,\n _theme: GrafanaTheme2,\n fieldConfig?: FieldConfig<GraphFieldConfig>,\n _showHighlights?: boolean\n): { frame: DataFrame; warning?: string } => {\n const frame = nullToValue(preparePlotFrame(sparkline, fieldConfig));\n if (frame.fields.some((f) => f.values.length <= 1)) {\n return {\n warning: t(\n 'grafana-ui.components.sparkline.warning.too-few-values',\n 'Sparkline requires at least two values to render.'\n ),\n frame,\n };\n }\n // TODO:rgb(24, 24, 24) will address this.\n // if (showHighlights && typeof sparkline.highlightLine === 'number') {\n // const highlightY = sparkline.highlightLine;\n // const colorMode = getFieldColorModeForField(sparkline.y);\n // const seriesColor = colorMode.getCalculator(sparkline.y, theme)(highlightY, 0);\n // frame.fields.push({\n // name: 'highlightLine',\n // type: FieldType.number,\n // values: new Array(frame.length).fill(highlightY),\n // config: {\n // color: {\n // mode: FieldColorModeId.Fixed,\n // fixedColor: colorManipulator.lighten(seriesColor, 0.5),\n // },\n // custom: {\n // lineStyle: {\n // fill: 'dash',\n // dash: [5, 2],\n // },\n // },\n // },\n // state: {},\n // });\n // }\n return { frame };\n};\n\nexport const prepareConfig = (\n sparkline: FieldSparkline,\n dataFrame: DataFrame,\n theme: GrafanaTheme2,\n showHighlights?: boolean\n): UPlotConfigBuilder => {\n const builder = new UPlotConfigBuilder();\n const rangePad = HIGHLIGHT_IDX_POINT_SIZE / 2;\n\n builder.setCursor({\n show: false,\n x: false, // no crosshairs\n y: false,\n });\n\n // X is the first field in the aligned frame\n const xField = dataFrame.fields[0];\n builder.addScale({\n scaleKey: 'x',\n orientation: ScaleOrientation.Horizontal,\n direction: ScaleDirection.Right,\n isTime: false, // xField.type === FieldType.time,\n range: () => {\n if (sparkline.x) {\n if (sparkline.timeRange && sparkline.x.type === FieldType.time) {\n return [sparkline.timeRange.from.valueOf(), sparkline.timeRange.to.valueOf()];\n }\n const vals = sparkline.x.values;\n return [vals[0], vals[vals.length - 1]];\n }\n return [0, sparkline.y.values.length - 1];\n },\n });\n\n builder.addAxis({\n scaleKey: 'x',\n theme,\n placement: AxisPlacement.Hidden,\n show: false,\n });\n\n for (let i = 0; i < dataFrame.fields.length; i++) {\n const field = dataFrame.fields[i];\n const config: FieldConfig<GraphFieldConfig> = field.config;\n const customConfig: GraphFieldConfig = {\n ...defaultConfig,\n ...config.custom,\n };\n\n if (field === xField || field.type !== FieldType.number) {\n continue;\n }\n\n const scaleKey = config.unit || '__fixed';\n builder.addScale({\n scaleKey,\n orientation: ScaleOrientation.Vertical,\n direction: ScaleDirection.Up,\n range: () => getYRange(dataFrame),\n });\n\n builder.addAxis({\n scaleKey,\n theme,\n placement: AxisPlacement.Hidden,\n show: false,\n });\n\n const colorMode = getFieldColorModeForField(field);\n const seriesColor = colorMode.getCalculator(field, theme)(0, 0);\n\n const hasHighlightIndex = showHighlights && typeof sparkline.highlightIndex === 'number';\n if (hasHighlightIndex) {\n builder.setPadding([rangePad, rangePad, rangePad, rangePad]);\n }\n\n const pointsMode =\n customConfig.drawStyle === GraphDrawStyle.Points || hasHighlightIndex\n ? VisibilityMode.Always\n : customConfig.showPoints;\n\n builder.addSeries({\n pxAlign: false,\n scaleKey,\n theme,\n colorMode,\n thresholds: config.thresholds,\n drawStyle: customConfig.drawStyle!,\n lineColor: customConfig.lineColor ?? seriesColor,\n lineWidth: customConfig.lineWidth,\n lineInterpolation: customConfig.lineInterpolation,\n showPoints: pointsMode,\n pointSize: hasHighlightIndex ? HIGHLIGHT_IDX_POINT_SIZE : customConfig.pointSize,\n pointsFilter: hasHighlightIndex ? [sparkline.highlightIndex!] : undefined,\n fillOpacity: customConfig.fillOpacity,\n fillColor: customConfig.fillColor,\n lineStyle: customConfig.lineStyle,\n gradientMode: customConfig.gradientMode,\n spanNulls: customConfig.spanNulls,\n });\n }\n\n return builder;\n};\n"],"names":[],"mappings":"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"}