From 17069ce2756cf5ea16f89865931f328692ba3db5 Mon Sep 17 00:00:00 2001 From: Soryn Date: Sun, 3 May 2026 12:47:52 +0300 Subject: [PATCH 1/2] Container: Add `load` / `render` / `redraw` lifecycle events --- .../single-container.component.ts | 35 ++++++++++++-- .../xy-container/xy-container.component.ts | 23 +++++++++ .../single-container/single-container.svelte | 26 ++++++++-- .../xy-container/xy-container.svelte | 47 ++++++++++++------- packages/ts/src/containers.ts | 4 +- .../src/containers/single-container/config.ts | 9 ++++ .../src/containers/single-container/index.ts | 9 +++- .../ts/src/containers/xy-container/config.ts | 10 ++++ .../ts/src/containers/xy-container/index.ts | 10 +++- .../src/containers/single-container/index.vue | 25 ++++++++-- .../vue/src/containers/xy-container/index.vue | 25 ++++++++-- .../docs/containers/Single_Container.mdx | 38 +++++++++++++++ .../website/docs/containers/XY_Container.mdx | 39 +++++++++++++++ 13 files changed, 268 insertions(+), 32 deletions(-) diff --git a/packages/angular/src/containers/single-container/single-container.component.ts b/packages/angular/src/containers/single-container/single-container.component.ts index d1ae75398..56d4ef943 100644 --- a/packages/angular/src/containers/single-container/single-container.component.ts +++ b/packages/angular/src/containers/single-container/single-container.component.ts @@ -1,7 +1,17 @@ -import { Component, ViewChild, ElementRef, AfterViewInit, Input, OnDestroy, SimpleChanges, ContentChild } from '@angular/core' +import { Component, ViewChild, ElementRef, AfterViewInit, EventEmitter, Input, OnDestroy, Output, SimpleChanges, ContentChild } from '@angular/core' // Vis -import { ColorFunction, ComponentCore, SingleContainer, SingleContainerConfigInterface, Tooltip, Spacing, Annotations, Sizing } from '@unovis/ts' +import { + ColorFunction, + ComponentCore, + SingleContainer, + SingleContainerConfigInterface, + SingleContainerRenderPayload, + Tooltip, + Spacing, + Annotations, + Sizing, +} from '@unovis/ts' import { VisCoreComponent } from '../../core' import { VisTooltipComponent } from '../../components/tooltip/tooltip.component' import { VisAnnotationsComponent } from '../../components/annotations/annotations.component' @@ -54,7 +64,26 @@ export class VisSingleContainerComponent() + /** Emitted after every render of the chart, including the first. */ + @Output() render = new EventEmitter() + /** Emitted after every render except the first. */ + @Output() redraw = new EventEmitter() + chart: SingleContainer + private _hasLoaded = false + + private _onRenderComplete: SingleContainerConfigInterface['onRenderComplete'] = (svg, margin, containerWidth, containerHeight, componentWidth, componentHeight) => { + const payload: SingleContainerRenderPayload = { svg, margin, containerWidth, containerHeight, componentWidth, componentHeight } + this.render.emit(payload) + if (this._hasLoaded) { + this.redraw.emit(payload) + } else { + this._hasLoaded = true + this.load.emit(payload) + } + } ngAfterViewInit (): void { this.chart = new SingleContainer(this.containerRef.nativeElement, this.getConfig(), this.data) @@ -80,7 +109,7 @@ export class VisSingleContainerComponent implements AfterViewInit, AfterConte * have their individual data. Default: `undefined` */ @Input() data?: Datum[] | undefined = undefined + /** Emitted once after the chart's first render completes. */ + @Output() load = new EventEmitter() + /** Emitted after every render of the chart, including the first. */ + @Output() render = new EventEmitter() + /** Emitted after every render except the first. */ + @Output() redraw = new EventEmitter() + chart: XYContainer + private _hasLoaded = false + + private _onRenderComplete: XYContainerConfigInterface['onRenderComplete'] = (svg, margin, bleed, containerWidth, containerHeight, componentWidth, componentHeight) => { + const payload: XYContainerRenderPayload = { svg, margin, bleed, containerWidth, containerHeight, componentWidth, componentHeight } + this.render.emit(payload) + if (this._hasLoaded) { + this.redraw.emit(payload) + } else { + this._hasLoaded = true + this.load.emit(payload) + } + } ngAfterViewInit (): void { this.chart = new XYContainer(this.containerRef.nativeElement, this.getConfig(), this.data) @@ -207,6 +229,7 @@ export class VisXYContainerComponent implements AfterViewInit, AfterConte yDirection, ariaLabel, colorFunction, + onRenderComplete: this._onRenderComplete, } } diff --git a/packages/svelte/src/containers/single-container/single-container.svelte b/packages/svelte/src/containers/single-container/single-container.svelte index 2c4689208..f17311a1c 100644 --- a/packages/svelte/src/containers/single-container/single-container.svelte +++ b/packages/svelte/src/containers/single-container/single-container.svelte @@ -1,7 +1,7 @@