Skip to content

Commit

Permalink
fix(bar): fix animations when swapping keys (#1656)
Browse files Browse the repository at this point in the history
  • Loading branch information
wyze committed Jul 6, 2021
1 parent 2e5df09 commit f665bc3
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 38 deletions.
84 changes: 67 additions & 17 deletions packages/bar/src/Bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
BarLayer,
BarLayerId,
BarSvgProps,
ComputedBarDatum,
ComputedBarDatumWithValue,
LegendData,
} from './types'
Expand Down Expand Up @@ -118,11 +117,17 @@ const InnerBar = <RawDatum extends BarDatum>({
)

const formatValue = useValueFormatter(valueFormat)
const getBorderColor = useInheritedColor<ComputedBarDatum<RawDatum>>(borderColor, theme)
const getBorderColor = useInheritedColor<ComputedBarDatumWithValue<RawDatum>>(
borderColor,
theme
)
const getColor = useOrdinalColorScale(colors, colorBy)
const getIndex = usePropertyAccessor(indexBy)
const getLabel = usePropertyAccessor(label)
const getLabelColor = useInheritedColor<ComputedBarDatum<RawDatum>>(labelTextColor, theme)
const getLabelColor = useInheritedColor<ComputedBarDatumWithValue<RawDatum>>(
labelTextColor,
theme
)
const getTooltipLabel = usePropertyAccessor(tooltipLabel)

const generateBars = groupMode === 'grouped' ? generateGroupedBars : generateStackedBars
Expand Down Expand Up @@ -164,23 +169,70 @@ const InnerBar = <RawDatum extends BarDatum>({
[result.bars]
)

const transition = useTransition(barsWithValue, {
keys: bar => bar.key,
enter: bar => ({
x: bar.width / 2,
y: bar.height / 2,
const transition = useTransition<
ComputedBarDatumWithValue<RawDatum>,
{
borderColor: string
color: string
height: number
labelColor: string
labelOpacity: number
labelX: number
labelY: number
opacity: number
transform: string
width: number
}
>(barsWithValue, {
keys: bar => `${bar.key}.${layout}.${reverse}.${groupMode}`,
from: bar => ({
borderColor: getBorderColor(bar) as string,
color: bar.color,
height: 0,
labelColor: getLabelColor(bar) as string,
labelOpacity: 0,
labelX: bar.width / 2,
labelY: bar.height / 2,
transform: `translate(${bar.x}, ${bar.y + bar.height})`,
width: bar.width,
height: bar.height,
...(layout === 'vertical'
? {}
: {
height: bar.height,
transform: `translate(${bar.x}, ${bar.y})`,
width: 0,
}),
}),
enter: bar => ({
borderColor: getBorderColor(bar) as string,
color: bar.color,
height: bar.height,
labelColor: getLabelColor(bar) as string,
labelOpacity: 1,
labelX: bar.width / 2,
labelY: bar.height / 2,
transform: `translate(${bar.x}, ${bar.y})`,
}),
update: bar => ({
x: bar.width / 2,
y: bar.height / 2,
width: bar.width,
height: bar.height,
}),
leave: bar => ({
borderColor: getBorderColor(bar) as string,
color: bar.color,
transform: `translate(${bar.x}, ${bar.y})`,
height: 0,
labelColor: getLabelColor(bar) as string,
labelOpacity: 0,
labelX: bar.width / 2,
labelY: 0,
transform: `translate(${bar.x}, ${bar.y + bar.height})`,
width: bar.width,
...(layout === 'vertical'
? {}
: {
labelX: 0,
labelY: bar.height / 2,
height: bar.height,
transform: `translate(${bar.x}, ${bar.y})`,
width: 0,
}),
}),
config: springConfig,
immediate: !animate,
Expand Down Expand Up @@ -271,8 +323,6 @@ const InnerBar = <RawDatum extends BarDatum>({
style,
shouldRenderLabel: shouldRenderLabel(bar),
label: getLabel(bar.data),
labelColor: getLabelColor(bar),
borderColor: getBorderColor(bar),
})
)}
</Fragment>
Expand Down
14 changes: 10 additions & 4 deletions packages/bar/src/BarCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,17 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
const { showTooltipFromEvent, hideTooltip } = useTooltip()

const formatValue = useValueFormatter(valueFormat)
const getBorderColor = useInheritedColor<ComputedBarDatum<RawDatum>>(borderColor, theme)
const getBorderColor = useInheritedColor<ComputedBarDatumWithValue<RawDatum>>(
borderColor,
theme
)
const getColor = useOrdinalColorScale(colors, colorBy)
const getIndex = usePropertyAccessor(indexBy)
const getLabel = usePropertyAccessor(label)
const getLabelColor = useInheritedColor<ComputedBarDatum<RawDatum>>(labelTextColor, theme)
const getLabelColor = useInheritedColor<ComputedBarDatumWithValue<RawDatum>>(
labelTextColor,
theme
)
const getTooltipLabel = usePropertyAccessor(tooltipLabel)

const options = {
Expand Down Expand Up @@ -362,11 +368,11 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
barsWithValue.forEach(bar => {
renderBar(ctx, {
bar,
borderColor: getBorderColor(bar),
borderColor: getBorderColor(bar) as string,
borderRadius,
borderWidth,
label: getLabel(bar.data),
labelColor: getLabelColor(bar),
labelColor: getLabelColor(bar) as string,
shouldRenderLabel: shouldRenderLabel(bar),
})
})
Expand Down
27 changes: 18 additions & 9 deletions packages/bar/src/BarItem.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import { BarDatum, BarItemProps } from './types'
import { animated } from '@react-spring/web'
import { animated, to } from '@react-spring/web'
import { createElement, useCallback } from 'react'
import { useTheme } from '@nivo/core'
import { useTooltip } from '@nivo/tooltip'

export const BarItem = <RawDatum extends BarDatum>({
bar: { data, ...bar },

style: { height, transform, width, x, y, ...style },
style: {
borderColor,
color,
height,
labelColor,
labelOpacity,
labelX,
labelY,
transform,
width,
},

borderRadius,
borderWidth,
borderColor,

label,
shouldRenderLabel,
labelColor,

isInteractive,
onClick,
Expand Down Expand Up @@ -56,11 +64,11 @@ export const BarItem = <RawDatum extends BarDatum>({
return (
<animated.g transform={transform}>
<animated.rect
width={width}
height={height}
width={to(width, value => Math.max(value, 0))}
height={to(height, value => Math.max(value, 0))}
rx={borderRadius}
ry={borderRadius}
fill={data.fill ?? style.color}
fill={data.fill ?? color}
strokeWidth={borderWidth}
stroke={borderColor}
onMouseEnter={isInteractive ? handleMouseEnter : undefined}
Expand All @@ -70,10 +78,11 @@ export const BarItem = <RawDatum extends BarDatum>({
/>
{shouldRenderLabel && (
<animated.text
x={x}
y={y}
x={labelX}
y={labelY}
textAnchor="middle"
dominantBaseline="central"
fillOpacity={labelOpacity}
style={{
...theme.labels.text,
pointerEvents: 'none',
Expand Down
20 changes: 12 additions & 8 deletions packages/bar/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,26 +143,30 @@ export interface BarItemProps<RawDatum>
}
}

borderColor: string

style: SpringValues<{
borderColor: string
color: string
height: number
labelColor: string
labelOpacity: number
labelX: number
labelY: number
opacity: number
transform: string
width: number
x: number
y: number
}>

label: string
labelColor: string
shouldRenderLabel: boolean
}

export type RenderBarProps<RawDatum> = Omit<
BarItemProps<RawDatum>,
'isInteractive' | 'style' | 'tooltip'
>
> & {
borderColor: string
labelColor: string
}

export interface BarTooltipProps<RawDatum> extends ComputedDatum<RawDatum> {
color: string
Expand Down Expand Up @@ -198,7 +202,7 @@ export type BarCommonProps<RawDatum> = {
enableGridY: boolean
gridYValues?: GridValues<string | number>

borderColor: InheritedColorConfig<ComputedBarDatum<RawDatum>>
borderColor: InheritedColorConfig<ComputedBarDatumWithValue<RawDatum>>
borderRadius: number
borderWidth: number

Expand All @@ -207,7 +211,7 @@ export type BarCommonProps<RawDatum> = {
labelFormat: string | LabelFormatter
labelSkipWidth: number
labelSkipHeight: number
labelTextColor: InheritedColorConfig<ComputedBarDatum<RawDatum>>
labelTextColor: InheritedColorConfig<ComputedBarDatumWithValue<RawDatum>>

isInteractive: boolean

Expand Down

0 comments on commit f665bc3

Please sign in to comment.