diff --git a/db/migration/1732195571407-RemoveColorDimensionFromSlopeCharts.ts b/db/migration/1732195571407-RemoveColorDimensionFromSlopeCharts.ts index bbd12966c7d..1750d7e2576 100644 --- a/db/migration/1732195571407-RemoveColorDimensionFromSlopeCharts.ts +++ b/db/migration/1732195571407-RemoveColorDimensionFromSlopeCharts.ts @@ -4,7 +4,9 @@ export class RemoveColorDimensionFromSlopeCharts1732195571407 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - // update dimensions field in chart configs + // remove color dimension for all slope charts + // the y-dimension always comes first and the color dimension second, + // so it's safe to keep the first dimension only await queryRunner.query(` -- sql UPDATE chart_configs @@ -15,7 +17,7 @@ export class RemoveColorDimensionFromSlopeCharts1732195571407 chartType = 'SlopeChart' `) - // remove from chart_dimensions table + // remove the color dimension for slope charts from the chart_dimensions table await queryRunner.query(` -- sql DELETE cd FROM chart_dimensions cd diff --git a/packages/@ourworldindata/core-table/src/OwidTable.ts b/packages/@ourworldindata/core-table/src/OwidTable.ts index 34dc42551cb..c17d1e7b540 100644 --- a/packages/@ourworldindata/core-table/src/OwidTable.ts +++ b/packages/@ourworldindata/core-table/src/OwidTable.ts @@ -124,8 +124,8 @@ export class OwidTable extends CoreTable { return min(this.allTimes) as Time } - @imemo get maxTime(): Time { - return max(this.allTimes) as Time + @imemo get maxTime(): number | undefined { + return max(this.allTimes) } @imemo private get allTimes(): Time[] { diff --git a/packages/@ourworldindata/grapher/src/barCharts/DiscreteBarChart.tsx b/packages/@ourworldindata/grapher/src/barCharts/DiscreteBarChart.tsx index 144ed286209..242ddc08248 100644 --- a/packages/@ourworldindata/grapher/src/barCharts/DiscreteBarChart.tsx +++ b/packages/@ourworldindata/grapher/src/barCharts/DiscreteBarChart.tsx @@ -409,11 +409,14 @@ export class DiscreteBarChart {this.placedSeries.map((series) => { return ( - series.label && - series.label.render( - series.entityLabelX, - series.barY - series.label.height / 2, - { textProps: style } + series.label && ( + + {series.label.render( + series.entityLabelX, + series.barY - series.label.height / 2, + { textProps: style } + )} + ) ) })} @@ -990,6 +993,7 @@ function makeProjectedDataPattern(color: string): React.ReactElement { const size = 7 return ( + | React.TouchEvent + export interface SlopeChartManager extends ChartManager { - isModalOpen?: boolean - canChangeEntity?: boolean canSelectMultipleEntities?: boolean } @@ -92,9 +92,9 @@ export class SlopeChart bounds?: Bounds manager: SlopeChartManager }> - implements ChartInterface, ColorScaleManager + implements ChartInterface { - base: React.RefObject = React.createRef() + slopeAreaRef: React.RefObject = React.createRef() defaultBaseColorScheme = ColorSchemeName.OwidDistinctLines @observable hoveredSeriesName?: string @@ -166,7 +166,7 @@ export class SlopeChart } @computed private get isLogScale(): boolean { - return this.props.manager.yAxisConfig?.scaleType === ScaleType.log + return this.yScaleType === ScaleType.log } @computed private get missingDataStrategy(): MissingDataStrategy { @@ -204,26 +204,22 @@ export class SlopeChart return this.xScale(this.endTime) } - private updateTooltipPosition( - event: React.MouseEvent | React.TouchEvent - ) { + private updateTooltipPosition(event: SVGMouseOrTouchEvent) { const ref = this.manager.base?.current if (ref) this.tooltipState.position = getRelativeMouse(ref, event) } - private detectHoveredSlope( - event: React.MouseEvent | React.TouchEvent - ) { - const ref = this.base.current + private detectHoveredSlope(event: SVGMouseOrTouchEvent) { + const ref = this.slopeAreaRef.current if (!ref) return const mouse = getRelativeMouse(ref, event) this.mouseFrame = requestAnimationFrame(() => { if (this.placedSeries.length === 0) return - const distToSlope = new Map() + const distanceMap = new Map() for (const series of this.placedSeries) { - distToSlope.set( + distanceMap.set( series, PointVector.distanceFromPointToLineSegmentSq( mouse, @@ -234,9 +230,9 @@ export class SlopeChart } const closestSlope = minBy(this.placedSeries, (s) => - distToSlope.get(s) - ) - const distanceSq = distToSlope.get(closestSlope!)! + distanceMap.get(s) + )! + const distanceSq = distanceMap.get(closestSlope)! const tolerance = 10 const toleranceSq = tolerance * tolerance @@ -506,7 +502,7 @@ export class SlopeChart @computed get xRange(): [number, number] { const lineLegendWidth = this.maxLineLegendWidth + LINE_LEGEND_PADDING - // pick a reasonable width based on an ideal aspect ratio + // pick a reasonable max width based on an ideal aspect ratio const idealAspectRatio = 0.6 const chartAreaWidth = this.bounds.width - this.sidebarWidth const availableWidth = @@ -553,7 +549,7 @@ export class SlopeChart private playIntroAnimation() { // Nice little intro animation - select(this.base.current) + select(this.slopeAreaRef.current) .select(".slopes") .attr("stroke-dasharray", "100%") .attr("stroke-dashoffset", "100%") @@ -594,11 +590,9 @@ export class SlopeChart } mouseFrame?: number - @action.bound onMouseMove( - ev: React.MouseEvent | React.TouchEvent - ) { - this.updateTooltipPosition(ev) - this.detectHoveredSlope(ev) + @action.bound onMouseMove(event: SVGMouseOrTouchEvent) { + this.updateTooltipPosition(event) + this.detectHoveredSlope(event) } @action.bound onMouseLeave() { @@ -771,7 +765,7 @@ export class SlopeChart />