@devexperts/dxcharts-lite
Version:
114 lines (113 loc) • 6.51 kB
JavaScript
/*
* Copyright (C) 2019 - 2025 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 { CanvasElement } from '../../canvas/canvas-bounds-container';
import { ChartBaseElement } from '../../model/chart-base-element';
import { DragNDropXComponent } from '../dran-n-drop_helper/drag-n-drop-x.component';
// TODO find out why do we need this correction
const NAV_MAP_KNOT_CORRECTION = 4;
export class NavigationMapMoveHandler extends ChartBaseElement {
constructor(bus, chartModel, scale, canvasInputListeners, canvasBoundsContainer, chartPanComponent) {
super();
this.bus = bus;
this.chartModel = chartModel;
this.scale = scale;
this.canvasInputListeners = canvasInputListeners;
this.canvasBoundsContainer = canvasBoundsContainer;
this.chartPanComponent = chartPanComponent;
this.leftKnotDragStartXRelative = 0;
this.rightKnotDragStartXRelative = 0;
this.lastMousePosition = 0;
this.leftKnotDragStart = (point) => {
const nMapChart = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
this.leftKnotDragStartXRelative = point.x - nMapChart.x - NAV_MAP_KNOT_CORRECTION;
};
this.leftKnotDragTick = (dragInfo) => {
const { delta: xDelta } = dragInfo;
const chart = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
const knotsWindowWidth = chart.width;
const moveLeftRatio = (this.leftKnotDragStartXRelative + xDelta) / knotsWindowWidth;
this.canvasBoundsContainer.leftRatio = moveLeftRatio;
this.scale.setXScale(Math.round(this.chartModel.mainCandleSeries.dataPoints.length * this.canvasBoundsContainer.leftRatio), this.scale.xEnd);
};
this.rightKnotDragStart = (point) => {
const nMapChart = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
this.rightKnotDragStartXRelative = point.x - nMapChart.x + NAV_MAP_KNOT_CORRECTION;
};
this.rightKnotDragTick = (dragInfo) => {
const { delta: xDelta } = dragInfo;
const nMapChart = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
const nMapChartWidth = nMapChart.width;
const moveRightRatio = (this.rightKnotDragStartXRelative + xDelta) / nMapChartWidth;
this.canvasBoundsContainer.rightRatio = moveRightRatio;
this.scale.setXScale(this.scale.xStart, Math.round(this.chartModel.mainCandleSeries.dataPoints.length * this.canvasBoundsContainer.rightRatio));
};
this.sliderDragStart = () => {
this.lastMousePosition = 0;
};
this.sliderDragTick = (dragInfo) => {
const { delta: absoluteXDelta } = dragInfo;
const navMap = this.canvasBoundsContainer.getBounds(CanvasElement.N_MAP_CHART);
const moveMultiplier = this.chartModel.mainCandleSeries.meanCandleWidth /
(navMap.width / this.chartModel.mainCandleSeries.dataPoints.length);
const step = (this.lastMousePosition - absoluteXDelta) * moveMultiplier;
this.scale.moveXStart(this.scale.xStart - step);
this.lastMousePosition = absoluteXDelta;
};
//#region knots
const knotLeftHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_KNOT_L);
const knotRightHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_KNOT_R);
const leftKnotDNDComponent = new DragNDropXComponent(knotLeftHitTest, {
onDragStart: this.leftKnotDragStart,
onDragTick: this.leftKnotDragTick,
}, this.canvasInputListeners, this.chartPanComponent);
const rightKnotDNDComponent = new DragNDropXComponent(knotRightHitTest, {
onDragStart: this.rightKnotDragStart,
onDragTick: this.rightKnotDragTick,
}, this.canvasInputListeners, this.chartPanComponent);
this.addChildEntity(leftKnotDNDComponent);
this.addChildEntity(rightKnotDNDComponent);
//#endregion
//#region slider
const sliderHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_SLIDER_WINDOW);
const sliderDNDComponent = new DragNDropXComponent(sliderHitTest, {
onDragStart: this.sliderDragStart,
onDragTick: this.sliderDragTick,
}, this.canvasInputListeners, this.chartPanComponent);
this.addChildEntity(sliderDNDComponent);
//#endregion
}
/**
* Method that activates the navigation map buttons and subscribes to their click and touch events.
* It also subscribes to the xChanged event of the scaleModel and updates the canvasBoundsContainer accordingly.
* @returns {void}
*/
doActivate() {
super.doActivate();
//#region btns
const btnLeftHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_BTN_L);
this.addRxSubscription(this.canvasInputListeners.observeClick(btnLeftHitTest).subscribe(() => {
this.scale.moveXStart(this.scale.xStart - 1);
}));
this.addRxSubscription(this.canvasInputListeners.observeTouchStart(btnLeftHitTest).subscribe(() => {
this.scale.moveXStart(this.scale.xStart - 1);
}));
const btnRightHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.N_MAP_BTN_R);
this.addRxSubscription(this.canvasInputListeners.observeClick(btnRightHitTest).subscribe(() => {
this.scale.moveXStart(this.scale.xStart + 1);
}));
this.addRxSubscription(this.canvasInputListeners.observeTouchStart(btnRightHitTest).subscribe(() => {
this.scale.moveXStart(this.scale.xStart + 1);
}));
this.addRxSubscription(this.scale.xChanged.subscribe(() => {
const candleSeries = this.chartModel.mainCandleSeries;
this.canvasBoundsContainer.leftRatio = candleSeries.dataIdxStart / (candleSeries.dataPoints.length - 1);
this.canvasBoundsContainer.rightRatio = candleSeries.dataIdxEnd / (candleSeries.dataPoints.length - 1);
this.canvasBoundsContainer.recalculateNavigationMapElementBounds();
this.bus.fireDraw();
}));
//#endregion
}
}