energy-visualization-sankey 1.0.11 → 1.0.13
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/.cursorrules +41 -0
- package/README.md +8 -1
- package/bun.lock +1426 -0
- package/dist/sankey.esm.js +108 -79
- package/dist/sankey.esm.js.map +1 -1
- package/dist/sankey.umd.js +8720 -8687
- package/dist/sankey.umd.js.map +1 -1
- package/dist/types/core/Sankey.d.ts +294 -0
- package/dist/types/core/Sankey.d.ts.map +1 -0
- package/dist/types/core/events/EventBus.d.ts +195 -0
- package/dist/types/core/events/EventBus.d.ts.map +1 -0
- package/dist/types/core/types/events.d.ts +42 -0
- package/dist/types/core/types/events.d.ts.map +1 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/services/AnimationService.d.ts +229 -0
- package/dist/types/services/AnimationService.d.ts.map +1 -0
- package/dist/types/services/ConfigurationService.d.ts +182 -0
- package/dist/types/services/ConfigurationService.d.ts.map +1 -0
- package/dist/types/services/InteractionService.d.ts +377 -0
- package/dist/types/services/InteractionService.d.ts.map +1 -0
- package/dist/types/services/RenderingService.d.ts +160 -0
- package/dist/types/services/RenderingService.d.ts.map +1 -0
- package/dist/types/services/calculation/GraphService.d.ts +111 -0
- package/dist/types/services/calculation/GraphService.d.ts.map +1 -0
- package/dist/types/services/calculation/SummaryService.d.ts +149 -0
- package/dist/types/services/calculation/SummaryService.d.ts.map +1 -0
- package/dist/types/services/data/DataService.d.ts +167 -0
- package/dist/types/services/data/DataService.d.ts.map +1 -0
- package/dist/types/services/data/DataValidationService.d.ts +48 -0
- package/dist/types/services/data/DataValidationService.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +194 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/utils/Logger.d.ts +88 -0
- package/dist/types/utils/Logger.d.ts.map +1 -0
- package/package.json +4 -3
- package/rollup.config.js +11 -2
- package/src/core/Sankey.ts +3 -9
- package/src/index.ts +3 -3
- package/src/services/ConfigurationService.ts +59 -22
- package/src/services/RenderingService.ts +3 -3
- package/src/services/calculation/GraphService.ts +6 -6
- package/src/services/calculation/SummaryService.ts +3 -3
- package/src/types/index.ts +8 -1
- package/tsconfig.json +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "energy-visualization-sankey",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "A modern TypeScript library for creating interactive Sankey diagrams that visualize energy flows from sources to consumption sectors.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sankey",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"import": "./dist/sankey.esm.js",
|
|
31
31
|
"require": "./dist/sankey.umd.js"
|
|
32
32
|
},
|
|
33
|
-
"./styles": "./dist/
|
|
33
|
+
"./styles": "./dist/sankey.css"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"dev": "rollup -c -w",
|
|
37
|
-
"build": "rollup -c",
|
|
37
|
+
"build": "rollup -c && tsc-alias -p tsconfig.json",
|
|
38
38
|
"build:dev": "rollup -c",
|
|
39
39
|
"type-check": "tsc --noEmit",
|
|
40
40
|
"clean": "rm -rf dist",
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"rollup": "^4.6.1",
|
|
74
74
|
"rollup-plugin-postcss": "^4.0.2",
|
|
75
75
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
76
|
+
"tsc-alias": "^1.8.16",
|
|
76
77
|
"tslib": "^2.6.0",
|
|
77
78
|
"typescript": "^5.3.0"
|
|
78
79
|
}
|
package/rollup.config.js
CHANGED
|
@@ -27,7 +27,7 @@ const cssConfig = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const baseConfig = {
|
|
30
|
-
input: 'src/
|
|
30
|
+
input: 'src/index.ts',
|
|
31
31
|
// Embed D3 in the bundle for standalone distribution
|
|
32
32
|
external: [],
|
|
33
33
|
plugins: [
|
|
@@ -41,7 +41,16 @@ const baseConfig = {
|
|
|
41
41
|
clean: true,
|
|
42
42
|
abortOnError: false,
|
|
43
43
|
rollupCommonJSResolveHack: false,
|
|
44
|
-
typescript: ts
|
|
44
|
+
typescript: ts,
|
|
45
|
+
tsconfigOverride: {
|
|
46
|
+
compilerOptions: {
|
|
47
|
+
declaration: true,
|
|
48
|
+
declarationMap: true,
|
|
49
|
+
declarationDir: './dist/types',
|
|
50
|
+
baseUrl: '.',
|
|
51
|
+
paths: {}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
45
54
|
})
|
|
46
55
|
]
|
|
47
56
|
};
|
package/src/core/Sankey.ts
CHANGED
|
@@ -205,7 +205,6 @@ export default class Sankey {
|
|
|
205
205
|
timestamp: Date.now(),
|
|
206
206
|
source: 'SankeyVisualization',
|
|
207
207
|
data: {
|
|
208
|
-
version: '7.0.0',
|
|
209
208
|
services: [], // Will be populated as services come online
|
|
210
209
|
initTime: 0 // Will be updated when initialization completes
|
|
211
210
|
}
|
|
@@ -266,7 +265,6 @@ export default class Sankey {
|
|
|
266
265
|
timestamp: Date.now(),
|
|
267
266
|
source: 'SankeyVisualization',
|
|
268
267
|
data: {
|
|
269
|
-
version: '7.0.0',
|
|
270
268
|
totalInitTime: totalInitializationTime,
|
|
271
269
|
dataPointCount: this.options.data.length,
|
|
272
270
|
yearRange: [
|
|
@@ -672,7 +670,7 @@ export default class Sankey {
|
|
|
672
670
|
};
|
|
673
671
|
|
|
674
672
|
for (let i = 0; i < graphs.length; ++i) {
|
|
675
|
-
let top = this.services.configurationService!.
|
|
673
|
+
let top = this.services.configurationService!.LEFT_Y;
|
|
676
674
|
const y = graphs[i].year;
|
|
677
675
|
|
|
678
676
|
graphNest.strokes[y] = {};
|
|
@@ -686,7 +684,7 @@ export default class Sankey {
|
|
|
686
684
|
graphNest.strokes[y][f] = {};
|
|
687
685
|
|
|
688
686
|
if (f == 'elec') {
|
|
689
|
-
graphNest.tops[y][f] = this.services.configurationService!.
|
|
687
|
+
graphNest.tops[y][f] = this.services.configurationService!.ELECTRICITY_BOX_Y - summary.totals[i].elec * SCALE;
|
|
690
688
|
} else if (f == 'heat') {
|
|
691
689
|
graphNest.tops[y][f] = this.services.configurationService!.HEAT_BOX_Y - summary.totals[i].heat * SCALE;
|
|
692
690
|
} else {
|
|
@@ -1053,16 +1051,12 @@ export default class Sankey {
|
|
|
1053
1051
|
private mergeOptionsWithDefaults(options: SankeyOptions): SankeyOptions {
|
|
1054
1052
|
// Merge user options with system defaults
|
|
1055
1053
|
return {
|
|
1056
|
-
|
|
1057
|
-
country: options.country,
|
|
1054
|
+
...options,
|
|
1058
1055
|
includeControls: options.includeControls !== false,
|
|
1059
1056
|
includeTimeline: options.includeTimeline !== false,
|
|
1060
1057
|
includeWasteToggle: options.includeWasteToggle !== false,
|
|
1061
1058
|
autoPlay: options.autoPlay || false,
|
|
1062
1059
|
showWasteHeat: options.showWasteHeat !== false,
|
|
1063
|
-
animationSpeed: options.animationSpeed || 200,
|
|
1064
|
-
width: options.width || null,
|
|
1065
|
-
height: options.height || 620,
|
|
1066
1060
|
loopAnimation: options.loopAnimation !== undefined ? options.loopAnimation : false
|
|
1067
1061
|
};
|
|
1068
1062
|
}
|
package/src/index.ts
CHANGED
|
@@ -23,13 +23,13 @@ export type {
|
|
|
23
23
|
YearTotals,
|
|
24
24
|
BoxMaxes,
|
|
25
25
|
BoxTops
|
|
26
|
-
} from '
|
|
26
|
+
} from './types/index';
|
|
27
27
|
|
|
28
28
|
// Export error handling types
|
|
29
29
|
export {
|
|
30
30
|
SankeyError,
|
|
31
31
|
DataValidationError
|
|
32
|
-
} from '
|
|
32
|
+
} from './types/index';
|
|
33
33
|
|
|
34
34
|
// Export the main visualization class
|
|
35
|
-
export {default as default} from '
|
|
35
|
+
export {default as default} from './core/Sankey';
|
|
@@ -61,24 +61,22 @@ export class ConfigurationService {
|
|
|
61
61
|
// ===================== COORDINATE POSITIONING CONSTANTS =====================
|
|
62
62
|
|
|
63
63
|
// LEFT COLUMN POSITIONING: Fuel source boxes alignment
|
|
64
|
-
public readonly LEFT_X = 10; // X-coordinate for left column (fuel sources)
|
|
65
|
-
public readonly
|
|
64
|
+
public readonly LEFT_X: number = 10; // X-coordinate for left column (fuel sources)
|
|
65
|
+
public readonly LEFT_Y: number = 100; // Y-coordinate for top margin (visual breathing space)
|
|
66
66
|
|
|
67
67
|
// ==================== MATHEMATICAL SCALING CONSTANTS ====================
|
|
68
68
|
|
|
69
69
|
// ENERGY-TO-PIXEL CONVERSION: Critical scaling factor for proportional representation
|
|
70
|
-
public readonly SCALE = 0.02; // Converts Quads to pixels: 1 Quad = 0.02 pixels height
|
|
70
|
+
public readonly SCALE: number = 0.02; // Converts Quads to pixels: 1 Quad = 0.02 pixels height
|
|
71
71
|
// Calibrated for typical US energy consumption (0-100+ Quads)
|
|
72
72
|
// Example: 50 Quads × 0.02 = 1.0 pixel height
|
|
73
73
|
|
|
74
74
|
// ELECTRICITY BOX POSITIONING: Special coordinates for electricity box (bidirectional flows)
|
|
75
|
-
public readonly
|
|
76
|
-
public readonly
|
|
75
|
+
public readonly ELECTRICITY_BOX_X: number = 320 as const;
|
|
76
|
+
public readonly ELECTRICITY_BOX_Y: number = 120 as const;
|
|
77
77
|
|
|
78
|
-
public readonly HEAT_BOX_X = 750 as const;
|
|
79
|
-
public readonly HEAT_BOX_Y = 200 as const;
|
|
80
|
-
// X=350: Positioned between fuel sources (left) and sectors (right)
|
|
81
|
-
// Y=120: Offset below title area for visual clarity
|
|
78
|
+
public readonly HEAT_BOX_X: number = 750 as const;
|
|
79
|
+
public readonly HEAT_BOX_Y: number = 200 as const;
|
|
82
80
|
|
|
83
81
|
// ======================== VISUAL SPACING CONSTANTS ========================
|
|
84
82
|
|
|
@@ -87,7 +85,7 @@ export class ConfigurationService {
|
|
|
87
85
|
public readonly RIGHT_GAP: number; // Gap between sector boxes (right column) - computed as LEFT_GAP × 2.1
|
|
88
86
|
|
|
89
87
|
// ANIMATION PARAMETERS: Timing and transition control
|
|
90
|
-
public readonly SPEED: number; // Animation speed in milliseconds (from user options, default 200)
|
|
88
|
+
public readonly SPEED: number = 200; // Animation speed in milliseconds (from user options, default 200)
|
|
91
89
|
public readonly BLEED = 0.5; // Edge bleed factor for smooth visual transitions
|
|
92
90
|
|
|
93
91
|
// =================== GEOMETRIC CALCULATION CONSTANTS ===================
|
|
@@ -100,7 +98,7 @@ export class ConfigurationService {
|
|
|
100
98
|
// FLOW PATH SPACING: Visual separation between parallel energy flows
|
|
101
99
|
public readonly PATH_GAP: number = 20; // Pixel gap between parallel flow paths
|
|
102
100
|
// Prevents visual overlap while maintaining readability
|
|
103
|
-
public readonly
|
|
101
|
+
public readonly ELECTRICITY_GAP = 19; // Special gap for electricity flows (slightly smaller)
|
|
104
102
|
// Optimized for electricity box's central position
|
|
105
103
|
|
|
106
104
|
// ====================== ENERGY SOURCE DEFINITIONS ======================
|
|
@@ -165,7 +163,31 @@ export class ConfigurationService {
|
|
|
165
163
|
) {
|
|
166
164
|
// Calculate computed properties
|
|
167
165
|
this.RIGHT_GAP = this.LEFT_GAP * 2.1;
|
|
168
|
-
|
|
166
|
+
|
|
167
|
+
if (options.animationSpeed) {
|
|
168
|
+
this.SPEED = options.animationSpeed;
|
|
169
|
+
}
|
|
170
|
+
if (options.scale) {
|
|
171
|
+
this.SCALE = options.scale;
|
|
172
|
+
}
|
|
173
|
+
if (options.leftX) {
|
|
174
|
+
this.LEFT_X = options.leftX;
|
|
175
|
+
}
|
|
176
|
+
if (options.leftY) {
|
|
177
|
+
this.LEFT_Y = options.leftY;
|
|
178
|
+
}
|
|
179
|
+
if (options.electricityBoxX) {
|
|
180
|
+
this.ELECTRICITY_BOX_X = options.electricityBoxX;
|
|
181
|
+
}
|
|
182
|
+
if (options.electricityBoxY) {
|
|
183
|
+
this.ELECTRICITY_BOX_Y = options.electricityBoxY;
|
|
184
|
+
}
|
|
185
|
+
if (options.heatBoxX) {
|
|
186
|
+
this.HEAT_BOX_X = options.heatBoxX;
|
|
187
|
+
}
|
|
188
|
+
if (options.heatBoxY) {
|
|
189
|
+
this.HEAT_BOX_Y = options.heatBoxY;
|
|
190
|
+
}
|
|
169
191
|
|
|
170
192
|
this.FLOW_PATHS_ORDER = {
|
|
171
193
|
"elec": this.BOXES_DEFAULT_FLOW_PATHS_ORDER,
|
|
@@ -366,39 +388,54 @@ export class ConfigurationService {
|
|
|
366
388
|
private validateConfiguration(): void {
|
|
367
389
|
// Validate dimensions
|
|
368
390
|
if (this.WIDTH <= 0 || this.HEIGHT <= 0) {
|
|
369
|
-
throw new Error('
|
|
391
|
+
throw new Error('Invalid dimensions');
|
|
370
392
|
}
|
|
371
393
|
|
|
372
394
|
// Validate box positioning
|
|
373
395
|
if (this.BOX_WIDTH <= 0 || this.BOX_HEIGHT <= 0) {
|
|
374
|
-
throw new Error('
|
|
396
|
+
throw new Error('Invalid box dimensions');
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Validate scaling factors
|
|
400
|
+
if (this.SPEED <= 0) {
|
|
401
|
+
throw new Error('Invalid animation speed');
|
|
375
402
|
}
|
|
376
403
|
|
|
377
404
|
// Validate scaling factors
|
|
378
405
|
if (this.SCALE <= 0) {
|
|
379
|
-
throw new Error('
|
|
406
|
+
throw new Error('Invalid scale factor');
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Validate left source positioning
|
|
410
|
+
if (this.LEFT_X <= 0 || this.LEFT_Y <= 0) {
|
|
411
|
+
throw new Error('Invalid left sources position');
|
|
380
412
|
}
|
|
381
413
|
|
|
382
414
|
// Validate electricity box positioning
|
|
383
|
-
if (this.
|
|
384
|
-
throw new Error('
|
|
415
|
+
if (this.ELECTRICITY_BOX_X <= 0 || this.ELECTRICITY_BOX_Y <= 0) {
|
|
416
|
+
throw new Error('Invalid electricity box position');
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Validate heat box positioning
|
|
420
|
+
if (this.HEAT_BOX_X <= 0 || this.HEAT_BOX_Y <= 0) {
|
|
421
|
+
throw new Error('Invalid heat box position');
|
|
385
422
|
}
|
|
386
423
|
|
|
387
424
|
// Validate fuel definitions
|
|
388
425
|
if (this.FUELS.length === 0) {
|
|
389
|
-
throw new Error('
|
|
426
|
+
throw new Error('No fuels defined');
|
|
390
427
|
}
|
|
391
428
|
|
|
392
429
|
// Validate sector definitions
|
|
393
430
|
if (this.BOXES.length === 0) {
|
|
394
|
-
throw new Error('
|
|
431
|
+
throw new Error('No sectors defined');
|
|
395
432
|
}
|
|
396
433
|
|
|
397
434
|
// Validate required fuels exist
|
|
398
435
|
const requiredFuels = ['elec', 'solar', 'nuclear', 'hydro', 'wind', 'geo', 'gas', 'coal', 'bio', 'petro'];
|
|
399
436
|
for (const fuel of requiredFuels) {
|
|
400
437
|
if (!this.FUEL_NAMES.includes(fuel)) {
|
|
401
|
-
console.warn(`
|
|
438
|
+
console.warn(`Missing required fuel: ${fuel}`);
|
|
402
439
|
}
|
|
403
440
|
}
|
|
404
441
|
|
|
@@ -406,11 +443,11 @@ export class ConfigurationService {
|
|
|
406
443
|
const requiredSectors = ['elec', 'res', 'ag', 'indus', 'trans'];
|
|
407
444
|
for (const sector of requiredSectors) {
|
|
408
445
|
if (!this.BOX_NAMES.includes(sector)) {
|
|
409
|
-
console.warn(`
|
|
446
|
+
console.warn(`Missing required sector: ${sector}`);
|
|
410
447
|
}
|
|
411
448
|
}
|
|
412
449
|
|
|
413
|
-
this.logger.log('
|
|
450
|
+
this.logger.log('All configuration validated successfully');
|
|
414
451
|
}
|
|
415
452
|
|
|
416
453
|
// ==================== UTILITY METHODS ====================
|
|
@@ -172,7 +172,7 @@ export class RenderingService {
|
|
|
172
172
|
.attr('x', this.configService.LEFT_X) // X-position: left column alignment
|
|
173
173
|
.attr('y', (d: any, i: number) => { // Y-position: calculated per fuel
|
|
174
174
|
// Calculate cumulative Y position for this fuel
|
|
175
|
-
let cumulativeTop = this.configService.
|
|
175
|
+
let cumulativeTop = this.configService.LEFT_Y;
|
|
176
176
|
for (let j = 0; j < i; j++) {
|
|
177
177
|
const prevFuel = leftFuels[j];
|
|
178
178
|
const prevFuelTotal = totals[prevFuel.fuel] || 0;
|
|
@@ -236,8 +236,8 @@ export class RenderingService {
|
|
|
236
236
|
// CONDITIONAL POSITIONING ALGORITHM: Electricity vs. Regular Sectors
|
|
237
237
|
if (boxConfig.box === 'elec') {
|
|
238
238
|
// ELECTRICITY BOX: Special central positioning
|
|
239
|
-
x = this.configService.
|
|
240
|
-
y = this.configService.
|
|
239
|
+
x = this.configService.ELECTRICITY_BOX_X; // Configured X-position
|
|
240
|
+
y = this.configService.ELECTRICITY_BOX_Y - totals.elec * this.configService.SCALE; // Dynamic Y-position
|
|
241
241
|
} else if (boxConfig.box === 'heat') {
|
|
242
242
|
// ELECTRICITY BOX: Special central positioning
|
|
243
243
|
x = this.configService.HEAT_BOX_X; // Configured X-position
|
|
@@ -97,13 +97,13 @@ export class GraphService {
|
|
|
97
97
|
// Eliminates repeated property access during O(n³) loop execution
|
|
98
98
|
// Performance improvement: 5-10% reduction in execution time
|
|
99
99
|
const SCALE = this.configService.SCALE; // Energy-to-pixel conversion (0.02)
|
|
100
|
-
const ELEC_BOX_X = this.configService.
|
|
101
|
-
const ELEC_BOX_Y = this.configService.
|
|
100
|
+
const ELEC_BOX_X = this.configService.ELECTRICITY_BOX_X; // Electricity box X-coordinate
|
|
101
|
+
const ELEC_BOX_Y = this.configService.ELECTRICITY_BOX_Y; // Electricity box Y-coordinate
|
|
102
102
|
const HEAT_BOX_X = this.configService.HEAT_BOX_X; // Heat box X-coordinate
|
|
103
103
|
const HEAT_BOX_Y = this.configService.HEAT_BOX_Y; // Heat box Y-coordinate
|
|
104
104
|
const BOX_WIDTH = this.configService.BOX_WIDTH; // Standard box width
|
|
105
105
|
const LEFT_X = this.configService.LEFT_X; // Left column X-coordinate
|
|
106
|
-
const TOP_Y = this.configService.
|
|
106
|
+
const TOP_Y = this.configService.LEFT_Y; // Top margin Y-coordinate
|
|
107
107
|
const SR3 = this.configService.SR3; // Slope ratio (height/3)
|
|
108
108
|
const PATH_GAP = this.configService.PATH_GAP; // Visual gap between flow paths
|
|
109
109
|
const LEFT_GAP = this.configService.LEFT_GAP; // Gap between fuel boxes
|
|
@@ -382,7 +382,7 @@ export class GraphService {
|
|
|
382
382
|
const BOX_WIDTH = this.configService.BOX_WIDTH;
|
|
383
383
|
const SCALE = this.configService.SCALE;
|
|
384
384
|
const SR3 = this.configService.SR3;
|
|
385
|
-
const ELEC_GAP = this.configService.
|
|
385
|
+
const ELEC_GAP = this.configService.ELECTRICITY_GAP;
|
|
386
386
|
const HSR3 = this.configService.HSR3;
|
|
387
387
|
|
|
388
388
|
for (let i = 0; i < this.graphs.length; ++i) {
|
|
@@ -415,8 +415,8 @@ export class GraphService {
|
|
|
415
415
|
const BOX_WIDTH = this.configService.BOX_WIDTH;
|
|
416
416
|
const SR3 = this.configService.SR3;
|
|
417
417
|
const HSR3 = this.configService.HSR3;
|
|
418
|
-
const ELEC_GAP = this.configService.
|
|
419
|
-
const ELEC_BOX_Y = this.configService.
|
|
418
|
+
const ELEC_GAP = this.configService.ELECTRICITY_GAP;
|
|
419
|
+
const ELEC_BOX_Y = this.configService.ELECTRICITY_BOX_Y;
|
|
420
420
|
|
|
421
421
|
for (let i = 0; i < this.graphs.length; ++i) {
|
|
422
422
|
let current_box: string | null = null;
|
|
@@ -118,9 +118,9 @@ export class SummaryService {
|
|
|
118
118
|
// Measured improvement: 5-10% reduction in execution time
|
|
119
119
|
const FUELS = this.configService.FUELS; // Energy source types array
|
|
120
120
|
const BOX_NAMES = this.configService.BOX_NAMES; // Consumption sector names
|
|
121
|
-
const ELEC_BOX_Y = this.configService.
|
|
121
|
+
const ELEC_BOX_Y = this.configService.ELECTRICITY_BOX_Y; // Electricity box Y-coordinate
|
|
122
122
|
const HEAT_BOX_Y = this.configService.HEAT_BOX_Y; // Heat box Y-coordinate
|
|
123
|
-
const TOP_Y = this.configService.
|
|
123
|
+
const TOP_Y = this.configService.LEFT_Y; // Top margin for fuel labels
|
|
124
124
|
const SCALE = this.configService.SCALE; // Energy-to-pixel conversion (0.02)
|
|
125
125
|
const LEFT_GAP = this.configService.LEFT_GAP; // Visual gap between fuel boxes
|
|
126
126
|
|
|
@@ -372,7 +372,7 @@ export class SummaryService {
|
|
|
372
372
|
// ELEC_BOX_Y: Base Y-coordinate for electricity box (right-hand column)
|
|
373
373
|
// +50: Visual offset below electricity box for residential sector
|
|
374
374
|
this.boxTops = {
|
|
375
|
-
res: this.configService.
|
|
375
|
+
res: this.configService.ELECTRICITY_BOX_Y + 50, // Base position for residential
|
|
376
376
|
heat: this.configService.HEAT_BOX_Y + 50, // Base position for residential
|
|
377
377
|
ag: 0, // Will be calculated based on residential
|
|
378
378
|
indus: 0, // Will be calculated based on agriculture
|
package/src/types/index.ts
CHANGED
|
@@ -74,8 +74,15 @@ export interface SankeyOptions {
|
|
|
74
74
|
readonly autoPlay?: boolean;
|
|
75
75
|
readonly showWasteHeat?: boolean;
|
|
76
76
|
readonly animationSpeed?: number;
|
|
77
|
-
readonly width?: number
|
|
77
|
+
readonly width?: number;
|
|
78
78
|
readonly height?: number;
|
|
79
|
+
readonly scale?: number;
|
|
80
|
+
readonly leftX?: number;
|
|
81
|
+
readonly leftY?: number;
|
|
82
|
+
readonly electricityBoxX?: number;
|
|
83
|
+
readonly electricityBoxY?: number;
|
|
84
|
+
readonly heatBoxX?: number;
|
|
85
|
+
readonly heatBoxY?: number;
|
|
79
86
|
readonly loopAnimation?: boolean;
|
|
80
87
|
readonly debugLogging?: boolean;
|
|
81
88
|
}
|