@trebco/treb 28.17.5 → 29.1.2
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/dist/treb-spreadsheet-light.mjs +12 -12
- package/dist/treb-spreadsheet.mjs +12 -12
- package/dist/treb.d.ts +121 -82
- package/eslint.config.js +21 -0
- package/package.json +6 -6
- package/treb-base-types/src/area.ts +4 -2
- package/treb-base-types/src/cell.ts +1 -1
- package/treb-base-types/src/cells.ts +16 -7
- package/treb-base-types/src/dom-utilities.ts +4 -2
- package/treb-base-types/src/import.ts +2 -2
- package/treb-base-types/src/rectangle.ts +5 -5
- package/treb-base-types/src/union.ts +6 -1
- package/treb-base-types/src/value-type.ts +1 -1
- package/treb-calculator/src/calculator.ts +114 -165
- package/treb-calculator/src/dag/calculation_leaf_vertex.ts +1 -2
- package/treb-calculator/src/dag/graph.ts +3 -3
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +2 -2
- package/treb-calculator/src/dag/state_leaf_vertex.ts +2 -4
- package/treb-calculator/src/descriptors.ts +28 -2
- package/treb-calculator/src/expression-calculator.ts +25 -34
- package/treb-calculator/src/function-error.ts +2 -2
- package/treb-calculator/src/function-library.ts +16 -0
- package/treb-calculator/src/functions/base-functions.ts +185 -211
- package/treb-calculator/src/functions/checkbox.ts +0 -1
- package/treb-calculator/src/functions/complex-functions.ts +49 -47
- package/treb-calculator/src/functions/finance-functions.ts +10 -10
- package/treb-calculator/src/functions/function-utilities.ts +26 -0
- package/treb-calculator/src/functions/information-functions.ts +21 -41
- package/treb-calculator/src/functions/matrix-functions.ts +8 -1
- package/treb-calculator/src/functions/sparkline.ts +6 -4
- package/treb-calculator/src/functions/statistics-functions.ts +21 -17
- package/treb-calculator/src/functions/text-functions.ts +14 -13
- package/treb-calculator/src/primitives.ts +48 -37
- package/treb-calculator/src/utilities.ts +117 -134
- package/treb-charts/src/chart-functions.ts +3 -3
- package/treb-charts/src/chart-types.ts +42 -1
- package/treb-charts/src/chart-utils.ts +155 -113
- package/treb-charts/src/chart.ts +6 -5
- package/treb-charts/src/default-chart-renderer.ts +6 -5
- package/treb-charts/src/renderer.ts +12 -11
- package/treb-charts/src/util.ts +25 -36
- package/treb-data-model/package.json +5 -0
- package/{treb-grid/src/types → treb-data-model/src}/annotation.ts +2 -2
- package/{treb-grid/src/types → treb-data-model/src}/conditional_format.ts +20 -0
- package/{treb-grid/src/types → treb-data-model/src}/data_model.ts +231 -133
- package/treb-data-model/src/index.ts +45 -0
- package/{treb-grid/src/types/named_range.ts → treb-data-model/src/named.ts} +459 -376
- package/{treb-grid/src/types → treb-data-model/src}/sheet.ts +13 -5
- package/treb-data-model/src/sheet_collection.ts +114 -0
- package/{treb-grid/src/types → treb-data-model/src}/sheet_types.ts +6 -3
- package/treb-embed/modern.tsconfig.json +1 -0
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +2 -2
- package/treb-embed/src/embedded-spreadsheet.ts +125 -270
- package/treb-embed/src/selection-state.ts +1 -1
- package/treb-embed/src/toolbar-message.ts +1 -1
- package/treb-embed/src/types.ts +13 -5
- package/treb-export/src/export-worker/export-worker.ts +22 -7
- package/treb-export/src/export2.ts +110 -41
- package/treb-export/src/import2.ts +6 -5
- package/treb-export/src/workbook2.ts +31 -13
- package/treb-export/src/xml-utils.ts +5 -1
- package/treb-format/src/format.ts +8 -6
- package/treb-grid/src/editors/autocomplete.ts +2 -2
- package/treb-grid/src/editors/autocomplete_matcher.ts +57 -19
- package/treb-grid/src/editors/editor.ts +27 -25
- package/treb-grid/src/editors/formula_bar.ts +5 -5
- package/treb-grid/src/editors/overlay_editor.ts +1 -2
- package/treb-grid/src/index.ts +0 -11
- package/treb-grid/src/layout/base_layout.ts +20 -8
- package/treb-grid/src/layout/grid_layout.ts +2 -2
- package/treb-grid/src/layout/mock-layout.ts +5 -6
- package/treb-grid/src/render/selection-renderer.ts +2 -3
- package/treb-grid/src/render/tile_renderer.ts +1 -1
- package/treb-grid/src/types/grid.ts +95 -66
- package/treb-grid/src/types/grid_base.ts +76 -60
- package/treb-grid/src/types/grid_command.ts +3 -2
- package/treb-grid/src/types/grid_events.ts +12 -6
- package/treb-grid/src/types/tab_bar.ts +1 -2
- package/treb-parser/src/parser-types.ts +2 -1
- package/treb-parser/src/parser.ts +7 -5
- package/treb-utils/src/event_source.ts +1 -1
- package/treb-utils/src/serialize_html.ts +31 -6
- package/.eslintignore +0 -8
- package/.eslintrc.cjs +0 -168
- package/treb-grid/src/layout/rectangle_cache.ts +0 -86
- /package/{treb-grid/src/types → treb-data-model/src}/serialize_options.ts +0 -0
- /package/{treb-grid/src/types/grid_selection.ts → treb-data-model/src/sheet_selection.ts} +0 -0
|
@@ -24,8 +24,7 @@ import type { Cell, ICellAddress, ICellAddress2, UnionValue, EvaluateOptions,
|
|
|
24
24
|
import { Localization, Area, ValueType, IsCellAddress} from 'treb-base-types';
|
|
25
25
|
|
|
26
26
|
import type { ExpressionUnit, DependencyList, UnitRange, UnitAddress, UnitIdentifier, ParseResult } from 'treb-parser';
|
|
27
|
-
import { Parser,
|
|
28
|
-
DecimalMarkType, ArgumentSeparatorType, QuotedSheetNameRegex } from 'treb-parser';
|
|
27
|
+
import { Parser, DecimalMarkType, QuotedSheetNameRegex } from 'treb-parser';
|
|
29
28
|
|
|
30
29
|
import { Graph } from './dag/graph';
|
|
31
30
|
import type { SpreadsheetVertex } from './dag/spreadsheet_vertex';
|
|
@@ -35,7 +34,7 @@ import { ExpressionCalculator, UnionIsMetadata } from './expression-calculator';
|
|
|
35
34
|
import * as Utilities from './utilities';
|
|
36
35
|
|
|
37
36
|
import { FunctionLibrary } from './function-library';
|
|
38
|
-
import type { FunctionMap} from './descriptors';
|
|
37
|
+
import type { FunctionMap } from './descriptors';
|
|
39
38
|
import { ReturnType } from './descriptors';
|
|
40
39
|
import { AltFunctionLibrary, BaseFunctionLibrary } from './functions/base-functions';
|
|
41
40
|
import { FinanceFunctionLibrary } from './functions/finance-functions';
|
|
@@ -49,13 +48,15 @@ import { Variance } from './functions/statistics-functions';
|
|
|
49
48
|
|
|
50
49
|
import * as Primitives from './primitives';
|
|
51
50
|
|
|
52
|
-
import type {
|
|
51
|
+
import type { FunctionDescriptor } from 'treb-grid';
|
|
53
52
|
import type { LeafVertex } from './dag/graph';
|
|
54
53
|
|
|
55
54
|
import { ArgumentError, ReferenceError, UnknownError, ValueError, ExpressionError, NAError, DivideByZeroError } from './function-error';
|
|
56
55
|
import { StateLeafVertex } from './dag/state_leaf_vertex';
|
|
57
56
|
import { CalculationLeafVertex } from './dag/calculation_leaf_vertex';
|
|
58
|
-
|
|
57
|
+
|
|
58
|
+
import { Sheet } from 'treb-data-model';
|
|
59
|
+
import type { Annotation, DataModel, ConnectedElementType, ConditionalFormat } from 'treb-data-model';
|
|
59
60
|
|
|
60
61
|
import { ValueParser } from 'treb-format';
|
|
61
62
|
|
|
@@ -162,10 +163,10 @@ const default_calculator_options: CalculatorOptions = {
|
|
|
162
163
|
*/
|
|
163
164
|
export class Calculator extends Graph {
|
|
164
165
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
/**
|
|
167
|
+
* localized parser instance. we're sharing.
|
|
168
|
+
* FIXME: remove local references so we can remove this accessor
|
|
169
|
+
*/
|
|
169
170
|
protected get parser(): Parser {
|
|
170
171
|
return this.model.parser;
|
|
171
172
|
}
|
|
@@ -174,19 +175,6 @@ export class Calculator extends Graph {
|
|
|
174
175
|
|
|
175
176
|
protected registered_libraries: Record<string, boolean> = {};
|
|
176
177
|
|
|
177
|
-
// protected notifier_id_source = 100;
|
|
178
|
-
// protected notifiers: InternalNotifierType[] = [];
|
|
179
|
-
|
|
180
|
-
// protected graph: Graph = new Graph(); // |null = null;
|
|
181
|
-
// protected status: GraphStatus = GraphStatus.OK;
|
|
182
|
-
|
|
183
|
-
/*
|
|
184
|
-
// FIXME: why is this a separate class? [actually is this a composition issue?]
|
|
185
|
-
protected expression_calculator = new ExpressionCalculator(
|
|
186
|
-
this.library,
|
|
187
|
-
this.parser);
|
|
188
|
-
*/
|
|
189
|
-
|
|
190
178
|
protected expression_calculator: ExpressionCalculator;
|
|
191
179
|
|
|
192
180
|
/** the next calculation must do a full rebuild -- set on reset */
|
|
@@ -255,7 +243,7 @@ export class Calculator extends Graph {
|
|
|
255
243
|
return result;
|
|
256
244
|
};
|
|
257
245
|
|
|
258
|
-
const CountIfInternal = (range:
|
|
246
|
+
const CountIfInternal = (range: CellValue[][], criteria: CellValue): UnionValue => {
|
|
259
247
|
|
|
260
248
|
// do we really need parser/calculator for this? I think
|
|
261
249
|
// we've maybe gone overboard here, could we just use valueparser
|
|
@@ -263,7 +251,7 @@ export class Calculator extends Graph {
|
|
|
263
251
|
// in any event there are no dynamic dependencies with this
|
|
264
252
|
// function.
|
|
265
253
|
|
|
266
|
-
const data = Utilities.
|
|
254
|
+
const data = Utilities.FlattenCellValues(range);
|
|
267
255
|
|
|
268
256
|
let parse_result: ParseResult|undefined;
|
|
269
257
|
let expression: ExpressionUnit|undefined;
|
|
@@ -318,7 +306,7 @@ export class Calculator extends Graph {
|
|
|
318
306
|
}
|
|
319
307
|
|
|
320
308
|
if (expression?.type === 'call' && expression.args[0]?.type === 'array') {
|
|
321
|
-
expression.args[0].values = [data];
|
|
309
|
+
expression.args[0].values = [Utilities.FilterIntrinsics(data)];
|
|
322
310
|
}
|
|
323
311
|
|
|
324
312
|
}
|
|
@@ -369,7 +357,7 @@ export class Calculator extends Graph {
|
|
|
369
357
|
}
|
|
370
358
|
}
|
|
371
359
|
|
|
372
|
-
expression.left.values = [data];
|
|
360
|
+
expression.left.values = [Utilities.FilterIntrinsics(data)];
|
|
373
361
|
|
|
374
362
|
}
|
|
375
363
|
|
|
@@ -410,7 +398,7 @@ export class Calculator extends Graph {
|
|
|
410
398
|
{ name: 'type' },
|
|
411
399
|
{ name: 'range', metadata: true, }
|
|
412
400
|
],
|
|
413
|
-
fn: (type: number|string, ...args:
|
|
401
|
+
fn: (type: number|string, ...args: UnionValue[]): UnionValue => {
|
|
414
402
|
|
|
415
403
|
type = TranslateSubtotalType(type);
|
|
416
404
|
|
|
@@ -447,7 +435,8 @@ export class Calculator extends Graph {
|
|
|
447
435
|
|
|
448
436
|
// where is the metadata type? sigh
|
|
449
437
|
|
|
450
|
-
const address = (entry.value?.address) as UnitAddress;
|
|
438
|
+
const address = ((entry.value as {address?: UnitAddress})?.address) as UnitAddress;
|
|
439
|
+
|
|
451
440
|
if (!address) {
|
|
452
441
|
return ReferenceError();
|
|
453
442
|
}
|
|
@@ -472,7 +461,7 @@ export class Calculator extends Graph {
|
|
|
472
461
|
continue;
|
|
473
462
|
}
|
|
474
463
|
|
|
475
|
-
const entry_value = entry.value?.value;
|
|
464
|
+
const entry_value = (entry.value as {value?: CellValue})?.value;
|
|
476
465
|
|
|
477
466
|
// counta includes empty strings
|
|
478
467
|
|
|
@@ -575,7 +564,7 @@ export class Calculator extends Graph {
|
|
|
575
564
|
|
|
576
565
|
let count = 0;
|
|
577
566
|
|
|
578
|
-
|
|
567
|
+
const result = CountIfInternal(args[0], args[1]);
|
|
579
568
|
if (result.type !== ValueType.array) {
|
|
580
569
|
return result; // error
|
|
581
570
|
}
|
|
@@ -753,7 +742,7 @@ export class Calculator extends Graph {
|
|
|
753
742
|
],
|
|
754
743
|
return_type: ReturnType.reference,
|
|
755
744
|
volatile: true, // necessary?
|
|
756
|
-
fn: ((reference: string) => {
|
|
745
|
+
fn: ((reference: string): UnionValue => {
|
|
757
746
|
|
|
758
747
|
if (!reference || (typeof reference !== 'string')) {
|
|
759
748
|
return ArgumentError();
|
|
@@ -780,7 +769,7 @@ export class Calculator extends Graph {
|
|
|
780
769
|
return { type: ValueType.undefined, value: undefined };
|
|
781
770
|
}
|
|
782
771
|
|
|
783
|
-
return { type: ValueType.object, value: parse_result.expression
|
|
772
|
+
return { type: ValueType.object, value: parse_result.expression };
|
|
784
773
|
|
|
785
774
|
}).bind(this),
|
|
786
775
|
|
|
@@ -960,13 +949,18 @@ export class Calculator extends Graph {
|
|
|
960
949
|
},
|
|
961
950
|
|
|
962
951
|
|
|
963
|
-
|
|
952
|
+
/**
|
|
953
|
+
* not sure when this one appeared, but it's what I was looking for
|
|
954
|
+
*
|
|
955
|
+
* ---
|
|
956
|
+
* what an odd comment. what does that mean?
|
|
957
|
+
*/
|
|
964
958
|
FormulaText: {
|
|
965
959
|
description: 'Returns a formula as a string',
|
|
966
960
|
arguments: [
|
|
967
|
-
{ name: 'reference', description: 'Cell reference', metadata: true, },
|
|
961
|
+
{ name: 'reference', description: 'Cell reference', metadata: true, unroll: true },
|
|
968
962
|
],
|
|
969
|
-
fn:
|
|
963
|
+
fn: (reference: UnionValue): UnionValue => {
|
|
970
964
|
|
|
971
965
|
if (!UnionIsMetadata(reference)) {
|
|
972
966
|
return ReferenceError();
|
|
@@ -983,7 +977,7 @@ export class Calculator extends Graph {
|
|
|
983
977
|
|
|
984
978
|
return ReferenceError();
|
|
985
979
|
|
|
986
|
-
}
|
|
980
|
+
},
|
|
987
981
|
},
|
|
988
982
|
|
|
989
983
|
/**
|
|
@@ -994,16 +988,19 @@ export class Calculator extends Graph {
|
|
|
994
988
|
description: 'Returns true if the reference is a formula',
|
|
995
989
|
arguments: [{
|
|
996
990
|
name: 'Reference',
|
|
991
|
+
unroll: true,
|
|
997
992
|
metadata: true, /* OK with array metadata */
|
|
998
993
|
}],
|
|
999
|
-
fn:
|
|
994
|
+
fn: (ref: UnionValue): UnionValue => {
|
|
1000
995
|
|
|
1001
996
|
// this is wasteful because we know that the range will all
|
|
1002
997
|
// be in the same sheet... we don't need to look up every time
|
|
1003
998
|
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
999
|
+
const addr = (ref?.value as {address?: UnitAddress})?.address;
|
|
1000
|
+
|
|
1001
|
+
const sheet = this.model.sheets.Find(addr?.sheet_id || 0);
|
|
1002
|
+
if (addr && sheet) {
|
|
1003
|
+
const cell = sheet.cells.GetCell(addr, false);
|
|
1007
1004
|
return {
|
|
1008
1005
|
type: ValueType.boolean,
|
|
1009
1006
|
value: cell?.type === ValueType.formula,
|
|
@@ -1014,7 +1011,7 @@ export class Calculator extends Graph {
|
|
|
1014
1011
|
type: ValueType.boolean, value: false,
|
|
1015
1012
|
};
|
|
1016
1013
|
|
|
1017
|
-
}
|
|
1014
|
+
},
|
|
1018
1015
|
},
|
|
1019
1016
|
|
|
1020
1017
|
});
|
|
@@ -1031,7 +1028,7 @@ export class Calculator extends Graph {
|
|
|
1031
1028
|
* values to followers.
|
|
1032
1029
|
*/
|
|
1033
1030
|
public ExportCalculatedValues(): Record<number, CellDataWithAddress[]> {
|
|
1034
|
-
const data:
|
|
1031
|
+
const data: Record<number, CellDataWithAddress[]> = {};
|
|
1035
1032
|
for (const sheet of this.model.sheets.list) {
|
|
1036
1033
|
const calculated = sheet.cells.toJSON({calculated_value: true}).data as CellDataWithAddress[];
|
|
1037
1034
|
data[sheet.id] = calculated.filter(test => test.calculated !== undefined);
|
|
@@ -1098,7 +1095,39 @@ export class Calculator extends Graph {
|
|
|
1098
1095
|
if (values[row]) {
|
|
1099
1096
|
let column = 0;
|
|
1100
1097
|
for (; column < columns && column < values[row].length; column++) {
|
|
1101
|
-
|
|
1098
|
+
|
|
1099
|
+
// if there's a nested array, take the first value. but
|
|
1100
|
+
// don't recurse; if there's another array in there set
|
|
1101
|
+
// as undefined (should be error?)
|
|
1102
|
+
|
|
1103
|
+
let indexed_value = values[row][column];
|
|
1104
|
+
if (indexed_value.type === ValueType.array) {
|
|
1105
|
+
indexed_value = indexed_value.value[0][0];
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
switch (indexed_value.type) {
|
|
1109
|
+
case ValueType.array:
|
|
1110
|
+
case ValueType.object:
|
|
1111
|
+
cells.data[row + area.start.row][column + area.start.column].SetCalculatedValue(undefined); // error?
|
|
1112
|
+
break;
|
|
1113
|
+
|
|
1114
|
+
default:
|
|
1115
|
+
cells.data[row + area.start.row][column + area.start.column].SetCalculatedValue(
|
|
1116
|
+
indexed_value.value, indexed_value.type);
|
|
1117
|
+
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/*
|
|
1121
|
+
if (indexed_value.type !== ValueType.object) {
|
|
1122
|
+
cells.data[row + area.start.row][column + area.start.column].SetCalculatedValue(
|
|
1123
|
+
indexed_value.value, indexed_value.type);
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
cells.data[row + area.start.row][column + area.start.column].SetCalculatedValue(
|
|
1127
|
+
values[row][column].value,
|
|
1128
|
+
values[row][column].type);
|
|
1129
|
+
*/
|
|
1130
|
+
|
|
1102
1131
|
}
|
|
1103
1132
|
for (; column < columns; column++) {
|
|
1104
1133
|
cells.data[row + area.start.row][column + area.start.column].SetCalculatedValue(undefined, ValueType.undefined);
|
|
@@ -1116,9 +1145,15 @@ export class Calculator extends Graph {
|
|
|
1116
1145
|
|
|
1117
1146
|
// single, recycle
|
|
1118
1147
|
|
|
1148
|
+
let applied: UnionValue = { ...value };
|
|
1149
|
+
|
|
1150
|
+
if (applied.type === ValueType.object) {
|
|
1151
|
+
applied = { type: ValueType.undefined, value: undefined };
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1119
1154
|
for (let row = 0; row < rows; row++) {
|
|
1120
1155
|
for (let column = 0; column < columns; column++) {
|
|
1121
|
-
cells.data[row + area.start.row][column + area.start.column].SetCalculatedValue(
|
|
1156
|
+
cells.data[row + area.start.row][column + area.start.column].SetCalculatedValue(applied.value, applied.type);
|
|
1122
1157
|
}
|
|
1123
1158
|
}
|
|
1124
1159
|
|
|
@@ -1343,7 +1378,7 @@ export class Calculator extends Graph {
|
|
|
1343
1378
|
|
|
1344
1379
|
const list = this.library.List();
|
|
1345
1380
|
|
|
1346
|
-
const function_list = Object.keys(list).map((key) => {
|
|
1381
|
+
const function_list: FunctionDescriptor[] = Object.keys(list).map((key) => {
|
|
1347
1382
|
let name = list[key].canonical_name;
|
|
1348
1383
|
if (!name) name = key.replace(/_/g, '.');
|
|
1349
1384
|
return {
|
|
@@ -1352,6 +1387,7 @@ export class Calculator extends Graph {
|
|
|
1352
1387
|
arguments: (list[key].arguments || []).map((argument) => {
|
|
1353
1388
|
return { name: argument.name || '' };
|
|
1354
1389
|
}),
|
|
1390
|
+
type: 'function', // DescriptorType.Function,
|
|
1355
1391
|
};
|
|
1356
1392
|
});
|
|
1357
1393
|
|
|
@@ -1362,6 +1398,7 @@ export class Calculator extends Graph {
|
|
|
1362
1398
|
arguments: (macro.argument_names || []).map(argument => {
|
|
1363
1399
|
return { name: argument };
|
|
1364
1400
|
}),
|
|
1401
|
+
type: 'function', // DescriptorType.Function,
|
|
1365
1402
|
});
|
|
1366
1403
|
}
|
|
1367
1404
|
|
|
@@ -1402,9 +1439,10 @@ export class Calculator extends Graph {
|
|
|
1402
1439
|
public RegisterFunction(map: FunctionMap): void {
|
|
1403
1440
|
|
|
1404
1441
|
for (const name of Object.keys(map)) {
|
|
1442
|
+
|
|
1405
1443
|
const descriptor = map[name];
|
|
1406
1444
|
const original_function = descriptor.fn;
|
|
1407
|
-
|
|
1445
|
+
|
|
1408
1446
|
// we don't bind to the actual context because that would allow
|
|
1409
1447
|
// functions to change it, and potentially break subsequent functions
|
|
1410
1448
|
// that rely on it. which is a pretty far-fetched scenario, but we might
|
|
@@ -1886,7 +1924,7 @@ export class Calculator extends Graph {
|
|
|
1886
1924
|
const area = IsCellAddress(ref) ? new Area(ref) : new Area(ref.start, ref.end);
|
|
1887
1925
|
|
|
1888
1926
|
if (named) {
|
|
1889
|
-
const named_range = this.model.
|
|
1927
|
+
const named_range = this.model.named.MatchSelection(area);
|
|
1890
1928
|
if (named_range) {
|
|
1891
1929
|
return named_range;
|
|
1892
1930
|
}
|
|
@@ -1938,7 +1976,7 @@ export class Calculator extends Graph {
|
|
|
1938
1976
|
}
|
|
1939
1977
|
|
|
1940
1978
|
public RemoveConnectedELement(element: ConnectedElementType) {
|
|
1941
|
-
|
|
1979
|
+
const internal = element.internal as { vertex: StateLeafVertex };
|
|
1942
1980
|
if (internal?.vertex) {
|
|
1943
1981
|
this.RemoveLeafVertex(internal.vertex);
|
|
1944
1982
|
return true;
|
|
@@ -1959,7 +1997,7 @@ export class Calculator extends Graph {
|
|
|
1959
1997
|
}
|
|
1960
1998
|
|
|
1961
1999
|
if (element) {
|
|
1962
|
-
|
|
2000
|
+
const internal = element.internal as { vertex: StateLeafVertex };
|
|
1963
2001
|
if (internal?.vertex) {
|
|
1964
2002
|
this.RemoveLeafVertex(internal.vertex);
|
|
1965
2003
|
}
|
|
@@ -2094,10 +2132,11 @@ export class Calculator extends Graph {
|
|
|
2094
2132
|
}
|
|
2095
2133
|
|
|
2096
2134
|
public RemoveAnnotation(annotation: Annotation): void {
|
|
2097
|
-
const
|
|
2098
|
-
if (
|
|
2099
|
-
|
|
2100
|
-
|
|
2135
|
+
const vertex_data = annotation.temp as { vertex?: LeafVertex };
|
|
2136
|
+
if (vertex_data.vertex) {
|
|
2137
|
+
vertex_data.vertex.Reset();
|
|
2138
|
+
this.RemoveLeafVertex(vertex_data.vertex);
|
|
2139
|
+
}
|
|
2101
2140
|
}
|
|
2102
2141
|
|
|
2103
2142
|
public UpdateAnnotations(list?: Annotation|Annotation[], context?: Sheet): void {
|
|
@@ -2126,12 +2165,15 @@ export class Calculator extends Graph {
|
|
|
2126
2165
|
|
|
2127
2166
|
for (const entry of list) {
|
|
2128
2167
|
if (entry.data.formula) {
|
|
2129
|
-
|
|
2130
|
-
|
|
2168
|
+
|
|
2169
|
+
const vertex_data = entry.temp as { vertex?: LeafVertex };
|
|
2170
|
+
|
|
2171
|
+
if (!vertex_data.vertex) {
|
|
2172
|
+
vertex_data.vertex = new StateLeafVertex();
|
|
2131
2173
|
}
|
|
2132
|
-
|
|
2133
|
-
this.AddLeafVertex(vertex);
|
|
2134
|
-
this.UpdateLeafVertex(vertex, entry.data.formula, context);
|
|
2174
|
+
|
|
2175
|
+
this.AddLeafVertex(vertex_data.vertex);
|
|
2176
|
+
this.UpdateLeafVertex(vertex_data.vertex, entry.data.formula, context);
|
|
2135
2177
|
}
|
|
2136
2178
|
}
|
|
2137
2179
|
|
|
@@ -2162,9 +2204,9 @@ export class Calculator extends Graph {
|
|
|
2162
2204
|
case 'identifier':
|
|
2163
2205
|
{
|
|
2164
2206
|
const named_range =
|
|
2165
|
-
this.model.
|
|
2166
|
-
if (named_range) {
|
|
2167
|
-
return new Area(named_range.start, named_range.end);
|
|
2207
|
+
this.model.GetName(expr.name, context?.sheet_id || 0);
|
|
2208
|
+
if (named_range && named_range.type === 'range') {
|
|
2209
|
+
return new Area(named_range.area.start, named_range.area.end);
|
|
2168
2210
|
}
|
|
2169
2211
|
}
|
|
2170
2212
|
break;
|
|
@@ -2174,19 +2216,19 @@ export class Calculator extends Graph {
|
|
|
2174
2216
|
|
|
2175
2217
|
}
|
|
2176
2218
|
|
|
2177
|
-
protected NamedRangeToAddressUnit(unit: UnitIdentifier): UnitAddress|UnitRange|undefined {
|
|
2219
|
+
protected NamedRangeToAddressUnit(unit: UnitIdentifier, context: ICellAddress): UnitAddress|UnitRange|undefined {
|
|
2178
2220
|
|
|
2179
2221
|
const normalized = unit.name.toUpperCase();
|
|
2180
|
-
const named_range = this.model.
|
|
2181
|
-
if (named_range) {
|
|
2182
|
-
if (named_range.count === 1) {
|
|
2183
|
-
return this.ConstructAddressUnit(named_range.start, normalized, unit.id, unit.position);
|
|
2222
|
+
const named_range = this.model.GetName(normalized, context.sheet_id || 0);
|
|
2223
|
+
if (named_range && named_range.type === 'range') {
|
|
2224
|
+
if (named_range.area.count === 1) {
|
|
2225
|
+
return this.ConstructAddressUnit(named_range.area.start, normalized, unit.id, unit.position);
|
|
2184
2226
|
}
|
|
2185
2227
|
else {
|
|
2186
2228
|
return {
|
|
2187
2229
|
type: 'range',
|
|
2188
|
-
start: this.ConstructAddressUnit(named_range.start, normalized, unit.id, unit.position),
|
|
2189
|
-
end: this.ConstructAddressUnit(named_range.end, normalized, unit.id, unit.position),
|
|
2230
|
+
start: this.ConstructAddressUnit(named_range.area.start, normalized, unit.id, unit.position),
|
|
2231
|
+
end: this.ConstructAddressUnit(named_range.area.end, normalized, unit.id, unit.position),
|
|
2190
2232
|
label: normalized,
|
|
2191
2233
|
id: unit.id,
|
|
2192
2234
|
position: unit.position,
|
|
@@ -2251,16 +2293,13 @@ export class Calculator extends Graph {
|
|
|
2251
2293
|
// update to handle named expressions. just descend into
|
|
2252
2294
|
// the expression as if it were inline.
|
|
2253
2295
|
|
|
2254
|
-
const
|
|
2296
|
+
const fetched = this.model.GetName(unit.name, context_address.sheet_id || 0);
|
|
2255
2297
|
|
|
2256
|
-
if (
|
|
2257
|
-
|
|
2258
|
-
if (expr) {
|
|
2259
|
-
this.RebuildDependencies(expr, relative_sheet_id, relative_sheet_name, dependencies, context_address);
|
|
2260
|
-
}
|
|
2298
|
+
if (fetched?.type === 'expression') {
|
|
2299
|
+
this.RebuildDependencies(fetched.expression, relative_sheet_id, relative_sheet_name, dependencies, context_address);
|
|
2261
2300
|
}
|
|
2262
2301
|
else {
|
|
2263
|
-
const resolved = this.NamedRangeToAddressUnit(unit);
|
|
2302
|
+
const resolved = this.NamedRangeToAddressUnit(unit, context_address);
|
|
2264
2303
|
if (resolved) {
|
|
2265
2304
|
if (resolved.type === 'address') {
|
|
2266
2305
|
dependencies.addresses[resolved.label] = resolved;
|
|
@@ -2506,96 +2545,6 @@ export class Calculator extends Graph {
|
|
|
2506
2545
|
|
|
2507
2546
|
}
|
|
2508
2547
|
|
|
2509
|
-
/* *
|
|
2510
|
-
* we're passing model here to skip the test on each call
|
|
2511
|
-
*
|
|
2512
|
-
* @param unit
|
|
2513
|
-
* @param model
|
|
2514
|
-
* /
|
|
2515
|
-
protected ApplyMacroFunctionInternal(
|
|
2516
|
-
unit: ExpressionUnit,
|
|
2517
|
-
model: DataModel,
|
|
2518
|
-
name_stack: Array<{[index: string]: ExpressionUnit}>,
|
|
2519
|
-
): ExpressionUnit {
|
|
2520
|
-
|
|
2521
|
-
switch (unit.type) {
|
|
2522
|
-
|
|
2523
|
-
case 'identifier':
|
|
2524
|
-
if (name_stack[0]) {
|
|
2525
|
-
const value = name_stack[0][(unit.name || '').toUpperCase()];
|
|
2526
|
-
if (value) {
|
|
2527
|
-
return JSON.parse(JSON.stringify(value)) as ExpressionUnit;
|
|
2528
|
-
}
|
|
2529
|
-
}
|
|
2530
|
-
break;
|
|
2531
|
-
|
|
2532
|
-
case 'binary':
|
|
2533
|
-
unit.left = this.ApplyMacroFunctionInternal(unit.left, model, name_stack);
|
|
2534
|
-
unit.right = this.ApplyMacroFunctionInternal(unit.right, model, name_stack);
|
|
2535
|
-
break;
|
|
2536
|
-
|
|
2537
|
-
case 'unary':
|
|
2538
|
-
unit.operand = this.ApplyMacroFunctionInternal(unit.operand, model, name_stack);
|
|
2539
|
-
break;
|
|
2540
|
-
|
|
2541
|
-
case 'group':
|
|
2542
|
-
unit.elements = unit.elements.map(element => this.ApplyMacroFunctionInternal(element, model, name_stack));
|
|
2543
|
-
break;
|
|
2544
|
-
|
|
2545
|
-
case 'call':
|
|
2546
|
-
{
|
|
2547
|
-
// do this first, so we can pass through directly
|
|
2548
|
-
unit.args = unit.args.map(arg => this.ApplyMacroFunctionInternal(arg, model, name_stack));
|
|
2549
|
-
|
|
2550
|
-
const func = this.library.Get(unit.name);
|
|
2551
|
-
if (!func) {
|
|
2552
|
-
const macro = model.macro_functions[unit.name.toUpperCase()];
|
|
2553
|
-
if (macro && macro.expression) {
|
|
2554
|
-
|
|
2555
|
-
// clone
|
|
2556
|
-
const expression = JSON.parse(JSON.stringify(macro.expression));
|
|
2557
|
-
|
|
2558
|
-
const bound_names: {[index: string]: ExpressionUnit} = {};
|
|
2559
|
-
|
|
2560
|
-
if (macro.argument_names) {
|
|
2561
|
-
for (let i = 0; i < macro.argument_names.length; i++) {
|
|
2562
|
-
const name = macro.argument_names[i].toUpperCase();
|
|
2563
|
-
|
|
2564
|
-
// temp just pass in
|
|
2565
|
-
bound_names[name] = unit.args[i] ? unit.args[i] : {type: 'missing'} as UnitMissing;
|
|
2566
|
-
}
|
|
2567
|
-
}
|
|
2568
|
-
|
|
2569
|
-
// replace arguments
|
|
2570
|
-
name_stack.unshift(bound_names);
|
|
2571
|
-
const replacement = this.ApplyMacroFunctionInternal(expression, model, name_stack);
|
|
2572
|
-
name_stack.shift();
|
|
2573
|
-
return replacement;
|
|
2574
|
-
|
|
2575
|
-
}
|
|
2576
|
-
}
|
|
2577
|
-
}
|
|
2578
|
-
|
|
2579
|
-
break;
|
|
2580
|
-
|
|
2581
|
-
}
|
|
2582
|
-
|
|
2583
|
-
return unit;
|
|
2584
|
-
|
|
2585
|
-
}
|
|
2586
|
-
|
|
2587
|
-
protected ApplyMacroFunctions(expression: ExpressionUnit): ExpressionUnit|undefined {
|
|
2588
|
-
|
|
2589
|
-
if (!this.model) { return; }
|
|
2590
|
-
|
|
2591
|
-
const count = Object.keys(this.model.macro_functions).length;
|
|
2592
|
-
if (!count) { return; }
|
|
2593
|
-
|
|
2594
|
-
return this.ApplyMacroFunctionInternal(expression, this.model, []);
|
|
2595
|
-
|
|
2596
|
-
}
|
|
2597
|
-
*/
|
|
2598
|
-
|
|
2599
2548
|
/**
|
|
2600
2549
|
*
|
|
2601
2550
|
*/
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
|
|
22
22
|
import type { GraphCallbacks } from './spreadsheet_vertex_base';
|
|
23
23
|
import { SpreadsheetVertex } from './spreadsheet_vertex';
|
|
24
|
-
import type { Vertex} from './vertex';
|
|
25
24
|
import { Color } from './vertex';
|
|
26
25
|
|
|
27
26
|
/**
|
|
@@ -97,7 +96,7 @@ export class CalculationLeafVertex extends SpreadsheetVertex {
|
|
|
97
96
|
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
public AddDependent(
|
|
99
|
+
public AddDependent(): void {
|
|
101
100
|
throw(new Error('leaf vertex cannot have dependents'));
|
|
102
101
|
}
|
|
103
102
|
|
|
@@ -27,7 +27,7 @@ import type { SpreadsheetVertexBase, CalculationResult, GraphCallbacks } from '.
|
|
|
27
27
|
import type { StateLeafVertex } from './state_leaf_vertex';
|
|
28
28
|
import type { ICellAddress, ICellAddress2, IArea, UnionValue } from 'treb-base-types';
|
|
29
29
|
import { Area } from 'treb-base-types';
|
|
30
|
-
import type { DataModel } from 'treb-
|
|
30
|
+
import type { DataModel } from 'treb-data-model';
|
|
31
31
|
import { CalculationLeafVertex } from './calculation_leaf_vertex';
|
|
32
32
|
|
|
33
33
|
export type LeafVertex = StateLeafVertex|CalculationLeafVertex;
|
|
@@ -696,7 +696,7 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
696
696
|
}
|
|
697
697
|
|
|
698
698
|
/** adds an edge from u -> v */
|
|
699
|
-
public AddEdge(u: ICellAddress, v: ICellAddress, tag?: string): void {
|
|
699
|
+
public AddEdge(u: ICellAddress, v: ICellAddress, /* tag?: string */ ): void {
|
|
700
700
|
|
|
701
701
|
const v_u = this.GetVertex(u, true);
|
|
702
702
|
const v_v = this.GetVertex(v, true);
|
|
@@ -732,7 +732,7 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
732
732
|
...u,
|
|
733
733
|
row: v_u.reference.area.start.row,
|
|
734
734
|
column: v_u.reference.area.start.column,
|
|
735
|
-
}, v, 'implicit');
|
|
735
|
+
}, v); // , 'implicit');
|
|
736
736
|
}
|
|
737
737
|
|
|
738
738
|
this.loop_check_required = true; // because new edges
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
import type { GraphCallbacks } from './spreadsheet_vertex_base';
|
|
23
23
|
import { SpreadsheetVertexBase } from './spreadsheet_vertex_base';
|
|
24
|
-
import type { Cell, ICellAddress, UnionValue } from 'treb-base-types';
|
|
24
|
+
import type { Cell, CellValue, ICellAddress, UnionValue } from 'treb-base-types';
|
|
25
25
|
import { Box, ValueType } from 'treb-base-types';
|
|
26
26
|
import type { ExpressionUnit } from 'treb-parser';
|
|
27
27
|
import { Color } from './vertex';
|
|
@@ -237,7 +237,7 @@ export class SpreadsheetVertex extends SpreadsheetVertexBase {
|
|
|
237
237
|
// whitelist types. or blacklist types. or something.
|
|
238
238
|
|
|
239
239
|
{
|
|
240
|
-
this.reference.SetCalculatedValue(single.value as
|
|
240
|
+
this.reference.SetCalculatedValue(single.value as CellValue, single.type);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
/*
|
|
@@ -19,9 +19,7 @@
|
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import type { GraphCallbacks } from './spreadsheet_vertex_base';
|
|
23
22
|
import { SpreadsheetVertex } from './spreadsheet_vertex';
|
|
24
|
-
import type { Vertex} from './vertex';
|
|
25
23
|
import { Color } from './vertex';
|
|
26
24
|
|
|
27
25
|
/**
|
|
@@ -93,7 +91,7 @@ export class StateLeafVertex extends SpreadsheetVertex {
|
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
/** overrides calculate function */
|
|
96
|
-
public Calculate(
|
|
94
|
+
public Calculate(): void {
|
|
97
95
|
|
|
98
96
|
// if we are not dirty, nothing to do
|
|
99
97
|
if (!this.dirty) return;
|
|
@@ -112,7 +110,7 @@ export class StateLeafVertex extends SpreadsheetVertex {
|
|
|
112
110
|
// we are not allowed to have edges out, so nothing to do
|
|
113
111
|
}
|
|
114
112
|
|
|
115
|
-
public AddDependent(
|
|
113
|
+
public AddDependent(): void {
|
|
116
114
|
throw(new Error('leaf vertex cannot have dependents'));
|
|
117
115
|
}
|
|
118
116
|
|