@lieselthuriot/widget-renderer 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,993 @@
1
+ import { i as defaultWidgetRendererLocale, n as chartAriaLabel, r as WidgetTooltip, t as chartAccessibilitySummary } from "./lieselthuriot-widget-renderer-chart-accessibility-BzH2alxy.mjs";
2
+ import * as i0 from "@angular/core";
3
+ import { Component, Directive, afterNextRender, computed, effect, inject, input, signal, viewChild } from "@angular/core";
4
+ import { arc, curveMonotoneX, line, pie } from "d3-shape";
5
+ import { tickIncrement, ticks } from "d3-array";
6
+ const START_ANGLE = -110 * Math.PI / 180;
7
+ const END_ANGLE = 110 * Math.PI / 180;
8
+ const MINOR_SPLITS = 5;
9
+ const BELOW_CENTER = Math.sin(20 * Math.PI / 180);
10
+ function gaugeRatio(element) {
11
+ const { value, min, max } = element.data;
12
+ return max === min ? 0 : Math.max(0, Math.min(1, (value - min) / (max - min)));
13
+ }
14
+ function polar(centerX, centerY, radius, angle) {
15
+ return [centerX + radius * Math.sin(angle), centerY - radius * Math.cos(angle)];
16
+ }
17
+ function gaugeChartLayout(element, width, height) {
18
+ const fontSize = element.style.font.size;
19
+ const outside = element.showLegend ? 16 + fontSize * 1.2 : 12;
20
+ const radius = Math.max(8, Math.min(width / 2 - outside, (height - outside - 4) / (1 + BELOW_CENTER)));
21
+ const centerX = width / 2;
22
+ const used = outside + radius * (1 + BELOW_CENTER);
23
+ const centerY = outside + radius + Math.max(0, (height - used) / 2);
24
+ const band = Math.min(16, radius * .25);
25
+ const ring = arc().innerRadius(radius - band).outerRadius(radius).cornerRadius(band / 2);
26
+ const valueAngle = START_ANGLE + (END_ANGLE - START_ANGLE) * gaugeRatio(element);
27
+ const ticks = [];
28
+ const labels = [];
29
+ const { min, max } = element.data;
30
+ for (let step = 0; step <= 30; step++) {
31
+ const major = step % MINOR_SPLITS === 0;
32
+ const angle = START_ANGLE + (END_ANGLE - START_ANGLE) * step / 30;
33
+ const [x1, y1] = polar(centerX, centerY, radius + 2, angle);
34
+ const [x2, y2] = polar(centerX, centerY, radius + (major ? 10 : 6), angle);
35
+ ticks.push({
36
+ x1,
37
+ y1,
38
+ x2,
39
+ y2,
40
+ major
41
+ });
42
+ if (major && element.showLegend) {
43
+ const [x, y] = polar(centerX, centerY, radius + 12 + fontSize * .8, angle);
44
+ const value = min + (max - min) * step / 30;
45
+ labels.push({
46
+ x,
47
+ y,
48
+ text: `${Math.round(value)}`
49
+ });
50
+ }
51
+ }
52
+ const [tipX, tipY] = polar(centerX, centerY, radius * .55, valueAngle);
53
+ const [leftX, leftY] = polar(centerX, centerY, 2.5, valueAngle - Math.PI / 2);
54
+ const [rightX, rightY] = polar(centerX, centerY, 2.5, valueAngle + Math.PI / 2);
55
+ return {
56
+ centerX,
57
+ centerY,
58
+ radius,
59
+ track: ring({
60
+ startAngle: START_ANGLE,
61
+ endAngle: END_ANGLE
62
+ }) ?? "",
63
+ fill: valueAngle > START_ANGLE ? ring({
64
+ startAngle: START_ANGLE,
65
+ endAngle: valueAngle
66
+ }) ?? "" : "",
67
+ ticks,
68
+ labels,
69
+ pointer: `${leftX},${leftY} ${tipX},${tipY} ${rightX},${rightY}`,
70
+ valueY: centerY + radius * .4
71
+ };
72
+ }
73
+ const DEFAULT_CHART_COLORS = [
74
+ "#5470c6",
75
+ "#91cc75",
76
+ "#fac858",
77
+ "#ee6666",
78
+ "#73c0de",
79
+ "#3ba272",
80
+ "#fc8452",
81
+ "#9a60b4",
82
+ "#ea7ccc"
83
+ ];
84
+ function defaultChartColor(index) {
85
+ return DEFAULT_CHART_COLORS[index % DEFAULT_CHART_COLORS.length];
86
+ }
87
+ var InteractiveChart = class InteractiveChart {
88
+ element = input.required(...ngDevMode ? [{ debugName: "element" }] : /* istanbul ignore next */ []);
89
+ sensitiveHidden = input(false, ...ngDevMode ? [{ debugName: "sensitiveHidden" }] : /* istanbul ignore next */ []);
90
+ locale = input(defaultWidgetRendererLocale, ...ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []);
91
+ summaryId = `chart-summary-${crypto.randomUUID()}`;
92
+ activeIndex = signal(null, ...ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []);
93
+ size = signal({
94
+ width: 0,
95
+ height: 0
96
+ }, ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
97
+ announcement = computed(() => {
98
+ const point = this.activePoint();
99
+ return point ? this.locale().aria.chart.dataPointLabel(point.label, `${point.value}`) : "";
100
+ }, ...ngDevMode ? [{ debugName: "announcement" }] : /* istanbul ignore next */ []);
101
+ activePoint = computed(() => {
102
+ const index = this.activeIndex();
103
+ return index === null ? void 0 : this.points()[index];
104
+ }, ...ngDevMode ? [{ debugName: "activePoint" }] : /* istanbul ignore next */ []);
105
+ host = viewChild.required("chartHost", ...ngDevMode ? [{ debugName: "host" }] : /* istanbul ignore next */ []);
106
+ widgetTooltip = inject(WidgetTooltip);
107
+ tooltipOwner = {};
108
+ resizeObserver = null;
109
+ constructor() {
110
+ afterNextRender(() => {
111
+ const host = this.host().nativeElement;
112
+ this.measure(host);
113
+ if (typeof ResizeObserver === "undefined") return;
114
+ this.resizeObserver = new ResizeObserver(() => this.measure(host));
115
+ this.resizeObserver.observe(host);
116
+ });
117
+ effect(() => {
118
+ this.element();
119
+ this.sensitiveHidden();
120
+ this.hideTooltip();
121
+ });
122
+ effect(() => {
123
+ const owner = this.widgetTooltip.owner();
124
+ if (owner && owner !== this.tooltipOwner) this.activeIndex.set(null);
125
+ });
126
+ }
127
+ ngOnDestroy() {
128
+ this.resizeObserver?.disconnect();
129
+ this.widgetTooltip.hide(this.tooltipOwner);
130
+ }
131
+ ariaLabel(element) {
132
+ return chartAriaLabel(element, this.locale().aria.chart);
133
+ }
134
+ accessibilitySummary(element) {
135
+ return chartAccessibilitySummary(element, this.locale().aria.chart);
136
+ }
137
+ pointerMove(index, event) {
138
+ if (this.sensitiveHidden()) return;
139
+ if (event.pointerType === "touch") event.stopPropagation();
140
+ const point = this.points()[index];
141
+ if (point) this.showTooltip(point, event.clientX, event.clientY);
142
+ }
143
+ pointerLeave() {
144
+ this.hideTooltip();
145
+ }
146
+ focus() {
147
+ if (this.sensitiveHidden()) return;
148
+ this.select(this.activeIndex() ?? 0);
149
+ }
150
+ keyDown(event) {
151
+ if (event.key === "Escape") {
152
+ if (this.activeIndex() === null) return;
153
+ event.preventDefault();
154
+ this.hideTooltip();
155
+ return;
156
+ }
157
+ const count = this.points().length;
158
+ if (!count || this.sensitiveHidden()) return;
159
+ const current = this.activeIndex();
160
+ const next = event.key === "ArrowRight" || event.key === "ArrowDown" ? current === null ? 0 : Math.min(count - 1, current + 1) : event.key === "ArrowLeft" || event.key === "ArrowUp" ? current === null ? 0 : Math.max(0, current - 1) : event.key === "Home" ? 0 : event.key === "End" ? count - 1 : null;
161
+ if (next === null) return;
162
+ event.preventDefault();
163
+ this.select(next);
164
+ }
165
+ onDocumentPointerDown(event) {
166
+ if (!(event.target instanceof Element) || !this.host().nativeElement.contains(event.target)) this.hideTooltip();
167
+ }
168
+ select(index) {
169
+ const point = this.points()[index];
170
+ if (!point) return;
171
+ const bounds = this.host().nativeElement.getBoundingClientRect();
172
+ this.showTooltip(point, bounds.left + point.anchorX, bounds.top + point.anchorY);
173
+ }
174
+ showTooltip(point, clientX, clientY) {
175
+ const shell = this.widgetTooltip.overlayElement()?.parentElement;
176
+ this.activeIndex.set(point.index);
177
+ if (!shell) return;
178
+ const bounds = shell.getBoundingClientRect();
179
+ this.widgetTooltip.show(this.tooltipOwner, {
180
+ x: clientX - bounds.left,
181
+ y: clientY - bounds.top,
182
+ label: point.label,
183
+ value: point.value,
184
+ color: point.color
185
+ });
186
+ }
187
+ hideTooltip() {
188
+ this.activeIndex.set(null);
189
+ this.widgetTooltip.hide(this.tooltipOwner);
190
+ }
191
+ measure(host) {
192
+ const width = host.clientWidth;
193
+ const height = host.clientHeight;
194
+ const current = this.size();
195
+ if (current.width !== width || current.height !== height) this.size.set({
196
+ width,
197
+ height
198
+ });
199
+ }
200
+ static ɵfac = i0.ɵɵngDeclareFactory({
201
+ minVersion: "12.0.0",
202
+ version: "22.2.4",
203
+ ngImport: i0,
204
+ type: InteractiveChart,
205
+ deps: [],
206
+ target: i0.ɵɵFactoryTarget.Directive
207
+ });
208
+ static ɵdir = i0.ɵɵngDeclareDirective({
209
+ minVersion: "17.2.0",
210
+ version: "22.2.4",
211
+ type: InteractiveChart,
212
+ isStandalone: true,
213
+ inputs: {
214
+ element: {
215
+ classPropertyName: "element",
216
+ publicName: "element",
217
+ isSignal: true,
218
+ isRequired: true,
219
+ transformFunction: null
220
+ },
221
+ sensitiveHidden: {
222
+ classPropertyName: "sensitiveHidden",
223
+ publicName: "sensitiveHidden",
224
+ isSignal: true,
225
+ isRequired: false,
226
+ transformFunction: null
227
+ },
228
+ locale: {
229
+ classPropertyName: "locale",
230
+ publicName: "locale",
231
+ isSignal: true,
232
+ isRequired: false,
233
+ transformFunction: null
234
+ }
235
+ },
236
+ host: { listeners: { "document:pointerdown": "onDocumentPointerDown($event)" } },
237
+ viewQueries: [{
238
+ propertyName: "host",
239
+ first: true,
240
+ predicate: ["chartHost"],
241
+ descendants: true,
242
+ isSignal: true
243
+ }],
244
+ ngImport: i0
245
+ });
246
+ };
247
+ i0.ɵɵngDeclareClassMetadata({
248
+ minVersion: "12.0.0",
249
+ version: "22.2.4",
250
+ ngImport: i0,
251
+ type: InteractiveChart,
252
+ decorators: [{
253
+ type: Directive,
254
+ args: [{ host: { "(document:pointerdown)": "onDocumentPointerDown($event)" } }]
255
+ }],
256
+ ctorParameters: () => [],
257
+ propDecorators: {
258
+ element: [{
259
+ type: i0.Input,
260
+ args: [{
261
+ isSignal: true,
262
+ alias: "element",
263
+ required: true
264
+ }]
265
+ }],
266
+ sensitiveHidden: [{
267
+ type: i0.Input,
268
+ args: [{
269
+ isSignal: true,
270
+ alias: "sensitiveHidden",
271
+ required: false
272
+ }]
273
+ }],
274
+ locale: [{
275
+ type: i0.Input,
276
+ args: [{
277
+ isSignal: true,
278
+ alias: "locale",
279
+ required: false
280
+ }]
281
+ }],
282
+ host: [{
283
+ type: i0.ViewChild,
284
+ args: ["chartHost", { isSignal: true }]
285
+ }]
286
+ }
287
+ });
288
+ var GaugeChartRenderer = class GaugeChartRenderer extends InteractiveChart {
289
+ layout = computed(() => {
290
+ const { width, height } = this.size();
291
+ return width > 0 && height > 0 ? gaugeChartLayout(this.element(), width, height) : null;
292
+ }, ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
293
+ points = computed(() => {
294
+ const layout = this.layout();
295
+ const element = this.element();
296
+ return layout ? [{
297
+ index: 0,
298
+ label: element.title || this.locale().aria.chart.gaugeValueLabel,
299
+ value: element.data.value,
300
+ color: element.style.color.fill,
301
+ anchorX: layout.centerX,
302
+ anchorY: layout.centerY - layout.radius
303
+ }] : [];
304
+ }, ...ngDevMode ? [{ debugName: "points" }] : /* istanbul ignore next */ []);
305
+ roundedValue(element) {
306
+ return Math.round(element.data.value);
307
+ }
308
+ static ɵfac = i0.ɵɵngDeclareFactory({
309
+ minVersion: "12.0.0",
310
+ version: "22.2.4",
311
+ ngImport: i0,
312
+ type: GaugeChartRenderer,
313
+ deps: null,
314
+ target: i0.ɵɵFactoryTarget.Component
315
+ });
316
+ static ɵcmp = i0.ɵɵngDeclareComponent({
317
+ minVersion: "17.0.0",
318
+ version: "22.2.4",
319
+ type: GaugeChartRenderer,
320
+ isStandalone: true,
321
+ selector: "widget-gauge-chart",
322
+ usesInheritance: true,
323
+ ngImport: i0,
324
+ template: "<div\n class=\"chart-chart chart-stack\"\n [attr.aria-hidden]=\"sensitiveHidden() ? 'true' : null\"\n [style.pointer-events]=\"sensitiveHidden() ? 'none' : null\"\n [style.font-size.px]=\"element().style.font.size\"\n>\n <div #chartHost class=\"chart-host\">\n <svg\n class=\"chart-svg gauge-chart\"\n role=\"img\"\n [attr.aria-label]=\"ariaLabel(element())\"\n [attr.aria-describedby]=\"sensitiveHidden() ? null : summaryId\"\n [attr.tabindex]=\"sensitiveHidden() ? -1 : 0\"\n [attr.width]=\"size().width\"\n [attr.height]=\"size().height\"\n (focus)=\"focus()\"\n (blur)=\"pointerLeave()\"\n (keydown)=\"keyDown($event)\"\n >\n @if (layout(); as gauge) {\n <g\n class=\"chart-shape\"\n (pointerenter)=\"pointerMove(0, $event)\"\n (pointermove)=\"pointerMove(0, $event)\"\n (pointerdown)=\"pointerMove(0, $event)\"\n (pointerleave)=\"pointerLeave()\"\n >\n <g [attr.transform]=\"'translate(' + gauge.centerX + ',' + gauge.centerY + ')'\">\n <path [attr.d]=\"gauge.track\" [attr.fill]=\"element().style.color.track\" />\n @if (gauge.fill) {\n <path [attr.d]=\"gauge.fill\" [attr.fill]=\"element().style.color.fill\" />\n }\n </g>\n @for (tick of gauge.ticks; track $index) {\n <line\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n [attr.stroke]=\"element().style.color.legend\"\n [attr.stroke-width]=\"tick.major ? 2 : 1\"\n />\n }\n @for (label of gauge.labels; track $index) {\n <text\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n [attr.x]=\"label.x\"\n [attr.y]=\"label.y\"\n [attr.fill]=\"element().style.color.legend\"\n >\n {{ label.text }}\n </text>\n }\n <polygon [attr.points]=\"gauge.pointer\" [attr.fill]=\"element().style.color.legend\" />\n <circle\n [attr.cx]=\"gauge.centerX\"\n [attr.cy]=\"gauge.centerY\"\n r=\"4\"\n [attr.fill]=\"element().style.color.legend\"\n />\n @if (element().showLegend) {\n <text\n class=\"gauge-value\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n [attr.x]=\"gauge.centerX\"\n [attr.y]=\"gauge.valueY\"\n [attr.fill]=\"element().style.color.legend\"\n >\n {{ roundedValue(element()) }}\n </text>\n }\n </g>\n }\n </svg>\n </div>\n @if (element().title) {\n <span class=\"chart-title\" [style.color]=\"element().style.color.title\">{{\n element().title\n }}</span>\n }\n @if (!sensitiveHidden()) {\n <span class=\"visually-hidden\" [id]=\"summaryId\">{{ accessibilitySummary(element()) }}</span>\n <span class=\"visually-hidden\" aria-live=\"polite\">{{ announcement() }}</span>\n }\n</div>\n",
325
+ styles: [":host{display:block;width:100%;height:100%;min-width:0;min-height:0;--widget-renderer-chart-min-height: 40px}.chart-chart{position:relative;width:100%;height:100%;min-height:var(--widget-renderer-chart-min-height)}.chart-host{position:absolute;inset:0;overflow:hidden}.chart-stack{display:flex;flex-direction:column}.chart-stack .chart-host{position:relative;flex:1 1 auto;min-height:0}.chart-svg{position:absolute;inset:0;display:block;font-family:inherit}.chart-svg:focus{outline:none}.chart-svg:focus-visible{outline:2px solid var(--widget-renderer-focus-ring-contrast, #fff);outline-offset:-2px;box-shadow:inset 0 0 0 4px var(--widget-renderer-focus-ring, #1d4ed8)}.chart-title{overflow:hidden;flex:0 0 auto;padding:5px 5px 0;font-weight:700;text-align:center;text-overflow:ellipsis;white-space:nowrap}.chart-legend{display:flex;flex:0 0 auto;flex-wrap:wrap;justify-content:center;gap:5px 10px;padding:4px 5px 10px}.chart-legend-item{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.chart-legend-marker{width:25px;height:14px;flex:0 0 auto;border-radius:4px}.chart-shape{cursor:pointer;transition:opacity .12s ease}.chart-shape.is-dimmed{opacity:.55}@media(prefers-reduced-motion:reduce){.chart-shape{transition:none}}.series-chart line{shape-rendering:crispEdges}.series-title{font-weight:700}.series-pointer{fill:#96969633}.series-pointer-line{stroke:#b6b9c0;stroke-dasharray:4 3}.series-line{fill:none;stroke-width:2}.series-point{stroke:none}.series-hit{fill:transparent;cursor:pointer}.gauge-value{font-weight:700}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
326
+ });
327
+ };
328
+ i0.ɵɵngDeclareClassMetadata({
329
+ minVersion: "12.0.0",
330
+ version: "22.2.4",
331
+ ngImport: i0,
332
+ type: GaugeChartRenderer,
333
+ decorators: [{
334
+ type: Component,
335
+ args: [{
336
+ selector: "widget-gauge-chart",
337
+ template: "<div\n class=\"chart-chart chart-stack\"\n [attr.aria-hidden]=\"sensitiveHidden() ? 'true' : null\"\n [style.pointer-events]=\"sensitiveHidden() ? 'none' : null\"\n [style.font-size.px]=\"element().style.font.size\"\n>\n <div #chartHost class=\"chart-host\">\n <svg\n class=\"chart-svg gauge-chart\"\n role=\"img\"\n [attr.aria-label]=\"ariaLabel(element())\"\n [attr.aria-describedby]=\"sensitiveHidden() ? null : summaryId\"\n [attr.tabindex]=\"sensitiveHidden() ? -1 : 0\"\n [attr.width]=\"size().width\"\n [attr.height]=\"size().height\"\n (focus)=\"focus()\"\n (blur)=\"pointerLeave()\"\n (keydown)=\"keyDown($event)\"\n >\n @if (layout(); as gauge) {\n <g\n class=\"chart-shape\"\n (pointerenter)=\"pointerMove(0, $event)\"\n (pointermove)=\"pointerMove(0, $event)\"\n (pointerdown)=\"pointerMove(0, $event)\"\n (pointerleave)=\"pointerLeave()\"\n >\n <g [attr.transform]=\"'translate(' + gauge.centerX + ',' + gauge.centerY + ')'\">\n <path [attr.d]=\"gauge.track\" [attr.fill]=\"element().style.color.track\" />\n @if (gauge.fill) {\n <path [attr.d]=\"gauge.fill\" [attr.fill]=\"element().style.color.fill\" />\n }\n </g>\n @for (tick of gauge.ticks; track $index) {\n <line\n [attr.x1]=\"tick.x1\"\n [attr.y1]=\"tick.y1\"\n [attr.x2]=\"tick.x2\"\n [attr.y2]=\"tick.y2\"\n [attr.stroke]=\"element().style.color.legend\"\n [attr.stroke-width]=\"tick.major ? 2 : 1\"\n />\n }\n @for (label of gauge.labels; track $index) {\n <text\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n [attr.x]=\"label.x\"\n [attr.y]=\"label.y\"\n [attr.fill]=\"element().style.color.legend\"\n >\n {{ label.text }}\n </text>\n }\n <polygon [attr.points]=\"gauge.pointer\" [attr.fill]=\"element().style.color.legend\" />\n <circle\n [attr.cx]=\"gauge.centerX\"\n [attr.cy]=\"gauge.centerY\"\n r=\"4\"\n [attr.fill]=\"element().style.color.legend\"\n />\n @if (element().showLegend) {\n <text\n class=\"gauge-value\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n [attr.x]=\"gauge.centerX\"\n [attr.y]=\"gauge.valueY\"\n [attr.fill]=\"element().style.color.legend\"\n >\n {{ roundedValue(element()) }}\n </text>\n }\n </g>\n }\n </svg>\n </div>\n @if (element().title) {\n <span class=\"chart-title\" [style.color]=\"element().style.color.title\">{{\n element().title\n }}</span>\n }\n @if (!sensitiveHidden()) {\n <span class=\"visually-hidden\" [id]=\"summaryId\">{{ accessibilitySummary(element()) }}</span>\n <span class=\"visually-hidden\" aria-live=\"polite\">{{ announcement() }}</span>\n }\n</div>\n",
338
+ styles: [":host{display:block;width:100%;height:100%;min-width:0;min-height:0;--widget-renderer-chart-min-height: 40px}.chart-chart{position:relative;width:100%;height:100%;min-height:var(--widget-renderer-chart-min-height)}.chart-host{position:absolute;inset:0;overflow:hidden}.chart-stack{display:flex;flex-direction:column}.chart-stack .chart-host{position:relative;flex:1 1 auto;min-height:0}.chart-svg{position:absolute;inset:0;display:block;font-family:inherit}.chart-svg:focus{outline:none}.chart-svg:focus-visible{outline:2px solid var(--widget-renderer-focus-ring-contrast, #fff);outline-offset:-2px;box-shadow:inset 0 0 0 4px var(--widget-renderer-focus-ring, #1d4ed8)}.chart-title{overflow:hidden;flex:0 0 auto;padding:5px 5px 0;font-weight:700;text-align:center;text-overflow:ellipsis;white-space:nowrap}.chart-legend{display:flex;flex:0 0 auto;flex-wrap:wrap;justify-content:center;gap:5px 10px;padding:4px 5px 10px}.chart-legend-item{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.chart-legend-marker{width:25px;height:14px;flex:0 0 auto;border-radius:4px}.chart-shape{cursor:pointer;transition:opacity .12s ease}.chart-shape.is-dimmed{opacity:.55}@media(prefers-reduced-motion:reduce){.chart-shape{transition:none}}.series-chart line{shape-rendering:crispEdges}.series-title{font-weight:700}.series-pointer{fill:#96969633}.series-pointer-line{stroke:#b6b9c0;stroke-dasharray:4 3}.series-line{fill:none;stroke-width:2}.series-point{stroke:none}.series-hit{fill:transparent;cursor:pointer}.gauge-value{font-weight:700}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
339
+ }]
340
+ }]
341
+ });
342
+ const HOVER_GROWTH = 6;
343
+ function chartColor(point, index) {
344
+ return point.color || defaultChartColor(index);
345
+ }
346
+ function pieChartLayout(element, width, height) {
347
+ const outerRadius = Math.max(0, Math.min(width, height) / 2 * .86 - HOVER_GROWTH);
348
+ const innerRadius = element.type === "donut" ? outerRadius * .62 : 0;
349
+ const shape = arc().innerRadius(innerRadius);
350
+ const arcs = pie().sort(null).value(({ value }) => Math.max(0, value))(element.data);
351
+ return {
352
+ centerX: width / 2,
353
+ centerY: height / 2,
354
+ innerRadius,
355
+ outerRadius,
356
+ slices: arcs.map((slice, index) => {
357
+ const point = element.data[index];
358
+ const angles = {
359
+ startAngle: slice.startAngle,
360
+ endAngle: slice.endAngle
361
+ };
362
+ const centroid = shape.outerRadius(outerRadius).centroid(angles);
363
+ return {
364
+ index,
365
+ label: point.label,
366
+ value: point.value,
367
+ color: chartColor(point, index),
368
+ path: shape.outerRadius(outerRadius)(angles) ?? "",
369
+ activePath: shape.outerRadius(outerRadius + HOVER_GROWTH)(angles) ?? "",
370
+ centroid: [centroid[0] + width / 2, centroid[1] + height / 2]
371
+ };
372
+ })
373
+ };
374
+ }
375
+ function funnelChartLayout(element, width, height) {
376
+ const gap = 3;
377
+ const count = element.data.length;
378
+ if (!count) return [];
379
+ const boxLeft = width * .08;
380
+ const boxWidth = width * .84;
381
+ const top = 4;
382
+ const itemHeight = Math.max(1, (height - 8 - gap * (count - 1)) / count);
383
+ const max = Math.max(1, ...element.data.map(({ value }) => value));
384
+ const size = (value) => boxWidth * (.1 + .78 * Math.min(1, Math.max(0, value / max)));
385
+ const order = element.data.map((point, index) => ({
386
+ point,
387
+ index
388
+ })).sort((a, b) => b.point.value - a.point.value);
389
+ const centerX = boxLeft + boxWidth / 2;
390
+ return order.map(({ point, index }, position) => {
391
+ const y = top + position * (itemHeight + gap);
392
+ const topWidth = size(point.value);
393
+ const bottomWidth = size(order[position + 1]?.point.value ?? 0);
394
+ return {
395
+ index,
396
+ label: point.label,
397
+ value: point.value,
398
+ color: chartColor(point, index),
399
+ points: [
400
+ [centerX - topWidth / 2, y],
401
+ [centerX + topWidth / 2, y],
402
+ [centerX + bottomWidth / 2, y + itemHeight],
403
+ [centerX - bottomWidth / 2, y + itemHeight]
404
+ ].map(([x, pointY]) => `${x},${pointY}`).join(" "),
405
+ centerX,
406
+ centerY: y + itemHeight / 2
407
+ };
408
+ }).sort((a, b) => a.index - b.index);
409
+ }
410
+ var PartChartRenderer = class PartChartRenderer extends InteractiveChart {
411
+ pie = computed(() => {
412
+ const element = this.element();
413
+ const { width, height } = this.size();
414
+ return element.type !== "funnel" && width > 0 && height > 0 ? pieChartLayout(element, width, height) : null;
415
+ }, ...ngDevMode ? [{ debugName: "pie" }] : /* istanbul ignore next */ []);
416
+ funnel = computed(() => {
417
+ const element = this.element();
418
+ const { width, height } = this.size();
419
+ return element.type === "funnel" && width > 0 && height > 0 ? funnelChartLayout(element, width, height) : null;
420
+ }, ...ngDevMode ? [{ debugName: "funnel" }] : /* istanbul ignore next */ []);
421
+ legend = computed(() => this.element().data.map((point, index) => ({
422
+ index,
423
+ label: point.label,
424
+ color: chartColor(point, index)
425
+ })), ...ngDevMode ? [{ debugName: "legend" }] : /* istanbul ignore next */ []);
426
+ points = computed(() => {
427
+ const pie = this.pie();
428
+ if (pie) return pie.slices.map(({ index, label, value, color, centroid }) => ({
429
+ index,
430
+ label,
431
+ value,
432
+ color,
433
+ anchorX: centroid[0],
434
+ anchorY: centroid[1]
435
+ }));
436
+ return (this.funnel() ?? []).map(({ index, label, value, color, centerX, centerY }) => ({
437
+ index,
438
+ label,
439
+ value,
440
+ color,
441
+ anchorX: centerX,
442
+ anchorY: centerY
443
+ }));
444
+ }, ...ngDevMode ? [{ debugName: "points" }] : /* istanbul ignore next */ []);
445
+ static ɵfac = i0.ɵɵngDeclareFactory({
446
+ minVersion: "12.0.0",
447
+ version: "22.2.4",
448
+ ngImport: i0,
449
+ type: PartChartRenderer,
450
+ deps: null,
451
+ target: i0.ɵɵFactoryTarget.Component
452
+ });
453
+ static ɵcmp = i0.ɵɵngDeclareComponent({
454
+ minVersion: "17.0.0",
455
+ version: "22.2.4",
456
+ type: PartChartRenderer,
457
+ isStandalone: true,
458
+ selector: "widget-part-chart",
459
+ usesInheritance: true,
460
+ ngImport: i0,
461
+ template: "<div\n class=\"chart-chart chart-stack\"\n [attr.aria-hidden]=\"sensitiveHidden() ? 'true' : null\"\n [style.pointer-events]=\"sensitiveHidden() ? 'none' : null\"\n [style.font-size.px]=\"element().style.font.size\"\n>\n @if (element().title) {\n <span class=\"chart-title\" [style.color]=\"element().style.color.title\">{{\n element().title\n }}</span>\n }\n <div #chartHost class=\"chart-host\">\n <svg\n class=\"chart-svg part-chart\"\n role=\"img\"\n [attr.aria-label]=\"ariaLabel(element())\"\n [attr.aria-describedby]=\"sensitiveHidden() ? null : summaryId\"\n [attr.tabindex]=\"sensitiveHidden() || !element().data.length ? -1 : 0\"\n [attr.width]=\"size().width\"\n [attr.height]=\"size().height\"\n (focus)=\"focus()\"\n (blur)=\"pointerLeave()\"\n (keydown)=\"keyDown($event)\"\n >\n @if (pie(); as chart) {\n <g [attr.transform]=\"'translate(' + chart.centerX + ',' + chart.centerY + ')'\">\n @for (slice of chart.slices; track slice.index) {\n <path\n class=\"chart-shape\"\n [class.is-dimmed]=\"activeIndex() !== null && activeIndex() !== slice.index\"\n [attr.d]=\"activeIndex() === slice.index ? slice.activePath : slice.path\"\n [attr.fill]=\"slice.color\"\n (pointerenter)=\"pointerMove(slice.index, $event)\"\n (pointermove)=\"pointerMove(slice.index, $event)\"\n (pointerdown)=\"pointerMove(slice.index, $event)\"\n (pointerleave)=\"pointerLeave()\"\n />\n }\n </g>\n }\n @if (funnel(); as segments) {\n @for (segment of segments; track segment.index) {\n <polygon\n class=\"chart-shape\"\n [class.is-dimmed]=\"activeIndex() !== null && activeIndex() !== segment.index\"\n [attr.points]=\"segment.points\"\n [attr.fill]=\"segment.color\"\n (pointerenter)=\"pointerMove(segment.index, $event)\"\n (pointermove)=\"pointerMove(segment.index, $event)\"\n (pointerdown)=\"pointerMove(segment.index, $event)\"\n (pointerleave)=\"pointerLeave()\"\n />\n }\n }\n </svg>\n </div>\n @if (element().showLegend) {\n <div class=\"chart-legend\" [style.color]=\"element().style.color.legend\" aria-hidden=\"true\">\n @for (item of legend(); track item.index) {\n <span class=\"chart-legend-item\"\n ><span class=\"chart-legend-marker\" [style.background]=\"item.color\"></span\n >{{ item.label }}</span\n >\n }\n </div>\n }\n @if (!sensitiveHidden()) {\n <span class=\"visually-hidden\" [id]=\"summaryId\">{{ accessibilitySummary(element()) }}</span>\n <span class=\"visually-hidden\" aria-live=\"polite\">{{ announcement() }}</span>\n }\n</div>\n",
462
+ styles: [":host{display:block;width:100%;height:100%;min-width:0;min-height:0;--widget-renderer-chart-min-height: 40px}.chart-chart{position:relative;width:100%;height:100%;min-height:var(--widget-renderer-chart-min-height)}.chart-host{position:absolute;inset:0;overflow:hidden}.chart-stack{display:flex;flex-direction:column}.chart-stack .chart-host{position:relative;flex:1 1 auto;min-height:0}.chart-svg{position:absolute;inset:0;display:block;font-family:inherit}.chart-svg:focus{outline:none}.chart-svg:focus-visible{outline:2px solid var(--widget-renderer-focus-ring-contrast, #fff);outline-offset:-2px;box-shadow:inset 0 0 0 4px var(--widget-renderer-focus-ring, #1d4ed8)}.chart-title{overflow:hidden;flex:0 0 auto;padding:5px 5px 0;font-weight:700;text-align:center;text-overflow:ellipsis;white-space:nowrap}.chart-legend{display:flex;flex:0 0 auto;flex-wrap:wrap;justify-content:center;gap:5px 10px;padding:4px 5px 10px}.chart-legend-item{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.chart-legend-marker{width:25px;height:14px;flex:0 0 auto;border-radius:4px}.chart-shape{cursor:pointer;transition:opacity .12s ease}.chart-shape.is-dimmed{opacity:.55}@media(prefers-reduced-motion:reduce){.chart-shape{transition:none}}.series-chart line{shape-rendering:crispEdges}.series-title{font-weight:700}.series-pointer{fill:#96969633}.series-pointer-line{stroke:#b6b9c0;stroke-dasharray:4 3}.series-line{fill:none;stroke-width:2}.series-point{stroke:none}.series-hit{fill:transparent;cursor:pointer}.gauge-value{font-weight:700}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
463
+ });
464
+ };
465
+ i0.ɵɵngDeclareClassMetadata({
466
+ minVersion: "12.0.0",
467
+ version: "22.2.4",
468
+ ngImport: i0,
469
+ type: PartChartRenderer,
470
+ decorators: [{
471
+ type: Component,
472
+ args: [{
473
+ selector: "widget-part-chart",
474
+ template: "<div\n class=\"chart-chart chart-stack\"\n [attr.aria-hidden]=\"sensitiveHidden() ? 'true' : null\"\n [style.pointer-events]=\"sensitiveHidden() ? 'none' : null\"\n [style.font-size.px]=\"element().style.font.size\"\n>\n @if (element().title) {\n <span class=\"chart-title\" [style.color]=\"element().style.color.title\">{{\n element().title\n }}</span>\n }\n <div #chartHost class=\"chart-host\">\n <svg\n class=\"chart-svg part-chart\"\n role=\"img\"\n [attr.aria-label]=\"ariaLabel(element())\"\n [attr.aria-describedby]=\"sensitiveHidden() ? null : summaryId\"\n [attr.tabindex]=\"sensitiveHidden() || !element().data.length ? -1 : 0\"\n [attr.width]=\"size().width\"\n [attr.height]=\"size().height\"\n (focus)=\"focus()\"\n (blur)=\"pointerLeave()\"\n (keydown)=\"keyDown($event)\"\n >\n @if (pie(); as chart) {\n <g [attr.transform]=\"'translate(' + chart.centerX + ',' + chart.centerY + ')'\">\n @for (slice of chart.slices; track slice.index) {\n <path\n class=\"chart-shape\"\n [class.is-dimmed]=\"activeIndex() !== null && activeIndex() !== slice.index\"\n [attr.d]=\"activeIndex() === slice.index ? slice.activePath : slice.path\"\n [attr.fill]=\"slice.color\"\n (pointerenter)=\"pointerMove(slice.index, $event)\"\n (pointermove)=\"pointerMove(slice.index, $event)\"\n (pointerdown)=\"pointerMove(slice.index, $event)\"\n (pointerleave)=\"pointerLeave()\"\n />\n }\n </g>\n }\n @if (funnel(); as segments) {\n @for (segment of segments; track segment.index) {\n <polygon\n class=\"chart-shape\"\n [class.is-dimmed]=\"activeIndex() !== null && activeIndex() !== segment.index\"\n [attr.points]=\"segment.points\"\n [attr.fill]=\"segment.color\"\n (pointerenter)=\"pointerMove(segment.index, $event)\"\n (pointermove)=\"pointerMove(segment.index, $event)\"\n (pointerdown)=\"pointerMove(segment.index, $event)\"\n (pointerleave)=\"pointerLeave()\"\n />\n }\n }\n </svg>\n </div>\n @if (element().showLegend) {\n <div class=\"chart-legend\" [style.color]=\"element().style.color.legend\" aria-hidden=\"true\">\n @for (item of legend(); track item.index) {\n <span class=\"chart-legend-item\"\n ><span class=\"chart-legend-marker\" [style.background]=\"item.color\"></span\n >{{ item.label }}</span\n >\n }\n </div>\n }\n @if (!sensitiveHidden()) {\n <span class=\"visually-hidden\" [id]=\"summaryId\">{{ accessibilitySummary(element()) }}</span>\n <span class=\"visually-hidden\" aria-live=\"polite\">{{ announcement() }}</span>\n }\n</div>\n",
475
+ styles: [":host{display:block;width:100%;height:100%;min-width:0;min-height:0;--widget-renderer-chart-min-height: 40px}.chart-chart{position:relative;width:100%;height:100%;min-height:var(--widget-renderer-chart-min-height)}.chart-host{position:absolute;inset:0;overflow:hidden}.chart-stack{display:flex;flex-direction:column}.chart-stack .chart-host{position:relative;flex:1 1 auto;min-height:0}.chart-svg{position:absolute;inset:0;display:block;font-family:inherit}.chart-svg:focus{outline:none}.chart-svg:focus-visible{outline:2px solid var(--widget-renderer-focus-ring-contrast, #fff);outline-offset:-2px;box-shadow:inset 0 0 0 4px var(--widget-renderer-focus-ring, #1d4ed8)}.chart-title{overflow:hidden;flex:0 0 auto;padding:5px 5px 0;font-weight:700;text-align:center;text-overflow:ellipsis;white-space:nowrap}.chart-legend{display:flex;flex:0 0 auto;flex-wrap:wrap;justify-content:center;gap:5px 10px;padding:4px 5px 10px}.chart-legend-item{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.chart-legend-marker{width:25px;height:14px;flex:0 0 auto;border-radius:4px}.chart-shape{cursor:pointer;transition:opacity .12s ease}.chart-shape.is-dimmed{opacity:.55}@media(prefers-reduced-motion:reduce){.chart-shape{transition:none}}.series-chart line{shape-rendering:crispEdges}.series-title{font-weight:700}.series-pointer{fill:#96969633}.series-pointer-line{stroke:#b6b9c0;stroke-dasharray:4 3}.series-line{fill:none;stroke-width:2}.series-point{stroke:none}.series-hit{fill:transparent;cursor:pointer}.gauge-value{font-weight:700}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
476
+ }]
477
+ }]
478
+ });
479
+ var ProgressElementRenderer = class ProgressElementRenderer {
480
+ element = input.required(...ngDevMode ? [{ debugName: "element" }] : /* istanbul ignore next */ []);
481
+ sensitiveHidden = input(false, ...ngDevMode ? [{ debugName: "sensitiveHidden" }] : /* istanbul ignore next */ []);
482
+ locale = input(defaultWidgetRendererLocale, ...ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []);
483
+ summaryId = `progress-summary-${crypto.randomUUID()}`;
484
+ tooltipIndex = signal(null, ...ngDevMode ? [{ debugName: "tooltipIndex" }] : /* istanbul ignore next */ []);
485
+ widgetTooltip = inject(WidgetTooltip);
486
+ tooltipOwner = {};
487
+ tooltipHideTimer = null;
488
+ constructor() {
489
+ effect(() => {
490
+ this.element();
491
+ this.sensitiveHidden();
492
+ this.clearTooltip();
493
+ });
494
+ }
495
+ ngOnDestroy() {
496
+ this.cancelTooltipHide();
497
+ this.widgetTooltip.hide(this.tooltipOwner);
498
+ }
499
+ progressStyle(element) {
500
+ const radius = element.style.radius ?? {
501
+ segment: 0,
502
+ track: 999
503
+ };
504
+ return {
505
+ "--progress-track": element.style.color.track,
506
+ "--progress-title-color": element.style.color.title,
507
+ "--progress-legend-color": element.style.color.legend,
508
+ "--progress-font-size": `${element.style?.font.size ?? 11}px`,
509
+ "--progress-segment-radius": `${radius.segment}px`,
510
+ "--progress-track-radius": `${radius.track}px`
511
+ };
512
+ }
513
+ progressItems(element) {
514
+ const range = element.data.max - element.data.min;
515
+ let position = element.data.min;
516
+ return element.data.items.map((item, index) => {
517
+ const start = position;
518
+ position += item.value;
519
+ return {
520
+ item,
521
+ index,
522
+ start,
523
+ end: position,
524
+ width: item.value / range * 100,
525
+ center: (start - element.data.min + item.value / 2) / range * 100
526
+ };
527
+ });
528
+ }
529
+ progressSegments(element) {
530
+ return this.progressItems(element).filter(({ item }) => item.kind === "segment");
531
+ }
532
+ segment(item) {
533
+ return item;
534
+ }
535
+ segmentStyle(width, color) {
536
+ return {
537
+ width: `${width}%`,
538
+ ...color ? { background: color } : {}
539
+ };
540
+ }
541
+ progressValue(element) {
542
+ return element.data.items.reduce((total, item) => total + (item.kind === "segment" ? item.value : 0), 0);
543
+ }
544
+ showTooltip(index, event) {
545
+ if (this.sensitiveHidden()) return;
546
+ this.cancelTooltipHide();
547
+ this.showTooltipAt(index, event.currentTarget instanceof HTMLElement ? event.currentTarget : event.target instanceof HTMLElement ? event.target : null);
548
+ }
549
+ hideTooltip(index) {
550
+ this.cancelTooltipHide();
551
+ this.tooltipHideTimer = setTimeout(() => {
552
+ if (this.tooltipIndex() === index) {
553
+ this.tooltipIndex.set(null);
554
+ this.widgetTooltip.hide(this.tooltipOwner);
555
+ }
556
+ this.tooltipHideTimer = null;
557
+ }, 100);
558
+ }
559
+ moveTooltip(index, event) {
560
+ if (this.sensitiveHidden() || event.pointerType === "touch") return;
561
+ this.positionTooltip(index, event);
562
+ }
563
+ toggleTouchTooltip(index, event) {
564
+ if (this.sensitiveHidden() || event.pointerType === "mouse") return;
565
+ event.stopPropagation();
566
+ this.cancelTooltipHide();
567
+ if (this.tooltipIndex() === index) {
568
+ this.tooltipIndex.set(null);
569
+ this.widgetTooltip.hide(this.tooltipOwner);
570
+ return;
571
+ }
572
+ this.positionTooltip(index, event);
573
+ }
574
+ segmentKeyDown(index, event) {
575
+ if (event.key !== "Escape") return;
576
+ event.preventDefault();
577
+ this.hideTooltip(index);
578
+ }
579
+ onDocumentPointerDown(event) {
580
+ if (!(event.target instanceof Element) || !event.target.closest(".progress-segment")) {
581
+ this.tooltipIndex.set(null);
582
+ this.widgetTooltip.hide(this.tooltipOwner);
583
+ }
584
+ }
585
+ positionTooltip(index, event) {
586
+ const target = event.currentTarget;
587
+ if (!(target instanceof HTMLElement)) return;
588
+ this.showTooltipAt(index, target, event.clientX, event.clientY);
589
+ }
590
+ showTooltipAt(index, target, x, y) {
591
+ if (!target) return;
592
+ const shell = this.widgetTooltip.overlayElement()?.parentElement;
593
+ if (!shell) return;
594
+ const bounds = shell.getBoundingClientRect();
595
+ const targetBounds = target.getBoundingClientRect();
596
+ const entry = this.progressSegments(this.element()).find(({ index: entryIndex }) => entryIndex === index);
597
+ if (!entry) return;
598
+ const segment = this.segment(entry.item);
599
+ this.tooltipIndex.set(index);
600
+ this.widgetTooltip.show(this.tooltipOwner, {
601
+ x: (x ?? targetBounds.left + targetBounds.width / 2) - bounds.left,
602
+ y: (y ?? targetBounds.top) - bounds.top,
603
+ label: segment.label,
604
+ value: segment.value,
605
+ color: segment.color
606
+ });
607
+ }
608
+ cancelTooltipHide() {
609
+ if (this.tooltipHideTimer) clearTimeout(this.tooltipHideTimer);
610
+ this.tooltipHideTimer = null;
611
+ }
612
+ clearTooltip() {
613
+ this.cancelTooltipHide();
614
+ this.tooltipIndex.set(null);
615
+ this.widgetTooltip.hide(this.tooltipOwner);
616
+ }
617
+ progressTextAlign(element) {
618
+ return (element.grid.anchor ?? "center").endsWith("left") ? "left" : (element.grid.anchor ?? "center").endsWith("right") ? "right" : "center";
619
+ }
620
+ ariaLabel(element) {
621
+ return chartAriaLabel(element, this.locale().aria.chart);
622
+ }
623
+ accessibilitySummary(element) {
624
+ return chartAccessibilitySummary(element, this.locale().aria.chart);
625
+ }
626
+ static ɵfac = i0.ɵɵngDeclareFactory({
627
+ minVersion: "12.0.0",
628
+ version: "22.2.4",
629
+ ngImport: i0,
630
+ type: ProgressElementRenderer,
631
+ deps: [],
632
+ target: i0.ɵɵFactoryTarget.Component
633
+ });
634
+ static ɵcmp = i0.ɵɵngDeclareComponent({
635
+ minVersion: "17.0.0",
636
+ version: "22.2.4",
637
+ type: ProgressElementRenderer,
638
+ isStandalone: true,
639
+ selector: "widget-progress-element",
640
+ inputs: {
641
+ element: {
642
+ classPropertyName: "element",
643
+ publicName: "element",
644
+ isSignal: true,
645
+ isRequired: true,
646
+ transformFunction: null
647
+ },
648
+ sensitiveHidden: {
649
+ classPropertyName: "sensitiveHidden",
650
+ publicName: "sensitiveHidden",
651
+ isSignal: true,
652
+ isRequired: false,
653
+ transformFunction: null
654
+ },
655
+ locale: {
656
+ classPropertyName: "locale",
657
+ publicName: "locale",
658
+ isSignal: true,
659
+ isRequired: false,
660
+ transformFunction: null
661
+ }
662
+ },
663
+ host: {
664
+ listeners: { "document:pointerdown": "onDocumentPointerDown($event)" },
665
+ classAttribute: "is-progress"
666
+ },
667
+ ngImport: i0,
668
+ template: "<div\n class=\"progress-element\"\n [style]=\"progressStyle(element())\"\n [style.pointer-events]=\"sensitiveHidden() ? 'none' : null\"\n [attr.aria-hidden]=\"sensitiveHidden() ? 'true' : null\"\n>\n @if (!sensitiveHidden()) {\n <span\n class=\"visually-hidden\"\n role=\"progressbar\"\n [attr.aria-label]=\"ariaLabel(element())\"\n [attr.aria-describedby]=\"summaryId\"\n aria-valuemin=\"0\"\n [attr.aria-valuemax]=\"element().data.max - element().data.min\"\n [attr.aria-valuenow]=\"progressValue(element())\"\n ></span>\n }\n @if (element().title) {\n <span class=\"progress-title\" [style.text-align]=\"progressTextAlign(element())\">{{\n element().title\n }}</span>\n }\n <span class=\"progress-track-wrap\"\n ><span class=\"progress-track\">\n @for (entry of progressItems(element()); track entry.index) {\n @if (entry.item.kind === 'segment') {\n <button\n type=\"button\"\n class=\"progress-item progress-segment\"\n [class.is-active]=\"segment(entry.item).active\"\n [style]=\"segmentStyle(entry.width, segment(entry.item).color)\"\n [attr.tabindex]=\"sensitiveHidden() ? -1 : 0\"\n [attr.aria-label]=\"\n locale().aria.chart.progressSegmentLabel(\n segment(entry.item).label,\n segment(entry.item).value.toString()\n )\n \"\n (pointerenter)=\"moveTooltip(entry.index, $event)\"\n (pointermove)=\"moveTooltip(entry.index, $event)\"\n (pointerleave)=\"hideTooltip(entry.index)\"\n (pointerdown)=\"toggleTouchTooltip(entry.index, $event)\"\n (focus)=\"showTooltip(entry.index, $event)\"\n (blur)=\"hideTooltip(entry.index)\"\n (keydown)=\"segmentKeyDown(entry.index, $event)\"\n ></button>\n } @else {\n <span class=\"progress-item progress-gap\" [style]=\"segmentStyle(entry.width)\"></span>\n }\n }\n </span>\n </span>\n @if (element().showLegend) {\n <span class=\"progress-legend\" [style.justify-content]=\"progressTextAlign(element())\">\n @for (entry of progressSegments(element()); track entry.index) {\n <span class=\"progress-label\"\n ><span class=\"legend-marker\" [style.background]=\"segment(entry.item).color\"></span\n >{{ segment(entry.item).label }}: {{ entry.start }}–{{ entry.end }}</span\n >\n }\n </span>\n }\n @if (!sensitiveHidden()) {\n <span class=\"visually-hidden\" [id]=\"summaryId\">{{ accessibilitySummary(element()) }}</span>\n }\n</div>\n",
669
+ styles: [":host{display:block;width:100%;height:auto;max-height:100%;--widget-renderer-progress-label-padding: 6px}.progress-element{display:flex;width:100%;flex-direction:column;justify-content:center;gap:7px;color:inherit;font-size:11px}.progress-track{display:flex;overflow:hidden;height:10px;border:1px solid transparent;border-radius:var(--progress-track-radius);background:var(--progress-track)}.progress-track-wrap{position:relative;display:block}.progress-title{padding-inline:var(--widget-renderer-progress-label-padding);overflow:hidden;color:var(--progress-title-color);font-size:var(--progress-font-size);text-overflow:ellipsis;white-space:nowrap}.progress-item{position:relative;display:block;flex:0 0 auto;height:100%;padding:0;border:0;border-radius:var(--progress-segment-radius)}.progress-segment{cursor:pointer}.progress-segment:focus-visible{z-index:1;outline:2px solid currentColor;outline-offset:-2px}.progress-segment.is-active{overflow:hidden}.progress-segment.is-active:after{position:absolute;inset:0;content:\"\";background:repeating-linear-gradient(135deg,transparent 0,transparent 18px,rgb(255 255 255 / .18) 18px,rgb(255 255 255 / .18) 36px);background-position:0 0;background-size:51px 51px;animation:progress-active .9s linear infinite}@keyframes progress-active{0%{background-position:0 0}to{background-position:51px 0}}@media(prefers-reduced-motion:reduce){.progress-segment.is-active:after,.progress-tooltip{animation:none;transition:none}}.progress-legend{display:flex;flex-wrap:wrap;gap:5px 12px;padding-inline:var(--widget-renderer-progress-label-padding)}.progress-label{display:inline-flex;align-items:center;gap:5px;color:var(--progress-legend-color);font-size:var(--progress-font-size)}.legend-marker,.tooltip-marker{width:9px;height:9px;flex:0 0 auto;border-radius:50%}.progress-tooltip{--tooltip-x: 50%;--tooltip-y: 0px;--tooltip-border: rgb(0 0 0 / .12);position:absolute;z-index:4;top:var(--tooltip-y);left:clamp(64px,var(--tooltip-x),calc(100% - 64px));display:flex;min-width:104px;align-items:center;gap:7px;padding:10px;transform:translate(-50%,calc(-100% - 10px));transition:left .4s cubic-bezier(.23,1,.32,1),top .4s cubic-bezier(.23,1,.32,1);border:1px solid var(--tooltip-border);border-radius:var(--widget-renderer-radius, 4px);background:var(--widget-renderer-control-hover-background, #fff);box-shadow:1px 2px 10px #0003;color:#6e7079;font-size:14px;font-weight:400;line-height:1;pointer-events:none;white-space:nowrap}.progress-tooltip strong{margin-inline-start:auto;color:#464646;font-size:14px;font-weight:900}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
670
+ });
671
+ };
672
+ i0.ɵɵngDeclareClassMetadata({
673
+ minVersion: "12.0.0",
674
+ version: "22.2.4",
675
+ ngImport: i0,
676
+ type: ProgressElementRenderer,
677
+ decorators: [{
678
+ type: Component,
679
+ args: [{
680
+ selector: "widget-progress-element",
681
+ host: {
682
+ class: "is-progress",
683
+ "(document:pointerdown)": "onDocumentPointerDown($event)"
684
+ },
685
+ template: "<div\n class=\"progress-element\"\n [style]=\"progressStyle(element())\"\n [style.pointer-events]=\"sensitiveHidden() ? 'none' : null\"\n [attr.aria-hidden]=\"sensitiveHidden() ? 'true' : null\"\n>\n @if (!sensitiveHidden()) {\n <span\n class=\"visually-hidden\"\n role=\"progressbar\"\n [attr.aria-label]=\"ariaLabel(element())\"\n [attr.aria-describedby]=\"summaryId\"\n aria-valuemin=\"0\"\n [attr.aria-valuemax]=\"element().data.max - element().data.min\"\n [attr.aria-valuenow]=\"progressValue(element())\"\n ></span>\n }\n @if (element().title) {\n <span class=\"progress-title\" [style.text-align]=\"progressTextAlign(element())\">{{\n element().title\n }}</span>\n }\n <span class=\"progress-track-wrap\"\n ><span class=\"progress-track\">\n @for (entry of progressItems(element()); track entry.index) {\n @if (entry.item.kind === 'segment') {\n <button\n type=\"button\"\n class=\"progress-item progress-segment\"\n [class.is-active]=\"segment(entry.item).active\"\n [style]=\"segmentStyle(entry.width, segment(entry.item).color)\"\n [attr.tabindex]=\"sensitiveHidden() ? -1 : 0\"\n [attr.aria-label]=\"\n locale().aria.chart.progressSegmentLabel(\n segment(entry.item).label,\n segment(entry.item).value.toString()\n )\n \"\n (pointerenter)=\"moveTooltip(entry.index, $event)\"\n (pointermove)=\"moveTooltip(entry.index, $event)\"\n (pointerleave)=\"hideTooltip(entry.index)\"\n (pointerdown)=\"toggleTouchTooltip(entry.index, $event)\"\n (focus)=\"showTooltip(entry.index, $event)\"\n (blur)=\"hideTooltip(entry.index)\"\n (keydown)=\"segmentKeyDown(entry.index, $event)\"\n ></button>\n } @else {\n <span class=\"progress-item progress-gap\" [style]=\"segmentStyle(entry.width)\"></span>\n }\n }\n </span>\n </span>\n @if (element().showLegend) {\n <span class=\"progress-legend\" [style.justify-content]=\"progressTextAlign(element())\">\n @for (entry of progressSegments(element()); track entry.index) {\n <span class=\"progress-label\"\n ><span class=\"legend-marker\" [style.background]=\"segment(entry.item).color\"></span\n >{{ segment(entry.item).label }}: {{ entry.start }}–{{ entry.end }}</span\n >\n }\n </span>\n }\n @if (!sensitiveHidden()) {\n <span class=\"visually-hidden\" [id]=\"summaryId\">{{ accessibilitySummary(element()) }}</span>\n }\n</div>\n",
686
+ styles: [":host{display:block;width:100%;height:auto;max-height:100%;--widget-renderer-progress-label-padding: 6px}.progress-element{display:flex;width:100%;flex-direction:column;justify-content:center;gap:7px;color:inherit;font-size:11px}.progress-track{display:flex;overflow:hidden;height:10px;border:1px solid transparent;border-radius:var(--progress-track-radius);background:var(--progress-track)}.progress-track-wrap{position:relative;display:block}.progress-title{padding-inline:var(--widget-renderer-progress-label-padding);overflow:hidden;color:var(--progress-title-color);font-size:var(--progress-font-size);text-overflow:ellipsis;white-space:nowrap}.progress-item{position:relative;display:block;flex:0 0 auto;height:100%;padding:0;border:0;border-radius:var(--progress-segment-radius)}.progress-segment{cursor:pointer}.progress-segment:focus-visible{z-index:1;outline:2px solid currentColor;outline-offset:-2px}.progress-segment.is-active{overflow:hidden}.progress-segment.is-active:after{position:absolute;inset:0;content:\"\";background:repeating-linear-gradient(135deg,transparent 0,transparent 18px,rgb(255 255 255 / .18) 18px,rgb(255 255 255 / .18) 36px);background-position:0 0;background-size:51px 51px;animation:progress-active .9s linear infinite}@keyframes progress-active{0%{background-position:0 0}to{background-position:51px 0}}@media(prefers-reduced-motion:reduce){.progress-segment.is-active:after,.progress-tooltip{animation:none;transition:none}}.progress-legend{display:flex;flex-wrap:wrap;gap:5px 12px;padding-inline:var(--widget-renderer-progress-label-padding)}.progress-label{display:inline-flex;align-items:center;gap:5px;color:var(--progress-legend-color);font-size:var(--progress-font-size)}.legend-marker,.tooltip-marker{width:9px;height:9px;flex:0 0 auto;border-radius:50%}.progress-tooltip{--tooltip-x: 50%;--tooltip-y: 0px;--tooltip-border: rgb(0 0 0 / .12);position:absolute;z-index:4;top:var(--tooltip-y);left:clamp(64px,var(--tooltip-x),calc(100% - 64px));display:flex;min-width:104px;align-items:center;gap:7px;padding:10px;transform:translate(-50%,calc(-100% - 10px));transition:left .4s cubic-bezier(.23,1,.32,1),top .4s cubic-bezier(.23,1,.32,1);border:1px solid var(--tooltip-border);border-radius:var(--widget-renderer-radius, 4px);background:var(--widget-renderer-control-hover-background, #fff);box-shadow:1px 2px 10px #0003;color:#6e7079;font-size:14px;font-weight:400;line-height:1;pointer-events:none;white-space:nowrap}.progress-tooltip strong{margin-inline-start:auto;color:#464646;font-size:14px;font-weight:900}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
687
+ }]
688
+ }],
689
+ ctorParameters: () => [],
690
+ propDecorators: {
691
+ element: [{
692
+ type: i0.Input,
693
+ args: [{
694
+ isSignal: true,
695
+ alias: "element",
696
+ required: true
697
+ }]
698
+ }],
699
+ sensitiveHidden: [{
700
+ type: i0.Input,
701
+ args: [{
702
+ isSignal: true,
703
+ alias: "sensitiveHidden",
704
+ required: false
705
+ }]
706
+ }],
707
+ locale: [{
708
+ type: i0.Input,
709
+ args: [{
710
+ isSignal: true,
711
+ alias: "locale",
712
+ required: false
713
+ }]
714
+ }]
715
+ }
716
+ });
717
+ const CHAR_WIDTH = .6;
718
+ const numberFormat = new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 });
719
+ function niceDomain(start, stop, count) {
720
+ let previous;
721
+ for (let attempt = 0; attempt < 10; attempt++) {
722
+ const step = tickIncrement(start, stop, count);
723
+ if (step === previous || step === 0 || !Number.isFinite(step)) break;
724
+ if (step > 0) {
725
+ start = Math.floor(start / step) * step;
726
+ stop = Math.ceil(stop / step) * step;
727
+ } else {
728
+ start = Math.ceil(start * step) / step;
729
+ stop = Math.floor(stop * step) / step;
730
+ }
731
+ previous = step;
732
+ }
733
+ return [start, stop];
734
+ }
735
+ function estimateTextWidth(text, fontSize) {
736
+ return text.length * fontSize * CHAR_WIDTH;
737
+ }
738
+ function formatAxisValue(value) {
739
+ return numberFormat.format(value);
740
+ }
741
+ function seriesChartLayout(element, width, height) {
742
+ const fontSize = element.style.font.size;
743
+ const values = element.data.map(({ value }) => value);
744
+ const minValue = Math.min(0, ...values);
745
+ const maxValue = Math.max(0, ...values);
746
+ const top = element.title ? Math.max(30, fontSize + 18) : 12;
747
+ const bottom = Math.max(top + 1, height - fontSize - (element.showLegend ? 38 : 34));
748
+ const plotHeight = Math.max(1, bottom - top);
749
+ const tickCount = Math.min(5, Math.max(2, Math.round(plotHeight / 45)));
750
+ const [domainMin, domainMax] = niceDomain(minValue, minValue === maxValue ? 1 : maxValue, tickCount);
751
+ const y = (value) => bottom - (value - domainMin) / (domainMax - domainMin) * (bottom - top);
752
+ const ticks$1 = ticks(domainMin, domainMax, tickCount).map((value) => ({
753
+ value,
754
+ y: y(value),
755
+ label: formatAxisValue(value)
756
+ }));
757
+ const labelWidth = Math.max(0, ...ticks$1.map(({ label }) => estimateTextWidth(label, fontSize)));
758
+ const left = Math.min(width / 2, labelWidth + 34);
759
+ const right = Math.max(left + 1, width - 12);
760
+ const bandWidth = (right - left) / Math.max(1, element.data.length);
761
+ const barWidth = Math.max(1, Math.min(bandWidth * .6, 48));
762
+ const labelSlot = Math.max(1, ...element.data.map(({ label }) => estimateTextWidth(label, fontSize) + 8));
763
+ const labelInterval = Math.max(1, Math.ceil(labelSlot / Math.max(bandWidth, 1)));
764
+ const zeroY = y(0);
765
+ const lineColor = element.style.color.line ?? "#5470c6";
766
+ const categories = element.data.map(({ label, value, color }, index) => {
767
+ const bandX = left + index * bandWidth;
768
+ const valueY = y(value);
769
+ return {
770
+ index,
771
+ label,
772
+ value,
773
+ color: color ?? (element.type === "line" ? lineColor : "#5470c6"),
774
+ x: bandX,
775
+ center: bandX + bandWidth / 2,
776
+ width: bandWidth,
777
+ barY: Math.min(valueY, zeroY),
778
+ barHeight: Math.abs(zeroY - valueY),
779
+ pointY: valueY,
780
+ showLabel: index % labelInterval === 0
781
+ };
782
+ });
783
+ const linePath = element.type === "line" && categories.length ? line().x(({ center }) => center).y(({ pointY }) => pointY).curve(curveMonotoneX)(categories) : null;
784
+ return {
785
+ width,
786
+ height,
787
+ plot: {
788
+ left,
789
+ top,
790
+ right,
791
+ bottom
792
+ },
793
+ title: element.title ? {
794
+ x: width / 2,
795
+ y: 5 + fontSize
796
+ } : null,
797
+ ticks: ticks$1,
798
+ zeroY,
799
+ categories,
800
+ linePath,
801
+ bandWidth,
802
+ barWidth
803
+ };
804
+ }
805
+ var SeriesChartRenderer = class SeriesChartRenderer extends InteractiveChart {
806
+ lineColor = computed(() => this.element().style.color.line ?? "#5470c6", ...ngDevMode ? [{ debugName: "lineColor" }] : /* istanbul ignore next */ []);
807
+ layout = computed(() => {
808
+ const { width, height } = this.size();
809
+ return width > 0 && height > 0 ? seriesChartLayout(this.element(), width, height) : null;
810
+ }, ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
811
+ points = computed(() => this.layout()?.categories.map(({ index, label, value, color, center, pointY }) => ({
812
+ index,
813
+ label,
814
+ value,
815
+ color,
816
+ anchorX: center,
817
+ anchorY: pointY
818
+ })) ?? [], ...ngDevMode ? [{ debugName: "points" }] : /* istanbul ignore next */ []);
819
+ static ɵfac = i0.ɵɵngDeclareFactory({
820
+ minVersion: "12.0.0",
821
+ version: "22.2.4",
822
+ ngImport: i0,
823
+ type: SeriesChartRenderer,
824
+ deps: null,
825
+ target: i0.ɵɵFactoryTarget.Component
826
+ });
827
+ static ɵcmp = i0.ɵɵngDeclareComponent({
828
+ minVersion: "17.0.0",
829
+ version: "22.2.4",
830
+ type: SeriesChartRenderer,
831
+ isStandalone: true,
832
+ selector: "widget-series-chart",
833
+ usesInheritance: true,
834
+ ngImport: i0,
835
+ template: "<div\n class=\"chart-chart\"\n [attr.aria-hidden]=\"sensitiveHidden() ? 'true' : null\"\n [style.pointer-events]=\"sensitiveHidden() ? 'none' : null\"\n>\n <div #chartHost class=\"chart-host\">\n <svg\n class=\"chart-svg series-chart\"\n role=\"img\"\n [attr.aria-label]=\"ariaLabel(element())\"\n [attr.aria-describedby]=\"sensitiveHidden() ? null : summaryId\"\n [attr.tabindex]=\"sensitiveHidden() || !element().data.length ? -1 : 0\"\n [attr.width]=\"layout()?.width ?? 0\"\n [attr.height]=\"layout()?.height ?? 0\"\n [attr.viewBox]=\"layout() ? '0 0 ' + layout()!.width + ' ' + layout()!.height : null\"\n [style.font-size.px]=\"element().style.font.size\"\n (focus)=\"focus()\"\n (blur)=\"pointerLeave()\"\n (keydown)=\"keyDown($event)\"\n >\n @if (layout(); as chart) {\n @if (chart.title) {\n <text\n class=\"series-title\"\n text-anchor=\"middle\"\n [attr.x]=\"chart.title.x\"\n [attr.y]=\"chart.title.y\"\n [attr.fill]=\"element().style.color.title\"\n >\n {{ element().title }}\n </text>\n }\n @for (tick of chart.ticks; track tick.value) {\n <line\n [attr.x1]=\"chart.plot.left\"\n [attr.x2]=\"chart.plot.right\"\n [attr.y1]=\"tick.y\"\n [attr.y2]=\"tick.y\"\n [attr.stroke]=\"element().style.axis.grid\"\n />\n <text\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n [attr.x]=\"chart.plot.left - 8\"\n [attr.y]=\"tick.y\"\n [attr.fill]=\"element().style.axis.label\"\n >\n {{ tick.label }}\n </text>\n }\n @if (activeIndex() !== null && chart.categories[activeIndex()!]; as active) {\n @if (element().type === 'bar') {\n <rect\n class=\"series-pointer\"\n [attr.x]=\"active.x\"\n [attr.y]=\"chart.plot.top\"\n [attr.width]=\"active.width\"\n [attr.height]=\"chart.plot.bottom - chart.plot.top\"\n />\n } @else {\n <line\n class=\"series-pointer-line\"\n [attr.x1]=\"active.center\"\n [attr.x2]=\"active.center\"\n [attr.y1]=\"chart.plot.top\"\n [attr.y2]=\"chart.plot.bottom\"\n />\n }\n }\n @if (element().type === 'bar') {\n @for (category of chart.categories; track category.index) {\n <rect\n [attr.x]=\"category.center - chart.barWidth / 2\"\n [attr.y]=\"category.barY\"\n [attr.width]=\"chart.barWidth\"\n [attr.height]=\"category.barHeight\"\n [attr.fill]=\"category.color\"\n />\n }\n } @else {\n @if (chart.linePath) {\n <path class=\"series-line\" [attr.d]=\"chart.linePath\" [attr.stroke]=\"lineColor()\" />\n }\n @for (category of chart.categories; track category.index) {\n <circle\n class=\"series-point\"\n [attr.cx]=\"category.center\"\n [attr.cy]=\"category.pointY\"\n [attr.r]=\"activeIndex() === category.index ? 5 : 3\"\n [attr.fill]=\"category.color\"\n />\n }\n }\n <line\n [attr.x1]=\"chart.plot.left\"\n [attr.x2]=\"chart.plot.right\"\n [attr.y1]=\"chart.zeroY\"\n [attr.y2]=\"chart.zeroY\"\n [attr.stroke]=\"element().style.axis.line\"\n />\n @for (category of chart.categories; track category.index) {\n <line\n [attr.x1]=\"category.x\"\n [attr.x2]=\"category.x\"\n [attr.y1]=\"chart.plot.bottom\"\n [attr.y2]=\"chart.plot.bottom + 5\"\n [attr.stroke]=\"element().style.axis.line\"\n />\n @if (category.showLabel) {\n <text\n text-anchor=\"middle\"\n dominant-baseline=\"hanging\"\n [attr.x]=\"category.center\"\n [attr.y]=\"chart.plot.bottom + 8\"\n [attr.fill]=\"element().style.axis.label\"\n >\n {{ category.label }}\n </text>\n }\n }\n @if (!sensitiveHidden()) {\n @for (category of chart.categories; track category.index) {\n <rect\n class=\"series-hit\"\n [attr.x]=\"category.x\"\n [attr.y]=\"chart.plot.top\"\n [attr.width]=\"category.width\"\n [attr.height]=\"chart.plot.bottom - chart.plot.top\"\n (pointerenter)=\"pointerMove(category.index, $event)\"\n (pointermove)=\"pointerMove(category.index, $event)\"\n (pointerdown)=\"pointerMove(category.index, $event)\"\n (pointerleave)=\"pointerLeave()\"\n />\n }\n }\n }\n </svg>\n </div>\n @if (!sensitiveHidden()) {\n <span class=\"visually-hidden\" [id]=\"summaryId\">{{ accessibilitySummary(element()) }}</span>\n <span class=\"visually-hidden\" aria-live=\"polite\">{{ announcement() }}</span>\n }\n</div>\n",
836
+ styles: [":host{display:block;width:100%;height:100%;min-width:0;min-height:0;--widget-renderer-chart-min-height: 40px}.chart-chart{position:relative;width:100%;height:100%;min-height:var(--widget-renderer-chart-min-height)}.chart-host{position:absolute;inset:0;overflow:hidden}.chart-stack{display:flex;flex-direction:column}.chart-stack .chart-host{position:relative;flex:1 1 auto;min-height:0}.chart-svg{position:absolute;inset:0;display:block;font-family:inherit}.chart-svg:focus{outline:none}.chart-svg:focus-visible{outline:2px solid var(--widget-renderer-focus-ring-contrast, #fff);outline-offset:-2px;box-shadow:inset 0 0 0 4px var(--widget-renderer-focus-ring, #1d4ed8)}.chart-title{overflow:hidden;flex:0 0 auto;padding:5px 5px 0;font-weight:700;text-align:center;text-overflow:ellipsis;white-space:nowrap}.chart-legend{display:flex;flex:0 0 auto;flex-wrap:wrap;justify-content:center;gap:5px 10px;padding:4px 5px 10px}.chart-legend-item{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.chart-legend-marker{width:25px;height:14px;flex:0 0 auto;border-radius:4px}.chart-shape{cursor:pointer;transition:opacity .12s ease}.chart-shape.is-dimmed{opacity:.55}@media(prefers-reduced-motion:reduce){.chart-shape{transition:none}}.series-chart line{shape-rendering:crispEdges}.series-title{font-weight:700}.series-pointer{fill:#96969633}.series-pointer-line{stroke:#b6b9c0;stroke-dasharray:4 3}.series-line{fill:none;stroke-width:2}.series-point{stroke:none}.series-hit{fill:transparent;cursor:pointer}.gauge-value{font-weight:700}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
837
+ });
838
+ };
839
+ i0.ɵɵngDeclareClassMetadata({
840
+ minVersion: "12.0.0",
841
+ version: "22.2.4",
842
+ ngImport: i0,
843
+ type: SeriesChartRenderer,
844
+ decorators: [{
845
+ type: Component,
846
+ args: [{
847
+ selector: "widget-series-chart",
848
+ template: "<div\n class=\"chart-chart\"\n [attr.aria-hidden]=\"sensitiveHidden() ? 'true' : null\"\n [style.pointer-events]=\"sensitiveHidden() ? 'none' : null\"\n>\n <div #chartHost class=\"chart-host\">\n <svg\n class=\"chart-svg series-chart\"\n role=\"img\"\n [attr.aria-label]=\"ariaLabel(element())\"\n [attr.aria-describedby]=\"sensitiveHidden() ? null : summaryId\"\n [attr.tabindex]=\"sensitiveHidden() || !element().data.length ? -1 : 0\"\n [attr.width]=\"layout()?.width ?? 0\"\n [attr.height]=\"layout()?.height ?? 0\"\n [attr.viewBox]=\"layout() ? '0 0 ' + layout()!.width + ' ' + layout()!.height : null\"\n [style.font-size.px]=\"element().style.font.size\"\n (focus)=\"focus()\"\n (blur)=\"pointerLeave()\"\n (keydown)=\"keyDown($event)\"\n >\n @if (layout(); as chart) {\n @if (chart.title) {\n <text\n class=\"series-title\"\n text-anchor=\"middle\"\n [attr.x]=\"chart.title.x\"\n [attr.y]=\"chart.title.y\"\n [attr.fill]=\"element().style.color.title\"\n >\n {{ element().title }}\n </text>\n }\n @for (tick of chart.ticks; track tick.value) {\n <line\n [attr.x1]=\"chart.plot.left\"\n [attr.x2]=\"chart.plot.right\"\n [attr.y1]=\"tick.y\"\n [attr.y2]=\"tick.y\"\n [attr.stroke]=\"element().style.axis.grid\"\n />\n <text\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n [attr.x]=\"chart.plot.left - 8\"\n [attr.y]=\"tick.y\"\n [attr.fill]=\"element().style.axis.label\"\n >\n {{ tick.label }}\n </text>\n }\n @if (activeIndex() !== null && chart.categories[activeIndex()!]; as active) {\n @if (element().type === 'bar') {\n <rect\n class=\"series-pointer\"\n [attr.x]=\"active.x\"\n [attr.y]=\"chart.plot.top\"\n [attr.width]=\"active.width\"\n [attr.height]=\"chart.plot.bottom - chart.plot.top\"\n />\n } @else {\n <line\n class=\"series-pointer-line\"\n [attr.x1]=\"active.center\"\n [attr.x2]=\"active.center\"\n [attr.y1]=\"chart.plot.top\"\n [attr.y2]=\"chart.plot.bottom\"\n />\n }\n }\n @if (element().type === 'bar') {\n @for (category of chart.categories; track category.index) {\n <rect\n [attr.x]=\"category.center - chart.barWidth / 2\"\n [attr.y]=\"category.barY\"\n [attr.width]=\"chart.barWidth\"\n [attr.height]=\"category.barHeight\"\n [attr.fill]=\"category.color\"\n />\n }\n } @else {\n @if (chart.linePath) {\n <path class=\"series-line\" [attr.d]=\"chart.linePath\" [attr.stroke]=\"lineColor()\" />\n }\n @for (category of chart.categories; track category.index) {\n <circle\n class=\"series-point\"\n [attr.cx]=\"category.center\"\n [attr.cy]=\"category.pointY\"\n [attr.r]=\"activeIndex() === category.index ? 5 : 3\"\n [attr.fill]=\"category.color\"\n />\n }\n }\n <line\n [attr.x1]=\"chart.plot.left\"\n [attr.x2]=\"chart.plot.right\"\n [attr.y1]=\"chart.zeroY\"\n [attr.y2]=\"chart.zeroY\"\n [attr.stroke]=\"element().style.axis.line\"\n />\n @for (category of chart.categories; track category.index) {\n <line\n [attr.x1]=\"category.x\"\n [attr.x2]=\"category.x\"\n [attr.y1]=\"chart.plot.bottom\"\n [attr.y2]=\"chart.plot.bottom + 5\"\n [attr.stroke]=\"element().style.axis.line\"\n />\n @if (category.showLabel) {\n <text\n text-anchor=\"middle\"\n dominant-baseline=\"hanging\"\n [attr.x]=\"category.center\"\n [attr.y]=\"chart.plot.bottom + 8\"\n [attr.fill]=\"element().style.axis.label\"\n >\n {{ category.label }}\n </text>\n }\n }\n @if (!sensitiveHidden()) {\n @for (category of chart.categories; track category.index) {\n <rect\n class=\"series-hit\"\n [attr.x]=\"category.x\"\n [attr.y]=\"chart.plot.top\"\n [attr.width]=\"category.width\"\n [attr.height]=\"chart.plot.bottom - chart.plot.top\"\n (pointerenter)=\"pointerMove(category.index, $event)\"\n (pointermove)=\"pointerMove(category.index, $event)\"\n (pointerdown)=\"pointerMove(category.index, $event)\"\n (pointerleave)=\"pointerLeave()\"\n />\n }\n }\n }\n </svg>\n </div>\n @if (!sensitiveHidden()) {\n <span class=\"visually-hidden\" [id]=\"summaryId\">{{ accessibilitySummary(element()) }}</span>\n <span class=\"visually-hidden\" aria-live=\"polite\">{{ announcement() }}</span>\n }\n</div>\n",
849
+ styles: [":host{display:block;width:100%;height:100%;min-width:0;min-height:0;--widget-renderer-chart-min-height: 40px}.chart-chart{position:relative;width:100%;height:100%;min-height:var(--widget-renderer-chart-min-height)}.chart-host{position:absolute;inset:0;overflow:hidden}.chart-stack{display:flex;flex-direction:column}.chart-stack .chart-host{position:relative;flex:1 1 auto;min-height:0}.chart-svg{position:absolute;inset:0;display:block;font-family:inherit}.chart-svg:focus{outline:none}.chart-svg:focus-visible{outline:2px solid var(--widget-renderer-focus-ring-contrast, #fff);outline-offset:-2px;box-shadow:inset 0 0 0 4px var(--widget-renderer-focus-ring, #1d4ed8)}.chart-title{overflow:hidden;flex:0 0 auto;padding:5px 5px 0;font-weight:700;text-align:center;text-overflow:ellipsis;white-space:nowrap}.chart-legend{display:flex;flex:0 0 auto;flex-wrap:wrap;justify-content:center;gap:5px 10px;padding:4px 5px 10px}.chart-legend-item{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}.chart-legend-marker{width:25px;height:14px;flex:0 0 auto;border-radius:4px}.chart-shape{cursor:pointer;transition:opacity .12s ease}.chart-shape.is-dimmed{opacity:.55}@media(prefers-reduced-motion:reduce){.chart-shape{transition:none}}.series-chart line{shape-rendering:crispEdges}.series-title{font-weight:700}.series-pointer{fill:#96969633}.series-pointer-line{stroke:#b6b9c0;stroke-dasharray:4 3}.series-line{fill:none;stroke-width:2}.series-point{stroke:none}.series-hit{fill:transparent;cursor:pointer}.gauge-value{font-weight:700}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
850
+ }]
851
+ }]
852
+ });
853
+ var ChartElementRenderer = class ChartElementRenderer {
854
+ element = input.required(...ngDevMode ? [{ debugName: "element" }] : /* istanbul ignore next */ []);
855
+ sensitiveHidden = input(false, ...ngDevMode ? [{ debugName: "sensitiveHidden" }] : /* istanbul ignore next */ []);
856
+ locale = input(defaultWidgetRendererLocale, ...ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []);
857
+ isProgress(element) {
858
+ return element.type === "progress";
859
+ }
860
+ progress(element) {
861
+ return element;
862
+ }
863
+ gauge(element) {
864
+ return element;
865
+ }
866
+ isSeries(element) {
867
+ return element.type === "bar" || element.type === "line";
868
+ }
869
+ series(element) {
870
+ return element;
871
+ }
872
+ isPart(element) {
873
+ return element.type === "pie" || element.type === "donut" || element.type === "funnel";
874
+ }
875
+ part(element) {
876
+ return element;
877
+ }
878
+ static ɵfac = i0.ɵɵngDeclareFactory({
879
+ minVersion: "12.0.0",
880
+ version: "22.2.4",
881
+ ngImport: i0,
882
+ type: ChartElementRenderer,
883
+ deps: [],
884
+ target: i0.ɵɵFactoryTarget.Component
885
+ });
886
+ static ɵcmp = i0.ɵɵngDeclareComponent({
887
+ minVersion: "17.0.0",
888
+ version: "22.2.4",
889
+ type: ChartElementRenderer,
890
+ isStandalone: true,
891
+ selector: "widget-chart-element",
892
+ inputs: {
893
+ element: {
894
+ classPropertyName: "element",
895
+ publicName: "element",
896
+ isSignal: true,
897
+ isRequired: true,
898
+ transformFunction: null
899
+ },
900
+ sensitiveHidden: {
901
+ classPropertyName: "sensitiveHidden",
902
+ publicName: "sensitiveHidden",
903
+ isSignal: true,
904
+ isRequired: false,
905
+ transformFunction: null
906
+ },
907
+ locale: {
908
+ classPropertyName: "locale",
909
+ publicName: "locale",
910
+ isSignal: true,
911
+ isRequired: false,
912
+ transformFunction: null
913
+ }
914
+ },
915
+ ngImport: i0,
916
+ template: "@if (isProgress(element())) {\n <widget-progress-element\n [element]=\"progress(element())\"\n [sensitiveHidden]=\"sensitiveHidden()\"\n [locale]=\"locale()\"\n />\n} @else if (isSeries(element())) {\n <widget-series-chart\n [element]=\"series(element())\"\n [sensitiveHidden]=\"sensitiveHidden()\"\n [locale]=\"locale()\"\n />\n} @else if (isPart(element())) {\n <widget-part-chart\n [element]=\"part(element())\"\n [sensitiveHidden]=\"sensitiveHidden()\"\n [locale]=\"locale()\"\n />\n} @else {\n <widget-gauge-chart\n [element]=\"gauge(element())\"\n [sensitiveHidden]=\"sensitiveHidden()\"\n [locale]=\"locale()\"\n />\n}\n",
917
+ dependencies: [
918
+ {
919
+ kind: "component",
920
+ type: GaugeChartRenderer,
921
+ selector: "widget-gauge-chart"
922
+ },
923
+ {
924
+ kind: "component",
925
+ type: PartChartRenderer,
926
+ selector: "widget-part-chart"
927
+ },
928
+ {
929
+ kind: "component",
930
+ type: ProgressElementRenderer,
931
+ selector: "widget-progress-element",
932
+ inputs: [
933
+ "element",
934
+ "sensitiveHidden",
935
+ "locale"
936
+ ]
937
+ },
938
+ {
939
+ kind: "component",
940
+ type: SeriesChartRenderer,
941
+ selector: "widget-series-chart"
942
+ }
943
+ ]
944
+ });
945
+ };
946
+ i0.ɵɵngDeclareClassMetadata({
947
+ minVersion: "12.0.0",
948
+ version: "22.2.4",
949
+ ngImport: i0,
950
+ type: ChartElementRenderer,
951
+ decorators: [{
952
+ type: Component,
953
+ args: [{
954
+ selector: "widget-chart-element",
955
+ imports: [
956
+ GaugeChartRenderer,
957
+ PartChartRenderer,
958
+ ProgressElementRenderer,
959
+ SeriesChartRenderer
960
+ ],
961
+ template: "@if (isProgress(element())) {\n <widget-progress-element\n [element]=\"progress(element())\"\n [sensitiveHidden]=\"sensitiveHidden()\"\n [locale]=\"locale()\"\n />\n} @else if (isSeries(element())) {\n <widget-series-chart\n [element]=\"series(element())\"\n [sensitiveHidden]=\"sensitiveHidden()\"\n [locale]=\"locale()\"\n />\n} @else if (isPart(element())) {\n <widget-part-chart\n [element]=\"part(element())\"\n [sensitiveHidden]=\"sensitiveHidden()\"\n [locale]=\"locale()\"\n />\n} @else {\n <widget-gauge-chart\n [element]=\"gauge(element())\"\n [sensitiveHidden]=\"sensitiveHidden()\"\n [locale]=\"locale()\"\n />\n}\n"
962
+ }]
963
+ }],
964
+ propDecorators: {
965
+ element: [{
966
+ type: i0.Input,
967
+ args: [{
968
+ isSignal: true,
969
+ alias: "element",
970
+ required: true
971
+ }]
972
+ }],
973
+ sensitiveHidden: [{
974
+ type: i0.Input,
975
+ args: [{
976
+ isSignal: true,
977
+ alias: "sensitiveHidden",
978
+ required: false
979
+ }]
980
+ }],
981
+ locale: [{
982
+ type: i0.Input,
983
+ args: [{
984
+ isSignal: true,
985
+ alias: "locale",
986
+ required: false
987
+ }]
988
+ }]
989
+ }
990
+ });
991
+ export { ChartElementRenderer };
992
+
993
+ //# sourceMappingURL=lieselthuriot-widget-renderer-chart-element-renderer-wVHdIYuJ.mjs.map