diff --git a/src/app/(main)/reports/journey/JourneyView.module.css b/src/app/(main)/reports/journey/JourneyView.module.css index b4297b5f..f4571cda 100644 --- a/src/app/(main)/reports/journey/JourneyView.module.css +++ b/src/app/(main)/reports/journey/JourneyView.module.css @@ -147,7 +147,6 @@ } .end { - right: 0; width: 50px; height: 30px; border: 0; @@ -161,7 +160,7 @@ } .up .end { - width: 53px; + width: 52px; bottom: 27px; right: 0; border-bottom-left-radius: 100%; @@ -177,7 +176,7 @@ } .down .end { - width: 53px; + width: 52px; top: 30px; right: 0; border-top-left-radius: 100%; @@ -186,16 +185,15 @@ } .flat .start { + left: 0; top: 30px; - width: 50px; border-top: 3px solid var(--journey-line-color); } .flat .end { right: 0; - bottom: 27px; - width: 50px; - border-bottom: 3px solid var(--journey-line-color); + top: 30px; + border-top: 3px solid var(--journey-line-color); } .start:before, @@ -214,14 +212,12 @@ display: none; } -.up .start:before, -.flat .start:before { +.up .start:before { left: -8px; top: -8px; } -.up .end:before, -.flat .end:before { +.up .end:before { right: -8px; bottom: -8px; } @@ -236,6 +232,16 @@ top: -8px; } +.flat .start:before { + left: -8px; + top: -8px; +} + +.flat .end:before { + right: -8px; + top: -8px; +} + .line.active .segment, .line.active .segment:before { border-color: var(--journey-active-color); diff --git a/src/app/(main)/reports/journey/JourneyView.tsx b/src/app/(main)/reports/journey/JourneyView.tsx index 26815430..d9a43346 100644 --- a/src/app/(main)/reports/journey/JourneyView.tsx +++ b/src/app/(main)/reports/journey/JourneyView.tsx @@ -23,61 +23,69 @@ export default function JourneyView() { if (!data) { return []; } + + const selectedPaths = selectedNode?.paths ?? []; + const activePaths = activeNode?.paths ?? []; + return Array(Number(parameters.steps)) .fill(undefined) - .map((column = {}, index) => { + .map((nodes = {}, index) => { data.forEach(({ items, count }) => { const name = items[index]; - const selectedNodes = selectedNode?.paths ?? []; if (name) { - const selected = !!selectedNodes.find(a => a.items[index] === name); - if (!column[name]) { + const selected = !!selectedPaths.find(path => path.items[index] === name); + const active = selected && !!activePaths.find(path => path.items[index] === name); + + if (!nodes[name]) { const paths = data.filter((d, i) => { return i !== index && d.items[index] === name; }); + const from = index > 0 && selected && paths.reduce((obj, path) => { const { items, count } = path; const name = items[index - 1]; + if (!obj[name]) { obj[name] = { name, count }; } else { obj[name].count += count; } + return obj; }, {}); - column[name] = { + nodes[name] = { name, count, total: count, columnIndex: index, selected, - selectedCount: count, + active, paths, from: objectToArray(from), }; } else { - column[name].selectedCount += selected ? count : 0; - column[name].total += count; + nodes[name].total += count; } } }); return { - nodes: objectToArray(column).sort(firstBy('total', -1)), + nodes: objectToArray(nodes).sort(firstBy('total', -1)), }; }); - }, [data, selectedNode]); + }, [data, selectedNode, activeNode]); - const handleClick = (item: string, index: number, paths: any[]) => { - if (item !== selectedNode?.item || index !== selectedNode?.index) { - setSelectedNode({ item, index, paths }); + const handleClick = (name: string, index: number, paths: any[]) => { + if (name !== selectedNode?.name || index !== selectedNode?.index) { + setSelectedNode({ name, index, paths }); } else { setSelectedNode(null); + setActiveNode(null); } }; @@ -85,7 +93,7 @@ export default function JourneyView() { return null; } - //console.log({ columns, selectedNode, activeNode }); + //console.log({ data, columns, selectedNode, activeNode }); return (
@@ -100,81 +108,89 @@ export default function JourneyView() {
{columnIndex + 1}
- {column.nodes.map( - ({ name, total, selected, paths, from, selectedCount }, nodeIndex) => { - const active = - selected && activeNode?.paths.find(path => path.items[columnIndex] === name); + {column.nodes.map(({ name, total, selected, active, paths, from }, nodeIndex) => { + const previousNodes = columns[columnIndex - 1]?.nodes; + let selectedCount = from?.length ? 0 : total; + let activeCount = selectedCount; - const lines = from?.reduce((arr, { name }: any) => { - const fromIndex = columns[columnIndex - 1]?.nodes.findIndex(node => { - return node.name === name && node.selected; - }); + const lines = from?.reduce((arr, { name, count }: any) => { + const fromIndex = previousNodes.findIndex(node => { + return node.name === name && node.selected; + }); - if (fromIndex > -1) { - arr.push([fromIndex, nodeIndex]); - } + if (fromIndex > -1) { + arr.push([fromIndex, nodeIndex]); + selectedCount += count; + } - return arr; - }, []); + if ( + previousNodes.findIndex(node => { + return node.name === name && node.active; + }) > -1 + ) { + activeCount += count; + } - return ( -
handleClick(name, columnIndex, paths)} - onMouseEnter={() => selected && setActiveNode({ name, columnIndex, paths })} - onMouseLeave={() => selected && setActiveNode(null)} - > -
{name}
-
- {selected || active ? selectedCount : total} -
- {columnIndex < columns.length && - lines.map(([fromIndex, nodeIndex], i) => { - const height = - (Math.abs(nodeIndex - fromIndex) + 1) * (NODE_HEIGHT + NODE_GAP) - - NODE_GAP; - const midHeight = - (Math.abs(nodeIndex - fromIndex) - 1) * (NODE_HEIGHT + NODE_GAP) + - NODE_GAP + - LINE_WIDTH; - const nodeName = columns[columnIndex - 1]?.nodes[fromIndex].name; + return arr; + }, []); - return ( -
- path.items[columnIndex] === name && - path.items[columnIndex - 1] === nodeName, - ), - [styles.up]: fromIndex < nodeIndex, - [styles.down]: fromIndex > nodeIndex, - [styles.flat]: fromIndex === nodeIndex, - })} - style={{ height }} - > -
-
-
-
- ); - })} + return ( +
handleClick(name, columnIndex, paths)} + onMouseEnter={() => selected && setActiveNode({ name, columnIndex, paths })} + onMouseLeave={() => selected && setActiveNode(null)} + > +
{name}
+
+ {selected ? (active ? activeCount : selectedCount) : total}
- ); - }, - )} + {columnIndex < columns.length && + lines.map(([fromIndex, nodeIndex], i) => { + const height = + (Math.abs(nodeIndex - fromIndex) + 1) * (NODE_HEIGHT + NODE_GAP) - + NODE_GAP; + const midHeight = + (Math.abs(nodeIndex - fromIndex) - 1) * (NODE_HEIGHT + NODE_GAP) + + NODE_GAP + + LINE_WIDTH; + const nodeName = columns[columnIndex - 1]?.nodes[fromIndex].name; + + return ( +
+ path.items[columnIndex] === name && + path.items[columnIndex - 1] === nodeName, + ), + [styles.up]: fromIndex < nodeIndex, + [styles.down]: fromIndex > nodeIndex, + [styles.flat]: fromIndex === nodeIndex, + })} + style={{ height }} + > +
+
+
+
+ ); + })} +
+ ); + })}
);