Skip to content

Commit

Permalink
fix(grapher): remove entities that are not plotted from the entity se…
Browse files Browse the repository at this point in the history
…lector
  • Loading branch information
sophiamersmann committed Oct 16, 2023
1 parent 3a28913 commit 8845200
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,24 @@ export class DiscreteBarChart
return table
}

transformTableForSelection(table: OwidTable): OwidTable {
table = table
.replaceNonNumericCellsWithErrorValues(this.yColumnSlugs)
.dropRowsWithErrorValuesForAllColumns(this.yColumnSlugs)

if (this.missingDataStrategy === MissingDataStrategy.hide) {
const groupedByEntity = table.groupBy("entityName").map((t) => {
if (t.hasAnyColumnNoValidValue(this.yColumnSlugs)) {
t = t.dropAllRows()
}
return t
})
table = groupedByEntity[0].concat(groupedByEntity.slice(1))
}

return table
}

@computed get inputTable(): OwidTable {
return this.manager.table
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface ChartInterface {
// Todo: should all charts additionally have a placedSeries: ChartPlacedSeries[] getter?

transformTable: ChartTableTransformer
transformTableForSelection?: ChartTableTransformer

yAxis?: HorizontalAxis | VerticalAxis
xAxis?: HorizontalAxis | VerticalAxis
Expand Down
23 changes: 14 additions & 9 deletions packages/@ourworldindata/grapher/src/core/Grapher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -664,16 +664,21 @@ export class Grapher
// Depending on the chart type, the criteria for being able to select an entity are
// different; e.g. for scatterplots, the entity needs to (1) not be excluded and
// (2) needs to have data for the x and y dimension.
let table =
this.isScatter || this.isSlopeChart
? this.tableAfterAuthorTimelineAndActiveChartTransform
: this.inputTable

if (!this.isReady) return table

// Some chart types (e.g. stacked area charts) choose not to show an entity
// with incomplete data. Such chart types define a custom transform function
// to ensure that the entity selector only offers entities that are actually plotted.
if (this.chartInstance.transformTableForSelection) {
table = this.chartInstance.transformTableForSelection(table)
}

if (this.isScatter || this.isSlopeChart)
// for scatter and slope charts, the `transformTable()` call takes care of removing
// all entities that cannot be selected
return this.tableAfterAuthorTimelineAndActiveChartTransform

// for other chart types, the `transformTable()` call would sometimes remove too many
// entities, and we want to use the inputTable instead (which should have exactly the
// entities where data is available)
return this.inputTable
return table
}

// If an author sets a timeline filter run it early in the pipeline so to the charts it's as if the filtered times do not exist
Expand Down
16 changes: 16 additions & 0 deletions packages/@ourworldindata/grapher/src/lineCharts/LineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,22 @@ export class LineChart
return table
}

transformTableForSelection(table: OwidTable): OwidTable {
table = table.replaceNonNumericCellsWithErrorValues(this.yColumnSlugs)

if (this.missingDataStrategy === MissingDataStrategy.hide) {
const groupedByEntity = table.groupBy("entityName").map((t) => {
if (t.hasAnyColumnNoValidValue(this.yColumnSlugs)) {
t = t.dropAllRows()
}
return t
})
table = groupedByEntity[0].concat(groupedByEntity.slice(1))
}

return table
}

@computed private get missingDataStrategy(): MissingDataStrategy {
return this.manager.missingDataStrategy || MissingDataStrategy.auto
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,29 @@ export class AbstractStackedChart
return table
}

transformTableForSelection(table: OwidTable): OwidTable {
table = table
.replaceNonNumericCellsWithErrorValues(this.yColumnSlugs)
.dropRowsWithErrorValuesForAllColumns(this.yColumnSlugs)

if (this.shouldRunLinearInterpolation) {
this.yColumnSlugs.forEach((slug) => {
table = table.interpolateColumnLinearly(slug)
})
}

if (this.missingDataStrategy !== MissingDataStrategy.show) {
const groupedByEntity = table
.groupBy("entityName")
.map((t: OwidTable) =>
t.dropRowsWithErrorValuesForAnyColumn(this.yColumnSlugs)
)
table = groupedByEntity[0].concat(groupedByEntity.slice(1))
}

return table
}

@computed private get missingDataStrategy(): MissingDataStrategy {
return this.manager.missingDataStrategy || MissingDataStrategy.auto
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,28 @@ export class StackedDiscreteBarChart
return table
}

transformTableForSelection(table: OwidTable): OwidTable {
table = table
.replaceNonNumericCellsWithErrorValues(this.yColumnSlugs)
.dropRowsWithErrorValuesForAllColumns(this.yColumnSlugs)

this.yColumnSlugs.forEach((slug) => {
table = table.interpolateColumnWithTolerance(slug)
})

if (this.missingDataStrategy === MissingDataStrategy.hide) {
const groupedByEntity = table.groupBy("entityName").map((t) => {
if (t.hasAnyColumnNoValidValue(this.yColumnSlugs)) {
t = t.dropAllRows()
}
return t
})
table = groupedByEntity[0].concat(groupedByEntity.slice(1))
}

return table
}

@computed get sortConfig(): SortConfig {
return this.manager.sortConfig ?? {}
}
Expand Down

0 comments on commit 8845200

Please sign in to comment.