Skip to content

Commit

Permalink
feat(dendogram): add support for custom svg layers
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed May 2, 2024
1 parent fb854f5 commit 5ac5a4d
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 21 deletions.
22 changes: 14 additions & 8 deletions packages/dendogram/src/Dendogram.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createElement, Fragment, ReactNode } from 'react'
import { createElement, Fragment, ReactNode, useMemo } from 'react'
import { Container, useDimensions, SvgWrapper } from '@nivo/core'
import { DefaultDatum, LayerId, DendogramSvgProps } from './types'
import { DefaultDatum, LayerId, DendogramSvgProps, CustomLayerProps } from './types'
import { svgDefaultProps } from './defaults'
import { useDendogram } from './hooks'
import { Links } from './Links'
Expand All @@ -18,8 +18,9 @@ const InnerDendogram = <Datum extends object>({
data,
identity,
nodeComponent = svgDefaultProps.nodeComponent,
linkComponent = svgDefaultProps.linkComponent,
layout = svgDefaultProps.layout,
layers = svgDefaultProps.layers as LayerId[],
layers = svgDefaultProps.layers,
isInteractive = svgDefaultProps.isInteractive,
onNodeMouseEnter,
onNodeMouseMove,
Expand Down Expand Up @@ -52,7 +53,7 @@ const InnerDendogram = <Datum extends object>({
}

if (layers.includes('links')) {
layerById.links = <Links key="links" links={links} />
layerById.links = <Links<Datum> key="links" links={links} linkComponent={linkComponent} />
}

if (layers.includes('nodes')) {
Expand All @@ -71,10 +72,15 @@ const InnerDendogram = <Datum extends object>({
)
}

const customLayerProps = {} /*useCustomLayerProps<D>({
cells,
computedData,
})*/
const customLayerProps: CustomLayerProps<Datum> = useMemo(
() => ({
nodes,
links,
innerWidth,
innerHeight,
}),
[nodes, links, innerWidth, innerHeight]
)

return (
<SvgWrapper
Expand Down
8 changes: 2 additions & 6 deletions packages/dendogram/src/Link.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { ComputedLink } from './types'
import { LinkComponentProps } from './types'

interface LinkProps<Datum extends object> {
link: ComputedLink<Datum>
}

export const Link = <Datum extends object>({ link }: LinkProps<Datum>) => {
export const Link = <Datum extends object>({ link }: LinkComponentProps<Datum>) => {
// console.log(link)

return (
Expand Down
3 changes: 2 additions & 1 deletion packages/dendogram/src/Links.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ComputedLink } from './types'
import { ComputedLink, LinkComponent } from './types'
import { Link } from './Link'

interface LinksProps<Datum extends object> {
links: ComputedLink<Datum>[]
linkComponent: LinkComponent<Datum>
}

export const Links = <Datum extends object>({ links }: LinksProps<Datum>) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/dendogram/src/Nodes.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createElement } from 'react'
import { useTransition } from '@react-spring/web'
import { useMotionConfig } from '@nivo/core'
import { ComputedNode, NodeMouseEventHandler, DendogramSvgProps, NodeTooltip } from './types'
import { ComputedNode, NodeComponent, NodeMouseEventHandler, NodeTooltip } from './types'

interface NodesProps<Datum extends object> {
nodes: ComputedNode<Datum>[]
nodeComponent: Exclude<DendogramSvgProps<Datum>['nodeComponent'], undefined>
nodeComponent: NodeComponent<Datum>
isInteractive: boolean
onMouseEnter?: NodeMouseEventHandler<Datum>
onMouseMove?: NodeMouseEventHandler<Datum>
Expand Down
14 changes: 11 additions & 3 deletions packages/dendogram/src/defaults.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { CommonProps, DendogramSvgProps } from './types'
import { Node } from './Node'
import { Link } from './Link'

export const commonDefaultProps: any = {
export const commonDefaultProps: Pick<
CommonProps<any>,
'identity' | 'layout' | 'isInteractive' | 'role' | 'animate' | 'motionConfig'
> = {
identity: 'id',
layout: 'top-to-bottom',
layers: ['links', 'nodes', 'labels'],
isInteractive: true,
role: 'img',
animate: true,
motionConfig: 'gentle',
}

export const svgDefaultProps = {
export const svgDefaultProps: typeof commonDefaultProps &
Required<Pick<DendogramSvgProps<any>, 'layers' | 'nodeComponent' | 'linkComponent'>> = {
...commonDefaultProps,
layers: ['links', 'nodes', 'labels'],
nodeComponent: Node,
linkComponent: Link,
}
16 changes: 15 additions & 1 deletion packages/dendogram/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ export type NodeMouseEventHandler<Datum extends object> = (
event: MouseEvent
) => void

export interface LinkComponentProps<Datum extends object> {
link: ComputedLink<Datum>
}
export type LinkComponent<Datum extends object> = FunctionComponent<LinkComponentProps<Datum>>

export interface CustomLayerProps<Datum extends object> {
nodes: ComputedNode<Datum>[]
links: ComputedLink<Datum>[]
innerWidth: number
innerHeight: number
}
export type CustomSvgLayer<Datum extends object> = FunctionComponent<CustomLayerProps<Datum>>

export interface DendogramDataProps<Datum extends object> {
data: Datum
}
Expand Down Expand Up @@ -93,8 +106,9 @@ export interface CommonProps<Datum extends object> extends MotionProps {
export type DendogramSvgProps<Datum extends object> = DendogramDataProps<Datum> &
Dimensions &
Partial<CommonProps<Datum>> & {
layers?: LayerId[]
layers?: (LayerId | CustomSvgLayer<Datum>)[]
nodeComponent?: NodeComponent<Datum>
linkComponent?: LinkComponent<Datum>
}

export type ResponsiveDendogramSvgProps<Datum extends object> = Omit<
Expand Down

0 comments on commit 5ac5a4d

Please sign in to comment.