@devexperts/dxcharts-lite
Version:
129 lines (128 loc) • 6.3 kB
JavaScript
/*
* Copyright (C) 2019 - 2026 Devexperts Solutions IE Limited
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/*
* Copyright (C) 2019 - 2024 Devexperts Solutions IE Limited
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { BehaviorSubject } from 'rxjs';
import { CHART_UUID } from '../../canvas/canvas-bounds-container';
import { ChartBaseElement } from '../../model/chart-base-element';
import { SeparateVolumesComponent } from './separate-volumes.component';
import { resolveColorForBar, resolveColorForCandle, resolveColorForLine } from './volume-color-resolvers.functions';
import { VolumesDrawer } from './volumes.drawer';
import { VOLUMES_UUID, VolumesModel } from './volumes.model';
export class VolumesComponent extends ChartBaseElement {
constructor(canvasModel, chartComponent, scale, canvasBoundsContainer, drawingManager, config, paneManager, dynamicObjectsComponent) {
super();
this.canvasModel = canvasModel;
this.canvasBoundsContainer = canvasBoundsContainer;
this.config = config;
this.dynamicObjectsComponent = dynamicObjectsComponent;
this.volumesColorByChartTypeMap = {};
this.volumeVisibilityChangedSubject = new BehaviorSubject(false);
this.volumeIsSeparateModeChangedSubject = new BehaviorSubject(false);
const volumesModel = new VolumesModel(chartComponent, scale);
this.volumesModel = volumesModel;
this.addChildEntity(volumesModel);
this.separateVolumes = new SeparateVolumesComponent(chartComponent, config, volumesModel, paneManager);
this.volumesDrawer = new VolumesDrawer(config, this.volumesModel, chartComponent.chartModel, () => { var _a, _b; return (this.config.components.volumes.showSeparately ? ((_b = (_a = this.separateVolumes.pane) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : scale) : scale); }, this.volumesColorByChartTypeMap, () => true);
config.components.volumes.visible && this.syncVolumesDynamicObject();
this.addChildEntity(this.separateVolumes);
this.registerDefaultVolumeColorResolvers();
this.volumeVisibilityChangedSubject.next(config.components.volumes.visible);
this.volumeIsSeparateModeChangedSubject.next(config.components.volumes.showSeparately);
}
/**
* Registers default volume color resolvers for candle, line and bar charts
* @private
*/
registerDefaultVolumeColorResolvers() {
this.registerVolumeColorResolver('candle', resolveColorForCandle);
this.registerVolumeColorResolver('trend', resolveColorForCandle);
this.registerVolumeColorResolver('hollow', resolveColorForCandle);
this.registerVolumeColorResolver('line', resolveColorForLine);
this.registerVolumeColorResolver('bar', resolveColorForBar);
}
/**
* Sets whether the volumes should be shown separately or not.
*
* @param {boolean} separate - A boolean value indicating whether the volumes should be shown separately or not.
* @returns {void}
*/
setShowVolumesSeparatly(separate) {
if (this.config.components.volumes.showSeparately !== separate) {
this.config.components.volumes.showSeparately = separate;
if (separate) {
this.separateVolumes.activateSeparateVolumes();
}
else {
this.separateVolumes.deactiveSeparateVolumes();
}
this.volumeIsSeparateModeChangedSubject.next(separate);
this.syncVolumesDynamicObject();
}
}
/**
* This method deactivates the current component by calling the superclass doDeactivate method and setting the visibility of the component to false.
* @returns {void}
*/
doDeactivate() {
super.doDeactivate();
this.setVisible(false);
}
/**
* You can use this method to determine volumes' color for specified chart type.
* @param chartType
* @param resolver
*/
registerVolumeColorResolver(chartType, resolver) {
this.volumesColorByChartTypeMap[chartType] = resolver;
}
/**
* Sets the visibility of the volumes component and updates the canvas accordingly.
* @param {boolean} visible - Whether the volumes component should be visible or not. Default is true.
* @returns {void}
*/
setVisible(visible = true) {
this.config.components.volumes.visible = visible;
this.volumeVisibilityChangedSubject.next(visible);
if (this.config.components.volumes.showSeparately) {
if (visible) {
this.separateVolumes.activateSeparateVolumes();
this.volumeIsSeparateModeChangedSubject.next(true);
}
else {
this.separateVolumes.deactiveSeparateVolumes();
this.volumeIsSeparateModeChangedSubject.next(false);
}
}
this.canvasBoundsContainer.recalculatePanesHeightRatios();
this.syncVolumesDynamicObject();
this.canvasModel.fireDraw();
}
syncVolumesDynamicObject() {
const visible = this.config.components.volumes.visible;
if (!visible) {
this.dynamicObjectsComponent.model.removeObject(this.volumesModel.id);
return;
}
const paneId = this.config.components.volumes.showSeparately ? VOLUMES_UUID : CHART_UUID;
const volumesDynamicObject = {
id: this.volumesModel.id,
paneId,
drawer: this.volumesDrawer,
model: this.volumesModel,
};
// check if the volumes dynamic object is already added
const position = this.dynamicObjectsComponent.model.getObjectPosition(this.volumesModel.id);
if (position === -1) {
this.dynamicObjectsComponent.model.addObject(volumesDynamicObject);
return;
}
this.dynamicObjectsComponent.model.updateObject(volumesDynamicObject);
}
}