Format Chart Area: Chart Type offers the stacked and 100% stacked types and marks the current one

The Chart Type section of the Format Chart Area pane listed nine types,
with stacked column as the only stacked one, so a chart could not be
switched there to stacked bar, 100% stacked column or bar, stacked
line, or stacked or 100% stacked area. It now lists them after their
family's entries, and "Stacked" is renamed "Stacked Column".

Each entry is drawn selected when it is the chart's current type, as
the Legend entries are, using the same type and subtype mapping that
chart.set applies.
This commit is contained in:
dotCooCoo
2026-10-25 16:53:40 -07:00
parent 0870b1ad1c
commit 0b6d243946
3 changed files with 101 additions and 2 deletions
+9 -2
View File
@@ -185,16 +185,23 @@ fn format_chart(app: &mut SheetApp, ui: &mut Ui) {
ui.horizontal_wrapped(|ui| {
for (l, k, s) in [
("Column", "column", ""),
("Stacked", "column", "stacked"),
("Stacked Column", "column", "stacked"),
("100% Stacked Column", "column", "stacked100"),
("Bar", "bar", ""),
("Stacked Bar", "bar", "stacked"),
("100% Stacked Bar", "bar", "stacked100"),
("Line", "line", "markers"),
("Stacked Line", "line", "stacked"),
("Area", "area", ""),
("Stacked Area", "area", "stacked"),
("100% Stacked Area", "area", "stacked100"),
("Pie", "pie", ""),
("Doughnut", "doughnut", ""),
("Scatter", "scatter", ""),
("Radar", "radar", ""),
] {
if ui.button(l).clicked() {
let cur = chart.kind == gridcraft_engine::cmd::insert::chart_kind(k, s);
if ui.selectable_label(cur, l).clicked() {
app.run_or_alert("chart.set", json!({"chart": id, "type": k, "subtype": s}));
}
}
@@ -0,0 +1,91 @@
//! The Format Chart Area pane's Chart Type section changes the chart's type and marks the current one.
use egui::accesskit::{Role, Toggled};
use egui_kittest::kittest::{NodeT, Queryable};
use gridcraft_engine::Session;
use gridcraft_engine::model::ChartKind;
use gridcraft_ui_egui::SheetApp;
use serde_json::json;
type Harness = egui_kittest::Harness<'static, SheetApp>;
/// A two-series chart made with `insert.chart`'s `type` `t` and `subtype` `sub`, with Format Chart Area open on its Chart Type section.
fn open_chart_type(t: &str, sub: &str) -> (Harness, u32) {
let mut session = Session::new();
session.new_workbook();
session.execute("range.setValues", json!({"range": "A1", "values": [["Quarter", "North", "South"], ["Q1", 10, 30], ["Q2", 30, 10]]})).unwrap();
session.execute("selection.set", json!({"range": "A1:C3"})).unwrap();
let chart = session.execute("insert.chart", json!({"type": t, "subtype": sub, "at": "E3"})).unwrap();
let id = chart["chart"].as_u64().unwrap() as u32;
let mut h = crate::support::harness(session, 4);
h.state_mut().selected_chart = Some(id);
h.state_mut().grid.pane = Some("formatChart".into());
h.run_steps(2);
h.get_by_role_and_label(Role::DisclosureTriangle, "Chart Type").click();
h.run_steps(2);
(h, id)
}
fn kind(h: &Harness, id: u32) -> ChartKind {
h.state().session.active().unwrap().wb.active().unwrap().charts.iter().find(|c| c.id == id).unwrap().kind
}
/// Whether the pane's `label` button is drawn as the chart's current type. The pane sits on the
/// right, past the Chart Type header's left edge; the ribbon's buttons are elsewhere.
fn marked(h: &Harness, label: &str) -> bool {
let left = h.get_by_role_and_label(Role::DisclosureTriangle, "Chart Type").rect().left();
let button = h.get_all_by_role_and_label(Role::Button, label).find(|n| n.rect().left() >= left - 1.0).unwrap();
button.accesskit_node().toggled() == Some(Toggled::True)
}
fn click(h: &mut Harness, label: &str) {
let left = h.get_by_role_and_label(Role::DisclosureTriangle, "Chart Type").rect().left();
h.get_all_by_role_and_label(Role::Button, label).find(|n| n.rect().left() >= left - 1.0).unwrap().click();
h.run_steps(2);
}
#[test]
fn chart_type_offers_the_stacked_and_hundred_percent_stacked_types() {
let (mut h, id) = open_chart_type("column", "");
for (label, want) in [
("Stacked Column", ChartKind::ColumnStacked),
("100% Stacked Column", ChartKind::ColumnStacked100),
("Stacked Bar", ChartKind::BarStacked),
("100% Stacked Bar", ChartKind::BarStacked100),
("Stacked Line", ChartKind::LineStacked),
("Stacked Area", ChartKind::AreaStacked),
("100% Stacked Area", ChartKind::AreaStacked100),
("Column", ChartKind::ColumnClustered),
] {
click(&mut h, label);
assert_eq!(kind(&h, id), want, "{label} changes the chart's type");
}
}
#[test]
fn chart_type_marks_the_chart_s_current_type() {
for (t, sub, label) in
[("bar", "stacked100", "100% Stacked Bar"), ("area", "stacked", "Stacked Area"), ("column", "", "Column"), ("line", "markers", "Line")]
{
let (h, _) = open_chart_type(t, sub);
for other in [
"Column",
"Stacked Column",
"100% Stacked Column",
"Bar",
"Stacked Bar",
"100% Stacked Bar",
"Line",
"Stacked Line",
"Area",
"Stacked Area",
"100% Stacked Area",
"Pie",
"Doughnut",
"Scatter",
"Radar",
] {
assert_eq!(marked(&h, other), other == label, "{other} on a {t} {sub} chart");
}
}
}
+1
View File
@@ -37,6 +37,7 @@ mod filter_menu_enter;
mod find_dialog_focus;
mod floating_pictures;
mod font_size_box;
mod format_chart_type;
mod format_painter;
mod formula_bar;
mod formula_bar_expand;