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,399 @@
1
+ // MintWaterfall Zoom & Pan System - TypeScript Version
2
+ // Provides interactive zoom and pan functionality with smooth performance and full type safety
3
+
4
+ import * as d3 from 'd3';
5
+
6
+ // Type definitions for zoom system
7
+ export interface ZoomConfig {
8
+ enabled: boolean;
9
+ scaleExtent: [number, number];
10
+ translateExtent: [[number, number], [number, number]] | null;
11
+ wheelDelta: ((event: WheelEvent) => number) | null;
12
+ touchable: boolean;
13
+ filter: ((event: any) => boolean) | null;
14
+ constrain: {
15
+ x: boolean;
16
+ y: boolean;
17
+ };
18
+ duration: number;
19
+ ease: (t: number) => number;
20
+ }
21
+
22
+ export interface ChartDimensions {
23
+ width: number;
24
+ height: number;
25
+ margin: {
26
+ top: number;
27
+ right: number;
28
+ bottom: number;
29
+ left: number;
30
+ };
31
+ }
32
+
33
+ export interface ZoomEventData {
34
+ transform: d3.ZoomTransform;
35
+ sourceEvent: any;
36
+ }
37
+
38
+ export interface ZoomTransition {
39
+ to: d3.ZoomTransform;
40
+ duration?: number;
41
+ ease?: (t: number) => number;
42
+ }
43
+
44
+ export interface ZoomBounds {
45
+ x: [number, number];
46
+ y: [number, number];
47
+ }
48
+
49
+ export interface ZoomSystem {
50
+ enable(): ZoomSystem;
51
+ disable(): ZoomSystem;
52
+ attach(container: d3.Selection<any, any, any, any>): ZoomSystem;
53
+ detach(): ZoomSystem;
54
+ transform(selection: d3.Selection<any, any, any, any>, transform: d3.ZoomTransform, duration?: number): ZoomSystem;
55
+ reset(duration?: number): ZoomSystem;
56
+ zoomTo(bounds: ZoomBounds, duration?: number): ZoomSystem;
57
+ setDimensions(dimensions: ChartDimensions): ZoomSystem;
58
+ configure(newConfig: Partial<ZoomConfig>): ZoomSystem;
59
+ getCurrentTransform(): d3.ZoomTransform;
60
+ isEnabled(): boolean;
61
+ on(type: string, callback: (event: ZoomEventData) => void): ZoomSystem;
62
+ off(type: string, callback?: (event: ZoomEventData) => void): ZoomSystem;
63
+ }
64
+
65
+ export type ZoomEventType = 'zoomstart' | 'zoom' | 'zoomend' | 'reset';
66
+
67
+ export function createZoomSystem(): ZoomSystem {
68
+
69
+ // Zoom configuration
70
+ const config: ZoomConfig = {
71
+ enabled: true,
72
+ scaleExtent: [0.1, 10],
73
+ translateExtent: null, // Auto-calculated based on chart dimensions
74
+ wheelDelta: null, // Use D3 default for proper zoom in/out
75
+ touchable: true,
76
+ filter: null, // Custom filter function
77
+ constrain: {
78
+ x: true,
79
+ y: true
80
+ },
81
+ duration: 250,
82
+ ease: d3.easeQuadOut
83
+ };
84
+
85
+ let zoomBehavior: d3.ZoomBehavior<any, any> | null = null;
86
+ let currentTransform: d3.ZoomTransform = d3.zoomIdentity;
87
+ let chartContainer: d3.Selection<any, any, any, any> | null = null;
88
+ let chartDimensions: ChartDimensions = {
89
+ width: 800,
90
+ height: 400,
91
+ margin: { top: 60, right: 80, bottom: 60, left: 80 }
92
+ };
93
+
94
+ // Event listeners
95
+ const listeners = d3.dispatch("zoomstart", "zoom", "zoomend", "reset");
96
+
97
+ function createZoomBehavior(): d3.ZoomBehavior<any, any> {
98
+ if (zoomBehavior) return zoomBehavior;
99
+
100
+ zoomBehavior = d3.zoom<any, any>()
101
+ .scaleExtent(config.scaleExtent)
102
+ .touchable(config.touchable)
103
+ .filter(config.filter || defaultFilter)
104
+ .on("start", handleZoomStart)
105
+ .on("zoom", handleZoom)
106
+ .on("end", handleZoomEnd);
107
+
108
+ // Only set wheelDelta if explicitly configured (null means use D3 default)
109
+ if (config.wheelDelta !== null) {
110
+ zoomBehavior.wheelDelta(config.wheelDelta);
111
+ }
112
+
113
+ updateTranslateExtent();
114
+ return zoomBehavior;
115
+ }
116
+
117
+ function defaultFilter(event: any): boolean {
118
+ // Allow zoom on wheel, but prevent on right-click
119
+ return (!event.ctrlKey || event.type === "wheel") && !event.button;
120
+ }
121
+
122
+ function updateTranslateExtent(): void {
123
+ if (!zoomBehavior || !chartDimensions) return;
124
+
125
+ const { width, height, margin } = chartDimensions;
126
+ const chartWidth = width - margin.left - margin.right;
127
+ const chartHeight = height - margin.top - margin.bottom;
128
+
129
+ // Calculate translate extent based on zoom constraints
130
+ const extent: [[number, number], [number, number]] = config.translateExtent || [
131
+ [-chartWidth * 2, -chartHeight * 2],
132
+ [chartWidth * 3, chartHeight * 3]
133
+ ];
134
+
135
+ zoomBehavior.translateExtent(extent);
136
+ }
137
+
138
+ function handleZoomStart(event: d3.D3ZoomEvent<any, any>): void {
139
+ const eventData: ZoomEventData = {
140
+ transform: event.transform,
141
+ sourceEvent: event.sourceEvent
142
+ };
143
+ listeners.call("zoomstart", undefined, eventData);
144
+ }
145
+
146
+ function handleZoom(event: d3.D3ZoomEvent<any, any>): void {
147
+ currentTransform = event.transform;
148
+
149
+ // Apply constraints if specified
150
+ if (!config.constrain.x) {
151
+ currentTransform = currentTransform.translate(-currentTransform.x, 0);
152
+ }
153
+ if (!config.constrain.y) {
154
+ currentTransform = currentTransform.translate(0, -currentTransform.y);
155
+ }
156
+
157
+ // Apply transform to chart elements
158
+ if (chartContainer) {
159
+ applyTransform(chartContainer, currentTransform);
160
+ }
161
+
162
+ const eventData: ZoomEventData = {
163
+ transform: currentTransform,
164
+ sourceEvent: event.sourceEvent
165
+ };
166
+ listeners.call("zoom", undefined, eventData);
167
+ }
168
+
169
+ function handleZoomEnd(event: d3.D3ZoomEvent<any, any>): void {
170
+ const eventData: ZoomEventData = {
171
+ transform: event.transform,
172
+ sourceEvent: event.sourceEvent
173
+ };
174
+ listeners.call("zoomend", undefined, eventData);
175
+ }
176
+
177
+ function applyTransform(container: d3.Selection<any, any, any, any>, transform: d3.ZoomTransform): void {
178
+ // Apply transform to the main chart group
179
+ const chartGroup = container.select(".chart-group");
180
+ if (!chartGroup.empty()) {
181
+ chartGroup.attr("transform", transform.toString());
182
+ }
183
+
184
+ // Update axes if they exist
185
+ updateAxes(container, transform);
186
+ }
187
+
188
+ function updateAxes(container: d3.Selection<any, any, any, any>, transform: d3.ZoomTransform): void {
189
+ // Update X axis if constrained
190
+ if (config.constrain.x) {
191
+ const xAxisGroup = container.select(".x-axis");
192
+ if (!xAxisGroup.empty()) {
193
+ const xScale = getScaleFromAxis(xAxisGroup);
194
+ if (xScale) {
195
+ const newXScale = transform.rescaleX(xScale);
196
+ (xAxisGroup as any).call(d3.axisBottom(newXScale));
197
+ }
198
+ }
199
+ }
200
+
201
+ // Update Y axis if constrained
202
+ if (config.constrain.y) {
203
+ const yAxisGroup = container.select(".y-axis");
204
+ if (!yAxisGroup.empty()) {
205
+ const yScale = getScaleFromAxis(yAxisGroup);
206
+ if (yScale) {
207
+ const newYScale = transform.rescaleY(yScale);
208
+ (yAxisGroup as any).call(d3.axisLeft(newYScale));
209
+ }
210
+ }
211
+ }
212
+ }
213
+
214
+ function getScaleFromAxis(axisGroup: d3.Selection<any, any, any, any>): d3.ScaleLinear<number, number> | null {
215
+ // This is a simplified implementation - in practice, you'd store references to scales
216
+ // or implement a more sophisticated scale retrieval mechanism
217
+ try {
218
+ const axisNode = axisGroup.node();
219
+ if (axisNode && (axisNode as any).__scale__) {
220
+ return (axisNode as any).__scale__;
221
+ }
222
+ } catch (e) {
223
+ // Scale retrieval failed - this is expected in some cases
224
+ }
225
+ return null;
226
+ }
227
+
228
+ // Enable zoom
229
+ function enable(): ZoomSystem {
230
+ config.enabled = true;
231
+ if (zoomBehavior && chartContainer) {
232
+ chartContainer.call(zoomBehavior);
233
+ }
234
+ return zoomSystem;
235
+ }
236
+
237
+ // Disable zoom
238
+ function disable(): ZoomSystem {
239
+ config.enabled = false;
240
+ if (chartContainer) {
241
+ chartContainer.on(".zoom", null);
242
+ }
243
+ return zoomSystem;
244
+ }
245
+
246
+ // Attach zoom to container
247
+ function attach(container: d3.Selection<any, any, any, any>): ZoomSystem {
248
+ chartContainer = container;
249
+
250
+ if (config.enabled) {
251
+ const behavior = createZoomBehavior();
252
+ container.call(behavior);
253
+ }
254
+
255
+ return zoomSystem;
256
+ }
257
+
258
+ // Detach zoom from container
259
+ function detach(): ZoomSystem {
260
+ if (chartContainer) {
261
+ chartContainer.on(".zoom", null);
262
+ chartContainer = null;
263
+ }
264
+ return zoomSystem;
265
+ }
266
+
267
+ // Transform to specific state
268
+ function transform(selection: d3.Selection<any, any, any, any>, newTransform: d3.ZoomTransform, duration: number = 0): ZoomSystem {
269
+ if (!zoomBehavior) createZoomBehavior();
270
+
271
+ if (duration > 0) {
272
+ selection
273
+ .transition()
274
+ .duration(duration)
275
+ .ease(config.ease)
276
+ .call(zoomBehavior!.transform, newTransform);
277
+ } else {
278
+ selection.call(zoomBehavior!.transform, newTransform);
279
+ }
280
+
281
+ return zoomSystem;
282
+ }
283
+
284
+ // Reset zoom to identity
285
+ function reset(duration: number = config.duration): ZoomSystem {
286
+ if (chartContainer) {
287
+ transform(chartContainer, d3.zoomIdentity, duration);
288
+ listeners.call("reset", undefined, { transform: d3.zoomIdentity, sourceEvent: null });
289
+ }
290
+ return zoomSystem;
291
+ }
292
+
293
+ // Zoom to specific bounds
294
+ function zoomTo(bounds: ZoomBounds, duration: number = config.duration): ZoomSystem {
295
+ if (!chartContainer || !chartDimensions) return zoomSystem;
296
+
297
+ const { width, height, margin } = chartDimensions;
298
+ const chartWidth = width - margin.left - margin.right;
299
+ const chartHeight = height - margin.top - margin.bottom;
300
+
301
+ // Calculate transform to fit bounds
302
+ const [x0, x1] = bounds.x;
303
+ const [y0, y1] = bounds.y;
304
+
305
+ const scale = Math.min(
306
+ chartWidth / (x1 - x0),
307
+ chartHeight / (y1 - y0)
308
+ );
309
+
310
+ const translateX = chartWidth / 2 - scale * (x0 + x1) / 2;
311
+ const translateY = chartHeight / 2 - scale * (y0 + y1) / 2;
312
+
313
+ const newTransform = d3.zoomIdentity
314
+ .translate(translateX, translateY)
315
+ .scale(scale);
316
+
317
+ transform(chartContainer, newTransform, duration);
318
+ return zoomSystem;
319
+ }
320
+
321
+ // Set chart dimensions
322
+ function setDimensions(dimensions: ChartDimensions): ZoomSystem {
323
+ chartDimensions = dimensions;
324
+ updateTranslateExtent();
325
+ return zoomSystem;
326
+ }
327
+
328
+ // Configure zoom system
329
+ function configure(newConfig: Partial<ZoomConfig>): ZoomSystem {
330
+ Object.assign(config, newConfig);
331
+
332
+ // Update zoom behavior if it exists
333
+ if (zoomBehavior) {
334
+ if (newConfig.scaleExtent) {
335
+ zoomBehavior.scaleExtent(newConfig.scaleExtent);
336
+ }
337
+ if (newConfig.touchable !== undefined) {
338
+ zoomBehavior.touchable(newConfig.touchable);
339
+ }
340
+ if (newConfig.filter !== undefined) {
341
+ zoomBehavior.filter(newConfig.filter || defaultFilter);
342
+ }
343
+ if (newConfig.wheelDelta !== undefined) {
344
+ if (newConfig.wheelDelta) {
345
+ zoomBehavior.wheelDelta(newConfig.wheelDelta);
346
+ }
347
+ }
348
+ }
349
+
350
+ updateTranslateExtent();
351
+ return zoomSystem;
352
+ }
353
+
354
+ // Get current transform
355
+ function getCurrentTransform(): d3.ZoomTransform {
356
+ return currentTransform;
357
+ }
358
+
359
+ // Check if zoom is enabled
360
+ function isEnabled(): boolean {
361
+ return config.enabled;
362
+ }
363
+
364
+ // Add event listener
365
+ function on(type: string, callback: (event: ZoomEventData) => void): ZoomSystem {
366
+ (listeners as any).on(type, callback);
367
+ return zoomSystem;
368
+ }
369
+
370
+ // Remove event listener
371
+ function off(type: string, callback?: (event: ZoomEventData) => void): ZoomSystem {
372
+ if (callback) {
373
+ (listeners as any).on(type, null);
374
+ } else {
375
+ (listeners as any).on(type, null);
376
+ }
377
+ return zoomSystem;
378
+ }
379
+
380
+ const zoomSystem: ZoomSystem = {
381
+ enable,
382
+ disable,
383
+ attach,
384
+ detach,
385
+ transform,
386
+ reset,
387
+ zoomTo,
388
+ setDimensions,
389
+ configure,
390
+ getCurrentTransform,
391
+ isEnabled,
392
+ on,
393
+ off
394
+ };
395
+
396
+ return zoomSystem;
397
+ }
398
+
399
+ // The function is already exported above, no need for duplicate export
@@ -0,0 +1,25 @@
1
+ // Type declarations for JavaScript modules during gradual TypeScript migration
2
+
3
+ declare module "../mintwaterfall-brush.js" {
4
+ export function createBrushSystem(): any;
5
+ }
6
+
7
+ declare module "../mintwaterfall-accessibility.js" {
8
+ export function createAccessibilitySystem(): any;
9
+ }
10
+
11
+ declare module "../mintwaterfall-tooltip.js" {
12
+ export function createTooltipSystem(): any;
13
+ }
14
+
15
+ declare module "../mintwaterfall-export.js" {
16
+ export function createExportSystem(): any;
17
+ }
18
+
19
+ declare module "../mintwaterfall-zoom.js" {
20
+ export function createZoomSystem(): any;
21
+ }
22
+
23
+ declare module "../mintwaterfall-performance.js" {
24
+ export function createPerformanceManager(): any;
25
+ }
File without changes