diff --git a/packages/marimekko/src/Bar.tsx b/packages/marimekko/src/Bar.tsx index 0cd36af0f..9d420b2ec 100644 --- a/packages/marimekko/src/Bar.tsx +++ b/packages/marimekko/src/Bar.tsx @@ -1,13 +1,11 @@ import React, { createElement, MouseEvent } from 'react' -import { animated, SpringValues } from 'react-spring' +import { animated, SpringValues, to } from 'react-spring' import { useTooltip } from '@nivo/tooltip' -import { DimensionDatum } from './types' +import { BarDatum } from './types' import { BarTooltip } from './BarTooltip' interface BarProps { - datum: DimensionDatum - borderWidth: number - borderColor: string + bar: BarDatum animatedProps: SpringValues<{ x: number y: number @@ -19,12 +17,12 @@ interface BarProps { }> } -export const Bar = ({ datum, borderWidth, animatedProps }: BarProps) => { +export const Bar = ({ bar, animatedProps }: BarProps) => { const { showTooltipFromEvent, hideTooltip } = useTooltip() const handle = (event: MouseEvent) => { showTooltipFromEvent( - createElement<{ datum: DimensionDatum }>(BarTooltip, { datum }), + createElement<{ bar: BarDatum }>(BarTooltip, { bar }), event ) } @@ -33,11 +31,11 @@ export const Bar = ({ datum, borderWidth, animatedProps }: BarProps Math.max(value, 0))} + height={to(animatedProps.height, value => Math.max(value, 0))} fill={animatedProps.color} stroke={animatedProps.borderColor} - strokeWidth={borderWidth} + strokeWidth={bar.borderWidth} onMouseEnter={handle} onMouseMove={handle} onMouseLeave={hideTooltip} diff --git a/packages/marimekko/src/BarTooltip.tsx b/packages/marimekko/src/BarTooltip.tsx index 153041c15..9a6da368b 100644 --- a/packages/marimekko/src/BarTooltip.tsx +++ b/packages/marimekko/src/BarTooltip.tsx @@ -1,12 +1,12 @@ import React from 'react' import { BasicTooltip } from '@nivo/tooltip' -import { DimensionDatum } from './types' +import { BarDatum } from './types' -export const BarTooltip = ({ datum }: { datum: DimensionDatum }) => ( +export const BarTooltip = ({ bar }: { bar: BarDatum }) => ( ) diff --git a/packages/marimekko/src/Bars.tsx b/packages/marimekko/src/Bars.tsx index 7cab5fc89..d0bb6303e 100644 --- a/packages/marimekko/src/Bars.tsx +++ b/packages/marimekko/src/Bars.tsx @@ -1,43 +1,15 @@ -import React, { useMemo } from 'react' +import React from 'react' import { useTransition, config } from 'react-spring' -// @ts-ignore -import { useTheme } from '@nivo/core' -import { InheritedColorConfig, useInheritedColor } from '@nivo/colors' -import { ComputedDatum, DimensionDatum } from './types' +import { BarDatum } from './types' import { Bar } from './Bar' interface BarsProps { - data: ComputedDatum[] - borderWidth: number - borderColor: InheritedColorConfig> + bars: BarDatum[] } -interface BarData extends DimensionDatum { - key: string - borderColor: string -} - -export const Bars = ({ data, borderWidth, borderColor }: BarsProps) => { - const theme = useTheme() - const getBorderColor = useInheritedColor>(borderColor, theme) - - const allBars = useMemo(() => { - const all: BarData[] = [] - data.forEach(datum => { - datum.dimensions.forEach(dimension => { - all.push({ - key: `${datum.id}-${dimension.id}`, - ...dimension, - borderColor: getBorderColor(dimension), - }) - }) - }) - - return all - }, [data, borderWidth, getBorderColor]) - +export const Bars = ({ bars }: BarsProps) => { const transition = useTransition< - BarData, + BarDatum, { x: number y: number @@ -47,7 +19,7 @@ export const Bars = ({ data, borderWidth, borderColor }: BarsProps(allBars, { + >(bars, { key: bar => bar.key, initial: bar => ({ x: bar.x, @@ -100,15 +72,7 @@ export const Bars = ({ data, borderWidth, borderColor }: BarsProps {transition((style, bar) => { - return ( - - key={bar.key} - datum={bar} - borderWidth={borderWidth} - borderColor={bar.borderColor} - animatedProps={style} - /> - ) + return key={bar.key} bar={bar} animatedProps={style} /> })} ) diff --git a/packages/marimekko/src/Marimekko.tsx b/packages/marimekko/src/Marimekko.tsx index ffea4682d..90b81892b 100644 --- a/packages/marimekko/src/Marimekko.tsx +++ b/packages/marimekko/src/Marimekko.tsx @@ -3,7 +3,7 @@ import { Container, SvgWrapper, useDimensions } from '@nivo/core' import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors' import { SvgProps, LayerId, DimensionDatum } from './types' import { defaultProps } from './props' -import { useMarimekko } from './hooks' +import { useMarimekko, useLayerContext } from './hooks' import { Bars } from './Bars' const InnerMarimekko = ({ @@ -29,13 +29,15 @@ const InnerMarimekko = ({ partialMargin ) - const { computedData } = useMarimekko({ + const { computedData, bars } = useMarimekko({ data, id, value, - colors, dimensions, layout, + colors, + borderColor, + borderWidth, width: innerWidth, height: innerHeight, }) @@ -47,16 +49,12 @@ const InnerMarimekko = ({ legends: null, } - layerById.bars = ( - - key="bars" - data={computedData} - borderWidth={borderWidth} - borderColor={borderColor} - /> - ) + layerById.bars = key="bars" bars={bars} /> - const layerContext: any = {} + const layerContext = useLayerContext({ + data: computedData, + bars, + }) return ( ({ return computedData } +export const useBars = ( + data: ComputedDatum[], + borderColor: InheritedColorConfig>, + borderWidth: number +) => { + const theme = useTheme() + const getBorderColor = useInheritedColor>(borderColor, theme) + + return useMemo(() => { + const all: BarDatum[] = [] + data.forEach(datum => { + datum.dimensions.forEach(dimension => { + all.push({ + key: `${datum.id}-${dimension.id}`, + ...dimension, + borderColor: getBorderColor(dimension), + borderWidth, + }) + }) + }) + + return all + }, [data, borderWidth, getBorderColor]) +} + export const useMarimekko = ({ data, id, @@ -219,6 +248,8 @@ export const useMarimekko = ({ dimensions: rawDimensions, layout, colors, + borderColor, + borderWidth, width, height, }: { @@ -228,6 +259,8 @@ export const useMarimekko = ({ dimensions: DataProps['dimensions'] layout: Layout colors: CommonProps['colors'] + borderColor: InheritedColorConfig> + borderWidth: number width: number height: number }) => { @@ -246,8 +279,25 @@ export const useMarimekko = ({ colors, layout, }) + const bars = useBars(computedData, borderColor, borderWidth) return { computedData, + bars, } } + +export const useLayerContext = ({ + data, + bars, +}: { + data: ComputedDatum[] + bars: BarDatum[] +}): CustomLayerProps => + useMemo( + () => ({ + data, + bars, + }), + [data, bars] + ) diff --git a/packages/marimekko/src/types.ts b/packages/marimekko/src/types.ts index e45cf9dcc..53fb644b2 100644 --- a/packages/marimekko/src/types.ts +++ b/packages/marimekko/src/types.ts @@ -45,12 +45,19 @@ export interface ComputedDatum extends NormalizedDatum { dimensions: DimensionDatum[] } +export interface BarDatum extends DimensionDatum { + key: string + borderColor: string + borderWidth: number +} + export type LabelAccessorFunction = (datum: ComputedDatum) => string | number export type LayerId = 'grid' | 'axes' | 'bars' | 'legends' export interface CustomLayerProps { - nodes: ComputedDatum + data: ComputedDatum[] + bars: BarDatum[] } export type CustomLayer = React.FC> diff --git a/website/src/data/components/marimekko/props.js b/website/src/data/components/marimekko/props.js index c33690a7e..b9a155e93 100644 --- a/website/src/data/components/marimekko/props.js +++ b/website/src/data/components/marimekko/props.js @@ -50,11 +50,19 @@ const props = [ help: 'Value accessor.', description: ` Define how to access the value of each datum, + wich is gonna dictate the thickness of the bars, by default, nivo will look for the \`value\` property. `, type: 'string | (datum: RawDatum): number', required: true, }, + { + key: 'dimensions', + group: 'Base', + help: 'Data dimensions configuration.', + type: '{ id: string, value: string | (datum: RawDatum) => number }', + required: true, + }, { key: 'valueFormat', group: 'Base',