Skip to content

Commit

Permalink
Merge pull request #4129 from owid/stacked-area-hover-viz
Browse files Browse the repository at this point in the history
✨ (stacked area) improve hover states / TAS-687
  • Loading branch information
sophiamersmann authored Nov 19, 2024
2 parents c28ede3 + 4d8182a commit 8d5104d
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 102 deletions.
2 changes: 1 addition & 1 deletion packages/@ourworldindata/grapher/src/chart/ChartManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export interface ChartManager {
sortConfig?: SortConfig
showNoDataArea?: boolean

externalLegendFocusBin?: ColorScaleBin | undefined
externalLegendHoverBin?: ColorScaleBin | undefined
disableIntroAnimation?: boolean

missingDataStrategy?: MissingDataStrategy
Expand Down
2 changes: 2 additions & 0 deletions packages/@ourworldindata/grapher/src/core/GrapherConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export const GRAPHER_AXIS_LINE_WIDTH_DEFAULT = 1
export const GRAPHER_AXIS_LINE_WIDTH_THICK = 2

export const GRAPHER_AREA_OPACITY_DEFAULT = 0.8
export const GRAPHER_AREA_OPACITY_MUTE = 0.3
export const GRAPHER_AREA_OPACITY_FOCUS = 1

export const BASE_FONT_SIZE = 16

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ export class FacetChart
const manager = {
...series.manager,
useValueBasedColorScheme,
externalLegendFocusBin: this.legendFocusBin,
externalLegendHoverBin: this.legendHoverBin,
xAxisConfig: {
// For now, sharing an x axis means hiding the tick labels of inner facets.
// This means that none of the x axes are actually hidden (we just don't plot their tick labels).
Expand Down Expand Up @@ -757,15 +757,15 @@ export class FacetChart
return newBins
}

@observable.ref private legendFocusBin: ColorScaleBin | undefined =
@observable.ref private legendHoverBin: ColorScaleBin | undefined =
undefined

@action.bound onLegendMouseOver(bin: ColorScaleBin): void {
this.legendFocusBin = bin
this.legendHoverBin = bin
}

@action.bound onLegendMouseLeave(): void {
this.legendFocusBin = undefined
this.legendHoverBin = undefined
}

// end of legend props
Expand Down
18 changes: 9 additions & 9 deletions packages/@ourworldindata/grapher/src/lineCharts/LineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,9 @@ class Lines extends React.Component<LinesProps> {
"background-line",
series.seriesName
),
stroke: "#ddd",
stroke: series.color,
strokeWidth: 1,
strokeOpacity: 0.3,
})}
</React.Fragment>
))}
Expand Down Expand Up @@ -479,7 +480,6 @@ export class LineChart
if (!ref) return

const mouse = getRelativeMouse(ref, ev)

const boxPadding = isMobile() ? 44 : 25

// expand the box width, so it's easier to see the tooltip for the first & last timepoints
Expand Down Expand Up @@ -550,7 +550,7 @@ export class LineChart

seriesIsBlurred(series: LineChartSeries): boolean {
return (
this.isFocusMode &&
this.isFocusModeActive &&
!this.focusedSeriesNames.includes(series.seriesName)
)
}
Expand Down Expand Up @@ -716,13 +716,14 @@ export class LineChart
const blurred =
this.seriesIsBlurred(series) || point === undefined

const swatch = blurred
const color = blurred
? BLUR_LINE_COLOR
: this.hasColorScale
? darkenColorForLine(
this.getColorScaleColor(point?.colorValue)
)
: series.color
const swatch = { color }

const values = excludeUndefined([
point?.y,
Expand All @@ -746,7 +747,6 @@ export class LineChart
defaultRightPadding = 1

@observable hoveredSeriesName?: SeriesName

@observable private hoverTimer?: NodeJS.Timeout

@action.bound onLineLegendMouseOver(seriesName: SeriesName): void {
Expand All @@ -767,22 +767,22 @@ export class LineChart
}

@computed get focusedSeriesNames(): string[] {
const { externalLegendFocusBin } = this.manager
const { externalLegendHoverBin } = this.manager
const focusedSeriesNames = excludeUndefined([
this.props.manager.entityYearHighlight?.entityName,
this.hoveredSeriesName,
])
if (externalLegendFocusBin) {
if (externalLegendHoverBin) {
focusedSeriesNames.push(
...this.series
.map((s) => s.seriesName)
.filter((name) => externalLegendFocusBin.contains(name))
.filter((name) => externalLegendHoverBin.contains(name))
)
}
return focusedSeriesNames
}

@computed get isFocusMode(): boolean {
@computed get isFocusModeActive(): boolean {
return this.focusedSeriesNames.length > 0
}

Expand Down
17 changes: 11 additions & 6 deletions packages/@ourworldindata/grapher/src/lineLegend/LineLegend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,15 @@ class LineLabels extends React.Component<{
})
}

@computed get textOpacity(): number {
return this.props.isFocus ? 1 : 0.6
}

@computed get textLabels(): React.ReactElement {
return (
<g id={makeIdForHumanConsumption("text-labels")}>
{this.markers.map(({ series, labelText }, index) => {
const textColor = this.props.isFocus
? darkenColorForText(series.color)
: "#ddd"
const textColor = darkenColorForText(series.color)
return (
<React.Fragment
key={getSeriesKey(
Expand All @@ -138,7 +140,10 @@ class LineLabels extends React.Component<{
)}
>
{series.textWrap.render(labelText.x, labelText.y, {
textProps: { fill: textColor },
textProps: {
fill: textColor,
opacity: this.textOpacity,
},
})}
</React.Fragment>
)
Expand All @@ -155,7 +160,6 @@ class LineLabels extends React.Component<{
return (
<g id={makeIdForHumanConsumption("text-annotations")}>
{markersWithAnnotations.map(({ series, labelText }, index) => {
const annotationColor = this.props.isFocus ? "#333" : "#ddd"
return (
<React.Fragment
key={getSeriesKey(
Expand All @@ -169,7 +173,8 @@ class LineLabels extends React.Component<{
labelText.y + series.textWrap.height,
{
textProps: {
fill: annotationColor,
fill: "#333",
opacity: this.textOpacity,
style: { fontWeight: 300 },
},
}
Expand Down
Loading

0 comments on commit 8d5104d

Please sign in to comment.