@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.
Files changed (168) hide show
  1. package/dist/treb-spreadsheet-light.mjs +15 -15
  2. package/dist/treb-spreadsheet.mjs +15 -15
  3. package/dist/treb.d.ts +37 -6
  4. package/package.json +1 -1
  5. package/treb-base-types/src/api_types.ts +1 -1
  6. package/treb-base-types/src/area.ts +1 -1
  7. package/treb-base-types/src/basic_types.ts +21 -21
  8. package/treb-base-types/src/cell.ts +1 -1
  9. package/treb-base-types/src/cells.ts +1 -1
  10. package/treb-base-types/src/color.ts +1 -1
  11. package/treb-base-types/src/dom-utilities.ts +1 -1
  12. package/treb-base-types/src/gradient.ts +1 -1
  13. package/treb-base-types/src/import.ts +1 -1
  14. package/treb-base-types/src/index-standalone.ts +9 -9
  15. package/treb-base-types/src/index.ts +1 -1
  16. package/treb-base-types/src/layout.ts +21 -21
  17. package/treb-base-types/src/localization.ts +27 -21
  18. package/treb-base-types/src/rectangle.ts +1 -1
  19. package/treb-base-types/src/render_text.ts +1 -1
  20. package/treb-base-types/src/style.ts +1 -1
  21. package/treb-base-types/src/table.ts +1 -1
  22. package/treb-base-types/src/text_part.ts +21 -21
  23. package/treb-base-types/src/theme.ts +1 -1
  24. package/treb-base-types/src/union.ts +1 -1
  25. package/treb-base-types/src/value-type.ts +1 -1
  26. package/treb-base-types/style/resizable.css +21 -21
  27. package/treb-calculator/src/calculator.ts +24 -31
  28. package/treb-calculator/src/complex-math.ts +1 -1
  29. package/treb-calculator/src/dag/array-vertex.ts +1 -1
  30. package/treb-calculator/src/dag/calculation_leaf_vertex.ts +8 -1
  31. package/treb-calculator/src/dag/graph.ts +8 -1
  32. package/treb-calculator/src/dag/spreadsheet_vertex.ts +1 -1
  33. package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +21 -21
  34. package/treb-calculator/src/dag/state_leaf_vertex.ts +1 -1
  35. package/treb-calculator/src/dag/vertex.ts +21 -21
  36. package/treb-calculator/src/descriptors.ts +1 -1
  37. package/treb-calculator/src/expression-calculator.ts +1 -1
  38. package/treb-calculator/src/function-error.ts +1 -1
  39. package/treb-calculator/src/function-library.ts +1 -1
  40. package/treb-calculator/src/functions/base-functions.ts +31 -2
  41. package/treb-calculator/src/functions/checkbox.ts +1 -1
  42. package/treb-calculator/src/functions/complex-functions.ts +1 -1
  43. package/treb-calculator/src/functions/finance-functions.ts +1 -1
  44. package/treb-calculator/src/functions/information-functions.ts +1 -1
  45. package/treb-calculator/src/functions/matrix-functions.ts +1 -1
  46. package/treb-calculator/src/functions/sparkline.ts +1 -1
  47. package/treb-calculator/src/functions/statistics-functions.ts +1 -1
  48. package/treb-calculator/src/functions/text-functions.ts +1 -1
  49. package/treb-calculator/src/index.ts +1 -1
  50. package/treb-calculator/src/notifier-types.ts +1 -1
  51. package/treb-calculator/src/primitives.ts +1 -1
  52. package/treb-calculator/src/utilities.ts +1 -1
  53. package/treb-charts/src/chart-functions.ts +12 -1
  54. package/treb-charts/src/chart-types.ts +39 -21
  55. package/treb-charts/src/chart-utils.ts +783 -0
  56. package/treb-charts/src/chart.ts +96 -1291
  57. package/treb-charts/src/default-chart-renderer.ts +560 -0
  58. package/treb-charts/src/index.ts +5 -4
  59. package/treb-charts/src/main.ts +17 -17
  60. package/treb-charts/src/rectangle.ts +21 -21
  61. package/treb-charts/src/renderer-type.ts +32 -0
  62. package/treb-charts/src/renderer.ts +82 -1
  63. package/treb-charts/src/util.ts +1 -1
  64. package/treb-charts/style/charts.scss +9 -1
  65. package/treb-charts/style/old-charts.scss +21 -21
  66. package/treb-embed/markup/toolbar.html +35 -34
  67. package/treb-embed/src/custom-element/treb-global.ts +10 -2
  68. package/treb-embed/src/embedded-spreadsheet.ts +72 -113
  69. package/treb-embed/src/language-model.ts +1 -1
  70. package/treb-embed/src/options.ts +37 -1
  71. package/treb-embed/src/progress-dialog.ts +1 -1
  72. package/treb-embed/src/spinner.ts +1 -1
  73. package/treb-embed/src/types.ts +1 -1
  74. package/treb-embed/style/autocomplete.scss +1 -1
  75. package/treb-embed/style/dark-theme.scss +1 -1
  76. package/treb-embed/style/defaults.scss +1 -1
  77. package/treb-embed/style/dialog.scss +1 -1
  78. package/treb-embed/style/dropdown-select.scss +1 -1
  79. package/treb-embed/style/formula-bar.scss +1 -1
  80. package/treb-embed/style/grid.scss +1 -1
  81. package/treb-embed/style/layout.scss +4 -0
  82. package/treb-embed/style/mouse-mask.scss +1 -1
  83. package/treb-embed/style/note.scss +1 -1
  84. package/treb-embed/style/overlay-editor.scss +1 -1
  85. package/treb-embed/style/spinner.scss +1 -1
  86. package/treb-embed/style/tab-bar.scss +1 -1
  87. package/treb-embed/style/table.scss +1 -1
  88. package/treb-embed/style/theme-defaults.scss +1 -1
  89. package/treb-embed/style/toolbar.scss +37 -0
  90. package/treb-embed/style/tooltip.scss +1 -1
  91. package/treb-embed/style/z-index.scss +1 -1
  92. package/treb-export/src/address-type.ts +21 -21
  93. package/treb-export/src/base-template.ts +1 -1
  94. package/treb-export/src/column-width.ts +1 -1
  95. package/treb-export/src/drawing2/chart-template-components2.ts +1 -1
  96. package/treb-export/src/drawing2/chart2.ts +1 -1
  97. package/treb-export/src/drawing2/column-chart-template2.ts +1 -1
  98. package/treb-export/src/drawing2/donut-chart-template2.ts +1 -1
  99. package/treb-export/src/drawing2/drawing2.ts +1 -1
  100. package/treb-export/src/drawing2/embedded-image.ts +1 -1
  101. package/treb-export/src/drawing2/scatter-chart-template2.ts +1 -1
  102. package/treb-export/src/export-worker/export-worker.ts +1 -1
  103. package/treb-export/src/export-worker/index.worker.ts +1 -1
  104. package/treb-export/src/export2.ts +1 -1
  105. package/treb-export/src/import2.ts +1 -1
  106. package/treb-export/src/relationship.ts +1 -1
  107. package/treb-export/src/shared-strings2.ts +1 -1
  108. package/treb-export/src/template-2.ts +2 -2
  109. package/treb-export/src/workbook-sheet2.ts +1 -1
  110. package/treb-export/src/workbook-style2.ts +1 -1
  111. package/treb-export/src/workbook-theme2.ts +1 -1
  112. package/treb-export/src/workbook2.ts +1 -1
  113. package/treb-export/src/xml-utils.ts +1 -1
  114. package/treb-format/src/format.test.ts +21 -21
  115. package/treb-format/src/format.ts +1 -1
  116. package/treb-format/src/format_cache.ts +21 -21
  117. package/treb-format/src/format_parser.ts +1 -1
  118. package/treb-format/src/index.ts +4 -4
  119. package/treb-format/src/number_format_section.ts +21 -21
  120. package/treb-format/src/value_parser.ts +1 -1
  121. package/treb-grid/src/editors/autocomplete.ts +1 -1
  122. package/treb-grid/src/editors/autocomplete_matcher.ts +21 -21
  123. package/treb-grid/src/editors/editor.ts +1 -1
  124. package/treb-grid/src/editors/formula_bar.ts +1 -1
  125. package/treb-grid/src/editors/overlay_editor.ts +1 -1
  126. package/treb-grid/src/index.ts +1 -1
  127. package/treb-grid/src/layout/base_layout.ts +1 -1
  128. package/treb-grid/src/layout/grid_layout.ts +1 -1
  129. package/treb-grid/src/layout/rectangle_cache.ts +21 -21
  130. package/treb-grid/src/render/selection-renderer.ts +1 -1
  131. package/treb-grid/src/render/svg_header_overlay.ts +1 -1
  132. package/treb-grid/src/render/svg_selection_block.ts +1 -1
  133. package/treb-grid/src/render/tile_renderer.ts +1 -1
  134. package/treb-grid/src/types/annotation.ts +1 -1
  135. package/treb-grid/src/types/border_constants.ts +1 -1
  136. package/treb-grid/src/types/clipboard_data.ts +1 -1
  137. package/treb-grid/src/types/conditional_format.ts +1 -1
  138. package/treb-grid/src/types/data_model.ts +1 -1
  139. package/treb-grid/src/types/drag_mask.ts +21 -21
  140. package/treb-grid/src/types/grid.ts +12 -2
  141. package/treb-grid/src/types/grid_base.ts +128 -6
  142. package/treb-grid/src/types/grid_command.ts +33 -1
  143. package/treb-grid/src/types/grid_events.ts +8 -1
  144. package/treb-grid/src/types/grid_options.ts +9 -1
  145. package/treb-grid/src/types/grid_selection.ts +1 -1
  146. package/treb-grid/src/types/named_range.ts +1 -1
  147. package/treb-grid/src/types/scale-control.ts +1 -1
  148. package/treb-grid/src/types/serialize_options.ts +1 -1
  149. package/treb-grid/src/types/set_range_options.ts +1 -1
  150. package/treb-grid/src/types/sheet.ts +1 -57
  151. package/treb-grid/src/types/sheet_types.ts +1 -1
  152. package/treb-grid/src/types/tab_bar.ts +1 -1
  153. package/treb-grid/src/types/tile.ts +21 -21
  154. package/treb-grid/src/types/update_flags.ts +2 -1
  155. package/treb-grid/src/util/fontmetrics2.ts +1 -1
  156. package/treb-grid/src/util/ua.ts +21 -21
  157. package/treb-parser/src/csv-parser.ts +21 -21
  158. package/treb-parser/src/index.ts +5 -5
  159. package/treb-parser/src/md-parser.ts +1 -1
  160. package/treb-parser/src/parser-types.ts +1 -1
  161. package/treb-parser/src/parser.test.ts +21 -21
  162. package/treb-parser/src/parser.ts +1 -1
  163. package/treb-utils/src/event_source.ts +1 -1
  164. package/treb-utils/src/ievent_source.ts +13 -13
  165. package/treb-utils/src/index.ts +1 -1
  166. package/treb-utils/src/measurement.ts +1 -1
  167. package/treb-utils/src/scale.ts +21 -21
  168. 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-2023 trebco, llc.
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>,
@@ -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-2023 trebco, llc.
17
+ * Copyright 2022-2024 trebco, llc.
18
18
  * info@treb.app
19
19
  *
20
20
  */
@@ -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-2023 trebco, llc.
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-2023 trebco, llc.
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
- * build version
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
- * create a spreadsheet instance
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-2023 trebco, llc.
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
- /** opaque user data (metadata) */
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
- /** opaque user data (metadata) */
495
- public set user_data(data: USER_DATA_TYPE) {
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
- // moved up so we can share parser w/ grid
1034
-
1035
- // this.calculator = this.InitCalculator();
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
- const sheet = this.model.sheets.Find(format.area.start.sheet_id||0);
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
- const area = format.area;
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,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-2023 trebco, llc.
17
+ * Copyright 2022-2024 trebco, llc.
18
18
  * info@treb.app
19
19
  *
20
20
  */
@@ -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-2023 trebco, llc.
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
  /**
@@ -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-2023 trebco, llc.
17
+ * Copyright 2022-2024 trebco, llc.
18
18
  * info@treb.app
19
19
  *
20
20
  */