Skip to content

Commit

Permalink
fix(axes): restore memoization (#1521)
Browse files Browse the repository at this point in the history
Co-authored-by: Neil Kistner <[email protected]>
  • Loading branch information
cameronevans and wyze authored May 22, 2021
1 parent 5580e96 commit 729cd55
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 115 deletions.
95 changes: 49 additions & 46 deletions packages/axes/src/components/Axes.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,57 @@
import React from 'react'
import React, { memo } from 'react'
import { Axis } from './Axis'
import { positions } from '../props'
import { AnyScale, AxisProps, AxisValue } from '../types'

export const Axes = <X extends AxisValue, Y extends AxisValue>({
xScale,
yScale,
width,
height,
top,
right,
bottom,
left,
}: {
xScale: AnyScale
yScale: AnyScale
width: number
height: number
top?: AxisProps<X>
right?: AxisProps<Y>
bottom?: AxisProps<X>
left?: AxisProps<Y>
}) => {
const axes = { top, right, bottom, left }
export const Axes = memo(
<X extends AxisValue, Y extends AxisValue>({
xScale,
yScale,
width,
height,
top,
right,
bottom,
left,
}: {
xScale: AnyScale
yScale: AnyScale
width: number
height: number
top?: AxisProps<X>
right?: AxisProps<Y>
bottom?: AxisProps<X>
left?: AxisProps<Y>
}) => {
const axes = { top, right, bottom, left }

return (
<>
{positions.map(position => {
const axis = axes[position] as typeof position extends 'bottom' | 'top'
? AxisProps<X> | undefined
: AxisProps<Y> | undefined
return (
<>
{positions.map(position => {
const axis = axes[position] as typeof position extends 'bottom' | 'top'
? AxisProps<X> | undefined
: AxisProps<Y> | undefined

if (!axis) return null
if (!axis) return null

const isXAxis = position === 'top' || position === 'bottom'
const ticksPosition = position === 'top' || position === 'left' ? 'before' : 'after'
const isXAxis = position === 'top' || position === 'bottom'
const ticksPosition =
position === 'top' || position === 'left' ? 'before' : 'after'

return (
<Axis
key={position}
{...axis}
axis={isXAxis ? 'x' : 'y'}
x={position === 'right' ? width : 0}
y={position === 'bottom' ? height : 0}
scale={isXAxis ? xScale : yScale}
length={isXAxis ? width : height}
ticksPosition={ticksPosition}
/>
)
})}
</>
)
}
return (
<Axis
key={position}
{...axis}
axis={isXAxis ? 'x' : 'y'}
x={position === 'right' ? width : 0}
y={position === 'bottom' ? height : 0}
scale={isXAxis ? xScale : yScale}
length={isXAxis ? width : height}
ticksPosition={ticksPosition}
/>
)
})}
</>
)
}
)
8 changes: 6 additions & 2 deletions packages/axes/src/components/Axis.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useMemo } from 'react'
import React, { useMemo, memo } from 'react'
import { useSpring, useTransition, animated } from '@react-spring/web'
import { useTheme, useMotionConfig } from '@nivo/core'
import { computeCartesianTicks, getFormatter } from '../compute'
import { AxisTick } from './AxisTick'
import { AnyScale, AxisProps, AxisValue } from '../types'

export const Axis = <Value extends AxisValue>({
const Axis = <Value extends AxisValue>({
axis,
scale,
x = 0,
Expand Down Expand Up @@ -158,3 +158,7 @@ export const Axis = <Value extends AxisValue>({
</animated.g>
)
}

const memoizedAxis = memo(Axis) as typeof Axis

export { memoizedAxis as Axis }
8 changes: 6 additions & 2 deletions packages/axes/src/components/AxisTick.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useMemo } from 'react'
import React, { useMemo, memo } from 'react'
import { animated } from '@react-spring/web'
import { useTheme } from '@nivo/core'
import { AxisTickProps, AxisValue } from '../types'

export const AxisTick = <Value extends AxisValue>({
const AxisTick = <Value extends AxisValue>({
value: _value,
format,
lineX,
Expand Down Expand Up @@ -44,3 +44,7 @@ export const AxisTick = <Value extends AxisValue>({
</animated.g>
)
}

const memoizedAxisTick = memo(AxisTick) as typeof AxisTick

export { memoizedAxisTick as AxisTick }
88 changes: 45 additions & 43 deletions packages/axes/src/components/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,53 @@
import React, { useMemo } from 'react'
import React, { useMemo, memo } from 'react'
import { GridLines } from './GridLines'
import { computeGridLines } from '../compute'
import { AnyScale, AxisValue } from '../types'

export const Grid = <X extends AxisValue, Y extends AxisValue>({
width,
height,
xScale,
yScale,
xValues,
yValues,
}: {
width: number
height: number
xScale?: AnyScale
xValues?: number | X[]
yScale?: AnyScale
yValues?: number | Y[]
}) => {
const xLines = useMemo(() => {
if (!xScale) return false
export const Grid = memo(
<X extends AxisValue, Y extends AxisValue>({
width,
height,
xScale,
yScale,
xValues,
yValues,
}: {
width: number
height: number
xScale?: AnyScale
xValues?: number | X[]
yScale?: AnyScale
yValues?: number | Y[]
}) => {
const xLines = useMemo(() => {
if (!xScale) return false

return computeGridLines({
width,
height,
scale: xScale,
axis: 'x',
values: xValues,
})
}, [xScale, xValues, width, height])
return computeGridLines({
width,
height,
scale: xScale,
axis: 'x',
values: xValues,
})
}, [xScale, xValues, width, height])

const yLines = useMemo(() => {
if (!yScale) return false
const yLines = useMemo(() => {
if (!yScale) return false

return computeGridLines({
width,
height,
scale: yScale,
axis: 'y',
values: yValues,
})
}, [height, width, yScale, yValues])
return computeGridLines({
width,
height,
scale: yScale,
axis: 'y',
values: yValues,
})
}, [height, width, yScale, yValues])

return (
<>
{xLines && <GridLines lines={xLines} />}
{yLines && <GridLines lines={yLines} />}
</>
)
}
return (
<>
{xLines && <GridLines lines={xLines} />}
{yLines && <GridLines lines={yLines} />}
</>
)
}
)
32 changes: 17 additions & 15 deletions packages/axes/src/components/GridLine.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import React from 'react'
import React, { memo } from 'react'
import { SpringValues, animated } from '@react-spring/web'
import { useTheme } from '@nivo/core'

export const GridLine = ({
animatedProps,
}: {
animatedProps: SpringValues<{
opacity: number
x1: number
x2: number
y1: number
y2: number
}>
}) => {
const theme = useTheme()
export const GridLine = memo(
({
animatedProps,
}: {
animatedProps: SpringValues<{
opacity: number
x1: number
x2: number
y1: number
y2: number
}>
}) => {
const theme = useTheme()

return <animated.line {...animatedProps} {...(theme.grid.line as unknown)} />
}
return <animated.line {...animatedProps} {...(theme.grid.line as unknown)} />
}
)
6 changes: 3 additions & 3 deletions packages/axes/src/components/GridLines.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react'
import React, { memo } from 'react'
import { useTransition } from '@react-spring/web'
import { useMotionConfig } from '@nivo/core'
import { GridLine } from './GridLine'
import { Line } from '../types'

export const GridLines = ({ lines }: { lines: Line[] }) => {
export const GridLines = memo(({ lines }: { lines: Line[] }) => {
const { animate, config: springConfig } = useMotionConfig()

const transition = useTransition<Line, Record<'opacity' | 'x1' | 'x2' | 'y1' | 'y2', number>>(
Expand Down Expand Up @@ -54,4 +54,4 @@ export const GridLines = ({ lines }: { lines: Line[] }) => {
))}
</g>
)
}
})
5 changes: 2 additions & 3 deletions packages/bullet/tests/Bullet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('Bullet', () => {
it('should use horizontal layout by default', () => {
const wrapper = mount(<Bullet width={300} height={300} data={sampleData} />)
const items = wrapper.find('BulletItem')
const ticks = wrapper.find('Axis').first().find('AxisTick')
const ticks = wrapper.find('Memo(Axis)').first().find('Memo(AxisTick)')

expect(
ticks.map(el => el.prop('animatedProps').transform.get()).join('; ')
Expand All @@ -83,8 +83,7 @@ describe('Bullet', () => {
it('should support reverse layout', () => {
const wrapper = mount(<Bullet width={300} height={300} data={sampleData} reverse />)
const items = wrapper.find('BulletItem')
const ticks = wrapper.find('Axis').first().find('AxisTick')

const ticks = wrapper.find('Memo(Axis)').first().find('Memo(AxisTick)')
expect(
ticks.map(el => el.prop('animatedProps').transform.get()).join('; ')
).toMatchInlineSnapshot(
Expand Down
2 changes: 1 addition & 1 deletion packages/line/tests/Line.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ it('should have left and bottom axis by default', () => {
]
const wrapper = mount(<Line width={500} height={300} data={data} animate={false} />)

const axes = wrapper.find('Axis')
const axes = wrapper.find('Memo(Axis)')
expect(axes).toHaveLength(2)
expect(axes.at(0).prop('axis')).toBe('x')
expect(axes.at(1).prop('axis')).toBe('y')
Expand Down

0 comments on commit 729cd55

Please sign in to comment.