diff --git a/examples/iris.rs b/examples/iris.rs index 2d894d9..3c964f5 100644 --- a/examples/iris.rs +++ b/examples/iris.rs @@ -2,44 +2,56 @@ use blarg::{derive::*, prelude::*, CommandLineParser, Parameter, Scalar, Switch} use flat::*; use ordered_float::OrderedFloat; use serde::Deserialize; +use std::fmt::Formatter; fn main() { - let parameters = Parameters::blarg_parse(); - let dataset: Vec = serde_json::from_str(IRIS_JSON).unwrap(); + // let parameters = Parameters::blarg_parse(); + let json_data: Vec = serde_json::from_str(IRIS_JSON).unwrap(); + bar_chart(true, json_data.as_slice()); + bar_chart_breakdown(true, json_data.as_slice()); + // let mut dataset = Dataset::builder(FlowerSchema); + // + // for flower in &json_data { + // dataset.update(flower.into(), 1); + // } + // + // let sepal_view = SepalView { dataset: &dataset }; - match parameters.widget { - Widget::BarChart => { - if parameters.breakdown { - bar_chart_breakdown(¶meters, dataset); - } else { - bar_chart(¶meters, dataset); - } - } - Widget::Histogram => { - if parameters.breakdown { - histogram_breakdown(¶meters, dataset); - } else { - histogram(¶meters, dataset); - } - } - } + // BarChart::new(&sepal_view).render(Render::default()); + + // match parameters.widget { + // Widget::BarChart => { + // if parameters.breakdown { + // bar_chart_breakdown(¶meters, dataset); + // } else { + // bar_chart(¶meters, dataset); + // } + // } + // Widget::Histogram => { + // if parameters.breakdown { + // histogram_breakdown(¶meters, dataset); + // } else { + // histogram(¶meters, dataset); + // } + // } + // } } -fn bar_chart(parameters: &Parameters, dataset: Vec) { +fn bar_chart(verbose: bool, json_data: &[FlowerJson]) { let schema = Schemas::one("Species", "Petal Length"); let mut builder = Dataset::builder(schema); - for flower in dataset { + for flower in json_data { builder.update((flower.species.clone(),), flower.petal_length); } let view = builder.view(); let flat = BarChart::new(&view).render(Render { aggregate: Aggregate::Average, - show_aggregate: parameters.verbose, + show_aggregate: verbose, widget_config: { BarChartConfig { - show_aggregate: parameters.verbose, + show_aggregate: verbose, ..BarChartConfig::default() } }, @@ -50,11 +62,11 @@ fn bar_chart(parameters: &Parameters, dataset: Vec) { println!("{flat}"); } -fn bar_chart_breakdown(parameters: &Parameters, dataset: Vec) { - let schema = Schemas::two("Attribute", "Species", "moot"); +fn bar_chart_breakdown(verbose: bool, json_data: &[FlowerJson]) { + let schema = Schemas::two("Attribute", "Species", "Value"); let mut builder = Dataset::builder(schema); - for flower in dataset { + for flower in json_data { builder.update( ("sepal_length", flower.species.clone()), flower.sepal_length, @@ -67,13 +79,13 @@ fn bar_chart_breakdown(parameters: &Parameters, dataset: Vec) { builder.update(("petal_width", flower.species.clone()), flower.petal_width); } - let view = builder.view_breakdown2(); + let view = builder.view(); let flat = BarChart::new(&view).render(Render { aggregate: Aggregate::Average, - show_aggregate: parameters.verbose, + show_aggregate: verbose, widget_config: { BarChartConfig { - show_aggregate: parameters.verbose, + show_aggregate: verbose, ..BarChartConfig::default() } }, @@ -82,45 +94,61 @@ fn bar_chart_breakdown(parameters: &Parameters, dataset: Vec) { println!("Shows the relative attribute values of flowers in the dataset, broken down by their species."); println!(); println!("{flat}"); -} - -fn histogram(parameters: &Parameters, dataset: Vec) { - let schema = Schemas::one("Petal Length", "Flower Count"); - let mut builder = Dataset::builder(schema); - - for flower in dataset { - builder.update((flower.petal_length,), 1); - } - - let view = builder.view(); - let flat = Histogram::new(&view, 10).render(Render { - aggregate: Aggregate::Sum, - show_aggregate: parameters.verbose, - ..Render::default() - }); - println!("Shows the relative count of flowers in the dataset, organized into bins based off their petal length."); - println!(); - println!("{flat}"); -} - -fn histogram_breakdown(parameters: &Parameters, dataset: Vec) { - let schema = Schemas::two("Petal Length", "Petal Widths", "moot"); - let mut builder = Dataset::builder(schema); - - for flower in dataset { - builder.update((flower.petal_length, OrderedFloat(flower.petal_width)), 1); - } let view = builder.view_breakdown2(); - let flat = Histogram::new(&view, 10).render(Render { - aggregate: Aggregate::Sum, - show_aggregate: parameters.verbose, + let flat = BarChart::new(&view).render(Render { + aggregate: Aggregate::Average, + show_aggregate: verbose, + widget_config: { + BarChartConfig { + show_aggregate: verbose, + ..BarChartConfig::default() + } + }, ..Render::default() }); - println!("Shows the relative count of flowers in the dataset, broken down by their petal widths, organized into bins based off their petal length."); + println!("Shows the relative attribute values of flowers in the dataset, broken down by their species."); println!(); println!("{flat}"); } +// +// fn histogram(parameters: &Parameters, dataset: Vec) { +// let schema = Schemas::one("Petal Length", "Flower Count"); +// let mut builder = Dataset::builder(schema); +// +// for flower in dataset { +// builder.update((flower.petal_length,), 1); +// } +// +// let view = builder.view(); +// let flat = Histogram::new(&view, 10).render(Render { +// aggregate: Aggregate::Sum, +// show_aggregate: parameters.verbose, +// ..Render::default() +// }); +// println!("Shows the relative count of flowers in the dataset, organized into bins based off their petal length."); +// println!(); +// println!("{flat}"); +// } +// +// fn histogram_breakdown(parameters: &Parameters, dataset: Vec) { +// let schema = Schemas::two("Petal Length", "Petal Widths", "moot"); +// let mut builder = Dataset::builder(schema); +// +// for flower in dataset { +// builder.update((flower.petal_length, OrderedFloat(flower.petal_width)), 1); +// } +// +// let view = builder.view_breakdown2(); +// let flat = Histogram::new(&view, 10).render(Render { +// aggregate: Aggregate::Sum, +// show_aggregate: parameters.verbose, +// ..Render::default() +// }); +// println!("Shows the relative count of flowers in the dataset, broken down by their petal widths, organized into bins based off their petal length."); +// println!(); +// println!("{flat}"); +// } #[derive(BlargChoices, PartialEq)] enum Widget { @@ -166,13 +194,136 @@ struct Parameters { breakdown: bool, } -#[derive(Debug, Deserialize)] +// #[derive(Debug, Clone)] +#[derive(Debug, Clone)] +struct SepalLength(f64); + +impl std::fmt::Display for SepalLength { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", minimal_precision_string(self.0)) + } +} + +#[derive(Debug, Clone)] +struct SepalWidth(f64); + +impl std::fmt::Display for SepalWidth { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", minimal_precision_string(self.0)) + } +} + +#[derive(Debug, Clone)] +struct PetalLength(f64); + +impl std::fmt::Display for PetalLength { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", minimal_precision_string(self.0)) + } +} + +#[derive(Debug, Clone)] +struct PetalWidth(f64); + +impl std::fmt::Display for PetalWidth { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", minimal_precision_string(self.0)) + } +} + +#[derive(Debug, Clone)] +// #[derive(Debug, Clone, PartialEq, Eq, Hash)] struct Flower { + species: String, + sepal_length: SepalLength, + sepal_width: SepalWidth, + petal_length: PetalLength, + petal_width: PetalWidth, +} + +#[derive(Debug, Deserialize)] +struct FlowerJson { + species: String, sepal_length: f64, sepal_width: f64, petal_length: f64, petal_width: f64, - species: String, +} + +impl From<&FlowerJson> for Flower { + fn from(value: &FlowerJson) -> Self { + Self { + species: value.species.clone(), + sepal_length: SepalLength(value.sepal_length), + sepal_width: SepalWidth(value.sepal_width), + petal_length: PetalLength(value.petal_length), + petal_width: PetalWidth(value.petal_width), + } + } +} + +impl Dimensions for Flower { + fn as_strings(&self) -> Vec { + vec![ + self.species.clone(), + self.sepal_length.0.to_string(), + self.sepal_width.0.to_string(), + self.petal_length.0.to_string(), + self.petal_width.0.to_string(), + ] + } + + fn len(&self) -> usize { + 5 + } +} + +struct FlowerSchema; + +impl Schema for FlowerSchema { + type Dimensions = Flower; +} + +struct SepalView<'a> { + dataset: &'a Dataset, +} + +impl<'a> View for SepalView<'a> { + type Dimensions = Flower; + type PrimaryDimension = (SepalLength, SepalWidth); + type BreakdownDimension = Nothing; + type SortDimensions = (SepalLength, SepalWidth); + + fn dataset(&self) -> &Dataset { + &self.dataset + } + + fn primary_dim(&self, dims: &::Dimensions) -> Self::PrimaryDimension { + (dims.sepal_length.clone(), dims.sepal_width.clone()) + } + + fn breakdown_dim( + &self, + dims: &::Dimensions, + ) -> Self::BreakdownDimension { + Nothing + } + + fn sort_dims(&self, dims: &::Dimensions) -> Self::SortDimensions { + (dims.sepal_length.clone(), dims.sepal_width.clone()) + } + + fn headers(&self) -> Vec { + vec!["Sepal Length".to_string(), "Sepal Width".to_string()] + } + + fn data_header(&self) -> String { + "abc".to_string() + } + + fn is_breakdown(&self) -> bool { + false + } } const IRIS_JSON: &str = r#"[