@trebco/treb 23.6.5 → 25.0.0-rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +8 -0
- package/.eslintrc.js +164 -0
- package/README-shadow-DOM.md +88 -0
- package/README.md +37 -130
- package/api-config.json +29 -0
- package/api-generator/api-generator-types.ts +82 -0
- package/api-generator/api-generator.ts +1172 -0
- package/api-generator/package.json +3 -0
- package/build/treb-spreadsheet.mjs +14 -0
- package/{treb.d.ts → build/treb.d.ts} +285 -269
- package/esbuild-custom-element.mjs +336 -0
- package/esbuild.js +305 -0
- package/package.json +43 -14
- package/treb-base-types/package.json +5 -0
- package/treb-base-types/src/api_types.ts +36 -0
- package/treb-base-types/src/area.ts +583 -0
- package/treb-base-types/src/basic_types.ts +45 -0
- package/treb-base-types/src/cell.ts +612 -0
- package/treb-base-types/src/cells.ts +1066 -0
- package/treb-base-types/src/color.ts +124 -0
- package/treb-base-types/src/import.ts +71 -0
- package/treb-base-types/src/index-standalone.ts +29 -0
- package/treb-base-types/src/index.ts +42 -0
- package/treb-base-types/src/layout.ts +47 -0
- package/treb-base-types/src/localization.ts +187 -0
- package/treb-base-types/src/rectangle.ts +145 -0
- package/treb-base-types/src/render_text.ts +72 -0
- package/treb-base-types/src/style.ts +545 -0
- package/treb-base-types/src/table.ts +109 -0
- package/treb-base-types/src/text_part.ts +54 -0
- package/treb-base-types/src/theme.ts +608 -0
- package/treb-base-types/src/union.ts +152 -0
- package/treb-base-types/src/value-type.ts +164 -0
- package/treb-base-types/style/resizable.css +59 -0
- package/treb-calculator/modern.tsconfig.json +11 -0
- package/treb-calculator/package.json +5 -0
- package/treb-calculator/src/calculator.ts +2546 -0
- package/treb-calculator/src/complex-math.ts +558 -0
- package/treb-calculator/src/dag/array-vertex.ts +198 -0
- package/treb-calculator/src/dag/graph.ts +951 -0
- package/treb-calculator/src/dag/leaf_vertex.ts +118 -0
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +327 -0
- package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +44 -0
- package/treb-calculator/src/dag/vertex.ts +352 -0
- package/treb-calculator/src/descriptors.ts +162 -0
- package/treb-calculator/src/expression-calculator.ts +1069 -0
- package/treb-calculator/src/function-error.ts +103 -0
- package/treb-calculator/src/function-library.ts +103 -0
- package/treb-calculator/src/functions/base-functions.ts +1214 -0
- package/treb-calculator/src/functions/checkbox.ts +164 -0
- package/treb-calculator/src/functions/complex-functions.ts +253 -0
- package/treb-calculator/src/functions/finance-functions.ts +399 -0
- package/treb-calculator/src/functions/information-functions.ts +102 -0
- package/treb-calculator/src/functions/matrix-functions.ts +182 -0
- package/treb-calculator/src/functions/sparkline.ts +335 -0
- package/treb-calculator/src/functions/statistics-functions.ts +350 -0
- package/treb-calculator/src/functions/text-functions.ts +298 -0
- package/treb-calculator/src/index.ts +27 -0
- package/treb-calculator/src/notifier-types.ts +59 -0
- package/treb-calculator/src/primitives.ts +428 -0
- package/treb-calculator/src/utilities.ts +305 -0
- package/treb-charts/package.json +5 -0
- package/treb-charts/src/chart-functions.ts +156 -0
- package/treb-charts/src/chart-types.ts +230 -0
- package/treb-charts/src/chart.ts +1288 -0
- package/treb-charts/src/index.ts +24 -0
- package/treb-charts/src/main.ts +37 -0
- package/treb-charts/src/rectangle.ts +52 -0
- package/treb-charts/src/renderer.ts +1841 -0
- package/treb-charts/src/util.ts +122 -0
- package/treb-charts/style/charts.scss +221 -0
- package/treb-charts/style/old-charts.scss +250 -0
- package/treb-embed/markup/layout.html +137 -0
- package/treb-embed/markup/toolbar.html +175 -0
- package/treb-embed/modern.tsconfig.json +25 -0
- package/treb-embed/src/custom-element/content-types.d.ts +18 -0
- package/treb-embed/src/custom-element/global.d.ts +11 -0
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1227 -0
- package/treb-embed/src/custom-element/treb-global.ts +44 -0
- package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +52 -0
- package/treb-embed/src/embedded-spreadsheet.ts +5362 -0
- package/treb-embed/src/index.ts +16 -0
- package/treb-embed/src/language-model.ts +41 -0
- package/treb-embed/src/options.ts +320 -0
- package/treb-embed/src/progress-dialog.ts +228 -0
- package/treb-embed/src/selection-state.ts +16 -0
- package/treb-embed/src/spinner.ts +42 -0
- package/treb-embed/src/toolbar-message.ts +96 -0
- package/treb-embed/src/types.ts +167 -0
- package/treb-embed/style/autocomplete.scss +103 -0
- package/treb-embed/style/dark-theme.scss +114 -0
- package/treb-embed/style/defaults.scss +36 -0
- package/treb-embed/style/dialog.scss +181 -0
- package/treb-embed/style/dropdown-select.scss +101 -0
- package/treb-embed/style/formula-bar.scss +193 -0
- package/treb-embed/style/grid.scss +374 -0
- package/treb-embed/style/layout.scss +424 -0
- package/treb-embed/style/mouse-mask.scss +67 -0
- package/treb-embed/style/note.scss +92 -0
- package/treb-embed/style/overlay-editor.scss +102 -0
- package/treb-embed/style/spinner.scss +92 -0
- package/treb-embed/style/tab-bar.scss +228 -0
- package/treb-embed/style/table.scss +80 -0
- package/treb-embed/style/theme-defaults.scss +444 -0
- package/treb-embed/style/toolbar.scss +416 -0
- package/treb-embed/style/tooltip.scss +68 -0
- package/treb-embed/style/treb-icons.scss +130 -0
- package/treb-embed/style/treb-spreadsheet-element.scss +20 -0
- package/treb-embed/style/z-index.scss +43 -0
- package/treb-export/docs/charts.md +68 -0
- package/treb-export/modern.tsconfig.json +19 -0
- package/treb-export/package.json +4 -0
- package/treb-export/src/address-type.ts +77 -0
- package/treb-export/src/base-template.ts +22 -0
- package/treb-export/src/column-width.ts +85 -0
- package/treb-export/src/drawing2/chart-template-components2.ts +389 -0
- package/treb-export/src/drawing2/chart2.ts +282 -0
- package/treb-export/src/drawing2/column-chart-template2.ts +521 -0
- package/treb-export/src/drawing2/donut-chart-template2.ts +296 -0
- package/treb-export/src/drawing2/drawing2.ts +355 -0
- package/treb-export/src/drawing2/embedded-image.ts +71 -0
- package/treb-export/src/drawing2/scatter-chart-template2.ts +555 -0
- package/treb-export/src/export-worker/export-worker.ts +99 -0
- package/treb-export/src/export-worker/index-modern.ts +22 -0
- package/treb-export/src/export2.ts +2204 -0
- package/treb-export/src/import2.ts +882 -0
- package/treb-export/src/relationship.ts +36 -0
- package/treb-export/src/shared-strings2.ts +128 -0
- package/treb-export/src/template-2.ts +22 -0
- package/treb-export/src/unescape_xml.ts +47 -0
- package/treb-export/src/workbook-sheet2.ts +182 -0
- package/treb-export/src/workbook-style2.ts +1285 -0
- package/treb-export/src/workbook-theme2.ts +88 -0
- package/treb-export/src/workbook2.ts +491 -0
- package/treb-export/src/xml-utils.ts +201 -0
- package/treb-export/template/base/[Content_Types].xml +2 -0
- package/treb-export/template/base/_rels/.rels +2 -0
- package/treb-export/template/base/docProps/app.xml +2 -0
- package/treb-export/template/base/docProps/core.xml +12 -0
- package/treb-export/template/base/xl/_rels/workbook.xml.rels +2 -0
- package/treb-export/template/base/xl/sharedStrings.xml +2 -0
- package/treb-export/template/base/xl/styles.xml +2 -0
- package/treb-export/template/base/xl/theme/theme1.xml +2 -0
- package/treb-export/template/base/xl/workbook.xml +2 -0
- package/treb-export/template/base/xl/worksheets/sheet1.xml +2 -0
- package/treb-export/template/base.xlsx +0 -0
- package/treb-format/package.json +8 -0
- package/treb-format/src/format.test.ts +213 -0
- package/treb-format/src/format.ts +942 -0
- package/treb-format/src/format_cache.ts +199 -0
- package/treb-format/src/format_parser.ts +723 -0
- package/treb-format/src/index.ts +25 -0
- package/treb-format/src/number_format_section.ts +100 -0
- package/treb-format/src/value_parser.ts +337 -0
- package/treb-grid/package.json +5 -0
- package/treb-grid/src/editors/autocomplete.ts +394 -0
- package/treb-grid/src/editors/autocomplete_matcher.ts +260 -0
- package/treb-grid/src/editors/formula_bar.ts +473 -0
- package/treb-grid/src/editors/formula_editor_base.ts +910 -0
- package/treb-grid/src/editors/overlay_editor.ts +511 -0
- package/treb-grid/src/index.ts +37 -0
- package/treb-grid/src/layout/base_layout.ts +2618 -0
- package/treb-grid/src/layout/grid_layout.ts +299 -0
- package/treb-grid/src/layout/rectangle_cache.ts +86 -0
- package/treb-grid/src/render/selection-renderer.ts +414 -0
- package/treb-grid/src/render/svg_header_overlay.ts +93 -0
- package/treb-grid/src/render/svg_selection_block.ts +187 -0
- package/treb-grid/src/render/tile_renderer.ts +2122 -0
- package/treb-grid/src/types/annotation.ts +216 -0
- package/treb-grid/src/types/border_constants.ts +34 -0
- package/treb-grid/src/types/clipboard_data.ts +31 -0
- package/treb-grid/src/types/data_model.ts +334 -0
- package/treb-grid/src/types/drag_mask.ts +81 -0
- package/treb-grid/src/types/grid.ts +7743 -0
- package/treb-grid/src/types/grid_base.ts +3644 -0
- package/treb-grid/src/types/grid_command.ts +470 -0
- package/treb-grid/src/types/grid_events.ts +124 -0
- package/treb-grid/src/types/grid_options.ts +97 -0
- package/treb-grid/src/types/grid_selection.ts +60 -0
- package/treb-grid/src/types/named_range.ts +369 -0
- package/treb-grid/src/types/scale-control.ts +202 -0
- package/treb-grid/src/types/serialize_options.ts +72 -0
- package/treb-grid/src/types/set_range_options.ts +52 -0
- package/treb-grid/src/types/sheet.ts +3099 -0
- package/treb-grid/src/types/sheet_types.ts +95 -0
- package/treb-grid/src/types/tab_bar.ts +464 -0
- package/treb-grid/src/types/tile.ts +59 -0
- package/treb-grid/src/types/update_flags.ts +75 -0
- package/treb-grid/src/util/dom_utilities.ts +44 -0
- package/treb-grid/src/util/fontmetrics2.ts +179 -0
- package/treb-grid/src/util/ua.ts +104 -0
- package/treb-logo.svg +18 -0
- package/treb-parser/package.json +5 -0
- package/treb-parser/src/csv-parser.ts +122 -0
- package/treb-parser/src/index.ts +25 -0
- package/treb-parser/src/md-parser.ts +526 -0
- package/treb-parser/src/parser-types.ts +397 -0
- package/treb-parser/src/parser.test.ts +298 -0
- package/treb-parser/src/parser.ts +2673 -0
- package/treb-utils/package.json +5 -0
- package/treb-utils/src/dispatch.ts +57 -0
- package/treb-utils/src/event_source.ts +147 -0
- package/treb-utils/src/ievent_source.ts +33 -0
- package/treb-utils/src/index.ts +31 -0
- package/treb-utils/src/measurement.ts +174 -0
- package/treb-utils/src/resizable.ts +160 -0
- package/treb-utils/src/scale.ts +137 -0
- package/treb-utils/src/serialize_html.ts +124 -0
- package/treb-utils/src/template.ts +70 -0
- package/treb-utils/src/validate_uri.ts +61 -0
- package/tsconfig.json +10 -0
- package/tsproject.json +30 -0
- package/util/license-plugin-esbuild.js +86 -0
- package/util/list-css-vars.sh +46 -0
- package/README-esm.md +0 -37
- package/treb-bundle.css +0 -2
- package/treb-bundle.mjs +0 -15
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of TREB.
|
|
3
|
+
*
|
|
4
|
+
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
+
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
* later version.
|
|
8
|
+
*
|
|
9
|
+
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
* details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License along
|
|
15
|
+
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2022-2023 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { ArrayUnion, UnionValue, ValueType } from 'treb-base-types';
|
|
23
|
+
|
|
24
|
+
export const DAY_MS = 1000 * 60 * 60 * 24;
|
|
25
|
+
|
|
26
|
+
export const IsArrayOrTypedArray = (test: any): boolean => {
|
|
27
|
+
return Array.isArray(test) || (test instanceof Float64Array) || (test instanceof Float64Array);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Transpose2 = <T> (arr: T[][]): T[][] => {
|
|
31
|
+
|
|
32
|
+
const result: T[][] = [];
|
|
33
|
+
|
|
34
|
+
const cols = arr.length;
|
|
35
|
+
const rows = arr[0].length;
|
|
36
|
+
for (let r = 0; r < rows; r++) {
|
|
37
|
+
result[r] = [];
|
|
38
|
+
for (let c = 0; c < cols; c++ ) {
|
|
39
|
+
result[r][c] = arr[c][r];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return result;
|
|
44
|
+
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const TransposeArray = (arr: any[][]) => {
|
|
48
|
+
|
|
49
|
+
if (!arr) return [];
|
|
50
|
+
if (typeof arr[0] === 'undefined') return [];
|
|
51
|
+
|
|
52
|
+
if (!IsArrayOrTypedArray(arr[0])) {
|
|
53
|
+
if (arr instanceof Float32Array || arr instanceof Float64Array){
|
|
54
|
+
return Array.prototype.slice.call(arr).map((x: any) => [x]);
|
|
55
|
+
}
|
|
56
|
+
return arr.map((x) => [x]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const tmp: any = [];
|
|
60
|
+
const cols = arr.length;
|
|
61
|
+
const rows = arr[0].length;
|
|
62
|
+
for (let r = 0; r < rows; r++) {
|
|
63
|
+
tmp[r] = [];
|
|
64
|
+
for (let c = 0; c < cols; c++ ) {
|
|
65
|
+
tmp[r][c] = arr[c][r];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return tmp;
|
|
69
|
+
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const StringToColumn = (s: string) => {
|
|
73
|
+
let index = 0;
|
|
74
|
+
s = s.toUpperCase();
|
|
75
|
+
for (let i = 0; i < s.length; i++) {
|
|
76
|
+
index *= 26;
|
|
77
|
+
index += (s.charCodeAt(i) - 64);
|
|
78
|
+
}
|
|
79
|
+
return index - 1;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const ColumnToString = (column: number) => {
|
|
83
|
+
|
|
84
|
+
// there's some weird case where this hangs, not sure
|
|
85
|
+
// how that happens. trap it and figure it out.
|
|
86
|
+
|
|
87
|
+
const original = column;
|
|
88
|
+
|
|
89
|
+
let s = '';
|
|
90
|
+
for (;;) {
|
|
91
|
+
const c = column % 26;
|
|
92
|
+
s = String.fromCharCode(65 + c) + s;
|
|
93
|
+
column = Math.floor(column / 26);
|
|
94
|
+
if (column) column--;
|
|
95
|
+
if (column < 0) throw(new Error('Column < 0!, original was ' + original));
|
|
96
|
+
else break;
|
|
97
|
+
}
|
|
98
|
+
return s;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const OffsetFormula = (formula: string, offset: {columns: number, rows: number}) => {
|
|
102
|
+
|
|
103
|
+
const cache: any = {};
|
|
104
|
+
formula = formula.replace(/\b([A-Za-z]+)(\d+)\b/g, (m, p1, p2) => {
|
|
105
|
+
if (!cache[m]) {
|
|
106
|
+
const c = ColumnToString(StringToColumn(p1) + offset.columns);
|
|
107
|
+
const r = Number(p2) + offset.rows;
|
|
108
|
+
cache[m] = c + r.toString();
|
|
109
|
+
}
|
|
110
|
+
return cache[m];
|
|
111
|
+
});
|
|
112
|
+
return formula;
|
|
113
|
+
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* assuming boxed (union) arguments, return a flat list of values.
|
|
118
|
+
* @param args
|
|
119
|
+
*/
|
|
120
|
+
export const FlattenBoxed = (args: UnionValue[]): UnionValue[] => {
|
|
121
|
+
|
|
122
|
+
// let's go back to imperative style for now
|
|
123
|
+
|
|
124
|
+
let result: UnionValue[] = [];
|
|
125
|
+
for (const arg of args) {
|
|
126
|
+
if (arg.type === ValueType.array) {
|
|
127
|
+
|
|
128
|
+
// possibly recursive
|
|
129
|
+
for (const row of arg.value) {
|
|
130
|
+
|
|
131
|
+
// what's faster, concatenate or ...push?
|
|
132
|
+
|
|
133
|
+
// result.push(...FlattenBoxed(row));
|
|
134
|
+
result = result.concat(FlattenBoxed(row));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
result.push(arg);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return result;
|
|
144
|
+
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* flatten a set of arguments
|
|
149
|
+
* UPDATE: we no longer accept the "arguments" object. must be an array.
|
|
150
|
+
* callers can use rest spread to collect arguments.
|
|
151
|
+
*/
|
|
152
|
+
export const FlattenUnboxed = (args: any[]): any[] => {
|
|
153
|
+
if (!Array.isArray(args)) { return [args]; } // special case
|
|
154
|
+
return args.reduce((a: any[], b: any) => {
|
|
155
|
+
if (typeof b === 'undefined') return a;
|
|
156
|
+
if (Array.isArray(b)) return a.concat(FlattenUnboxed(b));
|
|
157
|
+
if (b instanceof Float32Array) return a.concat(Array.from(b));
|
|
158
|
+
if (b instanceof Float64Array) return a.concat(Array.from(b));
|
|
159
|
+
return a.concat([b]);
|
|
160
|
+
}, []);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const UndefinedToEmptyString = (args: any[]): any[] => {
|
|
164
|
+
for (let i = 0; i < args.length; i++) {
|
|
165
|
+
if (Array.isArray(args[i])) {
|
|
166
|
+
args[i] = UndefinedToEmptyString(args[i]);
|
|
167
|
+
}
|
|
168
|
+
else if (typeof args[i] === 'undefined') {
|
|
169
|
+
args[i] = '';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return args;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* returns a function that applies the given function to a scalar or a matrix
|
|
177
|
+
* @param base the underlying function
|
|
178
|
+
*/
|
|
179
|
+
export const ApplyArrayFunc = (base: (...args: any[]) => any) => {
|
|
180
|
+
return (a: any) => {
|
|
181
|
+
if (Array.isArray(a)) {
|
|
182
|
+
const tmp = [];
|
|
183
|
+
const rows = a[0].length;
|
|
184
|
+
for (let c = 0; c < a.length; c++) {
|
|
185
|
+
const col = [];
|
|
186
|
+
for (let r = 0; r < rows; r++) col[r] = base(a[c][r]);
|
|
187
|
+
tmp.push(col);
|
|
188
|
+
}
|
|
189
|
+
return tmp;
|
|
190
|
+
}
|
|
191
|
+
return base(a);
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const ApplyAsArray = (base: (a: any, ...rest: any[]) => UnionValue) => {
|
|
196
|
+
return (a: any, ...rest: any[]): UnionValue => {
|
|
197
|
+
if (Array.isArray(a)) {
|
|
198
|
+
|
|
199
|
+
console.info("AAA 71823");
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
type: ValueType.array,
|
|
203
|
+
value: a.map(row => row.map((element: any) => {
|
|
204
|
+
return base(element, ...rest);
|
|
205
|
+
})),
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/*
|
|
209
|
+
return a.map(row => row.map((element: any) => {
|
|
210
|
+
return base(element, ...rest);
|
|
211
|
+
}));
|
|
212
|
+
*/
|
|
213
|
+
}
|
|
214
|
+
else if (typeof a === 'object' && !!a && a.type === ValueType.array ) {
|
|
215
|
+
return {
|
|
216
|
+
type: ValueType.array,
|
|
217
|
+
value: (a as ArrayUnion).value.map(row => row.map((element: any) => {
|
|
218
|
+
return base(element, ...rest);
|
|
219
|
+
})),
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
return base(a, ...rest);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export const ApplyAsArray2 = (base: (a: any, b: any, ...rest: any[]) => UnionValue) => {
|
|
230
|
+
return (a: any, b: any, ...rest: any[]): UnionValue => {
|
|
231
|
+
|
|
232
|
+
// do we need to worry about unboxed values? probably
|
|
233
|
+
// what about combinations of boxed/unboxed (implying there are 4)
|
|
234
|
+
|
|
235
|
+
// we could simplify this by pulling out the lists...
|
|
236
|
+
|
|
237
|
+
let a_array = false;
|
|
238
|
+
let b_array = false;
|
|
239
|
+
|
|
240
|
+
if (!!a && typeof a === 'object' && a.type === ValueType.array) {
|
|
241
|
+
a = (a as ArrayUnion).value;
|
|
242
|
+
a_array = true; // don't test again
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
a_array = Array.isArray(a);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (!!b && typeof b === 'object' && b.type === ValueType.array) {
|
|
249
|
+
b = (b as ArrayUnion).value;
|
|
250
|
+
b_array = true; // don't test again
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
b_array = Array.isArray(b);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (a_array){
|
|
257
|
+
if (b_array) {
|
|
258
|
+
// a and b are arrays
|
|
259
|
+
return {
|
|
260
|
+
type: ValueType.array,
|
|
261
|
+
value: a.map((row: any[], i: number) => row.map((element: any, j: number) => {
|
|
262
|
+
return base(element, b[i][j], ...rest);
|
|
263
|
+
})),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// a is array, b is scalar
|
|
267
|
+
return {
|
|
268
|
+
type: ValueType.array,
|
|
269
|
+
value: a.map((row: any[]) => row.map((element: any) => {
|
|
270
|
+
return base(element, b, ...rest);
|
|
271
|
+
})),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
else if (b_array) {
|
|
275
|
+
// a is scalar, b is array
|
|
276
|
+
return {
|
|
277
|
+
type: ValueType.array,
|
|
278
|
+
value: b.map((row: any[]) => row.map((element: any) => {
|
|
279
|
+
return base(a, element, ...rest);
|
|
280
|
+
})),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/*
|
|
285
|
+
if (Array.isArray(a)) {
|
|
286
|
+
if (Array.isArray(b)) {
|
|
287
|
+
return a.map((row, i: number) => row.map((element: any, j: number) => {
|
|
288
|
+
return base(element, b[i][j], ...rest);
|
|
289
|
+
}));
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
return a.map(row => row.map((element: any) => {
|
|
293
|
+
return base(element, b, ...rest);
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
return base(a, b, ...rest);
|
|
299
|
+
}
|
|
300
|
+
*/
|
|
301
|
+
return base(a, b, ...rest);
|
|
302
|
+
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of TREB.
|
|
3
|
+
*
|
|
4
|
+
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
+
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
* later version.
|
|
8
|
+
*
|
|
9
|
+
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
* details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License along
|
|
15
|
+
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2022-2023 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { UnionValue, ValueType } from 'treb-base-types';
|
|
23
|
+
import type { FunctionMap } from 'treb-calculator/src/descriptors';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* function returns its arguments
|
|
27
|
+
*
|
|
28
|
+
* UPDATE: box this properly as "extended" type
|
|
29
|
+
*/
|
|
30
|
+
const Identity = (...args: any[]): UnionValue => {
|
|
31
|
+
return {
|
|
32
|
+
type: ValueType.object,
|
|
33
|
+
value: args,
|
|
34
|
+
key: 'arguments',
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* chart functions for registration
|
|
40
|
+
*/
|
|
41
|
+
export const ChartFunctions: FunctionMap = {
|
|
42
|
+
|
|
43
|
+
/* new: also helper */
|
|
44
|
+
Group: {
|
|
45
|
+
arguments: [
|
|
46
|
+
{ name: 'Array...', metadata: true, },
|
|
47
|
+
],
|
|
48
|
+
fn: (...args: any) => {
|
|
49
|
+
return {
|
|
50
|
+
type: ValueType.object,
|
|
51
|
+
value: args,
|
|
52
|
+
key: 'group',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* UPDATE: adding explicit names to Series, for convention. Use the
|
|
60
|
+
* more general "group" if you just want to group things.
|
|
61
|
+
*
|
|
62
|
+
* boxing properly as "extended" type
|
|
63
|
+
*/
|
|
64
|
+
Series: {
|
|
65
|
+
arguments: [
|
|
66
|
+
{ name: 'Label' }, // , metadata: true, },
|
|
67
|
+
{ name: 'X', metadata: true, },
|
|
68
|
+
{ name: 'Y', metadata: true, },
|
|
69
|
+
{ name: 'index', },
|
|
70
|
+
{ name: 'subtype', },
|
|
71
|
+
],
|
|
72
|
+
fn: (...args: any) => {
|
|
73
|
+
return {
|
|
74
|
+
type: ValueType.object,
|
|
75
|
+
value: args,
|
|
76
|
+
key: 'series',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
'Bar.Chart': {
|
|
83
|
+
arguments: [
|
|
84
|
+
{ name: 'Data', metadata: true, },
|
|
85
|
+
{ name: 'Categories', metadata: true, },
|
|
86
|
+
{ name: 'ChartTitle' },
|
|
87
|
+
],
|
|
88
|
+
fn: Identity,
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
'Line.Chart': {
|
|
92
|
+
arguments: [
|
|
93
|
+
{ name: 'y', metadata: true, },
|
|
94
|
+
{ name: 'x', metadata: true, },
|
|
95
|
+
{ name: 'ChartTitle' },
|
|
96
|
+
],
|
|
97
|
+
fn: Identity,
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
'Area.Chart': {
|
|
101
|
+
arguments: [
|
|
102
|
+
{ name: 'y', metadata: true, },
|
|
103
|
+
{ name: 'x', metadata: true, },
|
|
104
|
+
{ name: 'ChartTitle' },
|
|
105
|
+
],
|
|
106
|
+
fn: Identity,
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
'Pie.Chart': {
|
|
110
|
+
arguments: [
|
|
111
|
+
{ name: 'Values', metadata: true, },
|
|
112
|
+
{ name: 'Labels' },
|
|
113
|
+
{ name: 'Title' },
|
|
114
|
+
{ name: 'Sort' },
|
|
115
|
+
{ name: 'Label' },
|
|
116
|
+
],
|
|
117
|
+
fn: Identity,
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
'Donut.Chart': {
|
|
121
|
+
arguments: [
|
|
122
|
+
{ name: 'Values', metadata: true, },
|
|
123
|
+
{ name: 'Labels', metadata: true },
|
|
124
|
+
{ name: 'Title' },
|
|
125
|
+
{ name: 'Sort' },
|
|
126
|
+
{ name: 'Label' },
|
|
127
|
+
],
|
|
128
|
+
fn: Identity,
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
'Scatter.Line': {
|
|
132
|
+
arguments: [
|
|
133
|
+
{ name: 'Data', metadata: true, },
|
|
134
|
+
{ name: 'ChartTitle' },
|
|
135
|
+
],
|
|
136
|
+
fn: Identity,
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
'Scatter.Plot': {
|
|
140
|
+
arguments: [
|
|
141
|
+
{ name: 'Data', metadata: true, },
|
|
142
|
+
{ name: 'ChartTitle' },
|
|
143
|
+
],
|
|
144
|
+
fn: Identity,
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
'Column.Chart': {
|
|
148
|
+
arguments: [
|
|
149
|
+
{ name: 'Data', metadata: true, },
|
|
150
|
+
{ name: 'Categories', metadata: true, },
|
|
151
|
+
{ name: 'Chart Title' },
|
|
152
|
+
],
|
|
153
|
+
fn: Identity,
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
};
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of TREB.
|
|
3
|
+
*
|
|
4
|
+
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
+
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
* later version.
|
|
8
|
+
*
|
|
9
|
+
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
* details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License along
|
|
15
|
+
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2022-2023 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { RangeScale } from 'treb-utils';
|
|
23
|
+
import type { Area } from './rectangle';
|
|
24
|
+
|
|
25
|
+
export type NumberOrUndefinedArray = Array<number|undefined>;
|
|
26
|
+
|
|
27
|
+
export interface AxisOptions {
|
|
28
|
+
|
|
29
|
+
/** show labels */
|
|
30
|
+
labels?: boolean;
|
|
31
|
+
|
|
32
|
+
/** label number format */
|
|
33
|
+
format?: string;
|
|
34
|
+
|
|
35
|
+
/** tickmarks, only on x-axis (atm) */
|
|
36
|
+
ticks?: boolean;
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CalloutType {
|
|
41
|
+
value: number;
|
|
42
|
+
label?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface CellData {
|
|
46
|
+
address: { row: number; column: number };
|
|
47
|
+
value?: any;
|
|
48
|
+
format?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface DonutSlice {
|
|
52
|
+
index: number;
|
|
53
|
+
value: number;
|
|
54
|
+
percent: number;
|
|
55
|
+
label?: string;
|
|
56
|
+
title?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** common to all chart data types */
|
|
60
|
+
export interface ChartDataBaseType {
|
|
61
|
+
title?: string;
|
|
62
|
+
// legend?: string[];
|
|
63
|
+
legend?: Array<{label: string, index?: number}>;
|
|
64
|
+
legend_position?: LegendPosition;
|
|
65
|
+
legend_style?: LegendStyle;
|
|
66
|
+
title_layout?: 'top'|'bottom';
|
|
67
|
+
|
|
68
|
+
lines?: boolean;
|
|
69
|
+
filled?: boolean;
|
|
70
|
+
markers?: boolean;
|
|
71
|
+
smooth?: boolean;
|
|
72
|
+
data_labels?: boolean;
|
|
73
|
+
|
|
74
|
+
class_name?: string;
|
|
75
|
+
|
|
76
|
+
/** different marker type for scatter plot */
|
|
77
|
+
points?: boolean;
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** default, empty chart (you can still add a title, I suppose) */
|
|
82
|
+
export interface NullChartData extends ChartDataBaseType {
|
|
83
|
+
type: 'null';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** scatter plot (only used for correlation, atm) */
|
|
87
|
+
export interface ScatterData extends ChartDataBaseType {
|
|
88
|
+
type: 'scatter';
|
|
89
|
+
x: number[];
|
|
90
|
+
y: number[];
|
|
91
|
+
count: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** scatter plot used for line charting */
|
|
95
|
+
export interface ScatterData2 extends ChartDataBaseType {
|
|
96
|
+
type: 'scatter2';
|
|
97
|
+
|
|
98
|
+
series?: SeriesType[];
|
|
99
|
+
|
|
100
|
+
x_scale: RangeScale;
|
|
101
|
+
y_scale: RangeScale;
|
|
102
|
+
|
|
103
|
+
x_labels?: string[];
|
|
104
|
+
y_labels?: string[];
|
|
105
|
+
|
|
106
|
+
style?: 'plot'|'line'|'area';
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** base for column types (FIXME: probably common to scatter/line/area also) */
|
|
111
|
+
export interface ColumnDataBaseType extends ChartDataBaseType {
|
|
112
|
+
column_width: number;
|
|
113
|
+
x_labels?: string[];
|
|
114
|
+
y_labels?: string[];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** histogram */
|
|
118
|
+
export interface HistogramData extends ColumnDataBaseType {
|
|
119
|
+
type: 'histogram';
|
|
120
|
+
bins: number[];
|
|
121
|
+
min: number;
|
|
122
|
+
max: number;
|
|
123
|
+
count: number;
|
|
124
|
+
scale: RangeScale;
|
|
125
|
+
titles?: string[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface LineBaseData extends ChartDataBaseType {
|
|
129
|
+
series?: NumberOrUndefinedArray[];
|
|
130
|
+
series2?: SeriesType[];
|
|
131
|
+
scale: RangeScale;
|
|
132
|
+
x_scale?: RangeScale;
|
|
133
|
+
titles?: string[];
|
|
134
|
+
x_labels?: string[];
|
|
135
|
+
y_labels?: string[];
|
|
136
|
+
callouts?: CalloutType[];
|
|
137
|
+
smooth?: boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface LineData extends LineBaseData {
|
|
141
|
+
type: 'line';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface AreaData extends LineBaseData {
|
|
145
|
+
type: 'area';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface ColumnData extends LineBaseData {
|
|
149
|
+
type: 'column';
|
|
150
|
+
round?: boolean;
|
|
151
|
+
space?: number;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface HistogramData2 extends LineBaseData {
|
|
155
|
+
type: 'histogram2';
|
|
156
|
+
round?: boolean;
|
|
157
|
+
space?: number;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface BarData extends LineBaseData {
|
|
161
|
+
type: 'bar';
|
|
162
|
+
round?: boolean;
|
|
163
|
+
space?: number;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface DonutDataBaseType extends ChartDataBaseType {
|
|
167
|
+
slices: DonutSlice[];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** donut (FIXME: common type for pie, donut) */
|
|
171
|
+
export interface DonutChartData extends DonutDataBaseType {
|
|
172
|
+
type: 'donut';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** pie (FIXME: common type for pie, donut) */
|
|
176
|
+
export interface PieChartData extends DonutDataBaseType {
|
|
177
|
+
type: 'pie';
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** union type */
|
|
181
|
+
export type ChartData
|
|
182
|
+
= NullChartData
|
|
183
|
+
| DonutChartData
|
|
184
|
+
| HistogramData
|
|
185
|
+
| HistogramData2
|
|
186
|
+
| PieChartData
|
|
187
|
+
| ScatterData
|
|
188
|
+
| ScatterData2
|
|
189
|
+
| LineData
|
|
190
|
+
| AreaData
|
|
191
|
+
| ColumnData
|
|
192
|
+
| BarData
|
|
193
|
+
;
|
|
194
|
+
|
|
195
|
+
export enum LegendLayout {
|
|
196
|
+
horizontal, vertical
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export enum LegendPosition {
|
|
200
|
+
top, bottom, left, right,
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export enum LegendStyle {
|
|
204
|
+
line, marker
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface LegendOptions {
|
|
208
|
+
// labels: string[];
|
|
209
|
+
labels: Array<{label: string, index?: number}>;
|
|
210
|
+
layout?: LegendLayout;
|
|
211
|
+
position?: LegendPosition;
|
|
212
|
+
style?: LegendStyle;
|
|
213
|
+
area: Area;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface SubSeries {
|
|
217
|
+
data: Array<number|undefined>;
|
|
218
|
+
format?: string;
|
|
219
|
+
range?: { min: number, max: number };
|
|
220
|
+
labels?: Array<string|undefined>;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface SeriesType {
|
|
224
|
+
label?: string;
|
|
225
|
+
subtype?: string;
|
|
226
|
+
x: SubSeries;
|
|
227
|
+
y: SubSeries;
|
|
228
|
+
index?: number;
|
|
229
|
+
}
|
|
230
|
+
|