@trebco/treb 29.8.4 → 30.1.0
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 +11 -11
- package/dist/treb-spreadsheet.mjs +15 -15
- package/dist/treb.d.ts +11 -1
- package/eslint.config.js +9 -0
- package/package.json +1 -1
- package/treb-base-types/src/area-utils.ts +60 -0
- package/treb-base-types/src/area.ts +11 -0
- package/treb-base-types/src/cell.ts +6 -1
- package/treb-base-types/src/cells.ts +38 -7
- package/treb-base-types/src/index.ts +2 -0
- package/treb-calculator/src/calculator.ts +274 -4
- package/treb-calculator/src/dag/array-vertex.ts +0 -10
- package/treb-calculator/src/dag/graph.ts +118 -77
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +38 -9
- package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +1 -0
- package/treb-calculator/src/expression-calculator.ts +7 -2
- package/treb-calculator/src/function-error.ts +6 -0
- package/treb-charts/src/chart-functions.ts +39 -5
- package/treb-charts/src/chart-types.ts +23 -0
- package/treb-charts/src/chart-utils.ts +165 -2
- package/treb-charts/src/chart.ts +6 -1
- package/treb-charts/src/default-chart-renderer.ts +70 -1
- package/treb-charts/src/index.ts +1 -0
- package/treb-charts/src/renderer.ts +95 -2
- package/treb-charts/style/charts.scss +41 -0
- package/treb-embed/src/embedded-spreadsheet.ts +11 -4
- package/treb-embed/src/options.ts +8 -0
- package/treb-embed/style/dark-theme.scss +4 -0
- package/treb-embed/style/grid.scss +15 -0
- package/treb-embed/style/z-index.scss +3 -0
- package/treb-export/src/import2.ts +9 -0
- package/treb-export/src/workbook2.ts +67 -3
- package/treb-grid/src/editors/editor.ts +12 -5
- package/treb-grid/src/layout/base_layout.ts +41 -0
- package/treb-grid/src/types/grid.ts +61 -25
- package/treb-parser/src/parser-types.ts +3 -0
- package/treb-parser/src/parser.ts +21 -2
- package/treb-utils/src/serialize_html.ts +35 -10
|
@@ -30,6 +30,8 @@ import { Area } from 'treb-base-types';
|
|
|
30
30
|
import type { DataModel } from 'treb-data-model';
|
|
31
31
|
import { CalculationLeafVertex } from './calculation_leaf_vertex';
|
|
32
32
|
|
|
33
|
+
import { AreaUtils } from 'treb-base-types';
|
|
34
|
+
|
|
33
35
|
export type LeafVertex = StateLeafVertex|CalculationLeafVertex;
|
|
34
36
|
export type { StateLeafVertex };
|
|
35
37
|
|
|
@@ -55,6 +57,10 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
55
57
|
|
|
56
58
|
public calculation_list: SpreadsheetVertexBase[] = [];
|
|
57
59
|
|
|
60
|
+
// list of spills we have created
|
|
61
|
+
// public spills: IArea[] = [];
|
|
62
|
+
public spill_data: { area: IArea, vertex: StateLeafVertex }[] = [];
|
|
63
|
+
|
|
58
64
|
// public cells_map: {[index: number]: Cells} = {};
|
|
59
65
|
|
|
60
66
|
protected abstract readonly model: DataModel;
|
|
@@ -110,6 +116,9 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
110
116
|
this.leaf_vertices.clear();
|
|
111
117
|
// this.cells_map = {};
|
|
112
118
|
|
|
119
|
+
// can we flush spills here without cleaning up? (...)
|
|
120
|
+
// this.spills = [];
|
|
121
|
+
|
|
113
122
|
/** array vertex maintains its own list */
|
|
114
123
|
ArrayVertex.Clear();
|
|
115
124
|
|
|
@@ -142,6 +151,24 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
142
151
|
|
|
143
152
|
}
|
|
144
153
|
|
|
154
|
+
/**
|
|
155
|
+
* iterate vertices
|
|
156
|
+
* @param area
|
|
157
|
+
*/
|
|
158
|
+
public *IterateVertices(area: IArea, create = false): Generator<SpreadsheetVertex> {
|
|
159
|
+
|
|
160
|
+
// this is wasteful because it repeatedly gets the cells, but
|
|
161
|
+
// for a contiguous area we know they're in the same sheet. we
|
|
162
|
+
// cal also skip the repeated tests. FIXME
|
|
163
|
+
|
|
164
|
+
for (const address of AreaUtils.Iterate(area)) {
|
|
165
|
+
const vertex = this.GetVertex(address, create);
|
|
166
|
+
if (vertex) {
|
|
167
|
+
yield vertex;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
145
172
|
/** overload */
|
|
146
173
|
public GetVertex(address: ICellAddress, create: true): SpreadsheetVertex;
|
|
147
174
|
|
|
@@ -717,77 +744,6 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
717
744
|
|
|
718
745
|
this.CompositeAddArrayEdge(u, v_v);
|
|
719
746
|
|
|
720
|
-
/*
|
|
721
|
-
// create or use existing
|
|
722
|
-
const [array_vertex, created] = ArrayVertex.GetVertex(u);
|
|
723
|
-
|
|
724
|
-
// add an edge
|
|
725
|
-
v_v.DependsOn(array_vertex);
|
|
726
|
-
|
|
727
|
-
// force a check on next calculation pass
|
|
728
|
-
this.loop_check_required = true;
|
|
729
|
-
|
|
730
|
-
if (!created) {
|
|
731
|
-
// console.info('reusing, so not adding edges');
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
// now add edges from/to nodes THAT ALREADY EXIST
|
|
736
|
-
|
|
737
|
-
// range can't span sheets, so we only need one set to look up
|
|
738
|
-
|
|
739
|
-
const map = this.vertices[u.start.sheet_id];
|
|
740
|
-
|
|
741
|
-
// this might happen on create, we can let it go because the
|
|
742
|
-
// references will be added when the relevant sheet is added
|
|
743
|
-
|
|
744
|
-
if (!map) {
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
// ...
|
|
749
|
-
|
|
750
|
-
if (u.entire_row) {
|
|
751
|
-
// console.group('entire row(s)')
|
|
752
|
-
for (let column = 0; column < map.length; column++) {
|
|
753
|
-
if (map[column]) {
|
|
754
|
-
for (let row = u.start.row; row <= u.end.row; row++ ) {
|
|
755
|
-
const vertex = map[column][row];
|
|
756
|
-
if (vertex) {
|
|
757
|
-
// console.info('add', column, row);
|
|
758
|
-
array_vertex.DependsOn(vertex);
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
// console.groupEnd();
|
|
764
|
-
}
|
|
765
|
-
else if (u.entire_column) {
|
|
766
|
-
// console.group('entire column(s)');
|
|
767
|
-
for (let column = u.start.column; column <= u.end.column; column++) {
|
|
768
|
-
if(map[column]) {
|
|
769
|
-
for (const vertex of map[column]) {
|
|
770
|
-
if (vertex?.address) {
|
|
771
|
-
// console.info('add', vertex.address);
|
|
772
|
-
array_vertex.DependsOn(vertex);
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
// console.groupEnd();
|
|
778
|
-
}
|
|
779
|
-
else {
|
|
780
|
-
for (let row = u.start.row; row <= u.end.row; row++) {
|
|
781
|
-
for (let column = u.start.column; column <= u.end.column; column++) {
|
|
782
|
-
const vertex = map[column][row];
|
|
783
|
-
if (vertex) {
|
|
784
|
-
array_vertex.DependsOn(vertex);
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
*/
|
|
790
|
-
|
|
791
747
|
}
|
|
792
748
|
|
|
793
749
|
/** adds an edge from u -> v */
|
|
@@ -997,16 +953,101 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
997
953
|
// vertex.SetDirty();
|
|
998
954
|
// }
|
|
999
955
|
|
|
1000
|
-
//
|
|
1001
|
-
|
|
1002
|
-
// we do this using the local function so we can trace back arrays
|
|
956
|
+
// we do this using the local function so we can trace back arrays.
|
|
957
|
+
// be sure to do this _before_ checking spills
|
|
1003
958
|
|
|
1004
959
|
for (const vertex of this.volatile_list) {
|
|
1005
960
|
this.SetVertexDirty(vertex as SpreadsheetVertex);
|
|
1006
961
|
}
|
|
1007
|
-
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
////////////////////////////////////////
|
|
965
|
+
|
|
966
|
+
// (moving this up so it comes before we slice the dirty list)
|
|
967
|
+
|
|
968
|
+
// the problem with flushing all the spills here
|
|
969
|
+
// is that if we're not calculating a range that
|
|
970
|
+
// intersects with the spill, it will disappear.
|
|
971
|
+
// options are (1) to dirty the spill root, so it
|
|
972
|
+
// calculates, or (2) to check for intersection.
|
|
973
|
+
|
|
974
|
+
// checking for intersection might work because
|
|
975
|
+
// we should have vertices and they should be marked
|
|
976
|
+
// as dirty...
|
|
977
|
+
|
|
978
|
+
// eh that's not going to work, because edges point
|
|
979
|
+
// the wrong way. if you edit a cell within a spill
|
|
980
|
+
// range, it won't dirty the spill source because
|
|
981
|
+
// the edge goes from spill source -> spill cell.
|
|
982
|
+
|
|
983
|
+
// we could create a special leaf vertex to watch the
|
|
984
|
+
// range. or we could just check here. vertices is
|
|
985
|
+
// more elegant (and more memory), this is clumsier (and
|
|
986
|
+
// more calc).
|
|
987
|
+
|
|
988
|
+
this.spill_data = this.spill_data.filter(({area, vertex}) => {
|
|
989
|
+
if (vertex.dirty) {
|
|
990
|
+
vertex.Reset();
|
|
991
|
+
const cells = area.start.sheet_id ? this.model.sheets.Find(area.start.sheet_id)?.cells : undefined;
|
|
992
|
+
if (cells) {
|
|
993
|
+
for (const {cell, row, column} of cells.IterateRC(new Area(area.start, area.end))) {
|
|
994
|
+
if (cell.spill) {
|
|
995
|
+
cell.spill = undefined;
|
|
996
|
+
if (typeof cell.value === 'undefined') {
|
|
997
|
+
cell.Reset();
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// this is necessary for non-head cells in case the cell has deps
|
|
1002
|
+
this.SetDirty({row, column, sheet_id: area.start.sheet_id});
|
|
1003
|
+
|
|
1004
|
+
}
|
|
1005
|
+
// this.SetDirty(area.start);
|
|
1006
|
+
}
|
|
1007
|
+
return false; // drop
|
|
1008
|
+
}
|
|
1009
|
+
return true; // keep
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
/*
|
|
1013
|
+
this.spills = this.spills.filter(spill => {
|
|
1014
|
+
let dirty = false;
|
|
1015
|
+
for (const vertex of this.IterateVertices(spill)) {
|
|
1016
|
+
if (vertex.dirty) {
|
|
1017
|
+
console.info("spill is dirty (it)");
|
|
1018
|
+
dirty = true;
|
|
1019
|
+
break;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
if (dirty) {
|
|
1024
|
+
const cells = spill.start.sheet_id ? this.model.sheets.Find(spill.start.sheet_id)?.cells : undefined;
|
|
1025
|
+
if (cells) {
|
|
1026
|
+
for (const {cell, row, column} of cells.IterateRC(new Area(spill.start, spill.end))) {
|
|
1027
|
+
if (cell.spill) {
|
|
1028
|
+
cell.spill = undefined;
|
|
1029
|
+
if (typeof cell.value === 'undefined') {
|
|
1030
|
+
cell.Reset();
|
|
1031
|
+
}
|
|
1032
|
+
else {
|
|
1033
|
+
this.SetDirty({row, column, sheet_id: spill.start.sheet_id})
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
return false; // drop
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
return true; // keep
|
|
1042
|
+
});
|
|
1043
|
+
*/
|
|
1044
|
+
|
|
1045
|
+
//////////////////////////////////////////
|
|
1046
|
+
|
|
1008
1047
|
this.calculation_list = this.dirty_list.slice(0);
|
|
1009
1048
|
|
|
1049
|
+
// console.info("CL", this.calculation_list);
|
|
1050
|
+
|
|
1010
1051
|
this.volatile_list = [];
|
|
1011
1052
|
this.dirty_list = [];
|
|
1012
1053
|
|
|
@@ -1018,6 +1059,7 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
1018
1059
|
|
|
1019
1060
|
}
|
|
1020
1061
|
|
|
1062
|
+
|
|
1021
1063
|
// console.info("CL", calculation_list)
|
|
1022
1064
|
|
|
1023
1065
|
// recalculate everything that's dirty. FIXME: optimize path
|
|
@@ -1036,9 +1078,8 @@ export abstract class Graph implements GraphCallbacks {
|
|
|
1036
1078
|
}
|
|
1037
1079
|
|
|
1038
1080
|
public abstract CalculationCallback(vertex: SpreadsheetVertexBase): CalculationResult;
|
|
1039
|
-
|
|
1040
1081
|
public abstract SpreadCallback(vertex: SpreadsheetVertexBase, value: UnionValue): void;
|
|
1041
|
-
|
|
1082
|
+
public abstract SpillCallback(vertex: SpreadsheetVertexBase, value: UnionValue): void;
|
|
1042
1083
|
protected abstract CheckVolatile(vertex: SpreadsheetVertex): boolean;
|
|
1043
1084
|
|
|
1044
1085
|
}
|
|
@@ -219,20 +219,49 @@ export class SpreadsheetVertex extends SpreadsheetVertexBase {
|
|
|
219
219
|
}
|
|
220
220
|
else if (this.reference.type === ValueType.formula) {
|
|
221
221
|
|
|
222
|
-
//
|
|
222
|
+
// adding check for spill, not withstanding the below
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
// function of our new polynomial methods, BUT, we should probably
|
|
226
|
-
// handle it properly regardless.
|
|
224
|
+
if (this.result.type === ValueType.array) {
|
|
227
225
|
|
|
228
|
-
|
|
226
|
+
// note array of length 1 should not trigger spill behavior
|
|
227
|
+
// (moved to callback method)
|
|
229
228
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
229
|
+
const recalc = graph.SpillCallback.call(graph, this, this.result);
|
|
230
|
+
if (recalc) {
|
|
231
|
+
// console.info("RC", recalc);
|
|
232
|
+
for (const entry of (recalc as SpreadsheetVertex[])) {
|
|
233
233
|
|
|
234
|
-
|
|
234
|
+
// will this work properly with loops? (...)
|
|
235
235
|
|
|
236
|
+
for (const edge of entry.edges_out) {
|
|
237
|
+
(edge as SpreadsheetVertex).dirty = true;
|
|
238
|
+
(edge as SpreadsheetVertex).Calculate(graph);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
|
|
247
|
+
// ---
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
// data should now be clean when it gets here (famous last words)
|
|
251
|
+
|
|
252
|
+
// we're now sometimes getting 0-length arrays here. that's a
|
|
253
|
+
// function of our new polynomial methods, BUT, we should probably
|
|
254
|
+
// handle it properly regardless.
|
|
255
|
+
|
|
256
|
+
// neven // const single = (this.result.type === ValueType.array) ? this.result.value[0][0] : this.result;
|
|
257
|
+
|
|
258
|
+
// we are using object type in the returned value for sparklines...
|
|
259
|
+
// so we can't drop it here. we could change rendering though. or
|
|
260
|
+
// whitelist types. or blacklist types. or something.
|
|
261
|
+
|
|
262
|
+
this.reference.SetCalculatedValue(this.result.value as CellValue, this.result.type);
|
|
263
|
+
|
|
264
|
+
}
|
|
236
265
|
}
|
|
237
266
|
|
|
238
267
|
}
|
|
@@ -34,6 +34,7 @@ export interface CalculationResult {
|
|
|
34
34
|
export interface GraphCallbacks {
|
|
35
35
|
CalculationCallback: (vertex: SpreadsheetVertexBase) => CalculationResult;
|
|
36
36
|
SpreadCallback: (vertex: SpreadsheetVertexBase, value: UnionValue) => void;
|
|
37
|
+
SpillCallback: (vertex: SpreadsheetVertexBase, value: UnionValue) => Vertex[]|void;
|
|
37
38
|
volatile_list: SpreadsheetVertexBase[];
|
|
38
39
|
calculation_list: SpreadsheetVertexBase[];
|
|
39
40
|
}
|
|
@@ -31,7 +31,7 @@ import { ValueType, GetValueType, Area } from 'treb-base-types';
|
|
|
31
31
|
import type { Parser, ExpressionUnit, UnitBinary, UnitIdentifier,
|
|
32
32
|
UnitGroup, UnitUnary, UnitAddress, UnitRange, UnitCall, UnitDimensionedQuantity, UnitStructuredReference } from 'treb-parser';
|
|
33
33
|
import type { DataModel, MacroFunction, Sheet } from 'treb-data-model';
|
|
34
|
-
import { NameError, ReferenceError, ExpressionError, UnknownError } from './function-error';
|
|
34
|
+
import { NameError, ReferenceError, ExpressionError, UnknownError, SpillError } from './function-error';
|
|
35
35
|
import { ReturnType } from './descriptors';
|
|
36
36
|
|
|
37
37
|
import * as Primitives from './primitives';
|
|
@@ -136,7 +136,6 @@ export class ExpressionCalculator {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
// const cells = this.cells_map[expr.sheet_id];
|
|
140
139
|
const cells = this.data_model.sheets.Find(expr.sheet_id)?.cells;
|
|
141
140
|
|
|
142
141
|
if (!cells) {
|
|
@@ -156,6 +155,12 @@ export class ExpressionCalculator {
|
|
|
156
155
|
};
|
|
157
156
|
}
|
|
158
157
|
|
|
158
|
+
if (expr.spill && cell.spill && cell.spill.start.row === expr.row && cell.spill.start.column === expr.column) {
|
|
159
|
+
return () => {
|
|
160
|
+
return cell.spill ? cells.GetRange4(cell.spill.start, cell.spill.end, true) || ReferenceError() : SpillError();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
159
164
|
// close
|
|
160
165
|
return () => cell.GetValue4();
|
|
161
166
|
|
|
@@ -34,6 +34,7 @@ export enum ErrorType {
|
|
|
34
34
|
Div0 = 'DIV/0',
|
|
35
35
|
NA = 'N/A',
|
|
36
36
|
Loop = 'LOOP', // circular reference
|
|
37
|
+
Spill = 'SPILL',
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
export interface FunctionError {
|
|
@@ -74,6 +75,10 @@ export const NameError = (): UnionValue => {
|
|
|
74
75
|
return { type: ValueType.error, value: ErrorType.Name };
|
|
75
76
|
};
|
|
76
77
|
|
|
78
|
+
export const SpillError = (): UnionValue => {
|
|
79
|
+
return { type: ValueType.error, value: ErrorType.Spill };
|
|
80
|
+
};
|
|
81
|
+
|
|
77
82
|
export const UnknownError = (): UnionValue => {
|
|
78
83
|
return { type: ValueType.error, value: ErrorType.Unknown };
|
|
79
84
|
};
|
|
@@ -94,6 +99,7 @@ export const IsError = (test: unknown): test is FunctionError => {
|
|
|
94
99
|
(test as FunctionError).error === ErrorType.Unknown ||
|
|
95
100
|
(test as FunctionError).error === ErrorType.NotImpl ||
|
|
96
101
|
(test as FunctionError).error === ErrorType.Value ||
|
|
102
|
+
(test as FunctionError).error === ErrorType.Spill ||
|
|
97
103
|
(test as FunctionError).error === ErrorType.Div0
|
|
98
104
|
);
|
|
99
105
|
};
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { type UnionValue, ValueType } from 'treb-base-types';
|
|
23
|
-
import type {
|
|
23
|
+
import type { CompositeFunctionDescriptor } from 'treb-calculator/src/descriptors';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* function returns its arguments
|
|
@@ -35,10 +35,25 @@ const Identity = (...args: unknown[]): UnionValue => {
|
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
export type ChartFunction
|
|
39
|
+
= 'Bar.Chart'
|
|
40
|
+
| 'Line.Chart'
|
|
41
|
+
| 'Area.Chart'
|
|
42
|
+
| 'Column.Chart'
|
|
43
|
+
| 'Bubble.Chart'
|
|
44
|
+
| 'Donut.Chart'
|
|
45
|
+
| 'Pie.Chart'
|
|
46
|
+
| 'Scatter.Line'
|
|
47
|
+
| 'Scatter.Plot'
|
|
48
|
+
| 'Box.Plot'
|
|
49
|
+
;
|
|
50
|
+
|
|
51
|
+
type SupportFunction = 'Group'|'Series';
|
|
52
|
+
|
|
38
53
|
/**
|
|
39
54
|
* chart functions for registration
|
|
40
55
|
*/
|
|
41
|
-
export const ChartFunctions:
|
|
56
|
+
export const ChartFunctions: Record<ChartFunction|SupportFunction, CompositeFunctionDescriptor> = {
|
|
42
57
|
|
|
43
58
|
/* new: also helper */
|
|
44
59
|
Group: {
|
|
@@ -52,7 +67,8 @@ export const ChartFunctions: FunctionMap = {
|
|
|
52
67
|
key: 'group',
|
|
53
68
|
};
|
|
54
69
|
|
|
55
|
-
}
|
|
70
|
+
},
|
|
71
|
+
category: ['grouping'],
|
|
56
72
|
},
|
|
57
73
|
|
|
58
74
|
/**
|
|
@@ -81,8 +97,8 @@ export const ChartFunctions: FunctionMap = {
|
|
|
81
97
|
value: args,
|
|
82
98
|
key: 'series',
|
|
83
99
|
};
|
|
84
|
-
}
|
|
85
|
-
|
|
100
|
+
},
|
|
101
|
+
category: ['chart functions'],
|
|
86
102
|
},
|
|
87
103
|
|
|
88
104
|
'Bar.Chart': {
|
|
@@ -92,6 +108,7 @@ export const ChartFunctions: FunctionMap = {
|
|
|
92
108
|
{ name: 'ChartTitle' },
|
|
93
109
|
],
|
|
94
110
|
fn: Identity,
|
|
111
|
+
category: ['chart functions'],
|
|
95
112
|
},
|
|
96
113
|
|
|
97
114
|
'Line.Chart': {
|
|
@@ -101,6 +118,7 @@ export const ChartFunctions: FunctionMap = {
|
|
|
101
118
|
{ name: 'ChartTitle' },
|
|
102
119
|
],
|
|
103
120
|
fn: Identity,
|
|
121
|
+
category: ['chart functions'],
|
|
104
122
|
},
|
|
105
123
|
|
|
106
124
|
'Area.Chart': {
|
|
@@ -110,6 +128,7 @@ export const ChartFunctions: FunctionMap = {
|
|
|
110
128
|
{ name: 'ChartTitle' },
|
|
111
129
|
],
|
|
112
130
|
fn: Identity,
|
|
131
|
+
category: ['chart functions'],
|
|
113
132
|
},
|
|
114
133
|
|
|
115
134
|
'Pie.Chart': {
|
|
@@ -121,6 +140,7 @@ export const ChartFunctions: FunctionMap = {
|
|
|
121
140
|
{ name: 'Label' },
|
|
122
141
|
],
|
|
123
142
|
fn: Identity,
|
|
143
|
+
category: ['chart functions'],
|
|
124
144
|
},
|
|
125
145
|
|
|
126
146
|
'Donut.Chart': {
|
|
@@ -132,6 +152,7 @@ export const ChartFunctions: FunctionMap = {
|
|
|
132
152
|
{ name: 'Label' },
|
|
133
153
|
],
|
|
134
154
|
fn: Identity,
|
|
155
|
+
category: ['chart functions'],
|
|
135
156
|
},
|
|
136
157
|
|
|
137
158
|
'Scatter.Line': {
|
|
@@ -140,6 +161,7 @@ export const ChartFunctions: FunctionMap = {
|
|
|
140
161
|
{ name: 'ChartTitle' },
|
|
141
162
|
],
|
|
142
163
|
fn: Identity,
|
|
164
|
+
category: ['chart functions'],
|
|
143
165
|
},
|
|
144
166
|
|
|
145
167
|
'Scatter.Plot': {
|
|
@@ -148,6 +170,7 @@ export const ChartFunctions: FunctionMap = {
|
|
|
148
170
|
{ name: 'ChartTitle' },
|
|
149
171
|
],
|
|
150
172
|
fn: Identity,
|
|
173
|
+
category: ['chart functions'],
|
|
151
174
|
},
|
|
152
175
|
|
|
153
176
|
'Column.Chart': {
|
|
@@ -157,6 +180,7 @@ export const ChartFunctions: FunctionMap = {
|
|
|
157
180
|
{ name: 'Chart Title' },
|
|
158
181
|
],
|
|
159
182
|
fn: Identity,
|
|
183
|
+
category: ['chart functions'],
|
|
160
184
|
},
|
|
161
185
|
|
|
162
186
|
'Bubble.Chart': {
|
|
@@ -165,6 +189,16 @@ export const ChartFunctions: FunctionMap = {
|
|
|
165
189
|
{ name: 'Chart Title' },
|
|
166
190
|
],
|
|
167
191
|
fn: Identity,
|
|
192
|
+
category: ['chart functions'],
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
'Box.Plot': {
|
|
196
|
+
arguments: [
|
|
197
|
+
{ name: 'Data', metadata: true, },
|
|
198
|
+
{ name: 'Chart Title' },
|
|
199
|
+
],
|
|
200
|
+
fn: Identity,
|
|
201
|
+
category: ['chart functions'],
|
|
168
202
|
},
|
|
169
203
|
|
|
170
204
|
};
|
|
@@ -199,6 +199,28 @@ export interface LineBaseData extends ChartDataBaseType {
|
|
|
199
199
|
smooth?: boolean;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
export interface BoxPlotData extends ChartDataBaseType {
|
|
203
|
+
type: 'box';
|
|
204
|
+
series: SeriesType[];
|
|
205
|
+
x_labels?: string[];
|
|
206
|
+
series_names?: string[];
|
|
207
|
+
y_labels?: string[];
|
|
208
|
+
scale: RangeScale;
|
|
209
|
+
max_n: number,
|
|
210
|
+
|
|
211
|
+
data: {
|
|
212
|
+
data: number[],
|
|
213
|
+
quartiles: [number, number, number],
|
|
214
|
+
whiskers: [number, number],
|
|
215
|
+
iqr: number,
|
|
216
|
+
n: number,
|
|
217
|
+
min: number,
|
|
218
|
+
max: number,
|
|
219
|
+
mean: number,
|
|
220
|
+
}[];
|
|
221
|
+
|
|
222
|
+
}
|
|
223
|
+
|
|
202
224
|
export interface LineData extends LineBaseData {
|
|
203
225
|
type: 'line';
|
|
204
226
|
}
|
|
@@ -253,6 +275,7 @@ export type ChartData
|
|
|
253
275
|
| ColumnData
|
|
254
276
|
| BarData
|
|
255
277
|
| BubbleChartData
|
|
278
|
+
| BoxPlotData
|
|
256
279
|
;
|
|
257
280
|
|
|
258
281
|
export enum LegendLayout {
|