energy-visualization-sankey 1.0.0

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 (79) hide show
  1. package/README.md +497 -0
  2. package/babel.config.cjs +28 -0
  3. package/coverage/clover.xml +6 -0
  4. package/coverage/coverage-final.json +1 -0
  5. package/coverage/lcov-report/base.css +224 -0
  6. package/coverage/lcov-report/block-navigation.js +87 -0
  7. package/coverage/lcov-report/favicon.png +0 -0
  8. package/coverage/lcov-report/index.html +101 -0
  9. package/coverage/lcov-report/prettify.css +1 -0
  10. package/coverage/lcov-report/prettify.js +2 -0
  11. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  12. package/coverage/lcov-report/sorter.js +210 -0
  13. package/coverage/lcov.info +0 -0
  14. package/demo-caching.js +68 -0
  15. package/dist/core/Sankey.d.ts +294 -0
  16. package/dist/core/Sankey.d.ts.map +1 -0
  17. package/dist/core/events/EventBus.d.ts +195 -0
  18. package/dist/core/events/EventBus.d.ts.map +1 -0
  19. package/dist/core/types/events.d.ts +42 -0
  20. package/dist/core/types/events.d.ts.map +1 -0
  21. package/dist/index.d.ts +19 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/sankey.esm.js +5212 -0
  24. package/dist/sankey.esm.js.map +1 -0
  25. package/dist/sankey.standalone.esm.js +9111 -0
  26. package/dist/sankey.standalone.esm.js.map +1 -0
  27. package/dist/sankey.standalone.min.js +2 -0
  28. package/dist/sankey.standalone.min.js.map +1 -0
  29. package/dist/sankey.standalone.umd.js +9119 -0
  30. package/dist/sankey.standalone.umd.js.map +1 -0
  31. package/dist/sankey.umd.js +5237 -0
  32. package/dist/sankey.umd.js.map +1 -0
  33. package/dist/sankey.umd.min.js +2 -0
  34. package/dist/sankey.umd.min.js.map +1 -0
  35. package/dist/services/AnimationService.d.ts +229 -0
  36. package/dist/services/AnimationService.d.ts.map +1 -0
  37. package/dist/services/ConfigurationService.d.ts +173 -0
  38. package/dist/services/ConfigurationService.d.ts.map +1 -0
  39. package/dist/services/InteractionService.d.ts +377 -0
  40. package/dist/services/InteractionService.d.ts.map +1 -0
  41. package/dist/services/RenderingService.d.ts +152 -0
  42. package/dist/services/RenderingService.d.ts.map +1 -0
  43. package/dist/services/calculation/GraphService.d.ts +111 -0
  44. package/dist/services/calculation/GraphService.d.ts.map +1 -0
  45. package/dist/services/calculation/SummaryService.d.ts +149 -0
  46. package/dist/services/calculation/SummaryService.d.ts.map +1 -0
  47. package/dist/services/data/DataService.d.ts +167 -0
  48. package/dist/services/data/DataService.d.ts.map +1 -0
  49. package/dist/services/data/DataValidationService.d.ts +48 -0
  50. package/dist/services/data/DataValidationService.d.ts.map +1 -0
  51. package/dist/types/index.d.ts +189 -0
  52. package/dist/types/index.d.ts.map +1 -0
  53. package/dist/utils/Logger.d.ts +88 -0
  54. package/dist/utils/Logger.d.ts.map +1 -0
  55. package/jest.config.cjs +20 -0
  56. package/package.json +68 -0
  57. package/rollup.config.js +131 -0
  58. package/scripts/performance-validation-real.js +411 -0
  59. package/scripts/validate-optimization.sh +147 -0
  60. package/scripts/visual-validation-real-data.js +374 -0
  61. package/src/core/Sankey.ts +1039 -0
  62. package/src/core/events/EventBus.ts +488 -0
  63. package/src/core/types/events.ts +80 -0
  64. package/src/index.ts +35 -0
  65. package/src/services/AnimationService.ts +983 -0
  66. package/src/services/ConfigurationService.ts +497 -0
  67. package/src/services/InteractionService.ts +920 -0
  68. package/src/services/RenderingService.ts +484 -0
  69. package/src/services/calculation/GraphService.ts +616 -0
  70. package/src/services/calculation/SummaryService.ts +394 -0
  71. package/src/services/data/DataService.ts +380 -0
  72. package/src/services/data/DataValidationService.ts +155 -0
  73. package/src/styles/controls.css +184 -0
  74. package/src/styles/sankey.css +211 -0
  75. package/src/types/index.ts +220 -0
  76. package/src/utils/Logger.ts +105 -0
  77. package/tests/numerical-validation.test.js +575 -0
  78. package/tests/setup.js +53 -0
  79. package/tsconfig.json +54 -0
@@ -0,0 +1,184 @@
1
+ /* US Energy Sankey - Controls Styles */
2
+
3
+ /* Range Slider */
4
+ .range-slider {
5
+ width: 100%;
6
+ margin-top: 5px;
7
+ position: relative;
8
+ overflow: visible;
9
+ padding-top: 40px;
10
+ }
11
+
12
+ .range-slider__range {
13
+ -webkit-appearance: none;
14
+ width: 100%;
15
+ border-radius: 5px;
16
+ outline: none;
17
+ padding: 0;
18
+ margin: 0;
19
+ }
20
+
21
+ .range-slider__range:first-child {
22
+ background: #d7dcdf;
23
+ }
24
+
25
+ .range-slider__range::-webkit-slider-thumb {
26
+ -webkit-appearance: none;
27
+ appearance: none;
28
+ width: 11px;
29
+ height: 11px;
30
+ border-radius: 50%;
31
+ background: #fff;
32
+ box-shadow: 0 0 4px 0 rgba(0, 0, 0, 1);
33
+ cursor: pointer;
34
+ transition: background 0.15s ease-in-out;
35
+ }
36
+
37
+ .range-slider__range::-moz-range-thumb {
38
+ width: 11px;
39
+ height: 11px;
40
+ border: 0;
41
+ border-radius: 50%;
42
+ background: #fff;
43
+ box-shadow: 0 0 4px 0 rgba(0, 0, 0, 1);
44
+ cursor: pointer;
45
+ transition: background 0.15s ease-in-out;
46
+ }
47
+
48
+ /* Dynamic Year Display */
49
+ #dynamicYear {
50
+ color: black;
51
+ position: absolute;
52
+ height: 25px;
53
+ width: 50px;
54
+ text-align: center;
55
+ border: 1px solid black;
56
+ border-radius: 3px;
57
+ display: block;
58
+ font-size: 16px;
59
+ top: 40%;
60
+ /*bottom: 100%;*/
61
+ background: white;
62
+ padding: 3px 5px;
63
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
64
+ }
65
+
66
+ /* Add downward arrow pointing to slider */
67
+ #dynamicYear::after {
68
+ content: '';
69
+ position: absolute;
70
+ top: 100%;
71
+ left: 50%;
72
+ margin-left: -4px;
73
+ width: 0;
74
+ height: 0;
75
+ border-left: 4px solid transparent;
76
+ border-right: 4px solid transparent;
77
+ border-top: 6px solid black;
78
+ }
79
+
80
+ /* Play/Pause Button */
81
+ #play-button {
82
+ border-radius: 0;
83
+ display: block;
84
+ height: 0;
85
+ }
86
+
87
+ #play-button:hover {
88
+ background: transparent !important;
89
+ }
90
+
91
+ #play-button.playbutton {
92
+ outline: 0;
93
+ background: transparent;
94
+ border-color: transparent transparent transparent #202020;
95
+ transition: 100ms all ease;
96
+ cursor: pointer;
97
+ border-style: solid;
98
+ border-width: 13px 0 13px 20px;
99
+ }
100
+
101
+ #play-button.playpaused {
102
+ outline: 0;
103
+ background: transparent;
104
+ height: 26px;
105
+ border-color: transparent transparent transparent #202020;
106
+ transition: 100ms all ease;
107
+ cursor: pointer;
108
+ border-style: double;
109
+ border-width: 0px 0 0px 20px;
110
+ }
111
+
112
+ #play-button.playbutton:hover {
113
+ border-color: transparent transparent transparent #404040;
114
+ }
115
+
116
+ /* Waste Heat Toggle Switch */
117
+ .switch_box {
118
+ display: -webkit-box;
119
+ display: -ms-flexbox;
120
+ display: flex;
121
+ min-width: 200px;
122
+ -webkit-box-pack: center;
123
+ -ms-flex-pack: center;
124
+ justify-content: center;
125
+ -webkit-box-align: center;
126
+ -ms-flex-align: center;
127
+ align-items: center;
128
+ -webkit-box-flex: 1;
129
+ -ms-flex: 1;
130
+ flex: 1;
131
+ }
132
+
133
+ .box_1 {
134
+ background: #ffffff;
135
+ }
136
+
137
+ input[type="checkbox"].switch_1 {
138
+ -webkit-appearance: none;
139
+ -moz-appearance: none;
140
+ appearance: none;
141
+ width: 3.5em;
142
+ height: 1.5em;
143
+ background: black;
144
+ border-radius: 3em;
145
+ position: relative;
146
+ cursor: pointer;
147
+ outline: none;
148
+ -webkit-transition: all .2s ease-in-out;
149
+ transition: all .2s ease-in-out;
150
+ }
151
+
152
+ input[type="checkbox"].switch_1:checked {
153
+ background: black;
154
+ }
155
+
156
+ input[type="checkbox"].switch_1:after {
157
+ position: absolute;
158
+ content: "";
159
+ width: 1.5em;
160
+ height: 1.5em;
161
+ border-radius: 50%;
162
+ background: #fff;
163
+ -webkit-box-shadow: 0 0 .25em rgba(0, 0, 0, .3);
164
+ box-shadow: 0 0 .25em rgba(0, 0, 0, .3);
165
+ -webkit-transform: scale(.7);
166
+ transform: scale(.7);
167
+ left: 0;
168
+ -webkit-transition: all .2s ease-in-out;
169
+ transition: all .2s ease-in-out;
170
+ }
171
+
172
+ input[type="checkbox"].switch_1:checked:after {
173
+ left: calc(100% - 1.5em);
174
+ }
175
+
176
+ /* Milestone Tick Markers */
177
+ #testTick .tick text {
178
+ cursor: pointer;
179
+ }
180
+
181
+ #testTick .tick text:hover {
182
+ color: grey;
183
+ transition: color 250ms;
184
+ }
@@ -0,0 +1,211 @@
1
+ /* US Energy Sankey - Core Styles */
2
+
3
+ /* Typography */
4
+ text, tspan {
5
+ font-family: Fieldwork, Futura, sans-serif;
6
+ font-size: 16px;
7
+ }
8
+
9
+ /* Flow Styles */
10
+ .flow {
11
+ fill: none;
12
+ }
13
+
14
+ .flow.heat {
15
+ stroke: #98002e;
16
+ }
17
+
18
+ .flow.elec, .flow.waste.heat {
19
+ stroke: #e49942;
20
+ }
21
+
22
+ .flow.waste {
23
+ stroke: #e49942;
24
+ opacity: 0.4;
25
+ }
26
+
27
+ .flow.solar {
28
+ stroke: #fed530;
29
+ }
30
+
31
+ .flow.nuclear {
32
+ stroke: #ca0813;
33
+ }
34
+
35
+ .flow.hydro {
36
+ stroke: #0b24fb;
37
+ }
38
+
39
+ .flow.wind {
40
+ stroke: #901d8f;
41
+ }
42
+
43
+ .flow.geo {
44
+ stroke: #905a1c;
45
+ }
46
+
47
+ .flow.gas {
48
+ stroke: #4cabf2;
49
+ }
50
+
51
+ .flow.coal {
52
+ stroke: #000000;
53
+ }
54
+
55
+ .flow.bio {
56
+ stroke: #46be48;
57
+ }
58
+
59
+ .flow.petro {
60
+ stroke: #095f0b;
61
+ }
62
+
63
+ /* Box Styles */
64
+ .box.sector {
65
+ fill: #cccccc;
66
+ }
67
+
68
+ .box.solar {
69
+ fill: #fed530;
70
+ }
71
+
72
+ .box.nuclear {
73
+ fill: #ca0813;
74
+ }
75
+
76
+ .box.hydro {
77
+ fill: #0b24fb;
78
+ }
79
+
80
+ .box.wind {
81
+ fill: #901d8f;
82
+ }
83
+
84
+ .box.geo {
85
+ fill: #905a1c;
86
+ }
87
+
88
+ .box.gas {
89
+ fill: #4cabf2;
90
+ }
91
+
92
+ .box.coal {
93
+ fill: #000000;
94
+ }
95
+
96
+ .box.bio {
97
+ fill: #46be48;
98
+ }
99
+
100
+ .box.petro {
101
+ fill: #095f0b;
102
+ }
103
+
104
+ /* Other Elements */
105
+ .maxline {
106
+ stroke: #cccccc;
107
+ stroke-width: 1px;
108
+ }
109
+
110
+ .bkgd {
111
+ fill: #000000;
112
+ }
113
+
114
+ /* Title Container */
115
+ .title_container {
116
+ border-top: 2px solid #000000;
117
+ border-bottom: 1px solid #000000;
118
+ position: relative;
119
+ }
120
+
121
+ .title_container img {
122
+ max-height: 40px;
123
+ position: absolute;
124
+ top: 5px;
125
+ }
126
+
127
+ .title_container svg {
128
+ position: absolute;
129
+ font-size: 15px;
130
+ }
131
+
132
+ .title_container .title {
133
+ font-size: 1em;
134
+ fill: black;
135
+ }
136
+
137
+ .title_container .title .unit {
138
+ font-size: .9em;
139
+ font-weight: bold;
140
+ }
141
+
142
+ .title_container .title .year {
143
+ font-size: 3.1em;
144
+ font-weight: bold;
145
+ clear: left;
146
+ letter-spacing: .05em;
147
+ font-variant-numeric: tabular-nums;
148
+ }
149
+
150
+ .title_container .citation, .title_container .affiliation {
151
+ font-family: Fieldwork-HumThin, Futura, sans-serif;
152
+ font-size: 1em;
153
+ fill: #000000;
154
+ font-weight: bolder;
155
+ }
156
+
157
+ .title_container .title-bottom, .title_container .affiliation-bottom {
158
+ font-family: Fieldwork-HumThin, Futura, sans-serif;
159
+ font-size: 1em;
160
+ fill: #000000;
161
+ font-weight: bolder;
162
+ }
163
+
164
+ /* Totals */
165
+ .total.sector {
166
+ font-size: 0.7em;
167
+ font-weight: bold;
168
+ }
169
+
170
+ .total.waste-level {
171
+ fill: #e49942;
172
+ opacity: 0.4;
173
+ }
174
+
175
+ /* Visibility */
176
+ .hidden {
177
+ visibility: hidden;
178
+ }
179
+
180
+ /* Tooltip */
181
+ .tooltip {
182
+ color: #000000;
183
+ position: absolute;
184
+ text-align: justify;
185
+ width: auto;
186
+ padding: 5px;
187
+ background: #efefef;
188
+ border: 1px solid black;
189
+ pointer-events: none;
190
+ z-index: 3;
191
+ }
192
+
193
+ .fuel_value {
194
+ text-align: center;
195
+ vertical-align: middle;
196
+ }
197
+
198
+ /* Waste Heat Visibility Control */
199
+ .waste-heat-hidden .flow.waste {
200
+ display: none !important;
201
+ }
202
+
203
+ .waste-heat-hidden .total.waste-level {
204
+ display: none !important;
205
+ }
206
+
207
+ /* Smooth transition for waste heat toggle (optional) */
208
+ .flow.waste,
209
+ .total.waste-level {
210
+ transition: opacity 0.3s ease;
211
+ }
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Type Definitions for Energy Sankey Library
3
+ *
4
+ * Comprehensive TypeScript type definitions for energy visualization data structures,
5
+ * configuration options, service interfaces, and mathematical computation types.
6
+ *
7
+ * Key Type Categories:
8
+ * - Error types: Custom error classes with detailed context
9
+ * - Data structures: Energy data points, summaries, and flow calculations
10
+ * - Configuration: Visual constants, fuel definitions, and styling
11
+ * - Mathematical types: Graph data, positioning, and computational results
12
+ * - Service interfaces: D3 selections, render data, and layout structures
13
+ *
14
+ * Type Safety Features:
15
+ * - Immutable readonly properties for data integrity
16
+ * - Strict type constraints for fuel and sector names
17
+ * - Comprehensive interface coverage for all service operations
18
+ * - Generic types for flexible service composition
19
+ *
20
+ */
21
+
22
+ // Error types
23
+ export class SankeyError extends Error {
24
+ constructor(message: string, public code?: string) {
25
+ super(message);
26
+ this.name = 'SankeyError';
27
+ }
28
+ }
29
+
30
+ export class DataValidationError extends SankeyError {
31
+ constructor(message: string, public field?: string) {
32
+ super(message, 'DATA_VALIDATION');
33
+ this.name = 'DataValidationError';
34
+ }
35
+ }
36
+
37
+ // Energy sector breakdown interface
38
+ export interface EnergySectorBreakdown {
39
+ readonly elec: number;
40
+ readonly res: number;
41
+ readonly ag: number;
42
+ readonly indus: number;
43
+ readonly trans: number;
44
+ readonly heat: number;
45
+
46
+ [key: string]: number; // Allow dynamic access
47
+ }
48
+
49
+ // Core data structures
50
+ export interface EnergyDataPoint {
51
+ readonly year: number;
52
+ readonly milestone?: string;
53
+ readonly elec: EnergySectorBreakdown;
54
+ readonly waste: EnergySectorBreakdown;
55
+ readonly solar: EnergySectorBreakdown;
56
+ readonly nuclear: EnergySectorBreakdown;
57
+ readonly hydro: EnergySectorBreakdown;
58
+ readonly wind: EnergySectorBreakdown;
59
+ readonly geo: EnergySectorBreakdown;
60
+ readonly gas: EnergySectorBreakdown;
61
+ readonly coal: EnergySectorBreakdown;
62
+ readonly bio: EnergySectorBreakdown;
63
+ readonly petro: EnergySectorBreakdown;
64
+ readonly heat: EnergySectorBreakdown;
65
+ }
66
+
67
+ // Options interface
68
+ export interface SankeyOptions {
69
+ readonly data: EnergyDataPoint[];
70
+ readonly country: string;
71
+ readonly includeControls?: boolean;
72
+ readonly includeTimeline?: boolean;
73
+ readonly includeWasteToggle?: boolean;
74
+ readonly autoPlay?: boolean;
75
+ readonly showWasteHeat?: boolean;
76
+ readonly animationSpeed?: number;
77
+ readonly width?: number | null;
78
+ readonly height?: number;
79
+ readonly loopAnimation?: boolean;
80
+ readonly debugLogging?: boolean;
81
+ }
82
+
83
+ export interface RequiredSankeyOptions extends Required<SankeyOptions> {
84
+ // All optional properties are now required with defaults
85
+ }
86
+
87
+ // Mathematical structures
88
+ export interface GraphPoint {
89
+ x: number;
90
+ y: number;
91
+ }
92
+
93
+ export interface GraphStroke {
94
+ fuel: string;
95
+ box: string;
96
+ value: number;
97
+ stroke: number;
98
+ a: GraphPoint;
99
+ b: GraphPoint;
100
+ c: GraphPoint;
101
+ d: GraphPoint;
102
+ cc: GraphPoint;
103
+ }
104
+
105
+ export interface GraphData {
106
+ year: number;
107
+ graph: GraphStroke[];
108
+ totals: { [key: string]: number };
109
+ offsets: Offest;
110
+ }
111
+
112
+ interface OffestX {
113
+ solar: number,
114
+ nuclear: number,
115
+ hydro: number,
116
+ wind: number,
117
+ geo: number,
118
+ gas: number,
119
+ coal: number,
120
+ bio: number,
121
+ petro: number
122
+ }
123
+
124
+ interface OffestY {
125
+ elec: number,
126
+ res: number, // Electricity and residential
127
+ ag: number,
128
+ indus: number,
129
+ trans: number,
130
+ heat?: number | undefined,
131
+ }
132
+
133
+ export interface Offest {
134
+ x: OffestX;
135
+ y: OffestY;
136
+ }
137
+
138
+ // Summary data structures
139
+ export interface YearTotals {
140
+ year: number;
141
+ elec: number;
142
+ res: number;
143
+ ag: number;
144
+ indus: number;
145
+ trans: number;
146
+ solar: number;
147
+ nuclear: number;
148
+ hydro: number;
149
+ wind: number;
150
+ geo: number;
151
+ gas: number;
152
+ coal: number;
153
+ bio: number;
154
+ petro: number;
155
+ fuel_height: number;
156
+ waste: number;
157
+ heat?: number | undefined;
158
+ milestone?: any;
159
+
160
+ [key: string]: any;
161
+ }
162
+
163
+ export interface YearFlows {
164
+ year: number;
165
+ elec: number;
166
+ res: number;
167
+ ag: number;
168
+ indus: number;
169
+ trans: number;
170
+ heat?: number | undefined;
171
+ }
172
+
173
+ export interface YearLabels {
174
+ year: number;
175
+ elec: number;
176
+ res: number;
177
+ ag: number;
178
+ indus: number;
179
+ trans: number;
180
+ solar: number;
181
+ nuclear: number;
182
+ hydro: number;
183
+ wind: number;
184
+ geo: number;
185
+ gas: number;
186
+ coal: number;
187
+ bio: number;
188
+ petro: number;
189
+ heat?: number | undefined;
190
+ }
191
+
192
+ export interface BoxMaxes {
193
+ [boxName: string]: number;
194
+ }
195
+
196
+ export interface BoxTops {
197
+ [key: string]: number;
198
+
199
+ res: number;
200
+ ag: number;
201
+ indus: number;
202
+ trans: number;
203
+ }
204
+
205
+ export interface YearSums {
206
+ [year: number]: number;
207
+ }
208
+
209
+ export interface SummaryData {
210
+ totals: YearTotals[];
211
+ flows: YearFlows[];
212
+ labels: YearLabels[];
213
+ maxes: BoxMaxes;
214
+ boxTops: BoxTops;
215
+ yearSums: YearSums;
216
+ }
217
+
218
+ // D3 Selection types
219
+ export type D3SVGSelection = d3.Selection<SVGSVGElement, unknown, HTMLElement, any>;
220
+ export type D3DivSelection = d3.Selection<HTMLDivElement, unknown, HTMLElement, any>;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Performance Monitoring and Debug Logging Utility
3
+ *
4
+ * **Performance Monitoring Responsibility:**
5
+ * - Provides configurable debug logging for performance analysis
6
+ * - Tracks service initialization, calculation timing, and system events
7
+ * - Enables production performance monitoring without overhead
8
+ * - Supports performance regression detection and optimization efforts
9
+ *
10
+ * **Debug Logging Architecture:**
11
+ * - Configuration-controlled logging (debugLogging option)
12
+ * - Zero performance overhead when disabled (early returns)
13
+ * - Structured logging levels: log, debug, warn for different diagnostic needs
14
+ * - Console API integration for browser dev tools compatibility
15
+ *
16
+ * **Performance Analysis Features:**
17
+ * - Timing information: Service initialization, calculation duration
18
+ * - Cache statistics: Hit rates, cache efficiency metrics
19
+ * - System events: Service lifecycle, error conditions
20
+ * - Performance warnings: Threshold-based alerting for slow operations
21
+ *
22
+ * **Production Considerations:**
23
+ * - Logging disabled by default (performance-first approach)
24
+ * - Minimal memory footprint when disabled
25
+ * - No sensitive data logging (energy data values excluded)
26
+ * - Development-friendly: Rich diagnostic information when enabled
27
+ */
28
+
29
+ import {SankeyOptions} from "@/types";
30
+
31
+ /**
32
+ * Logger Implementation
33
+ *
34
+ * **Performance-Optimized Logging Service:**
35
+ * - Configuration-controlled output (respects debugLogging option)
36
+ * - Early return pattern for zero overhead when disabled
37
+ * - Console API delegation for browser dev tools integration
38
+ * - Structured message formatting for diagnostic clarity
39
+ */
40
+ export class Logger {
41
+
42
+ constructor(private options: SankeyOptions) {
43
+ }
44
+
45
+ /**
46
+ * General information logging
47
+ *
48
+ * **Usage Patterns:**
49
+ * - Service initialization completion and timing
50
+ * - Major system milestones (data loaded, services ready)
51
+ * - Performance metrics (calculation times, cache statistics)
52
+ * - User interaction events (animation start, year changes)
53
+ *
54
+ * **Performance Impact:**
55
+ * - Zero overhead when debugLogging disabled (early return)
56
+ * - Minimal string formatting cost when enabled
57
+ * - Console.log delegation for browser optimization
58
+ */
59
+ public log(message: string, ...args: any[]): void {
60
+ if (this.options.debugLogging) {
61
+ console.log(message, ...args);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Detailed debug information logging
67
+ *
68
+ * **Usage Patterns:**
69
+ * - Algorithm step-by-step tracing
70
+ * - Cache hit/miss detailed reporting
71
+ * - Data transformation pipeline debugging
72
+ * - Complex calculation intermediate results
73
+ *
74
+ * **Development Benefits:**
75
+ * - Granular system behavior visibility
76
+ * - Algorithm verification and debugging
77
+ * - Performance bottleneck identification
78
+ */
79
+ public debug(message: string, ...args: any[]): void {
80
+ if (this.options.debugLogging) {
81
+ console.debug(message, ...args);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Warning and performance issue logging
87
+ *
88
+ * **Usage Patterns:**
89
+ * - Performance threshold violations (slow initialization)
90
+ * - Potential optimization opportunities
91
+ * - Data quality warnings (unusual values)
92
+ * - System resource constraints
93
+ *
94
+ * **Performance Monitoring Integration:**
95
+ * - Automatic alerting for performance degradation
96
+ * - Actionable optimization recommendations
97
+ * - System health status reporting
98
+ * - Production performance monitoring
99
+ */
100
+ public warn(message: string, ...args: any[]): void {
101
+ if (this.options.debugLogging) {
102
+ console.warn(message, ...args);
103
+ }
104
+ }
105
+ }