Skip to main content

esoc_chart/grammar/
encoding.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2//! Encoding: maps data fields to visual channels.
3
4/// A data field type.
5#[derive(Clone, Debug)]
6pub enum FieldType {
7    /// Continuous numeric data.
8    Quantitative,
9    /// Categorical/nominal data.
10    Nominal,
11    /// Ordered categorical data.
12    Ordinal,
13    /// Temporal data.
14    Temporal,
15}
16
17/// A visual channel.
18#[derive(Clone, Debug)]
19pub enum Channel {
20    /// X position.
21    X,
22    /// Y position.
23    Y,
24    /// Fill color.
25    Color,
26    /// Marker size.
27    Size,
28    /// Marker shape (not yet supported).
29    #[doc(hidden)]
30    Shape,
31    /// Opacity (not yet supported).
32    #[doc(hidden)]
33    Opacity,
34    /// Text content (not yet supported).
35    #[doc(hidden)]
36    Text,
37}
38
39/// An encoding maps a data field to a visual channel.
40#[derive(Clone, Debug)]
41pub struct Encoding {
42    /// Visual channel.
43    pub channel: Channel,
44    /// Field type.
45    pub field_type: FieldType,
46    /// Data accessor (column index or field name).
47    pub field: FieldAccessor,
48    /// Optional title for this encoding (used in legends/axis labels).
49    pub title: Option<String>,
50}
51
52/// How to access a data field.
53#[derive(Clone, Debug)]
54pub enum FieldAccessor {
55    /// Column index.
56    Index(usize),
57    /// Field name.
58    Name(String),
59}
60
61/// Convenience constructors.
62#[deprecated(note = "Defaults channel to X which is misleading; use Encoding struct directly")]
63pub fn quantitative(index: usize) -> Encoding {
64    Encoding {
65        channel: Channel::X,
66        field_type: FieldType::Quantitative,
67        field: FieldAccessor::Index(index),
68        title: None,
69    }
70}
71
72/// Create a nominal encoding.
73#[deprecated(note = "Defaults channel to X which is misleading; use Encoding struct directly")]
74pub fn nominal(index: usize) -> Encoding {
75    Encoding {
76        channel: Channel::X,
77        field_type: FieldType::Nominal,
78        field: FieldAccessor::Index(index),
79        title: None,
80    }
81}
82
83impl Encoding {
84    /// Set the channel.
85    pub fn channel(mut self, ch: Channel) -> Self {
86        self.channel = ch;
87        self
88    }
89
90    /// Set a title.
91    pub fn title(mut self, title: impl Into<String>) -> Self {
92        self.title = Some(title.into());
93        self
94    }
95}