where
D: Deserializer<'de>,
{
+ #[derive(Deserialize, Debug)]
+ #[serde(rename_all = "camelCase")]
+ pub struct RawVisualization {
+ /// Locale used for output, e.g. `en-US`.
+ #[serde(rename = "@lang")]
+ lang: Option<String>,
+
+ /// The `id` for the base [Style] for the graph.
+ #[serde(rename = "@style")]
+ _style: Option<String>,
+
+ /// Title or caption.
+ #[serde(rename = "@description")]
+ _description: Option<String>,
+
+ /// VizML Schema version number.
+ #[serde(rename = "@version")]
+ _version: Option<String>,
+
+ #[serde(rename = "@id")]
+ id: Option<String>,
+
+ #[serde(rename = "$value")]
+ children: Vec<VisChild>,
+ }
+
+ #[derive(Deserialize, Debug)]
+ #[serde(rename_all = "camelCase")]
+ enum VisChild {
+ SourceVariable(SourceVariable),
+ DerivedVariable(DerivedVariable),
+ /// This is a kind of stub for data that is supplied through another source.
+ /// In the corpus, these just have an `id` attribute, but there's no value
+ /// in parsing it.
+ UserSource,
+ DelimitedFileSource(DelimitedFileSource),
+ EmbeddedSource(EmbeddedSource),
+ CategoricalDomain(CategoricalDomain),
+ IntervalDomain(IntervalDomain),
+ Graph(Graph),
+ LabelFrame(LabelFrame),
+ Container(Container),
+ StyleCycle(StyleCycle),
+ Style(Style),
+ Location(Location),
+ #[serde(other)]
+ Other,
+ }
+
let RawVisualization {
lang,
_style,
}
}
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-pub struct RawVisualization {
- /// Locale used for output, e.g. `en-US`.
- #[serde(rename = "@lang")]
- lang: Option<String>,
-
- /// The `id` for the base [Style] for the graph.
- #[serde(rename = "@style")]
- _style: Option<String>,
-
- /// Title or caption.
- #[serde(rename = "@description")]
- _description: Option<String>,
-
- /// VizML Schema version number.
- #[serde(rename = "@version")]
- _version: Option<String>,
-
- #[serde(rename = "@id")]
- id: Option<String>,
-
- #[serde(rename = "$value")]
- children: Vec<VisChild>,
-}
-
impl Visualization {
fn all_variables(&self) -> impl Iterator<Item = &dyn Variable> {
let source_variables = self
let elements = graph
.elements
.iter()
- .map(|(raw, graphic)| {
- Element::new(
- raw,
- locale,
- *graphic,
- series,
- bin_widths,
- axis_domains,
- styles,
- )
- })
+ .map(|raw| Element::new(raw, locale, series, bin_widths, axis_domains, styles))
.collect::<Result<Vec<_>, _>>()?;
let dimensions = graph.coordinates.dimensions().collect_vec();
for (index, axis) in [Axis3::X, Axis3::Y, Axis3::Z].into_iter().enumerate() {
}
let mut element_svg = Group::new().with_id(&element.raw.id);
- match element.graphic {
+ match element.raw.graphic {
Graphic::Interval => {
// Size defaults to 33%.
let fraction = match style.symbol_size {
}
}
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-enum VisChild {
- SourceVariable(SourceVariable),
- DerivedVariable(DerivedVariable),
- /// This is a kind of stub for data that is supplied through another source.
- /// In the corpus, these just have an `id` attribute, but there's no value
- /// in parsing it.
- UserSource,
- DelimitedFileSource(DelimitedFileSource),
- EmbeddedSource(EmbeddedSource),
- CategoricalDomain(CategoricalDomain),
- IntervalDomain(IntervalDomain),
- Graph(Graph),
- LabelFrame(LabelFrame),
- Container(Container),
- StyleCycle(StyleCycle),
- Style(Style),
- Location(Location),
- #[serde(other)]
- Other,
-}
-
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct DelimitedFileSource {
struct Element<'a> {
raw: &'a RawElement,
style: Cow<'a, Style>,
- graphic: Graphic,
variables: EnumMap<Axis3, Option<Series>>,
/// Whether to ignore this element for the purpose of computing minimum and
fn new(
raw: &'a RawElement,
locale: &'static Locale<'static>,
- graphic: Graphic,
series: &BTreeMap<&str, Series>,
bin_widths: &mut BTreeMap<String, f64>,
axis_domains: &mut EnumMap<Axis3, AxisDomain<'a>>,
} else {
Cow::Owned(Style::default())
},
- graphic,
variables,
ignore_minmax,
})
faceting: Option<Faceting>,
facet_layout: Option<FacetLayout>,
coordinates: Coordinates,
- elements: Vec<(RawElement, Graphic)>,
+ elements: Vec<RawElement>,
}
impl Graph {
where
D: Deserializer<'de>,
{
+ #[derive(Deserialize, Debug)]
+ #[serde(rename_all = "camelCase")]
+ struct RawGraph {
+ #[serde(rename = "@id")]
+ id: Option<String>,
+
+ #[serde(rename = "@cellStyle")]
+ cell_style: Option<String>,
+
+ #[serde(rename = "$value")]
+ children: Vec<GraphChild>,
+ }
+
+ #[derive(Deserialize, Debug)]
+ #[serde(rename_all = "camelCase")]
+ enum GraphChild {
+ Location(Location),
+ Faceting(Faceting),
+ FacetLayout(FacetLayout),
+ Coordinates(Coordinates),
+ Interval(RawElement),
+ Point(RawElement),
+ Line(RawElement),
+ Polygon(RawElement),
+ Area(RawElement),
+ Schema(RawElement),
+ Edge(RawElement),
+ Path(RawElement),
+ LineGuide,
+ }
+
let raw_graph = RawGraph::deserialize(deserializer)?;
let mut locations = Vec::new();
let mut faceting = None;
let mut elements = Vec::new();
for child in raw_graph.children {
match child {
- GraphChild::Interval(interval) => elements.push((interval, Graphic::Interval)),
- GraphChild::Point(point) => elements.push((point, Graphic::Point)),
- GraphChild::Line(line) => elements.push((line, Graphic::Line)),
- GraphChild::Polygon(polygon) => elements.push((polygon, Graphic::Polygon)),
- GraphChild::Area(area) => elements.push((area, Graphic::Area)),
- GraphChild::Schema(schema) => elements.push((schema, Graphic::Schema)),
- GraphChild::Edge(edge) => elements.push((edge, Graphic::Edge)),
- GraphChild::Path(path) => elements.push((path, Graphic::Path)),
+ GraphChild::Interval(interval) => {
+ elements.push(interval.with_graphic(Graphic::Interval))
+ }
+ GraphChild::Point(point) => elements.push(point.with_graphic(Graphic::Point)),
+ GraphChild::Line(line) => elements.push(line.with_graphic(Graphic::Line)),
+ GraphChild::Polygon(polygon) => {
+ elements.push(polygon.with_graphic(Graphic::Polygon))
+ }
+ GraphChild::Area(area) => elements.push(area.with_graphic(Graphic::Area)),
+ GraphChild::Schema(schema) => elements.push(schema.with_graphic(Graphic::Schema)),
+ GraphChild::Edge(edge) => elements.push(edge.with_graphic(Graphic::Edge)),
+ GraphChild::Path(path) => elements.push(path.with_graphic(Graphic::Path)),
GraphChild::Location(location) => locations.push(location),
GraphChild::Faceting(value) => {
if faceting.replace(value).is_some() {
}
}
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct RawGraph {
- #[serde(rename = "@id")]
- id: Option<String>,
-
- #[serde(rename = "@cellStyle")]
- cell_style: Option<String>,
-
- #[serde(rename = "$value")]
- children: Vec<GraphChild>,
-}
-
-impl RawGraph {
- fn coordinates(&self) -> impl Iterator<Item = &Coordinates> {
- self.children.iter().filter_map(|child| match child {
- GraphChild::Coordinates(coordinates) => Some(coordinates),
- _ => None,
- })
- }
-
- fn elements(&self) -> impl Iterator<Item = (&RawElement, Graphic)> {
- self.children.iter().filter_map(|child| child.element())
- }
-
- fn faceting(&self) -> Option<&Faceting> {
- self.children.iter().find_map(|child| child.faceting())
- }
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-enum GraphChild {
- Location(Location),
- Faceting(Faceting),
- FacetLayout(FacetLayout),
- Coordinates(Coordinates),
- Interval(RawElement),
- Point(RawElement),
- Line(RawElement),
- Polygon(RawElement),
- Area(RawElement),
- Schema(RawElement),
- Edge(RawElement),
- Path(RawElement),
- LineGuide,
-}
-
-impl GraphChild {
- fn element(&self) -> Option<(&RawElement, Graphic)> {
- match self {
- GraphChild::Interval(interval) => Some((interval, Graphic::Interval)),
- GraphChild::Point(point) => Some((point, Graphic::Point)),
- GraphChild::Line(line) => Some((line, Graphic::Line)),
- GraphChild::Polygon(polygon) => Some((polygon, Graphic::Polygon)),
- GraphChild::Area(area) => Some((area, Graphic::Area)),
- GraphChild::Schema(schema) => Some((schema, Graphic::Schema)),
- GraphChild::Edge(edge) => Some((edge, Graphic::Edge)),
- GraphChild::Path(path) => Some((path, Graphic::Path)),
- _ => None,
- }
- }
-
- fn facet_layout(&self) -> Option<&FacetLayout> {
- match self {
- Self::FacetLayout(facet_layout) => Some(facet_layout),
- _ => None,
- }
- }
-
- fn location(&self) -> Option<&Location> {
- match self {
- Self::Location(location) => Some(location),
- _ => None,
- }
- }
-
- fn faceting(&self) -> Option<&Faceting> {
- match self {
- Self::Faceting(faceting) => Some(faceting),
- _ => None,
- }
- }
-}
-
#[derive(Copy, Clone, Deserialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
enum BreakRepresentation {
Wings,
}
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
enum Graphic {
/// Bar chart of bars. Each `(x,y)` bar covers `0..y` at the given `x`
/// coordinate.
+ #[default]
Interval,
/// Scatter-plot of `(x,y)` points.
Point,
z: Option<Coordinate>,
color: Vec<ColorAesthetic>,
style_by: Vec<StyleBy>,
+ #[serde(skip)]
+ graphic: Graphic,
}
impl RawElement {
+ fn with_graphic(mut self, graphic: Graphic) -> Self {
+ self.graphic = graphic;
+ self
+ }
fn coordinate(&self, index: usize) -> Option<&Coordinate> {
match index {
0 => self.x.as_ref(),
where
D: Deserializer<'de>,
{
+ #[derive(Deserialize, Debug)]
+ #[serde(rename_all = "camelCase")]
+ struct RawContainer {
+ #[serde(rename = "@id")]
+ id: Option<String>,
+ #[serde(rename = "$value")]
+ #[serde(default)]
+ children: Vec<ContainerChild>,
+ }
+
+ #[derive(Deserialize, Debug)]
+ #[serde(rename_all = "camelCase")]
+ enum ContainerChild {
+ Location(Location),
+ Container(Container),
+ Graph(Graph),
+ Legend(Legend),
+ LabelFrame(LabelFrame),
+ }
+
+ impl ContainerChild {
+ fn location(&self) -> Option<&Location> {
+ match self {
+ Self::Location(location) => Some(location),
+ _ => None,
+ }
+ }
+ }
+
let raw_container = RawContainer::deserialize(deserializer)?;
let mut locations = Vec::new();
let mut children = Vec::new();
}
}
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct RawContainer {
- #[serde(rename = "@id")]
- id: Option<String>,
- #[serde(rename = "$value")]
- #[serde(default)]
- children: Vec<ContainerChild>,
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-enum ContainerChild {
- Location(Location),
- Container(Container),
- Graph(Graph),
- Legend(Legend),
- LabelFrame(LabelFrame),
-}
-
-impl ContainerChild {
- fn location(&self) -> Option<&Location> {
- match self {
- Self::Location(location) => Some(location),
- _ => None,
- }
- }
-}
-
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Legend {