@trebco/treb 30.15.0 → 31.0.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.
Files changed (52) hide show
  1. package/api-generator/api-generator.ts +3 -1
  2. package/api-generator/package.json +2 -1
  3. package/dist/treb-export-worker.mjs +2 -2
  4. package/dist/treb-spreadsheet.mjs +13 -13
  5. package/dist/treb.d.ts +19 -2
  6. package/package.json +8 -7
  7. package/treb-base-types/src/font-stack.ts +144 -0
  8. package/treb-base-types/src/style.ts +121 -11
  9. package/treb-base-types/src/theme.ts +53 -8
  10. package/treb-calculator/src/calculator.ts +13 -13
  11. package/treb-calculator/src/descriptors.ts +12 -4
  12. package/treb-calculator/src/expression-calculator.ts +17 -4
  13. package/treb-calculator/src/functions/base-functions.ts +57 -4
  14. package/treb-calculator/src/functions/statistics-functions.ts +9 -6
  15. package/treb-calculator/tsconfig.json +11 -0
  16. package/treb-charts/src/chart-functions.ts +41 -4
  17. package/treb-charts/src/chart-types.ts +20 -1
  18. package/treb-charts/src/chart-utils.ts +86 -9
  19. package/treb-charts/src/default-chart-renderer.ts +40 -1
  20. package/treb-charts/src/renderer.ts +3 -3
  21. package/treb-charts/style/charts.scss +7 -1
  22. package/treb-data-model/src/annotation.ts +6 -0
  23. package/treb-data-model/src/data_model.ts +14 -3
  24. package/treb-data-model/src/sheet.ts +57 -56
  25. package/treb-embed/markup/toolbar.html +15 -1
  26. package/treb-embed/src/custom-element/spreadsheet-constructor.ts +38 -0
  27. package/treb-embed/src/embedded-spreadsheet.ts +119 -29
  28. package/treb-embed/src/options.ts +3 -0
  29. package/treb-embed/src/selection-state.ts +1 -0
  30. package/treb-embed/src/toolbar-message.ts +6 -0
  31. package/treb-embed/src/types.ts +9 -0
  32. package/treb-embed/style/defaults.scss +12 -1
  33. package/treb-embed/style/font-stacks.scss +105 -0
  34. package/treb-embed/style/layout.scss +1 -0
  35. package/treb-embed/style/theme-defaults.scss +12 -2
  36. package/treb-embed/style/toolbar.scss +16 -0
  37. package/treb-grid/src/editors/overlay_editor.ts +36 -3
  38. package/treb-grid/src/layout/base_layout.ts +52 -37
  39. package/treb-grid/src/layout/grid_layout.ts +7 -0
  40. package/treb-grid/src/render/tile_renderer.ts +154 -148
  41. package/treb-grid/src/types/grid.ts +188 -54
  42. package/treb-grid/src/types/grid_events.ts +1 -1
  43. package/treb-grid/src/types/grid_options.ts +3 -0
  44. package/treb-grid/src/util/fontmetrics.ts +134 -0
  45. package/treb-parser/src/parser.ts +12 -3
  46. package/treb-utils/src/measurement.ts +2 -3
  47. package/tsproject.json +1 -1
  48. package/treb-calculator/modern.tsconfig.json +0 -11
  49. package/treb-grid/src/util/fontmetrics2.ts +0 -182
  50. package/treb-parser/src/parser.test.ts +0 -298
  51. /package/treb-embed/{modern.tsconfig.json → tsconfig.json} +0 -0
  52. /package/treb-export/{modern.tsconfig.json → tsconfig.json} +0 -0
@@ -41,6 +41,8 @@ import { CoerceComplex } from './function-utilities';
41
41
  import type { UnitAddress, UnitRange } from 'treb-parser';
42
42
  import { ConstructDate } from './date-utils';
43
43
 
44
+ // import type { CalculationContext } from '../descriptors';
45
+
44
46
  /**
45
47
  * BaseFunctionLibrary is a static object that has basic spreadsheet
46
48
  * functions and associated metadata (there's also a list of aliases).
@@ -1253,10 +1255,35 @@ export const BaseFunctionLibrary: FunctionMap = {
1253
1255
  },
1254
1256
  */
1255
1257
 
1256
-
1257
1258
  Row: {
1258
1259
  arguments: [{ name: 'reference', metadata: true }],
1259
- fn: (ref: UnionValue): UnionValue => {
1260
+ fn: function(ref?: UnionValue): UnionValue {
1261
+
1262
+ if (!ref) {
1263
+ if (this?.area) {
1264
+ const value: UnionValue[][] = [];
1265
+ for (let c = this.area.start.column; c <= this.area.end.column; c++) {
1266
+ const col: UnionValue[] = [];
1267
+ for (let r = this.area.start.row; r <= this.area.end.row; r++) {
1268
+ col.push({
1269
+ type: ValueType.number,
1270
+ value: r + 1,
1271
+ });
1272
+ }
1273
+ value.push(col);
1274
+ }
1275
+ return {
1276
+ type: ValueType.array, value,
1277
+ }
1278
+ }
1279
+ else {
1280
+ return {
1281
+ type: ValueType.number,
1282
+ value: this ? this.address.row + 1 : -1,
1283
+ };
1284
+ }
1285
+ }
1286
+
1260
1287
  if (ref.type === ValueType.array) {
1261
1288
  const arr = ref.value;
1262
1289
  const first = arr[0][0];
@@ -1283,7 +1310,33 @@ export const BaseFunctionLibrary: FunctionMap = {
1283
1310
 
1284
1311
  Column: {
1285
1312
  arguments: [{ name: 'reference', metadata: true }],
1286
- fn: (ref: UnionValue): UnionValue => {
1313
+ fn: function(ref?: UnionValue): UnionValue {
1314
+
1315
+ if (!ref) {
1316
+ if (this?.area) {
1317
+ const value: UnionValue[][] = [];
1318
+ for (let c = this.area.start.column; c <= this.area.end.column; c++) {
1319
+ const col: UnionValue[] = [];
1320
+ for (let r = this.area.start.row; r <= this.area.end.row; r++) {
1321
+ col.push({
1322
+ type: ValueType.number,
1323
+ value: c + 1,
1324
+ });
1325
+ }
1326
+ value.push(col);
1327
+ }
1328
+ return {
1329
+ type: ValueType.array, value,
1330
+ }
1331
+ }
1332
+ else {
1333
+ return {
1334
+ type: ValueType.number,
1335
+ value: this ? this.address.column + 1 : -1,
1336
+ };
1337
+ }
1338
+ }
1339
+
1287
1340
  if (ref.type === ValueType.array) {
1288
1341
  const arr = ref.value;
1289
1342
  const first = arr[0][0];
@@ -1307,7 +1360,7 @@ export const BaseFunctionLibrary: FunctionMap = {
1307
1360
  return ArgumentError();
1308
1361
  },
1309
1362
  },
1310
-
1363
+
1311
1364
  Choose: {
1312
1365
  arguments: [
1313
1366
  { name: 'Selected index', },
@@ -409,6 +409,7 @@ export const StatisticsFunctionLibrary: FunctionMap = {
409
409
  },
410
410
  },
411
411
 
412
+ /* use alias instead
412
413
  'NormsInv': {
413
414
 
414
415
  description: 'Inverse of the normal cumulative distribution',
@@ -423,7 +424,8 @@ export const StatisticsFunctionLibrary: FunctionMap = {
423
424
  }
424
425
  }
425
426
  },
426
-
427
+ */
428
+
427
429
  'Norm.Inv': {
428
430
  description: 'Inverse of the normal cumulative distribution',
429
431
  arguments: [
@@ -441,17 +443,15 @@ export const StatisticsFunctionLibrary: FunctionMap = {
441
443
  },
442
444
 
443
445
  'Norm.S.Inv': {
444
- description: 'Inverse of the normal cumulative distribution',
446
+ description: 'Inverse of the standard normal cumulative distribution',
445
447
  arguments: [
446
448
  {name: 'probability'},
447
- {name: 'mean', default: 0},
448
- {name: 'standard deviation', default: 1},
449
449
  ],
450
450
  xlfn: true,
451
- fn: (q: number, mean = 0, stdev = 1): UnionValue => {
451
+ fn: (q: number): UnionValue => {
452
452
  return {
453
453
  type: ValueType.number,
454
- value: inverse_normal(q) * stdev + mean,
454
+ value: inverse_normal(q),
455
455
  }
456
456
  }
457
457
  },
@@ -1073,4 +1073,7 @@ export const StatisticsFunctionAliases: {[index: string]: string} = {
1073
1073
  'StDevPA': 'StDev.P',
1074
1074
  'Var': 'Var.S',
1075
1075
  'Quartile': 'Quartile.Inc',
1076
+ 'NormSInv': 'Norm.S.Inv',
1077
+ 'NormSDist': 'Norm.S.Dist',
1078
+
1076
1079
  };
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../tsproject.json",
3
+ "references": [
4
+ { "path": "../treb-grid/tsconfig.json" },
5
+ { "path": "../treb-utils/tsconfig.json" }
6
+ ],
7
+ "include": [
8
+ "../treb-base-types/**/*.ts"
9
+ ]
10
+ }
11
+
@@ -48,7 +48,7 @@ export type ChartFunction
48
48
  | 'Box.Plot'
49
49
  ;
50
50
 
51
- type SupportFunction = 'Group'|'Series';
51
+ type SupportFunction = 'Group'|'Series' ; // |'Scatter.Series';
52
52
 
53
53
  /**
54
54
  * chart functions for registration
@@ -87,20 +87,57 @@ export const ChartFunctions: Record<ChartFunction|SupportFunction, CompositeFunc
87
87
  { name: 'X', metadata: true, },
88
88
  { name: 'Y', metadata: true, },
89
89
  { name: 'Z', metadata: true, },
90
- { name: 'index', },
91
- { name: 'subtype', },
90
+ { name: 'Index', },
91
+ { name: 'Subtype', },
92
92
  { name: 'Labels', description: 'Labels for bubble charts only (atm)' },
93
+ { name: 'Axis', description: `Series axis (scatter plot only)` },
93
94
  ],
94
95
  fn: (...args: unknown[]) => {
95
96
  return {
96
97
  type: ValueType.object,
97
- value: args,
98
+ value: {
99
+ label: args[0],
100
+ x: args[1],
101
+ y: args[2],
102
+ z: args[3],
103
+ index: args[4],
104
+ subtype: args[5],
105
+ data_labels: args[6],
106
+ axis: args[7],
107
+ },
98
108
  key: 'series',
99
109
  };
100
110
  },
101
111
  category: ['chart functions'],
102
112
  },
103
113
 
114
+ /*
115
+ 'Scatter.Series': {
116
+ arguments: [
117
+ { name: 'Label' }, // , metadata: true, },
118
+ { name: 'X', metadata: true, },
119
+ { name: 'Y', metadata: true, },
120
+ { name: 'index', },
121
+ { name: 'subtype', },
122
+ { name: 'axis', },
123
+ ],
124
+ fn: (...args: unknown[]) => {
125
+ return {
126
+ type: ValueType.object,
127
+ value: {
128
+ label: args[0],
129
+ x: args[1],
130
+ y: args[2],
131
+ index: args[3],
132
+ subtype: args[4],
133
+ axis: args[5],
134
+ },
135
+ key: 'series',
136
+ };
137
+ },
138
+ },
139
+ */
140
+
104
141
  'Bar.Chart': {
105
142
  arguments: [
106
143
  { name: 'Data', metadata: true, },
@@ -33,6 +33,18 @@ export interface ReferenceMetadata {
33
33
 
34
34
  export interface ReferenceSeries extends ExtendedUnion {
35
35
  key: 'series',
36
+ value: {
37
+ label?: string;
38
+ x?: UnionValue;
39
+ y?: UnionValue;
40
+ z?: UnionValue;
41
+ index?: number;
42
+ subtype?: string;
43
+ data_labels?: string[];
44
+ axis?: number;
45
+ }
46
+
47
+ /*
36
48
  value: [
37
49
  CellValue?, // { name: 'Label' }, // , metadata: true, },
38
50
  UnionValue?, // { name: 'X', metadata: true, },
@@ -42,6 +54,8 @@ export interface ReferenceSeries extends ExtendedUnion {
42
54
  CellValue?, // { name: 'subtype', },
43
55
  CellValue?, // { name: 'Labels', description: 'Labels for bubble charts only (atm)' },
44
56
  ];
57
+ */
58
+
45
59
  }
46
60
 
47
61
  export const IsMetadata = (value?: unknown): value is ExtendedUnion & { value: ReferenceMetadata } => {
@@ -54,7 +68,8 @@ export const IsMetadata = (value?: unknown): value is ExtendedUnion & { value: R
54
68
  export const IsSeries = (value?: unknown): value is ReferenceSeries => {
55
69
  return (!!value && (typeof value === 'object')
56
70
  && (value as ReferenceSeries).key === 'series'
57
- && Array.isArray((value as ReferenceSeries).value));
71
+ // && Array.isArray((value as ReferenceSeries).value));
72
+ && (typeof (value as ReferenceSeries).value === 'object'));
58
73
  };
59
74
 
60
75
  export const IsArrayUnion = (value?: unknown): value is ArrayUnion => {
@@ -140,9 +155,11 @@ export interface ScatterData2 extends ChartDataBaseType {
140
155
 
141
156
  x_scale: RangeScale;
142
157
  y_scale: RangeScale;
158
+ y2_scale?: RangeScale;
143
159
 
144
160
  x_labels?: string[];
145
161
  y_labels?: string[];
162
+ y2_labels?: string[];
146
163
 
147
164
  style?: 'plot'|'line'|'area';
148
165
 
@@ -311,8 +328,10 @@ export interface SeriesType {
311
328
  subtype?: string;
312
329
  x: SubSeries;
313
330
  y: SubSeries;
331
+ y2?: SubSeries;
314
332
  z?: SubSeries;
315
333
  index?: number;
316
334
  labels?: string[];
335
+ axis?: number;
317
336
  }
318
337
 
@@ -61,8 +61,10 @@ export const ArrayMinMax = (data: number[]) => {
61
61
 
62
62
  export const ReadSeries = (data: ReferenceSeries['value']): SeriesType => {
63
63
 
64
- const [label, x, y, z, index, subtype, data_labels] = data;
64
+ // const label, x, y, z, index, subtype, data_labels] = data;
65
65
 
66
+ const { label, x, y, z, index, subtype, data_labels, axis } = data;
67
+
66
68
  // series type is (now)
67
69
  //
68
70
  // [0] label, string
@@ -79,6 +81,10 @@ export const ReadSeries = (data: ReferenceSeries['value']): SeriesType => {
79
81
  y: { data: [] },
80
82
  };
81
83
 
84
+ if (typeof axis === 'number') {
85
+ series.axis = axis;
86
+ }
87
+
82
88
  if (typeof index === 'number') {
83
89
  series.index = index;
84
90
  }
@@ -431,10 +437,22 @@ export const CommonData = (series: SeriesType[], y_floor?: number, y_ceiling?: n
431
437
 
432
438
  let x_format = '';
433
439
  let y_format = '';
440
+ let y2_format = '';
434
441
 
435
442
  for (const entry of series) {
436
- if (entry.y.format && !y_format) { y_format = entry.y.format; }
437
- if (entry.x.format && !x_format) { x_format = entry.x.format; }
443
+ if (entry.axis) {
444
+ if (entry.y.format && !y2_format) {
445
+ y2_format = entry.y.format;
446
+ }
447
+ }
448
+ else {
449
+ if (entry.y.format && !y_format) {
450
+ y_format = entry.y.format;
451
+ }
452
+ }
453
+ if (entry.x.format && !x_format) {
454
+ x_format = entry.x.format;
455
+ }
438
456
  }
439
457
 
440
458
  let legend: Array<{ label: string, index?: number }> | undefined; // string[]|undefined;
@@ -449,13 +467,25 @@ export const CommonData = (series: SeriesType[], y_floor?: number, y_ceiling?: n
449
467
  let x_min = Math.min.apply(0, x.map(test => test.x.range?.min || 0));
450
468
  let x_max = Math.max.apply(0, x.map(test => test.x.range?.max || 0));
451
469
 
452
- // const y = series.filter(test => test.y.range);
453
- let y_min = Math.min.apply(0, x.map(test => test.y.range?.min || 0));
454
- let y_max = Math.max.apply(0, x.map(test => test.y.range?.max || 0));
470
+ const x1 = x.filter(test => !test.axis);
471
+ const x2 = x.filter(test => test.axis);
472
+
473
+ let y_min = Math.min.apply(0, x1.map(test => test.y.range?.min || 0));
474
+ let y_max = Math.max.apply(0, x1.map(test => test.y.range?.max || 0));
475
+
476
+ let y2_min = -1;
477
+ let y2_max = -1;
478
+
479
+ if (x2.length) {
480
+ y2_min = Math.min.apply(0, x2.map(test => test.y.range?.min || 0));
481
+ y2_max = Math.max.apply(0, x2.map(test => test.y.range?.max || 0));
482
+ }
455
483
 
456
484
  // if there's z data (used for bubble size), adjust x/y min/max to
457
485
  // account for the z size so bubbles are contained within the grid
458
486
 
487
+ // this can't be used with axis (atm)
488
+
459
489
  for (const subseries of series) {
460
490
  if (subseries.z) {
461
491
  for (const [index, z] of subseries.z.data.entries()) {
@@ -496,9 +526,29 @@ export const CommonData = (series: SeriesType[], y_floor?: number, y_ceiling?: n
496
526
 
497
527
  const x_scale = Util.Scale(x_min, x_max, 7);
498
528
  const y_scale = Util.Scale(y_min, y_max, 7);
529
+ const y2_scale = Util.Scale(y2_min, y2_max, 7);
530
+
531
+ if (y2_min !== y2_max && y_scale && y2_scale) {
532
+ if (y_scale.count !== y2_scale.count) {
533
+ const max = Math.max(y_scale.count, y2_scale.count);
534
+ const target = y_scale.count < max ? y_scale : y2_scale;
535
+ for (let i = target.count; i < max; i += 2) {
536
+ // add high
537
+ target.max += target.step;
538
+ target.count++;
539
+
540
+ if (target.count < max) {
541
+ // add low
542
+ target.min -= target.step;
543
+ target.count++;
544
+ }
545
+ }
546
+ }
547
+ }
499
548
 
500
549
  let x_labels: string[] | undefined;
501
550
  let y_labels: string[] | undefined;
551
+ let y2_labels: string[] | undefined;
502
552
 
503
553
  if (x_format) {
504
554
  x_labels = [];
@@ -509,10 +559,13 @@ export const CommonData = (series: SeriesType[], y_floor?: number, y_ceiling?: n
509
559
  }
510
560
 
511
561
  if (!y_format && auto_number_format) {
512
- // y_format = default_number_format;
513
562
  y_format = AutoFormat(y_scale);
514
563
  }
515
564
 
565
+ if (!y2_format && auto_number_format) {
566
+ y2_format = AutoFormat(y2_scale);
567
+ }
568
+
516
569
  if (y_format) {
517
570
  y_labels = [];
518
571
  const format = NumberFormatCache.Get(y_format);
@@ -520,8 +573,20 @@ export const CommonData = (series: SeriesType[], y_floor?: number, y_ceiling?: n
520
573
  y_labels.push(format.Format(y_scale.min + i * y_scale.step));
521
574
  }
522
575
  }
576
+ if (y2_format) {
577
+ y2_labels = [];
578
+ const format = NumberFormatCache.Get(y2_format);
579
+ for (let i = 0; i <= y2_scale.count; i++) {
580
+ y2_labels.push(format.Format(y2_scale.min + i * y2_scale.step));
581
+ }
582
+ }
523
583
 
524
- return {
584
+ const result: {
585
+ legend?: { label: string, index?: number }[],
586
+ x: { format: string, scale: RangeScale, labels?: string[] },
587
+ y: { format: string, scale: RangeScale, labels?: string[] },
588
+ y2?: { format: string, scale: RangeScale, labels?: string[] },
589
+ } = {
525
590
  x: {
526
591
  format: x_format,
527
592
  scale: x_scale,
@@ -535,6 +600,16 @@ export const CommonData = (series: SeriesType[], y_floor?: number, y_ceiling?: n
535
600
  legend,
536
601
  };
537
602
 
603
+ if (y2_min !== y2_max) {
604
+ result.y2 = {
605
+ format: y2_format,
606
+ scale: y2_scale,
607
+ labels: y2_labels,
608
+ };
609
+ }
610
+
611
+ return result;
612
+
538
613
  };
539
614
 
540
615
  const ApplyLabels = (series_list: SeriesType[], pattern: string, category_labels?: string[]): void => {
@@ -859,7 +934,6 @@ export const CreateScatterChart = (args: [UnionValue, string, string], style: 'p
859
934
  // transform).
860
935
 
861
936
  const series: SeriesType[] = TransformSeriesData(args[0]);
862
-
863
937
  const common = CommonData(series);
864
938
 
865
939
  const title = args[1]?.toString() || undefined;
@@ -878,6 +952,9 @@ export const CreateScatterChart = (args: [UnionValue, string, string], style: 'p
878
952
  y_scale: common.y.scale,
879
953
  y_labels: common.y.labels,
880
954
 
955
+ y2_scale: common.y2?.scale,
956
+ y2_labels: common.y2?.labels,
957
+
881
958
  lines: style === 'line', // true,
882
959
  points: style === 'plot',
883
960
 
@@ -175,6 +175,44 @@ export class DefaultChartRenderer implements ChartRendererType {
175
175
 
176
176
  }
177
177
 
178
+ if (chart_data.type === 'scatter2' && chart_data.y2_labels && chart_data.y2_labels.length && chart_data.y2_scale) {
179
+
180
+ const y2_labels: Array<{label: string; metrics: Metrics}> = [];
181
+ let max_width = 0;
182
+ let max_height = 0;
183
+
184
+ const scale = chart_data.y2_scale;
185
+
186
+ const count = scale.count + 1;
187
+
188
+ for (let i = 0; i < count; i++ ){
189
+ const metrics = this.renderer.MeasureText(chart_data.y2_labels[i], ['axis-label', 'y-axis-label']);
190
+ y2_labels.push({ label: chart_data.y2_labels[i], metrics });
191
+ max_width = Math.max(max_width, metrics.width);
192
+ max_height = Math.max(max_height, metrics.height);
193
+ }
194
+
195
+ /*
196
+ area.bottom = Math.round(area.bottom - max_height / 2);
197
+ area.top = Math.round(area.top + max_height / 2);
198
+
199
+ if (x_metrics.length) {
200
+ area.bottom -= (max_x_height + chart_margin.bottom);
201
+ }
202
+ if (x_metrics2.length) {
203
+ area.bottom -= (max_x_height2 + chart_margin.bottom);
204
+ }
205
+ if (extra_padding) {
206
+ area.bottom -= extra_padding;
207
+ }
208
+ */
209
+
210
+ this.renderer.RenderYAxis(area, area.right - max_width, y2_labels, ['axis-label', 'y-axis-label'], 'left');
211
+ area.right -= (max_width + chart_margin.left);
212
+ // area.left += (max_width + chart_margin.left);
213
+
214
+ }
215
+
178
216
  // now render x axis
179
217
 
180
218
  if (x_metrics.length && chart_data.x_labels?.length) {
@@ -318,11 +356,12 @@ export class DefaultChartRenderer implements ChartRendererType {
318
356
  }
319
357
 
320
358
  const index = typeof series.index === 'number' ? series.index : i + 1;
359
+
321
360
  this.renderer.RenderScatterSeries(area,
322
361
  series.x.data,
323
362
  series.y.data,
324
363
  chart_data.x_scale,
325
- chart_data.y_scale,
364
+ (series.axis && chart_data.y2_scale) ? chart_data.y2_scale : chart_data.y_scale,
326
365
  lines,
327
366
  points,
328
367
  !!chart_data.filled,
@@ -577,11 +577,11 @@ export class ChartRenderer {
577
577
  /**
578
578
  * render y axis labels; skips over labels to prevent overlap
579
579
  */
580
- public RenderYAxis(area: Area, left: number,
580
+ public RenderYAxis(area: Area, x: number,
581
581
  labels: Array<{
582
582
  label: string;
583
583
  metrics: Metrics;
584
- }>, classes?: string | string[]) {
584
+ }>, classes?: string | string[], align:'left'|'right' = 'right') {
585
585
 
586
586
  const count = labels.length;
587
587
  if (!count) return;
@@ -612,7 +612,7 @@ export class ChartRenderer {
612
612
  for (let i = 0; i < count; i += increment) {
613
613
  const label = labels[i];
614
614
  const y = Math.round(area.bottom - step * i + label.metrics.height / 4);
615
- this.RenderText(this.axis_group, label.label, 'right', { x: left, y }, classes);
615
+ this.RenderText(this.axis_group, label.label, align, { x, y }, classes);
616
616
  }
617
617
 
618
618
  }
@@ -43,8 +43,14 @@
43
43
  // this was getting lost by the new higher-specificity reset
44
44
  background: var(--treb-chart-background, #fff);
45
45
 
46
- }
46
+ }
47
47
 
48
+ /**
49
+ * new override allows inheriting fonts in annotations (at least for charts)
50
+ */
51
+ .treb-main.treb-main .treb-inherit-font .treb-chart {
52
+ font-family: inherit;
53
+ }
48
54
 
49
55
  /* container style */
50
56
  .treb-chart {
@@ -117,6 +117,12 @@ export interface AnnotationDataBase {
117
117
  /** the new layout, persisted and takes preference over the old one */
118
118
  layout?: AnnotationLayout;
119
119
 
120
+ /**
121
+ * adding cell style as a convenient store for font stack; atm we are
122
+ * ignoring everything but the font_face attribute
123
+ */
124
+ style?: CellStyle;
125
+
120
126
  /**
121
127
  * the old layout used rectangles, and we need to keep support for
122
128
  * that. this is not the layout rectangle. this rectangle is just
@@ -435,8 +435,8 @@ export class DataModel {
435
435
  }
436
436
 
437
437
  /** wrapper method ensures it always returns an Area (instance, not interface) */
438
- public ResolveArea(address: string|ICellAddress|IArea, active_sheet: Sheet): Area {
439
- const resolved = this.ResolveAddress(address, active_sheet);
438
+ public ResolveArea(address: string|ICellAddress|IArea, active_sheet: Sheet, options?: { r1c1?: boolean }): Area {
439
+ const resolved = this.ResolveAddress(address, active_sheet, options);
440
440
  return IsCellAddress(resolved) ? new Area(resolved) : new Area(resolved.start, resolved.end);
441
441
  }
442
442
 
@@ -449,10 +449,21 @@ export class DataModel {
449
449
  * Q: why are we not preserving absoute/relative? (...)
450
450
  *
451
451
  */
452
- public ResolveAddress(address: string|ICellAddress|IArea, active_sheet: Sheet): ICellAddress|IArea {
452
+ public ResolveAddress(address: string|ICellAddress|IArea, active_sheet: Sheet, options? : { r1c1?: boolean }): ICellAddress|IArea {
453
453
 
454
454
  if (typeof address === 'string') {
455
+
456
+ if (options?.r1c1) {
457
+ this.parser.Save();
458
+ this.parser.flags.r1c1 = true;
459
+ }
460
+
455
461
  const parse_result = this.parser.Parse(address);
462
+
463
+ if (options?.r1c1) {
464
+ this.parser.Restore();
465
+ }
466
+
456
467
  if (parse_result.expression && parse_result.expression.type === 'address') {
457
468
  this.ResolveSheetID(parse_result.expression, undefined, active_sheet);
458
469
  return {