Building an Accessible UK Energy Grid Dashboard with Angular
2025-07-20
I wanted to understand the UK grid — how clean the electricity is right now, where it's coming from, how it varies by region — and the public data from the National Grid API is rich but unfriendly. So I built a dashboard to make it legible, and made accessibility a first-class requirement rather than an afterthought.
The Data
The National Grid's carbon intensity API is a quietly brilliant public resource. It exposes real-time carbon intensity — how many grams of CO₂ per kilowatt-hour the electricity you're using right now is responsible for — alongside the generation mix: how much is coming from wind, solar, gas, nuclear, imports, and the rest. And it breaks all of this down across the 14 UK DNO (Distribution Network Operator) regions, so the picture in the North Scotland is genuinely different from the one in South Wales.
The challenge isn't getting the data. It's making it mean something. A number like "212 gCO₂/kWh" is meaningless to most people. A map where the North glows green because it's windy up there and the South sits amber is something anyone can read in a glance. The whole project was about that translation — from accurate-but-opaque to immediate-and-honest.
The Build
I built it in Angular 21, and used the project as a reason to go all-in on the modern reactive model:
- NgRx SignalStore for state, with signal-based components throughout. Carbon intensity and generation data are exactly the kind of live, derived, interdependent state that signals handle cleanly — change the selected region and everything downstream recomputes without a tangle of subscriptions.
- OnPush change detection everywhere, so the framework only does work when the signals it depends on actually change.
- Lazy-loaded routes, so the initial load only ships what the first screen needs.
- Leaflet for the colour-coded regional map — the centrepiece, where the 14 DNO regions shade by current intensity.
- SVG donut charts for the generation mix, hand-built so I controlled every accessibility detail rather than fighting a charting library's defaults.
- Weekly historical trends, so you can see not just the snapshot but the shape of the last few days.
Accessibility as a Requirement
This is the part I'm most deliberate about. Accessibility wasn't a pass I did at the end — it was a requirement that shaped the build, targeting WCAG 2.1 AA.
- High-contrast mode, for users who need stronger separation than a pretty pastel palette gives.
- Reduced-motion support, honouring
prefers-reduced-motionso transitions and chart animations don't trigger discomfort. - Full keyboard navigation — every control, the map included, reachable and operable without a mouse.
- Screen-reader announcements for the data that updates live, so a blind user isn't left with a silent dashboard that's "changed" in some invisible way.
- Colour-blind-friendly patterns alongside colour.
That last one is the one I'd press hardest on. Data visualisation leans on colour to carry meaning — green is clean, red is dirty — and that's exactly the encoding that disappears for the millions of people with colour vision deficiency. If the only difference between "renewable" and "fossil" in a chart is hue, you've built something a chunk of your audience literally cannot read. So the generation mix uses patterns as well as colour: texture and shape carry the same information the colour does, redundantly. Colour is an enhancement, never the sole channel.
Performance
Accessibility and performance turned out to pull in the same direction. The dashboard scores 95+ on Lighthouse, with sub-1-second First Contentful Paint and a bundle around 80KB.
That didn't come from a magic flag. It came from the architecture: OnPush plus signals means minimal change-detection work, lazy routes mean a small initial payload, hand-rolled SVG charts mean no heavy visualisation dependency dragging in hundreds of kilobytes. A fast, light page is also a more accessible one — it works on a cheap phone on a weak connection, which is precisely the situation a lot of real users are in.
Reflection
The lesson I took from this is that accessible, performant data visualisation isn't a constraint on good engineering — it is good engineering. The discipline of "don't rely on colour alone", "don't ship work the user didn't ask for", "make sure the keyboard reaches everything" doesn't water down the product. It produces a cleaner architecture, a smaller bundle, and a thing that more people can actually use.
You can see it live — it's the kind of project I'd rather show than describe.