This commit is contained in:
Simon Gardling 2022-02-23 15:37:49 -05:00
parent 59e4793a1b
commit e049038813
4 changed files with 28 additions and 7 deletions

View File

@ -1,4 +1,3 @@
## TODO: ## TODO:
1. Port to [egui](https://github.com/emilk/egui) 1. Port to [egui](https://github.com/emilk/egui)
- Reimplement testing the validity of functions.
- Proper support for dynamic chart display size. - Proper support for dynamic chart display size.

View File

@ -1,8 +1,10 @@
use core::num;
use eframe::{egui, epi}; use eframe::{egui, epi};
use egui::{plot::{HLine, Line, Plot, Value, Values, Text}, Pos2}; use egui::{plot::{HLine, Line, Plot, Value, Values, Text}, Pos2};
use crate::chart_manager::ChartManager; use crate::chart_manager::ChartManager;
use meval::Expr; use meval::Expr;
use crate::misc::{add_asterisks, Cache, Function}; use crate::misc::{add_asterisks, Cache, Function, digits_precision, test_func};
use egui::{Color32, ColorImage, Ui}; use egui::{Color32, ColorImage, Ui};
use emath::Rect; use emath::Rect;
use epaint::{Rounding, RectShape, Stroke}; use epaint::{Rounding, RectShape, Stroke};
@ -56,6 +58,7 @@ impl epi::App for MathApp {
chart_manager chart_manager
} = self; } = self;
let mut parse_error: String = "".to_string();
egui::SidePanel::left("side_panel").show(ctx, |ui| { egui::SidePanel::left("side_panel").show(ctx, |ui| {
ui.heading("Side Panel"); ui.heading("Side Panel");
@ -63,6 +66,10 @@ impl epi::App for MathApp {
ui.label("Function: "); ui.label("Function: ");
ui.text_edit_singleline(func_str); ui.text_edit_singleline(func_str);
}); });
let func_test_output = test_func(func_str.clone());
if func_test_output != "" {
parse_error = func_test_output;
}
ui.add(egui::Slider::new(min_x, -1000.0..=1000.0).text("Min X")); ui.add(egui::Slider::new(min_x, -1000.0..=1000.0).text("Min X"));
ui.add(egui::Slider::new(max_x, *min_x..=1000.0).text("Max X")); ui.add(egui::Slider::new(max_x, *min_x..=1000.0).text("Max X"));
@ -71,22 +78,29 @@ impl epi::App for MathApp {
}); });
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
if parse_error != "" {
ui.label(format!("Error: {}", parse_error));
return;
}
let (filtered_data, rect_data, area) = chart_manager.update(self.func_str.clone(), self.min_x, self.max_x, self.num_interval, self.resolution); let (filtered_data, rect_data, area) = chart_manager.update(self.func_str.clone(), self.min_x, self.max_x, self.num_interval, self.resolution);
let filtered_data_values = filtered_data.iter().map(|(x, y)| Value::new(*x, *y)).collect(); let filtered_data_values = filtered_data.iter().map(|(x, y)| Value::new(*x, *y)).collect();
let curve = Line::new(Values::from_values(filtered_data_values)).color(Color32::RED); let curve = Line::new(Values::from_values(filtered_data_values)).color(Color32::RED);
let bars = rect_data.iter().map(|(_, x2, y)| Bar::new(*x2, *y)).collect(); let bars = rect_data.iter().map(|(_, x2, y)| Bar::new(*x2, *y)).collect();
let barchart = BarChart::new(bars).color(Color32::BLUE); let barchart = BarChart::new(bars).color(Color32::BLUE);
// ui.label("Graph:"); ui.label(format!("Area: {}", digits_precision(area, 8)));
ui.label(format!("Area: {:.10}", area));
Plot::new("plot") Plot::new("plot")
.view_aspect(1.0) .view_aspect(1.0)
.include_y(0) .include_y(0)
.show(ui, |plot_ui| { .show(ui, |plot_ui| {
plot_ui.line(curve); plot_ui.line(curve);
plot_ui.bar_chart(barchart); if self.num_interval > 0 {
plot_ui.bar_chart(barchart);
}
}); });
}); });

View File

@ -1,8 +1,10 @@
use eframe::{epi, egui};
mod egui_app; mod egui_app;
// These 2 are needed for rust-analyzer to work in vscode.
mod misc; mod misc;
mod chart_manager; mod chart_manager;
// For running the program natively! (Because why not?)
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
fn main() { fn main() {
let app = egui_app::MathApp::default(); let app = egui_app::MathApp::default();

View File

@ -107,6 +107,12 @@ pub fn test_func(function_string: String) -> String {
"".to_string() "".to_string()
} }
// Rounds f64 to specific number of digits
pub fn digits_precision(x: f64, digits: usize) -> f64 {
let large_number: f64 = (10.0 as f64).powf(digits as f64);
(x * large_number).round() / large_number
}
pub struct Function { pub struct Function {
function: Box<dyn Fn(f64) -> f64>, function: Box<dyn Fn(f64) -> f64>,
func_str: String, func_str: String,