Skip to content

Commit

Permalink
feat(network): add separated node and link components
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored and Raphaël Benitte committed May 9, 2019
1 parent 2ea8581 commit a54ac59
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 52 deletions.
37 changes: 19 additions & 18 deletions packages/network/src/AnimatedLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ import React, { memo } from 'react'
import PropTypes from 'prop-types'
import { TransitionMotion, spring } from 'react-motion'
import { useMotionConfig } from '@nivo/core'
import Link from './Link'

const willEnter = ({ style, data }) => {
const x0 = data.previousSource ? data.previousSource.x : style.x0.val
const y0 = data.previousSource ? data.previousSource.y : style.y0.val
const sourceX = data.previousSource ? data.previousSource.x : style.sourceX.val
const sourceY = data.previousSource ? data.previousSource.y : style.sourceY.val

return {
x0,
y0,
x1: x0,
y1: y0,
sourceX,
sourceY,
targetX: sourceX,
targetY: sourceY,
}
}

Expand All @@ -33,26 +34,26 @@ const AnimatedLinks = ({ links, linkThickness, linkColor }) => {
key: link.id,
data: link,
style: {
x0: spring(link.source.x, springConfig),
y0: spring(link.source.y, springConfig),
x1: spring(link.target.x, springConfig),
y1: spring(link.target.y, springConfig),
sourceX: spring(link.source.x, springConfig),
sourceY: spring(link.source.y, springConfig),
targetX: spring(link.target.x, springConfig),
targetY: spring(link.target.y, springConfig),
},
}))}
>
{interpolatedStyles => (
<>
{interpolatedStyles.map(({ key, style, data: link }) => {
return (
<line
<Link
key={key}
stroke={linkColor(link)}
strokeWidth={linkThickness(link)}
strokeLinecap="round"
x1={style.x0}
y1={style.y0}
x2={style.x1}
y2={style.y1}
link={link}
color={linkColor(link)}
thickness={linkThickness(link)}
sourceX={style.sourceX}
sourceY={style.sourceY}
targetX={style.targetX}
targetY={style.targetY}
/>
)
})}
Expand Down
24 changes: 11 additions & 13 deletions packages/network/src/AnimatedNodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import React, { memo } from 'react'
import PropTypes from 'prop-types'
import { TransitionMotion, spring } from 'react-motion'
import { useMotionConfig } from '@nivo/core'
import Node from './Node'

const willEnter = ({ style }) => ({
x: style.x.val,
Expand Down Expand Up @@ -47,20 +48,17 @@ const AnimatedNodes = ({ nodes, color, borderWidth, borderColor }) => {
<>
{interpolatedStyles.map(({ key, style, data: node }) => {
return (
<g
<Node
key={key}
transform={`translate(${style.x},${style.y}) scale(${Math.max(
style.scale,
0
)})`}
>
<circle
r={Math.max(style.radius, 0)}
fill={color(node)}
strokeWidth={borderWidth}
stroke={borderColor(node)}
/>
</g>
node={node}
x={style.x}
y={style.y}
radius={Math.max(style.radius, 0)}
color={color(node)}
borderWidth={borderWidth}
borderColor={borderColor(node)}
scale={Math.max(style.scale, 0)}
/>
)
})}
</>
Expand Down
36 changes: 36 additions & 0 deletions packages/network/src/Link.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* This file is part of the nivo project.
*
* Copyright 2016-present, Raphaël Benitte.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { memo } from 'react'
import PropTypes from 'prop-types'

const Link = ({ sourceX, sourceY, targetX, targetY, thickness, color }) => {
return (
<line
stroke={color}
strokeWidth={thickness}
strokeLinecap="round"
x1={sourceX}
y1={sourceY}
x2={targetX}
y2={targetY}
/>
)
}

Link.propTypes = {
link: PropTypes.object.isRequired,
sourceX: PropTypes.number.isRequired,
sourceY: PropTypes.number.isRequired,
targetX: PropTypes.number.isRequired,
targetY: PropTypes.number.isRequired,
thickness: PropTypes.number.isRequired,
color: PropTypes.string.isRequired,
}

export default memo(Link)
40 changes: 19 additions & 21 deletions packages/network/src/Network.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
* file that was distributed with this source code.
*/
import React, { Fragment } from 'react'
import { withContainer, useDimensions, SvgWrapper, useTheme } from '@nivo/core'
import { withContainer, useDimensions, SvgWrapper, useTheme, useMotionConfig } from '@nivo/core'
import { useInheritedColor } from '@nivo/colors'
import { NetworkPropTypes, NetworkDefaultProps } from './props'
import { useNetwork, useNodeColor, useLinkThickness } from './hooks'
import AnimatedNodes from './AnimatedNodes'
import StaticNodes from './StaticNodes'
import AnimatedLinks from './AnimatedLinks'
import StaticLinks from './StaticLinks'

const Network = props => {
const {
Expand Down Expand Up @@ -45,6 +47,7 @@ const Network = props => {
partialMargin
)

const { animate } = useMotionConfig()
const theme = useTheme()
const getColor = useNodeColor(nodeColor)
const getBorderColor = useInheritedColor(nodeBorderColor, theme)
Expand All @@ -62,26 +65,21 @@ const Network = props => {
center: [innerWidth / 2, innerHeight / 2],
})

const layerById = {}

layerById.links = (
<AnimatedLinks
key="links"
links={links}
linkThickness={getLinkThickness}
linkColor={getLinkColor}
/>
)

layerById.nodes = (
<AnimatedNodes
key="nodes"
nodes={nodes}
color={getColor}
borderWidth={nodeBorderWidth}
borderColor={getBorderColor}
/>
)
const layerById = {
links: React.createElement(animate === true ? AnimatedLinks : StaticLinks, {
key: 'links',
links,
linkThickness: getLinkThickness,
linkColor: getLinkColor,
}),
nodes: React.createElement(animate === true ? AnimatedNodes : StaticNodes, {
key: 'nodes',
nodes,
color: getColor,
borderWidth: nodeBorderWidth,
borderColor: getBorderColor,
}),
}

return (
<SvgWrapper width={outerWidth} height={outerHeight} margin={margin}>
Expand Down
35 changes: 35 additions & 0 deletions packages/network/src/Node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This file is part of the nivo project.
*
* Copyright 2016-present, Raphaël Benitte.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { memo } from 'react'
import PropTypes from 'prop-types'

const Node = ({ x, y, radius, color, borderWidth, borderColor, scale = 1 }) => {
return (
<circle
transform={`translate(${x},${y}) scale(${scale})`}
r={radius}
fill={color}
strokeWidth={borderWidth}
stroke={borderColor}
/>
)
}

Node.propTypes = {
node: PropTypes.object.isRequired,
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
radius: PropTypes.number.isRequired,
color: PropTypes.string.isRequired,
borderWidth: PropTypes.number.isRequired,
borderColor: PropTypes.string.isRequired,
scale: PropTypes.number,
}

export default memo(Node)
36 changes: 36 additions & 0 deletions packages/network/src/StaticLinks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* This file is part of the nivo project.
*
* Copyright 2016-present, Raphaël Benitte.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { memo } from 'react'
import PropTypes from 'prop-types'
import Link from './Link'

const StaticLinks = ({ links, linkThickness, linkColor }) => {
return links.map(link => {
return (
<Link
key={link.id}
link={link}
color={linkColor(link)}
thickness={linkThickness(link)}
sourceX={link.source.x}
sourceY={link.source.y}
targetX={link.target.x}
targetY={link.target.y}
/>
)
})
}

StaticLinks.propTypes = {
links: PropTypes.array.isRequired,
linkThickness: PropTypes.func.isRequired,
linkColor: PropTypes.func.isRequired,
}

export default memo(StaticLinks)
37 changes: 37 additions & 0 deletions packages/network/src/StaticNodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* This file is part of the nivo project.
*
* Copyright 2016-present, Raphaël Benitte.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { memo } from 'react'
import PropTypes from 'prop-types'
import Node from './Node'

const StaticNodes = ({ nodes, color, borderWidth, borderColor }) => {
return nodes.map(node => {
return (
<Node
key={node.id}
node={node}
x={node.x}
y={node.y}
radius={node.radius}
color={color(node)}
borderWidth={borderWidth}
borderColor={borderColor(node)}
/>
)
})
}

StaticNodes.propTypes = {
nodes: PropTypes.array.isRequired,
color: PropTypes.func.isRequired,
borderWidth: PropTypes.number.isRequired,
borderColor: PropTypes.func.isRequired,
}

export default memo(StaticNodes)

0 comments on commit a54ac59

Please sign in to comment.