Skip to content

Commit

Permalink
Core | Container: Adding _preRender step; Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
rokotyan committed Aug 23, 2023
1 parent ccf1384 commit a20ff1b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 29 deletions.
15 changes: 10 additions & 5 deletions packages/ts/src/containers/single-container/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class SingleContainer<Data> extends ContainerCore {

public updateContainer (containerConfig: SingleContainerConfigInterface<Data>, preventRender?: boolean): void {
super.updateContainer(containerConfig)
this.removeAllChildren()
this._removeAllChildren()

this.component = containerConfig.component
if (containerConfig.sizing) this.component.sizing = containerConfig.sizing
Expand Down Expand Up @@ -86,11 +86,15 @@ export class SingleContainer<Data> extends ContainerCore {
return this.width / componentWidth
}

_render (duration?: number): void {
protected _preRender (): void {
super._preRender()
this.component.setSize(this.width, this.height, this.containerWidth, this.containerHeight)
}

protected _render (duration?: number): void {
const { config, component } = this
super._render(duration)

component.setSize(this.width, this.height, this.containerWidth, this.containerHeight)
component.g.attr('transform', `translate(${config.margin.left},${config.margin.top})`)
component.render(duration)

Expand All @@ -99,7 +103,7 @@ export class SingleContainer<Data> extends ContainerCore {

// Re-defining the `render()` function to handle different sizing techniques (`Sizing.Extend` and `Sizing.FitWidth`)
// Not calling `super.render()` because we don't want it to interfere with setting the SVG size here.
render (duration = this.config.duration): void {
public render (duration = this.config.duration): void {
const { config, component } = this

if (config.sizing === Sizing.Extend || config.sizing === Sizing.FitWidth) {
Expand Down Expand Up @@ -133,11 +137,12 @@ export class SingleContainer<Data> extends ContainerCore {
// Schedule the actual rendering in the next frame
cancelAnimationFrame(this._requestedAnimationFrame)
this._requestedAnimationFrame = requestAnimationFrame(() => {
this._preRender()
this._render(duration)
})
}

_onResize (): void {
protected _onResize (): void {
const { config } = this
super._onResize()
config.tooltip?.hide()
Expand Down
39 changes: 22 additions & 17 deletions packages/ts/src/containers/xy-container/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export class XYContainer<Datum> extends ContainerCore {
return clamp(this.containerHeight - margin.top - margin.bottom, 0, Number.POSITIVE_INFINITY)
}

setData (data: Datum[], preventRender?: boolean): void {
public setData (data: Datum[], preventRender?: boolean): void {
const { components, config } = this
if (!data) return
this.datamodel.data = data
Expand All @@ -129,9 +129,9 @@ export class XYContainer<Datum> extends ContainerCore {
if (!preventRender) this.render()
}

updateContainer (containerConfig: XYContainerConfigInterface<Datum>, preventRender?: boolean): void {
public updateContainer (containerConfig: XYContainerConfigInterface<Datum>, preventRender?: boolean): void {
super.updateContainer(containerConfig)
this.removeAllChildren()
this._removeAllChildren()

// If there were any new components added we need to pass them data
this.setData(this.datamodel.data, true)
Expand Down Expand Up @@ -177,7 +177,7 @@ export class XYContainer<Datum> extends ContainerCore {
if (!preventRender) this.render()
}

updateComponents (componentConfigs: XYConfigInterface<Datum>[], preventRender?: boolean): void {
public updateComponents (componentConfigs: XYConfigInterface<Datum>[], preventRender?: boolean): void {
const { config } = this

this.components.forEach((c, i) => {
Expand All @@ -187,32 +187,37 @@ export class XYContainer<Datum> extends ContainerCore {
}
})

this.updateScales(...this.components, config.xAxis, config.yAxis, config.crosshair)
this._updateScales(...this.components, config.xAxis, config.yAxis, config.crosshair)
if (!preventRender) this.render()
}

update (containerConfig: XYContainerConfigInterface<Datum>, componentConfigs?: XYComponentConfigInterface<Datum>[], data?: Datum[]): void {
public update (containerConfig: XYContainerConfigInterface<Datum>, componentConfigs?: XYComponentConfigInterface<Datum>[], data?: Datum[]): void {
if (data) this.datamodel.data = data // Just updating the data model because the `updateContainer` method has the `setData` step inside
if (containerConfig) this.updateContainer(containerConfig, true)
if (componentConfigs) this.updateComponents(componentConfigs, true)
this.render()
}

_render (customDuration?: number): void {
protected _preRender (): void {
const { config } = this
super._render()
super._preRender()

// Calculate extra margin required to fit the axes
if (config.autoMargin) {
this._setAutoMargin()
}

// Update Scales of all the components at once to calculate required paddings and sync them
this._updateScales(...this.components, config.xAxis, config.yAxis, config.crosshair)
}

protected _render (customDuration?: number): void {
const { config } = this
super._render()

// Get chart total margin after auto margin calculations
const margin = this._getMargin()

// Update Scales of all the components at once to calculate required paddings and sync them
this.updateScales(...this.components, config.xAxis, config.yAxis, config.crosshair)

// Render components
for (const c of this.components) {
c.g.attr('transform', `translate(${margin.left},${margin.top})`)
Expand Down Expand Up @@ -261,14 +266,14 @@ export class XYContainer<Datum> extends ContainerCore {
this._firstRender = false
}

updateScales<T extends XYComponentCore<Datum>> (...components: T[]): void {
private _updateScales<T extends XYComponentCore<Datum>> (...components: T[]): void {
const c = clean(components || this.components)
this._setScales(...c)
this._updateScalesDomain(...c)
this._updateScalesRange(...c)
}

_setScales<T extends XYComponentCore<Datum>> (...components: T[]): void {
private _setScales<T extends XYComponentCore<Datum>> (...components: T[]): void {
const { config } = this
if (!components) return

Expand All @@ -277,7 +282,7 @@ export class XYContainer<Datum> extends ContainerCore {
if (config.yScale) components.forEach(c => c.setScale(ScaleDimension.Y, config.yScale))
}

_updateScalesDomain<T extends XYComponentCore<Datum>> (...components: T[]): void {
private _updateScalesDomain<T extends XYComponentCore<Datum>> (...components: T[]): void {
const { config } = this
if (!components) return

Expand Down Expand Up @@ -309,7 +314,7 @@ export class XYContainer<Datum> extends ContainerCore {
})
}

_updateScalesRange<T extends XYComponentCore<Datum>> (...components: T[]): void {
private _updateScalesRange<T extends XYComponentCore<Datum>> (...components: T[]): void {
const { config } = this
if (!components) return

Expand Down Expand Up @@ -345,7 +350,7 @@ export class XYContainer<Datum> extends ContainerCore {
}
}

_renderAxes (duration: number): void {
private _renderAxes (duration: number): void {
const { config: { xAxis, yAxis } } = this
const margin = this._getMargin()

Expand All @@ -357,7 +362,7 @@ export class XYContainer<Datum> extends ContainerCore {
})
}

_setAutoMargin (): void {
private _setAutoMargin (): void {
const { config: { xAxis, yAxis } } = this

// At first we need to set the domain to the scales
Expand Down
21 changes: 14 additions & 7 deletions packages/ts/src/core/container/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,20 @@ export class ContainerCore {
this.element = this.svg.node()
}

updateContainer<T extends ContainerConfigInterface> (config: T): void {
public updateContainer<T extends ContainerConfigInterface> (config: T): void {
// eslint-disable-next-line @typescript-eslint/naming-convention
const ConfigModel = (this.config.constructor as typeof ContainerConfig)
this.prevConfig = this.config
this.config = new ConfigModel().init(config)
}

_render (duration?: number): void {
// The `_preRender` step should be used to perform some actions before rendering.
// For example, calculating scales, setting component sizes, etc ...
// eslint-disable-next-line @typescript-eslint/no-empty-function
protected _preRender (): void {}

// The `_render` step should be used to perform the actual rendering
protected _render (duration?: number): void {
const { config } = this

// Add `svgDefs` if provided in the config
Expand All @@ -70,7 +76,7 @@ export class ContainerCore {

// Warning: Some Containers (i.e. Single Container) may override this method, so if you introduce any changes here,
// make sure to check that other containers didn't break after them.
render (duration = this.config.duration): void {
public render (duration = this.config.duration): void {
const width = this.config.width || this.containerWidth
const height = this.config.height || this.containerHeight

Expand All @@ -88,6 +94,7 @@ export class ContainerCore {
// Schedule the actual rendering in the next frame
cancelAnimationFrame(this._requestedAnimationFrame)
this._requestedAnimationFrame = requestAnimationFrame(() => {
this._preRender()
this._render(duration)
})
}
Expand All @@ -112,19 +119,19 @@ export class ContainerCore {
return clamp(this.containerHeight - this.config.margin.top - this.config.margin.bottom, 0, Number.POSITIVE_INFINITY)
}

removeAllChildren (): void {
protected _removeAllChildren (): void {
while (this.element.firstChild) {
this.element.removeChild(this.element.firstChild)
}
}

_onResize (): void {
protected _onResize (): void {
const { config } = this
const redrawOnResize = config.sizing === Sizing.Fit || config.sizing === Sizing.FitWidth
if (redrawOnResize) this.render(0)
}

_setUpResizeObserver (): void {
protected _setUpResizeObserver (): void {
if (this._resizeObserver) return
const containerRect = this._container.getBoundingClientRect()
this._containerSize = { width: containerRect.width, height: containerRect.height }
Expand All @@ -143,7 +150,7 @@ export class ContainerCore {
this._resizeObserver.observe(this._container)
}

destroy (): void {
public destroy (): void {
cancelAnimationFrame(this._requestedAnimationFrame)
this._resizeObserver?.disconnect()
this.svg.remove()
Expand Down

0 comments on commit a20ff1b

Please sign in to comment.