@praxisui/charts 3.0.0-beta.0 → 3.0.0-beta.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/fesm2022/praxisui-charts.mjs +669 -55
- package/fesm2022/praxisui-charts.mjs.map +1 -1
- package/index.d.ts +36 -10
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@ import * as i1$1 from '@praxisui/core';
|
|
|
5
5
|
import { buildApiUrl, API_URL, PraxisI18nService, ComponentMetadataRegistry, createDefaultTableConfig, DynamicWidgetPageComponent, DynamicGridPageComponent } from '@praxisui/core';
|
|
6
6
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
7
7
|
import { use, init } from 'echarts/core';
|
|
8
|
-
import { BarChart, LineChart, PieChart } from 'echarts/charts';
|
|
8
|
+
import { BarChart, LineChart, PieChart, ScatterChart } from 'echarts/charts';
|
|
9
9
|
import { AriaComponent, DatasetComponent, GridComponent, LegendComponent, TitleComponent, TooltipComponent, TransformComponent } from 'echarts/components';
|
|
10
10
|
import { CanvasRenderer } from 'echarts/renderers';
|
|
11
11
|
import * as i1 from '@angular/common/http';
|
|
@@ -19,6 +19,9 @@ class PraxisChartDataTransformerService {
|
|
|
19
19
|
if (config.type === 'pie' || config.type === 'donut') {
|
|
20
20
|
return this.transformPie(config, rows);
|
|
21
21
|
}
|
|
22
|
+
if (config.type === 'scatter') {
|
|
23
|
+
return this.transformScatter(config, rows);
|
|
24
|
+
}
|
|
22
25
|
return this.transformCartesian(config, rows);
|
|
23
26
|
}
|
|
24
27
|
transformCartesian(config, rows) {
|
|
@@ -86,10 +89,11 @@ class PraxisChartDataTransformerService {
|
|
|
86
89
|
return {
|
|
87
90
|
id: seriesConfig.id,
|
|
88
91
|
name: seriesConfig.name ?? seriesConfig.metric?.label ?? seriesConfig.id,
|
|
89
|
-
type:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
type: this.resolveCartesianSeriesType(config, seriesConfig),
|
|
93
|
+
axis: seriesConfig.axis ?? 'primary',
|
|
94
|
+
stack: config.type === 'stacked-bar' || config.type === 'stacked-area' ? seriesConfig.stackId ?? 'stack-1' : undefined,
|
|
95
|
+
smooth: seriesConfig.smooth ?? this.isAreaLikeSeries(config, seriesConfig),
|
|
96
|
+
area: this.isAreaLikeSeries(config, seriesConfig),
|
|
93
97
|
color: seriesConfig.color,
|
|
94
98
|
labelsVisible: seriesConfig.labels?.visible ?? false,
|
|
95
99
|
points: categories.map((category) => {
|
|
@@ -100,6 +104,66 @@ class PraxisChartDataTransformerService {
|
|
|
100
104
|
}),
|
|
101
105
|
};
|
|
102
106
|
}
|
|
107
|
+
resolveCartesianSeriesType(config, seriesConfig) {
|
|
108
|
+
if (config.type === 'combo') {
|
|
109
|
+
return seriesConfig.type === 'bar' ? 'bar' : 'line';
|
|
110
|
+
}
|
|
111
|
+
return config.type === 'bar' || config.type === 'stacked-bar' || config.type === 'horizontal-bar'
|
|
112
|
+
? 'bar'
|
|
113
|
+
: 'line';
|
|
114
|
+
}
|
|
115
|
+
isAreaLikeSeries(config, seriesConfig) {
|
|
116
|
+
if (config.type === 'combo') {
|
|
117
|
+
return seriesConfig.type === 'area';
|
|
118
|
+
}
|
|
119
|
+
return config.type === 'area' || config.type === 'stacked-area';
|
|
120
|
+
}
|
|
121
|
+
transformScatter(config, rows) {
|
|
122
|
+
const xField = config.axes?.x?.field;
|
|
123
|
+
const seriesConfig = config.series[0];
|
|
124
|
+
const yField = config.axes?.y?.field ?? seriesConfig?.metric?.field;
|
|
125
|
+
if (!xField || !seriesConfig || !yField || !rows.length) {
|
|
126
|
+
return {
|
|
127
|
+
mode: 'scatter',
|
|
128
|
+
categories: [],
|
|
129
|
+
series: [],
|
|
130
|
+
slices: [],
|
|
131
|
+
hasData: false,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const points = rows
|
|
135
|
+
.map((row) => {
|
|
136
|
+
const xValue = this.extractScatterXValue(row[xField], config.axes?.x?.type);
|
|
137
|
+
const yValue = this.extractMetricValue(row, {
|
|
138
|
+
...seriesConfig,
|
|
139
|
+
metric: {
|
|
140
|
+
...seriesConfig.metric,
|
|
141
|
+
field: yField,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
if (xValue === null || !Number.isFinite(yValue)) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
return [xValue, yValue];
|
|
148
|
+
})
|
|
149
|
+
.filter((point) => point !== null);
|
|
150
|
+
return {
|
|
151
|
+
mode: 'scatter',
|
|
152
|
+
categories: [],
|
|
153
|
+
series: [
|
|
154
|
+
{
|
|
155
|
+
id: seriesConfig.id,
|
|
156
|
+
name: seriesConfig.name ?? seriesConfig.metric?.label ?? seriesConfig.id,
|
|
157
|
+
type: 'scatter',
|
|
158
|
+
color: seriesConfig.color,
|
|
159
|
+
labelsVisible: seriesConfig.labels?.visible ?? false,
|
|
160
|
+
points,
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
slices: [],
|
|
164
|
+
hasData: points.length > 0,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
103
167
|
aggregate(rows, seriesConfig) {
|
|
104
168
|
const aggregation = seriesConfig.metric?.aggregation ?? 'sum';
|
|
105
169
|
if (aggregation === 'count') {
|
|
@@ -145,6 +209,25 @@ class PraxisChartDataTransformerService {
|
|
|
145
209
|
}
|
|
146
210
|
return String(value);
|
|
147
211
|
}
|
|
212
|
+
extractScatterXValue(value, axisType) {
|
|
213
|
+
if (value instanceof Date) {
|
|
214
|
+
return axisType === 'time' ? value.toISOString() : value.getTime();
|
|
215
|
+
}
|
|
216
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
if (typeof value === 'string') {
|
|
220
|
+
const trimmed = value.trim();
|
|
221
|
+
if (!trimmed)
|
|
222
|
+
return null;
|
|
223
|
+
const parsed = Number(trimmed);
|
|
224
|
+
if (axisType === 'value' && Number.isFinite(parsed)) {
|
|
225
|
+
return parsed;
|
|
226
|
+
}
|
|
227
|
+
return trimmed;
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
148
231
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisChartDataTransformerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
149
232
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisChartDataTransformerService, providedIn: 'root' });
|
|
150
233
|
}
|
|
@@ -191,6 +274,47 @@ class PraxisChartOptionBuilderService {
|
|
|
191
274
|
series: [pieSeries],
|
|
192
275
|
};
|
|
193
276
|
}
|
|
277
|
+
if (transformed.mode === 'scatter') {
|
|
278
|
+
const scatterSeries = transformed.series.map((series) => ({
|
|
279
|
+
id: series.id,
|
|
280
|
+
name: series.name,
|
|
281
|
+
type: 'scatter',
|
|
282
|
+
label: { show: series.labelsVisible },
|
|
283
|
+
itemStyle: series.color ? { color: series.color } : undefined,
|
|
284
|
+
data: series.points,
|
|
285
|
+
}));
|
|
286
|
+
return {
|
|
287
|
+
backgroundColor: config.theme?.backgroundColor,
|
|
288
|
+
color: palette,
|
|
289
|
+
title: {
|
|
290
|
+
text: this.resolveText(config.title),
|
|
291
|
+
subtext: this.resolveText(config.subtitle),
|
|
292
|
+
left: 'left',
|
|
293
|
+
},
|
|
294
|
+
tooltip: tooltipEnabled ? { trigger: 'item' } : undefined,
|
|
295
|
+
legend: legendVisible ? { show: true, top: 0 } : { show: false },
|
|
296
|
+
grid: this.buildGrid(),
|
|
297
|
+
xAxis: {
|
|
298
|
+
type: config.axes?.x?.type ?? 'value',
|
|
299
|
+
name: config.axes?.x?.label,
|
|
300
|
+
axisLabel: {
|
|
301
|
+
show: config.axes?.x?.labels?.visible ?? true,
|
|
302
|
+
rotate: config.axes?.x?.labels?.rotate ?? 0,
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
yAxis: {
|
|
306
|
+
type: config.axes?.y?.type ?? 'value',
|
|
307
|
+
name: config.axes?.y?.label,
|
|
308
|
+
min: config.axes?.y?.min,
|
|
309
|
+
max: config.axes?.y?.max,
|
|
310
|
+
axisLabel: {
|
|
311
|
+
show: config.axes?.y?.labels?.visible ?? true,
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
series: scatterSeries,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
const horizontal = config.orientation === 'horizontal' || config.type === 'horizontal-bar';
|
|
194
318
|
return {
|
|
195
319
|
backgroundColor: config.theme?.backgroundColor,
|
|
196
320
|
color: palette,
|
|
@@ -205,35 +329,42 @@ class PraxisChartOptionBuilderService {
|
|
|
205
329
|
legend: legendVisible
|
|
206
330
|
? { show: true, top: 0 }
|
|
207
331
|
: { show: false },
|
|
208
|
-
grid:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
min: config.axes?.y?.min,
|
|
228
|
-
max: config.axes?.y?.max,
|
|
229
|
-
axisLabel: {
|
|
230
|
-
show: config.axes?.y?.labels?.visible ?? true,
|
|
332
|
+
grid: this.buildGrid(),
|
|
333
|
+
xAxis: horizontal
|
|
334
|
+
? {
|
|
335
|
+
type: config.axes?.y?.type ?? 'value',
|
|
336
|
+
name: config.axes?.y?.label,
|
|
337
|
+
min: config.axes?.y?.min,
|
|
338
|
+
max: config.axes?.y?.max,
|
|
339
|
+
axisLabel: {
|
|
340
|
+
show: config.axes?.y?.labels?.visible ?? true,
|
|
341
|
+
},
|
|
342
|
+
}
|
|
343
|
+
: {
|
|
344
|
+
type: config.axes?.x?.type ?? 'category',
|
|
345
|
+
name: config.axes?.x?.label,
|
|
346
|
+
data: transformed.categories,
|
|
347
|
+
axisLabel: {
|
|
348
|
+
show: config.axes?.x?.labels?.visible ?? true,
|
|
349
|
+
rotate: config.axes?.x?.labels?.rotate ?? 0,
|
|
350
|
+
},
|
|
231
351
|
},
|
|
232
|
-
|
|
352
|
+
yAxis: horizontal
|
|
353
|
+
? {
|
|
354
|
+
type: config.axes?.x?.type ?? 'category',
|
|
355
|
+
name: config.axes?.x?.label,
|
|
356
|
+
data: transformed.categories,
|
|
357
|
+
axisLabel: {
|
|
358
|
+
show: config.axes?.x?.labels?.visible ?? true,
|
|
359
|
+
rotate: config.axes?.x?.labels?.rotate ?? 0,
|
|
360
|
+
},
|
|
361
|
+
}
|
|
362
|
+
: this.buildCartesianYAxis(config),
|
|
233
363
|
series: transformed.series.map((series) => ({
|
|
234
364
|
id: series.id,
|
|
235
365
|
name: series.name,
|
|
236
366
|
type: series.type,
|
|
367
|
+
yAxisIndex: series.axis === 'secondary' ? 1 : 0,
|
|
237
368
|
stack: series.stack,
|
|
238
369
|
smooth: series.smooth,
|
|
239
370
|
areaStyle: series.area ? {} : undefined,
|
|
@@ -254,6 +385,45 @@ class PraxisChartOptionBuilderService {
|
|
|
254
385
|
}
|
|
255
386
|
return undefined;
|
|
256
387
|
}
|
|
388
|
+
buildGrid() {
|
|
389
|
+
return {
|
|
390
|
+
top: 56,
|
|
391
|
+
right: 24,
|
|
392
|
+
bottom: 32,
|
|
393
|
+
left: 48,
|
|
394
|
+
// ECharts deprecou containLabel; esta combinacao preserva o mesmo comportamento
|
|
395
|
+
// sem depender da feature legacy de grid.
|
|
396
|
+
outerBoundsMode: 'same',
|
|
397
|
+
outerBoundsContain: 'axisLabel',
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
buildCartesianYAxis(config) {
|
|
401
|
+
const primaryAxis = {
|
|
402
|
+
type: config.axes?.y?.type ?? 'value',
|
|
403
|
+
name: config.axes?.y?.label,
|
|
404
|
+
min: config.axes?.y?.min,
|
|
405
|
+
max: config.axes?.y?.max,
|
|
406
|
+
axisLabel: {
|
|
407
|
+
show: config.axes?.y?.labels?.visible ?? true,
|
|
408
|
+
},
|
|
409
|
+
};
|
|
410
|
+
if (!config.axes?.ySecondary) {
|
|
411
|
+
return primaryAxis;
|
|
412
|
+
}
|
|
413
|
+
return [
|
|
414
|
+
primaryAxis,
|
|
415
|
+
{
|
|
416
|
+
type: config.axes.ySecondary.type ?? 'value',
|
|
417
|
+
name: config.axes.ySecondary.label,
|
|
418
|
+
min: config.axes.ySecondary.min,
|
|
419
|
+
max: config.axes.ySecondary.max,
|
|
420
|
+
position: config.axes.ySecondary.position ?? 'right',
|
|
421
|
+
axisLabel: {
|
|
422
|
+
show: config.axes.ySecondary.labels?.visible ?? true,
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
];
|
|
426
|
+
}
|
|
257
427
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisChartOptionBuilderService, deps: [{ token: PraxisChartDataTransformerService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
258
428
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: PraxisChartOptionBuilderService, providedIn: 'root' });
|
|
259
429
|
}
|
|
@@ -271,6 +441,7 @@ use([
|
|
|
271
441
|
LegendComponent,
|
|
272
442
|
LineChart,
|
|
273
443
|
PieChart,
|
|
444
|
+
ScatterChart,
|
|
274
445
|
TitleComponent,
|
|
275
446
|
TooltipComponent,
|
|
276
447
|
TransformComponent,
|
|
@@ -327,23 +498,22 @@ class PraxisChartStatsApiService {
|
|
|
327
498
|
return throwError(() => new Error('PraxisChartStatsApiService requires query.statsPath and query.statsRequest for praxis.stats execution.'));
|
|
328
499
|
}
|
|
329
500
|
const categoryField = this.resolveCategoryField(config, statsRequest);
|
|
330
|
-
const metricField = this.resolveMetricField(config);
|
|
331
501
|
const url = this.buildStatsUrl(query.statsPath);
|
|
332
502
|
return this.http
|
|
333
503
|
.post(url, statsRequest)
|
|
334
|
-
.pipe(map((response) => this.toChartRows(response?.data, statsRequest, categoryField,
|
|
504
|
+
.pipe(map((response) => this.toChartRows(response?.data, statsRequest, categoryField, config)), catchError((error) => this.handleHttpError(error)));
|
|
335
505
|
}
|
|
336
|
-
toChartRows(response, request, categoryField,
|
|
506
|
+
toChartRows(response, request, categoryField, config) {
|
|
337
507
|
if (!response) {
|
|
338
508
|
return [];
|
|
339
509
|
}
|
|
510
|
+
const metricBindings = this.resolveMetricBindings(config, request, response);
|
|
340
511
|
if ('points' in response) {
|
|
341
512
|
return response.points.map((point) => {
|
|
342
513
|
const category = point.label ?? point.start ?? point.end ?? '';
|
|
343
|
-
const metricValue = this.resolveMetricValue(point.value, point.count);
|
|
344
514
|
return {
|
|
345
515
|
[categoryField]: category,
|
|
346
|
-
|
|
516
|
+
...this.projectMetricValues(metricBindings, point.values, point.value, point.count),
|
|
347
517
|
key: point.start ?? point.label ?? point.end ?? category,
|
|
348
518
|
label: point.label ?? category,
|
|
349
519
|
value: point.value ?? null,
|
|
@@ -357,10 +527,9 @@ class PraxisChartStatsApiService {
|
|
|
357
527
|
if ('buckets' in response) {
|
|
358
528
|
return response.buckets.map((bucket) => {
|
|
359
529
|
const category = this.resolveBucketCategory(bucket);
|
|
360
|
-
const metricValue = this.resolveMetricValue(bucket.value, bucket.count);
|
|
361
530
|
return {
|
|
362
531
|
[categoryField]: category,
|
|
363
|
-
|
|
532
|
+
...this.projectMetricValues(metricBindings, bucket.values, bucket.value, bucket.count),
|
|
364
533
|
key: bucket.key ?? null,
|
|
365
534
|
label: bucket.label ?? category,
|
|
366
535
|
value: bucket.value ?? null,
|
|
@@ -402,8 +571,46 @@ class PraxisChartStatsApiService {
|
|
|
402
571
|
|| request.field
|
|
403
572
|
|| 'category');
|
|
404
573
|
}
|
|
405
|
-
|
|
406
|
-
|
|
574
|
+
resolveMetricBindings(config, request, response) {
|
|
575
|
+
const queryMetrics = config.dataSource?.kind === 'remote'
|
|
576
|
+
? (config.dataSource.query?.metrics ?? [])
|
|
577
|
+
: [];
|
|
578
|
+
if (queryMetrics.length) {
|
|
579
|
+
return queryMetrics.map((metric, index) => ({
|
|
580
|
+
field: metric.field || `value${index + 1}`,
|
|
581
|
+
alias: metric.alias || metric.field || `value${index + 1}`,
|
|
582
|
+
}));
|
|
583
|
+
}
|
|
584
|
+
const responseMetrics = 'metrics' in response ? response.metrics : undefined;
|
|
585
|
+
if (responseMetrics?.length) {
|
|
586
|
+
return responseMetrics.map((metric, index) => ({
|
|
587
|
+
field: metric.alias || metric.field || `value${index + 1}`,
|
|
588
|
+
alias: metric.alias || metric.field || `value${index + 1}`,
|
|
589
|
+
}));
|
|
590
|
+
}
|
|
591
|
+
const requestMetrics = 'metrics' in request ? request.metrics : undefined;
|
|
592
|
+
if (requestMetrics?.length) {
|
|
593
|
+
return requestMetrics.map((metric, index) => ({
|
|
594
|
+
field: metric.alias || metric.field || `value${index + 1}`,
|
|
595
|
+
alias: metric.alias || metric.field || `value${index + 1}`,
|
|
596
|
+
}));
|
|
597
|
+
}
|
|
598
|
+
const metric = ('metric' in response && response.metric) || ('metric' in request ? request.metric : undefined);
|
|
599
|
+
return [
|
|
600
|
+
{
|
|
601
|
+
field: metric?.alias || metric?.field || config.series[0]?.metric?.field || 'value',
|
|
602
|
+
alias: metric?.alias || metric?.field || config.series[0]?.metric?.field || 'value',
|
|
603
|
+
},
|
|
604
|
+
];
|
|
605
|
+
}
|
|
606
|
+
projectMetricValues(bindings, values, primaryValue, count) {
|
|
607
|
+
return bindings.reduce((acc, binding, index) => {
|
|
608
|
+
const rawValue = values?.[binding.alias];
|
|
609
|
+
acc[binding.field] = index === 0
|
|
610
|
+
? this.resolveMetricValue(rawValue ?? primaryValue, count)
|
|
611
|
+
: this.resolveMetricValue(rawValue, null);
|
|
612
|
+
return acc;
|
|
613
|
+
}, {});
|
|
407
614
|
}
|
|
408
615
|
buildStatsUrl(statsPath) {
|
|
409
616
|
const base = this.buildDefaultApiBase();
|
|
@@ -1339,6 +1546,7 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1339
1546
|
return {
|
|
1340
1547
|
id: contract.chartId,
|
|
1341
1548
|
type: contract.kind,
|
|
1549
|
+
orientation: this.resolveOrientation(contract),
|
|
1342
1550
|
title: this.mapTextValue(contract.title),
|
|
1343
1551
|
subtitle: this.mapTextValue(contract.subtitle),
|
|
1344
1552
|
height: contract.height,
|
|
@@ -1365,16 +1573,13 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1365
1573
|
};
|
|
1366
1574
|
}
|
|
1367
1575
|
assertSupportedContract(contract) {
|
|
1368
|
-
if (contract.source.kind
|
|
1369
|
-
throw new Error('x-ui.chart source.kind="derived" is not yet implemented in @praxisui/charts.');
|
|
1370
|
-
}
|
|
1371
|
-
if (contract.source.kind !== 'praxis.stats') {
|
|
1576
|
+
if (contract.source.kind !== 'praxis.stats' && contract.source.kind !== 'derived') {
|
|
1372
1577
|
throw new Error(`x-ui.chart source.kind="${contract.source.kind}" is not supported in @praxisui/charts.`);
|
|
1373
1578
|
}
|
|
1374
|
-
if (!contract.source.resource?.trim()) {
|
|
1579
|
+
if (contract.source.kind === 'praxis.stats' && !contract.source.resource?.trim()) {
|
|
1375
1580
|
throw new Error('x-ui.chart source.resource is required for source.kind="praxis.stats".');
|
|
1376
1581
|
}
|
|
1377
|
-
if (!contract.source.operation) {
|
|
1582
|
+
if (contract.source.kind === 'praxis.stats' && !contract.source.operation) {
|
|
1378
1583
|
throw new Error('x-ui.chart source.operation is required for source.kind="praxis.stats".');
|
|
1379
1584
|
}
|
|
1380
1585
|
if (contract.theme?.palette && typeof contract.theme.palette === 'string') {
|
|
@@ -1402,9 +1607,31 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1402
1607
|
if (contract.metrics.length > 1 && (contract.kind === 'pie' || contract.kind === 'donut')) {
|
|
1403
1608
|
throw new Error('x-ui.chart pie/donut charts with multiple metrics are not yet implemented in @praxisui/charts.');
|
|
1404
1609
|
}
|
|
1405
|
-
if (contract.
|
|
1610
|
+
if (contract.kind === 'combo') {
|
|
1611
|
+
if (contract.metrics.length < 2) {
|
|
1612
|
+
throw new Error('x-ui.chart combo charts require at least two metrics.');
|
|
1613
|
+
}
|
|
1614
|
+
if (contract.source.kind === 'praxis.stats'
|
|
1615
|
+
&& contract.source.operation !== 'group-by'
|
|
1616
|
+
&& contract.source.operation !== 'timeseries') {
|
|
1617
|
+
throw new Error('x-ui.chart combo charts over praxis.stats currently support only group-by or timeseries operations in @praxisui/charts.');
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
if (contract.source.kind === 'praxis.stats' && contract.metrics.length > 1 && contract.kind !== 'combo') {
|
|
1406
1621
|
throw new Error('x-ui.chart praxis.stats currently supports a single metric per chart in @praxisui/charts.');
|
|
1407
1622
|
}
|
|
1623
|
+
if (contract.kind === 'horizontal-bar' && contract.orientation && contract.orientation !== 'horizontal') {
|
|
1624
|
+
throw new Error('x-ui.chart kind="horizontal-bar" requires orientation="horizontal" when orientation is provided.');
|
|
1625
|
+
}
|
|
1626
|
+
if (contract.kind === 'scatter') {
|
|
1627
|
+
const firstDimension = contract.dimensions?.[0];
|
|
1628
|
+
if (!firstDimension?.field) {
|
|
1629
|
+
throw new Error('x-ui.chart scatter charts require dimensions[0].field for the x axis.');
|
|
1630
|
+
}
|
|
1631
|
+
if (!contract.metrics?.[0]?.field) {
|
|
1632
|
+
throw new Error('x-ui.chart scatter charts require metrics[0].field for the y axis.');
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1408
1635
|
if (contract.events?.selectionChange || contract.events?.crossFilter) {
|
|
1409
1636
|
throw new Error('x-ui.chart selectionChange/crossFilter declarative runtime actions are not yet implemented in @praxisui/charts.');
|
|
1410
1637
|
}
|
|
@@ -1412,6 +1639,7 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1412
1639
|
buildAxes(contract) {
|
|
1413
1640
|
const firstDimension = contract.dimensions?.[0];
|
|
1414
1641
|
const firstMetric = contract.metrics?.[0];
|
|
1642
|
+
const secondaryMetric = contract.metrics?.find((metric) => metric.axis === 'secondary');
|
|
1415
1643
|
if (contract.kind === 'pie' || contract.kind === 'donut') {
|
|
1416
1644
|
return {
|
|
1417
1645
|
x: {
|
|
@@ -1420,6 +1648,20 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1420
1648
|
},
|
|
1421
1649
|
};
|
|
1422
1650
|
}
|
|
1651
|
+
if (contract.kind === 'scatter') {
|
|
1652
|
+
return {
|
|
1653
|
+
x: {
|
|
1654
|
+
field: firstDimension?.field,
|
|
1655
|
+
label: this.toLabel(firstDimension?.label),
|
|
1656
|
+
type: firstDimension?.role === 'time' ? 'time' : 'value',
|
|
1657
|
+
},
|
|
1658
|
+
y: {
|
|
1659
|
+
field: firstMetric?.field,
|
|
1660
|
+
label: this.toLabel(firstMetric?.label),
|
|
1661
|
+
type: 'value',
|
|
1662
|
+
},
|
|
1663
|
+
};
|
|
1664
|
+
}
|
|
1423
1665
|
return {
|
|
1424
1666
|
x: {
|
|
1425
1667
|
field: firstDimension?.field,
|
|
@@ -1430,6 +1672,13 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1430
1672
|
label: this.toLabel(firstMetric?.label),
|
|
1431
1673
|
type: 'value',
|
|
1432
1674
|
},
|
|
1675
|
+
ySecondary: contract.kind === 'combo' && secondaryMetric
|
|
1676
|
+
? {
|
|
1677
|
+
label: this.toLabel(secondaryMetric.label),
|
|
1678
|
+
type: 'value',
|
|
1679
|
+
position: 'right',
|
|
1680
|
+
}
|
|
1681
|
+
: undefined,
|
|
1433
1682
|
};
|
|
1434
1683
|
}
|
|
1435
1684
|
buildSeries(contract) {
|
|
@@ -1438,19 +1687,24 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1438
1687
|
return (contract.metrics ?? []).map((metric, index) => ({
|
|
1439
1688
|
id: `${metric.field}-${index + 1}`,
|
|
1440
1689
|
name: this.toLabel(metric.label) ?? metric.field,
|
|
1441
|
-
type: contract.kind
|
|
1690
|
+
type: this.resolveSeriesType(contract.kind, metric.seriesKind, index),
|
|
1691
|
+
axis: metric.axis ?? 'primary',
|
|
1442
1692
|
categoryField: contract.kind === 'pie' || contract.kind === 'donut' ? firstDimension?.field : undefined,
|
|
1443
1693
|
metric: {
|
|
1444
1694
|
field: metric.field,
|
|
1445
1695
|
aggregation: this.mapAggregation(metric.aggregation),
|
|
1446
1696
|
label: this.toLabel(metric.label),
|
|
1447
1697
|
},
|
|
1448
|
-
|
|
1698
|
+
color: metric.color,
|
|
1699
|
+
stackId: contract.kind === 'stacked-bar' || contract.kind === 'stacked-area' ? 'stack-1' : undefined,
|
|
1449
1700
|
labels: labelsVisible ? { visible: true } : undefined,
|
|
1450
|
-
smooth: contract.kind
|
|
1701
|
+
smooth: this.shouldSmoothSeries(contract.kind, metric.seriesKind),
|
|
1451
1702
|
}));
|
|
1452
1703
|
}
|
|
1453
1704
|
buildDataSource(contract) {
|
|
1705
|
+
if (contract.source.kind === 'derived') {
|
|
1706
|
+
return undefined;
|
|
1707
|
+
}
|
|
1454
1708
|
return {
|
|
1455
1709
|
kind: 'remote',
|
|
1456
1710
|
resourcePath: contract.source.resource,
|
|
@@ -1459,6 +1713,9 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1459
1713
|
};
|
|
1460
1714
|
}
|
|
1461
1715
|
buildQuery(contract) {
|
|
1716
|
+
if (contract.source.kind !== 'praxis.stats') {
|
|
1717
|
+
return undefined;
|
|
1718
|
+
}
|
|
1462
1719
|
const filtersFromContract = this.toQueryFilterMap(contract.filters);
|
|
1463
1720
|
const combinedFilters = {
|
|
1464
1721
|
...filtersFromContract,
|
|
@@ -1498,10 +1755,28 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1498
1755
|
legend: { visible: this.resolveToggle(contract.legend, true) },
|
|
1499
1756
|
tooltip: {
|
|
1500
1757
|
enabled: this.resolveToggle(contract.tooltip, true),
|
|
1501
|
-
trigger: contract.kind === 'pie' || contract.kind === 'donut' ? 'item' : 'axis',
|
|
1758
|
+
trigger: contract.kind === 'pie' || contract.kind === 'donut' || contract.kind === 'scatter' ? 'item' : 'axis',
|
|
1502
1759
|
},
|
|
1503
1760
|
};
|
|
1504
1761
|
}
|
|
1762
|
+
resolveOrientation(contract) {
|
|
1763
|
+
if (contract.kind === 'horizontal-bar') {
|
|
1764
|
+
return 'horizontal';
|
|
1765
|
+
}
|
|
1766
|
+
return contract.orientation;
|
|
1767
|
+
}
|
|
1768
|
+
resolveSeriesType(chartKind, seriesKind, index) {
|
|
1769
|
+
if (chartKind === 'combo') {
|
|
1770
|
+
return seriesKind ?? (index === 0 ? 'bar' : 'line');
|
|
1771
|
+
}
|
|
1772
|
+
return chartKind === 'stacked-bar' ? 'bar' : chartKind;
|
|
1773
|
+
}
|
|
1774
|
+
shouldSmoothSeries(chartKind, seriesKind) {
|
|
1775
|
+
if (chartKind === 'combo') {
|
|
1776
|
+
return seriesKind === 'line' || seriesKind === 'area' ? true : undefined;
|
|
1777
|
+
}
|
|
1778
|
+
return chartKind === 'line' || chartKind === 'area' || chartKind === 'stacked-area' ? true : undefined;
|
|
1779
|
+
}
|
|
1505
1780
|
mapTextValue(value) {
|
|
1506
1781
|
if (!value)
|
|
1507
1782
|
return undefined;
|
|
@@ -1559,15 +1834,18 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1559
1834
|
}
|
|
1560
1835
|
buildStatsRequest(contract, filters) {
|
|
1561
1836
|
const field = this.resolveStatsField(contract);
|
|
1562
|
-
const
|
|
1837
|
+
const metrics = this.buildStatsMetricRequests(contract);
|
|
1838
|
+
const metric = metrics[0];
|
|
1563
1839
|
const limit = contract.limit ?? contract.source.options?.limit;
|
|
1564
1840
|
const orderBy = this.mapStatsOrderByToBackend(contract.source.options?.orderBy);
|
|
1841
|
+
const requestMetrics = metrics.length > 1 ? metrics : undefined;
|
|
1565
1842
|
switch (contract.source.operation) {
|
|
1566
1843
|
case 'group-by':
|
|
1567
1844
|
return {
|
|
1568
1845
|
filter: filters,
|
|
1569
1846
|
field,
|
|
1570
1847
|
metric,
|
|
1848
|
+
metrics: requestMetrics,
|
|
1571
1849
|
limit,
|
|
1572
1850
|
orderBy,
|
|
1573
1851
|
};
|
|
@@ -1577,6 +1855,7 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1577
1855
|
field,
|
|
1578
1856
|
granularity: this.mapStatsGranularityToBackend(contract.source.options?.granularity),
|
|
1579
1857
|
metric,
|
|
1858
|
+
metrics: requestMetrics,
|
|
1580
1859
|
fillGaps: contract.source.options?.fillGaps,
|
|
1581
1860
|
};
|
|
1582
1861
|
case 'distribution':
|
|
@@ -1610,8 +1889,22 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1610
1889
|
return {
|
|
1611
1890
|
operation,
|
|
1612
1891
|
field: operation === 'COUNT' ? undefined : metric.field,
|
|
1892
|
+
alias: metric.field,
|
|
1613
1893
|
};
|
|
1614
1894
|
}
|
|
1895
|
+
buildStatsMetricRequests(contract) {
|
|
1896
|
+
if (!contract.metrics?.length) {
|
|
1897
|
+
throw new Error('x-ui.chart requires at least one metric to derive the canonical praxis.stats request.');
|
|
1898
|
+
}
|
|
1899
|
+
return contract.metrics.map((metric) => {
|
|
1900
|
+
const operation = this.mapStatsMetricOperation(metric.aggregation);
|
|
1901
|
+
return {
|
|
1902
|
+
operation,
|
|
1903
|
+
field: operation === 'COUNT' ? undefined : metric.field,
|
|
1904
|
+
alias: metric.field,
|
|
1905
|
+
};
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1615
1908
|
mapStatsOrderBy(value) {
|
|
1616
1909
|
if (!value)
|
|
1617
1910
|
return undefined;
|
|
@@ -2007,7 +2300,7 @@ const PRAXIS_CHART_BACKEND_MOCK_TIMESERIES = {
|
|
|
2007
2300
|
widget: {
|
|
2008
2301
|
kind: 'x-ui.chart',
|
|
2009
2302
|
key: 'incident-timeseries-chart',
|
|
2010
|
-
layout: { col: 7, row: 1, colSpan:
|
|
2303
|
+
layout: { col: 7, row: 1, colSpan: 6, rowSpan: 4 },
|
|
2011
2304
|
shell: {
|
|
2012
2305
|
title: 'Incidentes por mes',
|
|
2013
2306
|
subtitle: 'Time series real consumindo praxis.stats publicado',
|
|
@@ -2063,7 +2356,7 @@ const PRAXIS_CHART_BACKEND_MOCK_DONUT = {
|
|
|
2063
2356
|
widget: {
|
|
2064
2357
|
kind: 'x-ui.chart',
|
|
2065
2358
|
key: 'ticket-status-chart',
|
|
2066
|
-
layout: { col: 7, row:
|
|
2359
|
+
layout: { col: 7, row: 5, colSpan: 6, rowSpan: 4 },
|
|
2067
2360
|
shell: {
|
|
2068
2361
|
title: 'Severidade de incidentes',
|
|
2069
2362
|
subtitle: 'Distribution real consumindo praxis.stats publicado',
|
|
@@ -2107,6 +2400,247 @@ const PRAXIS_CHART_BACKEND_MOCK_DONUT = {
|
|
|
2107
2400
|
},
|
|
2108
2401
|
},
|
|
2109
2402
|
};
|
|
2403
|
+
const PRAXIS_CHART_BACKEND_MOCK_HORIZONTAL_BAR = {
|
|
2404
|
+
schemaMeta: {
|
|
2405
|
+
schemaId: 'api/human-resources/vw-analytics-folha-pagamento|post|response|tenant:demo|locale:pt-BR',
|
|
2406
|
+
schemaHash: 'published-hash-payroll-department-ranking-v1',
|
|
2407
|
+
resourcePath: 'api/human-resources/vw-analytics-folha-pagamento',
|
|
2408
|
+
operation: 'post',
|
|
2409
|
+
schemaType: 'response',
|
|
2410
|
+
source: 'backend',
|
|
2411
|
+
},
|
|
2412
|
+
widget: {
|
|
2413
|
+
kind: 'x-ui.chart',
|
|
2414
|
+
key: 'payroll-department-horizontal-bar',
|
|
2415
|
+
layout: { col: 1, row: 5, colSpan: 6, rowSpan: 4 },
|
|
2416
|
+
shell: {
|
|
2417
|
+
title: 'Massa salarial por departamento',
|
|
2418
|
+
subtitle: 'Ranking horizontal em payroll analytics',
|
|
2419
|
+
},
|
|
2420
|
+
chart: {
|
|
2421
|
+
version: '0.1.0',
|
|
2422
|
+
kind: 'horizontal-bar',
|
|
2423
|
+
preset: 'ranking',
|
|
2424
|
+
chartId: 'payroll-department-horizontal-bar',
|
|
2425
|
+
title: { key: 'charts.payroll.department.title', fallback: 'Massa salarial por departamento' },
|
|
2426
|
+
subtitle: { key: 'charts.payroll.department.subtitle', fallback: 'Ranking horizontal consumindo praxis.stats' },
|
|
2427
|
+
orientation: 'horizontal',
|
|
2428
|
+
height: 340,
|
|
2429
|
+
source: {
|
|
2430
|
+
kind: 'praxis.stats',
|
|
2431
|
+
resource: 'api/human-resources/vw-analytics-folha-pagamento',
|
|
2432
|
+
operation: 'group-by',
|
|
2433
|
+
options: {
|
|
2434
|
+
orderBy: 'value-desc',
|
|
2435
|
+
limit: 8,
|
|
2436
|
+
},
|
|
2437
|
+
},
|
|
2438
|
+
dimensions: [
|
|
2439
|
+
{
|
|
2440
|
+
field: 'departamento',
|
|
2441
|
+
label: 'Departamento',
|
|
2442
|
+
role: 'category',
|
|
2443
|
+
},
|
|
2444
|
+
],
|
|
2445
|
+
metrics: [
|
|
2446
|
+
{
|
|
2447
|
+
field: 'salarioLiquido',
|
|
2448
|
+
label: 'Massa liquida',
|
|
2449
|
+
aggregation: 'sum',
|
|
2450
|
+
},
|
|
2451
|
+
],
|
|
2452
|
+
legend: { enabled: false },
|
|
2453
|
+
tooltip: { enabled: true },
|
|
2454
|
+
theme: {
|
|
2455
|
+
palette: ['#0f766e'],
|
|
2456
|
+
},
|
|
2457
|
+
events: {
|
|
2458
|
+
pointClick: {
|
|
2459
|
+
action: 'emit',
|
|
2460
|
+
},
|
|
2461
|
+
},
|
|
2462
|
+
},
|
|
2463
|
+
},
|
|
2464
|
+
};
|
|
2465
|
+
const PRAXIS_CHART_BACKEND_MOCK_STACKED_AREA = {
|
|
2466
|
+
schemaMeta: {
|
|
2467
|
+
schemaId: 'api/human-resources/vw-analytics-folha-pagamento|post|response|tenant:demo|locale:pt-BR',
|
|
2468
|
+
schemaHash: 'published-hash-payroll-net-trend-stacked-v1',
|
|
2469
|
+
resourcePath: 'api/human-resources/vw-analytics-folha-pagamento',
|
|
2470
|
+
operation: 'post',
|
|
2471
|
+
schemaType: 'response',
|
|
2472
|
+
source: 'backend',
|
|
2473
|
+
},
|
|
2474
|
+
widget: {
|
|
2475
|
+
kind: 'x-ui.chart',
|
|
2476
|
+
key: 'payroll-net-stacked-area',
|
|
2477
|
+
layout: { col: 1, row: 9, colSpan: 12, rowSpan: 4 },
|
|
2478
|
+
shell: {
|
|
2479
|
+
title: 'Composicao temporal da folha',
|
|
2480
|
+
subtitle: 'Stacked area inicial sobre timeseries published',
|
|
2481
|
+
},
|
|
2482
|
+
chart: {
|
|
2483
|
+
version: '0.1.0',
|
|
2484
|
+
kind: 'stacked-area',
|
|
2485
|
+
preset: 'composition',
|
|
2486
|
+
chartId: 'payroll-net-stacked-area',
|
|
2487
|
+
title: { key: 'charts.payroll.stackedArea.title', fallback: 'Composicao temporal da folha' },
|
|
2488
|
+
subtitle: { key: 'charts.payroll.stackedArea.subtitle', fallback: 'Stacked area sobre payroll analytics' },
|
|
2489
|
+
height: 340,
|
|
2490
|
+
source: {
|
|
2491
|
+
kind: 'praxis.stats',
|
|
2492
|
+
resource: 'api/human-resources/vw-analytics-folha-pagamento',
|
|
2493
|
+
operation: 'timeseries',
|
|
2494
|
+
options: {
|
|
2495
|
+
granularity: 'month',
|
|
2496
|
+
fillGaps: false,
|
|
2497
|
+
},
|
|
2498
|
+
},
|
|
2499
|
+
dimensions: [
|
|
2500
|
+
{
|
|
2501
|
+
field: 'competencia',
|
|
2502
|
+
label: 'Competencia',
|
|
2503
|
+
role: 'time',
|
|
2504
|
+
},
|
|
2505
|
+
],
|
|
2506
|
+
metrics: [
|
|
2507
|
+
{
|
|
2508
|
+
field: 'salarioLiquido',
|
|
2509
|
+
label: 'Massa liquida',
|
|
2510
|
+
aggregation: 'sum',
|
|
2511
|
+
},
|
|
2512
|
+
],
|
|
2513
|
+
legend: { enabled: true },
|
|
2514
|
+
tooltip: { enabled: true },
|
|
2515
|
+
theme: {
|
|
2516
|
+
palette: ['#1263b4'],
|
|
2517
|
+
},
|
|
2518
|
+
},
|
|
2519
|
+
},
|
|
2520
|
+
};
|
|
2521
|
+
const PRAXIS_CHART_BACKEND_MOCK_SCATTER = {
|
|
2522
|
+
schemaMeta: {
|
|
2523
|
+
schemaId: 'api/human-resources/vw-analytics-folha-pagamento|post|response|tenant:demo|locale:pt-BR',
|
|
2524
|
+
schemaHash: 'published-hash-payroll-scatter-v1',
|
|
2525
|
+
resourcePath: 'api/human-resources/vw-analytics-folha-pagamento',
|
|
2526
|
+
operation: 'post',
|
|
2527
|
+
schemaType: 'response',
|
|
2528
|
+
source: 'backend',
|
|
2529
|
+
},
|
|
2530
|
+
widget: {
|
|
2531
|
+
kind: 'x-ui.chart',
|
|
2532
|
+
key: 'payroll-net-vs-discount-scatter',
|
|
2533
|
+
layout: { col: 1, row: 13, colSpan: 12, rowSpan: 4 },
|
|
2534
|
+
shell: {
|
|
2535
|
+
title: 'Liquido x desconto medio',
|
|
2536
|
+
subtitle: 'Dispersao inicial sobre payroll analytics',
|
|
2537
|
+
},
|
|
2538
|
+
chart: {
|
|
2539
|
+
version: '0.1.0',
|
|
2540
|
+
kind: 'scatter',
|
|
2541
|
+
preset: 'comparison',
|
|
2542
|
+
chartId: 'payroll-net-vs-discount-scatter',
|
|
2543
|
+
title: { key: 'charts.payroll.scatter.title', fallback: 'Liquido x desconto medio' },
|
|
2544
|
+
subtitle: { key: 'charts.payroll.scatter.subtitle', fallback: 'Scatter sobre recortes do payroll' },
|
|
2545
|
+
height: 340,
|
|
2546
|
+
source: {
|
|
2547
|
+
kind: 'praxis.stats',
|
|
2548
|
+
resource: 'api/human-resources/vw-analytics-folha-pagamento',
|
|
2549
|
+
operation: 'group-by',
|
|
2550
|
+
options: {
|
|
2551
|
+
orderBy: 'key-asc',
|
|
2552
|
+
limit: 25,
|
|
2553
|
+
},
|
|
2554
|
+
},
|
|
2555
|
+
dimensions: [
|
|
2556
|
+
{
|
|
2557
|
+
field: 'salarioLiquido',
|
|
2558
|
+
label: 'Salario liquido',
|
|
2559
|
+
role: 'value',
|
|
2560
|
+
},
|
|
2561
|
+
],
|
|
2562
|
+
metrics: [
|
|
2563
|
+
{
|
|
2564
|
+
field: 'pctDesconto',
|
|
2565
|
+
label: 'Percentual medio de desconto',
|
|
2566
|
+
aggregation: 'avg',
|
|
2567
|
+
},
|
|
2568
|
+
],
|
|
2569
|
+
legend: { enabled: false },
|
|
2570
|
+
tooltip: { enabled: true },
|
|
2571
|
+
theme: {
|
|
2572
|
+
palette: ['#c92a2a'],
|
|
2573
|
+
},
|
|
2574
|
+
},
|
|
2575
|
+
},
|
|
2576
|
+
};
|
|
2577
|
+
const PRAXIS_CHART_BACKEND_MOCK_COMBO = {
|
|
2578
|
+
schemaMeta: {
|
|
2579
|
+
schemaId: 'api/human-resources/vw-analytics-folha-pagamento|post|response|tenant:demo|locale:pt-BR',
|
|
2580
|
+
schemaHash: 'published-hash-payroll-combo-v2',
|
|
2581
|
+
resourcePath: 'api/human-resources/vw-analytics-folha-pagamento',
|
|
2582
|
+
operation: 'post',
|
|
2583
|
+
schemaType: 'response',
|
|
2584
|
+
source: 'backend',
|
|
2585
|
+
},
|
|
2586
|
+
widget: {
|
|
2587
|
+
kind: 'x-ui.chart',
|
|
2588
|
+
key: 'payroll-combo-variance',
|
|
2589
|
+
layout: { col: 1, row: 17, colSpan: 12, rowSpan: 4 },
|
|
2590
|
+
shell: {
|
|
2591
|
+
title: 'Folha liquida e desconto medio',
|
|
2592
|
+
subtitle: 'Combo remoto sobre praxis.stats multi-metrica',
|
|
2593
|
+
},
|
|
2594
|
+
chart: {
|
|
2595
|
+
version: '0.1.0',
|
|
2596
|
+
kind: 'combo',
|
|
2597
|
+
preset: 'comparison',
|
|
2598
|
+
chartId: 'payroll-combo-variance',
|
|
2599
|
+
title: { key: 'charts.payroll.combo.title', fallback: 'Folha liquida e desconto medio' },
|
|
2600
|
+
subtitle: { key: 'charts.payroll.combo.subtitle', fallback: 'Barras para liquido e linha para desconto medio via praxis.stats' },
|
|
2601
|
+
height: 340,
|
|
2602
|
+
source: {
|
|
2603
|
+
kind: 'praxis.stats',
|
|
2604
|
+
resource: 'api/human-resources/vw-analytics-folha-pagamento',
|
|
2605
|
+
operation: 'timeseries',
|
|
2606
|
+
options: {
|
|
2607
|
+
granularity: 'month',
|
|
2608
|
+
fillGaps: true,
|
|
2609
|
+
},
|
|
2610
|
+
},
|
|
2611
|
+
dimensions: [
|
|
2612
|
+
{
|
|
2613
|
+
field: 'competencia',
|
|
2614
|
+
label: 'Competencia',
|
|
2615
|
+
role: 'time',
|
|
2616
|
+
},
|
|
2617
|
+
],
|
|
2618
|
+
metrics: [
|
|
2619
|
+
{
|
|
2620
|
+
field: 'salarioLiquido',
|
|
2621
|
+
label: 'Massa liquida',
|
|
2622
|
+
aggregation: 'sum',
|
|
2623
|
+
seriesKind: 'bar',
|
|
2624
|
+
axis: 'primary',
|
|
2625
|
+
color: '#1263b4',
|
|
2626
|
+
},
|
|
2627
|
+
{
|
|
2628
|
+
field: 'pctDesconto',
|
|
2629
|
+
label: 'Desconto medio',
|
|
2630
|
+
aggregation: 'avg',
|
|
2631
|
+
seriesKind: 'line',
|
|
2632
|
+
axis: 'secondary',
|
|
2633
|
+
color: '#c92a2a',
|
|
2634
|
+
},
|
|
2635
|
+
],
|
|
2636
|
+
legend: { enabled: true },
|
|
2637
|
+
tooltip: { enabled: true },
|
|
2638
|
+
theme: {
|
|
2639
|
+
palette: ['#1263b4', '#c92a2a'],
|
|
2640
|
+
},
|
|
2641
|
+
},
|
|
2642
|
+
},
|
|
2643
|
+
};
|
|
2110
2644
|
|
|
2111
2645
|
function buildPraxisChartMockWidgetPage(adapter) {
|
|
2112
2646
|
return {
|
|
@@ -2114,6 +2648,10 @@ function buildPraxisChartMockWidgetPage(adapter) {
|
|
|
2114
2648
|
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_BAR)),
|
|
2115
2649
|
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_TIMESERIES)),
|
|
2116
2650
|
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_DONUT)),
|
|
2651
|
+
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_HORIZONTAL_BAR)),
|
|
2652
|
+
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_STACKED_AREA)),
|
|
2653
|
+
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_SCATTER)),
|
|
2654
|
+
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_COMBO)),
|
|
2117
2655
|
],
|
|
2118
2656
|
layout: {
|
|
2119
2657
|
orientation: 'columns',
|
|
@@ -2128,6 +2666,10 @@ function buildPraxisChartMockGridPage(adapter) {
|
|
|
2128
2666
|
withShowcaseViewToggle(adapter.toGridWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_BAR)),
|
|
2129
2667
|
withShowcaseViewToggle(adapter.toGridWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_TIMESERIES)),
|
|
2130
2668
|
withShowcaseViewToggle(adapter.toGridWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_DONUT)),
|
|
2669
|
+
withShowcaseViewToggle(adapter.toGridWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_HORIZONTAL_BAR)),
|
|
2670
|
+
withShowcaseViewToggle(adapter.toGridWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_STACKED_AREA)),
|
|
2671
|
+
withShowcaseViewToggle(adapter.toGridWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_SCATTER)),
|
|
2672
|
+
withShowcaseViewToggle(adapter.toGridWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_COMBO)),
|
|
2131
2673
|
],
|
|
2132
2674
|
options: {
|
|
2133
2675
|
cols: 12,
|
|
@@ -2141,6 +2683,7 @@ function buildPraxisChartInteractiveWidgetPage(adapter) {
|
|
|
2141
2683
|
widgets: [
|
|
2142
2684
|
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_BAR)),
|
|
2143
2685
|
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_TIMESERIES)),
|
|
2686
|
+
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_HORIZONTAL_BAR)),
|
|
2144
2687
|
{
|
|
2145
2688
|
key: 'chart-drilldown-panel',
|
|
2146
2689
|
definition: {
|
|
@@ -2170,6 +2713,9 @@ function buildPraxisChartInteractiveWidgetPage(adapter) {
|
|
|
2170
2713
|
},
|
|
2171
2714
|
},
|
|
2172
2715
|
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_DONUT)),
|
|
2716
|
+
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_STACKED_AREA)),
|
|
2717
|
+
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_SCATTER)),
|
|
2718
|
+
withShowcaseViewToggle(adapter.toWidgetInstance(PRAXIS_CHART_BACKEND_MOCK_COMBO)),
|
|
2173
2719
|
],
|
|
2174
2720
|
connections: [
|
|
2175
2721
|
{
|
|
@@ -2208,6 +2754,34 @@ function buildPraxisChartInteractiveGridPage(adapter) {
|
|
|
2208
2754
|
layout: { col: 7, row: 5, colSpan: 6, rowSpan: 4 },
|
|
2209
2755
|
},
|
|
2210
2756
|
})),
|
|
2757
|
+
withShowcaseViewToggle(adapter.toGridWidgetInstance({
|
|
2758
|
+
...PRAXIS_CHART_BACKEND_MOCK_HORIZONTAL_BAR,
|
|
2759
|
+
widget: {
|
|
2760
|
+
...PRAXIS_CHART_BACKEND_MOCK_HORIZONTAL_BAR.widget,
|
|
2761
|
+
layout: { col: 1, row: 9, colSpan: 6, rowSpan: 4 },
|
|
2762
|
+
},
|
|
2763
|
+
})),
|
|
2764
|
+
withShowcaseViewToggle(adapter.toGridWidgetInstance({
|
|
2765
|
+
...PRAXIS_CHART_BACKEND_MOCK_STACKED_AREA,
|
|
2766
|
+
widget: {
|
|
2767
|
+
...PRAXIS_CHART_BACKEND_MOCK_STACKED_AREA.widget,
|
|
2768
|
+
layout: { col: 1, row: 13, colSpan: 12, rowSpan: 4 },
|
|
2769
|
+
},
|
|
2770
|
+
})),
|
|
2771
|
+
withShowcaseViewToggle(adapter.toGridWidgetInstance({
|
|
2772
|
+
...PRAXIS_CHART_BACKEND_MOCK_SCATTER,
|
|
2773
|
+
widget: {
|
|
2774
|
+
...PRAXIS_CHART_BACKEND_MOCK_SCATTER.widget,
|
|
2775
|
+
layout: { col: 1, row: 17, colSpan: 12, rowSpan: 4 },
|
|
2776
|
+
},
|
|
2777
|
+
})),
|
|
2778
|
+
withShowcaseViewToggle(adapter.toGridWidgetInstance({
|
|
2779
|
+
...PRAXIS_CHART_BACKEND_MOCK_COMBO,
|
|
2780
|
+
widget: {
|
|
2781
|
+
...PRAXIS_CHART_BACKEND_MOCK_COMBO.widget,
|
|
2782
|
+
layout: { col: 1, row: 21, colSpan: 12, rowSpan: 4 },
|
|
2783
|
+
},
|
|
2784
|
+
})),
|
|
2211
2785
|
],
|
|
2212
2786
|
connections: [
|
|
2213
2787
|
{
|
|
@@ -2429,6 +3003,14 @@ class PraxisChartCompositionShowcaseComponent {
|
|
|
2429
3003
|
return 'Envelope timeseries';
|
|
2430
3004
|
case 'distribution':
|
|
2431
3005
|
return 'Envelope distribution';
|
|
3006
|
+
case 'horizontal-bar':
|
|
3007
|
+
return 'Envelope horizontal-bar';
|
|
3008
|
+
case 'stacked-area':
|
|
3009
|
+
return 'Envelope stacked-area';
|
|
3010
|
+
case 'scatter':
|
|
3011
|
+
return 'Envelope scatter';
|
|
3012
|
+
case 'combo':
|
|
3013
|
+
return 'Envelope combo';
|
|
2432
3014
|
case 'group-by':
|
|
2433
3015
|
default:
|
|
2434
3016
|
return 'Envelope group-by';
|
|
@@ -2441,6 +3023,14 @@ class PraxisChartCompositionShowcaseComponent {
|
|
|
2441
3023
|
return PRAXIS_CHART_BACKEND_MOCK_TIMESERIES;
|
|
2442
3024
|
case 'distribution':
|
|
2443
3025
|
return PRAXIS_CHART_BACKEND_MOCK_DONUT;
|
|
3026
|
+
case 'horizontal-bar':
|
|
3027
|
+
return PRAXIS_CHART_BACKEND_MOCK_HORIZONTAL_BAR;
|
|
3028
|
+
case 'stacked-area':
|
|
3029
|
+
return PRAXIS_CHART_BACKEND_MOCK_STACKED_AREA;
|
|
3030
|
+
case 'scatter':
|
|
3031
|
+
return PRAXIS_CHART_BACKEND_MOCK_SCATTER;
|
|
3032
|
+
case 'combo':
|
|
3033
|
+
return PRAXIS_CHART_BACKEND_MOCK_COMBO;
|
|
2444
3034
|
case 'group-by':
|
|
2445
3035
|
default:
|
|
2446
3036
|
return PRAXIS_CHART_BACKEND_MOCK_BAR;
|
|
@@ -2485,6 +3075,18 @@ class PraxisChartCompositionShowcaseComponent {
|
|
|
2485
3075
|
<button type="button" [class.active]="payloadMode() === 'distribution'" (click)="payloadMode.set('distribution')">
|
|
2486
3076
|
Distribution
|
|
2487
3077
|
</button>
|
|
3078
|
+
<button type="button" [class.active]="payloadMode() === 'horizontal-bar'" (click)="payloadMode.set('horizontal-bar')">
|
|
3079
|
+
Horizontal bar
|
|
3080
|
+
</button>
|
|
3081
|
+
<button type="button" [class.active]="payloadMode() === 'stacked-area'" (click)="payloadMode.set('stacked-area')">
|
|
3082
|
+
Stacked area
|
|
3083
|
+
</button>
|
|
3084
|
+
<button type="button" [class.active]="payloadMode() === 'scatter'" (click)="payloadMode.set('scatter')">
|
|
3085
|
+
Scatter
|
|
3086
|
+
</button>
|
|
3087
|
+
<button type="button" [class.active]="payloadMode() === 'combo'" (click)="payloadMode.set('combo')">
|
|
3088
|
+
Combo
|
|
3089
|
+
</button>
|
|
2488
3090
|
</div>
|
|
2489
3091
|
</div>
|
|
2490
3092
|
|
|
@@ -2518,7 +3120,7 @@ class PraxisChartCompositionShowcaseComponent {
|
|
|
2518
3120
|
<p class="panel-kicker">Runtime</p>
|
|
2519
3121
|
<h3>{{ layoutMode() === 'widget' ? 'DynamicWidgetPage' : 'DynamicGridPage' }}</h3>
|
|
2520
3122
|
</div>
|
|
2521
|
-
<span class="panel-chip">{{ layoutMode() }}
|
|
3123
|
+
<span class="panel-chip">{{ layoutMode() }} / {{ scenarioMode() }}</span>
|
|
2522
3124
|
</div>
|
|
2523
3125
|
|
|
2524
3126
|
@if (layoutMode() === 'widget') {
|
|
@@ -2587,6 +3189,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
2587
3189
|
<button type="button" [class.active]="payloadMode() === 'distribution'" (click)="payloadMode.set('distribution')">
|
|
2588
3190
|
Distribution
|
|
2589
3191
|
</button>
|
|
3192
|
+
<button type="button" [class.active]="payloadMode() === 'horizontal-bar'" (click)="payloadMode.set('horizontal-bar')">
|
|
3193
|
+
Horizontal bar
|
|
3194
|
+
</button>
|
|
3195
|
+
<button type="button" [class.active]="payloadMode() === 'stacked-area'" (click)="payloadMode.set('stacked-area')">
|
|
3196
|
+
Stacked area
|
|
3197
|
+
</button>
|
|
3198
|
+
<button type="button" [class.active]="payloadMode() === 'scatter'" (click)="payloadMode.set('scatter')">
|
|
3199
|
+
Scatter
|
|
3200
|
+
</button>
|
|
3201
|
+
<button type="button" [class.active]="payloadMode() === 'combo'" (click)="payloadMode.set('combo')">
|
|
3202
|
+
Combo
|
|
3203
|
+
</button>
|
|
2590
3204
|
</div>
|
|
2591
3205
|
</div>
|
|
2592
3206
|
|
|
@@ -2620,7 +3234,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
2620
3234
|
<p class="panel-kicker">Runtime</p>
|
|
2621
3235
|
<h3>{{ layoutMode() === 'widget' ? 'DynamicWidgetPage' : 'DynamicGridPage' }}</h3>
|
|
2622
3236
|
</div>
|
|
2623
|
-
<span class="panel-chip">{{ layoutMode() }}
|
|
3237
|
+
<span class="panel-chip">{{ layoutMode() }} / {{ scenarioMode() }}</span>
|
|
2624
3238
|
</div>
|
|
2625
3239
|
|
|
2626
3240
|
@if (layoutMode() === 'widget') {
|
|
@@ -2658,5 +3272,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
2658
3272
|
* Generated bundle index. Do not edit.
|
|
2659
3273
|
*/
|
|
2660
3274
|
|
|
2661
|
-
export { PRAXIS_CHART_BACKEND_MOCK_BAR, PRAXIS_CHART_BACKEND_MOCK_DONUT, PRAXIS_CHART_BACKEND_MOCK_TIMESERIES, PRAXIS_CHART_COMPONENT_METADATA, PRAXIS_CHART_DRILLDOWN_DATA_BY_MONTH, PRAXIS_CHART_DRILLDOWN_PANEL_METADATA, PRAXIS_CHART_ENGINE, PRAXIS_CHART_STATE_PROBE_COMPONENT_METADATA, PraxisChartBackendPayloadAdapterService, PraxisChartCanonicalContractMapperService, PraxisChartComponent, PraxisChartCompositionShowcaseComponent, PraxisChartDataTransformerService, PraxisChartDrilldownPanelComponent, PraxisChartOptionBuilderService, PraxisChartSchemaMapperService, PraxisChartStateProbeComponent, PraxisChartStatsApiService, buildPraxisChartInteractiveGridPage, buildPraxisChartInteractiveWidgetPage, buildPraxisChartMockGridPage, buildPraxisChartMockWidgetPage, providePraxisChartDrilldownPanelMetadata, providePraxisChartStateProbeMetadata, providePraxisCharts, providePraxisChartsMetadata };
|
|
3275
|
+
export { PRAXIS_CHART_BACKEND_MOCK_BAR, PRAXIS_CHART_BACKEND_MOCK_COMBO, PRAXIS_CHART_BACKEND_MOCK_DONUT, PRAXIS_CHART_BACKEND_MOCK_HORIZONTAL_BAR, PRAXIS_CHART_BACKEND_MOCK_SCATTER, PRAXIS_CHART_BACKEND_MOCK_STACKED_AREA, PRAXIS_CHART_BACKEND_MOCK_TIMESERIES, PRAXIS_CHART_COMPONENT_METADATA, PRAXIS_CHART_DRILLDOWN_DATA_BY_MONTH, PRAXIS_CHART_DRILLDOWN_PANEL_METADATA, PRAXIS_CHART_ENGINE, PRAXIS_CHART_STATE_PROBE_COMPONENT_METADATA, PraxisChartBackendPayloadAdapterService, PraxisChartCanonicalContractMapperService, PraxisChartComponent, PraxisChartCompositionShowcaseComponent, PraxisChartDataTransformerService, PraxisChartDrilldownPanelComponent, PraxisChartOptionBuilderService, PraxisChartSchemaMapperService, PraxisChartStateProbeComponent, PraxisChartStatsApiService, buildPraxisChartInteractiveGridPage, buildPraxisChartInteractiveWidgetPage, buildPraxisChartMockGridPage, buildPraxisChartMockWidgetPage, providePraxisChartDrilldownPanelMetadata, providePraxisChartStateProbeMetadata, providePraxisCharts, providePraxisChartsMetadata };
|
|
2662
3276
|
//# sourceMappingURL=praxisui-charts.mjs.map
|