diff --git a/src/axis.rs b/src/axis.rs index a361201..d26b0e0 100644 --- a/src/axis.rs +++ b/src/axis.rs @@ -20,6 +20,11 @@ impl Range { } } +pub enum AxisType { + Continuous, + Discrete, +} + #[derive(Debug)] pub struct ContinuousAxis { range: Range, diff --git a/src/boxplot.rs b/src/boxplot.rs index 8a0535d..f0e367e 100644 --- a/src/boxplot.rs +++ b/src/boxplot.rs @@ -18,7 +18,7 @@ use std::f64; use svg; use axis; -use representation::DiscreteRepresentation; +use representation::{Representation, DiscreteRepresentation}; use svg_render; use style; use utils; @@ -118,6 +118,12 @@ impl<'a> BoxPlot<'a> { } } +impl<'a> Representation for BoxPlot<'a> { + fn axis_types(&self) -> Vec { + vec![axis::AxisType::Discrete, axis::AxisType::Continuous] + } +} + impl<'a> DiscreteRepresentation for BoxPlot<'a> { /// The maximum range. Used for auto-scaling axis fn range(&self) -> (f64, f64) { diff --git a/src/function.rs b/src/function.rs index 27c6d3b..a90012e 100644 --- a/src/function.rs +++ b/src/function.rs @@ -18,7 +18,7 @@ use std::f64; use svg; use axis; -use representation::ContinuousRepresentation; +use representation::{Representation, ContinuousRepresentation}; use svg_render; use style; @@ -129,6 +129,12 @@ impl Function { } } +impl Representation for Function { + fn axis_types(&self) -> Vec { + vec![axis::AxisType::Continuous, axis::AxisType::Continuous] + } +} + impl ContinuousRepresentation for Function { fn range(&self, dim: u32) -> (f64, f64) { match dim { diff --git a/src/histogram.rs b/src/histogram.rs index 87a2adf..5f2e1da 100644 --- a/src/histogram.rs +++ b/src/histogram.rs @@ -26,7 +26,7 @@ use axis; use utils::PairWise; use svg_render; use text_render; -use representation::ContinuousRepresentation; +use representation::{Representation, ContinuousRepresentation}; use style; #[derive(Debug, Default)] @@ -147,6 +147,12 @@ impl Histogram { } } +impl Representation for Histogram { + fn axis_types(&self) -> Vec { + vec![axis::AxisType::Continuous, axis::AxisType::Continuous] + } +} + impl ContinuousRepresentation for Histogram { fn range(&self, dim: u32) -> (f64, f64) { match dim { diff --git a/src/line.rs b/src/line.rs index fd2b084..27af612 100644 --- a/src/line.rs +++ b/src/line.rs @@ -18,7 +18,7 @@ use std::f64; use svg; use axis; -use representation::ContinuousRepresentation; +use representation::{Representation, ContinuousRepresentation}; use svg_render; use style; @@ -116,6 +116,12 @@ impl Line { } } +impl Representation for Line { + fn axis_types(&self) -> Vec { + vec![axis::AxisType::Continuous, axis::AxisType::Continuous] + } +} + impl ContinuousRepresentation for Line { fn range(&self, dim: u32) -> (f64, f64) { match dim { diff --git a/src/representation.rs b/src/representation.rs index 01eef13..edd94ef 100644 --- a/src/representation.rs +++ b/src/representation.rs @@ -15,10 +15,14 @@ These points may then be layered with other SVG elements from other representati use svg; use axis; +pub trait Representation { + fn axis_types(&self) -> Vec; +} + /** A representation of data that is continuous in two dimensions. */ -pub trait ContinuousRepresentation { +pub trait ContinuousRepresentation: Representation { /// The maximum range in each dimension. Used for auto-scaling axes. fn range(&self, dim: u32) -> (f64, f64); @@ -42,7 +46,7 @@ pub trait ContinuousRepresentation { /** A representation of data that is discrete in the x-axis but continuous in the y-axis. */ -pub trait DiscreteRepresentation { +pub trait DiscreteRepresentation: Representation { /// The maximum range in the y-axis. Used for auto-scaling the axis. fn range(&self) -> (f64, f64); diff --git a/src/scatter.rs b/src/scatter.rs index 48c9615..8feeff5 100644 --- a/src/scatter.rs +++ b/src/scatter.rs @@ -5,7 +5,7 @@ use svg; use axis; use svg_render; use text_render; -use representation::ContinuousRepresentation; +use representation::{Representation, ContinuousRepresentation}; use style; /// `Style` follows the 'optional builder' pattern @@ -133,6 +133,12 @@ impl Scatter { } } +impl Representation for Scatter { + fn axis_types(&self) -> Vec { + vec![axis::AxisType::Continuous, axis::AxisType::Continuous] + } +} + impl ContinuousRepresentation for Scatter { fn range(&self, dim: u32) -> (f64, f64) { match dim { diff --git a/src/view.rs b/src/view.rs index ab0f441..350598a 100644 --- a/src/view.rs +++ b/src/view.rs @@ -12,7 +12,7 @@ use std::f64; use svg; use svg::Node; -use representation::{DiscreteRepresentation, ContinuousRepresentation}; +use representation::{Representation, DiscreteRepresentation, ContinuousRepresentation}; use axis; use svg_render; use text_render; @@ -341,11 +341,28 @@ impl<'a> View for DiscreteView<'a> { } } -/*pub struct AnyView<'a> { +use std::collections::HashMap; + +/** +A ReprMap is an N-dimensional plot object which can contain many data representations. + +Its building blocks are: +- a list of reprs +- a list of axes, one for each dimension +- a mapping of repr dimensions onto view dimensions +*/ +pub struct ReprMap<'a> { representations: Vec<&'a Representation>, - axes: Vec<>, - x_range: Option, - y_range: Option, - x_label: Option, - y_label: Option, -}*/ + axes: Vec, + mapping: HashMap<(usize, usize), usize>, +} + +impl<'a> ReprMap<'a> { + fn add(&mut self, repr: &'a Representation) { + self.representations.push(repr); + let repr_pos = self.representations.len(); + for (i, axis_type) in repr.axis_types().iter().enumerate() { + self.mapping.insert((repr_pos, i), i); + } + } +}