mintwaterfall 0.8.6

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +223 -0
  2. package/CONTRIBUTING.md +199 -0
  3. package/README.md +363 -0
  4. package/dist/index.d.ts +149 -0
  5. package/dist/mintwaterfall.cjs.js +7978 -0
  6. package/dist/mintwaterfall.esm.js +7907 -0
  7. package/dist/mintwaterfall.min.js +7 -0
  8. package/dist/mintwaterfall.umd.js +7978 -0
  9. package/index.d.ts +149 -0
  10. package/package.json +126 -0
  11. package/src/enterprise/enterprise-core.js +0 -0
  12. package/src/enterprise/enterprise-feature-template.js +0 -0
  13. package/src/enterprise/feature-registry.js +0 -0
  14. package/src/enterprise/features/breakdown.js +0 -0
  15. package/src/features/breakdown.js +0 -0
  16. package/src/features/conditional-formatting.js +0 -0
  17. package/src/index.js +111 -0
  18. package/src/mintwaterfall-accessibility.ts +680 -0
  19. package/src/mintwaterfall-advanced-data.ts +1034 -0
  20. package/src/mintwaterfall-advanced-interactions.ts +649 -0
  21. package/src/mintwaterfall-advanced-performance.ts +582 -0
  22. package/src/mintwaterfall-animations.ts +595 -0
  23. package/src/mintwaterfall-brush.ts +471 -0
  24. package/src/mintwaterfall-chart-core.ts +296 -0
  25. package/src/mintwaterfall-chart.ts +1915 -0
  26. package/src/mintwaterfall-data.ts +1100 -0
  27. package/src/mintwaterfall-export.ts +475 -0
  28. package/src/mintwaterfall-hierarchical-layouts.ts +724 -0
  29. package/src/mintwaterfall-layouts.ts +647 -0
  30. package/src/mintwaterfall-performance.ts +573 -0
  31. package/src/mintwaterfall-scales.ts +437 -0
  32. package/src/mintwaterfall-shapes.ts +385 -0
  33. package/src/mintwaterfall-statistics.ts +821 -0
  34. package/src/mintwaterfall-themes.ts +391 -0
  35. package/src/mintwaterfall-tooltip.ts +450 -0
  36. package/src/mintwaterfall-zoom.ts +399 -0
  37. package/src/types/js-modules.d.ts +25 -0
  38. package/src/utils/compatibility-layer.js +0 -0
@@ -0,0 +1,647 @@
1
+ // MintWaterfall - D3.js compatible hierarchical layout system - TypeScript Version
2
+ // Implements d3.hierarchy, d3.treemap, d3.partition, and other layout algorithms with full type safety
3
+
4
+ import * as d3 from 'd3';
5
+
6
+ // Type definitions for hierarchical layout system
7
+ export interface HierarchicalData {
8
+ id?: string;
9
+ name?: string;
10
+ value?: number;
11
+ data?: any;
12
+ children?: HierarchicalData[];
13
+ }
14
+
15
+ export interface LayoutOptions {
16
+ size?: [number, number];
17
+ padding?: number;
18
+ round?: boolean;
19
+ type?: LayoutType;
20
+ paddingInner?: number;
21
+ paddingOuter?: number;
22
+ paddingTop?: number;
23
+ paddingRight?: number;
24
+ paddingBottom?: number;
25
+ paddingLeft?: number;
26
+ ratio?: number;
27
+ orientation?: "horizontal" | "vertical";
28
+ nodeSize?: [number, number] | null;
29
+ separation?: ((a: d3.HierarchyNode<any>, b: d3.HierarchyNode<any>) => number) | null;
30
+ }
31
+
32
+ export interface HierarchyOptions {
33
+ idAccessor?: (d: any) => string;
34
+ parentAccessor?: (d: any) => string | null;
35
+ valueAccessor?: (d: any) => number;
36
+ sort?: (a: d3.HierarchyNode<any>, b: d3.HierarchyNode<any>) => number;
37
+ includeRoot?: boolean;
38
+ includeInternal?: boolean;
39
+ maxDepth?: number;
40
+ }
41
+
42
+ export interface ExtractionOptions {
43
+ includeRoot?: boolean;
44
+ includeInternal?: boolean;
45
+ maxDepth?: number;
46
+ }
47
+
48
+ export interface ConversionOptions extends ExtractionOptions {
49
+ colorScale?: any;
50
+ }
51
+
52
+ export interface ExtractedNode {
53
+ id: string;
54
+ name: string;
55
+ value: number;
56
+ depth: number;
57
+ height: number;
58
+ parent: string | null;
59
+ x0: number;
60
+ y0: number;
61
+ x1: number;
62
+ y1: number;
63
+ r?: number;
64
+ originalData: any;
65
+ }
66
+
67
+ export interface WaterfallStackItem {
68
+ value: number;
69
+ color: string;
70
+ label: string;
71
+ }
72
+
73
+ export interface WaterfallFormatNode {
74
+ label: string;
75
+ stacks: WaterfallStackItem[];
76
+ hierarchyData: {
77
+ id: string;
78
+ depth: number;
79
+ height: number;
80
+ parent: string | null;
81
+ x0: number;
82
+ y0: number;
83
+ x1: number;
84
+ y1: number;
85
+ r?: number;
86
+ };
87
+ }
88
+
89
+ export type LayoutType = "treemap" | "partition" | "pack" | "cluster" | "tree";
90
+
91
+ export interface PartitionOptions {
92
+ orientation: "horizontal" | "vertical";
93
+ }
94
+
95
+ export interface TreeOptions {
96
+ nodeSize: [number, number] | null;
97
+ separation: ((a: d3.HierarchyNode<any>, b: d3.HierarchyNode<any>) => number) | null;
98
+ }
99
+
100
+ // Extended interfaces for D3 hierarchy nodes with layout properties
101
+ export interface LayoutNode extends d3.HierarchyNode<any> {
102
+ x0?: number;
103
+ y0?: number;
104
+ x1?: number;
105
+ y1?: number;
106
+ r?: number;
107
+ }
108
+
109
+ export interface HierarchicalLayout {
110
+ (data: d3.HierarchyNode<any>): LayoutNode;
111
+ size(): [number, number];
112
+ size(size: [number, number]): HierarchicalLayout;
113
+ padding(): number;
114
+ padding(padding: number): HierarchicalLayout;
115
+ paddingInner(): number;
116
+ paddingInner(padding: number): HierarchicalLayout;
117
+ paddingOuter(): number;
118
+ paddingOuter(padding: number): HierarchicalLayout;
119
+ paddingTop(): number;
120
+ paddingTop(padding: number): HierarchicalLayout;
121
+ paddingRight(): number;
122
+ paddingRight(padding: number): HierarchicalLayout;
123
+ paddingBottom(): number;
124
+ paddingBottom(padding: number): HierarchicalLayout;
125
+ paddingLeft(): number;
126
+ paddingLeft(padding: number): HierarchicalLayout;
127
+ round(): boolean;
128
+ round(round: boolean): HierarchicalLayout;
129
+ ratio(): number;
130
+ ratio(ratio: number): HierarchicalLayout;
131
+ type(): LayoutType;
132
+ type(type: LayoutType): HierarchicalLayout;
133
+ partitionOrientation(): "horizontal" | "vertical";
134
+ partitionOrientation(orientation: "horizontal" | "vertical"): HierarchicalLayout;
135
+ nodeSize(): [number, number] | null;
136
+ nodeSize(size: [number, number] | null): HierarchicalLayout;
137
+ separation(): ((a: d3.HierarchyNode<any>, b: d3.HierarchyNode<any>) => number) | null;
138
+ separation(separation: ((a: d3.HierarchyNode<any>, b: d3.HierarchyNode<any>) => number) | null): HierarchicalLayout;
139
+ }
140
+
141
+ export interface HierarchyLayouts {
142
+ treemap(data: HierarchicalData | any[], options?: LayoutOptions & HierarchyOptions): LayoutNode;
143
+ partition(data: HierarchicalData | any[], options?: LayoutOptions & HierarchyOptions): LayoutNode;
144
+ pack(data: HierarchicalData | any[], options?: LayoutOptions & HierarchyOptions): LayoutNode;
145
+ }
146
+
147
+ /**
148
+ * Creates a hierarchical layout system for advanced data visualization
149
+ * @returns {HierarchicalLayout} Layout system API
150
+ */
151
+ export function createHierarchicalLayout(): HierarchicalLayout {
152
+ let size: [number, number] = [800, 400];
153
+ let padding = 0;
154
+ let round = false;
155
+ let layoutType: LayoutType = "treemap";
156
+ let paddingInner = 0;
157
+ let paddingOuter = 0;
158
+ let paddingTop = 0;
159
+ let paddingRight = 0;
160
+ let paddingBottom = 0;
161
+ let paddingLeft = 0;
162
+ let ratio = 1.618033988749895; // Golden ratio by default
163
+
164
+ // Additional layout-specific options
165
+ let partitionOptions: PartitionOptions = {
166
+ orientation: "horizontal"
167
+ };
168
+
169
+ let treeOptions: TreeOptions = {
170
+ nodeSize: null,
171
+ separation: null
172
+ };
173
+
174
+ /**
175
+ * Main layout function that processes hierarchical data
176
+ * @param {d3.HierarchyNode<any>} data - d3.hierarchy compatible data
177
+ * @returns {LayoutNode} Processed layout data
178
+ */
179
+ function layout(data: d3.HierarchyNode<any>): LayoutNode {
180
+ if (!data) {
181
+ console.error("MintWaterfall: No hierarchical data provided to layout");
182
+ throw new Error("No hierarchical data provided");
183
+ }
184
+
185
+ // Ensure we have a d3.hierarchy object with proper sum calculation
186
+ const root = data;
187
+
188
+ // Apply the selected layout
189
+ switch (layoutType) {
190
+ case "treemap":
191
+ return applyTreemapLayout(root);
192
+ case "partition":
193
+ return applyPartitionLayout(root);
194
+ case "pack":
195
+ return applyPackLayout(root);
196
+ case "cluster":
197
+ return applyClusterLayout(root);
198
+ case "tree":
199
+ return applyTreeLayout(root);
200
+ default:
201
+ console.warn(`MintWaterfall: Unknown layout type '${layoutType}', falling back to treemap`);
202
+ return applyTreemapLayout(root);
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Applies treemap layout to hierarchical data
208
+ * @param {d3.HierarchyNode<any>} root - d3.hierarchy data
209
+ * @returns {d3.HierarchyNode<any>} Processed layout data
210
+ */
211
+ function applyTreemapLayout(root: d3.HierarchyNode<any>): LayoutNode {
212
+ const treemap = d3.treemap()
213
+ .size(size)
214
+ .round(round)
215
+ .padding(padding);
216
+
217
+ // Apply additional padding options if they exist
218
+ if (paddingInner !== undefined) treemap.paddingInner(paddingInner);
219
+ if (paddingOuter !== undefined) treemap.paddingOuter(paddingOuter);
220
+ if (paddingTop !== undefined) treemap.paddingTop(paddingTop);
221
+ if (paddingRight !== undefined) treemap.paddingRight(paddingRight);
222
+ if (paddingBottom !== undefined) treemap.paddingBottom(paddingBottom);
223
+ if (paddingLeft !== undefined) treemap.paddingLeft(paddingLeft);
224
+
225
+ return treemap(root) as LayoutNode;
226
+ }
227
+
228
+ /**
229
+ * Applies partition layout to hierarchical data
230
+ * @param {d3.HierarchyNode<any>} root - d3.hierarchy data
231
+ * @returns {LayoutNode} Processed layout data
232
+ */
233
+ function applyPartitionLayout(root: d3.HierarchyNode<any>): LayoutNode {
234
+ const partitionLayout = d3.partition()
235
+ .size(size)
236
+ .round(round)
237
+ .padding(padding);
238
+
239
+ // Apply partition layout
240
+ const result = partitionLayout(root) as LayoutNode;
241
+
242
+ // Handle orientation for partition layout
243
+ if (partitionOptions.orientation === "vertical") {
244
+ // Swap x/y coordinates and dimensions for vertical orientation
245
+ result.each((node: LayoutNode) => {
246
+ if (node.x0 !== undefined && node.y0 !== undefined &&
247
+ node.x1 !== undefined && node.y1 !== undefined) {
248
+ const temp = node.x0;
249
+ node.x0 = node.y0;
250
+ node.y0 = temp;
251
+
252
+ const tempX1 = node.x1;
253
+ node.x1 = node.y1;
254
+ node.y1 = tempX1;
255
+ }
256
+ });
257
+ }
258
+
259
+ return result;
260
+ }
261
+
262
+ /**
263
+ * Applies pack layout to hierarchical data
264
+ * @param {d3.HierarchyNode<any>} root - d3.hierarchy data
265
+ * @returns {LayoutNode} Processed layout data
266
+ */
267
+ function applyPackLayout(root: d3.HierarchyNode<any>): LayoutNode {
268
+ return d3.pack()
269
+ .size(size)
270
+ .padding(padding)
271
+ (root) as LayoutNode;
272
+ }
273
+
274
+ /**
275
+ * Applies cluster layout to hierarchical data
276
+ * @param {d3.HierarchyNode<any>} root - d3.hierarchy data
277
+ * @returns {LayoutNode} Processed layout data
278
+ */
279
+ function applyClusterLayout(root: d3.HierarchyNode<any>): LayoutNode {
280
+ const clusterLayout = d3.cluster()
281
+ .size(size);
282
+
283
+ if (treeOptions.nodeSize) {
284
+ clusterLayout.nodeSize(treeOptions.nodeSize);
285
+ }
286
+
287
+ if (treeOptions.separation) {
288
+ clusterLayout.separation(treeOptions.separation);
289
+ }
290
+
291
+ return clusterLayout(root) as LayoutNode;
292
+ }
293
+
294
+ /**
295
+ * Applies tree layout to hierarchical data
296
+ * @param {d3.HierarchyNode<any>} root - d3.hierarchy data
297
+ * @returns {LayoutNode} Processed layout data
298
+ */
299
+ function applyTreeLayout(root: d3.HierarchyNode<any>): LayoutNode {
300
+ const treeLayout = d3.tree()
301
+ .size(size);
302
+
303
+ if (treeOptions.nodeSize) {
304
+ treeLayout.nodeSize(treeOptions.nodeSize);
305
+ }
306
+
307
+ if (treeOptions.separation) {
308
+ treeLayout.separation(treeOptions.separation);
309
+ }
310
+
311
+ return treeLayout(root) as LayoutNode;
312
+ }
313
+
314
+ // Create layout object with simple object assignment
315
+ const hierarchicalLayout = layout as any;
316
+
317
+ // Add chainable methods
318
+ hierarchicalLayout.size = function(_?: [number, number]) {
319
+ return arguments.length ? (size = _!, hierarchicalLayout) : size;
320
+ };
321
+
322
+ hierarchicalLayout.padding = function(_?: number) {
323
+ return arguments.length ? (padding = _!, hierarchicalLayout) : padding;
324
+ };
325
+
326
+ hierarchicalLayout.paddingInner = function(_?: number) {
327
+ return arguments.length ? (paddingInner = _!, hierarchicalLayout) : paddingInner;
328
+ };
329
+
330
+ hierarchicalLayout.paddingOuter = function(_?: number) {
331
+ return arguments.length ? (paddingOuter = _!, hierarchicalLayout) : paddingOuter;
332
+ };
333
+
334
+ hierarchicalLayout.paddingTop = function(_?: number) {
335
+ return arguments.length ? (paddingTop = _!, hierarchicalLayout) : paddingTop;
336
+ };
337
+
338
+ hierarchicalLayout.paddingRight = function(_?: number) {
339
+ return arguments.length ? (paddingRight = _!, hierarchicalLayout) : paddingRight;
340
+ };
341
+
342
+ hierarchicalLayout.paddingBottom = function(_?: number) {
343
+ return arguments.length ? (paddingBottom = _!, hierarchicalLayout) : paddingBottom;
344
+ };
345
+
346
+ hierarchicalLayout.paddingLeft = function(_?: number) {
347
+ return arguments.length ? (paddingLeft = _!, hierarchicalLayout) : paddingLeft;
348
+ };
349
+
350
+ hierarchicalLayout.round = function(_?: boolean) {
351
+ return arguments.length ? (round = _!, hierarchicalLayout) : round;
352
+ };
353
+
354
+ hierarchicalLayout.ratio = function(_?: number) {
355
+ return arguments.length ? (ratio = _!, hierarchicalLayout) : ratio;
356
+ };
357
+
358
+ hierarchicalLayout.type = function(_?: LayoutType) {
359
+ return arguments.length ? (layoutType = _!, hierarchicalLayout) : layoutType;
360
+ };
361
+
362
+ hierarchicalLayout.partitionOrientation = function(_?: "horizontal" | "vertical") {
363
+ return arguments.length ? (partitionOptions.orientation = _!, hierarchicalLayout) : partitionOptions.orientation;
364
+ };
365
+
366
+ hierarchicalLayout.nodeSize = function(_?: [number, number] | null) {
367
+ return arguments.length ? (treeOptions.nodeSize = _!, hierarchicalLayout) : treeOptions.nodeSize;
368
+ };
369
+
370
+ hierarchicalLayout.separation = function(_?: ((a: d3.HierarchyNode<any>, b: d3.HierarchyNode<any>) => number) | null) {
371
+ return arguments.length ? (treeOptions.separation = _!, hierarchicalLayout) : treeOptions.separation;
372
+ };
373
+
374
+ return hierarchicalLayout as HierarchicalLayout;
375
+ }
376
+
377
+ /**
378
+ * Helper function to create hierarchical data structure from flat data
379
+ * @param {any[]} data - Flat data array
380
+ * @param {(d: any) => string} idAccessor - Function to get node ID
381
+ * @param {(d: any) => string | null} parentAccessor - Function to get parent ID
382
+ * @param {(d: any) => number} valueAccessor - Function to get node value
383
+ * @returns {HierarchicalData | null} Hierarchical data structure
384
+ */
385
+ export function createHierarchyFromFlatData(
386
+ data: any[],
387
+ idAccessor: (d: any) => string,
388
+ parentAccessor: (d: any) => string | null,
389
+ valueAccessor?: (d: any) => number
390
+ ): HierarchicalData | null {
391
+ if (!data || !Array.isArray(data) || data.length === 0) {
392
+ console.error("MintWaterfall: Invalid data provided to createHierarchyFromFlatData");
393
+ return null;
394
+ }
395
+
396
+ // Create map for fast lookup
397
+ const dataMap = new Map<string, HierarchicalData>();
398
+
399
+ // First pass: create nodes
400
+ const root: HierarchicalData = {
401
+ id: "root",
402
+ name: "Root",
403
+ children: []
404
+ };
405
+ dataMap.set("root", root);
406
+
407
+ // Create nodes for each data item
408
+ data.forEach(item => {
409
+ const id = idAccessor(item);
410
+ if (!id) {
411
+ console.warn("MintWaterfall: Item missing ID in createHierarchyFromFlatData");
412
+ return;
413
+ }
414
+
415
+ const node: HierarchicalData = {
416
+ id,
417
+ name: id,
418
+ data: item,
419
+ value: valueAccessor ? valueAccessor(item) : undefined,
420
+ children: []
421
+ };
422
+ dataMap.set(id, node);
423
+ });
424
+
425
+ // Second pass: establish parent-child relationships
426
+ data.forEach(item => {
427
+ const id = idAccessor(item);
428
+ const parentId = parentAccessor(item) || "root";
429
+
430
+ const node = dataMap.get(id);
431
+ const parent = dataMap.get(parentId);
432
+
433
+ if (parent && node && parent.children) {
434
+ parent.children.push(node);
435
+ }
436
+ });
437
+
438
+ // Return the root node
439
+ return root;
440
+ }
441
+
442
+ /**
443
+ * Creates a d3.hierarchy object from data
444
+ * @param {HierarchicalData | any[]} data - Hierarchical data or flat data array
445
+ * @param {HierarchyOptions} options - Configuration options
446
+ * @returns {d3.HierarchyNode<any> | null} d3.hierarchy object
447
+ */
448
+ export function createHierarchy(
449
+ data: HierarchicalData | any[],
450
+ options: HierarchyOptions = {}
451
+ ): d3.HierarchyNode<any> | null {
452
+ if (!data) {
453
+ console.error("MintWaterfall: No data provided to createHierarchy");
454
+ return null;
455
+ }
456
+
457
+ let hierarchyData: HierarchicalData | null;
458
+
459
+ // If data is flat array and we have accessor functions, convert to hierarchical
460
+ if (Array.isArray(data) && options.idAccessor && options.parentAccessor) {
461
+ hierarchyData = createHierarchyFromFlatData(
462
+ data,
463
+ options.idAccessor,
464
+ options.parentAccessor,
465
+ options.valueAccessor
466
+ );
467
+ } else {
468
+ // Assume data is already in hierarchical format
469
+ hierarchyData = data as HierarchicalData;
470
+ }
471
+
472
+ if (!hierarchyData) {
473
+ return null;
474
+ }
475
+
476
+ // Create d3.hierarchy object
477
+ const hierarchy = d3.hierarchy(hierarchyData);
478
+
479
+ // Apply value accessor if provided
480
+ if (options.valueAccessor) {
481
+ hierarchy.sum(d => {
482
+ // For leaf nodes, use the value accessor
483
+ if (!d.children || d.children.length === 0) {
484
+ return d.value !== undefined ? d.value : (options.valueAccessor!(d) || 0);
485
+ }
486
+ // For parent nodes, return 0 (sum will be calculated from children)
487
+ return 0;
488
+ });
489
+ } else {
490
+ hierarchy.sum(d => d.value || 0);
491
+ }
492
+
493
+ // Apply sorting if provided
494
+ if (options.sort) {
495
+ hierarchy.sort(options.sort);
496
+ }
497
+
498
+ return hierarchy;
499
+ }
500
+
501
+ /**
502
+ * Helper function to extract data from a hierarchical layout
503
+ * @param {d3.HierarchyNode<any>} layoutData - Processed layout data
504
+ * @param {ExtractionOptions} options - Extraction options
505
+ * @returns {ExtractedNode[]} Extracted data
506
+ */
507
+ export function extractLayoutData(
508
+ layoutData: LayoutNode,
509
+ options: ExtractionOptions = {}
510
+ ): ExtractedNode[] {
511
+ if (!layoutData) {
512
+ console.error("MintWaterfall: No layout data provided to extractLayoutData");
513
+ return [];
514
+ }
515
+
516
+ const result: ExtractedNode[] = [];
517
+ const includeRoot = options.includeRoot || false;
518
+ const includeInternal = options.includeInternal || false;
519
+ const maxDepth = options.maxDepth || Infinity;
520
+
521
+ // Traverse the hierarchy
522
+ layoutData.each((node: LayoutNode) => {
523
+ // Skip root if not included
524
+ if (!includeRoot && !node.parent) {
525
+ return;
526
+ }
527
+
528
+ // Skip internal nodes if not included
529
+ if (!includeInternal && node.children && node.children.length > 0) {
530
+ return;
531
+ }
532
+
533
+ // Skip nodes beyond max depth
534
+ if (node.depth > maxDepth) {
535
+ return;
536
+ }
537
+
538
+ // Extract node data with proper type casting
539
+ result.push({
540
+ id: node.data.id || `node-${node.depth}-${node.height}`,
541
+ name: node.data.name || "",
542
+ value: node.value!,
543
+ depth: node.depth,
544
+ height: node.height,
545
+ parent: node.parent ? (node.parent.data.id || `node-${node.parent.depth}-${node.parent.height}`) : null,
546
+ x0: node.x0 || 0,
547
+ y0: node.y0 || 0,
548
+ x1: node.x1 || 0,
549
+ y1: node.y1 || 0,
550
+ r: node.r,
551
+ originalData: node.data
552
+ });
553
+ });
554
+
555
+ return result;
556
+ }
557
+
558
+ /**
559
+ * Helper function to convert hierarchical layout to waterfall-compatible format
560
+ * @param {d3.HierarchyNode<any>} layoutData - Processed layout data
561
+ * @param {ConversionOptions} options - Conversion options
562
+ * @returns {WaterfallFormatNode[]} Waterfall-compatible data
563
+ */
564
+ export function convertToWaterfallFormat(
565
+ layoutData: LayoutNode,
566
+ options: ConversionOptions = {}
567
+ ): WaterfallFormatNode[] {
568
+ if (!layoutData) {
569
+ console.error("MintWaterfall: No layout data provided to convertToWaterfallFormat");
570
+ return [];
571
+ }
572
+
573
+ const extractedData = extractLayoutData(layoutData, {
574
+ includeRoot: options.includeRoot || false,
575
+ includeInternal: options.includeInternal || true,
576
+ maxDepth: options.maxDepth || 2
577
+ });
578
+
579
+ // Generate color scale if not provided
580
+ const colorScale = options.colorScale || d3.scaleOrdinal(d3.schemeCategory10);
581
+
582
+ // Convert to waterfall format
583
+ return extractedData.map(node => {
584
+ return {
585
+ label: node.name,
586
+ stacks: [{
587
+ value: node.value,
588
+ color: typeof colorScale === "function" ? colorScale(node.depth.toString()) : colorScale,
589
+ label: node.value.toString()
590
+ }],
591
+ hierarchyData: {
592
+ id: node.id,
593
+ depth: node.depth,
594
+ height: node.height,
595
+ parent: node.parent,
596
+ x0: node.x0,
597
+ y0: node.y0,
598
+ x1: node.x1,
599
+ y1: node.y1,
600
+ r: node.r
601
+ }
602
+ };
603
+ });
604
+ }
605
+
606
+ // Export layout helpers for direct use
607
+ export const hierarchyLayouts: HierarchyLayouts = {
608
+ treemap: function(data: HierarchicalData | any[], options: LayoutOptions & HierarchyOptions = {}) {
609
+ const layout = createHierarchicalLayout()
610
+ .type("treemap")
611
+ .size(options.size || [800, 400])
612
+ .padding(options.padding || 1);
613
+
614
+ const hierarchy = createHierarchy(data, options);
615
+ if (!hierarchy) {
616
+ throw new Error("Failed to create hierarchy");
617
+ }
618
+ return layout(hierarchy);
619
+ },
620
+
621
+ partition: function(data: HierarchicalData | any[], options: LayoutOptions & HierarchyOptions = {}) {
622
+ const layout = createHierarchicalLayout()
623
+ .type("partition")
624
+ .size(options.size || [800, 400])
625
+ .padding(options.padding || 1)
626
+ .partitionOrientation(options.orientation || "horizontal");
627
+
628
+ const hierarchy = createHierarchy(data, options);
629
+ if (!hierarchy) {
630
+ throw new Error("Failed to create hierarchy");
631
+ }
632
+ return layout(hierarchy);
633
+ },
634
+
635
+ pack: function(data: HierarchicalData | any[], options: LayoutOptions & HierarchyOptions = {}) {
636
+ const layout = createHierarchicalLayout()
637
+ .type("pack")
638
+ .size(options.size || [800, 400])
639
+ .padding(options.padding || 1);
640
+
641
+ const hierarchy = createHierarchy(data, options);
642
+ if (!hierarchy) {
643
+ throw new Error("Failed to create hierarchy");
644
+ }
645
+ return layout(hierarchy);
646
+ }
647
+ };