Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add data download handling for multi-dims #4495

Merged
merged 2 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions functions/_common/downloadFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export async function fetchMetadataForGrapher(
searchParams?: URLSearchParams
) {
console.log("Initializing grapher")
const grapher = await initGrapher(
const { grapher, multiDimAvailableDimensions } = await initGrapher(
identifier,
TWITTER_OPTIONS,
searchParams ?? new URLSearchParams(""),
Expand All @@ -25,7 +25,8 @@ export async function fetchMetadataForGrapher(

const fullMetadata = assembleMetadata(
grapher,
searchParams ?? new URLSearchParams("")
searchParams ?? new URLSearchParams(""),
multiDimAvailableDimensions
)

return Response.json(fullMetadata)
Expand All @@ -37,7 +38,7 @@ export async function fetchZipForGrapher(
searchParams?: URLSearchParams
) {
console.log("preparing to generate zip file")
const grapher = await initGrapher(
const { grapher } = await initGrapher(
identifier,
TWITTER_OPTIONS,
searchParams ?? new URLSearchParams(""),
Expand Down Expand Up @@ -82,7 +83,7 @@ export async function fetchCsvForGrapher(
env: Env,
searchParams?: URLSearchParams
) {
const grapher = await initGrapher(
const { grapher } = await initGrapher(
identifier,
TWITTER_OPTIONS,
searchParams ?? new URLSearchParams(""),
Expand Down Expand Up @@ -118,7 +119,7 @@ export async function fetchReadmeForGrapher(
searchParams?: URLSearchParams
) {
console.log("Initializing grapher")
const grapher = await initGrapher(
const { grapher, multiDimAvailableDimensions } = await initGrapher(
identifier,
TWITTER_OPTIONS,
searchParams ?? new URLSearchParams(""),
Expand All @@ -127,17 +128,28 @@ export async function fetchReadmeForGrapher(

await grapher.downloadLegacyDataFromOwidVariableIds()

const readme = assembleReadme(grapher, searchParams)
const readme = assembleReadme(
grapher,
searchParams,
multiDimAvailableDimensions
)
return new Response(readme, {
headers: {
"Content-Type": "text/markdown; charset=utf-8",
},
})
}

function assembleReadme(
grapher: Grapher,
searchParams: URLSearchParams
searchParams: URLSearchParams,
multiDimAvailableDimensions?: string[]
): string {
const metadataCols = getColumnsForMetadata(grapher)
return constructReadme(grapher, metadataCols, searchParams)
return constructReadme(
grapher,
metadataCols,
searchParams,
multiDimAvailableDimensions
)
}
7 changes: 6 additions & 1 deletion functions/_common/grapherRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ async function fetchAndRenderGrapherToSvg(
env: Env
) {
const grapherLogger = new TimeLogger("grapher")
const grapher = await initGrapher(identifier, options, searchParams, env)
const { grapher } = await initGrapher(
identifier,
options,
searchParams,
env
)

grapherLogger.log("initGrapher")
const promises = []
Expand Down
26 changes: 22 additions & 4 deletions functions/_common/grapherTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ImageOptions } from "./imageOptions.js"

interface FetchGrapherConfigResult {
grapherConfig: GrapherInterface | null
multiDimAvailableDimensions?: string[]
status: number
etag: string | undefined
}
Expand Down Expand Up @@ -139,28 +140,41 @@ export async function fetchGrapherConfig({

const config = await fetchResponse.json()
let grapherConfig: GrapherInterface
let multiDimAvailableDimensions: string[]
if (identifier.type === "multi-dim-slug") {
const multiDimConfig = config as MultiDimDataPageConfigEnriched
grapherConfig = await fetchMultiDimGrapherConfig(
config as MultiDimDataPageConfigEnriched,
multiDimConfig,
searchParams,
env
)
multiDimAvailableDimensions = multiDimConfig.dimensions.map(
(dim) => dim.slug
)
} else {
grapherConfig = config
}
console.log("grapher title", grapherConfig.title)
return {
const result: FetchGrapherConfigResult = {
grapherConfig,
status: 200,
etag: fetchResponse.headers.get("etag"),
}
if (identifier.type === "multi-dim-slug") {
result.multiDimAvailableDimensions = multiDimAvailableDimensions
}
return result
}

export async function initGrapher(
identifier: GrapherIdentifier,
options: ImageOptions,
searchParams: URLSearchParams,
env: Env
): Promise<Grapher> {
): Promise<{
grapher: Grapher
multiDimAvailableDimensions?: string[]
}> {
let grapherConfigResponse: FetchGrapherConfigResult
try {
grapherConfigResponse = await fetchGrapherConfig({
Expand Down Expand Up @@ -211,7 +225,11 @@ export async function initGrapher(
grapher.isExportingToSvgOrPng = true
grapher.shouldIncludeDetailsInStaticExport = options.details

return grapher
return {
grapher,
multiDimAvailableDimensions:
grapherConfigResponse.multiDimAvailableDimensions,
}
}

/**
Expand Down
8 changes: 6 additions & 2 deletions functions/_common/metadataTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ export const getColumnsForMetadata = (grapher: Grapher) => {
}
export function assembleMetadata(
grapher: Grapher,
searchParams: URLSearchParams
searchParams: URLSearchParams,
multiDimAvailableDimensions?: string[]
) {
const useShortNames = searchParams.get("useColumnShortNames") === "true"

Expand Down Expand Up @@ -192,7 +193,10 @@ export function assembleMetadata(
dateDownloaded: dateDownloaded.toISOString().split("T")[0],
// NOTE: this is filtered by whitelisted grapher query params - if you want other params to be
// inlucded here (e.g. MDIM selection), add them to the whitelist inside getGrapherFilters
activeFilters: getGrapherFilters(searchParams),
activeFilters: getGrapherFilters(
searchParams,
multiDimAvailableDimensions
),
}

return fullMetadata
Expand Down
25 changes: 16 additions & 9 deletions functions/_common/readmeTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,16 @@ function* columnReadmeText(col: CoreColumn) {
yield ""
}

function* activeFilterSettings(searchParams: URLSearchParams) {
function* activeFilterSettings(
searchParams: URLSearchParams,
multiDimAvailableDimensions?: string[]
) {
// NOTE: this is filtered by whitelisted grapher query params - if you want other params to be
// inlucded here (e.g. MDIM selection), add them to the whitelist inside getGrapherFilters
const filterSettings = getGrapherFilters(searchParams)
// inlucded here, add them to the whitelist inside getGrapherFilters
const filterSettings = getGrapherFilters(
searchParams,
multiDimAvailableDimensions
)
if (filterSettings) {
yield ""
yield `### Active Filters`
Expand All @@ -251,7 +257,8 @@ function* activeFilterSettings(searchParams: URLSearchParams) {
export function constructReadme(
grapher: Grapher,
columns: CoreColumn[],
searchParams: URLSearchParams
searchParams: URLSearchParams,
multiDimAvailableDimensions?: string[]
): string {
const isSingleColumn = columns.length === 1
// Some computed columns have neither a source nor origins - filter these away
Expand All @@ -265,10 +272,10 @@ export function constructReadme(

const downloadDate = formatDate(new Date()) // formats the date as "October 10, 2024"
if (isSingleColumn)
readme = `# ${grapher.title} - Data package
readme = `# ${grapher.displayTitle} - Data package
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grapher.title is undefined for mdims. The title we show in the UI gets set after we fetch the indicator metadata, so we have to use grapher.displayTitle. This should be safe also for normal graphers, since we return grapher.title from grapher.displayTitle, if it exists.


This data package contains the data that powers the chart ["${grapher.title}"](${urlWithFilters}) on the Our World in Data website. It was downloaded on ${downloadDate}.
${[...activeFilterSettings(searchParams)].join("\n")}
This data package contains the data that powers the chart ["${grapher.displayTitle}"](${urlWithFilters}) on the Our World in Data website. It was downloaded on ${downloadDate}.
${[...activeFilterSettings(searchParams, multiDimAvailableDimensions)].join("\n")}
## CSV Structure

The high level structure of the CSV file is that each row is an observation for an entity (usually a country or region) and a timepoint (usually a year).
Expand All @@ -293,9 +300,9 @@ ${sources.join("\n")}

`
else
readme = `# ${grapher.title} - Data package
readme = `# ${grapher.displayTitle} - Data package

This data package contains the data that powers the chart ["${grapher.title}"](${urlWithFilters}) on the Our World in Data website.
This data package contains the data that powers the chart ["${grapher.displayTitle}"](${urlWithFilters}) on the Our World in Data website.

## CSV Structure

Expand Down
8 changes: 6 additions & 2 deletions functions/_common/urlTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { pick } from "@ourworldindata/utils"
import { GRAPHER_QUERY_PARAM_KEYS } from "@ourworldindata/types"

export function getGrapherFilters(
searchParams: URLSearchParams
searchParams: URLSearchParams,
multiDimAvailableDimensions?: string[]
): Record<string, string> | undefined {
const params = searchParams.size
? Object.fromEntries(searchParams)
Expand All @@ -12,5 +13,8 @@ export function getGrapherFilters(
delete params.v1
delete params.csvType
delete params.useColumnShortNames
return pick(params, GRAPHER_QUERY_PARAM_KEYS)
return pick(params, [
...GRAPHER_QUERY_PARAM_KEYS,
...(multiDimAvailableDimensions ?? []),
])
}
13 changes: 9 additions & 4 deletions site/multiDim/MultiDimDataPageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ import {
fetchWithRetry,
} from "@ourworldindata/utils"
import cx from "classnames"
import { ADMIN_BASE_URL, DATA_API_URL } from "../../settings/clientSettings.js"
import {
ADMIN_BASE_URL,
BAKED_GRAPHER_URL,
DATA_API_URL,
} from "../../settings/clientSettings.js"
import {
DataPageRelatedResearch,
FaqEntryKeyedByGdocIdAndFragmentId,
Expand Down Expand Up @@ -295,6 +299,9 @@ export const MultiDimDataPageContent = ({
const grapherConfigComputed = useMemo(() => {
const baseConfig: GrapherProgrammaticInterface = {
bounds,
bakedGrapherURL: BAKED_GRAPHER_URL,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this for constructing the URLs we show in the downloads modal.

adminBaseUrl: ADMIN_BASE_URL,
dataApiUrl: DATA_API_URL,
manager: {}, // Don't resize while data is loading.
}

Expand All @@ -307,12 +314,11 @@ export const MultiDimDataPageContent = ({
return {
...varGrapherConfig,
...baseConfig,
dataApiUrl: DATA_API_URL,
manager: {
canonicalUrl,
editUrl,
},
} as GrapherProgrammaticInterface
}
}, [
varGrapherConfig,
grapherConfigIsReady,
Expand Down Expand Up @@ -399,7 +405,6 @@ export const MultiDimDataPageContent = ({
{...grapherConfigComputed}
queryStr={queryStr}
getGrapherInstance={setGrapherInst}
adminBaseUrl={ADMIN_BASE_URL}
/>
</figure>
</div>
Expand Down