UI tweaks on the hover
This commit is contained in:
parent
1a3aaac5b3
commit
1dd188323e
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user