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.
- package/CHANGELOG.md +223 -0
- package/CONTRIBUTING.md +199 -0
- package/README.md +363 -0
- package/dist/index.d.ts +149 -0
- package/dist/mintwaterfall.cjs.js +7978 -0
- package/dist/mintwaterfall.esm.js +7907 -0
- package/dist/mintwaterfall.min.js +7 -0
- package/dist/mintwaterfall.umd.js +7978 -0
- package/index.d.ts +149 -0
- package/package.json +126 -0
- package/src/enterprise/enterprise-core.js +0 -0
- package/src/enterprise/enterprise-feature-template.js +0 -0
- package/src/enterprise/feature-registry.js +0 -0
- package/src/enterprise/features/breakdown.js +0 -0
- package/src/features/breakdown.js +0 -0
- package/src/features/conditional-formatting.js +0 -0
- package/src/index.js +111 -0
- package/src/mintwaterfall-accessibility.ts +680 -0
- package/src/mintwaterfall-advanced-data.ts +1034 -0
- package/src/mintwaterfall-advanced-interactions.ts +649 -0
- package/src/mintwaterfall-advanced-performance.ts +582 -0
- package/src/mintwaterfall-animations.ts +595 -0
- package/src/mintwaterfall-brush.ts +471 -0
- package/src/mintwaterfall-chart-core.ts +296 -0
- package/src/mintwaterfall-chart.ts +1915 -0
- package/src/mintwaterfall-data.ts +1100 -0
- package/src/mintwaterfall-export.ts +475 -0
- package/src/mintwaterfall-hierarchical-layouts.ts +724 -0
- package/src/mintwaterfall-layouts.ts +647 -0
- package/src/mintwaterfall-performance.ts +573 -0
- package/src/mintwaterfall-scales.ts +437 -0
- package/src/mintwaterfall-shapes.ts +385 -0
- package/src/mintwaterfall-statistics.ts +821 -0
- package/src/mintwaterfall-themes.ts +391 -0
- package/src/mintwaterfall-tooltip.ts +450 -0
- package/src/mintwaterfall-zoom.ts +399 -0
- package/src/types/js-modules.d.ts +25 -0
- 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);
|