diff --git a/packages/@ourworldindata/components/src/TextWrap/TextWrapGroup.tsx b/packages/@ourworldindata/components/src/TextWrap/TextWrapGroup.tsx index 5515573dd7e..d59bea2e354 100644 --- a/packages/@ourworldindata/components/src/TextWrap/TextWrapGroup.tsx +++ b/packages/@ourworldindata/components/src/TextWrap/TextWrapGroup.tsx @@ -147,6 +147,9 @@ export class TextWrapGroup { return max(this.textWraps.map((textWrap) => textWrap.width)) ?? 0 } + // split concatenated fragments into lines for rendering. a line may have + // multiple fragments since each fragment comes with its own style and + // is therefore rendered into a separate tspan. @computed get lines(): { fragments: Omit[] textWrap: TextWrap diff --git a/packages/@ourworldindata/grapher/src/lineCharts/LineChart.tsx b/packages/@ourworldindata/grapher/src/lineCharts/LineChart.tsx index 710b04f0397..d75109dcf9b 100644 --- a/packages/@ourworldindata/grapher/src/lineCharts/LineChart.tsx +++ b/packages/@ourworldindata/grapher/src/lineCharts/LineChart.tsx @@ -881,7 +881,7 @@ export class LineChart // only pass props that are required to calculate // the width to avoid circular dependencies - return LineLegend.width({ + return LineLegend.stableWidth({ labelSeries: this.lineLegendSeries, maxWidth: this.maxLineLegendWidth, fontSize: this.fontSize, diff --git a/packages/@ourworldindata/grapher/src/lineLegend/LineLegend.tsx b/packages/@ourworldindata/grapher/src/lineLegend/LineLegend.tsx index 68778d3c36d..9b1cd91be3e 100644 --- a/packages/@ourworldindata/grapher/src/lineLegend/LineLegend.tsx +++ b/packages/@ourworldindata/grapher/src/lineLegend/LineLegend.tsx @@ -354,9 +354,9 @@ export class LineLegend extends React.Component { * This is partly due to a circular dependency (in line and stacked area * charts), partly to avoid jumpy layout changes (slope charts). */ - static width(props: LineLegendProps): number { + static stableWidth(props: LineLegendProps): number { const test = new LineLegend(props) - return test.maxLabelWidth + DEFAULT_CONNECTOR_LINE_WIDTH + MARKER_MARGIN + return test.stableWidth } static fontSize(props: Partial): number { @@ -371,7 +371,7 @@ export class LineLegend extends React.Component { static visibleSeriesNames(props: LineLegendProps): SeriesName[] { const test = new LineLegend(props as LineLegendProps) - return test.partialInitialSeries.map((series) => series.seriesName) + return test.visibleSeriesNames } @computed private get fontSize(): number { @@ -420,6 +420,7 @@ export class LineLegend extends React.Component { text: label.annotation, maxWidth: maxAnnotationWidth, fontSize: fontSize * 0.9, + lineHeight: 1, }) : undefined @@ -445,6 +446,10 @@ export class LineLegend extends React.Component { return max(sizedLabels.map((d) => d.width)) ?? 0 } + @computed get stableWidth(): number { + return this.maxLabelWidth + DEFAULT_CONNECTOR_LINE_WIDTH + MARKER_MARGIN + } + @computed get onMouseOver(): any { return this.props.onMouseOver ?? noop } @@ -755,6 +760,10 @@ export class LineLegend extends React.Component { } } + @computed get visibleSeriesNames(): SeriesName[] { + return this.partialInitialSeries.map((series) => series.seriesName) + } + @computed private get backgroundSeries(): PlacedSeries[] { const { focusedSeriesNames } = this const { isFocusMode } = this diff --git a/packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx b/packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx index e802f63b1b8..cee0643457d 100644 --- a/packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx +++ b/packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx @@ -411,10 +411,6 @@ export class SlopeChart ) } - @computed get seriesByName(): Map { - return new Map(this.series.map((series) => [series.seriesName, series])) - } - @computed private get placedSeries(): PlacedSlopeChartSeries[] { const { yAxis, startX, endX } = this @@ -595,31 +591,28 @@ export class SlopeChart @computed get lineLegendWidthLeft(): number { if (!this.manager.showLegend) return 0 - return LineLegend.width({ + return LineLegend.stableWidth({ labelSeries: this.lineLegendSeriesLeft, ...this.lineLegendPropsCommon, ...this.lineLegendPropsLeft, }) } - @computed get lineLegendWidthRight(): number { - if (!this.manager.showLegend) return 0 - return LineLegend.width({ + @computed get lineLegendRight(): LineLegend | undefined { + if (!this.manager.showLegend) return undefined + return new LineLegend({ labelSeries: this.lineLegendSeriesRight, ...this.lineLegendPropsCommon, ...this.lineLegendPropsRight, }) } + @computed get lineLegendWidthRight(): number { + return this.lineLegendRight?.stableWidth ?? 0 + } + @computed get visibleLineLegendLabelsRight(): Set { - if (!this.manager.showLegend) return new Set() - return new Set( - LineLegend.visibleSeriesNames({ - labelSeries: this.lineLegendSeriesRight, - ...this.lineLegendPropsCommon, - ...this.lineLegendPropsRight, - }) - ) + return new Set(this.lineLegendRight?.visibleSeriesNames ?? []) } @computed get seriesSortedByImportanceForLineLegendLeft(): SeriesName[] { diff --git a/packages/@ourworldindata/grapher/src/stackedCharts/StackedAreaChart.tsx b/packages/@ourworldindata/grapher/src/stackedCharts/StackedAreaChart.tsx index eaf919a43d1..b06229817ce 100644 --- a/packages/@ourworldindata/grapher/src/stackedCharts/StackedAreaChart.tsx +++ b/packages/@ourworldindata/grapher/src/stackedCharts/StackedAreaChart.tsx @@ -317,7 +317,7 @@ export class StackedAreaChart extends AbstractStackedChart { // only pass props that are required to calculate // the width to avoid circular dependencies - return LineLegend.width({ + return LineLegend.stableWidth({ labelSeries: this.lineLegendSeries, maxWidth: this.maxLineLegendWidth, fontSize: this.fontSize,