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,391 @@
1
+ // MintWaterfall Enhanced Theme System - TypeScript Version
2
+ // Provides predefined themes, advanced D3.js color schemes, and interpolation with full type safety
3
+
4
+ import * as d3 from 'd3';
5
+
6
+ // Type definitions for enhanced theme system
7
+ export interface AdvancedColorScale {
8
+ type: 'sequential' | 'diverging' | 'ordinal';
9
+ interpolator?: (t: number) => string;
10
+ domain?: number[];
11
+ range?: string[];
12
+ }
13
+
14
+ export interface Theme {
15
+ name: string;
16
+ background: string;
17
+ gridColor: string;
18
+ axisColor: string;
19
+ textColor: string;
20
+ totalColor: string;
21
+ colors: string[];
22
+ // NEW: Advanced color features
23
+ sequentialScale?: AdvancedColorScale;
24
+ divergingScale?: AdvancedColorScale;
25
+ conditionalFormatting?: {
26
+ positive: string;
27
+ negative: string;
28
+ neutral: string;
29
+ };
30
+ }
31
+
32
+ export interface ThemeCollection {
33
+ default: Theme;
34
+ dark: Theme;
35
+ corporate: Theme;
36
+ accessible: Theme;
37
+ colorful: Theme;
38
+ [key: string]: Theme;
39
+ }
40
+
41
+ export interface ChartWithTheme {
42
+ totalColor(color: string): ChartWithTheme;
43
+ [key: string]: any;
44
+ }
45
+
46
+ export const themes: ThemeCollection = {
47
+ default: {
48
+ name: "Default",
49
+ background: "#ffffff",
50
+ gridColor: "#e0e0e0",
51
+ axisColor: "#666666",
52
+ textColor: "#333333",
53
+ totalColor: "#95A5A6",
54
+ colors: ["#3498db", "#2ecc71", "#e74c3c", "#f39c12", "#9b59b6", "#1abc9c", "#e67e22", "#f1c40f"],
55
+ // NEW: Advanced color features
56
+ sequentialScale: {
57
+ type: 'sequential',
58
+ interpolator: d3.interpolateBlues
59
+ },
60
+ divergingScale: {
61
+ type: 'diverging',
62
+ interpolator: d3.interpolateRdYlBu
63
+ },
64
+ conditionalFormatting: {
65
+ positive: "#2ecc71",
66
+ negative: "#e74c3c",
67
+ neutral: "#95a5a6"
68
+ }
69
+ },
70
+
71
+ dark: {
72
+ name: "Dark",
73
+ background: "#2c3e50",
74
+ gridColor: "#34495e",
75
+ axisColor: "#bdc3c7",
76
+ textColor: "#ecf0f1",
77
+ totalColor: "#95a5a6",
78
+ colors: ["#3498db", "#2ecc71", "#e74c3c", "#f39c12", "#9b59b6", "#1abc9c", "#e67e22", "#f1c40f"],
79
+ sequentialScale: {
80
+ type: 'sequential',
81
+ interpolator: d3.interpolateViridis
82
+ },
83
+ divergingScale: {
84
+ type: 'diverging',
85
+ interpolator: d3.interpolatePiYG
86
+ },
87
+ conditionalFormatting: {
88
+ positive: "#2ecc71",
89
+ negative: "#e74c3c",
90
+ neutral: "#95a5a6"
91
+ }
92
+ },
93
+
94
+ corporate: {
95
+ name: "Corporate",
96
+ background: "#ffffff",
97
+ gridColor: "#e8e8e8",
98
+ axisColor: "#555555",
99
+ textColor: "#333333",
100
+ totalColor: "#7f8c8d",
101
+ colors: ["#2c3e50", "#34495e", "#7f8c8d", "#95a5a6", "#bdc3c7", "#ecf0f1"],
102
+ sequentialScale: {
103
+ type: 'sequential',
104
+ interpolator: d3.interpolateGreys
105
+ },
106
+ divergingScale: {
107
+ type: 'diverging',
108
+ interpolator: d3.interpolateRdBu
109
+ },
110
+ conditionalFormatting: {
111
+ positive: "#27ae60",
112
+ negative: "#c0392b",
113
+ neutral: "#7f8c8d"
114
+ }
115
+ },
116
+
117
+ accessible: {
118
+ name: "Accessible",
119
+ background: "#ffffff",
120
+ gridColor: "#cccccc",
121
+ axisColor: "#000000",
122
+ textColor: "#000000",
123
+ totalColor: "#666666",
124
+ // High contrast, colorblind-friendly palette
125
+ colors: ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f"],
126
+ sequentialScale: {
127
+ type: 'sequential',
128
+ interpolator: (t: number) => d3.interpolateHsl("#ffffff", "#000000")(t)
129
+ },
130
+ divergingScale: {
131
+ type: 'diverging',
132
+ interpolator: d3.interpolateRdBu
133
+ },
134
+ conditionalFormatting: {
135
+ positive: "#1f77b4", // High contrast blue
136
+ negative: "#d62728", // High contrast red
137
+ neutral: "#666666"
138
+ }
139
+ },
140
+
141
+ colorful: {
142
+ name: "Colorful",
143
+ background: "#ffffff",
144
+ gridColor: "#f0f0f0",
145
+ axisColor: "#666666",
146
+ textColor: "#333333",
147
+ totalColor: "#34495e",
148
+ colors: ["#ff6b6b", "#4ecdc4", "#45b7d1", "#f9ca24", "#f0932b", "#eb4d4b", "#6c5ce7", "#a29bfe"],
149
+ sequentialScale: {
150
+ type: 'sequential',
151
+ interpolator: d3.interpolateRainbow
152
+ },
153
+ divergingScale: {
154
+ type: 'diverging',
155
+ interpolator: d3.interpolateSpectral
156
+ },
157
+ conditionalFormatting: {
158
+ positive: "#4ecdc4",
159
+ negative: "#ff6b6b",
160
+ neutral: "#f9ca24"
161
+ }
162
+ }
163
+ };
164
+
165
+ export function applyTheme(chart: ChartWithTheme, themeName: keyof ThemeCollection = "default"): Theme {
166
+ const theme = themes[themeName] || themes.default;
167
+
168
+ // Apply theme colors to chart configuration
169
+ chart.totalColor(theme.totalColor);
170
+
171
+ return theme;
172
+ }
173
+
174
+ export function getThemeColorPalette(themeName: keyof ThemeCollection = "default"): string[] {
175
+ const theme = themes[themeName] || themes.default;
176
+ return theme.colors;
177
+ }
178
+
179
+ // ============================================================================
180
+ // ADVANCED COLOR SCALE FUNCTIONS
181
+ // ============================================================================
182
+
183
+ /**
184
+ * Create a sequential color scale for continuous data visualization
185
+ * Perfect for heat-map style conditional formatting in waterfall charts
186
+ */
187
+ export function createSequentialScale(
188
+ domain: [number, number],
189
+ themeName: keyof ThemeCollection = "default"
190
+ ): d3.ScaleSequential<string> {
191
+ const theme = themes[themeName] || themes.default;
192
+ const interpolator = theme.sequentialScale?.interpolator || d3.interpolateBlues;
193
+
194
+ return d3.scaleSequential(interpolator)
195
+ .domain(domain);
196
+ }
197
+
198
+ /**
199
+ * Create a diverging color scale for data with a meaningful center point (e.g., zero)
200
+ * Perfect for positive/negative value emphasis in waterfall charts
201
+ */
202
+ export function createDivergingScale(
203
+ domain: [number, number, number],
204
+ themeName: keyof ThemeCollection = "default"
205
+ ): d3.ScaleDiverging<string> {
206
+ const theme = themes[themeName] || themes.default;
207
+ const interpolator = theme.divergingScale?.interpolator || d3.interpolateRdYlBu;
208
+
209
+ return d3.scaleDiverging(interpolator)
210
+ .domain(domain);
211
+ }
212
+
213
+ /**
214
+ * Get conditional formatting color based on value
215
+ * Returns appropriate color for positive, negative, or neutral values
216
+ */
217
+ export function getConditionalColor(
218
+ value: number,
219
+ themeName: keyof ThemeCollection = "default",
220
+ neutralThreshold: number = 0
221
+ ): string {
222
+ const theme = themes[themeName] || themes.default;
223
+ const formatting = theme.conditionalFormatting || {
224
+ positive: "#2ecc71",
225
+ negative: "#e74c3c",
226
+ neutral: "#95a5a6"
227
+ };
228
+
229
+ if (Math.abs(value) <= Math.abs(neutralThreshold)) {
230
+ return formatting.neutral;
231
+ }
232
+ return value > neutralThreshold ? formatting.positive : formatting.negative;
233
+ }
234
+
235
+ /**
236
+ * Create a color scale for waterfall data with automatic domain detection
237
+ * Automatically chooses between sequential or diverging based on data characteristics
238
+ */
239
+ export function createWaterfallColorScale(
240
+ data: Array<{value: number}>,
241
+ themeName: keyof ThemeCollection = "default",
242
+ scaleType: 'auto' | 'sequential' | 'diverging' = 'auto'
243
+ ): d3.ScaleSequential<string> | d3.ScaleDiverging<string> {
244
+ const values = data.map(d => d.value);
245
+ const extent = d3.extent(values) as [number, number];
246
+ const hasPositiveAndNegative = extent[0] < 0 && extent[1] > 0;
247
+
248
+ // Auto-detect scale type
249
+ if (scaleType === 'auto') {
250
+ scaleType = hasPositiveAndNegative ? 'diverging' : 'sequential';
251
+ }
252
+
253
+ if (scaleType === 'diverging' && hasPositiveAndNegative) {
254
+ const maxAbs = Math.max(Math.abs(extent[0]), Math.abs(extent[1]));
255
+ return createDivergingScale([-maxAbs, 0, maxAbs], themeName);
256
+ } else {
257
+ return createSequentialScale(extent, themeName);
258
+ }
259
+ }
260
+
261
+ /**
262
+ * Apply color interpolation to a value within a range
263
+ * Useful for creating smooth color transitions in large datasets
264
+ */
265
+ export function interpolateThemeColor(
266
+ value: number,
267
+ domain: [number, number],
268
+ themeName: keyof ThemeCollection = "default"
269
+ ): string {
270
+ const theme = themes[themeName] || themes.default;
271
+ const interpolator = theme.sequentialScale?.interpolator || d3.interpolateBlues;
272
+
273
+ const normalizedValue = (value - domain[0]) / (domain[1] - domain[0]);
274
+ return interpolator(Math.max(0, Math.min(1, normalizedValue)));
275
+ }
276
+
277
+ /**
278
+ * Get advanced bar color based on value, context, and theme
279
+ * This is the main function for determining bar colors with advanced features
280
+ */
281
+ export function getAdvancedBarColor(
282
+ value: number,
283
+ defaultColor: string,
284
+ allData: Array<{barTotal?: number; value?: number}> = [],
285
+ themeName: keyof ThemeCollection = "default",
286
+ colorMode: 'default' | 'conditional' | 'sequential' | 'diverging' = 'conditional'
287
+ ): string {
288
+ const theme = themes[themeName] || themes.default;
289
+
290
+ switch (colorMode) {
291
+ case 'conditional':
292
+ return getConditionalColor(value, themeName);
293
+
294
+ case 'sequential':
295
+ if (allData.length > 0) {
296
+ const values = allData.map(d => d.barTotal || d.value || 0);
297
+ const domain = d3.extent(values) as [number, number];
298
+ return interpolateThemeColor(value, domain, themeName);
299
+ }
300
+ return defaultColor;
301
+
302
+ case 'diverging':
303
+ if (allData.length > 0) {
304
+ const values = allData.map(d => d.barTotal || d.value || 0);
305
+ const maxAbs = Math.max(...values.map(Math.abs));
306
+ const scale = createDivergingScale([-maxAbs, 0, maxAbs], themeName);
307
+ return scale(value);
308
+ }
309
+ return getConditionalColor(value, themeName);
310
+
311
+ default:
312
+ return defaultColor;
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Create professional financial color schemes for waterfall charts
318
+ */
319
+ export const financialThemes: Partial<ThemeCollection> = {
320
+ financial: {
321
+ name: "Financial",
322
+ background: "#ffffff",
323
+ gridColor: "#f5f5f5",
324
+ axisColor: "#333333",
325
+ textColor: "#333333",
326
+ totalColor: "#2c3e50",
327
+ colors: ["#27ae60", "#e74c3c", "#3498db", "#f39c12", "#9b59b6"],
328
+ sequentialScale: {
329
+ type: 'sequential',
330
+ interpolator: d3.interpolateRdYlGn
331
+ },
332
+ divergingScale: {
333
+ type: 'diverging',
334
+ interpolator: d3.interpolateRdYlGn
335
+ },
336
+ conditionalFormatting: {
337
+ positive: "#27ae60", // Strong green for profits
338
+ negative: "#e74c3c", // Strong red for losses
339
+ neutral: "#95a5a6" // Neutral gray
340
+ }
341
+ },
342
+
343
+ professional: {
344
+ name: "Professional",
345
+ background: "#ffffff",
346
+ gridColor: "#e8e8e8",
347
+ axisColor: "#444444",
348
+ textColor: "#333333",
349
+ totalColor: "#2c3e50",
350
+ colors: ["#1f4e79", "#2e75b6", "#70ad47", "#ffc000", "#c55a11"],
351
+ sequentialScale: {
352
+ type: 'sequential',
353
+ interpolator: (t: number) => d3.interpolateHsl("#f0f8ff", "#1f4e79")(t)
354
+ },
355
+ divergingScale: {
356
+ type: 'diverging',
357
+ interpolator: d3.interpolateRdYlBu
358
+ },
359
+ conditionalFormatting: {
360
+ positive: "#70ad47", // Professional green
361
+ negative: "#c55a11", // Professional orange-red
362
+ neutral: "#7f8c8d" // Professional gray
363
+ }
364
+ },
365
+
366
+ heatmap: {
367
+ name: "Heat Map",
368
+ background: "#ffffff",
369
+ gridColor: "#f0f0f0",
370
+ axisColor: "#333333",
371
+ textColor: "#333333",
372
+ totalColor: "#2c3e50",
373
+ colors: ["#ffffcc", "#ffeda0", "#fed976", "#feb24c", "#fd8d3c", "#fc4e2a", "#e31a1c", "#bd0026", "#800026"],
374
+ sequentialScale: {
375
+ type: 'sequential',
376
+ interpolator: d3.interpolateYlOrRd
377
+ },
378
+ divergingScale: {
379
+ type: 'diverging',
380
+ interpolator: d3.interpolateRdYlBu
381
+ },
382
+ conditionalFormatting: {
383
+ positive: "#2ca02c",
384
+ negative: "#d62728",
385
+ neutral: "#ff7f0e"
386
+ }
387
+ }
388
+ };
389
+
390
+ // Merge financial themes with existing themes
391
+ Object.assign(themes, financialThemes);