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// Re-export essential types
43pub use dear_imgui_rs::{Context, Ui};
44pub use sys::{ImPlotPoint, ImPlotRange, ImPlotRect};
45pub use sys::{ImTextureID, ImVec2, ImVec4};
46
47mod advanced;
48mod context;
49mod plot;
50
51mod style;
52mod utils;
53
54// New modular plot types
55pub mod plots;
56
57pub use context::*;
58pub use plot::*;
59pub use style::*;
60pub use utils::*;
61
62// Re-export new modular plot types for convenience
63pub use plots::{
64    Plot, PlotData, PlotError,
65    bar::{BarPlot, PositionalBarPlot},
66    error_bars::{AsymmetricErrorBarsPlot, ErrorBarsPlot, SimpleErrorBarsPlot},
67    heatmap::{HeatmapPlot, HeatmapPlotF32},
68    histogram::{Histogram2DPlot, HistogramPlot},
69    line::{LinePlot, SimpleLinePlot},
70    pie::{PieChartPlot, PieChartPlotF32},
71    scatter::{ScatterPlot, SimpleScatterPlot},
72    shaded::{ShadedBetweenPlot, ShadedPlot, SimpleShadedPlot},
73    stems::{SimpleStemPlot, StemPlot},
74};
75
76// Constants
77const IMPLOT_AUTO: i32 = -1;
78
79/// Choice of Y axis for multi-axis plots
80#[derive(Clone, Copy, Debug, PartialEq, Eq)]
81#[repr(u32)]
82pub enum YAxisChoice {
83    First = 0,
84    Second = 1,
85    Third = 2,
86}
87
88/// Convert an Option<YAxisChoice> into an i32. Picks IMPLOT_AUTO for None.
89fn y_axis_choice_option_to_i32(y_axis_choice: Option<YAxisChoice>) -> i32 {
90    match y_axis_choice {
91        Some(choice) => choice as i32,
92        None => IMPLOT_AUTO,
93    }
94}
95
96/// X axis selector matching ImPlot's ImAxis values
97#[derive(Clone, Copy, Debug, PartialEq, Eq)]
98#[repr(i32)]
99pub enum XAxis {
100    X1 = 0,
101    X2 = 1,
102    X3 = 2,
103}
104
105/// Y axis selector matching ImPlot's ImAxis values
106#[derive(Clone, Copy, Debug, PartialEq, Eq)]
107#[repr(i32)]
108pub enum YAxis {
109    Y1 = 3,
110    Y2 = 4,
111    Y3 = 5,
112}
113
114impl YAxis {
115    /// Convert a Y axis (Y1..Y3) to the 0-based index used by ImPlotPlot_YAxis_Nil
116    pub(crate) fn to_index(self) -> i32 {
117        (self as i32) - 3
118    }
119}
120
121/// Ui extension for obtaining a PlotUi from an ImPlot PlotContext
122pub trait ImPlotExt {
123    fn implot<'ui>(&'ui self, ctx: &'ui PlotContext) -> PlotUi<'ui>;
124}
125
126impl ImPlotExt for Ui {
127    fn implot<'ui>(&'ui self, ctx: &'ui PlotContext) -> PlotUi<'ui> {
128        ctx.get_plot_ui(self)
129    }
130}
131
132/// Markers for plot points
133#[repr(i32)]
134#[derive(Copy, Clone, Debug, PartialEq, Eq)]
135pub enum Marker {
136    None = sys::ImPlotMarker_None,
137    Circle = sys::ImPlotMarker_Circle,
138    Square = sys::ImPlotMarker_Square,
139    Diamond = sys::ImPlotMarker_Diamond,
140    Up = sys::ImPlotMarker_Up,
141    Down = sys::ImPlotMarker_Down,
142    Left = sys::ImPlotMarker_Left,
143    Right = sys::ImPlotMarker_Right,
144    Cross = sys::ImPlotMarker_Cross,
145    Plus = sys::ImPlotMarker_Plus,
146    Asterisk = sys::ImPlotMarker_Asterisk,
147}
148
149/// Colorable plot elements
150#[repr(u32)]
151#[derive(Copy, Clone, Debug, PartialEq, Eq)]
152pub enum PlotColorElement {
153    Line = 0,
154    Fill = 1,
155    MarkerOutline = 2,
156    MarkerFill = 3,
157    ErrorBar = 4,
158    FrameBg = 5,
159    PlotBg = 6,
160    PlotBorder = 7,
161    LegendBackground = 8,
162    LegendBorder = 9,
163    LegendText = 10,
164    TitleText = 11,
165    InlayText = 12,
166    XAxis = 13,
167    XAxisGrid = 14,
168    YAxis = 15,
169    YAxisGrid = 16,
170    YAxis2 = 17,
171    YAxisGrid2 = 18,
172    YAxis3 = 19,
173    YAxisGrid3 = 20,
174    Selection = 21,
175    Crosshairs = 22,
176    Query = 23,
177}
178
179/// Built-in colormaps
180#[repr(u32)]
181#[derive(Copy, Clone, Debug, PartialEq, Eq)]
182pub enum Colormap {
183    Deep = 0,
184    Dark = 1,
185    Pastel = 2,
186    Paired = 3,
187    Viridis = 4,
188    Plasma = 5,
189    Hot = 6,
190    Cool = 7,
191    Pink = 8,
192    Jet = 9,
193}
194
195/// Plot location for legends, labels, etc.
196#[repr(u32)]
197#[derive(Copy, Clone, Debug, PartialEq, Eq)]
198pub enum PlotLocation {
199    Center = 0,
200    North = 1,
201    South = 2,
202    West = 4,
203    East = 8,
204    NorthWest = 5,
205    NorthEast = 9,
206    SouthWest = 6,
207    SouthEast = 10,
208}
209
210/// Plot orientation
211#[repr(u32)]
212#[derive(Copy, Clone, Debug, PartialEq, Eq)]
213pub enum PlotOrientation {
214    Horizontal = 0,
215    Vertical = 1,
216}
217
218/// Binning methods for histograms
219#[repr(i32)]
220#[derive(Copy, Clone, Debug, PartialEq, Eq)]
221pub enum BinMethod {
222    Sqrt = -1,
223    Sturges = -2,
224    Rice = -3,
225    Scott = -4,
226}
227
228// Plot flags for different plot types
229bitflags::bitflags! {
230    /// Flags for heatmap plots
231    pub struct HeatmapFlags: u32 {
232        const NONE = 0;
233        const COL_MAJOR = 1 << 10;
234    }
235}
236
237bitflags::bitflags! {
238    /// Flags for histogram plots
239    pub struct HistogramFlags: u32 {
240        const NONE = 0;
241        const HORIZONTAL = 1 << 10;
242        const CUMULATIVE = 1 << 11;
243        const DENSITY = 1 << 12;
244        const NO_OUTLIERS = 1 << 13;
245        const COL_MAJOR = 1 << 14;
246    }
247}
248
249bitflags::bitflags! {
250    /// Flags for pie chart plots
251    pub struct PieChartFlags: u32 {
252        const NONE = 0;
253        const NORMALIZE = 1 << 10;
254        const IGNORE_HIDDEN = 1 << 11;
255        const EXPLODING = 1 << 12;
256    }
257}
258
259bitflags::bitflags! {
260    /// Flags for line plots
261    pub struct LineFlags: u32 {
262        const NONE = 0;
263        const SEGMENTS = 1 << 10;
264        const LOOP = 1 << 11;
265        const SKIP_NAN = 1 << 12;
266        const NO_CLIP = 1 << 13;
267        const SHADED = 1 << 14;
268    }
269}
270
271bitflags::bitflags! {
272    /// Flags for scatter plots
273    pub struct ScatterFlags: u32 {
274        const NONE = 0;
275        const NO_CLIP = 1 << 10;
276    }
277}
278
279bitflags::bitflags! {
280    /// Flags for bar plots
281    pub struct BarsFlags: u32 {
282        const NONE = 0;
283        const HORIZONTAL = 1 << 10;
284    }
285}
286
287bitflags::bitflags! {
288    /// Flags for shaded plots
289    pub struct ShadedFlags: u32 {
290        const NONE = 0;
291    }
292}
293
294bitflags::bitflags! {
295    /// Flags for stem plots
296    pub struct StemsFlags: u32 {
297        const NONE = 0;
298        const HORIZONTAL = 1 << 10;
299    }
300}
301
302bitflags::bitflags! {
303    /// Flags for error bar plots
304    pub struct ErrorBarsFlags: u32 {
305        const NONE = 0;
306        const HORIZONTAL = 1 << 10;
307    }
308}
309
310bitflags::bitflags! {
311    /// Flags for stairs plots
312    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
313    pub struct StairsFlags: u32 {
314        const NONE = 0;
315        const PRE_STEP = 1 << 10;
316        const SHADED = 1 << 11;
317    }
318}
319
320bitflags::bitflags! {
321    /// Flags for bar groups plots
322    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
323    pub struct BarGroupsFlags: u32 {
324        const NONE = 0;
325        const HORIZONTAL = 1 << 10;
326        const STACKED = 1 << 11;
327    }
328}
329
330bitflags::bitflags! {
331    /// Flags for digital plots
332    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
333    pub struct DigitalFlags: u32 {
334        const NONE = 0;
335    }
336}
337
338bitflags::bitflags! {
339    /// Flags for text plots
340    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
341    pub struct TextFlags: u32 {
342        const NONE = 0;
343        const VERTICAL = 1 << 10;
344    }
345}
346
347bitflags::bitflags! {
348    /// Flags for dummy plots
349    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
350    pub struct DummyFlags: u32 {
351        const NONE = 0;
352    }
353}
354
355bitflags::bitflags! {
356    /// Flags for drag tools (points/lines)
357    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
358    pub struct DragToolFlags: u32 {
359        const NONE = 0;
360        const NO_CURSORS = 1 << 0;
361        const NO_FIT = 1 << 1;
362        const NO_INPUTS = 1 << 2;
363        const DELAYED = 1 << 3;
364    }
365}
366
367bitflags::bitflags! {
368    /// Flags for infinite lines plots
369    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
370    pub struct InfLinesFlags: u32 {
371        const NONE = 0;
372        const HORIZONTAL = 1 << 10;
373    }
374}
375
376bitflags::bitflags! {
377    /// Flags for image plots
378    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
379    pub struct ImageFlags: u32 {
380        const NONE = 0;
381    }
382}
383
384bitflags::bitflags! {
385    /// Axis flags matching ImPlotAxisFlags_ (see cimplot.h)
386    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
387    pub struct AxisFlags: u32 {
388        const NONE           = 0;
389        const NO_LABEL       = 1 << 0;
390        const NO_GRID_LINES  = 1 << 1;
391        const NO_TICK_MARKS  = 1 << 2;
392        const NO_TICK_LABELS = 1 << 3;
393        const NO_INITIAL_FIT = 1 << 4;
394        const NO_MENUS       = 1 << 5;
395        const NO_SIDE_SWITCH = 1 << 6;
396        const NO_HIGHLIGHT   = 1 << 7;
397        const OPPOSITE       = 1 << 8;
398        const FOREGROUND     = 1 << 9;
399        const INVERT         = 1 << 10;
400        const AUTO_FIT       = 1 << 11;
401        const RANGE_FIT      = 1 << 12;
402        const PAN_STRETCH    = 1 << 13;
403        const LOCK_MIN       = 1 << 14;
404        const LOCK_MAX       = 1 << 15;
405    }
406}
407
408/// Plot condition (setup/next) matching ImPlotCond (ImGuiCond)
409#[derive(Clone, Copy, Debug, PartialEq, Eq)]
410#[repr(i32)]
411pub enum PlotCond {
412    None = 0,
413    Always = 1,
414    Once = 2,
415}
416
417// Re-export all plot types for convenience
418pub use plots::*;
419
420// Re-export advanced features (explicit to avoid AxisFlags name clash)
421pub use advanced::{
422    LegendFlags, LegendLocation, LegendManager, LegendToken, MultiAxisPlot, MultiAxisToken,
423    SubplotFlags, SubplotGrid, SubplotToken, YAxisConfig,
424};