140 lines
4.7 KiB
TypeScript
140 lines
4.7 KiB
TypeScript
/**
|
|
* The pre-filled document ("roter Faden" of the study), in the v2 canvas model:
|
|
* one sheet ("Analyse") carrying three table objects and a chart object, plus a
|
|
* second empty sheet to try things out.
|
|
*
|
|
* Note on the brief: the acceptance list mentions "Übersicht!B2 = 6070" as the
|
|
* yearly Nord revenue, but the given Nord row is 1200 + 1450 + 1600 + 1720 =
|
|
* 5970. The explicit table wins -- the exact number is deterministic and the
|
|
* propagation behaviour it demonstrates is unchanged.
|
|
*/
|
|
|
|
import { parseA1 } from '../engine';
|
|
import type { ChartObject, DocumentState, TableObject } from '../store/types';
|
|
import { defaultTableView } from '../store/types';
|
|
|
|
let uid = 0;
|
|
const nextId = (p: string) => `${p}-seed-${(uid++).toString(36)}`;
|
|
|
|
function makeTable(
|
|
name: string,
|
|
x: number,
|
|
y: number,
|
|
rows: number,
|
|
cols: number,
|
|
entries: Array<[string, string | number]>,
|
|
colWidths: Record<number, number> = {},
|
|
viewOverride: Partial<TableObject['view']> = {},
|
|
): TableObject {
|
|
const cells: Record<string, string> = {};
|
|
for (const [a1, value] of entries) {
|
|
const { col, row } = parseA1(a1);
|
|
cells[`${col},${row}`] = String(value);
|
|
}
|
|
return {
|
|
kind: 'table',
|
|
id: nextId('tbl'),
|
|
name,
|
|
x,
|
|
y,
|
|
rows,
|
|
cols,
|
|
colWidths,
|
|
cells,
|
|
view: { ...defaultTableView(), ...viewOverride },
|
|
};
|
|
}
|
|
|
|
export function createSeedDocument(): DocumentState {
|
|
const umsatz = makeTable('Umsatz', 40, 40, 20, 8, [
|
|
['A1', 'Region'], ['B1', 'Q1'], ['C1', 'Q2'], ['D1', 'Q3'], ['E1', 'Q4'],
|
|
['A2', 'Nord'], ['B2', 1200], ['C2', 1450], ['D2', 1600], ['E2', 1720],
|
|
['A3', 'Süd'], ['B3', 980], ['C3', 1100], ['D3', 1250], ['E3', 1310],
|
|
['A4', 'Ost'], ['B4', 1550], ['C4', 1480], ['D4', 1620], ['E4', 1700],
|
|
['A5', 'West'], ['B5', 1340], ['C5', 1390], ['D5', 1500], ['E5', 1580],
|
|
['A6', 'Zentral'], ['B6', 1105], ['C6', 1205], ['D6', 1298], ['E6', 1402],
|
|
['A8', 'Summe'],
|
|
['B8', '=SUM(B2:B6)'], ['C8', '=SUM(C2:C6)'], ['D8', '=SUM(D2:D6)'], ['E8', '=SUM(E2:E6)'],
|
|
['A9', 'Mittelwert'],
|
|
['B9', '=AVG(B2:B6)'], ['C9', '=AVG(C2:C6)'], ['D9', '=AVG(D2:D6)'], ['E9', '=AVG(E2:E6)'],
|
|
['A10', 'Minimum'],
|
|
['B10', '=MIN(B2:B6)'], ['C10', '=MIN(C2:C6)'], ['D10', '=MIN(D2:D6)'], ['E10', '=MIN(E2:E6)'],
|
|
['A11', 'Maximum'],
|
|
['B11', '=MAX(B2:B6)'], ['C11', '=MAX(C2:C6)'], ['D11', '=MAX(D2:D6)'], ['E11', '=MAX(E2:E6)'],
|
|
['A12', 'Anzahl'],
|
|
['B12', '=COUNT(B2:B6)'], ['C12', '=COUNT(C2:C6)'], ['D12', '=COUNT(D2:D6)'], ['E12', '=COUNT(E2:E6)'],
|
|
['G2', 'Jahr Nord'], ['H2', '=SUM(B2:E2)'],
|
|
['G3', 'Schnitt/Q'], ['H3', '=SUM(B2:E2)/4'],
|
|
['G4', 'Delta Q4-Q1'], ['H4', '=E2-B2'],
|
|
], { 0: 92, 6: 96 }, { mode: 'fixed', width: 545, height: 360, frozenRows: 1, frozenCols: 1 });
|
|
|
|
const kosten = makeTable('Kosten', 40, 700, 12, 8, [
|
|
['A1', 'Region'], ['B1', 'Q1'], ['C1', 'Q2'], ['D1', 'Q3'], ['E1', 'Q4'],
|
|
['A2', 'Nord'], ['B2', 800], ['C2', 820], ['D2', 900], ['E2', 880],
|
|
['A3', 'Süd'], ['B3', 700], ['C3', 690], ['D3', 710], ['E3', 720],
|
|
['A4', 'Ost'], ['B4', 900], ['C4', 910], ['D4', 950], ['E4', 980],
|
|
['A5', 'West'], ['B5', 760], ['C5', 770], ['D5', 780], ['E5', 790],
|
|
['A6', 'Zentral'], ['B6', 640], ['C6', 650], ['D6', 660], ['E6', 670],
|
|
], { 0: 92 });
|
|
|
|
const regions = ['Nord', 'Süd', 'Ost', 'West', 'Zentral'];
|
|
const overview: Array<[string, string | number]> = [
|
|
['A1', 'Region'], ['B1', 'Umsatz Jahr'], ['C1', 'Kosten Jahr'],
|
|
['D1', 'Deckungsbeitrag'], ['E1', 'Marge %'],
|
|
];
|
|
regions.forEach((region, i) => {
|
|
const r = i + 2;
|
|
overview.push(
|
|
[`A${r}`, region],
|
|
[`B${r}`, `=SUM(Umsatz!B${r}:E${r})`],
|
|
[`C${r}`, `=SUM(Kosten!B${r}:E${r})`],
|
|
[`D${r}`, `=B${r}-C${r}`],
|
|
[`E${r}`, `=D${r}/B${r}*100`],
|
|
);
|
|
});
|
|
overview.push(
|
|
['A8', 'Gesamt'],
|
|
['B8', '=SUM(B2:B6)'], ['C8', '=SUM(C2:C6)'],
|
|
['D8', '=SUM(D2:D6)'], ['E8', '=AVG(E2:E6)'],
|
|
);
|
|
const uebersicht = makeTable('Übersicht', 1000, 40, 12, 6, overview, {
|
|
0: 84, 3: 118,
|
|
});
|
|
|
|
const chart: ChartObject = {
|
|
kind: 'chart',
|
|
id: nextId('cht'),
|
|
name: 'Umsatz je Region',
|
|
x: 1000,
|
|
y: 460,
|
|
width: 560,
|
|
height: 340,
|
|
view: 'bar',
|
|
sourceTableId: umsatz.id,
|
|
};
|
|
|
|
const analyse = {
|
|
id: nextId('sheet'),
|
|
name: 'Analyse',
|
|
objects: [umsatz, kosten, uebersicht, chart],
|
|
};
|
|
// second sheet demos the per-sheet backdrop colour + hidden grid
|
|
const blatt2 = {
|
|
id: nextId('sheet'),
|
|
name: 'Blatt 2',
|
|
objects: [],
|
|
background: '#f4f1ff',
|
|
showGrid: false,
|
|
};
|
|
|
|
return {
|
|
version: 2,
|
|
sheets: [analyse, blatt2],
|
|
activeSheetId: analyse.id,
|
|
activeObjectId: umsatz.id,
|
|
selection: { tableId: umsatz.id, anchor: { col: 0, row: 0 }, focus: { col: 0, row: 0 } },
|
|
locale: 'de-DE',
|
|
csvDelimiter: ',',
|
|
};
|
|
}
|