Behovskartan
AI Sweden
Sweden's electricity demand forecast explorer. Visualizes projected demand across regions, sectors, and scenarios through 2050. Built for Energimyndigheten.
How much electricity will we need? Scenario-based demand projections from historical data, with interactive charts and geographic maps.
The Demand tool ships as a template repository. Fork it, point a coding agent at the config files, and customize it for your own region and data.
A full-stack framework for forecasting electricity demand. Python generator, Node.js + DuckDB API, SvelteKit explorer. Fork it, swap in your data and scenarios, deploy.
config.yaml ← Scenarios, geographies, segments, parameters
│
▼
Generator (Python) ← Historical data + modular transformations
│
▼
/data/*.parquet ← Base scenarios + parametric variations + aggregations
│
▼
API (Node.js + DuckDB) ← Static JSON endpoints + dynamic time series queries
│
▼
Explorer (SvelteKit) ← Charts, maps, reports, scenario comparison, exportThe generator takes historical electricity demand data and applies modular transformations to create future scenarios. The transformation system is composable: build scenarios by stacking functions that modify demand curves for specific segments and time periods.
Define independent parameters (electrification rates, growth factors, efficiency) that create a multiplicative scenario space. Each parameter variation is stored separately and combined at query time.
Forecasts are generated per demand segment: industry, residential, transport, services, etc. Segments can be aggregated or viewed independently through the API.
Data is stored as Parquet files with pre-computed aggregations for common queries (geography × year, segment × year, national × year). This gives 50-100x speedup on dashboard queries.
Everything is defined in config.yaml:
scenarios, geographies, segments, parameters, units. Change the config
and regenerate, and no code changes are needed.
An OpenAPI 3.1 REST API that combines pre-built static endpoints with DuckDB-powered dynamic queries. The API reads Parquet files directly, with no ETL step, no database to maintain.
| Endpoint | Type | Description |
|---|---|---|
| /scenarios | Static | Scenario definitions with parameter combinations |
| /geographies | Static | Geographic regions with metadata |
| /parameters | Static | Available years, segments, resolutions |
| /config | Static | Framework configuration |
| /globals | Static | Min/max bounds for chart scales |
| /demand | Dynamic | Time series data with flexible filtering, resolution (1h–1Y), and aggregation (sum, mean, max) |
A SvelteKit application that renders forecast data as interactive visualizations. Built with Svelte 5 runes, Tailwind CSS, LayerChart, and Mapbox GL. Generates as a fully static site that can be served from any static host or CDN.
Time series, histograms, sector breakdowns, heatmaps, geographic bar charts. Each chart has per-chart parameter overrides, scenario comparison, and multi-format export (PNG, SVG, CSV, JSON).
Mapbox GL-powered choropleth maps with regional drill-down. Shows demand by geography with year and segment selection. Responsive from mobile to desktop.
Pages and reports authored in Markdown with embedded interactive components. Custom directive syntax lets domain experts write narrative content with live data visualizations inline.
Technical reference for implementers. Expand the section below for API details, data pipeline internals, file layout, and development practices.
/data/generate-api.js builds JSON files in /data/+page.ts fetches initial data and passes props to componentsPre-built JSON files served directly. Regenerated by node generate-api.js --defaults.
| Endpoint | Description |
|---|---|
GET /globals | Min/max bounds for different aggregation levels |
GET /parameters | Available years, geographies, segments, resolutions |
GET /scenarios | Scenario definitions with growth rates and parameter combinations |
GET /geographies | Geography metadata and GeoJSON |
GET /config | General configuration |
GET /demand: Time series data powered by DuckDB queries on Parquet files.
1h, 1d, 1w, 1M, 1Ysum, mean, maxgeography='total' and segment='total' for server-side aggregationTime series data returns an array of records:
{ "period": "2025-01-01T00:00:00Z", "value": 123.45, "geography": "SE01", "segment": "housing" } /data/
├── base/
│ └── {scenario_id}/
│ └── data.parquet # Base scenario data
├── scenarios/
│ └── {param1}={val1}/
│ └── {param2}={val2}/
│ └── data.parquet # Parametric variations
├── aggregated/
│ ├── geography_yearly.parquet # For maps
│ ├── segment_yearly.parquet # For sector charts
│ ├── national_yearly.parquet # For time series
│ └── scenario_metadata.parquet # Parameter combinations
└── [static JSON endpoints] type(scope): descriptionLive applications built with the Demand framework.
AI Sweden
Sweden's electricity demand forecast explorer. Visualizes projected demand across regions, sectors, and scenarios through 2050. Built for Energimyndigheten.
The stack has two deployable pieces: a static frontend and a containerized API. Run them on your own infrastructure with your preferred cloud, container platform, or static host. Nothing in the framework is tied to a specific vendor.
The Explorer builds to a fully static bundle. Deploy it to any static host or CDN. Content-hash cache busting on assets lets you set long cache lifetimes safely.
The API ships as a Docker container that bundles all Parquet data. Run it on any container platform with health checks and zero-downtime updates.