import uPlot from 'uplot'; import { LocaleInfo } from '../utilities/formatTimestamp'; import { VizTheme } from '../theme'; import { AxisRange, GenericDataSet, DataSet, ScaleConfig, SeriesConfig, TimestampFormat, TickInterval, LineDashStyle, StepPosition } from '../types'; import { SeriesInfo } from './types'; /** * Converts a LineDashStyle string to a canvas setLineDash array. * Based on the specification and reference images provided. * @param dashStyle - The dash style string * @returns Array of numbers for canvas setLineDash, or undefined for solid */ export declare const getLineDashArray: (dashStyle?: LineDashStyle) => number[] | undefined; export type SeriesWithKey = uPlot.Series & { key: string; }; export type CustomRotatedLabel = { split: number; label: string; }; export declare const getRotatedLabels: () => CustomRotatedLabel[]; export declare const setRotatedLabels: (labels: CustomRotatedLabel[]) => void; /** Canvas hover marker (SCP-82958 / Figma): outer halo 20px @ 20% series color, white ring 11px, inner dot 9px. */ export declare const HOVER_MARKER_OUTER_RADIUS_PX = 10; /** * Draws the canvas hover marker (line/area): halo, white ring, solid inner dot. * Draw order: outer (largest) to inner so the ring reads correctly. */ export declare const drawHoverMarker: (ctx: CanvasRenderingContext2D, xPos: number, yPos: number, seriesColor: string) => void; /** * Parses a font string and scales it by the device pixel ratio for canvas rendering. * This function extracts the font size and font family from a CSS font string, * then scales the font size by the provided pixel ratio to ensure proper rendering * on high-DPI displays when drawing directly on canvas. * * @param fontString - Font string in CSS format (e.g., "10px Arial" or "12px Helvetica Neue") * @param pixelRatio - Device pixel ratio to scale the font size by (typically window.devicePixelRatio) * @returns Scaled font string in CSS format (e.g., "20px Arial" when pixelRatio is 2) * * @example * parseAndScaleFont('10px Arial', 1) // returns '10px Arial' * parseAndScaleFont('10px Arial', 2) // returns '20px Arial' (for Retina displays) * parseAndScaleFont('invalid', 1) // returns '10px [FONT_FAMILY]' (fallback) */ export declare const parseAndScaleFont: (fontString: string, pixelRatio: number) => string; interface GenerateSeriesOptions { field: string; seriesIdx: number; config?: SeriesConfig[keyof SeriesConfig]; show?: boolean; seriesColors?: string[]; seriesColorsByField?: Record; markerFill?: string; hasSingleDatapoint?: boolean; showLineSmoothing?: boolean; lineDashStyle?: LineDashStyle; stepPosition?: StepPosition; areaOpacity?: number; } /** * @param options.field - Field name * @param options.seriesIdx - Series index, starts at "1" * @param options.config - Series configuration * @param options.show - Whether or not the series will be shown * @returns Series configuration for uPlot */ export declare const generateSeries: ({ field, seriesIdx, config, show, seriesColors, seriesColorsByField, markerFill, hasSingleDatapoint, showLineSmoothing, lineDashStyle, stepPosition, areaOpacity, }: GenerateSeriesOptions) => SeriesWithOptionalStackingGroup; export interface MapDSToSeriesOptions { fields: GenericDataSet['fields']; hiddenSeries?: string[]; seriesColors?: string[]; seriesColorsByField?: Record; markerFill?: string; dataLength?: number; seriesConfig?: SeriesConfig; scaleConfig?: ScaleConfig; showLineSmoothing?: boolean; stepPosition?: StepPosition; areaOpacity?: number; } export declare const mapDSToSeries: ({ fields, hiddenSeries, seriesColors, seriesColorsByField, markerFill, dataLength, seriesConfig, scaleConfig, showLineSmoothing, stepPosition, areaOpacity, }: MapDSToSeriesOptions) => SeriesWithKey[]; export declare const getMaxRangeValue: (numberOfDatapoints: number, max: number, range?: AxisRange) => number; export declare const isTimeSeriesData: (dataSet: DataSet | GenericDataSet) => boolean; export declare const mapDSToScales: (opts: { seriesConfig?: SeriesConfig; scaleConfig?: ScaleConfig; range?: AxisRange; isTimeSeries?: boolean; yAxisMajorTickInterval?: number; y2AxisMajorTickInterval?: number; showYAxisWithZero?: boolean; showY2AxisWithZero?: boolean; }) => uPlot.Scales; export declare const isShowOnlyRangeValues: (range: AxisRange) => boolean; export declare const isTimeSeriesWithExpandedTimeFormat: (isTimeSeries: boolean, timestampFormat: TimestampFormat) => boolean; export declare const isXScaleConfig: (scaleConfigInput: ScaleConfig) => boolean; export declare const lastTickHideCondition: (splits: number[], idx: number, isTimeSeries: boolean, timestampFormat: TimestampFormat) => boolean; /** * Checks whether there is enough horizontal space to render the last tick label * for an expanded timeseries format without it overflowing the right edge of the plot area. * * Expanded labels are left-aligned to the tick position, so we check whether * tickX + fullLabelWidth exceeds the plot right edge. * * @param u - The uPlot instance (provides bbox and valToPos, both in physical px) * @param lastSplit - The value of the last tick * @param label - The label text (may be multiline, separated by '\n') * @returns true if there is enough space to render the label without clipping */ export declare const hasSpaceForLastTick: (u: uPlot, lastSplit: number, label: string) => boolean; /** * Generates an expanded timestamp label and updates the last seen day, month, and year. * This function is intended to be called iteratively for time series data. * * @param {number} millisecondsEpoch - The timestamp in milliseconds since epoch. * @param {TickInterval} tickInterval - The interval of the tick (e.g., '1d', '7d', '1mo'). * @param {string} locale - The locale string for date formatting. * @param {number} idx - The index of the current label in a sequence (e.g., 0 for the first label). * @param {string} currentLastDay - The 'day' string from the previously processed timestamp. * @param {string} currentLastMonth - The 'month' string from the previously processed timestamp. * @param {string} currentLastYear - The 'year' string from the previously processed timestamp. * @returns {{label: string, lastDay: string, lastMonth: string, lastYear: string}} An object * containing the formatted label string and the updated last day, month, and year values. */ export declare const getExpandedTimestampLabelAndState: (opts: { millisecondsEpoch: number; tickInterval: TickInterval; locale: LocaleInfo; idx: number; currentLastDay: string; currentLastMonth: string; currentLastYear: string; xAxisMaxLabelParts: number; }) => { label: string; lastDay: string; lastMonth: string; lastYear: string; }; export declare const drawMinorGridLines: (u: uPlot, scaleKey: string, strokeColor: string, showMajorGridLines: boolean, minorTickCount?: number) => void; /** * Draws major tick marks on the Y or Y2 axis * @param u - uPlot instance * @param scaleKey - Scale key ('y' or 'y2') * @param strokeColor - Color of the tick marks * @param tickSize - Length of tick marks in pixels (default 6) * @param side - 'left' for Y-axis, 'right' for Y2-axis */ export declare const drawMajorTicks: (u: uPlot, scaleKey: string, strokeColor: string, tickSize?: number, side?: "left" | "right") => void; /** * Draws minor tick marks on the Y or Y2 axis (between major ticks) * @param u - uPlot instance * @param scaleKey - Scale key ('y' or 'y2') * @param strokeColor - Color of the tick marks * @param tickSize - Length of tick marks in pixels (default 4) * @param side - 'left' for Y-axis, 'right' for Y2-axis */ export declare const drawMinorTicks: (u: uPlot, scaleKey: string, strokeColor: string, tickSize?: number, side?: "left" | "right") => void; interface MapScalesToAxesParams { xAxisResolution: number; xAxisMaxLabelParts?: number; theme: VizTheme; locale: LocaleInfo; hideXAxis?: true; range?: AxisRange; isTimeSeries?: boolean; rawXaxisValues?: (string | number | null)[]; scaleConfig?: ScaleConfig; timestampFormat?: TimestampFormat; dataLength?: number; /** Show major grid lines on the X-axis; default false */ showXMajorGridLines?: boolean; /** Show major grid lines on the Y-axis; default true */ showYMajorGridLines?: boolean; /** Show major grid lines on the Y2-axis (right axis); default false */ showY2MajorGridLines?: boolean; /** Show major tick marks on the X-axis; default true */ showXMajorTicks?: boolean; /** Size (length) of major tick marks on the X-axis in pixels; uses uPlot default if not specified */ xAxisMajorTickSize?: number; /** Major tick interval for the Y-axis; controls spacing between ticks/labels */ yAxisMajorTickInterval?: number; /** Major tick interval for the Y2-axis; controls spacing between ticks/labels */ y2AxisMajorTickInterval?: number; /** Data columns for calculating dynamic Y-axis width */ dataColumns?: ((string | number | null)[] | number[])[]; /** Whether this is a Y2-only scenario (Y2 has data but Y doesn't) */ isY2Only?: boolean; } /** * Measures the width (in physical/device pixels) of the widest line of the worst-case * expanded timestamp label for the given tick interval, locale, and xAxisMaxLabelParts. * * The first tick (idx=0, no prior state) always produces the maximum label because all * parts (time + day + year) are included. A representative epoch is used so the result * reflects real locale-specific strings (e.g. long month names). * * Note: ctx.measureText returns physical pixels. Callers that need CSS pixels must * divide the result by window.devicePixelRatio. */ export declare const getWorstCaseExpandedLabelWidth: (ctx: CanvasRenderingContext2D, tickInterval: TickInterval, locale: LocaleInfo, xAxisMaxLabelParts: number, axisFont: string) => number; export declare const mapScalesToAxes: ({ xAxisResolution, xAxisMaxLabelParts, theme, locale, hideXAxis, range, isTimeSeries, scaleConfig, timestampFormat, dataLength, showXMajorGridLines, showYMajorGridLines, showY2MajorGridLines, showXMajorTicks, xAxisMajorTickSize, yAxisMajorTickInterval, y2AxisMajorTickInterval, }: MapScalesToAxesParams) => uPlot.Axis[]; export type SeriesWithOptionalStackingGroup = SeriesWithKey & { negY?: boolean; stacking?: { mode: 'none' | 'normal' | 'percent'; group: string; }; }; /** * Stacks the data according to the series properties. Returns the transformed * stacked data to be used in the plot, and the band configurations that should * be provided to uPlot. * * Derived from: https://github.com/leeoniya/uPlot/blob/24663e48a0db7247692dbf61280174fa71b17980/demos/stack.js */ export declare function stackData(series: SeriesWithOptionalStackingGroup[], _data: uPlot.AlignedData): { data: uPlot.AlignedData; bands?: uPlot.Band[]; }; export declare function getSeriesKey(seriesIndex?: number, allSeries?: SeriesInfo[]): string; export type AxisPaddingInfo = { hasYAxisLabel: boolean; hasAbbreviationOff: boolean; hasY2Config: boolean; hasYAxisWithData: boolean; hasY2AxisLabel: boolean; hasY2AbbreviationOff: boolean; hasY2AxisWithData: boolean; }; export declare const getScaleKeyFlags: (key: string, config: ScaleConfig[string]) => Partial; export declare const getSeriesScaleFlags: (sc: SeriesConfig[string], hasY2Config: boolean) => Partial; export declare const getAxisPaddingInfo: (scaleConfig: ScaleConfig | undefined, seriesConfig: SeriesConfig | undefined) => AxisPaddingInfo; export declare const calculateExpandedPadding: (scaleConfig: ScaleConfig | undefined, seriesConfig: SeriesConfig | undefined) => [number, number, number, number]; export declare const getLocaleInfo: (userLocale: LocaleInfo | undefined, defaultLocale: LocaleInfo) => LocaleInfo; export declare const getIsSingleVizFullscreen: () => boolean; export {};