scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
436 lines (435 loc) • 21 kB
TypeScript
import { TDataSeriesDefinition } from "../../Builder/buildDataSeries";
import { DeletableEntity } from "../../Core/DeletableEntity";
import { EventHandler } from "../../Core/EventHandler";
import { NumberRange } from "../../Core/NumberRange";
import { NumberArray } from "../../types/NumberArray";
import { ESearchMode } from "../../types/SearchMode";
import { SCRTDoubleVector, TSciChart } from "../../types/TSciChart";
import { EYRangeMode } from "../../types/YRangeMode";
import { ExtremeResamplerHelper } from "../Numerics/Resamplers/ExtremeResamplerHelper";
import { ResamplingParams } from "../Numerics/Resamplers/ResamplingParams";
import { SeriesAnimation } from "../Visuals/RenderableSeries/Animations/SeriesAnimation";
import { IDataDistributionCalculator } from "./DataDistributionCalculator/IDataDistributionCalculator";
import { IDoubleVectorProvider } from "./DoubleVectorProvider";
import { EDataChangeType, EDataSeriesType, EDataSeriesValueType, IDataChangeArgs, IDataSeries } from "./IDataSeries";
import { IMetadataGenerator, IPointMetadata } from "./IPointMetadata";
import { IPointSeries } from "./PointSeries/IPointSeries";
/**
* Options to pass to the {@link BaseDataSeries} constructor
*/
export interface IBaseDataSeriesOptions {
/**
* A unique Id for the {@link IDataSeries}
*/
id?: string;
/**
* The DataSeries name, used in legends, tooltips to identify the chart series
*/
dataSeriesName?: string;
/**
* When true, the Data is sorted in X. Same as isSorted.
* @remarks The user must specify this parameter if the data is not sorted in X
* in order to have correct rendering. This parameter is used to choose the correct
* algorithms for zooming, panning and ranging and ensure best performance.
*/
dataIsSortedInX?: boolean;
/**
* When true, the Data is sorted in X. Same as dataIsSortedInX.
* @remarks The user must specify this parameter if the data is not sorted in X
* in order to have correct rendering. This parameter is used to choose the correct
* algorithms for zooming, panning and ranging and ensure best performance.
*/
isSorted?: boolean;
/**
* When true, the Data is evenly spaced in X.
* @remarks
* The user must specify this flag (defaults to true) in order to choose the correct, and
* fastest algorithms for drawing, indexing and ranging. If you experience glitches or
* strange drawing, it may be because you have set data with uneven spacing in X but not set this flag.
*/
dataEvenlySpacedInX?: boolean;
/**
* Gets or sets whether the Y data contains NaN values.
*/
containsNaN?: boolean;
/**
* Set the maximum size of the dataSeries in FIFO (First In First Out) mode. This can only be set in the constructor options.
* If set, the dataSeries does not support insert/insertRange or remove/removeRange. Any data that is appended once the dataSeries has reached fifoCapacity will cause
* the oldest data to be discarded. This is much more efficient than appending and removing for achieving scrolling data.
* Spline series and Stacked series currently do not support fifo mode.
* To get the scrolling effect, you need to consider the behaviour of your X Axis. You can either
* Use a {@link CategoryAxis}
* Use a {@link NumericAxis} with increasing x values, and update the visibleRange (or use zoomExtents)
*/
fifoCapacity?: number;
/**
* If true, data in fifo mode will not be "unwrapped" before drawing, giving ecg style sweeping mode.
* To get the sweeping effect, you need to consider the behaviour of your X Axis. You can either
* Use a {@link CategoryAxis}
* Use a {@link NumericAxis} and make your x values an offset from the first value, eg by doing x % fifoCapcity
*/
fifoSweeping?: boolean;
/** In fifo sweeping mode, the number of earliest points to skip to create a gap between the latest and earliest data */
fifoSweepingGap?: number;
/** Sets the starting index of data for fifo mode. */
fifoStartIndex?: number;
/**
* Gets or sets the capacity of the data series. This is the amount of memory reserved for the data. For a normal dataSeries this will grow as data is appended.
* You can avoid memory fragmentation by creating your series with a larger capacity if you know it will grow to that.
*/
capacity?: number;
/**
* The X-values array to pre-populate the {@link XyDataSeries}
*/
xValues?: NumberArray;
/**
* The Y-values array to pre-populate the {@link XyDataSeries}
*/
yValues?: NumberArray;
/**
* The Metadata values of type {@link IPointMetadata} to pre-populate the {@link IDataSeries}
* If a single metadata value is supplied, this will be used as a template for all data values.
* If type is specified, it should refer to a registered metadataGenerator {@link IMetadataGenerator},
* which can provide all metadata, based on the data provided, or a single object that will be used when adding data if no metadata is provided.
*/
metadata?: IPointMetadata[] | IPointMetadata | {
type: string;
data?: any;
};
/** The number of y values arrays. Eg Xy = 1, Xyy = 2 xOHLC = 4 */
arrayCount?: number;
/** The names for the y values arrays. Defaults to y, y1, y2 etc */
valueNames?: string[];
/** Whether each set of Y values should be included when calculating y Range */
includeInYRange?: boolean[];
}
/**
* The base class for DataSeries in SciChart's
* {@link https://www.scichart.com/javascript-chart-features | JavaScript Charts}
* @remarks
* A DataSeries stores the data to render. This is independent from the {@link IRenderableSeries | RenderableSeries}
* which defines how that data should be rendered.
*
* See derived types of {@link BaseDataSeries} to find out what data-series are available.
* See derived types of {@link IRenderableSeries} to find out what 2D JavaScript Chart types are available.
*/
export declare abstract class BaseDataSeries<T = IPointMetadata> extends DeletableEntity implements IDataSeries {
/** @inheritDoc */
abstract readonly type: EDataSeriesType;
/** @inheritDoc */
readonly dataChanged: EventHandler<IDataChangeArgs>;
/** @inheritDoc */
readonly id: string;
/** @inheritDoc */
readonly dataDistributionCalculator: IDataDistributionCalculator;
minXSpacing: number;
/**
* If set, these will be included in the serialised definition, so that it can be used with sharedData
*/
dataIds: Record<number | string, number[]>;
/**
* The {@link TSciChart | SciChart WebAssembly Context} containing native methods and access to our WebGL2 Engine
*/
readonly webAssemblyContext: TSciChart;
/**
* X vector with initial animation values
*/
xInitialAnimationValues: SCRTDoubleVector;
/**
* Y vector with initial animation values
*/
yInitialAnimationValuesArray: SCRTDoubleVector[];
/**
* X vector with final animation values
*/
xFinalAnimationValues: SCRTDoubleVector;
/**
* Y vector with final animation values
*/
yFinalAnimationValuesArray: SCRTDoubleVector[];
readonly valueNames: string[];
protected xValues: SCRTDoubleVector;
protected indexes: SCRTDoubleVector;
protected readonly yValuesArray: SCRTDoubleVector[];
/** The number of y values arrays in this DataSeries */
readonly arrayCount: number;
protected isDeleted: boolean;
protected doubleVectorProvider: IDoubleVectorProvider;
protected includeInYRange: boolean[];
private dataSeriesNameProperty;
private isSortedProperty;
private containsNaNProperty;
private isEvenlySpacedProperty;
private metadataProperty;
private metadataGeneratorProperty;
private changeCountProperty;
private fifoCapacityProperty;
private fifoSweepingProperty;
private fifoSweepingGapProperty;
/**
* Creates an instance of {@link BaseDataSeries}
* @param webAssemblyContext the {@link TSciChart | SciChart WebAssembly Context} containing native methods
* and access to our underlying WebGL2 rendering engine
* @param options the {@link IBaseDataSeriesOptions} which can be passed to config the DataSeries at construct time
*/
protected constructor(webAssemblyContext: TSciChart, options?: IBaseDataSeriesOptions);
getYValuesByName(name: string, dataSeriesValueType?: EDataSeriesValueType): SCRTDoubleVector;
/**
* Appends a single X, ...YArray, point to the DataSeries
* @remarks
* For best performance on drawing large datasets, use the {@link appendRange} method
*
* Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param x The X-value
* @param metadata The point metadata
* @param yArray An array of the y values
*/
appendN(x: number, yArray: number[], metadata?: T, onAppend?: () => void): void;
/**
* Appends a range of X, yValuesArray points to the DataSeries
* @remarks
* This method is considerably higher performance than {@link append} which appends a single point
*
* Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param xValues The X-values
* @param yValuesArray An array of Y-value arrays
* @param metadata The array of point metadata
*/
appendRangeN(xValues: NumberArray, yValuesArray: NumberArray[], metadata?: T[], onAppend?: () => void): void;
/**
* Appends a range of X, yValuesArray points to the DataSeries
* @remarks
* This method is an optimized version of the {@link appendRangeN}.
* It skips some data validation steps.
* So, make sure to set the proper optimization flags manually ({@link isSorted}, {@link containsNaN}, etc.) when using this method.
*
* Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param xValues The X-values defined as 64bit float numbers contained within an ArrayBuffer
* @param yValuesArray An array of Y-value arrays defined as 64bit float numbers contained within an ArrayBuffer
* @param metadata The array of point metadata
*/
appendBufferRangeN(xValues: ArrayBuffer, yValuesArray: ArrayBuffer[], metadata?: T[], onAppend?: () => void): void;
/**
* Updates a single set of y values by X-index
* @remarks Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param index the index to update
* @param yArray The new Y values
* @param metadata The point metadata
*/
updateN(index: number, yArray: number[], metadata?: T, onUpdate?: () => void): void;
/**
* Updates a single X, and set of Y-values by X-index. Might also need to set isSorted = false
* @remarks Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param index The index to update
* @param x The new X value
* @param yArray The new Y values
* @param metadata The point metadata
*/
updateXyN(index: number, x: number, yArray: number[], metadata?: T, onUpdate?: () => void): void;
/**
* @summary Inserts a single X and set of Y-values at the start index
* @remarks
* For best performance on drawing large datasets, use the {@link insertRange} method
*
* Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param startIndex the index to insert at
* @param x the X value
* @param yArray the Y values
* @param metadata The point metadata
*/
insertN(startIndex: number, x: number, yArray: number[], metadata?: T, onInsert?: () => void): void;
/**
* @summary Inserts a range of X,Y values at the startIndex
* @remarks
* Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param startIndex the index to insert at
* @param xValues the XValues
* @param yValues yValuesArray An array of Y-value arrays
* @param metadata The array of point metadata
*/
insertRangeN(startIndex: number, xValues: NumberArray, yValuesArray: NumberArray[], metadata?: T[], onInsert?: () => void): void;
/**
* Removes an X, and all associated y values at the specified index
* @remarks Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param index the index to remove at
*/
removeAt(index: number): void;
/**
* @summary Removes a range of X, and all associated y values starting at the specified index
* @remarks Any changes of the DataSeries will trigger a redraw on the parent {@link SciChartSurface}
* @param startIndex the start index to remove at
* @param count the number of points to remove
*/
removeRange(startIndex: number, count: number): void;
/** @inheritDoc */
clear(): void;
/**
* Gets or sets the capacity of data-points in the DataSeries
*/
get capacity(): number;
/**
* Gets or sets the capacity of data-points in the DataSeries
*/
set capacity(value: number);
/** @inheritDoc */
get containsNaN(): boolean;
/** @inheritDoc */
set containsNaN(containsNaN: boolean);
/** @inheritDoc */
get isSorted(): boolean;
/** @inheritDoc */
set isSorted(isSorted: boolean);
/** @inheritDoc */
get isEvenlySpaced(): boolean;
/** @inheritDoc */
set isEvenlySpaced(isSorted: boolean);
/** @inheritDoc */
get dataSeriesName(): string;
/** @inheritDoc */
set dataSeriesName(dataSeriesName: string);
/** @inheritDoc */
count(): number;
/** @inheritDoc */
getIsDeleted(): boolean;
/** @inheritDoc */
get fifoCapacity(): number;
/** @inheritDoc */
get fifoStartIndex(): number;
/** @inheritDoc */
get fifoSweeping(): boolean;
/** @inheritDoc */
set fifoSweeping(enabled: boolean);
/** @inheritDoc */
get fifoSweepingGap(): number;
/** @inheritDoc */
set fifoSweepingGap(fifoSweepingGap: number);
/** @inheritDoc */
getNativeIndexes(): SCRTDoubleVector;
/** @inheritDoc */
getNativeXValues(): SCRTDoubleVector;
/** @inheritDoc */
getNativeYValues(i?: number): SCRTDoubleVector;
get yInitialAnimationValues(): SCRTDoubleVector;
get yFinalAnimationValues(): SCRTDoubleVector;
getNativeValue(values: SCRTDoubleVector, index: number): number;
/** @inheritDoc */
delete(): void;
/**
* Call to notify subscribers of {@link dataChanged} that the data has changed and {@link SciChartSurface} needs redrawing
*/
notifyDataChanged(changeType: EDataChangeType, index: number, count: number, name?: string): void;
/** @inheritDoc */
get xRange(): NumberRange;
private memoizedgetXRange;
/** @inheritDoc */
getXRange(dataSeriesValueType?: EDataSeriesValueType): NumberRange;
getXRangeByName(dataSeriesValueType?: EDataSeriesValueType, valueName?: string): NumberRange;
private memoizedGetWindowedYRange;
/** @inheritDoc */
getWindowedYRange(xRange: NumberRange, getPositiveRange: boolean, isXCategoryAxis?: boolean, dataSeriesValueType?: EDataSeriesValueType, yRangeMode?: EYRangeMode): NumberRange;
/** @inheritDoc */
getIndicesRange(xRange: NumberRange, isCategoryData?: boolean, downSearchMode?: ESearchMode, upSearchMode?: ESearchMode): NumberRange;
/** @inheritDoc */
get hasValues(): boolean;
/**
* Check if the series has an existing metadataGenerator
*/
hasMetadataGenerator(): boolean;
/**
* Sets a function that will be used to generate metadata for values when they are appended/inserted, if no explicit metadata is supplied.
* @param generator
*/
setMetadataGenerator(generator: IMetadataGenerator): void;
/**
* Gets the metadata by index
* @param index The X index
*/
getMetadataAt(index: number, ignoreFifo?: boolean): T;
/**
* Gets the metadata array length
*/
getMetadataLength(): number;
/**
* Check if the series has an existing metadata
*/
get hasMetadata(): boolean;
createAnimationVectors(): void;
/**
* Sets initial values for the data animation
* @param dataSeries The {@link BaseDataSeries} to be used for initial values
*/
setInitialAnimationVectors(dataSeries?: BaseDataSeries<T>): void;
/**
* Sets final values for the data animation
* @param dataSeries The {@link BaseDataSeries} to be used for final values
*/
setFinalAnimationVectors(dataSeries?: BaseDataSeries<T>): void;
/**
* Puts the animation values back into the dataSeries after a reverse animation
* @param dataSeries The {@link BaseDataSeries} to be used for target values
*/
revertAnimationVectors(dataSeries?: BaseDataSeries<T>): void;
/**
* Validates the length of the animation vectors
*/
validateAnimationVectors(): void;
/**
* Updates the {@link BaseDataSeries} values for the animation
* @param progress The animation progress from 0 to 1
* @param animation The animation
*/
updateAnimationProperties(progress: number, animation: SeriesAnimation): void;
/**
* Get if a named yValues array should be included when calculating yRange
* @param name
* @param isUsed
*/
isUsedForYRange(name: string): boolean;
/**
* Set if a named yValues array should be included when calculating yRange
* @param name Usually an {@link EValueName}
* @param isUsed
*/
setUsedForYRange(name: string, isUsed: boolean): void;
/** @inheritDoc */
toJSON(excludeData?: boolean): TDataSeriesDefinition;
/** @inheritDoc */
get changeCount(): number;
protected getOptions(excludeData?: boolean): IBaseDataSeriesOptions;
/**
* Base behaviour is to return a wrapped pointSeries - ie no resampling.
* @param rp
* @param pointSeries
* @param resamplerHelper
* @returns
*/
toPointSeries(rp?: ResamplingParams, pointSeries?: IPointSeries, resamplerHelper?: ExtremeResamplerHelper): IPointSeries;
/**
* Finds the nearest index of the xValue passed in by performing binary or linear search on the X-Values array.
* Returns -1 for index not found. Other negative numbers indicate an error condition
* @param xValue the X-value to find
* @param findMode the {@link ESearchMode} to use when searching. Defaults to {@link ESearchMode.Nearest}.
* Mode {@link ESearchMode.Exact} will result in a slower search, other modes will result in fast binary search.
* @return The index, or -1 if not found
*/
findIndex(xValue: number, searchMode?: ESearchMode): number;
protected validateIndex(index: number, message?: string): void;
protected setMetadataAt(index: number, metadata: T): void;
protected appendMetadata(metadata: T): void;
protected appendMetadataRange(metadata: T[], length: number): void;
protected insertMetadata(startIndex: number, metadata: T): void;
protected insertMetadataRange(startIndex: number, metadata: T[]): void;
protected removeMetadataAt(index: number): void;
protected removeMetadataRange(startIndex: number, count: number): void;
protected setMetadata(value: T[]): void;
getXValues(dataSeriesValueType: EDataSeriesValueType): SCRTDoubleVector;
getYValuesArray(dataSeriesValueType: EDataSeriesValueType): SCRTDoubleVector[];
protected throwIfFifo(operation: string): void;
protected reserve(size: number): void;
protected calculateInitialCapacity(options: IBaseDataSeriesOptions): number;
private fillMetadataIfUndefined;
getYValues(dataSeriesValueType: EDataSeriesValueType, index?: number): SCRTDoubleVector;
}
/** @ignore */
export declare const getIndicesRange: (webAssemblyContext: TSciChart, xValues: SCRTDoubleVector, xRange: NumberRange, isSorted: boolean, downSearchMode?: ESearchMode, upSearchMode?: ESearchMode) => NumberRange;
export declare const getWindowedYRange: (webAssemblyContext: TSciChart, xValues: SCRTDoubleVector, yValues: SCRTDoubleVector, xRange: NumberRange, getPositiveRange: boolean, isXCategoryAxis: boolean, isSorted: boolean, containsNaN: boolean, minSearchMode?: ESearchMode, maxSearchMode?: ESearchMode) => NumberRange;