Added bar plot support
This commit is contained in:
parent
ff96a07ef3
commit
03f9fefba7
4 changed files with 158 additions and 6 deletions
|
@ -52,10 +52,10 @@ See below for an overview of the progress.
|
||||||
- [ ] Plotting functionality
|
- [ ] Plotting functionality
|
||||||
- [x] Line plot
|
- [x] Line plot
|
||||||
- [x] Text plot
|
- [x] Text plot
|
||||||
- [ ] Scatter plot
|
- [x] Scatter plot
|
||||||
- [ ] Bar plot
|
- [x] Bar plot
|
||||||
- [ ] Vertical
|
- [x] Vertical
|
||||||
- [ ] Horizontal
|
- [x] Horizontal
|
||||||
- [ ] Error bar plot
|
- [ ] Error bar plot
|
||||||
- [ ] Vertical
|
- [ ] Vertical
|
||||||
- [ ] Horizontal
|
- [ ] Horizontal
|
||||||
|
|
76
implot-examples/examples/bar_plots.rs
Normal file
76
implot-examples/examples/bar_plots.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
//! This example demonstrates how bar plots are to be used. For more general
|
||||||
|
//! features of the libray, see the line_plots example.
|
||||||
|
|
||||||
|
use imgui::{im_str, CollapsingHeader, Condition, Ui, Window};
|
||||||
|
use implot::{push_style_var_f32, push_style_var_u32, Marker, Plot, PlotBars, StyleVar};
|
||||||
|
|
||||||
|
mod support;
|
||||||
|
|
||||||
|
fn show_basic_vertical_plot(ui: &Ui) {
|
||||||
|
ui.text(im_str!("This header shows a simple vertical bar plot."));
|
||||||
|
let content_width = ui.window_content_region_width();
|
||||||
|
Plot::new("Vertical bar 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(|| {
|
||||||
|
// 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];
|
||||||
|
let values = vec![0.1, 0.2, 0.3, 0.4];
|
||||||
|
PlotBars::new("legend label")
|
||||||
|
.with_bar_width(0.1)
|
||||||
|
.plot(&axis_positions, &values);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_basic_horizontal_plot(ui: &Ui) {
|
||||||
|
ui.text(im_str!("This header shows a simple horizontal bar plot."));
|
||||||
|
let content_width = ui.window_content_region_width();
|
||||||
|
Plot::new("Horizontal bar 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(|| {
|
||||||
|
// 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];
|
||||||
|
let values = vec![0.1, 0.2, 0.3, 0.4];
|
||||||
|
PlotBars::new("legend label")
|
||||||
|
.with_bar_width(0.05)
|
||||||
|
.with_horizontal_bars()
|
||||||
|
.plot(&axis_positions, &values);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let system = support::init(file!());
|
||||||
|
let mut showing_demo = false;
|
||||||
|
system.main_loop(move |_, ui| {
|
||||||
|
Window::new(im_str!("Line plots example"))
|
||||||
|
.size([430.0, 450.0], Condition::FirstUseEver)
|
||||||
|
.build(ui, || {
|
||||||
|
ui.text(im_str!("Hello from implot-rs!"));
|
||||||
|
ui.text_wrapped(im_str!(
|
||||||
|
"The headers here demo the bar plotting features of the library. \
|
||||||
|
Have a look at the example source code to see how they are implemented.\n\
|
||||||
|
Check out the demo from ImPlot itself first \
|
||||||
|
(by enabling the 'Show demo' checkbox) for instructions \
|
||||||
|
on how to interact with ImPlot plots."
|
||||||
|
));
|
||||||
|
|
||||||
|
ui.checkbox(im_str!("Show demo"), &mut showing_demo);
|
||||||
|
|
||||||
|
// Show individual examples in collapsed headers
|
||||||
|
if CollapsingHeader::new(im_str!("Basic vertical plot")).build(&ui) {
|
||||||
|
show_basic_vertical_plot(&ui);
|
||||||
|
}
|
||||||
|
|
||||||
|
if CollapsingHeader::new(im_str!("Basic horizontal plot")).build(&ui) {
|
||||||
|
show_basic_horizontal_plot(&ui);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if showing_demo {
|
||||||
|
implot::show_demo_window(&mut showing_demo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ mod support;
|
||||||
|
|
||||||
fn show_basic_plot(ui: &Ui) {
|
fn show_basic_plot(ui: &Ui) {
|
||||||
ui.text(im_str!(
|
ui.text(im_str!(
|
||||||
"This header just plots a line with as little code as possible."
|
"This header just draws a scatter plot with as little code as possible."
|
||||||
));
|
));
|
||||||
let content_width = ui.window_content_region_width();
|
let content_width = ui.window_content_region_width();
|
||||||
Plot::new("Simple scatter plot")
|
Plot::new("Simple scatter plot")
|
78
src/lib.rs
78
src/lib.rs
|
@ -444,7 +444,7 @@ impl PlotLine {
|
||||||
|
|
||||||
/// Struct to provide functionality for creating a scatter plot
|
/// Struct to provide functionality for creating a scatter plot
|
||||||
pub struct PlotScatter {
|
pub struct PlotScatter {
|
||||||
/// Label to show in the legend for this line
|
/// Label to show in the legend for this scatter plot
|
||||||
label: String,
|
label: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,6 +476,82 @@ impl PlotScatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Struct to provide bar plotting functionality.
|
||||||
|
pub struct PlotBars {
|
||||||
|
/// Label to show in the legend for this line
|
||||||
|
label: String,
|
||||||
|
|
||||||
|
/// Width of the bars, in plot coordinate terms
|
||||||
|
bar_width: f64,
|
||||||
|
|
||||||
|
/// Horizontal bar mode
|
||||||
|
horizontal_bars: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlotBars {
|
||||||
|
/// Create a new bar plot to be shown. Defaults to drawing vertical bars.
|
||||||
|
/// Does not draw anything yet.
|
||||||
|
pub fn new(label: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
label: label.to_owned(),
|
||||||
|
bar_width: 0.67, // Default value taken from C++ implot
|
||||||
|
horizontal_bars: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the width of the bars
|
||||||
|
pub fn with_bar_width(mut self, bar_width: f64) -> Self {
|
||||||
|
self.bar_width = bar_width;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the bars to be horizontal (default is vertical)
|
||||||
|
pub fn with_horizontal_bars(mut self) -> Self {
|
||||||
|
self.horizontal_bars = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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
|
||||||
|
/// bar is drawn, and the `bar_values` specify what values the bars have.
|
||||||
|
pub fn plot(&self, axis_positions: &Vec<f64>, bar_values: &Vec<f64>) {
|
||||||
|
let number_of_points = axis_positions.len().min(bar_values.len());
|
||||||
|
// If there is no data to plot, we stop here
|
||||||
|
if number_of_points == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
// C++ implot has separate functions for the two variants, but the interfaces
|
||||||
|
// are the same, so they are unified here. The x and y values have different
|
||||||
|
// meanings though, hence the swapping around before they are passed to the
|
||||||
|
// plotting function.
|
||||||
|
let (plot_function, x, y);
|
||||||
|
if self.horizontal_bars {
|
||||||
|
plot_function = sys::ImPlot_PlotBarsHdoublePtrdoublePtr
|
||||||
|
as unsafe extern "C" fn(*const i8, *const f64, *const f64, i32, f64, i32, i32);
|
||||||
|
x = bar_values;
|
||||||
|
y = axis_positions;
|
||||||
|
} else {
|
||||||
|
plot_function = sys::ImPlot_PlotBarsdoublePtrdoublePtr
|
||||||
|
as unsafe extern "C" fn(*const i8, *const f64, *const f64, i32, f64, i32, i32);
|
||||||
|
x = axis_positions;
|
||||||
|
y = bar_values;
|
||||||
|
};
|
||||||
|
|
||||||
|
plot_function(
|
||||||
|
im_str!("{}", self.label).as_ptr() as *const i8,
|
||||||
|
x.as_ptr(),
|
||||||
|
y.as_ptr(),
|
||||||
|
number_of_points as i32, // "as" casts saturate as of Rust 1.45. This is safe here.
|
||||||
|
self.bar_width,
|
||||||
|
0, // No offset
|
||||||
|
std::mem::size_of::<f64>() as i32, // Stride, set to one f64 for the standard use case
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Struct to provide functionality for adding text within a plot
|
/// Struct to provide functionality for adding text within a plot
|
||||||
pub struct PlotText {
|
pub struct PlotText {
|
||||||
/// Label to show in plot
|
/// Label to show in plot
|
||||||
|
|
Loading…
Reference in a new issue