detect-diagram-crossings
npx skills add https://github.com/oocx/tfplan2md --skill detect-diagram-crossings
Agent 安装分布
Skill 文档
Detect Diagram Crossings
Purpose
Provide a rigorous, multi-method approach to detecting edge crossings and overlaps in SVG flowchart diagrams. This skill combines mathematical geometric analysis with visual inspection to ensure diagrams have clean, crossing-free layouts.
When to Use
- Validating Diagram Layouts: After creating or modifying workflow diagrams
- Quality Assurance: Before committing diagram changes to ensure no crossings
- Debugging Visual Issues: When users report crossing/overlap problems
- Comparative Analysis: Testing multiple layout versions to find the best one
Detection Methods
Method 1: Parametric Line Intersection (Mathematical)
The primary detection method uses parametric line equations to mathematically determine if two line segments intersect.
Algorithm:
- Parse SVG paths into line segments (sequences of points connected by lines)
- For each pair of line segments from different paths:
- Calculate intersection using parametric equations:
- Line 1: P = P1 + t(P2 – P1)
- Line 2: P = P3 + u(P4 – P3)
- Solve for parameters t and u
- Intersection occurs if 0.01 < t < 0.99 AND 0.01 < u < 0.99
- Calculate intersection using parametric equations:
- Exclude endpoint connections (valid node-to-node connections)
- Report all internal segment intersections as crossings
Why This Works:
- Mathematically precise: detects exact intersection points
- Coordinate-based: doesn’t rely on visual rendering
- Tolerance-aware: excludes near-endpoint intersections (within 1% of segment length)
Limitations:
- May not detect visual overlaps that aren’t true mathematical intersections
- Doesn’t account for stroke width or arrow markers
- Requires well-formed SVG path data
Method 2: Node-Path Proximity Analysis
Detects when paths pass through or very close to node bodies (not at connection points).
Algorithm:
- Extract all node bounding boxes from
<rect>elements: (x, y, width, height) - Parse each path’s
dattribute into individual line segments - For EACH segment of EACH path (not just waypoints):
- Vertical segments (same x, different y): Check if x is within any node’s x-range AND the y-range of the segment overlaps with the node’s y-range
- Horizontal segments (same y, different x): Check if y is within any node’s y-range AND the x-range of the segment overlaps with the node’s x-range
- Diagonal segments: Check if the line passes through the node’s bounding box
- For each detected intersection:
- Exclude segments that START or END at a node edge (valid connection points)
- Report all segments that PASS THROUGH a node’s interior
Critical: Segment-by-Segment Analysis
A multi-segment path like M 890 1180 L 550 1180 L 550 820 L 890 820 has THREE segments:
- Horizontal: (890,1180) â (550,1180) at y=1180
- Vertical: (550,1180) â (550,820) at x=550
- Horizontal: (550,820) â (890,820) at y=820
Each segment must be checked independently against ALL nodes. A single path can cross MULTIPLE nodes.
Why This Works:
- Catches paths that visually obscure nodes
- Identifies routing issues where paths don’t avoid nodes
- Complements line intersection by checking path-node relationships
- Detects all nodes crossed by multi-segment paths, not just the first one
Method 3: Path Overlap and Shared Point Analysis
Detects paths that share segments or start/end points, causing visual confusion.
Algorithm:
- Extract all path endpoints (start and end coordinates)
- Extract all path segments with their coordinates
- Check for:
- Shared endpoints: Multiple paths starting or ending at exact same point
- Overlapping segments: Two paths sharing the same line segment (same x or y and overlapping range)
- Convergence points: Multiple paths arriving at the same node edge within close proximity
Why This Works:
- Identifies visual clutter where paths merge
- Catches paths that are hard to distinguish
- Highlights areas needing offset routing for clarity
Method 4: Routing Quality Analysis
Detects suboptimal path routing that could be improved for visual clarity.
Algorithm:
-
Shared Start Points: Check if multiple paths originate from the exact same coordinate
- Example violation: UAT Tester â UAT PR and UAT Tester â Developer both starting at (890, 1180)
- Fix: Offset one path to start from a different point on the same node edge
-
Off-Center Connections: For nodes with only one incoming/outgoing path on an edge, verify the connection is centered
- Example violation: Path connecting to lower-left of a node instead of center-left
- Fix: Adjust path endpoint to center of the edge
-
Unnecessary Segments: Check if paths use more segments than necessary
- Example violation: 4-segment path when a 2-segment orthogonal path would work without crossings
- Fix: Simplify the path to use the minimum number of segments
-
Suboptimal Routes: Check if shorter intersection-free routes exist
- Example violation: Retro Report â Workflow Engineer going left-down-right instead of right-up-left
- Fix: Reroute using the shorter valid alternative
Why This Works:
- Ensures visual consistency and professionalism
- Reduces clutter by minimizing unnecessary path complexity
- Improves readability by using the most direct valid routes
Method 5: Visual Screenshot Analysis
Uses actual rendered output to catch visual issues that math might miss.
Algorithm:
- Capture high-resolution screenshot of rendered diagram
- Visually inspect for:
- Lines crossing over each other
- Paths obscuring node labels
- Arrow markers colliding with nodes/paths
- Color overlaps making paths indistinguishable
- Document specific coordinates of visual crossings
Why This Works:
- Catches rendering artifacts (antialiasing, stroke width effects)
- Validates user-perceived quality
- Identifies issues in arrow markers and decorations
- Accounts for font rendering and text overlaps
Systematic Detection Checklist
When detecting issues manually (without scripts), follow this checklist:
Step 1: Build Node Inventory
Create a table of ALL nodes with their bounding boxes:
| Node Name | x-min | x-max | y-min | y-max |
|-----------|-------|-------|-------|-------|
| Developer | 780 | 1000 | 780 | 820 |
| Tech Writer | 490 | 710 | 960 | 1000 |
...
Step 2: Parse Each Path into Segments
For each path, break down the d attribute into individual segments:
Path: "M 890 1180 L 550 1180 L 550 820 L 890 820"
Segments:
1. Horizontal at y=1180: x from 890 to 550
2. Vertical at x=550: y from 1180 to 820
3. Horizontal at y=820: x from 550 to 890
Step 3: Check EVERY Segment Against EVERY Node
For each segment, systematically check against all nodes:
-
Vertical segment at x=X, y from Y1 to Y2:
- Does X fall within [node.x-min, node.x-max]?
- Does [Y1, Y2] overlap with [node.y-min, node.y-max]?
- If BOTH yes â CROSSING DETECTED
-
Horizontal segment at y=Y, x from X1 to X2:
- Does Y fall within [node.y-min, node.y-max]?
- Does [X1, X2] overlap with [node.x-min, node.x-max]?
- If BOTH yes â CROSSING DETECTED
Step 4: Check Path Start/End Points
For each path, check if its start or end point is shared with other paths:
- Same exact coordinates = SHARED ENDPOINT
- Different paths arriving at same node edge within 5px = CONVERGENCE
Step 5: Check Path-Path Intersections
For each pair of paths, check if their segments intersect:
- Two horizontal segments at same y with overlapping x-range = OVERLAP
- Two vertical segments at same x with overlapping y-range = OVERLAP
- Horizontal and vertical segments that cross = CROSSING
Hard Rules
Must
- Build a complete node inventory FIRST before analyzing any paths
- Parse each path into individual line segments – never analyze paths as single entities
- Check EVERY segment against EVERY node – a single path can cross multiple nodes
- Run all detection methods for thorough validation
- Report exact coordinates of intersection points
- Identify which paths AND which specific segments are involved in each crossing
- Calculate parametric intersection parameters (t, u values) for path-path crossings
- Test with actual SVG data from the diagram file
- Create visual annotations showing crossing locations
- Report shared endpoints and overlapping path segments as separate issues
Must Not
- Rely on only one detection method
- Report endpoint connections as crossings
- Skip proximity analysis
- Ignore visual rendering validation
- Treat a multi-segment path as a single line – always decompose into segments
- Stop after finding one crossing on a path – continue checking remaining segments
- Assume segment routing based on comments – verify actual coordinates
Testing Approach
Test 1: Node Inventory Verification
Build the complete node inventory table and verify all nodes are captured.
Test 2: Path Segment Decomposition
Decompose ALL paths into segments and verify segment count matches expected.
Test 3: Systematic Segment-Node Checking
For each segment, check against ALL nodes (not just visually nearby ones).
Test 4: Mathematical Verification
Run parametric line intersection detection on all path-path segment pairs.
Test 5: Shared Point Detection
Check for paths sharing start/end points or overlapping segments.
Test 6: Visual Inspection
Analyze rendered screenshot for visual crossing artifacts.
Actions
1. Run Full Detection Suite
Execute the comprehensive Python detection script:
python3 .github/skills/detect-diagram-crossings/detect_crossings.py website/ai-workflow.html
This will:
- Parse SVG and extract all paths and nodes
- Decompose paths into individual line segments
- Run segment-by-segment node crossing detection
- Check path-path intersections
- Detect shared endpoints and overlapping segments
- Generate a detailed report with node inventory, path inventory, and issues
2. Run Extended Validation (Recommended)
Execute the JavaScript detection script for additional quality checks:
node .github/skills/detect-diagram-crossings/detect_all.js website/ai-workflow.html
This performs additional validation including:
- Shared start points: Multiple paths must not start at the same point of a node
- Off-center connections: If a path is the only connection to a node edge, it must connect at the center
- Unnecessary segments: Flags paths with more than 2 segments when a simpler 2-segment orthogonal path would work
- Suboptimal routes: Identifies paths that take longer routes when a shorter intersection-free alternative exists
Note: The JavaScript script requires Node.js and jsdom. Install dependencies with:
cd .github/skills/detect-diagram-crossings && npm install jsdom
3. Validate Fix
After modifying the diagram, re-run both detection scripts to confirm improvements:
python3 .github/skills/detect-diagram-crossings/detect_crossings.py website/ai-workflow.html
node .github/skills/detect-diagram-crossings/detect_all.js website/ai-workflow.html
Both scripts exit with:
- Exit code 0: No errors (warnings are OK for Python script)
- Exit code 1: Errors detected
Detection Metrics
Success Criteria
- â Zero mathematical crossings: All parametric tests pass
- â Zero proximity issues: No path segments through node bodies
- â Zero shared start points: Each path starts from a unique point on a node
- â Zero segment overlaps: No path segments overlap with other path segments
- â Centered single connections: Paths connecting to nodes with no other connections use center of edge
- â Minimal segment paths: No paths use more segments than necessary
- â Optimal routes: No significantly shorter intersection-free alternatives exist
- â Clean visual rendering: Screenshot confirms no visual crossings
- â All paths routed: Every connection has a clear, non-crossing path
Quality Thresholds
- Excellent: 0 crossings by all methods
- Good: 0 mathematical crossings, minor visual artifacts only
- Fair: 1-2 mathematical crossings in complex areas
- Poor: 3+ crossings or major visual overlaps
- Unacceptable: Multiple obvious crossings visible in screenshot
Common Mistakes to Avoid
Mistake 1: Incomplete Path Decomposition
Wrong: Checking only path endpoints or waypoints
Right: Parse d attribute into ALL individual line segments
Mistake 2: Stopping Early
Wrong: Finding one crossing on a path and moving to next path Right: Check ALL segments of the path against ALL nodes
Mistake 3: Visual Proximity Assumption
Wrong: Assuming a path doesn’t cross a node because they look far apart Right: Mathematically verify segment coordinates against node bounds
Mistake 4: Ignoring Multi-Node Crossings
Wrong: Reporting “path crosses Tech Writer” and stopping Right: Continue checking – same path might also cross Documentation, UAT Tester, etc.
Mistake 5: Missing Shared Points
Wrong: Only checking for geometric crossings Right: Also check for paths sharing exact start/end coordinates
Common Issues and Solutions
Issue: False Positives at Endpoints
Symptom: Detections at valid node-to-node connections
Fix: Increase endpoint tolerance from 0.01 to 0.05
Issue: Missed Visual Crossings
Symptom: Math says no crossings but visually there are
Fix: Check stroke width, arrow markers, and rendering artifacts
Issue: Paths Too Close to Nodes
Symptom: Proximity warnings but no crossings
Fix: Add routing margins, use wider node spacing
Best Practices
- Test Early and Often: Run detection after every layout change
- Use All Three Methods: Don’t rely on just mathematical analysis
- Document Findings: Save screenshots and coordinate data
- Iterative Refinement: Fix one crossing at a time, re-test after each fix
- Validate Visually: Always check rendered output, not just data
Example Output
CROSSING DETECTION REPORT
=========================
Method 1: Parametric Line Intersection
- Paths analyzed: 30
- Crossings detected: 0
- Status: â
PASS
Method 2: Node-Path Proximity
- Nodes analyzed: 25
- Proximity issues: 0
- Status: â
PASS
Method 3: Shared Points Analysis
- Shared endpoints: 0
- Overlapping segments: 0
- Status: â
PASS
Method 4: Visual Screenshot Analysis
- Resolution: 1920x2000px
- Visual crossings: 0
- Status: â
PASS
OVERALL: â
NO CROSSINGS DETECTED
Diagram has a clean, crossing-free layout.
Worked Example: UAT Rework Path Analysis
This example demonstrates the complete detection process for a problematic path.
Input Path
<!-- UAT rework path -->
<path d="M 890 1180 L 550 1180 L 550 820 L 890 820" stroke="#ff6b6b" .../>
Step 1: Decompose into Segments
| Segment | Type | Fixed Coord | Range |
|---|---|---|---|
| 1 | Horizontal | y=1180 | x: 550-890 |
| 2 | Vertical | x=550 | y: 820-1180 |
| 3 | Horizontal | y=820 | x: 550-890 |
Step 2: Relevant Node Bounds
| Node | x-min | x-max | y-min | y-max |
|---|---|---|---|---|
| UAT Tester | 780 | 1000 | 1140 | 1180 |
| Tech Writer | 490 | 710 | 960 | 1000 |
| Documentation | 490 | 710 | 1050 | 1085 |
| Developer | 780 | 1000 | 780 | 820 |
Step 3: Check Each Segment Against Each Node
Segment 1 (Horizontal y=1180, x: 550-890):
- UAT Tester: y=1180 within [1140,1180]? YES (touches edge). x:[550,890] overlaps [780,1000]? YES â CROSSING (edge)
- Tech Writer: y=1180 within [960,1000]? NO â OK
- Documentation: y=1180 within [1050,1085]? NO â OK
- Developer: y=1180 within [780,820]? NO â OK
Segment 2 (Vertical x=550, y: 820-1180):
- UAT Tester: x=550 within [780,1000]? NO â OK
- Tech Writer: x=550 within [490,710]? YES. y:[820,1180] overlaps [960,1000]? YES â CROSSING
- Documentation: x=550 within [490,710]? YES. y:[820,1180] overlaps [1050,1085]? YES â CROSSING
- Developer: x=550 within [780,1000]? NO â OK
Segment 3 (Horizontal y=820, x: 550-890):
- UAT Tester: y=820 within [1140,1180]? NO â OK
- Tech Writer: y=820 within [960,1000]? NO â OK
- Documentation: y=820 within [1050,1085]? NO â OK
- Developer: y=820 within [780,820]? YES (touches edge). x:[550,890] overlaps [780,1000]? YES â ENDPOINT (valid)
Step 4: Final Report for This Path
UAT Rework Path Crossings:
- Segment 1 (y=1180): Touches UAT Tester bottom edge at x=780-890 (start point)
- Segment 2 (x=550): CROSSES Tech Writer (y=960-1000)
- Segment 2 (x=550): CROSSES Documentation (y=1050-1085)
- Segment 3 (y=820): Ends at Developer node (valid endpoint)
ISSUES FOUND: 2 node crossings (Tech Writer, Documentation)