use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use super::coord::Coord;
use crate::plot::{Layer, Parameters};
use crate::reader::SqlDialect;
use crate::DataFrame;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Projection {
pub coord: Coord,
pub aesthetics: Vec<String>,
pub properties: Parameters,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub computed: Parameters,
}
impl Projection {
pub fn cartesian() -> Self {
Self::with_defaults(Coord::cartesian())
}
pub fn polar() -> Self {
Self::with_defaults(Coord::polar())
}
pub fn map() -> Self {
Self::with_defaults(Coord::map("crs", &Parameters::new()))
}
fn with_defaults(coord: Coord) -> Self {
let aesthetics = coord
.position_aesthetic_names()
.iter()
.map(|s| s.to_string())
.collect();
Self {
coord,
aesthetics,
properties: Parameters::new(),
computed: Parameters::new(),
}
}
pub fn position_names(&self) -> Vec<&str> {
self.aesthetics.iter().map(|s| s.as_str()).collect()
}
pub fn apply_projection_transforms(
&mut self,
layers: &mut [Layer],
layer_queries: &mut [String],
dialect: &dyn SqlDialect,
execute_query: &dyn Fn(&str) -> crate::Result<DataFrame>,
) -> crate::Result<()> {
let coord = self.coord.clone();
coord.apply_projection_transforms(layers, layer_queries, self, dialect, execute_query)
}
}