news 2026/9/16 10:48:57

Rerun GraphNodes 图节点 Archetype 完整指南:字段、坐标布局与 Python/Rust/C++ 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Rerun GraphNodes 图节点 Archetype 完整指南:字段、坐标布局与 Python/Rust/C++ 实战

Rerun GraphNodes 图节点 Archetype 完整指南:字段、坐标布局与 Python/Rust/C++ 实战

【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun

GraphNodes是 Rerun 中用于可视化图(Graph)数据的基础 archetype,它描述了一组带可选标签、颜色、位置与半径的图节点。本文以 docs/content/reference/types/archetypes/graph_nodes.md 为主体,结合仓库中三种语言(Python / Rust / C++)的生成实现与官方示例,讲解GraphNodes的每个字段、与GraphEdges的配合方式、可用的展示视图,以及它背后的类型定义与代码生成机制,帮助你在自己的多模态数据可视化流程中直接落地图结构数据。

GraphNodes 在 Rerun 数据模型中的定位

Rerun 采用“Archetype(原型)— Component(组件)— Batch(批次)”的分层数据模型:archetype 是面向用户的高层数据结构,由若干组件组成;组件描述单个属性,批处理则对应 Arrow 数组列。GraphNodes正是这样一类 archetype,用于"承载一张图中所有节点的描述"。

它的类型定义源头位于 crates/build/re_type_definitions/rerun/archetypes/graph_nodes.def.rs,这是一份由re_types_builder解析的 Rerun 类型定义(非可执行代码)。该定义文件同时标注了:

  • #[docs(category = "Graph")]:归属于 Graph 类别;
  • #[docs(view_types = "GraphView")]:主要面向GraphView展示;
  • #[rerun(state = "stable")]:API 状态为稳定;
  • #[rerun(visualizer = "GraphNodes")]:绑定同名 visualizer。

而面向最终用户的参考文档 graph_nodes.md 是由crates/build/re_types_builder/src/codegen/docs/website.rs自动生成的,因此文档中的字段列表与三种语言 SDK 的 API 始终保持一致——这保证了本文所述的字段结构即当前仓库各 SDK 的实际 API。

字段与组件类型对照

GraphNodes共包含 6 个字段:1 个必填字段 + 5 个可选字段。字段与底层组件的对应关系如下(依据 graph_nodes.md 与三种语言实现):

字段对应组件必填/可选说明
node_idsGraphNode必填节点 ID 列表,是节点唯一标识
positionsPosition2D可选节点的中心位置(二维坐标)
colorsColor可选节点的颜色
labelsText可选节点的文本标签
show_labelsShowLabels可选是否显示文本标签
radiiRadius可选节点的半径(大小)

从 Rust 生成实现 crates/store/re_sdk_types/src/archetypes/graph_nodes.rs 可以看到,编译器将组件分成三组注册:REQUIRED_COMPONENTS(仅node_ids)、RECOMMENDED_COMPONENTS(为空)、OPTIONAL_COMPONENTSpositionscolorslabelsshow_labelsradii共 5 个),总数NUM_COMPONENTS = 6。这说明除node_ids外,其余字段均可按需填充,未设置的字段不会写入数据流。

各字段详解

node_ids(必填):节点的身份

node_idsGraphNodes唯一必填字段,类型为GraphNode组件列表。它是每个节点的唯一标识,也是后续GraphEdges引用节点的"主键"。在 graph_nodes.def.rs 中该字段被标记为#[rerun(required)],同时带有#[rerun(no_ui_edit)](不参与 UI 编辑)。示例中节点 ID 通常为字符串(如"a""b""c"),但本质上它可以是任意可序列化的GraphNode值。

positions(可选):节点的坐标布局

positionsPosition2D组件列表,表示节点的中心位置,直接决定节点在 2D 空间中的摆放。定义注释将其描述为 "Optional center positions of the nodes"。

设置positions后,图将按你给定的坐标静态布局;不设置时,GraphView会启用内置的力导向布局(force-directed layout)自动排布节点,这对节点数量较多、没有明确空间语义的拓扑图尤其有用。

colors(可选):节点颜色

colorsColor组件列表,用于为节点着色。定义注释中的表述为 "Optional colors for the boxes",即作用于节点的填充色。每个节点可指定一个 RGBA 颜色值,也可只提供 RGB。

labels(可选)与 show_labels(可选):文本标签控制

labelsText组件列表,为每个节点附加一个文本标签;show_labelsShowLabels组件(单个布尔值),控制标签是否显示。两者在源码注释中有一处重要的自动行为说明(见 graph_nodes.def.rs 与 graph_nodes.rs):

If not set, labels will automatically appear when there is exactly one label for this entity or the number of instances on this entity is under a certain threshold. (若未显式设置,当该实体只有一个标签、或实体上的实例数量低于某个阈值时,标签会自动出现。)

也就是说,show_labels缺省时由 Rerun 根据数据规模自动决定是否展示标签,避免在大规模图(海量节点)时标签互相遮挡;当你需要强制显示或隐藏时,再显式传入该字段。

radii(可选):节点半径

radiiRadius组件列表,用于控制每个节点的绘制半径(大小)。它可以配合GraphView的碰撞力(collision force)使用——在 graph_view.md 中,force_collision_radius属性描述为"根据节点的半径解析节点包围球之间的碰撞",因此合理的半径设置会让布局更自然地避让重叠。

三种语言快速上手

仓库在 docs/snippets/all/archetypes/ 中提供了graph_undirected(无向图)与graph_directed(有向图)两个官方示例,分别有 Python、Rust、C++ 三个版本,并预生成了对应的.rrd录制文件(位于 tests/assets/rrd/snippets/archetypes/),可以直接用 Rerun Viewer 打开查看渲染结果。

无向图(默认类型)

Python(graph_undirected.py):

"""Log a simple undirected graph.""" import rerun as rr rr.init("rerun_example_graph_undirected", spawn=True) rr.log( "simple", rr.GraphNodes( node_ids=["a", "b", "c"], positions=[(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)], labels=["A", "B", "C"], ), rr.GraphEdges( edges=[("a", "b"), ("b", "c"), ("c", "a")], # Optional: graphs are undirected by default. graph_type="undirected", ), )

Rust(graph_undirected.rs):

//! Log a simple undirected graph. fn main() -> Result<(), Box<dyn std::error::Error>> { let rec = rerun::RecordingStreamBuilder::new("rerun_example_graph_undirected") .spawn()?; rec.log( "simple", &[ &rerun::GraphNodes::new(["a", "b", "c"]) .with_positions([(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)]) .with_labels(["A", "B", "C"]) as &dyn rerun::AsComponents, &rerun::GraphEdges::new([("a", "b"), ("b", "c"), ("c", "a")]) // Optional: graphs are undirected by default. .with_undirected_edges(), ], )?; Ok(()) }

C++(graph_undirected.cpp):

//! Log a simple undirected graph. #include <rerun.hpp> int main(int argc, char* argv[]) { const auto rec = rerun::RecordingStream("rerun_example_graph_undirected"); rec.spawn().exit_on_failure(); rec.log( "simple", rerun::GraphNodes({"a", "b", "c"}) .with_positions({{0.0, 100.0}, {-100.0, 0.0}, {100.0, 0.0}}) .with_labels({"A", "B", "C"}), rerun::GraphEdges({{"a", "b"}, {"b", "c"}, {"c", "a"}}) // Optional: graphs are undirected by default. .with_graph_type(rerun::GraphType::Undirected) ); }

三个示例把 3 个节点放在一个等边三角形的位置上((0, 100)(-100, 0)(100, 0)),并给出标签A/B/C,再用 3 条边a-bb-cc-a连成一个环。注意:无向图是默认行为,graph_type="undirected"一行是可选的。

有向图

有向图与无向图的唯一区别在于边方向的显式声明。Python(graph_directed.py):

"""Log a simple directed graph.""" import rerun as rr rr.init("rerun_example_graph_directed", spawn=True) rr.log( "simple", rr.GraphNodes( node_ids=["a", "b", "c"], positions=[(0.0, 100.0), (-100.0, 0.0), (100.0, 0.0)], labels=["A", "B", "C"], ), rr.GraphEdges( edges=[("a", "b"), ("b", "c"), ("c", "a")], graph_type="directed" ), )

Rust(graph_directed.rs)与 C++ 版本(见 rerun_cpp 中的 GraphNodes 头文件 内嵌示例)结构一致,Rust 使用.with_directed_edges(),C++ 使用.with_graph_type(rerun::GraphType::Directed)

从上述示例可以看出三个要点:

  1. GraphNodesGraphEdges是成对使用的:节点只负责"有哪些点",边的连接关系完全由GraphEdges决定;
  2. 节点 ID(node_ids)是GraphNodesGraphEdges之间建立关联的键——边的两个端点必须引用已存在的节点 ID;
  3. 无向/有向由GraphEdgesgraph_type控制,GraphNodes本身并不关心方向性。

在哪些视图中展示

依据 graph_nodes.md 的 "Can be shown in" 部分,GraphNodes可以在以下两种视图中展示:

  • GraphView:专门的图可视化视图,支持有向/无向图渲染与力导向布局;
  • DataframeView:表格视图,用于以行/列形式查看与查询节点数据。

GraphView 的布局与力学属性

GraphView 被标记为"不稳定类型"(可能在未来发生不向后兼容的变更),其核心属性包括:

  • background:图背景配置;
  • visual_bounds:可视范围,范围内的内容保证可见(范围外可能因 letterbox 效应部分可见);
  • force_link:控制由边连接的两个节点之间的相互作用力,含enabled(是否启用)、distance(目标距离)、iterations(每轮迭代应用次数);
  • force_many_body:模拟节点两两之间的"电荷"斥力,含enabledstrength(强度);
  • force_position:类似重力,把节点拉向指定位置,含enabledstrengthposition
  • force_collision_radius:按节点半径解析节点间碰撞,含enabledstrengthiterations
  • force_center:尝试将图的重心移到原点,含enabledstrength

当你不给GraphNodes设置positions时,正是这些力的组合在驱动节点自动布局。GraphView 可视化 archetype 的完整清单见 graph_view.md:GraphEdgesGraphNodes

源码实现探秘:一个 archetype 如何贯通三门语言

GraphNodes的三种语言 API 并非手写,而是由re_types_builder依据同一份类型定义 graph_nodes.def.rs 生成,这保证了跨语言行为一致:

  • Rust(crates/store/re_sdk_types/src/archetypes/graph_nodes.rs):实现了re_types_core::Archetypetrait,提供descriptor_*()系列方法返回各字段的ComponentDescriptor,并通过from_arrow_components从 Arrow 数组反序列化;此外还提供了columns()/columns_of_unit_batches()辅助方法,可把组件批按长度切分为列,配合RecordingStream::send_columns直接发送列式(columnar)数据。
  • Python(rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py):基于 attrs 定义GraphNodes类,构造函数接收node_idsUtf8ArrayLike)以及positionsVec2DArrayLike)、colorsRgba32ArrayLike)、labelsUtf8ArrayLike)、show_labelsBoolLike)、radiiFloat32ArrayLike)等可选参数;类方法columns()支持rr.send_columns的列式写入,from_fields(clear_unset=...)支持按字段增量更新与整体清除。该文件头部注释还提示可通过创建GraphNodesExt扩展类自定义行为。
  • C++(rerun_cpp/src/rerun/archetypes/graph_nodes.hpp):以结构体形式暴露字段(std::optional<ComponentBatch>),提供with_positionswith_labelswith_colorswith_show_labelswith_radii等链式构造方法,以及update_fields()/clear_fields()静态方法。

值得留意的是,Rust 实现中每个字段的ComponentDescriptor都带有archetype = "rerun.archetypes.GraphNodes"与组件路径(如"GraphNodes:node_ids"component_type = "rerun.components.GraphNode"),这构成了 Rerun 数据流中查询、索引与可视化匹配的基础——Viewer 正是通过这类描述符把记录数据路由到对应 visualizer(graph_nodes.rs 中可见VisualizableArchetype实现)。

实战建议与注意事项

  1. 务必保证节点 ID 一致GraphEdges的端点必须与GraphNodesnode_ids严格对应,否则边会因引用不存在的节点而无法渲染。建议在数据预处理阶段统一 ID 的规范化规则(如统一字符串格式)。
  2. 静态布局与自动布局的选择:如果数据本身带有空间语义(如机器人轨迹的拓扑、传感器拓扑图),显式传入positions可获得确定性的坐标布局;如果只关心连接关系,省略positions交给GraphView的力导向布局(可调force_link/force_many_body/force_position等)往往更省事。
  3. 利用标签自动显隐show_labels缺省时会按"单标签实体或实例数低于阈值"的规则自动显示,节点规模大时无需手动处理;需要强制开关时再显式设置。
  4. 批量写入考虑columns():当图结构随时间变化(时间序列图)时,Python 的GraphNodes.columns()或 Rust 的columns()可以把每个时间步的节点状态组织为列式数据,用send_columns一次性下发,性能优于逐帧log
  5. 验证渲染效果:仓库中已生成无向/有向图的参考录制文件 graph_undirected.rrd 与 graph_directed.rrd,可用 Rerun Viewer 打开对照你自己的渲染结果,快速排查位置、标签或边方向的问题。

总而言之,GraphNodes是 Rerun 图可视化的"节点半边":掌握它的 6 个字段、与GraphEdges的键值关联,以及GraphView的力学布局行为,你就能在 Rerun 中快速搭建起可交互、可查询的图结构数据看板,无论是简单拓扑、依赖关系图,还是机器人多模态数据中的关系网络。

【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 10:48:09

Workflow Connector MCP Server MCP 服务说明文档

1. 服务概述一句话简介&#xff1a;AI Agent工作流连接器MCP Server - 连接SaaS服务、创建自动化工作流、管理Webhook、提供工作流模板服务名称&#xff1a;Workflow Connector MCP Server版本号&#xff1a;最新版本开发者/提供方&#xff1a;zhaohongyuziranerran协议类型&am…

作者头像 李华
网站建设 2026/9/16 10:47:51

SpringBoot+微信小程序打造乐器社区平台实战

1. 项目背景与核心价值作为一个在Web开发领域摸爬滚打多年的老码农&#xff0c;我见过太多千篇一律的毕业设计项目。但这个乐器社区平台确实让我眼前一亮——它巧妙地将传统SpringBoot后端与微信小程序前端结合&#xff0c;打造了一个完整的乐器爱好者生态圈。不同于简单的CRUD…

作者头像 李华
网站建设 2026/9/16 10:47:45

GEO优化公司推荐:AI搜索长期合作怎么选

GEO优化公司推荐&#xff1a;AI搜索长期合作怎么选当用户打开豆包、元宝、DeepSeek问一句"哪个品牌靠谱"&#xff0c;AI给出的答案里有没有你&#xff0c;已经成为企业品牌增长的新分水岭。越来越多企业开始寻找GEO优化公司推荐相关的信息&#xff0c;但很多人还在用…

作者头像 李华
网站建设 2026/9/16 10:47:40

Ryzen AI MAX+ 395实测:125B MoE模型双后端部署与显存调优指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 10:46:44

CMSIS-4静态工程构建原理与迁移实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华