@sisense/sdk-data 2.11.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/dimensional-model/attributes.js +1 -1
- package/dist/cjs/dimensional-model/base.js +1 -0
- package/dist/cjs/dimensional-model/data-model.js +1 -0
- package/dist/cjs/dimensional-model/filters/factory.d.ts +140 -0
- package/dist/cjs/dimensional-model/filters/factory.js +162 -15
- package/dist/cjs/dimensional-model/filters/filter-relations.d.ts +1 -1
- package/dist/cjs/dimensional-model/filters/filter-relations.js +31 -6
- package/dist/cjs/dimensional-model/filters/filters.d.ts +35 -1
- package/dist/cjs/dimensional-model/filters/filters.js +68 -10
- package/dist/cjs/dimensional-model/filters/helpers.d.ts +1 -1
- package/dist/cjs/dimensional-model/filters/helpers.js +8 -9
- package/dist/cjs/dimensional-model/filters/utils/condition-filter-util.js +4 -0
- package/dist/cjs/dimensional-model/measures/factory.js +1 -0
- package/dist/cjs/dimensional-model/measures/measures.js +1 -1
- package/dist/cjs/dimensional-model/types.d.ts +4 -0
- package/dist/cjs/dimensional-model/types.js +24 -5
- package/dist/cjs/utils.js +1 -1
- package/dist/dimensional-model/base.js +1 -0
- package/dist/dimensional-model/data-model.js +1 -0
- package/dist/dimensional-model/filters/factory.d.ts +140 -0
- package/dist/dimensional-model/filters/factory.js +161 -14
- package/dist/dimensional-model/filters/filter-relations.d.ts +1 -1
- package/dist/dimensional-model/filters/filter-relations.js +3 -1
- package/dist/dimensional-model/filters/filters.d.ts +35 -1
- package/dist/dimensional-model/filters/filters.js +65 -9
- package/dist/dimensional-model/filters/helpers.d.ts +1 -1
- package/dist/dimensional-model/filters/helpers.js +1 -2
- package/dist/dimensional-model/filters/utils/condition-filter-util.js +4 -0
- package/dist/dimensional-model/measures/factory.js +1 -0
- package/dist/dimensional-model/types.d.ts +4 -0
- package/dist/dimensional-model/types.js +24 -5
- package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -1
- package/dist/utils.js +2 -2
- package/package.json +3 -3
|
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.withoutGuids = exports.findFilter = exports.withReplacedFilter = exports.withoutFilters = exports.withoutFilter = exports.withAddedFilters = exports.withAddedFilter = void 0;
|
|
7
7
|
const omit_js_1 = __importDefault(require("lodash-es/omit.js"));
|
|
8
|
-
const index_js_1 = require("../../index.js");
|
|
9
8
|
const filter_relations_js_1 = require("./filter-relations.js");
|
|
10
9
|
/**
|
|
11
10
|
* Returns a function that adds a filter to existing filters or filter relations.
|
|
@@ -28,7 +27,7 @@ const filter_relations_js_1 = require("./filter-relations.js");
|
|
|
28
27
|
*/
|
|
29
28
|
function withAddedFilter(filter) {
|
|
30
29
|
return (filters) => {
|
|
31
|
-
if ((0,
|
|
30
|
+
if ((0, filter_relations_js_1.isFilterRelations)(filters)) {
|
|
32
31
|
const { filters: existingFilters, relations } = (0, filter_relations_js_1.splitFiltersAndRelations)(filters);
|
|
33
32
|
const newFilters = [...existingFilters, filter];
|
|
34
33
|
const newRelations = (0, filter_relations_js_1.calculateNewRelations)(existingFilters, relations, newFilters);
|
|
@@ -59,7 +58,7 @@ exports.withAddedFilter = withAddedFilter;
|
|
|
59
58
|
*/
|
|
60
59
|
function withAddedFilters(filtersToAdd) {
|
|
61
60
|
return (filters) => {
|
|
62
|
-
if ((0,
|
|
61
|
+
if ((0, filter_relations_js_1.isFilterRelations)(filters)) {
|
|
63
62
|
const { filters: existingFilters, relations } = (0, filter_relations_js_1.splitFiltersAndRelations)(filters);
|
|
64
63
|
const newFilters = [...existingFilters, ...filtersToAdd];
|
|
65
64
|
const newRelations = (0, filter_relations_js_1.calculateNewRelations)(existingFilters, relations, newFilters);
|
|
@@ -90,7 +89,7 @@ exports.withAddedFilters = withAddedFilters;
|
|
|
90
89
|
*/
|
|
91
90
|
function withoutFilter(filterToRemove) {
|
|
92
91
|
return (filters) => {
|
|
93
|
-
if ((0,
|
|
92
|
+
if ((0, filter_relations_js_1.isFilterRelations)(filters)) {
|
|
94
93
|
const { filters: existingFilters, relations } = (0, filter_relations_js_1.splitFiltersAndRelations)(filters);
|
|
95
94
|
const newFilters = existingFilters.filter((filter) => filter.config.guid !== filterToRemove.config.guid);
|
|
96
95
|
const newRelations = (0, filter_relations_js_1.calculateNewRelations)(existingFilters, relations, newFilters);
|
|
@@ -121,7 +120,7 @@ exports.withoutFilter = withoutFilter;
|
|
|
121
120
|
*/
|
|
122
121
|
function withoutFilters(filtersToRemove) {
|
|
123
122
|
return (filters) => {
|
|
124
|
-
if ((0,
|
|
123
|
+
if ((0, filter_relations_js_1.isFilterRelations)(filters)) {
|
|
125
124
|
const { filters: existingFilters, relations } = (0, filter_relations_js_1.splitFiltersAndRelations)(filters);
|
|
126
125
|
const newFilters = existingFilters.filter((filter) => !filtersToRemove.some((filterToRemove) => filter.config.guid === filterToRemove.config.guid));
|
|
127
126
|
const newRelations = (0, filter_relations_js_1.calculateNewRelations)(existingFilters, relations, newFilters);
|
|
@@ -153,7 +152,7 @@ exports.withoutFilters = withoutFilters;
|
|
|
153
152
|
*/
|
|
154
153
|
function withReplacedFilter(filterToReplace, newFilter) {
|
|
155
154
|
return (filters) => {
|
|
156
|
-
if ((0,
|
|
155
|
+
if ((0, filter_relations_js_1.isFilterRelations)(filters)) {
|
|
157
156
|
const { filters: existingFilters, relations } = (0, filter_relations_js_1.splitFiltersAndRelations)(filters);
|
|
158
157
|
const newFilters = existingFilters.map((filter) => filter.config.guid === filterToReplace.config.guid ? newFilter : filter);
|
|
159
158
|
const newRelations = (0, filter_relations_js_1.getRelationsWithReplacedFilter)(relations, filterToReplace, newFilter);
|
|
@@ -176,7 +175,7 @@ function findFilter(filters, searchFn) {
|
|
|
176
175
|
if (!filters) {
|
|
177
176
|
return undefined;
|
|
178
177
|
}
|
|
179
|
-
const filtersArray = (0,
|
|
178
|
+
const filtersArray = (0, filter_relations_js_1.isFilterRelations)(filters) ? (0, filter_relations_js_1.getFiltersArray)(filters) : filters;
|
|
180
179
|
return filtersArray.find(searchFn);
|
|
181
180
|
}
|
|
182
181
|
exports.findFilter = findFilter;
|
|
@@ -197,7 +196,7 @@ function filterRelationsWithoutGuids(filterRelations) {
|
|
|
197
196
|
if (isFilter(node)) {
|
|
198
197
|
return filterWithoutGuid(node);
|
|
199
198
|
}
|
|
200
|
-
if ((0,
|
|
199
|
+
if ((0, filter_relations_js_1.isFilterRelations)(node)) {
|
|
201
200
|
return Object.assign(Object.assign({}, node), { left: traverse(node.left), right: traverse(node.right) });
|
|
202
201
|
}
|
|
203
202
|
return node;
|
|
@@ -215,7 +214,7 @@ function filterRelationsWithoutGuids(filterRelations) {
|
|
|
215
214
|
* @internal
|
|
216
215
|
*/
|
|
217
216
|
function withoutGuids(filters) {
|
|
218
|
-
if ((0,
|
|
217
|
+
if ((0, filter_relations_js_1.isFilterRelations)(filters)) {
|
|
219
218
|
return filterRelationsWithoutGuids(filters);
|
|
220
219
|
}
|
|
221
220
|
else {
|
|
@@ -209,6 +209,10 @@ const createMeasureFilterFromConditionFilterJaql = (measure, conditionFilterJaql
|
|
|
209
209
|
return filterFactory.measureBetween(measure, conditionFilterJaql.from, conditionFilterJaql.to, { guid });
|
|
210
210
|
case types_js_1.ConditionFilterType.IS_NOT_BETWEEN:
|
|
211
211
|
return filterFactory.exclude(filterFactory.measureBetween(measure, (_a = conditionFilterJaql.exclude) === null || _a === void 0 ? void 0 : _a.from, (_b = conditionFilterJaql.exclude) === null || _b === void 0 ? void 0 : _b.to, { guid }), undefined, { guid });
|
|
212
|
+
case types_js_1.ConditionFilterType.TOP:
|
|
213
|
+
return filterFactory.measureTopRanking(measure, conditionFilterJaql[types_js_1.ConditionFilterType.TOP], { guid });
|
|
214
|
+
case types_js_1.ConditionFilterType.BOTTOM:
|
|
215
|
+
return filterFactory.measureBottomRanking(measure, conditionFilterJaql[types_js_1.ConditionFilterType.BOTTOM], { guid });
|
|
212
216
|
}
|
|
213
217
|
throw new translatable_error_js_1.TranslatableError('errors.filter.unsupportedConditionFilter', {
|
|
214
218
|
filter: JSON.stringify(conditionFilterJaql),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* eslint-disable max-lines */
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.rank = exports.forecast = exports.trend = exports.contribution = exports.pastYear = exports.pastQuarter = exports.pastMonth = exports.pastWeek = exports.pastDay = exports.diffPastYear = exports.diffPastQuarter = exports.diffPastMonth = exports.diffPastWeek = exports.difference = exports.growthPastYear = exports.growthPastQuarter = exports.growthPastMonth = exports.growthPastWeek = exports.growthRate = exports.growth = exports.runningSum = exports.weekToDateSum = exports.monthToDateSum = exports.quarterToDateSum = exports.yearToDateSum = exports.divide = exports.multiply = exports.subtract = exports.add = exports.measuredValue = exports.countDistinct = exports.count = exports.median = exports.max = exports.min = exports.avg = exports.average = exports.sum = exports.constant = exports.aggregate = exports.customFormula = exports.RankingSortTypes = exports.RankingTypes = void 0;
|
|
4
5
|
const base_js_1 = require("../base.js");
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* eslint-disable max-params */
|
|
2
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
4
|
if (k2 === undefined) k2 = k;
|
|
4
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -24,7 +25,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
25
|
};
|
|
25
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
27
|
exports.createMeasure = exports.isDimensionalMeasureTemplate = exports.DimensionalMeasureTemplate = exports.isDimensionalCalculatedMeasure = exports.DimensionalCalculatedMeasure = exports.isDimensionalBaseMeasure = exports.DimensionalBaseMeasure = exports.AbstractMeasure = void 0;
|
|
27
|
-
/* eslint-disable max-params */
|
|
28
28
|
/* eslint-disable no-underscore-dangle */
|
|
29
29
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
30
30
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
@@ -157,6 +157,10 @@ export declare const DateLevels: {
|
|
|
157
157
|
readonly AggMinutesRoundTo1: "AggMinutesRoundTo1";
|
|
158
158
|
/** @internal */
|
|
159
159
|
readonly all: string[];
|
|
160
|
+
/** @internal */
|
|
161
|
+
readonly dateOnly: string[];
|
|
162
|
+
/** @internal */
|
|
163
|
+
readonly timeOnly: string[];
|
|
160
164
|
};
|
|
161
165
|
/** @internal */
|
|
162
166
|
export declare type DateLevel = Exclude<(typeof DateLevels)[keyof typeof DateLevels], typeof DateLevels.all>;
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
|
-
/*
|
|
6
|
-
* Types
|
|
7
|
-
*/
|
|
8
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
4
|
exports.CurrencyPosition = exports.JaqlSortDirection = exports.DataType = exports.DateLevels = exports.MetadataTypes = exports.Sort = exports.AggregationTypes = void 0;
|
|
10
5
|
/**
|
|
@@ -289,6 +284,30 @@ exports.DateLevels = {
|
|
|
289
284
|
exports.DateLevels.AggMinutesRoundTo1,
|
|
290
285
|
];
|
|
291
286
|
},
|
|
287
|
+
/** @internal */
|
|
288
|
+
get dateOnly() {
|
|
289
|
+
return [
|
|
290
|
+
exports.DateLevels.Years,
|
|
291
|
+
exports.DateLevels.Quarters,
|
|
292
|
+
exports.DateLevels.Months,
|
|
293
|
+
exports.DateLevels.Weeks,
|
|
294
|
+
exports.DateLevels.Days,
|
|
295
|
+
];
|
|
296
|
+
},
|
|
297
|
+
/** @internal */
|
|
298
|
+
get timeOnly() {
|
|
299
|
+
return [
|
|
300
|
+
exports.DateLevels.Hours,
|
|
301
|
+
exports.DateLevels.MinutesRoundTo30,
|
|
302
|
+
exports.DateLevels.MinutesRoundTo15,
|
|
303
|
+
exports.DateLevels.Minutes,
|
|
304
|
+
exports.DateLevels.Seconds,
|
|
305
|
+
exports.DateLevels.AggHours,
|
|
306
|
+
exports.DateLevels.AggMinutesRoundTo30,
|
|
307
|
+
exports.DateLevels.AggMinutesRoundTo15,
|
|
308
|
+
exports.DateLevels.AggMinutesRoundTo1,
|
|
309
|
+
];
|
|
310
|
+
},
|
|
292
311
|
};
|
|
293
312
|
/** @internal */
|
|
294
313
|
var DataType;
|
package/dist/cjs/utils.js
CHANGED
|
@@ -314,7 +314,7 @@ exports.getSortType = getSortType;
|
|
|
314
314
|
const createAttributeHelper = ({ expression, dataType, granularity, format, sort, title, panel, dataSource, }) => {
|
|
315
315
|
const column = parseExpression(expression).column;
|
|
316
316
|
const sortEnum = convertSort(sort);
|
|
317
|
-
const isDataTypeDatetime = dataType
|
|
317
|
+
const isDataTypeDatetime = dataType !== undefined && (0, simple_column_types_js_1.isDatetime)(dataType);
|
|
318
318
|
if (isDataTypeDatetime) {
|
|
319
319
|
const levelAttribute = new attributes_js_1.DimensionalLevelAttribute(title !== null && title !== void 0 ? title : column, expression, granularity || types_js_1.DateLevels.Years, format ||
|
|
320
320
|
attributes_js_1.DimensionalLevelAttribute.getDefaultFormatForGranularity(granularity || types_js_1.DateLevels.Years), undefined, sortEnum, dataSource, undefined, panel);
|
|
@@ -721,6 +721,146 @@ export declare const topRanking: (attribute: Attribute, measure: Measure, count:
|
|
|
721
721
|
* @returns A filter instance
|
|
722
722
|
*/
|
|
723
723
|
export declare const bottomRanking: (attribute: Attribute, measure: Measure, count: number, config?: BaseFilterConfig) => Filter;
|
|
724
|
+
/**
|
|
725
|
+
* Creates a filter that returns the top N values of the last dimension,
|
|
726
|
+
* independently for each unique combination of all preceding dimensions.
|
|
727
|
+
*
|
|
728
|
+
* This filter applies ranking within groups rather than globally. It shows the top N values
|
|
729
|
+
* of the rightmost dimension for every unique combination of the other dimensions to its left.
|
|
730
|
+
* The order of dimensions in your query determines the grouping behavior.
|
|
731
|
+
*
|
|
732
|
+
* **Key Differences from {@link topRanking}:**
|
|
733
|
+
* - `topRanking`: Filters a specific dimension globally (you specify which dimension)
|
|
734
|
+
* - `measureTopRanking`: Always filters the last/rightmost dimension, grouped by all others
|
|
735
|
+
*
|
|
736
|
+
* **How it works:**
|
|
737
|
+
* - With 1 dimension: Returns the top N values of that dimension
|
|
738
|
+
* - With 2+ dimensions: Returns the top N values of the LAST dimension for each combination of the others
|
|
739
|
+
*
|
|
740
|
+
* @example
|
|
741
|
+
* **Example 1: Single dimension (equivalent to topRanking) - Query with one dimension [Category]**
|
|
742
|
+
* ```ts
|
|
743
|
+
* // Returns top 5 Categories by total revenue
|
|
744
|
+
* filterFactory.measureTopRanking(
|
|
745
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
746
|
+
* 5
|
|
747
|
+
* )
|
|
748
|
+
* ```
|
|
749
|
+
* Result: 5 categories (e.g., Cell Phones, Computers, TVs, etc.)
|
|
750
|
+
*
|
|
751
|
+
* This produces the same result as:
|
|
752
|
+
* ```ts
|
|
753
|
+
* filterFactory.topRanking(
|
|
754
|
+
* DM.Commerce.Category,
|
|
755
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
756
|
+
* 5
|
|
757
|
+
* )
|
|
758
|
+
* ```
|
|
759
|
+
*
|
|
760
|
+
* **Note:** With only one dimension, there are no groups to rank within,
|
|
761
|
+
* so the behavior is identical to `topRanking`.
|
|
762
|
+
*
|
|
763
|
+
* @example
|
|
764
|
+
* **Example 2: Two dimensions - Query with dimensions [Gender, Category]**
|
|
765
|
+
* ```ts
|
|
766
|
+
* // Returns top 2 Categories for each Gender
|
|
767
|
+
* filterFactory.measureTopRanking(
|
|
768
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
769
|
+
* 2
|
|
770
|
+
* )
|
|
771
|
+
* ```
|
|
772
|
+
* Result: 3 genders × 2 categories each = 6 rows
|
|
773
|
+
* - Male: Top 2 categories by revenue
|
|
774
|
+
* - Female: Top 2 categories by revenue
|
|
775
|
+
* - Unspecified: Top 2 categories by revenue
|
|
776
|
+
*
|
|
777
|
+
* @example
|
|
778
|
+
* **Example 3: Three dimensions - Query with dimensions [Gender, Age Range, Category]**
|
|
779
|
+
* ```ts
|
|
780
|
+
* // Returns top 2 Categories for each (Gender, Age Range) combination
|
|
781
|
+
* filterFactory.measureTopRanking(
|
|
782
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
783
|
+
* 2
|
|
784
|
+
* )
|
|
785
|
+
* ```
|
|
786
|
+
* Result: 3 genders × 7 age ranges × 2 categories per combination = ~42 rows
|
|
787
|
+
*
|
|
788
|
+
* @param measure - Base measure to rank by
|
|
789
|
+
* @param count - Number of items to return per group (applies to the last dimension)
|
|
790
|
+
* @param config - Optional configuration for the filter
|
|
791
|
+
* @returns A filter instance
|
|
792
|
+
*/
|
|
793
|
+
export declare const measureTopRanking: (measure: BaseMeasure, count: number, config?: BaseFilterConfig) => Filter;
|
|
794
|
+
/**
|
|
795
|
+
* Creates a filter that returns the bottom N values of the last dimension,
|
|
796
|
+
* independently for each unique combination of all preceding dimensions.
|
|
797
|
+
*
|
|
798
|
+
* This filter applies ranking within groups rather than globally. It shows the bottom N values
|
|
799
|
+
* of the rightmost dimension for every unique combination of the other dimensions to its left.
|
|
800
|
+
* The order of dimensions in your query determines the grouping behavior.
|
|
801
|
+
*
|
|
802
|
+
* **Key Differences from {@link bottomRanking}:**
|
|
803
|
+
* - `bottomRanking`: Filters a specific dimension globally (you specify which dimension)
|
|
804
|
+
* - `measureBottomRanking`: Always filters the last/rightmost dimension, grouped by all others
|
|
805
|
+
*
|
|
806
|
+
* **How it works:**
|
|
807
|
+
* - With 1 dimension: Returns the bottom N values of that dimension
|
|
808
|
+
* - With 2+ dimensions: Returns the bottom N values of the LAST dimension for each combination of the others
|
|
809
|
+
*
|
|
810
|
+
* @example
|
|
811
|
+
* **Example 1: Single dimension (equivalent to bottomRanking) - Query with one dimension [Category]**
|
|
812
|
+
* ```ts
|
|
813
|
+
* // Returns bottom 5 Categories by revenue
|
|
814
|
+
* filterFactory.measureBottomRanking(
|
|
815
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
816
|
+
* 5
|
|
817
|
+
* )
|
|
818
|
+
* ```
|
|
819
|
+
* Result: 5 categories with lowest revenue (e.g., Accessories, Cables, etc.)
|
|
820
|
+
*
|
|
821
|
+
* This produces the same result as:
|
|
822
|
+
* ```ts
|
|
823
|
+
* filterFactory.bottomRanking(
|
|
824
|
+
* DM.Commerce.Category,
|
|
825
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
826
|
+
* 5
|
|
827
|
+
* )
|
|
828
|
+
* ```
|
|
829
|
+
*
|
|
830
|
+
* **Note:** With only one dimension, there are no groups to rank within,
|
|
831
|
+
* so the behavior is identical to `bottomRanking`.
|
|
832
|
+
*
|
|
833
|
+
* @example
|
|
834
|
+
* **Example 2: Two dimensions - Query with dimensions [Gender, Category]**
|
|
835
|
+
* ```ts
|
|
836
|
+
* // Returns bottom 2 Categories for each Gender
|
|
837
|
+
* filterFactory.measureBottomRanking(
|
|
838
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
839
|
+
* 2
|
|
840
|
+
* )
|
|
841
|
+
* ```
|
|
842
|
+
* Result: 3 genders × 2 categories each = 6 rows
|
|
843
|
+
* - Male: Bottom 2 categories by revenue
|
|
844
|
+
* - Female: Bottom 2 categories by revenue
|
|
845
|
+
* - Unspecified: Bottom 2 categories by revenue
|
|
846
|
+
*
|
|
847
|
+
* @example
|
|
848
|
+
* **Example 3: Three dimensions - Query with dimensions [Gender, Age Range, Category]**
|
|
849
|
+
* ```ts
|
|
850
|
+
* // Returns bottom 2 Categories for each (Gender, Age Range) combination
|
|
851
|
+
* filterFactory.measureBottomRanking(
|
|
852
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
853
|
+
* 2
|
|
854
|
+
* )
|
|
855
|
+
* ```
|
|
856
|
+
* Result: 3 genders × 7 age ranges × 2 categories per combination = ~42 rows
|
|
857
|
+
*
|
|
858
|
+
* @param measure - Base measure to rank by
|
|
859
|
+
* @param count - Number of items to return per group (applies to the last dimension)
|
|
860
|
+
* @param config - Optional configuration for the filter
|
|
861
|
+
* @returns A filter instance
|
|
862
|
+
*/
|
|
863
|
+
export declare const measureBottomRanking: (measure: BaseMeasure, count: number, config?: BaseFilterConfig) => Filter;
|
|
724
864
|
/**
|
|
725
865
|
* Creates a filter that contains a list of dependent/cascading filters,
|
|
726
866
|
* where each filter depends on the results or state of the previous ones in the array.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* eslint-disable max-params */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-shadow */
|
|
4
4
|
import { withComposeCodeForFilter, withComposeCodeForFilterRelations, } from '../compose-code-utils.js';
|
|
5
|
-
import { CascadingFilter, CustomFilter, DateOperators, DateRangeFilter, ExcludeFilter, LogicalAttributeFilter, LogicalOperators, MeasureFilter, MembersFilter, NumericFilter, NumericOperators, RankingFilter, RankingOperators, RelativeDateFilter, TextFilter, TextOperators, } from './filters.js';
|
|
5
|
+
import { CascadingFilter, CustomFilter, DateOperators, DateRangeFilter, ExcludeFilter, LogicalAttributeFilter, LogicalOperators, MeasureFilter, MeasureRankingFilter, MembersFilter, NumericFilter, NumericOperators, RankingFilter, RankingOperators, RelativeDateFilter, TextFilter, TextOperators, } from './filters.js';
|
|
6
6
|
// LOGICAL FILTERS
|
|
7
7
|
/**
|
|
8
8
|
* Creates a filter representing the union of multiple filters on the same attribute. The resulting
|
|
@@ -746,19 +746,146 @@ export const topRanking = withComposeCodeForFilter((attribute, measure, count, c
|
|
|
746
746
|
* @returns A filter instance
|
|
747
747
|
*/
|
|
748
748
|
export const bottomRanking = withComposeCodeForFilter((attribute, measure, count, config) => new RankingFilter(attribute, measure, RankingOperators.Bottom, count, config), 'bottomRanking');
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
749
|
+
/**
|
|
750
|
+
* Creates a filter that returns the top N values of the last dimension,
|
|
751
|
+
* independently for each unique combination of all preceding dimensions.
|
|
752
|
+
*
|
|
753
|
+
* This filter applies ranking within groups rather than globally. It shows the top N values
|
|
754
|
+
* of the rightmost dimension for every unique combination of the other dimensions to its left.
|
|
755
|
+
* The order of dimensions in your query determines the grouping behavior.
|
|
756
|
+
*
|
|
757
|
+
* **Key Differences from {@link topRanking}:**
|
|
758
|
+
* - `topRanking`: Filters a specific dimension globally (you specify which dimension)
|
|
759
|
+
* - `measureTopRanking`: Always filters the last/rightmost dimension, grouped by all others
|
|
760
|
+
*
|
|
761
|
+
* **How it works:**
|
|
762
|
+
* - With 1 dimension: Returns the top N values of that dimension
|
|
763
|
+
* - With 2+ dimensions: Returns the top N values of the LAST dimension for each combination of the others
|
|
764
|
+
*
|
|
765
|
+
* @example
|
|
766
|
+
* **Example 1: Single dimension (equivalent to topRanking) - Query with one dimension [Category]**
|
|
767
|
+
* ```ts
|
|
768
|
+
* // Returns top 5 Categories by total revenue
|
|
769
|
+
* filterFactory.measureTopRanking(
|
|
770
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
771
|
+
* 5
|
|
772
|
+
* )
|
|
773
|
+
* ```
|
|
774
|
+
* Result: 5 categories (e.g., Cell Phones, Computers, TVs, etc.)
|
|
775
|
+
*
|
|
776
|
+
* This produces the same result as:
|
|
777
|
+
* ```ts
|
|
778
|
+
* filterFactory.topRanking(
|
|
779
|
+
* DM.Commerce.Category,
|
|
780
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
781
|
+
* 5
|
|
782
|
+
* )
|
|
783
|
+
* ```
|
|
784
|
+
*
|
|
785
|
+
* **Note:** With only one dimension, there are no groups to rank within,
|
|
786
|
+
* so the behavior is identical to `topRanking`.
|
|
787
|
+
*
|
|
788
|
+
* @example
|
|
789
|
+
* **Example 2: Two dimensions - Query with dimensions [Gender, Category]**
|
|
790
|
+
* ```ts
|
|
791
|
+
* // Returns top 2 Categories for each Gender
|
|
792
|
+
* filterFactory.measureTopRanking(
|
|
793
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
794
|
+
* 2
|
|
795
|
+
* )
|
|
796
|
+
* ```
|
|
797
|
+
* Result: 3 genders × 2 categories each = 6 rows
|
|
798
|
+
* - Male: Top 2 categories by revenue
|
|
799
|
+
* - Female: Top 2 categories by revenue
|
|
800
|
+
* - Unspecified: Top 2 categories by revenue
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* **Example 3: Three dimensions - Query with dimensions [Gender, Age Range, Category]**
|
|
804
|
+
* ```ts
|
|
805
|
+
* // Returns top 2 Categories for each (Gender, Age Range) combination
|
|
806
|
+
* filterFactory.measureTopRanking(
|
|
807
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
808
|
+
* 2
|
|
809
|
+
* )
|
|
810
|
+
* ```
|
|
811
|
+
* Result: 3 genders × 7 age ranges × 2 categories per combination = ~42 rows
|
|
812
|
+
*
|
|
813
|
+
* @param measure - Base measure to rank by
|
|
814
|
+
* @param count - Number of items to return per group (applies to the last dimension)
|
|
815
|
+
* @param config - Optional configuration for the filter
|
|
816
|
+
* @returns A filter instance
|
|
817
|
+
*/
|
|
818
|
+
export const measureTopRanking = withComposeCodeForFilter((measure, count, config) => new MeasureRankingFilter(measure, RankingOperators.Top, count, config), 'measureTopRanking');
|
|
819
|
+
/**
|
|
820
|
+
* Creates a filter that returns the bottom N values of the last dimension,
|
|
821
|
+
* independently for each unique combination of all preceding dimensions.
|
|
822
|
+
*
|
|
823
|
+
* This filter applies ranking within groups rather than globally. It shows the bottom N values
|
|
824
|
+
* of the rightmost dimension for every unique combination of the other dimensions to its left.
|
|
825
|
+
* The order of dimensions in your query determines the grouping behavior.
|
|
826
|
+
*
|
|
827
|
+
* **Key Differences from {@link bottomRanking}:**
|
|
828
|
+
* - `bottomRanking`: Filters a specific dimension globally (you specify which dimension)
|
|
829
|
+
* - `measureBottomRanking`: Always filters the last/rightmost dimension, grouped by all others
|
|
830
|
+
*
|
|
831
|
+
* **How it works:**
|
|
832
|
+
* - With 1 dimension: Returns the bottom N values of that dimension
|
|
833
|
+
* - With 2+ dimensions: Returns the bottom N values of the LAST dimension for each combination of the others
|
|
834
|
+
*
|
|
835
|
+
* @example
|
|
836
|
+
* **Example 1: Single dimension (equivalent to bottomRanking) - Query with one dimension [Category]**
|
|
837
|
+
* ```ts
|
|
838
|
+
* // Returns bottom 5 Categories by revenue
|
|
839
|
+
* filterFactory.measureBottomRanking(
|
|
840
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
841
|
+
* 5
|
|
842
|
+
* )
|
|
843
|
+
* ```
|
|
844
|
+
* Result: 5 categories with lowest revenue (e.g., Accessories, Cables, etc.)
|
|
845
|
+
*
|
|
846
|
+
* This produces the same result as:
|
|
847
|
+
* ```ts
|
|
848
|
+
* filterFactory.bottomRanking(
|
|
849
|
+
* DM.Commerce.Category,
|
|
850
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
851
|
+
* 5
|
|
852
|
+
* )
|
|
853
|
+
* ```
|
|
854
|
+
*
|
|
855
|
+
* **Note:** With only one dimension, there are no groups to rank within,
|
|
856
|
+
* so the behavior is identical to `bottomRanking`.
|
|
857
|
+
*
|
|
858
|
+
* @example
|
|
859
|
+
* **Example 2: Two dimensions - Query with dimensions [Gender, Category]**
|
|
860
|
+
* ```ts
|
|
861
|
+
* // Returns bottom 2 Categories for each Gender
|
|
862
|
+
* filterFactory.measureBottomRanking(
|
|
863
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
864
|
+
* 2
|
|
865
|
+
* )
|
|
866
|
+
* ```
|
|
867
|
+
* Result: 3 genders × 2 categories each = 6 rows
|
|
868
|
+
* - Male: Bottom 2 categories by revenue
|
|
869
|
+
* - Female: Bottom 2 categories by revenue
|
|
870
|
+
* - Unspecified: Bottom 2 categories by revenue
|
|
871
|
+
*
|
|
872
|
+
* @example
|
|
873
|
+
* **Example 3: Three dimensions - Query with dimensions [Gender, Age Range, Category]**
|
|
874
|
+
* ```ts
|
|
875
|
+
* // Returns bottom 2 Categories for each (Gender, Age Range) combination
|
|
876
|
+
* filterFactory.measureBottomRanking(
|
|
877
|
+
* measureFactory.sum(DM.Commerce.Revenue),
|
|
878
|
+
* 2
|
|
879
|
+
* )
|
|
880
|
+
* ```
|
|
881
|
+
* Result: 3 genders × 7 age ranges × 2 categories per combination = ~42 rows
|
|
882
|
+
*
|
|
883
|
+
* @param measure - Base measure to rank by
|
|
884
|
+
* @param count - Number of items to return per group (applies to the last dimension)
|
|
885
|
+
* @param config - Optional configuration for the filter
|
|
886
|
+
* @returns A filter instance
|
|
887
|
+
*/
|
|
888
|
+
export const measureBottomRanking = withComposeCodeForFilter((measure, count, config) => new MeasureRankingFilter(measure, RankingOperators.Bottom, count, config), 'measureBottomRanking');
|
|
762
889
|
// CASCADING FILTERS
|
|
763
890
|
/**
|
|
764
891
|
* Creates a filter that contains a list of dependent/cascading filters,
|
|
@@ -815,6 +942,26 @@ export const cascading = withComposeCodeForFilter((filters, config) => new Casca
|
|
|
815
942
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
816
943
|
export var logic;
|
|
817
944
|
(function (logic) {
|
|
945
|
+
/**
|
|
946
|
+
* Relates a filter or filter relations node
|
|
947
|
+
*
|
|
948
|
+
* @param node - Filter or filter relations node
|
|
949
|
+
* @returns Related filter or filter relations node
|
|
950
|
+
* @internal
|
|
951
|
+
*/
|
|
952
|
+
const relate = (node) => {
|
|
953
|
+
if (Array.isArray(node)) {
|
|
954
|
+
const [first, ...rest] = node;
|
|
955
|
+
return rest.length === 0
|
|
956
|
+
? relate(first)
|
|
957
|
+
: {
|
|
958
|
+
operator: 'AND',
|
|
959
|
+
left: relate(first),
|
|
960
|
+
right: relate(rest),
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
return node;
|
|
964
|
+
};
|
|
818
965
|
/**
|
|
819
966
|
* Creates an 'AND' filter relations
|
|
820
967
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Filter, FilterRelations, FilterRelationsJaql, FilterRelationsModel, FilterRelationsModelNode } from '
|
|
1
|
+
import { Filter, FilterRelations, FilterRelationsJaql, FilterRelationsModel, FilterRelationsModelNode } from '../interfaces.js';
|
|
2
2
|
/**
|
|
3
3
|
* Type guard for checking if the provided filters are FilterRelations.
|
|
4
4
|
*
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/default-param-last */
|
|
2
2
|
import cloneDeep from 'lodash-es/cloneDeep.js';
|
|
3
3
|
import isArray from 'lodash-es/isArray.js';
|
|
4
|
-
import { DimensionalLevelAttribute, filterFactory, isCascadingFilter, } from '../../index.js';
|
|
5
4
|
import { TranslatableError } from '../../translation/translatable-error.js';
|
|
5
|
+
import { DimensionalLevelAttribute } from '../attributes.js';
|
|
6
|
+
import * as filterFactory from './factory.js';
|
|
7
|
+
import { isCascadingFilter } from './filters.js';
|
|
6
8
|
/**
|
|
7
9
|
* Type guard for checking if the provided filters are FilterRelations.
|
|
8
10
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DimensionalElement } from '../base.js';
|
|
2
|
-
import { Attribute, BaseFilterConfig, CompleteBaseFilterConfig, CompleteMembersFilterConfig, Filter, LevelAttribute, Measure, MembersFilterConfig } from '../interfaces.js';
|
|
2
|
+
import { Attribute, BaseFilterConfig, BaseMeasure, CompleteBaseFilterConfig, CompleteMembersFilterConfig, Filter, LevelAttribute, Measure, MembersFilterConfig } from '../interfaces.js';
|
|
3
3
|
import { AnyObject, JSONObject } from '../types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Different text operators that can be used with text filters
|
|
@@ -70,6 +70,7 @@ export declare const FilterTypes: {
|
|
|
70
70
|
readonly exclude: "exclude";
|
|
71
71
|
readonly measure: "measure";
|
|
72
72
|
readonly ranking: "ranking";
|
|
73
|
+
readonly measureRanking: "measure-ranking";
|
|
73
74
|
readonly text: "text";
|
|
74
75
|
readonly numeric: "numeric";
|
|
75
76
|
readonly dateRange: "dateRange";
|
|
@@ -298,6 +299,32 @@ export declare class RankingFilter extends AbstractFilter {
|
|
|
298
299
|
*/
|
|
299
300
|
filterJaql(): any;
|
|
300
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* @internal
|
|
304
|
+
*/
|
|
305
|
+
export declare class MeasureRankingFilter extends AbstractFilter {
|
|
306
|
+
/**
|
|
307
|
+
* @internal
|
|
308
|
+
*/
|
|
309
|
+
readonly __serializable: string;
|
|
310
|
+
count: number;
|
|
311
|
+
operator: string;
|
|
312
|
+
measure: BaseMeasure;
|
|
313
|
+
constructor(measure: BaseMeasure, operator: string, count: number, config?: BaseFilterConfig, composeCode?: string);
|
|
314
|
+
/**
|
|
315
|
+
* gets the element's ID
|
|
316
|
+
*/
|
|
317
|
+
get id(): string;
|
|
318
|
+
/**
|
|
319
|
+
* Gets a serializable representation of the element
|
|
320
|
+
*/
|
|
321
|
+
serialize(): JSONObject;
|
|
322
|
+
/**
|
|
323
|
+
* Gets JAQL representing this Filter instance
|
|
324
|
+
*/
|
|
325
|
+
filterJaql(): any;
|
|
326
|
+
jaql(nested?: boolean | undefined): any;
|
|
327
|
+
}
|
|
301
328
|
/**
|
|
302
329
|
* @internal
|
|
303
330
|
*/
|
|
@@ -427,6 +454,13 @@ export declare function isNumericFilter(filter: Filter & AnyObject): filter is N
|
|
|
427
454
|
* @internal
|
|
428
455
|
*/
|
|
429
456
|
export declare function isRankingFilter(filter: Filter & AnyObject): filter is RankingFilter;
|
|
457
|
+
/**
|
|
458
|
+
* Checks if a filter is a MeasureRankingFilter.
|
|
459
|
+
*
|
|
460
|
+
* @param filter - The filter to check.
|
|
461
|
+
* @internal
|
|
462
|
+
*/
|
|
463
|
+
export declare function isMeasureRankingFilter(filter: Filter & AnyObject): filter is MeasureRankingFilter;
|
|
430
464
|
/**
|
|
431
465
|
* Checks if a filter is a MeasureFilter.
|
|
432
466
|
*
|