Skip to content

Commit

Permalink
fix: revert addCustomSeries method
Browse files Browse the repository at this point in the history
  • Loading branch information
illetid committed Nov 5, 2024
1 parent 7356856 commit 50d8f38
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 119 deletions.
75 changes: 41 additions & 34 deletions src/api/chart-api.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { ChartWidget, MouseEventParamsImpl, MouseEventParamsImplSupplier } from '../gui/chart-widget';

import { assert, ensureDefined } from '../helpers/assertions';
import { assert, ensure, ensureDefined } from '../helpers/assertions';
import { Delegate } from '../helpers/delegate';
import { warn } from '../helpers/logger';
import { clone, DeepPartial, isBoolean, merge } from '../helpers/strict-type-checks';

import { ChartOptionsImpl, ChartOptionsInternal } from '../model/chart-model';
import { DataUpdatesConsumer, isFulfilledData, SeriesDataItemTypeMap } from '../model/data-consumer';
import { DataUpdatesConsumer, isFulfilledData, SeriesDataItemTypeMap, WhitespaceData } from '../model/data-consumer';
import { DataLayer, DataUpdateResponse, SeriesChanges } from '../model/data-layer';
import { CustomData } from '../model/icustom-series';
import { CustomData, ICustomSeriesPaneView } from '../model/icustom-series';
import { IHorzScaleBehavior } from '../model/ihorz-scale-behavior';
import { Pane } from '../model/pane';
import { Series } from '../model/series';
import { SeriesPlotRow } from '../model/series-data';
import {
CustomSeriesOptions,
CustomSeriesPartialOptions,
precisionByMinMove,
PriceFormat,
PriceFormatBuiltIn,
Expand All @@ -23,8 +24,8 @@ import {
SeriesPartialOptionsMap,
SeriesType,
} from '../model/series-options';
import { isCustomSeriesDefinition } from '../model/series/custom-series';
import { CustomSeriesDefinition, isSeriesDefinition, SeriesDefinition } from '../model/series/series-def';
import { createCustomSeriesDefinition } from '../model/series/custom-series';
import { isSeriesDefinition, SeriesDefinition } from '../model/series/series-def';
import { Logical } from '../model/time-data';

import { getSeriesDataCreator } from './get-series-data-creator';
Expand Down Expand Up @@ -179,24 +180,34 @@ export class ChartApi<HorzScaleItem> implements IChartApiBase<HorzScaleItem>, Da
this._chartWidget.resize(width, height, forceRepaint);
}

public addCustomSeries<
TData extends CustomData<HorzScaleItem>,
TOptions extends CustomSeriesOptions,
TPartialOptions extends CustomSeriesPartialOptions = SeriesPartialOptions<TOptions>,
>(
customPaneView: ICustomSeriesPaneView<HorzScaleItem, TData, TOptions>,
options: SeriesPartialOptions<TOptions> = {},
paneIndex: number = 0
): ISeriesApi<'Custom', HorzScaleItem, TData, TOptions, TPartialOptions> {
const paneView = ensure(customPaneView);
const definition = createCustomSeriesDefinition<HorzScaleItem, TData, TOptions>(paneView);
return this._addSeriesImpl<'Custom', TData, TOptions, TPartialOptions>(
definition,
options,
paneIndex
);
}

public addSeries<T extends SeriesType>(
definition: SeriesDefinition<T> | CustomSeriesDefinition<HorzScaleItem, CustomData<HorzScaleItem>, CustomSeriesOptions>,
options: SeriesPartialOptionsMap[T] | SeriesPartialOptions<CustomSeriesOptions> = {},
definition: SeriesDefinition<T>,
options: SeriesPartialOptionsMap[T] = {},
paneIndex: number = 0
): ISeriesApi<T, HorzScaleItem> {
if (isCustomSeriesDefinition(definition)) {
return this._addSeriesImpl<T, SeriesPartialOptions<CustomSeriesOptions>>(
return this._addSeriesImpl<T>(
definition,
options as SeriesPartialOptions<CustomSeriesOptions>,
options,
paneIndex
);
} else {
return this._addSeriesImpl<T, SeriesPartialOptionsMap[T]>(
definition,
options as SeriesPartialOptionsMap[T],
paneIndex
);
}
}

public removeSeries(seriesApi: SeriesApi<SeriesType, HorzScaleItem>): void {
Expand Down Expand Up @@ -313,29 +324,25 @@ export class ChartApi<HorzScaleItem> implements IChartApiBase<HorzScaleItem>, Da
}

private _addSeriesImpl<
T extends SeriesType,
TPartialOptions extends SeriesPartialOptionsMap[T]
>(
definition: SeriesDefinition<T> | CustomSeriesDefinition<HorzScaleItem, CustomData<HorzScaleItem>, CustomSeriesOptions>,
options: TPartialOptions,
paneIndex: number = 0
): ISeriesApi<T, HorzScaleItem> {
assert(isSeriesDefinition<T>(definition));
TSeries extends SeriesType,
TData extends WhitespaceData<HorzScaleItem> = SeriesDataItemTypeMap<HorzScaleItem>[TSeries],
TOptions extends SeriesOptionsMap[TSeries] = SeriesOptionsMap[TSeries],
TPartialOptions extends SeriesPartialOptionsMap[TSeries] = SeriesPartialOptionsMap[TSeries]
>(
definition: SeriesDefinition<TSeries>,
options: SeriesPartialOptionsMap[TSeries] = {},
paneIndex: number = 0
): ISeriesApi<TSeries, HorzScaleItem, TData, TOptions, TPartialOptions> {
assert(isSeriesDefinition<TSeries>(definition));
patchPriceFormat(options.priceFormat);
const strictOptions = merge(clone(seriesOptionsDefaults), clone(definition.defaultOptions), options) as SeriesOptionsMap[T];
const strictOptions = merge(clone(seriesOptionsDefaults), clone(definition.defaultOptions), options) as SeriesOptionsMap[TSeries];
const createPaneView = definition.createPaneView;
const series = new Series(
this._chartWidget.model(),
definition.type,
strictOptions,
createPaneView,
isCustomSeriesDefinition(definition) ? definition.customPaneView : undefined
);
const series = new Series(this._chartWidget.model(), definition.type, strictOptions, createPaneView, definition.customPaneView);
this._chartWidget.model().addSeriesToPane(
series,
paneIndex
);
const res = new SeriesApi<T, HorzScaleItem>(series, this, this, this, this._horzScaleBehavior, (pane: Pane) => this._getPaneApi(pane));
const res = new SeriesApi<TSeries, HorzScaleItem, TData, TOptions, TPartialOptions>(series, this, this, this, this._horzScaleBehavior, (pane: Pane) => this._getPaneApi(pane));
this._seriesMap.set(res, series);
this._seriesMapReversed.set(series, res);

Expand Down
43 changes: 24 additions & 19 deletions src/api/ichart-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ import { DeepPartial } from '../helpers/strict-type-checks';
import { ChartOptionsImpl } from '../model/chart-model';
import { BarData, HistogramData, LineData, WhitespaceData } from '../model/data-consumer';
import { Time } from '../model/horz-scale-behavior-time/types';
import { CustomData } from '../model/icustom-series';
import { CustomData, ICustomSeriesPaneView } from '../model/icustom-series';
import { Point } from '../model/point';
import {
CustomSeriesOptions,
SeriesOptionsMap,
SeriesPartialOptions,
SeriesPartialOptionsMap,
SeriesType,
} from '../model/series-options';
import { CustomSeriesDefinition, SeriesDefinition } from '../model/series/series-def';
import { SeriesDefinition } from '../model/series/series-def';
import { Logical } from '../model/time-data';
import { TouchMouseEventData } from '../model/touch-mouse-event-data';

Expand Down Expand Up @@ -103,6 +102,26 @@ export interface IChartApiBase<HorzScaleItem = Time> {
*/
resize(width: number, height: number, forceRepaint?: boolean): void;

/**
* Creates a custom series with specified parameters.
*
* A custom series is a generic series which can be extended with a custom renderer to
* implement chart types which the library doesn't support by default.
*
* @param customPaneView - A custom series pane view which implements the custom renderer.
* @param customOptions - Customization parameters of the series being created.
* ```js
* const series = chart.addCustomSeries(myCustomPaneView);
* ```
*/
addCustomSeries<TData extends CustomData<HorzScaleItem>,
TOptions extends CustomSeriesOptions,
TPartialOptions extends SeriesPartialOptions<TOptions> = SeriesPartialOptions<TOptions>
>(
customPaneView: ICustomSeriesPaneView<HorzScaleItem, TData, TOptions>,
customOptions?: SeriesPartialOptions<TOptions>,
paneIndex?: number
): ISeriesApi<'Custom', HorzScaleItem, TData | WhitespaceData<HorzScaleItem>, TOptions, TPartialOptions>;
/**
* Creates a series with specified parameters.
*
Expand All @@ -116,26 +135,12 @@ export interface IChartApiBase<HorzScaleItem = Time> {
* const series = chart.addSeries(LineSeries, { lineWidth: 2 });
* ```
*/
addSeries<
T extends SeriesType,
TData extends WhitespaceData<HorzScaleItem>,
TOptions extends SeriesOptionsMap[T],
TPartialOptions extends SeriesPartialOptionsMap[T]
>(
addSeries<T extends SeriesType>(
definition: SeriesDefinition<T>,
options?: SeriesPartialOptionsMap[T],
paneIndex?: number
): ISeriesApi<T, HorzScaleItem>;
// eslint-disable-next-line tsdoc/syntax
/** @inheritdoc */
addSeries<
TData extends CustomData<HorzScaleItem>,
TOptions extends CustomSeriesOptions,
TPartialOptions extends SeriesPartialOptions<TOptions> = SeriesPartialOptions<TOptions>
>(
definition: CustomSeriesDefinition<HorzScaleItem, TData, TOptions>,
options?: Partial<TOptions>
): ISeriesApi<'Custom', HorzScaleItem, TData | WhitespaceData<HorzScaleItem>, TOptions, TPartialOptions>;

/**
* Removes a series of any type. This is an irreversible operation, you cannot do anything with the series after removing it.
*
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const customSeriesDefaultOptions: CustomSeriesOptions = {
export { ICustomSeriesPaneView, ICustomSeriesPaneRenderer, CustomBarItemData, CustomData } from './model/icustom-series';

export { createChart, createChartEx, defaultHorzScaleBehavior } from './api/create-chart';
export { createCustomSeries } from './model/series/create-custom-series';
export { lineSeries as LineSeries } from './model/series/line-series';
export { baselineSeries as BaselineSeries } from './model/series/baseline-series';
export { areaSeries as AreaSeries } from './model/series/area-series';
Expand Down
27 changes: 0 additions & 27 deletions src/model/series/create-custom-series.ts

This file was deleted.

16 changes: 4 additions & 12 deletions src/model/series/custom-series.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CustomData, ICustomSeriesPaneView } from '../icustom-series';
import { ISeries } from '../iseries';
import { CustomSeriesOptions, CustomStyleOptions } from '../series-options';
import { SeriesCustomPaneView } from './custom-pane-view';
import { CustomSeriesDefinition, CustomSeriesDefinitionInternal } from './series-def';
import { SeriesDefinition, SeriesDefinitionInternal } from './series-def';

export const customStyleDefaults: CustomStyleOptions = {
color: '#2196f3',
Expand All @@ -22,8 +22,8 @@ export const createCustomSeriesDefinition = <
HorzScaleItem,
TData extends CustomData<HorzScaleItem> = CustomData<HorzScaleItem>,
TSeriesOptions extends CustomSeriesOptions = CustomSeriesOptions
>(paneView: ICustomSeriesPaneView<HorzScaleItem, TData, TSeriesOptions>): CustomSeriesDefinition<HorzScaleItem, TData, TSeriesOptions> => {
const definition: CustomSeriesDefinitionInternal<HorzScaleItem, TData, TSeriesOptions> = {
>(paneView: ICustomSeriesPaneView<HorzScaleItem, TData, TSeriesOptions>): SeriesDefinition<'Custom'> => {
const definition: SeriesDefinitionInternal<'Custom'> = {
type: seriesType,
isBuiltIn: false as const,
defaultOptions: { ...customStyleDefaults, ...paneView.defaultOptions() },
Expand All @@ -33,13 +33,5 @@ export const createCustomSeriesDefinition = <
createPaneView: createPaneView,
customPaneView: paneView,
};
return definition as CustomSeriesDefinition<HorzScaleItem, TData, TSeriesOptions>;
return definition as SeriesDefinition<'Custom'>;
};

export function isCustomSeriesDefinition<
HorzScaleItem,
TData extends CustomData<HorzScaleItem> = CustomData<HorzScaleItem>,
TOptions extends CustomSeriesOptions = CustomSeriesOptions
>(def: unknown): def is CustomSeriesDefinition<HorzScaleItem, TData, TOptions> {
return (def as CustomSeriesDefinition<HorzScaleItem, TData, TOptions>)?.type === 'Custom';
}
24 changes: 3 additions & 21 deletions src/model/series/series-def.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,15 @@
import { IUpdatablePaneView } from '../../views/pane/iupdatable-pane-view';

import { IChartModelBase } from '../chart-model';
import { CustomData, ICustomSeriesPaneView } from '../icustom-series';
import { ICustomSeriesPaneView } from '../icustom-series';
import { ISeries } from '../iseries';
import { CustomSeriesOptions, CustomStyleOptions, SeriesStyleOptionsMap, SeriesType } from '../series-options';
import { SeriesStyleOptionsMap, SeriesType } from '../series-options';

export interface SeriesDefinition<T extends SeriesType> {
readonly type: T;
readonly isBuiltIn: boolean;
readonly defaultOptions: SeriesStyleOptionsMap[T];
}
export interface CustomSeriesDefinition<
HorzScaleItem,
TData extends CustomData<HorzScaleItem>,
TOptions extends CustomSeriesOptions
> {
readonly type: 'Custom';
readonly isBuiltIn: boolean;
/** @internal */
readonly defaultOptions: CustomStyleOptions;
/** @internal */
customPaneView: ICustomSeriesPaneView<HorzScaleItem, TData, TOptions>;
}
export interface CustomSeriesDefinitionInternal<
HorzScaleItem,
TData extends CustomData<HorzScaleItem>,
TOptions extends CustomSeriesOptions
> extends CustomSeriesDefinition<HorzScaleItem, TData, TOptions> {
createPaneView: (series: ISeries<'Custom'>, model: IChartModelBase, customPaneView?: ICustomSeriesPaneView<HorzScaleItem, TData, TOptions>) => IUpdatablePaneView;
readonly customPaneView?: ICustomSeriesPaneView<unknown>;
}

export const isSeriesDefinition = <T extends SeriesType>(value: unknown): value is SeriesDefinitionInternal<T> => {
Expand Down
10 changes: 5 additions & 5 deletions tests/type-checks/non-time-based-custom-series.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createChartEx, createCustomSeries, createTextWatermark, customSeriesDefaultOptions } from '../../src';
import { createChartEx, createTextWatermark, customSeriesDefaultOptions } from '../../src';
import { CandlestickData, WhitespaceData } from '../../src/model/data-consumer';
import { Time } from '../../src/model/horz-scale-behavior-time/types';
import { CustomData, CustomSeriesPricePlotValues, ICustomSeriesPaneRenderer, ICustomSeriesPaneView, PaneRendererCustomData } from '../../src/model/icustom-series';
Expand Down Expand Up @@ -56,12 +56,12 @@ const horizontalScaleBehaviourMock = new MyHorizontalScaleBehaviour();
// @ts-expect-error Mock Class
const chart = createChartEx<HorizontalScaleType, MyHorizontalScaleBehaviour>('anything', horizontalScaleBehaviourMock);
const customSeriesView = (new NonTimeSeries()) as ICustomSeriesPaneView<HorizontalScaleType, NonTimeData, NonTimeSeriesOptions>;
const customSeriesDefinition = createCustomSeries<HorizontalScaleType, NonTimeData, NonTimeSeriesOptions>(customSeriesView);

// @ts-expect-error invalid property
const failSeries = chart.addSeries(createCustomSeries(customSeriesView), { badOption: 123 });
const failSeries = chart.addCustomSeries(customSeriesView, { badOption: 123 });
// @ts-expect-error invalid value
const failSeries2 = chart.addSeries(customSeriesDefinition, { testOption: 123 });
const series = chart.addSeries<NonTimeData, NonTimeSeriesOptions>(customSeriesDefinition, { testOption: 'string' });
const failSeries2 = chart.addCustomSeries(customSeriesView, { testOption: 123 });
const series = chart.addCustomSeries<NonTimeData, NonTimeSeriesOptions>(customSeriesView, { testOption: 'string' });

const data: (NonTimeData | WhitespaceData<HorizontalScaleType>)[] = [
{ time: 12345 }, // whitespace
Expand Down

0 comments on commit 50d8f38

Please sign in to comment.