dbgate-datalib 6.4.3-alpha.1 → 6.5.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.
@@ -32,6 +32,7 @@ export declare class FreeTableGridDisplay extends GridDisplay {
32
32
  options?: [];
33
33
  canSelectMultipleOptions?: boolean;
34
34
  undropColumnName?: string;
35
+ hasAutoValue?: boolean;
35
36
  contentHash?: string;
36
37
  engine?: string;
37
38
  }[];
@@ -61,6 +62,7 @@ export declare class FreeTableGridDisplay extends GridDisplay {
61
62
  options?: [];
62
63
  canSelectMultipleOptions?: boolean;
63
64
  undropColumnName?: string;
65
+ hasAutoValue?: boolean;
64
66
  contentHash?: string;
65
67
  engine?: string;
66
68
  };
@@ -12,6 +12,7 @@ export interface DisplayColumn {
12
12
  notNull?: boolean;
13
13
  autoIncrement?: boolean;
14
14
  isPrimaryKey?: boolean;
15
+ hasAutoValue?: boolean;
15
16
  isPartitionKey?: boolean;
16
17
  isClusterKey?: boolean;
17
18
  isUniqueKey?: boolean;
@@ -40,7 +41,8 @@ export declare abstract class GridDisplay {
40
41
  driver?: EngineDriver;
41
42
  dbinfo: DatabaseInfo;
42
43
  serverVersion: any;
43
- constructor(config: GridConfig, setConfig: ChangeConfigFunc, cache: GridCache, setCache: ChangeCacheFunc, driver?: EngineDriver, dbinfo?: DatabaseInfo, serverVersion?: any);
44
+ currentSettings: any;
45
+ constructor(config: GridConfig, setConfig: ChangeConfigFunc, cache: GridCache, setCache: ChangeCacheFunc, driver?: EngineDriver, dbinfo?: DatabaseInfo, serverVersion?: any, currentSettings?: any);
44
46
  dialect: SqlDialect;
45
47
  columns: DisplayColumn[];
46
48
  formColumns: DisplayColumn[];
@@ -11,7 +11,7 @@ const dbgate_tools_1 = require("dbgate-tools");
11
11
  const dbgate_sqltree_1 = require("dbgate-sqltree");
12
12
  const dbgate_tools_2 = require("dbgate-tools");
13
13
  class GridDisplay {
14
- constructor(config, setConfig, cache, setCache, driver, dbinfo = null, serverVersion = null) {
14
+ constructor(config, setConfig, cache, setCache, driver, dbinfo = null, serverVersion = null, currentSettings = null) {
15
15
  this.config = config;
16
16
  this.setConfig = setConfig;
17
17
  this.cache = cache;
@@ -19,6 +19,7 @@ class GridDisplay {
19
19
  this.driver = driver;
20
20
  this.dbinfo = dbinfo;
21
21
  this.serverVersion = serverVersion;
22
+ this.currentSettings = currentSettings;
22
23
  this.formColumns = [];
23
24
  this.changeSetKeyFields = null;
24
25
  this.editableStructure = null;
@@ -114,9 +115,10 @@ class GridDisplay {
114
115
  this.setConfig(cfg => (Object.assign(Object.assign({}, cfg), { searchInColumns })));
115
116
  }
116
117
  get hiddenColumnIndexes() {
118
+ var _a;
117
119
  // console.log('GridDisplay.hiddenColumn', this.config.hiddenColumns);
118
120
  const res = (this.config.hiddenColumns || []).map(x => lodash_1.default.findIndex(this.allColumns, y => y.uniqueName == x));
119
- if (this.config.searchInColumns) {
121
+ if (this.config.searchInColumns && !((_a = this.currentSettings) === null || _a === void 0 ? void 0 : _a['dataGrid.showAllColumnsWhenSearch'])) {
120
122
  for (let i = 0; i < this.allColumns.length; i++) {
121
123
  if (!(0, dbgate_tools_1.filterName)(this.config.searchInColumns, this.allColumns[i].columnName)) {
122
124
  res.push(i);
@@ -13,10 +13,11 @@ export declare class TableGridDisplay extends GridDisplay {
13
13
  displayOptions: any;
14
14
  getDictionaryDescription: DictionaryDescriptionFunc;
15
15
  isRawMode: boolean;
16
+ currentSettings: any;
16
17
  table: TableInfo;
17
18
  addAllExpandedColumnsToSelected: boolean;
18
19
  hintBaseColumns: DisplayColumn[];
19
- constructor(tableName: NamedObjectInfo, driver: EngineDriver, config: GridConfig, setConfig: ChangeConfigFunc, cache: GridCache, setCache: ChangeCacheFunc, dbinfo: DatabaseInfo, displayOptions: any, serverVersion: any, getDictionaryDescription?: DictionaryDescriptionFunc, isReadOnly?: boolean, isRawMode?: boolean);
20
+ constructor(tableName: NamedObjectInfo, driver: EngineDriver, config: GridConfig, setConfig: ChangeConfigFunc, cache: GridCache, setCache: ChangeCacheFunc, dbinfo: DatabaseInfo, displayOptions: any, serverVersion: any, getDictionaryDescription?: DictionaryDescriptionFunc, isReadOnly?: boolean, isRawMode?: boolean, currentSettings?: any);
20
21
  addFormDisplayColumns(columns: any): void;
21
22
  findTable({ schemaName, pureName }: {
22
23
  schemaName?: any;
@@ -33,6 +34,7 @@ export declare class TableGridDisplay extends GridDisplay {
33
34
  uniqueName: string;
34
35
  uniquePath: string[];
35
36
  isPrimaryKey: boolean;
37
+ hasAutoValue: boolean;
36
38
  foreignKey: ForeignKeyInfo;
37
39
  isForeignKeyUnique: boolean;
38
40
  pairingId?: string;
@@ -75,6 +77,7 @@ export declare class TableGridDisplay extends GridDisplay {
75
77
  uniqueName: string;
76
78
  uniquePath: string[];
77
79
  isPrimaryKey: boolean;
80
+ hasAutoValue: boolean;
78
81
  foreignKey: ForeignKeyInfo;
79
82
  isForeignKeyUnique: boolean;
80
83
  pairingId?: string;
@@ -4,12 +4,13 @@ exports.TableGridDisplay = void 0;
4
4
  const dbgate_tools_1 = require("dbgate-tools");
5
5
  const GridDisplay_1 = require("./GridDisplay");
6
6
  class TableGridDisplay extends GridDisplay_1.GridDisplay {
7
- constructor(tableName, driver, config, setConfig, cache, setCache, dbinfo, displayOptions, serverVersion, getDictionaryDescription = null, isReadOnly = false, isRawMode = false) {
8
- super(config, setConfig, cache, setCache, driver, dbinfo, serverVersion);
7
+ constructor(tableName, driver, config, setConfig, cache, setCache, dbinfo, displayOptions, serverVersion, getDictionaryDescription = null, isReadOnly = false, isRawMode = false, currentSettings = null) {
8
+ super(config, setConfig, cache, setCache, driver, dbinfo, serverVersion, currentSettings);
9
9
  this.tableName = tableName;
10
10
  this.displayOptions = displayOptions;
11
11
  this.getDictionaryDescription = getDictionaryDescription;
12
12
  this.isRawMode = isRawMode;
13
+ this.currentSettings = currentSettings;
13
14
  this.addAllExpandedColumnsToSelected = false;
14
15
  this.table = this.findTable(tableName);
15
16
  if (!this.table) {
@@ -197,7 +198,7 @@ class TableGridDisplay extends GridDisplay_1.GridDisplay {
197
198
  const uniqueName = uniquePath.join('.');
198
199
  // console.log('this.config.addedColumns', this.config.addedColumns, uniquePath);
199
200
  const res = Object.assign(Object.assign({}, col), { pureName: table.pureName, schemaName: table.schemaName, headerText: uniquePath.length == 1 ? col.columnName : `${table.pureName}.${col.columnName}`, uniqueName,
200
- uniquePath, isPrimaryKey: table.primaryKey && !!table.primaryKey.columns.find(x => x.columnName == col.columnName), foreignKey: table.foreignKeys &&
201
+ uniquePath, isPrimaryKey: table.primaryKey && !!table.primaryKey.columns.find(x => x.columnName == col.columnName), hasAutoValue: col.hasAutoValue, foreignKey: table.foreignKeys &&
201
202
  table.foreignKeys.find(fk => fk.columns.length == 1 && fk.columns[0].columnName == col.columnName), isForeignKeyUnique: false });
202
203
  if (res.foreignKey) {
203
204
  const refTableInfo = this.dbinfo.tables.find(x => x.schemaName == res.foreignKey.refSchemaName && x.pureName == res.foreignKey.refTableName);
@@ -31,6 +31,7 @@ export declare class ViewGridDisplay extends GridDisplay {
31
31
  options?: [];
32
32
  canSelectMultipleOptions?: boolean;
33
33
  undropColumnName?: string;
34
+ hasAutoValue?: boolean;
34
35
  contentHash?: string;
35
36
  engine?: string;
36
37
  }[];
@@ -60,6 +61,7 @@ export declare class ViewGridDisplay extends GridDisplay {
60
61
  options?: [];
61
62
  canSelectMultipleOptions?: boolean;
62
63
  undropColumnName?: string;
64
+ hasAutoValue?: boolean;
63
65
  contentHash?: string;
64
66
  engine?: string;
65
67
  };
@@ -0,0 +1,80 @@
1
+ export type ChartTypeEnum = 'bar' | 'line' | 'pie' | 'polarArea';
2
+ export type ChartXTransformFunction = 'identity' | 'date:minute' | 'date:hour' | 'date:day' | 'date:month' | 'date:year';
3
+ export type ChartYAggregateFunction = 'sum' | 'first' | 'last' | 'min' | 'max' | 'count' | 'avg';
4
+ export type ChartDataLabelFormatter = 'number' | 'size:bytes' | 'size:kb' | 'size:mb' | 'size:gb';
5
+ export declare const ChartConstDefaults: {
6
+ sortOrder: string;
7
+ windowAlign: string;
8
+ windowSize: number;
9
+ parentAggregateLimit: number;
10
+ };
11
+ export declare const ChartLimits: {
12
+ AUTODETECT_CHART_LIMIT: number;
13
+ AUTODETECT_MEASURES_LIMIT: number;
14
+ APPLY_LIMIT_AFTER_ROWS: number;
15
+ MAX_DISTINCT_VALUES: number;
16
+ VALID_VALUE_RATIO_LIMIT: number;
17
+ PIE_RATIO_LIMIT: number;
18
+ PIE_COUNT_LIMIT: number;
19
+ };
20
+ export interface ChartXFieldDefinition {
21
+ field: string;
22
+ title?: string;
23
+ transformFunction: ChartXTransformFunction;
24
+ sortOrder?: 'natural' | 'ascKeys' | 'descKeys' | 'ascValues' | 'descValues';
25
+ windowAlign?: 'start' | 'end';
26
+ windowSize?: number;
27
+ parentAggregateLimit?: number;
28
+ }
29
+ export interface ChartYFieldDefinition {
30
+ field: string;
31
+ title?: string;
32
+ aggregateFunction: ChartYAggregateFunction;
33
+ }
34
+ export interface ChartDefinition {
35
+ chartType: ChartTypeEnum;
36
+ title?: string;
37
+ pieRatioLimit?: number;
38
+ pieCountLimit?: number;
39
+ xdef: ChartXFieldDefinition;
40
+ ydefs: ChartYFieldDefinition[];
41
+ useDataLabels?: boolean;
42
+ dataLabelFormatter?: ChartDataLabelFormatter;
43
+ }
44
+ export interface ChartDateParsed {
45
+ year: number;
46
+ month?: number;
47
+ day?: number;
48
+ hour?: number;
49
+ minute?: number;
50
+ second?: number;
51
+ fraction?: string;
52
+ }
53
+ export interface ChartAvailableColumn {
54
+ field: string;
55
+ }
56
+ export interface ProcessedChart {
57
+ minX?: string;
58
+ maxX?: string;
59
+ rowsAdded: number;
60
+ buckets: {
61
+ [key: string]: any;
62
+ };
63
+ bucketKeysOrdered: string[];
64
+ bucketKeyDateParsed: {
65
+ [key: string]: ChartDateParsed;
66
+ };
67
+ isGivenDefinition: boolean;
68
+ invalidXRows: number;
69
+ invalidYRows: {
70
+ [key: string]: number;
71
+ };
72
+ validYRows: {
73
+ [key: string]: number;
74
+ };
75
+ topDistinctValues: {
76
+ [key: string]: Set<any>;
77
+ };
78
+ availableColumns: ChartAvailableColumn[];
79
+ definition: ChartDefinition;
80
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChartLimits = exports.ChartConstDefaults = void 0;
4
+ exports.ChartConstDefaults = {
5
+ sortOrder: ' asc',
6
+ windowAlign: 'end',
7
+ windowSize: 100,
8
+ parentAggregateLimit: 200,
9
+ };
10
+ exports.ChartLimits = {
11
+ AUTODETECT_CHART_LIMIT: 10,
12
+ AUTODETECT_MEASURES_LIMIT: 10,
13
+ APPLY_LIMIT_AFTER_ROWS: 100,
14
+ MAX_DISTINCT_VALUES: 10,
15
+ VALID_VALUE_RATIO_LIMIT: 0.5,
16
+ PIE_RATIO_LIMIT: 0.05,
17
+ PIE_COUNT_LIMIT: 10, // limit for number of pie chart slices, if the number of slices is above this, it will be grouped into "Other"
18
+ };
@@ -0,0 +1,23 @@
1
+ import { ChartAvailableColumn, ChartDateParsed, ChartDefinition, ProcessedChart } from './chartDefinitions';
2
+ export declare class ChartProcessor {
3
+ givenDefinitions: ChartDefinition[];
4
+ chartsProcessing: ProcessedChart[];
5
+ charts: ProcessedChart[];
6
+ availableColumnsDict: {
7
+ [field: string]: ChartAvailableColumn;
8
+ };
9
+ availableColumns: ChartAvailableColumn[];
10
+ autoDetectCharts: boolean;
11
+ rowsAdded: number;
12
+ constructor(givenDefinitions?: ChartDefinition[]);
13
+ addRow(row: any): void;
14
+ applyLimitsOnCharts(): void;
15
+ addRows(...rows: any[]): void;
16
+ finalize(): void;
17
+ groupPieOtherBuckets(chart: ProcessedChart): void;
18
+ applyRawData(chart: ProcessedChart, row: any, dateParsed: ChartDateParsed, numericColumns: {
19
+ [key: string]: number;
20
+ }, stringColumns: {
21
+ [key: string]: string;
22
+ }): void;
23
+ }
@@ -0,0 +1,296 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ChartProcessor = void 0;
7
+ const chartDefinitions_1 = require("./chartDefinitions");
8
+ const sortBy_1 = __importDefault(require("lodash/sortBy"));
9
+ const sum_1 = __importDefault(require("lodash/sum"));
10
+ const chartTools_1 = require("./chartTools");
11
+ const chartScoring_1 = require("./chartScoring");
12
+ class ChartProcessor {
13
+ constructor(givenDefinitions = []) {
14
+ this.givenDefinitions = givenDefinitions;
15
+ this.chartsProcessing = [];
16
+ this.charts = [];
17
+ this.availableColumnsDict = {};
18
+ this.availableColumns = [];
19
+ this.autoDetectCharts = false;
20
+ this.rowsAdded = 0;
21
+ for (const definition of givenDefinitions) {
22
+ this.chartsProcessing.push({
23
+ definition,
24
+ rowsAdded: 0,
25
+ bucketKeysOrdered: [],
26
+ buckets: {},
27
+ bucketKeyDateParsed: {},
28
+ isGivenDefinition: true,
29
+ invalidXRows: 0,
30
+ invalidYRows: {},
31
+ availableColumns: [],
32
+ validYRows: {},
33
+ topDistinctValues: {},
34
+ });
35
+ }
36
+ this.autoDetectCharts = this.givenDefinitions.length == 0;
37
+ }
38
+ // findOrCreateChart(definition: ChartDefinition, isGivenDefinition: boolean): ProcessedChart {
39
+ // const signatureItems = [
40
+ // definition.chartType,
41
+ // definition.xdef.field,
42
+ // definition.xdef.transformFunction,
43
+ // definition.ydefs.map(y => y.field).join(','),
44
+ // ];
45
+ // const signature = signatureItems.join('::');
46
+ // if (this.chartsBySignature[signature]) {
47
+ // return this.chartsBySignature[signature];
48
+ // }
49
+ // const chart: ProcessedChart = {
50
+ // definition,
51
+ // rowsAdded: 0,
52
+ // bucketKeysOrdered: [],
53
+ // buckets: {},
54
+ // bucketKeyDateParsed: {},
55
+ // isGivenDefinition,
56
+ // };
57
+ // this.chartsBySignature[signature] = chart;
58
+ // return chart;
59
+ // }
60
+ addRow(row) {
61
+ const dateColumns = {};
62
+ const numericColumns = {};
63
+ const numericColumnsForAutodetect = {};
64
+ const stringColumns = {};
65
+ for (const [key, value] of Object.entries(row)) {
66
+ const number = typeof value == 'string' ? Number(value) : typeof value == 'number' ? value : NaN;
67
+ this.availableColumnsDict[key] = {
68
+ field: key,
69
+ };
70
+ const keyLower = key.toLowerCase();
71
+ const keyIsId = keyLower.endsWith('_id') || keyLower == 'id' || key.endsWith('Id');
72
+ const parsedDate = (0, chartTools_1.tryParseChartDate)(value);
73
+ if (parsedDate) {
74
+ dateColumns[key] = parsedDate;
75
+ continue;
76
+ }
77
+ if (!isNaN(number) && isFinite(number)) {
78
+ numericColumns[key] = number;
79
+ if (!keyIsId) {
80
+ numericColumnsForAutodetect[key] = number; // for auto-detecting charts
81
+ }
82
+ continue;
83
+ }
84
+ if (typeof value === 'string' && isNaN(number) && value.length < 100) {
85
+ stringColumns[key] = value;
86
+ }
87
+ }
88
+ // const sortedNumericColumnns = Object.keys(numericColumns).sort();
89
+ if (this.autoDetectCharts) {
90
+ // create charts from data, if there are no given definitions
91
+ for (const datecol in dateColumns) {
92
+ let usedChart = this.chartsProcessing.find(chart => {
93
+ var _a;
94
+ return !chart.isGivenDefinition &&
95
+ chart.definition.xdef.field === datecol &&
96
+ ((_a = chart.definition.xdef.transformFunction) === null || _a === void 0 ? void 0 : _a.startsWith('date:'));
97
+ });
98
+ if (!usedChart &&
99
+ (this.rowsAdded < chartDefinitions_1.ChartLimits.APPLY_LIMIT_AFTER_ROWS ||
100
+ this.chartsProcessing.length < chartDefinitions_1.ChartLimits.AUTODETECT_CHART_LIMIT)) {
101
+ usedChart = {
102
+ definition: {
103
+ chartType: 'line',
104
+ xdef: {
105
+ field: datecol,
106
+ transformFunction: 'date:day',
107
+ },
108
+ ydefs: [],
109
+ },
110
+ rowsAdded: 0,
111
+ bucketKeysOrdered: [],
112
+ buckets: {},
113
+ bucketKeyDateParsed: {},
114
+ isGivenDefinition: false,
115
+ invalidXRows: 0,
116
+ invalidYRows: {},
117
+ availableColumns: [],
118
+ validYRows: {},
119
+ topDistinctValues: {},
120
+ };
121
+ this.chartsProcessing.push(usedChart);
122
+ }
123
+ for (const [key, value] of Object.entries(row)) {
124
+ if (value == null)
125
+ continue;
126
+ if (key == datecol)
127
+ continue; // skip date column itself
128
+ let existingYDef = usedChart.definition.ydefs.find(y => y.field === key);
129
+ if (!existingYDef &&
130
+ (this.rowsAdded < chartDefinitions_1.ChartLimits.APPLY_LIMIT_AFTER_ROWS ||
131
+ usedChart.definition.ydefs.length < chartDefinitions_1.ChartLimits.AUTODETECT_MEASURES_LIMIT)) {
132
+ existingYDef = {
133
+ field: key,
134
+ aggregateFunction: 'sum',
135
+ };
136
+ usedChart.definition.ydefs.push(existingYDef);
137
+ }
138
+ }
139
+ }
140
+ }
141
+ // apply on all charts with this date column
142
+ for (const chart of this.chartsProcessing) {
143
+ this.applyRawData(chart, row, dateColumns[chart.definition.xdef.field], chart.isGivenDefinition ? numericColumns : numericColumnsForAutodetect, stringColumns);
144
+ }
145
+ for (let i = 0; i < this.chartsProcessing.length; i++) {
146
+ this.chartsProcessing[i] = (0, chartTools_1.autoAggregateCompactTimelineChart)(this.chartsProcessing[i]);
147
+ }
148
+ this.rowsAdded += 1;
149
+ if (this.rowsAdded == chartDefinitions_1.ChartLimits.APPLY_LIMIT_AFTER_ROWS) {
150
+ this.applyLimitsOnCharts();
151
+ }
152
+ }
153
+ applyLimitsOnCharts() {
154
+ const autodetectProcessingCharts = this.chartsProcessing.filter(chart => !chart.isGivenDefinition);
155
+ if (autodetectProcessingCharts.length > chartDefinitions_1.ChartLimits.AUTODETECT_CHART_LIMIT) {
156
+ const newAutodetectProcessingCharts = (0, sortBy_1.default)(this.chartsProcessing.slice(0, chartDefinitions_1.ChartLimits.AUTODETECT_CHART_LIMIT), chart => -(0, chartScoring_1.getChartScore)(chart));
157
+ for (const chart of autodetectProcessingCharts) {
158
+ chart.definition.ydefs = (0, sortBy_1.default)(chart.definition.ydefs, yfield => -(0, chartScoring_1.getChartYFieldScore)(chart, yfield)).slice(0, chartDefinitions_1.ChartLimits.AUTODETECT_MEASURES_LIMIT);
159
+ }
160
+ this.chartsProcessing = [
161
+ ...this.chartsProcessing.filter(chart => chart.isGivenDefinition),
162
+ ...newAutodetectProcessingCharts,
163
+ ];
164
+ }
165
+ }
166
+ addRows(...rows) {
167
+ for (const row of rows) {
168
+ this.addRow(row);
169
+ }
170
+ }
171
+ finalize() {
172
+ var _a;
173
+ this.applyLimitsOnCharts();
174
+ this.availableColumns = Object.values(this.availableColumnsDict);
175
+ for (const chart of this.chartsProcessing) {
176
+ let addedChart = chart;
177
+ if (chart.rowsAdded == 0) {
178
+ continue; // skip empty charts
179
+ }
180
+ const sortOrder = (_a = chart.definition.xdef.sortOrder) !== null && _a !== void 0 ? _a : 'ascKeys';
181
+ if (sortOrder != 'natural') {
182
+ if (sortOrder == 'ascKeys' || sortOrder == 'descKeys') {
183
+ if (chart.definition.xdef.transformFunction.startsWith('date:')) {
184
+ addedChart = (0, chartTools_1.autoAggregateCompactTimelineChart)(addedChart);
185
+ (0, chartTools_1.fillChartTimelineBuckets)(addedChart);
186
+ }
187
+ addedChart.bucketKeysOrdered = (0, sortBy_1.default)(Object.keys(addedChart.buckets));
188
+ if (sortOrder == 'descKeys') {
189
+ addedChart.bucketKeysOrdered.reverse();
190
+ }
191
+ }
192
+ if (sortOrder == 'ascValues' || sortOrder == 'descValues') {
193
+ addedChart.bucketKeysOrdered = (0, sortBy_1.default)(Object.keys(addedChart.buckets), key => (0, chartTools_1.computeChartBucketCardinality)(addedChart.buckets[key]));
194
+ if (sortOrder == 'descValues') {
195
+ addedChart.bucketKeysOrdered.reverse();
196
+ }
197
+ }
198
+ }
199
+ if (!addedChart.isGivenDefinition) {
200
+ addedChart = Object.assign(Object.assign({}, addedChart), { definition: Object.assign(Object.assign({}, addedChart.definition), { ydefs: addedChart.definition.ydefs.filter(y => !addedChart.invalidYRows[y.field] &&
201
+ addedChart.validYRows[y.field] / addedChart.rowsAdded >= chartDefinitions_1.ChartLimits.VALID_VALUE_RATIO_LIMIT) }) });
202
+ }
203
+ if (addedChart) {
204
+ addedChart.availableColumns = this.availableColumns;
205
+ this.charts.push(addedChart);
206
+ }
207
+ this.groupPieOtherBuckets(addedChart);
208
+ }
209
+ this.charts = [
210
+ ...this.charts.filter(x => x.isGivenDefinition),
211
+ ...(0, sortBy_1.default)(this.charts.filter(x => !x.isGivenDefinition), chart => -(0, chartScoring_1.getChartScore)(chart)),
212
+ ];
213
+ }
214
+ groupPieOtherBuckets(chart) {
215
+ var _a, _b, _c;
216
+ if (chart.definition.chartType !== 'pie') {
217
+ return; // only for pie charts
218
+ }
219
+ const ratioLimit = (_a = chart.definition.pieRatioLimit) !== null && _a !== void 0 ? _a : chartDefinitions_1.ChartLimits.PIE_RATIO_LIMIT;
220
+ const countLimit = (_b = chart.definition.pieCountLimit) !== null && _b !== void 0 ? _b : chartDefinitions_1.ChartLimits.PIE_COUNT_LIMIT;
221
+ if (ratioLimit == 0 && countLimit == 0) {
222
+ return; // no grouping if limit is 0
223
+ }
224
+ const otherBucket = {};
225
+ let newBuckets = {};
226
+ const cardSum = (0, sum_1.default)(Object.values(chart.buckets).map(bucket => (0, chartTools_1.computeChartBucketCardinality)(bucket)));
227
+ if (cardSum == 0) {
228
+ return; // no buckets to process
229
+ }
230
+ for (const [bucketKey, bucket] of Object.entries(chart.buckets)) {
231
+ if ((0, chartTools_1.computeChartBucketCardinality)(bucket) / cardSum < ratioLimit) {
232
+ for (const field in bucket) {
233
+ otherBucket[field] = ((_c = otherBucket[field]) !== null && _c !== void 0 ? _c : 0) + bucket[field];
234
+ }
235
+ }
236
+ else {
237
+ newBuckets[bucketKey] = bucket;
238
+ }
239
+ }
240
+ if (Object.keys(newBuckets).length > countLimit) {
241
+ const sortedBucketKeys = (0, sortBy_1.default)(Object.entries(newBuckets), ([, bucket]) => -(0, chartTools_1.computeChartBucketCardinality)(bucket)).map(([key]) => key);
242
+ const newBuckets2 = {};
243
+ sortedBucketKeys.forEach((key, index) => {
244
+ var _a;
245
+ if (index < countLimit) {
246
+ newBuckets2[key] = newBuckets[key];
247
+ }
248
+ else {
249
+ for (const field in newBuckets[key]) {
250
+ otherBucket[field] = ((_a = otherBucket[field]) !== null && _a !== void 0 ? _a : 0) + newBuckets[key][field];
251
+ }
252
+ }
253
+ });
254
+ newBuckets = newBuckets2;
255
+ }
256
+ if (Object.keys(otherBucket).length > 0) {
257
+ newBuckets['Other'] = otherBucket;
258
+ }
259
+ chart.buckets = newBuckets;
260
+ chart.bucketKeysOrdered = [...chart.bucketKeysOrdered, 'Other'].filter(key => key in newBuckets);
261
+ }
262
+ applyRawData(chart, row, dateParsed, numericColumns, stringColumns) {
263
+ if (chart.definition.xdef == null) {
264
+ return;
265
+ }
266
+ if (row[chart.definition.xdef.field] == null) {
267
+ return;
268
+ }
269
+ if (dateParsed == null && chart.definition.xdef.transformFunction.startsWith('date:')) {
270
+ chart.invalidXRows += 1;
271
+ return; // skip if date is invalid
272
+ }
273
+ const [bucketKey, bucketKeyParsed] = (0, chartTools_1.computeChartBucketKey)(dateParsed, chart, row);
274
+ if (!bucketKey) {
275
+ return; // skip if no bucket key
276
+ }
277
+ if (bucketKeyParsed) {
278
+ chart.bucketKeyDateParsed[bucketKey] = bucketKeyParsed;
279
+ }
280
+ if (chart.minX == null || bucketKey < chart.minX) {
281
+ chart.minX = bucketKey;
282
+ }
283
+ if (chart.maxX == null || bucketKey > chart.maxX) {
284
+ chart.maxX = bucketKey;
285
+ }
286
+ if (!chart.buckets[bucketKey]) {
287
+ chart.buckets[bucketKey] = {};
288
+ if (chart.definition.xdef.sortOrder == 'natural') {
289
+ chart.bucketKeysOrdered.push(bucketKey);
290
+ }
291
+ }
292
+ (0, chartTools_1.aggregateChartNumericValuesFromSource)(chart, bucketKey, numericColumns, row);
293
+ chart.rowsAdded += 1;
294
+ }
295
+ }
296
+ exports.ChartProcessor = ChartProcessor;
@@ -0,0 +1,3 @@
1
+ import { ChartYFieldDefinition, ProcessedChart } from './chartDefinitions';
2
+ export declare function getChartScore(chart: ProcessedChart): number;
3
+ export declare function getChartYFieldScore(chart: ProcessedChart, yField: ChartYFieldDefinition): number;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getChartYFieldScore = exports.getChartScore = void 0;
7
+ const sortBy_1 = __importDefault(require("lodash/sortBy"));
8
+ const sum_1 = __importDefault(require("lodash/sum"));
9
+ const chartDefinitions_1 = require("./chartDefinitions");
10
+ function getChartScore(chart) {
11
+ let res = 0;
12
+ res += chart.rowsAdded * 5;
13
+ const ydefScores = chart.definition.ydefs.map(yField => getChartYFieldScore(chart, yField));
14
+ const sorted = (0, sortBy_1.default)(ydefScores).reverse();
15
+ res += (0, sum_1.default)(sorted.slice(0, chartDefinitions_1.ChartLimits.AUTODETECT_MEASURES_LIMIT));
16
+ return res;
17
+ }
18
+ exports.getChartScore = getChartScore;
19
+ function getChartYFieldScore(chart, yField) {
20
+ var _a, _b, _c;
21
+ let res = 0;
22
+ res += chart.validYRows[yField.field] * 5; // score for valid Y rows
23
+ res += ((_b = (_a = chart.topDistinctValues[yField.field]) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0) * 20; // score for distinct values in Y field
24
+ res += chart.rowsAdded * 2; // base score for rows added
25
+ res -= ((_c = chart.invalidYRows[yField.field]) !== null && _c !== void 0 ? _c : 0) * 50; // penalty for invalid Y rows
26
+ return res;
27
+ }
28
+ exports.getChartYFieldScore = getChartYFieldScore;
@@ -0,0 +1,19 @@
1
+ import { ChartDateParsed, ChartXTransformFunction, ProcessedChart } from './chartDefinitions';
2
+ export declare function getChartDebugPrint(chart: ProcessedChart): string;
3
+ export declare function tryParseChartDate(dateInput: any): ChartDateParsed | null;
4
+ export declare function stringifyChartDate(value: ChartDateParsed, transform: ChartXTransformFunction): string;
5
+ export declare function incrementChartDate(value: ChartDateParsed, transform: ChartXTransformFunction): ChartDateParsed;
6
+ export declare function computeChartBucketKey(dateParsed: ChartDateParsed, chart: ProcessedChart, row: any): [string, ChartDateParsed];
7
+ export declare function computeDateBucketDistance(begin: ChartDateParsed, end: ChartDateParsed, transform: ChartXTransformFunction): number;
8
+ export declare function compareChartDatesParsed(a: ChartDateParsed, b: ChartDateParsed, transform: ChartXTransformFunction): number;
9
+ export declare function autoAggregateCompactTimelineChart(chart: ProcessedChart): ProcessedChart;
10
+ export declare function aggregateChartNumericValuesFromSource(chart: ProcessedChart, bucketKey: string, numericColumns: {
11
+ [key: string]: number;
12
+ }, row: any): void;
13
+ export declare function aggregateChartNumericValuesFromChild(chart: ProcessedChart, bucketKey: string, childBucketValues: {
14
+ [key: string]: any;
15
+ }): void;
16
+ export declare function fillChartTimelineBuckets(chart: ProcessedChart): void;
17
+ export declare function computeChartBucketCardinality(bucket: {
18
+ [key: string]: any;
19
+ }): number;