UNPKG

@devexperts/dxcharts-lite

Version:
119 lines (118 loc) 5.24 kB
/* * 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 { binarySearch } from '../utils/array.utils'; import { calcLogValue, logValueToUnit, percentToUnit, unitToPercent, } from './scaling/viewport.model'; class PercentScaleAnimationHandler { constructor(scale, dataSeries) { this.scale = scale; this.dataSeries = dataSeries; this.prevAnimationId = ''; } /** * This logic calculates correct baseline helping avoid shaking during zoom animation * @param getBaseline * @returns */ getBaselineForPercent(getBaseline) { const animation = this.scale.currentAnimation; let baseline; if (animation === null || animation === void 0 ? void 0 : animation.animationInProgress) { if (animation.id !== this.prevAnimationId) { this.initialBaseline = undefined; this.targetBaseline = undefined; this.prevAnimationId = animation.id; } const easedProgress = animation.easingFn(animation.getProgress()); if (this.initialBaseline === undefined) { this.initialBaseline = getBaseline(binarySearch(this.dataSeries.visualPoints, animation.xStart, i => i.centerUnit).index); } if (this.targetBaseline === undefined) { this.targetBaseline = getBaseline(binarySearch(this.dataSeries.visualPoints, animation.animationConfig.targetXStart, i => i.centerUnit).index); } baseline = this.initialBaseline + (this.targetBaseline - this.initialBaseline) * easedProgress; } else { baseline = getBaseline(); } return baseline; } } /** * A class representing a view for a data series chart. * It contains methods to convert between price values and pixel coordinates using the selected scale model, * as well as between price values and units based on the selected price type and axis type. */ export class DataSeriesView { constructor(dataSeries, scale, getAxisType, getBaseline) { this.dataSeries = dataSeries; this.scale = scale; this.getAxisType = getAxisType; this.getBaseline = getBaseline; /** * Convert the input value to its corresponding y-pixel coordinate based on the selected price type and scale model. * @param value - The value to be converted to y-pixel coordinate. * @returns - The converted value in y-pixel coordinate. */ this.toY = (value) => { return this.scale.toY(this.toAxisUnits(value)); }; /** * Convert the input unit to its corresponding x-pixel coordinate based on the scale model. * @param unit - The unit to be converted to x-pixel coordinate. * @returns - The converted value in x-pixel coordinate. */ this.toX = (unit) => this.scale.toX(unit); this.xPixels = (unit) => this.scale.xPixels(unit); /** * Pay attention! This method doesn't convert price to pixels, it converts only current axis UNITs! * @param unit */ this.yPixels = (unit) => this.scale.yPixels(unit); this.percentAnimationHandler = new PercentScaleAnimationHandler(this.scale, this.dataSeries); } /** * Convert the input value to the corresponding unit based on the current axis type. * @param value - The value to be converted to unit. * @param getBaseline - A function that returns the baseline for percent. * @returns - The converted value in the corresponding unit. */ toAxisUnits(value, getBaseline = this.getBaseline) { switch (this.getAxisType()) { case 'percent': const baseline = this.percentAnimationHandler.getBaselineForPercent(getBaseline); return unitToPercent(value, baseline); case 'logarithmic': // TODO: temporary fix for dataseries with negative values, think about the requirements for these cases // should probably not allow to switch to log values at all, or just keep it as it is return value <= 0 ? value : calcLogValue(value); case 'regular': return value; } } /** * Converts "y" in pixels to price * @param y - source value in pixels */ priceFromY(y) { const unit = this.scale.fromY(y); return this.fromAxisUnits(unit); } /** * Convert the input unit to its corresponding price value based on the selected axis type. * @param {number} unit - The unit to be converted to price value. * @returns {number} - The converted value in price. */ fromAxisUnits(unit) { switch (this.getAxisType()) { case 'percent': return percentToUnit(unit, this.getBaseline()); case 'logarithmic': return logValueToUnit(unit); case 'regular': return unit; } } }