Skip to content

Feature: Group-Base Graph Filtering #16

Description

@lilmissy4205

Problem

Relationship type grouping already exists for legend organization, but there's no way to use it for filtering. Users want to create different graph views focused on specific relationship categories:

  • One embed: "show only Social relationships" (allies, enemies, friends)
  • Another: "show only Family relationships" (parents, children, siblings)
  • Another: "show only Bond relationships" (spouses, romantic partners)

Without this, users have to repeatedly toggle the global type filter, or maintain separate vaults, to get a focused view. This is particularly useful in TTRPG worldbuilding and narrative-heavy vaults where a note has many relationship categories and a given embed (a faction page, a family tree callout) only cares about one of them.

Solution

Add a groups: option to code blocks, using the same group field that already drives legend clustering:

relations
size: small
groups: "Social, Bond"
  • OR logic across multiple groups: groups: ["Social", "Bond"] or groups: "Social, Bond"
  • Strict match — an edge is shown only when its type's group is in the requested set. Ungrouped types are excluded once groups: is set, same as any type whose group isn't requested.
  • Composes with the existing global type filter, which is applied first
  • Fully opt-in: blocks without groups: render exactly as before

Implementation

  • filterGraphByGroups() in graph.ts — pure function, filters edges by type→group lookup, keeps the center/highlight node even if filtering would otherwise isolate it
  • groups: parsed from code-block YAML (comma-separated string or array) via a new resolveGroups() helper in codeblock.ts, threaded through parseOptions() into the render path
  • Addressed maintainer feedback from review:
    1. Bug: parseOptions built groups but never returned it, so the option never reached rendering. Fixed, plus added a genuine parseOptions() round-trip test — which required upgrading the test suite's parseYaml mock from a stub that always returned {} to a small real parser, since nothing could otherwise exercise the actual parsing path.
    2. Behavior: switched from "ungrouped types always shown" to strict matching. Updated the group field's doc comment in types.ts (no longer "purely cosmetic") and the Settings panel's help text/tooltip.
    3. Docs: added groups to the README options table, rebased onto current main (0.25.0).

Expected Files to Modify

File Planned Changes Type
src/graph.ts +60 filterGraphByGroups()
src/codeblock.ts +41 groups: option, resolveGroups(), render-path wiring
src/types.ts +12/-4 group field doc update
src/settings.ts +9/-3 Help text + tooltip update
README.md +4 Options table + known-limitation note
tests/filter-graph-groups.test.ts +262 Filter logic coverage
tests/parse-options-groups.test.ts +47 Parsing round-trip coverage
tests/mocks/obsidian.ts +38 Real parseYaml mock (was a {} stub)
Total ~460 lines 8 files

Backward Compatibility

Fully backward compatible for existing usage — groups: is opt-in, and blocks that don't set it are unaffected. The one behavior decision worth flagging for review: groups: filtering excludes ungrouped types (strict match), rather than always showing them. This only affects blocks that explicitly set groups:.

Known Limitation (found in manual testing) — tracked as #28

With scope: local / scope: connected, the note neighborhood is currently walked using every relationship type before groups: (or the existing global type filter) hides anything — so a note reachable only through a now-hidden type can still surface if it has its own edges of a visible type, rendering as a seemingly disconnected extra node/cluster. This predates this PR (the same pattern exists for the global type filter) but is far more visible with groups:, since a whole category can be hidden at once. Filed as #28; a fix (computing hop-distance over the already-filtered edge set) is in progress separately, since it touches shared graph-building code beyond this feature.

Use Case

  • Focus on social relationships: groups: ["Social"]
  • Family tree view: groups: ["Family", "Genealogy"]
  • Romantic connections: groups: ["Bond"]
  • Professional network: groups: ["Mentor", "Professional"]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions