-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement graph components and archetypes #7500
base: main
Are you sure you want to change the base?
Conversation
In this design, are the node id's global? |
"attr.rust.custom_clause": | ||
'cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))' | ||
) { | ||
edge: [rerun.datatypes.GraphNodeId: 2] (order: 100); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any practical use (in robotics, primarily) in support hypergraphs (where an edge can join multiple nodes)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm 🤔, I'm not aware of any practical applications that use hypergraphs. There also does not seem to be any support in the petgraph
crate, so maybe we should focus on regular graphs first. If we think hypergraphs will become important, we can probably add a HyperGraphEdge
component to remain backwards compatible.
Of course, an hypergraph could also be "normalized" by adding virtual nodes for the edges that join multiple nodes.
@nikolausWest Good point! So far I've made the assumption that all node IDs are global and can be referenced across entities to allow edges that connect nodes from different entities (similar to We could probably use a namespaced approach (e.g. based on entity path) by changing the way we gather the nodes from the entities that are currently being visualized. Then, we would have to store this entity information in the edges though. However, it's probably simpler for the user to encode this information in the node IDs themselves. In the case of Do you have a particular use case for namespaced node IDs in mind? How would you expect Rerun to behave in that case? |
Class Ids aren't actually global in the sense that to resolve a class id into e.g. a color, we walk up the graph to the first Annotation Context and use that to look up the value. That means these are actually scoped.
I'm rather thinking about what happens if a user has multiple graphs. It would be a bit strange if edges started going between them because the user didn't correctly partition their node ids. |
One option to consider here could be to have two types of edges. One that is within-entity edges (just a pair of node ids). The other could be between entity edges (destination entity, optional(source id), optional(destination id)). There might be several ways to model that but that would at least be the general idea |
@nikolausWest Brief update: Edges now have two additional attributes
The following shows a new toy example of the new logging API, which I also streamlined: https://github.com/rerun-io/rerun/pull/7500/files#diff-d054c306b388fcc1e8daf9f0477735519df3eeb486030979c62478b5d43404dcR36-R66. I've also improved the debug graph viewer to show lists of nodes, edges, and their corresponding entity path. I'm currently working on getting overrides in the UI to work so that we can color nodes and edges to more easily understand the data model. This also helps me better understand the visualizer concepts. I have one outstanding design decision: The current systems allows for edges to live in completely unrelated parts of the entity hierarchy. This means that when the user choses to visualize a certain sub-entity not all edges are retrieved by default and the user has to manually specify the additional entities that contain the edges using Entity Path Filters:
Since this can be confusing due to the lack of discoverability, I think we should pull in global edges from outside the current hierarchy and visualizing them as dummy nodes. In the current design this forces us to iterate over all edges starting from the root. Should we mitigate this by introducing a new |
@grtlr I actually think having edges on different entities than nodes is the main reason to go with your proposal. That allows users to put different meta data on edges and nodes which is a very important feature. If you can think of a way to still keep it more local that might be worth while.
I'm not completely sure about this. Maybe @Wumpf has some thoughts? |
Haven't been following the entire discussion, but there's a lot of issues with pulling data from outside of a viewer's query/entity-pathfilter:
|
I think it's pretty clear we shouldn't include data from outside the entity path query. I think one question that leaves though is how to handle edges that are within the included entities but refer to nodes that are not. Perhaps some kind of greyed out nodes could make sense there (maybe even an option to include or exclude those) |
Thank you @Wumpf for the clarification—that makes a lot of sense! @nikolausWest I agree that we should show those as edges to some dummy nodes. In fact this is how I stumbled upon the above problem in the first place (undirected edges). |
d0e1194
to
acbefcb
Compare
a16219f
to
69d225e
Compare
@emilk, @Wumpf: @nikolausWest asked me to post this here to open up the discussion: I wanted to sync with you to map out the next steps of the graph implementation. It would be awesome if we could settle on a definition-of-done (DoD) for the initial version. I'm happy to add features and improve my work going forward, but I think having a milestone to work against will help a lot. There are several areas that I've worked on and that will require future work: Data modelOverall I think the data model is finished. Becaue of the use of flatbuffers we can easily add fields like edge and node weights in the future. There are currently some fields in the model like Graph ViewerThe basic graph viewer is working correctly. It has the following features:
The code for the graph viewer still requires quite a bit of cleanup as I was still experimenting with the different layout algorithms, but I think I have a pretty good idea on what needs to be done—and I'm currently working on that. Graph layoutsThis is the biggest outstanding area, as the existing crates in the Rust ecosystem are all lacking—I implemented layout providers for all apart from
Unfortunately, I think the features provided by the existing crates don't really suffice for our needs. Ideally we would want to have a Rust version of: https://d3js.org/d3-force. Porting it over should be pretty straight forward, as it is not too much code. To efficiently find collisions, we would also need a quadtree. As per @Wumpf we don't yet have an implementation in Rerun, and I don't know how good the existing implementations on crates.io are—do you have experience with quadtree crates in Rust? SummaryOverall, I don't think it makes sense to merge the graph primitives without having at least one basic (but robust) layout algorithm implemented to visualize them—we just need to consider if it is worth adding this additional complexity to Rerun. |
This implements basic graph primitives in the Rerun data model. This is a first step towards visualizing node-link diagrams in Rerun (related issue: #6898).
In addition to the changes to the data model, this PR adds two example crates,
node_link_graph
andgraph_view
to the Rust examples that show how these primitives can be used.Design Decisions
components
and can be batched. To have a single node per entity we can use Rerun’s [clamping mechanism](https://rerun.io/docs/concepts/batches#component-clamping).GraphNodeId
is modeled asstrings for better user experience.u32
to improve performance when usingpetgraph
GraphNodeId
and itsEntityPath
.labels
component and toggled viashow_labels
Logging example
TODOs
Get rid of theDefault
derive forGraphNodeId
andGraphEdge
in the flatbuffer definitions.Checklist
main
build: rerun.io/viewernightly
build: rerun.io/viewerCHANGELOG.md
and the migration guideTo run all checks from
main
, comment on the PR with@rerun-bot full-check
.