UNPKG

1.4 kBJavaScriptView Raw
1import { CrosTab } from '@analys/crostab';
2import { Cubic } from '@analys/cubic';
3import { parseField } from '@analys/tablespec';
4
5/**
6 * @typedef {string|number} str
7 * @typedef {{head:*[],rows:*[][]}} TableObject
8 */
9
10/**
11 * @param {str|str[]|Object<str,Function>|[string,Function][]} side
12 * @param {str|str[]|Object<str,Function>|[string,Function][]} banner
13 * @param {Object|*[]|string|number} [field]
14 * @param {Object<string|number,function(*?):boolean>} [filter]
15 * @param {function():number} [formula] - formula is valid only when cell is CubeCell array.
16 */
17
18/**
19 *
20 * @param {Table|TableObject} table
21 * @returns {CrosTab}
22 */
23
24const tablePivot = function (table) {
25 const {
26 side,
27 banner,
28 field,
29 formula
30 } = this;
31 const {
32 head,
33 rows
34 } = table;
35
36 const parseConf = keyConf => parseField(keyConf).map(({
37 key,
38 to
39 }) => ({
40 key: head.indexOf(key),
41 to
42 }));
43
44 const sideConf = parseConf(side),
45 bannerConf = parseConf(banner),
46 fieldConf = parseConf(field);
47 const pivotEngine = Cubic.build(sideConf, bannerConf, fieldConf);
48 const crostab = CrosTab.from(pivotEngine.record(rows).toObject());
49
50 if (formula) {
51 if (fieldConf.length === 1) crostab.mutate(el => formula.call(null, el));
52 if (fieldConf.length > 1) crostab.mutate(vec => formula.apply(null, vec));
53 }
54
55 return crostab;
56};
57
58export { tablePivot };