@carto/api-client 0.5.7-alpha.1 → 0.5.7-alpha.3

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/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "homepage": "https://github.com/CartoDB/carto-api-client#readme",
9
9
  "author": "Don McCurdy <donmccurdy@carto.com>",
10
10
  "packageManager": "yarn@4.3.1",
11
- "version": "0.5.7-alpha.1",
11
+ "version": "0.5.7-alpha.3",
12
12
  "license": "MIT",
13
13
  "publishConfig": {
14
14
  "access": "public"
@@ -1,4 +1,5 @@
1
1
  import {aggregationFunctions, aggregate} from './aggregation.js';
2
+ import {OTHERS_CATEGORY_NAME} from '../widget-sources/constants.js';
2
3
  import type {AggregationType} from '../types.js';
3
4
  import type {FeatureData} from '../types-internal.js';
4
5
 
@@ -15,12 +16,14 @@ export function groupValuesByColumn({
15
16
  joinOperation,
16
17
  keysColumn,
17
18
  operation,
19
+ othersThreshold,
18
20
  }: {
19
21
  data: FeatureData[];
20
22
  valuesColumns?: string[];
21
23
  joinOperation?: AggregationType;
22
24
  keysColumn: string;
23
25
  operation: AggregationType;
26
+ othersThreshold?: number;
24
27
  }): GroupByFeature | null {
25
28
  if (Array.isArray(data) && data.length === 0) {
26
29
  return null;
@@ -48,12 +51,27 @@ export function groupValuesByColumn({
48
51
  const targetOperation =
49
52
  aggregationFunctions[operation as Exclude<AggregationType, 'custom'>];
50
53
 
51
- if (targetOperation) {
52
- return Array.from(groups).map(([name, value]) => ({
53
- name,
54
- value: targetOperation(value),
55
- }));
54
+ if (!targetOperation) {
55
+ return [];
56
56
  }
57
57
 
58
- return [];
58
+ const allCategories = Array.from(groups).map(([name, value]) => ({
59
+ name,
60
+ value: targetOperation(value),
61
+ }));
62
+
63
+ allCategories.sort((a, b) => b.value - a.value);
64
+
65
+ if (othersThreshold && allCategories.length > othersThreshold) {
66
+ const otherNames = allCategories
67
+ .map((entry) => entry.name)
68
+ .slice(othersThreshold);
69
+ const otherValue = otherNames.flatMap((name) => groups.get(name));
70
+ allCategories.push({
71
+ name: OTHERS_CATEGORY_NAME,
72
+ value: targetOperation(otherValue),
73
+ });
74
+ }
75
+
76
+ return allCategories;
59
77
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Name of the category that represents the "Others" category.
3
+ *
4
+ * See `WidgetSource.getCategories` for more information.
5
+ */
6
+ export const OTHERS_CATEGORY_NAME = '_carto_others';
@@ -5,3 +5,4 @@ export * from './widget-remote-source.js';
5
5
  export * from './widget-table-source.js';
6
6
  export * from './widget-tileset-source.js';
7
7
  export * from './types.js';
8
+ export * from './constants.js';
@@ -59,8 +59,8 @@ export interface CategoryRequestOptions extends BaseRequestOptions {
59
59
  operationColumn?: string;
60
60
  /** Local only. */
61
61
  joinOperation?: 'count' | 'avg' | 'min' | 'max' | 'sum';
62
- /** Maximum number of items to return. Backend calculates also __carto_others category. Remote only. */
63
- maxItems?: number;
62
+ /** Calculate `_carto_others` category for all categories after first N (N is threshold). */
63
+ othersThreshold?: number;
64
64
  }
65
65
 
66
66
  /**
@@ -208,7 +208,7 @@ export type FeaturesResponse = {rows: Record<string, unknown>[]};
208
208
  export type FormulaResponse = {value: number | null};
209
209
 
210
210
  /** Response from {@link WidgetRemoteSource#getCategories}. */
211
- export type CategoryResponse = {name: string; value: number}[];
211
+ export type CategoryResponse = {name: string | null; value: number}[];
212
212
 
213
213
  /** Response from {@link WidgetRemoteSource#getRange}. */
214
214
  export type RangeResponse = {min: number; max: number} | null;
@@ -74,7 +74,8 @@ export abstract class WidgetRemoteSource<
74
74
  spatialFiltersMode,
75
75
  ...params
76
76
  } = options;
77
- const {column, operation, operationColumn, operationExp, maxItems} = params;
77
+ const {column, operation, operationColumn, operationExp, othersThreshold} =
78
+ params;
78
79
 
79
80
  if (operation === AggregationTypes.Custom) {
80
81
  assert(operationExp, 'operationExp is required for custom operation');
@@ -94,7 +95,7 @@ export abstract class WidgetRemoteSource<
94
95
  operation,
95
96
  operationExp,
96
97
  operationColumn: operationColumn || column,
97
- maxItems,
98
+ othersThreshold,
98
99
  },
99
100
  opts: {signal, headers: this.props.headers},
100
101
  }).then((res: CategoriesModelResponse) => normalizeObjectKeys(res.rows));
@@ -190,6 +190,7 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
190
190
  filters,
191
191
  filterOwner,
192
192
  spatialFilter,
193
+ othersThreshold,
193
194
  }: CategoryRequestOptions): Promise<CategoryResponse> {
194
195
  const filteredFeatures = this._getFilteredFeatures(
195
196
  spatialFilter,
@@ -209,6 +210,7 @@ export class WidgetTilesetSourceImpl extends WidgetSource<WidgetTilesetSourcePro
209
210
  joinOperation,
210
211
  keysColumn: column,
211
212
  operation,
213
+ othersThreshold,
212
214
  });
213
215
 
214
216
  return groups || [];