From: Ben Pfaff Date: Mon, 12 Jan 2026 02:57:43 +0000 (-0800) Subject: work on graphs X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a9ea4267f7c6d6c23342cbd112250d7d3eafe025;p=pspp work on graphs --- diff --git a/rust/pspp/src/spv/read.rs b/rust/pspp/src/spv/read.rs index 6a8c2c58dd..cd8fca8d97 100644 --- a/rust/pspp/src/spv/read.rs +++ b/rust/pspp/src/spv/read.rs @@ -31,6 +31,7 @@ use crate::{ spv::{ legacy_bin::LegacyBinWarning, read::{ + graph::GraphWarning, legacy_xml::LegacyXmlWarning, light::LightWarning, structure::{OutlineItem, StructureMember}, @@ -39,6 +40,8 @@ use crate::{ }; mod css; +#[allow(missing_docs)] +pub mod graph; pub mod html; pub mod legacy_bin; #[allow(missing_docs)] @@ -79,6 +82,9 @@ pub enum WarningDetails { /// {0} LegacyXmlWarning(LegacyXmlWarning), + /// {0} + GraphWarning(GraphWarning), + /// Unknown page orientation {0:?}. UnknownOrientation(String), } @@ -255,9 +261,6 @@ pub enum Error { /// Legacy table missing `graph` element. LegacyMissingGraph, - /// Graphs not yet implemented. - GraphTodo, - /// Models not yet implemented. ModelTodo, diff --git a/rust/pspp/src/spv/read/graph.rs b/rust/pspp/src/spv/read/graph.rs new file mode 100644 index 0000000000..5b26160064 --- /dev/null +++ b/rust/pspp/src/spv/read/graph.rs @@ -0,0 +1,1292 @@ +// PSPP - a program for statistical analysis. +// Copyright (C) 2025 Free Software Foundation, Inc. +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +#![allow(dead_code)] +use std::{ + cell::{Cell, RefCell}, + collections::{BTreeMap, HashMap}, + fmt::Debug, + marker::PhantomData, + num::NonZeroUsize, +}; + +use displaydoc::Display; +use enum_map::Enum; +use indexmap::IndexMap; +use ordered_float::OrderedFloat; +use serde::Deserialize; + +use crate::{ + data::Datum, + format::{F8_0, Type, UncheckedFormat}, + output::pivot::{ + CategoryLocator, Length, PivotTable, + look::{Color, VertAlign}, + }, +}; + +#[derive(Debug)] +struct Ref { + references: String, + _phantom: PhantomData, +} + +impl Ref { + fn get<'a>(&self, table: &HashMap<&str, &'a T>) -> Option<&'a T> { + table.get(self.references.as_str()).map(|v| &**v) + } +} + +impl<'de, T> Deserialize<'de> for Ref { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Ok(Self { + references: String::deserialize(deserializer)?, + _phantom: PhantomData, + }) + } +} + +#[derive(Clone, Debug, Default)] +struct Map(HashMap, Datum>); + +impl Map { + fn apply(&self, data: &mut Vec>) { + for value in data { + if let Datum::Number(Some(number)) = value + && let Some(to) = self.0.get(&OrderedFloat(*number)) + { + *value = to.clone(); + } + } + } +} + +/// A warning decoding a legacy XML member. +#[derive(Clone, Debug, Display, thiserror::Error)] +pub enum GraphWarning { + /// Table has no data. + MissingData, + + /// Table has variables with unresolved dependencies: {0:?}. + UnresolvedDependencies(Vec), + + /// Derived variable {variable:?} has unsupported value expression {value:?}. + UnsupportedValue { + /// Name of derived variable. + variable: String, + /// Value expression. + value: String, + }, + + /// Unsupported applyToConverse. + UnsupportedApplyToConverse, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct Visualization { + // Locale used for output, e.g. `en-US`. + #[serde(rename = "@lang")] + _lang: String, + + /// Base style for the graph. + #[serde(rename = "@style")] + _style: Ref