diff --git a/src/Chart.ts b/src/Chart.ts index 024f4ce54..c3de7cbdc 100644 --- a/src/Chart.ts +++ b/src/Chart.ts @@ -26,6 +26,7 @@ import type LoadMoreCallback from './common/LoadMoreCallback' import type LoadDataCallback from './common/LoadDataCallback' import type Precision from './common/Precision' import type VisibleRange from './common/VisibleRange' +import { type CustomApi, LayoutChildType, type Options } from './Options' import { createId } from './common/utils/id' import { createDom } from './common/utils/dom' @@ -36,6 +37,7 @@ import { binarySearchNearest } from './common/utils/number' import { LoadDataType } from './common/LoadDataCallback' import ChartStore from './store/ChartStore' +import { SCALE_MULTIPLIER } from './store/TimeScaleStore' import CandlePane from './pane/CandlePane' import IndicatorPane from './pane/IndicatorPane' @@ -55,8 +57,6 @@ import { getStyles as getExtensionStyles } from './extension/styles/index' import Event from './Event' -import { type CustomApi, LayoutChildType, type Options } from './Options' - export enum DomPosition { Root = 'root', Main = 'main', @@ -905,17 +905,19 @@ export default class ChartImp implements Chart { const timeScaleStore = this._chartStore.getTimeScaleStore() if (duration > 0) { const { bar: barSpace } = timeScaleStore.getBarSpace() - const scaleDataSpace = barSpace * scale - const difSpace = scaleDataSpace - barSpace + const scaleBarSpace = barSpace * scale + const difSpace = scaleBarSpace - barSpace const startTime = new Date().getTime() - let preScale = 0 + let prevProgressBarSpace = 0 + const animation: (() => void) = () => { const progress = (new Date().getTime() - startTime) / duration + const progressBarSpace = difSpace * progress const finished = progress >= 1 const progressDataSpace = finished ? difSpace : difSpace * progress - const scale = progressDataSpace / barSpace - timeScaleStore.zoom(scale - preScale, coordinate) - preScale = scale + const scale = (progressDataSpace - prevProgressBarSpace) / timeScaleStore.getBarSpace().bar * SCALE_MULTIPLIER + timeScaleStore.zoom(scale, coordinate) + prevProgressBarSpace = progressBarSpace if (!finished) { requestAnimationFrame(animation) } diff --git a/src/store/TimeScaleStore.ts b/src/store/TimeScaleStore.ts index f0a0dd886..f87244261 100644 --- a/src/store/TimeScaleStore.ts +++ b/src/store/TimeScaleStore.ts @@ -46,6 +46,10 @@ const DEFAULT_BAR_SPACE = 8 const DEFAULT_OFFSET_RIGHT_DISTANCE = 80 +const GAP_BAR_SPACE_RATIO = 0.88 + +export const SCALE_MULTIPLIER = 10 + export default class TimeScaleStore { /** * Root store @@ -126,7 +130,7 @@ export default class TimeScaleStore { private _calcGapBarSpace (): number { let gapBarSpace: number if (this._barSpace > 3) { - gapBarSpace = Math.floor(this._barSpace * 0.88) + gapBarSpace = Math.floor(this._barSpace * GAP_BAR_SPACE_RATIO) } else { gapBarSpace = Math.floor(this._barSpace) if (gapBarSpace === this._barSpace) { @@ -338,11 +342,17 @@ export default class TimeScaleStore { return } const distanceBarCount = distance / this._barSpace - this._chartStore.getActionStore().execute(ActionType.OnScroll) + const prevLastBarRightSideDistance = this._lastBarRightSideDiffBarCount * this._barSpace this._lastBarRightSideDiffBarCount = this._startLastBarRightSideDiffBarCount - distanceBarCount this.adjustVisibleRange() this._chartStore.getTooltipStore().recalculateCrosshair(true) this._chartStore.getChart().adjustPaneViewport(false, true, true, true) + const realDistance = Math.round( + this._lastBarRightSideDiffBarCount * this._barSpace - prevLastBarRightSideDistance + ) + if (realDistance !== 0) { + this._chartStore.getActionStore().execute(ActionType.OnScroll, { distance: realDistance }) + } } getDataByDataIndex (dataIndex: number): Nullable { @@ -389,13 +399,17 @@ export default class TimeScaleStore { const crosshair = this._chartStore.getTooltipStore().getCrosshair() zoomCoordinate = { x: crosshair?.x ?? this._totalBarSpace / 2 } } - this._chartStore.getActionStore().execute(ActionType.OnZoom) const x = zoomCoordinate!.x! const floatIndex = this.coordinateToFloatIndex(x) - const barSpace = this._barSpace + scale * (this._barSpace / 10) + const prevBarSpace = this._barSpace + const barSpace = this._barSpace + scale * (this._barSpace / SCALE_MULTIPLIER) this.setBarSpace(barSpace, () => { this._lastBarRightSideDiffBarCount += (floatIndex - this.coordinateToFloatIndex(x)) }) + const realScale = this._barSpace / prevBarSpace + if (realScale !== 1) { + this._chartStore.getActionStore().execute(ActionType.OnZoom, { scale: realScale }) + } } setZoomEnabled (enabled: boolean): this {