Added better Y axis handling and API coverage

This commit is contained in:
4bb4 2020-10-18 16:22:37 +02:00
parent 44a065c8c7
commit 0af4203d4f
5 changed files with 248 additions and 138 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "implot"
version = "0.1.0"
version = "0.2.0"
edition = "2018"
authors = ["Sandro Merkli", "implot-rs contributors"]
description = "Rust bindings to https://github.com/epezent/implot"

View file

@ -6,6 +6,10 @@ Rust bindings for [ImPlot](https://github.com/epezent/implot), built by running
The bindings are currently based on ImPlot version 0.7. See the status section below for
detailed information on implementation status.
**Important note:** As long as the code is pre-1.0 release, the API is expected to have
breaking changes between minor versions. Patch versions should be backwards compatible.
After 1.0, semver will be followed more properly.
![demo](demo.png)
## Requirements
@ -20,27 +24,20 @@ clone the repo, change into the `implot-examples` directory and try for example
```
## Documentation
Since the crate is not released yet, the documentation is not hosted yet either. You
can build it yourself however by cloning this repo and then doing
For released versions, see
[![Docs.rs documentation](https://docs.rs/implot/badge.svg)](https://docs.rs/implot/).
Make sure you are looking at the right release, since the API is still changing.
For the master branch, can build it yourself however by cloning this repo and then doing
```
cargo doc --open
```
An effort is made to document everything as it is being added. Feel free to open an issue
if documentation is unclear or lacking.
## Design approach
This repo tries to follow the approaches and style used in `imgui-rs` somewhat closely,
because implot is to be used within imgui programs, and hence keeping the interfaces
and design philosophies close should make it easier to do that.
If you spot any design inconsistencies or paper cuts, feel free to open an issue.
## Status
Currently a work in progress. The author is open to collaboration, if you'd like to
help, feel free to reach out via a Github issue.
Note that the API is not stabilized yet and expected to change as development progresses.
Once there are actual releases on crates.io, semantic versioning will be followed.
## Implementation status
Currently a work in progress, coverage of the C++ API is increased steadily. The author
is open to collaboration, if you'd like to help, feel free to reach out via a Github issue.
At this point, raw bindings are working in implot-sys, and more idiomatic interfaces
for plot creation as well a subset of the functionality for plots are implemented.
@ -69,20 +66,30 @@ for plot creation as well a subset of the functionality for plots are implemente
- [x] Styling colors
- [x] Styling variables
- [x] Colormaps
- [ ] Plot querying
- [x] Plot querying
- [x] is hovered
- [x] mouse position in plot
- [x] plot limits
- [x] is queried
- [x] get plot query
- [ ] Choice of y axis
- [x] are axes hovered
- [x] Choice of y axis
- [ ] Utils
- [x] Plot limit setting
- [x] imgui-rs style safe push/pop stacks
- [x] Plot tick setting
- [ ] Input remapping
- [ ] Set Y axis setting for subsequent elements
- [x] Set Y axis setting for subsequent elements
- [ ] Set non-default Y axis ticks and labels
- [ ] Plot position and size reading
- [ ] Pixel to plot position
- [ ] Plot to pixel position
- [ ] Push/pop plotclip rect (?)
# Developer documentation
## Design approach
This repo tries to follow the approaches and style used in `imgui-rs` somewhat closely,
because implot is to be used within imgui programs, and hence keeping the interfaces
and design philosophies close should make it easier to do that.
If you spot any design inconsistencies or paper cuts, feel free to open an issue.

View file

@ -5,8 +5,9 @@ use imgui::{im_str, CollapsingHeader, Condition, Ui, Window};
use implot::{
get_plot_limits, get_plot_mouse_position, get_plot_query, is_plot_hovered, is_plot_queried,
push_style_color, push_style_var_f32, push_style_var_i32, set_colormap_from_preset,
set_colormap_from_vec, AxisFlags, Colormap, Context, ImPlotLimits, ImPlotPoint, ImPlotRange,
ImVec4, Marker, Plot, PlotColorElement, PlotFlags, PlotLine, PlotUi, StyleVar,
set_colormap_from_vec, set_plot_y_axis, AxisFlags, Colormap, Context, ImPlotLimits,
ImPlotPoint, ImPlotRange, ImVec4, Marker, Plot, PlotColorElement, PlotFlags, PlotLine, PlotUi,
StyleVar, YAxisChoice,
};
mod support;
@ -28,9 +29,43 @@ fn show_basic_plot(ui: &Ui, plot_ui: &PlotUi) {
});
}
fn show_two_yaxis_plot(ui: &Ui, plot_ui: &PlotUi) {
ui.text(im_str!(
"This header shows how to create a plot with multiple Y axes."
));
let content_width = ui.window_content_region_width();
Plot::new("Multiple Y axis plots")
// The size call could also be omitted, though the defaults don't consider window
// width, which is why we're not doing so here.
.size(content_width, 300.0)
.with_plot_flags(&(PlotFlags::NONE | PlotFlags::Y_AXIS_2))
.y_limits(
&ImPlotRange { Min: 0.0, Max: 1.0 },
YAxisChoice::First,
Condition::Always,
)
.y_limits(
&ImPlotRange { Min: 1.0, Max: 3.5 },
YAxisChoice::Second,
Condition::Always,
)
.build(plot_ui, || {
let x_positions = vec![0.1, 0.9];
// The first Y axis is the default
let y_positions = vec![0.1, 0.9];
PlotLine::new("legend label").plot(&x_positions, &y_positions);
// Now we switch to the second axis for the next call
set_plot_y_axis(YAxisChoice::Second);
let y_positions = vec![3.3, 1.2];
PlotLine::new("legend label two").plot(&x_positions, &y_positions);
});
}
fn show_configurable_plot(ui: &Ui, plot_ui: &PlotUi) {
ui.text(im_str!(
"This header demos what we can configure about plots. €."
"This header demos what we can configure about plots."
));
// Settings for the plot
@ -79,14 +114,15 @@ fn show_configurable_plot(ui: &Ui, plot_ui: &PlotUi) {
Min: y_min,
Max: y_max,
},
YAxisChoice::First,
Condition::Always,
)
.x_ticks(&x_ticks, false)
.y_ticks_with_labels(&y_ticks, false)
.y_ticks_with_labels(YAxisChoice::First, &y_ticks, false)
// If any of these flag setting calls are omitted, the defaults are used.
.with_plot_flags(&plot_flags)
.with_x_axis_flags(&x_axis_flags)
.with_y_axis_flags(&y_axis_flags)
.with_y_axis_flags(YAxisChoice::First, &y_axis_flags)
.build(plot_ui, || {
PlotLine::new("A line").plot(&vec![2.1, 2.9], &vec![1.1, 1.9]);
});
@ -107,17 +143,21 @@ fn show_query_features_plot(ui: &Ui, plot_ui: &PlotUi) {
Plot::new("Plot querying")
.size(content_width, 300.0)
.x_limits(&ImPlotRange { Min: 0.0, Max: 5.0 }, Condition::FirstUseEver)
.y_limits(&ImPlotRange { Min: 0.0, Max: 5.0 }, Condition::FirstUseEver)
.y_limits(
&ImPlotRange { Min: 0.0, Max: 5.0 },
YAxisChoice::First,
Condition::FirstUseEver,
)
.with_plot_flags(&(PlotFlags::NONE | PlotFlags::QUERY))
.build(plot_ui, || {
if is_plot_hovered() {
hover_pos = Some(get_plot_mouse_position());
hover_pos = Some(get_plot_mouse_position(None));
}
if is_plot_queried() {
query_limits = Some(get_plot_query());
query_limits = Some(get_plot_query(None));
}
plot_limits = Some(get_plot_limits());
plot_limits = Some(get_plot_limits(None));
});
// Print some previously-exfiltrated info. This is because calling
@ -153,10 +193,11 @@ fn show_style_plot(ui: &Ui, plot_ui: &PlotUi) {
Min: -1.0,
Max: 3.0,
},
YAxisChoice::First,
Condition::Always,
)
.with_plot_flags(&(PlotFlags::NONE))
.with_y_axis_flags(&(AxisFlags::NONE))
.with_y_axis_flags(YAxisChoice::First, &(AxisFlags::NONE))
.build(plot_ui, || {
// Markers can be selected as shown here. The markers are internally represented
// as an u32, hence this calling style.
@ -268,6 +309,9 @@ fn main() {
if CollapsingHeader::new(im_str!("Colormap selection")).build(&ui) {
show_colormaps_plot(&ui, &plot_ui);
}
if CollapsingHeader::new(im_str!("Multiple Y Axes")).build(&ui) {
show_two_yaxis_plot(&ui, &plot_ui);
}
});
if showing_demo {

View file

@ -28,6 +28,28 @@ mod context;
mod plot;
mod plot_elements;
// The bindings for some reason don't contain this - it has to match the IMPLOT_AUTO from
// the original C++ header for things to work properly.
const IMPLOT_AUTO: i32 = -1;
// Number of Y axes, this is used in a bunch of places for storing things like settings.
// If this changes, also change the YAxisChoice enum.
const NUMBER_OF_Y_AXES: usize = 3;
/// Choice of Y axis. This an enum instead of just an integer so as to make it impossible
/// to select a Y axis that is not present - this makes it easier to avoid `Result`-type
/// return values on functions that could otherwise not really fail.
// Implementation note: This enum is converted straight to an usize index in a few places
// so we can store data about individual axes in arrays, so this pretty much should stay
// just a mapping of words to numbers.
#[derive(Clone)]
#[repr(i32)]
pub enum YAxisChoice {
First = 0,
Second = 1,
Third = 2,
}
/// A temporary reference for building plots. This does not really do anything on its own at
/// this point, but it is used to enforce that a context is created and active for other features,
/// such as creating plots.
@ -251,9 +273,6 @@ pub fn push_style_color(
/// Tracks a change pushed to the style color stack
pub struct StyleColorToken {
/// Whether this token has been popped or not.
/// TODO(4bb4) figure out if it is a good idea to warn about this not being popped when it is
/// dropped - this may not be a good idea since users may want to push some style vars for
/// longer durations.
was_popped: bool,
}
@ -311,9 +330,6 @@ pub fn push_style_var_imvec2(element: &StyleVar, value: ImVec2) -> StyleVarToken
/// Tracks a change pushed to the style variable stack
pub struct StyleVarToken {
/// Whether this token has been popped or not.
/// TODO(4bb4) figure out if it is a good idea to warn about this not being popped when it is
/// dropped - this may not be a good idea since users may want to push some style vars for
/// longer durations.
was_popped: bool,
}
@ -341,47 +357,79 @@ pub fn is_plot_queried() -> bool {
unsafe { sys::ImPlot_IsPlotQueried() }
}
/// Returns the mouse position in x,y coordinates of the current or most recent plot. Currently
/// pertains to whatever Y axis was most recently selected. TODO(4bb4) add y axis selection
pub fn get_plot_mouse_position() -> ImPlotPoint {
let y_axis_selection = 0;
/// Returns the mouse position in x,y coordinates of the current or most recent plot,
/// for the specified choice of Y axis. If `None` is the Y axis choice, that means the
/// most recently selected Y axis is chosen.
pub fn get_plot_mouse_position(y_axis_choice: Option<YAxisChoice>) -> ImPlotPoint {
let y_axis_choice_i32 = match y_axis_choice {
Some(choice) => choice as i32,
None => IMPLOT_AUTO,
};
let mut point = ImPlotPoint { x: 0.0, y: 0.0 }; // doesn't seem to have default()
unsafe {
sys::ImPlot_GetPlotMousePos(&mut point as *mut ImPlotPoint, y_axis_selection);
sys::ImPlot_GetPlotMousePos(&mut point as *mut ImPlotPoint, y_axis_choice_i32);
}
point
}
/// Returns the current or most recent plot axis range. Currently pertains to whatever Y axis was
/// most recently selected. TODO(4bb4) add y axis selection
pub fn get_plot_limits() -> ImPlotLimits {
let y_axis_selection = 0;
/// Returns the current or most recent plot axis range for the specified choice of Y axis. If
/// `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
pub fn get_plot_limits(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
let y_axis_choice_i32 = match y_axis_choice {
Some(choice) => choice as i32,
None => IMPLOT_AUTO,
};
// ImPlotLimits doesn't seem to have default()
let mut limits = ImPlotLimits {
X: ImPlotRange { Min: 0.0, Max: 0.0 },
Y: ImPlotRange { Min: 0.0, Max: 0.0 },
};
unsafe {
sys::ImPlot_GetPlotLimits(&mut limits as *mut ImPlotLimits, y_axis_selection);
sys::ImPlot_GetPlotLimits(&mut limits as *mut ImPlotLimits, y_axis_choice_i32);
}
limits
}
/// Returns the query limits of the current or most recent plot. Currently pertains to whatever Y
/// axis was most recently selected. TODO(4bb4) add y axis selection
pub fn get_plot_query() -> ImPlotLimits {
let y_axis_selection = 0;
/// Returns the query limits of the current or most recent plot, for the specified choice of Y
/// axis. If `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
pub fn get_plot_query(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
let y_axis_choice_i32 = match y_axis_choice {
Some(choice) => choice as i32,
None => IMPLOT_AUTO,
};
// ImPlotLimits doesn't seem to have default()
let mut limits = ImPlotLimits {
X: ImPlotRange { Min: 0.0, Max: 0.0 },
Y: ImPlotRange { Min: 0.0, Max: 0.0 },
};
unsafe {
sys::ImPlot_GetPlotQuery(&mut limits as *mut ImPlotLimits, y_axis_selection);
sys::ImPlot_GetPlotQuery(&mut limits as *mut ImPlotLimits, y_axis_choice_i32);
}
limits
}
/// Set the Y axis to be used for any upcoming plot elements
pub fn set_plot_y_axis(y_axis_choice: YAxisChoice) {
unsafe {
sys::ImPlot_SetPlotYAxis(y_axis_choice as i32);
}
}
/// Returns true if the XAxis plot area in the current plot is hovered.
pub fn is_plot_x_axis_hovered() -> bool {
unsafe { sys::ImPlot_IsPlotXAxisHovered() }
}
/// Returns true if the YAxis[n] plot area in the current plot is hovered. If `None` is the Y axis
/// choice, that means the most recently selected Y axis is chosen.
pub fn is_plot_y_axis_hovered(y_axis_choice: Option<YAxisChoice>) -> bool {
let y_axis_choice_i32 = match y_axis_choice {
Some(choice) => choice as i32,
None => IMPLOT_AUTO,
};
unsafe { sys::ImPlot_IsPlotYAxisHovered(y_axis_choice_i32) }
}
// --- Demo window -------------------------------------------------------------------------------
/// Show the demo window for poking around what functionality implot has to
/// offer. Note that not all of this is necessarily implemented in implot-rs

View file

@ -8,7 +8,7 @@ pub use sys::imgui::Condition;
use sys::imgui::{im_str, ImString};
pub use sys::{ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};
use crate::{Context, PlotUi};
use crate::{Context, PlotUi, YAxisChoice, NUMBER_OF_Y_AXES};
const DEFAULT_PLOT_SIZE_X: f32 = 400.0;
const DEFAULT_PLOT_SIZE_Y: f32 = 400.0;
@ -107,11 +107,11 @@ pub struct Plot {
/// X axis limits, if present
x_limits: Option<ImPlotRange>,
/// Y axis limits, if present
y_limits: Option<ImPlotRange>,
y_limits: [Option<ImPlotRange>; NUMBER_OF_Y_AXES],
/// Condition on which the x limits are set
x_limit_condition: Option<Condition>,
/// Condition on which the y limits are set (first y axis for now)
y_limit_condition: Option<Condition>,
/// Condition on which the y limits are set for each of the axes
y_limit_condition: [Option<Condition>; NUMBER_OF_Y_AXES],
/// Positions for custom X axis ticks, if any
x_tick_positions: Option<Vec<f64>>,
/// Labels for custom X axis ticks, if any. I'd prefer to store these together
@ -124,33 +124,31 @@ pub struct Plot {
/// Whether to also show the default X ticks when showing custom ticks or not
show_x_default_ticks: bool,
/// Positions for custom Y axis ticks, if any
y_tick_positions: Option<Vec<f64>>,
y_tick_positions: [Option<Vec<f64>>; NUMBER_OF_Y_AXES],
/// Labels for custom Y axis ticks, if any. I'd prefer to store these together
/// with the positions in one vector of an algebraic data type, but this would mean extra
/// copies when it comes time to draw the plot because the C++ library expects separate lists.
/// The data is stored as ImStrings because those are null-terminated, and since we have to
/// convert to null-terminated data anyway, we may as well do that directly instead of cloning
/// Strings and converting them afterwards.
y_tick_labels: Option<Vec<ImString>>,
y_tick_labels: [Option<Vec<ImString>>; NUMBER_OF_Y_AXES],
/// Whether to also show the default Y ticks when showing custom ticks or not
show_y_default_ticks: bool,
show_y_default_ticks: [bool; NUMBER_OF_Y_AXES],
/// Flags relating to the plot TODO(4bb4) make those into bitflags
plot_flags: sys::ImPlotFlags,
/// Flags relating to the first x axis of the plot TODO(4bb4) make those into bitflags
/// Flags relating to the X axis of the plot TODO(4bb4) make those into bitflags
x_flags: sys::ImPlotAxisFlags,
/// Flags relating to the first y axis of the plot TODO(4bb4) make those into bitflags
y_flags: sys::ImPlotAxisFlags,
/// Flags relating to the second y axis of the plot (if present, otherwise ignored)
/// TODO(4bb4) make those into bitflags
y2_flags: sys::ImPlotAxisFlags,
/// Flags relating to the third y axis of the plot (if present, otherwise ignored)
/// TODO(4bb4) make those into bitflags
y3_flags: sys::ImPlotAxisFlags,
/// Flags relating to the each of the Y axes of the plot TODO(4bb4) make those into bitflags
y_flags: [sys::ImPlotAxisFlags; NUMBER_OF_Y_AXES],
}
impl Plot {
/// Create a new plot with some defaults set. Does not draw anything yet.
pub fn new(title: &str) -> Self {
// Needed for initialization, see https://github.com/rust-lang/rust/issues/49147
const POS_NONE: Option<Vec<f64>> = None;
const TICK_NONE: Option<Vec<ImString>> = None;
// TODO(4bb4) question these defaults, maybe remove some of them
Self {
title: im_str!("{}", title),
@ -159,20 +157,18 @@ impl Plot {
x_label: im_str!("").into(),
y_label: im_str!("").into(),
x_limits: None,
y_limits: None,
y_limits: [None; NUMBER_OF_Y_AXES],
x_limit_condition: None,
y_limit_condition: None,
y_limit_condition: [None; NUMBER_OF_Y_AXES],
x_tick_positions: None,
x_tick_labels: None,
show_x_default_ticks: false,
y_tick_positions: None,
y_tick_labels: None,
show_y_default_ticks: false,
y_tick_positions: [POS_NONE; NUMBER_OF_Y_AXES],
y_tick_labels: [TICK_NONE; NUMBER_OF_Y_AXES],
show_y_default_ticks: [false; NUMBER_OF_Y_AXES],
plot_flags: PlotFlags::NONE.bits() as sys::ImPlotFlags,
x_flags: AxisFlags::NONE.bits() as sys::ImPlotAxisFlags,
y_flags: AxisFlags::NONE.bits() as sys::ImPlotAxisFlags,
y2_flags: AxisFlags::NONE.bits() as sys::ImPlotAxisFlags,
y3_flags: AxisFlags::NONE.bits() as sys::ImPlotAxisFlags,
y_flags: [AxisFlags::NONE.bits() as sys::ImPlotAxisFlags; NUMBER_OF_Y_AXES],
}
}
@ -207,11 +203,18 @@ impl Plot {
self
}
/// Set the y limits of the plot
/// Set the Y limits of the plot for the given Y axis. Call multiple times
/// to set for multiple axes.
#[inline]
pub fn y_limits(mut self, limits: &ImPlotRange, condition: Condition) -> Self {
self.y_limits = Some(*limits);
self.y_limit_condition = Some(condition);
pub fn y_limits(
mut self,
limits: &ImPlotRange,
y_axis_choice: YAxisChoice,
condition: Condition,
) -> Self {
let axis_index = y_axis_choice as usize;
self.y_limits[axis_index] = Some(*limits);
self.y_limit_condition[axis_index] = Some(condition);
self
}
@ -229,9 +232,15 @@ impl Plot {
/// the form of a tuple `(label_position, label_string)`. The `show_default` setting
/// determines whether the default ticks are also shown.
#[inline]
pub fn y_ticks(mut self, ticks: &Vec<f64>, show_default: bool) -> Self {
self.y_tick_positions = Some(ticks.clone());
self.show_y_default_ticks = show_default;
pub fn y_ticks(
mut self,
y_axis_choice: YAxisChoice,
ticks: &Vec<f64>,
show_default: bool,
) -> Self {
let axis_index = y_axis_choice as usize;
self.y_tick_positions[axis_index] = Some(ticks.clone());
self.show_y_default_ticks[axis_index] = show_default;
self
}
@ -256,12 +265,15 @@ impl Plot {
#[inline]
pub fn y_ticks_with_labels(
mut self,
y_axis_choice: YAxisChoice,
tick_labels: &Vec<(f64, String)>,
show_default: bool,
) -> Self {
self.y_tick_positions = Some(tick_labels.iter().map(|x| x.0).collect());
self.y_tick_labels = Some(tick_labels.iter().map(|x| im_str!("{}", x.1)).collect());
self.show_y_default_ticks = show_default;
let axis_index = y_axis_choice as usize;
self.y_tick_positions[axis_index] = Some(tick_labels.iter().map(|x| x.0).collect());
self.y_tick_labels[axis_index] =
Some(tick_labels.iter().map(|x| im_str!("{}", x.1)).collect());
self.show_y_default_ticks[axis_index] = show_default;
self
}
@ -279,24 +291,11 @@ impl Plot {
self
}
/// Set the axis flags for the first Y axis in this plot
/// Set the axis flags for the selected Y axis in this plot
#[inline]
pub fn with_y_axis_flags(mut self, flags: &AxisFlags) -> Self {
self.y_flags = flags.bits() as sys::ImPlotAxisFlags;
self
}
/// Set the axis flags for the second Y axis in this plot
#[inline]
pub fn with_y2_axis_flags(mut self, flags: &AxisFlags) -> Self {
self.y2_flags = flags.bits() as sys::ImPlotAxisFlags;
self
}
/// Set the axis flags for the third Y axis in this plot
#[inline]
pub fn with_y3_axis_flags(mut self, flags: &AxisFlags) -> Self {
self.y3_flags = flags.bits() as sys::ImPlotAxisFlags;
pub fn with_y_axis_flags(mut self, y_axis_choice: YAxisChoice, flags: &AxisFlags) -> Self {
let axis_index = y_axis_choice as usize;
self.y_flags[axis_index] = flags.bits() as sys::ImPlotAxisFlags;
self
}
@ -309,19 +308,23 @@ impl Plot {
}
}
// Set X limits if specified
if let (Some(limits), Some(condition)) = (self.y_limits, self.y_limit_condition) {
// TODO(4bb4) allow for specification of multiple y limits, not just the first
let selected_y_axis = 0;
// Set Y limits if specified
self.y_limits
.iter()
.zip(self.y_limit_condition.iter())
.enumerate()
.for_each(|(k, (limits, condition))| {
if let (Some(limits), Some(condition)) = (limits, condition) {
unsafe {
sys::ImPlot_SetNextPlotLimitsY(
limits.Min,
limits.Max,
condition as sys::ImGuiCond,
selected_y_axis,
*condition as sys::ImGuiCond,
k as i32,
);
}
}
});
}
/// Internal helper function to set tick labels in case they are specified. This does the
@ -351,9 +354,16 @@ impl Plot {
}
}
if self.y_tick_positions.is_some() && self.y_tick_positions.as_ref().unwrap().len() > 0 {
let mut pointer_vec; // The vector of pointers we create has to have a longer lifetime
let labels_pointer = if let Some(labels_value) = &self.y_tick_labels {
self.y_tick_positions
.iter()
.zip(self.y_tick_labels.iter())
.zip(self.show_y_default_ticks.iter())
.enumerate()
.for_each(|(k, ((positions, labels), show_defaults))| {
if positions.is_some() && positions.as_ref().unwrap().len() > 0 {
// The vector of pointers we create has to have a longer lifetime
let mut pointer_vec;
let labels_pointer = if let Some(labels_value) = &labels {
pointer_vec = labels_value
.iter()
.map(|x| x.as_ptr() as *const i8)
@ -365,14 +375,15 @@ impl Plot {
unsafe {
sys::ImPlot_SetNextPlotTicksYdoublePtr(
self.y_tick_positions.as_ref().unwrap().as_ptr(),
self.y_tick_positions.as_ref().unwrap().len() as i32,
positions.as_ref().unwrap().as_ptr(),
positions.as_ref().unwrap().len() as i32,
labels_pointer,
self.show_y_default_ticks,
0, // y axis selection, TODO(4bb4) make this configurable
*show_defaults,
k as i32,
)
}
}
});
}
/// Attempt to show the plot. If this returns a token, the plot will actually
@ -397,9 +408,9 @@ impl Plot {
},
self.plot_flags,
self.x_flags,
self.y_flags,
self.y2_flags,
self.y3_flags,
self.y_flags[0],
self.y_flags[1],
self.y_flags[2],
)
};