From 44ddb579dad100c348119c4729e3c337182b633d Mon Sep 17 00:00:00 2001 From: MarekSpodBiedry <73122968+MarekSpodBiedry@users.noreply.github.com> Date: Sun, 11 Oct 2026 13:51:58 +0200 Subject: [PATCH] Charts: a single-series chart without an explicit title shows the series name as its automatic title (#142) --- crates/pptx/src/read/chart.rs | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/crates/pptx/src/read/chart.rs b/crates/pptx/src/read/chart.rs index a9a960a3..b93378bb 100644 --- a/crates/pptx/src/read/chart.rs +++ b/crates/pptx/src/read/chart.rs @@ -202,6 +202,10 @@ pub(crate) fn chart_from(root: &El) -> Option { c.series.push(ser); } } + // `autoTitleDeleted val="0"` without `c:title`: PowerPoint and LibreOffice draw the series name as the title of a single-series chart. + if ch.child("title").is_none() && ch.child("autoTitleDeleted").and_then(|a| a.bool("val")) == Some(false) && c.series.len() == 1 { + c.title = c.series.first().map(|s| s.name.clone()).filter(|n| !n.is_empty()); + } let first = *kinds.first()?; c.kind = if kinds.iter().any(|k| *k != first) { ChartType::Combo } else { first }; if c.kind != ChartType::Combo { @@ -225,3 +229,37 @@ pub(crate) fn chart_from(root: &El) -> Option { } Some(c) } + +#[cfg(test)] +mod tests { + use super::*; + + const NS_C: &str = "http://schemas.openxmlformats.org/drawingml/2006/chart"; + const NS_A: &str = "http://schemas.openxmlformats.org/drawingml/2006/main"; + + fn chart(auto_deleted: &str, title: &str, series: usize) -> Chart { + let val = r#"1"#; + let ser: String = (0..series).map(|i| format!(r#"S{i}{val}"#)).collect(); + let plot = format!(r#"{ser}"#); + let xml = format!(r#"{title}{auto_deleted}{plot}"#); + read_chart_xml(xml.as_bytes()).unwrap() + } + + #[test] + fn single_series_gets_automatic_title() { + assert_eq!(chart(r#""#, "", 1).title.as_deref(), Some("S0")); + } + + #[test] + fn no_automatic_title_when_deleted_or_multi_series() { + assert_eq!(chart(r#""#, "", 1).title, None); + assert_eq!(chart("", "", 1).title, None); + assert_eq!(chart(r#""#, "", 2).title, None); + } + + #[test] + fn explicit_title_wins() { + let t = "Mine"; + assert_eq!(chart(r#""#, t, 1).title.as_deref(), Some("Mine")); + } +}