Signals · D3 Force Graph
An Obsidian-style force-directed signal map for early-warning detection.
Signals was the most technically ambitious surface I designed at Trmeric. A D3 force simulation with 79 nodes, each representing a project signal: a risk, an assumption, a dependency, an issue. The brief: give a Portfolio Manager an early-warning system that shows how problems propagate across a portfolio before they surface in status updates.
The interaction pattern came from Obsidian, the knowledge graph tool. In Obsidian, hovering a node highlights all its direct connections and dims everything else. That neighbour-highlight pattern is the right answer for signal propagation: a delayed delivery ripples to its downstream dependencies, and the graph shows you exactly which ones.
Signals isn't a standalone destination. It lives embedded beside the Project Manager, and a signal click surfaces the related project card inline, so investigating a risk never costs a navigation.
This is the real hover-to-highlight model, at a smaller scale: three clusters standing in for a portfolio's worth of signals. Hover any node.
Hover over click
Click-to-expand commits you to a node before you've seen its neighbours. Hover shows the local graph instantly and costs nothing to back out of.
Physics carries meaning
Severity is a simulation weight, not just a fill colour. High-severity nodes pull harder, so systemic risk clusters toward the centre before anyone reads a single label.
Never lose your place
The full map stays rendered at all times. Focusing a node dims its neighbours; it never re-lays-out the graph or hides the rest of the portfolio.
Zero-navigation action
A signal click surfaces the related project card inline, in the same view. Acting on a risk should never cost you your place in the map.
Cluster by project, not flat node soup.
An undifferentiated cloud of 79 signal dots is unreadable. Clustering by project (Solace Migration, Talvera Sync, Unified Customer) lets a Portfolio Manager see at a glance which initiative is generating the most noise, with red rings marking clusters that need a decision today.
Iframe integration instead of a standalone route.
Signals is a lens on the Project Manager, not a separate destination. Embedding it via iframe means a signal click can surface the related project card in place, with zero navigation cost, instead of round-tripping through a route change and losing scroll position.
Force parameters tuned by hand against real data, not left at D3 defaults.
Default Fruchterman-Reingold spacing overlapped labels in dense clusters and left too much dead space in sparse ones. Charge strength, link distance, and collision radius were each tuned against the actual Q2 portfolio export until clusters read as clusters at a glance, before anyone read a single label.
"I used to build this map in my head from six different status reports. Now I open one screen and the map already exists."
"The red cluster in the centre told me in ten seconds what would have taken a week of one-on-ones to piece together."
Learnings that apply beyond this project
Physics is a legitimate design material
Force-directed layout isn't just a pretty visualisation technique. Weighting the simulation by severity turns spatial position into a second encoding channel that reinforces colour instead of duplicating it.
Borrow proven interaction grammar
Obsidian's hover-to-highlight had already trained thousands of users on this exact pattern. Reusing it instead of inventing a novel interaction meant zero onboarding cost for anyone who'd used a graph tool before.
The pivot from click-to-bloom to hover-to-highlight came out of a single usability session where a Portfolio Manager got visibly lost after three clicks deep. Reversing course early, before the pattern shipped widely, saved the feature.
I spent the first two weeks on visual styling before realising the default force parameters made the real portfolio data unreadable. Tuning the simulation against real data should have come before any styling pass, not after it.