egui_graphs 自定义渲染完全指南:DisplayNode、DisplayEdge 与 DrawContext 实现专属图表外观 📅 发布时间:2026/8/26 20:08:23 👁 浏览次数: egui_graphs 自定义渲染完全指南DisplayNode、DisplayEdge 与 DrawContext 实现专属图表外观【免费下载链接】egui_graphsInteractive graph visualization widget for rust powered by egui and petgraph项目地址: https://gitcode.com/gh_mirrors/eg/egui_graphsegui_graphs是一款基于 Rust 的交互式图表可视化组件由 egui 与 petgraph 驱动。它的「自定义渲染」能力允许你替换默认渲染器通过DisplayNode、DisplayEdge与DrawContext三个核心类型自由定义节点形状、连线样式与鼠标命中区域做出只属于你应用的专属图表外观。本文面向新手用尽量少的代码讲清楚完整的定制流程。自定义渲染是什么先认识 3 个核心类型 一句话概括GraphView每帧都会调用你提供的「显示类型」来画图并做命中检测你只需要把画什么、算在哪里实现好。核心类型角色你能决定什么DisplayNode节点渲染器接口节点长什么样圆、方块、图标、边从哪里长出、鼠标是否点中DisplayEdge连线渲染器接口直线 / 曲线 / 自环怎么画、是否带箭头DrawContext每帧传给渲染器的上下文包坐标换算画布→屏幕、字体与主题、全局样式设置、画布绘制器两个 trait 定义在 displays.rs上下文结构体定义在 drawer.rs。官方默认实现圆形节点 直线/曲线/自环连线是最佳的模板代码建议直接参照默认节点displays_default/node.rs默认连线displays_default/edge.rs快速上手克隆项目并运行自定义示例 git clone https://gitcode.com/gh_mirrors/eg/egui_graphs cd egui_graphs cargo run --release --example basic_custombasic_custom演示了最轻量的外观定制常显标签更多可运行示例集中在 examples 目录其中 basic_custom.rs 是最值得先读的起步文件。DrawContext自定义渲染能拿到哪些数据 DrawContext是渲染器与世界之间的唯一窗口共 5 个字段字段类型用途ctxegui::Context全局上下文字体排布、主题、视觉样式选中/未选中的前景色等painteregui::Painter底层绘制入口你的Shape由框架统一提交给它styleSettingsStyle图级样式设置labels_always()、resolve_node_stroke()、resolve_edge_stroke()is_directedbool当前是否是有向图用来决定是否画箭头metaMetadataFrame坐标系换算canvas_to_screen_pos/canvas_to_screen_size⚠️ 新手最常踩的坑一定要用ctx.meta做画布坐标 → 屏幕坐标的换算。节点位置、尺寸都是画布坐标直接当屏幕坐标用缩放和平移就会全部失效。DisplayNode实现专属节点外观的 4 个方法DisplayNode要求你的类型实现Clone、FromNodePropsN从节点数据构造显示对象以及以下 4 个方法详见 displays.rs方法何时被调用你要做的事shapes(mut self, ctx) - VecShape每帧返回 egui 的Shape列表即节点的长相update(mut self, state)每帧从NodeProps同步位置、标签、选中/拖拽/悬停状态closest_boundary_point(dir)画边之前返回dir方向上形状边界最近的点让边的端点吸附到节点边缘is_inside(pos)交互时命中检测判断画布坐标pos是否落在节点内节点显示对象通常只保留绘制所需的状态例如#[derive(Clone)] struct SquareNode { pos: Pos2, // 画布坐标 radius: f32, label: String, selected: bool, }在shapes()里记住三个必做动作换算坐标ctx.meta.canvas_to_screen_pos(self.pos)、ctx.meta.canvas_to_screen_size(self.radius)尊重标签策略只在ctx.style.labels_always()或节点被选中/悬停/拖拽时才画文字标签行为才和默认渲染器一致尊重描边钩子通过ctx.style.resolve_node_stroke(...)获取轮廓Stroke用户注册的样式钩子才会生效。DisplayEdge实现专属连线外观DisplayEdge与节点类似定义见 displays.rs但shapes()会额外收到起点与终点两个Node引用方法作用shapes(start, end, ctx)绘制连线用start.display().closest_boundary_point(dir)取边界锚点update(state)每帧同步order平行边序号、selected、labelis_inside(start, end, pos)边是否被鼠标点中直线/曲线/自环各有算法extra_bounds(start, end)可选返回曲线/自环超出节点范围的包围盒让适应屏幕更精准 不用重复造轮子公开的EdgeShapeBuilder、EdgeShapePropsStraight/Curved/Looped三种几何和TipProps箭头尺寸与角度可以直接复用默认渲染器的贝塞尔与箭头计算见 displays_default 模块。是否加箭头由ctx.is_directed决定。不想重写渲染器用 SettingsStyle 钩子轻定制如果你只想微调外观比如选中时描边加粗不必实现完整的显示类型。SettingsStyle提供了两个样式钩子定义于 settings.rsSettingsStyle::new() .with_labels_always(true) .with_node_stroke_hook(|selected, _dragged, _color, mut stroke, _style| { if selected { stroke.width 3.0; } stroke })配合DefaultGraphView::new().with_styles(style)即可应用完整写法参考 basic_custom.rs。把自定义渲染器接入 GraphView 的步骤实现显示类型为你的SquareNode实现DisplayNode如需换边再实现DisplayEdge构造图时带上类型参数显示类型是Graph泛型的一部分可借助 helpers.rs 中的to_graph_custom/add_node_custom/add_edge_custom完成转换照常显示GraphView::状态, 布局::new().show(ui, mut graph)—— 视图代码完全不变graph_view.rs 中的渲染流程会自动调用你的update与shapes顺序为同步节点 → 画边 → 画节点 → 置顶绘制选中项。核心源码文件导航 路径内容crates/egui_graphs/src/draw/mod.rsDisplayNode/DisplayEdge/DrawContext等公开导出crates/egui_graphs/src/draw/displays.rs两个渲染器 trait 的完整定义与文档crates/egui_graphs/src/draw/drawer.rsDrawContext与每帧渲染流程crates/egui_graphs/src/draw/displays_default/默认渲染器node.rs、edge.rs、edge_shape.rscrates/egui_graphs/src/settings.rsSettingsStyle与描边钩子crates/egui_graphs/src/graph_view.rsGraphView主体与DefaultGraphView别名crates/egui_graphs/examples/一组可运行示例basic、basic_custom、undirected 等README.md快速上手与布局机制总览总结如何选择合适的定制方案 ✅只调轮廓、标签显示策略→ 用SettingsStyle钩子代码量最小改节点形状或连线几何→ 实现DisplayNode/DisplayEdge务必通过ctx.meta做坐标换算、通过ctx.style尊重全局样式不确定怎么画→ 先读displays_default/下的默认实现它同时是行为基准与模板代码。egui_graphs 处于稳定维护状态官方建议直接 fork 后按需修改。掌握这 3 个类型后从默认小圆点到专属品牌化图表只差一次 trait 实现了。【免费下载链接】egui_graphsInteractive graph visualization widget for rust powered by egui and petgraph项目地址: https://gitcode.com/gh_mirrors/eg/egui_graphs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考