Skip to content

Commit 47a28d3

Browse files
committed
feat(circle-packing): improve typings, expose ref, and improve responsive components
1 parent 65d4ee3 commit 47a28d3

29 files changed

+785
-464
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { ResponsiveProps } from '@nivo/core'
2+
import { CirclePacking, ResponsiveCirclePacking, CirclePackingSvgProps } from '@nivo/circle-packing'
3+
import { testChartResponsiveness } from '../../helpers/responsive'
4+
import { Datum, defaultData } from './shared'
5+
6+
const defaultResponsiveProps: ResponsiveProps<CirclePackingSvgProps<Datum>> = {
7+
data: defaultData,
8+
margin: {
9+
top: 3,
10+
right: 3,
11+
bottom: 3,
12+
left: 3,
13+
},
14+
animate: false,
15+
role: 'chart',
16+
}
17+
18+
const defaultProps: CirclePackingSvgProps<Datum> = {
19+
...defaultResponsiveProps,
20+
width: 500,
21+
height: 500,
22+
}
23+
24+
describe('CirclePacking', () => {
25+
it('should render a circle-packing chart', () => {
26+
cy.mount(<CirclePacking {...defaultProps} />)
27+
})
28+
29+
testChartResponsiveness(defaults => (
30+
<ResponsiveCirclePacking
31+
defaultWidth={defaults?.[0]}
32+
defaultHeight={defaults?.[1]}
33+
{...defaultResponsiveProps}
34+
/>
35+
))
36+
})
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { ResponsiveProps } from '@nivo/core'
2+
import {
3+
CirclePackingCanvas,
4+
ResponsiveCirclePackingCanvas,
5+
CirclePackingCanvasProps,
6+
} from '@nivo/circle-packing'
7+
import { testChartResponsiveness } from '../../helpers/responsive'
8+
import { Datum, defaultData } from './shared'
9+
10+
const defaultResponsiveProps: ResponsiveProps<CirclePackingCanvasProps<Datum>> = {
11+
data: defaultData,
12+
margin: {
13+
top: 3,
14+
right: 3,
15+
bottom: 3,
16+
left: 3,
17+
},
18+
animate: false,
19+
role: 'chart',
20+
}
21+
22+
const defaultProps: CirclePackingCanvasProps<Datum> = {
23+
...defaultResponsiveProps,
24+
width: 500,
25+
height: 500,
26+
}
27+
28+
describe('CirclePackingCanvas', () => {
29+
it('should render a circle-packing chart', () => {
30+
cy.mount(<CirclePackingCanvas {...defaultProps} />)
31+
})
32+
33+
testChartResponsiveness(defaults => (
34+
<ResponsiveCirclePackingCanvas
35+
pixelRatio={1}
36+
defaultWidth={defaults?.[0]}
37+
defaultHeight={defaults?.[1]}
38+
{...defaultResponsiveProps}
39+
/>
40+
))
41+
})
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { ResponsiveProps } from '@nivo/core'
2+
import {
3+
CirclePackingHtml,
4+
ResponsiveCirclePackingHtml,
5+
CirclePackingHtmlProps,
6+
} from '@nivo/circle-packing'
7+
import { testChartResponsiveness } from '../../helpers/responsive'
8+
import { Datum, defaultData } from './shared'
9+
10+
const defaultResponsiveProps: ResponsiveProps<CirclePackingHtmlProps<Datum>> = {
11+
data: defaultData,
12+
margin: {
13+
top: 3,
14+
right: 3,
15+
bottom: 3,
16+
left: 3,
17+
},
18+
animate: false,
19+
role: 'chart',
20+
}
21+
22+
const defaultProps: CirclePackingHtmlProps<Datum> = {
23+
...defaultResponsiveProps,
24+
width: 500,
25+
height: 500,
26+
}
27+
28+
describe('CirclePackingHtml', () => {
29+
it('should render a circle-packing chart', () => {
30+
cy.mount(<CirclePackingHtml {...defaultProps} />)
31+
})
32+
33+
testChartResponsiveness(
34+
defaults => (
35+
<ResponsiveCirclePackingHtml
36+
defaultWidth={defaults?.[0]}
37+
defaultHeight={defaults?.[1]}
38+
{...defaultResponsiveProps}
39+
/>
40+
),
41+
{ isHtml: true }
42+
)
43+
})
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export interface Datum {
2+
id: string
3+
value?: number
4+
children?: Datum[]
5+
}
6+
7+
export const defaultData: Datum = {
8+
id: 'nivo',
9+
children: [
10+
{
11+
id: 'bar',
12+
children: [
13+
{ id: 'bar-svg', value: 12 },
14+
{ id: 'bar-canvas', value: 34 },
15+
{ id: 'bar-html', value: 2 },
16+
],
17+
},
18+
{
19+
id: 'line',
20+
children: [
21+
{ id: 'line-svg', value: 43 },
22+
{ id: 'line-canvas', value: 27 },
23+
],
24+
},
25+
{
26+
id: 'pie',
27+
children: [
28+
{ id: 'pie-svg', value: 17 },
29+
{ id: 'pie-canvas', value: 23 },
30+
],
31+
},
32+
],
33+
}

cypress/src/helpers/responsive.tsx

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { ReactNode } from 'react'
22

3-
export const testChartResponsiveness = (render: (defaults?: [number, number]) => ReactNode) => {
3+
export const testChartResponsiveness = (
4+
render: (defaults?: [number, number]) => ReactNode,
5+
{
6+
isHtml = false,
7+
}: {
8+
isHtml?: boolean
9+
} = {}
10+
) => {
411
describe('Responsiveness', () => {
512
it('should adapt to the container size', () => {
613
cy.viewport(600, 400)
@@ -23,17 +30,21 @@ export const testChartResponsiveness = (render: (defaults?: [number, number]) =>
2330
</div>
2431
)
2532

26-
cy.findByRole('chart')
27-
.should('exist')
28-
.and('have.attr', 'width', 600)
29-
.and('have.attr', 'height', 400)
33+
let root = cy.findByRole('chart').should('exist')
34+
if (!isHtml) {
35+
root.should('have.attr', 'width', 600).and('have.attr', 'height', 400)
36+
} else {
37+
root.should('have.css', 'width', `${600}px`).and('have.css', 'height', `${400}px`)
38+
}
3039

3140
cy.viewport(500, 300)
3241

33-
cy.findByRole('chart')
34-
.should('exist')
35-
.and('have.attr', 'width', 500)
36-
.and('have.attr', 'height', 300)
42+
root = cy.findByRole('chart').should('exist')
43+
if (!isHtml) {
44+
root.should('have.attr', 'width', 500).and('have.attr', 'height', 300)
45+
} else {
46+
root.should('have.css', 'width', `${500}px`).and('have.css', 'height', `${300}px`)
47+
}
3748
})
3849

3950
it('should support CSS grids', () => {
@@ -56,10 +67,12 @@ export const testChartResponsiveness = (render: (defaults?: [number, number]) =>
5667
</div>
5768
)
5869

59-
cy.findByRole('chart')
60-
.should('exist')
61-
.and('have.attr', 'width', 300)
62-
.and('have.attr', 'height', 300)
70+
const root = cy.findByRole('chart').should('exist')
71+
if (!isHtml) {
72+
root.should('have.attr', 'width', 300).and('have.attr', 'height', 300)
73+
} else {
74+
root.should('have.css', 'width', `${300}px`).and('have.css', 'height', `${300}px`)
75+
}
6376
})
6477

6578
it('should support flexbox', () => {
@@ -78,10 +91,12 @@ export const testChartResponsiveness = (render: (defaults?: [number, number]) =>
7891
</div>
7992
)
8093

81-
cy.findByRole('chart')
82-
.should('exist')
83-
.and('have.attr', 'width', 500)
84-
.and('have.attr', 'height', 300)
94+
const root = cy.findByRole('chart').should('exist')
95+
if (!isHtml) {
96+
root.should('have.attr', 'width', 500).and('have.attr', 'height', 300)
97+
} else {
98+
root.should('have.css', 'width', `${500}px`).and('have.css', 'height', `${300}px`)
99+
}
85100
})
86101

87102
it('should support default dimensions', () => {

packages/circle-packing/src/CircleHtml.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ export const interpolateSize = (radiusValue: Interpolation<number>) =>
1313
export const interpolateBorderWidth = (borderWidth: number, radiusValue: Interpolation<number>) =>
1414
to([radiusValue], radius => Math.min(borderWidth, radius))
1515

16-
export const CircleHtml = <RawDatum,>({
16+
export const CircleHtml = <Datum,>({
1717
node,
1818
style,
1919
onMouseEnter,
2020
onMouseMove,
2121
onMouseLeave,
2222
onClick,
23-
}: CircleProps<RawDatum>) => {
23+
}: CircleProps<Datum>) => {
2424
const size = interpolateSize(style.radius)
2525

26-
const handlers = useNodeMouseHandlers<RawDatum>(node, {
26+
const handlers = useNodeMouseHandlers<Datum>(node, {
2727
onMouseEnter,
2828
onMouseMove,
2929
onMouseLeave,

0 commit comments

Comments
 (0)