diff --git a/packages/dev/src/examples/misc/donut/donut-full-height/index.tsx b/packages/dev/src/examples/misc/donut/donut-full-height/index.tsx
new file mode 100644
index 000000000..b984204be
--- /dev/null
+++ b/packages/dev/src/examples/misc/donut/donut-full-height/index.tsx
@@ -0,0 +1,22 @@
+import React from 'react'
+import { VisSingleContainer, VisDonut } from '@unovis/react'
+import { ExampleViewerDurationProps } from '@src/components/ExampleViewer/index'
+
+export const title = 'Donut: Full Height'
+export const subTitle = 'Testing the resize behavior'
+
+export const component = (props: ExampleViewerDurationProps): JSX.Element => {
+ const data = [3, 2, 5, 4, 0, 1]
+ return (
+
+ d}
+ data={data}
+ padAngle={0.02}
+ duration={props.duration}
+ arcWidth={80}
+ />
+
+ )
+}
+
diff --git a/packages/ts/src/containers/single-container/index.ts b/packages/ts/src/containers/single-container/index.ts
index 11aba2ba7..3752f9a9a 100644
--- a/packages/ts/src/containers/single-container/index.ts
+++ b/packages/ts/src/containers/single-container/index.ts
@@ -147,8 +147,8 @@ export class SingleContainer extends ContainerCore {
if (!this._resizeObserver) this._setUpResizeObserver()
// Schedule the actual rendering in the next frame
- cancelAnimationFrame(this._requestedAnimationFrame)
- this._requestedAnimationFrame = requestAnimationFrame(() => {
+ cancelAnimationFrame(this._renderAnimationFrameId)
+ this._renderAnimationFrameId = requestAnimationFrame(() => {
this._preRender()
this._render(duration)
})
diff --git a/packages/ts/src/core/container/index.ts b/packages/ts/src/core/container/index.ts
index 7c4c78346..9e828cc0c 100644
--- a/packages/ts/src/core/container/index.ts
+++ b/packages/ts/src/core/container/index.ts
@@ -18,9 +18,10 @@ export class ContainerCore {
protected _defaultConfig: ContainerConfigInterface = ContainerDefaultConfig
protected _container: HTMLElement
- protected _requestedAnimationFrame: number
+ protected _renderAnimationFrameId: number
protected _isFirstRender = true
protected _resizeObserver: ResizeObserver | undefined
+ protected _resizeObserverAnimationFrameId: number
protected _svgDefs: Selection
protected _svgDefsExternal: Selection
private _containerSize: { width: number; height: number }
@@ -29,7 +30,7 @@ export class ContainerCore {
static DEFAULT_CONTAINER_HEIGHT = 300
constructor (element: HTMLElement) {
- this._requestedAnimationFrame = null
+ this._renderAnimationFrameId = null
this._container = element
// Setting `role` attribute to `image` to make the container accessible
@@ -96,8 +97,8 @@ export class ContainerCore {
if (!this._resizeObserver) this._setUpResizeObserver()
// Schedule the actual rendering in the next frame
- cancelAnimationFrame(this._requestedAnimationFrame)
- this._requestedAnimationFrame = requestAnimationFrame(() => {
+ cancelAnimationFrame(this._renderAnimationFrameId)
+ this._renderAnimationFrameId = requestAnimationFrame(() => {
this._preRender()
this._render(duration)
})
@@ -137,25 +138,32 @@ export class ContainerCore {
protected _setUpResizeObserver (): void {
if (this._resizeObserver) return
+
const containerRect = this._container.getBoundingClientRect()
this._containerSize = { width: containerRect.width, height: containerRect.height }
this._resizeObserver = new ResizeObserver((entries, observer) => {
- const resizedContainerRect = this._container.getBoundingClientRect()
- const resizedContainerSize = { width: resizedContainerRect.width, height: resizedContainerRect.height }
- const hasSizeChanged = !isEqual(this._containerSize, resizedContainerSize)
- // Do resize only if element is attached to the DOM
- // will come in useful when some ancestor of container becomes detached
- if (hasSizeChanged && resizedContainerSize.width && resizedContainerSize.height) {
- this._containerSize = resizedContainerSize
- this._onResize()
- }
+ // Using request animation frame to avoid multiple resize events when scrollbars appear/disappear
+ // See more: https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#observation_errors
+ cancelAnimationFrame(this._resizeObserverAnimationFrameId)
+ this._resizeObserverAnimationFrameId = requestAnimationFrame(() => {
+ const resizedContainerRect = this._container.getBoundingClientRect()
+ const resizedContainerSize = { width: resizedContainerRect.width, height: resizedContainerRect.height }
+ const hasSizeChanged = !isEqual(this._containerSize, resizedContainerSize)
+ // Do resize only if element is attached to the DOM
+ // will come in useful when some ancestor of container becomes detached
+ if (hasSizeChanged && resizedContainerSize.width && resizedContainerSize.height) {
+ this._containerSize = resizedContainerSize
+ this._onResize()
+ }
+ })
})
this._resizeObserver.observe(this._container)
}
public destroy (): void {
- cancelAnimationFrame(this._requestedAnimationFrame)
+ cancelAnimationFrame(this._renderAnimationFrameId)
+ cancelAnimationFrame(this._resizeObserverAnimationFrameId)
this._resizeObserver?.disconnect()
this.svg.remove()
}