mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-10 12:29:58 -06:00
#1448: PivotTable ranks are dense; Count Numbers is captioned "Count of"
Show Values As › Rank Largest to Smallest counted every larger sibling, so ties skipped ranks: 5, 4, 3, 3, 4 ranked 1, 2, 4, 4, 2 where Excel gives 1, 2, 3, 3, 2. It now counts the distinct larger values. A new Count Numbers value field was captioned "Count Numbers of Units"; Excel captions it "Count of Units", as GridCraft's XLSX reader already names a value field saved without a name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
178f3eb745
commit
7bea3d1d6a
@@ -1013,3 +1013,19 @@ fn detail_cells_are_the_cells_show_details_takes() {
|
||||
let pt = &d.wb.active().unwrap().pivots[0];
|
||||
assert!(crate::pivot::detail_cells(&d.wb, pt, d.wb.active_sheet()).unwrap_err().contains("out of date"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rank_ties_are_dense_and_count_numbers_is_captioned_count_of() {
|
||||
// #1448 items 10 and 12: Excel ranks 5, 4, 3, 3, 4 as 1, 2, 3, 3, 2 (GridCraft gave 1, 2, 4,
|
||||
// 4, 2), and captions a Count Numbers field "Count of Val".
|
||||
let mut s = Session::new();
|
||||
s.new_workbook();
|
||||
let rows = json!([["Key", "Val"], ["A", 5], ["B", 4], ["C", 3], ["D", 3], ["E", 4]]);
|
||||
s.execute("range.setValues", json!({"range": "A1", "values": rows})).unwrap();
|
||||
s.execute("insert.pivotTable", json!({"source": "Sheet1!$A$1:$B$6", "destination": "Sheet1!D3", "rows": ["Key"], "values": ["Val"]})).unwrap();
|
||||
s.execute("pivot.valueSettings", json!({"index": 0, "showAs": "rank"})).unwrap();
|
||||
let ranks: Vec<Value> = ["E4", "E5", "E6", "E7", "E8"].iter().map(|a| val(&s, a)).collect();
|
||||
assert_eq!(ranks, [1.0, 2.0, 3.0, 3.0, 2.0].map(Value::Number));
|
||||
s.execute("pivot.valueSettings", json!({"index": 0, "showAs": "normal", "func": "countNumbers"})).unwrap();
|
||||
assert_eq!(text(&s, "E3"), "Count of Val");
|
||||
}
|
||||
|
||||
@@ -355,15 +355,19 @@ fn ranked_value(raw: Value, lookup: &ValueLookup<'_>, context: &ShowContext<'_>)
|
||||
let Some((_, parent)) = context.row_path.split_last() else { return Value::Empty };
|
||||
let Some(me) = raw.as_f64() else { return raw };
|
||||
let siblings = context.siblings.get(parent).cloned().unwrap_or_default();
|
||||
let mut rank = 1u64;
|
||||
for sibling in siblings {
|
||||
let mut path = parent.to_vec();
|
||||
path.push(sibling);
|
||||
if number(&lookup.get(&path, context.col_path, context.value_index)).is_some_and(|value| value > me) {
|
||||
rank += 1;
|
||||
}
|
||||
}
|
||||
Value::number(rank as f64)
|
||||
// Excel's ranks are dense: ties share a rank and the next value takes the next one
|
||||
// (5, 4, 3, 3, 4 rank 1, 2, 3, 3, 2), so count the distinct larger values.
|
||||
let mut larger: Vec<f64> = siblings
|
||||
.into_iter()
|
||||
.filter_map(|sibling| {
|
||||
let mut path = parent.to_vec();
|
||||
path.push(sibling);
|
||||
number(&lookup.get(&path, context.col_path, context.value_index)).filter(|value| *value > me)
|
||||
})
|
||||
.collect();
|
||||
larger.sort_by(f64::total_cmp);
|
||||
larger.dedup();
|
||||
Value::number(larger.len() as f64 + 1.0)
|
||||
}
|
||||
|
||||
fn show_value(definition: &PivotValue, raw: Value, lookup: &ValueLookup<'_>, context: &ShowContext<'_>) -> Value {
|
||||
|
||||
@@ -197,7 +197,8 @@ impl Acc {
|
||||
}
|
||||
}
|
||||
|
||||
/// Excel's caption verb for a function ("Sum of Sales").
|
||||
/// Excel's caption verb for a function ("Sum of Sales"). Count Numbers is captioned "Count of
|
||||
/// Sales", as Excel names it and as the XLSX reader names a value field saved without a name.
|
||||
pub fn func_caption(f: PivotFunc) -> &'static str {
|
||||
match f {
|
||||
PivotFunc::Sum => "Sum",
|
||||
@@ -206,7 +207,7 @@ pub fn func_caption(f: PivotFunc) -> &'static str {
|
||||
PivotFunc::Max => "Max",
|
||||
PivotFunc::Min => "Min",
|
||||
PivotFunc::Product => "Product",
|
||||
PivotFunc::CountNumbers => "Count Numbers",
|
||||
PivotFunc::CountNumbers => "Count",
|
||||
PivotFunc::StdDev => "StdDev",
|
||||
PivotFunc::StdDevP => "StdDevp",
|
||||
PivotFunc::Var => "Var",
|
||||
|
||||
Reference in New Issue
Block a user