From 9c4207da58b23b74c492bd8d5c9773e4407874fb Mon Sep 17 00:00:00 2001 From: Sophia Mersmann Date: Fri, 10 Jan 2025 11:02:07 +0100 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=94=A8=20consolidate=20table=20for=20?= =?UTF-8?q?display=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../grapher/src/core/Grapher.tsx | 45 ++++++++++++++++--- .../grapher/src/dataTable/DataTable.sample.ts | 2 + .../grapher/src/dataTable/DataTable.tsx | 36 +-------------- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/packages/@ourworldindata/grapher/src/core/Grapher.tsx b/packages/@ourworldindata/grapher/src/core/Grapher.tsx index 307698ab32a..174f709b7d3 100644 --- a/packages/@ourworldindata/grapher/src/core/Grapher.tsx +++ b/packages/@ourworldindata/grapher/src/core/Grapher.tsx @@ -158,7 +158,7 @@ import { isOnTheMap } from "../mapCharts/EntitiesOnTheMap" import { ChartManager } from "../chart/ChartManager" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js" import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons" -import { SettingsMenuManager } from "../controls/SettingsMenu" +import { SettingsMenu, SettingsMenuManager } from "../controls/SettingsMenu" import { TooltipContainer } from "../tooltip/Tooltip" import { EntitySelectorModal, @@ -811,13 +811,48 @@ export class Grapher return !this.hideLegend } + @computed private get showsAllEntitiesInChart(): boolean { + return this.isScatter || this.isMarimekko + } + + @computed private get settingsMenu(): SettingsMenu { + return new SettingsMenu({ manager: this, top: 0, bottom: 0, right: 0 }) + } + + /** + * If the table filter toggle isn't offered, then we default to + * to showing only the selected entities – unless there is a view + * that displays all data points, like a map or a scatter plot. + */ + @computed get forceShowSelectionOnlyInDataTable(): boolean { + return ( + !this.settingsMenu.showTableFilterToggle && + this.hasChartTab && + !this.showsAllEntitiesInChart && + !this.hasMapTab + ) + } + // table that is used for display in the table tab @computed get tableForDisplay(): OwidTable { - const table = this.table + let table = this.table + if (!this.isReady || !this.isOnTableTab) return table - return this.chartInstance.transformTableForDisplay - ? this.chartInstance.transformTableForDisplay(table) - : table + + if (this.chartInstance.transformTableForDisplay) { + table = this.chartInstance.transformTableForDisplay(table) + } + + if ( + this.forceShowSelectionOnlyInDataTable || + this.showSelectionOnlyInDataTable + ) { + table = table.filterByEntityNames( + this.selection.selectedEntityNames + ) + } + + return table } @computed get tableForSelection(): OwidTable { diff --git a/packages/@ourworldindata/grapher/src/dataTable/DataTable.sample.ts b/packages/@ourworldindata/grapher/src/dataTable/DataTable.sample.ts index 885b71afdf8..6326d2752b8 100644 --- a/packages/@ourworldindata/grapher/src/dataTable/DataTable.sample.ts +++ b/packages/@ourworldindata/grapher/src/dataTable/DataTable.sample.ts @@ -86,6 +86,7 @@ export const GrapherWithIncompleteData = ( ] return new Grapher({ tab: GRAPHER_TAB_OPTIONS.table, + selectedEntityNames: ["Iceland", "France", "Afghanistan"], dimensions, ...props, owidDataset: createOwidTestDataset([{ metadata, data }]), @@ -127,6 +128,7 @@ export const GrapherWithAggregates = ( return new Grapher({ tab: GRAPHER_TAB_OPTIONS.table, dimensions, + selectedEntityNames: ["Afghanistan", "Iceland", "World"], ...props, owidDataset: createOwidTestDataset([ { metadata: childMortalityMetadata, data: childMortalityData }, diff --git a/packages/@ourworldindata/grapher/src/dataTable/DataTable.tsx b/packages/@ourworldindata/grapher/src/dataTable/DataTable.tsx index f7113ced87a..b6b4c89f094 100644 --- a/packages/@ourworldindata/grapher/src/dataTable/DataTable.tsx +++ b/packages/@ourworldindata/grapher/src/dataTable/DataTable.tsx @@ -44,7 +44,6 @@ import { IndicatorTitleWithFragments, joinTitleFragments, } from "@ourworldindata/utils" -import { makeSelectionArray } from "../chart/ChartUtils" import { SelectionArray } from "../selection/SelectionArray" import { DEFAULT_GRAPHER_ENTITY_TYPE } from "../core/GrapherConstants" @@ -86,7 +85,6 @@ export interface DataTableManager { endTime?: Time startTime?: Time dataTableSlugs?: ColumnSlug[] - showSelectionOnlyInDataTable?: boolean entitiesAreCountryLike?: boolean isSmall?: boolean isMedium?: boolean @@ -138,36 +136,8 @@ export class DataTable extends React.Component<{ } } - @computed get showSelectionOnlyInDataTable(): boolean { - const { - showSelectionOnlyInDataTable, - canChangeAddOrHighlightEntities, - hasChartTab, - hasMapTab, - } = this.manager - const { selectionArray } = this - - // filter the table if the "Show selection only" toggle is hidden - if ( - !canChangeAddOrHighlightEntities && - selectionArray.hasSelection && - hasChartTab && - // if we have a map tab, we want to show all entities - !hasMapTab - ) - return true - - return !!showSelectionOnlyInDataTable - } - @computed get table(): OwidTable { - let table = this.manager.tableForDisplay - if (this.showSelectionOnlyInDataTable) { - table = table.filterByEntityNames( - this.selectionArray.selectedEntityNames - ) - } - return table + return this.manager.tableForDisplay } @computed get manager(): DataTableManager { @@ -693,10 +663,6 @@ export class DataTable extends React.Component<{ ) } - @computed private get selectionArray(): SelectionArray { - return makeSelectionArray(this.manager.selection) - } - @computed private get entityNames(): string[] { const tableForEntities = this.table return union( From 7d02902c9ddd23037b9a263c7354f1a3cc717cf1 Mon Sep 17 00:00:00 2001 From: Sophia Mersmann Date: Fri, 10 Jan 2025 11:37:57 +0100 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9B=20take=20table=20filter=20togg?= =?UTF-8?q?le=20into=20account?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions/_common/downloadFunctions.ts | 8 +++-- .../grapher/src/modal/DownloadModal.tsx | 29 ++++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/functions/_common/downloadFunctions.ts b/functions/_common/downloadFunctions.ts index 390cb0bd7b0..67d33b80984 100644 --- a/functions/_common/downloadFunctions.ts +++ b/functions/_common/downloadFunctions.ts @@ -68,10 +68,12 @@ export async function fetchZipForGrapher( } function assembleCsv(grapher: Grapher, searchParams: URLSearchParams): string { const useShortNames = searchParams.get("useColumnShortNames") === "true" + const fullTable = grapher.inputTable + const filteredTable = grapher.isOnTableTab + ? grapher.tableForDisplay + : grapher.transformedTable const table = - searchParams.get("csvType") === "filtered" - ? grapher.transformedTable - : grapher.inputTable + searchParams.get("csvType") === "filtered" ? filteredTable : fullTable return table.toPrettyCsv(useShortNames) } diff --git a/packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx b/packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx index 55f41ca8134..6bf00473451 100644 --- a/packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx +++ b/packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx @@ -56,6 +56,7 @@ export interface DownloadModalManager { queryStr?: string table?: OwidTable transformedTable?: OwidTable + tableForDisplay?: OwidTable yColumnsFromDimensionsOrSlugsOrAuto?: CoreColumn[] shouldIncludeDetailsInStaticExport?: boolean detailsOrderedByReference?: string[] @@ -63,6 +64,7 @@ export interface DownloadModalManager { frameBounds?: Bounds captionedChartBounds?: Bounds isOnChartOrMapTab?: boolean + isOnTableTab?: boolean showAdminControls?: boolean isSocialMediaExport?: boolean isPublished?: boolean @@ -432,19 +434,20 @@ interface DataDownloadContextClientSide extends DataDownloadContextBase { shortColNames: boolean // Only needed for local CSV generation - table: OwidTable - transformedTable: OwidTable + fullTable: OwidTable + filteredTable: OwidTable activeColumnSlugs: string[] | undefined } const createCsvBlobLocally = async (ctx: DataDownloadContextClientSide) => { - const csv = + const downloadTable = ctx.csvDownloadType === CsvDownloadType.Full - ? ctx.table.toPrettyCsv(ctx.shortColNames, ctx.activeColumnSlugs) - : ctx.transformedTable.toPrettyCsv( - ctx.shortColNames, - ctx.activeColumnSlugs - ) + ? ctx.fullTable + : ctx.filteredTable + const csv = downloadTable.toPrettyCsv( + ctx.shortColNames, + ctx.activeColumnSlugs + ) return new Blob([csv], { type: "text/csv;charset=utf-8" }) } @@ -768,17 +771,21 @@ export const DownloadModalDataTab = (props: DownloadModalProps) => { props.manager.baseUrl ?? `/grapher/${props.manager.displaySlug}`, - table: props.manager.table ?? BlankOwidTable(), - transformedTable: - props.manager.transformedTable ?? BlankOwidTable(), + fullTable: props.manager.table ?? BlankOwidTable(), + filteredTable: + (props.manager.isOnTableTab + ? props.manager.tableForDisplay + : props.manager.transformedTable) ?? BlankOwidTable(), activeColumnSlugs: props.manager.activeColumnSlugs, }), [ props.manager.baseUrl, props.manager.displaySlug, props.manager.queryStr, + props.manager.isOnTableTab, props.manager.table, props.manager.transformedTable, + props.manager.tableForDisplay, props.manager.activeColumnSlugs, ] )