diff --git a/adminSiteServer/multiDim.ts b/adminSiteServer/multiDim.ts index 0241b88c571..e6481e8198a 100644 --- a/adminSiteServer/multiDim.ts +++ b/adminSiteServer/multiDim.ts @@ -11,7 +11,9 @@ import { DbPlainMultiDimXChartConfig, DbRawChartConfig, GrapherInterface, + IndicatorConfig, IndicatorEntryBeforePreProcessing, + isIndicatorConfig, MultiDimDataPageConfigEnriched, MultiDimDataPageConfigPreProcessed, MultiDimDataPageConfigRaw, @@ -84,12 +86,27 @@ async function resolveMultiDimDataPageCatalogPathsToIndicatorIds( ) } - function resolveSingleField(indicator?: IndicatorEntryBeforePreProcessing) { - if (typeof indicator === "string") { - const indicatorId = catalogPathToIndicatorIdMap.get(indicator) - return indicatorId ?? undefined + function resolveSingleField( + indicator?: IndicatorEntryBeforePreProcessing + ): IndicatorConfig | undefined { + switch (typeof indicator) { + case "number": + return { id: indicator } + case "string": { + const id = catalogPathToIndicatorIdMap.get(indicator) + return id ? { id } : undefined + } + case "object": { + if (isIndicatorConfig(indicator)) return indicator + if (typeof indicator.id === "string") { + const id = catalogPathToIndicatorIdMap.get(indicator.id) + return id ? { ...indicator, id } : undefined + } + return undefined + } + default: + return undefined } - return indicator } function resolveSingleOrArrayField( @@ -202,7 +219,7 @@ export async function createMultiDimConfig( ) const variableConfigs = await getMergedGrapherConfigsForVariables( knex, - uniq(config.views.map((view) => view.indicators.y[0])) + uniq(config.views.map((view) => view.indicators.y[0].id)) ) const existingViewIdsToChartConfigIds = await getViewIdToChartConfigIdMap( knex, @@ -215,7 +232,7 @@ export async function createMultiDimConfig( const enrichedViews = await Promise.all( config.views.map(async (view) => { - const variableId = view.indicators.y[0] + const variableId = view.indicators.y[0].id // Main config for each view. const mainGrapherConfig: GrapherInterface = { $schema: defaultGrapherConfig.$schema, @@ -283,7 +300,7 @@ export async function createMultiDimConfig( await upsertMultiDimXChartConfigs(knex, { multiDimId, viewId: dimensionsToViewId(view.dimensions), - variableId: view.indicators.y[0], + variableId: view.indicators.y[0].id, chartConfigId: view.fullConfigId, }) } diff --git a/baker/MultiDimBaker.tsx b/baker/MultiDimBaker.tsx index db04ecdb3c7..3461aa62c94 100644 --- a/baker/MultiDimBaker.tsx +++ b/baker/MultiDimBaker.tsx @@ -37,7 +37,7 @@ import { const getRelevantVariableIds = (config: MultiDimDataPageConfigPreProcessed) => { // A "relevant" variable id is the first y indicator of each view const allIndicatorIds = config.views - .map((view) => view.indicators.y?.[0]) + .map((view) => view.indicators.y?.[0]?.id) .filter((id) => id !== undefined) return new Set(allIndicatorIds) diff --git a/packages/@ourworldindata/types/src/index.ts b/packages/@ourworldindata/types/src/index.ts index a8a3f80db50..c780e53bb2c 100644 --- a/packages/@ourworldindata/types/src/index.ts +++ b/packages/@ourworldindata/types/src/index.ts @@ -728,6 +728,7 @@ export { } from "./domainTypes/Author.js" export type { + IndicatorConfig, IndicatorEntryBeforePreProcessing, IndicatorsAfterPreProcessing, MultiDimDataPageConfigEnriched, @@ -742,3 +743,5 @@ export type { View, ViewEnriched, } from "./siteTypes/MultiDimDataPage.js" + +export { isIndicatorConfig } from "./siteTypes/MultiDimDataPage.js" diff --git a/packages/@ourworldindata/types/src/siteTypes/MultiDimDataPage.ts b/packages/@ourworldindata/types/src/siteTypes/MultiDimDataPage.ts index ddfd3a3a1b8..1f992e37d21 100644 --- a/packages/@ourworldindata/types/src/siteTypes/MultiDimDataPage.ts +++ b/packages/@ourworldindata/types/src/siteTypes/MultiDimDataPage.ts @@ -6,9 +6,27 @@ import { OwidVariableWithSource, } from "../OwidVariable.js" -// Indicator ID, catalog path, or maybe an array of those -export type IndicatorEntryBeforePreProcessing = string | number -export type IndicatorEntryAfterPreProcessing = number // catalog paths have been resolved to indicator IDs +export type IndicatorConfig = Pick + +type IndicatorConfigBeforePreProcessing = Omit & { + // Indicator ID or catalog path + id: number | string +} + +// Indicator ID, catalog path or a an object +export type IndicatorEntryBeforePreProcessing = + | string + | number + | IndicatorConfigBeforePreProcessing + +// Catalog paths have been resolved to indicator IDs +export type IndicatorEntryAfterPreProcessing = IndicatorConfig + +export function isIndicatorConfig( + indicator: IndicatorEntryBeforePreProcessing | IndicatorConfig +): indicator is IndicatorConfig { + return typeof indicator === "object" && typeof indicator.id === "number" +} type Metadata = Omit diff --git a/packages/@ourworldindata/utils/src/MultiDimDataPageConfig.test.ts b/packages/@ourworldindata/utils/src/MultiDimDataPageConfig.test.ts index a6fa83b2d0a..4122a6625ae 100644 --- a/packages/@ourworldindata/utils/src/MultiDimDataPageConfig.test.ts +++ b/packages/@ourworldindata/utils/src/MultiDimDataPageConfig.test.ts @@ -51,7 +51,7 @@ const CONFIG: MultiDimDataPageConfigEnriched = { interval: "yearly", }, indicators: { - y: [111, 222], + y: [{ id: 111 }, { id: 222 }], }, fullConfigId: uuidv7(), }, @@ -61,7 +61,7 @@ const CONFIG: MultiDimDataPageConfigEnriched = { interval: "yearly", }, indicators: { - y: [819727], + y: [{ id: 819727 }], }, fullConfigId: uuidv7(), }, diff --git a/packages/@ourworldindata/utils/src/MultiDimDataPageConfig.ts b/packages/@ourworldindata/utils/src/MultiDimDataPageConfig.ts index db93b04fe95..0644d02c438 100644 --- a/packages/@ourworldindata/utils/src/MultiDimDataPageConfig.ts +++ b/packages/@ourworldindata/utils/src/MultiDimDataPageConfig.ts @@ -156,27 +156,41 @@ export class MultiDimDataPageConfig { } static viewToDimensionsConfig( - view: View | undefined + view?: View ): OwidChartDimensionInterface[] { + const dimensions: OwidChartDimensionInterface[] = [] if (!view?.indicators) return [] - - return Object.entries(view.indicators) - .flatMap(([property, variableIdOrIds]) => { - if (Array.isArray(variableIdOrIds)) { - return variableIdOrIds.map((variableId) => ({ - property: property as DimensionProperty, - variableId, - })) - } else { - return [ - { - property: property as DimensionProperty, - variableId: variableIdOrIds, - }, - ] - } + if (view.indicators.y) { + dimensions.push( + ...view.indicators.y.map(({ id, display }) => ({ + property: DimensionProperty.y, + variableId: id, + display, + })) + ) + } + if (view.indicators.x) { + dimensions.push({ + property: DimensionProperty.x, + variableId: view.indicators.x.id, + display: view.indicators.x.display, + }) + } + if (view.indicators.size) { + dimensions.push({ + property: DimensionProperty.size, + variableId: view.indicators.size.id, + display: view.indicators.size.display, + }) + } + if (view.indicators.color) { + dimensions.push({ + property: DimensionProperty.color, + variableId: view.indicators.color.id, + display: view.indicators.color.display, }) - .filter((dim) => dim.variableId !== undefined) + } + return dimensions } } diff --git a/site/multiDim/MultiDimDataPageContent.tsx b/site/multiDim/MultiDimDataPageContent.tsx index 6edf6798f7c..b79d26e9451 100644 --- a/site/multiDim/MultiDimDataPageContent.tsx +++ b/site/multiDim/MultiDimDataPageContent.tsx @@ -150,10 +150,7 @@ const useVarDatapageData = ( setGrapherConfigIsReady(false) setGrapherConfig(null) setVarDatapageData(null) - const yIndicatorOrIndicators = currentView?.indicators?.["y"] - const variableId = Array.isArray(yIndicatorOrIndicators) - ? yIndicatorOrIndicators[0] - : yIndicatorOrIndicators + const variableId = currentView?.indicators?.["y"]?.[0]?.id if (!variableId) return const datapageDataPromise = cachedGetVariableMetadata(variableId).then( @@ -297,7 +294,7 @@ export const MultiDimDataPageContent = ({ const variables = currentView?.indicators?.["y"] const editUrl = variables?.length === 1 - ? `variables/${variables[0]}/config` + ? `variables/${variables[0].id}/config` : undefined return { ...varGrapherConfig,