egui-map
An egui widget that renders an interactive 2D map and displays information about it.
Features
- Pan with click & drag, and zoom with the mouse wheel (hold
Ctrl— orCmdon macOS — to zoom faster) or the built-in slider. - Spatial indexing via kd-tree: only the nodes inside the viewport are painted each frame.
- Node names with configurable visibility rules (always / on hover / hidden).
- Connection lines between nodes and free-floating text labels.
- Text is sized in screen pixels (
MapSettings::node_text_size,MapSettings::label_text_size), so names stay readable at any zoom level instead of shrinking away as you zoom out. - Animations attached per node through
map.node(id): one-off events that end on their own (pulse,ripple,countdown,scale_in,crosshair) and lasting state that runs untilclear()(halo,blink,orbit), each with an optionalcolor(). The effects live inmap::animation::Animationand can be reused from your ownNodeTemplate. - Custom node rendering and right-click context menus through the
NodeTemplateandContextMenuManagertraits. - Built-in light and dark themes, customizable through
MapSettings.
Usage
Add the dependency:
[]
= "0.0"
Feed the map a set of nodes and add it to your UI:
use Map;
use ;
use HashMap;
// Build the node set, keyed by node id.
let mut points: = new;
points.insert;
points.insert;
let mut map = new;
map.add_hashmap_points;
// Then, on every frame of your egui update loop:
// ui.add(&mut map);
Connecting nodes with lines
Lines are wired in three steps: create the nodes, register a unique connection id in the connections of both endpoints, and load the line geometry keyed by that same id:
use ;
use HashMap;
let mut points: = new;
points.insert;
points.insert;
// Register the connection id on both endpoints.
for id in
map.add_hashmap_points;
// Line geometry, keyed by the same connection id.
let mut lines: = new;
lines.insert;
map.add_lines;
A line is only drawn while the zoom level is above MapSettings::line_visible_zoom and its bounding box intersects the viewport. Segments are culled broad-phase with an R-tree, so long lines crossing the view are drawn even when both endpoints lie outside of it.
Custom node rendering and animations
Implement NodeTemplate to take over how nodes, selection highlights, notifications and markers are drawn — including the name labels, which the widget no longer paints once a template is installed:
use ;
use ;
use Instant;
;
map.set_node_template;
See the NodeTemplate rustdoc for a complete example with a custom node shape and an animated notification.
Crate features
debug_overlay: adds a read-out of the widget's internal viewport state (bounds, current position, distance, zoom, node counts, pointer position). It stays out of the way: a dimdbgtoggle in the map's top-left corner, collapsed by default and with no background of its own, that you click open when you need the numbers. egui remembers the open/closed state per widget, and the overlay never affects the map's layout.
Profiling
The widget's hot paths (rendering, viewport culling, point/line loading) are instrumented with tracing spans. tracing is a normal, unconditional dependency of this crate, and the spans are cheap no-ops unless a subscriber is installed somewhere in your binary -- egui-map never installs one itself.
To see these spans in the Tracy profiler, install a tracing_tracy::TracyLayer in your own main, e.g.:
registry
.with
.init;
The profile feature pulls in tracing-subscriber and tracing-tracy so examples/tracy_profile.rs can demonstrate exactly this. Run it (with a Tracy capture window already listening) with:
License
MIT. See LICENSE.md.