Skip to content

Commit

Permalink
Make something work again with FetchingGrapher
Browse files Browse the repository at this point in the history
  • Loading branch information
danyx23 committed Dec 30, 2024
1 parent 8a17e70 commit 29148e1
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 75 deletions.
3 changes: 2 additions & 1 deletion adminSiteClient/GrapherConfigGridEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,8 @@ export class GrapherConfigGridEditor extends React.Component<GrapherConfigGridEd
// the same country selection as you zap through the variables
this.grapher.clearSelection()
this.grapher.updateFromObject(newConfig)
this.grapher.downloadData()
// TODO: ensure data is downloaded
// this.grapher.downloadData()
} else this.grapherElement = <Grapher {...newConfig} />
}

Expand Down
6 changes: 3 additions & 3 deletions baker/GrapherImageBaker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function bakeGrapherToSvgAndPng(
optimizeSvgs = false
) {
const grapher = initGrapherForSvgExport(jsonConfig)
grapher.receiveOwidData(vardata)
// grapher.receiveOwidData(vardata)
const outPath = path.join(outDir, grapher.slug as string)

let svgCode = grapher.staticSVG
Expand Down Expand Up @@ -125,7 +125,7 @@ export async function bakeGrapherToSvg(
if (fs.existsSync(outPath) && !overwriteExisting) return
const variableIds = grapher.dimensions.map((d) => d.variableId)
const vardata = await getDataForMultipleVariables(variableIds)

Check warning on line 127 in baker/GrapherImageBaker.tsx

View workflow job for this annotation

GitHub Actions / eslint

'vardata' is assigned a value but never used. Allowed unused vars must match /^_/u

Check warning on line 127 in baker/GrapherImageBaker.tsx

View workflow job for this annotation

GitHub Actions / eslint

'vardata' is assigned a value but never used. Allowed unused vars must match /^_/u
grapher.receiveOwidData(vardata)
// grapher.receiveOwidData(vardata)

let svgCode = grapher.staticSVG
if (optimizeSvgs) svgCode = await optimizeSvg(svgCode)
Expand Down Expand Up @@ -234,6 +234,6 @@ export async function grapherToSVG(
const grapher = new Grapher({ ...jsonConfig, manuallyProvideData: true })
grapher.isExportingToSvgOrPng = true
grapher.shouldIncludeDetailsInStaticExport = false
grapher.receiveOwidData(vardata)
// grapher.receiveOwidData(vardata)
return grapher.staticSVG
}
3 changes: 2 additions & 1 deletion baker/updateChartEntities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ const obtainAvailableEntitiesForGrapherConfig = async (
await getVariableDataUsingCache(variableId),
])
)
grapher.receiveOwidData(variableData)
// TODO: make sure that data is loaded here
// grapher.receiveOwidData(variableData)

// If the grapher has a chart tab, then the available entities there are the "most interesting" ones to us
if (grapher.hasChartTab) {
Expand Down
2 changes: 1 addition & 1 deletion devTools/svgTester/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ export async function renderSvg(
{ shouldHashQueryStr: false, separator: "?" }
)

grapher.receiveOwidData(configAndData.variableData)
// grapher.receiveOwidData(configAndData.variableData)
const durationReceiveData = Date.now() - timeStart

const svg = grapher.staticSVG
Expand Down
22 changes: 18 additions & 4 deletions packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ export interface FetchingGrapherProps {
configUrl?: string
queryString?: string
dataApiUrl: string
adminBaseUrl: string
bakedGrapherURL: string
}
export async function FetchingGrapher(
export function FetchingGrapher(
props: FetchingGrapherProps
): Promise<React.JSX.Element | null> {
): JSX.Element | null {
// if config is not provided, fetch it from configUrl
console.log("FetchingGrapher")

Check warning on line 24 in packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx

View workflow job for this annotation

GitHub Actions / eslint

Unexpected console statement

Check warning on line 24 in packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx

View workflow job for this annotation

GitHub Actions / eslint

Unexpected console statement

const [config, setConfig] = React.useState<GrapherInterface | undefined>(
undefined
props.config
)

const [inputTable, setInputTable] = React.useState<OwidTable | undefined>(
Expand All @@ -30,12 +33,14 @@ export async function FetchingGrapher(

React.useEffect(() => {
async function fetchConfigAndLoadData(): Promise<void> {
console.log("fetchConfigAndLoadData", props.configUrl)

Check warning on line 36 in packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx

View workflow job for this annotation

GitHub Actions / eslint

Unexpected console statement

Check warning on line 36 in packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx

View workflow job for this annotation

GitHub Actions / eslint

Unexpected console statement
if (!config && props.configUrl) {
const fetchedConfig = await fetch(props.configUrl).then((res) =>
res.json()
)
setConfig(fetchedConfig)
}
console.log("fetchConfigAndLoadData: config", config)

Check warning on line 43 in packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx

View workflow job for this annotation

GitHub Actions / eslint

Unexpected console statement

Check warning on line 43 in packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx

View workflow job for this annotation

GitHub Actions / eslint

Unexpected console statement
if (!config) return
const dimensions = config.dimensions || []
if (dimensions.length === 0) return
Expand All @@ -48,14 +53,23 @@ export async function FetchingGrapher(
variablesDataMap,
dimensions
)
console.log("setting input table")

Check warning on line 56 in packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx

View workflow job for this annotation

GitHub Actions / eslint

Unexpected console statement

Check warning on line 56 in packages/@ourworldindata/grapher/src/core/FetchingGrapher.tsx

View workflow job for this annotation

GitHub Actions / eslint

Unexpected console statement
setInputTable(inputTable)
}
void fetchConfigAndLoadData()
}, [props.configUrl, config, props.dataApiUrl])

if (!config) return null
if (!inputTable) return null
return <Grapher table={inputTable} queryStr={props.queryString} />
return (
<Grapher
table={inputTable}
queryStr={props.queryString}
dataApiUrl={props.dataApiUrl}
adminBaseUrl={props.adminBaseUrl}
bakedGrapherURL={props.bakedGrapherURL}
/>
)
}

// async function loadVariablesDataAdmin(
Expand Down
1 change: 1 addition & 0 deletions packages/@ourworldindata/grapher/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export {
type ColorScaleBin,
} from "./color/ColorScaleBin"
export { ChartDimension } from "./chart/ChartDimension"
export { FetchingGrapher } from "./core/FetchingGrapher"
export {
GRAPHER_EMBEDDED_FIGURE_ATTR,
GRAPHER_EMBEDDED_FIGURE_CONFIG_ATTR,
Expand Down
118 changes: 59 additions & 59 deletions site/DataPageV2Content.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { useState, useEffect, useMemo } from "react"
import { Grapher, GrapherProgrammaticInterface } from "@ourworldindata/grapher"
import { useState, useMemo } from "react";
import {
FetchingGrapher,
GrapherProgrammaticInterface,
} from "@ourworldindata/grapher";
import {
REUSE_THIS_WORK_SECTION_ID,
DATAPAGE_SOURCES_AND_PROCESSING_SECTION_ID,
} from "@ourworldindata/components"
import ReactDOM from "react-dom"
import { GrapherWithFallback } from "./GrapherWithFallback.js"
import { RelatedCharts } from "./blocks/RelatedCharts.js"
} from "@ourworldindata/components";
import ReactDOM from "react-dom";
import { RelatedCharts } from "./blocks/RelatedCharts.js";
import {
DataPageV2ContentFields,
formatAuthors,
Expand All @@ -15,41 +17,46 @@ import {
joinTitleFragments,
ImageMetadata,
DEFAULT_THUMBNAIL_FILENAME,
} from "@ourworldindata/utils"
import { AttachmentsContext, DocumentContext } from "./gdocs/OwidGdoc.js"
import StickyNav from "./blocks/StickyNav.js"
import { DebugProvider } from "./gdocs/DebugContext.js"
import { BAKED_BASE_URL } from "../settings/clientSettings.js"
import Image from "./gdocs/components/Image.js"
import AboutThisData from "./AboutThisData.js"
import MetadataSection from "./MetadataSection.js"
import TopicTags from "./TopicTags.js"
} from "@ourworldindata/utils";
import { AttachmentsContext, DocumentContext } from "./gdocs/OwidGdoc.js";
import StickyNav from "./blocks/StickyNav.js";
import { DebugProvider } from "./gdocs/DebugContext.js";
import {
ADMIN_BASE_URL,
BAKED_BASE_URL,
BAKED_GRAPHER_URL,
DATA_API_URL,
} from "../settings/clientSettings.js";
import Image from "./gdocs/components/Image.js";
import AboutThisData from "./AboutThisData.js";
import MetadataSection from "./MetadataSection.js";
import TopicTags from "./TopicTags.js";

declare global {
interface Window {
_OWID_DATAPAGEV2_PROPS: DataPageV2ContentFields
_OWID_GRAPHER_CONFIG: GrapherInterface
_OWID_DATAPAGEV2_PROPS: DataPageV2ContentFields;
_OWID_GRAPHER_CONFIG: GrapherInterface;
}
}
export const OWID_DATAPAGE_CONTENT_ROOT_ID = "owid-datapageJson-root"
export const OWID_DATAPAGE_CONTENT_ROOT_ID = "owid-datapageJson-root";

// We still have topic pages on WordPress, whose featured images are specified as absolute URLs which this component handles
// Once we've migrated all WP topic pages to gdocs, we'll be able to remove this component and just use <Image />
const DatapageResearchThumbnail = ({
urlOrFilename,
}: {
urlOrFilename: string | undefined | null
urlOrFilename: string | undefined | null;
}) => {
if (!urlOrFilename) {
urlOrFilename = `${BAKED_BASE_URL}/${DEFAULT_THUMBNAIL_FILENAME}`
urlOrFilename = `${BAKED_BASE_URL}/${DEFAULT_THUMBNAIL_FILENAME}`;
}
if (urlOrFilename.startsWith("http")) {
return (
<img
src={urlOrFilename}
className="span-lg-cols-2 span-sm-cols-3"
/>
)
);
}
return (
<Image
Expand All @@ -58,8 +65,8 @@ const DatapageResearchThumbnail = ({
containerType="thumbnail"
className="span-lg-cols-2 span-sm-cols-3"
/>
)
}
);
};

export const DataPageV2Content = ({
datapageData,
Expand All @@ -70,15 +77,13 @@ export const DataPageV2Content = ({
tagToSlugMap,
imageMetadata,
}: DataPageV2ContentFields & {
grapherConfig: GrapherInterface
imageMetadata: Record<string, ImageMetadata>
grapherConfig: GrapherInterface;
imageMetadata: Record<string, ImageMetadata>;
}) => {
const [grapher, setGrapher] = useState<Grapher | undefined>(undefined)

const titleFragments = joinTitleFragments(
datapageData.attributionShort,
datapageData.titleVariant
)
);

// Initialize the grapher for client-side rendering
const mergedGrapherConfig: GrapherProgrammaticInterface = useMemo(
Expand All @@ -88,11 +93,7 @@ export const DataPageV2Content = ({
bindUrlToWindow: true,
}),
[grapherConfig]
)

useEffect(() => {
setGrapher(new Grapher(mergedGrapherConfig))
}, [mergedGrapherConfig])
);

const stickyNavLinks = [
{
Expand All @@ -110,30 +111,30 @@ export const DataPageV2Content = ({
target: "#" + DATAPAGE_SOURCES_AND_PROCESSING_SECTION_ID,
},
{ text: "Reuse This Work", target: "#" + REUSE_THIS_WORK_SECTION_ID },
]
];

const relatedResearchCandidates = datapageData.relatedResearch
const relatedResearchCandidates = datapageData.relatedResearch;
const relatedResearch =
relatedResearchCandidates.length > 3 &&
datapageData.topicTagsLinks?.length
? relatedResearchCandidates.filter((research) => {
const shared = intersection(
research.tags,
datapageData.topicTagsLinks ?? []
)
return shared.length > 0
);
return shared.length > 0;
})
: relatedResearchCandidates
: relatedResearchCandidates;
for (const item of relatedResearch) {
// TODO: these are workarounds to not link to the (not really existing) template pages for energy or co2
// country profiles but instead to the topic page at the country selector.
if (item.url === "/co2-country-profile")
item.url =
"/co2-and-greenhouse-gas-emissions#co2-and-greenhouse-gas-emissions-country-profiles"
"/co2-and-greenhouse-gas-emissions#co2-and-greenhouse-gas-emissions-country-profiles";
else if (item.url === "/energy-country-profile")
item.url = "/energy#country-profiles"
item.url = "/energy#country-profiles";
else if (item.url === "/coronavirus-country-profile")
item.url = "/coronavirus#coronavirus-country-profiles"
item.url = "/coronavirus#coronavirus-country-profiles";
}

return (
Expand All @@ -148,9 +149,11 @@ export const DataPageV2Content = ({
>
<DocumentContext.Provider value={{ isPreviewing }}>
<div className="DataPageContent__grapher-for-embed">
<GrapherWithFallback
grapher={grapher}
slug={grapherConfig.slug}
<FetchingGrapher
config={mergedGrapherConfig}
dataApiUrl={DATA_API_URL}
adminBaseUrl={ADMIN_BASE_URL}
bakedGrapherURL={BAKED_GRAPHER_URL}
/>
</div>
<div className="DataPageContent grid grid-cols-12-full-width">
Expand Down Expand Up @@ -182,14 +185,11 @@ export const DataPageV2Content = ({
</nav>
<div className="span-cols-14 grid grid-cols-12-full-width full-width--border">
<div className="chart-key-info col-start-2 span-cols-12">
<GrapherWithFallback
grapher={grapher}
slug={grapherConfig.slug} // TODO: On grapher pages,
// there will always be a slug, but if we just show a data page preview for an indicator in the admin, there will be no slug
// and then thumbnails will be broken for those. When we consider baking data pages for
// non-grapher pages then we need to make sure that there are thunbnails that are generated for the these non-chart graphers and
// then this piece will have to change anyhow and know how to provide the thumbnail.
id="explore-the-data"
<FetchingGrapher
config={mergedGrapherConfig}
dataApiUrl={DATA_API_URL}
adminBaseUrl={ADMIN_BASE_URL}
bakedGrapherURL={BAKED_GRAPHER_URL}
/>
<AboutThisData
datapageData={datapageData}
Expand Down Expand Up @@ -272,13 +272,13 @@ export const DataPageV2Content = ({
</div>
</DocumentContext.Provider>
</AttachmentsContext.Provider>
)
}
);
};

export const hydrateDataPageV2Content = (isPreviewing?: boolean) => {
const wrapper = document.querySelector(`#${OWID_DATAPAGE_CONTENT_ROOT_ID}`)
const props: DataPageV2ContentFields = window._OWID_DATAPAGEV2_PROPS
const grapherConfig = window._OWID_GRAPHER_CONFIG
const wrapper = document.querySelector(`#${OWID_DATAPAGE_CONTENT_ROOT_ID}`);
const props: DataPageV2ContentFields = window._OWID_DATAPAGEV2_PROPS;
const grapherConfig = window._OWID_GRAPHER_CONFIG;

ReactDOM.hydrate(
<DebugProvider debug={isPreviewing}>
Expand All @@ -289,5 +289,5 @@ export const hydrateDataPageV2Content = (isPreviewing?: boolean) => {
/>
</DebugProvider>,
wrapper
)
}
);
};
13 changes: 7 additions & 6 deletions site/GrapherPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
FetchingGrapher,
getVariableDataRoute,
getVariableMetadataRoute,
GRAPHER_PAGE_BODY_CLASS,
Expand Down Expand Up @@ -111,12 +112,12 @@ window.Grapher.renderSingleGrapherOnGrapherPage(jsonConfig)`
<body className={GRAPHER_PAGE_BODY_CLASS}>
<SiteHeader baseUrl={baseUrl} />
<main>
<figure
className="js--hide-if-js-disabled"
data-grapher-src={`/grapher/${grapher.slug}`}
>
<LoadingIndicator />
</figure>
<FetchingGrapher
config={grapher}
dataApiUrl={DATA_API_URL}
adminBaseUrl={ADMIN_BASE_URL}
bakedGrapherURL={BAKED_GRAPHER_URL}
/>
<div className="js--hide-if-js-enabled" id="fallback">
{grapher.slug && (
<GrapherImage
Expand Down

0 comments on commit 29148e1

Please sign in to comment.