LGTM
This commit is contained in:
parent
701c17a703
commit
f114ada255
44 changed files with 5264 additions and 1674 deletions
|
|
@ -72,7 +72,7 @@ export const PARTY_FEATURE_GRADIENTS: Record<string, GradientStop[]> = {
|
|||
'% Liberal Democrat': partyGradient([255, 100, 0]), // Liberal Democrat orange
|
||||
'% Reform UK': partyGradient([18, 182, 207]), // Reform UK cyan
|
||||
'% Green': partyGradient([106, 176, 35]), // Green Party green
|
||||
'% Other parties': partyGradient([107, 114, 128]), // neutral fallback for grouped parties
|
||||
'% Other parties': partyGradient([107, 114, 128]), // neutral color for grouped parties
|
||||
};
|
||||
|
||||
export const PARTY_FEATURE_COLORS: Record<string, string> = Object.fromEntries(
|
||||
|
|
@ -127,9 +127,6 @@ export const POI_GROUP_COLORS: Record<string, [number, number, number]> = {
|
|||
Shops: [99, 102, 241],
|
||||
};
|
||||
|
||||
/** Default color for unknown POI groups */
|
||||
export const POI_DEFAULT_COLOR: [number, number, number] = [107, 114, 128];
|
||||
|
||||
/** POI category → icon/logo URL for branded and transport categories */
|
||||
export const POI_CATEGORY_LOGOS: Record<string, string> = {
|
||||
Airport: '/assets/twemoji/2708.png',
|
||||
|
|
@ -152,22 +149,22 @@ export const POI_CATEGORY_LOGOS: Record<string, string> = {
|
|||
'Co-op': '/assets/poi-icons/logos/coop.svg',
|
||||
COOK: '/assets/poi-icons/brands_2024/cook.svg',
|
||||
'Convenience Store': '/assets/twemoji/1f3ea.png',
|
||||
Costco: '/assets/poi-icons/brands/costco.svg',
|
||||
Costco: '/assets/poi-icons/logos/costco.svg',
|
||||
'Deli & Specialty': '/assets/twemoji/1f9c6.png',
|
||||
'Dunnes Stores': '/assets/poi-icons/brands_2024/dunnes_stores.svg',
|
||||
Farmfoods: '/assets/poi-icons/brands_2023/supermarkets/farmfoods.svg',
|
||||
Ferry: '/assets/twemoji/26f4.png',
|
||||
Greengrocer: '/assets/twemoji/1f96c.png',
|
||||
'Heron Foods': '/assets/poi-icons/brands_2023/supermarkets/heron_foods.svg',
|
||||
Iceland: '/assets/poi-icons/logos/iceland.svg',
|
||||
Iceland: '/assets/poi-icons/brands_2024/iceland.svg',
|
||||
Lidl: '/assets/poi-icons/logos/lidl.svg',
|
||||
Makro: '/assets/poi-icons/brands_2024/makro.svg',
|
||||
'M&S': '/assets/poi-icons/brands/mns.svg',
|
||||
'M&S Clothing': '/assets/poi-icons/brands/mns_high_street.svg',
|
||||
'M&S Food': '/assets/poi-icons/brands/mns_food.svg',
|
||||
'M&S Hospital': '/assets/poi-icons/brands/mns_hospital.svg',
|
||||
'M&S MSA': '/assets/poi-icons/brands/mns_moto.svg',
|
||||
'M&S Outlet': '/assets/poi-icons/brands/mns_outlet.svg',
|
||||
'M&S': '/assets/poi-icons/brands_2024/mns.svg',
|
||||
'M&S Clothing': '/assets/poi-icons/brands_2024/mns.svg',
|
||||
'M&S Food': '/assets/poi-icons/visuals/mns.svg',
|
||||
'M&S Hospital': '/assets/poi-icons/brands_2024/mns.svg',
|
||||
'M&S MSA': '/assets/poi-icons/brands_2024/mns.svg',
|
||||
'M&S Outlet': '/assets/poi-icons/brands_2024/mns.svg',
|
||||
Morrisons: '/assets/poi-icons/logos/morrisons.svg',
|
||||
'Morrisons Daily': '/assets/poi-icons/brands_2024/morrisons_daily.svg',
|
||||
'Off-Licence': '/assets/twemoji/1f377.png',
|
||||
|
|
@ -181,10 +178,10 @@ export const POI_CATEGORY_LOGOS: Record<string, string> = {
|
|||
'Tesco Express': '/assets/poi-icons/logos/tesco_express.svg',
|
||||
'Tesco Extra': '/assets/poi-icons/logos/tesco_extra.svg',
|
||||
'Taxi rank': '/assets/twemoji/1f695.png',
|
||||
'The Food Warehouse': '/assets/poi-icons/logos/iceland.svg',
|
||||
'The Food Warehouse': '/assets/poi-icons/logos/the_food_warehouse.png',
|
||||
'Tube station': '/assets/poi-icons/public_transport/london_tube.svg',
|
||||
Waitrose: '/assets/poi-icons/logos/waitrose.svg',
|
||||
'Little Waitrose': '/assets/poi-icons/brands/little_waitrose.svg',
|
||||
'Little Waitrose': '/assets/poi-icons/brands_2023/supermarkets/little_waitrose.svg',
|
||||
'Whole Foods Market': '/assets/poi-icons/brands_2024/wholefoods.svg',
|
||||
};
|
||||
|
||||
|
|
@ -329,9 +326,8 @@ export const ENUM_PALETTE: [number, number, number][] = [
|
|||
];
|
||||
|
||||
/**
|
||||
* Per-feature color overrides for enum values on the map and dashboard.
|
||||
* Per-feature color definitions for enum values on the map and dashboard.
|
||||
* Keys are feature names (as returned by the server), values map enum value → RGB.
|
||||
* Any value not listed falls back to ENUM_PALETTE by index.
|
||||
*/
|
||||
export const ENUM_COLOR_OVERRIDES: Record<string, Record<string, [number, number, number]>> = {
|
||||
'Property type': {
|
||||
|
|
@ -341,49 +337,105 @@ export const ENUM_COLOR_OVERRIDES: Record<string, Record<string, [number, number
|
|||
'Flats/Maisonettes': [236, 72, 153], // pink
|
||||
Other: [107, 114, 128], // gray
|
||||
},
|
||||
'Leasehold/Freehold': {
|
||||
Freehold: [59, 130, 246],
|
||||
Leasehold: [245, 158, 11],
|
||||
},
|
||||
'Former council house': {
|
||||
Yes: [239, 68, 68],
|
||||
No: [34, 197, 94],
|
||||
},
|
||||
'Current energy rating': {
|
||||
A: [22, 163, 74],
|
||||
B: [132, 204, 22],
|
||||
C: [234, 179, 8],
|
||||
D: [245, 158, 11],
|
||||
E: [249, 115, 22],
|
||||
F: [239, 68, 68],
|
||||
G: [126, 34, 206],
|
||||
},
|
||||
'Potential energy rating': {
|
||||
A: [22, 163, 74],
|
||||
B: [132, 204, 22],
|
||||
C: [234, 179, 8],
|
||||
D: [245, 158, 11],
|
||||
E: [249, 115, 22],
|
||||
F: [239, 68, 68],
|
||||
G: [126, 34, 206],
|
||||
},
|
||||
'Max available download speed (Mbps)': {
|
||||
'10': [107, 114, 128],
|
||||
'30': [245, 158, 11],
|
||||
'100': [59, 130, 246],
|
||||
'300': [20, 184, 166],
|
||||
'1000': [34, 197, 94],
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Build a 10-color palette for a given feature, using overrides where defined.
|
||||
* Returns the default ENUM_PALETTE when no overrides exist.
|
||||
* Build the 10-color shader palette for a given enum feature.
|
||||
* The trailing slots are invisible for features with fewer than 10 enum values.
|
||||
*/
|
||||
export function getEnumPaletteForFeature(
|
||||
featureName: string | null,
|
||||
values?: string[]
|
||||
featureName: string,
|
||||
values: string[]
|
||||
): [number, number, number][] {
|
||||
if (!featureName || !values) return ENUM_PALETTE;
|
||||
const overrides = ENUM_COLOR_OVERRIDES[featureName];
|
||||
if (!overrides) return ENUM_PALETTE;
|
||||
if (!overrides) {
|
||||
throw new Error(`Missing enum color definitions for '${featureName}'`);
|
||||
}
|
||||
|
||||
const palette: [number, number, number][] = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
if (i < values.length && overrides[values[i]]) {
|
||||
palette.push(overrides[values[i]]);
|
||||
if (i < values.length) {
|
||||
const color = overrides[values[i]];
|
||||
if (!color) {
|
||||
throw new Error(`Missing enum color for '${featureName}' value '${values[i]}'`);
|
||||
}
|
||||
palette.push(color);
|
||||
} else {
|
||||
palette.push(ENUM_PALETTE[i % ENUM_PALETTE.length]);
|
||||
palette.push([0, 0, 0]);
|
||||
}
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
/** Look up override color for a specific enum value, or null if none. */
|
||||
/** Look up the configured color for a specific enum value. */
|
||||
export function getEnumValueColor(
|
||||
featureName: string,
|
||||
valueName: string
|
||||
): [number, number, number] | null {
|
||||
return ENUM_COLOR_OVERRIDES[featureName]?.[valueName] ?? null;
|
||||
): [number, number, number] {
|
||||
const color = ENUM_COLOR_OVERRIDES[featureName]?.[valueName];
|
||||
if (!color) {
|
||||
throw new Error(`Missing enum color for '${featureName}' value '${valueName}'`);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
/** 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
|
||||
];
|
||||
/** Explicit colors for stacked bar segments. */
|
||||
export const STACKED_SEGMENT_COLORS: Record<string, string> = {
|
||||
'Violence and sexual offences (avg/yr)': '#ef4444',
|
||||
'Robbery (avg/yr)': '#f97316',
|
||||
'Burglary (avg/yr)': '#eab308',
|
||||
'Possession of weapons (avg/yr)': '#8b5cf6',
|
||||
'Anti-social behaviour (avg/yr)': '#14b8a6',
|
||||
'Criminal damage and arson (avg/yr)': '#f97316',
|
||||
'Shoplifting (avg/yr)': '#ec4899',
|
||||
'Bicycle theft (avg/yr)': '#22c55e',
|
||||
'Theft from the person (avg/yr)': '#d946ef',
|
||||
'Other theft (avg/yr)': '#06b6d4',
|
||||
'Vehicle crime (avg/yr)': '#3b82f6',
|
||||
'Public order (avg/yr)': '#8b5cf6',
|
||||
'Drugs (avg/yr)': '#22c55e',
|
||||
'Other crime (avg/yr)': '#6b7280',
|
||||
'% White': '#3b82f6',
|
||||
'% South Asian': '#f97316',
|
||||
'% East Asian': '#eab308',
|
||||
'% Black': '#8b5cf6',
|
||||
'% Mixed': '#14b8a6',
|
||||
'% Other': '#6b7280',
|
||||
'Anti-social': '#14b8a6',
|
||||
Vehicle: '#3b82f6',
|
||||
Burglary: '#eab308',
|
||||
Other: '#6b7280',
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue