Skip to content

Commit 89a8698

Browse files
🚧 make interaction state into record
1 parent 830fd44 commit 89a8698

File tree

8 files changed

+38
-65
lines changed

8 files changed

+38
-65
lines changed

packages/@ourworldindata/grapher/src/chart/ChartUtils.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,9 @@ export function findValidChartTypeCombination(
197197
export function byInteractionState(series: {
198198
hover: InteractionState
199199
}): number {
200-
// background series first,
201-
// then series in their default state,
202-
// then active series
203-
switch (series.hover) {
204-
case InteractionState.background:
205-
return 1
206-
case InteractionState.foreground:
207-
return 2
208-
}
200+
if (series.hover.background) return 1
201+
if (series.hover.active) return 3
202+
return 2
209203
}
210204

211205
export function findSeriesNamesContainedInBin(

packages/@ourworldindata/grapher/src/lineCharts/LineChart.tsx

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ import {
5353
ColorScaleConfigInterface,
5454
ColorSchemeName,
5555
VerticalAlign,
56-
InteractionState,
5756
} from "@ourworldindata/types"
5857
import {
5958
GRAPHER_AXIS_LINE_WIDTH_THICK,
@@ -1283,7 +1282,7 @@ class Lines extends React.Component<LinesProps> {
12831282
if (this.props.hidePoints) return false
12841283
const totalPoints = sum(
12851284
this.props.series
1286-
.filter((s) => s.hover !== InteractionState.background)
1285+
.filter((series) => this.seriesHasMarkers(series))
12871286
.map((series) => series.placedPoints.length)
12881287
)
12891288
return totalPoints < 500
@@ -1314,24 +1313,17 @@ class Lines extends React.Component<LinesProps> {
13141313
}
13151314

13161315
private seriesHasMarkers(series: RenderLineChartSeries): boolean {
1317-
// Don't show markers for lines in the background
1318-
if (series.hover === InteractionState.background) return false
1319-
1320-
// If the series only contains one point, then we will always want to
1321-
// show a marker/circle because we can't draw a line.
1322-
return (
1323-
(this.hasMarkers || series.placedPoints.length === 1) &&
1324-
!series.isProjection
1325-
)
1316+
return !series.hover.background
13261317
}
13271318

13281319
renderLine(series: RenderLineChartSeries): React.ReactElement {
1320+
const { hover } = series
1321+
13291322
const color = series.placedPoints[0]?.color ?? DEFAULT_LINE_COLOR
13301323
const strokeDasharray = series.isProjection ? "2,3" : undefined
13311324

1332-
const nonHovered = series.hover === InteractionState.background
1333-
const strokeWidth = nonHovered ? 1 : this.strokeWidth
1334-
const strokeOpacity = nonHovered ? 0.3 : 1
1325+
const strokeWidth = hover.background ? 1 : this.strokeWidth
1326+
const strokeOpacity = hover.background ? 0.3 : 1
13351327

13361328
const outline = this.renderPathForSeries(series, {
13371329
id: makeIdForHumanConsumption("outline", series.seriesName),
@@ -1374,11 +1366,17 @@ class Lines extends React.Component<LinesProps> {
13741366
renderLineMarkers(
13751367
series: RenderLineChartSeries
13761368
): React.ReactElement | void {
1377-
if (!this.seriesHasMarkers(series)) return
1369+
// If the series only contains one point, then we will always want to
1370+
// show a marker/circle because we can't draw a line.
1371+
const forceMarkers = series.placedPoints.length === 1
1372+
1373+
// check if we should hide markers on the chart and series level
1374+
const hideMarkers = !this.hasMarkers || !this.seriesHasMarkers(series)
1375+
1376+
if (hideMarkers && !forceMarkers) return
13781377

13791378
const { horizontalAxis } = this.props.dualAxis
1380-
const nonHovered = series.hover === InteractionState.background
1381-
const opacity = nonHovered ? 0.3 : 1
1379+
const opacity = series.hover.background ? 0.3 : 1
13821380

13831381
return (
13841382
<g
@@ -1414,15 +1412,12 @@ class Lines extends React.Component<LinesProps> {
14141412
renderLines(): React.ReactElement {
14151413
return (
14161414
<>
1417-
{this.props.series.map((series) => {
1418-
const showMarkers = this.seriesHasMarkers(series)
1419-
return (
1420-
<React.Fragment key={series.seriesName}>
1421-
{this.renderLine(series)}
1422-
{showMarkers && this.renderLineMarkers(series)}
1423-
</React.Fragment>
1424-
)
1425-
})}
1415+
{this.props.series.map((series) => (
1416+
<React.Fragment key={series.seriesName}>
1417+
{this.renderLine(series)}
1418+
{this.renderLineMarkers(series)}
1419+
</React.Fragment>
1420+
))}
14261421
</>
14271422
)
14281423
}

packages/@ourworldindata/grapher/src/lineLegend/LineLegend.tsx

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class LineLabels extends React.Component<{
116116
}
117117

118118
private textOpacityForSeries(series: PlacedSeries): number {
119-
return series.hover === InteractionState.background ? 0.6 : 1
119+
return series.hover?.background ? 0.6 : 1
120120
}
121121

122122
@computed private get markers(): {
@@ -225,10 +225,7 @@ class LineLabels extends React.Component<{
225225
const step = (x2 - x1) / (totalLevels + 1)
226226
const markerXMid = x1 + step + level * step
227227
const d = `M${x1},${leftCenterY} H${markerXMid} V${rightCenterY} H${x2}`
228-
const lineColor =
229-
series.hover === InteractionState.background
230-
? "#eee"
231-
: "#999"
228+
const lineColor = series.hover?.background ? "#eee" : "#999"
232229

233230
return (
234231
<path
@@ -740,18 +737,6 @@ export class LineLegend extends React.Component<LineLegendProps> {
740737
return this.partialInitialSeries.map((series) => series.seriesName)
741738
}
742739

743-
@computed private get backgroundSeries(): PlacedSeries[] {
744-
return this.placedSeries.filter(
745-
(series) => series.hover === InteractionState.background
746-
)
747-
}
748-
749-
@computed private get focusedSeries(): PlacedSeries[] {
750-
return this.placedSeries.filter(
751-
(series) => series.hover !== InteractionState.background
752-
)
753-
}
754-
755740
// Does this placement need line markers or is the position of the labels already clear?
756741
@computed private get needsLines(): boolean {
757742
return this.placedSeries.some((series) => series.totalLevels > 1)

packages/@ourworldindata/grapher/src/selection/InteractionArray.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ export class InteractionArray {
6060
* isn't currently interacted with.
6161
*/
6262
state(seriesName: SeriesName): InteractionState {
63-
return this.isInForeground(seriesName)
64-
? InteractionState.foreground
65-
: InteractionState.background
63+
return {
64+
active: this.isActive(seriesName),
65+
background: this.isInBackground(seriesName),
66+
}
6667
}
6768

6869
@action.bound private _activate(seriesName: SeriesName): this {

packages/@ourworldindata/grapher/src/slopeCharts/SlopeChart.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import {
3535
EntityName,
3636
VerticalAlign,
3737
FacetStrategy,
38-
InteractionState,
3938
} from "@ourworldindata/types"
4039
import { ChartInterface } from "../chart/ChartInterface"
4140
import { ChartManager } from "../chart/ChartManager"
@@ -1285,7 +1284,7 @@ function Slope({
12851284
}: SlopeProps) {
12861285
const { seriesName, startPoint, endPoint } = series
12871286

1288-
const isInBackground = series.hover === InteractionState.background
1287+
const isInBackground = series.hover.background
12891288
const showOutline = !isInBackground
12901289
const opacity = isInBackground ? 0.3 : 1
12911290

packages/@ourworldindata/grapher/src/stackedCharts/StackedAreaChart.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,9 @@ export class StackedAreaChart extends AbstractStackedChart {
297297
private hoverStateForSeries(
298298
series: StackedSeries<number>
299299
): InteractionState {
300-
if (!this.focusedSeriesName) return InteractionState.foreground
301-
return this.focusedSeriesName === series.seriesName
302-
? InteractionState.foreground
303-
: InteractionState.background
300+
const active = this.focusedSeriesName === series.seriesName
301+
const background = !!this.focusedSeriesName && !active
302+
return { active, background }
304303
}
305304

306305
@computed get lineLegendSeries(): LineLabelSeries[] {

packages/@ourworldindata/types/src/grapherTypes/GrapherTypes.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ export enum DimensionProperty {
9595
table = "table",
9696
}
9797

98-
export enum InteractionState {
99-
foreground = "foreground", // series is either actively hovered/focused or the chart is not currently being interacted with
100-
background = "background", // another series is actively hovered/focused
98+
export interface InteractionState {
99+
active: boolean // actively hovered or focused
100+
background: boolean // another series is actively hovered or focused
101101
}
102102

103103
// see CoreTableConstants.ts

packages/@ourworldindata/types/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export {
113113
GrapherWindowType,
114114
AxisMinMaxValueStr,
115115
GrapherTooltipAnchor,
116-
InteractionState,
116+
type InteractionState,
117117
} from "./grapherTypes/GrapherTypes.js"
118118

119119
export {

0 commit comments

Comments
 (0)