Added stem plots and legend entry hover checking
This commit is contained in:
parent
2c56bd9803
commit
21aa28591c
7 changed files with 113 additions and 10 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,6 +1,9 @@
|
|||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
**/target/
|
||||
|
||||
# Editor temporary files
|
||||
**/*.swp
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
|
|
|
@ -83,7 +83,7 @@ created for 64-bit floats.
|
|||
- [x] Styling variables
|
||||
- [x] Colormaps
|
||||
- [x] Legend locations
|
||||
- [ ] Plot querying
|
||||
- [x] Plot querying
|
||||
- [x] is hovered
|
||||
- [x] mouse position in plot
|
||||
- [x] plot limits
|
||||
|
@ -91,7 +91,7 @@ created for 64-bit floats.
|
|||
- [x] get plot query
|
||||
- [x] are axes hovered
|
||||
- [x] Choice of y axis
|
||||
- [ ] Are legend entries hovered
|
||||
- [x] Are legend entries hovered
|
||||
- [ ] Utils
|
||||
- [x] Plot limit setting
|
||||
- [x] imgui-rs style safe push/pop stacks
|
||||
|
|
|
@ -3,6 +3,7 @@ pub mod heatmaps;
|
|||
pub mod line_plots;
|
||||
pub mod scatter_plots;
|
||||
pub mod stairs_plots;
|
||||
mod stem_plots;
|
||||
pub mod text_plots;
|
||||
|
||||
use imgui::{im_str, Condition, Ui, Window};
|
||||
|
@ -43,5 +44,9 @@ pub fn show_demos(ui: &Ui, plot_ui: &PlotUi) {
|
|||
ui.separator();
|
||||
ui.text(im_str!("Heatmaps:"));
|
||||
heatmaps::show_demo_headers(ui, plot_ui);
|
||||
|
||||
ui.separator();
|
||||
ui.text(im_str!("Stem plots:"));
|
||||
stem_plots::show_demo_headers(ui, plot_ui);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
use imgui::{im_str, CollapsingHeader, Condition, Ui};
|
||||
use implot::{
|
||||
get_plot_limits, get_plot_mouse_position, get_plot_query, is_plot_hovered, is_plot_queried,
|
||||
pixels_to_plot_vec2, plot_to_pixels_vec2, push_style_color, push_style_var_f32,
|
||||
push_style_var_i32, set_colormap_from_preset, set_colormap_from_vec, set_plot_y_axis,
|
||||
AxisFlags, Colormap, ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4, Marker, Plot,
|
||||
PlotColorElement, PlotFlags, PlotLine, PlotLocation, PlotOrientation, PlotUi, StyleVar,
|
||||
YAxisChoice,
|
||||
get_plot_limits, get_plot_mouse_position, get_plot_query, is_legend_entry_hovered,
|
||||
is_plot_hovered, is_plot_queried, pixels_to_plot_vec2, plot_to_pixels_vec2, push_style_color,
|
||||
push_style_var_f32, push_style_var_i32, set_colormap_from_preset, set_colormap_from_vec,
|
||||
set_plot_y_axis, AxisFlags, Colormap, ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4,
|
||||
Marker, Plot, PlotColorElement, PlotFlags, PlotLine, PlotLocation, PlotOrientation, PlotUi,
|
||||
StyleVar, YAxisChoice,
|
||||
};
|
||||
|
||||
pub fn show_basic_plot(ui: &Ui, plot_ui: &PlotUi) {
|
||||
|
@ -156,6 +156,8 @@ pub fn show_query_features_plot(ui: &Ui, plot_ui: &PlotUi) {
|
|||
let mut hover_pos_from_pixels: Option<ImPlotPoint> = None;
|
||||
let mut plot_limits: Option<ImPlotLimits> = None;
|
||||
let mut query_limits: Option<ImPlotLimits> = None;
|
||||
let mut legend1_hovered = false;
|
||||
let mut legend2_hovered = false;
|
||||
|
||||
// Draw a plot
|
||||
Plot::new("Plot querying")
|
||||
|
@ -183,6 +185,12 @@ pub fn show_query_features_plot(ui: &Ui, plot_ui: &PlotUi) {
|
|||
None,
|
||||
));
|
||||
|
||||
// Plot a line so we have a legend entry
|
||||
PlotLine::new("Legend1").plot(&vec![2.0, 2.0], &vec![2.0, 1.0]);
|
||||
PlotLine::new("Legend2").plot(&vec![0.0, 0.0], &vec![1.0, 1.0]);
|
||||
legend1_hovered = is_legend_entry_hovered("Legend1");
|
||||
legend2_hovered = is_legend_entry_hovered("Legend2");
|
||||
|
||||
if is_plot_queried() {
|
||||
query_limits = Some(get_plot_query(None));
|
||||
}
|
||||
|
@ -214,6 +222,11 @@ pub fn show_query_features_plot(ui: &Ui, plot_ui: &PlotUi) {
|
|||
if let Some(query) = query_limits {
|
||||
ui.text(im_str!("Query limits are {:#?}", query));
|
||||
}
|
||||
ui.text(im_str!(
|
||||
"Legend hovering - 1: {}, 2: {}",
|
||||
legend1_hovered,
|
||||
legend2_hovered
|
||||
));
|
||||
|
||||
// Try out converting pixel position to plot position
|
||||
if let Some(pos) = hover_pos_from_pixels {
|
||||
|
|
28
implot-examples/examples-shared/src/stem_plots.rs
Normal file
28
implot-examples/examples-shared/src/stem_plots.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
//! This example demonstrates how stem plots are to be used. For more general
|
||||
//! features of the libray, see the line_plots example.
|
||||
|
||||
use imgui::{im_str, CollapsingHeader, Ui};
|
||||
use implot::{Plot, PlotStems, PlotUi};
|
||||
|
||||
pub fn show_basic_plot(ui: &Ui, plot_ui: &PlotUi) {
|
||||
ui.text(im_str!("This header shows a simple stem plot."));
|
||||
let content_width = ui.window_content_region_width();
|
||||
Plot::new("Stem plot")
|
||||
// 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)
|
||||
.build(plot_ui, || {
|
||||
// If this is called outside a plot build callback, the program will panic.
|
||||
let axis_positions = vec![0.2, 0.4, 0.6, 0.8, 0.9, 0.93];
|
||||
let values = vec![0.1, 0.2, 0.3, 0.4, 0.3, 0.8];
|
||||
PlotStems::new("legend label")
|
||||
.with_reference_y(0.1)
|
||||
.plot(&axis_positions, &values);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn show_demo_headers(ui: &Ui, plot_ui: &PlotUi) {
|
||||
if CollapsingHeader::new(im_str!("Stem plots")).build(&ui) {
|
||||
show_basic_plot(&ui, &plot_ui);
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ use implot_sys as sys;
|
|||
|
||||
// TODO(4bb4) facade-wrap these?
|
||||
pub use self::{context::*, plot::*, plot_elements::*};
|
||||
use imgui::im_str;
|
||||
pub use sys::{ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};
|
||||
|
||||
mod context;
|
||||
|
@ -572,6 +573,11 @@ pub fn is_plot_y_axis_hovered(y_axis_choice: Option<YAxisChoice>) -> bool {
|
|||
unsafe { sys::ImPlot_IsPlotYAxisHovered(y_axis_choice_i32) }
|
||||
}
|
||||
|
||||
/// Returns true if the given item in the legend of the current plot is hovered.
|
||||
pub fn is_legend_entry_hovered(legend_entry: &str) -> bool {
|
||||
unsafe { sys::ImPlot_IsLegendEntryHovered(im_str!("{}", legend_entry).as_ptr() as *const i8) }
|
||||
}
|
||||
|
||||
// --- 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
|
||||
|
|
|
@ -147,7 +147,7 @@ impl PlotBars {
|
|||
|
||||
/// Draw a previously-created bar plot. Use this in closures passed to
|
||||
/// [`Plot::build()`](struct.Plot.html#method.build). The `axis_positions`
|
||||
/// specify where on the corersponding axis (X for vertical mode, Y for horizontal mode) the
|
||||
/// specify where on the corresponding axis (X for vertical mode, Y for horizontal mode) the
|
||||
/// bar is drawn, and the `bar_values` specify what values the bars have.
|
||||
pub fn plot(&self, axis_positions: &[f64], bar_values: &[f64]) {
|
||||
let number_of_points = axis_positions.len().min(bar_values.len());
|
||||
|
@ -332,3 +332,51 @@ impl PlotHeatmap {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct to provide stem plotting functionality.
|
||||
pub struct PlotStems {
|
||||
/// Label to show in the legend for this line
|
||||
label: String,
|
||||
|
||||
/// Reference value for the y value, which the stems are "with respect to"
|
||||
reference_y: f64,
|
||||
}
|
||||
|
||||
impl PlotStems {
|
||||
/// Create a new stem plot to be shown. Does not draw anything by itself, call
|
||||
/// [`PlotStems::plot`] on the struct for that.
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: label.to_owned(),
|
||||
reference_y: 0.0, // Default value taken from C++ implot
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the reference y value for the stems
|
||||
pub fn with_reference_y(mut self, reference_y: f64) -> Self {
|
||||
self.reference_y = reference_y;
|
||||
self
|
||||
}
|
||||
|
||||
/// Draw a previously-created stem plot. Use this in closures passed to
|
||||
/// [`Plot::build()`](struct.Plot.html#method.build). The `axis_positions` specify where on the
|
||||
/// X axis the stems are drawn, and the `stem_values` specify what values the stems have.
|
||||
pub fn plot(&self, axis_positions: &[f64], stem_values: &[f64]) {
|
||||
let number_of_points = axis_positions.len().min(stem_values.len());
|
||||
// If there is no data to plot, we stop here
|
||||
if number_of_points == 0 {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
sys::ImPlot_PlotStemsdoublePtrdoublePtr(
|
||||
im_str!("{}", self.label).as_ptr() as *const i8,
|
||||
axis_positions.as_ptr(),
|
||||
stem_values.as_ptr(),
|
||||
number_of_points as i32, // "as" casts saturate as of Rust 1.45. This is safe here.
|
||||
self.reference_y,
|
||||
0, // No offset
|
||||
std::mem::size_of::<f64>() as i32, // Stride, set to one f64 for the standard use case
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue