@lumeer/pivot 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,647 @@
1
+ /*
2
+ * Lumeer: Modern Data Definition and Processing Platform
3
+ *
4
+ * Copyright (C) since 2017 Lumeer.io, s.r.o. and/or its affiliates.
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+ import {AttributesResourceType, Collection, DataAggregationType, DataResource, DocumentModel, DocumentsAndLinksData, LinkInstance, LinkType, Query, UnknownConstraint} from '@lumeer/data-filters';
20
+
21
+
22
+ import {PivotDataConverter} from './pivot-data-converter';
23
+ import {LmrPivotConfig, LmrPivotTransform} from './lmr-pivot-config';
24
+
25
+ const documents: DocumentModel[] = [
26
+ {collectionId: 'C1', id: 'D1', data: {a1: 'abc'}},
27
+ {collectionId: 'C1', id: 'D2', data: {a1: 'abc'}},
28
+ {collectionId: 'C1', id: 'D3', data: {a1: 'def'}},
29
+
30
+ {collectionId: 'C2', id: 'D21', data: {a1: 'a'}},
31
+ {collectionId: 'C2', id: 'D22', data: {a1: 'c'}},
32
+ {collectionId: 'C2', id: 'D23', data: {a1: 'a'}},
33
+ {collectionId: 'C2', id: 'D24', data: {a1: 'b'}},
34
+ {collectionId: 'C2', id: 'D25', data: {a1: 'b'}},
35
+ {collectionId: 'C2', id: 'D26', data: {a1: 'c'}},
36
+
37
+ {collectionId: 'C3', id: 'D31', data: {a1: 'xyz'}},
38
+ {collectionId: 'C3', id: 'D32', data: {a1: 'xyz'}},
39
+ {collectionId: 'C3', id: 'D33', data: {a1: 'vuw'}},
40
+ {collectionId: 'C3', id: 'D34', data: {a1: 'vuw'}},
41
+ {collectionId: 'C3', id: 'D35', data: {a1: 'vuw'}},
42
+ {collectionId: 'C3', id: 'D36', data: {a1: 'xyz'}},
43
+
44
+ {collectionId: 'C4', id: 'D41', data: {a1: 2, a2: 3}},
45
+ {collectionId: 'C4', id: 'D42', data: {a1: 4, a2: 0}},
46
+ {collectionId: 'C4', id: 'D43', data: {a1: 6, a2: -10}},
47
+ {collectionId: 'C4', id: 'D44', data: {a1: 1, a2: 3}},
48
+ {collectionId: 'C4', id: 'D45', data: {a1: null, a2: 1}},
49
+ {collectionId: 'C4', id: 'D46', data: {a1: 2, a2: null}},
50
+ {collectionId: 'C4', id: 'D47', data: {}},
51
+ {collectionId: 'C4', id: 'D48', data: {a1: 20, a2: 7}},
52
+ {collectionId: 'C4', id: 'D49', data: {a1: 11, a2: 9}},
53
+ ];
54
+
55
+ const collections: Collection[] = [
56
+ {
57
+ id: 'C1',
58
+ attributes: [{id: 'a1', name: 'Aaa'}],
59
+ },
60
+ {
61
+ id: 'C2',
62
+ attributes: [{id: 'a1', name: 'Bbb'}],
63
+ },
64
+ {
65
+ id: 'C3',
66
+ attributes: [{id: 'a1', name: 'Ccc'}],
67
+ },
68
+ {
69
+ id: 'C4',
70
+ attributes: [
71
+ {id: 'a1', name: 'Ddd'},
72
+ {id: 'a2', name: 'Eee'},
73
+ ],
74
+ },
75
+ ];
76
+
77
+ const linkInstances: LinkInstance[] = [
78
+ {
79
+ id: 'l121',
80
+ linkTypeId: 'LT1',
81
+ documentIds: ['D1', 'D21'],
82
+ data: {},
83
+ },
84
+ {
85
+ id: 'l122',
86
+ linkTypeId: 'LT1',
87
+ documentIds: ['D1', 'D22'],
88
+ data: {},
89
+ },
90
+ {
91
+ id: 'l123',
92
+ linkTypeId: 'LT1',
93
+ documentIds: ['D2', 'D23'],
94
+ data: {},
95
+ },
96
+ {
97
+ id: 'l124',
98
+ linkTypeId: 'LT1',
99
+ documentIds: ['D2', 'D24'],
100
+ data: {},
101
+ },
102
+ {
103
+ id: 'l125',
104
+ linkTypeId: 'LT1',
105
+ documentIds: ['D2', 'D25'],
106
+ data: {},
107
+ },
108
+ {
109
+ id: 'l126',
110
+ linkTypeId: 'LT1',
111
+ documentIds: ['D3', 'D26'],
112
+ data: {},
113
+ },
114
+ {
115
+ id: 'l2131',
116
+ linkTypeId: 'LT2',
117
+ documentIds: ['D21', 'D31'],
118
+ data: {},
119
+ },
120
+ {
121
+ id: 'l2232',
122
+ linkTypeId: 'LT2',
123
+ documentIds: ['D22', 'D32'],
124
+ data: {},
125
+ },
126
+ {
127
+ id: 'l2233',
128
+ linkTypeId: 'LT2',
129
+ documentIds: ['D22', 'D33'],
130
+ data: {},
131
+ },
132
+ {
133
+ id: 'l2334',
134
+ linkTypeId: 'LT2',
135
+ documentIds: ['D23', 'D34'],
136
+ data: {},
137
+ },
138
+ {
139
+ id: 'l2434',
140
+ linkTypeId: 'LT2',
141
+ documentIds: ['D24', 'D34'],
142
+ data: {},
143
+ },
144
+ {
145
+ id: 'l2534',
146
+ linkTypeId: 'LT2',
147
+ documentIds: ['D25', 'D34'],
148
+ data: {},
149
+ },
150
+ {
151
+ id: 'l2535',
152
+ linkTypeId: 'LT2',
153
+ documentIds: ['D25', 'D35'],
154
+ data: {},
155
+ },
156
+ {
157
+ id: 'l2636',
158
+ linkTypeId: 'LT2',
159
+ documentIds: ['D26', 'D36'],
160
+ data: {},
161
+ },
162
+ {
163
+ id: 'l3141',
164
+ linkTypeId: 'LT3',
165
+ documentIds: ['D31', 'D41'],
166
+ data: {},
167
+ },
168
+ {
169
+ id: 'l3241',
170
+ linkTypeId: 'LT3',
171
+ documentIds: ['D32', 'D41'],
172
+ data: {},
173
+ },
174
+ {
175
+ id: 'l3242',
176
+ linkTypeId: 'LT3',
177
+ documentIds: ['D32', 'D42'],
178
+ data: {},
179
+ },
180
+ {
181
+ id: 'l3342',
182
+ linkTypeId: 'LT3',
183
+ documentIds: ['D33', 'D43'],
184
+ data: {},
185
+ },
186
+ {
187
+ id: 'l3443',
188
+ linkTypeId: 'LT3',
189
+ documentIds: ['D34', 'D43'],
190
+ data: {},
191
+ },
192
+ {
193
+ id: 'l3444',
194
+ linkTypeId: 'LT3',
195
+ documentIds: ['D34', 'D44'],
196
+ data: {},
197
+ },
198
+ {
199
+ id: 'l3545',
200
+ linkTypeId: 'LT3',
201
+ documentIds: ['D35', 'D45'],
202
+ data: {},
203
+ },
204
+ {
205
+ id: 'l3546',
206
+ linkTypeId: 'LT3',
207
+ documentIds: ['D35', 'D46'],
208
+ data: {},
209
+ },
210
+ {
211
+ id: 'l3647',
212
+ linkTypeId: 'LT3',
213
+ documentIds: ['D36', 'D47'],
214
+ data: {},
215
+ },
216
+ {
217
+ id: 'l3648',
218
+ linkTypeId: 'LT3',
219
+ documentIds: ['D36', 'D48'],
220
+ data: {},
221
+ },
222
+ {
223
+ id: 'l3649',
224
+ linkTypeId: 'LT3',
225
+ documentIds: ['D36', 'D49'],
226
+ data: {},
227
+ },
228
+ ];
229
+
230
+ const linkTypes: LinkType[] = [
231
+ {
232
+ id: 'LT1',
233
+ collectionIds: ['C1', 'C2'],
234
+ attributes: [],
235
+ },
236
+ {
237
+ id: 'LT2',
238
+ collectionIds: ['C2', 'C3'],
239
+ attributes: [],
240
+ },
241
+ {
242
+ id: 'LT3',
243
+ collectionIds: ['C3', 'C4'],
244
+ attributes: [],
245
+ },
246
+ ];
247
+
248
+ const query: Query = {stems: [{collectionId: 'C1', linkTypeIds: ['LT1', 'LT2', 'LT3']}]};
249
+
250
+ const data: DocumentsAndLinksData = {
251
+ uniqueLinkInstances: linkInstances,
252
+ uniqueDocuments: documents,
253
+ dataByStems: [{stem: query.stems![0], documents, linkInstances}],
254
+ };
255
+
256
+ describe('Pivot data converter', () => {
257
+ const transform: LmrPivotTransform = {
258
+ translateAggregation: type => type.toString(),
259
+ checkValidConstraintOverride: (c1, c2) => c1,
260
+ }
261
+ const dataConverter: PivotDataConverter = new PivotDataConverter();
262
+
263
+ it('should return empty data', () => {
264
+ const config: LmrPivotConfig = {stemsConfigs: [{rowAttributes: [], columnAttributes: [], valueAttributes: []}]};
265
+ const pivotData = dataConverter.createData(config, transform, collections, linkTypes, data, query);
266
+ expect(pivotData.data).toEqual([]);
267
+ });
268
+
269
+ it('should return by one row', () => {
270
+ const config: LmrPivotConfig = {
271
+ stemsConfigs: [
272
+ {
273
+ rowAttributes: [
274
+ {resourceId: 'C2', resourceType: AttributesResourceType.Collection, attributeId: 'a1', resourceIndex: 2},
275
+ ],
276
+ columnAttributes: [],
277
+ valueAttributes: [],
278
+ },
279
+ ],
280
+ };
281
+ const pivotData = dataConverter.createData(config, transform, collections, linkTypes, data, query);
282
+ expect(pivotData.data[0].rowHeaders).toEqual([
283
+ {
284
+ title: 'a',
285
+ targetIndex: 0,
286
+ color: undefined,
287
+ constraint: new UnknownConstraint(),
288
+ isValueHeader: false,
289
+ attributeName: collections[1].attributes![0].name,
290
+ },
291
+ {
292
+ title: 'c',
293
+ targetIndex: 1,
294
+ color: undefined,
295
+ constraint: new UnknownConstraint(),
296
+ isValueHeader: false,
297
+ attributeName: collections[1].attributes![0].name,
298
+ },
299
+ {
300
+ title: 'b',
301
+ targetIndex: 2,
302
+ color: undefined,
303
+ constraint: new UnknownConstraint(),
304
+ isValueHeader: false,
305
+ attributeName: collections[1].attributes![0].name,
306
+ },
307
+ ]);
308
+ expect(pivotData.data[0].columnHeaders).toEqual([]);
309
+ expect(pivotData.data[0].values).toEqual([[undefined], [undefined], [undefined]]);
310
+ expect(pivotData.data[0].dataResources).toEqual([[undefined], [undefined], [undefined]]);
311
+ });
312
+
313
+ it('should return by one column', () => {
314
+ const config: LmrPivotConfig = {
315
+ stemsConfigs: [
316
+ {
317
+ rowAttributes: [],
318
+ columnAttributes: [
319
+ {resourceId: 'C3', resourceType: AttributesResourceType.Collection, attributeId: 'a1', resourceIndex: 4},
320
+ ],
321
+ valueAttributes: [],
322
+ },
323
+ ],
324
+ };
325
+ const pivotData = dataConverter.createData(config, transform, collections, linkTypes, data, query);
326
+ expect(pivotData.data[0].rowHeaders).toEqual([]);
327
+ expect(pivotData.data[0].columnHeaders).toEqual([
328
+ {
329
+ title: 'xyz',
330
+ targetIndex: 0,
331
+ color: undefined,
332
+ constraint: new UnknownConstraint(),
333
+ isValueHeader: false,
334
+ attributeName: collections[2].attributes![0].name,
335
+ },
336
+ {
337
+ title: 'vuw',
338
+ targetIndex: 1,
339
+ color: undefined,
340
+ constraint: new UnknownConstraint(),
341
+ isValueHeader: false,
342
+ attributeName: collections[2].attributes![0].name,
343
+ },
344
+ ]);
345
+ expect(pivotData.data[0].values).toEqual([[undefined, undefined]]);
346
+ expect(pivotData.data[0].dataResources).toEqual([[undefined, undefined]]);
347
+ });
348
+
349
+ it('should return by two values', () => {
350
+ const config: LmrPivotConfig = {
351
+ stemsConfigs: [
352
+ {
353
+ rowAttributes: [],
354
+ columnAttributes: [],
355
+ valueAttributes: [
356
+ {
357
+ resourceId: 'C4',
358
+ resourceType: AttributesResourceType.Collection,
359
+ attributeId: 'a1',
360
+ resourceIndex: 6,
361
+ aggregation: DataAggregationType.Sum,
362
+ },
363
+ {
364
+ resourceId: 'C4',
365
+ resourceType: AttributesResourceType.Collection,
366
+ attributeId: 'a2',
367
+ resourceIndex: 6,
368
+ aggregation: DataAggregationType.Min,
369
+ },
370
+ ],
371
+ },
372
+ ],
373
+ };
374
+ const pivotData = dataConverter.createData(config, transform, collections, linkTypes, data, query);
375
+ expect(pivotData.data[0].rowHeaders).toEqual([]);
376
+ expect(pivotData.data[0].columnHeaders).toEqual([
377
+ {
378
+ title: dataConverter.createValueTitle(DataAggregationType.Sum, 'Ddd'),
379
+ targetIndex: 0,
380
+ color: undefined,
381
+ isValueHeader: true,
382
+ },
383
+ {
384
+ title: dataConverter.createValueTitle(DataAggregationType.Min, 'Eee'),
385
+ targetIndex: 1,
386
+ color: undefined,
387
+ isValueHeader: true,
388
+ },
389
+ ]);
390
+ expect(pivotData.data[0].values).toEqual([[46, -10]]);
391
+ expect(pivotData.data[0].dataResources[0][0]).toHaveSize(9);
392
+ expect(pivotData.data[0].dataResources[0][0].map((d: DataResource) => d.id)).toEqual(
393
+ jasmine.arrayContaining(['D41', 'D42', 'D43', 'D44', 'D45', 'D46', 'D47', 'D48', 'D49'])
394
+ );
395
+ expect(pivotData.data[0].dataResources[0][1]).toHaveSize(9);
396
+ expect(pivotData.data[0].dataResources[0][1].map((d: DataResource) => d.id)).toEqual(
397
+ jasmine.arrayContaining(['D41', 'D42', 'D43', 'D44', 'D45', 'D46', 'D47', 'D48', 'D49'])
398
+ );
399
+ });
400
+
401
+ it('should return by row and value', () => {
402
+ const config: LmrPivotConfig = {
403
+ stemsConfigs: [
404
+ {
405
+ rowAttributes: [
406
+ {resourceId: 'C1', resourceType: AttributesResourceType.Collection, attributeId: 'a1', resourceIndex: 0},
407
+ ],
408
+ columnAttributes: [],
409
+ valueAttributes: [
410
+ {
411
+ resourceId: 'C4',
412
+ resourceType: AttributesResourceType.Collection,
413
+ attributeId: 'a1',
414
+ resourceIndex: 6,
415
+ aggregation: DataAggregationType.Sum,
416
+ },
417
+ ],
418
+ },
419
+ ],
420
+ };
421
+ const pivotData = dataConverter.createData(config, transform, collections, linkTypes, data, query);
422
+ expect(pivotData.data[0].rowHeaders).toEqual([
423
+ {
424
+ title: 'abc',
425
+ targetIndex: 0,
426
+ color: undefined,
427
+ constraint: new UnknownConstraint(),
428
+ isValueHeader: false,
429
+ attributeName: collections[0].attributes![0].name,
430
+ },
431
+ {
432
+ title: 'def',
433
+ targetIndex: 1,
434
+ color: undefined,
435
+ constraint: new UnknownConstraint(),
436
+ isValueHeader: false,
437
+ attributeName: collections[0].attributes![0].name,
438
+ },
439
+ ]);
440
+ expect(pivotData.data[0].columnHeaders).toEqual([
441
+ {
442
+ title: dataConverter.createValueTitle(DataAggregationType.Sum, 'Ddd'),
443
+ targetIndex: 0,
444
+ color: undefined,
445
+ isValueHeader: true,
446
+ },
447
+ ]);
448
+
449
+ expect(pivotData.data[0].values).toEqual([[37], [31]]);
450
+ expect(pivotData.data[0].dataResources[0][0].map((d: DataResource) => d.id)).toEqual(
451
+ jasmine.arrayContaining(['D41', 'D41', 'D42', 'D43', 'D43', 'D44', 'D43', 'D44', 'D43', 'D44', 'D45', 'D46'])
452
+ );
453
+ expect(pivotData.data[0].dataResources[1][0].map((d: DataResource) => d.id)).toEqual(
454
+ jasmine.arrayContaining(['D47', 'D48', 'D49'])
455
+ );
456
+ });
457
+
458
+ it('should return by column and value', () => {
459
+ const config: LmrPivotConfig = {
460
+ stemsConfigs: [
461
+ {
462
+ rowAttributes: [],
463
+ columnAttributes: [
464
+ {resourceId: 'C2', resourceType: AttributesResourceType.Collection, attributeId: 'a1', resourceIndex: 2},
465
+ ],
466
+ valueAttributes: [
467
+ {
468
+ resourceId: 'C4',
469
+ resourceType: AttributesResourceType.Collection,
470
+ attributeId: 'a2',
471
+ resourceIndex: 6,
472
+ aggregation: DataAggregationType.Sum,
473
+ },
474
+ ],
475
+ },
476
+ ],
477
+ };
478
+ const pivotData = dataConverter.createData(config, transform, collections, linkTypes, data, query);
479
+ expect(pivotData.data[0].rowHeaders).toEqual([]);
480
+ expect(pivotData.data[0].columnHeaders).toEqual([
481
+ {
482
+ title: 'a',
483
+ targetIndex: 0,
484
+ color: undefined,
485
+ constraint: new UnknownConstraint(),
486
+ isValueHeader: false,
487
+ attributeName: collections[1].attributes![0].name,
488
+ },
489
+ {
490
+ title: 'c',
491
+ targetIndex: 1,
492
+ color: undefined,
493
+ constraint: new UnknownConstraint(),
494
+ isValueHeader: false,
495
+ attributeName: collections[1].attributes![0].name,
496
+ },
497
+ {
498
+ title: 'b',
499
+ targetIndex: 2,
500
+ color: undefined,
501
+ constraint: new UnknownConstraint(),
502
+ isValueHeader: false,
503
+ attributeName: collections[1].attributes![0].name,
504
+ },
505
+ ]);
506
+ expect(pivotData.data[0].values).toEqual([[-4, 9, -13]]);
507
+ expect(pivotData.data[0].dataResources[0][0].map((d: DataResource) => d.id)).toEqual(
508
+ jasmine.arrayContaining(['D41', 'D43', 'D44'])
509
+ );
510
+ expect(pivotData.data[0].dataResources[0][1].map((d: DataResource) => d.id)).toEqual(
511
+ jasmine.arrayContaining(['D41', 'D42', 'D43', 'D47', 'D48', 'D49'])
512
+ );
513
+ expect(pivotData.data[0].dataResources[0][2].map((d: DataResource) => d.id)).toEqual(
514
+ jasmine.arrayContaining(['D43', 'D44', 'D43', 'D44', 'D45', 'D46'])
515
+ );
516
+ });
517
+
518
+ it('should return by two rows, column and three values', () => {
519
+ const config: LmrPivotConfig = {
520
+ stemsConfigs: [
521
+ {
522
+ rowAttributes: [
523
+ {resourceId: 'C1', resourceType: AttributesResourceType.Collection, attributeId: 'a1', resourceIndex: 0},
524
+ {resourceId: 'C2', resourceType: AttributesResourceType.Collection, attributeId: 'a1', resourceIndex: 2},
525
+ ],
526
+ columnAttributes: [
527
+ {resourceId: 'C3', resourceType: AttributesResourceType.Collection, attributeId: 'a1', resourceIndex: 4},
528
+ ],
529
+ valueAttributes: [
530
+ {
531
+ resourceId: 'C4',
532
+ resourceType: AttributesResourceType.Collection,
533
+ attributeId: 'a1',
534
+ resourceIndex: 6,
535
+ aggregation: DataAggregationType.Sum,
536
+ },
537
+ {
538
+ resourceId: 'C4',
539
+ resourceType: AttributesResourceType.Collection,
540
+ attributeId: 'a1',
541
+ resourceIndex: 6,
542
+ aggregation: DataAggregationType.Max,
543
+ },
544
+ {
545
+ resourceId: 'C4',
546
+ resourceType: AttributesResourceType.Collection,
547
+ attributeId: 'a2',
548
+ resourceIndex: 6,
549
+ aggregation: DataAggregationType.Count,
550
+ },
551
+ ],
552
+ },
553
+ ],
554
+ };
555
+ const pivotData = dataConverter.createData(config, transform, collections, linkTypes, data, query);
556
+ expect(pivotData.data[0].rowHeaders).toEqual([
557
+ {
558
+ title: 'abc',
559
+ children: [
560
+ {
561
+ title: 'a',
562
+ targetIndex: 0,
563
+ color: undefined,
564
+ constraint: new UnknownConstraint(),
565
+ isValueHeader: false,
566
+ attributeName: collections[1].attributes![0].name,
567
+ },
568
+ {
569
+ title: 'c',
570
+ targetIndex: 1,
571
+ color: undefined,
572
+ constraint: new UnknownConstraint(),
573
+ isValueHeader: false,
574
+ attributeName: collections[1].attributes![0].name,
575
+ },
576
+ {
577
+ title: 'b',
578
+ targetIndex: 2,
579
+ color: undefined,
580
+ constraint: new UnknownConstraint(),
581
+ isValueHeader: false,
582
+ attributeName: collections[1].attributes![0].name,
583
+ },
584
+ ],
585
+ color: undefined,
586
+ constraint: new UnknownConstraint(),
587
+ isValueHeader: false,
588
+ attributeName: collections[0].attributes![0].name,
589
+ },
590
+ {
591
+ title: 'def',
592
+ children: [
593
+ {
594
+ title: 'c',
595
+ targetIndex: 3,
596
+ color: undefined,
597
+ constraint: new UnknownConstraint(),
598
+ isValueHeader: false,
599
+ attributeName: collections[1].attributes![0].name,
600
+ },
601
+ ],
602
+ color: undefined,
603
+ constraint: new UnknownConstraint(),
604
+ isValueHeader: false,
605
+ attributeName: collections[0].attributes![0].name,
606
+ },
607
+ ]);
608
+ const valueTitles = [
609
+ dataConverter.createValueTitle(DataAggregationType.Sum, 'Ddd'),
610
+ dataConverter.createValueTitle(DataAggregationType.Max, 'Ddd'),
611
+ dataConverter.createValueTitle(DataAggregationType.Count, 'Eee'),
612
+ ];
613
+ expect(pivotData.data[0].columnHeaders).toEqual([
614
+ {
615
+ title: 'xyz',
616
+ children: [
617
+ {title: valueTitles[0], targetIndex: 0, color: undefined, isValueHeader: true},
618
+ {title: valueTitles[1], targetIndex: 1, color: undefined, isValueHeader: true},
619
+ {title: valueTitles[2], targetIndex: 2, color: undefined, isValueHeader: true},
620
+ ],
621
+ color: undefined,
622
+ constraint: new UnknownConstraint(),
623
+ isValueHeader: false,
624
+ attributeName: collections[2].attributes![0].name,
625
+ },
626
+ {
627
+ title: 'vuw',
628
+ children: [
629
+ {title: valueTitles[0], targetIndex: 3, color: undefined, isValueHeader: true},
630
+ {title: valueTitles[1], targetIndex: 4, color: undefined, isValueHeader: true},
631
+ {title: valueTitles[2], targetIndex: 5, color: undefined, isValueHeader: true},
632
+ ],
633
+ color: undefined,
634
+ constraint: new UnknownConstraint(),
635
+ isValueHeader: false,
636
+ attributeName: collections[2].attributes![0].name,
637
+ },
638
+ ]);
639
+ expect(pivotData.data[0].values).toEqual([
640
+ [2, 2, 1, 7, 6, 2],
641
+ [6, 4, 2, 6, 6, 1],
642
+ [undefined, undefined, undefined, 16, 6, 6],
643
+ [31, 20, 3, undefined, undefined, undefined],
644
+ ]);
645
+ expect(pivotData.data[0].valueTitles).toEqual(valueTitles);
646
+ });
647
+ });