@malloydata/render 0.0.99-dev231102165615 → 0.0.99-dev231102185815

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.
@@ -1,19 +1,35 @@
1
- import { DataColumn, Field, SortableField } from '@malloydata/malloy';
1
+ import { DataColumn, DataRecord, Field, SortableField } from '@malloydata/malloy';
2
2
  import { StyleDefaults } from '../data_styles';
3
3
  import { ContainerRenderer } from './container';
4
- import { Renderer } from '../renderer';
4
+ import { ChildRenderers, Renderer } from '../renderer';
5
+ declare class FlattenedColumnField {
6
+ readonly flattenedField: Field;
7
+ readonly field: Field;
8
+ readonly name: string;
9
+ constructor(flattenedField: Field, field: Field, name: string);
10
+ isFlattenedColumnField(): this is FlattenedColumnField;
11
+ getChildRenderer(childRenderers: ChildRenderers): Renderer;
12
+ getValue(row: DataRecord): DataColumn;
13
+ }
14
+ type NonDimension = SortableField & {
15
+ flattenedField?: FlattenedColumnField;
16
+ };
5
17
  export declare class HTMLTableRenderer extends ContainerRenderer {
6
18
  protected childrenStyleDefaults: StyleDefaults;
7
19
  render(table: DataColumn): Promise<HTMLElement>;
8
20
  calculatePivotDimensions(table: DataColumn, userSpecifiedDimensions?: Array<string>): {
9
21
  dimensions: SortableField[];
10
- nonDimensions: SortableField[];
22
+ nonDimensions: NonDimension[];
11
23
  };
12
24
  generatePivotedCells(table: DataColumn, shouldTranspose: boolean, userSpecifiedDimensions?: Array<string>): Promise<Map<string, Map<string, HTMLTableCellElement>>>;
13
25
  generateNoValueCell(field: Field, shouldTranspose: boolean): HTMLTableCellElement;
14
26
  createCellAndRender(childRenderer: Renderer, value: DataColumn, shouldTranspose: boolean): Promise<HTMLTableCellElement>;
15
27
  createEmptyHeaderCell(): HTMLTableCellElement;
16
- createHeaderCell(field: Field, shouldTranspose: boolean): HTMLTableCellElement;
28
+ createHeaderCell(field: Field, shouldTranspose: boolean, override?: {
29
+ name?: string;
30
+ childRenderer?: Renderer;
31
+ }): HTMLTableCellElement;
17
32
  createCell(childRenderer: Renderer, shouldTranspose: boolean): HTMLTableCellElement;
18
33
  renderChild(value: DataColumn): Promise<HTMLElement>;
19
34
  }
35
+ export {};
@@ -53,6 +53,38 @@ class PivotedColumnField {
53
53
  return this instanceof PivotedColumnField;
54
54
  }
55
55
  }
56
+ class FlattenedColumnField {
57
+ constructor(flattenedField, field, name) {
58
+ this.flattenedField = flattenedField;
59
+ this.field = field;
60
+ this.name = name;
61
+ }
62
+ isFlattenedColumnField() {
63
+ return this instanceof FlattenedColumnField;
64
+ }
65
+ getChildRenderer(childRenderers) {
66
+ const baseRenderer = childRenderers[this.flattenedField.name];
67
+ if (baseRenderer instanceof HTMLTableRenderer) {
68
+ return baseRenderer.childRenderers[this.field.name];
69
+ }
70
+ else {
71
+ throw Error('Could not render flattened table. `# flatten` only supports nests.');
72
+ }
73
+ }
74
+ getValue(row) {
75
+ const parentRecord = row.cell(this.flattenedField);
76
+ if (parentRecord.isRecord())
77
+ return parentRecord.cell(this.field);
78
+ else
79
+ throw Error('Cannot find nested record within flattened field. `# flatten` only supports nests with no group_bys.');
80
+ }
81
+ }
82
+ function shouldFlattenField(field) {
83
+ const { tag } = field.tagParse();
84
+ return (field.isExploreField() &&
85
+ tag.has('flatten') &&
86
+ field.structDef.structSource.type === 'inline');
87
+ }
56
88
  class HTMLTableRenderer extends container_1.ContainerRenderer {
57
89
  constructor() {
58
90
  super(...arguments);
@@ -61,7 +93,7 @@ class HTMLTableRenderer extends container_1.ContainerRenderer {
61
93
  };
62
94
  }
63
95
  async render(table) {
64
- var _a;
96
+ var _a, _b, _c;
65
97
  if (table.isNull()) {
66
98
  return this.document.createElement('span');
67
99
  }
@@ -144,12 +176,27 @@ class HTMLTableRenderer extends container_1.ContainerRenderer {
144
176
  for (const pf of sortedPivotedFields) {
145
177
  for (const nonDimension of nonDimensions) {
146
178
  columnFields.push(new PivotedColumnField(pf, nonDimension.field, userDefinedDimensions));
147
- cells[rowIndex][columnIndex] = childRenderer.createHeaderCell(nonDimension.field, shouldTranspose);
179
+ cells[rowIndex][columnIndex] = childRenderer.createHeaderCell(nonDimension.field, shouldTranspose, {
180
+ name: (_a = nonDimension.flattenedField) === null || _a === void 0 ? void 0 : _a.name,
181
+ childRenderer: (_b = nonDimension.flattenedField) === null || _b === void 0 ? void 0 : _b.getChildRenderer(childRenderer.childRenderers),
182
+ });
148
183
  columnIndex++;
149
184
  }
150
185
  }
151
186
  pivotDepth = Math.max(pivotDepth, dimensions.length);
152
187
  }
188
+ else if (shouldFlattenField(field)) {
189
+ const parentField = field;
190
+ const flattenedFields = parentField.allFields.map(f => new FlattenedColumnField(parentField, f, `${parentField.name} ${f.name}`));
191
+ for (const flatField of flattenedFields) {
192
+ cells[rowIndex][columnIndex] = this.createHeaderCell(flatField.field, shouldTranspose, {
193
+ name: flatField.name,
194
+ childRenderer: flatField.getChildRenderer(this.childRenderers),
195
+ });
196
+ columnFields.push(flatField);
197
+ columnIndex++;
198
+ }
199
+ }
153
200
  else {
154
201
  cells[rowIndex][columnIndex] = this.createHeaderCell(field, shouldTranspose);
155
202
  columnFields.push(field);
@@ -230,7 +277,7 @@ class HTMLTableRenderer extends container_1.ContainerRenderer {
230
277
  }
231
278
  const pfKey = field.pivotedField.key;
232
279
  if (pivotedCells.has(pfKey) &&
233
- ((_a = pivotedCells.get(pfKey)) === null || _a === void 0 ? void 0 : _a.has(field.field.name))) {
280
+ ((_c = pivotedCells.get(pfKey)) === null || _c === void 0 ? void 0 : _c.has(field.field.name))) {
234
281
  cells[rowIndex][columnIndex] = pivotedCells
235
282
  .get(pfKey)
236
283
  .get(field.field.name);
@@ -241,6 +288,10 @@ class HTMLTableRenderer extends container_1.ContainerRenderer {
241
288
  columnIndex++;
242
289
  // back
243
290
  }
291
+ else if (field instanceof FlattenedColumnField) {
292
+ cells[rowIndex][columnIndex] = await this.createCellAndRender(field.getChildRenderer(this.childRenderers), field.getValue(row), shouldTranspose);
293
+ columnIndex++;
294
+ }
244
295
  else {
245
296
  if ((0, tags_utils_1.isFieldHidden)(field)) {
246
297
  continue;
@@ -318,7 +369,22 @@ class HTMLTableRenderer extends container_1.ContainerRenderer {
318
369
  else {
319
370
  dimensions = table.field.dimensions;
320
371
  }
321
- const nonDimensions = table.field.allFieldsWithOrder.filter(f => dimensions.indexOf(f) < 0);
372
+ const nonDimensions = [];
373
+ for (const f of table.field.allFieldsWithOrder) {
374
+ if (dimensions.indexOf(f) >= 0)
375
+ continue;
376
+ if (shouldFlattenField(f.field)) {
377
+ const nestedFields = f.field.allFieldsWithOrder.map(nf => ({
378
+ dir: nf.dir,
379
+ field: nf.field,
380
+ flattenedField: new FlattenedColumnField(f.field, nf.field, `${f.field.name} ${nf.field.name}`),
381
+ }));
382
+ nonDimensions.push(...nestedFields);
383
+ }
384
+ else {
385
+ nonDimensions.push(f);
386
+ }
387
+ }
322
388
  if (nonDimensions.length === 0) {
323
389
  throw new Error(`Can not pivot ${table.field.name} since all of its fields are dimensions.`);
324
390
  }
@@ -336,9 +402,18 @@ class HTMLTableRenderer extends container_1.ContainerRenderer {
336
402
  for (const row of table) {
337
403
  const pf = new PivotedField(table.field, dimensions.map(f => row.cell(f.field.name)), nonDimensions.length);
338
404
  const renderedCells = new Map();
339
- for (const nonDimension of table.field.allFieldsWithOrder.filter(f => dimensions.indexOf(f) < 0)) {
340
- const childRenderer = this.childRenderers[nonDimension.field.name];
341
- renderedCells.set(nonDimension.field.name, await this.createCellAndRender(childRenderer, row.cell(nonDimension.field.name), shouldTranspose));
405
+ for (const nonDimension of nonDimensions) {
406
+ let childRenderer;
407
+ let value;
408
+ if (nonDimension.flattenedField) {
409
+ childRenderer = nonDimension.flattenedField.getChildRenderer(this.childRenderers);
410
+ value = nonDimension.flattenedField.getValue(row);
411
+ }
412
+ else {
413
+ childRenderer = this.childRenderers[nonDimension.field.name];
414
+ value = row.cell(nonDimension.field.name);
415
+ }
416
+ renderedCells.set(nonDimension.field.name, await this.createCellAndRender(childRenderer, value, shouldTranspose));
342
417
  }
343
418
  if (result.has(pf.key)) {
344
419
  throw new Error(`Can not pivot ${table.field.name} dimensions lead to non unique pivots.`);
@@ -366,9 +441,11 @@ class HTMLTableRenderer extends container_1.ContainerRenderer {
366
441
  `;
367
442
  return headerCell;
368
443
  }
369
- createHeaderCell(field, shouldTranspose) {
370
- let name = (0, utils_1.formatTitle)(this.options, field, this.options.dataStyles[field.name], field.parentExplore.queryTimezone);
371
- const isNumeric = this.childRenderers[field.name] instanceof number_1.HTMLNumberRenderer;
444
+ createHeaderCell(field, shouldTranspose, override = {}) {
445
+ var _a, _b;
446
+ let name = (_a = override.name) !== null && _a !== void 0 ? _a : (0, utils_1.formatTitle)(this.options, field, this.options.dataStyles[field.name], field.parentExplore.queryTimezone);
447
+ const childRenderer = (_b = override.childRenderer) !== null && _b !== void 0 ? _b : this.childRenderers[field.name];
448
+ const isNumeric = childRenderer instanceof number_1.HTMLNumberRenderer;
372
449
  const headerCell = this.document.createElement('th');
373
450
  headerCell.style.cssText = `
374
451
  padding: 8px;
@@ -23,3 +23,9 @@ export declare const ProductsBar: {
23
23
  view: string;
24
24
  };
25
25
  };
26
+ export declare const FlattenNestedMeasures: {
27
+ args: {
28
+ source: string;
29
+ view: string;
30
+ };
31
+ };
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ProductsBar = exports.ProductsTable = void 0;
6
+ exports.FlattenNestedMeasures = exports.ProductsBar = exports.ProductsTable = void 0;
7
7
  const basic_malloy_raw_1 = __importDefault(require("./static/basic.malloy?raw"));
8
8
  const render_malloy_1 = require("./render-malloy");
9
9
  exports.default = {
@@ -25,4 +25,10 @@ exports.ProductsBar = {
25
25
  view: 'category_bar',
26
26
  },
27
27
  };
28
+ exports.FlattenNestedMeasures = {
29
+ args: {
30
+ source: 'products',
31
+ view: 'flatten',
32
+ },
33
+ };
28
34
  //# sourceMappingURL=basic.stories.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/render",
3
- "version": "0.0.99-dev231102165615",
3
+ "version": "0.0.99-dev231102185815",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -23,7 +23,7 @@
23
23
  "build-storybook": "storybook build"
24
24
  },
25
25
  "dependencies": {
26
- "@malloydata/malloy": "^0.0.99-dev231102165615",
26
+ "@malloydata/malloy": "^0.0.99-dev231102185815",
27
27
  "@types/luxon": "^2.4.0",
28
28
  "lodash": "^4.17.20",
29
29
  "luxon": "^2.4.0",