Skip to content

Commit

Permalink
feat(bump): add tests for the AreaBump chart
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed Dec 29, 2021
1 parent 6bb16dc commit 3f5ed41
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/bump/src/area-bump/Area.tsx
Expand Up @@ -64,6 +64,7 @@ export const Area = <Datum extends AreaBumpDatum, ExtraProps extends AreaBumpSer

return (
<animated.path
data-testid={`area.${serie.id}`}
d={animatedPath}
fill={serie.fill ? serie.fill : animatedProps.color}
fillOpacity={animatedProps.fillOpacity}
Expand Down
4 changes: 2 additions & 2 deletions packages/bump/src/area-bump/AreaBump.tsx
Expand Up @@ -182,7 +182,7 @@ const InnerAreaBump = <Datum extends AreaBumpDatum, ExtraProps extends AreaBumpS
<Fragment key="labels">
{startLabel !== false && (
<AreasLabels<Datum, ExtraProps>
label={startLabel}
getLabel={startLabel}
series={series}
position="start"
padding={startLabelPadding}
Expand All @@ -191,7 +191,7 @@ const InnerAreaBump = <Datum extends AreaBumpDatum, ExtraProps extends AreaBumpS
)}
{endLabel !== false && (
<AreasLabels<Datum, ExtraProps>
label={endLabel}
getLabel={endLabel}
series={series}
position="end"
padding={endLabelPadding}
Expand Down
7 changes: 4 additions & 3 deletions packages/bump/src/area-bump/AreasLabels.tsx
Expand Up @@ -10,7 +10,7 @@ import {
import { useAreaBumpSeriesLabels } from './hooks'

interface AreaLabelsProps<Datum extends AreaBumpDatum, ExtraProps extends AreaBumpSerieExtraProps> {
label: Exclude<AreaBumpLabel<Datum, ExtraProps>, false>
getLabel: Exclude<AreaBumpLabel<Datum, ExtraProps>, false>
series: AreaBumpComputedSerie<Datum, ExtraProps>[]
position: 'start' | 'end'
padding: number
Expand All @@ -21,7 +21,7 @@ export const AreasLabels = <
Datum extends AreaBumpDatum,
ExtraProps extends AreaBumpSerieExtraProps
>({
label,
getLabel,
series,
position,
padding,
Expand All @@ -31,7 +31,7 @@ export const AreasLabels = <
const { animate, config: springConfig } = useMotionConfig()

const labels = useAreaBumpSeriesLabels<Datum, ExtraProps>({
label,
getLabel,
series,
position,
padding,
Expand Down Expand Up @@ -60,6 +60,7 @@ export const AreasLabels = <

return (
<animated.text
data-testid={`label.${position}.${label.serie.id}`}
key={label.id}
x={animatedProps.x}
y={animatedProps.y}
Expand Down
2 changes: 1 addition & 1 deletion packages/bump/src/area-bump/defaults.ts
Expand Up @@ -36,7 +36,7 @@ const commonDefaultProps: Omit<
startLabel: false,
startLabelPadding: 12,
startLabelTextColor: { from: 'color', modifiers: [['darker', 1]] },
endLabel: 'id',
endLabel: true,
endLabelPadding: 12,
endLabelTextColor: { from: 'color', modifiers: [['darker', 1]] },

Expand Down
15 changes: 9 additions & 6 deletions packages/bump/src/area-bump/hooks.ts
@@ -1,6 +1,6 @@
import { createElement, useMemo, useCallback, useState } from 'react'
import { area as d3Area, curveBasis, curveLinear } from 'd3-shape'
import { useTheme, usePropertyAccessor } from '@nivo/core'
import { useTheme } from '@nivo/core'
import { useOrdinalColorScale, useInheritedColor, InheritedColorConfig } from '@nivo/colors'
import { useTooltip } from '@nivo/tooltip'
import { computeSeries } from './compute'
Expand Down Expand Up @@ -321,23 +321,21 @@ export const useAreaBumpSeriesLabels = <
Datum extends AreaBumpDatum,
ExtraProps extends AreaBumpSerieExtraProps
>({
label,
series,
position,
padding,
color,
getLabel,
}: {
label: Exclude<AreaBumpLabel<Datum, ExtraProps>, false>
series: AreaBumpComputedSerie<Datum, ExtraProps>[]
position: 'start' | 'end'
padding: number
color: InheritedColorConfig<AreaBumpComputedSerie<Datum, ExtraProps>>
getLabel: Exclude<AreaBumpLabel<Datum, ExtraProps>, false>
}): AreaBumpLabelData<Datum, ExtraProps>[] => {
const theme = useTheme()
const getColor = useInheritedColor(color, theme)

const getLabel = usePropertyAccessor(label)

return useMemo(() => {
let textAnchor: 'start' | 'end'
let signedPadding: number
Expand All @@ -350,12 +348,17 @@ export const useAreaBumpSeriesLabels = <
}

return series.map(serie => {
let label = serie.id
if (typeof getLabel === 'function') {
label = getLabel(serie.data)
}

const point =
position === 'start' ? serie.points[0] : serie.points[serie.points.length - 1]

return {
id: serie.id,
label: getLabel(serie.data),
label,
x: point.x + signedPadding,
y: point.y,
color: getColor(serie),
Expand Down
3 changes: 1 addition & 2 deletions packages/bump/src/area-bump/types.ts
@@ -1,7 +1,6 @@
import { FunctionComponent, MouseEvent } from 'react'
import { Area } from 'd3-shape'
import {
PropertyAccessor,
Box,
Theme,
Dimensions,
Expand Down Expand Up @@ -78,7 +77,7 @@ export type AreaBumpInterpolation = 'smooth' | 'linear'
export type AreaBumpLabel<
Datum extends AreaBumpDatum,
ExtraProps extends AreaBumpSerieExtraProps
> = PropertyAccessor<AreaBumpSerie<Datum, ExtraProps>, string> | false
> = ((serie: AreaBumpSerie<Datum, ExtraProps>) => string) | boolean
export interface AreaBumpLabelData<
Datum extends AreaBumpDatum,
ExtraProps extends AreaBumpSerieExtraProps
Expand Down
2 changes: 1 addition & 1 deletion packages/bump/src/bump/LinesLabels.tsx
Expand Up @@ -6,7 +6,7 @@ import { useBumpSeriesLabels } from './hooks'

interface LineLabelsProps<Datum extends BumpDatum, ExtraProps extends BumpSerieExtraProps> {
series: BumpComputedSerie<Datum, ExtraProps>[]
getLabel: BumpLabel<Datum, ExtraProps>
getLabel: Exclude<BumpLabel<Datum, ExtraProps>, false>
position: 'start' | 'end'
padding: number
color: InheritedColorConfig<BumpComputedSerie<Datum, ExtraProps>>
Expand Down
2 changes: 1 addition & 1 deletion packages/bump/src/bump/hooks.ts
Expand Up @@ -384,7 +384,7 @@ export const useBumpSeriesLabels = <
position: 'start' | 'end'
padding: number
color: InheritedColorConfig<BumpComputedSerie<Datum, ExtraProps>>
getLabel: BumpLabel<Datum, ExtraProps>
getLabel: Exclude<BumpLabel<Datum, ExtraProps>, false>
}) => {
const theme = useTheme()
const getColor = useInheritedColor(color, theme)
Expand Down
190 changes: 190 additions & 0 deletions packages/bump/tests/AreaBump.test.tsx
@@ -0,0 +1,190 @@
import { mount } from 'enzyme'
// @ts-ignore
import { AreaBump, AreaBumpSvgProps } from '../src'

interface Datum {
x: number
y: number
}

const sampleData: AreaBumpSvgProps<Datum, Record<string, unknown>>['data'] = [
{
id: 'A',
data: [
{
x: 2000,
y: 9,
},
{
x: 2001,
y: 9,
},
{
x: 2002,
y: 2,
},
{
x: 2003,
y: 4,
},
],
},
{
id: 'B',
data: [
{
x: 2000,
y: 8,
},
{
x: 2001,
y: 3,
},
{
x: 2002,
y: 1,
},
{
x: 2003,
y: 7,
},
],
},
{
id: 'C',
data: [
{
x: 2000,
y: 12,
},
{
x: 2001,
y: 4,
},
{
x: 2002,
y: 5,
},
{
x: 2003,
y: 6,
},
],
},
]

const baseProps: AreaBumpSvgProps<Datum, Record<string, unknown>> = {
width: 800,
height: 600,
data: sampleData,
animate: false,
}

it('should render a basic area bump chart', () => {
const wrapper = mount(<AreaBump<Datum> {...baseProps} />)

const areaA = wrapper.find(`path[data-testid='area.A']`)
expect(areaA.exists()).toBeTruthy()

const areaB = wrapper.find(`path[data-testid='area.B']`)
expect(areaB.exists()).toBeTruthy()

const areaC = wrapper.find(`path[data-testid='area.C']`)
expect(areaC.exists()).toBeTruthy()
})

describe('style', () => {
it('custom colors array', () => {
const colors = ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)', 'rgba(0, 0, 255, 1)']
const wrapper = mount(<AreaBump<Datum> {...baseProps} colors={colors} />)

expect(wrapper.find(`path[data-testid='area.A']`).prop('fill')).toEqual(colors[0])
expect(wrapper.find(`path[data-testid='area.B']`).prop('fill')).toEqual(colors[1])
expect(wrapper.find(`path[data-testid='area.C']`).prop('fill')).toEqual(colors[2])
})

it('colors from data', () => {
const colors = ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)', 'rgba(0, 0, 255, 1)']
const wrapper = mount(
<AreaBump<Datum, { color: string }>
{...baseProps}
data={sampleData.map((serie, i) => ({
...serie,
color: colors[i],
}))}
colors={serie => serie.color}
/>
)

expect(wrapper.find(`path[data-testid='area.A']`).prop('fill')).toEqual(colors[0])
expect(wrapper.find(`path[data-testid='area.B']`).prop('fill')).toEqual(colors[1])
expect(wrapper.find(`path[data-testid='area.C']`).prop('fill')).toEqual(colors[2])
})
})

describe('labels', () => {
it('default end labels', () => {
const wrapper = mount(<AreaBump<Datum> {...baseProps} />)

const endLabelA = wrapper.find(`text[data-testid='label.end.A']`)
expect(endLabelA.exists()).toBeTruthy()
expect(endLabelA.text()).toEqual('A')
expect(endLabelA.prop('textAnchor')).toEqual('start')

const endLabelB = wrapper.find(`text[data-testid='label.end.B']`)
expect(endLabelB.exists()).toBeTruthy()
expect(endLabelB.text()).toEqual('B')
expect(endLabelB.prop('textAnchor')).toEqual('start')

const endLabelC = wrapper.find(`text[data-testid='label.end.C']`)
expect(endLabelC.exists()).toBeTruthy()
expect(endLabelC.text()).toEqual('C')
expect(endLabelC.prop('textAnchor')).toEqual('start')
})

it('customize end labels', () => {
const wrapper = mount(
<AreaBump<Datum> {...baseProps} endLabel={serie => `Serie ${serie.id}`} />
)

expect(wrapper.find(`text[data-testid='label.end.A']`).text()).toEqual('Serie A')
expect(wrapper.find(`text[data-testid='label.end.B']`).text()).toEqual('Serie B')
expect(wrapper.find(`text[data-testid='label.end.C']`).text()).toEqual('Serie C')
})

it('label from data', () => {
const wrapper = mount(
<AreaBump<Datum, { label: string }>
{...baseProps}
data={sampleData.map(serie => ({
...serie,
label: `Serie ${serie.id} label`,
}))}
endLabel={serie => serie.label}
/>
)

expect(wrapper.find(`text[data-testid='label.end.A']`).text()).toEqual('Serie A label')
expect(wrapper.find(`text[data-testid='label.end.B']`).text()).toEqual('Serie B label')
expect(wrapper.find(`text[data-testid='label.end.C']`).text()).toEqual('Serie C label')
})

it('start labels', () => {
const wrapper = mount(<AreaBump<Datum> {...baseProps} startLabel />)

const startLabelA = wrapper.find(`text[data-testid='label.start.A']`)
expect(startLabelA.exists()).toBeTruthy()
expect(startLabelA.text()).toEqual('A')
expect(startLabelA.prop('textAnchor')).toEqual('end')

const startLabelB = wrapper.find(`text[data-testid='label.start.B']`)
expect(startLabelB.exists()).toBeTruthy()
expect(startLabelB.text()).toEqual('B')
expect(startLabelB.prop('textAnchor')).toEqual('end')

const startLabelC = wrapper.find(`text[data-testid='label.start.C']`)
expect(startLabelC.exists()).toBeTruthy()
expect(startLabelC.text()).toEqual('C')
expect(startLabelC.prop('textAnchor')).toEqual('end')
})
})

0 comments on commit 3f5ed41

Please sign in to comment.