Skip to content

Commit

Permalink
🎉 (static charts) add output channel for social media
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiamersmann committed Oct 4, 2024
1 parent 16f0fdf commit 1f10da4
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,10 @@ export class DiscreteBarChart
opacity={GRAPHER_AREA_OPACITY_DEFAULT}
style={{ transition: "height 200ms ease" }}
/>
<Halo id={series.seriesName + "-label"}>
<Halo
id={series.seriesName + "-label"}
background={this.manager.backgroundColor}
>
<text
x={0}
y={0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
Patterns,
STATIC_EXPORT_DETAIL_SPACING,
DEFAULT_GRAPHER_FRAME_PADDING,
GRAPHER_BACKGROUND_DEFAULT,
} from "../core/GrapherConstants"
import { MapChartManager } from "../mapCharts/MapChartConstants"
import { ChartManager } from "../chart/ChartManager"
Expand All @@ -36,6 +37,7 @@ import {
FacetStrategy,
GrapherTabOption,
RelatedQuestionsConfig,
Color,
} from "@ourworldindata/types"
import { DataTable, DataTableManager } from "../dataTable/DataTable"
import {
Expand Down Expand Up @@ -66,12 +68,13 @@ export interface CaptionedChartManager
staticBounds?: Bounds
staticBoundsWithDetails?: Bounds

// layout
// layout & style
isSmall?: boolean
isMedium?: boolean
framePaddingHorizontal?: number
framePaddingVertical?: number
fontSize?: number
backgroundColor?: string

// state
tab?: GrapherTabOption
Expand All @@ -80,6 +83,7 @@ export interface CaptionedChartManager
type: ChartTypeName
typeExceptWhenLineChartAndSingleTimeThenWillBeBarChart?: ChartTypeName
showEntitySelectionToggle?: boolean
isExportingForSocialMedia?: boolean

// timeline
hasTimeline?: boolean
Expand Down Expand Up @@ -403,7 +407,12 @@ export class CaptionedChart extends React.Component<CaptionedChartProps> {
// #5 Footer
// #6 [Related question]
return (
<div className="CaptionedChart">
<div
className="CaptionedChart"
style={{
backgroundColor: this.backgroundColor,
}}
>
{/* #1 Header */}
<Header manager={this.manager} maxWidth={this.maxWidth} />
<VerticalSpace height={this.verticalPadding} />
Expand Down Expand Up @@ -435,6 +444,10 @@ export class CaptionedChart extends React.Component<CaptionedChartProps> {
)
}

@computed protected get backgroundColor(): Color {
return this.manager.backgroundColor ?? GRAPHER_BACKGROUND_DEFAULT
}

@computed protected get svgProps(): React.SVGProps<SVGSVGElement> {
return {
xmlns: "http://www.w3.org/2000/svg",
Expand All @@ -443,7 +456,8 @@ export class CaptionedChart extends React.Component<CaptionedChartProps> {
fontFamily:
"Lato, 'Helvetica Neue', Helvetica, Arial, 'Liberation Sans', sans-serif",
fontSize: this.manager.fontSize ?? BASE_FONT_SIZE,
backgroundColor: "white",
// needs to be set here or else pngs will have a black background
backgroundColor: this.backgroundColor,
textRendering: "geometricPrecision",
WebkitFontSmoothing: "antialiased",
},
Expand Down Expand Up @@ -571,13 +585,15 @@ export class StaticCaptionedChart extends CaptionedChart {
>
{this.fonts}
{this.patterns}
<rect
id={makeIdForHumanConsumption("background")}
className="background-fill"
fill="white"
width={width}
height={height}
/>
{!this.manager.isExportingForSocialMedia && (
<rect
id={makeIdForHumanConsumption("background")}
className="background-fill"
fill={this.backgroundColor}
width={width}
height={height}
/>
)}
<StaticHeader
manager={manager}
maxWidth={maxWidth}
Expand Down
3 changes: 3 additions & 0 deletions packages/@ourworldindata/grapher/src/chart/ChartManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ColorSchemeName,
EntityName,
DetailsMarker,
Color,
} from "@ourworldindata/types"
import { TooltipManager } from "../tooltip/TooltipProps"
import { OwidTable, CoreColumn } from "@ourworldindata/core-table"
Expand Down Expand Up @@ -95,7 +96,9 @@ export interface ChartManager {
isStatic?: boolean
isSemiNarrow?: boolean
isStaticAndSmall?: boolean
isExportingForSocialMedia?: boolean
secondaryColorInStaticCharts?: string
backgroundColor?: Color

detailsOrderedByReference?: string[]
detailsMarkerInSvg?: DetailsMarker
Expand Down
20 changes: 19 additions & 1 deletion packages/@ourworldindata/grapher/src/core/Grapher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ import {
DetailDictionary,
GrapherWindowType,
MultiDimDataPageProps,
Color,
} from "@ourworldindata/types"
import {
BlankOwidTable,
Expand All @@ -126,6 +127,8 @@ import {
GRAPHER_LOADED_EVENT_NAME,
isContinentsVariableId,
isPopulationVariableETLPath,
GRAPHER_BACKGROUND_BEIGE,
GRAPHER_BACKGROUND_DEFAULT,
} from "../core/GrapherConstants"
import { defaultGrapherConfig } from "../schema/defaultGrapherConfig"
import { loadVariableDataAndMetadata } from "./loadVariable"
Expand Down Expand Up @@ -851,6 +854,7 @@ export class Grapher

@observable.ref renderToStatic = false
@observable.ref isExportingToSvgOrPng = false
@observable.ref isSocialMediaExport = false

tooltips?: TooltipManager["tooltips"] = observable.map({}, { deep: false })
@observable isPlaying = false
Expand Down Expand Up @@ -2896,10 +2900,24 @@ export class Grapher
return staticPixelCount < 0.66 * idealPixelCount
}

@computed get secondaryColorInStaticCharts(): string {
@computed get secondaryColorInStaticCharts(): Color {
return this.isStaticAndSmall ? GRAPHER_LIGHT_TEXT : GRAPHER_DARK_TEXT
}

@computed get isExportingForSocialMedia(): boolean {
return (
this.isExportingToSvgOrPng &&
this.isStaticAndSmall &&
this.isSocialMediaExport
)
}

@computed get backgroundColor(): Color {
return this.isExportingForSocialMedia
? GRAPHER_BACKGROUND_BEIGE
: GRAPHER_BACKGROUND_DEFAULT
}

// Binds chart properties to global window title and URL. This should only
// ever be invoked from top-level JavaScript.
private bindToWindow(): void {
Expand Down
3 changes: 3 additions & 0 deletions packages/@ourworldindata/grapher/src/core/GrapherConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export const DEFAULT_GRAPHER_HEIGHT = 600
export const DEFAULT_GRAPHER_FRAME_PADDING = 16
export const STATIC_EXPORT_DETAIL_SPACING = 8

export const GRAPHER_BACKGROUND_DEFAULT = "#ffffff"
export const GRAPHER_BACKGROUND_BEIGE = "#fffbf5"

export const GRAPHER_DARK_TEXT = "#5b5b5b"
export const GRAPHER_LIGHT_TEXT = "#858585"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ export class FacetChart
startTime,
endTime,
missingDataStrategy,
backgroundColor,
} = manager

// Use compact labels, e.g. 50k instead of 50,000.
Expand Down Expand Up @@ -316,6 +317,7 @@ export class FacetChart
startTime,
endTime,
missingDataStrategy,
backgroundColor,
...series.manager,
xAxisConfig: {
...globalXAxisConfig,
Expand Down
12 changes: 11 additions & 1 deletion packages/@ourworldindata/grapher/src/halo/Halo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react"
import { Color } from "@ourworldindata/types"

const defaultHaloStyle: React.CSSProperties = {
fill: "#fff",
Expand All @@ -12,10 +13,19 @@ const defaultHaloStyle: React.CSSProperties = {
export function Halo(props: {
id: React.Key
children: React.ReactElement
background?: Color
style?: React.CSSProperties
}): React.ReactElement {
const defaultStyle = {
...defaultHaloStyle,
fill: props.background ?? defaultHaloStyle.fill,
stroke: props.background ?? defaultHaloStyle.stroke,
}
const halo = React.cloneElement(props.children, {
style: { ...defaultHaloStyle, ...props.style },
style: {
...defaultStyle,
...props.style,
},
})
return (
<React.Fragment key={props.id}>
Expand Down
23 changes: 17 additions & 6 deletions packages/@ourworldindata/grapher/src/lineCharts/LineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
GRAPHER_AXIS_LINE_WIDTH_THICK,
GRAPHER_AXIS_LINE_WIDTH_DEFAULT,
BASE_FONT_SIZE,
GRAPHER_BACKGROUND_DEFAULT,
} from "../core/GrapherConstants"
import { ColorSchemes } from "../color/ColorSchemes"
import { AxisConfig, AxisManager } from "../axis/AxisConfig"
Expand Down Expand Up @@ -101,8 +102,6 @@ import {
HorizontalNumericColorLegend,
} from "../horizontalColorLegend/HorizontalColorLegends"

// background
const BACKGROUND_COLOR = "#fff"
// line color
const BLUR_LINE_COLOR = "#eee"
const DEFAULT_LINE_COLOR = "#000"
Expand Down Expand Up @@ -207,7 +206,9 @@ class Lines extends React.Component<LinesProps> {
"outline",
series.seriesName
),
stroke: BACKGROUND_COLOR,
stroke:
this.props.backgroundColor ??
GRAPHER_BACKGROUND_DEFAULT,
strokeWidth:
this.strokeWidth +
this.lineOutlineWidth * 2,
Expand Down Expand Up @@ -585,7 +586,10 @@ export class LineChart
)
: series.color
}
stroke="#fff"
stroke={
this.manager.backgroundColor ??
GRAPHER_BACKGROUND_DEFAULT
}
strokeWidth={0.5}
/>
)
Expand Down Expand Up @@ -854,7 +858,9 @@ export class LineChart
const lineWidth = manager.isStaticAndSmall
? GRAPHER_AXIS_LINE_WIDTH_THICK
: GRAPHER_AXIS_LINE_WIDTH_DEFAULT
const dashPattern = manager.isStaticAndSmall ? "7, 7" : undefined
const dashPattern = manager.isExportingForSocialMedia
? "7, 7"
: undefined

return (
<DualAxisComponent
Expand Down Expand Up @@ -887,6 +893,7 @@ export class LineChart
dualAxis={this.dualAxis}
comparisonLine={line}
baseFontSize={this.fontSize}
backgroundColor={this.manager.backgroundColor}
/>
))}
{manager.showLegend && <LineLegend manager={this} />}
Expand All @@ -898,6 +905,7 @@ export class LineChart
focusedSeriesNames={this.focusedSeriesNames}
lineStrokeWidth={this.lineStrokeWidth}
lineOutlineWidth={this.lineOutlineWidth}
backgroundColor={this.manager.backgroundColor}
markerRadius={this.markerRadius}
isStatic={manager.isStatic}
/>
Expand Down Expand Up @@ -1067,11 +1075,14 @@ export class LineChart
}

numericBinSize = 6
numericBinStroke = BACKGROUND_COLOR
numericBinStrokeWidth = 1
legendTextColor = "#555"
legendTickSize = 1

@computed get numericBinStroke(): Color {
return this.manager.backgroundColor ?? GRAPHER_BACKGROUND_DEFAULT
}

@computed get numericLegend(): HorizontalNumericColorLegend | undefined {
return this.hasColorScale && this.manager.showLegend
? new HorizontalNumericColorLegend({ manager: this })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface LinesProps {
markerRadius?: number
isStatic?: boolean
multiColor?: boolean
backgroundColor?: string
}

export interface LineChartManager extends ChartManager {
Expand Down
39 changes: 37 additions & 2 deletions packages/@ourworldindata/grapher/src/modal/DownloadModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export interface DownloadModalManager {
isOnChartOrMapTab?: boolean
framePaddingVertical?: number
showAdminControls?: boolean
isSocialMediaExport?: boolean
}

interface DownloadModalProps {
Expand All @@ -63,6 +64,10 @@ export class DownloadModal extends React.Component<DownloadModalProps> {
return this.manager.staticFormat === GrapherStaticFormat.square
}

@computed private get isSocialMediaExport(): boolean {
return this.manager.isSocialMediaExport ?? false
}

@computed private get shouldIncludeDetails(): boolean {
return !!this.manager.shouldIncludeDetailsInStaticExport
}
Expand Down Expand Up @@ -204,6 +209,10 @@ export class DownloadModal extends React.Component<DownloadModalProps> {
: GrapherStaticFormat.square
}

@action.bound private toggleExportForUseInSocialMedia(): void {
this.manager.isSocialMediaExport = !this.isSocialMediaExport
}

@action.bound private toggleIncludeDetails(): void {
this.manager.shouldIncludeDetailsInStaticExport =
!this.manager.shouldIncludeDetailsInStaticExport
Expand Down Expand Up @@ -295,11 +304,37 @@ export class DownloadModal extends React.Component<DownloadModalProps> {
<Checkbox
checked={this.isExportingSquare}
label="Square format"
onChange={(): void => {
onChange={action((): void => {
this.reset()
this.toggleExportFormat()

if (!this.isExportingSquare) {
this.manager.isSocialMediaExport =
false
}

this.export()
}}
})}
/>
)}
{this.manager.showAdminControls && (
<Checkbox
checked={this.isSocialMediaExport}
label="For use in social media (internal)"
onChange={action((): void => {
this.reset()
this.toggleExportForUseInSocialMedia()

// set reasonable defaults for social media exports
if (this.isSocialMediaExport) {
this.manager.staticFormat =
GrapherStaticFormat.square
this.manager.shouldIncludeDetailsInStaticExport =
false
}

this.export()
})}
/>
)}
</div>
Expand Down
Loading

0 comments on commit 1f10da4

Please sign in to comment.