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
|
# Generated by Cargo
|
||||||
# will have compiled files and executables
|
# 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
|
# 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
|
# 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] Styling variables
|
||||||
- [x] Colormaps
|
- [x] Colormaps
|
||||||
- [x] Legend locations
|
- [x] Legend locations
|
||||||
- [ ] Plot querying
|
- [x] Plot querying
|
||||||
- [x] is hovered
|
- [x] is hovered
|
||||||
- [x] mouse position in plot
|
- [x] mouse position in plot
|
||||||
- [x] plot limits
|
- [x] plot limits
|
||||||
|
@ -91,7 +91,7 @@ created for 64-bit floats.
|
||||||
- [x] get plot query
|
- [x] get plot query
|
||||||
- [x] are axes hovered
|
- [x] are axes hovered
|
||||||
- [x] Choice of y axis
|
- [x] Choice of y axis
|
||||||
- [ ] Are legend entries hovered
|
- [x] Are legend entries hovered
|
||||||
- [ ] Utils
|
- [ ] Utils
|
||||||
- [x] Plot limit setting
|
- [x] Plot limit setting
|
||||||
- [x] imgui-rs style safe push/pop stacks
|
- [x] imgui-rs style safe push/pop stacks
|
||||||
|
|
|
@ -3,6 +3,7 @@ pub mod heatmaps;
|
||||||
pub mod line_plots;
|
pub mod line_plots;
|
||||||
pub mod scatter_plots;
|
pub mod scatter_plots;
|
||||||
pub mod stairs_plots;
|
pub mod stairs_plots;
|
||||||
|
mod stem_plots;
|
||||||
pub mod text_plots;
|
pub mod text_plots;
|
||||||
|
|
||||||
use imgui::{im_str, Condition, Ui, Window};
|
use imgui::{im_str, Condition, Ui, Window};
|
||||||
|
@ -43,5 +44,9 @@ pub fn show_demos(ui: &Ui, plot_ui: &PlotUi) {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.text(im_str!("Heatmaps:"));
|
ui.text(im_str!("Heatmaps:"));
|
||||||
heatmaps::show_demo_headers(ui, plot_ui);
|
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 imgui::{im_str, CollapsingHeader, Condition, Ui};
|
||||||
use implot::{
|
use implot::{
|
||||||
get_plot_limits, get_plot_mouse_position, get_plot_query, is_plot_hovered, is_plot_queried,
|
get_plot_limits, get_plot_mouse_position, get_plot_query, is_legend_entry_hovered,
|
||||||
pixels_to_plot_vec2, plot_to_pixels_vec2, push_style_color, push_style_var_f32,
|
is_plot_hovered, is_plot_queried, pixels_to_plot_vec2, plot_to_pixels_vec2, push_style_color,
|
||||||
push_style_var_i32, set_colormap_from_preset, set_colormap_from_vec, set_plot_y_axis,
|
push_style_var_f32, push_style_var_i32, set_colormap_from_preset, set_colormap_from_vec,
|
||||||
AxisFlags, Colormap, ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4, Marker, Plot,
|
set_plot_y_axis, AxisFlags, Colormap, ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4,
|
||||||
PlotColorElement, PlotFlags, PlotLine, PlotLocation, PlotOrientation, PlotUi, StyleVar,
|
Marker, Plot, PlotColorElement, PlotFlags, PlotLine, PlotLocation, PlotOrientation, PlotUi,
|
||||||
YAxisChoice,
|
StyleVar, YAxisChoice,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn show_basic_plot(ui: &Ui, plot_ui: &PlotUi) {
|
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 hover_pos_from_pixels: Option<ImPlotPoint> = None;
|
||||||
let mut plot_limits: Option<ImPlotLimits> = None;
|
let mut plot_limits: Option<ImPlotLimits> = None;
|
||||||
let mut query_limits: Option<ImPlotLimits> = None;
|
let mut query_limits: Option<ImPlotLimits> = None;
|
||||||
|
let mut legend1_hovered = false;
|
||||||
|
let mut legend2_hovered = false;
|
||||||
|
|
||||||
// Draw a plot
|
// Draw a plot
|
||||||
Plot::new("Plot querying")
|
Plot::new("Plot querying")
|
||||||
|
@ -183,6 +185,12 @@ pub fn show_query_features_plot(ui: &Ui, plot_ui: &PlotUi) {
|
||||||
None,
|
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() {
|
if is_plot_queried() {
|
||||||
query_limits = Some(get_plot_query(None));
|
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 {
|
if let Some(query) = query_limits {
|
||||||
ui.text(im_str!("Query limits are {:#?}", query));
|
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
|
// Try out converting pixel position to plot position
|
||||||
if let Some(pos) = hover_pos_from_pixels {
|
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?
|
// TODO(4bb4) facade-wrap these?
|
||||||
pub use self::{context::*, plot::*, plot_elements::*};
|
pub use self::{context::*, plot::*, plot_elements::*};
|
||||||
|
use imgui::im_str;
|
||||||
pub use sys::{ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};
|
pub use sys::{ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};
|
||||||
|
|
||||||
mod context;
|
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) }
|
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 -------------------------------------------------------------------------------
|
// --- Demo window -------------------------------------------------------------------------------
|
||||||
/// Show the demo window for poking around what functionality implot has to
|
/// 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
|
/// 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
|
/// Draw a previously-created bar plot. Use this in closures passed to
|
||||||
/// [`Plot::build()`](struct.Plot.html#method.build). The `axis_positions`
|
/// [`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.
|
/// bar is drawn, and the `bar_values` specify what values the bars have.
|
||||||
pub fn plot(&self, axis_positions: &[f64], bar_values: &[f64]) {
|
pub fn plot(&self, axis_positions: &[f64], bar_values: &[f64]) {
|
||||||
let number_of_points = axis_positions.len().min(bar_values.len());
|
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