From b0adb9534b2041e448817cccac0d9cb5562233c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Tue, 17 Dec 2024 12:45:21 +0100 Subject: [PATCH 1/2] Fix setting fallback `Position2D` --- .../re_view_graph/src/layout/provider.rs | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/crates/viewer/re_view_graph/src/layout/provider.rs b/crates/viewer/re_view_graph/src/layout/provider.rs index b49f3f6669a0..d9c718d29146 100644 --- a/crates/viewer/re_view_graph/src/layout/provider.rs +++ b/crates/viewer/re_view_graph/src/layout/provider.rs @@ -139,13 +139,17 @@ impl ForceLayoutProvider { layout: &Layout, params: &ForceLayoutParams, ) -> Self { - let nodes = request.all_nodes().map(|(id, v)| { - if let Some(rect) = layout.get_node(&id) { - let pos = rect.center(); - fj::Node::from(v).position(pos.x as f64, pos.y as f64) - } else { - fj::Node::from(v) + let nodes = request.all_nodes().map(|(id, template)| { + let node = fj::Node::from(template); + + if template.fixed_position.is_none() { + if let Some(rect) = layout.get_node(&id) { + let pos = rect.center(); + return node.position(pos.x as f64, pos.y as f64); + } } + + node }); let radii = request .all_nodes() @@ -207,13 +211,17 @@ impl ForceLayoutProvider { target: edge.target, }) .or_default(); - geometries.push(EdgeGeometry { - target_arrow, - path: line_segment( - layout.nodes[&edge.source], - layout.nodes[&edge.target], - ), - }); + + let source = layout.nodes[&edge.source]; + let target = layout.nodes[&edge.target]; + + // We only draw edges if they can be displayed meaningfully. + if source.center() != target.center() && !source.intersects(target) { + geometries.push(EdgeGeometry { + target_arrow, + path: line_segment(source, target), + }); + } } else { // Multiple edges occupy the same space, so we fan them out. let num_edges = edges.len(); @@ -222,6 +230,14 @@ impl ForceLayoutProvider { let source_rect = layout.nodes[slot_source]; let target_rect = layout.nodes[slot_target]; + if source_rect.center() == target_rect.center() + || source_rect.intersects(target_rect) + { + // There is no meaningful geometry to draw here. + // Keep in mind that self-edges are handled separately above. + continue; + } + let d = (target_rect.center() - source_rect.center()).normalized(); let source_pos = source_rect.intersects_ray_from_center(d); From 151061f17e5f0dd32ae43e1feb68e25cdbd49837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Tue, 17 Dec 2024 13:28:08 +0100 Subject: [PATCH 2/2] Add checklist item --- tests/python/release_checklist/check_graph_view.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/python/release_checklist/check_graph_view.py b/tests/python/release_checklist/check_graph_view.py index 97e9964394bd..27ae31d839c4 100644 --- a/tests/python/release_checklist/check_graph_view.py +++ b/tests/python/release_checklist/check_graph_view.py @@ -15,6 +15,7 @@ * `graph` has directed edges, while `graph2` has undirected edges. * `graph` and `graph2` are shown in two different viewers. * There is a third viewer, `Both`, that shows both `graph` and `graph2` in the same viewer. +* The `coincident` viewer shows two nodes, `A` and `B`, at the same position """ @@ -22,6 +23,10 @@ def log_readme() -> None: rr.log("readme", rr.TextDocument(README, media_type=rr.MediaType.MARKDOWN), static=True) +def log_coincident_nodes() -> None: + rr.log("coincident", rr.GraphNodes(["A", "B"], labels=["A", "B"], positions=[[-150, 0], [150, 0]])) + + def log_graphs() -> None: DATA = [ ("A", None), @@ -51,6 +56,7 @@ def run(args: Namespace) -> None: log_readme() log_graphs() + log_coincident_nodes() rr.send_blueprint( rrb.Blueprint( @@ -58,6 +64,11 @@ def run(args: Namespace) -> None: rrb.GraphView(origin="graph", name="Graph 1"), rrb.GraphView(origin="graph2", name="Graph 2"), rrb.GraphView(name="Both", contents=["/graph", "/graph2"]), + rrb.GraphView( + origin="coincident", + name="Coincident nodes", + overrides={"coincident": [rr.components.Position2D([0, 0])]}, + ), rrb.TextDocumentView(origin="readme", name="Instructions"), ) )