From: Ben Pfaff Date: Tue, 28 Jul 2026 00:09:26 +0000 (-0700) Subject: label alignment X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f77a3e6e030f858a768445a3c5a694e7d89e31c;p=pspp label alignment --- diff --git a/rust/pspp/src/spv/read/graph.rs b/rust/pspp/src/spv/read/graph.rs index bf033c0e19..5984568fab 100644 --- a/rust/pspp/src/spv/read/graph.rs +++ b/rust/pspp/src/spv/read/graph.rs @@ -22,7 +22,6 @@ use std::{ fmt::Debug, io::{Cursor, ErrorKind}, iter::{repeat, zip}, - marker::PhantomData, mem::take, num::NonZeroUsize, ops::{Not, Range}, @@ -55,7 +54,10 @@ use crate::{ output::{ SpvGraphMembers, SpvInfo, SpvMembers, drivers::cairo::{pt_to_xr, xr_to_pt}, - pivot::{Axis2, Axis3, Length, ParseLengthError, look::Color}, + pivot::{ + Axis2, Axis3, Length, ParseLengthError, + look::{Color, HorzAlign}, + }, }, spv::{ legacy_bin::{DataSeries, DataSource, DataSources, LegacyBin, LegacyBinWarning}, @@ -74,30 +76,6 @@ mod patterns; mod style; mod symbols; -#[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, String>); @@ -158,9 +136,9 @@ pub struct Visualization { #[serde(rename = "@lang")] lang: Option, - /// Base style for the graph. + /// The `id` for the base [Style] for the graph. #[serde(rename = "@style")] - _style: Option>, + _style: Option, /// Title or caption. #[serde(rename = "@description")] @@ -587,18 +565,31 @@ impl Visualization { for frame in &frames.frames { if let Some(label_frame) = frame.frame_type.as_label_frame() && let Some(left) = frame.position[Axis2::X].start() - && let Some(_width) = frame.position[Axis2::X].length() + && let Some(right) = frame.position[Axis2::X].end() && let Some(top) = frame.position[Axis2::Y].start() && let Some(_height) = frame.position[Axis2::Y].length() - && let Some(text) = label_frame.text() + && let Some(label) = &label_frame.label { + let text = label.text().unwrap_or_default(); let _metrics = font_metrics.measure(&text); + let text_alignment = label + .style + .as_deref() + .and_then(|style| styles.get(style)) + .and_then(|style| style.label_horz_align()) + .unwrap_or(HorzAlign::Center); + let (x, text_anchor) = match text_alignment { + HorzAlign::Left | HorzAlign::Decimal { .. } => (left, "start"), + HorzAlign::Right => (right, "end"), + HorzAlign::Center => (left.midpoint(right), "middle"), + }; document.append( svg::node::element::Text::new(text) .with_id(&label_frame.id) - .set("x", left) + .set("x", x) .set("y", top) .set("dominant-baseline", "hanging") + .set("text-anchor", text_anchor) .set("font-family", "sans-serif"), ); /* document.append( @@ -1471,10 +1462,11 @@ struct SourceVariable { #[serde(default)] // XXX not sure this is the correct default categorical: bool, - /// A variable whose string values correspond one-to-one with the values of - /// this variable and are suitable as value labels. + /// The `id` for a [SourceVariable] whose string values correspond + /// one-to-one with the values of this variable and are suitable as value + /// labels. #[serde(rename = "@labelVariable")] - label_variable: Option>, + label_variable: Option, format: Option, string_format: Option, @@ -1500,7 +1492,7 @@ impl Variable for SourceVariable { _warn: &mut dyn FnMut(GraphWarning), ) -> bool { let label_series = if let Some(label_variable) = &self.label_variable { - if let Some(label_series) = series.get(label_variable.references.as_str()) { + if let Some(label_series) = series.get(label_variable.as_str()) { Some(label_series) } else { return false; @@ -3634,8 +3626,9 @@ struct SetStyle { #[serde(rename = "@target")] target: String, + /// The `id` for a [Style]. #[serde(rename = "@style")] - style: Ref