Skip to content

Commit

Permalink
Add support for custom tooltips in Funnel #1169
Browse files Browse the repository at this point in the history
  • Loading branch information
onionhammer authored and plouc committed Dec 30, 2021
1 parent 0feb061 commit e3a4b7b
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 4 deletions.
2 changes: 2 additions & 0 deletions packages/funnel/src/Funnel.tsx
Expand Up @@ -45,6 +45,7 @@ const InnerFunnel = <D extends FunnelDatum>({
onMouseMove,
onMouseLeave,
onClick,
tooltip,
role = svgDefaultProps.role,
ariaLabel,
ariaLabelledBy,
Expand Down Expand Up @@ -91,6 +92,7 @@ const InnerFunnel = <D extends FunnelDatum>({
onMouseMove,
onMouseLeave,
onClick,
tooltip,
})

const layerById: Record<FunnelLayerId, ReactNode> = {
Expand Down
2 changes: 1 addition & 1 deletion packages/funnel/src/PartTooltip.tsx
@@ -1,7 +1,7 @@
import { BasicTooltip } from '@nivo/tooltip'
import { FunnelDatum, FunnelPartWithHandlers } from './types'

interface PartTooltipProps<D extends FunnelDatum> {
export interface PartTooltipProps<D extends FunnelDatum> {
part: FunnelPartWithHandlers<D>
}

Expand Down
12 changes: 9 additions & 3 deletions packages/funnel/src/hooks.ts
Expand Up @@ -6,7 +6,7 @@ import { useTheme, useValueFormatter } from '@nivo/core'
import { useAnnotations } from '@nivo/annotations'
import { useTooltip, TooltipActionsContextData } from '@nivo/tooltip'
import { svgDefaultProps as defaults } from './props'
import { PartTooltip } from './PartTooltip'
import { PartTooltip, PartTooltipProps } from './PartTooltip'
import {
FunnelDatum,
FunnelCommonProps,
Expand Down Expand Up @@ -213,6 +213,7 @@ export const computePartsHandlers = <D extends FunnelDatum>({
onClick,
showTooltipFromEvent,
hideTooltip,
tooltip = PartTooltip,
}: {
parts: FunnelPart<D>[]
setCurrentPartId: (id: string | number | null) => void
Expand All @@ -223,13 +224,14 @@ export const computePartsHandlers = <D extends FunnelDatum>({
onClick?: FunnelCommonProps<D>['onClick']
showTooltipFromEvent: TooltipActionsContextData['showTooltipFromEvent']
hideTooltip: () => void
tooltip?: (props: PartTooltipProps<D>) => JSX.Element
}) => {
if (!isInteractive) return parts

return parts.map(part => {
const boundOnMouseEnter = (event: MouseEvent) => {
setCurrentPartId(part.data.id)
showTooltipFromEvent(createElement(PartTooltip, { part }), event)
showTooltipFromEvent(createElement(tooltip, { part }), event)
onMouseEnter !== undefined && onMouseEnter(part, event)
}

Expand All @@ -240,7 +242,7 @@ export const computePartsHandlers = <D extends FunnelDatum>({
}

const boundOnMouseMove = (event: MouseEvent) => {
showTooltipFromEvent(createElement(PartTooltip, { part }), event)
showTooltipFromEvent(createElement(tooltip, { part }), event)
onMouseMove !== undefined && onMouseMove(part, event)
}

Expand Down Expand Up @@ -296,6 +298,7 @@ export const useFunnel = <D extends FunnelDatum>({
onMouseMove,
onMouseLeave,
onClick,
tooltip,
}: {
data: FunnelDataProps<D>['data']
width: number
Expand Down Expand Up @@ -324,6 +327,7 @@ export const useFunnel = <D extends FunnelDatum>({
onMouseMove?: FunnelCommonProps<D>['onMouseMove']
onMouseLeave?: FunnelCommonProps<D>['onMouseLeave']
onClick?: FunnelCommonProps<D>['onClick']
tooltip?: (props: PartTooltipProps<D>) => JSX.Element
}) => {
const theme = useTheme()
const getColor = useOrdinalColorScale<D>(colors, 'id')
Expand Down Expand Up @@ -573,6 +577,7 @@ export const useFunnel = <D extends FunnelDatum>({
onClick,
showTooltipFromEvent,
hideTooltip,
tooltip,
}),
[
parts,
Expand All @@ -584,6 +589,7 @@ export const useFunnel = <D extends FunnelDatum>({
onClick,
showTooltipFromEvent,
hideTooltip,
tooltip,
]
)

Expand Down
2 changes: 2 additions & 0 deletions packages/funnel/src/types.ts
Expand Up @@ -3,6 +3,7 @@ import { Area, Line } from 'd3-shape'
import { Box, Theme, Dimensions, ModernMotionProps, ValueFormat } from '@nivo/core'
import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors'
import { AnnotationMatcher } from '@nivo/annotations'
import { PartTooltipProps } from './PartTooltip'

export interface FunnelDatum {
id: string | number
Expand Down Expand Up @@ -116,6 +117,7 @@ export interface FunnelCommonProps<D extends FunnelDatum> {
onMouseLeave: FunnelPartEventHandler<D>
onMouseMove: FunnelPartEventHandler<D>
onClick: FunnelPartEventHandler<D>
tooltip: (props: PartTooltipProps<D>) => JSX.Element

renderWrapper: boolean

Expand Down
65 changes: 65 additions & 0 deletions packages/funnel/stories/funnel.stories.tsx
@@ -0,0 +1,65 @@
import { withKnobs } from '@storybook/addon-knobs'
import { storiesOf } from '@storybook/react'

import { ResponsiveFunnel } from '../src'

const commonProps = {
data: [
{
id: 'step_sent',
value: 85523,
label: 'Sent',
},
{
id: 'step_viewed',
value: 74844,
label: 'Viewed',
},
{
id: 'step_clicked',
value: 62617,
label: 'Clicked',
},
{
id: 'step_add_to_card',
value: 50425,
label: 'Add To Card',
},
{
id: 'step_purchased',
value: 31139,
label: 'Purchased',
},
],
margin: { top: 20, right: 20, bottom: 20, left: 20 },
borderWidth: 20,
motionConfig: 'wobbly',
}

const stories = storiesOf('Funnel', module)

stories.addDecorator(withKnobs)

stories.add('custom tooltip', () => (
<div style={{ width: 900, height: 300 }}>
<ResponsiveFunnel
{...commonProps}
direction={'horizontal'}
tooltip={({ part }) => (
<div
style={{
padding: 12,
color: '#fff',
background: '#222222',
}}
>
<span>Look, I'm custom :)</span>
<br />
<strong>
{part.data.id}: {part.formattedValue}
</strong>
</div>
)}
/>
</div>
))

0 comments on commit e3a4b7b

Please sign in to comment.