From b44c1016c9671289ef28a34f3c60e690d473caf4 Mon Sep 17 00:00:00 2001 From: liihuu Date: Sat, 11 Nov 2023 05:51:05 +0800 Subject: [PATCH] impr: modify internal data structure --- src/Chart.ts | 294 +++++++++++++++++-------------- src/Event.ts | 5 +- src/component/YAxis.ts | 4 +- src/pane/CandlePane.ts | 6 - src/pane/IndicatorPane.ts | 6 - src/pane/Pane.ts | 2 - src/pane/SeparatorPane.ts | 31 ++-- src/pane/XAxisPane.ts | 5 - src/pane/types.ts | 7 - src/view/GridView.ts | 6 +- src/view/IndicatorTooltipView.ts | 5 +- src/view/IndicatorView.ts | 6 +- src/view/OverlayView.ts | 4 +- src/widget/SeparatorWidget.ts | 24 +-- 14 files changed, 199 insertions(+), 206 deletions(-) diff --git a/src/Chart.ts b/src/Chart.ts index 10c8d0c94..d7a5fc35c 100644 --- a/src/Chart.ts +++ b/src/Chart.ts @@ -40,7 +40,8 @@ import ChartStore from './store/ChartStore' import CandlePane from './pane/CandlePane' import IndicatorPane from './pane/IndicatorPane' import XAxisPane from './pane/XAxisPane' -import { PaneOptions, PanePosition, PANE_DEFAULT_HEIGHT, PaneIdConstants, PaneNameConstants } from './pane/types' +import DrawPane from './pane/DrawPane' +import { PaneOptions, PanePosition, PANE_DEFAULT_HEIGHT, PaneIdConstants } from './pane/types' import Axis from './component/Axis' @@ -53,7 +54,6 @@ import { getStyles as getExtensionStyles } from './extension/styles/index' import Event from './Event' import { CustomApi, LayoutChildType, Options } from './Options' -import DrawPane from './pane/DrawPane' import SeparatorPane from './pane/SeparatorPane' export enum DomPosition { @@ -128,8 +128,9 @@ export default class ChartImp implements Chart { private _chartContainer: HTMLElement private readonly _chartEvent: Event private readonly _chartStore: ChartStore - private readonly _drawPanes: Map = new Map() - private readonly _elementPanes: Map = new Map() + private _drawPanes: DrawPane[] = [] + private _candlePane: CandlePane + private _xAxisPane: XAxisPane private readonly _separatorPanes: Map = new Map() constructor (container: HTMLElement, options?: Options) { @@ -167,15 +168,8 @@ export default class ChartImp implements Chart { const createXAxisPane: ((ops?: PaneOptions) => void) = (ops?: PaneOptions) => { if (!xAxisPaneInitialized) { - const pane = new XAxisPane( - this._chartContainer, - this._getInsertElement(ops?.position), - this, - PaneIdConstants.X_AXIS - ) - pane.setOptions(ops ?? {}) - this._drawPanes.set(PaneIdConstants.X_AXIS, pane) - this._elementPanes.set(pane.getContainer(), pane) + const pane = this._createPane(XAxisPane, PaneIdConstants.X_AXIS, ops ?? {}) + this._xAxisPane = pane xAxisPaneInitialized = true } } @@ -186,15 +180,8 @@ export default class ChartImp implements Chart { if (!candlePaneInitialized) { const paneOptions = child.options ?? {} merge(paneOptions, { id: PaneIdConstants.CANDLE }) - const pane = new CandlePane( - this._chartContainer, - this._getInsertElement(paneOptions.position), - this, - PaneIdConstants.CANDLE - ) - this._createSeparatorPane(pane) - this._drawPanes.set(PaneIdConstants.CANDLE, pane) - this._elementPanes.set(pane.getContainer(), pane) + const pane = this._createPane(CandlePane, PaneIdConstants.CANDLE, paneOptions) + this._candlePane = pane const content = child.content ?? [] content.forEach(v => { this.createIndicator(v, true, paneOptions) @@ -225,54 +212,84 @@ export default class ChartImp implements Chart { createXAxisPane({ position: PanePosition.Bottom }) } - private _createSeparatorPane (bottomPane: DrawPane): void { - const panes = Array.from(this._drawPanes.values()) - let topPane = panes[panes.length - 1] - if (isValid(topPane)) { - if (topPane.getName() === PaneNameConstants.X_AXIS) { - topPane = panes[panes.length - 2] - } - } - if (isValid(topPane)) { - const pane = new SeparatorPane(this._chartContainer, bottomPane.getContainer(), this, '', topPane, bottomPane) - this._separatorPanes.set(bottomPane, pane) - } - } - - private _getInsertElement (position?: PanePosition): Nullable { + private _createPane

( + DrawPaneClass: new (rootContainer: HTMLElement, afterElement: Nullable, chart: Chart, id: string) => P, + id: string, + options?: PaneOptions + ): P { + let index + let pane + const position = options?.position switch (position) { case PanePosition.Top: { - const panes = Array.from(this._drawPanes.values()) - const firstPane = panes[0] + const firstPane = this._drawPanes[0] if (isValid(firstPane)) { - return firstPane.getContainer() + pane = new DrawPaneClass(this._chartContainer, firstPane.getContainer(), this, id) + index = 0 } - return null + break } - case PanePosition.Bottom: { return null } + case PanePosition.Bottom: { break } default: { - const children = this._chartContainer.children - for (let i = children.length - 1; i > -1; i--) { - const child = children[i] - const prevChild = children[i - 1] - const pane = this._elementPanes.get(child) - const prevPane = this._elementPanes.get(prevChild) + for (let i = this._drawPanes.length - 1; i > -1; i--) { + const p = this._drawPanes[i] + const prevP = this._drawPanes[i - 1] if ( - pane?.getOptions().position === PanePosition.Bottom && - prevPane?.getOptions().position !== PanePosition.Bottom + p?.getOptions().position === PanePosition.Bottom && + prevP?.getOptions().position !== PanePosition.Bottom ) { - return pane.getContainer() + pane = new DrawPaneClass(this._chartContainer, p.getContainer(), this, id) + index = i } } - return null } } + if (!isValid(pane)) { + pane = new DrawPaneClass(this._chartContainer, null, this, id) + } + pane.setOptions(options ?? {}) + let newIndex: number + if (isValid(index)) { + this._drawPanes.splice(index, 0, pane) + newIndex = index + } else { + this._drawPanes.push(pane) + newIndex = this._drawPanes.length - 1 + } + if (pane.getId() !== PaneIdConstants.X_AXIS) { + let nextPane = this._drawPanes[newIndex + 1] + if (isValid(nextPane)) { + if (nextPane.getId() === PaneIdConstants.X_AXIS) { + nextPane = this._drawPanes[newIndex + 2] + } + } + if (isValid(nextPane)) { + let separatorPane = this._separatorPanes.get(nextPane) + if (isValid(separatorPane)) { + separatorPane.setTopPane(pane) + } else { + separatorPane = new SeparatorPane(this._chartContainer, nextPane.getContainer(), this, '', pane, nextPane) + this._separatorPanes.set(nextPane, separatorPane) + } + } + let prevPane = this._drawPanes[newIndex - 1] + if (isValid(prevPane)) { + if (prevPane.getId() === PaneIdConstants.X_AXIS) { + prevPane = this._drawPanes[newIndex - 2] + } + } + if (isValid(prevPane)) { + const separatorPane = new SeparatorPane(this._chartContainer, pane.getContainer(), this, '', prevPane, pane) + this._separatorPanes.set(pane, separatorPane) + } + } + return pane } private _measurePaneHeight (): void { const totalHeight = this._container.offsetHeight const separatorSize = this._chartStore.getStyles().separator.size - const xAxisHeight = this._drawPanes.get(PaneIdConstants.X_AXIS)?.getAxisComponent().getAutoSize() ?? 0 + const xAxisHeight = this._xAxisPane.getAxisComponent().getAutoSize() let paneExcludeXAxisHeight = totalHeight - xAxisHeight - this._separatorPanes.size * separatorSize if (paneExcludeXAxisHeight < 0) { paneExcludeXAxisHeight = 0 @@ -295,26 +312,20 @@ export default class ChartImp implements Chart { pane.setBounding({ height: paneHeight }) } }) - const candlePaneHeight = paneExcludeXAxisHeight - indicatorPaneTotalHeight - this._drawPanes.get(PaneIdConstants.CANDLE)?.setBounding({ height: candlePaneHeight }) - this._drawPanes.get(PaneIdConstants.X_AXIS)?.setBounding({ height: xAxisHeight }) + this._candlePane?.setBounding({ height: candlePaneHeight }) + this._xAxisPane.setBounding({ height: xAxisHeight }) let top = 0 - const children = this._chartContainer.children - - for (let i = 0; i < children.length; i++) { - const pane = this._elementPanes.get(children[i]) - if (isValid(pane)) { - const separatorPane = this._separatorPanes.get(pane) - if (isValid(separatorPane)) { - separatorPane.setBounding({ height: separatorSize, top }) - top += separatorSize - } - pane.setBounding({ top }) - top += pane.getBounding().height + this._drawPanes.forEach(pane => { + const separatorPane = this._separatorPanes.get(pane) + if (isValid(separatorPane)) { + separatorPane.setBounding({ height: separatorSize, top }) + top += separatorSize } - } + pane.setBounding({ top }) + top += pane.getBounding().height + }) } private _measurePaneWidth (): void { @@ -359,36 +370,60 @@ export default class ChartImp implements Chart { const paneBounding = { width: totalWidth } const mainBounding = { width: mainWidth, left: mainLeft } const yAxisBounding = { width: yAxisWidth, left: yAxisLeft } + const separatorFill = styles.separator.fill + let separatorBounding + if (isOutside && !separatorFill) { + separatorBounding = mainBounding + } else { + separatorBounding = paneBounding + } this._drawPanes.forEach((pane) => { - this._separatorPanes.get(pane)?.setBounding(paneBounding) + this._separatorPanes.get(pane)?.setBounding(separatorBounding) pane.setBounding(paneBounding, mainBounding, yAxisBounding) }) } private _setPaneOptions (options: PaneOptions, forceShouldAdjust: boolean): void { - const pane = this._drawPanes.get(options?.id ?? '') - let shouldMeasureHeight = false - if (pane !== undefined) { - let shouldAdjust = forceShouldAdjust - if (options.id !== PaneIdConstants.CANDLE && options.height !== undefined && options.height > 0) { - const minHeight = Math.max(options.minHeight ?? pane.getOptions().minHeight, 0) - const height = Math.max(minHeight, options.height) - pane.setBounding({ height }) - shouldAdjust = true - shouldMeasureHeight = true - } - pane.setOptions(options) - if (shouldAdjust) { - this.adjustPaneViewport(shouldMeasureHeight, true, true, true, true) + if (isString(options.id)) { + const pane = this.getDrawPaneById(options.id) + let shouldMeasureHeight = false + if (pane !== null) { + let shouldAdjust = forceShouldAdjust + if (options.id !== PaneIdConstants.CANDLE && options.height !== undefined && options.height > 0) { + const minHeight = Math.max(options.minHeight ?? pane.getOptions().minHeight, 0) + const height = Math.max(minHeight, options.height) + pane.setBounding({ height }) + shouldAdjust = true + shouldMeasureHeight = true + } + pane.setOptions(options) + if (shouldAdjust) { + this.adjustPaneViewport(shouldMeasureHeight, true, true, true, true) + } } } } + getDrawPaneById (paneId: string): Nullable> { + if (paneId === PaneIdConstants.CANDLE) { + return this._candlePane + } + if (paneId === PaneIdConstants.X_AXIS) { + return this._xAxisPane + } + const pane = this._drawPanes.find(p => p.getId() === paneId) + return pane ?? null + } + getContainer (): HTMLElement { return this._container } getChartStore (): ChartStore { return this._chartStore } - getAllDrawPanes (): Map { return this._drawPanes } + getCandlePane (): CandlePane { return this._candlePane } + + getXAxisPane (): XAxisPane { return this._xAxisPane } + + getAllDrawPanes (): DrawPane[] { return this._drawPanes } getAllSeparatorPanes (): Map { return this._separatorPanes } @@ -417,14 +452,15 @@ export default class ChartImp implements Chart { this._measurePaneWidth() } if (shouldUpdate ?? false) { - this._drawPanes.get(PaneIdConstants.X_AXIS)?.getAxisComponent().buildTicks(true) + this._xAxisPane.getAxisComponent().buildTicks(true) this.updatePane(UpdateLevel.All) } } updatePane (level: UpdateLevel, paneId?: string): void { - if (paneId !== undefined) { - this.getDrawPaneById(paneId)?.update(level) + if (isValid(paneId)) { + const pane = this.getDrawPaneById(paneId) + pane?.update(level) } else { this._separatorPanes.forEach(pane => { pane.update(level) @@ -435,15 +471,12 @@ export default class ChartImp implements Chart { } } - getDrawPaneById (paneId: string): Nullable> { - return this._drawPanes.get(paneId) ?? null - } - crosshairChange (crosshair: Crosshair): void { const actionStore = this._chartStore.getActionStore() if (actionStore.has(ActionType.OnCrosshairChange)) { const indicatorData = {} - this._drawPanes.forEach((_, id) => { + this._drawPanes.forEach(pane => { + const id = pane.getId() const paneIndicatorData = {} const indicators = this._chartStore.getIndicatorStore().getInstances(id) indicators.forEach(indicator => { @@ -462,7 +495,7 @@ export default class ChartImp implements Chart { } getDom (paneId?: string, position?: DomPosition): Nullable { - if (paneId !== undefined) { + if (isValid(paneId)) { const pane = this.getDrawPaneById(paneId) if (pane !== null) { const pos = position ?? DomPosition.Root @@ -485,7 +518,7 @@ export default class ChartImp implements Chart { } getSize (paneId?: string, position?: DomPosition): Nullable { - if (paneId !== undefined) { + if (isValid(paneId)) { const pane = this.getDrawPaneById(paneId) if (pane !== null) { const pos = position ?? DomPosition.Root @@ -522,8 +555,8 @@ export default class ChartImp implements Chart { } else { realStyles = styles } - if (realStyles?.yAxis?.type !== undefined) { - this.getDrawPaneById(PaneIdConstants.CANDLE)?.getAxisComponent().setAutoCalcTickFlag(true) + if (isValid(realStyles?.yAxis?.type)) { + this._candlePane?.getAxisComponent().setAutoCalcTickFlag(true) } this.adjustPaneViewport(true, true, true, true, true) } @@ -556,9 +589,8 @@ export default class ChartImp implements Chart { setTimezone (timezone: string): void { this._chartStore.setOptions({ timezone }) - const xAxisPane = this._drawPanes.get(PaneIdConstants.X_AXIS) - xAxisPane?.getAxisComponent().buildTicks(true) - xAxisPane?.update(UpdateLevel.Drawer) + this._xAxisPane.getAxisComponent().buildTicks(true) + this._xAxisPane.update(UpdateLevel.Drawer) } getTimezone (): string { @@ -662,34 +694,23 @@ export default class ChartImp implements Chart { return null } - let paneId: string - if (isValid(paneOptions) && isString(paneOptions?.id) && this._drawPanes.has(paneOptions.id)) { - paneId = paneOptions.id - this._chartStore.getIndicatorStore().addInstance(indicator, paneId, isStack ?? false).then(_ => { - this._setPaneOptions(paneOptions, this._drawPanes.get(paneId)?.getAxisComponent().buildTicks(true) ?? false) + let paneId = paneOptions?.id + const currentPane = this.getDrawPaneById(paneId ?? '') + if (currentPane !== null) { + this._chartStore.getIndicatorStore().addInstance(indicator, paneId ?? '', isStack ?? false).then(_ => { + this._setPaneOptions(paneOptions ?? {}, currentPane.getAxisComponent().buildTicks(true) ?? false) }).catch(_ => {}) } else { - paneId = paneOptions?.id ?? createId(PaneIdConstants.INDICATOR) - const pane = new IndicatorPane( - this._chartContainer, - this._getInsertElement(paneOptions?.position), - this, - paneId - ) - this._createSeparatorPane(pane) + paneId ??= createId(PaneIdConstants.INDICATOR) + const pane = this._createPane(IndicatorPane, paneId, paneOptions ?? {}) const height = paneOptions?.height ?? PANE_DEFAULT_HEIGHT pane.setBounding({ height }) - if (isValid(paneOptions)) { - pane.setOptions(paneOptions) - } - this._drawPanes.set(paneId, pane) - this._elementPanes.set(pane.getContainer(), pane) this._chartStore.getIndicatorStore().addInstance(indicator, paneId, isStack ?? false).finally(() => { this.adjustPaneViewport(true, true, true, true, true) callback?.() }) } - return paneId + return paneId ?? null } overrideIndicator (override: IndicatorCreate, paneId?: Nullable, callback?: () => void): void { @@ -714,8 +735,9 @@ export default class ChartImp implements Chart { let shouldMeasureHeight = false if (paneId !== PaneIdConstants.CANDLE) { if (!indicatorStore.hasInstances(paneId)) { - const pane = this._drawPanes.get(paneId) - if (isValid(pane)) { + const pane = this.getDrawPaneById(paneId) + const index = this._drawPanes.findIndex(p => p.getId() === paneId) + if (pane !== null) { shouldMeasureHeight = true const separatorPane = this._separatorPanes.get(pane) if (isValid(separatorPane)) { @@ -729,9 +751,17 @@ export default class ChartImp implements Chart { separatorPane.destroy() this._separatorPanes.delete(pane) } - this._drawPanes.delete(paneId) - this._elementPanes.delete(pane.getContainer()) + this._drawPanes.splice(index, 1) pane.destroy() + + let firstPane = this._drawPanes[0] + if (isValid(firstPane)) { + if (firstPane.getId() === PaneIdConstants.X_AXIS) { + firstPane = this._drawPanes[1] + } + } + this._separatorPanes.get(firstPane)?.destroy() + this._separatorPanes.delete(firstPane) } } } @@ -755,7 +785,7 @@ export default class ChartImp implements Chart { overlays = [overlay] } let appointPaneFlag = true - if (paneId === undefined || this.getDrawPaneById(paneId) === null) { + if (!isValid(paneId) || this.getDrawPaneById(paneId) === null) { paneId = PaneIdConstants.CANDLE appointPaneFlag = false } @@ -891,7 +921,7 @@ export default class ChartImp implements Chart { const timeScaleStore = this._chartStore.getTimeScaleStore() const bounding = pane.getBounding() const ps = new Array>().concat(points) - const xAxis = this._drawPanes.get(PaneIdConstants.X_AXIS)?.getAxisComponent() + const xAxis = this._xAxisPane.getAxisComponent() const yAxis = pane.getAxisComponent() coordinates = ps.map(point => { const coordinate: Partial = {} @@ -922,7 +952,7 @@ export default class ChartImp implements Chart { const timeScaleStore = this._chartStore.getTimeScaleStore() const bounding = pane.getBounding() const cs = new Array>().concat(coordinates) - const xAxis = this._drawPanes.get(PaneIdConstants.X_AXIS)?.getAxisComponent() + const xAxis = this._xAxisPane.getAxisComponent() const yAxis = pane.getAxisComponent() points = cs.map(coordinate => { const point: Partial = {} @@ -979,6 +1009,15 @@ export default class ChartImp implements Chart { ctx.fillRect(0, 0, width, height) const overlayFlag = includeOverlay ?? false this._drawPanes.forEach(pane => { + const separatorPane = this._separatorPanes.get(pane) + if (isValid(separatorPane)) { + const separatorBounding = separatorPane.getBounding() + ctx.drawImage( + separatorPane.getImage(overlayFlag), + separatorBounding.left, separatorBounding.top, separatorBounding.width, separatorBounding.height + ) + } + const bounding = pane.getBounding() ctx.drawImage( pane.getImage(overlayFlag), @@ -997,8 +1036,7 @@ export default class ChartImp implements Chart { this._drawPanes.forEach(pane => { pane.destroy() }) - this._drawPanes.clear() - this._elementPanes.clear() + this._drawPanes = [] this._container.removeChild(this._chartContainer) } } diff --git a/src/Event.ts b/src/Event.ts index 2bc3588e1..a24751c94 100644 --- a/src/Event.ts +++ b/src/Event.ts @@ -16,7 +16,6 @@ import Nullable from './common/Nullable' import SyntheticEvent, { EventHandler, MouseTouchEvent, TOUCH_MIN_RADIUS } from './common/SyntheticEvent' import Coordinate from './common/Coordinate' import { UpdateLevel } from './common/Updater' -import Bounding from './common/Bounding' import Crosshair from './common/Crosshair' import { requestAnimationFrame, cancelAnimationFrame } from './common/utils/compatible' @@ -143,7 +142,7 @@ export default class Event implements EventHandler { if (name === WidgetNameConstants.MAIN || name === WidgetNameConstants.X_AXIS) { zoomCoordinate = { x: event.x, y: event.y } } else { - const bounding = this._chart.getDrawPaneById(PaneIdConstants.CANDLE)?.getBounding() as Bounding + const bounding = this._chart.getCandlePane().getBounding() zoomCoordinate = { x: bounding.width / 2, y: bounding.height / 2 } } } else { @@ -625,7 +624,7 @@ export default class Event implements EventHandler { const drawPanes = this._chart.getAllDrawPanes() let pane: Nullable = null - for (const [, p] of drawPanes) { + for (const p of drawPanes) { const bounding = p.getBounding() if ( x >= bounding.left && x <= bounding.left + bounding.width && diff --git a/src/component/YAxis.ts b/src/component/YAxis.ts index 815c081f3..f23d30ff0 100644 --- a/src/component/YAxis.ts +++ b/src/component/YAxis.ts @@ -23,6 +23,8 @@ import { index10, log10 } from '../common/utils/number' import { calcTextWidth } from '../common/utils/canvas' import { formatPrecision, formatThousands } from '../common/utils/format' +import { PaneIdConstants } from '../pane/types' + interface FiguresResult { figures: IndicatorFigure[] result: any[] @@ -192,7 +194,7 @@ export default class YAxisImp extends AxisImp implements YAxis { * @return {boolean} */ isInCandle (): boolean { - return this.getParent().getName() === 'candle' + return this.getParent().getId() === PaneIdConstants.CANDLE } /** diff --git a/src/pane/CandlePane.ts b/src/pane/CandlePane.ts index 6532d7f15..86252f660 100644 --- a/src/pane/CandlePane.ts +++ b/src/pane/CandlePane.ts @@ -19,13 +19,7 @@ import DrawPane from './DrawPane' import IndicatorPane from './IndicatorPane' import YAxis from '../component/YAxis' -import { PaneNameConstants } from './types' - export default class CandlePane extends IndicatorPane { - override getName (): string { - return PaneNameConstants.CANDLE - } - override createMainWidget (container: HTMLElement): DrawWidget> { return new CandleWidget(container, this) } diff --git a/src/pane/IndicatorPane.ts b/src/pane/IndicatorPane.ts index cc0eb2b01..7cec09f9b 100644 --- a/src/pane/IndicatorPane.ts +++ b/src/pane/IndicatorPane.ts @@ -22,13 +22,7 @@ import YAxis from '../component/YAxis' import DrawPane from './DrawPane' -import { PaneNameConstants } from './types' - export default class IndicatorPane extends DrawPane { - override getName (): string { - return PaneNameConstants.INDICATOR - } - override createAxisComponent (): YAxis { return new YAxis(this) } diff --git a/src/pane/Pane.ts b/src/pane/Pane.ts index 63b31326a..aa4a90a57 100644 --- a/src/pane/Pane.ts +++ b/src/pane/Pane.ts @@ -80,7 +80,5 @@ export default abstract class Pane implements Updater { abstract getImage (includeOverlay: boolean): HTMLCanvasElement - abstract getName (): string - abstract updateImp (level: UpdateLevel, container: HTMLElement, bounding: Bounding): void } diff --git a/src/pane/SeparatorPane.ts b/src/pane/SeparatorPane.ts index 1b4f03385..c355c8619 100644 --- a/src/pane/SeparatorPane.ts +++ b/src/pane/SeparatorPane.ts @@ -16,12 +16,13 @@ import Nullable from '../common/Nullable' import { UpdateLevel } from '../common/Updater' import Bounding from '../common/Bounding' import { merge } from '../common/utils/typeChecks' +import { createDom } from '../common/utils/dom' +import { getPixelRatio } from '../common/utils/canvas' import Chart from '../Chart' import DrawPane from './DrawPane' import Pane from './Pane' -import { PaneNameConstants } from './types' import SeparatorWidget from '../widget/SeparatorWidget' @@ -65,22 +66,32 @@ export default class SeparatorPane extends Pane { getWidget (): SeparatorWidget { return this._separatorWidget } override getImage (_includeOverlay: boolean): HTMLCanvasElement { - throw new Error('Method not implemented.') + const { width, height } = this.getBounding() + + const styles = this.getChart().getStyles().separator + const canvas = createDom('canvas', { + width: `${width}px`, + height: `${height}px`, + boxSizing: 'border-box' + }) + const ctx = canvas.getContext('2d') as CanvasRenderingContext2D + const pixelRatio = getPixelRatio(canvas) + canvas.width = width * pixelRatio + canvas.height = height * pixelRatio + ctx.scale(pixelRatio, pixelRatio) + ctx.fillStyle = styles.color + ctx.fillRect(0, 0, width, height) + return canvas } override updateImp (level: UpdateLevel, container: HTMLElement, bounding: Bounding): void { if (level === UpdateLevel.All || level === UpdateLevel.Separator) { const styles = this.getChart().getStyles().separator - const fill = styles.fill container.style.backgroundColor = styles.color - container.style.height = `${styles.size}px` - container.style.marginLeft = `${fill ? 0 : bounding.left}px` - container.style.width = fill ? '100%' : `${bounding.width}px` + container.style.height = `${bounding.height}px` + container.style.marginLeft = `${bounding.left}px` + container.style.width = `${bounding.width}px` this._separatorWidget.update(level) } } - - override getName (): string { - return PaneNameConstants.SEPARATOR - } } diff --git a/src/pane/XAxisPane.ts b/src/pane/XAxisPane.ts index 3e263fa58..3a04e389f 100644 --- a/src/pane/XAxisPane.ts +++ b/src/pane/XAxisPane.ts @@ -18,13 +18,8 @@ import XAxisWidget from '../widget/XAxisWidget' import XAxis from '../component/XAxis' import DrawPane from './DrawPane' -import { PaneNameConstants } from './types' export default class XAxisPane extends DrawPane { - override getName (): string { - return PaneNameConstants.X_AXIS - } - override createAxisComponent (): XAxis { return new XAxis(this) } diff --git a/src/pane/types.ts b/src/pane/types.ts index bbe3dffb5..08a4308ca 100644 --- a/src/pane/types.ts +++ b/src/pane/types.ts @@ -36,13 +36,6 @@ export interface PaneOptions { axisOptions?: PaneAxisOptions } -export const PaneNameConstants = { - CANDLE: 'candle', - INDICATOR: 'indicator', - SEPARATOR: 'separator', - X_AXIS: 'xAxis' -} - export const PANE_MIN_HEIGHT = 30 export const PANE_DEFAULT_HEIGHT = 100 diff --git a/src/view/GridView.ts b/src/view/GridView.ts index 17e7111bf..7d57118b1 100644 --- a/src/view/GridView.ts +++ b/src/view/GridView.ts @@ -12,10 +12,6 @@ * limitations under the License. */ -import XAxis from '../component/XAxis' - -import { PaneIdConstants } from '../pane/types' - import View from './View' export default class GridView extends View { @@ -51,7 +47,7 @@ export default class GridView extends View { const verticalStyles = gridStyles.vertical const verticalShow = verticalStyles.show if (verticalShow) { - const xAxis = chart.getDrawPaneById(PaneIdConstants.X_AXIS)?.getAxisComponent() as XAxis + const xAxis = chart.getXAxisPane().getAxisComponent() xAxis.getTicks().forEach(tick => { this.createFigure( 'line', diff --git a/src/view/IndicatorTooltipView.ts b/src/view/IndicatorTooltipView.ts index 91b454cfa..45ecbbf9d 100644 --- a/src/view/IndicatorTooltipView.ts +++ b/src/view/IndicatorTooltipView.ts @@ -21,13 +21,10 @@ import { ActionType } from '../common/Action' import { CustomApi } from '../Options' -import XAxis from '../component/XAxis' import YAxis from '../component/YAxis' import IndicatorImp, { eachFigures, Indicator, IndicatorFigure, IndicatorFigureStyle, IndicatorTooltipData } from '../component/Indicator' -import { PaneIdConstants } from '../pane/types' - import { formatPrecision, formatThousands } from '../common/utils/format' import { isValid, isObject } from '../common/utils/typeChecks' import { createFont } from '../common/utils/canvas' @@ -333,7 +330,7 @@ export default class IndicatorTooltipView extends View { bounding: widget.getBounding(), crosshair, defaultStyles: styles, - xAxis: pane.getChart().getDrawPaneById(PaneIdConstants.X_AXIS)?.getAxisComponent() as XAxis, + xAxis: pane.getChart().getXAxisPane().getAxisComponent(), yAxis: pane.getAxisComponent() }) if (customName !== undefined && tooltipStyles.showName) { diff --git a/src/view/IndicatorView.ts b/src/view/IndicatorView.ts index 12100e596..87c2baac0 100644 --- a/src/view/IndicatorView.ts +++ b/src/view/IndicatorView.ts @@ -17,12 +17,8 @@ import VisibleData from '../common/VisibleData' import BarSpace from '../common/BarSpace' import { CandleType } from '../common/Styles' -import { PaneIdConstants } from '../pane/types' - import ChartStore from '../store/ChartStore' -import Axis from '../component/Axis' - import { eachFigures, IndicatorFigure, IndicatorFigureAttrs, IndicatorFigureStyle } from '../component/Indicator' import CandleBarView, { CandleBarOptions } from './CandleBarView' @@ -70,7 +66,7 @@ export default class IndicatorView extends CandleBarView { const pane = widget.getPane() const chart = pane.getChart() const bounding = widget.getBounding() - const xAxis = chart.getDrawPaneById(PaneIdConstants.X_AXIS)?.getAxisComponent() as Axis + const xAxis = chart.getXAxisPane().getAxisComponent() const yAxis = pane.getAxisComponent() const chartStore = chart.getChartStore() const dataList = chartStore.getDataList() diff --git a/src/view/OverlayView.ts b/src/view/OverlayView.ts index 88521689d..e5d871a20 100644 --- a/src/view/OverlayView.ts +++ b/src/view/OverlayView.ts @@ -288,7 +288,7 @@ export default class OverlayView extends View { const paneId = pane.getId() const timeScaleStore = chart.getChartStore().getTimeScaleStore() if (this.coordinateToPointTimestampDataIndexFlag()) { - const xAxis = chart.getDrawPaneById(PaneIdConstants.X_AXIS)?.getAxisComponent() as Axis + const xAxis = chart.getXAxisPane().getAxisComponent() const dataIndex = xAxis.convertFromPixel(coordinate.x) const timestamp = timeScaleStore.dataIndexToTimestamp(dataIndex) ?? undefined point.dataIndex = dataIndex @@ -374,7 +374,7 @@ export default class OverlayView extends View { const paneId = pane.getId() const chart = pane.getChart() const yAxis = pane.getAxisComponent() as unknown as Nullable - const xAxis = chart.getDrawPaneById(PaneIdConstants.X_AXIS)?.getAxisComponent() as Nullable + const xAxis = chart.getXAxisPane().getAxisComponent() const bounding = widget.getBounding() const chartStore = chart.getChartStore() const customApi = chartStore.getCustomApi() diff --git a/src/widget/SeparatorWidget.ts b/src/widget/SeparatorWidget.ts index b1c0657bc..5f9dae18a 100644 --- a/src/widget/SeparatorWidget.ts +++ b/src/widget/SeparatorWidget.ts @@ -16,15 +16,14 @@ import Bounding from '../common/Bounding' import { UpdateLevel } from '../common/Updater' import { MouseTouchEvent } from '../common/SyntheticEvent' import { ActionType } from '../common/Action' +import { createDom } from '../common/utils/dom' +import { throttle } from '../common/utils/performance' import Widget from './Widget' import { WidgetNameConstants, REAL_SEPARATOR_HEIGHT } from './types' import SeparatorPane from '../pane/SeparatorPane' -import { createDom } from '../common/utils/dom' -import { getPixelRatio } from '../common/utils/canvas' -import { throttle } from '../common/utils/performance' import AxisPane from '../pane/DrawPane' export default class SeparatorWidget extends Widget { @@ -147,23 +146,4 @@ export default class SeparatorWidget extends Widget { container.style.height = `${REAL_SEPARATOR_HEIGHT}px` } } - - getImage (): HTMLCanvasElement { - const styles = this.getPane().getChart().getStyles().separator - const width = this.getContainer().offsetWidth - const height = styles.size - const canvas = createDom('canvas', { - width: `${width}px`, - height: `${height}px`, - boxSizing: 'border-box' - }) - const ctx = canvas.getContext('2d') as CanvasRenderingContext2D - const pixelRatio = getPixelRatio(canvas) - canvas.width = width * pixelRatio - canvas.height = height * pixelRatio - ctx.scale(pixelRatio, pixelRatio) - ctx.fillStyle = styles.color - ctx.fillRect(this.getBounding().left, 0, width, height) - return canvas - } }