@@ -4,28 +4,26 @@ import {
4
4
TreeMap ,
5
5
TreeMapSvgProps ,
6
6
DefaultTreeMapDatum ,
7
+ NodeProps ,
8
+ svgDefaultProps ,
9
+ TooltipProps ,
7
10
// @ts -ignore
8
11
} from '../src'
9
12
13
+ const nodes = [
14
+ { id : 'root' , sum : 100 } ,
15
+ { id : 'A' , value : 50 } ,
16
+ { id : 'B' , sum : 50 } ,
17
+ { id : 'B.0' , value : 25 } ,
18
+ { id : 'B.1' , value : 25 } ,
19
+ ]
10
20
const sampleData : DefaultTreeMapDatum = {
11
- id : 'root' ,
21
+ ... nodes [ 0 ] ,
12
22
children : [
23
+ nodes [ 1 ] ,
13
24
{
14
- id : 'A' ,
15
- value : 50 ,
16
- } ,
17
- {
18
- id : 'B' ,
19
- children : [
20
- {
21
- id : 'B.0' ,
22
- value : 25 ,
23
- } ,
24
- {
25
- id : 'B.1' ,
26
- value : 25 ,
27
- } ,
28
- ] ,
25
+ ...nodes [ 2 ] ,
26
+ children : [ nodes [ 3 ] , nodes [ 4 ] ] ,
29
27
} ,
30
28
] ,
31
29
}
@@ -45,308 +43,81 @@ afterAll(() => {
45
43
Globals . assign ( { skipAnimation : false } )
46
44
} )
47
45
48
- it ( 'should render a basic treemap chart' , ( ) => { } )
46
+ it ( 'should render a basic treemap chart' , ( ) => {
47
+ const wrapper = mount ( < TreeMap { ...baseProps } /> )
49
48
50
- /*
51
- it('should render a basic network chart', () => {
52
- const wrapper = mount(<Network {...baseProps} />)
53
-
54
- sampleData.nodes.forEach(node => {
55
- const nodeElement = wrapper.find(`circle[data-testid='node.${node.id}']`)
49
+ nodes . forEach ( node => {
50
+ const nodeElement = wrapper . find ( `rect[data-testid='node.${ node . id } ']` )
56
51
expect ( nodeElement . exists ( ) ) . toBeTruthy ( )
57
- })
58
52
59
- sampleData.links.forEach(link => {
60
- const linkElement = wrapper.find(`line[data-testid='link.${link.source}.${link.target}']`)
61
- expect(linkElement.exists()).toBeTruthy()
53
+ if ( node . value !== undefined ) {
54
+ const label = wrapper . find ( `text[data-testid='label.${ node . id } ']` )
55
+ expect ( label . exists ( ) ) . toBeTruthy ( )
56
+ expect ( label . text ( ) ) . toEqual ( `${ node . value } ` )
57
+ } else {
58
+ const parentLabel = wrapper . find ( `text[data-testid='parentLabel.${ node . id } ']` )
59
+ expect ( parentLabel . exists ( ) ) . toBeTruthy ( )
60
+ expect ( parentLabel . text ( ) ) . toEqual ( node . id )
61
+ }
62
62
} )
63
63
} )
64
64
65
65
describe ( 'nodes' , ( ) => {
66
- it('static node color', () => {
67
- const color = 'rgba(255, 0, 255, 1)'
68
- const wrapper = mount(<Network {...baseProps} nodeColor={color} />)
69
-
70
- sampleData.nodes.forEach(node => {
71
- expect(wrapper.find(`circle[data-testid='node.${node.id}']`).prop('fill')).toEqual(
72
- color
73
- )
74
- })
75
- })
76
-
77
- it('static node size', () => {
78
- const size = 32
79
- const wrapper = mount(<Network {...baseProps} nodeSize={size} />)
80
-
81
- sampleData.nodes.forEach(node => {
82
- expect(wrapper.find(`circle[data-testid='node.${node.id}']`).prop('r')).toEqual(
83
- size / 2
84
- )
85
- })
86
- })
87
-
88
- it('dynamic node size', () => {
89
- const computeSize = (node: { id: string; index: number }) => 10 + node.index * 2
90
- const nodesWithIndex = sampleData.nodes.map((node, index) => ({
91
- ...node,
92
- index,
93
- }))
94
- const wrapper = mount(
95
- <Network<{ id: string; index: number }, InputLink>
96
- {...baseProps}
97
- data={{
98
- nodes: nodesWithIndex,
99
- links: sampleData.links,
100
- }}
101
- nodeSize={computeSize}
102
- />
103
- )
104
-
105
- nodesWithIndex.forEach(node => {
106
- expect(wrapper.find(`circle[data-testid='node.${node.id}']`).prop('r')).toEqual(
107
- computeSize(node) / 2
108
- )
109
- })
110
- })
111
-
112
66
it ( 'custom node component' , ( ) => {
113
- const CustomNode = ({ node }: NodeProps<InputNode >) => (
67
+ const CustomNode = ( { node } : NodeProps < DefaultTreeMapDatum > ) => (
114
68
< g data-testid = { `node.${ node . id } .custom` } />
115
69
)
70
+ const wrapper = mount ( < TreeMap { ...baseProps } nodeComponent = { CustomNode } /> )
116
71
117
- const wrapper = mount(<Network {...baseProps} nodeComponent={CustomNode} />)
118
-
119
- sampleData.nodes.forEach(node => {
72
+ nodes . forEach ( node => {
120
73
expect ( wrapper . find ( `g[data-testid='node.${ node . id } .custom']` ) . exists ( ) ) . toBeTruthy ( )
121
74
} )
122
75
} )
123
76
} )
124
77
125
- describe('active/inactive nodes', () => {
126
- it('styles depending on nodes status', () => {
127
- const wrapper = mount(
128
- <Network {...baseProps} nodeSize={10} activeNodeSize={20} inactiveNodeSize={0} />
129
- )
130
-
131
- sampleData.nodes.forEach(activeNode => {
132
- wrapper.find(`circle[data-testid='node.${activeNode.id}']`).simulate('mouseenter')
133
-
134
- expect(
135
- wrapper.find(`circle[data-testid='node.${activeNode.id}']`).parent().prop('r').get()
136
- ).toEqual(10)
137
-
138
- sampleData.nodes
139
- .filter(node => node.id !== activeNode.id)
140
- .forEach(otherNode => {
141
- expect(
142
- wrapper
143
- .find(`circle[data-testid='node.${otherNode.id}']`)
144
- .parent()
145
- .prop('r')
146
- .get()
147
- ).toEqual(0)
148
- })
149
- })
150
- })
151
-
152
- it('default active node ids', () => {
153
- const activeIds = ['A', 'C']
154
- const wrapper = mount(
155
- <Network
156
- {...baseProps}
157
- nodeSize={10}
158
- activeNodeSize={20}
159
- inactiveNodeSize={0}
160
- defaultActiveNodeIds={activeIds}
161
- />
162
- )
163
-
164
- sampleData.nodes.forEach(node => {
165
- const nodeElement = wrapper.find(`circle[data-testid='node.${node.id}']`)
166
-
167
- if (activeIds.includes(node.id)) {
168
- expect(nodeElement.prop('r')).toEqual(10)
169
- } else {
170
- expect(nodeElement.prop('r')).toEqual(0)
171
- }
172
- })
173
- })
174
-
175
- it('ignored if non interactive', () => {
176
- const wrapper = mount(
177
- <Network
178
- {...baseProps}
179
- nodeSize={10}
180
- activeNodeSize={20}
181
- inactiveNodeSize={0}
182
- defaultActiveNodeIds={['B', 'D']}
183
- isInteractive={false}
184
- />
185
- )
186
-
187
- sampleData.nodes.forEach(node => {
188
- expect(wrapper.find(`circle[data-testid='node.${node.id}']`).prop('r')).toEqual(5)
189
- })
190
- })
191
- })
192
-
193
- describe('links', () => {
194
- it('static link thickness', () => {
195
- const wrapper = mount(<Network {...baseProps} linkThickness={3} />)
196
-
197
- sampleData.links.forEach(link => {
198
- expect(
199
- wrapper
200
- .find(`line[data-testid='link.${link.source}.${link.target}']`)
201
- .prop('strokeWidth')
202
- ).toEqual(3)
203
- })
204
- })
205
-
206
- it('dynamic link thickness', () => {
207
- const wrapper = mount(<Network {...baseProps} linkThickness={link => 1 + link.index} />)
208
-
209
- sampleData.links.forEach((link, index) => {
210
- expect(
211
- wrapper
212
- .find(`line[data-testid='link.${link.source}.${link.target}']`)
213
- .prop('strokeWidth')
214
- ).toEqual(1 + index)
215
- })
216
- })
217
-
218
- it('static link color', () => {
219
- const color = 'rgba(255, 0, 0, 1)'
220
- const wrapper = mount(<Network {...baseProps} linkColor={color} />)
221
-
222
- sampleData.links.forEach(link => {
223
- expect(
224
- wrapper
225
- .find(`line[data-testid='link.${link.source}.${link.target}']`)
226
- .prop('stroke')
227
- ).toEqual(color)
228
- })
229
- })
230
-
231
- it('dynamic link color', () => {
232
- const wrapper = mount(
233
- <Network {...baseProps} linkColor={link => `rgba(${link.index * 10}, 0, 0, 1)` } />
234
- )
235
-
236
- sampleData.links.forEach((link, index) => {
237
- expect(
238
- wrapper
239
- .find(`line[data-testid='link.${link.source}.${link.target}']`)
240
- .prop('stroke')
241
- ).toEqual(`rgba(${index * 10}, 0, 0, 1)`)
242
- })
243
- })
244
-
245
- it('link color from source node color', () => {
246
- const color = 'rgba(125, 255, 125, 1)'
247
- const wrapper = mount(
248
- <Network
249
- {...baseProps}
250
- nodeColor={color}
251
- linkColor={{
252
- from: 'source.color',
253
- }}
254
- />
255
- )
256
-
257
- sampleData.links.forEach(link => {
258
- expect(
259
- wrapper
260
- .find(`line[data-testid='link.${link.source}.${link.target}']`)
261
- .prop('stroke')
262
- ).toEqual(color)
263
- })
264
- })
265
-
266
- it('link color from target node color', () => {
267
- const color = 'rgba(125, 125, 255, 1)'
268
- const wrapper = mount(
269
- <Network
270
- {...baseProps}
271
- nodeColor={color}
272
- linkColor={{
273
- from: 'target.color',
274
- }}
275
- />
276
- )
277
-
278
- sampleData.links.forEach(link => {
279
- expect(
280
- wrapper
281
- .find(`line[data-testid='link.${link.source}.${link.target}']`)
282
- .prop('stroke')
283
- ).toEqual(color)
284
- })
285
- })
286
-
287
- it('link blend mode', () => {
288
- const wrapper = mount(<Network {...baseProps} linkBlendMode="multiply" />)
289
-
290
- sampleData.links.forEach(link => {
291
- expect(
292
- wrapper.find(`line[data-testid='link.${link.source}.${link.target}']`).prop('style')
293
- ).toEqual({ mixBlendMode: 'multiply' })
294
- })
295
- })
296
-
297
- it('custom link component', () => {
298
- const CustomLink = ({ link }: LinkProps<InputNode, InputLink>) => (
299
- <g data-testid={`link.${link.source.id}.${link.target.id}.custom` } />
300
- )
301
-
302
- const wrapper = mount(<Network {...baseProps} linkComponent={CustomLink} />)
303
-
304
- sampleData.links.forEach(link => {
305
- expect(
306
- wrapper.find(`g[data-testid='link.${link.source}.${link.target}.custom']`).exists()
307
- ).toBeTruthy()
308
- })
309
- })
310
- })
311
-
312
78
describe ( 'tooltip' , ( ) => {
313
79
it ( 'default node tooltip' , ( ) => {
314
- const wrapper = mount(<Network {...baseProps} />)
80
+ const wrapper = mount ( < TreeMap { ...baseProps } /> )
315
81
316
- sampleData. nodes.forEach(node => {
317
- const nodeElement = wrapper.find(`circle [data-testid='node.${node.id}']`)
82
+ nodes . forEach ( node => {
83
+ const nodeElement = wrapper . find ( `rect [data-testid='node.${ node . id } ']` )
318
84
319
85
nodeElement . simulate ( 'mouseenter' )
320
86
321
- const tooltip = wrapper.find(svgDefaultProps.nodeTooltip ).childAt(0).childAt(0)
87
+ const tooltip = wrapper . find ( svgDefaultProps . tooltip ) . childAt ( 0 ) . childAt ( 0 )
322
88
expect ( tooltip . exists ( ) ) . toBeTruthy ( )
323
- expect(tooltip.text()).toEqual(node.id)
89
+
90
+ if ( node . value !== undefined ) {
91
+ expect ( tooltip . text ( ) ) . toEqual ( `${ node . id } : ${ node . value } ` )
92
+ } else {
93
+ expect ( tooltip . text ( ) ) . toEqual ( `${ node . id } : ${ node . sum } ` )
94
+ }
324
95
325
96
nodeElement . simulate ( 'mouseleave' )
326
- expect(wrapper.find(svgDefaultProps.nodeTooltip ).children()).toHaveLength(0)
97
+ expect ( wrapper . find ( svgDefaultProps . tooltip ) . children ( ) ) . toHaveLength ( 0 )
327
98
} )
328
99
} )
329
100
330
101
it ( 'disabled if non interactive' , ( ) => {
331
- const wrapper = mount(<Network {...baseProps} isInteractive={false} />)
102
+ const wrapper = mount ( < TreeMap { ...baseProps } isInteractive = { false } /> )
332
103
333
- sampleData. nodes.forEach(node => {
334
- const nodeElement = wrapper.find(`circle [data-testid='node.${node.id}']`)
104
+ nodes . forEach ( node => {
105
+ const nodeElement = wrapper . find ( `rect [data-testid='node.${ node . id } ']` )
335
106
336
107
nodeElement . simulate ( 'mouseenter' )
337
108
338
- expect(wrapper.find(svgDefaultProps.nodeTooltip ).children()).toHaveLength(0)
109
+ expect ( wrapper . find ( svgDefaultProps . tooltip ) . children ( ) ) . toHaveLength ( 0 )
339
110
} )
340
111
} )
341
112
342
- it('custom node tooltip', () => {
343
- const CustomTooltip = ({ node }: { node: ComputedNode<InputNode> } ) => (
113
+ it ( 'custom tooltip' , ( ) => {
114
+ const CustomTooltip = ( { node } : TooltipProps < DefaultTreeMapDatum > ) => (
344
115
< div > Custom: { node . id } </ div >
345
116
)
346
- const wrapper = mount(<Network {...baseProps} nodeTooltip ={CustomTooltip} />)
117
+ const wrapper = mount ( < TreeMap { ...baseProps } tooltip = { CustomTooltip } /> )
347
118
348
- sampleData. nodes.forEach(node => {
349
- const nodeElement = wrapper.find(`circle [data-testid='node.${node.id}']`)
119
+ nodes . forEach ( node => {
120
+ const nodeElement = wrapper . find ( `rect [data-testid='node.${ node . id } ']` )
350
121
351
122
nodeElement . simulate ( 'mouseenter' )
352
123
@@ -363,10 +134,10 @@ describe('tooltip', () => {
363
134
describe ( 'interactivity' , ( ) => {
364
135
it ( 'onClick' , ( ) => {
365
136
const onClick = jest . fn ( )
366
- const wrapper = mount(<Network {...baseProps} onClick={onClick} />)
137
+ const wrapper = mount ( < TreeMap { ...baseProps } onClick = { onClick } /> )
367
138
368
- sampleData. nodes.forEach(node => {
369
- wrapper.find(`circle [data-testid='node.${node.id}']`).simulate('click')
139
+ nodes . forEach ( node => {
140
+ wrapper . find ( `rect [data-testid='node.${ node . id } ']` ) . simulate ( 'click' )
370
141
371
142
expect ( onClick ) . toHaveBeenCalledTimes ( 1 )
372
143
const [ datum ] = onClick . mock . calls [ 0 ]
@@ -378,10 +149,10 @@ describe('interactivity', () => {
378
149
379
150
it ( 'onMouseEnter' , ( ) => {
380
151
const onMouseEnter = jest . fn ( )
381
- const wrapper = mount(<Network {...baseProps} onMouseEnter={onMouseEnter} />)
152
+ const wrapper = mount ( < TreeMap { ...baseProps } onMouseEnter = { onMouseEnter } /> )
382
153
383
- sampleData. nodes.forEach(node => {
384
- wrapper.find(`circle [data-testid='node.${node.id}']`).simulate('mouseenter')
154
+ nodes . forEach ( node => {
155
+ wrapper . find ( `rect [data-testid='node.${ node . id } ']` ) . simulate ( 'mouseenter' )
385
156
386
157
expect ( onMouseEnter ) . toHaveBeenCalledTimes ( 1 )
387
158
const [ datum ] = onMouseEnter . mock . calls [ 0 ]
@@ -393,10 +164,10 @@ describe('interactivity', () => {
393
164
394
165
it ( 'onMouseMove handler' , ( ) => {
395
166
const onMouseMove = jest . fn ( )
396
- const wrapper = mount(<Network {...baseProps} onMouseMove={onMouseMove} />)
167
+ const wrapper = mount ( < TreeMap { ...baseProps } onMouseMove = { onMouseMove } /> )
397
168
398
- sampleData. nodes.forEach(node => {
399
- wrapper.find(`circle [data-testid='node.${node.id}']`).simulate('mousemove')
169
+ nodes . forEach ( node => {
170
+ wrapper . find ( `rect [data-testid='node.${ node . id } ']` ) . simulate ( 'mousemove' )
400
171
401
172
expect ( onMouseMove ) . toHaveBeenCalledTimes ( 1 )
402
173
const [ datum ] = onMouseMove . mock . calls [ 0 ]
@@ -408,10 +179,10 @@ describe('interactivity', () => {
408
179
409
180
it ( 'onMouseLeave handler' , ( ) => {
410
181
const onMouseLeave = jest . fn ( )
411
- const wrapper = mount(<Network {...baseProps} onMouseLeave={onMouseLeave} />)
182
+ const wrapper = mount ( < TreeMap { ...baseProps } onMouseLeave = { onMouseLeave } /> )
412
183
413
- sampleData. nodes.forEach(node => {
414
- wrapper.find(`circle [data-testid='node.${node.id}']`).simulate('mouseleave')
184
+ nodes . forEach ( node => {
185
+ wrapper . find ( `rect [data-testid='node.${ node . id } ']` ) . simulate ( 'mouseleave' )
415
186
416
187
expect ( onMouseLeave ) . toHaveBeenCalledTimes ( 1 )
417
188
const [ datum ] = onMouseLeave . mock . calls [ 0 ]
@@ -428,7 +199,7 @@ describe('interactivity', () => {
428
199
const onMouseLeave = jest . fn ( )
429
200
430
201
const wrapper = mount (
431
- <Network
202
+ < TreeMap
432
203
{ ...baseProps }
433
204
onClick = { onClick }
434
205
onMouseEnter = { onMouseEnter }
@@ -438,8 +209,8 @@ describe('interactivity', () => {
438
209
/>
439
210
)
440
211
441
- sampleData. nodes.forEach(node => {
442
- const nodeElement = wrapper.find(`circle [data-testid='node.${node.id}']`)
212
+ nodes . forEach ( node => {
213
+ const nodeElement = wrapper . find ( `rect [data-testid='node.${ node . id } ']` )
443
214
444
215
nodeElement . simulate ( 'mouseenter' )
445
216
expect ( onMouseEnter ) . not . toHaveBeenCalled ( )
@@ -457,68 +228,22 @@ describe('interactivity', () => {
457
228
} )
458
229
459
230
describe ( 'layers' , ( ) => {
460
- it('custom order', () => {
461
- const wrapper = mount(<Network {...baseProps} layers={['nodes', 'links']} />)
462
-
463
- const layers = wrapper.find('svg > g').children()
464
- expect(layers.at(0).is('NetworkNodes')).toBeTruthy()
465
- expect(layers.at(1).is('NetworkLinks')).toBeTruthy()
466
- })
467
-
468
231
it ( 'custom layer' , ( ) => {
469
232
const CustomLayer = ( ) => null
470
- const wrapper = mount(<Network {...baseProps} layers={[CustomLayer]} />)
233
+ const wrapper = mount ( < TreeMap { ...baseProps } layers = { [ CustomLayer ] } /> )
471
234
472
235
const customLayer = wrapper . find ( CustomLayer )
473
236
expect ( customLayer . exists ( ) ) . toBeTruthy ( )
474
237
475
238
const customLayerProps = customLayer . props ( )
476
239
expect ( customLayerProps ) . toHaveProperty ( 'nodes' )
477
- expect(customLayerProps).toHaveProperty('links')
478
- expect(customLayerProps).toHaveProperty('activeNodeIds')
479
- expect(customLayerProps).toHaveProperty('setActiveNodeIds')
480
- })
481
- })
482
-
483
- describe('annotations', () => {
484
- it('circle annotation using id', () => {
485
- const annotatedNodeId = 'C'
486
- const wrapper = mount(
487
- <Network
488
- {...baseProps}
489
- annotations={[
490
- {
491
- type: 'circle',
492
- match: {
493
- id: annotatedNodeId,
494
- },
495
- note: 'Note',
496
- noteX: 160,
497
- noteY: 36,
498
- },
499
- ]}
500
- />
501
- )
502
-
503
- const annotation = wrapper.find(Annotation)
504
- expect(annotation.exists()).toBeTruthy()
505
-
506
- const annotatedNode = wrapper.find(`circle[data-testid='node.${annotatedNodeId}']`)
507
- const [nodeX, nodeY] = Array.from(
508
- annotatedNode.prop('transform').match(/translate\(([0-9.]+),([0-9.]+)\)/)
509
- )
510
- .slice(1)
511
- .map(Number)
512
-
513
- expect(annotation.find('circle').first().prop('cx')).toEqual(nodeX)
514
- expect(annotation.find('circle').first().prop('cy')).toEqual(nodeY)
515
240
} )
516
241
} )
517
242
518
243
describe ( 'accessibility' , ( ) => {
519
244
it ( 'aria properties' , ( ) => {
520
245
const wrapper = mount (
521
- <Network
246
+ < TreeMap
522
247
{ ...baseProps }
523
248
ariaLabel = "AriaLabel"
524
249
ariaLabelledBy = "AriaLabelledBy"
@@ -533,4 +258,3 @@ describe('accessibility', () => {
533
258
expect ( svg . prop ( 'aria-describedby' ) ) . toBe ( 'AriaDescribedBy' )
534
259
} )
535
260
} )
536
- */
0 commit comments