import type { ViewState } from '../types'; export const INITIAL_RETRY_MS = 1000; export const MAX_RETRY_MS = 10000; export const MAP_BOUNDS: [number, number, number, number] = [-9.5, 49, 5, 57]; export const MAP_MIN_ZOOM = 5.5; export const BUFFER_MULTIPLIER = 1.5; export const INITIAL_VIEW_STATE: ViewState = { longitude: -1.5, latitude: 53.5, zoom: 6, pitch: 0, }; /** * Zoom to H3 resolution mapping thresholds. * Returns the H3 resolution to use for a given zoom level. */ export const ZOOM_TO_RESOLUTION_THRESHOLDS = [ { maxZoom: 7.5, resolution: 5 }, { maxZoom: 9.5, resolution: 6 }, { maxZoom: 10.5, resolution: 7 }, { maxZoom: 11.5, resolution: 8 }, { maxZoom: 13, resolution: 9 }, { maxZoom: Infinity, resolution: 10 }, ] as const; export const POSTCODE_ZOOM_THRESHOLD = 16; export const FEATURE_GRADIENT: { t: number; color: [number, number, number] }[] = [ { t: 0, color: [46, 204, 113] }, { t: 0.33, color: [241, 196, 15] }, { t: 0.66, color: [231, 76, 60] }, { t: 1, color: [142, 68, 173] }, ]; /** Property density gradient — light mode (cream → orange) */ export const DENSITY_GRADIENT: { t: number; color: [number, number, number] }[] = [ { t: 0, color: [255, 255, 255] }, { t: 0.1, color: [248, 233, 211] }, { t: 0.5, color: [255, 221, 173] }, { t: 0.8, color: [251, 171, 60] }, { t: 1, color: [255, 162, 31] }, ]; /** Property density gradient — dark mode (dark warm → bright amber) */ export const DENSITY_GRADIENT_DARK: { t: number; color: [number, number, number] }[] = [ { t: 0, color: [55, 45, 35] }, { t: 0.1, color: [85, 65, 40] }, { t: 0.5, color: [170, 115, 50] }, { t: 0.8, color: [230, 155, 45] }, { t: 1, color: [255, 170, 40] }, ]; /** Protomaps font glyphs URL (served locally from public/assets/) */ export const GLYPHS_URL = '/assets/fonts/{fontstack}/{range}.pbf'; /** Twemoji base URL (served locally from public/assets/) */ export const TWEMOJI_BASE = '/assets/twemoji/'; /** * Groups whose features should be collapsed into stacked bar charts. * Keyed by feature group name. Each entry defines one stacked chart. */ export const STACKED_GROUPS: Record = { Crime: [ { label: 'Serious crime', feature: 'Serious crime (avg/yr)', unit: 'avg/yr', components: [ 'Violence and sexual offences (avg/yr)', 'Robbery (avg/yr)', 'Burglary (avg/yr)', 'Possession of weapons (avg/yr)', ], }, { label: 'Minor crime', feature: 'Minor crime (avg/yr)', unit: 'avg/yr', components: [ 'Anti-social behaviour (avg/yr)', 'Criminal damage and arson (avg/yr)', 'Shoplifting (avg/yr)', 'Bicycle theft (avg/yr)', 'Theft from the person (avg/yr)', 'Other theft (avg/yr)', 'Vehicle crime (avg/yr)', 'Public order (avg/yr)', 'Drugs (avg/yr)', 'Other crime (avg/yr)', ], }, ], Demographics: [ { label: 'Ethnic composition', unit: '%', components: ['% White', '% Asian', '% Black', '% Mixed', '% Other'], }, ], }; /** * Groups whose enum features should be collapsed into compact multi-row charts. * Keyed by feature group name. Each entry defines one stacked enum chart. */ export const STACKED_ENUM_GROUPS: Record = { Property: [ { label: 'Property type', feature: 'Property type', components: ['Property type'], valueOrder: ['Detached', 'Semi-Detached', 'Terraced', 'Flat'], valueColors: ['#8b5cf6', '#3b82f6', '#14b8a6', '#f59e0b'], }, { label: 'Leasehold/Freehold', feature: 'Leashold/Freehold', components: ['Leashold/Freehold'], valueOrder: ['Freehold', 'Leasehold'], valueColors: ['#3b82f6', '#f59e0b'], }, ], Environment: [ { label: 'Ground Risk', feature: 'Environmental risk', components: [ 'Collapsible deposits risk', 'Compressible ground risk', 'Landslide risk', 'Running sand risk', 'Shrink-swell risk', 'Soluble rocks risk', ], valueOrder: ['Low', 'Moderate', 'Significant'], valueColors: ['#22c55e', '#eab308', '#ef4444'], }, ], }; /** Colors for stacked bar segments */ export const SEGMENT_COLORS = [ '#ef4444', // red-500 '#f97316', // orange-500 '#eab308', // yellow-500 '#22c55e', // green-500 '#14b8a6', // teal-500 '#06b6d4', // cyan-500 '#3b82f6', // blue-500 '#8b5cf6', // violet-500 '#d946ef', // fuchsia-500 '#ec4899', // pink-500 ];