import { Point } from "../../../../Core/Point"; import type { WebGlRenderContext2D } from "../../../Drawing/WebGlRenderContext2D"; import type { RenderPassData } from "../../../Services/RenderPassData"; import type { IBaseDataLabelProviderOptions, TDataLabel } from "./BaseDataLabelProvider"; import { BaseDataLabelProvider } from "./BaseDataLabelProvider"; import { EDataLabelProviderType } from "../../../../types/DataLabelProviderType"; import { DataLabelState } from "./DataLabelState"; import { EHorizontalTextPosition, EVerticalTextPosition } from "../../../../types/TextPosition"; import type { SCRTDoubleVector, SCRTStringDictionary, TSRTextBounds } from "../../../../types/TSciChart"; import type { TDataLabelStyle } from "../../../../types/TDataLabelStyle"; import type { IRenderableSeries } from "../IRenderableSeries"; import { ENumericFormat } from "../../../../types/NumericFormat"; import type { IEngineeringPrefix } from "../../../../types/NumericFormat"; import type { TFormatLabelFn } from "../../Axis/LabelProvider/LabelProvider"; export interface ITextDataLabelProviderOptions extends IBaseDataLabelProviderOptions { /** * If you want to be able to look at the position and size of labels before they are drawn, set this true * otherwise it is faster to leave it false. */ calculateTextBounds?: boolean; /** Sets the horizontal text position for the label */ horizontalTextPosition?: EHorizontalTextPosition; /** Sets the vertical text position for the label */ verticalTextPosition?: EVerticalTextPosition; /** Flag to enable/disable dataLabel generation. Default true */ isEnabled?: boolean; /** * The name or index of a value array on the dataSeries whose values are formatted as the label text. * When unset: an {@link XyTextDataSeries}' textValues are used if present, otherwise the series' * selected y values ({@link IRenderableSeries.yArrayFilter}-aware) are formatted. */ textField?: string | number; /** Numeric format used to convert values to text (includes date formats). Default {@link ENumericFormat.Decimal} */ labelFormat?: ENumericFormat; /** Number of decimal places (or significant figures, format-dependent) used to convert values to text. Default 1 */ labelPrecision?: number; /** A prefix added to each formatted label */ labelPrefix?: string; /** A postfix added to each formatted label */ labelPostfix?: string; /** Engineering prefixes used with {@link ENumericFormat.Engineering} */ engineeringPrefix?: IEngineeringPrefix; /** A function converting a data value to text, overriding labelFormat/labelPrecision/engineeringPrefix. Must depend only on the value (results are cached per value). */ formatValue?: TFormatLabelFn; } /** * Implemented by renderable series that supply constant or field-driven label positions * (see {@link FastTextRenderableSeries}). * @remarks Position overrides apply to label placement only — {@link TextSeriesHitTestProvider}'s * nearest-point math still reads the raw native x/y vectors (its label-rect isHit check is unaffected). */ export interface ITextPositionFields { /** A constant y position (data space) for all labels. Overridden by yField */ defaultY?: number; /** Name or index of a value array used as x position, overriding xValues */ xField?: string | number; /** Name or index of a value array used as y position, overriding defaultY and y values */ yField?: string | number; } /** * A {@link DataLabelState} whose x/y data values can be overridden by field views or a fixed y value. * Position chains: x: xOverrideValues → xValues; y: yOverrideValues → fixedYValue → yValues */ export declare class TextDataLabelState extends DataLabelState { xOverrideValues: Float64Array; yOverrideValues: Float64Array; fixedYValue: number; xVal(index?: number): number; yVal(index?: number): number; } /** * A DataLabelProvider sepcifically designed to work with {@link FastTextRenderableSeries } or any series that uses an {@link XYTextDataSeries } * Text is taken directly from the textValues on the dataSeries and placed at the x,y coordinates (anchored top, left) */ export declare class TextDataLabelProvider extends BaseDataLabelProvider { type: EDataLabelProviderType; /** * This default false for maximum performance. It will be true if you set the textPosition to something other than Above, Right. * You can force it true if you want to make use of the text sizes in onAfterGenerate */ calculateTextBounds: boolean; /** Max entries in the value→text cache before it is cleared (simple bound, no LRU) */ static MAX_CACHE_SIZE: number; /** One-shot: visibleIndices cannot be honoured against a resampled point series (see generateDataLabels). */ private static warnedVisibleIndicesResampled; protected horizontalTextPositionProperty: EHorizontalTextPosition; protected verticalTextPositionProperty: EVerticalTextPosition; protected isEnabledProperty: boolean; protected state: DataLabelState; protected textFieldProperty: string | number; /** * `undefined` until explicitly set, which is what distinguishes "the caller asked for nothing" * from "the caller asked for Decimal". Only that distinction lets an unset provider fall back to * the formatted column's {@link EColumnType} default while an explicit setting still wins. The * PUBLIC {@link labelFormat} getter resolves it, so the sentinel never leaves this class. */ protected labelFormatProperty: ENumericFormat; /** `undefined` until explicitly set - see {@link labelFormatProperty}. */ protected labelPrecisionProperty: number; /** The value {@link labelFormat} reports, and the last resort in {@link resolveFormat}. */ protected static readonly DEFAULT_LABEL_FORMAT = ENumericFormat.Decimal; /** The value {@link labelPrecision} reports, and the last resort in {@link resolveFormat}. */ protected static readonly DEFAULT_LABEL_PRECISION = 1; /** * The column type resolved for the CURRENT render pass, refreshed in {@link resolveTextSource}. * Held rather than looked up per value because {@link defaultFormatValue} runs behind the * {@link valueToText} cache and takes only a value - it has no way to reach the data series. */ private resolvedColumnType; protected labelPrefixProperty: string; protected labelPostfixProperty: string; /** Opt-in: draw string cells natively from the dictionary by code (no per-frame JS string). * Default off; only engages when {@link textField} names a string column on the data series and * there is no prefix/postfix (identity format). */ useNativeStringDraw: boolean; protected engineeringPrefixProperty: IEngineeringPrefix; protected formatValueProperty: TFormatLabelFn; protected readonly valueToText: Map; constructor(options?: ITextDataLabelProviderOptions); /** * Gets or sets the horizontal text position for the label * For more control, override getPosition */ get horizontalTextPosition(): EHorizontalTextPosition; set horizontalTextPosition(value: EHorizontalTextPosition); /** * Gets or sets the vertical text position for the label * For more control, override getPosition */ get verticalTextPosition(): EVerticalTextPosition; set verticalTextPosition(value: EVerticalTextPosition); /** Flag to enable/disable dataLabel generation. Default true */ get isEnabled(): boolean; /** Flag to enable/disable dataLabel generation. Default true */ set isEnabled(value: boolean); /** * Gets or sets the name or index of a value array on the dataSeries whose values are formatted as the label text. * When unset, an {@link XyTextDataSeries}' textValues or the series' selected y values are used. */ get textField(): string | number; set textField(value: string | number); /** Gets or sets the numeric format used to convert values to text (includes date formats). Default {@link ENumericFormat.Decimal} */ get labelFormat(): ENumericFormat; set labelFormat(value: ENumericFormat); /** Gets or sets the number of decimal places (or significant figures, format-dependent) used to convert values to text. Default 1 */ get labelPrecision(): number; set labelPrecision(value: number); /** Gets or sets a prefix added to each formatted label */ get labelPrefix(): string; set labelPrefix(value: string); /** Gets or sets a postfix added to each formatted label */ get labelPostfix(): string; set labelPostfix(value: string); /** Gets or sets the engineering prefixes used with {@link ENumericFormat.Engineering} */ get engineeringPrefix(): IEngineeringPrefix; set engineeringPrefix(value: IEngineeringPrefix); /** Gets or sets the function converting a data value to text. Defaults to formatNumber with labelFormat/labelPrecision/engineeringPrefix */ get formatValue(): TFormatLabelFn; set formatValue(value: TFormatLabelFn); private defaultFormatValue; /** * Resolves the format and precision to render a value with, in strict precedence: * 1. an explicit {@link labelFormat} / {@link labelPrecision} — always wins; * 2. otherwise the {@link DEFAULT_FORMAT_FOR_COLUMN_TYPE} entry for the declared * {@link EColumnType} of the column being formatted; * 3. otherwise the class defaults, `Decimal` and `1`. * * The two resolve INDEPENDENTLY, so setting one does not silently pin the other. */ protected resolveFormat(): { numericFormat: ENumericFormat; precision: number; }; /** Adds labelPrefix / labelPostfix around a formatted value */ applyFormat(value: string): string; /** Converts a numeric value to label text via {@link formatValue}, caching the result per value. NaN returns undefined (no label). */ getTextForValue(value: number): string; /** * Resolves the function that supplies label text per data index for this render pass: * textField → XyTextDataSeries textValues → the series' selected y values, formatted. * Returns undefined if no source is available. */ resolveTextSource(): ((dataIndex: number) => string) | undefined; /** * When {@link useNativeStringDraw} is on and {@link textField} names a string column on the data * series with no prefix/postfix, returns the native dictionary handle + a zero-copy codes view so * the renderer can draw each cell straight from the dictionary by code (no per-frame JS string). * The series' concrete type is irrelevant - only whether it carries the column. Returns * undefined otherwise, so the caller falls back to the normal string path. Prefix/postfix * disqualify it because native draw bypasses {@link applyFormat}. */ protected resolveNativeStringSource(): { dict: SCRTStringDictionary; codes: Int32Array; } | undefined; getPosition(state: DataLabelState, textBounds: TSRTextBounds): Point; getColor(state: DataLabelState, text: string): number; /** Called by generateDataLabels to get the DataLabelState helper object that supplies label values and coordinates */ getDataLabelState(renderContext: WebGlRenderContext2D, renderPassData: RenderPassData, style: TDataLabelStyle, color: string, yValues: SCRTDoubleVector, parentSeries: IRenderableSeries): DataLabelState; /** * Called at the start of generateDataLabels. If False, no labels will be generated. * @param state * @returns */ shouldGenerate(state: DataLabelState): boolean; generateDataLabels(renderContext: WebGlRenderContext2D, renderPassData: RenderPassData): void; /** Called after labels are generated but before they are drawn. */ onAfterGenerate(dataLabels: TDataLabel[]): void; toJSON(): { type: EDataLabelProviderType; options: { style: TDataLabelStyle; color: string; }; }; } /** Registers {@link TextDataLabelProvider} for `EDataLabelProviderType.Text` definitions. */ export declare function registerTextDataLabelProvider(overWrite?: boolean): void;