Side-panel button is now "🎯 Focus" / "🎯 Unfocus" (was "📌 Pin" /
"📌 Unpin"). Hint text, help legend, counts line, and README all
updated. Internal identifiers (focusSet, pinClass, the panel-btn.pin
CSS class, data-action="toggle-pin") stay as-is — they're invisible
to users and changing them invites bigger churn.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
in this program). Click any name to navigate.
- **Search** (top right or `/`) for classes and families, with badges
for `external` and `family` entries.
-- **Pin** classes from the side panel to focus the classes view to just
- the pinned classes plus their immediate superclass neighbourhood
- (xdot-style narrowing). Click a ghost neighbour to expand by one hop.
+- **Focus** the classes view on a small set of classes from the side
+ panel. The graph collapses to just the focused classes plus their
+ immediate superclass neighbourhood (xdot-style narrowing). Click a
+ ghost neighbour to expand the focus by one hop.
- **Mute** noisy ambient classes (`Show`, `Eq`, `Ord`, `NoThunks`,
`Typeable`…) so they vanish everywhere.
- Per-class **instance visibility filter** and per-family **type-instance
| **Double-click** a family | Drill into its family view |
| **Click** a class name in the side panel | Navigate to that class (highlight + center) |
| **Search** (`/` or top-right input) | Locate a class/family in the classes view |
-| **Pin** (side panel button) | Focus classes view to pinned classes + one-hop neighbours |
+| **Focus** (side panel button) | Narrow the classes view to focused classes + one-hop neighbours |
| **Mute** (side panel button) | Hide a class everywhere |
-| **Click** a ghost (focus-mode neighbour) | Pin it and expand the focus subgraph |
+| **Click** a ghost (focus-mode neighbour) | Add it to the focus and expand the subgraph |
| **Back arrow** (topbar) / browser back | Return to the classes view |
| **Fit** button or `F` | Re-frame the current view |
| **Help** (bottom-right) | Foldable legend of every node and edge style |
<div class="legend-row"><span class="swatch"><span class="swatch-node swatch-instance">Inst</span></span><span>Class instance</span></div>
<div class="legend-row"><span class="swatch"><span class="swatch-node swatch-faminst">f a=b</span></span><span>Type family instance (<code>type instance F … = …</code>)</span></div>
<div class="legend-row"><span class="swatch"><span class="swatch-node swatch-external">Ext</span></span><span>External class (referenced but not defined here)</span></div>
- <div class="legend-row"><span class="swatch"><span class="swatch-node swatch-ghost">Cls</span></span><span>Ghost — one-hop neighbour in focus mode (click to pin)</span></div>
+ <div class="legend-row"><span class="swatch"><span class="swatch-node swatch-ghost">Cls</span></span><span>Ghost — one-hop neighbour in focus mode (click to add it to the focus)</span></div>
<div class="legend-row"><span class="swatch"><span class="swatch-node swatch-orphan">Inst</span></span><span>Orphan instance (red dashed border)</span></div>
<h4>Classes-view edges</h4>
<div class="help-tip">Click → highlight + side panel</div>
<div class="help-tip">Double-click a class → instances; a family → type instances</div>
<div class="help-tip"><kbd>/</kbd> focuses search · <kbd>F</kbd> fits the graph</div>
- <div class="help-tip">Pin / mute via the right-side buttons (chips appear in the topbar)</div>
+ <div class="help-tip">Focus / mute via the right-side buttons (chips appear in the topbar)</div>
</div>
</details>
</div>
<aside id="panel">
<header>
<h1>classgraph</h1>
- <p class="hint" id="hint-classes">Search to locate a class. Click any node to inspect it on the right (with <em>Pin</em>/<em>Mute</em> buttons). <strong>Double-click</strong> a class to drill into its instances, or a family (diamond) to see its type instances. Scroll to zoom; drag to pan.</p>
+ <p class="hint" id="hint-classes">Search to locate a class. Click any node to inspect it on the right (with <em>Focus</em>/<em>Mute</em> buttons). <strong>Double-click</strong> a class to drill into its instances, or a family (diamond) to see its type instances. Scroll to zoom; drag to pan.</p>
<p class="hint" id="hint-instance" hidden>Click to highlight; <strong>double-click</strong> a class or family to drill in. The back arrow returns to the hierarchy.</p>
<p class="hint" id="hint-family" hidden>Each entry is a <code>type instance</code> declaration. <strong>Double-click</strong> the parent class to see its instances.</p>
</header>
return `${classById.size} classes · ${familyById.size} families · ${cy.edges().length} edges`;
}
const total = cy.nodes().length;
- const pinned = focusSet.size;
- return `Focus: ${pinned} pinned · ${total} visible nodes · ${cy.edges().length} edges`;
+ const focused = focusSet.size;
+ return `Focus: ${focused} class${focused === 1 ? '' : 'es'} · ${total} visible nodes · ${cy.edges().length} edges`;
}
function pinClass(id) {
parts.push(
`<button class="panel-btn pin${isPinned ? ' active' : ''}" ` +
`data-action="toggle-pin" data-id="${escapeAttr(cid)}" ` +
- `title="${isPinned ? 'Remove from focus' : 'Add to focus subgraph'}">` +
- `ð\9f\93\8c ${isPinned ? 'Unpin' : 'Pin'}</button>`
+ `title="${isPinned ? 'Remove from focus subgraph' : 'Focus the graph on this class'}">` +
+ `ð\9f\8e¯ ${isPinned ? 'Unfocus' : 'Focus'}</button>`
);
}
if (opts.canMute) {