Skip to content

[profiler] Draw a collapsed region nested inside an expanded one - #6947

Open
Karakatiza666 wants to merge 1 commit into
redesign-profiler-diagram-6from
redesign-profiler-diagram-7
Open

Karakatiza666 wants to merge 1 commit into
redesign-profiler-diagram-6from
redesign-profiler-diagram-7

Conversation

@Karakatiza666

@Karakatiza666 Karakatiza666 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Part of #6895, split one commit per PR.

Which node stands in for a hidden operator was decided by
getTopParent: the outermost region, consulted alone. Expanding it
therefore revealed every descendant at once, and a region inside an
expanded one could not be collapsed on its own.

drawnNode walks the regions around a node from the outside in and
returns the first collapsed one, or the node itself when all of them are
expanded. Edges land on whichever region is drawn in place of their
endpoints, and every region around a drawn node is now added to the
graph: cytoscape requires each parent it is given to exist as a node.

Describe Manual Test Plan

Expand a region that holds another region. The inner one stays collapsed and can be expanded on its own, rather than the outer expansion revealing every descendant at once.

Verified at this commit, not just at the tip of the stack: checked out detached with js-packages/profiler-lib/dist deleted and rebuilt from this commit's source, then profiler-lib bun run check and bun run test, and profiler-layout bun run check and bun run test (all three vitest projects, browser suites included). All four green.

Checklist

  • Unit tests added/updated
  • Integration tests added/updated
  • Documentation updated
  • Changelog updated

Breaking Changes?

Mark if you think the answer is yes for any of these components:

  • OpenAPI / REST HTTP API / feldera-types / manager
  • Feldera SQL (Syntax, Semantics)
  • feldera-sqllib (incl. dependencies fxp, etc.)
  • Python SDK
  • fda (CLI arguments)
  • Adapters (including configuration)
  • Storage Format / Checkpoints
  • Others (specify)

Describe Incompatible Changes

None. The change is confined to js-packages/.

const expand = selection.regionsExpanded.contains(topParent);
if (nodeId !== topParent && !expand) {
let set = result.nodeChildren.get(topParent);
// Find out whether we display this node or the innermost region that hides it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drawnNode returns the outermost collapsed region, not the innermost — that is the whole point of the walk, and this line says the opposite of the doc comment three functions up. Suggest "the outermost collapsed region that hides it".

Comment on lines +272 to +285
static drawnNode(profile: CircuitProfile, selection: CircuitSelection, nodeId: NodeId): NodeId {
let regions: Array<NodeId> = [];
let parent = profile.parents.get(nodeId);
while (parent.isSome()) {
regions.unshift(parent.unwrap());
parent = profile.parents.get(parent.unwrap());
}
for (const region of regions) {
if (!selection.regionsExpanded.contains(region)) {
return region;
}
}
return nodeId;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Outermost collapsed ancestor" is just the last collapsed node seen on a single upward walk — no array and no unshift (O(n) per insert) needed. This runs once per simple node and twice per edge, so it is worth keeping allocation-free:

Suggested change
static drawnNode(profile: CircuitProfile, selection: CircuitSelection, nodeId: NodeId): NodeId {
let regions: Array<NodeId> = [];
let parent = profile.parents.get(nodeId);
while (parent.isSome()) {
regions.unshift(parent.unwrap());
parent = profile.parents.get(parent.unwrap());
}
for (const region of regions) {
if (!selection.regionsExpanded.contains(region)) {
return region;
}
}
return nodeId;
}
static drawnNode(profile: CircuitProfile, selection: CircuitSelection, nodeId: NodeId): NodeId {
let drawn = nodeId;
let parent = profile.parents.get(nodeId);
while (parent.isSome()) {
const region = parent.unwrap();
if (!selection.regionsExpanded.contains(region))
drawn = region;
parent = profile.parents.get(region);
}
return drawn;
}

Comment on lines +320 to +326
// Every region around the drawn node is drawn too, expanded: cytoscape needs each
// `parent` it is given to be a node on the graph, up to the outermost one.
let ancestor = parent;
while (ancestor.isSome()) {
visibleParents.add(ancestor.unwrap());
ancestor = profile.parents.get(ancestor.unwrap());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This walk fixes a real dangling-parent bug, but no test in the PR covers it. I reverted it to visibleParents.add(parent.unwrap()) locally and all 178 tests still passed — nested() gives outer a direct simple child (n1), so outer is registered even without the walk.

A fixture with three levels (a > b > c > n2) where the outer regions have no direct simple child fails without it (b's parent is a, and a is not on the graph). Please add one, plus an invariant assertion that every parent referenced by a drawn node exists as a drawn node, across expansion states — that is exactly the cytoscape precondition the comment cites.

set.unwrap().add(nodeId);
else {
result.nodeChildren.set(topParent, new Set(nodeId));
result.nodeChildren.set(drawn, new Set([nodeId]));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new Set(nodeId)new Set([nodeId]) is a genuine bug fix hiding in a refactor: nodeId is a string, so the old code splatted it into its characters (new Set('n2') = {'n','2'}), corrupting nodeChildren for the first hidden child of every collapsed region and therefore getSimpleNodes() / reachableFrom() — i.e. edge highlighting for collapsed regions. Reverting it leaves all 178 tests green, so it is untested; worth an assertion on nodeChildren and a line in the commit message, since it is not what the message describes.

// Detect whether an edge represents the same channel as a previous edge
// (only suppressed if the edge goes to a complex node)
if (!expandTarget) {
if (targetCollapsed) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

targetCollapsed is not equivalent to the old !expandTarget for a target that sits in no region: getTopParent(t) === t and regionsExpanded.contains(t) was false for a simple node, so the old code deduped parallel edges into top-level operators; now it does not. Two n1 -> n2 edges between two region-less nodes render as two parallel edges instead of one (I confirmed: createEdge gives them n1->n2 and n1->n2:2).

That may well be the intent — the comment above says "only suppressed if the edge goes to a complex node" — but it is an unannounced behaviour change with no test. Please pin whichever behaviour you want.

@mythical-fred-oss

Copy link
Copy Markdown

Ran in js-packages/profiler-lib: bun install, bun run check (clean), bun run test (7 files / 178 tests green), and pre-commit run --files js-packages/profiler-lib/src/cytograph.{ts,test.ts} (JavaScript Check passed). The design is right — outermost-collapsed-wins is the correct rule, and the expand && hasChildrenfalse simplification is a genuine no-op (the old expression was unreachable-true). I probed the change with extra fixtures; three of the four things this diff actually changes are not pinned by the new tests:

Behaviour Covered? Evidence
Collapsed region nested in an expanded one new nested regions suite
visibleParents walked to the outermost ancestor reverting to add(parent.unwrap()) keeps all 178 green; fails only at 3 levels
new Set(nodeId)new Set([nodeId]) reverting keeps all 178 green
Edge dedup for region-less targets reverting keeps all 178 green

nested() gives outer a direct simple child, which masks the ancestor-walk fix — a a > b > c > n2 fixture plus an invariant check ("every parent a drawn node names is itself drawn") covers it and is the cytoscape precondition the code comment cites. Uncovered cases I would also add: CompleteSet selection (getFullSelection), a region whose only content is another region, and a nodeChildren/getSimpleNodes assertion for a region hiding exactly one node. Also, CircuitProfile.getTopParent (profile.ts:1782) now has zero callers and no test — drop it here or say which later PR in the stack needs it. Not a gate failure elsewhere: no Rust/SQL/connector/docs surface, no unsafe, no deps, no pull_request_target, and the manual test plan is present; the only feldera-pr-checks item I would hold on is hard rule 2, tests for changed behaviour, for the three untested rows above.

@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from 168cb4a to 8b215fc Compare August 26, 2026 07:38
@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from 8b215fc to 9647ae4 Compare September 1, 2026 14:06
@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from 9647ae4 to 858e6ec Compare September 1, 2026 17:14
@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from 858e6ec to 0ece59f Compare September 1, 2026 17:55
@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from 0ece59f to dbc6953 Compare September 15, 2026 09:33
@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from dbc6953 to 35bb864 Compare September 15, 2026 12:07
@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from 35bb864 to 9aaef86 Compare September 15, 2026 16:59
@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from 9aaef86 to 5ed0431 Compare September 15, 2026 18:44
Which node stands in for a hidden operator was decided by
`getTopParent`: the outermost region, consulted alone. Expanding it
therefore revealed every descendant at once, and a region inside an
expanded one could not be collapsed on its own.

`drawnNode` walks the regions around a node from the outside in and
returns the first collapsed one, or the node itself when all of them are
expanded. Edges land on whichever region is drawn in place of their
endpoints, and every region around a drawn node is now added to the
graph: cytoscape requires each `parent` it is given to exist as a node.

Signed-off-by: Karakatiza666 <bulakh.96@gmail.com>
@Karakatiza666
Karakatiza666 force-pushed the redesign-profiler-diagram-7 branch from 5ed0431 to 9767527 Compare September 22, 2026 20:46

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant