Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔨 (grapher) refactor mobile full width mode for embedded graphers #3243

Merged
merged 2 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions explorer/Explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ export interface ExplorerProps extends SerializedGridProgram {
isPreview?: boolean
canonicalUrl?: string
selection?: SelectionArray
shouldOptimizeForHorizontalSpace?: boolean // only relevant for explorers with hidden controls
}

const renderLivePreviewVersion = (props: ExplorerProps) => {
Expand Down Expand Up @@ -213,17 +212,6 @@ export class Explorer
this.setGrapher(this.grapherRef!.current!)
this.updateGrapherFromExplorer()

// Optimizing for horizontal space makes only sense if the controls are hidden
// and the explorer in fact looks like an ordinary grapher chart.
// Since switching between charts is not possible when the controls are hidden,
// we only need to run this code once.
if (
this.queryParams.hideControls &&
this.props.shouldOptimizeForHorizontalSpace
) {
this.grapher!.shouldOptimizeForHorizontalSpace = true
}

let url = Url.fromQueryParams(this.initialQueryParams)

if (this.props.selection?.hasSelection) {
Expand Down
1 change: 0 additions & 1 deletion explorer/ExplorerConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export const EMBEDDED_EXPLORER_PARTIAL_GRAPHER_CONFIGS =
"\n//EMBEDDED_PARTIAL_EXPLORER_GRAPHER_CONFIGS\n"

export const EXPLORER_EMBEDDED_FIGURE_SELECTOR = "data-explorer-src"
export const EXPLORER_EMBEDDED_FIGURE_PROPS_ATTR = "data-explorer-props"

export const ExplorerContainerId = "ExplorerContainer"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,3 @@ $controlRowHeight: 32px; // keep in sync with CONTROLS_ROW_HEIGHT
vertical-align: unset;
}
}

// when embedded in an owid page and viewed on a narrow screen,
// grapher bleeds onto the edges horizontally and the top and bottom borders
// stretch across the entire page. the top border of the related question element
// should do the same.
&.GrapherComponent.optimizeForHorizontalSpace .relatedQuestion {
border-top: 0;

// adds a top border that stretches across the entire page.
// since we don't know the width of the page, we use a large number (200vw)
// and offset it by another large number (-50vw) to make sure the border
// stretches across the entire page.
&::before {
content: "";
position: absolute;
left: -50vw;
height: 1px;
width: 200vw;
background: $frame-color;
top: 0;
}
}
20 changes: 1 addition & 19 deletions packages/@ourworldindata/grapher/src/core/Grapher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ export interface GrapherProgrammaticInterface extends GrapherInterface {
bindUrlToWindow?: boolean
isEmbeddedInAnOwidPage?: boolean
isEmbeddedInADataPage?: boolean
shouldOptimizeForHorizontalSpace?: boolean

manager?: GrapherManager
instanceRef?: React.RefObject<Grapher>
Expand Down Expand Up @@ -460,19 +459,6 @@ export class Grapher
isEmbeddedInAnOwidPage?: boolean = this.props.isEmbeddedInAnOwidPage
isEmbeddedInADataPage?: boolean = this.props.isEmbeddedInADataPage

// if true, grapher bleeds onto the edges horizontally and the left and right borders
// are removed while the top and bottom borders stretch across the entire page
@observable shouldOptimizeForHorizontalSpace = false

@computed private get optimizeForHorizontalSpace(): boolean {
return (
this.isNarrow &&
this.shouldOptimizeForHorizontalSpace &&
// in full-screen mode, we prefer padding on the sides
!this.isInFullScreenMode
)
}

/**
* todo: factor this out and make more RAII.
*
Expand Down Expand Up @@ -2517,7 +2503,6 @@ export class Grapher
GrapherPortraitClass: this.isPortrait,
isStatic: this.isStatic,
isExportingToSvgOrPng: this.isExportingToSvgOrPng,
optimizeForHorizontalSpace: this.optimizeForHorizontalSpace,
GrapherComponentNarrow: this.isNarrow,
GrapherComponentSemiNarrow: this.isSemiNarrow,
GrapherComponentSmall: this.isSmall,
Expand Down Expand Up @@ -2648,11 +2633,8 @@ export class Grapher
return this.props.baseFontSize ?? this.baseFontSize
}

// when optimized for horizontal screen, grapher bleeds onto the edges horizontally
@computed get framePaddingHorizontal(): number {
return this.optimizeForHorizontalSpace
? 0
: DEFAULT_GRAPHER_FRAME_PADDING
return DEFAULT_GRAPHER_FRAME_PADDING
}

@computed get framePaddingVertical(): number {
Expand Down
29 changes: 0 additions & 29 deletions packages/@ourworldindata/grapher/src/core/grapher.scss
Original file line number Diff line number Diff line change
Expand Up @@ -173,35 +173,6 @@ $zindex-controls-drawer: 140;
padding: 0 !important;
}

// when optimized for horizontal space, grapher bleeds onto the edges horizontally
// and the left and right borders are hidden. the top and bottom borders are visible,
// but stretch across the entire page.
.GrapherComponent.optimizeForHorizontalSpace {
border: none;

// adds top and bottom borders that stretch across the entire page.
// since we don't know the width of the page, we use a large number (200vw)
// and offset it by another large number (-50vw) to make sure the borders
// stretch across the entire page.
&::before,
&::after {
content: "";
position: absolute;
left: -50vw;
height: 1px;
width: 200vw;
background: $frame-color;
}

&::before {
top: 0;
}

&::after {
bottom: 0;
}
}

.Tooltip {
z-index: $zindex-Tooltip;
}
Expand Down
1 change: 1 addition & 0 deletions site/gdocs/components/ArticleBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ export default function ArticleBlock({
<Chart
className={getLayout(layoutSubtype, containerType)}
d={block}
fullWidthOnMobile={true}
/>
)
})
Expand Down
8 changes: 8 additions & 0 deletions site/gdocs/components/Chart.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ figure.explorer {
div.margin-0 figure {
margin: 0;
}

@include sm-only {
.full-width-on-mobile {
width: auto;
margin-left: calc(-1 * var(--grid-gap));
margin-right: calc(-1 * var(--grid-gap));
}
}
28 changes: 6 additions & 22 deletions site/gdocs/components/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@ import {
} from "@ourworldindata/utils"
import { renderSpans, useLinkedChart } from "../utils.js"
import cx from "classnames"
import { ExplorerProps } from "../../../explorer/Explorer.js"

export default function Chart({
d,
className,
shouldOptimizeForHorizontalSpace = true,
fullWidthOnMobile = false,
}: {
d: EnrichedBlockChart
className?: string
shouldOptimizeForHorizontalSpace?: boolean
fullWidthOnMobile?: boolean
}) {
const refChartContainer = useRef<HTMLDivElement>(null)
useEmbedChart(0, refChartContainer)
Expand All @@ -42,18 +41,6 @@ export default function Chart({
const isExplorer = url.isExplorer
const hasControls = url.queryParams.hideControls !== "true"

// applies to both charts and explorers
const common = {
// On mobile, we optimize for horizontal space by having Grapher bleed onto the edges horizontally
shouldOptimizeForHorizontalSpace,
}

// props passed to explorers
const explorerProps: Pick<
ExplorerProps,
"shouldOptimizeForHorizontalSpace"
> = merge({}, common)

// config passed to grapher charts
let customizedChartConfig: GrapherProgrammaticInterface = {}
const isCustomized = d.title || d.subtitle
Expand Down Expand Up @@ -92,11 +79,13 @@ export default function Chart({
}
}

const chartConfig = merge({}, customizedChartConfig, common)
const chartConfig = customizedChartConfig

return (
<div
className={cx(d.position, className)}
className={cx(d.position, className, {
"full-width-on-mobile": fullWidthOnMobile,
})}
style={{ gridRow: d.row, gridColumn: d.column }}
ref={refChartContainer}
>
Expand All @@ -109,11 +98,6 @@ export default function Chart({
isExplorer ? undefined : JSON.stringify(chartConfig)
}
data-explorer-src={isExplorer ? resolvedUrl : undefined}
data-explorer-props={
isExplorer && !hasControls
? JSON.stringify(explorerProps)
: undefined
}
style={{
width: "100%",
border: "0px none",
Expand Down
1 change: 0 additions & 1 deletion site/gdocs/components/KeyIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export default function KeyIndicator({
type: "chart",
parseErrors: [],
}}
shouldOptimizeForHorizontalSpace={false}
/>
<a
className="datapage-link datapage-link-mobile col-start-1 span-cols-12"
Expand Down
7 changes: 6 additions & 1 deletion site/gdocs/components/KeyInsights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ export const KeyInsights = ({
)
}
if (url) {
return <Chart d={{ url, type: "chart", parseErrors: [] }} />
return (
<Chart
d={{ url, type: "chart", parseErrors: [] }}
fullWidthOnMobile={true}
/>
)
}

return null
Expand Down
8 changes: 0 additions & 8 deletions site/multiembedder/MultiEmbedder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
EMBEDDED_EXPLORER_DELIMITER,
EMBEDDED_EXPLORER_GRAPHER_CONFIGS,
EMBEDDED_EXPLORER_PARTIAL_GRAPHER_CONFIGS,
EXPLORER_EMBEDDED_FIGURE_PROPS_ATTR,
EXPLORER_EMBEDDED_FIGURE_SELECTOR,
} from "../../explorer/ExplorerConstants.js"
import {
Expand Down Expand Up @@ -164,12 +163,6 @@ class MultiEmbedder {
const html = await fetchText(fullUrl)

if (isExplorer) {
const explorerPropsAttr = figure.getAttribute(
EXPLORER_EMBEDDED_FIGURE_PROPS_ATTR
)
const localProps = explorerPropsAttr
? JSON.parse(explorerPropsAttr)
: {}
let grapherConfigs = deserializeJSONFromHTML(
html,
EMBEDDED_EXPLORER_GRAPHER_CONFIGS
Expand Down Expand Up @@ -197,7 +190,6 @@ class MultiEmbedder {
const props: ExplorerProps = {
...common,
...deserializeJSONFromHTML(html, EMBEDDED_EXPLORER_DELIMITER),
...localProps,
grapherConfigs,
partialGrapherConfigs,
queryStr,
Expand Down
Loading