mirror of
https://github.com/umami-software/umami.git
synced 2026-02-16 10:35:35 +01:00
Added drop-off info to journey.
This commit is contained in:
parent
499392c110
commit
84548a669e
2 changed files with 50 additions and 7 deletions
|
|
@ -22,8 +22,29 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: 70px;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visitors {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
text-transform: lowercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropoff {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--base800);
|
||||||
|
background: var(--base200);
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.num {
|
.num {
|
||||||
|
|
@ -38,7 +59,7 @@
|
||||||
color: var(--base100);
|
color: var(--base100);
|
||||||
background: var(--base800);
|
background: var(--base800);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
margin: 0 auto;
|
margin: 0 auto 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.column {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { useContext, useMemo, useState } from 'react';
|
import { useContext, useMemo, useState } from 'react';
|
||||||
|
import { TooltipPopup } from 'react-basics';
|
||||||
import { firstBy } from 'thenby';
|
import { firstBy } from 'thenby';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useEscapeKey } from 'components/hooks';
|
import { useEscapeKey, useMessages } from 'components/hooks';
|
||||||
import { objectToArray } from 'lib/data';
|
import { objectToArray } from 'lib/data';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
// eslint-disable-next-line css-modules/no-unused-class
|
// eslint-disable-next-line css-modules/no-unused-class
|
||||||
|
|
@ -16,6 +17,7 @@ export default function JourneyView() {
|
||||||
const [activeNode, setActiveNode] = useState(null);
|
const [activeNode, setActiveNode] = useState(null);
|
||||||
const { report } = useContext(ReportContext);
|
const { report } = useContext(ReportContext);
|
||||||
const { data, parameters } = report || {};
|
const { data, parameters } = report || {};
|
||||||
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
||||||
useEscapeKey(() => setSelectedNode(null));
|
useEscapeKey(() => setSelectedNode(null));
|
||||||
|
|
||||||
|
|
@ -74,8 +76,16 @@ export default function JourneyView() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const nodesArray = objectToArray(nodes).sort(firstBy('total', -1));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
nodes: objectToArray(nodes).sort(firstBy('total', -1)),
|
nodes: nodesArray,
|
||||||
|
visitors: nodesArray.reduce((sum, { selected, total }) => {
|
||||||
|
if (!selectedNode || (selectedNode && selected)) {
|
||||||
|
sum += total;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}, 0),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}, [data, selectedNode, activeNode]);
|
}, [data, selectedNode, activeNode]);
|
||||||
|
|
@ -99,6 +109,10 @@ export default function JourneyView() {
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.view}>
|
<div className={styles.view}>
|
||||||
{columns.map((column, columnIndex) => {
|
{columns.map((column, columnIndex) => {
|
||||||
|
const previousTotal = columns[columnIndex - 1]?.visitors ?? 0;
|
||||||
|
const dropOff =
|
||||||
|
previousTotal > 0 ? ((column.visitors - previousTotal) / previousTotal) * 100 : 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={columnIndex}
|
key={columnIndex}
|
||||||
|
|
@ -106,6 +120,12 @@ export default function JourneyView() {
|
||||||
>
|
>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<div className={styles.num}>{columnIndex + 1}</div>
|
<div className={styles.num}>{columnIndex + 1}</div>
|
||||||
|
<div className={styles.stats}>
|
||||||
|
<div className={styles.visitors}>
|
||||||
|
{column.visitors} {formatMessage(labels.visitors)}
|
||||||
|
</div>
|
||||||
|
{columnIndex > 0 && <div className={styles.dropoff}>{`${~~dropOff}%`}</div>}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.nodes}>
|
<div className={styles.nodes}>
|
||||||
{column.nodes.map(({ name, total, selected, active, paths, from }, nodeIndex) => {
|
{column.nodes.map(({ name, total, selected, active, paths, from }, nodeIndex) => {
|
||||||
|
|
@ -146,9 +166,11 @@ export default function JourneyView() {
|
||||||
onMouseLeave={() => selected && setActiveNode(null)}
|
onMouseLeave={() => selected && setActiveNode(null)}
|
||||||
>
|
>
|
||||||
<div className={styles.name}>{name}</div>
|
<div className={styles.name}>{name}</div>
|
||||||
<div className={styles.count}>
|
<TooltipPopup label="hi" disabled={!selected}>
|
||||||
{selected ? (active ? activeCount : selectedCount) : total}
|
<div className={styles.count}>
|
||||||
</div>
|
{selected ? (active ? activeCount : selectedCount) : total}
|
||||||
|
</div>
|
||||||
|
</TooltipPopup>
|
||||||
{columnIndex < columns.length &&
|
{columnIndex < columns.length &&
|
||||||
lines.map(([fromIndex, nodeIndex], i) => {
|
lines.map(([fromIndex, nodeIndex], i) => {
|
||||||
const height =
|
const height =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue