An interactive data visualization application for exploring UK housing affordability by Middle Super Output Area (MSOA), built with SvelteKit and ONS visual components.
- Interactive Map: Visualize housing affordability across Middle Super Output Areas (MSOAs) in England and Wales using ONS vector tiles
- Color-Coded Affordability Ratios: Map displays 7-color gradient representing price-to-earnings ratios
- Property Type Filtering: Switch between "All", Detached, Semi-detached, Terraced, and Flats
- Price Level Filtering: View Median or Lower Quartile affordability ratios
- Dynamic Legend: Shows affordability ratio ranges with automatic color breaks calculated from data
- Smart Search: Find Lower Tier Local Authorities, MSOAs, or postcodes with autocomplete
- Interactive Selection: Click search results to zoom to location and highlight parent Local Authority
- Responsive Design: Works on desktop and mobile devices
- Hover & Select Feedback: Visual feedback when hovering over or selecting MSOAs
- Node.js (v18 or higher)
- npm
Install dependencies:
npm installTo start the development server:
npm run devThe app will be available at http://localhost:5173
To build the production version:
npm run buildTo build the preview version (for staging):
npm run build:previewGitHub Pages is deployed from the main branch via the Deploy to GitHub Pages workflow using the built build/ artifact rather than a gh-pages branch.
Before pushing a Pages deployment, generate the data locally and rebuild the committed build/ folder:
npm run generate-data
npm run build:previewTo preview the built app locally:
npm run previewThe application requires pre-processed ONS housing affordability data. Generate the data from raw Excel files:
npm run generate-dataThis processes:
- 7 Excel files with 5 property types each
- 7,264 MSOAs across 318 Local Authorities
- Calculates affordability ratios (price ÷ earnings)
- Creates time series data (119 quarters: 1995-Q4 to 2025-Q2)
- Generates map-ready files with property-type-specific aggregates
- Creates shared geography files (authorities + regions)
Output: ~834 MB of JSON files in static/data/ (not committed to git)
- Shared geography folder: authorities.json + regions.json
- 5 property-type directories: each with LA files + msoas-latest + national aggregates
- 1,607 JSON files total
Time: ~9 minutes (5 min parse + 2 min calculate + 2 min generate)
For detailed information about the data pipeline, see PIPELINE.md
The interactive map displays MSOA boundaries from ONS Vector Tiles and colors them based on housing affordability data:
- MSOA Boundaries: https://cdn.ons.gov.uk/maptiles/administrative/2021/msoa/v2/boundaries/{z}/{x}/{y}.pbf
- Affordability Data: Generated from
/data/[property-type]/msoas-latest.json - Base Map: OpenStreetMap raster tiles
Uses equal-interval method to divide affordability ratios into 7 color ranges:
- Red (#E92730) = Most affordable (lowest ratios)
- Green (#0a8647) = Least affordable (highest ratios)
- Gray (#ccc) = Data unavailable
Breaks are calculated dynamically based on the minimum and maximum affordability ratios in the selected property type and price level.
- Zoom: 6 (centered on England and Wales) with minzoom constraint
- Vector tile layer:
msoawith feature IDs fromareacd(MSOA codes) - Feature state: Each MSOA has a
colorproperty set based on affordability ratio - Paint expression: Simple case statement using feature state color
- Hover/select: Visual feedback when hovering or selecting MSOAs
- Feature opacity responds to selection state (0.7 normal, 0.85 hover, 0.9 selected)
- Searches across Lower Tier Local Authorities and MSOAs
- Includes MSOA names (hclnm) with parent Local Authority for context
- Postcode lookup support to find relevant MSOA
- Selection automatically:
- Sets MSOA as highlighted on map with darker color
- Outlines parent Local Authority boundary
- Zooms to level 8 for better visibility
- Keeps selection in search box for context
Format code with Prettier:
npm run formatCheck code formatting:
npm run lintEdit the base paths in /src/app.config.js to match your deployment environment:
export const base_prod = '/visualisations/affordability-explorer'; // Production path
export const base_preview = '/affordability-explorer'; // Preview/staging path/src/routes/- Page components and routing/src/lib/- Reusable components and utilities/src/lib/components/- Svelte components (ColorLegend, etc.)/static/data/- Generated affordability data files (not committed)/src/app.html- HTML shell/src/app.css- Global styles
- SvelteKit - Framework
- Svelte 5 - UI framework
- ONS Svelte Components - Visual components library
- ONS Svelte Charts - Charting library
- ONS Svelte Maps - Mapping library with Maplibre GL
- Vite - Build tool
MIT