@devexperts/dxcharts-lite
Version:
119 lines (118 loc) • 5.24 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 { 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;
}
}
}