Загрузка данных
import { IChartApi, Time } from 'lightweight-charts';
import { BehaviorSubject, Observable } from 'rxjs';
import { DataSource } from '@core/DataSource';
import { DOMObject, DOMObjectParams } from '@core/DOMObject';
import { IndicatorsIds, indicatorsMap, labelByIndicatorId } from '@core/Indicators';
import { getDefaultMaIndicatorSettings, MaIndicatorSettings } from '@src/core/Indicators/settings';
import { SeriesFactory, SeriesStrategies } from '@src/modules/series-strategies/SeriesFactory';
import { ChartTypeOptions } from '@src/types';
import { IndicatorLegendItem, LegendValueItem } from '@src/types/legend';
import { ensureDefined } from '@src/utils';
type IIndicator = DOMObject;
interface IndicatorParams extends DOMObjectParams {
mainSymbol$: Observable<string>;
mainSerie$: BehaviorSubject<SeriesStrategies | null>;
lwcChart: IChartApi;
dataSource: DataSource;
chartOptions?: ChartTypeOptions;
}
export class Indicator extends DOMObject implements IIndicator {
private series: SeriesStrategies[] = [];
private seriesMap = new Map<string, SeriesStrategies>();
private legendSeriesIds: string[] = [];
private legendSeriesColors = new Map<string, string | undefined>();
private readonly chartApi: IChartApi;
private readonly dataSource: DataSource;
private readonly chartOptions?: ChartTypeOptions;
private readonly mainSeries: BehaviorSubject<SeriesStrategies | null>;
private readonly mainSymbol: Observable<string>;
private maSettings: MaIndicatorSettings | null;
constructor({
id,
lwcChart,
dataSource,
chartOptions,
zIndex,
onDelete,
moveUp,
moveDown,
mainSerie$,
mainSymbol$,
}: IndicatorParams) {
super({ id: id as string, zIndex, onDelete, moveUp, moveDown });
this.chartApi = lwcChart;
this.dataSource = dataSource;
this.chartOptions = chartOptions;
this.mainSeries = mainSerie$;
this.mainSymbol = mainSymbol$;
this.maSettings = getDefaultMaIndicatorSettings(id as IndicatorsIds);
this.buildSeries();
}
private buildSeries(): void {
this.series = [];
this.seriesMap.clear();
this.legendSeriesIds = [];
this.legendSeriesColors.clear();
const indicatorConfig = ensureDefined(indicatorsMap[this.id as IndicatorsIds]);
const { series, paneIndex } = indicatorConfig;
series.forEach(
({ name, id: seriesId, dataFormatter, seriesOptions, priceScaleOptions, legendVisible, legendColor }) => {
const strategy = SeriesFactory.create(name!)({
lwcChart: this.chartApi,
dataSource: this.dataSource,
customFormatter: dataFormatter,
seriesOptions,
chartOptions: this.chartOptions,
priceScaleOptions,
mainSymbol$: this.mainSymbol,
mainSerie$: this.mainSeries,
showSymbolLabel: false,
paneIndex,
indicatorReference: this,
});
this.seriesMap.set(seriesId, strategy);
this.series.push(strategy);
if (legendVisible !== false) {
this.legendSeriesIds.push(seriesId);
this.legendSeriesColors.set(seriesId, legendColor);
}
},
);
}
private rebuildSeries(): void {
this.series.forEach((series) => {
series.destroy();
});
this.buildSeries();
}
public getIndicatorSettings(): MaIndicatorSettings | null {
return this.maSettings ? { ...this.maSettings } : null;
}
public updateIndicatorSettings(nextSettings: MaIndicatorSettings): void {
if (!this.maSettings) {
return;
}
this.maSettings = { ...nextSettings };
this.rebuildSeries();
}
public resetIndicatorSettings(): void {
const defaultSettings = getDefaultMaIndicatorSettings(this.id as IndicatorsIds);
if (!defaultSettings) {
return;
}
this.maSettings = defaultSettings;
this.rebuildSeries();
}
public getLegendItem(time?: Time): IndicatorLegendItem {
const indicatorId = this.id as IndicatorsIds;
const values = this.legendSeriesIds
.map((seriesId): LegendValueItem | null => {
const strategy = this.seriesMap.get(seriesId);
if (!strategy) {
return null;
}
const value = strategy.getLegendValue(time);
if (value == null) {
return null;
}
return {
id: `${indicatorId}-${seriesId}`,
value,
color: this.legendSeriesColors.get(seriesId) ?? strategy.getLegendColor(time) ?? '',
};
})
.filter((item): item is LegendValueItem => item != null);
return {
id: indicatorId,
label: labelByIndicatorId[indicatorId],
values,
};
}
public getSeriesMap() {
return this.seriesMap;
}
public delete(): void {
super.delete();
}
public show(): void {
this.series.forEach((series) => {
series.show();
});
super.show();
}
public hide(): void {
this.series.forEach((series) => {
series.hide();
});
super.hide();
}
public destroy(): void {
this.series.forEach((series) => {
series.destroy();
});
}
}