Skip to content

Commit

Permalink
feat(sankey): use hooks instead of recompose and migrate to react-spring
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed Jun 21, 2020
1 parent 0760d94 commit b08c691
Show file tree
Hide file tree
Showing 12 changed files with 528 additions and 705 deletions.
5 changes: 2 additions & 3 deletions packages/sankey/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@
],
"dependencies": {
"@nivo/colors": "0.62.0",
"@nivo/core": "0.62.0",
"@nivo/legends": "0.62.0",
"@nivo/tooltip": "0.62.0",
"d3-sankey": "^0.12.1",
"d3-shape": "^1.3.5",
"lodash": "^4.17.11",
"react-motion": "^0.5.2",
"recompose": "^0.30.0"
"react-spring": "^8.0.27"
},
"peerDependencies": {
"@nivo/core": "0.62.0",
"prop-types": ">= 15.5.10 < 16.0.0",
"react": ">= 16.8.4 < 17.0.0"
},
Expand Down
285 changes: 136 additions & 149 deletions packages/sankey/src/Sankey.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,66 +8,85 @@
*/
import React, { Fragment } from 'react'
import { uniq } from 'lodash'
import { Container, SvgWrapper } from '@nivo/core'
import { SvgWrapper, useDimensions, withContainer } from '@nivo/core'
import { BoxLegendSvg } from '@nivo/legends'
import { SankeyPropTypes } from './props'
import enhance from './enhance'
import { SankeyDefaultProps, SankeyPropTypes } from './props'
import { useSankey } from './hooks'
import SankeyNodes from './SankeyNodes'
import SankeyLinks from './SankeyLinks'
import SankeyLabels from './SankeyLabels'

const Sankey = ({
nodes,
links,
data,
layout,

margin,
sort,
align,
width,
height,
outerWidth,
outerHeight,

margin: partialMargin,
colors,
nodeThickness,
nodeSpacing,
nodeInnerPadding,
nodeBorderColor,
nodeOpacity,
nodeHoverOpacity,
nodeHoverOthersOpacity,
nodeBorderWidth,
getNodeBorderColor, // computed
setCurrentNode, // injected
currentNode, // injected

linkOpacity,
linkHoverOpacity,
linkHoverOthersOpacity,
linkContract,
linkBlendMode,
enableLinkGradient,
setCurrentLink, // injected
currentLink, // injected

enableLabels,
labelPosition,
labelPadding,
labelOrientation,
getLabelTextColor, // computed

theme,

label,
labelFormat,
labelTextColor,
nodeTooltip,
linkTooltip,

animate,
motionDamping,
motionStiffness,

isInteractive,
onClick,
tooltipFormat,

legends,
legendData,

layers,
}) => {
const { margin, innerWidth, innerHeight, outerWidth, outerHeight } = useDimensions(
width,
height,
partialMargin
)

const {
nodes,
links,
legendData,
getNodeBorderColor,
currentNode,
setCurrentNode,
currentLink,
setCurrentLink,
getLabelTextColor,
} = useSankey({
data,
layout,
width: innerWidth,
height: innerHeight,
sort,
align,
colors,
nodeThickness,
nodeSpacing,
nodeInnerPadding,
nodeBorderColor,
label,
labelFormat,
labelTextColor,
})

let isCurrentNode = () => false
let isCurrentLink = () => false

Expand All @@ -94,133 +113,101 @@ const Sankey = ({
source.id === currentNode.id || target.id === currentNode.id
}

return (
<Container
isInteractive={isInteractive}
theme={theme}
animate={animate}
motionDamping={motionDamping}
motionStiffness={motionStiffness}
>
{({ showTooltip, hideTooltip }) => {
const layerProps = {
links,
nodes,
margin,
width,
height,
outerWidth,
outerHeight,
}
const layerProps = {
links,
nodes,
margin,
width,
height,
outerWidth,
outerHeight,
}

const layerById = {
links: (
<SankeyLinks
key="links"
links={links}
layout={layout}
linkContract={linkContract}
linkOpacity={linkOpacity}
linkHoverOpacity={linkHoverOpacity}
linkHoverOthersOpacity={linkHoverOthersOpacity}
linkBlendMode={linkBlendMode}
enableLinkGradient={enableLinkGradient}
showTooltip={showTooltip}
hideTooltip={hideTooltip}
setCurrentLink={setCurrentLink}
currentNode={currentNode}
currentLink={currentLink}
isCurrentLink={isCurrentLink}
onClick={onClick}
tooltip={linkTooltip}
theme={theme}
tooltipFormat={tooltipFormat}
animate={animate}
motionDamping={motionDamping}
motionStiffness={motionStiffness}
/>
),
nodes: (
<SankeyNodes
key="nodes"
nodes={nodes}
nodeOpacity={nodeOpacity}
nodeHoverOpacity={nodeHoverOpacity}
nodeHoverOthersOpacity={nodeHoverOthersOpacity}
nodeBorderWidth={nodeBorderWidth}
getNodeBorderColor={getNodeBorderColor}
showTooltip={showTooltip}
hideTooltip={hideTooltip}
setCurrentNode={setCurrentNode}
currentNode={currentNode}
currentLink={currentLink}
isCurrentNode={isCurrentNode}
onClick={onClick}
tooltip={nodeTooltip}
theme={theme}
tooltipFormat={tooltipFormat}
animate={animate}
motionDamping={motionDamping}
motionStiffness={motionStiffness}
/>
),
labels: null,
legends: legends.map((legend, i) => (
<BoxLegendSvg
key={`legend${i}`}
{...legend}
containerWidth={width}
containerHeight={height}
data={legendData}
theme={theme}
/>
)),
}
const layerById = {
links: (
<SankeyLinks
key="links"
links={links}
layout={layout}
linkContract={linkContract}
linkOpacity={linkOpacity}
linkHoverOpacity={linkHoverOpacity}
linkHoverOthersOpacity={linkHoverOthersOpacity}
linkBlendMode={linkBlendMode}
enableLinkGradient={enableLinkGradient}
setCurrentLink={setCurrentLink}
currentNode={currentNode}
currentLink={currentLink}
isCurrentLink={isCurrentLink}
isInteractive={isInteractive}
onClick={onClick}
tooltip={linkTooltip}
tooltipFormat={tooltipFormat}
/>
),
nodes: (
<SankeyNodes
key="nodes"
nodes={nodes}
nodeOpacity={nodeOpacity}
nodeHoverOpacity={nodeHoverOpacity}
nodeHoverOthersOpacity={nodeHoverOthersOpacity}
nodeBorderWidth={nodeBorderWidth}
getNodeBorderColor={getNodeBorderColor}
setCurrentNode={setCurrentNode}
currentNode={currentNode}
currentLink={currentLink}
isCurrentNode={isCurrentNode}
isInteractive={isInteractive}
onClick={onClick}
tooltip={nodeTooltip}
tooltipFormat={tooltipFormat}
/>
),
labels: null,
legends: legends.map((legend, i) => (
<BoxLegendSvg
key={`legend${i}`}
{...legend}
containerWidth={innerWidth}
containerHeight={innerHeight}
data={legendData}
/>
)),
}

if (enableLabels) {
layerById.labels = (
<SankeyLabels
key="labels"
nodes={nodes}
layout={layout}
width={width}
height={height}
labelPosition={labelPosition}
labelPadding={labelPadding}
labelOrientation={labelOrientation}
getLabelTextColor={getLabelTextColor}
theme={theme}
animate={animate}
motionDamping={motionDamping}
motionStiffness={motionStiffness}
/>
)
}
if (enableLabels) {
layerById.labels = (
<SankeyLabels
key="labels"
nodes={nodes}
layout={layout}
width={innerWidth}
height={innerHeight}
labelPosition={labelPosition}
labelPadding={labelPadding}
labelOrientation={labelOrientation}
getLabelTextColor={getLabelTextColor}
/>
)
}

return (
<SvgWrapper
width={outerWidth}
height={outerHeight}
margin={margin}
theme={theme}
>
{layers.map((layer, i) => {
if (typeof layer === 'function') {
return <Fragment key={i}>{layer(layerProps)}</Fragment>
}
return (
<SvgWrapper width={outerWidth} height={outerHeight} margin={margin}>
{layers.map((layer, i) => {
if (typeof layer === 'function') {
return <Fragment key={i}>{layer(layerProps)}</Fragment>
}

return layerById[layer]
})}
</SvgWrapper>
)
}}
</Container>
return layerById[layer]
})}
</SvgWrapper>
)
}

Sankey.propTypes = SankeyPropTypes

const enhancedSankey = enhance(Sankey)
enhancedSankey.displayName = 'Sankey'
const WrappedSankey = withContainer(Sankey)
WrappedSankey.defaultProps = SankeyDefaultProps

export default enhancedSankey
export default WrappedSankey
Loading

0 comments on commit b08c691

Please sign in to comment.