diff --git a/web/src/data/config.ts b/web/src/data/config.ts index d6f3283..d72edde 100644 --- a/web/src/data/config.ts +++ b/web/src/data/config.ts @@ -70,6 +70,10 @@ const allIndicators: Map = new Map([ ["air_quality", { // This is an actual prose name of the indicator used in the UI. "short": "Air pollution", + // This is used in the map hover text. Generally you'll want this to be + // the same as 'short', but in the original DemoLand app 'accessibility' + // is condensed to 'access.' to save space. + "hover": "Air pollution", // 'less' and 'more' are used in the charts to describe what smaller and // larger values mean respectively. "less": "cleaner", @@ -87,6 +91,7 @@ const allIndicators: Map = new Map([ }], ["house_price", { "short": "House prices", + "hover": "House prices", "less": "cheaper", "more": "more expensive", "less_diff": "decreased", @@ -96,6 +101,7 @@ const allIndicators: Map = new Map([ }], ["job_accessibility", { "short": "Job accessibility", + "hover": "Job access.", "less": "lower", "more": "higher", "less_diff": "decreased", @@ -105,6 +111,7 @@ const allIndicators: Map = new Map([ }], ["greenspace_accessibility", { "short": "Greenspace accessibility", + "hover": "Greenspace access.", "less": "lower", "more": "higher", "less_diff": "decreased", diff --git a/web/src/types.ts b/web/src/types.ts index 00dcd5d..71bbc29 100644 --- a/web/src/types.ts +++ b/web/src/types.ts @@ -2,7 +2,7 @@ export type IndicatorName = "air_quality" | "house_price" | "job_accessibility" | "greenspace_accessibility"; -export type Indicator = { short: string, less: string, more: string, less_diff: string, more_diff: string, colormap: string, colormapReversed: boolean }; +export type Indicator = { short: string, hover: string, less: string, more: string, less_diff: string, more_diff: string, colormap: string, colormapReversed: boolean }; /* Model inputs (land use) */ diff --git a/web/src/utils/colors.ts b/web/src/utils/colors.ts index 60bd266..e7e9bfb 100644 --- a/web/src/utils/colors.ts +++ b/web/src/utils/colors.ts @@ -2,7 +2,7 @@ import colormap from "colormap"; import { type IndicatorName, type LayerName, } from "src/types"; import config from "src/data/config"; -export function makeColormap(indicator: IndicatorName | "diff", n: number) { +export function makeColormap(indicator: IndicatorName | "diff", n: number): string[] { if (indicator === "diff") { return colormap({ colormap: "RdBu", @@ -23,12 +23,11 @@ export function makeColormap(indicator: IndicatorName | "diff", n: number) { } } -const colormaps: { [key: string]: string[] } = { - "air_quality": makeColormap("air_quality", 100), - "house_price": makeColormap("house_price", 100), - "job_accessibility": makeColormap("job_accessibility", 100), - "greenspace_accessibility": makeColormap("greenspace_accessibility", 100), - "diff": makeColormap("diff", 100), +const colormaps: Map = new Map([ + ["diff", makeColormap("diff", 100)], +]) +for (const indiName of config.allIndicators.keys()) { + colormaps.set(indiName, makeColormap(indiName, 100)); } function getColorFromMap(map: string[], value: number, min: number, max: number) { @@ -46,14 +45,13 @@ function getColorFromMap(map: string[], value: number, min: number, max: number) * @param value The value of the layer in the scenario */ export function getColor(layerName: LayerName, value: number) { - if (layerName === "signature_type") { // Categorical variable return config.signatures[value].color; } else { // Continuous variables, use the respective colormaps - return getColorFromMap(colormaps[layerName], value, config.scale.min, config.scale.max); + return getColorFromMap(colormaps.get(layerName), value, config.scale.min, config.scale.max); } } @@ -81,6 +79,6 @@ export function getDiffColor(layerName: LayerName, value: number, cmpValue: numb // Continuous variables, use 'diff' colormap return value === cmpValue ? "rgba(0, 0, 0, 0.1)" - : getColorFromMap(colormaps["diff"], value - cmpValue, -maxDiffExtents.get(layerName), maxDiffExtents.get(layerName)); + : getColorFromMap(colormaps.get("diff"), value - cmpValue, -maxDiffExtents.get(layerName), maxDiffExtents.get(layerName)); } } diff --git a/web/src/utils/hover.ts b/web/src/utils/hover.ts index ed7fb2d..b887749 100644 --- a/web/src/utils/hover.ts +++ b/web/src/utils/hover.ts @@ -63,10 +63,7 @@ function makeHoverHtml(feat: GeoJSON.Feature, }${Math.abs(chg).toFixed(1)}%)`; } return [ - `${indi.short.replace( - "accessibility", - "access." - )}`, + `${indi.hover}`, ``, activeFactor === name ? `${makeColoredBlock(color)} ` : ``, diff --git a/web/src/utils/scenarios.ts b/web/src/utils/scenarios.ts index 495244a..1b722dd 100644 --- a/web/src/utils/scenarios.ts +++ b/web/src/utils/scenarios.ts @@ -103,12 +103,14 @@ function fromValuesObject( valuesMap.set(oa, new Map()); foundAreaNames.add(oa); for (const [key, value] of Object.entries(map)) { - if (value === null) { - throw new Error(`Null value found in scenario values for OA '${oa}'.${src}`); - } const layerName = key as LayerName; - valuesMap.get(oa) - .set(layerName, rescale(layerName, preprocess(value as number), scaleFactors)); + if (config.allLayers.has(layerName)) { + if (value === null) { + throw new Error(`Null value found in scenario values for OA '${oa}'.${src}`); + } + valuesMap.get(oa) + .set(layerName, rescale(layerName, preprocess(value as number), scaleFactors)); + } } } }