@forestadmin/datasource-customizer 1.36.0 → 1.37.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.
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { DateOperation, DistributionChart, LeaderboardChart, MultipleTimeBasedChart, ObjectiveChart, PercentageChart, SmartChart, TimeBasedChart, ValueChart } from '@forestadmin/datasource-toolkit';
|
|
2
|
+
import { TimeBasedChartOptions } from './types';
|
|
2
3
|
export default class ResultBuilder {
|
|
3
4
|
private static readonly formats;
|
|
4
5
|
value(value: number, previousValue?: number): ValueChart;
|
|
5
6
|
distribution(obj: Record<string, number>): DistributionChart;
|
|
6
7
|
/**
|
|
7
8
|
* Add a TimeBasedChart based on a time range and a set of values.
|
|
8
|
-
* @param {DateOperation} timeRange - The time range for the chart,
|
|
9
|
+
* @param {DateOperation} timeRange - The time range for the chart,
|
|
10
|
+
* specified as "Year", "Month", "Week" or "Day".
|
|
9
11
|
* @param {Array<{ date: Date; value: number | null }> | Record<string, number>} values -
|
|
10
12
|
* This can be an array of objects with 'date' and 'value' properties,
|
|
11
13
|
* or a record (object) with date-value pairs.
|
|
14
|
+
* @param {TimeBasedChartOptions} options - displayMissingPointsAsZeros:
|
|
15
|
+
* display a continuous line even if some data is missing.
|
|
12
16
|
*
|
|
13
17
|
* @returns {TimeBasedChart} Returns a TimeBasedChart representing the data within the specified
|
|
14
18
|
* time range.
|
|
@@ -26,16 +30,19 @@ export default class ResultBuilder {
|
|
|
26
30
|
timeBased(timeRange: DateOperation, values: Array<{
|
|
27
31
|
date: Date;
|
|
28
32
|
value: number | null;
|
|
29
|
-
}> | Record<string, number | null
|
|
33
|
+
}> | Record<string, number | null>, options?: TimeBasedChartOptions): TimeBasedChart;
|
|
30
34
|
/**
|
|
31
35
|
* Add a MultipleTimeBasedChart based on a time range,
|
|
32
36
|
* an array of dates, and multiple lines of data.
|
|
33
37
|
*
|
|
34
|
-
* @param {DateOperation} timeRange - The time range for the chart,
|
|
38
|
+
* @param {DateOperation} timeRange - The time range for the chart,
|
|
39
|
+
* specified as "Year", "Month", "Week" or "Day".
|
|
35
40
|
* @param {Date[]} dates - An array of dates that define the x-axis values for the chart.
|
|
36
41
|
* @param {Array<{ label: string; values: Array<number | null> }>} lines - An array of lines,
|
|
37
42
|
* each containing a label and an array of numeric data values (or null)
|
|
38
43
|
* corresponding to the dates.
|
|
44
|
+
* @param {TimeBasedChartOptions} options - displayMissingPointsAsZeros:
|
|
45
|
+
* display a continuous line even if some data is missing.
|
|
39
46
|
*
|
|
40
47
|
* @returns {MultipleTimeBasedChart} Returns a MultipleTimeBasedChart representing multiple
|
|
41
48
|
* lines of data within the specified time range.
|
|
@@ -57,7 +64,7 @@ export default class ResultBuilder {
|
|
|
57
64
|
multipleTimeBased(timeRange: DateOperation, dates: Date[], lines: Array<{
|
|
58
65
|
label: string;
|
|
59
66
|
values: Array<number | null>;
|
|
60
|
-
}
|
|
67
|
+
}>, options?: TimeBasedChartOptions): MultipleTimeBasedChart;
|
|
61
68
|
percentage(value: number): PercentageChart;
|
|
62
69
|
objective(value: number, objective: number): ObjectiveChart;
|
|
63
70
|
leaderboard(obj: Record<string, number>): LeaderboardChart;
|
|
@@ -10,10 +10,13 @@ class ResultBuilder {
|
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Add a TimeBasedChart based on a time range and a set of values.
|
|
13
|
-
* @param {DateOperation} timeRange - The time range for the chart,
|
|
13
|
+
* @param {DateOperation} timeRange - The time range for the chart,
|
|
14
|
+
* specified as "Year", "Month", "Week" or "Day".
|
|
14
15
|
* @param {Array<{ date: Date; value: number | null }> | Record<string, number>} values -
|
|
15
16
|
* This can be an array of objects with 'date' and 'value' properties,
|
|
16
17
|
* or a record (object) with date-value pairs.
|
|
18
|
+
* @param {TimeBasedChartOptions} options - displayMissingPointsAsZeros:
|
|
19
|
+
* display a continuous line even if some data is missing.
|
|
17
20
|
*
|
|
18
21
|
* @returns {TimeBasedChart} Returns a TimeBasedChart representing the data within the specified
|
|
19
22
|
* time range.
|
|
@@ -28,24 +31,30 @@ class ResultBuilder {
|
|
|
28
31
|
* ]
|
|
29
32
|
* );
|
|
30
33
|
*/
|
|
31
|
-
timeBased(timeRange, values) {
|
|
32
|
-
if (
|
|
33
|
-
return
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
timeBased(timeRange, values, options) {
|
|
35
|
+
if (!values)
|
|
36
|
+
return [];
|
|
37
|
+
if (Array.isArray(values)) {
|
|
38
|
+
return ResultBuilder.buildTimeBasedChartResult(timeRange, values, options);
|
|
39
|
+
}
|
|
40
|
+
const formattedValues = Object.entries(values).map(([stringDate, value]) => ({
|
|
41
|
+
date: new Date(stringDate),
|
|
42
|
+
value,
|
|
43
|
+
}));
|
|
44
|
+
return ResultBuilder.buildTimeBasedChartResult(timeRange, formattedValues, options);
|
|
39
45
|
}
|
|
40
46
|
/**
|
|
41
47
|
* Add a MultipleTimeBasedChart based on a time range,
|
|
42
48
|
* an array of dates, and multiple lines of data.
|
|
43
49
|
*
|
|
44
|
-
* @param {DateOperation} timeRange - The time range for the chart,
|
|
50
|
+
* @param {DateOperation} timeRange - The time range for the chart,
|
|
51
|
+
* specified as "Year", "Month", "Week" or "Day".
|
|
45
52
|
* @param {Date[]} dates - An array of dates that define the x-axis values for the chart.
|
|
46
53
|
* @param {Array<{ label: string; values: Array<number | null> }>} lines - An array of lines,
|
|
47
54
|
* each containing a label and an array of numeric data values (or null)
|
|
48
55
|
* corresponding to the dates.
|
|
56
|
+
* @param {TimeBasedChartOptions} options - displayMissingPointsAsZeros:
|
|
57
|
+
* display a continuous line even if some data is missing.
|
|
49
58
|
*
|
|
50
59
|
* @returns {MultipleTimeBasedChart} Returns a MultipleTimeBasedChart representing multiple
|
|
51
60
|
* lines of data within the specified time range.
|
|
@@ -64,19 +73,24 @@ class ResultBuilder {
|
|
|
64
73
|
* ],
|
|
65
74
|
* );
|
|
66
75
|
*/
|
|
67
|
-
multipleTimeBased(timeRange, dates, lines) {
|
|
68
|
-
|
|
76
|
+
multipleTimeBased(timeRange, dates, lines, options) {
|
|
77
|
+
if (!dates || !lines)
|
|
78
|
+
return { labels: null, values: null };
|
|
79
|
+
let formattedTimes = null;
|
|
69
80
|
const formattedLine = lines.map(line => {
|
|
70
81
|
const values = dates.reduce((computed, date, index) => {
|
|
71
82
|
computed.push({ date, value: line.values[index] });
|
|
72
83
|
return computed;
|
|
73
84
|
}, []);
|
|
74
|
-
const buildTimeBased = ResultBuilder.buildTimeBasedChartResult(timeRange, values);
|
|
85
|
+
const buildTimeBased = ResultBuilder.buildTimeBasedChartResult(timeRange, values, options);
|
|
75
86
|
if (!formattedTimes)
|
|
76
87
|
formattedTimes = buildTimeBased.map(timeBased => timeBased.label);
|
|
77
88
|
return { key: line.label, values: buildTimeBased.map(timeBased => timeBased.values.value) };
|
|
78
89
|
});
|
|
79
|
-
return {
|
|
90
|
+
return {
|
|
91
|
+
labels: formattedTimes,
|
|
92
|
+
values: formattedTimes?.length > 0 ? formattedLine : null,
|
|
93
|
+
};
|
|
80
94
|
}
|
|
81
95
|
percentage(value) {
|
|
82
96
|
return value;
|
|
@@ -106,11 +120,13 @@ class ResultBuilder {
|
|
|
106
120
|
* { label: 'Feb 22', values: { value: 6 } },
|
|
107
121
|
* ]
|
|
108
122
|
*/
|
|
109
|
-
static buildTimeBasedChartResult(timeRange, points) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
123
|
+
static buildTimeBasedChartResult(timeRange, points, options) {
|
|
124
|
+
if (!points.length)
|
|
125
|
+
return [];
|
|
126
|
+
const pointsInDateTime = points.map(point => ({
|
|
127
|
+
date: luxon_1.DateTime.fromJSDate(point.date),
|
|
128
|
+
value: point.value,
|
|
129
|
+
}));
|
|
114
130
|
const format = ResultBuilder.formats[timeRange];
|
|
115
131
|
const formatted = {};
|
|
116
132
|
pointsInDateTime.forEach(point => {
|
|
@@ -124,9 +140,10 @@ class ResultBuilder {
|
|
|
124
140
|
.sort((dateA, dateB) => dateA.toUnixInteger() - dateB.toUnixInteger());
|
|
125
141
|
const first = dates[0].startOf(timeRange.toLowerCase());
|
|
126
142
|
const last = dates[dates.length - 1];
|
|
143
|
+
const defaultValue = options?.displayMissingPointsAsZeros ? 0 : null;
|
|
127
144
|
for (let current = first; current <= last; current = current.plus({ [timeRange]: 1 })) {
|
|
128
145
|
const label = current.toFormat(format);
|
|
129
|
-
dataPoints.push({ label, values: { value: formatted[label] ??
|
|
146
|
+
dataPoints.push({ label, values: { value: formatted[label] ?? defaultValue } });
|
|
130
147
|
}
|
|
131
148
|
return dataPoints;
|
|
132
149
|
}
|
|
@@ -138,4 +155,4 @@ ResultBuilder.formats = {
|
|
|
138
155
|
Month: 'MMM yy',
|
|
139
156
|
Year: 'yyyy',
|
|
140
157
|
};
|
|
141
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
158
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdWx0LWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGVjb3JhdG9ycy9jaGFydC9yZXN1bHQtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVdBLGlDQUErQztBQUkvQyxNQUFxQixhQUFhO0lBUWhDLEtBQUssQ0FBQyxLQUFhLEVBQUUsYUFBc0I7UUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxDQUFDO0lBQy9ELENBQUM7SUFFRCxZQUFZLENBQUMsR0FBMkI7UUFDdEMsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzQkc7SUFDSCxTQUFTLENBQ1AsU0FBd0IsRUFDeEIsTUFBbUYsRUFDbkYsT0FBK0I7UUFFL0IsSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUV2QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDekIsT0FBTyxhQUFhLENBQUMseUJBQXlCLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztTQUM1RTtRQUVELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDM0UsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUMxQixLQUFLO1NBQ04sQ0FBQyxDQUFDLENBQUM7UUFFSixPQUFPLGFBQWEsQ0FBQyx5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
|
|
@@ -5,4 +5,7 @@ import AgentCustomizationContext from '../../context/agent-context';
|
|
|
5
5
|
import { TCollectionName, TSchema } from '../../templates';
|
|
6
6
|
export type DataSourceChartDefinition<S extends TSchema = TSchema> = (context: AgentCustomizationContext<S>, resultBuilder: ResultBuilder) => Promise<Chart> | Chart;
|
|
7
7
|
export type CollectionChartDefinition<S extends TSchema = TSchema, N extends TCollectionName<S> = TCollectionName<S>> = (context: CollectionChartContext<S, N>, resultBuilder: ResultBuilder) => Promise<Chart> | Chart;
|
|
8
|
+
export type TimeBasedChartOptions = {
|
|
9
|
+
displayMissingPointsAsZeros?: boolean;
|
|
10
|
+
};
|
|
8
11
|
//# sourceMappingURL=types.d.ts.map
|