umami/src/app/(main)/reports/funnel/FunnelChart.tsx

57 lines
2.0 KiB
TypeScript
Raw Normal View History

2024-02-24 05:31:35 +01:00
import { useContext } from 'react';
import classNames from 'classnames';
import { useMessages } from 'components/hooks';
2024-02-06 09:38:33 +01:00
import { ReportContext } from '../[reportId]/Report';
2024-02-24 05:31:35 +01:00
import { formatLongNumber } from 'lib/format';
2024-04-03 08:30:12 +02:00
import styles from './FunnelChart.module.css';
2023-12-03 12:07:03 +01:00
export interface FunnelChartProps {
className?: string;
isLoading?: boolean;
}
2023-05-18 20:17:35 +02:00
2024-02-24 05:31:35 +01:00
export function FunnelChart({ className }: FunnelChartProps) {
const { report } = useContext(ReportContext);
2023-05-18 20:17:35 +02:00
const { formatMessage, labels } = useMessages();
2024-02-24 05:31:35 +01:00
const { data } = report || {};
2023-05-18 20:17:35 +02:00
return (
2024-02-24 05:31:35 +01:00
<div className={classNames(styles.chart, className)}>
2024-04-03 08:30:12 +02:00
{data?.map(({ type, value, visitors, dropped, dropoff, remaining }, index: number) => {
2024-02-24 05:31:35 +01:00
return (
2024-04-03 08:30:12 +02:00
<div key={index} className={styles.step}>
2024-02-24 05:31:35 +01:00
<div className={styles.num}>{index + 1}</div>
<div className={styles.card}>
<div className={styles.header}>
2024-04-03 08:30:12 +02:00
<span className={styles.label}>
2024-04-03 08:53:08 +02:00
{formatMessage(type === 'url' ? labels.viewedPage : labels.triggeredEvent)}
2024-04-03 08:30:12 +02:00
</span>
<span className={styles.item}>{value}</span>
2024-02-24 05:31:35 +01:00
</div>
2024-04-03 08:30:12 +02:00
<div className={styles.metric}>
2024-02-24 05:31:35 +01:00
<div>
2024-04-03 08:30:12 +02:00
<span className={styles.visitors}>{formatLongNumber(visitors)}</span>
{formatMessage(labels.visitors)}
2024-02-24 05:31:35 +01:00
</div>
2024-04-03 08:30:12 +02:00
<div className={styles.percent}>{(remaining * 100).toFixed(2)}%</div>
</div>
<div className={styles.track}>
<div className={styles.bar} style={{ width: `${remaining * 100}%` }}></div>
2024-02-24 05:31:35 +01:00
</div>
2024-04-03 08:30:12 +02:00
{dropoff > 0 && (
<div className={styles.info}>
<b>{formatLongNumber(dropped)}</b> {formatMessage(labels.visitorsDroppedOff)} (
{(dropoff * 100).toFixed(2)}%)
</div>
)}
2024-02-24 05:31:35 +01:00
</div>
</div>
);
})}
</div>
2023-05-18 20:17:35 +02:00
);
}
export default FunnelChart;