@trebco/treb 28.5.2 → 28.10.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 +15 -15
- package/dist/treb-spreadsheet.mjs +15 -15
- package/dist/treb.d.ts +37 -6
- package/package.json +1 -1
- package/treb-base-types/src/api_types.ts +1 -1
- package/treb-base-types/src/area.ts +1 -1
- package/treb-base-types/src/basic_types.ts +21 -21
- package/treb-base-types/src/cell.ts +1 -1
- package/treb-base-types/src/cells.ts +1 -1
- package/treb-base-types/src/color.ts +1 -1
- package/treb-base-types/src/dom-utilities.ts +1 -1
- package/treb-base-types/src/gradient.ts +1 -1
- package/treb-base-types/src/import.ts +1 -1
- package/treb-base-types/src/index-standalone.ts +9 -9
- package/treb-base-types/src/index.ts +1 -1
- package/treb-base-types/src/layout.ts +21 -21
- package/treb-base-types/src/localization.ts +27 -21
- package/treb-base-types/src/rectangle.ts +1 -1
- package/treb-base-types/src/render_text.ts +1 -1
- package/treb-base-types/src/style.ts +1 -1
- package/treb-base-types/src/table.ts +1 -1
- package/treb-base-types/src/text_part.ts +21 -21
- package/treb-base-types/src/theme.ts +1 -1
- package/treb-base-types/src/union.ts +1 -1
- package/treb-base-types/src/value-type.ts +1 -1
- package/treb-base-types/style/resizable.css +21 -21
- package/treb-calculator/src/calculator.ts +24 -31
- package/treb-calculator/src/complex-math.ts +1 -1
- package/treb-calculator/src/dag/array-vertex.ts +1 -1
- package/treb-calculator/src/dag/calculation_leaf_vertex.ts +8 -1
- package/treb-calculator/src/dag/graph.ts +8 -1
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +1 -1
- package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +21 -21
- package/treb-calculator/src/dag/state_leaf_vertex.ts +1 -1
- package/treb-calculator/src/dag/vertex.ts +21 -21
- package/treb-calculator/src/descriptors.ts +1 -1
- package/treb-calculator/src/expression-calculator.ts +1 -1
- package/treb-calculator/src/function-error.ts +1 -1
- package/treb-calculator/src/function-library.ts +1 -1
- package/treb-calculator/src/functions/base-functions.ts +31 -2
- package/treb-calculator/src/functions/checkbox.ts +1 -1
- package/treb-calculator/src/functions/complex-functions.ts +1 -1
- package/treb-calculator/src/functions/finance-functions.ts +1 -1
- package/treb-calculator/src/functions/information-functions.ts +1 -1
- package/treb-calculator/src/functions/matrix-functions.ts +1 -1
- package/treb-calculator/src/functions/sparkline.ts +1 -1
- package/treb-calculator/src/functions/statistics-functions.ts +1 -1
- package/treb-calculator/src/functions/text-functions.ts +1 -1
- package/treb-calculator/src/index.ts +1 -1
- package/treb-calculator/src/notifier-types.ts +1 -1
- package/treb-calculator/src/primitives.ts +1 -1
- package/treb-calculator/src/utilities.ts +1 -1
- package/treb-charts/src/chart-functions.ts +12 -1
- package/treb-charts/src/chart-types.ts +39 -21
- package/treb-charts/src/chart-utils.ts +783 -0
- package/treb-charts/src/chart.ts +96 -1291
- package/treb-charts/src/default-chart-renderer.ts +560 -0
- package/treb-charts/src/index.ts +5 -4
- package/treb-charts/src/main.ts +17 -17
- package/treb-charts/src/rectangle.ts +21 -21
- package/treb-charts/src/renderer-type.ts +32 -0
- package/treb-charts/src/renderer.ts +82 -1
- package/treb-charts/src/util.ts +1 -1
- package/treb-charts/style/charts.scss +9 -1
- package/treb-charts/style/old-charts.scss +21 -21
- package/treb-embed/markup/toolbar.html +35 -34
- package/treb-embed/src/custom-element/treb-global.ts +10 -2
- package/treb-embed/src/embedded-spreadsheet.ts +72 -113
- package/treb-embed/src/language-model.ts +1 -1
- package/treb-embed/src/options.ts +37 -1
- package/treb-embed/src/progress-dialog.ts +1 -1
- package/treb-embed/src/spinner.ts +1 -1
- package/treb-embed/src/types.ts +1 -1
- package/treb-embed/style/autocomplete.scss +1 -1
- package/treb-embed/style/dark-theme.scss +1 -1
- package/treb-embed/style/defaults.scss +1 -1
- package/treb-embed/style/dialog.scss +1 -1
- package/treb-embed/style/dropdown-select.scss +1 -1
- package/treb-embed/style/formula-bar.scss +1 -1
- package/treb-embed/style/grid.scss +1 -1
- package/treb-embed/style/layout.scss +4 -0
- package/treb-embed/style/mouse-mask.scss +1 -1
- package/treb-embed/style/note.scss +1 -1
- package/treb-embed/style/overlay-editor.scss +1 -1
- package/treb-embed/style/spinner.scss +1 -1
- package/treb-embed/style/tab-bar.scss +1 -1
- package/treb-embed/style/table.scss +1 -1
- package/treb-embed/style/theme-defaults.scss +1 -1
- package/treb-embed/style/toolbar.scss +37 -0
- package/treb-embed/style/tooltip.scss +1 -1
- package/treb-embed/style/z-index.scss +1 -1
- package/treb-export/src/address-type.ts +21 -21
- package/treb-export/src/base-template.ts +1 -1
- package/treb-export/src/column-width.ts +1 -1
- package/treb-export/src/drawing2/chart-template-components2.ts +1 -1
- package/treb-export/src/drawing2/chart2.ts +1 -1
- package/treb-export/src/drawing2/column-chart-template2.ts +1 -1
- package/treb-export/src/drawing2/donut-chart-template2.ts +1 -1
- package/treb-export/src/drawing2/drawing2.ts +1 -1
- package/treb-export/src/drawing2/embedded-image.ts +1 -1
- package/treb-export/src/drawing2/scatter-chart-template2.ts +1 -1
- package/treb-export/src/export-worker/export-worker.ts +1 -1
- package/treb-export/src/export-worker/index.worker.ts +1 -1
- package/treb-export/src/export2.ts +1 -1
- package/treb-export/src/import2.ts +1 -1
- package/treb-export/src/relationship.ts +1 -1
- package/treb-export/src/shared-strings2.ts +1 -1
- package/treb-export/src/template-2.ts +2 -2
- package/treb-export/src/workbook-sheet2.ts +1 -1
- package/treb-export/src/workbook-style2.ts +1 -1
- package/treb-export/src/workbook-theme2.ts +1 -1
- package/treb-export/src/workbook2.ts +1 -1
- package/treb-export/src/xml-utils.ts +1 -1
- package/treb-format/src/format.test.ts +21 -21
- package/treb-format/src/format.ts +1 -1
- package/treb-format/src/format_cache.ts +21 -21
- package/treb-format/src/format_parser.ts +1 -1
- package/treb-format/src/index.ts +4 -4
- package/treb-format/src/number_format_section.ts +21 -21
- package/treb-format/src/value_parser.ts +1 -1
- package/treb-grid/src/editors/autocomplete.ts +1 -1
- package/treb-grid/src/editors/autocomplete_matcher.ts +21 -21
- package/treb-grid/src/editors/editor.ts +1 -1
- package/treb-grid/src/editors/formula_bar.ts +1 -1
- package/treb-grid/src/editors/overlay_editor.ts +1 -1
- package/treb-grid/src/index.ts +1 -1
- package/treb-grid/src/layout/base_layout.ts +1 -1
- package/treb-grid/src/layout/grid_layout.ts +1 -1
- package/treb-grid/src/layout/rectangle_cache.ts +21 -21
- package/treb-grid/src/render/selection-renderer.ts +1 -1
- package/treb-grid/src/render/svg_header_overlay.ts +1 -1
- package/treb-grid/src/render/svg_selection_block.ts +1 -1
- package/treb-grid/src/render/tile_renderer.ts +1 -1
- package/treb-grid/src/types/annotation.ts +1 -1
- package/treb-grid/src/types/border_constants.ts +1 -1
- package/treb-grid/src/types/clipboard_data.ts +1 -1
- package/treb-grid/src/types/conditional_format.ts +1 -1
- package/treb-grid/src/types/data_model.ts +1 -1
- package/treb-grid/src/types/drag_mask.ts +21 -21
- package/treb-grid/src/types/grid.ts +12 -2
- package/treb-grid/src/types/grid_base.ts +128 -6
- package/treb-grid/src/types/grid_command.ts +33 -1
- package/treb-grid/src/types/grid_events.ts +8 -1
- package/treb-grid/src/types/grid_options.ts +9 -1
- package/treb-grid/src/types/grid_selection.ts +1 -1
- package/treb-grid/src/types/named_range.ts +1 -1
- package/treb-grid/src/types/scale-control.ts +1 -1
- package/treb-grid/src/types/serialize_options.ts +1 -1
- package/treb-grid/src/types/set_range_options.ts +1 -1
- package/treb-grid/src/types/sheet.ts +1 -57
- package/treb-grid/src/types/sheet_types.ts +1 -1
- package/treb-grid/src/types/tab_bar.ts +1 -1
- package/treb-grid/src/types/tile.ts +21 -21
- package/treb-grid/src/types/update_flags.ts +2 -1
- package/treb-grid/src/util/fontmetrics2.ts +1 -1
- package/treb-grid/src/util/ua.ts +21 -21
- package/treb-parser/src/csv-parser.ts +21 -21
- package/treb-parser/src/index.ts +5 -5
- package/treb-parser/src/md-parser.ts +1 -1
- package/treb-parser/src/parser-types.ts +1 -1
- package/treb-parser/src/parser.test.ts +21 -21
- package/treb-parser/src/parser.ts +1 -1
- package/treb-utils/src/event_source.ts +1 -1
- package/treb-utils/src/ievent_source.ts +13 -13
- package/treb-utils/src/index.ts +1 -1
- package/treb-utils/src/measurement.ts +1 -1
- package/treb-utils/src/scale.ts +21 -21
- package/treb-utils/src/serialize_html.ts +1 -1
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* You should have received a copy of the GNU General Public License along
|
|
15
15
|
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
16
|
*
|
|
17
|
-
* Copyright 2022-
|
|
17
|
+
* Copyright 2022-2024 trebco, llc.
|
|
18
18
|
* info@treb.app
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
@@ -1193,6 +1193,87 @@ export class ChartRenderer {
|
|
|
1193
1193
|
|
|
1194
1194
|
}
|
|
1195
1195
|
|
|
1196
|
+
public RenderBubbleSeries(area: Area,
|
|
1197
|
+
x: Array<number | undefined>,
|
|
1198
|
+
y: Array<number | undefined>,
|
|
1199
|
+
z: Array<number | undefined>,
|
|
1200
|
+
c: any[] = [],
|
|
1201
|
+
x_scale: RangeScale,
|
|
1202
|
+
y_scale: RangeScale,
|
|
1203
|
+
min = 10,
|
|
1204
|
+
max = 30,
|
|
1205
|
+
classes?: string | string[]): void {
|
|
1206
|
+
|
|
1207
|
+
const count = Math.max(x.length, y.length, z.length);
|
|
1208
|
+
const xrange = (x_scale.max - x_scale.min) || 1;
|
|
1209
|
+
const yrange = (y_scale.max - y_scale.min) || 1;
|
|
1210
|
+
|
|
1211
|
+
// const marker_elements: string[] = [];
|
|
1212
|
+
const points: Array<{x: number, y: number, z: number, series: number} | undefined> = [];
|
|
1213
|
+
|
|
1214
|
+
const d: string[] = [];
|
|
1215
|
+
const areas: string[] = [];
|
|
1216
|
+
|
|
1217
|
+
const group = SVGNode('g', {class: classes});
|
|
1218
|
+
|
|
1219
|
+
// if (title) node.setAttribute('title', title);
|
|
1220
|
+
this.group.appendChild(group);
|
|
1221
|
+
|
|
1222
|
+
let z_min = z[0] || 0;
|
|
1223
|
+
let z_max = z[0] || 0;
|
|
1224
|
+
|
|
1225
|
+
const map: Map<string, number> = new Map();
|
|
1226
|
+
|
|
1227
|
+
for (let i = 0; i < count; i++) {
|
|
1228
|
+
|
|
1229
|
+
const a = x[i];
|
|
1230
|
+
const b = y[i];
|
|
1231
|
+
|
|
1232
|
+
if (typeof a === 'undefined' || typeof b === 'undefined') {
|
|
1233
|
+
points.push(undefined);
|
|
1234
|
+
}
|
|
1235
|
+
else {
|
|
1236
|
+
|
|
1237
|
+
const series_key = c[i] || '';
|
|
1238
|
+
let series = map.get(series_key);
|
|
1239
|
+
|
|
1240
|
+
if (typeof series === 'undefined') {
|
|
1241
|
+
|
|
1242
|
+
series = map.size + 1;
|
|
1243
|
+
|
|
1244
|
+
map.set(series_key, series);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
let size = z[i] || 0;
|
|
1248
|
+
if (size) {
|
|
1249
|
+
const size_x = size / xrange * area.width;
|
|
1250
|
+
const size_y = size / yrange * area.height;
|
|
1251
|
+
size = Math.min(size_x, size_y);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
points.push({
|
|
1255
|
+
x: area.left + ((a - x_scale.min) / xrange) * area.width,
|
|
1256
|
+
y: area.bottom - ((b - y_scale.min) / yrange) * area.height,
|
|
1257
|
+
z: size,
|
|
1258
|
+
series,
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
{
|
|
1266
|
+
for (const point of points) {
|
|
1267
|
+
if (point) {
|
|
1268
|
+
group.appendChild(SVGNode('circle', {cx: point.x, cy: point.y, r: point.z / 2, class: `point series-${point.series}`}));
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1196
1277
|
public RenderScatterSeries(area: Area,
|
|
1197
1278
|
x: Array<number | undefined>,
|
|
1198
1279
|
y: Array<number | undefined>,
|
package/treb-charts/src/util.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* You should have received a copy of the GNU General Public License along
|
|
15
15
|
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
16
|
*
|
|
17
|
-
* Copyright 2022-
|
|
17
|
+
* Copyright 2022-2024 trebco, llc.
|
|
18
18
|
* info@treb.app
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
@@ -161,6 +161,14 @@
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
.bubble-chart {
|
|
165
|
+
|
|
166
|
+
stroke-width: 3;
|
|
167
|
+
fill: color-mix(in srgb, currentColor 75%, transparent);
|
|
168
|
+
stroke: currentColor;
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
|
|
164
172
|
/* scatter plot line (and marker -- change that class name) */
|
|
165
173
|
.scatter-plot {
|
|
166
174
|
|
|
@@ -1,24 +1,24 @@
|
|
|
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-
|
|
18
|
-
* info@treb.app
|
|
19
|
-
*
|
|
20
|
-
*/
|
|
21
|
-
|
|
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-2024 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
22
|
/**
|
|
23
23
|
* NOTE: this file uses the color-mod() function and a postcss library
|
|
24
24
|
* to translate it. that function is no longer in the spec and will be
|
|
@@ -65,6 +65,27 @@
|
|
|
65
65
|
</div>
|
|
66
66
|
</div>
|
|
67
67
|
|
|
68
|
+
<div composite>
|
|
69
|
+
<button data-command="border-bottom" data-target="border" title="Bottom border"></button>
|
|
70
|
+
<div class="treb-menu">
|
|
71
|
+
<button dropdown title="Border options"></button>
|
|
72
|
+
<div class="treb-icon-buttons" data-replace="border">
|
|
73
|
+
<button data-command="border-top" title="Top border"></button>
|
|
74
|
+
<button data-command="border-left" title="Left border"></button>
|
|
75
|
+
<button data-command="border-right" title="Right border"></button>
|
|
76
|
+
<button data-command="border-bottom" title="Bottom border"></button>
|
|
77
|
+
<button data-command="border-double-bottom" title="Double bottom border"></button>
|
|
78
|
+
<button data-command="border-outside" title="Outside borders"></button>
|
|
79
|
+
<button data-command="border-all" title="All borders"></button>
|
|
80
|
+
<button data-command="border-none" title="Clear borders"></button>
|
|
81
|
+
<div separator></div>
|
|
82
|
+
<div class="treb-menu treb-color-menu treb-submenu" data-color-command="border-color" data-replace-color="border" title="Border color" data-default-color-text="Default border color">
|
|
83
|
+
<button data-icon="palette" data-color-bar="border" data-color="{}"></button>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
68
89
|
<div composite>
|
|
69
90
|
<button data-command="fill-color" data-color-bar="fill" data-color="{}" title="Fill color"></button>
|
|
70
91
|
<div class="treb-menu treb-color-menu" data-color-command="fill-color" data-replace-color="fill" data-default-color-text="No fill">
|
|
@@ -94,28 +115,8 @@
|
|
|
94
115
|
</div>
|
|
95
116
|
</div>
|
|
96
117
|
|
|
97
|
-
<div composite>
|
|
98
|
-
<button data-command="border-bottom" data-target="border" title="Bottom border"></button>
|
|
99
|
-
<div class="treb-menu">
|
|
100
|
-
<button dropdown title="Border options"></button>
|
|
101
|
-
<div class="treb-icon-buttons" data-replace="border">
|
|
102
|
-
<button data-command="border-top" title="Top border"></button>
|
|
103
|
-
<button data-command="border-left" title="Left border"></button>
|
|
104
|
-
<button data-command="border-right" title="Right border"></button>
|
|
105
|
-
<button data-command="border-bottom" title="Bottom border"></button>
|
|
106
|
-
<button data-command="border-double-bottom" title="Double bottom border"></button>
|
|
107
|
-
<button data-command="border-outside" title="Outside borders"></button>
|
|
108
|
-
<button data-command="border-all" title="All borders"></button>
|
|
109
|
-
<button data-command="border-none" title="Clear borders"></button>
|
|
110
|
-
<div separator></div>
|
|
111
|
-
<div class="treb-menu treb-color-menu treb-submenu" data-color-command="border-color" data-replace-color="border" title="Border color" data-default-color-text="Default border color">
|
|
112
|
-
<button data-icon="palette" data-color-bar="border" data-color="{}"></button>
|
|
113
|
-
</div>
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
118
|
<div composite font-scale>
|
|
119
|
+
<div class="treb-font-scale-icon"></div>
|
|
119
120
|
<input class="treb-font-scale" title="Font scale">
|
|
120
121
|
<div class="treb-menu">
|
|
121
122
|
<button dropdown title="Font scale options"></button>
|
|
@@ -131,19 +132,6 @@
|
|
|
131
132
|
</div>
|
|
132
133
|
</div>
|
|
133
134
|
|
|
134
|
-
<div class="treb-menu">
|
|
135
|
-
<button data-icon="layout" title="Rows & columns"></button>
|
|
136
|
-
<div>
|
|
137
|
-
<button data-command="insert-row">Insert row</button>
|
|
138
|
-
<button data-command="insert-column">Insert column</button>
|
|
139
|
-
<button data-command="delete-row">Delete row</button>
|
|
140
|
-
<button data-command="delete-column">Delete column</button>
|
|
141
|
-
<div separator add-remove-sheet></div>
|
|
142
|
-
<button data-command="insert-sheet" add-remove-sheet>Add sheet</button>
|
|
143
|
-
<button data-command="delete-sheet" add-remove-sheet>Delete sheet</button>
|
|
144
|
-
</div>
|
|
145
|
-
</div>
|
|
146
|
-
|
|
147
135
|
<div composite>
|
|
148
136
|
<input class="treb-number-format" title="Number format">
|
|
149
137
|
<div class="treb-menu">
|
|
@@ -157,6 +145,19 @@
|
|
|
157
145
|
<button data-command="increase-precision" title="Increase precision"></button>
|
|
158
146
|
</div>
|
|
159
147
|
|
|
148
|
+
<div class="treb-menu">
|
|
149
|
+
<button data-icon="layout" title="Rows & columns"></button>
|
|
150
|
+
<div>
|
|
151
|
+
<button data-command="insert-row">Insert row</button>
|
|
152
|
+
<button data-command="insert-column">Insert column</button>
|
|
153
|
+
<button data-command="delete-row">Delete row</button>
|
|
154
|
+
<button data-command="delete-column">Delete column</button>
|
|
155
|
+
<div separator add-remove-sheet></div>
|
|
156
|
+
<button data-command="insert-sheet" add-remove-sheet>Add sheet</button>
|
|
157
|
+
<button data-command="delete-sheet" add-remove-sheet>Delete sheet</button>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
160
161
|
<div composite chart-menu>
|
|
161
162
|
<button data-command="insert-column-chart" data-target="annotation" title="Insert column chart"></button>
|
|
162
163
|
<div class="treb-menu">
|
|
@@ -10,7 +10,7 @@ import type { EmbeddedSpreadsheet } from '../embedded-spreadsheet';
|
|
|
10
10
|
export class TREBGlobal {
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Package version
|
|
14
14
|
*
|
|
15
15
|
* @privateRemarks
|
|
16
16
|
*
|
|
@@ -25,7 +25,15 @@ export class TREBGlobal {
|
|
|
25
25
|
public version = process.env.BUILD_VERSION || '';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* Create a spreadsheet. The `USER_DATA_TYPE` template parameter is the type
|
|
29
|
+
* assigned to the `user_data` field of the spreadsheet instance -- it can
|
|
30
|
+
* help simplify typing if you are storing extra data in spreadsheet
|
|
31
|
+
* files.
|
|
32
|
+
*
|
|
33
|
+
* Just ignore this parameter if you don't need it.
|
|
34
|
+
*
|
|
35
|
+
* @typeParam USER_DATA_TYPE - type for the `user_data` field in the
|
|
36
|
+
* spreadsheet instance
|
|
29
37
|
*/
|
|
30
38
|
public CreateSpreadsheet<USER_DATA_TYPE = unknown>(options: EmbeddedSpreadsheetOptions): EmbeddedSpreadsheet<USER_DATA_TYPE> {
|
|
31
39
|
const container = options.container;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* You should have received a copy of the GNU General Public License along
|
|
15
15
|
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
16
|
*
|
|
17
|
-
* Copyright 2022-
|
|
17
|
+
* Copyright 2022-2024 trebco, llc.
|
|
18
18
|
* info@treb.app
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
} from 'treb-base-types';
|
|
70
70
|
|
|
71
71
|
import { EventSource, ValidateURI } from 'treb-utils';
|
|
72
|
-
import { NumberFormatCache, ValueParser, NumberFormat } from 'treb-format';
|
|
72
|
+
import { NumberFormatCache, ValueParser, NumberFormat, LotusDate, UnlotusDate } from 'treb-format';
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
|
|
@@ -486,13 +486,19 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
486
486
|
this.DocumentChange();
|
|
487
487
|
}
|
|
488
488
|
|
|
489
|
-
/**
|
|
489
|
+
/**
|
|
490
|
+
* opaque user data (metadata). `USER_DATA_TYPE` is a template
|
|
491
|
+
* parameter you can set when creating the spreadsheet.
|
|
492
|
+
*/
|
|
490
493
|
public get user_data(): USER_DATA_TYPE|undefined {
|
|
491
494
|
return this.grid.model.user_data;
|
|
492
495
|
}
|
|
493
496
|
|
|
494
|
-
/**
|
|
495
|
-
|
|
497
|
+
/**
|
|
498
|
+
* opaque user data (metadata). `USER_DATA_TYPE` is a template
|
|
499
|
+
* parameter you can set when creating the spreadsheet.
|
|
500
|
+
*/
|
|
501
|
+
public set user_data(data: USER_DATA_TYPE|undefined) {
|
|
496
502
|
this.grid.model.user_data = data;
|
|
497
503
|
this.DocumentChange();
|
|
498
504
|
}
|
|
@@ -883,6 +889,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
883
889
|
|
|
884
890
|
this.grid.grid_events.Subscribe((event) => {
|
|
885
891
|
|
|
892
|
+
// console.info({event});
|
|
893
|
+
|
|
886
894
|
switch (event.type) {
|
|
887
895
|
|
|
888
896
|
case 'error':
|
|
@@ -986,7 +994,14 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
986
994
|
|
|
987
995
|
case 'structure':
|
|
988
996
|
{
|
|
997
|
+
// console.info("S event", event);
|
|
998
|
+
|
|
989
999
|
const cached_selection = this.last_selection;
|
|
1000
|
+
if (event.conditional_format) {
|
|
1001
|
+
this.calculator.UpdateConditionals();
|
|
1002
|
+
this.ApplyConditionalFormats(this.grid.active_sheet, false);
|
|
1003
|
+
}
|
|
1004
|
+
|
|
990
1005
|
if (event.rebuild_required) {
|
|
991
1006
|
this.calculator.Reset();
|
|
992
1007
|
|
|
@@ -1030,10 +1045,9 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
1030
1045
|
// this.grid.headless = true; // ensure
|
|
1031
1046
|
}
|
|
1032
1047
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
// this.calculator = new type();
|
|
1048
|
+
if (options.preload) {
|
|
1049
|
+
options.preload.call(0, this);
|
|
1050
|
+
}
|
|
1037
1051
|
|
|
1038
1052
|
// FIXME: this should yield so we can subscribe to events before the initial load
|
|
1039
1053
|
|
|
@@ -1413,12 +1427,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
1413
1427
|
...options,
|
|
1414
1428
|
};
|
|
1415
1429
|
|
|
1416
|
-
// we need to calculate the formula once, to get an initial state
|
|
1417
|
-
// update: internal
|
|
1418
|
-
// let result = this.Evaluate(this.Unresolve(area, true, false) + ' ' + options.expression, options.options);
|
|
1419
|
-
|
|
1420
|
-
// ... apply ...
|
|
1421
|
-
|
|
1422
1430
|
this.AddConditionalFormat(format);
|
|
1423
1431
|
return format;
|
|
1424
1432
|
|
|
@@ -1446,18 +1454,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
1446
1454
|
...options,
|
|
1447
1455
|
};
|
|
1448
1456
|
|
|
1449
|
-
/*
|
|
1450
|
-
// we need to calculate the formula once, to get an initial state
|
|
1451
|
-
let result = this.Evaluate(options.expression, options.options);
|
|
1452
|
-
|
|
1453
|
-
if (Array.isArray(result)) {
|
|
1454
|
-
result = result[0][0];
|
|
1455
|
-
}
|
|
1456
|
-
const applied = !!result;
|
|
1457
|
-
|
|
1458
|
-
this.AddConditionalFormat({...format, applied });
|
|
1459
|
-
*/
|
|
1460
|
-
|
|
1461
1457
|
this.AddConditionalFormat(format);
|
|
1462
1458
|
|
|
1463
1459
|
return format;
|
|
@@ -1471,20 +1467,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
1471
1467
|
*/
|
|
1472
1468
|
public AddConditionalFormat(format: ConditionalFormat) {
|
|
1473
1469
|
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
if (!sheet) {
|
|
1477
|
-
throw new Error('invalid reference in format');
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
sheet.conditional_formats.push(format);
|
|
1481
|
-
|
|
1482
|
-
this.calculator.UpdateConditionals(format, sheet);
|
|
1483
|
-
|
|
1484
|
-
// call update if it's the current sheet
|
|
1485
|
-
this.ApplyConditionalFormats(sheet, sheet === this.grid.active_sheet);
|
|
1486
|
-
|
|
1487
|
-
this.PushUndo();
|
|
1470
|
+
this.grid.AddConditionalFormat(format);
|
|
1488
1471
|
|
|
1489
1472
|
// fluent
|
|
1490
1473
|
return format;
|
|
@@ -1497,40 +1480,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
1497
1480
|
* @internal
|
|
1498
1481
|
*/
|
|
1499
1482
|
public RemoveConditionalFormat(format: ConditionalFormat) {
|
|
1500
|
-
|
|
1501
|
-
const sheet = area.start.sheet_id ? this.model.sheets.Find(area.start.sheet_id) : this.grid.active_sheet;
|
|
1502
|
-
|
|
1503
|
-
if (!sheet) {
|
|
1504
|
-
throw new Error('invalid reference in format');
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
let count = 0;
|
|
1508
|
-
sheet.conditional_formats = sheet.conditional_formats.filter(test => {
|
|
1509
|
-
if (test === format) {
|
|
1510
|
-
count++;
|
|
1511
|
-
this.calculator.RemoveConditional(test);
|
|
1512
|
-
return false;
|
|
1513
|
-
}
|
|
1514
|
-
return true;
|
|
1515
|
-
});
|
|
1516
|
-
|
|
1517
|
-
if (count) {
|
|
1518
|
-
sheet.FlushConditionalFormats();
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
// we want to call update if it's the current sheet,
|
|
1522
|
-
// but we want a full repaint
|
|
1523
|
-
|
|
1524
|
-
this.ApplyConditionalFormats(sheet, false);
|
|
1525
|
-
|
|
1526
|
-
if (sheet === this.grid.active_sheet) {
|
|
1527
|
-
this.grid.Update(true);
|
|
1528
|
-
}
|
|
1529
|
-
|
|
1530
|
-
if (count) {
|
|
1531
|
-
this.PushUndo();
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1483
|
+
this.grid.RemoveConditionalFormat({ format });
|
|
1534
1484
|
}
|
|
1535
1485
|
|
|
1536
1486
|
/**
|
|
@@ -1549,37 +1499,9 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
1549
1499
|
}
|
|
1550
1500
|
range = ref.area;
|
|
1551
1501
|
}
|
|
1552
|
-
const area = this.model.ResolveArea(range, this.grid.active_sheet);
|
|
1553
|
-
const sheet = area.start.sheet_id ? this.model.sheets.Find(area.start.sheet_id) : this.grid.active_sheet;
|
|
1554
|
-
|
|
1555
|
-
if (sheet) {
|
|
1556
|
-
let count = 0;
|
|
1557
|
-
|
|
1558
|
-
sheet.conditional_formats = sheet.conditional_formats.filter(test => {
|
|
1559
|
-
const compare = new Area(test.area.start, test.area.end);
|
|
1560
|
-
if (compare.Intersects(area)) {
|
|
1561
|
-
count++;
|
|
1562
|
-
this.calculator.RemoveConditional(test);
|
|
1563
|
-
return false;
|
|
1564
|
-
}
|
|
1565
|
-
return true;
|
|
1566
|
-
});
|
|
1567
|
-
|
|
1568
|
-
if (count) {
|
|
1569
|
-
|
|
1570
|
-
sheet.FlushConditionalFormats();
|
|
1571
|
-
|
|
1572
|
-
this.ApplyConditionalFormats(sheet, false);
|
|
1573
|
-
|
|
1574
|
-
if (sheet === this.grid.active_sheet) {
|
|
1575
|
-
this.grid.Update(true);
|
|
1576
|
-
}
|
|
1577
|
-
|
|
1578
|
-
this.PushUndo();
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
}
|
|
1582
1502
|
|
|
1503
|
+
const area = this.model.ResolveArea(range, this.grid.active_sheet);
|
|
1504
|
+
this.grid.RemoveConditionalFormat({ area });
|
|
1583
1505
|
|
|
1584
1506
|
}
|
|
1585
1507
|
|
|
@@ -1997,18 +1919,23 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
1997
1919
|
|
|
1998
1920
|
/**
|
|
1999
1921
|
* Create (and return) a Chart object.
|
|
2000
|
-
*
|
|
2001
|
-
* @privateRemarks
|
|
2002
|
-
*
|
|
2003
|
-
* This method was created for RAW, no one else should need it. But it's
|
|
2004
|
-
* not really an internal method, because it's used by outside clients.
|
|
2005
|
-
*
|
|
2006
1922
|
* @internal
|
|
2007
1923
|
*/
|
|
2008
1924
|
public CreateChart(): Chart {
|
|
1925
|
+
|
|
2009
1926
|
if (this.calculator.RegisterLibrary('treb-charts', ChartFunctions)) {
|
|
2010
1927
|
this.UpdateAC();
|
|
2011
1928
|
}
|
|
1929
|
+
|
|
1930
|
+
if (this.options.chart_renderer) {
|
|
1931
|
+
if (typeof this.options.chart_renderer === 'function') {
|
|
1932
|
+
return new Chart(this.options.chart_renderer());
|
|
1933
|
+
}
|
|
1934
|
+
else {
|
|
1935
|
+
return new Chart(this.options.chart_renderer);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|
|
2012
1939
|
return new Chart();
|
|
2013
1940
|
}
|
|
2014
1941
|
|
|
@@ -3973,6 +3900,23 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
3973
3900
|
return NumberFormatCache.Get(format).Format(value);
|
|
3974
3901
|
}
|
|
3975
3902
|
|
|
3903
|
+
/**
|
|
3904
|
+
* convert a javascript date (or timestamp) to a spreadsheet date
|
|
3905
|
+
*/
|
|
3906
|
+
public SpreadsheetDate(javascript_date: number|Date) {
|
|
3907
|
+
if (javascript_date instanceof Date) {
|
|
3908
|
+
javascript_date = javascript_date.getTime();
|
|
3909
|
+
}
|
|
3910
|
+
return UnlotusDate(javascript_date, true);
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
/**
|
|
3914
|
+
* convert a spreadsheet date to a javascript date
|
|
3915
|
+
*/
|
|
3916
|
+
public JavascriptDate(spreadsheet_date: number) {
|
|
3917
|
+
return LotusDate(spreadsheet_date).getTime();
|
|
3918
|
+
}
|
|
3919
|
+
|
|
3976
3920
|
/**
|
|
3977
3921
|
* Apply borders to range.
|
|
3978
3922
|
*
|
|
@@ -4607,7 +4551,13 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
4607
4551
|
|
|
4608
4552
|
this.UpdateAnnotations();
|
|
4609
4553
|
|
|
4554
|
+
// we don't really need to call UpdateConditionals here unless
|
|
4555
|
+
// something has changed in a previously inactive sheet -- right?
|
|
4556
|
+
|
|
4610
4557
|
this.calculator.UpdateConditionals();
|
|
4558
|
+
|
|
4559
|
+
// we do need to call apply (I think)
|
|
4560
|
+
|
|
4611
4561
|
this.ApplyConditionalFormats(event.activate, true);
|
|
4612
4562
|
|
|
4613
4563
|
}
|
|
@@ -5036,7 +4986,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
5036
4986
|
{
|
|
5037
4987
|
|
|
5038
4988
|
const chart = this.CreateChart();
|
|
5039
|
-
// const chart = new Chart();
|
|
5040
4989
|
chart.Initialize(view.content_node);
|
|
5041
4990
|
|
|
5042
4991
|
//if (this.calculator.RegisterLibrary('treb-charts', ChartFunctions)) {
|
|
@@ -5795,15 +5744,25 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
5795
5744
|
|
|
5796
5745
|
/**
|
|
5797
5746
|
* handle key down to intercept ctrl+z (undo)
|
|
5798
|
-
*
|
|
5747
|
+
* UPDATE: we're also handling F9 for recalc (optionally)
|
|
5748
|
+
*
|
|
5799
5749
|
* FIXME: redo (ctrl+y or ctrl+shift+z)
|
|
5800
5750
|
*/
|
|
5801
5751
|
protected HandleKeyDown(event: KeyboardEvent): void {
|
|
5752
|
+
|
|
5753
|
+
// can we drop the event.code stuff in 2024? (YES)
|
|
5754
|
+
|
|
5802
5755
|
if (event.ctrlKey && (event.code === 'KeyZ' || event.key === 'z')) {
|
|
5803
5756
|
event.stopPropagation();
|
|
5804
5757
|
event.preventDefault();
|
|
5805
5758
|
this.Undo();
|
|
5806
5759
|
}
|
|
5760
|
+
else if (event.key === 'F9' && this.options.recalculate_on_f9) {
|
|
5761
|
+
event.stopPropagation();
|
|
5762
|
+
event.preventDefault();
|
|
5763
|
+
this.Recalculate();
|
|
5764
|
+
}
|
|
5765
|
+
|
|
5807
5766
|
}
|
|
5808
5767
|
|
|
5809
5768
|
|
|
@@ -14,13 +14,19 @@
|
|
|
14
14
|
* You should have received a copy of the GNU General Public License along
|
|
15
15
|
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
16
|
*
|
|
17
|
-
* Copyright 2022-
|
|
17
|
+
* Copyright 2022-2024 trebco, llc.
|
|
18
18
|
* info@treb.app
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import type { ICellAddress } from 'treb-base-types';
|
|
23
23
|
import type { TREBDocument } from './types';
|
|
24
|
+
import type { ChartRenderer } from 'treb-charts';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* factory type for chart renderer, if you want instances (pass a constructor)
|
|
28
|
+
*/
|
|
29
|
+
export type ChartRendererFactory = () => ChartRenderer;
|
|
24
30
|
|
|
25
31
|
/**
|
|
26
32
|
* options for exporting CSV/TSV
|
|
@@ -275,6 +281,36 @@ export interface EmbeddedSpreadsheetOptions {
|
|
|
275
281
|
*/
|
|
276
282
|
revert_indicator?: boolean;
|
|
277
283
|
|
|
284
|
+
/**
|
|
285
|
+
* @internal
|
|
286
|
+
* overload the chart renderer with your own type (or a type factory method).
|
|
287
|
+
* use a factory if you are going to persist state in the renderer, otherwise
|
|
288
|
+
* you can just use a single instance.
|
|
289
|
+
*/
|
|
290
|
+
chart_renderer?: ChartRenderer|ChartRendererFactory;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @internal
|
|
294
|
+
*
|
|
295
|
+
* optional function to run before loading data. this is useful for example
|
|
296
|
+
* if you want to load some custom functions before a document is loaded
|
|
297
|
+
* from local storage. otherwise you'll get #NAME errors when an unknown
|
|
298
|
+
* function is loaded (I suppose you could recalc, but this is better).
|
|
299
|
+
*
|
|
300
|
+
* @privateRemarks
|
|
301
|
+
* I'd prefer to pass the instance as a parameter, but I don't want a
|
|
302
|
+
* circular reference here. maybe that's not an issue? for the time being
|
|
303
|
+
* we'll treat it as opaque.
|
|
304
|
+
*/
|
|
305
|
+
preload?: (instance: unknown) => void;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* handle the F9 key and recalculate the spreadsheet. for compatibility.
|
|
309
|
+
* we're leaving this option to default `false` for now, but that may
|
|
310
|
+
* change in the future. key modifiers have no effect.
|
|
311
|
+
*/
|
|
312
|
+
recalculate_on_f9?: boolean;
|
|
313
|
+
|
|
278
314
|
}
|
|
279
315
|
|
|
280
316
|
/**
|