@trismegisto/charts 3.3.3 → 3.3.5
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.
|
@@ -31,6 +31,11 @@ const CHARTS_MESSAGES_EN = {
|
|
|
31
31
|
median: 'Median',
|
|
32
32
|
q3: 'Third quartile',
|
|
33
33
|
max: 'Maximum',
|
|
34
|
+
goal: 'Target',
|
|
35
|
+
ranges: 'Ranges',
|
|
36
|
+
change: 'Change',
|
|
37
|
+
cumulative: 'Cumulative',
|
|
38
|
+
size: 'Size',
|
|
34
39
|
},
|
|
35
40
|
types: {
|
|
36
41
|
bar: 'Bar chart',
|
|
@@ -47,6 +52,10 @@ const CHARTS_MESSAGES_EN = {
|
|
|
47
52
|
treemap: 'Treemap',
|
|
48
53
|
sankey: 'Sankey diagram',
|
|
49
54
|
boxplot: 'Box plot',
|
|
55
|
+
sparkline: 'Sparkline',
|
|
56
|
+
bubble: 'Bubble chart',
|
|
57
|
+
bullet: 'Bullet chart',
|
|
58
|
+
waterfall: 'Waterfall chart',
|
|
50
59
|
chart: 'Chart',
|
|
51
60
|
},
|
|
52
61
|
summary: {
|
|
@@ -67,6 +76,22 @@ const CHARTS_MESSAGES_EN = {
|
|
|
67
76
|
one: '{type} with 1 item.',
|
|
68
77
|
other: '{type} with {count} items.',
|
|
69
78
|
},
|
|
79
|
+
gaugeCaption: '{type}: {value} {caption}, on a scale from {min} to {max}.',
|
|
80
|
+
sparkline: {
|
|
81
|
+
one: '{type} with 1 point: {last}.',
|
|
82
|
+
other: '{type} with {count} points, from {first} to {last}. Minimum {min}, maximum {max}.',
|
|
83
|
+
},
|
|
84
|
+
bulletItem: '{name}: {value}, target {target}.',
|
|
85
|
+
bulletItemNoTarget: '{name}: {value}.',
|
|
86
|
+
waterfall: {
|
|
87
|
+
one: '{type} with 1 step: from {start} to {end}.',
|
|
88
|
+
other: '{type} with {count} steps: from {start} to {end}.',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
waterfall: {
|
|
92
|
+
increase: 'Increase',
|
|
93
|
+
decrease: 'Decrease',
|
|
94
|
+
total: 'Total',
|
|
70
95
|
},
|
|
71
96
|
engine: {
|
|
72
97
|
legendAll: 'All',
|
|
@@ -112,6 +137,11 @@ const CHARTS_MESSAGES_ES = {
|
|
|
112
137
|
median: 'Mediana',
|
|
113
138
|
q3: 'Tercer cuartil',
|
|
114
139
|
max: 'Máximo',
|
|
140
|
+
goal: 'Meta',
|
|
141
|
+
ranges: 'Rangos',
|
|
142
|
+
change: 'Variación',
|
|
143
|
+
cumulative: 'Acumulado',
|
|
144
|
+
size: 'Tamaño',
|
|
115
145
|
},
|
|
116
146
|
types: {
|
|
117
147
|
bar: 'Gráfico de barras',
|
|
@@ -128,6 +158,10 @@ const CHARTS_MESSAGES_ES = {
|
|
|
128
158
|
treemap: 'Mapa de árbol',
|
|
129
159
|
sankey: 'Diagrama de Sankey',
|
|
130
160
|
boxplot: 'Diagrama de caja',
|
|
161
|
+
sparkline: 'Minigráfico',
|
|
162
|
+
bubble: 'Gráfico de burbujas',
|
|
163
|
+
bullet: 'Gráfico de bala',
|
|
164
|
+
waterfall: 'Gráfico de cascada',
|
|
131
165
|
chart: 'Gráfico',
|
|
132
166
|
},
|
|
133
167
|
summary: {
|
|
@@ -148,6 +182,22 @@ const CHARTS_MESSAGES_ES = {
|
|
|
148
182
|
one: '{type} con 1 elemento.',
|
|
149
183
|
other: '{type} con {count} elementos.',
|
|
150
184
|
},
|
|
185
|
+
gaugeCaption: '{type}: {value} {caption}, en una escala de {min} a {max}.',
|
|
186
|
+
sparkline: {
|
|
187
|
+
one: '{type} con 1 punto: {last}.',
|
|
188
|
+
other: '{type} con {count} puntos, de {first} a {last}. Mínimo {min}, máximo {max}.',
|
|
189
|
+
},
|
|
190
|
+
bulletItem: '{name}: {value}, meta {target}.',
|
|
191
|
+
bulletItemNoTarget: '{name}: {value}.',
|
|
192
|
+
waterfall: {
|
|
193
|
+
one: '{type} con 1 etapa: de {start} a {end}.',
|
|
194
|
+
other: '{type} con {count} etapas: de {start} a {end}.',
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
waterfall: {
|
|
198
|
+
increase: 'Aumento',
|
|
199
|
+
decrease: 'Disminución',
|
|
200
|
+
total: 'Total',
|
|
151
201
|
},
|
|
152
202
|
engine: {
|
|
153
203
|
legendAll: 'Todos',
|
|
@@ -193,6 +243,11 @@ const CHARTS_MESSAGES_PT_BR = {
|
|
|
193
243
|
median: 'Mediana',
|
|
194
244
|
q3: '3º quartil',
|
|
195
245
|
max: 'Máximo',
|
|
246
|
+
goal: 'Meta',
|
|
247
|
+
ranges: 'Faixas',
|
|
248
|
+
change: 'Variação',
|
|
249
|
+
cumulative: 'Acumulado',
|
|
250
|
+
size: 'Tamanho',
|
|
196
251
|
},
|
|
197
252
|
types: {
|
|
198
253
|
bar: 'Gráfico de barras',
|
|
@@ -209,6 +264,10 @@ const CHARTS_MESSAGES_PT_BR = {
|
|
|
209
264
|
treemap: 'Mapa de árvore',
|
|
210
265
|
sankey: 'Diagrama de Sankey',
|
|
211
266
|
boxplot: 'Diagrama de caixa',
|
|
267
|
+
sparkline: 'Minigráfico',
|
|
268
|
+
bubble: 'Gráfico de bolhas',
|
|
269
|
+
bullet: 'Gráfico de bala',
|
|
270
|
+
waterfall: 'Gráfico de cascata',
|
|
212
271
|
chart: 'Gráfico',
|
|
213
272
|
},
|
|
214
273
|
summary: {
|
|
@@ -229,6 +288,22 @@ const CHARTS_MESSAGES_PT_BR = {
|
|
|
229
288
|
one: '{type} com 1 item.',
|
|
230
289
|
other: '{type} com {count} itens.',
|
|
231
290
|
},
|
|
291
|
+
gaugeCaption: '{type}: {value} {caption}, numa escala de {min} a {max}.',
|
|
292
|
+
sparkline: {
|
|
293
|
+
one: '{type} com 1 ponto: {last}.',
|
|
294
|
+
other: '{type} com {count} pontos, de {first} a {last}. Mínimo {min}, máximo {max}.',
|
|
295
|
+
},
|
|
296
|
+
bulletItem: '{name}: {value}, meta {target}.',
|
|
297
|
+
bulletItemNoTarget: '{name}: {value}.',
|
|
298
|
+
waterfall: {
|
|
299
|
+
one: '{type} com 1 etapa: de {start} a {end}.',
|
|
300
|
+
other: '{type} com {count} etapas: de {start} a {end}.',
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
waterfall: {
|
|
304
|
+
increase: 'Aumento',
|
|
305
|
+
decrease: 'Redução',
|
|
306
|
+
total: 'Total',
|
|
232
307
|
},
|
|
233
308
|
engine: {
|
|
234
309
|
legendAll: 'Todos',
|
|
@@ -4304,8 +4379,8 @@ class Storage {
|
|
|
4304
4379
|
* Licensed under the BSD 3-Clause License. The full license text is in
|
|
4305
4380
|
* LICENSES/zrender-BSD-3-Clause.txt at the root of this package.
|
|
4306
4381
|
*/
|
|
4307
|
-
let requestAnimationFrame;
|
|
4308
|
-
requestAnimationFrame = (env.hasGlobalWindow
|
|
4382
|
+
let requestAnimationFrame$1;
|
|
4383
|
+
requestAnimationFrame$1 = (env.hasGlobalWindow
|
|
4309
4384
|
&& ((window.requestAnimationFrame && window.requestAnimationFrame.bind(window))
|
|
4310
4385
|
// https://github.com/ecomfe/zrender/issues/189#issuecomment-224919809
|
|
4311
4386
|
|| (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window))
|
|
@@ -4314,7 +4389,7 @@ requestAnimationFrame = (env.hasGlobalWindow
|
|
|
4314
4389
|
|| window.webkitRequestAnimationFrame)) || function (func) {
|
|
4315
4390
|
return setTimeout(func, 16);
|
|
4316
4391
|
};
|
|
4317
|
-
var requestAnimationFrame$
|
|
4392
|
+
var requestAnimationFrame$2 = requestAnimationFrame$1;
|
|
4318
4393
|
|
|
4319
4394
|
/*
|
|
4320
4395
|
* Copyright (c) 2017, Baidu Inc.
|
|
@@ -7024,11 +7099,11 @@ class Animation extends Eventful {
|
|
|
7024
7099
|
this._running = true;
|
|
7025
7100
|
function step() {
|
|
7026
7101
|
if (self._running) {
|
|
7027
|
-
requestAnimationFrame$
|
|
7102
|
+
requestAnimationFrame$2(step);
|
|
7028
7103
|
!self._paused && self.update();
|
|
7029
7104
|
}
|
|
7030
7105
|
}
|
|
7031
|
-
requestAnimationFrame$
|
|
7106
|
+
requestAnimationFrame$2(step);
|
|
7032
7107
|
}
|
|
7033
7108
|
/**
|
|
7034
7109
|
* Start animation.
|
|
@@ -75203,6 +75278,19 @@ function resolveColor(probe, token) {
|
|
|
75203
75278
|
const value = getComputedStyle(probe).color;
|
|
75204
75279
|
return value && !value.includes('var(') ? value : undefined;
|
|
75205
75280
|
}
|
|
75281
|
+
/** Um token de cor resolvido para `rgb(...)` no elemento (sonda temporária); `undefined` se não resolver. */
|
|
75282
|
+
function resolveTokenColor(host, token) {
|
|
75283
|
+
const probe = host.ownerDocument.createElement('span');
|
|
75284
|
+
probe.setAttribute('aria-hidden', 'true');
|
|
75285
|
+
probe.style.display = 'none';
|
|
75286
|
+
host.appendChild(probe);
|
|
75287
|
+
try {
|
|
75288
|
+
return resolveColor(probe, token);
|
|
75289
|
+
}
|
|
75290
|
+
finally {
|
|
75291
|
+
probe.remove();
|
|
75292
|
+
}
|
|
75293
|
+
}
|
|
75206
75294
|
function readToken(host, token) {
|
|
75207
75295
|
const value = getComputedStyle(host).getPropertyValue(token).trim();
|
|
75208
75296
|
return value || undefined;
|
|
@@ -75255,7 +75343,17 @@ function readChartTheme(host, forced = false) {
|
|
|
75255
75343
|
radar: { axisName: { color: muted }, axisLine: { lineStyle: { color: divider } }, splitLine: { lineStyle: { color: divider } } },
|
|
75256
75344
|
calendar: { dayLabel: { color: muted }, monthLabel: { color: muted }, yearLabel: { color: muted }, splitLine: { lineStyle: { color: border } }, itemStyle: { borderColor: surface } },
|
|
75257
75345
|
visualMap: { textStyle: { color: muted }, inRange: sequential.length ? { color: sequential } : undefined },
|
|
75258
|
-
gauge: {
|
|
75346
|
+
gauge: {
|
|
75347
|
+
axisLabel: { color: muted },
|
|
75348
|
+
title: { color: muted },
|
|
75349
|
+
detail: { color: text },
|
|
75350
|
+
axisLine: { lineStyle: { color: [[1, divider]] } },
|
|
75351
|
+
// Escala e agulha do medidor: marcas neutras, agulha na cor do texto com o pino recortado na superfície.
|
|
75352
|
+
splitLine: { lineStyle: { color: muted } },
|
|
75353
|
+
axisTick: { lineStyle: { color: border } },
|
|
75354
|
+
pointer: { itemStyle: { color: text } },
|
|
75355
|
+
anchor: { itemStyle: { color: text, borderColor: surface } },
|
|
75356
|
+
},
|
|
75259
75357
|
pie: { itemStyle: { borderColor: surface } },
|
|
75260
75358
|
funnel: { itemStyle: { borderColor: surface } },
|
|
75261
75359
|
treemap: { itemStyle: { borderColor: surface }, upperLabel: { color: text } },
|
|
@@ -75340,6 +75438,12 @@ class HmChartComponent {
|
|
|
75340
75438
|
#resize;
|
|
75341
75439
|
#scope;
|
|
75342
75440
|
#cursor;
|
|
75441
|
+
/**
|
|
75442
|
+
* O tema foi lido com o gráfico fora do documento (conteúdo projetado num painel que ainda não está na
|
|
75443
|
+
* página, como um `hm-tab` sem `hmTabContent`): os tokens não resolvem e as cores saem vazias. Relido na
|
|
75444
|
+
* primeira medição com o gráfico já no documento; quem nasce visível nunca passa por aqui.
|
|
75445
|
+
*/
|
|
75446
|
+
#themeStale;
|
|
75343
75447
|
#cleanups;
|
|
75344
75448
|
#locale;
|
|
75345
75449
|
#finalOption;
|
|
@@ -75359,6 +75463,12 @@ class HmChartComponent {
|
|
|
75359
75463
|
this.#resize = null;
|
|
75360
75464
|
this.#scope = null;
|
|
75361
75465
|
this.#cursor = -1;
|
|
75466
|
+
/**
|
|
75467
|
+
* O tema foi lido com o gráfico fora do documento (conteúdo projetado num painel que ainda não está na
|
|
75468
|
+
* página, como um `hm-tab` sem `hmTabContent`): os tokens não resolvem e as cores saem vazias. Relido na
|
|
75469
|
+
* primeira medição com o gráfico já no documento; quem nasce visível nunca passa por aqui.
|
|
75470
|
+
*/
|
|
75471
|
+
this.#themeStale = false;
|
|
75362
75472
|
this.#cleanups = [];
|
|
75363
75473
|
this.announcement = signal('', ...(ngDevMode ? [{ debugName: "announcement" }] : /* istanbul ignore next */ []));
|
|
75364
75474
|
this.#locale = computed(() => engineLocale(this.#i18n.messages(), this.#i18n.locale()), ...(ngDevMode ? [{ debugName: "#locale" }] : /* istanbul ignore next */ []));
|
|
@@ -75376,7 +75486,11 @@ class HmChartComponent {
|
|
|
75376
75486
|
this.#watchMedia('(prefers-reduced-motion: reduce)', this.#reducedMotion);
|
|
75377
75487
|
this.#watchMedia('(forced-colors: active)', this.#forcedColors);
|
|
75378
75488
|
if (typeof ResizeObserver !== 'undefined') {
|
|
75379
|
-
this.#resize = new ResizeObserver(() =>
|
|
75489
|
+
this.#resize = new ResizeObserver(() => {
|
|
75490
|
+
if (this.#themeStale && host.isConnected)
|
|
75491
|
+
this.#applyTheme();
|
|
75492
|
+
this.#chart?.resize();
|
|
75493
|
+
});
|
|
75380
75494
|
this.#resize.observe(host);
|
|
75381
75495
|
}
|
|
75382
75496
|
this.#watchScope(host);
|
|
@@ -75390,7 +75504,7 @@ class HmChartComponent {
|
|
|
75390
75504
|
untracked(() => {
|
|
75391
75505
|
const host = this.#host.nativeElement;
|
|
75392
75506
|
this.#chart?.dispose();
|
|
75393
|
-
this.#chart = init(host,
|
|
75507
|
+
this.#chart = init(host, this.#readTheme(), { locale });
|
|
75394
75508
|
this.#chart.setOption(this.#finalOption(), { notMerge: true });
|
|
75395
75509
|
});
|
|
75396
75510
|
});
|
|
@@ -75399,8 +75513,8 @@ class HmChartComponent {
|
|
|
75399
75513
|
untracked(() => this.#chart?.setOption(option, { notMerge: true }));
|
|
75400
75514
|
});
|
|
75401
75515
|
effect(() => {
|
|
75402
|
-
|
|
75403
|
-
untracked(() => this.#
|
|
75516
|
+
this.#forcedColors();
|
|
75517
|
+
untracked(() => this.#applyTheme());
|
|
75404
75518
|
});
|
|
75405
75519
|
inject(DestroyRef).onDestroy(() => {
|
|
75406
75520
|
this.#cleanups.forEach((fn) => fn());
|
|
@@ -75465,6 +75579,16 @@ class HmChartComponent {
|
|
|
75465
75579
|
chart.dispatchAction({ type: 'showTip', seriesIndex: point.seriesIndex, dataIndex: point.dataIndex });
|
|
75466
75580
|
this.announcement.set(point.text);
|
|
75467
75581
|
}
|
|
75582
|
+
/** Tema lido dos tokens no elemento; marca para reler se o gráfico ainda não está no documento. */
|
|
75583
|
+
#readTheme() {
|
|
75584
|
+
const host = this.#host.nativeElement;
|
|
75585
|
+
this.#themeStale = !host.isConnected;
|
|
75586
|
+
return readChartTheme(host, this.#forcedColors());
|
|
75587
|
+
}
|
|
75588
|
+
#applyTheme() {
|
|
75589
|
+
if (this.#chart)
|
|
75590
|
+
this.#chart.setTheme(this.#readTheme());
|
|
75591
|
+
}
|
|
75468
75592
|
#watchMedia(query, target) {
|
|
75469
75593
|
const list = media(query);
|
|
75470
75594
|
if (!list)
|
|
@@ -75488,7 +75612,7 @@ class HmChartComponent {
|
|
|
75488
75612
|
pending = true;
|
|
75489
75613
|
queueMicrotask(() => {
|
|
75490
75614
|
pending = false;
|
|
75491
|
-
this.#
|
|
75615
|
+
this.#applyTheme();
|
|
75492
75616
|
});
|
|
75493
75617
|
});
|
|
75494
75618
|
this.#scope.observe(host.ownerDocument.documentElement, {
|
|
@@ -75524,6 +75648,8 @@ class HmChartFrameComponent {
|
|
|
75524
75648
|
this.label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
75525
75649
|
this.description = input('', ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
75526
75650
|
this.height = input('', ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
|
|
75651
|
+
/** Mostra o botão "Ver como tabela". Desligado (minigráfico), a tabela fica só na árvore de acessibilidade. */
|
|
75652
|
+
this.tableToggle = input(true, ...(ngDevMode ? [{ debugName: "tableToggle" }] : /* istanbul ignore next */ []));
|
|
75527
75653
|
/** Mostra a tabela no lugar do gráfico. */
|
|
75528
75654
|
this.showTable = model(false, ...(ngDevMode ? [{ debugName: "showTable" }] : /* istanbul ignore next */ []));
|
|
75529
75655
|
this.m = inject(ChartsI18nService).messages;
|
|
@@ -75536,12 +75662,14 @@ class HmChartFrameComponent {
|
|
|
75536
75662
|
return this.view().table.align?.[index] ?? 'start';
|
|
75537
75663
|
}
|
|
75538
75664
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmChartFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
75539
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: HmChartFrameComponent, isStandalone: true, selector: "hm-chart-frame", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, showTable: { classPropertyName: "showTable", publicName: "showTable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { showTable: "showTableChange" }, host: { classAttribute: "hm-chart-frame" }, ngImport: i0, template: `
|
|
75665
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: HmChartFrameComponent, isStandalone: true, selector: "hm-chart-frame", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, tableToggle: { classPropertyName: "tableToggle", publicName: "tableToggle", isSignal: true, isRequired: false, transformFunction: null }, showTable: { classPropertyName: "showTable", publicName: "showTable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { showTable: "showTableChange" }, host: { classAttribute: "hm-chart-frame" }, ngImport: i0, template: `
|
|
75666
|
+
@if (tableToggle()) {
|
|
75540
75667
|
<div class="hm-chart-frame__bar">
|
|
75541
75668
|
<button type="button" class="hm-btn hm-btn--minimal hm-btn--small" (click)="showTable.set(!showTable())">
|
|
75542
75669
|
{{ showTable() ? m().frame.showChart : m().frame.showTable }}
|
|
75543
75670
|
</button>
|
|
75544
75671
|
</div>
|
|
75672
|
+
}
|
|
75545
75673
|
<hm-chart
|
|
75546
75674
|
[class.hm-chart-frame__off]="showTable()"
|
|
75547
75675
|
[option]="view().option"
|
|
@@ -75590,11 +75718,13 @@ class HmChartFrameComponent {
|
|
|
75590
75718
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmChartFrameComponent, decorators: [{
|
|
75591
75719
|
type: Component,
|
|
75592
75720
|
args: [{ selector: 'hm-chart-frame', standalone: true, imports: [HmChartComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
75721
|
+
@if (tableToggle()) {
|
|
75593
75722
|
<div class="hm-chart-frame__bar">
|
|
75594
75723
|
<button type="button" class="hm-btn hm-btn--minimal hm-btn--small" (click)="showTable.set(!showTable())">
|
|
75595
75724
|
{{ showTable() ? m().frame.showChart : m().frame.showTable }}
|
|
75596
75725
|
</button>
|
|
75597
75726
|
</div>
|
|
75727
|
+
}
|
|
75598
75728
|
<hm-chart
|
|
75599
75729
|
[class.hm-chart-frame__off]="showTable()"
|
|
75600
75730
|
[option]="view().option"
|
|
@@ -75639,7 +75769,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImpo
|
|
|
75639
75769
|
</table>
|
|
75640
75770
|
</div>
|
|
75641
75771
|
`, host: { class: 'hm-chart-frame' }, styles: [":host{display:flex;flex-direction:column;inline-size:100%;gap:var(--hm-space-xxxs);min-inline-size:0}.hm-chart-frame__bar{display:flex;justify-content:flex-end}.hm-chart-frame__off{display:none}.hm-chart-frame__table:not(.hm-visually-hidden){overflow:auto;max-block-size:calc(var(--hm-control-height) * 12)}.hm-chart-frame__table caption{text-align:start;color:var(--hm-muted);font-size:var(--hm-font-size-sm);padding-block-end:var(--hm-space-xxxs)}.hm-chart-frame__num{text-align:end;font-variant-numeric:tabular-nums}\n"] }]
|
|
75642
|
-
}], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], showTable: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTable", required: false }] }, { type: i0.Output, args: ["showTableChange"] }] } });
|
|
75772
|
+
}], propDecorators: { view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], tableToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableToggle", required: false }] }], showTable: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTable", required: false }] }, { type: i0.Output, args: ["showTableChange"] }] } });
|
|
75643
75773
|
|
|
75644
75774
|
/** Tabela categoria × série (barras, linhas). */
|
|
75645
75775
|
function categoryTable(ctx, categories, series) {
|
|
@@ -75702,7 +75832,7 @@ class HmBarChartComponent extends HmChartBase {
|
|
|
75702
75832
|
};
|
|
75703
75833
|
}
|
|
75704
75834
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmBarChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
75705
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmBarChartComponent, isStandalone: true, selector: "hm-bar-chart", inputs: { categories: { classPropertyName: "categories", publicName: "categories", isSignal: true, isRequired: true, transformFunction: null }, series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, stacked: { classPropertyName: "stacked", publicName: "stacked", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75835
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmBarChartComponent, isStandalone: true, selector: "hm-bar-chart", inputs: { categories: { classPropertyName: "categories", publicName: "categories", isSignal: true, isRequired: true, transformFunction: null }, series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, stacked: { classPropertyName: "stacked", publicName: "stacked", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75706
75836
|
}
|
|
75707
75837
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmBarChartComponent, decorators: [{
|
|
75708
75838
|
type: Component,
|
|
@@ -75750,7 +75880,7 @@ class HmLineChartComponent extends HmChartBase {
|
|
|
75750
75880
|
};
|
|
75751
75881
|
}
|
|
75752
75882
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmLineChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
75753
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmLineChartComponent, isStandalone: true, selector: "hm-line-chart", inputs: { categories: { classPropertyName: "categories", publicName: "categories", isSignal: true, isRequired: true, transformFunction: null }, series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null }, area: { classPropertyName: "area", publicName: "area", isSignal: true, isRequired: false, transformFunction: null }, stacked: { classPropertyName: "stacked", publicName: "stacked", isSignal: true, isRequired: false, transformFunction: null }, smooth: { classPropertyName: "smooth", publicName: "smooth", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75883
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmLineChartComponent, isStandalone: true, selector: "hm-line-chart", inputs: { categories: { classPropertyName: "categories", publicName: "categories", isSignal: true, isRequired: true, transformFunction: null }, series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null }, area: { classPropertyName: "area", publicName: "area", isSignal: true, isRequired: false, transformFunction: null }, stacked: { classPropertyName: "stacked", publicName: "stacked", isSignal: true, isRequired: false, transformFunction: null }, smooth: { classPropertyName: "smooth", publicName: "smooth", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75754
75884
|
}
|
|
75755
75885
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmLineChartComponent, decorators: [{
|
|
75756
75886
|
type: Component,
|
|
@@ -75797,7 +75927,7 @@ class HmPieChartComponent extends HmChartBase {
|
|
|
75797
75927
|
};
|
|
75798
75928
|
}
|
|
75799
75929
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmPieChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
75800
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmPieChartComponent, isStandalone: true, selector: "hm-pie-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, donut: { classPropertyName: "donut", publicName: "donut", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75930
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmPieChartComponent, isStandalone: true, selector: "hm-pie-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, donut: { classPropertyName: "donut", publicName: "donut", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75801
75931
|
}
|
|
75802
75932
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmPieChartComponent, decorators: [{
|
|
75803
75933
|
type: Component,
|
|
@@ -75868,7 +75998,7 @@ class HmHeatmapChartComponent extends HmChartBase {
|
|
|
75868
75998
|
};
|
|
75869
75999
|
}
|
|
75870
76000
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmHeatmapChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
75871
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmHeatmapChartComponent, isStandalone: true, selector: "hm-heatmap-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, xCategories: { classPropertyName: "xCategories", publicName: "xCategories", isSignal: true, isRequired: false, transformFunction: null }, yCategories: { classPropertyName: "yCategories", publicName: "yCategories", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76001
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmHeatmapChartComponent, isStandalone: true, selector: "hm-heatmap-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, xCategories: { classPropertyName: "xCategories", publicName: "xCategories", isSignal: true, isRequired: false, transformFunction: null }, yCategories: { classPropertyName: "yCategories", publicName: "yCategories", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75872
76002
|
}
|
|
75873
76003
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmHeatmapChartComponent, decorators: [{
|
|
75874
76004
|
type: Component,
|
|
@@ -75953,7 +76083,7 @@ class HmCalendarHeatmapComponent extends HmChartBase {
|
|
|
75953
76083
|
};
|
|
75954
76084
|
}
|
|
75955
76085
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmCalendarHeatmapComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
75956
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmCalendarHeatmapComponent, isStandalone: true, selector: "hm-calendar-heatmap", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", isSignal: true, isRequired: false, transformFunction: null }, dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76086
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmCalendarHeatmapComponent, isStandalone: true, selector: "hm-calendar-heatmap", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", isSignal: true, isRequired: false, transformFunction: null }, dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75957
76087
|
}
|
|
75958
76088
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmCalendarHeatmapComponent, decorators: [{
|
|
75959
76089
|
type: Component,
|
|
@@ -75973,7 +76103,13 @@ function weekStart(locale) {
|
|
|
75973
76103
|
return /^(pt|en-US|es-MX)/.test(locale) ? 0 : 1;
|
|
75974
76104
|
}
|
|
75975
76105
|
|
|
75976
|
-
/**
|
|
76106
|
+
/** Diâmetro (px) do menor e do maior ponto no gráfico de bolhas. */
|
|
76107
|
+
const BUBBLE_MIN = 8;
|
|
76108
|
+
const BUBBLE_MAX = 44;
|
|
76109
|
+
/**
|
|
76110
|
+
* Relação entre duas medidas (preço × volume, prazo × satisfação), uma ou várias séries. Com `size`
|
|
76111
|
+
* nos pontos, vira gráfico de bolhas (a área de cada bolha mostra uma terceira medida).
|
|
76112
|
+
*/
|
|
75977
76113
|
class HmScatterChartComponent extends HmChartBase {
|
|
75978
76114
|
constructor() {
|
|
75979
76115
|
super(...arguments);
|
|
@@ -75982,16 +76118,26 @@ class HmScatterChartComponent extends HmChartBase {
|
|
|
75982
76118
|
this.xLabel = input('', ...(ngDevMode ? [{ debugName: "xLabel" }] : /* istanbul ignore next */ []));
|
|
75983
76119
|
/** Nome do eixo vertical (texto do app). */
|
|
75984
76120
|
this.yLabel = input('', ...(ngDevMode ? [{ debugName: "yLabel" }] : /* istanbul ignore next */ []));
|
|
76121
|
+
/** Nome da medida do tamanho das bolhas (texto do app); padrão "Tamanho". */
|
|
76122
|
+
this.sizeLabel = input('', ...(ngDevMode ? [{ debugName: "sizeLabel" }] : /* istanbul ignore next */ []));
|
|
75985
76123
|
}
|
|
75986
76124
|
build(ctx) {
|
|
75987
76125
|
const series = this.series();
|
|
75988
76126
|
const xName = this.xLabel() || ctx.m.columns.x;
|
|
75989
76127
|
const yName = this.yLabel() || ctx.m.columns.y;
|
|
75990
76128
|
const hasLegend = series.length > 1;
|
|
75991
|
-
const
|
|
76129
|
+
const sizeName = this.sizeLabel() || ctx.m.columns.size;
|
|
76130
|
+
const sizes = series.flatMap((s) => s.data.map((p) => p.size)).filter((v) => v != null && Number.isFinite(v) && v >= 0);
|
|
76131
|
+
const bubble = sizes.length > 0;
|
|
76132
|
+
const biggest = Math.max(0, ...sizes);
|
|
76133
|
+
// Área proporcional ao valor: o diâmetro cresce com a raiz quadrada, entre o ponto comum e uma bolha grande.
|
|
76134
|
+
const radius = (v) => v == null || !Number.isFinite(v) || v < 0 || biggest === 0 ? BUBBLE_MIN : BUBBLE_MIN + (BUBBLE_MAX - BUBBLE_MIN) * Math.sqrt(v / biggest);
|
|
76135
|
+
const describe = (s, p) => `${p.name ?? s.name}: ${xName} ${ctx.num(p.x)}, ${yName} ${ctx.num(p.y)}` + (bubble ? `, ${sizeName} ${ctx.num(p.size)}` : '');
|
|
75992
76136
|
return {
|
|
75993
76137
|
option: {
|
|
75994
|
-
|
|
76138
|
+
// Bolhas: folga no fim dos eixos para a bolha da ponta não ser cortada. Com nome no eixo X (o `containLabel` não
|
|
76139
|
+
// conta o nome), espaço entre ele e a legenda.
|
|
76140
|
+
grid: { ...gridOption(hasLegend && ctx.legend), top: 36, ...(bubble || this.xLabel() ? { bottom: hasLegend && ctx.legend ? 58 : 30 } : {}) },
|
|
75995
76141
|
tooltip: {
|
|
75996
76142
|
...tooltipOption(ctx, 'item'),
|
|
75997
76143
|
formatter: (p) => {
|
|
@@ -76001,71 +76147,348 @@ class HmScatterChartComponent extends HmChartBase {
|
|
|
76001
76147
|
},
|
|
76002
76148
|
},
|
|
76003
76149
|
legend: legendOption(ctx, hasLegend),
|
|
76004
|
-
xAxis: { type: 'value', name: this.xLabel(), nameLocation: 'middle', nameGap: 30, scale: true, axisLabel: { formatter: (v) => ctx.num(v) } },
|
|
76005
|
-
yAxis: { type: 'value', name: this.yLabel(), scale: true, axisLabel: { formatter: (v) => ctx.num(v) } },
|
|
76150
|
+
xAxis: { type: 'value', name: this.xLabel(), nameLocation: 'middle', nameGap: 30, scale: true, axisLabel: { formatter: (v) => ctx.num(v) }, ...(bubble ? { boundaryGap: ['8%', '8%'] } : {}) },
|
|
76151
|
+
yAxis: { type: 'value', name: this.yLabel(), scale: true, axisLabel: { formatter: (v) => ctx.num(v) }, ...(bubble ? { boundaryGap: ['12%', '12%'] } : {}) },
|
|
76006
76152
|
series: series.map((s) => ({
|
|
76007
76153
|
type: 'scatter',
|
|
76008
76154
|
name: s.name,
|
|
76009
|
-
symbolSize: 9,
|
|
76155
|
+
symbolSize: bubble ? (_, params) => radius(s.data[params.dataIndex]?.size) : 9,
|
|
76010
76156
|
data: s.data.map((p) => [p.x, p.y]),
|
|
76157
|
+
...(bubble ? { itemStyle: { opacity: 0.72 } } : {}),
|
|
76011
76158
|
emphasis: { focus: 'series' },
|
|
76012
76159
|
})),
|
|
76013
76160
|
},
|
|
76014
|
-
summary: seriesSummary(ctx, 'scatter', series.length, series.reduce((n, s) => n + s.data.length, 0), series.flatMap((s) => s.data.map((p) => p.y))),
|
|
76161
|
+
summary: seriesSummary(ctx, bubble ? 'bubble' : 'scatter', series.length, series.reduce((n, s) => n + s.data.length, 0), series.flatMap((s) => s.data.map((p) => p.y))),
|
|
76015
76162
|
table: {
|
|
76016
|
-
columns: [ctx.m.columns.series, xName, yName],
|
|
76017
|
-
align: ['start', 'end', 'end'],
|
|
76163
|
+
columns: bubble ? [ctx.m.columns.series, xName, yName, sizeName] : [ctx.m.columns.series, xName, yName],
|
|
76164
|
+
align: bubble ? ['start', 'end', 'end', 'end'] : ['start', 'end', 'end'],
|
|
76018
76165
|
rows: series.flatMap((s) => s.data.map((p) => ({
|
|
76019
76166
|
header: p.name ? `${s.name} · ${p.name}` : s.name,
|
|
76020
|
-
cells: [ctx.num(p.x), ctx.num(p.y)],
|
|
76167
|
+
cells: bubble ? [ctx.num(p.x), ctx.num(p.y), ctx.num(p.size)] : [ctx.num(p.x), ctx.num(p.y)],
|
|
76021
76168
|
}))),
|
|
76022
76169
|
},
|
|
76023
76170
|
points: series.flatMap((s, si) => s.data.map((p, di) => ({ seriesIndex: si, dataIndex: di, text: describe(s, p) }))),
|
|
76024
76171
|
};
|
|
76025
76172
|
}
|
|
76026
76173
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmScatterChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
76027
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmScatterChartComponent, isStandalone: true, selector: "hm-scatter-chart", inputs: { series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null }, xLabel: { classPropertyName: "xLabel", publicName: "xLabel", isSignal: true, isRequired: false, transformFunction: null }, yLabel: { classPropertyName: "yLabel", publicName: "yLabel", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76174
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmScatterChartComponent, isStandalone: true, selector: "hm-scatter-chart", inputs: { series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null }, xLabel: { classPropertyName: "xLabel", publicName: "xLabel", isSignal: true, isRequired: false, transformFunction: null }, yLabel: { classPropertyName: "yLabel", publicName: "yLabel", isSignal: true, isRequired: false, transformFunction: null }, sizeLabel: { classPropertyName: "sizeLabel", publicName: "sizeLabel", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76028
76175
|
}
|
|
76029
76176
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmScatterChartComponent, decorators: [{
|
|
76030
76177
|
type: Component,
|
|
76031
76178
|
args: [{ selector: 'hm-scatter-chart', standalone: true, imports: [HmChartFrameComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: CHART_TEMPLATE, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"] }]
|
|
76032
|
-
}], propDecorators: { series: [{ type: i0.Input, args: [{ isSignal: true, alias: "series", required: true }] }], xLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "xLabel", required: false }] }], yLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "yLabel", required: false }] }] } });
|
|
76179
|
+
}], propDecorators: { series: [{ type: i0.Input, args: [{ isSignal: true, alias: "series", required: true }] }], xLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "xLabel", required: false }] }], yLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "yLabel", required: false }] }], sizeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizeLabel", required: false }] }] } });
|
|
76033
76180
|
|
|
76034
|
-
|
|
76181
|
+
// Geometria do medidor: raio, centro e posição de cada rótulo da escala, calculados a partir do
|
|
76182
|
+
// tamanho real do gráfico e do tamanho das fontes (lidos dos tokens no elemento). Sem framework e
|
|
76183
|
+
// sem DOM: só números, para ser testável e portável.
|
|
76184
|
+
/** Ângulos do arco no sistema do motor (graus, anti-horário a partir das 3 horas): 240° com a abertura embaixo. */
|
|
76185
|
+
const GAUGE_START_ANGLE = 210;
|
|
76186
|
+
const GAUGE_END_ANGLE = -30;
|
|
76187
|
+
const SWEEP = GAUGE_START_ANGLE - GAUGE_END_ANGLE;
|
|
76188
|
+
/** Largura aproximada de um texto (média de glifos de uma fonte sem serifa com algarismos tabulares). */
|
|
76189
|
+
function textWidth(text, font) {
|
|
76190
|
+
return text.length * font * 0.6;
|
|
76191
|
+
}
|
|
76192
|
+
/** Ângulo (graus do motor) da marca `i` de `n`. */
|
|
76193
|
+
function tickAngle(i, n) {
|
|
76194
|
+
return GAUGE_START_ANGLE - (SWEEP * i) / n;
|
|
76195
|
+
}
|
|
76196
|
+
/** Mede tudo para um raio `r` com o centro em (0,0): devolve as posições e a caixa ocupada. */
|
|
76197
|
+
function measure(r, input) {
|
|
76198
|
+
const { box, labels } = input;
|
|
76199
|
+
const labelFont = box.smallFont;
|
|
76200
|
+
const captionFont = box.smallFont;
|
|
76201
|
+
const arcWidth = Math.max(6, r * 0.1);
|
|
76202
|
+
const tickGap = input.ticks ? Math.max(2, r * 0.045) : 0;
|
|
76203
|
+
const majorLength = input.ticks ? Math.max(4, r * 0.08) : 0;
|
|
76204
|
+
const minorLength = majorLength * 0.55;
|
|
76205
|
+
const labelGap = labelFont * 0.45;
|
|
76206
|
+
const labelRadius = r + tickGap + majorLength + labelGap;
|
|
76207
|
+
const labelHeight = labelFont * 1.2;
|
|
76208
|
+
const extent = { minX: -r, maxX: r, minY: -r, maxY: r * Math.sin((30 * Math.PI) / 180) + arcWidth / 2 };
|
|
76209
|
+
const grow = (x0, x1, y0, y1) => {
|
|
76210
|
+
extent.minX = Math.min(extent.minX, x0);
|
|
76211
|
+
extent.maxX = Math.max(extent.maxX, x1);
|
|
76212
|
+
extent.minY = Math.min(extent.minY, y0);
|
|
76213
|
+
extent.maxY = Math.max(extent.maxY, y1);
|
|
76214
|
+
};
|
|
76215
|
+
const n = Math.max(1, labels.length - 1);
|
|
76216
|
+
const placed = [];
|
|
76217
|
+
labels.forEach((text, i) => {
|
|
76218
|
+
if (text == null || text === '')
|
|
76219
|
+
return;
|
|
76220
|
+
const a = (tickAngle(i, n) * Math.PI) / 180;
|
|
76221
|
+
const ux = Math.cos(a);
|
|
76222
|
+
const uy = -Math.sin(a);
|
|
76223
|
+
const w = textWidth(text, labelFont);
|
|
76224
|
+
// Centro do rótulo afastado do arco pela metade da caixa na direção do raio: o texto fica
|
|
76225
|
+
// sempre do lado de fora, sem encostar nas marcas, em qualquer ângulo.
|
|
76226
|
+
const reach = labelRadius + Math.abs(ux) * (w / 2) + Math.abs(uy) * (labelHeight / 2);
|
|
76227
|
+
const dx = ux * reach;
|
|
76228
|
+
const dy = uy * reach;
|
|
76229
|
+
placed.push({ text, dx, dy });
|
|
76230
|
+
grow(dx - w / 2, dx + w / 2, dy - labelHeight / 2, dy + labelHeight / 2);
|
|
76231
|
+
});
|
|
76232
|
+
const hubSize = input.needle ? Math.max(8, r * 0.13) : 0;
|
|
76233
|
+
const valueFont = Math.min(box.baseFont * 3, Math.max(box.baseFont * 1.35, r * (input.needle ? 0.26 : 0.32)));
|
|
76234
|
+
const valueOffset = input.needle ? Math.max(r * 0.34, hubSize / 2 + valueFont * 0.75) : input.hasCaption ? -valueFont * 0.1 : 0;
|
|
76235
|
+
const captionOffset = valueOffset + valueFont * 0.62 + captionFont * 0.95;
|
|
76236
|
+
const valueW = textWidth(input.valueText, valueFont);
|
|
76237
|
+
grow(-valueW / 2, valueW / 2, valueOffset - valueFont * 0.6, valueOffset + valueFont * 0.6);
|
|
76238
|
+
if (input.hasCaption)
|
|
76239
|
+
grow(-r * 0.8, r * 0.8, captionOffset - captionFont * 0.7, captionOffset + captionFont * 0.7);
|
|
76240
|
+
return {
|
|
76241
|
+
layout: {
|
|
76242
|
+
radius: r,
|
|
76243
|
+
arcWidth,
|
|
76244
|
+
tickGap,
|
|
76245
|
+
majorLength,
|
|
76246
|
+
minorLength,
|
|
76247
|
+
labelFont,
|
|
76248
|
+
valueFont,
|
|
76249
|
+
captionFont,
|
|
76250
|
+
valueOffset,
|
|
76251
|
+
captionOffset,
|
|
76252
|
+
needleLength: r - arcWidth * 0.55,
|
|
76253
|
+
needleWidth: Math.max(3, r * 0.045),
|
|
76254
|
+
hubSize,
|
|
76255
|
+
labels: placed,
|
|
76256
|
+
},
|
|
76257
|
+
extent,
|
|
76258
|
+
};
|
|
76259
|
+
}
|
|
76260
|
+
/**
|
|
76261
|
+
* Maior raio em que arco, escala, valor e legenda cabem na caixa, com o conjunto centralizado.
|
|
76262
|
+
* Caixa sem tamanho (ainda não medida, testes em jsdom): `null`, e o componente usa porcentagens.
|
|
76263
|
+
*/
|
|
76264
|
+
function gaugeLayout(input) {
|
|
76265
|
+
const { width, height } = input.box;
|
|
76266
|
+
if (!(width > 0 && height > 0))
|
|
76267
|
+
return null;
|
|
76268
|
+
const pad = Math.max(2, input.box.smallFont * 0.25);
|
|
76269
|
+
const availW = width - pad * 2;
|
|
76270
|
+
const availH = height - pad * 2;
|
|
76271
|
+
const fits = (r) => {
|
|
76272
|
+
const { extent } = measure(r, input);
|
|
76273
|
+
return extent.maxX - extent.minX <= availW && extent.maxY - extent.minY <= availH;
|
|
76274
|
+
};
|
|
76275
|
+
let lo = 4;
|
|
76276
|
+
let hi = Math.max(lo, Math.min(availW, availH));
|
|
76277
|
+
if (!fits(lo))
|
|
76278
|
+
hi = lo;
|
|
76279
|
+
for (let i = 0; i < 24 && hi - lo > 0.25; i++) {
|
|
76280
|
+
const mid = (lo + hi) / 2;
|
|
76281
|
+
if (fits(mid))
|
|
76282
|
+
lo = mid;
|
|
76283
|
+
else
|
|
76284
|
+
hi = mid;
|
|
76285
|
+
}
|
|
76286
|
+
const { layout, extent } = measure(lo, input);
|
|
76287
|
+
const cx = pad + (availW - (extent.maxX - extent.minX)) / 2 - extent.minX;
|
|
76288
|
+
const cy = pad + (availH - (extent.maxY - extent.minY)) / 2 - extent.minY;
|
|
76289
|
+
return { ...layout, cx, cy };
|
|
76290
|
+
}
|
|
76291
|
+
/**
|
|
76292
|
+
* Quantas marcas maiores e de quantas em quantas há rótulo, sem rótulos se atropelando. `step` é o
|
|
76293
|
+
* intervalo pedido (na unidade do valor); inválido ou com marcas demais, a escala cai em 10 partes.
|
|
76294
|
+
*/
|
|
76295
|
+
function gaugeScale(min, max, step) {
|
|
76296
|
+
const span = max - min;
|
|
76297
|
+
if (step && step > 0 && span > 0) {
|
|
76298
|
+
const splits = span / step;
|
|
76299
|
+
if (Math.abs(splits - Math.round(splits)) < 1e-6 && Math.round(splits) >= 1 && Math.round(splits) <= 24) {
|
|
76300
|
+
return { splits: Math.round(splits) };
|
|
76301
|
+
}
|
|
76302
|
+
}
|
|
76303
|
+
return { splits: 10 };
|
|
76304
|
+
}
|
|
76305
|
+
/**
|
|
76306
|
+
* Menor passo de rótulo (divisor de `splits`, para a última marca sempre ter rótulo) em que os
|
|
76307
|
+
* rótulos não se encostam ao longo do arco de raio `radius`.
|
|
76308
|
+
*/
|
|
76309
|
+
function labelEvery(splits, radius, labelWidth, font) {
|
|
76310
|
+
const spacing = ((SWEEP * Math.PI) / 180 / splits) * radius;
|
|
76311
|
+
const need = labelWidth + font * 0.8;
|
|
76312
|
+
for (let k = 1; k <= splits; k++) {
|
|
76313
|
+
if (splits % k !== 0)
|
|
76314
|
+
continue;
|
|
76315
|
+
if (spacing * k >= need)
|
|
76316
|
+
return k;
|
|
76317
|
+
}
|
|
76318
|
+
return splits;
|
|
76319
|
+
}
|
|
76320
|
+
|
|
76321
|
+
/** Duração do preenchimento animado (ms): a mesma para o arco, a agulha e o número. */
|
|
76322
|
+
const DURATION = 900;
|
|
76323
|
+
/** Agulha fina com as pontas arredondadas (caminho na grade do motor, esticado até o comprimento pedido). */
|
|
76324
|
+
const NEEDLE_PATH = 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z';
|
|
76325
|
+
/** Lê o tamanho de fonte de um token (`--hm-font-size-*`) em px, resolvido no elemento. */
|
|
76326
|
+
function tokenFont(host, token, fallback) {
|
|
76327
|
+
const probe = host.ownerDocument.createElement('span');
|
|
76328
|
+
probe.setAttribute('aria-hidden', 'true');
|
|
76329
|
+
probe.style.cssText = `position:absolute;visibility:hidden;font-size:var(${token})`;
|
|
76330
|
+
host.appendChild(probe);
|
|
76331
|
+
try {
|
|
76332
|
+
const px = parseFloat(getComputedStyle(probe).fontSize);
|
|
76333
|
+
return Number.isFinite(px) && px > 0 ? px : fallback;
|
|
76334
|
+
}
|
|
76335
|
+
finally {
|
|
76336
|
+
probe.remove();
|
|
76337
|
+
}
|
|
76338
|
+
}
|
|
76339
|
+
/**
|
|
76340
|
+
* Um valor numa escala (meta atingida, ocupação, SLA). Para vários indicadores, vários medidores.
|
|
76341
|
+
* Arco de 240° com a escala por fora, agulha e valor no centro; ao aparecer e a cada troca de valor,
|
|
76342
|
+
* o arco preenche animado do valor anterior até o novo, com a agulha e o número acompanhando.
|
|
76343
|
+
*/
|
|
76035
76344
|
class HmGaugeChartComponent extends HmChartBase {
|
|
76345
|
+
/**
|
|
76346
|
+
* Tamanho medido do gráfico e das fontes (px). `undefined` até a primeira medição: até lá o motor
|
|
76347
|
+
* recebe só a moldura vazia, para a animação de entrada começar uma vez só, já na geometria final
|
|
76348
|
+
* (um primeiro desenho provisório recriaria a agulha no meio do caminho, fora de compasso com o número).
|
|
76349
|
+
*/
|
|
76350
|
+
#box;
|
|
76351
|
+
/**
|
|
76352
|
+
* Valor desenhado agora (arco, agulha e número). A animação é do próprio componente, quadro a quadro,
|
|
76353
|
+
* com o motor sem animação: assim os três saem sempre do mesmo número, mesmo que o motor redesenhe no
|
|
76354
|
+
* meio do caminho (troca de tema, de tamanho), o que faria a agulha recomeçar e o número não.
|
|
76355
|
+
*/
|
|
76356
|
+
#shown;
|
|
76357
|
+
#target;
|
|
76358
|
+
#frame;
|
|
76036
76359
|
constructor() {
|
|
76037
|
-
super(
|
|
76360
|
+
super();
|
|
76038
76361
|
this.value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
76039
76362
|
this.min = input(0, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
|
|
76040
76363
|
this.max = input(100, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
76364
|
+
/**
|
|
76365
|
+
* Preenche o arco animado ao aparecer e a cada troca de valor (do valor anterior até o novo).
|
|
76366
|
+
* Com `prefers-reduced-motion`, nunca anima. O resumo e a tabela já trazem o valor final.
|
|
76367
|
+
*/
|
|
76368
|
+
this.animated = input(true, ...(ngDevMode ? [{ debugName: "animated" }] : /* istanbul ignore next */ []));
|
|
76369
|
+
/** Agulha que gira junto com a ponta do arco. Sem ela, o valor vai para o centro do arco. */
|
|
76370
|
+
this.needle = input(true, ...(ngDevMode ? [{ debugName: "needle" }] : /* istanbul ignore next */ []));
|
|
76371
|
+
/** Marcas da escala por fora do arco, com rótulos. Desligado, só o mínimo e o máximo aparecem. */
|
|
76372
|
+
this.ticks = input(true, ...(ngDevMode ? [{ debugName: "ticks" }] : /* istanbul ignore next */ []));
|
|
76373
|
+
/** Intervalo entre as marcas, na unidade do valor; padrão (ou intervalo que não divide a escala): um décimo. */
|
|
76374
|
+
this.tickStep = input(null, ...(ngDevMode ? [{ debugName: "tickStep" }] : /* istanbul ignore next */ []));
|
|
76375
|
+
/** Legenda curta abaixo do valor (ex.: "das PAs conectadas"); entra também no resumo acessível. */
|
|
76376
|
+
this.caption = input('', ...(ngDevMode ? [{ debugName: "caption" }] : /* istanbul ignore next */ []));
|
|
76377
|
+
/** Formato do valor no centro, quando difere do `numberFormat` (que vale para a escala e a tabela). */
|
|
76378
|
+
this.valueFormat = input(null, ...(ngDevMode ? [{ debugName: "valueFormat" }] : /* istanbul ignore next */ []));
|
|
76379
|
+
/**
|
|
76380
|
+
* Tamanho medido do gráfico e das fontes (px). `undefined` até a primeira medição: até lá o motor
|
|
76381
|
+
* recebe só a moldura vazia, para a animação de entrada começar uma vez só, já na geometria final
|
|
76382
|
+
* (um primeiro desenho provisório recriaria a agulha no meio do caminho, fora de compasso com o número).
|
|
76383
|
+
*/
|
|
76384
|
+
this.#box = signal(undefined, { ...(ngDevMode ? { debugName: "#box" } : /* istanbul ignore next */ {}), equal: sameBox });
|
|
76385
|
+
/**
|
|
76386
|
+
* Valor desenhado agora (arco, agulha e número). A animação é do próprio componente, quadro a quadro,
|
|
76387
|
+
* com o motor sem animação: assim os três saem sempre do mesmo número, mesmo que o motor redesenhe no
|
|
76388
|
+
* meio do caminho (troca de tema, de tamanho), o que faria a agulha recomeçar e o número não.
|
|
76389
|
+
*/
|
|
76390
|
+
this.#shown = signal(undefined, ...(ngDevMode ? [{ debugName: "#shown" }] : /* istanbul ignore next */ []));
|
|
76391
|
+
this.#frame = 0;
|
|
76392
|
+
const host = inject(ElementRef).nativeElement;
|
|
76393
|
+
let observer = null;
|
|
76394
|
+
afterNextRender(() => {
|
|
76395
|
+
const target = host.querySelector('.hm-chart');
|
|
76396
|
+
if (!target) {
|
|
76397
|
+
this.#box.set({ width: 0, height: 0, smallFont: 12, baseFont: 14 });
|
|
76398
|
+
return;
|
|
76399
|
+
}
|
|
76400
|
+
const measure = () => {
|
|
76401
|
+
this.#box.set({
|
|
76402
|
+
width: Math.round(target.clientWidth),
|
|
76403
|
+
height: Math.round(target.clientHeight),
|
|
76404
|
+
smallFont: tokenFont(target, '--hm-font-size-sm', 12),
|
|
76405
|
+
baseFont: tokenFont(target, '--hm-font-size-md', 14),
|
|
76406
|
+
});
|
|
76407
|
+
};
|
|
76408
|
+
measure();
|
|
76409
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
76410
|
+
observer = new ResizeObserver(measure);
|
|
76411
|
+
observer.observe(target);
|
|
76412
|
+
}
|
|
76413
|
+
});
|
|
76414
|
+
inject(DestroyRef).onDestroy(() => {
|
|
76415
|
+
observer?.disconnect();
|
|
76416
|
+
this.#stop();
|
|
76417
|
+
});
|
|
76418
|
+
effect(() => {
|
|
76419
|
+
const value = this.value();
|
|
76420
|
+
const min = this.min();
|
|
76421
|
+
const animated = this.animated();
|
|
76422
|
+
const box = this.#box();
|
|
76423
|
+
untracked(() => this.#animateTo(value, min, animated, box));
|
|
76424
|
+
});
|
|
76425
|
+
}
|
|
76426
|
+
/** Leva o valor desenhado até `value`: animado do valor atual (ou do mínimo, na entrada), ou direto. */
|
|
76427
|
+
#animateTo(value, min, animated, box) {
|
|
76428
|
+
if (box === undefined)
|
|
76429
|
+
return; // ainda sem desenho: a entrada começa quando houver medida
|
|
76430
|
+
if (this.#target === value)
|
|
76431
|
+
return; // mesmo alvo (só mudou o tamanho): segue o que já estava
|
|
76432
|
+
this.#target = value;
|
|
76433
|
+
this.#stop();
|
|
76434
|
+
const reduced = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
76435
|
+
if (!animated || reduced || !(box.width > 0) || typeof requestAnimationFrame !== 'function' || !Number.isFinite(value)) {
|
|
76436
|
+
this.#shown.set(value);
|
|
76437
|
+
return;
|
|
76438
|
+
}
|
|
76439
|
+
const from = this.#shown() ?? min;
|
|
76440
|
+
const start = performance.now();
|
|
76441
|
+
const step = (now) => {
|
|
76442
|
+
const t = Math.min(1, (now - start) / DURATION);
|
|
76443
|
+
const eased = 1 - (1 - t) ** 3; // cubicOut: arranca rápido e assenta devagar
|
|
76444
|
+
this.#shown.set(t >= 1 ? value : from + (value - from) * eased);
|
|
76445
|
+
this.#frame = t < 1 ? requestAnimationFrame(step) : 0;
|
|
76446
|
+
};
|
|
76447
|
+
this.#shown.set(from);
|
|
76448
|
+
this.#frame = requestAnimationFrame(step);
|
|
76449
|
+
}
|
|
76450
|
+
#stop() {
|
|
76451
|
+
if (this.#frame && typeof cancelAnimationFrame === 'function')
|
|
76452
|
+
cancelAnimationFrame(this.#frame);
|
|
76453
|
+
this.#frame = 0;
|
|
76041
76454
|
}
|
|
76042
76455
|
build(ctx) {
|
|
76043
76456
|
const value = this.value();
|
|
76044
76457
|
const min = this.min();
|
|
76045
76458
|
const max = this.max();
|
|
76459
|
+
const caption = this.caption();
|
|
76460
|
+
const needle = this.needle();
|
|
76461
|
+
const ticks = this.ticks();
|
|
76462
|
+
const valueNum = this.valueFormat() ? numberFormatter(ctx.locale, this.valueFormat()) : ctx.num;
|
|
76463
|
+
const { splits } = ticks ? gaugeScale(min, max, this.tickStep()) : { splits: 1 };
|
|
76464
|
+
const tickValue = (i) => min + ((max - min) * i) / splits;
|
|
76465
|
+
const allLabels = Array.from({ length: splits + 1 }, (_, i) => ctx.num(tickValue(i)));
|
|
76466
|
+
// Reserva a largura do valor mais longo da escala (o número conta de min até max na animação).
|
|
76467
|
+
const valueText = [valueNum(min), valueNum(max), valueNum(value)].reduce((a, b) => (b.length > a.length ? b : a));
|
|
76468
|
+
const box = this.#box();
|
|
76469
|
+
const measured = box !== undefined;
|
|
76470
|
+
const layoutFor = (labels) => box ? gaugeLayout({ box, labels, valueText, hasCaption: !!caption, needle, ticks }) : null;
|
|
76471
|
+
let labels = allLabels;
|
|
76472
|
+
let layout = layoutFor(labels);
|
|
76473
|
+
if (layout && splits > 1) {
|
|
76474
|
+
const widest = Math.max(...allLabels.map((l) => l.length)) * layout.labelFont * 0.6;
|
|
76475
|
+
const every = labelEvery(splits, layout.radius + layout.tickGap + layout.majorLength, widest, layout.labelFont);
|
|
76476
|
+
if (every > 1) {
|
|
76477
|
+
labels = allLabels.map((l, i) => (i % every === 0 ? l : null));
|
|
76478
|
+
layout = layoutFor(labels);
|
|
76479
|
+
}
|
|
76480
|
+
}
|
|
76046
76481
|
return {
|
|
76047
76482
|
option: {
|
|
76048
76483
|
tooltip: { show: false },
|
|
76049
|
-
series: [
|
|
76050
|
-
|
|
76051
|
-
|
|
76052
|
-
|
|
76053
|
-
startAngle: 220,
|
|
76054
|
-
endAngle: -40,
|
|
76055
|
-
radius: '94%',
|
|
76056
|
-
progress: { show: true, width: 12, roundCap: true },
|
|
76057
|
-
axisLine: { roundCap: true, lineStyle: { width: 12 } },
|
|
76058
|
-
pointer: { show: false },
|
|
76059
|
-
axisTick: { show: false },
|
|
76060
|
-
splitLine: { show: false },
|
|
76061
|
-
axisLabel: { distance: 18, formatter: (v) => (v === min || v === max ? ctx.num(v) : '') },
|
|
76062
|
-
anchor: { show: false },
|
|
76063
|
-
title: { show: false },
|
|
76064
|
-
detail: { valueAnimation: true, offsetCenter: [0, '0%'], fontSize: 30, formatter: (v) => ctx.num(v) },
|
|
76065
|
-
data: [{ value, name: this.label() }],
|
|
76066
|
-
}],
|
|
76484
|
+
series: !measured ? [] : [
|
|
76485
|
+
this.#mainSeries(ctx, { value: this.#shown() ?? value, min, max, caption, needle, ticks, splits, layout, valueNum }),
|
|
76486
|
+
...(labels.some((l) => l) ? [this.#labelSeries(labels, layout, min, max)] : []),
|
|
76487
|
+
],
|
|
76067
76488
|
},
|
|
76068
|
-
summary:
|
|
76489
|
+
summary: caption
|
|
76490
|
+
? ctx.i18n.format(ctx.m.summary.gaugeCaption, { type: ctx.m.types.gauge, value: valueNum(value), caption, min: ctx.num(min), max: ctx.num(max) })
|
|
76491
|
+
: ctx.i18n.format(ctx.m.summary.gauge, { type: ctx.m.types.gauge, value: valueNum(value), min: ctx.num(min), max: ctx.num(max) }),
|
|
76069
76492
|
table: {
|
|
76070
76493
|
columns: [ctx.m.columns.indicator, ctx.m.columns.value, ctx.m.columns.min, ctx.m.columns.max],
|
|
76071
76494
|
align: ['start', 'end', 'end', 'end'],
|
|
@@ -76074,13 +76497,102 @@ class HmGaugeChartComponent extends HmChartBase {
|
|
|
76074
76497
|
points: [],
|
|
76075
76498
|
};
|
|
76076
76499
|
}
|
|
76077
|
-
|
|
76078
|
-
|
|
76500
|
+
/** Arco, progresso, agulha, marcas, valor e legenda. */
|
|
76501
|
+
#mainSeries(ctx, o) {
|
|
76502
|
+
const l = o.layout;
|
|
76503
|
+
const arcWidth = l?.arcWidth ?? 12;
|
|
76504
|
+
const gap = l?.tickGap ?? 4;
|
|
76505
|
+
const major = l?.majorLength ?? 8;
|
|
76506
|
+
const minor = l?.minorLength ?? 4;
|
|
76507
|
+
// As marcas ficam por fora: distância negativa conta a partir da borda externa do arco.
|
|
76508
|
+
const showMinor = o.ticks && (l ? l.radius >= 72 : true);
|
|
76509
|
+
return {
|
|
76510
|
+
type: 'gauge',
|
|
76511
|
+
min: o.min,
|
|
76512
|
+
max: o.max,
|
|
76513
|
+
startAngle: GAUGE_START_ANGLE,
|
|
76514
|
+
endAngle: GAUGE_END_ANGLE,
|
|
76515
|
+
center: l ? [l.cx, l.cy] : ['50%', '58%'],
|
|
76516
|
+
radius: l ? l.radius : '62%',
|
|
76517
|
+
splitNumber: o.splits,
|
|
76518
|
+
silent: true,
|
|
76519
|
+
// A animação é do componente (ver `#shown`): o motor só desenha cada quadro.
|
|
76520
|
+
animation: false,
|
|
76521
|
+
progress: { show: true, width: arcWidth, roundCap: true },
|
|
76522
|
+
axisLine: { roundCap: true, lineStyle: { width: arcWidth } },
|
|
76523
|
+
splitLine: { show: o.ticks, length: major, distance: -(arcWidth + gap + major), lineStyle: { width: Math.max(1.5, arcWidth * 0.16), cap: 'round' } },
|
|
76524
|
+
axisTick: { show: showMinor, splitNumber: 2, length: minor, distance: -(arcWidth + gap + minor), lineStyle: { width: 1, cap: 'round' } },
|
|
76525
|
+
axisLabel: { show: false },
|
|
76526
|
+
pointer: o.needle
|
|
76527
|
+
? { show: true, icon: NEEDLE_PATH, length: l?.needleLength ?? '82%', width: l?.needleWidth ?? 4, keepAspect: false, showAbove: true }
|
|
76528
|
+
: { show: false },
|
|
76529
|
+
anchor: o.needle
|
|
76530
|
+
? { show: true, showAbove: true, size: l?.hubSize ?? 14, itemStyle: { borderWidth: Math.max(2, (l?.hubSize ?? 14) * 0.22) } }
|
|
76531
|
+
: { show: false },
|
|
76532
|
+
title: {
|
|
76533
|
+
show: !!o.caption,
|
|
76534
|
+
offsetCenter: [0, l ? l.captionOffset : o.needle ? '72%' : '30%'],
|
|
76535
|
+
fontSize: l?.captionFont ?? 12,
|
|
76536
|
+
},
|
|
76537
|
+
detail: {
|
|
76538
|
+
offsetCenter: [0, l ? l.valueOffset : o.needle ? '42%' : '0%'],
|
|
76539
|
+
fontSize: l?.valueFont ?? 28,
|
|
76540
|
+
fontWeight: 'bold',
|
|
76541
|
+
color: 'inherit',
|
|
76542
|
+
formatter: (v) => o.valueNum(v),
|
|
76543
|
+
},
|
|
76544
|
+
data: [{ value: o.value, name: o.caption }],
|
|
76545
|
+
};
|
|
76546
|
+
}
|
|
76547
|
+
/**
|
|
76548
|
+
* Rótulos da escala, cada um posicionado por fora do arco (o rótulo nativo do motor fica por
|
|
76549
|
+
* dentro e alinhado para dentro). Série só de textos, sem arco nem agulha.
|
|
76550
|
+
*/
|
|
76551
|
+
#labelSeries(labels, l, min, max) {
|
|
76552
|
+
const n = Math.max(1, labels.length - 1);
|
|
76553
|
+
const placed = l?.labels;
|
|
76554
|
+
let k = 0;
|
|
76555
|
+
const data = labels.flatMap((text, i) => {
|
|
76556
|
+
if (!text)
|
|
76557
|
+
return [];
|
|
76558
|
+
const spot = placed?.[k++];
|
|
76559
|
+
// Sem medição (jsdom), uma aproximação em % do raio.
|
|
76560
|
+
const a = ((GAUGE_START_ANGLE - ((GAUGE_START_ANGLE - GAUGE_END_ANGLE) * i) / n) * Math.PI) / 180;
|
|
76561
|
+
const offset = spot ? [spot.dx, spot.dy] : [`${Math.round(Math.cos(a) * 128)}%`, `${Math.round(-Math.sin(a) * 124)}%`];
|
|
76562
|
+
return [{ value: min, name: text, title: { offsetCenter: offset } }];
|
|
76563
|
+
});
|
|
76564
|
+
return {
|
|
76565
|
+
type: 'gauge',
|
|
76566
|
+
min,
|
|
76567
|
+
max,
|
|
76568
|
+
startAngle: GAUGE_START_ANGLE,
|
|
76569
|
+
endAngle: GAUGE_END_ANGLE,
|
|
76570
|
+
center: l ? [l.cx, l.cy] : ['50%', '58%'],
|
|
76571
|
+
radius: l ? l.radius : '62%',
|
|
76572
|
+
silent: true,
|
|
76573
|
+
animation: false,
|
|
76574
|
+
progress: { show: false },
|
|
76575
|
+
axisLine: { show: false },
|
|
76576
|
+
splitLine: { show: false },
|
|
76577
|
+
axisTick: { show: false },
|
|
76578
|
+
axisLabel: { show: false },
|
|
76579
|
+
pointer: { show: false },
|
|
76580
|
+
anchor: { show: false },
|
|
76581
|
+
detail: { show: false },
|
|
76582
|
+
title: { show: true, fontSize: l?.labelFont ?? 12 },
|
|
76583
|
+
data,
|
|
76584
|
+
};
|
|
76585
|
+
}
|
|
76586
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmGaugeChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
76587
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmGaugeChartComponent, isStandalone: true, selector: "hm-gauge-chart", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, animated: { classPropertyName: "animated", publicName: "animated", isSignal: true, isRequired: false, transformFunction: null }, needle: { classPropertyName: "needle", publicName: "needle", isSignal: true, isRequired: false, transformFunction: null }, ticks: { classPropertyName: "ticks", publicName: "ticks", isSignal: true, isRequired: false, transformFunction: null }, tickStep: { classPropertyName: "tickStep", publicName: "tickStep", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `<hm-chart-frame [view]="view()" [label]="label()" [description]="description()" [height]="height()" [(showTable)]="showTable" />`, isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76079
76588
|
}
|
|
76080
76589
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmGaugeChartComponent, decorators: [{
|
|
76081
76590
|
type: Component,
|
|
76082
|
-
args: [{ selector: 'hm-gauge-chart', standalone: true, imports: [HmChartFrameComponent], changeDetection: ChangeDetectionStrategy.OnPush, template:
|
|
76083
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }] } });
|
|
76591
|
+
args: [{ selector: 'hm-gauge-chart', standalone: true, imports: [HmChartFrameComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `<hm-chart-frame [view]="view()" [label]="label()" [description]="description()" [height]="height()" [(showTable)]="showTable" />`, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"] }]
|
|
76592
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], animated: [{ type: i0.Input, args: [{ isSignal: true, alias: "animated", required: false }] }], needle: [{ type: i0.Input, args: [{ isSignal: true, alias: "needle", required: false }] }], ticks: [{ type: i0.Input, args: [{ isSignal: true, alias: "ticks", required: false }] }], tickStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "tickStep", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }] } });
|
|
76593
|
+
function sameBox(a, b) {
|
|
76594
|
+
return a === b || (!!a && !!b && a.width === b.width && a.height === b.height && a.smallFont === b.smallFont && a.baseFont === b.baseFont);
|
|
76595
|
+
}
|
|
76084
76596
|
|
|
76085
76597
|
/**
|
|
76086
76598
|
* Etapas sucessivas de um processo (visitas → cadastros → compras). A ordem de `data` é a ordem das
|
|
@@ -76122,7 +76634,7 @@ class HmFunnelChartComponent extends HmChartBase {
|
|
|
76122
76634
|
};
|
|
76123
76635
|
}
|
|
76124
76636
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmFunnelChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
76125
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmFunnelChartComponent, isStandalone: true, selector: "hm-funnel-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76637
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmFunnelChartComponent, isStandalone: true, selector: "hm-funnel-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76126
76638
|
}
|
|
76127
76639
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmFunnelChartComponent, decorators: [{
|
|
76128
76640
|
type: Component,
|
|
@@ -76168,7 +76680,7 @@ class HmRadarChartComponent extends HmChartBase {
|
|
|
76168
76680
|
};
|
|
76169
76681
|
}
|
|
76170
76682
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmRadarChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
76171
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmRadarChartComponent, isStandalone: true, selector: "hm-radar-chart", inputs: { indicators: { classPropertyName: "indicators", publicName: "indicators", isSignal: true, isRequired: true, transformFunction: null }, series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76683
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmRadarChartComponent, isStandalone: true, selector: "hm-radar-chart", inputs: { indicators: { classPropertyName: "indicators", publicName: "indicators", isSignal: true, isRequired: true, transformFunction: null }, series: { classPropertyName: "series", publicName: "series", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76172
76684
|
}
|
|
76173
76685
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmRadarChartComponent, decorators: [{
|
|
76174
76686
|
type: Component,
|
|
@@ -76223,7 +76735,7 @@ class HmTreemapChartComponent extends HmChartBase {
|
|
|
76223
76735
|
};
|
|
76224
76736
|
}
|
|
76225
76737
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmTreemapChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
76226
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmTreemapChartComponent, isStandalone: true, selector: "hm-treemap-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76738
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmTreemapChartComponent, isStandalone: true, selector: "hm-treemap-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76227
76739
|
}
|
|
76228
76740
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmTreemapChartComponent, decorators: [{
|
|
76229
76741
|
type: Component,
|
|
@@ -76268,7 +76780,7 @@ class HmSankeyChartComponent extends HmChartBase {
|
|
|
76268
76780
|
};
|
|
76269
76781
|
}
|
|
76270
76782
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmSankeyChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
76271
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmSankeyChartComponent, isStandalone: true, selector: "hm-sankey-chart", inputs: { links: { classPropertyName: "links", publicName: "links", isSignal: true, isRequired: true, transformFunction: null }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76783
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmSankeyChartComponent, isStandalone: true, selector: "hm-sankey-chart", inputs: { links: { classPropertyName: "links", publicName: "links", isSignal: true, isRequired: true, transformFunction: null }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76272
76784
|
}
|
|
76273
76785
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmSankeyChartComponent, decorators: [{
|
|
76274
76786
|
type: Component,
|
|
@@ -76347,13 +76859,446 @@ class HmBoxplotChartComponent extends HmChartBase {
|
|
|
76347
76859
|
};
|
|
76348
76860
|
}
|
|
76349
76861
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmBoxplotChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
76350
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmBoxplotChartComponent, isStandalone: true, selector: "hm-boxplot-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76862
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmBoxplotChartComponent, isStandalone: true, selector: "hm-boxplot-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76351
76863
|
}
|
|
76352
76864
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmBoxplotChartComponent, decorators: [{
|
|
76353
76865
|
type: Component,
|
|
76354
76866
|
args: [{ selector: 'hm-boxplot-chart', standalone: true, imports: [HmChartFrameComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: CHART_TEMPLATE, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"] }]
|
|
76355
76867
|
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }] } });
|
|
76356
76868
|
|
|
76869
|
+
/**
|
|
76870
|
+
* Minigráfico: a tendência de uma série em pouco espaço, sem eixos nem legenda (dentro de um card de
|
|
76871
|
+
* indicador, numa linha de tabela). O resumo (primeiro, último, mínimo e máximo) e a tabela de dados
|
|
76872
|
+
* ficam na árvore de acessibilidade; sem o botão "Ver como tabela", para caber no `[footer]` do
|
|
76873
|
+
* `hm-stat-card`.
|
|
76874
|
+
*/
|
|
76875
|
+
class HmSparklineChartComponent extends HmChartBase {
|
|
76876
|
+
constructor() {
|
|
76877
|
+
super(...arguments);
|
|
76878
|
+
/** Valores na ordem (o mais antigo primeiro); `null` é lacuna. */
|
|
76879
|
+
this.data = input.required(...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
76880
|
+
/** Rótulo de cada valor (datas, meses) para a tabela e o tooltip; padrão: a posição (1, 2, 3...). */
|
|
76881
|
+
this.categories = input([], ...(ngDevMode ? [{ debugName: "categories" }] : /* istanbul ignore next */ []));
|
|
76882
|
+
/** Preenche a área sob a linha. */
|
|
76883
|
+
this.area = input(false, ...(ngDevMode ? [{ debugName: "area" }] : /* istanbul ignore next */ []));
|
|
76884
|
+
/** Destaca o último ponto (o valor atual). */
|
|
76885
|
+
this.showLast = input(true, ...(ngDevMode ? [{ debugName: "showLast" }] : /* istanbul ignore next */ []));
|
|
76886
|
+
/** Barras em vez de linha (valores discretos: pedidos por dia). */
|
|
76887
|
+
this.bars = input(false, ...(ngDevMode ? [{ debugName: "bars" }] : /* istanbul ignore next */ []));
|
|
76888
|
+
/**
|
|
76889
|
+
* Entra na ordem de foco e mostra o tooltip (setas percorrem os pontos). Desligado (padrão), o
|
|
76890
|
+
* minigráfico é só uma imagem com resumo: um card de indicador não ganha uma parada de Tab a mais.
|
|
76891
|
+
*/
|
|
76892
|
+
this.interactive = input(false, ...(ngDevMode ? [{ debugName: "interactive" }] : /* istanbul ignore next */ []));
|
|
76893
|
+
}
|
|
76894
|
+
build(ctx) {
|
|
76895
|
+
const data = this.data();
|
|
76896
|
+
const names = data.map((_, i) => this.categories()[i] ?? String(i + 1));
|
|
76897
|
+
const last = data.length - 1;
|
|
76898
|
+
const interactive = this.interactive();
|
|
76899
|
+
const values = data.map((v, i) => !this.bars() && this.showLast() && i === last && v != null ? { value: v, symbol: 'circle', symbolSize: 6 } : v);
|
|
76900
|
+
const finite = data.filter((v) => v != null && Number.isFinite(v));
|
|
76901
|
+
const range = extent(finite);
|
|
76902
|
+
const describe = (i) => `${names[i]}: ${ctx.num(data[i])}`;
|
|
76903
|
+
return {
|
|
76904
|
+
option: {
|
|
76905
|
+
grid: { left: 4, right: 6, top: 6, bottom: 4, containLabel: false },
|
|
76906
|
+
tooltip: interactive
|
|
76907
|
+
? {
|
|
76908
|
+
...tooltipOption(ctx, 'axis'),
|
|
76909
|
+
axisPointer: { type: 'line' },
|
|
76910
|
+
formatter: (p) => escapeHtml(describe((Array.isArray(p) ? p[0] : p).dataIndex)),
|
|
76911
|
+
}
|
|
76912
|
+
: { show: false },
|
|
76913
|
+
xAxis: { type: 'category', data: names, show: false, boundaryGap: this.bars() },
|
|
76914
|
+
yAxis: { type: 'value', show: false, scale: !this.bars() },
|
|
76915
|
+
series: [
|
|
76916
|
+
this.bars()
|
|
76917
|
+
? { type: 'bar', name: this.label(), data: [...data], barCategoryGap: '30%', silent: !interactive }
|
|
76918
|
+
: {
|
|
76919
|
+
type: 'line',
|
|
76920
|
+
name: this.label(),
|
|
76921
|
+
data: values,
|
|
76922
|
+
symbol: 'none',
|
|
76923
|
+
lineStyle: { width: 1.75 },
|
|
76924
|
+
areaStyle: this.area() ? { opacity: 0.18 } : undefined,
|
|
76925
|
+
silent: !interactive,
|
|
76926
|
+
},
|
|
76927
|
+
],
|
|
76928
|
+
},
|
|
76929
|
+
summary: ctx.i18n.plural(ctx.m.summary.sparkline, finite.length, {
|
|
76930
|
+
type: ctx.m.types.sparkline,
|
|
76931
|
+
first: ctx.num(finite[0]),
|
|
76932
|
+
last: ctx.num(finite[finite.length - 1]),
|
|
76933
|
+
min: ctx.num(range?.[0]),
|
|
76934
|
+
max: ctx.num(range?.[1]),
|
|
76935
|
+
}),
|
|
76936
|
+
table: {
|
|
76937
|
+
columns: [ctx.m.columns.category, ctx.m.columns.value],
|
|
76938
|
+
align: ['start', 'end'],
|
|
76939
|
+
rows: data.map((v, i) => ({ header: names[i], cells: [ctx.num(v)] })),
|
|
76940
|
+
},
|
|
76941
|
+
points: interactive ? data.map((_, i) => ({ seriesIndex: 0, dataIndex: i, text: describe(i) })) : [],
|
|
76942
|
+
};
|
|
76943
|
+
}
|
|
76944
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmSparklineChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
76945
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmSparklineChartComponent, isStandalone: true, selector: "hm-sparkline-chart", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, categories: { classPropertyName: "categories", publicName: "categories", isSignal: true, isRequired: false, transformFunction: null }, area: { classPropertyName: "area", publicName: "area", isSignal: true, isRequired: false, transformFunction: null }, showLast: { classPropertyName: "showLast", publicName: "showLast", isSignal: true, isRequired: false, transformFunction: null }, bars: { classPropertyName: "bars", publicName: "bars", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `<hm-chart-frame
|
|
76946
|
+
[view]="view()"
|
|
76947
|
+
[label]="label()"
|
|
76948
|
+
[description]="description()"
|
|
76949
|
+
[height]="height() || 'calc(var(--hm-control-height) * 1.5)'"
|
|
76950
|
+
[tableToggle]="false"
|
|
76951
|
+
[(showTable)]="showTable"
|
|
76952
|
+
/>`, isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76953
|
+
}
|
|
76954
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmSparklineChartComponent, decorators: [{
|
|
76955
|
+
type: Component,
|
|
76956
|
+
args: [{ selector: 'hm-sparkline-chart', standalone: true, imports: [HmChartFrameComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `<hm-chart-frame
|
|
76957
|
+
[view]="view()"
|
|
76958
|
+
[label]="label()"
|
|
76959
|
+
[description]="description()"
|
|
76960
|
+
[height]="height() || 'calc(var(--hm-control-height) * 1.5)'"
|
|
76961
|
+
[tableToggle]="false"
|
|
76962
|
+
[(showTable)]="showTable"
|
|
76963
|
+
/>`, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"] }]
|
|
76964
|
+
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], categories: [{ type: i0.Input, args: [{ isSignal: true, alias: "categories", required: false }] }], area: [{ type: i0.Input, args: [{ isSignal: true, alias: "area", required: false }] }], showLast: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLast", required: false }] }], bars: [{ type: i0.Input, args: [{ isSignal: true, alias: "bars", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }] } });
|
|
76965
|
+
|
|
76966
|
+
/**
|
|
76967
|
+
* Tamanho real da área do gráfico (o `.hm-chart` dentro do componente), medido depois da primeira
|
|
76968
|
+
* pintura e a cada redimensionamento. `null` até a primeira medição (e em ambiente sem layout).
|
|
76969
|
+
* Chame no construtor de um gráfico tipado.
|
|
76970
|
+
*/
|
|
76971
|
+
function injectChartBox() {
|
|
76972
|
+
const host = inject(ElementRef).nativeElement;
|
|
76973
|
+
const box = signal(null, { ...(ngDevMode ? { debugName: "box" } : /* istanbul ignore next */ {}), equal: (a, b) => a === b || (!!a && !!b && a.width === b.width && a.height === b.height) });
|
|
76974
|
+
let observer = null;
|
|
76975
|
+
afterNextRender(() => {
|
|
76976
|
+
const target = host.querySelector('.hm-chart');
|
|
76977
|
+
if (!target)
|
|
76978
|
+
return;
|
|
76979
|
+
const measure = () => {
|
|
76980
|
+
const width = Math.round(target.clientWidth);
|
|
76981
|
+
const height = Math.round(target.clientHeight);
|
|
76982
|
+
box.set(width > 0 && height > 0 ? { width, height } : null);
|
|
76983
|
+
};
|
|
76984
|
+
measure();
|
|
76985
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
76986
|
+
observer = new ResizeObserver(measure);
|
|
76987
|
+
observer.observe(target);
|
|
76988
|
+
}
|
|
76989
|
+
});
|
|
76990
|
+
inject(DestroyRef).onDestroy(() => observer?.disconnect());
|
|
76991
|
+
return box;
|
|
76992
|
+
}
|
|
76993
|
+
/**
|
|
76994
|
+
* Cores de tokens (`--hm-*`) resolvidas para `rgb(...)` no elemento do gráfico, para os gráficos
|
|
76995
|
+
* que pintam partes fora da paleta (faixas neutras, aumento/redução). Relidas quando tema, família,
|
|
76996
|
+
* densidade ou paleta mudam num ancestral. `null` antes da primeira pintura e em `forced-colors`
|
|
76997
|
+
* (aí o tema do motor já usa cores de sistema e o gráfico cai na paleta dele).
|
|
76998
|
+
*/
|
|
76999
|
+
function injectTokenColors(tokens) {
|
|
77000
|
+
const host = inject(ElementRef).nativeElement;
|
|
77001
|
+
const colors = signal(null, { ...(ngDevMode ? { debugName: "colors" } : /* istanbul ignore next */ {}), equal: (a, b) => JSON.stringify(a) === JSON.stringify(b) });
|
|
77002
|
+
let scope = null;
|
|
77003
|
+
let forced = null;
|
|
77004
|
+
// Fora do documento (painel de aba ainda não exibido) os tokens não resolvem: relê ao entrar na página.
|
|
77005
|
+
let attach = null;
|
|
77006
|
+
const watchAttach = () => {
|
|
77007
|
+
if (attach || host.isConnected || typeof ResizeObserver === 'undefined')
|
|
77008
|
+
return;
|
|
77009
|
+
attach = new ResizeObserver(() => {
|
|
77010
|
+
if (!host.isConnected)
|
|
77011
|
+
return;
|
|
77012
|
+
attach?.disconnect();
|
|
77013
|
+
attach = null;
|
|
77014
|
+
read();
|
|
77015
|
+
});
|
|
77016
|
+
attach.observe(host);
|
|
77017
|
+
};
|
|
77018
|
+
const read = () => {
|
|
77019
|
+
if (forced?.matches) {
|
|
77020
|
+
colors.set(null);
|
|
77021
|
+
return;
|
|
77022
|
+
}
|
|
77023
|
+
const out = {};
|
|
77024
|
+
for (const key of Object.keys(tokens)) {
|
|
77025
|
+
const value = resolveTokenColor(host, tokens[key]);
|
|
77026
|
+
if (!value) {
|
|
77027
|
+
colors.set(null);
|
|
77028
|
+
return;
|
|
77029
|
+
}
|
|
77030
|
+
out[key] = value;
|
|
77031
|
+
}
|
|
77032
|
+
colors.set(out);
|
|
77033
|
+
};
|
|
77034
|
+
const onForced = () => read();
|
|
77035
|
+
afterNextRender(() => {
|
|
77036
|
+
forced = typeof matchMedia === 'function' ? matchMedia('(forced-colors: active)') : null;
|
|
77037
|
+
forced?.addEventListener?.('change', onForced);
|
|
77038
|
+
read();
|
|
77039
|
+
watchAttach();
|
|
77040
|
+
if (typeof MutationObserver === 'undefined')
|
|
77041
|
+
return;
|
|
77042
|
+
scope = new MutationObserver((records) => {
|
|
77043
|
+
if (records.some((r) => r.target.contains(host)))
|
|
77044
|
+
queueMicrotask(read);
|
|
77045
|
+
});
|
|
77046
|
+
scope.observe(host.ownerDocument.documentElement, {
|
|
77047
|
+
subtree: true,
|
|
77048
|
+
attributes: true,
|
|
77049
|
+
attributeFilter: ['data-theme', 'data-family', 'data-density', 'data-font', 'style'],
|
|
77050
|
+
});
|
|
77051
|
+
});
|
|
77052
|
+
inject(DestroyRef).onDestroy(() => {
|
|
77053
|
+
scope?.disconnect();
|
|
77054
|
+
attach?.disconnect();
|
|
77055
|
+
forced?.removeEventListener?.('change', onForced);
|
|
77056
|
+
});
|
|
77057
|
+
return colors;
|
|
77058
|
+
}
|
|
77059
|
+
/** `rgb(r, g, b)` (ou `rgba`) com outra opacidade; texto que não for rgb volta como veio. */
|
|
77060
|
+
function withAlpha(color, alpha) {
|
|
77061
|
+
const m = /^rgba?\(\s*([\d.]+)[\s,]+([\d.]+)[\s,]+([\d.]+)/.exec(color);
|
|
77062
|
+
return m ? `rgba(${m[1]}, ${m[2]}, ${m[3]}, ${alpha})` : color;
|
|
77063
|
+
}
|
|
77064
|
+
|
|
77065
|
+
/** Opacidade das faixas, da primeira (mais escura) à última: o texto translúcido funciona nos dois temas. */
|
|
77066
|
+
const BAND_ALPHA = [0.22, 0.14, 0.08, 0.05];
|
|
77067
|
+
/**
|
|
77068
|
+
* Gráfico de bala: cada linha é um indicador com o valor (barra fina na cor da série), a meta (marca
|
|
77069
|
+
* vertical) e as faixas qualitativas ao fundo. Substitui um painel de medidores lado a lado em pouco
|
|
77070
|
+
* espaço, com todos na mesma escala.
|
|
77071
|
+
*/
|
|
77072
|
+
class HmBulletChartComponent extends HmChartBase {
|
|
77073
|
+
constructor() {
|
|
77074
|
+
super(...arguments);
|
|
77075
|
+
this.items = input.required(...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
77076
|
+
/** Fim da escala (comum a todos); padrão: um valor redondo que cobre valores, metas e faixas. */
|
|
77077
|
+
this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
77078
|
+
this.#box = injectChartBox();
|
|
77079
|
+
this.#colors = injectTokenColors({ text: '--hm-text' });
|
|
77080
|
+
}
|
|
77081
|
+
#box;
|
|
77082
|
+
#colors;
|
|
77083
|
+
build(ctx) {
|
|
77084
|
+
const items = this.items();
|
|
77085
|
+
const names = items.map((i) => i.name);
|
|
77086
|
+
const bands = Math.max(0, ...items.map((i) => i.ranges?.length ?? 0));
|
|
77087
|
+
// Sem `max`, o motor escolhe um fim de escala redondo que cobre valores, metas e faixas (um fim
|
|
77088
|
+
// quebrado, como 270, cola o último rótulo no penúltimo).
|
|
77089
|
+
const top = this.max();
|
|
77090
|
+
const reach = Math.max(0, ...items.flatMap((i) => [i.value, i.target ?? 0, ...(i.ranges ?? [])]));
|
|
77091
|
+
const text = this.#colors()?.text;
|
|
77092
|
+
const box = this.#box();
|
|
77093
|
+
// Altura da marca da meta: 70% da faixa de cada linha (medida); antes da medida, um valor seguro.
|
|
77094
|
+
const row = box ? (box.height - 28) / Math.max(1, items.length) : 40;
|
|
77095
|
+
const markHeight = Math.max(10, Math.min(36, row * 0.62));
|
|
77096
|
+
const bandSeries = Array.from({ length: bands }, (_, b) => ({
|
|
77097
|
+
type: 'bar',
|
|
77098
|
+
name: `band-${b}`,
|
|
77099
|
+
stack: 'bands',
|
|
77100
|
+
yAxisIndex: 0,
|
|
77101
|
+
barWidth: '62%',
|
|
77102
|
+
silent: true,
|
|
77103
|
+
itemStyle: text ? { color: withAlpha(text, BAND_ALPHA[Math.min(b, BAND_ALPHA.length - 1)]) } : { opacity: 0.12 + 0.06 * (bands - b) },
|
|
77104
|
+
data: items.map((i) => {
|
|
77105
|
+
const r = i.ranges ?? [];
|
|
77106
|
+
return b < r.length ? r[b] - (b ? r[b - 1] : 0) : 0;
|
|
77107
|
+
}),
|
|
77108
|
+
tooltip: { show: false },
|
|
77109
|
+
animation: false,
|
|
77110
|
+
}));
|
|
77111
|
+
const series = [
|
|
77112
|
+
...bandSeries,
|
|
77113
|
+
{
|
|
77114
|
+
type: 'bar',
|
|
77115
|
+
name: ctx.m.columns.value,
|
|
77116
|
+
yAxisIndex: 1,
|
|
77117
|
+
barWidth: '24%',
|
|
77118
|
+
data: items.map((i) => i.value),
|
|
77119
|
+
emphasis: { focus: 'self' },
|
|
77120
|
+
},
|
|
77121
|
+
{
|
|
77122
|
+
type: 'scatter',
|
|
77123
|
+
name: ctx.m.columns.goal,
|
|
77124
|
+
yAxisIndex: 0,
|
|
77125
|
+
symbol: 'rect',
|
|
77126
|
+
symbolSize: [3, markHeight],
|
|
77127
|
+
itemStyle: text ? { color: text } : undefined,
|
|
77128
|
+
data: items.map((i, idx) => (i.target == null ? null : [i.target, idx])),
|
|
77129
|
+
z: 5,
|
|
77130
|
+
},
|
|
77131
|
+
];
|
|
77132
|
+
const describe = (i) => i.target == null
|
|
77133
|
+
? ctx.i18n.format(ctx.m.summary.bulletItemNoTarget, { name: i.name, value: ctx.num(i.value) })
|
|
77134
|
+
: ctx.i18n.format(ctx.m.summary.bulletItem, { name: i.name, value: ctx.num(i.value), target: ctx.num(i.target) });
|
|
77135
|
+
const valueSeries = bands;
|
|
77136
|
+
return {
|
|
77137
|
+
option: {
|
|
77138
|
+
grid: { left: 6, right: 20, top: 8, bottom: 6, containLabel: true },
|
|
77139
|
+
tooltip: {
|
|
77140
|
+
...tooltipOption(ctx, 'axis'),
|
|
77141
|
+
formatter: (p) => {
|
|
77142
|
+
const first = (Array.isArray(p) ? p[0] : p);
|
|
77143
|
+
return escapeHtml(describe(items[first.dataIndex]));
|
|
77144
|
+
},
|
|
77145
|
+
},
|
|
77146
|
+
legend: { show: false },
|
|
77147
|
+
xAxis: { type: 'value', min: 0, max: top ?? (reach > 0 ? undefined : 1), axisLabel: { formatter: (v) => ctx.num(v) } },
|
|
77148
|
+
yAxis: [
|
|
77149
|
+
{ type: 'category', data: names, inverse: true, axisTick: { show: false } },
|
|
77150
|
+
{ type: 'category', data: names, inverse: true, show: false },
|
|
77151
|
+
],
|
|
77152
|
+
series,
|
|
77153
|
+
},
|
|
77154
|
+
summary: [ctx.i18n.plural(ctx.m.summary.items, items.length, { type: ctx.m.types.bullet }), ...items.map(describe)].join(' '),
|
|
77155
|
+
table: {
|
|
77156
|
+
columns: [ctx.m.columns.indicator, ctx.m.columns.value, ctx.m.columns.goal, ctx.m.columns.ranges],
|
|
77157
|
+
align: ['start', 'end', 'end', 'end'],
|
|
77158
|
+
rows: items.map((i) => ({
|
|
77159
|
+
header: i.name,
|
|
77160
|
+
cells: [ctx.num(i.value), i.target == null ? EMPTY_VALUE : ctx.num(i.target), i.ranges?.length ? i.ranges.map((r) => ctx.num(r)).join(' · ') : EMPTY_VALUE],
|
|
77161
|
+
})),
|
|
77162
|
+
},
|
|
77163
|
+
points: items.map((i, idx) => ({ seriesIndex: valueSeries, dataIndex: idx, text: describe(i) })),
|
|
77164
|
+
};
|
|
77165
|
+
}
|
|
77166
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmBulletChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
77167
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmBulletChartComponent, isStandalone: true, selector: "hm-bullet-chart", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
77168
|
+
}
|
|
77169
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmBulletChartComponent, decorators: [{
|
|
77170
|
+
type: Component,
|
|
77171
|
+
args: [{ selector: 'hm-bullet-chart', standalone: true, imports: [HmChartFrameComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: CHART_TEMPLATE, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"] }]
|
|
77172
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }] } });
|
|
77173
|
+
|
|
77174
|
+
/** Calcula as barras da cascata (sem framework: testável e portável). */
|
|
77175
|
+
function waterfallBars(steps) {
|
|
77176
|
+
let running = 0;
|
|
77177
|
+
return steps.map((s) => {
|
|
77178
|
+
if (s.total)
|
|
77179
|
+
return { kind: 'total', from: 0, to: running, change: running, cumulative: running };
|
|
77180
|
+
const change = Number.isFinite(s.value) ? s.value : 0;
|
|
77181
|
+
const from = running;
|
|
77182
|
+
running += change;
|
|
77183
|
+
return { kind: change < 0 ? 'decrease' : 'increase', from, to: running, change, cumulative: running };
|
|
77184
|
+
});
|
|
77185
|
+
}
|
|
77186
|
+
/**
|
|
77187
|
+
* Gráfico de cascata: como um valor inicial chega ao final, etapa por etapa (receita → custos →
|
|
77188
|
+
* lucro). Aumentos e reduções flutuam a partir do acumulado; totais partem do zero. Cores da escala
|
|
77189
|
+
* divergente dos tokens (um polo para aumento, outro para redução, o ponto neutro para totais).
|
|
77190
|
+
*/
|
|
77191
|
+
class HmWaterfallChartComponent extends HmChartBase {
|
|
77192
|
+
constructor() {
|
|
77193
|
+
super(...arguments);
|
|
77194
|
+
this.steps = input.required(...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
|
|
77195
|
+
this.#colors = injectTokenColors({
|
|
77196
|
+
increase: '--hm-data-diverging-6',
|
|
77197
|
+
decrease: '--hm-data-diverging-2',
|
|
77198
|
+
total: '--hm-data-diverging-4',
|
|
77199
|
+
});
|
|
77200
|
+
}
|
|
77201
|
+
#colors;
|
|
77202
|
+
build(ctx) {
|
|
77203
|
+
const steps = this.steps();
|
|
77204
|
+
const bars = waterfallBars(steps);
|
|
77205
|
+
const names = steps.map((s) => s.name);
|
|
77206
|
+
const colors = this.#colors();
|
|
77207
|
+
const signed = numberFormatter(ctx.locale, { ...(this.numberFormat() ?? {}), signDisplay: 'exceptZero' });
|
|
77208
|
+
const label = { increase: ctx.m.waterfall.increase, decrease: ctx.m.waterfall.decrease, total: ctx.m.waterfall.total };
|
|
77209
|
+
// Empilhamento por sinal (padrão do motor): base invisível + a parte positiva e a negativa de cada barra.
|
|
77210
|
+
// Barra que cruza o zero sai do zero para os dois lados.
|
|
77211
|
+
const base = [];
|
|
77212
|
+
const parts = {
|
|
77213
|
+
increase: { pos: [], neg: [] },
|
|
77214
|
+
decrease: { pos: [], neg: [] },
|
|
77215
|
+
total: { pos: [], neg: [] },
|
|
77216
|
+
};
|
|
77217
|
+
bars.forEach((b, i) => {
|
|
77218
|
+
const low = Math.min(b.from, b.to);
|
|
77219
|
+
const high = Math.max(b.from, b.to);
|
|
77220
|
+
for (const k of Object.keys(parts)) {
|
|
77221
|
+
parts[k].pos[i] = null;
|
|
77222
|
+
parts[k].neg[i] = null;
|
|
77223
|
+
}
|
|
77224
|
+
if (low >= 0) {
|
|
77225
|
+
base[i] = low;
|
|
77226
|
+
parts[b.kind].pos[i] = high - low;
|
|
77227
|
+
}
|
|
77228
|
+
else if (high <= 0) {
|
|
77229
|
+
base[i] = high;
|
|
77230
|
+
parts[b.kind].neg[i] = low - high;
|
|
77231
|
+
}
|
|
77232
|
+
else {
|
|
77233
|
+
base[i] = 0;
|
|
77234
|
+
parts[b.kind].pos[i] = high;
|
|
77235
|
+
parts[b.kind].neg[i] = low;
|
|
77236
|
+
}
|
|
77237
|
+
});
|
|
77238
|
+
const kinds = ['increase', 'decrease', 'total'].filter((k) => bars.some((b) => b.kind === k));
|
|
77239
|
+
const series = [
|
|
77240
|
+
{
|
|
77241
|
+
type: 'bar',
|
|
77242
|
+
name: 'base',
|
|
77243
|
+
stack: 'waterfall',
|
|
77244
|
+
silent: true,
|
|
77245
|
+
itemStyle: { color: 'transparent', borderColor: 'transparent' },
|
|
77246
|
+
emphasis: { disabled: true },
|
|
77247
|
+
tooltip: { show: false },
|
|
77248
|
+
data: base,
|
|
77249
|
+
},
|
|
77250
|
+
...kinds.flatMap((k) => ['pos', 'neg'].map((side) => ({
|
|
77251
|
+
type: 'bar',
|
|
77252
|
+
name: label[k],
|
|
77253
|
+
stack: 'waterfall',
|
|
77254
|
+
barCategoryGap: '30%',
|
|
77255
|
+
itemStyle: colors ? { color: colors[k] } : undefined,
|
|
77256
|
+
data: parts[k][side],
|
|
77257
|
+
}))),
|
|
77258
|
+
];
|
|
77259
|
+
const describe = (i) => {
|
|
77260
|
+
const b = bars[i];
|
|
77261
|
+
return b.kind === 'total'
|
|
77262
|
+
? `${names[i]}: ${label.total} ${ctx.num(b.cumulative)}`
|
|
77263
|
+
: `${names[i]}: ${label[b.kind]} ${signed(b.change)}, ${ctx.m.columns.cumulative} ${ctx.num(b.cumulative)}`;
|
|
77264
|
+
};
|
|
77265
|
+
const hasLegend = kinds.length > 1;
|
|
77266
|
+
const end = bars.length ? bars[bars.length - 1].cumulative : 0;
|
|
77267
|
+
const start = bars.length ? bars[0].change : 0;
|
|
77268
|
+
return {
|
|
77269
|
+
option: {
|
|
77270
|
+
grid: gridOption(hasLegend && ctx.legend),
|
|
77271
|
+
tooltip: {
|
|
77272
|
+
...tooltipOption(ctx, 'axis'),
|
|
77273
|
+
formatter: (p) => escapeHtml(describe((Array.isArray(p) ? p[0] : p).dataIndex)),
|
|
77274
|
+
},
|
|
77275
|
+
legend: { ...legendOption(ctx, hasLegend), data: kinds.map((k) => label[k]) },
|
|
77276
|
+
xAxis: { type: 'category', data: names, axisTick: { alignWithLabel: true } },
|
|
77277
|
+
yAxis: { type: 'value', axisLabel: { formatter: (v) => ctx.num(v) } },
|
|
77278
|
+
series,
|
|
77279
|
+
},
|
|
77280
|
+
summary: ctx.i18n.plural(ctx.m.summary.waterfall, steps.length, { type: ctx.m.types.waterfall, start: ctx.num(start), end: ctx.num(end) }),
|
|
77281
|
+
table: {
|
|
77282
|
+
columns: [ctx.m.columns.category, ctx.m.columns.change, ctx.m.columns.cumulative],
|
|
77283
|
+
align: ['start', 'end', 'end'],
|
|
77284
|
+
rows: bars.map((b, i) => ({ header: names[i], cells: [b.kind === 'total' ? label.total : signed(b.change), ctx.num(b.cumulative)] })),
|
|
77285
|
+
},
|
|
77286
|
+
// Destaca a série visível da etapa (a da cor dela) ao navegar com as setas.
|
|
77287
|
+
points: bars.map((b, i) => {
|
|
77288
|
+
const k = kinds.indexOf(b.kind);
|
|
77289
|
+
const side = parts[b.kind].pos[i] != null ? 0 : 1;
|
|
77290
|
+
return { seriesIndex: 1 + k * 2 + side, dataIndex: i, text: describe(i) };
|
|
77291
|
+
}),
|
|
77292
|
+
};
|
|
77293
|
+
}
|
|
77294
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmWaterfallChartComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
77295
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.24", type: HmWaterfallChartComponent, isStandalone: true, selector: "hm-waterfall-chart", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<hm-chart-frame [view]=\"view()\" [label]=\"label()\" [description]=\"description()\" [height]=\"height()\" [(showTable)]=\"showTable\" />", isInline: true, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"], dependencies: [{ kind: "component", type: HmChartFrameComponent, selector: "hm-chart-frame", inputs: ["view", "label", "description", "height", "tableToggle", "showTable"], outputs: ["showTableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
77296
|
+
}
|
|
77297
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: HmWaterfallChartComponent, decorators: [{
|
|
77298
|
+
type: Component,
|
|
77299
|
+
args: [{ selector: 'hm-waterfall-chart', standalone: true, imports: [HmChartFrameComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: CHART_TEMPLATE, styles: [":host{display:block;inline-size:100%;min-inline-size:0}\n"] }]
|
|
77300
|
+
}], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: true }] }] } });
|
|
77301
|
+
|
|
76357
77302
|
// API pública de @trismegisto/charts.
|
|
76358
77303
|
// Gráficos tipados (API orientada a dados)
|
|
76359
77304
|
|
|
@@ -76361,5 +77306,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImpo
|
|
|
76361
77306
|
* Generated bundle index. Do not edit.
|
|
76362
77307
|
*/
|
|
76363
77308
|
|
|
76364
|
-
export { CHARTS_I18N_CONFIG, CHARTS_MESSAGES_EN, CHARTS_MESSAGES_ES, CHARTS_MESSAGES_PT_BR, ChartsI18nService, HmBarChartComponent, HmBoxplotChartComponent, HmCalendarHeatmapComponent, HmChartBase, HmChartComponent, HmFunnelChartComponent, HmGaugeChartComponent, HmHeatmapChartComponent, HmLineChartComponent, HmPieChartComponent, HmRadarChartComponent, HmSankeyChartComponent, HmScatterChartComponent, HmTreemapChartComponent, provideChartsMessages };
|
|
77309
|
+
export { CHARTS_I18N_CONFIG, CHARTS_MESSAGES_EN, CHARTS_MESSAGES_ES, CHARTS_MESSAGES_PT_BR, ChartsI18nService, HmBarChartComponent, HmBoxplotChartComponent, HmBulletChartComponent, HmCalendarHeatmapComponent, HmChartBase, HmChartComponent, HmFunnelChartComponent, HmGaugeChartComponent, HmHeatmapChartComponent, HmLineChartComponent, HmPieChartComponent, HmRadarChartComponent, HmSankeyChartComponent, HmScatterChartComponent, HmSparklineChartComponent, HmTreemapChartComponent, HmWaterfallChartComponent, provideChartsMessages, waterfallBars };
|
|
76365
77310
|
//# sourceMappingURL=trismegisto-charts.mjs.map
|