dear_implot/
lib.rs

1//! # Dear ImPlot - Rust Bindings with Dear ImGui Compatibility
2//!
3//! High-level Rust bindings for ImPlot, the immediate mode plotting library.
4//! This crate provides safe, idiomatic Rust bindings designed to work seamlessly
5//! with dear-imgui (C++ bindgen) rather than imgui-rs (cimgui).
6//!
7//! ## Features
8//!
9//! - Safe, idiomatic Rust API
10//! - Full compatibility with dear-imgui
11//! - Builder pattern for plots and plot elements
12//! - Memory-safe string handling
13//! - Support for all major plot types
14//!
15//! ## Quick Start
16//!
17//! ```no_run
18//! use dear_imgui_rs::*;
19//! use dear_implot::*;
20//!
21//! let mut ctx = Context::create();
22//! let mut plot_ctx = PlotContext::create(&ctx);
23//!
24//! let ui = ctx.frame();
25//! let plot_ui = plot_ctx.get_plot_ui(&ui);
26//!
27//! if let Some(token) = plot_ui.begin_plot("My Plot") {
28//!     plot_ui.plot_line("Line", &[1.0, 2.0, 3.0, 4.0], &[1.0, 4.0, 2.0, 3.0]);
29//!     token.end();
30//! }
31//! ```
32//!
33//! ## Integration with Dear ImGui
34//!
35//! This crate is designed to work with the `dear-imgui-rs` ecosystem:
36//! - Uses the same context management patterns
37//! - Compatible with dear-imgui's UI tokens and lifetime management
38//! - Shares the same underlying Dear ImGui context
39
40use dear_implot_sys as sys;
41
42// Bindgen output for `dear-implot-sys` can fluctuate between historical
43// out-parameter signatures and the newer return-by-value signatures depending
44// on which generated `OUT_DIR` file rust-analyzer happens to index.
45//
46// Keep the wrapper crate stable by calling a local extern declaration for the
47// specific APIs we expose.
48#[allow(non_snake_case)]
49pub(crate) mod compat_ffi {
50    use super::sys;
51
52    unsafe extern "C" {
53        pub fn ImPlot_GetPlotPos() -> sys::ImVec2;
54        pub fn ImPlot_GetPlotSize() -> sys::ImVec2;
55    }
56}
57
58// Re-export essential types
59pub use dear_imgui_rs::{Context, Ui};
60pub use sys::{ImPlotPoint, ImPlotRange, ImPlotRect};
61pub use sys::{ImTextureID, ImVec2, ImVec4};
62
63mod advanced;
64mod context;
65mod style;
66mod utils;
67
68// New modular plot types
69pub mod plots;
70
71pub use context::*;
72pub use style::*;
73pub use utils::*;
74
75// Re-export new modular plot types for convenience
76pub use plots::{
77    Plot, PlotData, PlotError,
78    bar::{BarPlot, PositionalBarPlot},
79    error_bars::{AsymmetricErrorBarsPlot, ErrorBarsPlot, SimpleErrorBarsPlot},
80    heatmap::{HeatmapPlot, HeatmapPlotF32},
81    histogram::{Histogram2DPlot, HistogramPlot},
82    line::{LinePlot, SimpleLinePlot},
83    pie::{PieChartPlot, PieChartPlotF32},
84    scatter::{ScatterPlot, SimpleScatterPlot},
85    shaded::{ShadedBetweenPlot, ShadedPlot, SimpleShadedPlot},
86    stems::{SimpleStemPlot, StemPlot},
87};
88
89// Constants
90const IMPLOT_AUTO: i32 = -1;
91
92/// Choice of Y axis for multi-axis plots
93#[derive(Clone, Copy, Debug, PartialEq, Eq)]
94#[repr(u32)]
95pub enum YAxisChoice {
96    First = 0,
97    Second = 1,
98    Third = 2,
99}
100
101/// Convert an Option<YAxisChoice> into an i32. Picks IMPLOT_AUTO for None.
102fn y_axis_choice_option_to_i32(y_axis_choice: Option<YAxisChoice>) -> i32 {
103    match y_axis_choice {
104        Some(choice) => choice as i32,
105        None => IMPLOT_AUTO,
106    }
107}
108
109/// X axis selector matching ImPlot's ImAxis values
110#[derive(Clone, Copy, Debug, PartialEq, Eq)]
111#[repr(i32)]
112pub enum XAxis {
113    X1 = 0,
114    X2 = 1,
115    X3 = 2,
116}
117
118/// Y axis selector matching ImPlot's ImAxis values
119#[derive(Clone, Copy, Debug, PartialEq, Eq)]
120#[repr(i32)]
121pub enum YAxis {
122    Y1 = 3,
123    Y2 = 4,
124    Y3 = 5,
125}
126
127impl YAxis {
128    /// Convert a Y axis (Y1..Y3) to the 0-based index used by ImPlotPlot_YAxis_Nil
129    pub(crate) fn to_index(self) -> i32 {
130        (self as i32) - 3
131    }
132}
133
134/// Ui extension for obtaining a PlotUi from an ImPlot PlotContext
135pub trait ImPlotExt {
136    fn implot<'ui>(&'ui self, ctx: &'ui PlotContext) -> PlotUi<'ui>;
137}
138
139impl ImPlotExt for Ui {
140    fn implot<'ui>(&'ui self, ctx: &'ui PlotContext) -> PlotUi<'ui> {
141        ctx.get_plot_ui(self)
142    }
143}
144
145/// Markers for plot points
146#[repr(i32)]
147#[derive(Copy, Clone, Debug, PartialEq, Eq)]
148pub enum Marker {
149    None = sys::ImPlotMarker_None,
150    Circle = sys::ImPlotMarker_Circle,
151    Square = sys::ImPlotMarker_Square,
152    Diamond = sys::ImPlotMarker_Diamond,
153    Up = sys::ImPlotMarker_Up,
154    Down = sys::ImPlotMarker_Down,
155    Left = sys::ImPlotMarker_Left,
156    Right = sys::ImPlotMarker_Right,
157    Cross = sys::ImPlotMarker_Cross,
158    Plus = sys::ImPlotMarker_Plus,
159    Asterisk = sys::ImPlotMarker_Asterisk,
160}
161
162/// Colorable plot elements
163#[repr(u32)]
164#[derive(Copy, Clone, Debug, PartialEq, Eq)]
165pub enum PlotColorElement {
166    Line = sys::ImPlotCol_Line as u32,
167    Fill = sys::ImPlotCol_Fill as u32,
168    MarkerOutline = sys::ImPlotCol_MarkerOutline as u32,
169    MarkerFill = sys::ImPlotCol_MarkerFill as u32,
170    ErrorBar = sys::ImPlotCol_ErrorBar as u32,
171    FrameBg = sys::ImPlotCol_FrameBg as u32,
172    PlotBg = sys::ImPlotCol_PlotBg as u32,
173    PlotBorder = sys::ImPlotCol_PlotBorder as u32,
174    LegendBg = sys::ImPlotCol_LegendBg as u32,
175    LegendBorder = sys::ImPlotCol_LegendBorder as u32,
176    LegendText = sys::ImPlotCol_LegendText as u32,
177    TitleText = sys::ImPlotCol_TitleText as u32,
178    InlayText = sys::ImPlotCol_InlayText as u32,
179    AxisText = sys::ImPlotCol_AxisText as u32,
180    AxisGrid = sys::ImPlotCol_AxisGrid as u32,
181    AxisTick = sys::ImPlotCol_AxisTick as u32,
182    AxisBg = sys::ImPlotCol_AxisBg as u32,
183    AxisBgHovered = sys::ImPlotCol_AxisBgHovered as u32,
184    AxisBgActive = sys::ImPlotCol_AxisBgActive as u32,
185    Selection = sys::ImPlotCol_Selection as u32,
186    Crosshairs = sys::ImPlotCol_Crosshairs as u32,
187}
188
189/// Built-in colormaps
190#[repr(u32)]
191#[derive(Copy, Clone, Debug, PartialEq, Eq)]
192pub enum Colormap {
193    Deep = sys::ImPlotColormap_Deep as u32,
194    Dark = sys::ImPlotColormap_Dark as u32,
195    Pastel = sys::ImPlotColormap_Pastel as u32,
196    Paired = sys::ImPlotColormap_Paired as u32,
197    Viridis = sys::ImPlotColormap_Viridis as u32,
198    Plasma = sys::ImPlotColormap_Plasma as u32,
199    Hot = sys::ImPlotColormap_Hot as u32,
200    Cool = sys::ImPlotColormap_Cool as u32,
201    Pink = sys::ImPlotColormap_Pink as u32,
202    Jet = sys::ImPlotColormap_Jet as u32,
203}
204
205/// Plot location for legends, labels, etc.
206#[repr(u32)]
207#[derive(Copy, Clone, Debug, PartialEq, Eq)]
208pub enum PlotLocation {
209    Center = sys::ImPlotLocation_Center as u32,
210    North = sys::ImPlotLocation_North as u32,
211    South = sys::ImPlotLocation_South as u32,
212    West = sys::ImPlotLocation_West as u32,
213    East = sys::ImPlotLocation_East as u32,
214    NorthWest = sys::ImPlotLocation_NorthWest as u32,
215    NorthEast = sys::ImPlotLocation_NorthEast as u32,
216    SouthWest = sys::ImPlotLocation_SouthWest as u32,
217    SouthEast = sys::ImPlotLocation_SouthEast as u32,
218}
219
220/// Plot orientation
221#[repr(u32)]
222#[derive(Copy, Clone, Debug, PartialEq, Eq)]
223pub enum PlotOrientation {
224    Horizontal = 0,
225    Vertical = 1,
226}
227
228/// Binning methods for histograms
229#[repr(i32)]
230#[derive(Copy, Clone, Debug, PartialEq, Eq)]
231pub enum BinMethod {
232    Sqrt = -1,
233    Sturges = -2,
234    Rice = -3,
235    Scott = -4,
236}
237
238// Plot flags for different plot types
239bitflags::bitflags! {
240    /// Flags for heatmap plots
241    pub struct HeatmapFlags: u32 {
242        const NONE = sys::ImPlotHeatmapFlags_None as u32;
243        const COL_MAJOR = sys::ImPlotHeatmapFlags_ColMajor as u32;
244    }
245}
246
247bitflags::bitflags! {
248    /// Flags for histogram plots
249    pub struct HistogramFlags: u32 {
250        const NONE = sys::ImPlotHistogramFlags_None as u32;
251        const HORIZONTAL = sys::ImPlotHistogramFlags_Horizontal as u32;
252        const CUMULATIVE = sys::ImPlotHistogramFlags_Cumulative as u32;
253        const DENSITY = sys::ImPlotHistogramFlags_Density as u32;
254        const NO_OUTLIERS = sys::ImPlotHistogramFlags_NoOutliers as u32;
255        const COL_MAJOR = sys::ImPlotHistogramFlags_ColMajor as u32;
256    }
257}
258
259bitflags::bitflags! {
260    /// Flags for pie chart plots
261    pub struct PieChartFlags: u32 {
262        const NONE = sys::ImPlotPieChartFlags_None as u32;
263        const NORMALIZE = sys::ImPlotPieChartFlags_Normalize as u32;
264        const IGNORE_HIDDEN = sys::ImPlotPieChartFlags_IgnoreHidden as u32;
265        const EXPLODING = sys::ImPlotPieChartFlags_Exploding as u32;
266    }
267}
268
269bitflags::bitflags! {
270    /// Flags for line plots
271    pub struct LineFlags: u32 {
272        const NONE = sys::ImPlotLineFlags_None as u32;
273        const SEGMENTS = sys::ImPlotLineFlags_Segments as u32;
274        const LOOP = sys::ImPlotLineFlags_Loop as u32;
275        const SKIP_NAN = sys::ImPlotLineFlags_SkipNaN as u32;
276        const NO_CLIP = sys::ImPlotLineFlags_NoClip as u32;
277        const SHADED = sys::ImPlotLineFlags_Shaded as u32;
278    }
279}
280
281bitflags::bitflags! {
282    /// Flags for scatter plots
283    pub struct ScatterFlags: u32 {
284        const NONE = sys::ImPlotScatterFlags_None as u32;
285        const NO_CLIP = sys::ImPlotScatterFlags_NoClip as u32;
286    }
287}
288
289bitflags::bitflags! {
290    /// Flags for bar plots
291    pub struct BarsFlags: u32 {
292        const NONE = sys::ImPlotBarsFlags_None as u32;
293        const HORIZONTAL = sys::ImPlotBarsFlags_Horizontal as u32;
294    }
295}
296
297bitflags::bitflags! {
298    /// Flags for shaded plots
299    pub struct ShadedFlags: u32 {
300        const NONE = sys::ImPlotShadedFlags_None as u32;
301    }
302}
303
304bitflags::bitflags! {
305    /// Flags for stem plots
306    pub struct StemsFlags: u32 {
307        const NONE = sys::ImPlotStemsFlags_None as u32;
308        const HORIZONTAL = sys::ImPlotStemsFlags_Horizontal as u32;
309    }
310}
311
312bitflags::bitflags! {
313    /// Flags for error bar plots
314    pub struct ErrorBarsFlags: u32 {
315        const NONE = sys::ImPlotErrorBarsFlags_None as u32;
316        const HORIZONTAL = sys::ImPlotErrorBarsFlags_Horizontal as u32;
317    }
318}
319
320bitflags::bitflags! {
321    /// Flags for stairs plots
322    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
323    pub struct StairsFlags: u32 {
324        const NONE = sys::ImPlotStairsFlags_None as u32;
325        const PRE_STEP = sys::ImPlotStairsFlags_PreStep as u32;
326        const SHADED = sys::ImPlotStairsFlags_Shaded as u32;
327    }
328}
329
330bitflags::bitflags! {
331    /// Flags for bar groups plots
332    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
333    pub struct BarGroupsFlags: u32 {
334        const NONE = sys::ImPlotBarGroupsFlags_None as u32;
335        const HORIZONTAL = sys::ImPlotBarGroupsFlags_Horizontal as u32;
336        const STACKED = sys::ImPlotBarGroupsFlags_Stacked as u32;
337    }
338}
339
340bitflags::bitflags! {
341    /// Flags for digital plots
342    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
343    pub struct DigitalFlags: u32 {
344        const NONE = sys::ImPlotDigitalFlags_None as u32;
345    }
346}
347
348bitflags::bitflags! {
349    /// Flags for text plots
350    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
351    pub struct TextFlags: u32 {
352        const NONE = sys::ImPlotTextFlags_None as u32;
353        const VERTICAL = sys::ImPlotTextFlags_Vertical as u32;
354    }
355}
356
357bitflags::bitflags! {
358    /// Flags for dummy plots
359    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
360    pub struct DummyFlags: u32 {
361        const NONE = sys::ImPlotDummyFlags_None as u32;
362    }
363}
364
365bitflags::bitflags! {
366    /// Flags for drag tools (points/lines)
367    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
368    pub struct DragToolFlags: u32 {
369        const NONE = sys::ImPlotDragToolFlags_None as u32;
370        const NO_CURSORS = sys::ImPlotDragToolFlags_NoCursors as u32;
371        const NO_FIT = sys::ImPlotDragToolFlags_NoFit as u32;
372        const NO_INPUTS = sys::ImPlotDragToolFlags_NoInputs as u32;
373        const DELAYED = sys::ImPlotDragToolFlags_Delayed as u32;
374    }
375}
376
377bitflags::bitflags! {
378    /// Flags for infinite lines plots
379    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
380    pub struct InfLinesFlags: u32 {
381        const NONE = sys::ImPlotInfLinesFlags_None as u32;
382        const HORIZONTAL = sys::ImPlotInfLinesFlags_Horizontal as u32;
383    }
384}
385
386bitflags::bitflags! {
387    /// Flags for image plots
388    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
389    pub struct ImageFlags: u32 {
390        const NONE = sys::ImPlotImageFlags_None as u32;
391    }
392}
393
394bitflags::bitflags! {
395    /// Axis flags matching ImPlotAxisFlags_ (see cimplot.h)
396    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
397    pub struct AxisFlags: u32 {
398        const NONE           = sys::ImPlotAxisFlags_None as u32;
399        const NO_LABEL       = sys::ImPlotAxisFlags_NoLabel as u32;
400        const NO_GRID_LINES  = sys::ImPlotAxisFlags_NoGridLines as u32;
401        const NO_TICK_MARKS  = sys::ImPlotAxisFlags_NoTickMarks as u32;
402        const NO_TICK_LABELS = sys::ImPlotAxisFlags_NoTickLabels as u32;
403        const NO_INITIAL_FIT = sys::ImPlotAxisFlags_NoInitialFit as u32;
404        const NO_MENUS       = sys::ImPlotAxisFlags_NoMenus as u32;
405        const NO_SIDE_SWITCH = sys::ImPlotAxisFlags_NoSideSwitch as u32;
406        const NO_HIGHLIGHT   = sys::ImPlotAxisFlags_NoHighlight as u32;
407        const OPPOSITE       = sys::ImPlotAxisFlags_Opposite as u32;
408        const FOREGROUND     = sys::ImPlotAxisFlags_Foreground as u32;
409        const INVERT         = sys::ImPlotAxisFlags_Invert as u32;
410        const AUTO_FIT       = sys::ImPlotAxisFlags_AutoFit as u32;
411        const RANGE_FIT      = sys::ImPlotAxisFlags_RangeFit as u32;
412        const PAN_STRETCH    = sys::ImPlotAxisFlags_PanStretch as u32;
413        const LOCK_MIN       = sys::ImPlotAxisFlags_LockMin as u32;
414        const LOCK_MAX       = sys::ImPlotAxisFlags_LockMax as u32;
415    }
416}
417
418/// Plot condition (setup/next) matching ImPlotCond (ImGuiCond)
419#[derive(Clone, Copy, Debug, PartialEq, Eq)]
420#[repr(i32)]
421pub enum PlotCond {
422    None = 0,
423    Always = 1,
424    Once = 2,
425}
426
427// Re-export all plot types for convenience
428pub use plots::*;
429
430// Re-export advanced features (explicit to avoid AxisFlags name clash)
431pub use advanced::{
432    LegendFlags, LegendLocation, LegendManager, LegendToken, MultiAxisPlot, MultiAxisToken,
433    SubplotFlags, SubplotGrid, SubplotToken, YAxisConfig,
434};