Skip to content

Commit 1b03cec

Browse files
committedDec 31, 2021
feat(network): network can be used in standalone mode via the useNetwork hook
1 parent 2b26bf3 commit 1b03cec

File tree

4 files changed

+57
-40
lines changed

4 files changed

+57
-40
lines changed
 

‎packages/network/src/Network.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ const InnerNetwork = <N extends NetworkInputNode>({
4949
)
5050

5151
const [nodes, links] = useNetwork<N>({
52+
center: [innerWidth / 2, innerHeight / 2],
5253
nodes: rawNodes,
5354
links: rawLinks,
5455
linkDistance,
5556
repulsivity,
5657
distanceMin,
5758
distanceMax,
5859
iterations,
59-
center: [innerWidth / 2, innerHeight / 2],
6060
nodeColor,
6161
nodeBorderWidth,
6262
nodeBorderColor,

‎packages/network/src/NetworkCanvas.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ const InnerNetworkCanvas = <N extends NetworkInputNode>({
4747
)
4848

4949
const [nodes, links] = useNetwork<N>({
50+
center: [innerWidth / 2, innerHeight / 2],
5051
nodes: rawNodes,
5152
links: rawLinks,
5253
linkDistance,
5354
repulsivity,
5455
distanceMin,
5556
distanceMax,
5657
iterations,
57-
center: [innerWidth / 2, innerHeight / 2],
5858
nodeColor,
5959
nodeBorderWidth,
6060
nodeBorderColor,

‎packages/network/src/hooks.ts

+46-38
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import isString from 'lodash/isString'
44
import isNumber from 'lodash/isNumber'
55
import { forceSimulation, forceManyBody, forceCenter, forceLink } from 'd3-force'
66
import { useTheme } from '@nivo/core'
7+
import { useInheritedColor } from '@nivo/colors'
8+
import { commonDefaultProps } from './defaults'
79
import {
810
InputLink,
911
NetworkInputNode,
@@ -13,7 +15,6 @@ import {
1315
NetworkComputedNode,
1416
ComputedLink,
1517
} from './types'
16-
import { useInheritedColor } from '@nivo/colors'
1718

1819
const computeForces = <N extends NetworkInputNode>({
1920
linkDistance,
@@ -51,45 +52,62 @@ const computeForces = <N extends NetworkInputNode>({
5152
return { link: linkForce, charge: chargeForce, center: centerForce }
5253
}
5354

55+
const useNodeColor = <N extends NetworkInputNode>(color: NetworkNodeColor<N>) =>
56+
useMemo(() => {
57+
if (typeof color === 'function') return color
58+
return () => color
59+
}, [color])
60+
61+
const useLinkThickness = <N extends NetworkInputNode>(thickness: NetworkLinkThickness<N>) =>
62+
useMemo(() => {
63+
if (typeof thickness === 'function') return thickness
64+
return () => thickness
65+
}, [thickness])
66+
5467
export const useNetwork = <N extends NetworkInputNode = NetworkInputNode>({
68+
center,
5569
nodes,
5670
links,
57-
linkDistance,
58-
repulsivity,
59-
distanceMin,
60-
distanceMax,
61-
center,
62-
iterations,
63-
nodeColor,
64-
nodeBorderWidth,
65-
nodeBorderColor,
66-
linkThickness,
67-
linkColor,
71+
linkDistance = commonDefaultProps.linkDistance,
72+
repulsivity = commonDefaultProps.repulsivity,
73+
distanceMin = commonDefaultProps.distanceMin,
74+
distanceMax = commonDefaultProps.distanceMax,
75+
iterations = commonDefaultProps.iterations,
76+
nodeColor = commonDefaultProps.nodeColor,
77+
nodeBorderWidth = commonDefaultProps.nodeBorderWidth,
78+
nodeBorderColor = commonDefaultProps.nodeBorderColor,
79+
linkThickness = commonDefaultProps.linkThickness,
80+
linkColor = commonDefaultProps.linkColor,
6881
}: {
82+
center: [number, number]
6983
nodes: N[]
7084
links: InputLink[]
71-
linkDistance: NetworkCommonProps<N>['linkDistance']
72-
repulsivity: NetworkCommonProps<N>['repulsivity']
73-
distanceMin: NetworkCommonProps<N>['distanceMin']
74-
distanceMax: NetworkCommonProps<N>['distanceMax']
75-
center: [number, number]
76-
iterations: NetworkCommonProps<N>['iterations']
77-
nodeColor: NetworkCommonProps<N>['nodeColor']
78-
nodeBorderWidth: NetworkCommonProps<N>['nodeBorderWidth']
79-
nodeBorderColor: NetworkCommonProps<N>['nodeBorderColor']
80-
linkThickness: NetworkCommonProps<N>['linkThickness']
81-
linkColor: NetworkCommonProps<N>['linkColor']
85+
linkDistance?: NetworkCommonProps<N>['linkDistance']
86+
repulsivity?: NetworkCommonProps<N>['repulsivity']
87+
distanceMin?: NetworkCommonProps<N>['distanceMin']
88+
distanceMax?: NetworkCommonProps<N>['distanceMax']
89+
iterations?: NetworkCommonProps<N>['iterations']
90+
nodeColor?: NetworkCommonProps<N>['nodeColor']
91+
nodeBorderWidth?: NetworkCommonProps<N>['nodeBorderWidth']
92+
nodeBorderColor?: NetworkCommonProps<N>['nodeBorderColor']
93+
linkThickness?: NetworkCommonProps<N>['linkThickness']
94+
linkColor?: NetworkCommonProps<N>['linkColor']
8295
}): [null | NetworkComputedNode<N>[], null | ComputedLink<N>[]] => {
96+
// we're using `null` instead of empty array so that we can dissociate
97+
// initial rendering from updates when using transitions.
8398
const [currentNodes, setCurrentNodes] = useState<null | NetworkComputedNode<N>[]>(null)
8499
const [currentLinks, setCurrentLinks] = useState<null | ComputedLink<N>[]>(null)
85100

101+
const centerX = center[0]
102+
const centerY = center[1]
103+
86104
useEffect(() => {
87105
const forces = computeForces<N>({
88106
linkDistance,
89107
repulsivity,
90108
distanceMin,
91109
distanceMax,
92-
center,
110+
center: [centerX, centerY],
93111
})
94112

95113
const nodesCopy: N[] = nodes.map(node => ({ ...node }))
@@ -122,18 +140,20 @@ export const useNetwork = <N extends NetworkInputNode = NetworkInputNode>({
122140
)
123141

124142
return () => {
143+
// prevent the simulation from continuing in case the data is updated,
144+
// would be a waste of resource.
125145
simulation.stop()
126146
}
127147
}, [
148+
centerX,
149+
centerY,
128150
nodes,
129151
links,
130152
linkDistance,
131153
repulsivity,
132154
distanceMin,
133155
distanceMax,
134156
iterations,
135-
center[0],
136-
center[1],
137157
])
138158

139159
const theme = useTheme()
@@ -169,15 +189,3 @@ export const useNetwork = <N extends NetworkInputNode = NetworkInputNode>({
169189

170190
return [enhancedNodes, enhancedLinks]
171191
}
172-
173-
export const useNodeColor = <N extends NetworkInputNode>(color: NetworkNodeColor<N>) =>
174-
useMemo(() => {
175-
if (typeof color === 'function') return color
176-
return () => color
177-
}, [color])
178-
179-
export const useLinkThickness = <N extends NetworkInputNode>(thickness: NetworkLinkThickness<N>) =>
180-
useMemo(() => {
181-
if (typeof thickness === 'function') return thickness
182-
return () => thickness
183-
}, [thickness])

‎website/src/data/components/network/meta.yml

+9
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@ Network:
1212
- experimental
1313
stories: []
1414
description: |
15+
A network component connecting nodes with links.
16+
1517
The responsive alternative of this component is `ResponsiveNetwork`.
1618
19+
Please note that you can also use the `useNetwork` React hook if you want
20+
to handle the rendering by yourself, it accepts an object with almost
21+
the same props as the component and returns computed nodes & links.
22+
1723
NetworkCanvas:
1824
package: '@nivo/network'
1925
tags:
@@ -28,3 +34,6 @@ NetworkCanvas:
2834
The responsive alternative of this component is
2935
`ResponsiveNetworkCanvas`.
3036
37+
Please note that you can also use the `useNetwork` React hook if you want
38+
to handle the rendering by yourself, it accepts an object with almost
39+
the same props as the component and returns computed nodes & links.

0 commit comments

Comments
 (0)
Please sign in to comment.