Skip to content
Snippets Groups Projects
Unverified Commit 74cfb332 authored by shaun's avatar shaun Committed by GitHub
Browse files

fix funnel tooltip artifacts in safari (#31494)


* fix funnel tooltip artifacts in safari

* force composite-layer instead of forceRedraw

* used styled components

---------

Co-authored-by: default avatarAleksandr Lesnenko <alxnddr@gmail.com>
parent 6ede838b
Branches
Tags
No related merge requests found
......@@ -14,6 +14,11 @@ function parseQueryStringOptions(s) {
return options;
}
export function isDesktopSafari() {
// from: https://stackoverflow.com/a/42189492/142317
return "safari" in window;
}
export function parseHashOptions(hash) {
return parseQueryStringOptions(hash.replace(/^#/, ""));
}
......
:local .Funnel {
color: var(--color-text-medium);
}
:local .FunnelStep {
width: 100%;
min-width: 20px;
border-right: 1px solid var(--color-border);
}
:local .FunnelStep.Initial {
min-width: unset;
width: unset;
}
/* Display information for the initial blox */
:local .Start {
display: flex;
justify-content: center;
flex-direction: column;
text-align: right;
flex-grow: 1;
padding-right: 0.5em;
font-size: 24px;
}
:local .Start .Title {
font-weight: bold;
color: black;
}
:local .Start .Subtitle {
font-size: 0.6875em;
}
/* Head information */
:local .Head {
text-align: right;
padding: 0.5em;
min-width: 0;
}
/* Plot graph element */
:local .Graph {
flex-grow: 1;
}
/* Information at the end of the step */
:local .Infos {
text-align: right;
padding: 0.5em 0.5em 0 0.5em;
font-size: 16px;
}
:local .Infos .Subtitle {
font-size: 0.6875em;
margin-top: 1em;
}
/* Narrow version */
:local .Funnel--narrow .Head {
font-size: 12px;
}
:local .Funnel--narrow .Infos {
font-size: 12px;
}
:local .Funnel--narrow .Infos .Subtitle {
font-size: 0.875em;
}
:local .Funnel--narrow .Start .Title {
font-size: 0.75em;
}
:local .Funnel--narrow .Start .Subtitle {
font-size: 0.5em;
}
......@@ -9,7 +9,15 @@ import { getFriendlyName } from "metabase/visualizations/lib/utils";
import { findSeriesByKey } from "metabase/visualizations/lib/series";
import { color } from "metabase/lib/colors";
import styles from "./FunnelNormal.css";
import {
FunnelNormalRoot,
FunnelStart,
FunnelStep,
Head,
Info,
Subtitle,
Title,
} from "metabase/visualizations/components/FunnelNormal.styled";
export default class FunnelNormal extends Component {
render() {
......@@ -121,52 +129,38 @@ export default class FunnelNormal extends Component {
const isClickable = visualizationIsClickable(infos[0].clicked);
return (
<div
<FunnelNormalRoot
className={className}
isSmall={isSmall}
data-testid="funnel-chart"
className={cx(className, styles.Funnel, "flex", {
[styles["Funnel--narrow"]]: isNarrow,
p1: isSmall,
p2: !isSmall,
})}
>
<div
className={cx(styles.FunnelStep, styles.Initial, "flex flex-column")}
>
<Ellipsified
className={styles.Head}
data-testid="funnel-chart-header"
>
{formatDimension(rows[0][dimensionIndex])}
</Ellipsified>
<div className={styles.Start}>
<div className={styles.Title}>
{formatMetric(rows[0][metricIndex])}
</div>
<div className={styles.Subtitle}>
{getFriendlyName(cols[metricIndex])}
</div>
</div>
<FunnelStep isFirst>
<Head isNarrow={isNarrow}>
<Ellipsified data-testid="funnel-chart-header">
{formatDimension(rows[0][dimensionIndex])}
</Ellipsified>
</Head>
<FunnelStart isNarrow={isNarrow}>
<Title>{formatMetric(rows[0][metricIndex])}</Title>
<Subtitle>{getFriendlyName(cols[metricIndex])}</Subtitle>
</FunnelStart>
{/* This part of code in used only to share height between .Start and .Graph columns. */}
<div className={styles.Infos}>
<div className={styles.Title}>&nbsp;</div>
<div className={styles.Subtitle}>&nbsp;</div>
</div>
</div>
<Info isNarrow={isNarrow}>
<Title>&nbsp;</Title>
<Subtitle>&nbsp;</Subtitle>
</Info>
</FunnelStep>
{infos.slice(1).map((info, index) => {
const stepPercentage =
initial.value > 0 ? info.value / initial.value : 0;
return (
<div
key={index}
className={cx(styles.FunnelStep, "flex flex-column")}
>
<Ellipsified
className={styles.Head}
data-testid="funnel-chart-header"
>
{formatDimension(rows[index + 1][dimensionIndex])}
</Ellipsified>
<FunnelStep key={index}>
<Head isNarrow={isNarrow}>
<Ellipsified data-testid="funnel-chart-header">
{formatDimension(rows[index + 1][dimensionIndex])}
</Ellipsified>
</Head>
<GraphSection
className={cx({ "cursor-pointer": isClickable })}
index={index}
......@@ -176,18 +170,20 @@ export default class FunnelNormal extends Component {
onHoverChange={onHoverChange}
onVisualizationClick={isClickable ? onVisualizationClick : null}
/>
<div className={styles.Infos}>
<Ellipsified className={styles.Title}>
{formatPercent(stepPercentage)}
</Ellipsified>
<Ellipsified className={styles.Subtitle}>
{formatMetric(rows[index + 1][metricIndex])}
</Ellipsified>
</div>
</div>
<Info isNarrow={isNarrow}>
<Title>
<Ellipsified>{formatPercent(stepPercentage)}</Ellipsified>
</Title>
<Subtitle>
<Ellipsified>
{formatMetric(rows[index + 1][metricIndex])}
</Ellipsified>
</Subtitle>
</Info>
</FunnelStep>
);
})}
</div>
</FunnelNormalRoot>
);
}
}
......
import styled from "@emotion/styled";
import { css } from "@emotion/react";
import { color } from "metabase/lib/colors";
import { isDesktopSafari } from "metabase/lib/browser";
interface SharedProps {
isNarrow: boolean;
}
export const Title = styled.div``;
export const Subtitle = styled.div``;
interface FunnelStepProps {
isFirst?: boolean;
}
export const FunnelStep = styled.div<FunnelStepProps>`
width: 100%;
min-width: 20px;
border-right: 1px solid ${color("border")};
display: flex;
flex-direction: column;
${props =>
props.isFirst
? css`
min-width: unset;
width: unset;
`
: null}
`;
export const Head = styled.div<SharedProps>`
text-align: right;
padding: 0.5em;
min-width: 0;
${props =>
props.isNarrow
? css`
font-size: 12px;
`
: null}
`;
export const Info = styled.div<SharedProps>`
text-align: right;
padding: 0.5em 0.5em 0 0.5em;
font-size: ${props => (props.isNarrow ? "12px" : "16px")};
${Subtitle} {
font-size: ${props => (props.isNarrow ? "0.875em" : "0.6875em")};
margin-top: 1em;
}
`;
export const FunnelStart = styled.div<SharedProps>`
display: flex;
justify-content: center;
flex-direction: column;
text-align: right;
flex-grow: 1;
padding-right: 0.5em;
font-size: 24px;
${Title} {
font-weight: bold;
color: black;
${props =>
props.isNarrow
? css`
font-size: 0.75em;
`
: null}
}
${Subtitle} {
font-size: 0.6875em;
${props =>
props.isNarrow
? css`
font-size: 0.5em;
`
: null}
}
`;
interface FunnelNormalRootProps {
isNarrow: boolean;
isSmall: boolean;
}
export const FunnelNormalRoot = styled.div<FunnelNormalRootProps>`
display: flex;
padding: ${props => (props.isSmall ? "0.5rem" : "1rem")};
color: ${color("text-medium")};
${isDesktopSafari()
? css`
will-change: transform;
`
: null}
`;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment