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,595 @@
1
+ // MintWaterfall Animation and Transitions System - TypeScript Version
2
+ // Provides smooth animations and transitions for chart updates with full type safety
3
+
4
+ // Type definitions for animation system
5
+ export interface EasingFunction {
6
+ (t: number): number;
7
+ }
8
+
9
+ export interface EasingFunctions {
10
+ linear: EasingFunction;
11
+ easeInQuad: EasingFunction;
12
+ easeOutQuad: EasingFunction;
13
+ easeInOutQuad: EasingFunction;
14
+ easeInCubic: EasingFunction;
15
+ easeOutCubic: EasingFunction;
16
+ easeInOutCubic: EasingFunction;
17
+ easeInSine: EasingFunction;
18
+ easeOutSine: EasingFunction;
19
+ easeInOutSine: EasingFunction;
20
+ easeInElastic: EasingFunction;
21
+ easeOutElastic: EasingFunction;
22
+ easeOutBounce: EasingFunction;
23
+ }
24
+
25
+ export interface TransitionConfig {
26
+ staggerDelay: number;
27
+ defaultDuration: number;
28
+ defaultEase: keyof EasingFunctions;
29
+ }
30
+
31
+ export interface AnimationOptions {
32
+ delay?: number;
33
+ duration?: number;
34
+ ease?: keyof EasingFunctions;
35
+ reverse?: boolean;
36
+ }
37
+
38
+ export interface TransitionStep {
39
+ fn: () => Promise<any>;
40
+ delay: number;
41
+ }
42
+
43
+ export interface TransitionSequence {
44
+ add(transitionFn: () => Promise<any>, delay?: number): TransitionSequence;
45
+ parallel(...transitionFns: (() => Promise<any>)[]): TransitionSequence;
46
+ play(): Promise<void>;
47
+ stop(): void;
48
+ readonly isRunning: boolean;
49
+ }
50
+
51
+ export interface SpringAnimation {
52
+ animate(
53
+ startValue: number,
54
+ endValue: number,
55
+ onUpdate?: (value: number) => void,
56
+ onComplete?: () => void
57
+ ): void;
58
+ }
59
+
60
+ export interface TransitionWithEvents {
61
+ start(): TransitionWithEvents;
62
+ interrupt(): TransitionWithEvents;
63
+ then(callback?: () => void): TransitionWithEvents;
64
+ }
65
+
66
+ export interface TransitionEventConfig {
67
+ duration?: number;
68
+ onStart?: () => void;
69
+ onEnd?: () => void;
70
+ onInterrupt?: () => void;
71
+ }
72
+
73
+ export interface AnimationPresets {
74
+ slideInLeft(element: any, duration?: number): Promise<void>;
75
+ slideInRight(element: any, duration?: number): Promise<void>;
76
+ fadeIn(element: any, duration?: number): Promise<void>;
77
+ fadeOut(element: any, duration?: number): Promise<void>;
78
+ scaleIn(element: any, duration?: number): Promise<void>;
79
+ scaleOut(element: any, duration?: number): Promise<void>;
80
+ pulse(element: any, duration?: number): Promise<void>;
81
+ bounce(element: any, duration?: number): Promise<void>;
82
+ }
83
+
84
+ export interface AnimationSystem {
85
+ easingFunctions: EasingFunctions;
86
+ animateValue(
87
+ startValue: number,
88
+ endValue: number,
89
+ duration: number,
90
+ easingType?: keyof EasingFunctions,
91
+ onUpdate?: (value: number, progress: number) => void,
92
+ onComplete?: () => void
93
+ ): void;
94
+ staggeredAnimation(
95
+ items: any[],
96
+ animationFn: (item: any, index: number, duration: number) => void,
97
+ staggerDelay?: number,
98
+ totalDuration?: number
99
+ ): void;
100
+ morphShape(
101
+ fromPath: string,
102
+ toPath: string,
103
+ duration?: number,
104
+ easingType?: keyof EasingFunctions,
105
+ onUpdate?: (path: string, progress: number) => void,
106
+ onComplete?: () => void
107
+ ): void;
108
+ fadeTransition(
109
+ element: any,
110
+ fromOpacity: number,
111
+ toOpacity: number,
112
+ duration?: number,
113
+ easingType?: keyof EasingFunctions
114
+ ): Promise<void>;
115
+ slideTransition(
116
+ element: any,
117
+ fromX: number,
118
+ toX: number,
119
+ duration?: number,
120
+ easingType?: keyof EasingFunctions
121
+ ): Promise<void>;
122
+ scaleTransition(
123
+ element: any,
124
+ fromScale: number,
125
+ toScale: number,
126
+ duration?: number,
127
+ easingType?: keyof EasingFunctions
128
+ ): Promise<void>;
129
+ createTransitionSequence(): TransitionSequence;
130
+ createSpringAnimation(tension?: number, friction?: number): SpringAnimation;
131
+ createStaggeredTransition(
132
+ elements: any[] | NodeListOf<Element>,
133
+ animationFn: (element: any, duration: number, ease: keyof EasingFunctions) => Promise<any>,
134
+ options?: AnimationOptions
135
+ ): Promise<any[]>;
136
+ createCustomTween(startValue: number, endValue: number, interpolator?: (start: number, end: number, t: number) => number): (t: number) => number;
137
+ createTransitionWithEvents(element: any, config: TransitionEventConfig): TransitionWithEvents;
138
+ transitionConfig: TransitionConfig;
139
+ presets: AnimationPresets;
140
+ }
141
+
142
+ export function createAnimationSystem(): AnimationSystem {
143
+
144
+ // Advanced transition configuration
145
+ const transitionConfig: TransitionConfig = {
146
+ staggerDelay: 100, // Default stagger delay between elements
147
+ defaultDuration: 750, // Default animation duration
148
+ defaultEase: "easeOutQuad"
149
+ };
150
+
151
+ function createEasingFunctions(): EasingFunctions {
152
+ return {
153
+ linear: (t: number) => t,
154
+ easeInQuad: (t: number) => t * t,
155
+ easeOutQuad: (t: number) => t * (2 - t),
156
+ easeInOutQuad: (t: number) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
157
+ easeInCubic: (t: number) => t * t * t,
158
+ easeOutCubic: (t: number) => (--t) * t * t + 1,
159
+ easeInOutCubic: (t: number) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
160
+ easeInSine: (t: number) => 1 - Math.cos(t * Math.PI / 2),
161
+ easeOutSine: (t: number) => Math.sin(t * Math.PI / 2),
162
+ easeInOutSine: (t: number) => -(Math.cos(Math.PI * t) - 1) / 2,
163
+ easeInElastic: (t: number) => {
164
+ const c4 = (2 * Math.PI) / 3;
165
+ return t === 0 ? 0 : t === 1 ? 1 : -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * c4);
166
+ },
167
+ easeOutElastic: (t: number) => {
168
+ const c4 = (2 * Math.PI) / 3;
169
+ return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
170
+ },
171
+ easeOutBounce: (t: number) => {
172
+ const n1 = 7.5625;
173
+ const d1 = 2.75;
174
+
175
+ if (t < 1 / d1) {
176
+ return n1 * t * t;
177
+ } else if (t < 2 / d1) {
178
+ return n1 * (t -= 1.5 / d1) * t + 0.75;
179
+ } else if (t < 2.5 / d1) {
180
+ return n1 * (t -= 2.25 / d1) * t + 0.9375;
181
+ } else {
182
+ return n1 * (t -= 2.625 / d1) * t + 0.984375;
183
+ }
184
+ }
185
+ };
186
+ }
187
+
188
+ const easingFunctions = createEasingFunctions();
189
+
190
+ function animateValue(
191
+ startValue: number,
192
+ endValue: number,
193
+ duration: number,
194
+ easingType: keyof EasingFunctions = "easeOutQuad",
195
+ onUpdate?: (value: number, progress: number) => void,
196
+ onComplete?: () => void
197
+ ): void {
198
+ const startTime = performance.now();
199
+ const valueRange = endValue - startValue;
200
+ const easing = easingFunctions[easingType] || easingFunctions.easeOutQuad;
201
+
202
+ function frame(currentTime: number): void {
203
+ const elapsed = currentTime - startTime;
204
+ const progress = Math.min(elapsed / duration, 1);
205
+
206
+ const easedProgress = easing(progress);
207
+ const currentValue = startValue + (valueRange * easedProgress);
208
+
209
+ if (onUpdate) {
210
+ onUpdate(currentValue, progress);
211
+ }
212
+
213
+ if (progress < 1) {
214
+ requestAnimationFrame(frame);
215
+ } else if (onComplete) {
216
+ onComplete();
217
+ }
218
+ }
219
+
220
+ requestAnimationFrame(frame);
221
+ }
222
+
223
+ function staggeredAnimation(
224
+ items: any[],
225
+ animationFn: (item: any, index: number, duration: number) => void,
226
+ staggerDelay: number = 100,
227
+ totalDuration: number = 1000
228
+ ): void {
229
+ if (!Array.isArray(items)) {
230
+ throw new Error("Items must be an array");
231
+ }
232
+
233
+ items.forEach((item, index) => {
234
+ const delay = index * staggerDelay;
235
+ const adjustedDuration = totalDuration - delay;
236
+
237
+ setTimeout(() => {
238
+ if (adjustedDuration > 0) {
239
+ animationFn(item, index, adjustedDuration);
240
+ }
241
+ }, delay);
242
+ });
243
+ }
244
+
245
+ function morphShape(
246
+ fromPath: string,
247
+ toPath: string,
248
+ duration: number = 1000,
249
+ easingType: keyof EasingFunctions = "easeInOutQuad",
250
+ onUpdate?: (path: string, progress: number) => void,
251
+ onComplete?: () => void
252
+ ): void {
253
+ // Simple path morphing for basic shapes
254
+ // Note: In a real implementation, you'd want more sophisticated path interpolation
255
+
256
+ if (typeof fromPath !== "string" || typeof toPath !== "string") {
257
+ throw new Error("Path values must be strings");
258
+ }
259
+
260
+ const startTime = performance.now();
261
+ const easing = easingFunctions[easingType] || easingFunctions.easeInOutQuad;
262
+
263
+ function frame(currentTime: number): void {
264
+ const elapsed = currentTime - startTime;
265
+ const progress = Math.min(elapsed / duration, 1);
266
+
267
+ const easedProgress = easing(progress);
268
+
269
+ // Simple interpolation - in production, use a proper path morphing library
270
+ const interpolatedPath = progress < 0.5 ? fromPath : toPath;
271
+
272
+ if (onUpdate) {
273
+ onUpdate(interpolatedPath, easedProgress);
274
+ }
275
+
276
+ if (progress < 1) {
277
+ requestAnimationFrame(frame);
278
+ } else if (onComplete) {
279
+ onComplete();
280
+ }
281
+ }
282
+
283
+ requestAnimationFrame(frame);
284
+ }
285
+
286
+ function fadeTransition(
287
+ element: any,
288
+ fromOpacity: number,
289
+ toOpacity: number,
290
+ duration: number = 500,
291
+ easingType: keyof EasingFunctions = "easeOutQuad"
292
+ ): Promise<void> {
293
+ return new Promise((resolve) => {
294
+ animateValue(
295
+ fromOpacity,
296
+ toOpacity,
297
+ duration,
298
+ easingType,
299
+ (value) => {
300
+ if (element && element.style) {
301
+ element.style.opacity = value.toString();
302
+ } else if (element && element.attr) {
303
+ // D3 selection
304
+ element.attr("opacity", value);
305
+ }
306
+ },
307
+ () => resolve()
308
+ );
309
+ });
310
+ }
311
+
312
+ function slideTransition(
313
+ element: any,
314
+ fromX: number,
315
+ toX: number,
316
+ duration: number = 500,
317
+ easingType: keyof EasingFunctions = "easeOutQuad"
318
+ ): Promise<void> {
319
+ return new Promise((resolve) => {
320
+ animateValue(
321
+ fromX,
322
+ toX,
323
+ duration,
324
+ easingType,
325
+ (value) => {
326
+ if (element && element.style) {
327
+ element.style.transform = `translateX(${value}px)`;
328
+ } else if (element && element.attr) {
329
+ // D3 selection
330
+ element.attr("transform", `translate(${value}, 0)`);
331
+ }
332
+ },
333
+ () => resolve()
334
+ );
335
+ });
336
+ }
337
+
338
+ function scaleTransition(
339
+ element: any,
340
+ fromScale: number,
341
+ toScale: number,
342
+ duration: number = 500,
343
+ easingType: keyof EasingFunctions = "easeOutQuad"
344
+ ): Promise<void> {
345
+ return new Promise((resolve) => {
346
+ animateValue(
347
+ fromScale,
348
+ toScale,
349
+ duration,
350
+ easingType,
351
+ (value) => {
352
+ if (element && element.style) {
353
+ element.style.transform = `scale(${value})`;
354
+ } else if (element && element.attr) {
355
+ // D3 selection
356
+ element.attr("transform", `scale(${value})`);
357
+ }
358
+ },
359
+ () => resolve()
360
+ );
361
+ });
362
+ }
363
+
364
+ function createTransitionSequence(): TransitionSequence {
365
+ const sequence: TransitionStep[] = [];
366
+ let isRunning = false;
367
+
368
+ function add(transitionFn: () => Promise<any>, delay: number = 0): TransitionSequence {
369
+ sequence.push({ fn: transitionFn, delay });
370
+ return transitionSequence;
371
+ }
372
+
373
+ function parallel(...transitionFns: (() => Promise<any>)[]): TransitionSequence {
374
+ sequence.push({
375
+ fn: () => Promise.all(transitionFns.map(fn => fn())),
376
+ delay: 0
377
+ });
378
+ return transitionSequence;
379
+ }
380
+
381
+ async function play(): Promise<void> {
382
+ if (isRunning) {
383
+ throw new Error("Sequence is already running");
384
+ }
385
+
386
+ isRunning = true;
387
+
388
+ try {
389
+ for (const step of sequence) {
390
+ if (step.delay > 0) {
391
+ await new Promise<void>(resolve => setTimeout(resolve, step.delay));
392
+ }
393
+ await step.fn();
394
+ }
395
+ } finally {
396
+ isRunning = false;
397
+ }
398
+ }
399
+
400
+ function stop(): void {
401
+ isRunning = false;
402
+ // Note: In a production system, you'd want to cancel running animations
403
+ }
404
+
405
+ const transitionSequence: TransitionSequence = {
406
+ add,
407
+ parallel,
408
+ play,
409
+ stop,
410
+ get isRunning() { return isRunning; }
411
+ };
412
+
413
+ return transitionSequence;
414
+ }
415
+
416
+ function createSpringAnimation(tension: number = 300, friction: number = 20): SpringAnimation {
417
+ // Simple spring physics implementation
418
+ function animate(
419
+ startValue: number,
420
+ endValue: number,
421
+ onUpdate?: (value: number) => void,
422
+ onComplete?: () => void
423
+ ): void {
424
+ let position = startValue;
425
+ let velocity = 0;
426
+ let lastTime = performance.now();
427
+
428
+ function frame(currentTime: number): void {
429
+ const deltaTime = (currentTime - lastTime) / 1000; // Convert to seconds
430
+ lastTime = currentTime;
431
+
432
+ const displacement = position - endValue;
433
+ const springForce = -tension * displacement;
434
+ const dampingForce = -friction * velocity;
435
+
436
+ const acceleration = springForce + dampingForce;
437
+ velocity += acceleration * deltaTime;
438
+ position += velocity * deltaTime;
439
+
440
+ if (onUpdate) {
441
+ onUpdate(position);
442
+ }
443
+
444
+ // Check if animation should continue
445
+ const isAtRest = Math.abs(displacement) < 0.01 && Math.abs(velocity) < 0.01;
446
+
447
+ if (!isAtRest) {
448
+ requestAnimationFrame(frame);
449
+ } else if (onComplete) {
450
+ onComplete();
451
+ }
452
+ }
453
+
454
+ requestAnimationFrame(frame);
455
+ }
456
+
457
+ return { animate };
458
+ }
459
+
460
+ function createAnimationPresets(): AnimationPresets {
461
+ return {
462
+ slideInLeft: (element: any, duration: number = 500) =>
463
+ slideTransition(element, -100, 0, duration, "easeOutQuad"),
464
+
465
+ slideInRight: (element: any, duration: number = 500) =>
466
+ slideTransition(element, 100, 0, duration, "easeOutQuad"),
467
+
468
+ fadeIn: (element: any, duration: number = 500) =>
469
+ fadeTransition(element, 0, 1, duration, "easeOutQuad"),
470
+
471
+ fadeOut: (element: any, duration: number = 500) =>
472
+ fadeTransition(element, 1, 0, duration, "easeOutQuad"),
473
+
474
+ scaleIn: (element: any, duration: number = 500) =>
475
+ scaleTransition(element, 0, 1, duration, "easeOutElastic"),
476
+
477
+ scaleOut: (element: any, duration: number = 500) =>
478
+ scaleTransition(element, 1, 0, duration, "easeInQuad"),
479
+
480
+ pulse: (element: any, duration: number = 300) => {
481
+ const sequence = createTransitionSequence();
482
+ return sequence
483
+ .add(() => scaleTransition(element, 1, 1.1, duration / 2, "easeOutQuad"))
484
+ .add(() => scaleTransition(element, 1.1, 1, duration / 2, "easeInQuad"))
485
+ .play();
486
+ },
487
+
488
+ bounce: (element: any, duration: number = 600) =>
489
+ scaleTransition(element, 0, 1, duration, "easeOutBounce")
490
+ };
491
+ }
492
+
493
+ const presets = createAnimationPresets();
494
+
495
+ // Advanced staggered animations
496
+ function createStaggeredTransition(
497
+ elements: any[] | NodeListOf<Element>,
498
+ animationFn: (element: any, duration: number, ease: keyof EasingFunctions) => Promise<any>,
499
+ options: AnimationOptions = {}
500
+ ): Promise<any[]> {
501
+ const {
502
+ delay = transitionConfig.staggerDelay,
503
+ duration = transitionConfig.defaultDuration,
504
+ ease = transitionConfig.defaultEase,
505
+ reverse = false
506
+ } = options;
507
+
508
+ const elementArray = Array.isArray(elements) ? elements : Array.from(elements);
509
+ const orderedElements = reverse ? [...elementArray].reverse() : elementArray;
510
+
511
+ return Promise.all(
512
+ orderedElements.map((element, index) => {
513
+ return new Promise<any>(resolve => {
514
+ setTimeout(() => {
515
+ animationFn(element, duration, ease).then(resolve);
516
+ }, index * delay);
517
+ });
518
+ })
519
+ );
520
+ }
521
+
522
+ // Custom tweening functions
523
+ function createCustomTween(
524
+ startValue: number,
525
+ endValue: number,
526
+ interpolator?: (start: number, end: number, t: number) => number
527
+ ): (t: number) => number {
528
+ return function(t: number): number {
529
+ if (typeof interpolator === "function") {
530
+ return interpolator(startValue, endValue, t);
531
+ }
532
+ // Default linear interpolation
533
+ return startValue + (endValue - startValue) * t;
534
+ };
535
+ }
536
+
537
+ // Transition event handlers
538
+ function createTransitionWithEvents(element: any, config: TransitionEventConfig): TransitionWithEvents {
539
+ const {
540
+ duration = transitionConfig.defaultDuration,
541
+ onStart,
542
+ onEnd,
543
+ onInterrupt
544
+ } = config;
545
+
546
+ let isInterrupted = false;
547
+
548
+ const transition: TransitionWithEvents = {
549
+ start(): TransitionWithEvents {
550
+ if (onStart) onStart();
551
+ return this;
552
+ },
553
+
554
+ interrupt(): TransitionWithEvents {
555
+ isInterrupted = true;
556
+ if (onInterrupt) onInterrupt();
557
+ return this;
558
+ },
559
+
560
+ then(callback?: () => void): TransitionWithEvents {
561
+ if (!isInterrupted && onEnd) {
562
+ setTimeout(() => {
563
+ onEnd();
564
+ if (callback) callback();
565
+ }, duration);
566
+ }
567
+ return this;
568
+ }
569
+ };
570
+
571
+ return transition;
572
+ }
573
+
574
+ const animationSystem: AnimationSystem = {
575
+ easingFunctions,
576
+ animateValue,
577
+ staggeredAnimation,
578
+ morphShape,
579
+ fadeTransition,
580
+ slideTransition,
581
+ scaleTransition,
582
+ createTransitionSequence,
583
+ createSpringAnimation,
584
+ createStaggeredTransition,
585
+ createCustomTween,
586
+ createTransitionWithEvents,
587
+ transitionConfig,
588
+ presets
589
+ };
590
+
591
+ return animationSystem;
592
+ }
593
+
594
+ // Create a global animation system instance
595
+ export const animationSystem = createAnimationSystem();