Skip to content

Commit

Permalink
fix: lock price scale behavior when y scale changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Keelaro1 authored and disyakidneyshot committed Jun 21, 2024
1 parent 9ba1f7b commit 1f21d57
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 57 deletions.
3 changes: 0 additions & 3 deletions src/chart/animation/types/viewport-movement-animation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { AnimationConfig } from '../canvas-animation';
import { Unit, ViewportModel, Zoom } from '../../model/scaling/viewport.model';
import { easeExpOut } from '../../utils/math.utils';
import { uuid } from '../../utils/uuid.utils';
import { ratioFromZoomXY } from '../../model/scaling/lock-ratio.model';

export type easingFn = (normalizedTime: number) => number;

Expand Down Expand Up @@ -72,7 +71,6 @@ export class ViewportMovementAnimation extends Animation {
yEnd: newYEnd,
zoomX: newZoomX,
zoomY: newZoomY,
zoomXY: ratioFromZoomXY(newZoomX, newZoomY),
inverseY: this.viewportModel.inverseY,
});
}
Expand All @@ -90,7 +88,6 @@ export class ViewportMovementAnimation extends Animation {
yEnd: this.animationConfig.targetYEnd,
zoomX: this.animationConfig.targetZoomX,
zoomY: this.animationConfig.targetZoomY,
zoomXY: ratioFromZoomXY(this.animationConfig.targetZoomX, this.animationConfig.targetZoomY),
inverseY: this.viewportModel.inverseY,
});
}
Expand Down
3 changes: 0 additions & 3 deletions src/chart/components/chart/basic-scale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@ import { ChartModel } from './chart.model';
*/
export const createBasicScaleViewportTransformer = (scale: ScaleModel) => (visualCandleSource: VisualCandle[]) => {
if (visualCandleSource.length !== 0) {
const state = scale.export();

const vCandles = visualCandleSource.slice(
Math.max(visualCandleSource.length - scale.state.defaultViewportItems, 0),
);
const startCandle = vCandles[0];
const endCandle = vCandles[vCandles.length - 1];
scale.setXScale(startCandle.startUnit, endCandle.startUnit + endCandle.width + scale.offsets.right);
scale.doAutoScale(true);
scale.recalculateZoomXYRatio(state);
scale.fireChanged();
}
};
Expand Down
44 changes: 16 additions & 28 deletions src/chart/model/scale.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CanvasAnimation } from '../animation/canvas-animation';
import { startViewportModelAnimation } from '../animation/viewport-model-animation';
import { cloneUnsafe } from '../utils/object.utils';
import { AutoScaleViewportSubModel } from './scaling/auto-scale.model';
import { changeXToKeepRatio, changeYToKeepRatio, ratioFromZoomXY } from './scaling/lock-ratio.model';
import { changeXToKeepRatio, changeYToKeepRatio } from './scaling/lock-ratio.model';
import { moveXStart, moveYStart } from './scaling/move-chart.functions';
import {
Price,
Expand Down Expand Up @@ -230,7 +230,7 @@ export class ScaleModel extends ViewportModel {
* @param fireChanged
* @param forceNoAutoScale - force NOT apply auto-scaling (for lazy loading)
*/
public setXScale(xStart: Unit, xEnd: Unit, forceNoAnimation: boolean = true, forceUpdateY = true) {
public setXScale(xStart: Unit, xEnd: Unit, forceNoAnimation: boolean = true) {
const initialState = this.export();
const zoomX = this.calculateZoomX(xStart, xEnd);
if (initialState.xStart === xStart && initialState.xEnd === xEnd && initialState.zoomX > 0) {
Expand All @@ -244,7 +244,7 @@ export class ScaleModel extends ViewportModel {
return;
}

if (this.state.lockPriceToBarRatio && forceUpdateY) {
if (this.state.lockPriceToBarRatio) {
changeYToKeepRatio(initialState, constrainedState);
}
if (this.state.auto) {
Expand All @@ -265,13 +265,21 @@ export class ScaleModel extends ViewportModel {
}

if (this.state.lockPriceToBarRatio) {
this.setLockPriceScale(yStart, yEnd, fire, initialState);
this.setLockedYScale(yStart, yEnd, fire, initialState);
return;
}
this.setYScaleCommon(yStart, yEnd, fire, initialState);

super.setYScale(yStart, yEnd, fire);
const state = this.export();
const constrainedState = this.scalePostProcessor(initialState, state);
if (this.state.auto) {
this.autoScaleModel.doAutoYScale(constrainedState);
}

this.apply(constrainedState);
}

private setLockPriceScale(yStart: Unit, yEnd: Unit, fire = false, initialState: ViewportModelState) {
private setLockedYScale(yStart: Unit, yEnd: Unit, fire = false, initialState: ViewportModelState) {
const zoomIn = yEnd < initialState.yEnd;
if ((this.zoomReached.min && zoomIn === false) || (this.zoomReached.max && zoomIn === true)) {
return;
Expand All @@ -283,19 +291,8 @@ export class ScaleModel extends ViewportModel {

changeXToKeepRatio(initialState, constrainedState);
this.zoomReached = this.calculateZoomReached(constrainedState.zoomX, zoomIn);
this.setXScale(constrainedState.xStart, constrainedState.xEnd, true, false);
this.fireChanged();
}

private setYScaleCommon(yStart: Unit, yEnd: Unit, fire = false, initialState: ViewportModelState) {
super.setYScale(yStart, yEnd, fire);
const state = this.export();
const constrainedState = this.scalePostProcessor(initialState, state);
if (this.state.auto) {
this.autoScaleModel.doAutoYScale(constrainedState);
}

this.apply(constrainedState);
this.fireChanged();
}

/**
Expand Down Expand Up @@ -440,18 +437,9 @@ export class ScaleModel extends ViewportModel {
this.state.lockPriceToBarRatio = false;
return;
}
if (value) {
const state = this.export();
this.recalculateZoomXYRatio(state);
}

this.state.lockPriceToBarRatio = value;
}
/**
* Recalculates the zoom X/Y ratio based on the current zoom levels.
*/
public recalculateZoomXYRatio(state: ViewportModelState) {
state.zoomXY = ratioFromZoomXY(state.zoomX, state.zoomY);
}
}

/**
Expand Down
14 changes: 4 additions & 10 deletions src/chart/model/scaling/lock-ratio.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export const zoomYToZoomX = (zoomY: Zoom, ratio: ZoomXToZoomYRatio): Zoom => zoo

/**
* Locks the zoomY with zoomX and zooms y-scale depending on x-scale.
* @param state
* @param zoomXYRatio
* @param prevState
* @param newState
*/
export const changeYToKeepRatio = (prevState: ViewportModelState, newState: ViewportModelState) => {
const prevZoomX = prevState.zoomX;
Expand All @@ -28,15 +28,12 @@ export const changeYToKeepRatio = (prevState: ViewportModelState, newState: View
const delta = newYHeight - prevYHeight;
newState.yEnd = newState.yEnd + delta / 2;
newState.yStart = newState.yStart - delta / 2;
// recalculate zoomXY ratio
const newZoomXY = ratioFromZoomXY(newState.zoomX, newState.zoomY);
newState.zoomXY = newZoomXY;
};

/**
* Locks the zoomY with zoomX and zooms x-scale depending on y-scale.
* @param state
* @param zoomXYRatio
* @param prevState
* @param newState
*/
export const changeXToKeepRatio = (prevState: ViewportModelState, newState: ViewportModelState) => {
const prevZoomX = prevState.zoomX;
Expand All @@ -49,7 +46,4 @@ export const changeXToKeepRatio = (prevState: ViewportModelState, newState: View
const newXWidth = prevXWidth * zoomXMult;
const delta = newXWidth - prevXWidth;
newState.xStart = newState.xStart - delta;
// recalculate zoomXY ratio
const newZoomXY = ratioFromZoomXY(newState.zoomX, newState.zoomY);
newState.zoomXY = newZoomXY;
};
21 changes: 8 additions & 13 deletions src/chart/model/scaling/viewport.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { ChartBaseElement } from '../chart-base-element';
import { ViewportMovementAnimation } from '../../animation/types/viewport-movement-animation';
import { keys } from '../../utils/object.utils';
import { Bounds } from '../bounds.model';
import { ZoomXToZoomYRatio } from './lock-ratio.model';

// Basic:
// ---------
Expand Down Expand Up @@ -101,7 +100,6 @@ export interface ViewportModelState {
yEnd: Unit;
zoomX: Zoom;
zoomY: Zoom;
zoomXY: ZoomXToZoomYRatio;
inverseY: boolean;
}

Expand All @@ -126,7 +124,6 @@ export abstract class ViewportModel extends ChartBaseElement implements Viewable
private _yEnd: Unit = 0;
private _zoomX: Zoom = 1;
private _zoomY: Zoom = 1;
private _zoomXY: ZoomXToZoomYRatio = 0;
//endregion
// toggle Y inverse mode
private _inverseY: boolean = false;
Expand Down Expand Up @@ -327,7 +324,6 @@ export abstract class ViewportModel extends ChartBaseElement implements Viewable
yEnd: this.yEnd,
zoomX: this.zoomX,
zoomY: this.zoomY,
zoomXY: this.zoomXY,
inverseY: this.inverseY,
};
}
Expand Down Expand Up @@ -407,14 +403,6 @@ export abstract class ViewportModel extends ChartBaseElement implements Viewable
this._zoomY = value;
}

get zoomXY(): ZoomXToZoomYRatio {
return this._zoomXY;
}

set zoomXY(value: ZoomXToZoomYRatio) {
this._zoomXY = value;
}

get inverseY(): boolean {
return this._inverseY;
}
Expand All @@ -429,7 +417,14 @@ export abstract class ViewportModel extends ChartBaseElement implements Viewable
* @returns {boolean} - Returns true if the viewport is valid, false otherwise.
*/
isViewportValid() {
return this.xStart !== this.xEnd && this.yStart !== this.yEnd && isFinite(this.yStart) && isFinite(this.yEnd) && this.zoomX > 0 && this.zoomY > 0;
return (
this.xStart !== this.xEnd &&
this.yStart !== this.yEnd &&
isFinite(this.yStart) &&
isFinite(this.yEnd) &&
this.zoomX > 0 &&
this.zoomY > 0
);
}
}

Expand Down

0 comments on commit 1f21d57

Please sign in to comment.