Skip to content

Commit

Permalink
Merge branch 'f5:main' into feat-solid-support
Browse files Browse the repository at this point in the history
  • Loading branch information
hngngn authored Oct 28, 2024
2 parents 816b684 + 58dd27a commit 78dee46
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@ export class VisSingleContainerComponent<Data = unknown, C extends ComponentCore
@ContentChild(VisTooltipComponent) tooltipComponent: VisTooltipComponent
@ContentChild(VisAnnotationsComponent) annotationsComponent: VisAnnotationsComponent

/** Width in pixels. By default, Container automatically fits to the size of the parent element. Default: `undefined`. */
/** Width in pixels or in CSS units.
* Percentage units `"%"` are not supported here. If you want to set `width` as a percentage, do it via `style` or `class`
* of the corresponding DOM element.
* Default: `undefined`
*/
@Input() width?: number
/** Height in pixels. By default, Container automatically fits to the size of the parent element. Default: `undefined`. */
/** Height in pixels or in CSS units.
* Percentage units `"%"` are not supported here. If you want to set `height` as a percentage, do it via `style` or `class`
* of the corresponding DOM element.
* Default: `undefined`
*/
@Input() height?: number

/** Margins. Default: `{ top: 0, bottom: 0, left: 0, right: 0 }` */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,17 @@ export class VisXYContainerComponent<Datum> implements AfterViewInit, AfterConte
@ContentChild(VisTooltipComponent) tooltipComponent: VisTooltipComponent
@ContentChild(VisAnnotationsComponent) annotationsComponent: VisAnnotationsComponent

/** Width in pixels. By default, Container automatically fits to the size of the parent element. Default: `undefined`. */
/** Width in pixels or in CSS units.
* Percentage units `"%"` are not supported here. If you want to set `width` as a percentage, do it via `style` or `class`
* of the corresponding DOM element.
* Default: `undefined`
*/
@Input() width?: number
/** Height in pixels. By default, Container automatically fits to the size of the parent element. Default: `undefined`. */
/** Height in pixels or in CSS units.
* Percentage units `"%"` are not supported here. If you want to set `height` as a percentage, do it via `style` or `class`
* of the corresponding DOM element.
* Default: `undefined`
*/
@Input() height?: number

/** Scale for X dimension, e.g. Scale.scaleLinear(). Default: `Scale.scaleLinear()` */
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/cypress/e2e/unovis.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Unovis Test', () => {
duration: test.duration,
},
})
cy.wait(test.duration > 100 ? test.duration : 100)
cy.wait(test.duration > 1000 ? test.duration : 1000)
cy.percySnapshot(test.title, { scope: scopeSelector })
})
})
Expand Down
22 changes: 22 additions & 0 deletions packages/dev/src/examples/misc/donut/donut-full-height/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<VisSingleContainer style={{ height: '100%' }}>
<VisDonut
value={d => d}
data={data}
padAngle={0.02}
duration={props.duration}
arcWidth={80}
/>
</VisSingleContainer>
)
}

4 changes: 2 additions & 2 deletions packages/ts/src/containers/single-container/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ export class SingleContainer<Data> 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)
})
Expand Down
6 changes: 2 additions & 4 deletions packages/ts/src/core/container/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,14 @@ export interface ContainerConfigInterface {
/** Defines whether components should fit into the container or the container should expand to fit to the component's size. Default: `Sizing.Fit` */
sizing?: Sizing | string;
/** Width in pixels or in CSS units.
* Percentage units `"%"` are not supported here. If you want to set `width` as a percentage, do it via `style`
* Percentage units `"%"` are not supported here. If you want to set `width` as a percentage, do it via `style` or `class`
* of the corresponding DOM element.
* By default, Container automatically fits to the size of the parent element.
* Default: `undefined`
*/
width?: number | string;
/** Height in pixels or in CSS units.
* Percentage units `"%"` are not supported here. If you want to set `height` as a percentage, do it via `style`
* Percentage units `"%"` are not supported here. If you want to set `height` as a percentage, do it via `style` or `class`
* of the corresponding DOM element.
* By default, Container automatically fits to the size of the parent element.
* Default: `undefined`
*/
height?: number | string;
Expand Down
36 changes: 22 additions & 14 deletions packages/ts/src/core/container/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<SVGDefsElement, unknown, null, undefined>
protected _svgDefsExternal: Selection<SVGDefsElement, unknown, null, undefined>
private _containerSize: { width: number; height: number }
Expand All @@ -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
Expand Down Expand Up @@ -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)
})
Expand Down Expand Up @@ -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()
}
Expand Down

0 comments on commit 78dee46

Please sign in to comment.