Skip to content

Commit

Permalink
feat(network): add separated node and link components
Browse files Browse the repository at this point in the history
Raphaël Benitte authored and Raphaël Benitte committed May 9, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 2ea8581 commit a54ac59
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
@@ -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,
}
}

@@ -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}
/>
)
})}
24 changes: 11 additions & 13 deletions packages/network/src/AnimatedNodes.js
Original file line number Diff line number Diff line change
@@ -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,
@@ -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)}
/>
)
})}
</>
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
@@ -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 {
@@ -45,6 +47,7 @@ const Network = props => {
partialMargin
)

const { animate } = useMotionConfig()
const theme = useTheme()
const getColor = useNodeColor(nodeColor)
const getBorderColor = useInheritedColor(nodeBorderColor, theme)
@@ -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}>
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.