@@ -4,6 +4,8 @@ import isString from 'lodash/isString'
4
4
import isNumber from 'lodash/isNumber'
5
5
import { forceSimulation , forceManyBody , forceCenter , forceLink } from 'd3-force'
6
6
import { useTheme } from '@nivo/core'
7
+ import { useInheritedColor } from '@nivo/colors'
8
+ import { commonDefaultProps } from './defaults'
7
9
import {
8
10
InputLink ,
9
11
NetworkInputNode ,
@@ -13,7 +15,6 @@ import {
13
15
NetworkComputedNode ,
14
16
ComputedLink ,
15
17
} from './types'
16
- import { useInheritedColor } from '@nivo/colors'
17
18
18
19
const computeForces = < N extends NetworkInputNode > ( {
19
20
linkDistance,
@@ -51,45 +52,62 @@ const computeForces = <N extends NetworkInputNode>({
51
52
return { link : linkForce , charge : chargeForce , center : centerForce }
52
53
}
53
54
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
+
54
67
export const useNetwork = < N extends NetworkInputNode = NetworkInputNode > ( {
68
+ center,
55
69
nodes,
56
70
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 ,
68
81
} : {
82
+ center : [ number , number ]
69
83
nodes : N [ ]
70
84
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' ]
82
95
} ) : [ 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.
83
98
const [ currentNodes , setCurrentNodes ] = useState < null | NetworkComputedNode < N > [ ] > ( null )
84
99
const [ currentLinks , setCurrentLinks ] = useState < null | ComputedLink < N > [ ] > ( null )
85
100
101
+ const centerX = center [ 0 ]
102
+ const centerY = center [ 1 ]
103
+
86
104
useEffect ( ( ) => {
87
105
const forces = computeForces < N > ( {
88
106
linkDistance,
89
107
repulsivity,
90
108
distanceMin,
91
109
distanceMax,
92
- center,
110
+ center : [ centerX , centerY ] ,
93
111
} )
94
112
95
113
const nodesCopy : N [ ] = nodes . map ( node => ( { ...node } ) )
@@ -122,18 +140,20 @@ export const useNetwork = <N extends NetworkInputNode = NetworkInputNode>({
122
140
)
123
141
124
142
return ( ) => {
143
+ // prevent the simulation from continuing in case the data is updated,
144
+ // would be a waste of resource.
125
145
simulation . stop ( )
126
146
}
127
147
} , [
148
+ centerX ,
149
+ centerY ,
128
150
nodes ,
129
151
links ,
130
152
linkDistance ,
131
153
repulsivity ,
132
154
distanceMin ,
133
155
distanceMax ,
134
156
iterations ,
135
- center [ 0 ] ,
136
- center [ 1 ] ,
137
157
] )
138
158
139
159
const theme = useTheme ( )
@@ -169,15 +189,3 @@ export const useNetwork = <N extends NetworkInputNode = NetworkInputNode>({
169
189
170
190
return [ enhancedNodes , enhancedLinks ]
171
191
}
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 ] )
0 commit comments