UI tweaks on the hover

This commit is contained in:
Colin Dawson 2026-03-13 01:14:39 +00:00
parent 1a3aaac5b3
commit 1dd188323e
2 changed files with 58 additions and 20 deletions

View File

@ -208,6 +208,19 @@
stroke-dasharray: 0; stroke-dasharray: 0;
} }
.visualiser-outcome-connector-line.is-active-outgoing {
stroke-width: 2.8px;
stroke: rgba($blue, 0.82);
stroke-dasharray: 0;
filter: drop-shadow(0 0 3px rgba($blue, 0.6));
}
.visualiser-outcome-connector-line.is-active-incoming {
stroke-width: 2.2px;
stroke: rgba($blue, 0.58);
stroke-dasharray: 2, 2;
}
.visualiser-outcome-connector-line.is-dim { .visualiser-outcome-connector-line.is-dim {
opacity: 0.2; opacity: 0.2;
} }
@ -216,6 +229,14 @@
fill: darken($blue, 8%); fill: darken($blue, 8%);
} }
.visualiser-outcome-connector-label.is-active-outgoing {
fill: darken($blue, 12%);
}
.visualiser-outcome-connector-label.is-active-incoming {
fill: darken($blue, 2%);
}
.visualiser-outcome-connector-label.is-dim { .visualiser-outcome-connector-label.is-dim {
opacity: 0.25; opacity: 0.25;
} }

View File

@ -650,28 +650,29 @@ const VisualiserTab: React.FC<VisualiserTabProps> = ({
labelY = startY - 1.5 - Math.abs(laneSpread) * 0.12; labelY = startY - 1.5 - Math.abs(laneSpread) * 0.12;
labelAnchor = "end"; labelAnchor = "end";
} else { } else {
// Adjacent forward flow: keep curved center connectors. // Adjacent forward flow: use orthogonal segments only.
const startX = source.x; const startX = source.x;
const startY = source.y + source.height / 2; const startY = source.y + source.height / 2;
const endX = target.x; const endX = target.x;
const endY = target.y - target.height / 2; const endY = target.y - target.height / 2;
const controlOffset = Math.max(4, Math.abs(endY - startY) * 0.25); const xDelta = Math.abs(endX - startX);
const startControlX = startX + sourceShift + laneSpread; const shouldSnapVertical = xDelta < 1.25;
const endControlX = endX + targetShift + laneSpread;
path = `M ${startX} ${startY} C ${startControlX} ${startY + controlOffset}, ${endControlX} ${endY - controlOffset}, ${endX} ${endY}`; if (shouldSnapVertical) {
const snappedX = (startX + endX) / 2;
path = `M ${snappedX} ${startY} L ${snappedX} ${endY}`;
labelX = snappedX;
labelY = (startY + endY) / 2;
} else {
const offsetX = (sourceShift + targetShift + laneSpread) * 0.35;
const midY = (startY + endY) / 2;
const fromX = startX + offsetX;
const toX = endX + offsetX;
const t = 0.5; path = `M ${startX} ${startY} L ${fromX} ${startY} L ${fromX} ${midY} L ${toX} ${midY} L ${toX} ${endY} L ${endX} ${endY}`;
labelX = labelX = (fromX + toX) / 2;
Math.pow(1 - t, 3) * startX + labelY = midY;
3 * Math.pow(1 - t, 2) * t * startControlX + }
3 * (1 - t) * Math.pow(t, 2) * endControlX +
Math.pow(t, 3) * endX;
labelY =
Math.pow(1 - t, 3) * startY +
3 * Math.pow(1 - t, 2) * t * (startY + controlOffset) +
3 * (1 - t) * Math.pow(t, 2) * (endY - controlOffset) +
Math.pow(t, 3) * endY;
labelAnchor = "middle"; labelAnchor = "middle";
} }
@ -699,12 +700,20 @@ const VisualiserTab: React.FC<VisualiserTabProps> = ({
(edge.sourceGuid === hoveredGuid || (edge.sourceGuid === hoveredGuid ||
edge.targetGuid === hoveredGuid); edge.targetGuid === hoveredGuid);
const edgeIsDim = hoveredGuid !== null && !edgeIsActive; const edgeIsDim = hoveredGuid !== null && !edgeIsActive;
const edgeIntensityClass =
hoveredGuid === edge.sourceGuid
? " is-active-outgoing"
: hoveredGuid === edge.targetGuid
? " is-active-incoming"
: edgeIsActive
? " is-active"
: "";
const adjustedLabelY = getAdjustedLabelY(labelX, labelY - 1.25); const adjustedLabelY = getAdjustedLabelY(labelX, labelY - 1.25);
return ( return (
<g key={`${edge.sourceGuid}-${edge.targetGuid}`}> <g key={`${edge.sourceGuid}-${edge.targetGuid}`}>
<path <path
className={`visualiser-outcome-connector-line${edgeIsActive ? " is-active" : ""}${edgeIsDim ? " is-dim" : ""}`} className={`visualiser-outcome-connector-line${edgeIntensityClass}${edgeIsDim ? " is-dim" : ""}`}
d={path} d={path}
markerEnd={ markerEnd={
isMergedLeft ? undefined : "url(#visualiser-arrow)" isMergedLeft ? undefined : "url(#visualiser-arrow)"
@ -714,7 +723,7 @@ const VisualiserTab: React.FC<VisualiserTabProps> = ({
<text <text
x={labelX} x={labelX}
y={adjustedLabelY} y={adjustedLabelY}
className={`visualiser-outcome-connector-label${edgeIsActive ? " is-active" : ""}${edgeIsDim ? " is-dim" : ""}`} className={`visualiser-outcome-connector-label${edgeIntensityClass}${edgeIsDim ? " is-dim" : ""}`}
textAnchor={labelAnchor} textAnchor={labelAnchor}
dominantBaseline="middle" dominantBaseline="middle"
> >
@ -739,14 +748,22 @@ const VisualiserTab: React.FC<VisualiserTabProps> = ({
edges.some( edges.some(
(edge) => (edge) =>
edge.targetGuid === targetGuid && edge.targetGuid === targetGuid &&
edge.sourceGuid === hoveredGuid, edge.sourceGuid === hoveredGuid &&
(levelByGuid.get(edge.sourceGuid) ?? 0) >
(levelByGuid.get(edge.targetGuid) ?? 0),
)); ));
const mergedIsDim = hoveredGuid !== null && !mergedIsActive; const mergedIsDim = hoveredGuid !== null && !mergedIsActive;
const mergedIntensityClass =
hoveredGuid === targetGuid
? " is-active-incoming"
: mergedIsActive
? " is-active-outgoing"
: "";
return ( return (
<path <path
key={`merged-left-${targetGuid}`} key={`merged-left-${targetGuid}`}
className={`visualiser-outcome-connector-line${mergedIsActive ? " is-active" : ""}${mergedIsDim ? " is-dim" : ""}`} className={`visualiser-outcome-connector-line${mergedIntensityClass}${mergedIsDim ? " is-dim" : ""}`}
d={`M ${laneX} ${endY} L ${endX} ${endY}`} d={`M ${laneX} ${endY} L ${endX} ${endY}`}
markerEnd="url(#visualiser-arrow)" markerEnd="url(#visualiser-arrow)"
/> />