Skip to content

Commit

Permalink
feat(sankey): move computing out of the rendering component
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored and Raphaël Benitte committed Mar 23, 2019
1 parent f63450f commit a0c29fe
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 60 deletions.
61 changes: 10 additions & 51 deletions packages/sankey/src/Sankey.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,18 @@
* file that was distributed with this source code.
*/
import React from 'react'
import cloneDeep from 'lodash/cloneDeep'
import uniq from 'lodash/uniq'
import { sankey as d3Sankey } from 'd3-sankey'
import { uniq } from 'lodash'
import { Container, SvgWrapper } from '@nivo/core'
import { BoxLegendSvg } from '@nivo/legends'
import { SankeyPropTypes } from './props'
import enhance from './enhance'
import SankeyNodes from './SankeyNodes'
import SankeyLinks from './SankeyLinks'
import SankeyLabels from './SankeyLabels'
import { SankeyPropTypes, sankeyAlignmentFromProp } from './props'
import enhance from './enhance'

const getId = d => d.id

const Sankey = ({
data: _data,

align,
sortFunction,
nodes,
links,

margin,
width,
Expand All @@ -35,9 +29,7 @@ const Sankey = ({
nodeOpacity,
nodeHoverOpacity,
nodeHoverOthersOpacity,
nodeWidth,
nodePaddingX,
nodePaddingY,
nodeBorderWidth,
getNodeBorderColor, // computed
setCurrentNode, // injected
Expand All @@ -49,19 +41,16 @@ const Sankey = ({
linkContract,
linkBlendMode,
enableLinkGradient,
getLinkColor, // computed
setCurrentLink, // injected
currentLink, // injected

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

theme,
getColor, // computed

nodeTooltip,
linkTooltip,
Expand All @@ -75,38 +64,8 @@ const Sankey = ({
tooltipFormat,

legends,
legendData,
}) => {
const sankey = d3Sankey()
.nodeAlign(sankeyAlignmentFromProp(align))
.nodeSort(sortFunction)
.nodeWidth(nodeWidth)
.nodePadding(nodePaddingY)
.size([width, height])
.nodeId(getId)

// deep clone is required as the sankey diagram mutates data
const data = cloneDeep(_data)
sankey(data)

data.nodes.forEach(node => {
node.color = getColor(node)
node.label = getLabel(node)
node.x = node.x0 + nodePaddingX
node.y = node.y0
node.width = Math.max(node.x1 - node.x0 - nodePaddingX * 2, 0)
node.height = Math.max(node.y1 - node.y0, 0)
})

data.links.forEach(link => {
link.color = getLinkColor(link)
})

const legendData = data.nodes.map(node => ({
id: node.id,
label: node.label,
color: node.color,
}))

const motionProps = {
animate,
motionDamping,
Expand All @@ -124,7 +83,7 @@ const Sankey = ({

if (currentNode) {
let currentNodeIds = [currentNode.id]
data.links
links
.filter(
({ source, target }) => source.id === currentNode.id || target.id === currentNode.id
)
Expand All @@ -144,7 +103,7 @@ const Sankey = ({
{({ showTooltip, hideTooltip }) => (
<SvgWrapper width={outerWidth} height={outerHeight} margin={margin} theme={theme}>
<SankeyLinks
links={data.links}
links={links}
linkContract={linkContract}
linkOpacity={linkOpacity}
linkHoverOpacity={linkHoverOpacity}
Expand All @@ -164,7 +123,7 @@ const Sankey = ({
{...motionProps}
/>
<SankeyNodes
nodes={data.nodes}
nodes={nodes}
nodePaddingX={nodePaddingX}
nodeOpacity={nodeOpacity}
nodeHoverOpacity={nodeHoverOpacity}
Expand All @@ -185,7 +144,7 @@ const Sankey = ({
/>
{enableLabels && (
<SankeyLabels
nodes={data.nodes}
nodes={nodes}
width={width}
labelPosition={labelPosition}
labelPadding={labelPadding}
Expand Down
92 changes: 84 additions & 8 deletions packages/sankey/src/enhance.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import compose from 'recompose/compose'
import defaultProps from 'recompose/defaultProps'
import withState from 'recompose/withState'
import withPropsOnChange from 'recompose/withPropsOnChange'
import pure from 'recompose/pure'
import { getLabelGenerator, getInheritedColorGenerator } from '@nivo/core'
import { withColors, withTheme, withDimensions, withMotion } from '@nivo/core'
import { SankeyDefaultProps } from './props'
import { cloneDeep } from 'lodash'
import { compose, defaultProps, withState, withPropsOnChange, pure } from 'recompose'
import { sankey as d3Sankey } from 'd3-sankey'
import {
getLabelGenerator,
getInheritedColorGenerator,
withColors,
withTheme,
withDimensions,
withMotion,
} from '@nivo/core'
import { SankeyDefaultProps, sankeyAlignmentFromProp } from './props'

const getId = d => d.id

export default Component =>
compose(
Expand Down Expand Up @@ -50,5 +56,75 @@ export default Component =>

return { sortFunction }
}),
withPropsOnChange(['align'], ({ align }) => {
return {
alignFunction: sankeyAlignmentFromProp(align),
}
}),
withPropsOnChange(
[
'data',
'alignFunction',
'sortFunction',
'nodeWidth',
'nodePaddingX',
'nodePaddingY',
'width',
'height',
'getColor',
'getLinkColor',
'getLabel',
],
({
data: _data,
alignFunction,
sortFunction,
nodeWidth,
nodePaddingX,
nodePaddingY,
width,
height,
getColor,
getLinkColor,
getLabel,
}) => {
const sankey = d3Sankey()
.nodeAlign(alignFunction)
.nodeSort(sortFunction)
.nodeWidth(nodeWidth)
.nodePadding(nodePaddingY)
.size([width, height])
.nodeId(getId)

// deep clone is required as the sankey diagram mutates data
// we need a different identity for correct updates
const data = cloneDeep(_data)
sankey(data)

data.nodes.forEach(node => {
node.color = getColor(node)
node.label = getLabel(node)
node.x = node.x0 + nodePaddingX
node.y = node.y0
node.width = Math.max(node.x1 - node.x0 - nodePaddingX * 2, 0)
node.height = Math.max(node.y1 - node.y0, 0)
})

data.links.forEach(link => {
link.color = getLinkColor(link)
})

return data
}
),
withPropsOnChange(['nodes'], ({ nodes }) => {
return {
legendData: nodes.map(node => ({
id: node.id,
label: node.label,
color: node.color,
})),
}
}),
pure
)(Component)
2 changes: 1 addition & 1 deletion website/src/components/charts/sankey/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export default [
top.
</li>
<li>
<code>(nodeA, nodeB) => number</code>
<code>(nodeA, nodeB) => number</code> user defined function.
</li>
</ul>
Please have a look at the{' '}
Expand Down

0 comments on commit a0c29fe

Please sign in to comment.