PassNetwork merges A↔B edge pairs into undirected edges by default
When the input contains `A→B` (10 passes) and `B→A` (8 passes), the default render collapses them into a single undirected edge with weight 18. `directed: true` keeps the pair distinct with arrowheads, at the cost of dense-network readability.
Context
The editorial reading of a passing network is “who connects with whom”. Directional asymmetry (Player A pushes the ball to B more than B recycles to A) is usually secondary to the partnership signal, and rendering every pair as two offset lines makes 11-player networks unreadable on mobile. The alternative — forcing consumers to aggregate upstream before plotting — pushes the undirected/directed choice outside the chart, making it harder to swap views.
Decision
directed: false (default). Renderer folds reversed pairs by lexicographic
key; edge weight is the sum; xT (if present) is summed; chord geometry uses
the shorter path between nodes. directed: true keeps both pairs, offsets
them slightly, and renders arrowheads. No re-aggregation on toggle — the
compute model carries the full directed adjacency either way.
Consequences
- Zero-config networks are readable at 11-player density on narrow screens.
- Consumers who want the asymmetry flip one prop; no data re-shape required.
- The compute layer assumes inputs are already deduplicated by
(source, target)tuple — the renderer does not validate that both{A→B, A→B}duplicates haven’t been supplied. - Edge-thickness encoding uses the merged weight under
directed: false, so a one-sided10/0pair renders identically to a balanced5/5pair. Recipe-level presets can expose an asymmetry indicator when the imbalance is editorially relevant.