Charts: Switch Row/Column on charts read from a file
chart.switchRowColumn did nothing on a chart read from a file: only charts made by insert.chart keep their source range. Without one, the command now takes the block the series' names, categories and values span (when they're all on one sheet), and keeps it.
This commit is contained in:
parent
13664fe66b
commit
fddd08bec3
|
|
@ -654,14 +654,16 @@ fn chart_switch(s: &mut Session, p: &Json) -> Result<Json> {
|
|||
edit(s, |cx| {
|
||||
let Some(sh) = cx.wb.sheet(si) else { return Ok(Json::Null) };
|
||||
let Some(c) = sh.charts.get(ci) else { return Ok(Json::Null) };
|
||||
let Some(src) = c.source.clone() else { return Ok(Json::Null) };
|
||||
// Charts read from a file have no source range: take the block their series span.
|
||||
let Some((src, by_rows)) = c.source.clone().map(|s| (s, c.by_rows)).or_else(|| series_block(&c.series)) else { return Ok(Json::Null) };
|
||||
let (sheet_name, body) = split_sheet(&src);
|
||||
let src_sheet = sheet_name.and_then(|n| cx.wb.sheet_index(&n)).unwrap_or(si);
|
||||
let Some(r) = RangeRef::parse(body) else { return Ok(Json::Null) };
|
||||
let Some(ssh) = cx.wb.sheet(src_sheet) else { return Ok(Json::Null) };
|
||||
let by_rows = !c.by_rows;
|
||||
let by_rows = !by_rows;
|
||||
let series = series_from_range(ssh, r, by_rows);
|
||||
if let Some(c) = cx.sheet_mut(si)?.charts.get_mut(ci) {
|
||||
c.source.get_or_insert(src);
|
||||
c.by_rows = by_rows;
|
||||
c.series = series;
|
||||
}
|
||||
|
|
@ -669,6 +671,29 @@ fn chart_switch(s: &mut Session, p: &Json) -> Result<Json> {
|
|||
})
|
||||
}
|
||||
|
||||
/// The block a chart's series come from, and whether each series is a row of it: the bounding
|
||||
/// range of the series names, categories and values, when they're all references to one sheet.
|
||||
fn series_block(series: &[Series]) -> Option<(String, bool)> {
|
||||
let mut sheet: Option<String> = None;
|
||||
let mut bounds: Option<RangeRef> = None;
|
||||
let mut rows = 0;
|
||||
for s in series {
|
||||
for (i, f) in [Some(&s.values), s.categories.as_ref(), s.name.as_ref()].into_iter().flatten().enumerate() {
|
||||
let Ok(gridcraft_formula::Expr::Ref(r)) = gridcraft_formula::parse(f) else { return None };
|
||||
let gridcraft_formula::SheetSel::Named(n) = &r.sheet else { return None };
|
||||
if !sheet.get_or_insert_with(|| n.clone()).eq_ignore_ascii_case(n) {
|
||||
return None;
|
||||
}
|
||||
let range = r.range();
|
||||
if i == 0 && range.height() == 1 && range.width() > 1 {
|
||||
rows += 1;
|
||||
}
|
||||
bounds = Some(bounds.map_or(range, |b| b.union(&range)));
|
||||
}
|
||||
}
|
||||
Some((format!("{}!{}", gridcraft_formula::quote_sheet(&sheet?), bounds?.a1()), rows > 0 && rows == series.len()))
|
||||
}
|
||||
|
||||
fn chart_delete(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
let (si, ci) = find_chart(s, p)?;
|
||||
edit(s, |cx| {
|
||||
|
|
|
|||
|
|
@ -174,6 +174,32 @@ fn parity_counts() {
|
|||
assert!(done > 150, "parity {done}/{total}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn switch_row_column_on_a_chart_read_from_a_file() {
|
||||
let mut s = s();
|
||||
s.execute(
|
||||
"range.setValues",
|
||||
json!({"range": "A1", "values": [["", "North", "South", "East", "West"], ["Mon", 10, 14, 9, 12], ["Tue", 12, 15, 11, 14], ["Wed", 14, 16, 10, 11], ["Thu", 11, 13, 8, 9], ["Fri", 9, 12, 7, 11], ["Sat", 11, 15, 10, 14]]}),
|
||||
)
|
||||
.unwrap();
|
||||
s.execute("insert.chart", json!({"type": "column", "range": "A1:E7"})).unwrap();
|
||||
let r = s.execute("file.saveBytes", json!({"format": "xlsx"})).unwrap();
|
||||
let b64 = r["base64"].as_str().unwrap().to_string();
|
||||
s.execute("file.open", json!({"name": "x.xlsx", "base64": b64})).unwrap();
|
||||
let chart = |s: &Session| s.doc().unwrap().wb.active().unwrap().charts[0].clone();
|
||||
assert_eq!((chart(&s).source, chart(&s).series.len()), (None, 4));
|
||||
s.execute("chart.switchRowColumn", json!({})).unwrap();
|
||||
let c = chart(&s);
|
||||
assert!(c.by_rows);
|
||||
assert_eq!(c.source.as_deref(), Some("Sheet1!A1:E7"));
|
||||
assert_eq!(c.series.len(), 6);
|
||||
assert_eq!(c.series[0].name.as_deref(), Some("Sheet1!$A$2"));
|
||||
assert_eq!(c.series[0].categories.as_deref(), Some("Sheet1!$B$1:$E$1"));
|
||||
assert_eq!(c.series[0].values, "Sheet1!$B$2:$E$2");
|
||||
s.execute("chart.switchRowColumn", json!({})).unwrap();
|
||||
assert_eq!(chart(&s).series.len(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ink_strokes_and_ink_to_shape() {
|
||||
let mut s = s();
|
||||
|
|
|
|||
Loading…
Reference in New Issue