use crate::{
data::Datum,
- format::{Type, UncheckedFormat},
locale::{Item, Locale, data::EN},
output::{
SpvGraphMembers, SpvInfo, SpvMembers,
let dimensions = &graph.coordinates.dimensions;
for axis in all() {
let mut domain = if let Some(dimension) = &dimensions[axis]
- && let Some(domain_name) = &dimension.domain
+ && let Some(domain_name) = &dimension._domain
&& let Some(domain) = domains.get(domain_name.as_str())
{
Some(domain.clone())
domain,
formatter: formatter.unwrap_or_else(|| Formatter::default_for_locale(locale)),
axis: axis2,
- label: axis2.and_then(|axis| axis.label.as_ref()),
+ _label: axis2.and_then(|axis| axis.label.as_ref()),
major_ticks: axis2.and_then(|axis| axis.major_ticks.as_ref()),
};
}
#[derive(Clone)]
struct Series {
pub name: String,
- label: Option<String>,
- short_label: Option<String>,
- weight: bool,
- key: bool,
+ _label: Option<String>,
+ _short_label: Option<String>,
+ _weight: bool,
+ _key: bool,
categorical: bool,
values: Vec<SeriesValue>,
unique_values: Vec<SeriesValue>,
};
Self {
name,
- label: None,
- short_label: None,
- weight: false,
- key: false,
+ _label: None,
+ _short_label: None,
+ _weight: false,
+ _key: false,
categorical,
values,
unique_values,
}
}
fn with_label(self, label: Option<String>) -> Self {
- Self { label, ..self }
+ Self {
+ _label: label,
+ ..self
+ }
}
}
/// Always "UTF-8" in the corpus.
#[serde(rename = "@encoding")]
- pub encoding: String,
+ pub _encoding: String,
/// A filename or URI-like string that probably names on a file on the host
/// of the person who created the graph.
#[serde(rename = "@fileName")]
- pub file_name: Option<String>,
+ pub _file_name: Option<String>,
#[serde(rename = "@missing")]
- pub missing: DelimitedFileSourceMissing,
+ pub _missing: DelimitedFileSourceMissing,
}
impl Default for DelimitedFileSource {
fn default() -> Self {
Self {
id: String::new(),
- encoding: String::from("UTF-8"),
- file_name: None,
- missing: DelimitedFileSourceMissing::default(),
+ _encoding: String::from("UTF-8"),
+ _file_name: None,
+ _missing: DelimitedFileSourceMissing::default(),
}
}
}
string_format: Option<StringFormat>,
}
-impl SourceVariable {
- fn affixes(&self) -> &[Affix] {
- if let Some(format) = &self.format {
- &format.affixes
- } else if let Some(string_format) = &self.string_format {
- &string_format.affixes
- } else {
- &[]
- }
- }
-}
impl Variable for SourceVariable {
fn decode<'a>(
&'a self,
domain: Domain,
formatter: Formatter,
axis: Option<&'a Axis>,
- label: Option<&'a Label>,
+ _label: Option<&'a Label>,
major_ticks: Option<&'a MajorTicks>,
}
domain: Domain::default(),
formatter: Formatter::default_for_locale(locale),
axis: None,
- label: None,
+ _label: None,
major_ticks: None,
}
}
exact: false,
}
}
- fn is_interval(&self) -> bool {
- matches!(self, Self::Interval { .. })
- }
- fn lookup_categorical(&self, value: &Datum<String>) -> Option<usize> {
- match self {
- Domain::Categorical { values } => values.get_index_of(value),
- _ => None,
- }
- }
fn lookup(&self, value: &Datum<String>) -> Option<f64> {
self.lookup_range(value)
.map(|range| range.start.midpoint(range.end))
id: String,
#[serde(default, rename = "@date")]
- date: bool,
+ _date: bool,
#[serde(default, rename = "$value")]
children: Vec<CategoricalDomainChild>,
id: String,
#[serde(default, rename = "@date")]
- date: bool,
+ _date: bool,
#[serde(default, rename = "$value")]
children: Vec<IntervalDomainChild>,
enum IntervalDomainChild {
Range(IntervalRange),
VariableReference(VariableReference),
- Format(Format),
+ Format(#[allow(dead_code)] Format),
}
impl IntervalDomainChild {
#[serde(default, rename = "relabel")]
relabels: Vec<Relabel>,
#[serde(default, rename = "affix")]
- affixes: Vec<Affix>,
+ _affixes: Vec<Affix>,
}
impl StringFormat {
#[serde(rename_all = "camelCase")]
struct Format {
#[serde(rename = "@tryStringsAsNumbers")]
- try_strings_as_numbers: Option<bool>,
+ _try_strings_as_numbers: Option<bool>,
#[serde(rename = "@relabelsArePreformatted")]
- relabels_are_preformatted: Option<bool>,
+ _relabels_are_preformatted: Option<bool>,
#[serde(rename = "@separatorChars")]
separator_chars: Option<String>,
#[serde(rename = "@hiddenseparator")]
#[serde(rename = "@mdyOrder")]
mdy_order: Option<MdyOrder>,
#[serde(rename = "@dayOfMonthPadding")]
- day_of_month_padding: Option<bool>,
+ _day_of_month_padding: Option<bool>,
#[serde(rename = "@weekPadding")]
week_padding: Option<bool>,
#[serde(rename = "@dayPadding")]
#[serde(default, rename = "relabel")]
relabels: Vec<Relabel>,
#[serde(default, rename = "affix")]
- affixes: Vec<Affix>,
+ _affixes: Vec<Affix>,
}
impl Format {
}
}
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct NumberFormat {
- #[serde(rename = "@maximumFractionDigits")]
- maximum_fraction_digits: Option<usize>,
- #[serde(rename = "@useGrouping")]
- use_grouping: Option<bool>,
- #[serde(rename = "@scientific")]
- scientific: Option<RawScientific>,
- #[serde(default, rename = "@prefix")]
- prefix: String,
- #[serde(default, rename = "@suffix")]
- suffix: String,
- #[serde(default, rename = "affix")]
- affixes: Vec<Affix>,
-}
-
-struct SignificantNumberFormat<'a> {
- scientific: Option<RawScientific>,
- prefix: &'a str,
- suffix: &'a str,
- use_grouping: Option<bool>,
- maximum_fraction_digits: Option<usize>,
-}
-
-impl<'a> From<&'a NumberFormat> for SignificantNumberFormat<'a> {
- fn from(value: &'a NumberFormat) -> Self {
- Self {
- scientific: value.scientific,
- prefix: &value.prefix,
- suffix: &value.suffix,
- use_grouping: value.use_grouping,
- maximum_fraction_digits: value.maximum_fraction_digits,
- }
- }
-}
-
-impl<'a> From<&'a Format> for SignificantNumberFormat<'a> {
- fn from(value: &'a Format) -> Self {
- Self {
- scientific: value.scientific,
- prefix: &value.prefix,
- suffix: &value.suffix,
- use_grouping: value.use_grouping,
- maximum_fraction_digits: value.maximum_fraction_digits,
- }
- }
-}
-
-impl<'a> SignificantNumberFormat<'a> {
- fn decode(&self) -> crate::format::Format {
- let type_ = if self.scientific == Some(RawScientific::True) {
- Type::E
- } else if self.prefix == "$" {
- Type::Dollar
- } else if self.suffix == "%" {
- Type::Pct
- } else if self.use_grouping == Some(true) {
- Type::Comma
- } else {
- Type::F
- };
- let d = match self.maximum_fraction_digits {
- Some(d) if (0..=15).contains(&d) => d,
- _ => 2,
- };
- UncheckedFormat {
- type_,
- w: 40,
- d: d as u8,
- }
- .fix()
- }
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct DateTimeFormat {
- #[serde(rename = "@baseFormat")]
- base_format: BaseFormat,
- #[serde(rename = "@mdyOrder")]
- mdy_order: Option<MdyOrder>,
- #[serde(rename = "@showQuarter")]
- show_quarter: Option<bool>,
- #[serde(rename = "@yearAbbreviation")]
- year_abbreviation: Option<bool>,
- #[serde(rename = "@monthFormat")]
- month_format: Option<MonthFormat>,
- #[serde(rename = "@showWeek")]
- show_week: Option<bool>,
- #[serde(rename = "@showDay")]
- show_day: Option<bool>,
- #[serde(rename = "@showHour")]
- show_hour: Option<bool>,
- #[serde(rename = "@showSecond")]
- show_second: Option<bool>,
- #[serde(rename = "@showMillis")]
- show_millis: Option<bool>,
- #[serde(default, rename = "affix")]
- affixes: Vec<Affix>,
-}
-
-struct SignificantDateTimeFormat {
- base_format: Option<BaseFormat>,
- show_quarter: Option<bool>,
- show_week: Option<bool>,
- show_day: Option<bool>,
- show_hour: Option<bool>,
- show_second: Option<bool>,
- show_millis: Option<bool>,
- mdy_order: Option<MdyOrder>,
- month_format: Option<MonthFormat>,
- year_abbreviation: Option<bool>,
-}
-
-impl From<&Format> for SignificantDateTimeFormat {
- fn from(value: &Format) -> Self {
- Self {
- base_format: value.base_format,
- show_quarter: value.show_quarter,
- show_week: value.show_week,
- show_day: value.show_day,
- show_hour: value.show_hour,
- show_second: value.show_second,
- show_millis: value.show_millis,
- mdy_order: value.mdy_order,
- month_format: value.month_format,
- year_abbreviation: value.year_abbreviation,
- }
- }
-}
-impl From<&DateTimeFormat> for SignificantDateTimeFormat {
- fn from(value: &DateTimeFormat) -> Self {
- Self {
- base_format: Some(value.base_format),
- show_quarter: value.show_quarter,
- show_week: value.show_week,
- show_day: value.show_day,
- show_hour: value.show_hour,
- show_second: value.show_second,
- show_millis: value.show_millis,
- mdy_order: value.mdy_order,
- month_format: value.month_format,
- year_abbreviation: value.year_abbreviation,
- }
- }
-}
-impl SignificantDateTimeFormat {
- fn decode(&self) -> crate::format::Format {
- let type_ = match self.base_format {
- Some(BaseFormat::Date) => {
- let type_ = if self.show_quarter == Some(true) {
- Type::QYr
- } else if self.show_week == Some(true) {
- Type::WkYr
- } else {
- match (self.mdy_order, self.month_format) {
- (Some(MdyOrder::DayMonthYear), Some(MonthFormat::Number)) => Type::EDate,
- (Some(MdyOrder::DayMonthYear), Some(MonthFormat::PaddedNumber)) => {
- Type::EDate
- }
- (Some(MdyOrder::DayMonthYear), _) => Type::Date,
- (Some(MdyOrder::YearMonthDay), _) => Type::SDate,
- _ => Type::ADate,
- }
- };
- let mut w = type_.min_width();
- if self.year_abbreviation != Some(true) {
- w += 2;
- };
- return UncheckedFormat { type_, w, d: 0 }.try_into().unwrap();
- }
- Some(BaseFormat::DateTime) => {
- if self.mdy_order == Some(MdyOrder::YearMonthDay) {
- Type::YmdHms
- } else {
- Type::DateTime
- }
- }
- _ => {
- if self.show_day == Some(true) {
- Type::DTime
- } else if self.show_hour == Some(true) {
- Type::Time
- } else {
- Type::MTime
- }
- }
- };
- date_time_format(type_, self.show_second, self.show_millis)
- }
-}
-
-fn date_time_format(
- type_: Type,
- show_second: Option<bool>,
- show_millis: Option<bool>,
-) -> crate::format::Format {
- let mut w = type_.min_width();
- let mut d = 0;
- if show_second == Some(true) {
- w += 3;
- if show_millis == Some(true) {
- d = 3;
- w += d as u16 + 1;
- }
- }
- UncheckedFormat { type_, w, d }.try_into().unwrap()
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct ElapsedTimeFormat {
- #[serde(rename = "@showDay")]
- show_day: Option<bool>,
- #[serde(rename = "@showHour")]
- show_hour: Option<bool>,
- #[serde(rename = "@showSecond")]
- show_second: Option<bool>,
- #[serde(rename = "@showMillis")]
- show_millis: Option<bool>,
- #[serde(default, rename = "affix")]
- affixes: Vec<Affix>,
-}
-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
enum BaseFormat {
struct Affix {
/// A reference to a footnote with the given 1-based index.
#[serde(rename = "@definesReference")]
- defines_reference: NonZeroUsize,
+ _defines_reference: NonZeroUsize,
}
#[derive(Deserialize, Debug)]
}
}
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct ValueMapEntry {
- #[serde(rename = "@from")]
- from: String,
- #[serde(rename = "@to")]
- to: String,
-}
-
struct Element<'a> {
raw: &'a RawElement,
style: Cow<'a, Style>,
.collect()
}
- fn x_dimension(&self) -> Option<&Dimension> {
- self.axis_dimension(Axis3::X)
- }
-
- fn y_dimension(&self) -> Option<&Dimension> {
- self.axis_dimension(Axis3::Y)
- }
-
fn axis_dimension(&self, axis: Axis3) -> Option<&Dimension> {
self.coordinates.dimensions[axis].as_ref()
}
#[derive(Debug)]
struct RawElement {
id: Option<String>,
- break_representation: Option<BreakRepresentation>,
- closed: bool,
- preserve_straight_lines: bool,
- center_in_3d: bool,
- median_style: Option<String>,
- fence_style: Option<String>,
- hinge_style: Option<String>,
- outlier_style: Option<String>,
- extreme_style: Option<String>,
+ _break_representation: Option<BreakRepresentation>,
+ _closed: bool,
+ _preserve_straight_lines: bool,
+ _center_in_3d: bool,
+ _median_style: Option<String>,
+ _fence_style: Option<String>,
+ _hinge_style: Option<String>,
+ _outlier_style: Option<String>,
+ _extreme_style: Option<String>,
style: Option<String>,
statistics: Vec<Statistic>,
#[serde(rename = "@style")]
style: Option<String>,
+ #[serde(rename = "@clip")]
+ clip: Option<Clip>,
+
#[serde(rename = "$value")]
statistics: Vec<Statistic>,
}
Ok(Self {
id: raw.id,
- break_representation: raw.break_representation,
- closed: raw.closed,
- preserve_straight_lines: raw.preserve_straight_lines,
- center_in_3d: raw.center_in_3d,
- median_style: raw.median_style,
- fence_style: raw.fence_style,
- hinge_style: raw.hinge_style,
- outlier_style: raw.outlier_style,
- extreme_style: raw.extreme_style,
+ _break_representation: raw.break_representation,
+ _closed: raw.closed,
+ _preserve_straight_lines: raw.preserve_straight_lines,
+ _center_in_3d: raw.center_in_3d,
+ _median_style: raw.median_style,
+ _fence_style: raw.fence_style,
+ _hinge_style: raw.hinge_style,
+ _outlier_style: raw.outlier_style,
+ _extreme_style: raw.extreme_style,
style: raw.style,
statistics: raw.statistics,
positions,
#[serde(rename_all = "camelCase")]
struct ColorAesthetic {
#[serde(rename = "@id")]
- id: Option<String>,
+ _id: Option<String>,
#[serde(rename = "@domainModifier")]
- domain_modifier: Option<String>,
+ _domain_modifier: Option<String>,
#[serde(rename = "@variable")]
variable: Option<String>,
#[serde(rename = "@dimension")]
- dimension: Option<usize>,
+ _dimension: Option<usize>,
#[serde(rename = "@domain")]
- domain: Option<String>,
+ _domain: Option<String>,
#[serde(rename = "@clamp")]
- clamp: Option<bool>,
+ _clamp: Option<bool>,
#[serde(default, rename = "@split")]
- split: bool,
+ _split: bool,
//summary_statistic: Option<SummaryStatistic>,
- #[serde(default)]
- color_mapping: Vec<ColorMapping>,
+ #[serde(default, rename = "colorMapping")]
+ _color_mapping: Vec<ColorMapping>,
#[serde(rename = "@scale")]
- scale: Option<ColorScale>,
+ _scale: Option<ColorScale>,
#[serde(rename = "@affect")]
affect: Option<ColorAffect>,
#[serde(rename = "@cycle")]
- cycle: Option<String>,
+ _cycle: Option<String>,
#[serde(rename = "@missing")]
- missing: Option<String>,
+ _missing: Option<String>,
#[serde(rename = "@low")]
- low: Option<String>,
+ _low: Option<String>,
#[serde(rename = "@high")]
- high: Option<String>,
+ _high: Option<String>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct ColorMapping {
#[serde(rename = "@from")]
- from: String,
+ _from: String,
#[serde(rename = "@to")]
- to: String,
+ _to: String,
}
#[derive(Copy, Clone, Deserialize, Debug, PartialEq, Eq)]
},
SizeToContent {
axis: Axis2,
- min: Option<LocationLength>,
+ _min: Option<LocationLength>,
max: Option<LocationLength>,
},
}
if self.component() == Component::Length {
Some(Location2::SizeToContent {
axis: self.axis(),
- min: self.min,
+ _min: self.min,
max: self.max,
})
} else {
}
}
+ #[allow(dead_code)]
fn opposite(&self) -> Option<Self> {
match self {
Part::Left => Some(Part::Right),
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Faceting {
+ /// How to derive the domain for the facet cells.
+ #[serde(default, rename = "@method")]
+ _method: FacetingMethod,
+
+ #[serde(default, rename = "@augmentEmptyCells")]
+ _augment_empty_cells: bool,
+
#[serde(default, rename = "$value")]
children: Vec<FacetingChild>,
}
+/// How to derive the domain for facet axes.
+#[derive(Copy, Clone, Deserialize, Debug, Default, PartialEq, Eq)]
+#[serde(rename_all = "camelCase")]
+enum FacetingMethod {
+ /// Produce a single domain for all of the facet cells by considering all of
+ /// their data together.
+ #[default]
+ Cross,
+
+ /// Each facet cell has its own independent domain based only on its own
+ /// data.
+ ///
+ /// Each facet cell will have its own axis (see [Axis]).
+ Nest,
+
+ /// Effect not known yet.
+ Dot,
+}
+
#[derive(Clone, Debug)]
struct Facet<'a> {
series: &'a Series,
#[serde(rename_all = "camelCase")]
struct Layer {
#[serde(rename = "@variable")]
- variable: String,
+ _variable: String,
#[serde(rename = "@value")]
- value: String,
+ _value: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct FacetLayout {
#[serde(default, rename = "@topDown")]
- top_down: bool,
+ _top_down: bool,
#[serde(default, rename = "$value")]
children: Vec<FacetLayoutChild>,
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
enum FacetLayoutChild {
- SetCellProperties(SetCellProperties),
+ SetCellProperties(#[allow(dead_code)] SetCellProperties),
FacetLevel(FacetLevel),
#[serde(other)]
Other,
#[serde(rename_all = "camelCase")]
struct SetCellProperties {
#[serde(rename = "@applyToConverse", default)]
- apply_to_converse: bool,
+ _apply_to_converse: bool,
#[serde(rename = "$value")]
- sets: Vec<Set>,
+ _sets: Vec<Set>,
#[serde(rename = "union")]
- union_: Option<Union>,
+ _union: Option<Union>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Union {
#[serde(default, rename = "intersect")]
- intersects: Vec<Intersect>,
+ _intersects: Vec<Intersect>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Intersect {
#[serde(default, rename = "$value")]
- children: Vec<IntersectChild>,
+ _children: Vec<IntersectChild>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
enum IntersectChild {
- Where(Where),
+ Where(#[allow(dead_code)] Where),
#[serde(other)]
Other,
}
#[serde(rename_all = "camelCase")]
struct Where {
#[serde(rename = "@variable")]
- variable: String,
+ _variable: String,
#[serde(rename = "@include")]
- include: String,
+ _include: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
enum Set {
- SetStyle(SetStyle),
- SetFrameStyle(SetFrameStyle),
+ SetStyle(#[allow(dead_code)] SetStyle),
+ SetFrameStyle(#[allow(dead_code)] SetFrameStyle),
#[serde(other)]
Other,
}
#[serde(rename_all = "camelCase")]
struct SetStyle {
#[serde(rename = "@target")]
- target: String,
+ _target: String,
/// The `id` for a [Style].
#[serde(rename = "@style")]
- style: String,
+ _style: String,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct SetFrameStyle {
#[serde(rename = "@target")]
- target: String,
+ _target: String,
/// The `id` for a [Style].
#[serde(rename = "@style")]
- style: String,
+ _style: String,
}
#[derive(Debug)]
#[serde(rename_all = "camelCase")]
struct Dimension {
#[serde(default, rename = "@unionDomain")]
- union_domain: bool,
+ _union_domain: bool,
/// A reference to an [IntervalDomain] or [CategoricalDomain].
#[serde(default, rename = "@domain")]
- domain: Option<String>,
+ _domain: Option<String>,
#[serde(rename = "@upperMargin")]
upper_margin: Option<LocationLength>,
lower_margin: Option<LocationLength>,
#[serde(default, rename = "@niceUpperMapping")]
- nice_upper_mapping: bool,
+ _nice_upper_mapping: bool,
#[serde(default, rename = "@niceLowerMapping")]
- nice_lower_mapping: bool,
+ _nice_lower_mapping: bool,
#[serde(default, rename = "@facetsShareScale")]
- facets_share_scale: bool,
+ _facets_share_scale: bool,
- scale: Option<Scale>,
+ #[serde(rename = "scale")]
+ _scale: Option<Scale>,
/// Maximum 2 axes.
///
#[serde(rename_all = "camelCase")]
struct Scale {
#[serde(rename = "@method")]
- method: Method,
+ _method: Method,
}
#[derive(Copy, Clone, Deserialize, Debug, PartialEq, Eq)]
enum Statistic {
BinStatistic(BinStatistic),
SummaryStatistic(SummaryStatistic),
- DistributionStatistic(DistributionStatistic),
+ DistributionStatistic(#[allow(dead_code)] DistributionStatistic),
TukeyStatistic,
#[serde(other)]
Other,
#[serde(rename_all = "camelCase")]
struct Coordinate {
#[serde(rename = "@id")]
- id: Option<String>,
+ _id: Option<String>,
#[serde(rename = "@variable")]
variable: String,
}
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct Labeling {
- #[serde(default, rename = "@connectingLines")]
- connecting_lines: bool,
-
- /// The `id` for a [Style].
- #[serde(rename = "@style")]
- style: Option<String>,
-
- /// The `id` for a [Style].
- #[serde(rename = "@textFrameStyle")]
- text_frame_style: Option<String>,
-
- #[serde(rename = "$value", default)]
- children: Vec<LabelingChild>,
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-enum LabelingChild {
- Formatting(Formatting),
- Footnotes(Footnotes),
- #[serde(other)]
- Other,
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct Formatting {
- #[serde(rename = "@variable")]
- variable: String,
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct Footnotes {
- #[serde(rename = "@variable")]
- variable: String,
-
- #[serde(default, rename = "@superscript")]
- superscript: bool,
-
- #[serde(default, rename = "footnoteMapping")]
- mappings: Vec<FootnoteMapping>,
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-struct FootnoteMapping {
- #[serde(rename = "@definesReference")]
- defines_reference: Option<NonZeroUsize>,
-
- #[serde(rename = "@from")]
- from: NonZeroUsize,
-
- #[serde(rename = "@to")]
- to: String,
-}
-
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct FacetLevel {
axis: Axis,
}
+/// Controls the display of the axis for a dimension.
+///
+/// An axis consists of:
+///
+/// - Tick marks, if `major_ticks` and optionally `minor_ticks` are set.
+///
+/// - A label, if `label` is set.
+///
+/// # Faceted axes
+///
+/// In a faceted graph, the axis is shown either once or in every cell,
+/// according to the rules below, in order of decreasing priority:
+///
+/// - If the dimension has a polar transform, then the axis is drawn in every
+/// cell (because there's no reasonable way to draw it just once).
+///
+/// - With [AxisRepeat::Never], then the axis is drawn just once. (This can
+/// produce deceptive results with [FacetingMethod::Nest], since in that case
+/// different facet cells might have different axes.)
+///
+/// - With [FacetingMethod::Nest] then the axis is drawn in every cell because
+/// each cell has a different axis.
+///
+/// - With [AxisRepeat::Always], the axis is drawn in every cell.
+///
+/// - Otherwise, the axis is drawn just once.
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Axis {
#[serde(rename = "@opposite", default)]
opposite: bool,
- /// If false, `label` appears once per facet along the axis.
+ /// When faceting is present, this influences whether the axis appears a
+ /// single time or separately for each facet cell.
+ ///
+ /// This is ignored if the axis has a polar transformation.
+ #[serde(rename = "@repeat")]
+ _repeat: Option<AxisRepeat>,
+
+ /// When axes are repeated in each facet cell (as influenced by `repeat`),
+ /// this determines whether `label` appears once or in each facet cell:
///
- /// If true, `label` appears once along the axis.
+ /// - If false, `label` appears once per facet cell.
+ ///
+ /// - If true, `label` appears just once.
+ ///
+ /// When axes appear just once, the axis label also appears only once
+ /// regardless of this setting.
#[serde(rename = "@combineAxisLabels", default)]
combine_axis_labels: bool,
- label: Option<Label>,
+ /// If set, enables showing tick marks and labels along the axis. If
+ /// `None`, the axis consists only of `label` (if any).
major_ticks: Option<MajorTicks>,
+
+ /// Label for the axis.
+ label: Option<Label>,
+}
+
+/// Whether an axis should appear a single time or separately for each facet
+/// cell.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize, Enum)]
+#[serde(rename_all = "camelCase")]
+enum AxisRepeat {
+ /// Repeat the axis in every facet cell.
+ Always,
+
+ /// Draw the axis only in one place.
+ ///
+ /// This can produce deceptive results if `faceting` specifies
+ /// `method="nest"`, since in that case different facet cells might have
+ /// different axes.
+ Never,
}
#[derive(Deserialize, Debug)]
struct MajorTicks {
/// The `id` for a [Style].
#[serde(rename = "@style")]
- style: String,
+ _style: String,
}
#[derive(Deserialize, Debug)]
/// The `id` for a [Style].
#[serde(rename = "@textFrameStyle")]
- text_frame_style: Option<String>,
+ _text_frame_style: Option<String>,
#[serde(rename = "@purpose")]
- purpose: Option<Purpose>,
+ _purpose: Option<Purpose>,
#[serde(rename = "$value")]
child: LabelChild,
/// If this is present, then `text` defines the content or the marker for a
/// footnote.
#[serde(rename = "@usesReference")]
- uses_reference: Option<NonZeroUsize>,
+ _uses_reference: Option<NonZeroUsize>,
/// If this is present, then
#[serde(rename = "@definesReference")]
- defines_reference: Option<NonZeroUsize>,
+ _defines_reference: Option<NonZeroUsize>,
#[serde(default, rename = "$text")]
text: String,
}
-enum DecodedText<'a> {
- /// Defines footnote `index` content or marker as `text`.
- FootnoteDefinition { index: usize, text: &'a str },
-
- /// Adds a reference to footnote `index`.
- FootnoteReference { index: usize },
-
- /// Text content.
- Text { text: &'a str },
-}
-
-impl Text {
- fn decode(&self) -> DecodedText<'_> {
- if let Some(uses_reference) = self.uses_reference {
- DecodedText::FootnoteDefinition {
- index: uses_reference.get() - 1,
- text: &self.text,
- }
- } else if let Some(defines_reference) = self.defines_reference {
- DecodedText::FootnoteReference {
- index: defines_reference.get() - 1,
- }
- } else {
- DecodedText::Text { text: &self.text }
- }
- }
-}
-
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct LabelFrame {
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();
}
}
+ #[allow(dead_code)]
fn as_percent(&self) -> Option<f64> {
match *self {
LocationLength::Absolute(_) => None,
.map(|position| position.missing_values())
.sum()
}
+ #[allow(dead_code)]
fn demerits(&self, frames: &Frames) -> f64 {
let error_demerits = self.position.values().map(|p| p.demerits()).sum::<f64>();
let preferred = frames.preferred_size(self, false);
.sum()
}
+ #[allow(dead_code)]
fn as_svg(&self) -> Rectangle {
Rectangle::new()
.set("x", self.0[Axis2::X].0)
(0..self.n_ticks).map(|i| self.base + self.interval * (i as f64))
}
+ #[allow(dead_code)]
pub fn first(&self) -> Option<f64> {
self.ticks().next()
}
+ #[allow(dead_code)]
pub fn last(&self) -> Option<f64> {
self.ticks().next_back()
}
// and so on.
let basic_interval = f64::powi(10.0, r.log10().floor() as i32 - 1);
- struct Candidate {
- /// The scaling candidate.
- scaling: Scaling,
- /// Lower scores are better.
- score: f64,
- }
-
// Find the most pleasing interval.
[1.0, 2.0, 5.0, 10.0]
.into_iter()
/// Returns the number of bins suggested by an approximation to Doane's rule,
/// for `n` observations.
+#[allow(dead_code)]
fn doane_rule(n: f64) -> Option<usize> {
NumCast::from((3.0 + n.log10() * n.log2()).ceil())
}
/// Returns the number of bins suggested by the Freedman-Diaconis rule for `n`
/// observations with an interquartile range of `iqr`.
+#[allow(dead_code)]
fn diaconis_rule(iqr: f64, n: f64) -> Option<usize> {
NumCast::from((2.0 * iqr / n.cbrt()).ceil())
}
/// Number of facets.
n_facets: usize,
-
- /// [AxisDomain] for X or Y axis.
- ///
- /// Currently there's always exactly one of these for an axis, although
- /// perhaps there should be up to 2.
- axis_domain: &'a AxisDomain<'a>,
-
- rotate_ticks: bool,
}
struct FacetAxisHeight<'a> {
Self {
width,
axes,
- axis_domain,
ticks,
facets,
n_facets,
- rotate_ticks,
}
}