import { Point } from "../../../../Core/Point"; import { EHorizontalTextPosition, EVerticalTextPosition } from "../../../../types/TextPosition"; import { EDataLabelProviderType } from "../../../../types/DataLabelProviderType"; import { EDataLabelSkipMode } from "../../../../types/DataLabelSkipMode"; import { ENumericFormat } from "../../../../types/NumericFormat"; import type { SCRTDoubleVector, TSRTextBounds } from "../../../../types/TSciChart"; import type { WebGlRenderContext2D } from "../../../Drawing/WebGlRenderContext2D"; import type { IPointMetadata } from "../../../Model/IPointMetadata"; import type { IPointSeries } from "../../../Model/PointSeries/IPointSeries"; import type { RenderPassData } from "../../../Services/RenderPassData"; import type { IRenderableSeries } from "../IRenderableSeries"; import type { IBaseDataLabelProviderOptions, TDataLabel } from "./BaseDataLabelProvider"; import { BaseDataLabelProvider } from "./BaseDataLabelProvider"; import { DataLabelState } from "./DataLabelState"; import type { IEngineeringPrefix } from "../../../../types/NumericFormat"; import type { TDataLabelStyle } from "../../../../types/TDataLabelStyle"; import { Thickness } from "../../../../Core/Thickness"; import { EHorizontalAnchorPoint, EVerticalAnchorPoint } from "../../../../types/AnchorPoint"; export interface IDataLabelProviderOptions extends IBaseDataLabelProviderOptions { /** * Gets or sets numeric format to use for formatting values to text. For a list of values, see {@link ENumericFormat} */ numericFormat?: ENumericFormat; /** * Gets or sets the engineering prefixes to use when formatting values to text. * Default - `['K','M','B,'T']` for "large" prefixes, `['m','u','n','p']` for small prefixes * @remarks Only works when {@link ENumericFormat.Engineering} is selected */ engineeringPrefix?: IEngineeringPrefix; /** * Gets or sets the precision to use when formatting values to text. */ precision?: number; /** * Gets or sets the zoom threshold above which label drawing will start. Default 0 * This is expressed as the gap between the first points divided by the size of the first text. * If data is unevenly spaced, consider {@link pointCountThreshold} or override shouldDrawText */ pointGapThreshold?: number; /** * Gets or sets the number of points below which drawing will start. Default Infinity * This can be used instead of {@link pointGapThreshold} when data is unevenly spaced or has large y variation */ pointCountThreshold?: number; /** * The number of points to skip while generating labels. Default 0 = no skip. 1 = skip every other. * When creating text with many data points, it will help performance to skip points rather than creating and checking overlap for every data point. * This is applied before any logic related to {@link skipMode} */ skipNumber?: number; /** * How do decide whether to keep or skip a label once generated. * Override {@link shouldSkipLabel} for more control */ skipMode?: EDataLabelSkipMode; /** * A function to pick which y values to use from the pointSeries passed in on the renderPassData */ ySelector?: (ps: IPointSeries) => SCRTDoubleVector; /** * If this is set it will be used to get text values from metaData, rather than formatting y values. * The selector will be called even if the metaData for an index is undefined. */ metaDataSelector?: (metadata: IPointMetadata) => string; /** * If this is set, label text is read from the string column of this name on the parent series' * DataSeries (see {@link IBaseDataSeriesOptions.stringColumns}), rather than formatting y values. * Takes precedence over {@link metaDataSelector}; setting both is a configuration error and warns. * An unknown column name is ignored, falling through to the other sources. */ textColumn?: string; /** * Whether the label text should update when the label position is animating. Default false. */ updateTextInAnimation?: boolean; /** Sets the horizontal text position for the label. Default Right */ horizontalTextPosition?: EHorizontalTextPosition; /** Sets the vertical text position for the label. Default Top */ verticalTextPosition?: EVerticalTextPosition; /** Flag to enable/disable dataLabel generation. Default true */ isEnabled?: boolean; } /** * This is the standard DataLabelProvider which provides a number of options for configuring data labels. * It defines a much richer api than BaseDataLabelProvider and is intended to be used as a base for doing small changes to data label behaviour * generateDataLabels calls the following functions which you can override parts of the behaviour * {@link ySelector} to pick the desired yValues from the pointSeries. * {@link shouldGenerate} to determine if any labels should be generated so you can enable labels depending on zoom or data level. * Then for each data point: * {@link getText} Build in behaviour can get text from metadata using {@link metaDataSelector} or format the y values using {@link numericFormat} and {@link precision} * {@link getPosition} By default return the x and y coordinate of the data point. Series-specific DataLabelProviders eg {@link LineSeriesDataLabelProvider} have logic to adjust text position based on the series * {@link getColor} Returns the color from the text style. Use {@link parseColorToUIntArgb} to turn color string to the required numeric value if overriding. * {@link shouldSkipLabel} Decides whether to keep or ship the generated label based on the {@link } */ export declare class DataLabelProvider extends BaseDataLabelProvider { readonly type: EDataLabelProviderType; /** * If this is set it will be used to get text values from metaData, rather than formatting y values. * The selector will be called even if the metaData for an index is undefined. */ metaDataSelector: (metadata: IPointMetadata) => string; /** * A function to pick which y values to use from the pointSeries passed in on the renderPassData */ ySelector: (ps: IPointSeries) => SCRTDoubleVector; /** * The text to draw, along with the sizes and positions. Usually generated, but can be set or updated before final drawing */ dataLabels: TDataLabel[]; /** * Whether the label text should update when the label position is animating. Default false. */ updateTextInAnimation: boolean; protected state: DataLabelState; protected pointGapThresholdProperty: number; protected pointCountThresholdProperty: 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 column-type default while an explicit setting still wins. The PUBLIC {@link numericFormat} * getter resolves it to a concrete value, so the sentinel never leaves this class. */ protected numericFormatProperty: ENumericFormat; protected engineeringPrefixProperty: IEngineeringPrefix; /** `undefined` until explicitly set - see {@link numericFormatProperty}. */ protected precisionProperty: number; /** The value {@link numericFormat} reports, and the last resort in {@link resolveFormat}. */ protected static readonly DEFAULT_NUMERIC_FORMAT = ENumericFormat.Decimal; /** The value {@link precision} reports, and the last resort in {@link resolveFormat}. */ protected static readonly DEFAULT_PRECISION = 1; protected skipModeProperty: EDataLabelSkipMode; protected skipNumberProperty: number; protected horizontalTextPositionProperty: EHorizontalTextPosition; protected verticalTextPositionProperty: EVerticalTextPosition; protected isEnabledProperty: boolean; protected textColumnProperty: string; /** One-shot latch so a misconfigured provider warns once, not once per point per frame. */ private textColumnConflictWarned; /** * Creates an instance of the {@link DataLabelProvider} */ constructor(options?: IDataLabelProviderOptions); /** * Gets or sets the zoom threshold above which label drawing will start. Default 0. * This is expressed as the gap between the first points divided by the size of the first text * If data is unevenly spaced, consider {@link pointCountThreshold} or override shouldDrawText */ get pointGapThreshold(): number; /** * Gets or sets the zoom threshold above which label drawing will start. Default 0. * This is expressed as the gap between the first points divided by the size of the first text * If data is unevenly spaced, consider {@link pointCountThreshold} or override shouldDrawText */ set pointGapThreshold(value: number); /** * Gets or sets the number of points below which drawing will start. Default Infinity * This can be used instead of {@link pointGapThreshold} when data is unevenly spaced or has large y variation */ get pointCountThreshold(): number; /** * Gets or sets the number of points below which drawing will start. Default Infinity * This can be used instead of {@link pointGapThreshold} when data is unevenly spaced or has large y variation */ set pointCountThreshold(value: number); /** * How do decide whether to keep or skip a label once generated. * Override {@link shouldSkipLabel} for more control */ get skipMode(): EDataLabelSkipMode; /** * How do decide whether to keep or skip a label once generated. * Override {@link shouldSkipLabel} for more control */ set skipMode(value: EDataLabelSkipMode); /** * The number of points to skip while generating labels. Default 0 = no skip. 1 = skip every other. * When creating text with many data points, it will help performance to skip points rather than creating and checking overlap for every data point. */ get skipNumber(): number; /** * The number of points to skip while generating labels. Default 0 = no skip. 1 = skip every other. * When creating text with many data points, it will help performance to skip points rather than creating and checking overlap for every data point. */ set skipNumber(value: number); /** * Gets or sets numeric format to use when formatting values to text. For a list of values, see {@link ENumericFormat} * For more control, override getText * @remarks Reports {@link ENumericFormat.Decimal} while unset, but an UNSET provider defers to the * formatted column's declared {@link EColumnType} first — see {@link resolveFormat}. Setting this * (to `Decimal` included) pins it and beats the column type. */ get numericFormat(): ENumericFormat; set numericFormat(value: ENumericFormat); /** * Gets or sets the name of a string column on the parent series' DataSeries to take label text * from, instead of formatting y values. See {@link IBaseDataSeriesOptions.stringColumns}. * Takes precedence over {@link metaDataSelector}; setting both is a configuration error and warns * once. An unknown column name is ignored, falling through to the other text sources. * For more control, override getText. */ get textColumn(): string; set textColumn(value: string); /** * Gets the engineering prefixes to use when formatting values to text. */ get engineeringPrefix(): IEngineeringPrefix; /** * Gets or sets the engineering prefixes to use when formatting values to text. * Default - `['K','M','B','T']` for "large" prefixes, `['m','u','n','p']` for small prefixes * @remarks Only works when {@link ENumericFormat.Engineering} is selected */ set engineeringPrefix(value: IEngineeringPrefix); /** * Gets or sets the precision to use when formatting values to text * For more control, override getText * @remarks Reports `1` while unset, but an UNSET provider defers to the formatted column's declared * {@link EColumnType} first — see {@link resolveFormat}. Setting this pins it. */ get precision(): number; set precision(value: number); /** * 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); /** * Maps the ordinal currently being drawn ({@link DataLabelState.index}) to the row of the parent * DataSeries it came from. * * The default composes the two mappings the way {@link DataLabelState.getMetaData} does - flip * FIRST (`getIndexInternal`, which reverses the window on a non-flipped X axis), then map through * the point series' `indexes` (which is non-identity once the data is resampled). That is the * order the label's own {@link DataLabelState.xVal}/{@link DataLabelState.yVal} use, so text and * coordinates always name the same row. * * Override this in a provider whose drawn ordinals do not follow that convention - see * {@link StackedColumnSeriesDataLabelProvider} - so that text sources resolve against the same row * the provider's own getPosition places the label on. */ protected resolveSourceIndex(state: DataLabelState): number; /** * Resolves the numeric format and precision to format this label with, in strict precedence: * 1. an explicit {@link numericFormat} / {@link precision} — always wins; * 2. otherwise the {@link DEFAULT_FORMAT_FOR_COLUMN_TYPE} entry for the declared * {@link EColumnType} of the column being formatted (see {@link resolveColumnType}); * 3. otherwise the class defaults, `Decimal` and `1`. * * The two resolve INDEPENDENTLY: setting only `precision` still inherits the column type's format, * and setting only `numericFormat` still inherits its precision. */ protected resolveFormat(state: DataLabelState): { numericFormat: ENumericFormat; precision: number; }; /** * Applies numeric format to current yValue */ getText(state: DataLabelState): string; /** * Called at the start of generateDataLabels. If False, no labels will be generated. * Checks {@link pointCountThreshold} then {@link pointGapThreshold} * @param state * @returns */ shouldGenerate(state: DataLabelState): boolean; /** * Returns x, y coordinates where the data-label should be drawn */ getPosition(state: DataLabelState, textBounds: TSRTextBounds): { position: Point; rotationCenter: Point; rotationAngle: number; }; getColor(state: DataLabelState, text: string): number; /** * Called before adding a new label to state. If True the label will not be rendered. */ shouldSkipLabel(state: DataLabelState, label: TDataLabel): boolean; /** 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; /** Generates labels using getText, getPosition, getColor. Overrides manually set labels. */ generateDataLabels(renderContext: WebGlRenderContext2D, renderPassData: RenderPassData): void; protected getPositionForPoint(x: number, y: number, textBounds: TSRTextBounds): { position: Point; rotationCenter: Point; rotationAngle: number; }; toJSON(): { type: EDataLabelProviderType; options: { style: TDataLabelStyle; color: string; }; }; protected horizontalTextPositionToAnchorPoint(horizontalPosition: EHorizontalTextPosition): EHorizontalAnchorPoint; protected verticalTextPositionToAnchorPoint(verticalPosition: EVerticalTextPosition): EVerticalAnchorPoint; protected getPadding(): Thickness; private skipIfOverlapPrevious; private skipIfOverlapNext; } /** Registers {@link DataLabelProvider} for `EDataLabelProviderType.Default` definitions. */ export declare function registerDefaultDataLabelProvider(overWrite?: boolean): void;