@xh/hoist 83.1.0 → 84.0.1
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/CHANGELOG.md +76 -0
- package/admin/tabs/cluster/instances/logs/levels/LogLevelDialogModel.ts +106 -10
- package/admin/tabs/cluster/metrics/MetricsModel.ts +3 -3
- package/appcontainer/AppContainerModel.ts +1 -1
- package/appcontainer/README.md +20 -0
- package/assets.d.ts +34 -0
- package/build/types/cmp/ag-grid/AgGrid.d.ts +8 -19
- package/build/types/cmp/ag-grid/AgGridModel.d.ts +18 -5
- package/build/types/cmp/card/Card.d.ts +9 -4
- package/build/types/cmp/card/CardModel.d.ts +15 -2
- package/build/types/cmp/chart/Chart.d.ts +2 -2
- package/build/types/cmp/chart/ChartModel.d.ts +11 -1
- package/build/types/cmp/dataview/DataView.d.ts +4 -2
- package/build/types/cmp/dataview/DataViewModel.d.ts +16 -4
- package/build/types/cmp/filter/FilterChooserModel.d.ts +7 -1
- package/build/types/cmp/form/Form.d.ts +2 -1
- package/build/types/cmp/form/FormModel.d.ts +12 -0
- package/build/types/cmp/form/field/BaseFieldModel.d.ts +7 -0
- package/build/types/cmp/form/formfieldset/FormFieldSetModel.d.ts +7 -1
- package/build/types/cmp/grid/GridModel.d.ts +16 -1
- package/build/types/cmp/grid/GridSorter.d.ts +14 -0
- package/build/types/cmp/grid/Types.d.ts +18 -0
- package/build/types/cmp/grid/columns/Column.d.ts +40 -2
- package/build/types/cmp/grid/columns/ColumnGroup.d.ts +10 -0
- package/build/types/cmp/grouping/GroupingChooserModel.d.ts +9 -2
- package/build/types/cmp/layout/Box.d.ts +19 -7
- package/build/types/cmp/layout/Frame.d.ts +17 -5
- package/build/types/cmp/loadingindicator/LoadingIndicator.d.ts +6 -4
- package/build/types/cmp/pinpad/PinPadModel.d.ts +6 -1
- package/build/types/cmp/spinner/Spinner.d.ts +31 -10
- package/build/types/cmp/tab/TabContainerModel.d.ts +11 -0
- package/build/types/cmp/tab/TabModel.d.ts +7 -0
- package/build/types/cmp/tab/Types.d.ts +4 -0
- package/build/types/cmp/treemap/TreeMapModel.d.ts +3 -3
- package/build/types/cmp/viewmanager/ViewManagerModel.d.ts +9 -0
- package/build/types/cmp/zoneGrid/ZoneGridModel.d.ts +22 -3
- package/build/types/cmp/zoneGrid/impl/ZoneMapperModel.d.ts +6 -0
- package/build/types/core/HoistComponent.d.ts +29 -8
- package/build/types/core/HoistProps.d.ts +9 -3
- package/build/types/core/load/LoadSpec.d.ts +1 -1
- package/build/types/core/persist/provider/ViewManagerProvider.d.ts +7 -0
- package/build/types/data/Store.d.ts +35 -1
- package/build/types/data/StoreSelectionModel.d.ts +18 -2
- package/build/types/data/cube/Cube.d.ts +26 -6
- package/build/types/data/cube/Query.d.ts +10 -0
- package/build/types/data/cube/View.d.ts +21 -2
- package/build/types/data/cube/aggregate/Aggregator.d.ts +13 -0
- package/build/types/data/cube/aggregate/AverageAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/AverageStrictAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/ChildCountAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/LeafCountAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/MaxAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/MinAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/NullAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/SingleAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/SumAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/SumStrictAggregator.d.ts +1 -0
- package/build/types/data/cube/aggregate/UniqueAggregator.d.ts +1 -0
- package/build/types/data/filter/BaseFilterFieldSpec.d.ts +9 -0
- package/build/types/data/filter/Types.d.ts +12 -0
- package/build/types/desktop/cmp/button/AppMenuButton.d.ts +5 -0
- package/build/types/desktop/cmp/button/Button.d.ts +5 -1
- package/build/types/desktop/cmp/dash/canvas/DashCanvasModel.d.ts +12 -3
- package/build/types/desktop/cmp/dash/container/DashContainerModel.d.ts +9 -0
- package/build/types/desktop/cmp/dock/DockViewModel.d.ts +7 -0
- package/build/types/desktop/cmp/filechooser/FileChooserModel.d.ts +8 -0
- package/build/types/desktop/cmp/grid/editors/BooleanEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/DateEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/NumberEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/SelectEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/TextAreaEditor.d.ts +1 -0
- package/build/types/desktop/cmp/grid/editors/TextEditor.d.ts +1 -0
- package/build/types/desktop/cmp/input/Picker.d.ts +1 -1
- package/build/types/desktop/cmp/input/SegmentedControl.d.ts +16 -2
- package/build/types/desktop/cmp/leftrightchooser/LeftRightChooserModel.d.ts +7 -0
- package/build/types/desktop/cmp/modalsupport/ModalSupportModel.d.ts +28 -2
- package/build/types/desktop/cmp/panel/Panel.d.ts +5 -2
- package/build/types/desktop/cmp/panel/PanelModel.d.ts +12 -2
- package/build/types/desktop/cmp/rest/RestGrid.d.ts +10 -0
- package/build/types/desktop/cmp/rest/RestGridModel.d.ts +9 -1
- package/build/types/desktop/cmp/toolbar/Toolbar.d.ts +4 -1
- package/build/types/format/FormatDate.d.ts +4 -4
- package/build/types/icon/Icon.d.ts +3 -0
- package/build/types/kit/blueprint/Wrappers.d.ts +12 -1
- package/build/types/mobile/cmp/navigator/NavigatorModel.d.ts +8 -0
- package/build/types/mobile/cmp/navigator/PageModel.d.ts +7 -0
- package/build/types/mobile/cmp/panel/DialogPanel.d.ts +0 -2
- package/build/types/security/BaseOAuthClient.d.ts +9 -0
- package/build/types/security/authzero/AuthZeroClient.d.ts +6 -0
- package/build/types/security/msal/MsalClient.d.ts +6 -0
- package/build/types/svc/FetchService.d.ts +10 -7
- package/build/types/svc/TraceService.d.ts +17 -2
- package/build/types/utils/async/Timer.d.ts +6 -0
- package/build/types/utils/js/LangUtils.d.ts +1 -1
- package/build/types/utils/js/TestUtils.d.ts +1 -1
- package/build/types/utils/react/index.d.ts +0 -1
- package/build/types/utils/telemetry/Span.d.ts +12 -2
- package/cmp/ag-grid/AgGrid.ts +8 -19
- package/cmp/ag-grid/AgGridModel.ts +18 -5
- package/cmp/card/Card.ts +9 -4
- package/cmp/card/CardModel.ts +15 -2
- package/cmp/chart/Chart.ts +2 -2
- package/cmp/chart/ChartModel.ts +11 -1
- package/cmp/dataview/DataView.ts +4 -2
- package/cmp/dataview/DataViewModel.ts +16 -4
- package/cmp/filter/FilterChooserModel.ts +7 -1
- package/cmp/form/Form.ts +2 -1
- package/cmp/form/FormModel.ts +12 -0
- package/cmp/form/README.md +13 -0
- package/cmp/form/field/BaseFieldModel.ts +7 -0
- package/cmp/form/formfieldset/FormFieldSetModel.ts +7 -1
- package/cmp/grid/Grid.scss +14 -8
- package/cmp/grid/GridModel.ts +16 -1
- package/cmp/grid/GridSorter.ts +14 -0
- package/cmp/grid/README.md +12 -0
- package/cmp/grid/Types.ts +18 -0
- package/cmp/grid/columns/Column.ts +40 -2
- package/cmp/grid/columns/ColumnGroup.ts +10 -0
- package/cmp/grouping/GroupingChooserModel.ts +9 -2
- package/cmp/layout/Box.ts +19 -7
- package/cmp/layout/Frame.ts +17 -5
- package/cmp/layout/README.md +16 -21
- package/cmp/loadingindicator/LoadingIndicator.scss +1 -1
- package/cmp/loadingindicator/LoadingIndicator.ts +11 -9
- package/cmp/pinpad/PinPadModel.ts +6 -1
- package/cmp/spinner/Spinner.scss +13 -0
- package/cmp/spinner/Spinner.ts +58 -20
- package/cmp/tab/TabContainerModel.ts +11 -0
- package/cmp/tab/TabModel.ts +7 -0
- package/cmp/tab/Types.ts +4 -0
- package/cmp/treemap/TreeMapModel.ts +3 -3
- package/cmp/viewmanager/ViewManagerModel.ts +9 -0
- package/cmp/zoneGrid/ZoneGridModel.ts +22 -3
- package/cmp/zoneGrid/impl/ZoneMapperModel.ts +6 -0
- package/core/ExceptionHandler.ts +1 -1
- package/core/HoistComponent.ts +36 -11
- package/core/HoistProps.ts +9 -3
- package/core/README.md +68 -6
- package/core/impl/InstanceManager.ts +1 -0
- package/core/load/LoadSpec.ts +1 -1
- package/core/persist/provider/ViewManagerProvider.ts +7 -0
- package/data/README.md +48 -124
- package/data/Store.ts +35 -1
- package/data/StoreSelectionModel.ts +18 -2
- package/data/cube/Cube.ts +26 -6
- package/data/cube/Query.ts +10 -0
- package/data/cube/README.md +236 -0
- package/data/cube/View.ts +21 -2
- package/data/cube/aggregate/Aggregator.ts +13 -0
- package/data/cube/aggregate/AverageAggregator.ts +1 -0
- package/data/cube/aggregate/AverageStrictAggregator.ts +1 -0
- package/data/cube/aggregate/ChildCountAggregator.ts +1 -0
- package/data/cube/aggregate/LeafCountAggregator.ts +1 -0
- package/data/cube/aggregate/MaxAggregator.ts +1 -0
- package/data/cube/aggregate/MinAggregator.ts +1 -0
- package/data/cube/aggregate/NullAggregator.ts +1 -0
- package/data/cube/aggregate/SingleAggregator.ts +1 -0
- package/data/cube/aggregate/SumAggregator.ts +1 -0
- package/data/cube/aggregate/SumStrictAggregator.ts +1 -0
- package/data/cube/aggregate/UniqueAggregator.ts +1 -0
- package/data/filter/BaseFilterFieldSpec.ts +9 -0
- package/data/filter/Types.ts +12 -0
- package/desktop/README.md +131 -9
- package/desktop/appcontainer/AboutDialog.ts +2 -0
- package/desktop/appcontainer/Banner.ts +5 -2
- package/desktop/appcontainer/ChangelogDialog.ts +1 -0
- package/desktop/appcontainer/ExceptionDialog.ts +4 -0
- package/desktop/appcontainer/ExceptionDialogDetails.ts +4 -1
- package/desktop/appcontainer/FeedbackDialog.ts +4 -1
- package/desktop/appcontainer/ImpersonationBar.ts +4 -0
- package/desktop/appcontainer/LockoutPanel.ts +4 -1
- package/desktop/appcontainer/LoginPanel.ts +7 -3
- package/desktop/appcontainer/Message.ts +9 -3
- package/desktop/appcontainer/OptionsDialog.ts +3 -1
- package/desktop/appcontainer/VersionBar.ts +1 -0
- package/desktop/appcontainer/suspend/IdlePanel.ts +4 -4
- package/desktop/appcontainer/suspend/SuspendPanel.ts +3 -0
- package/desktop/cmp/button/AppMenuButton.ts +5 -0
- package/desktop/cmp/button/Button.ts +14 -4
- package/desktop/cmp/dash/README.md +14 -0
- package/desktop/cmp/dash/canvas/DashCanvasModel.ts +12 -3
- package/desktop/cmp/dash/container/DashContainerModel.ts +9 -0
- package/desktop/cmp/dock/DockViewModel.ts +7 -0
- package/desktop/cmp/filechooser/FileChooserModel.ts +9 -2
- package/desktop/cmp/grid/editors/BooleanEditor.ts +1 -0
- package/desktop/cmp/grid/editors/DateEditor.ts +1 -0
- package/desktop/cmp/grid/editors/NumberEditor.ts +1 -0
- package/desktop/cmp/grid/editors/SelectEditor.ts +1 -0
- package/desktop/cmp/grid/editors/TextAreaEditor.ts +1 -0
- package/desktop/cmp/grid/editors/TextEditor.ts +1 -0
- package/desktop/cmp/input/Picker.ts +2 -2
- package/desktop/cmp/input/SegmentedControl.ts +20 -2
- package/desktop/cmp/leftrightchooser/LeftRightChooserModel.ts +7 -0
- package/desktop/cmp/modalsupport/ModalSupportModel.ts +31 -2
- package/desktop/cmp/panel/Panel.ts +29 -21
- package/desktop/cmp/panel/PanelModel.ts +12 -2
- package/desktop/cmp/panel/README.md +20 -0
- package/desktop/cmp/rest/RestGrid.ts +10 -0
- package/desktop/cmp/rest/RestGridModel.ts +9 -1
- package/desktop/cmp/toolbar/Toolbar.ts +9 -2
- package/desktop/cmp/viewmanager/ViewManager.ts +1 -1
- package/docs/README.md +9 -4
- package/docs/coding-conventions.md +29 -21
- package/docs/doc-registry.json +31 -15
- package/docs/planning/docs-roadmap-log.md +11 -0
- package/docs/planning/docs-roadmap.md +1 -0
- package/docs/upgrade-notes/v84-upgrade-notes.md +136 -0
- package/docs/version-compatibility.md +2 -0
- package/format/FormatDate.ts +4 -4
- package/icon/Icon.ts +9 -0
- package/icon/README.md +62 -22
- package/icon/index.ts +24 -0
- package/kit/README.md +8 -2
- package/kit/blueprint/Wrappers.ts +12 -1
- package/mcp/README.md +47 -26
- package/mcp/cli/ts.ts +39 -4
- package/mcp/data/ts-registry.ts +57 -17
- package/mcp/tools/typescript.ts +32 -4
- package/mobile/appcontainer/AboutDialog.ts +3 -0
- package/mobile/appcontainer/Banner.ts +2 -0
- package/mobile/appcontainer/ExceptionDialog.ts +4 -0
- package/mobile/appcontainer/ExceptionDialogDetails.ts +1 -0
- package/mobile/appcontainer/FeedbackDialog.ts +4 -1
- package/mobile/appcontainer/ImpersonationBar.ts +2 -0
- package/mobile/appcontainer/LockoutPanel.ts +2 -0
- package/mobile/appcontainer/LoginPanel.ts +7 -3
- package/mobile/appcontainer/Message.ts +9 -3
- package/mobile/appcontainer/OptionsDialog.ts +5 -1
- package/mobile/appcontainer/VersionBar.ts +1 -0
- package/mobile/appcontainer/suspend/IdlePanel.ts +5 -6
- package/mobile/appcontainer/suspend/SuspendPanel.ts +3 -0
- package/mobile/cmp/navigator/NavigatorModel.ts +8 -0
- package/mobile/cmp/navigator/PageModel.ts +7 -0
- package/mobile/cmp/panel/DialogPanel.ts +0 -2
- package/package.json +11 -11
- package/security/BaseOAuthClient.ts +9 -0
- package/security/authzero/AuthZeroClient.ts +6 -0
- package/security/msal/MsalClient.ts +6 -0
- package/styles/vars.scss +14 -0
- package/svc/FetchService.ts +25 -15
- package/svc/README.md +39 -9
- package/svc/TraceService.ts +69 -11
- package/utils/README.md +0 -1
- package/utils/async/Timer.ts +6 -0
- package/utils/js/LangUtils.ts +1 -1
- package/utils/js/TestUtils.ts +1 -1
- package/utils/react/index.ts +0 -1
- package/utils/telemetry/Span.ts +21 -4
- package/build/types/utils/react/ClassName.d.ts +0 -14
- package/utils/react/ClassName.ts +0 -24
package/data/README.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Data Package
|
|
2
2
|
|
|
3
|
+
| Section | Description |
|
|
4
|
+
|---------|-------------|
|
|
5
|
+
| [Overview](#overview) | Core classes, architecture diagram |
|
|
6
|
+
| [Store](#store) | Creating, loading, filtering, and observing record collections |
|
|
7
|
+
| [StoreRecord](#storerecord) | Record state, data access, tree navigation, validation |
|
|
8
|
+
| [Field](#field) | Type parsing, display names, descriptions, validation rules |
|
|
9
|
+
| [Filter System](#filter-system) | FieldFilter, CompoundFilter, FunctionFilter, and utilities |
|
|
10
|
+
| [Validation System](#validation-system) | Rules, constraints, severity levels, async validation |
|
|
11
|
+
| [Integration with GridModel](#integration-with-gridmodel) | Inline store config, data loading, and editing |
|
|
12
|
+
| [Tree Data](#tree-data) | Hierarchical loading, filtering, and summary records |
|
|
13
|
+
| [Cube (Aggregation)](#cube-aggregation) | Pointer to dedicated [`cube/README.md`](cube/README.md) |
|
|
14
|
+
| [Common Patterns](#common-patterns) | Record reuse, processRawData, composite IDs |
|
|
15
|
+
| [Common Pitfalls](#common-pitfalls) | ID fields, missing IDs, data mutation, FunctionFilter persistence |
|
|
16
|
+
|
|
3
17
|
## Overview
|
|
4
18
|
|
|
5
19
|
The `/data/` package provides Hoist's data management layer - observable, in-memory data containers
|
|
@@ -603,6 +617,36 @@ record.errors; // Map<field, string[]>
|
|
|
603
617
|
record.validationResults; // Map<field, ValidationResult[]>
|
|
604
618
|
```
|
|
605
619
|
|
|
620
|
+
## Integration with GridModel
|
|
621
|
+
|
|
622
|
+
Stores are the primary data source for GridModel:
|
|
623
|
+
|
|
624
|
+
```typescript
|
|
625
|
+
import {GridModel} from '@xh/hoist/cmp/grid';
|
|
626
|
+
import {numberEditor} from '@xh/hoist/desktop/cmp/grid';
|
|
627
|
+
|
|
628
|
+
const gridModel = new GridModel({
|
|
629
|
+
// Inline store config
|
|
630
|
+
store: {
|
|
631
|
+
fields: [
|
|
632
|
+
{name: 'name', type: 'string'},
|
|
633
|
+
{name: 'salary', type: 'number', rules: [required]}
|
|
634
|
+
]
|
|
635
|
+
},
|
|
636
|
+
columns: [
|
|
637
|
+
{field: 'name', flex: 1},
|
|
638
|
+
{field: 'salary', width: 120, editable: true, editor: numberEditor()}
|
|
639
|
+
]
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
// Load data through GridModel (delegates to store)
|
|
643
|
+
gridModel.loadData(data);
|
|
644
|
+
|
|
645
|
+
// Access store directly
|
|
646
|
+
gridModel.store.records;
|
|
647
|
+
gridModel.store.setFilter({field: 'salary', op: '>', value: 50000});
|
|
648
|
+
```
|
|
649
|
+
|
|
606
650
|
## Tree Data
|
|
607
651
|
|
|
608
652
|
Stores provide full support for hierarchical parent-child data.
|
|
@@ -690,130 +734,10 @@ See `cmp/grid/GridModel.ts` for details on summary row rendering.
|
|
|
690
734
|
|
|
691
735
|
## Cube (Aggregation)
|
|
692
736
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
### Creating a Cube
|
|
698
|
-
|
|
699
|
-
```typescript
|
|
700
|
-
import {Cube} from '@xh/hoist/data';
|
|
701
|
-
|
|
702
|
-
const cube = new Cube({
|
|
703
|
-
fields: [
|
|
704
|
-
// Dimensions - can be grouped on
|
|
705
|
-
{name: 'region', isDimension: true},
|
|
706
|
-
{name: 'product', isDimension: true},
|
|
707
|
-
{name: 'year', isDimension: true},
|
|
708
|
-
|
|
709
|
-
// Measures - aggregated values
|
|
710
|
-
{name: 'revenue', aggregator: 'SUM'},
|
|
711
|
-
{name: 'quantity', aggregator: 'SUM'},
|
|
712
|
-
{name: 'avgPrice', aggregator: 'AVG'}
|
|
713
|
-
]
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
await cube.loadDataAsync(salesData);
|
|
717
|
-
```
|
|
718
|
-
|
|
719
|
-
### Built-in Aggregators
|
|
720
|
-
|
|
721
|
-
| Aggregator | Description |
|
|
722
|
-
|------------|-------------|
|
|
723
|
-
| `'SUM'` | Total of non-null values |
|
|
724
|
-
| `'SUM_STRICT'` | Total only if all non-null |
|
|
725
|
-
| `'AVG'` | Average of non-null values |
|
|
726
|
-
| `'AVG_STRICT'` | Average only if all non-null |
|
|
727
|
-
| `'MIN'` | Minimum value |
|
|
728
|
-
| `'MAX'` | Maximum value |
|
|
729
|
-
| `'UNIQUE'` | Count of unique values |
|
|
730
|
-
| `'LEAF_COUNT'` | Count of leaf records |
|
|
731
|
-
| `'CHILD_COUNT'` | Count of immediate children |
|
|
732
|
-
|
|
733
|
-
### Querying and Accessing View Data
|
|
734
|
-
|
|
735
|
-
```typescript
|
|
736
|
-
// Create a view with specific groupings
|
|
737
|
-
const view = cube.createView({
|
|
738
|
-
query: {
|
|
739
|
-
cube,
|
|
740
|
-
dimensions: ['region', 'product'],
|
|
741
|
-
filter: {field: 'year', op: '=', value: 2024},
|
|
742
|
-
includeLeaves: false,
|
|
743
|
-
includeRoot: true
|
|
744
|
-
},
|
|
745
|
-
connect: true // Auto-update when cube data changes
|
|
746
|
-
});
|
|
747
|
-
```
|
|
748
|
-
|
|
749
|
-
There are two primary ways to access view data:
|
|
750
|
-
|
|
751
|
-
**Option 1: Read `view.result` directly**
|
|
752
|
-
|
|
753
|
-
The observable `ViewResult` contains hierarchical `ViewRowData` objects:
|
|
754
|
-
|
|
755
|
-
```typescript
|
|
756
|
-
// React to view updates
|
|
757
|
-
addReaction({
|
|
758
|
-
track: () => view.result,
|
|
759
|
-
run: (result) => {
|
|
760
|
-
const {rows, leafMap} = result;
|
|
761
|
-
// rows: ViewRowData[] - hierarchical aggregated data
|
|
762
|
-
// leafMap: Map<id, LeafRow> - direct access to leaf-level rows
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
```
|
|
766
|
-
|
|
767
|
-
**Option 2: Connect stores for automatic loading**
|
|
768
|
-
|
|
769
|
-
Provide one or more stores that the view will automatically populate:
|
|
770
|
-
|
|
771
|
-
```typescript
|
|
772
|
-
const store = new Store({fields: [...]});
|
|
773
|
-
|
|
774
|
-
const view = cube.createView({
|
|
775
|
-
query: {...},
|
|
776
|
-
stores: store, // View auto-loads data into this store
|
|
777
|
-
connect: true
|
|
778
|
-
});
|
|
779
|
-
|
|
780
|
-
// Store now receives updates automatically
|
|
781
|
-
gridModel.store === store; // Use with GridModel
|
|
782
|
-
```
|
|
783
|
-
|
|
784
|
-
**Update triggers:** View data updates when either:
|
|
785
|
-
- The underlying Cube data changes (requires `connect: true`)
|
|
786
|
-
- The `view.query` is modified via `view.updateQuery()`
|
|
787
|
-
|
|
788
|
-
## Integration with GridModel
|
|
789
|
-
|
|
790
|
-
Stores are the primary data source for GridModel:
|
|
791
|
-
|
|
792
|
-
```typescript
|
|
793
|
-
import {GridModel} from '@xh/hoist/cmp/grid';
|
|
794
|
-
import {numberEditor} from '@xh/hoist/desktop/cmp/grid';
|
|
795
|
-
|
|
796
|
-
const gridModel = new GridModel({
|
|
797
|
-
// Inline store config
|
|
798
|
-
store: {
|
|
799
|
-
fields: [
|
|
800
|
-
{name: 'name', type: 'string'},
|
|
801
|
-
{name: 'salary', type: 'number', rules: [required]}
|
|
802
|
-
]
|
|
803
|
-
},
|
|
804
|
-
columns: [
|
|
805
|
-
{field: 'name', flex: 1},
|
|
806
|
-
{field: 'salary', width: 120, editable: true, editor: numberEditor()}
|
|
807
|
-
]
|
|
808
|
-
});
|
|
809
|
-
|
|
810
|
-
// Load data through GridModel (delegates to store)
|
|
811
|
-
gridModel.loadData(data);
|
|
812
|
-
|
|
813
|
-
// Access store directly
|
|
814
|
-
gridModel.store.records;
|
|
815
|
-
gridModel.store.setFilter({field: 'salary', op: '>', value: 50000});
|
|
816
|
-
```
|
|
737
|
+
Client-side OLAP-style aggregation for multi-dimensional grouping and analysis. The Cube
|
|
738
|
+
subsystem has its own dedicated documentation — see the
|
|
739
|
+
[Cube package README](cube/README.md) for full coverage of creating Cubes, aggregators,
|
|
740
|
+
querying with Views, and accessing results.
|
|
817
741
|
|
|
818
742
|
## Common Patterns
|
|
819
743
|
|
package/data/Store.ts
CHANGED
|
@@ -47,6 +47,20 @@ import {
|
|
|
47
47
|
import {instanceManager} from '../core/impl/InstanceManager';
|
|
48
48
|
import {RecordSet} from './impl/RecordSet';
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Configuration for a {@link Store}. At minimum, provide `fields` (or let them be inferred
|
|
52
|
+
* from GridModel columns). Data can be supplied at construction via `data`, or loaded later
|
|
53
|
+
* via `Store.loadData()`.
|
|
54
|
+
*
|
|
55
|
+
* Can also be passed inline as the `store` config on {@link GridConfig}, where it will be
|
|
56
|
+
* used to construct a Store automatically.
|
|
57
|
+
*
|
|
58
|
+
* See the data package README (`data/README.md`) for tree data, filtering, validation, and
|
|
59
|
+
* performance tuning guidance.
|
|
60
|
+
*
|
|
61
|
+
* @see Store
|
|
62
|
+
* @see FieldSpec
|
|
63
|
+
*/
|
|
50
64
|
export interface StoreConfig {
|
|
51
65
|
/** Field names, configs, or instances. */
|
|
52
66
|
fields?: Array<string | FieldSpec | Field>;
|
|
@@ -203,7 +217,27 @@ export interface ChildRawData {
|
|
|
203
217
|
export type StoreRecordIdSpec = string | ((data: PlainObject) => StoreRecordId);
|
|
204
218
|
|
|
205
219
|
/**
|
|
206
|
-
* A managed
|
|
220
|
+
* A managed, observable collection of in-memory {@link StoreRecord}s - the core data container
|
|
221
|
+
* in Hoist. Used directly by applications and as the data source for {@link GridModel},
|
|
222
|
+
* {@link DataViewModel}, and other data-bound components.
|
|
223
|
+
*
|
|
224
|
+
* Stores provide:
|
|
225
|
+
* - Observable record collections with filtering via composable {@link Filter} objects
|
|
226
|
+
* - Hierarchical/tree data with parent-child navigation
|
|
227
|
+
* - Local modification tracking (add/modify/remove) with commit/revert
|
|
228
|
+
* - Record reuse across data reloads to preserve grid row state
|
|
229
|
+
* - Pluggable validation via {@link Field} rules
|
|
230
|
+
*
|
|
231
|
+
* Data is loaded via `loadData()` (full replacement) or `updateData()` (transactional). Fields
|
|
232
|
+
* can be defined explicitly or inferred from GridModel columns. `Store.defaults` provides
|
|
233
|
+
* app-wide configuration.
|
|
234
|
+
*
|
|
235
|
+
* See the data package README (`data/README.md`) for full documentation including tree data,
|
|
236
|
+
* filtering patterns, validation, and common pitfalls.
|
|
237
|
+
*
|
|
238
|
+
* @see StoreConfig
|
|
239
|
+
* @see StoreRecord
|
|
240
|
+
* @see Field
|
|
207
241
|
*/
|
|
208
242
|
export class Store
|
|
209
243
|
extends HoistBase
|
|
@@ -11,15 +11,31 @@ import {castArray, compact, remove, isEqual, union, map} from 'lodash';
|
|
|
11
11
|
import {Store} from './Store';
|
|
12
12
|
import {StoreRecord, StoreRecordId, StoreRecordOrId} from './StoreRecord';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for a {@link StoreSelectionModel}. Typically passed via the `selModel` config
|
|
16
|
+
* on {@link GridConfig} rather than constructed directly.
|
|
17
|
+
*
|
|
18
|
+
* @see StoreSelectionModel
|
|
19
|
+
*/
|
|
14
20
|
export interface StoreSelectionConfig {
|
|
15
21
|
store?: Store;
|
|
16
22
|
mode?: 'single' | 'multiple' | 'disabled';
|
|
23
|
+
/** @internal */
|
|
17
24
|
xhImpl?: boolean;
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
/**
|
|
21
|
-
* Model for managing
|
|
22
|
-
*
|
|
28
|
+
* Model for managing record selection within a {@link Store}. Supports `single`, `multiple`,
|
|
29
|
+
* and `disabled` modes.
|
|
30
|
+
*
|
|
31
|
+
* Typically accessed via `gridModel.selModel` rather than created directly - configure via
|
|
32
|
+
* the `selModel` property on {@link GridConfig}.
|
|
33
|
+
*
|
|
34
|
+
* Key observables for reacting to selection state: `selectedRecord` / `selectedRecords`
|
|
35
|
+
* (reactive to both identity and data changes), `selectedId` / `selectedIds` (identity only),
|
|
36
|
+
* `isEmpty`, `count`. Use `select()` and `clear()` for programmatic control.
|
|
37
|
+
*
|
|
38
|
+
* @see StoreSelectionConfig
|
|
23
39
|
*/
|
|
24
40
|
export class StoreSelectionModel extends HoistModel {
|
|
25
41
|
readonly store: Store;
|
package/data/cube/Cube.ts
CHANGED
|
@@ -20,6 +20,16 @@ import {BucketRow} from './row/BucketRow';
|
|
|
20
20
|
import {View} from './View';
|
|
21
21
|
import {ViewRowData} from './ViewRowData';
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Configuration for a {@link Cube}. Provide `fields` (including at least one dimension
|
|
25
|
+
* and one or more measures with aggregators) and load data via `data` or
|
|
26
|
+
* `Cube.loadDataAsync()`.
|
|
27
|
+
*
|
|
28
|
+
* See the Cube package README (`data/cube/README.md`) for aggregator options and usage patterns.
|
|
29
|
+
*
|
|
30
|
+
* @see Cube
|
|
31
|
+
* @see CubeFieldSpec
|
|
32
|
+
*/
|
|
23
33
|
export interface CubeConfig {
|
|
24
34
|
fields: CubeField[] | CubeFieldSpec[];
|
|
25
35
|
|
|
@@ -87,13 +97,23 @@ export type OmitFn = (row: AggregateRow | BucketRow) => boolean;
|
|
|
87
97
|
export type BucketSpecFn = (rows: BaseRow[]) => BucketSpec;
|
|
88
98
|
|
|
89
99
|
/**
|
|
90
|
-
*
|
|
100
|
+
* Client-side OLAP-style data structure for multi-dimensional grouping and aggregation.
|
|
101
|
+
*
|
|
102
|
+
* A Cube wraps a flat {@link Store} of leaf-level records and supports creating {@link View}s
|
|
103
|
+
* via structured {@link Query} objects. Each View filters, groups, and aggregates the source
|
|
104
|
+
* data into a hierarchical result for use in tree grids, treemaps, and other visualizations.
|
|
105
|
+
*
|
|
106
|
+
* Fields are defined as {@link CubeField}s - each marked as either a dimension (groupable)
|
|
107
|
+
* or a measure with an {@link Aggregator} (e.g. SUM, AVG, MIN, MAX). Views can be transient
|
|
108
|
+
* (run a query once) or connected for efficient, auto-updating results as source data changes.
|
|
109
|
+
*
|
|
110
|
+
* See the Cube package README (`data/cube/README.md`) for full documentation including
|
|
111
|
+
* aggregator options, querying patterns, and View integration with Store/GridModel.
|
|
91
112
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* auto-updating results in response to updates to the underlying data.
|
|
113
|
+
* @see CubeConfig
|
|
114
|
+
* @see CubeField
|
|
115
|
+
* @see View
|
|
116
|
+
* @see Query
|
|
97
117
|
*/
|
|
98
118
|
export class Cube extends HoistBase {
|
|
99
119
|
static RECORD_ID_DELIMITER = '>>';
|
package/data/cube/Query.ts
CHANGED
|
@@ -22,6 +22,16 @@ import {CubeField} from './CubeField';
|
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Queries determine what data is extracted, grouped, and aggregated from a {@link Cube}.
|
|
25
|
+
* Passed via the `query` property of {@link ViewConfig} when creating a View.
|
|
26
|
+
*
|
|
27
|
+
* Key options beyond `dimensions` and `filter`: `includeRoot` adds a grand-total row,
|
|
28
|
+
* `includeLeaves` exposes source records as tree children, and `provideLeaves` makes them
|
|
29
|
+
* accessible programmatically without rendering in the tree.
|
|
30
|
+
*
|
|
31
|
+
* See the Cube package README (`data/cube/README.md#querying-with-views`) for query patterns.
|
|
32
|
+
*
|
|
33
|
+
* @see Cube
|
|
34
|
+
* @see View
|
|
25
35
|
*/
|
|
26
36
|
export interface QueryConfig {
|
|
27
37
|
/**
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Cube Package
|
|
2
|
+
|
|
3
|
+
| Section | Description |
|
|
4
|
+
|---------|-------------|
|
|
5
|
+
| [Overview](#overview) | Architecture, dimensions vs. measures, CubeField configuration |
|
|
6
|
+
| [Creating a Cube](#creating-a-cube) | Field definitions, data loading |
|
|
7
|
+
| [Built-in Aggregators](#built-in-aggregators) | SUM, AVG, MIN, MAX, and counting aggregators |
|
|
8
|
+
| [Querying with Views](#querying-with-views) | Grouped queries, grand totals, leaf drill-down, dynamic updates |
|
|
9
|
+
| [Accessing View Data](#accessing-view-data) | Connected stores vs. direct result access |
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The `/data/cube/` package provides a client-side OLAP-style aggregation engine. A `Cube` wraps
|
|
14
|
+
a flat collection of leaf-level records and supports creating `View`s via structured `Query`
|
|
15
|
+
objects that filter, group, and aggregate the source data into hierarchical results.
|
|
16
|
+
|
|
17
|
+
| Class | Purpose |
|
|
18
|
+
|-------|---------|
|
|
19
|
+
| **Cube** | Aggregation engine holding source data and creating Views |
|
|
20
|
+
| **CubeField** | Field metadata extending `Field` with dimension/aggregator config |
|
|
21
|
+
| **Query** | Immutable specification of dimensions, filters, and output options |
|
|
22
|
+
| **View** | Observable query result, optionally auto-updating connected Stores |
|
|
23
|
+
|
|
24
|
+
Fields are defined as `CubeField`s — each marked as either a **dimension** (groupable category)
|
|
25
|
+
or a **measure** with an `Aggregator` (e.g. SUM, AVG). Views produce hierarchical results ready
|
|
26
|
+
for use in tree grids, treemaps, and other visualizations.
|
|
27
|
+
|
|
28
|
+
For the core data layer (Store, Field, Filter, Validation), see the
|
|
29
|
+
[data package README](../README.md).
|
|
30
|
+
|
|
31
|
+
## Creating a Cube
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import {Cube} from '@xh/hoist/data';
|
|
35
|
+
|
|
36
|
+
const cube = new Cube({
|
|
37
|
+
fields: [
|
|
38
|
+
// Dimensions - can be grouped on
|
|
39
|
+
{name: 'region', isDimension: true},
|
|
40
|
+
{name: 'product', isDimension: true},
|
|
41
|
+
{name: 'year', isDimension: true},
|
|
42
|
+
|
|
43
|
+
// Measures - aggregated values
|
|
44
|
+
{name: 'revenue', aggregator: 'SUM'},
|
|
45
|
+
{name: 'quantity', aggregator: 'SUM'},
|
|
46
|
+
{name: 'avgPrice', aggregator: 'AVG'}
|
|
47
|
+
]
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
await cube.loadDataAsync(salesData);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Built-in Aggregators
|
|
54
|
+
|
|
55
|
+
| Aggregator | Description |
|
|
56
|
+
|------------|-------------|
|
|
57
|
+
| `'SUM'` | Total of non-null values |
|
|
58
|
+
| `'SUM_STRICT'` | Total only if all non-null |
|
|
59
|
+
| `'AVG'` | Average of non-null values |
|
|
60
|
+
| `'AVG_STRICT'` | Average only if all non-null |
|
|
61
|
+
| `'MIN'` | Minimum value |
|
|
62
|
+
| `'MAX'` | Maximum value |
|
|
63
|
+
| `'UNIQUE'` | Count of unique values |
|
|
64
|
+
| `'LEAF_COUNT'` | Count of leaf records |
|
|
65
|
+
| `'CHILD_COUNT'` | Count of immediate children |
|
|
66
|
+
|
|
67
|
+
## Querying with Views
|
|
68
|
+
|
|
69
|
+
Views are the primary interface for consuming Cube data. Create them via `Cube.createView()`
|
|
70
|
+
with a `QueryConfig` specifying dimensions, filters, and output options.
|
|
71
|
+
|
|
72
|
+
**Basic grouped query:**
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
const view = cube.createView({
|
|
76
|
+
query: {
|
|
77
|
+
dimensions: ['region', 'product'],
|
|
78
|
+
filter: {field: 'year', op: '=', value: 2024}
|
|
79
|
+
},
|
|
80
|
+
stores: store,
|
|
81
|
+
connect: true // Auto-update when cube data changes
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This produces a hierarchy of aggregated rows: Region → Product, with measures (revenue,
|
|
86
|
+
quantity) summed at each level. Only aggregate rows are returned — leaf-level source records
|
|
87
|
+
are excluded by default.
|
|
88
|
+
|
|
89
|
+
**Grand totals with `includeRoot`:**
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// Include a synthetic root node with grand totals across all data.
|
|
93
|
+
// Pairs with GridConfig.showSummary and StoreConfig.loadRootAsSummary
|
|
94
|
+
// to display a docked total row in grids.
|
|
95
|
+
const view = cube.createView({
|
|
96
|
+
query: {
|
|
97
|
+
dimensions: ['region', 'product'],
|
|
98
|
+
includeRoot: true
|
|
99
|
+
},
|
|
100
|
+
stores: new Store({loadRootAsSummary: true}),
|
|
101
|
+
connect: true
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// The connected GridModel can then show the root as a summary row:
|
|
105
|
+
const gridModel = new GridModel({store, showSummary: true, ...});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Leaf-level drill-down with `includeLeaves`:**
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// Include the original source records as children of the lowest
|
|
112
|
+
// aggregation level — users can expand groups to see underlying facts.
|
|
113
|
+
const view = cube.createView({
|
|
114
|
+
query: {
|
|
115
|
+
dimensions: ['region'],
|
|
116
|
+
includeLeaves: true
|
|
117
|
+
},
|
|
118
|
+
stores: store,
|
|
119
|
+
connect: true
|
|
120
|
+
});
|
|
121
|
+
// In a tree grid, expanding "North America" shows its aggregated children,
|
|
122
|
+
// and expanding those shows the individual source records.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Programmatic leaf access with `provideLeaves`:**
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Like includeLeaves, but leaves are accessible programmatically via
|
|
129
|
+
// ViewRowData.cubeLeaves rather than rendered as tree children.
|
|
130
|
+
// Useful for showing detail in a separate panel on selection.
|
|
131
|
+
const view = cube.createView({
|
|
132
|
+
query: {
|
|
133
|
+
dimensions: ['region', 'product'],
|
|
134
|
+
provideLeaves: true
|
|
135
|
+
},
|
|
136
|
+
stores: store,
|
|
137
|
+
connect: true
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Flat aggregation (no dimensions):**
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// No dimensions — just filter and aggregate. Must specify includeRoot
|
|
145
|
+
// or includeLeaves, otherwise no data will be returned.
|
|
146
|
+
const view = cube.createView({
|
|
147
|
+
query: {
|
|
148
|
+
includeRoot: true, // Single row with grand totals
|
|
149
|
+
filter: {field: 'region', op: '=', value: 'EMEA'}
|
|
150
|
+
},
|
|
151
|
+
stores: store,
|
|
152
|
+
connect: true
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Updating queries dynamically:**
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// Change dimensions, filters, or options on an existing View.
|
|
160
|
+
// Connected stores are automatically refreshed.
|
|
161
|
+
view.updateQuery({
|
|
162
|
+
dimensions: ['product', 'region'], // Swap grouping order
|
|
163
|
+
filter: {field: 'year', op: '=', value: 2025}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Shorthand for filter-only updates:
|
|
167
|
+
view.setFilter({field: 'year', op: '=', value: 2025});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**One-shot queries with `executeQuery`:**
|
|
171
|
+
|
|
172
|
+
For cases where you need aggregated data once without retaining a View — e.g. computing a
|
|
173
|
+
summary for a tooltip or populating a one-time report — use `Cube.executeQuery()` directly.
|
|
174
|
+
This creates a transient View internally, extracts the results, and destroys it immediately:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// Returns ViewRowData[] directly — no View to manage or destroy.
|
|
178
|
+
const rows = cube.executeQuery({
|
|
179
|
+
dimensions: ['region'],
|
|
180
|
+
includeRoot: true,
|
|
181
|
+
filter: {field: 'year', op: '=', value: 2024}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Use the rows directly — e.g. extract the root for a grand total
|
|
185
|
+
const grandTotal = rows.find(r => r.isRoot);
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Use `createView()` when you need connected auto-updates or store integration;
|
|
189
|
+
use `executeQuery()` for lightweight, fire-and-forget queries.
|
|
190
|
+
|
|
191
|
+
## Accessing View Data
|
|
192
|
+
|
|
193
|
+
There are two ways to consume View results:
|
|
194
|
+
|
|
195
|
+
**Option 1: Connected stores (recommended for grids)**
|
|
196
|
+
|
|
197
|
+
Provide one or more stores via `ViewConfig.stores`. The View auto-loads hierarchical data
|
|
198
|
+
into them whenever the query results change:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
const store = new Store({fields: [...]});
|
|
202
|
+
|
|
203
|
+
const view = cube.createView({
|
|
204
|
+
query: {dimensions: ['region', 'product']},
|
|
205
|
+
stores: store,
|
|
206
|
+
connect: true
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Use the store with a GridModel
|
|
210
|
+
const gridModel = new GridModel({store, treeMode: true, columns: [...]});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Option 2: Read `view.result` directly**
|
|
214
|
+
|
|
215
|
+
The observable `ViewResult` contains hierarchical `ViewRowData` objects:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
addReaction({
|
|
219
|
+
track: () => view.result,
|
|
220
|
+
run: (result) => {
|
|
221
|
+
const {rows, leafMap} = result;
|
|
222
|
+
// rows: ViewRowData[] - hierarchical aggregated data
|
|
223
|
+
// leafMap: Map<id, LeafRow> - direct access to leaf-level rows
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Update triggers:** View data updates when either:
|
|
229
|
+
- The underlying Cube data changes (requires `connect: true`)
|
|
230
|
+
- The `view.query` is modified via `view.updateQuery()`
|
|
231
|
+
|
|
232
|
+
## Related Packages
|
|
233
|
+
|
|
234
|
+
- [`/data/`](../README.md) - Store, Field, Filter, Validation - the core data layer
|
|
235
|
+
- [`/cmp/grid/`](../../cmp/grid/README.md) - GridModel consumes Store for data display
|
|
236
|
+
- `/cmp/grouping/` - GroupingChooser for specifying multi-level dimension groupings
|
package/data/cube/View.ts
CHANGED
|
@@ -32,6 +32,15 @@ import {BaseRow} from './row/BaseRow';
|
|
|
32
32
|
import {BucketRow} from './row/BucketRow';
|
|
33
33
|
import {LeafRow} from './row/LeafRow';
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Configuration for a {@link View} - a query result from a {@link Cube} that can optionally
|
|
37
|
+
* stay connected for live updates. Create via {@link Cube.createView}.
|
|
38
|
+
*
|
|
39
|
+
* See the Cube package README (`data/cube/README.md`) for query patterns.
|
|
40
|
+
*
|
|
41
|
+
* @see View
|
|
42
|
+
* @see QueryConfig
|
|
43
|
+
*/
|
|
35
44
|
export interface ViewConfig {
|
|
36
45
|
/** Query to be used to construct this view. */
|
|
37
46
|
query: Query;
|
|
@@ -64,8 +73,18 @@ export interface DimensionValue {
|
|
|
64
73
|
}
|
|
65
74
|
|
|
66
75
|
/**
|
|
67
|
-
* Primary interface for consuming grouped and aggregated data from
|
|
68
|
-
*
|
|
76
|
+
* Primary interface for consuming grouped and aggregated data from a {@link Cube}.
|
|
77
|
+
* Created via {@link Cube.createView} with a {@link QueryConfig} and optional connected
|
|
78
|
+
* stores. Views can be transient (run once) or connected for auto-updating results.
|
|
79
|
+
*
|
|
80
|
+
* Use `updateQuery()` to change dimensions, filters, or options dynamically.
|
|
81
|
+
*
|
|
82
|
+
* See the Cube package README (`data/cube/README.md`) for query patterns and examples
|
|
83
|
+
* of grand totals, leaf drill-down, and store integration.
|
|
84
|
+
*
|
|
85
|
+
* @see ViewConfig
|
|
86
|
+
* @see QueryConfig
|
|
87
|
+
* @see Cube
|
|
69
88
|
*/
|
|
70
89
|
export class View
|
|
71
90
|
extends HoistBase
|
|
@@ -10,6 +10,19 @@ import {BaseRow} from '../row/BaseRow';
|
|
|
10
10
|
import {LeafRow} from '../row/LeafRow';
|
|
11
11
|
import {RowUpdate} from '../row/RowUpdate';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Abstract base class for Cube field aggregation functions.
|
|
15
|
+
*
|
|
16
|
+
* Subclasses implement {@link aggregate} to compute a summary value for a set of rows, and
|
|
17
|
+
* may optionally override {@link replace} to efficiently update the aggregation when a single
|
|
18
|
+
* child row changes (the default re-aggregates from scratch).
|
|
19
|
+
*
|
|
20
|
+
* Standard implementations are provided for common operations: sum, average, min, max,
|
|
21
|
+
* unique, count, and null. Custom aggregators can extend this class for application-specific
|
|
22
|
+
* aggregation logic.
|
|
23
|
+
*
|
|
24
|
+
* @see CubeField.aggregator
|
|
25
|
+
*/
|
|
13
26
|
export abstract class Aggregator {
|
|
14
27
|
/**
|
|
15
28
|
* Does this aggregator depend only on leaf nodes contained by the node being aggregated?
|