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.
- package/README.md +497 -0
- package/babel.config.cjs +28 -0
- package/coverage/clover.xml +6 -0
- package/coverage/coverage-final.json +1 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +101 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +0 -0
- package/demo-caching.js +68 -0
- package/dist/core/Sankey.d.ts +294 -0
- package/dist/core/Sankey.d.ts.map +1 -0
- package/dist/core/events/EventBus.d.ts +195 -0
- package/dist/core/events/EventBus.d.ts.map +1 -0
- package/dist/core/types/events.d.ts +42 -0
- package/dist/core/types/events.d.ts.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/sankey.esm.js +5212 -0
- package/dist/sankey.esm.js.map +1 -0
- package/dist/sankey.standalone.esm.js +9111 -0
- package/dist/sankey.standalone.esm.js.map +1 -0
- package/dist/sankey.standalone.min.js +2 -0
- package/dist/sankey.standalone.min.js.map +1 -0
- package/dist/sankey.standalone.umd.js +9119 -0
- package/dist/sankey.standalone.umd.js.map +1 -0
- package/dist/sankey.umd.js +5237 -0
- package/dist/sankey.umd.js.map +1 -0
- package/dist/sankey.umd.min.js +2 -0
- package/dist/sankey.umd.min.js.map +1 -0
- package/dist/services/AnimationService.d.ts +229 -0
- package/dist/services/AnimationService.d.ts.map +1 -0
- package/dist/services/ConfigurationService.d.ts +173 -0
- package/dist/services/ConfigurationService.d.ts.map +1 -0
- package/dist/services/InteractionService.d.ts +377 -0
- package/dist/services/InteractionService.d.ts.map +1 -0
- package/dist/services/RenderingService.d.ts +152 -0
- package/dist/services/RenderingService.d.ts.map +1 -0
- package/dist/services/calculation/GraphService.d.ts +111 -0
- package/dist/services/calculation/GraphService.d.ts.map +1 -0
- package/dist/services/calculation/SummaryService.d.ts +149 -0
- package/dist/services/calculation/SummaryService.d.ts.map +1 -0
- package/dist/services/data/DataService.d.ts +167 -0
- package/dist/services/data/DataService.d.ts.map +1 -0
- package/dist/services/data/DataValidationService.d.ts +48 -0
- package/dist/services/data/DataValidationService.d.ts.map +1 -0
- package/dist/types/index.d.ts +189 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils/Logger.d.ts +88 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/jest.config.cjs +20 -0
- package/package.json +68 -0
- package/rollup.config.js +131 -0
- package/scripts/performance-validation-real.js +411 -0
- package/scripts/validate-optimization.sh +147 -0
- package/scripts/visual-validation-real-data.js +374 -0
- package/src/core/Sankey.ts +1039 -0
- package/src/core/events/EventBus.ts +488 -0
- package/src/core/types/events.ts +80 -0
- package/src/index.ts +35 -0
- package/src/services/AnimationService.ts +983 -0
- package/src/services/ConfigurationService.ts +497 -0
- package/src/services/InteractionService.ts +920 -0
- package/src/services/RenderingService.ts +484 -0
- package/src/services/calculation/GraphService.ts +616 -0
- package/src/services/calculation/SummaryService.ts +394 -0
- package/src/services/data/DataService.ts +380 -0
- package/src/services/data/DataValidationService.ts +155 -0
- package/src/styles/controls.css +184 -0
- package/src/styles/sankey.css +211 -0
- package/src/types/index.ts +220 -0
- package/src/utils/Logger.ts +105 -0
- package/tests/numerical-validation.test.js +575 -0
- package/tests/setup.js +53 -0
- package/tsconfig.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
# Energy Sankey Visualization Library
|
|
2
|
+
|
|
3
|
+
A modern TypeScript library for creating interactive Sankey diagrams that visualize energy flows from sources to
|
|
4
|
+
consumption sectors. Built with event-driven architecture, comprehensive type safety, and optimized for smooth animation
|
|
5
|
+
across historical energy data.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Overview](#overview)
|
|
10
|
+
- [Features](#features)
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Quick Start](#quick-start)
|
|
13
|
+
- [API Reference](#api-reference)
|
|
14
|
+
- [Data Format](#data-format)
|
|
15
|
+
- [Architecture](#architecture)
|
|
16
|
+
- [Development](#development)
|
|
17
|
+
- [Examples](#examples)
|
|
18
|
+
- [Browser Support](#browser-support)
|
|
19
|
+
- [Contributing](#contributing)
|
|
20
|
+
- [License](#license)
|
|
21
|
+
|
|
22
|
+
## Overview
|
|
23
|
+
|
|
24
|
+
This library transforms complex energy consumption data into interactive, animated flow diagrams using D3.js v7. It
|
|
25
|
+
visualizes energy flows from sources (solar, nuclear, coal, etc.) to consumption sectors (residential, industrial,
|
|
26
|
+
transportation, etc.) with smooth timeline animations and comprehensive user controls.
|
|
27
|
+
|
|
28
|
+
### Key Capabilities
|
|
29
|
+
|
|
30
|
+
- **Interactive Energy Flow Visualization**: Real-time Sankey diagrams showing energy source-to-consumption
|
|
31
|
+
relationships
|
|
32
|
+
- **Timeline Animation**: Smooth animation across decades of historical energy data
|
|
33
|
+
- **Event-Driven Architecture**: Decoupled services communicating through type-safe events
|
|
34
|
+
- **Mobile Responsive**: Touch-optimized controls and responsive layouts
|
|
35
|
+
- **Accessibility Support**: Full keyboard navigation and screen reader compatibility
|
|
36
|
+
- **Mathematical Accuracy**: Precise energy flow calculations following EIA standards
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
### Core Features
|
|
41
|
+
|
|
42
|
+
- **Multiple Energy Sources**: Solar, nuclear, hydro, wind, geothermal, natural gas, coal, biomass, petroleum
|
|
43
|
+
- **Sectoral Analysis**: Electricity, residential, agriculture, industrial, transportation
|
|
44
|
+
- **Waste Heat Visualization**: Thermodynamically accurate waste heat calculations
|
|
45
|
+
- **Historical Timeline**: Animated progression through energy data with user controls
|
|
46
|
+
- **Interactive Elements**: Hover tooltips, click selection, play/pause controls
|
|
47
|
+
|
|
48
|
+
### Technical Features
|
|
49
|
+
|
|
50
|
+
- **TypeScript**: Full type safety with comprehensive interfaces
|
|
51
|
+
- **Event-Driven**: Services communicate through type-safe event bus
|
|
52
|
+
- **Modular Architecture**: Clean separation of concerns with focused services
|
|
53
|
+
- **Performance Optimized**: Caching and efficient rendering
|
|
54
|
+
- **Multiple Build Formats**: ESM, UMD, standalone versions available
|
|
55
|
+
|
|
56
|
+
### User Experience
|
|
57
|
+
|
|
58
|
+
- **Animation Controls**: Play, pause, speed adjustment, year scrubbing
|
|
59
|
+
- **Keyboard Navigation**: Full accessibility with keyboard shortcuts
|
|
60
|
+
- **Mobile Support**: Touch gestures and responsive design
|
|
61
|
+
- **Waste Heat Toggle**: Show/hide electricity waste heat flows
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
### NPM Installation
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm install us-energy-sankey
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Direct Browser Usage
|
|
72
|
+
|
|
73
|
+
For quick prototyping or simple integration, use the standalone build that includes D3:
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<!-- Standalone ES Module (recommended for modern browsers) -->
|
|
77
|
+
<script type="module">
|
|
78
|
+
import Sankey from './dist/sankey-v10.standalone.esm.js';
|
|
79
|
+
// Your code here
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<!-- Standalone UMD (compatible with older browsers) -->
|
|
83
|
+
<script src="./dist/us-energy-sankey.standalone.umd.js"></script>
|
|
84
|
+
<script>
|
|
85
|
+
const sankey = new Sankey('container', options);
|
|
86
|
+
</script>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### With External D3
|
|
90
|
+
|
|
91
|
+
If you already have D3 v7 in your project:
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
|
|
95
|
+
<script src="https://d3js.org/d3.v7.min.js"></script>
|
|
96
|
+
<script src="./dist/sankey-v10.umd.js"></script>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Quick Start
|
|
100
|
+
|
|
101
|
+
### Basic Example
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import Sankey from 'us-energy-sankey-v10';
|
|
105
|
+
|
|
106
|
+
// Load your energy data
|
|
107
|
+
const energyData = [
|
|
108
|
+
{
|
|
109
|
+
year: 2020,
|
|
110
|
+
milestone: "Renewable energy growth",
|
|
111
|
+
solar: {elec: 131, res: 0, ag: 0, indus: 0, trans: 0},
|
|
112
|
+
nuclear: {elec: 843, res: 0, ag: 0, indus: 0, trans: 0},
|
|
113
|
+
hydro: {elec: 259, res: 0, ag: 0, indus: 0, trans: 0},
|
|
114
|
+
wind: {elec: 380, res: 0, ag: 0, indus: 0, trans: 0},
|
|
115
|
+
geo: {elec: 18, res: 5, ag: 0, indus: 0, trans: 0},
|
|
116
|
+
gas: {elec: 1624, res: 187, ag: 12, indus: 442, trans: 3},
|
|
117
|
+
coal: {elec: 774, res: 0, ag: 0, indus: 65, trans: 0},
|
|
118
|
+
bio: {elec: 56, res: 21, ag: 0, indus: 135, trans: 140},
|
|
119
|
+
petro: {elec: 17, res: 89, ag: 23, indus: 456, trans: 2456},
|
|
120
|
+
elec: {elec: 0, res: 1539, ag: 18, indus: 1059, trans: 26},
|
|
121
|
+
waste: {elec: 0, res: 0, ag: 0, indus: 0, trans: 0}
|
|
122
|
+
}
|
|
123
|
+
// ... more years
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
// Create the visualization
|
|
127
|
+
const sankey = new Sankey('sankey-container', {
|
|
128
|
+
data: energyData,
|
|
129
|
+
country: "U.S.",
|
|
130
|
+
includeControls: true,
|
|
131
|
+
includeTimeline: true,
|
|
132
|
+
includeWasteToggle: true,
|
|
133
|
+
autoPlay: false,
|
|
134
|
+
showWasteHeat: true,
|
|
135
|
+
animationSpeed: 200,
|
|
136
|
+
loopAnimation: false
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### HTML Structure
|
|
141
|
+
|
|
142
|
+
```html
|
|
143
|
+
<!DOCTYPE html>
|
|
144
|
+
<html>
|
|
145
|
+
<head>
|
|
146
|
+
<link rel="stylesheet" href="./src/styles/sankey.css">
|
|
147
|
+
<link rel="stylesheet" href="./src/styles/controls.css">
|
|
148
|
+
</head>
|
|
149
|
+
<body>
|
|
150
|
+
<div id="sankey-container"></div>
|
|
151
|
+
|
|
152
|
+
<script type="module">
|
|
153
|
+
import Sankey from './dist/us-energy-sankey-v10.standalone.esm.js';
|
|
154
|
+
// Initialize as shown above
|
|
155
|
+
</script>
|
|
156
|
+
</body>
|
|
157
|
+
</html>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## API Reference
|
|
161
|
+
|
|
162
|
+
### Constructor
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
new Sankey(container: string | HTMLElement, options: SankeyOptions)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### SankeyOptions Interface
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
interface SankeyOptions {
|
|
172
|
+
data: EnergyDataPoint[]; // Required: Energy flow data
|
|
173
|
+
country: string; // Required: Country identifier
|
|
174
|
+
includeControls?: boolean; // Show play/pause controls (default: true)
|
|
175
|
+
includeTimeline?: boolean; // Show timeline slider (default: true)
|
|
176
|
+
includeWasteToggle?: boolean; // Show waste heat toggle (default: true)
|
|
177
|
+
autoPlay?: boolean; // Start animation automatically (default: false)
|
|
178
|
+
showWasteHeat?: boolean; // Show waste heat flows (default: true)
|
|
179
|
+
animationSpeed?: number; // Animation speed in ms (default: 200)
|
|
180
|
+
width?: number | null; // Container width (null = dynamic)
|
|
181
|
+
height?: number; // Container height (default: 620)
|
|
182
|
+
loopAnimation?: boolean; // Loop animation (default: false)
|
|
183
|
+
debugLogging?: boolean; // Enable debug logging (default: false)
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Public Methods
|
|
188
|
+
|
|
189
|
+
#### Animation Control
|
|
190
|
+
|
|
191
|
+
- `play(): this` - Start timeline animation
|
|
192
|
+
- `pause(): this` - Pause timeline animation
|
|
193
|
+
- `setYear(year: number): this` - Navigate to specific year
|
|
194
|
+
- `setSpeed(speed: number): this` - Set animation playback speed (milliseconds per year)
|
|
195
|
+
|
|
196
|
+
#### State Query
|
|
197
|
+
|
|
198
|
+
- `getCurrentYear(): number` - Get currently displayed year
|
|
199
|
+
- `isPlaying(): boolean` - Check if animation is running
|
|
200
|
+
- `isInitialized(): boolean` - Check if visualization is ready
|
|
201
|
+
- `getYears(): readonly number[]` - Get all available years
|
|
202
|
+
|
|
203
|
+
#### Feature Control
|
|
204
|
+
|
|
205
|
+
- `toggleWasteHeat(): this` - Toggle waste heat flow visibility
|
|
206
|
+
- `isWasteHeatVisible(): boolean` - Check waste heat visibility state
|
|
207
|
+
|
|
208
|
+
#### Lifecycle
|
|
209
|
+
|
|
210
|
+
- `destroy(): void` - Clean up resources and DOM elements
|
|
211
|
+
|
|
212
|
+
#### Development/Testing
|
|
213
|
+
|
|
214
|
+
- `getDataService(): DataService` - Access internal data service (for testing)
|
|
215
|
+
|
|
216
|
+
### Method Chaining
|
|
217
|
+
|
|
218
|
+
All control methods return `this` for fluent API usage:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
sankey
|
|
222
|
+
.setYear(1950)
|
|
223
|
+
.setSpeed(100)
|
|
224
|
+
.play();
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Data Format
|
|
228
|
+
|
|
229
|
+
Energy data must follow this structure with all required properties:
|
|
230
|
+
|
|
231
|
+
### EnergyDataPoint Interface
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
interface EnergyDataPoint {
|
|
235
|
+
year: number; // Required: Year for this data point
|
|
236
|
+
milestone?: string; // Optional: Historical context
|
|
237
|
+
|
|
238
|
+
// Energy Sources (all required with sector breakdown)
|
|
239
|
+
solar: EnergySectorBreakdown;
|
|
240
|
+
nuclear: EnergySectorBreakdown;
|
|
241
|
+
hydro: EnergySectorBreakdown;
|
|
242
|
+
wind: EnergySectorBreakdown;
|
|
243
|
+
geo: EnergySectorBreakdown; // Geothermal
|
|
244
|
+
gas: EnergySectorBreakdown; // Natural gas
|
|
245
|
+
coal: EnergySectorBreakdown;
|
|
246
|
+
bio: EnergySectorBreakdown; // Biomass
|
|
247
|
+
petro: EnergySectorBreakdown; // Petroleum
|
|
248
|
+
|
|
249
|
+
// Special categories
|
|
250
|
+
elec: EnergySectorBreakdown; // Electricity distribution
|
|
251
|
+
waste: EnergySectorBreakdown; // Waste heat
|
|
252
|
+
heat: EnergySectorBreakdown; // Direct heat (optional)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
interface EnergySectorBreakdown {
|
|
256
|
+
elec: number; // Electricity generation
|
|
257
|
+
res: number; // Residential/Commercial
|
|
258
|
+
ag: number; // Agriculture
|
|
259
|
+
indus: number; // Industrial
|
|
260
|
+
trans: number; // Transportation
|
|
261
|
+
heat: number; // Direct heat applications (optional in some datasets)
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Example Data Structure
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
{
|
|
269
|
+
"year": 2020,
|
|
270
|
+
"milestone": "COVID-19 pandemic impact on energy consumption",
|
|
271
|
+
"solar": { "elec": 131, "res": 0, "ag": 0, "indus": 0, "trans": 0 },
|
|
272
|
+
"nuclear": { "elec": 843, "res": 0, "ag": 0, "indus": 0, "trans": 0 },
|
|
273
|
+
"hydro": { "elec": 259, "res": 0, "ag": 0, "indus": 0, "trans": 0 },
|
|
274
|
+
"wind": { "elec": 380, "res": 0, "ag": 0, "indus": 0, "trans": 0 },
|
|
275
|
+
"geo": { "elec": 18, "res": 5, "ag": 0, "indus": 0, "trans": 0 },
|
|
276
|
+
"gas": { "elec": 1624, "res": 187, "ag": 12, "indus": 442, "trans": 3 },
|
|
277
|
+
"coal": { "elec": 774, "res": 0, "ag": 0, "indus": 65, "trans": 0 },
|
|
278
|
+
"bio": { "elec": 56, "res": 21, "ag": 0, "indus": 135, "trans": 140 },
|
|
279
|
+
"petro": { "elec": 17, "res": 89, "ag": 23, "indus": 456, "trans": 2456 },
|
|
280
|
+
"elec": { "elec": 0, "res": 1539, "ag": 18, "indus": 1059, "trans": 26 },
|
|
281
|
+
"waste": { "elec": 0, "res": 0, "ag": 0, "indus": 0, "trans": 0 }
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Architecture
|
|
286
|
+
|
|
287
|
+
The library uses a clean, event-driven architecture with focused service layers:
|
|
288
|
+
|
|
289
|
+
### Service Overview
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
Sankey (Main Orchestrator)
|
|
293
|
+
├── EventBus (Type-safe communication hub)
|
|
294
|
+
├── ConfigurationService (Mathematical constants & visual settings)
|
|
295
|
+
├── DataValidationService (Input validation & structure verification)
|
|
296
|
+
├── DataService (Data access, sorting & navigation)
|
|
297
|
+
├── SummaryService (Energy totals calculation with caching)
|
|
298
|
+
├── GraphService (Flow positioning & coordinate calculations)
|
|
299
|
+
├── RenderingService (SVG generation & D3.js integration)
|
|
300
|
+
├── AnimationService (Timeline management & user controls)
|
|
301
|
+
└── InteractionService (User input & accessibility)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Key Architectural Benefits
|
|
305
|
+
|
|
306
|
+
- **Event-Driven Communication**: Services communicate through typed events, enabling loose coupling
|
|
307
|
+
- **Dependency Injection**: Services receive dependencies explicitly through constructors
|
|
308
|
+
- **Immutable Data**: All data structures are immutable for safety and predictability
|
|
309
|
+
- **Type Safety**: Comprehensive TypeScript coverage with 15+ interface definitions
|
|
310
|
+
- **Memory Management**: Automatic cleanup and resource management
|
|
311
|
+
- **Performance Optimization**: Strategic caching in calculation services
|
|
312
|
+
|
|
313
|
+
### Build Outputs
|
|
314
|
+
|
|
315
|
+
The library provides multiple build formats:
|
|
316
|
+
|
|
317
|
+
| Build Type | File | Use Case | D3 Included |
|
|
318
|
+
|--------------------|------------------------------------------|---------------------------------|-------------|
|
|
319
|
+
| **ES Module** | `us-energy-sankey-v10.esm.js` | Modern bundlers (Webpack, Vite) | No |
|
|
320
|
+
| **UMD** | `us-energy-sankey-v10.umd.js` | Browser script tag | No |
|
|
321
|
+
| **UMD Minified** | `us-energy-sankey-v10.umd.min.js` | Production browser | No |
|
|
322
|
+
| **Standalone ES** | `us-energy-sankey-v10.standalone.esm.js` | Modern browsers, no bundler | Yes |
|
|
323
|
+
| **Standalone UMD** | `us-energy-sankey-v10.standalone.umd.js` | Any browser environment | Yes |
|
|
324
|
+
| **Standalone Min** | `us-energy-sankey-v10.standalone.min.js` | Production, no bundler | Yes |
|
|
325
|
+
|
|
326
|
+
## Development
|
|
327
|
+
|
|
328
|
+
### Building from Source
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# Clone the repository
|
|
332
|
+
cd us-energy-sankey-v10
|
|
333
|
+
|
|
334
|
+
# Install dependencies
|
|
335
|
+
npm install
|
|
336
|
+
|
|
337
|
+
# Development build with watch mode
|
|
338
|
+
npm run dev
|
|
339
|
+
|
|
340
|
+
# Production build (all formats)
|
|
341
|
+
npm run build
|
|
342
|
+
|
|
343
|
+
# Type checking only
|
|
344
|
+
npm run type-check
|
|
345
|
+
|
|
346
|
+
# Clean build artifacts
|
|
347
|
+
npm run clean
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Testing
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# Run all tests
|
|
354
|
+
npm test
|
|
355
|
+
|
|
356
|
+
# Run numerical validation tests
|
|
357
|
+
npm run test:numerical
|
|
358
|
+
|
|
359
|
+
# Run visual validation tests (requires browser)
|
|
360
|
+
npm run test:visual
|
|
361
|
+
|
|
362
|
+
# Run performance validation
|
|
363
|
+
npm run test:performance
|
|
364
|
+
|
|
365
|
+
# Full validation suite
|
|
366
|
+
npm run validate:full
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Development Server
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
# Start local development server
|
|
373
|
+
npm run serve
|
|
374
|
+
|
|
375
|
+
# Navigate to http://localhost:8080/examples/data-us.html
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Project Structure
|
|
379
|
+
|
|
380
|
+
```
|
|
381
|
+
src/
|
|
382
|
+
├── core/
|
|
383
|
+
│ ├── Sankey.ts # Main orchestrator class
|
|
384
|
+
│ ├── events/
|
|
385
|
+
│ │ └── EventBus.ts # Event communication system
|
|
386
|
+
│ └── types/
|
|
387
|
+
│ └── events.ts # Event type definitions
|
|
388
|
+
├── services/
|
|
389
|
+
│ ├── ConfigurationService.ts # Constants & settings
|
|
390
|
+
│ ├── data/
|
|
391
|
+
│ │ ├── DataService.ts # Data access & navigation
|
|
392
|
+
│ │ └── DataValidationService.ts # Input validation
|
|
393
|
+
│ ├── calculation/
|
|
394
|
+
│ │ ├── SummaryService.ts # Energy totals calculation
|
|
395
|
+
│ │ └── GraphService.ts # Flow positioning algorithms
|
|
396
|
+
│ ├── RenderingService.ts # SVG generation & D3 integration
|
|
397
|
+
│ ├── AnimationService.ts # Timeline management
|
|
398
|
+
│ └── InteractionService.ts # User input handling
|
|
399
|
+
├── styles/
|
|
400
|
+
│ ├── sankey.css # Main visualization styles
|
|
401
|
+
│ └── controls.css # Control panel styles
|
|
402
|
+
├── types/
|
|
403
|
+
│ └── index.ts # Public type definitions
|
|
404
|
+
├── utils/
|
|
405
|
+
│ └── Logger.ts # Logging utilities
|
|
406
|
+
└── index.ts # Public API exports
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
## Examples
|
|
410
|
+
|
|
411
|
+
### Working Examples
|
|
412
|
+
|
|
413
|
+
See the `examples/` directory for complete working examples:
|
|
414
|
+
|
|
415
|
+
- **examples/data-us.html** - US energy data visualization (1800-2021)
|
|
416
|
+
- **examples/data-china.html** - China energy data visualization
|
|
417
|
+
- **examples/visual-test.html** - Visual testing interface
|
|
418
|
+
|
|
419
|
+
### Running Examples
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
npm run serve
|
|
423
|
+
# Open http://localhost:8080/examples/data-us.html
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Custom Data Example
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
// Load your own energy dataset
|
|
430
|
+
fetch('./my-energy-data.json')
|
|
431
|
+
.then(response => response.json())
|
|
432
|
+
.then(energyData => {
|
|
433
|
+
const sankey = new Sankey('my-container', {
|
|
434
|
+
data: energyData,
|
|
435
|
+
country: "My Country",
|
|
436
|
+
includeControls: true,
|
|
437
|
+
animationSpeed: 150,
|
|
438
|
+
autoPlay: true
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## Browser Support
|
|
444
|
+
|
|
445
|
+
| Browser | Minimum Version | Notes |
|
|
446
|
+
|-------------------|-----------------|-----------------------------------------|
|
|
447
|
+
| **Chrome** | 88+ | Full support with hardware acceleration |
|
|
448
|
+
| **Firefox** | 85+ | Full support |
|
|
449
|
+
| **Safari** | 14+ | Full support |
|
|
450
|
+
| **Edge** | 88+ | Full support |
|
|
451
|
+
| **Mobile Safari** | 14+ | Touch-optimized interactions |
|
|
452
|
+
| **Chrome Mobile** | 88+ | Touch and gesture support |
|
|
453
|
+
|
|
454
|
+
### Requirements
|
|
455
|
+
|
|
456
|
+
- **ES Modules Support**: For standalone ESM builds
|
|
457
|
+
- **D3.js v7 Compatible**: Uses modern D3 APIs
|
|
458
|
+
- **TypeScript 5.3+**: For development and type definitions
|
|
459
|
+
- **Modern JavaScript**: ES2018+ features used
|
|
460
|
+
|
|
461
|
+
## Contributing
|
|
462
|
+
|
|
463
|
+
### Development Setup
|
|
464
|
+
|
|
465
|
+
1. Fork the repository
|
|
466
|
+
2. Clone your fork: `git clone https://github.com/your-username/us-energy-sankey.git`
|
|
467
|
+
3. Install dependencies: `npm install`
|
|
468
|
+
4. Create a feature branch: `git checkout -b feature/your-feature`
|
|
469
|
+
5. Make your changes with tests
|
|
470
|
+
6. Run the full test suite: `npm run validate:full`
|
|
471
|
+
7. Submit a pull request
|
|
472
|
+
|
|
473
|
+
### Contribution Guidelines
|
|
474
|
+
|
|
475
|
+
- **Code Style**: Follow TypeScript best practices with existing ESLint configuration
|
|
476
|
+
- **Testing**: Maintain test coverage for new features
|
|
477
|
+
- **Performance**: Benchmark changes against existing performance
|
|
478
|
+
- **Documentation**: Update README and inline documentation for API changes
|
|
479
|
+
- **Types**: Ensure full TypeScript coverage for public APIs
|
|
480
|
+
|
|
481
|
+
### Reporting Issues
|
|
482
|
+
|
|
483
|
+
When reporting issues, include:
|
|
484
|
+
|
|
485
|
+
- Browser and version
|
|
486
|
+
- Dataset size and structure
|
|
487
|
+
- Steps to reproduce
|
|
488
|
+
- Console errors (if any)
|
|
489
|
+
- Expected vs actual behavior
|
|
490
|
+
|
|
491
|
+
## License
|
|
492
|
+
|
|
493
|
+
MIT License. See [LICENSE](LICENSE) file for details.
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
**Developed by the Research Computing Center (RCC), University of Chicago**
|
package/babel.config.cjs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
presets: [
|
|
3
|
+
[
|
|
4
|
+
'@babel/preset-env',
|
|
5
|
+
{
|
|
6
|
+
targets: {
|
|
7
|
+
node: 'current',
|
|
8
|
+
},
|
|
9
|
+
modules: 'cjs' // Convert ES modules to CommonJS for Jest
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
],
|
|
13
|
+
env: {
|
|
14
|
+
test: {
|
|
15
|
+
presets: [
|
|
16
|
+
[
|
|
17
|
+
'@babel/preset-env',
|
|
18
|
+
{
|
|
19
|
+
targets: {
|
|
20
|
+
node: 'current',
|
|
21
|
+
},
|
|
22
|
+
modules: 'cjs'
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<coverage generated="1759954118933" clover="3.2.0">
|
|
3
|
+
<project timestamp="1759954118933" name="All files">
|
|
4
|
+
<metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0" elements="0" coveredelements="0" complexity="0" loc="0" ncloc="0" packages="0" files="0" classes="0"/>
|
|
5
|
+
</project>
|
|
6
|
+
</coverage>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|