Files
gridcraft/crates/model/src/features/pivot.rs
T

178 lines
5.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use super::{CellRef, RangeRef};
use serde::{Deserialize, Serialize};
// ---------------------------------------------------------------- pivot tables
/// How a PivotTable lays out its row fields.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PivotLayout {
/// All row fields in one column, inner items indented ("Row Labels" header).
#[default]
Compact,
/// One column per row field; each item on its own row.
Outline,
/// One column per row field; inner items start on their parent's row, totals below.
Tabular,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PivotSort {
#[default]
Asc,
Desc,
/// Source order (first appearance).
None,
}
/// Grouping of a date field (values are date serials).
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PivotDateGroup {
#[default]
None,
Years,
Quarters,
Months,
Days,
}
/// A field placed in the Rows or Columns area.
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct PivotField {
/// Source column header name.
pub source_col: String,
pub sort: PivotSort,
pub date_group: PivotDateGroup,
/// Item labels whose detail is hidden (collapsed).
pub collapsed_items: Vec<String>,
}
/// Summarize-values-by function.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PivotFunc {
#[default]
Sum,
Count,
Average,
Max,
Min,
Product,
CountNumbers,
StdDev,
StdDevP,
Var,
VarP,
}
/// Show-values-as transform.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PivotShowAs {
#[default]
Normal,
PercentOfGrandTotal,
PercentOfColumnTotal,
PercentOfRowTotal,
/// Running total in the first row field.
RunningTotal,
/// Rank largest to smallest among sibling row items.
Rank,
}
/// A field in the Values area.
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct PivotValue {
pub source_col: String,
pub func: PivotFunc,
/// Caption, e.g. "Sum of Sales".
pub name: String,
pub show_as: PivotShowAs,
pub number_format: Option<String>,
}
/// A report filter (or, for a field also in Rows/Columns, its hidden-items filter).
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct PivotFilter {
pub source_col: String,
/// Item labels shown; `None` = all.
pub selected: Option<Vec<String>>,
}
/// A PivotTable: its definition plus where its output was last written. The output itself is
/// static cell values and styles on the sheet, rewritten on every refresh.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct PivotTable {
pub id: u32,
pub name: String,
/// Source: range formula text (`Sheet1!$A$1:$E$200`), a table name or a defined name.
pub source: String,
/// Top-left of the output body on the pivot's sheet.
pub anchor: CellRef,
pub rows: Vec<PivotField>,
pub columns: Vec<PivotField>,
pub values: Vec<PivotValue>,
pub filters: Vec<PivotFilter>,
pub layout: PivotLayout,
/// PivotTable Options › Data › Enable show details: Show Details lists a value cell's
/// source records only while this is on.
pub enable_show_details: bool,
/// Grand total for each row (the "Grand Total" column), like Excel's "On for Rows".
pub grand_totals_rows: bool,
/// Grand total for each column (the "Grand Total" row), like Excel's "On for Columns".
pub grand_totals_cols: bool,
pub subtotals: bool,
/// Subtotals at the top of each group (Compact/Outline); otherwise below it.
pub subtotals_top: bool,
pub style: String,
pub show_headers: bool,
/// Area written by the last refresh.
pub last_range: Option<RangeRef>,
/// Calculated fields, usable in the Values area by name.
pub calculated_fields: Vec<PivotCalcField>,
/// The Σ Values pseudo-field (it exists with two or more value fields) sits in Rows rather
/// than Columns (Excel's "values on rows").
pub values_on_rows: bool,
/// Position of Σ Values among the row fields (`None` = after the last). Only used with
/// `values_on_rows`: in Columns Σ Values always comes after the last column field.
pub values_position: Option<usize>,
}
/// A calculated field: a formula over other fields (`=Sales*0.1`, `='Unit Price'*Units`). As in
/// Excel, it is evaluated on the sums of the fields it names for each report cell, not per record.
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct PivotCalcField {
pub name: String,
/// Formula text, starting with `=`.
pub formula: String,
}
impl Default for PivotTable {
fn default() -> Self {
PivotTable {
id: 0,
name: "PivotTable1".into(),
source: String::new(),
anchor: CellRef::default(),
rows: vec![],
columns: vec![],
values: vec![],
filters: vec![],
layout: PivotLayout::Compact,
enable_show_details: true,
grand_totals_rows: true,
grand_totals_cols: true,
subtotals: true,
subtotals_top: true,
style: "PivotStyleLight16".into(),
show_headers: true,
last_range: None,
calculated_fields: vec![],
values_on_rows: false,
values_position: None,
}
}
}