Updated Funnel report component.

This commit is contained in:
Mike Cao 2024-02-23 20:31:35 -08:00
parent 2832ff9622
commit f81f0839c6
7 changed files with 169 additions and 116 deletions

View file

@ -1,83 +1,57 @@
import { JSX, useCallback, useContext, useMemo } from 'react';
import { Loading, StatusLight } from 'react-basics';
import { useMessages, useTheme } from 'components/hooks';
import BarChart from 'components/metrics/BarChart';
import { formatLongNumber } from 'lib/format';
import { useContext } from 'react';
import classNames from 'classnames';
import { useMessages } from 'components/hooks';
import { ReportContext } from '../[reportId]/Report';
import styles from './FunnelChart.module.css';
import { formatLongNumber } from 'lib/format';
export interface FunnelChartProps {
className?: string;
isLoading?: boolean;
}
export function FunnelChart({ className, isLoading }: FunnelChartProps) {
export function FunnelChart({ className }: FunnelChartProps) {
const { report } = useContext(ReportContext);
const { formatMessage, labels } = useMessages();
const { colors } = useTheme();
const { parameters, data } = report || {};
const renderXLabel = useCallback(
(label: string, index: number) => {
return parameters.urls[index];
},
[parameters],
);
const renderTooltipPopup = useCallback(
(
setTooltipPopup: (arg0: JSX.Element) => void,
model: { tooltip: { opacity: any; labelColors: any; dataPoints: any } },
) => {
const { opacity, labelColors, dataPoints } = model.tooltip;
if (!dataPoints?.length || !opacity) {
setTooltipPopup(null);
return;
}
setTooltipPopup(
<>
<div>
{formatLongNumber(dataPoints[0].raw.y)} {formatMessage(labels.visitors)}
</div>
<div>
<StatusLight color={labelColors?.[0]?.backgroundColor}>
{formatLongNumber(dataPoints[0].raw.z)}% {formatMessage(labels.dropoff)}
</StatusLight>
</div>
</>,
);
},
[],
);
const datasets = useMemo(() => {
return [
{
label: formatMessage(labels.uniqueVisitors),
data: data,
borderWidth: 1,
...colors.chart.visitors,
},
];
}, [data, colors, formatMessage, labels]);
if (isLoading) {
return <Loading icon="dots" className={styles.loading} />;
}
const { data } = report || {};
return (
<BarChart
className={className}
datasets={datasets}
unit="day"
isLoading={isLoading}
renderXLabel={renderXLabel}
renderTooltipPopup={renderTooltipPopup}
XAxisType="category"
/>
<div className={classNames(styles.chart, className)}>
{data?.map(({ url, visitors, dropped, dropoff, remaining }, index: number) => {
return (
<div key={url} className={styles.step}>
<div className={styles.num}>{index + 1}</div>
<div className={styles.card}>
<div className={styles.header}>
<span className={styles.label}>{formatMessage(labels.viewedPage)}:</span>
<span className={styles.item}>{url}</span>
</div>
<div className={styles.track}>
<div className={styles.bar} style={{ width: `${remaining * 100}%` }}>
<span className={styles.value}>
{remaining > 0.1 && `${(remaining * 100).toFixed(2)}%`}
</span>
</div>
</div>
<div className={styles.info}>
<div>
<b>{formatLongNumber(visitors)}</b>
<span> {formatMessage(labels.visitors)}</span>
<span> ({(remaining * 100).toFixed(2)}%)</span>
</div>
{dropoff > 0 && (
<div>
<b>{formatLongNumber(dropped)}</b> {formatMessage(labels.visitorsDroppedOff)} (
{(dropoff * 100).toFixed(2)}%)
</div>
)}
</div>
</div>
</div>
);
})}
</div>
);
}