@praxisui/charts 9.0.38 → 9.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/ai/component-registry.json +2 -2
- package/fesm2022/praxisui-charts.mjs +404 -6
- package/package.json +3 -3
- package/types/praxisui-charts.d.ts +22 -1
package/README.md
CHANGED
|
@@ -142,6 +142,18 @@ Use the component with either local data or governed remote execution:
|
|
|
142
142
|
|
|
143
143
|
The public contract is `PraxisChartConfig` or the canonical `PraxisXUiChartContract`; raw ECharts options are adapter detail, not the host-facing model.
|
|
144
144
|
|
|
145
|
+
## Accessibility
|
|
146
|
+
|
|
147
|
+
`PraxisChartComponent` materializes accessibility from the same canonical config and transformed rows used by the visual renderer:
|
|
148
|
+
|
|
149
|
+
- the default ECharts adapter enables its engine-owned ARIA description without exposing ECharts options through the public contract;
|
|
150
|
+
- every ready chart offers a localized `Show chart data` / `Exibir dados do gráfico` control with a structured HTML table;
|
|
151
|
+
- each table point is a native button, so Enter and Space follow browser keyboard conventions and activate the same renderer-neutral `pointClick` path as the visual point;
|
|
152
|
+
- when single selection is configured, the point button publishes `aria-pressed` and preserves the existing select/deselect and cross-filter payloads;
|
|
153
|
+
- loading, empty and error states remove the data controls, preventing stale chart values from remaining available to assistive technology.
|
|
154
|
+
|
|
155
|
+
The structured alternative is automatic. It does not add an accessibility field to `PraxisChartConfig` or `x-ui.chart`, and custom engines remain responsible for an accessible visual rendering while the component-level data alternative remains renderer-neutral.
|
|
156
|
+
|
|
145
157
|
Supported canonical kinds are `bar`, `horizontal-bar`, `line`, `area`, `stacked-bar`,
|
|
146
158
|
`stacked-area`, `combo`, `pie`, `donut`, `scatter`, `funnel`, `pyramid`, `treemap`, and `gauge`. Funnel,
|
|
147
159
|
pyramid, and treemap require one categorical dimension and exactly one non-negative metric. Funnel
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-08-
|
|
3
|
+
"generatedAt": "2026-08-30T07:25:27.035Z",
|
|
4
4
|
"packageName": "@praxisui/charts",
|
|
5
|
-
"packageVersion": "9.0.
|
|
5
|
+
"packageVersion": "9.0.40",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 3,
|
|
@@ -1834,6 +1834,7 @@ const DEFAULT_CHART_CONFIG = {
|
|
|
1834
1834
|
},
|
|
1835
1835
|
series: [],
|
|
1836
1836
|
};
|
|
1837
|
+
let chartAccessibilityPanelSequence = 0;
|
|
1837
1838
|
class PraxisChartComponent {
|
|
1838
1839
|
config = input(DEFAULT_CHART_CONFIG, ...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
1839
1840
|
data = input(null, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
@@ -1879,6 +1880,9 @@ class PraxisChartComponent {
|
|
|
1879
1880
|
mappedRuntimeConfig = signal(null, ...(ngDevMode ? [{ debugName: "mappedRuntimeConfig" }] : /* istanbul ignore next */ []));
|
|
1880
1881
|
chartDocumentMappingError = signal(null, ...(ngDevMode ? [{ debugName: "chartDocumentMappingError" }] : /* istanbul ignore next */ []));
|
|
1881
1882
|
activeSelectionSignature = signal(null, ...(ngDevMode ? [{ debugName: "activeSelectionSignature" }] : /* istanbul ignore next */ []));
|
|
1883
|
+
showAccessibleData = signal(false, ...(ngDevMode ? [{ debugName: "showAccessibleData" }] : /* istanbul ignore next */ []));
|
|
1884
|
+
accessibilityPanelId = `praxis-chart-data-${++chartAccessibilityPanelSequence}`;
|
|
1885
|
+
accessibilityPanelTitleId = `${this.accessibilityPanelId}-title`;
|
|
1882
1886
|
fillContainerHeight = signal(false, ...(ngDevMode ? [{ debugName: "fillContainerHeight" }] : /* istanbul ignore next */ []));
|
|
1883
1887
|
renderAttempt = signal(0, ...(ngDevMode ? [{ debugName: "renderAttempt" }] : /* istanbul ignore next */ []));
|
|
1884
1888
|
resizeFrameId = null;
|
|
@@ -2002,6 +2006,7 @@ class PraxisChartComponent {
|
|
|
2002
2006
|
}, ...(ngDevMode ? [{ debugName: "renderConfig" }] : /* istanbul ignore next */ []));
|
|
2003
2007
|
loadingLabel = computed(() => this.i18n.resolve(this.renderConfig().state?.loadingLabel), ...(ngDevMode ? [{ debugName: "loadingLabel" }] : /* istanbul ignore next */ []));
|
|
2004
2008
|
transformedData = computed(() => this.transformer.transform(this.renderConfig(), this.resolvedData()), ...(ngDevMode ? [{ debugName: "transformedData" }] : /* istanbul ignore next */ []));
|
|
2009
|
+
accessiblePoints = computed(() => buildAccessibleChartPoints(this.renderConfig(), this.transformedData(), (value) => this.formatAccessibleValue(value), (index) => this.t('praxis.charts.runtime.accessibility.pointFallback', `Point ${index + 1}`, { index: index + 1 }), () => this.t('praxis.charts.runtime.accessibility.seriesFallback', 'Series')), ...(ngDevMode ? [{ debugName: "accessiblePoints" }] : /* istanbul ignore next */ []));
|
|
2005
2010
|
dataDiagnostic = computed(() => {
|
|
2006
2011
|
const config = this.renderConfig();
|
|
2007
2012
|
const explicitData = this.data();
|
|
@@ -2027,6 +2032,16 @@ class PraxisChartComponent {
|
|
|
2027
2032
|
: this.i18n.resolve(this.renderConfig().state?.error?.description)
|
|
2028
2033
|
|| this.t('praxis.charts.runtime.remoteErrorDescription', 'Revise a fonte de dados e os filtros antes de continuar.'), ...(ngDevMode ? [{ debugName: "errorDescription" }] : /* istanbul ignore next */ []));
|
|
2029
2034
|
editChartLabel = computed(() => this.t('praxis.charts.runtime.editChart', 'Edit chart settings'), ...(ngDevMode ? [{ debugName: "editChartLabel" }] : /* istanbul ignore next */ []));
|
|
2035
|
+
accessibleDataToggleLabel = computed(() => this.showAccessibleData()
|
|
2036
|
+
? this.t('praxis.charts.runtime.accessibility.hideData', 'Hide chart data')
|
|
2037
|
+
: this.t('praxis.charts.runtime.accessibility.showData', 'Show chart data'), ...(ngDevMode ? [{ debugName: "accessibleDataToggleLabel" }] : /* istanbul ignore next */ []));
|
|
2038
|
+
accessibleDataTitle = computed(() => this.i18n.resolve(this.renderConfig().title)
|
|
2039
|
+
|| this.t('praxis.charts.runtime.accessibility.dataTitle', 'Chart data'), ...(ngDevMode ? [{ debugName: "accessibleDataTitle" }] : /* istanbul ignore next */ []));
|
|
2040
|
+
accessibleDataDescription = computed(() => this.i18n.resolve(this.renderConfig().subtitle)
|
|
2041
|
+
|| this.t('praxis.charts.runtime.accessibility.dataDescription', 'Structured alternative for the values represented in the chart.'), ...(ngDevMode ? [{ debugName: "accessibleDataDescription" }] : /* istanbul ignore next */ []));
|
|
2042
|
+
accessibleCategoryHeading = computed(() => this.t('praxis.charts.runtime.accessibility.category', 'Category'), ...(ngDevMode ? [{ debugName: "accessibleCategoryHeading" }] : /* istanbul ignore next */ []));
|
|
2043
|
+
accessibleSeriesHeading = computed(() => this.t('praxis.charts.runtime.accessibility.series', 'Series'), ...(ngDevMode ? [{ debugName: "accessibleSeriesHeading" }] : /* istanbul ignore next */ []));
|
|
2044
|
+
accessibleValueHeading = computed(() => this.t('praxis.charts.runtime.accessibility.value', 'Value'), ...(ngDevMode ? [{ debugName: "accessibleValueHeading" }] : /* istanbul ignore next */ []));
|
|
2030
2045
|
loadState = computed(() => {
|
|
2031
2046
|
if (this.chartDocumentMappingError()) {
|
|
2032
2047
|
return 'error';
|
|
@@ -2114,6 +2129,9 @@ class PraxisChartComponent {
|
|
|
2114
2129
|
});
|
|
2115
2130
|
effect(() => {
|
|
2116
2131
|
const nextState = this.loadState();
|
|
2132
|
+
if (nextState !== 'ready' || !this.accessiblePoints().length) {
|
|
2133
|
+
this.showAccessibleData.set(false);
|
|
2134
|
+
}
|
|
2117
2135
|
if (this.currentLoadState() !== nextState) {
|
|
2118
2136
|
this.currentLoadState.set(nextState);
|
|
2119
2137
|
this.loadStateChange.emit(nextState);
|
|
@@ -2233,8 +2251,23 @@ class PraxisChartComponent {
|
|
|
2233
2251
|
const description = descriptions[diagnostic.code];
|
|
2234
2252
|
return this.t(description.key, description.text);
|
|
2235
2253
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2254
|
+
formatAccessibleValue(value) {
|
|
2255
|
+
if (Array.isArray(value)) {
|
|
2256
|
+
return value.map((item) => this.formatAccessibleValue(item)).join(', ');
|
|
2257
|
+
}
|
|
2258
|
+
if (value instanceof Date) {
|
|
2259
|
+
return this.i18n.formatDate(value);
|
|
2260
|
+
}
|
|
2261
|
+
if (typeof value === 'number') {
|
|
2262
|
+
return this.i18n.formatNumber(value);
|
|
2263
|
+
}
|
|
2264
|
+
if (value === null || value === undefined || value === '') {
|
|
2265
|
+
return this.t('praxis.charts.runtime.accessibility.notAvailable', 'Not available');
|
|
2266
|
+
}
|
|
2267
|
+
return String(value);
|
|
2268
|
+
}
|
|
2269
|
+
t(key, fallback, params) {
|
|
2270
|
+
return this.i18n.t(key, params, fallback, PRAXIS_CHARTS_I18N_NAMESPACE);
|
|
2238
2271
|
}
|
|
2239
2272
|
canOpenConfigEditor() {
|
|
2240
2273
|
return this.enableCustomization() && !!this.settingsPanel && !!this.runtimeChartDocument();
|
|
@@ -2382,6 +2415,34 @@ class PraxisChartComponent {
|
|
|
2382
2415
|
});
|
|
2383
2416
|
}
|
|
2384
2417
|
}
|
|
2418
|
+
toggleAccessibleData() {
|
|
2419
|
+
this.showAccessibleData.update((visible) => !visible);
|
|
2420
|
+
}
|
|
2421
|
+
activateAccessiblePoint(point) {
|
|
2422
|
+
this.handlePointClick({
|
|
2423
|
+
chartId: point.chartId,
|
|
2424
|
+
seriesId: point.seriesId,
|
|
2425
|
+
seriesName: point.seriesName,
|
|
2426
|
+
category: point.category,
|
|
2427
|
+
value: point.value,
|
|
2428
|
+
data: point.data,
|
|
2429
|
+
});
|
|
2430
|
+
}
|
|
2431
|
+
accessiblePointPressed(point) {
|
|
2432
|
+
if (!this.renderConfig().interactions?.selection) {
|
|
2433
|
+
return null;
|
|
2434
|
+
}
|
|
2435
|
+
return this.activeSelectionSignature() === this.buildPointSelectionSignature(this.renderConfig(), point)
|
|
2436
|
+
? 'true'
|
|
2437
|
+
: 'false';
|
|
2438
|
+
}
|
|
2439
|
+
accessiblePointActionLabel(point) {
|
|
2440
|
+
return this.t('praxis.charts.runtime.accessibility.activatePoint', 'Activate {{ category }}, {{ series }}: {{ value }}', {
|
|
2441
|
+
category: point.categoryLabel,
|
|
2442
|
+
series: point.seriesLabel,
|
|
2443
|
+
value: point.valueLabel,
|
|
2444
|
+
});
|
|
2445
|
+
}
|
|
2385
2446
|
buildSelectionEvent(config, event) {
|
|
2386
2447
|
const action = config.interactions?.eventActions?.selectionChange;
|
|
2387
2448
|
const filters = this.buildEventFilters(config, event, action?.mapping);
|
|
@@ -2751,6 +2812,22 @@ class PraxisChartComponent {
|
|
|
2751
2812
|
></button>
|
|
2752
2813
|
}
|
|
2753
2814
|
|
|
2815
|
+
@if (loadState() === 'ready' && accessiblePoints().length) {
|
|
2816
|
+
<button
|
|
2817
|
+
class="praxis-chart-data-trigger"
|
|
2818
|
+
[class.praxis-chart-data-trigger-with-settings]="canOpenConfigEditor()"
|
|
2819
|
+
praxisIconButton="table_view"
|
|
2820
|
+
size="compact"
|
|
2821
|
+
appearance="filled"
|
|
2822
|
+
type="button"
|
|
2823
|
+
[attr.aria-label]="accessibleDataToggleLabel()"
|
|
2824
|
+
[attr.aria-controls]="accessibilityPanelId"
|
|
2825
|
+
[attr.aria-expanded]="showAccessibleData()"
|
|
2826
|
+
[matTooltip]="accessibleDataToggleLabel()"
|
|
2827
|
+
(click)="toggleAccessibleData()"
|
|
2828
|
+
></button>
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2754
2831
|
@if (loadState() === 'loading') {
|
|
2755
2832
|
<div class="praxis-chart-state praxis-chart-state-loading">
|
|
2756
2833
|
<div class="praxis-chart-loading-hero" aria-hidden="true">
|
|
@@ -2794,10 +2871,53 @@ class PraxisChartComponent {
|
|
|
2794
2871
|
}
|
|
2795
2872
|
</div>
|
|
2796
2873
|
} @else {
|
|
2797
|
-
|
|
2874
|
+
@if (showAccessibleData()) {
|
|
2875
|
+
<section
|
|
2876
|
+
class="praxis-chart-accessible-data"
|
|
2877
|
+
[id]="accessibilityPanelId"
|
|
2878
|
+
role="region"
|
|
2879
|
+
[attr.aria-labelledby]="accessibilityPanelTitleId"
|
|
2880
|
+
>
|
|
2881
|
+
<h3 [id]="accessibilityPanelTitleId">{{ accessibleDataTitle() }}</h3>
|
|
2882
|
+
<table>
|
|
2883
|
+
<caption>{{ accessibleDataDescription() }}</caption>
|
|
2884
|
+
<thead>
|
|
2885
|
+
<tr>
|
|
2886
|
+
<th scope="col">{{ accessibleCategoryHeading() }}</th>
|
|
2887
|
+
<th scope="col">{{ accessibleSeriesHeading() }}</th>
|
|
2888
|
+
<th scope="col">{{ accessibleValueHeading() }}</th>
|
|
2889
|
+
</tr>
|
|
2890
|
+
</thead>
|
|
2891
|
+
<tbody>
|
|
2892
|
+
@for (point of accessiblePoints(); track point.id) {
|
|
2893
|
+
<tr>
|
|
2894
|
+
<th scope="row">
|
|
2895
|
+
<button
|
|
2896
|
+
type="button"
|
|
2897
|
+
class="praxis-chart-point-action"
|
|
2898
|
+
[attr.aria-label]="accessiblePointActionLabel(point)"
|
|
2899
|
+
[attr.aria-pressed]="accessiblePointPressed(point)"
|
|
2900
|
+
(click)="activateAccessiblePoint(point)"
|
|
2901
|
+
>
|
|
2902
|
+
{{ point.categoryLabel }}
|
|
2903
|
+
</button>
|
|
2904
|
+
</th>
|
|
2905
|
+
<td>{{ point.seriesLabel }}</td>
|
|
2906
|
+
<td>{{ point.valueLabel }}</td>
|
|
2907
|
+
</tr>
|
|
2908
|
+
}
|
|
2909
|
+
</tbody>
|
|
2910
|
+
</table>
|
|
2911
|
+
</section>
|
|
2912
|
+
}
|
|
2913
|
+
<div
|
|
2914
|
+
#chartHost
|
|
2915
|
+
class="praxis-chart-host"
|
|
2916
|
+
[attr.aria-hidden]="showAccessibleData() ? 'true' : null"
|
|
2917
|
+
></div>
|
|
2798
2918
|
}
|
|
2799
2919
|
</section>
|
|
2800
|
-
`, isInline: true, styles: [":host{display:block;min-height:var(--praxis-chart-runtime-height, 320px);min-width:0;color:var(--md-sys-color-on-surface, #1a1b20)}:host(.praxis-chart-host-fill-container){height:100%;min-height:0}:host-context(.pdx-shell.no-shell) .praxis-chart-shell,:host-context(.pdx-shell.body-fill) .praxis-chart-shell,:host-context(.pdx-shell.expanded) .praxis-chart-shell,:host-context(.pdx-shell.fullscreen) .praxis-chart-shell{height:100%!important}.praxis-chart-shell{position:relative;width:100%;height:100%;min-height:240px;border-radius:var(--praxis-chart-config-surface-radius, var(--praxis-chart-surface-radius, 8px));overflow:hidden;background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-surface-bg, var(--md-sys-color-surface-container-lowest, #fff)) );border-color:var( --praxis-chart-config-surface-border, var( --praxis-chart-surface-border, color-mix(in srgb, var(--md-sys-color-outline, #c5c7ce) 44%, transparent) ) );border-style:solid;border-width:var(--praxis-chart-config-surface-border-width, 1px)}.praxis-chart-shell-fill-container{min-height:0}:host-context(.pdx-shell) .praxis-chart-shell:not(.praxis-chart-shell-contained),.praxis-chart-shell-embedded{border-width:var( --praxis-chart-config-surface-border-width, var(--praxis-chart-embedded-surface-border-width, 0) );border-radius:var( --praxis-chart-config-surface-radius, var(--praxis-chart-embedded-surface-radius, 0) );background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-embedded-surface-bg, transparent) )}.praxis-chart-settings-trigger{position:absolute;top:10px;right:10px;z-index:3;--praxis-icon-button-filled-background: color-mix(in srgb, var(--md-sys-color-surface, #fff) 88%, rgba(18, 99, 180, .12));--praxis-icon-button-filled-foreground: var(--md-sys-color-on-surface-variant, #44474f);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.praxis-chart-host{width:100%;height:100%;min-height:inherit}.praxis-chart-state{height:100%;min-height:min(240px,100%);display:grid;align-content:center;justify-items:center;gap:14px;padding:24px;text-align:center}.praxis-chart-state-copy{display:grid;gap:6px;justify-items:center}.praxis-chart-state-title{font-size:1rem;font-weight:600;color:var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface, #1a1b20))}.praxis-chart-state-description{font-size:.925rem;color:color-mix(in srgb,var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface-variant, #5a5d67)) 72%,transparent);max-width:36rem}.praxis-chart-loading-hero{width:min(100%,320px);display:grid;gap:14px}.praxis-chart-loading-summary{display:flex;gap:8px;justify-content:center}.praxis-chart-loading-chip,.praxis-chart-loading-bar{border-radius:999px;background:linear-gradient(90deg,#1263b414,#1263b438,#1263b414);background-size:200% 100%;animation:praxis-chart-loading-wave 1.2s ease-in-out infinite}.praxis-chart-loading-chip{display:block;width:104px;height:12px}.praxis-chart-loading-chip--short{width:64px}.praxis-chart-loading-plot{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));align-items:end;gap:10px;height:108px;padding:12px 8px 4px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-surface-container, #eef3f8) 72%,transparent);border:1px solid rgba(18,99,180,.08)}.praxis-chart-loading-bar{display:block;width:100%}.praxis-chart-loading-bar--1{height:32%}.praxis-chart-loading-bar--2{height:68%}.praxis-chart-loading-bar--3{height:48%}.praxis-chart-loading-bar--4{height:78%}.praxis-chart-loading-bar--5{height:56%}@keyframes praxis-chart-loading-wave{0%{background-position:100% 0}to{background-position:-100% 0}}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2920
|
+
`, isInline: true, styles: [":host{display:block;min-height:var(--praxis-chart-runtime-height, 320px);min-width:0;color:var(--md-sys-color-on-surface, #1a1b20)}:host(.praxis-chart-host-fill-container){height:100%;min-height:0}:host-context(.pdx-shell.no-shell) .praxis-chart-shell,:host-context(.pdx-shell.body-fill) .praxis-chart-shell,:host-context(.pdx-shell.expanded) .praxis-chart-shell,:host-context(.pdx-shell.fullscreen) .praxis-chart-shell{height:100%!important}.praxis-chart-shell{position:relative;width:100%;height:100%;min-height:240px;border-radius:var(--praxis-chart-config-surface-radius, var(--praxis-chart-surface-radius, 8px));overflow:hidden;background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-surface-bg, var(--md-sys-color-surface-container-lowest, #fff)) );border-color:var( --praxis-chart-config-surface-border, var( --praxis-chart-surface-border, color-mix(in srgb, var(--md-sys-color-outline, #c5c7ce) 44%, transparent) ) );border-style:solid;border-width:var(--praxis-chart-config-surface-border-width, 1px)}.praxis-chart-shell-fill-container{min-height:0}:host-context(.pdx-shell) .praxis-chart-shell:not(.praxis-chart-shell-contained),.praxis-chart-shell-embedded{border-width:var( --praxis-chart-config-surface-border-width, var(--praxis-chart-embedded-surface-border-width, 0) );border-radius:var( --praxis-chart-config-surface-radius, var(--praxis-chart-embedded-surface-radius, 0) );background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-embedded-surface-bg, transparent) )}.praxis-chart-settings-trigger{position:absolute;top:10px;right:10px;z-index:3;--praxis-icon-button-filled-background: color-mix(in srgb, var(--md-sys-color-surface, #fff) 88%, rgba(18, 99, 180, .12));--praxis-icon-button-filled-foreground: var(--md-sys-color-on-surface-variant, #44474f);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.praxis-chart-data-trigger{position:absolute;top:10px;right:10px;z-index:5;--praxis-icon-button-filled-background: color-mix(in srgb, var(--md-sys-color-surface, #fff) 88%, rgba(18, 99, 180, .12));--praxis-icon-button-filled-foreground: var(--md-sys-color-on-surface-variant, #44474f);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.praxis-chart-data-trigger-with-settings{right:50px}.praxis-chart-accessible-data{position:absolute;inset:0;z-index:4;overflow:auto;padding:52px 16px 16px;color:var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface, #1a1b20));background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-surface-bg, var(--md-sys-color-surface-container-lowest, #fff)) )}.praxis-chart-accessible-data h3{margin:0 0 12px;font-size:1rem;line-height:1.4}.praxis-chart-accessible-data table{width:100%;border-collapse:collapse;font-size:.875rem}.praxis-chart-accessible-data caption{padding:0 0 12px;text-align:left;color:var(--md-sys-color-on-surface-variant, #5a5d67)}.praxis-chart-accessible-data th,.praxis-chart-accessible-data td{padding:8px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline, #c5c7ce) 44%,transparent);text-align:left}.praxis-chart-accessible-data thead th{font-weight:600}.praxis-chart-point-action{appearance:none;padding:4px 6px;border:0;border-radius:4px;color:var(--md-sys-color-primary, #1263b4);background:transparent;font:inherit;font-weight:600;text-align:left;cursor:pointer}.praxis-chart-point-action:hover{background:color-mix(in srgb,var(--md-sys-color-primary, #1263b4) 10%,transparent)}.praxis-chart-point-action:focus-visible{outline:3px solid var(--md-sys-color-primary, #1263b4);outline-offset:2px}.praxis-chart-point-action[aria-pressed=true]{color:var(--md-sys-color-on-primary-container, #001b3f);background:var(--md-sys-color-primary-container, #d7e3ff)}.praxis-chart-host{width:100%;height:100%;min-height:inherit}.praxis-chart-state{height:100%;min-height:min(240px,100%);display:grid;align-content:center;justify-items:center;gap:14px;padding:24px;text-align:center}.praxis-chart-state-copy{display:grid;gap:6px;justify-items:center}.praxis-chart-state-title{font-size:1rem;font-weight:600;color:var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface, #1a1b20))}.praxis-chart-state-description{font-size:.925rem;color:color-mix(in srgb,var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface-variant, #5a5d67)) 72%,transparent);max-width:36rem}.praxis-chart-loading-hero{width:min(100%,320px);display:grid;gap:14px}.praxis-chart-loading-summary{display:flex;gap:8px;justify-content:center}.praxis-chart-loading-chip,.praxis-chart-loading-bar{border-radius:999px;background:linear-gradient(90deg,#1263b414,#1263b438,#1263b414);background-size:200% 100%;animation:praxis-chart-loading-wave 1.2s ease-in-out infinite}.praxis-chart-loading-chip{display:block;width:104px;height:12px}.praxis-chart-loading-chip--short{width:64px}.praxis-chart-loading-plot{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));align-items:end;gap:10px;height:108px;padding:12px 8px 4px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-surface-container, #eef3f8) 72%,transparent);border:1px solid rgba(18,99,180,.08)}.praxis-chart-loading-bar{display:block;width:100%}.praxis-chart-loading-bar--1{height:32%}.praxis-chart-loading-bar--2{height:68%}.praxis-chart-loading-bar--3{height:48%}.praxis-chart-loading-bar--4{height:78%}.praxis-chart-loading-bar--5{height:56%}@keyframes praxis-chart-loading-wave{0%{background-position:100% 0}to{background-position:-100% 0}}\n"], dependencies: [{ kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2801
2921
|
}
|
|
2802
2922
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisChartComponent, decorators: [{
|
|
2803
2923
|
type: Component,
|
|
@@ -2832,6 +2952,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2832
2952
|
></button>
|
|
2833
2953
|
}
|
|
2834
2954
|
|
|
2955
|
+
@if (loadState() === 'ready' && accessiblePoints().length) {
|
|
2956
|
+
<button
|
|
2957
|
+
class="praxis-chart-data-trigger"
|
|
2958
|
+
[class.praxis-chart-data-trigger-with-settings]="canOpenConfigEditor()"
|
|
2959
|
+
praxisIconButton="table_view"
|
|
2960
|
+
size="compact"
|
|
2961
|
+
appearance="filled"
|
|
2962
|
+
type="button"
|
|
2963
|
+
[attr.aria-label]="accessibleDataToggleLabel()"
|
|
2964
|
+
[attr.aria-controls]="accessibilityPanelId"
|
|
2965
|
+
[attr.aria-expanded]="showAccessibleData()"
|
|
2966
|
+
[matTooltip]="accessibleDataToggleLabel()"
|
|
2967
|
+
(click)="toggleAccessibleData()"
|
|
2968
|
+
></button>
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2835
2971
|
@if (loadState() === 'loading') {
|
|
2836
2972
|
<div class="praxis-chart-state praxis-chart-state-loading">
|
|
2837
2973
|
<div class="praxis-chart-loading-hero" aria-hidden="true">
|
|
@@ -2875,10 +3011,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
2875
3011
|
}
|
|
2876
3012
|
</div>
|
|
2877
3013
|
} @else {
|
|
2878
|
-
|
|
3014
|
+
@if (showAccessibleData()) {
|
|
3015
|
+
<section
|
|
3016
|
+
class="praxis-chart-accessible-data"
|
|
3017
|
+
[id]="accessibilityPanelId"
|
|
3018
|
+
role="region"
|
|
3019
|
+
[attr.aria-labelledby]="accessibilityPanelTitleId"
|
|
3020
|
+
>
|
|
3021
|
+
<h3 [id]="accessibilityPanelTitleId">{{ accessibleDataTitle() }}</h3>
|
|
3022
|
+
<table>
|
|
3023
|
+
<caption>{{ accessibleDataDescription() }}</caption>
|
|
3024
|
+
<thead>
|
|
3025
|
+
<tr>
|
|
3026
|
+
<th scope="col">{{ accessibleCategoryHeading() }}</th>
|
|
3027
|
+
<th scope="col">{{ accessibleSeriesHeading() }}</th>
|
|
3028
|
+
<th scope="col">{{ accessibleValueHeading() }}</th>
|
|
3029
|
+
</tr>
|
|
3030
|
+
</thead>
|
|
3031
|
+
<tbody>
|
|
3032
|
+
@for (point of accessiblePoints(); track point.id) {
|
|
3033
|
+
<tr>
|
|
3034
|
+
<th scope="row">
|
|
3035
|
+
<button
|
|
3036
|
+
type="button"
|
|
3037
|
+
class="praxis-chart-point-action"
|
|
3038
|
+
[attr.aria-label]="accessiblePointActionLabel(point)"
|
|
3039
|
+
[attr.aria-pressed]="accessiblePointPressed(point)"
|
|
3040
|
+
(click)="activateAccessiblePoint(point)"
|
|
3041
|
+
>
|
|
3042
|
+
{{ point.categoryLabel }}
|
|
3043
|
+
</button>
|
|
3044
|
+
</th>
|
|
3045
|
+
<td>{{ point.seriesLabel }}</td>
|
|
3046
|
+
<td>{{ point.valueLabel }}</td>
|
|
3047
|
+
</tr>
|
|
3048
|
+
}
|
|
3049
|
+
</tbody>
|
|
3050
|
+
</table>
|
|
3051
|
+
</section>
|
|
3052
|
+
}
|
|
3053
|
+
<div
|
|
3054
|
+
#chartHost
|
|
3055
|
+
class="praxis-chart-host"
|
|
3056
|
+
[attr.aria-hidden]="showAccessibleData() ? 'true' : null"
|
|
3057
|
+
></div>
|
|
2879
3058
|
}
|
|
2880
3059
|
</section>
|
|
2881
|
-
`, styles: [":host{display:block;min-height:var(--praxis-chart-runtime-height, 320px);min-width:0;color:var(--md-sys-color-on-surface, #1a1b20)}:host(.praxis-chart-host-fill-container){height:100%;min-height:0}:host-context(.pdx-shell.no-shell) .praxis-chart-shell,:host-context(.pdx-shell.body-fill) .praxis-chart-shell,:host-context(.pdx-shell.expanded) .praxis-chart-shell,:host-context(.pdx-shell.fullscreen) .praxis-chart-shell{height:100%!important}.praxis-chart-shell{position:relative;width:100%;height:100%;min-height:240px;border-radius:var(--praxis-chart-config-surface-radius, var(--praxis-chart-surface-radius, 8px));overflow:hidden;background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-surface-bg, var(--md-sys-color-surface-container-lowest, #fff)) );border-color:var( --praxis-chart-config-surface-border, var( --praxis-chart-surface-border, color-mix(in srgb, var(--md-sys-color-outline, #c5c7ce) 44%, transparent) ) );border-style:solid;border-width:var(--praxis-chart-config-surface-border-width, 1px)}.praxis-chart-shell-fill-container{min-height:0}:host-context(.pdx-shell) .praxis-chart-shell:not(.praxis-chart-shell-contained),.praxis-chart-shell-embedded{border-width:var( --praxis-chart-config-surface-border-width, var(--praxis-chart-embedded-surface-border-width, 0) );border-radius:var( --praxis-chart-config-surface-radius, var(--praxis-chart-embedded-surface-radius, 0) );background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-embedded-surface-bg, transparent) )}.praxis-chart-settings-trigger{position:absolute;top:10px;right:10px;z-index:3;--praxis-icon-button-filled-background: color-mix(in srgb, var(--md-sys-color-surface, #fff) 88%, rgba(18, 99, 180, .12));--praxis-icon-button-filled-foreground: var(--md-sys-color-on-surface-variant, #44474f);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.praxis-chart-host{width:100%;height:100%;min-height:inherit}.praxis-chart-state{height:100%;min-height:min(240px,100%);display:grid;align-content:center;justify-items:center;gap:14px;padding:24px;text-align:center}.praxis-chart-state-copy{display:grid;gap:6px;justify-items:center}.praxis-chart-state-title{font-size:1rem;font-weight:600;color:var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface, #1a1b20))}.praxis-chart-state-description{font-size:.925rem;color:color-mix(in srgb,var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface-variant, #5a5d67)) 72%,transparent);max-width:36rem}.praxis-chart-loading-hero{width:min(100%,320px);display:grid;gap:14px}.praxis-chart-loading-summary{display:flex;gap:8px;justify-content:center}.praxis-chart-loading-chip,.praxis-chart-loading-bar{border-radius:999px;background:linear-gradient(90deg,#1263b414,#1263b438,#1263b414);background-size:200% 100%;animation:praxis-chart-loading-wave 1.2s ease-in-out infinite}.praxis-chart-loading-chip{display:block;width:104px;height:12px}.praxis-chart-loading-chip--short{width:64px}.praxis-chart-loading-plot{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));align-items:end;gap:10px;height:108px;padding:12px 8px 4px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-surface-container, #eef3f8) 72%,transparent);border:1px solid rgba(18,99,180,.08)}.praxis-chart-loading-bar{display:block;width:100%}.praxis-chart-loading-bar--1{height:32%}.praxis-chart-loading-bar--2{height:68%}.praxis-chart-loading-bar--3{height:48%}.praxis-chart-loading-bar--4{height:78%}.praxis-chart-loading-bar--5{height:56%}@keyframes praxis-chart-loading-wave{0%{background-position:100% 0}to{background-position:-100% 0}}\n"] }]
|
|
3060
|
+
`, styles: [":host{display:block;min-height:var(--praxis-chart-runtime-height, 320px);min-width:0;color:var(--md-sys-color-on-surface, #1a1b20)}:host(.praxis-chart-host-fill-container){height:100%;min-height:0}:host-context(.pdx-shell.no-shell) .praxis-chart-shell,:host-context(.pdx-shell.body-fill) .praxis-chart-shell,:host-context(.pdx-shell.expanded) .praxis-chart-shell,:host-context(.pdx-shell.fullscreen) .praxis-chart-shell{height:100%!important}.praxis-chart-shell{position:relative;width:100%;height:100%;min-height:240px;border-radius:var(--praxis-chart-config-surface-radius, var(--praxis-chart-surface-radius, 8px));overflow:hidden;background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-surface-bg, var(--md-sys-color-surface-container-lowest, #fff)) );border-color:var( --praxis-chart-config-surface-border, var( --praxis-chart-surface-border, color-mix(in srgb, var(--md-sys-color-outline, #c5c7ce) 44%, transparent) ) );border-style:solid;border-width:var(--praxis-chart-config-surface-border-width, 1px)}.praxis-chart-shell-fill-container{min-height:0}:host-context(.pdx-shell) .praxis-chart-shell:not(.praxis-chart-shell-contained),.praxis-chart-shell-embedded{border-width:var( --praxis-chart-config-surface-border-width, var(--praxis-chart-embedded-surface-border-width, 0) );border-radius:var( --praxis-chart-config-surface-radius, var(--praxis-chart-embedded-surface-radius, 0) );background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-embedded-surface-bg, transparent) )}.praxis-chart-settings-trigger{position:absolute;top:10px;right:10px;z-index:3;--praxis-icon-button-filled-background: color-mix(in srgb, var(--md-sys-color-surface, #fff) 88%, rgba(18, 99, 180, .12));--praxis-icon-button-filled-foreground: var(--md-sys-color-on-surface-variant, #44474f);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.praxis-chart-data-trigger{position:absolute;top:10px;right:10px;z-index:5;--praxis-icon-button-filled-background: color-mix(in srgb, var(--md-sys-color-surface, #fff) 88%, rgba(18, 99, 180, .12));--praxis-icon-button-filled-foreground: var(--md-sys-color-on-surface-variant, #44474f);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.praxis-chart-data-trigger-with-settings{right:50px}.praxis-chart-accessible-data{position:absolute;inset:0;z-index:4;overflow:auto;padding:52px 16px 16px;color:var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface, #1a1b20));background:var( --praxis-chart-config-surface-bg, var(--praxis-chart-surface-bg, var(--md-sys-color-surface-container-lowest, #fff)) )}.praxis-chart-accessible-data h3{margin:0 0 12px;font-size:1rem;line-height:1.4}.praxis-chart-accessible-data table{width:100%;border-collapse:collapse;font-size:.875rem}.praxis-chart-accessible-data caption{padding:0 0 12px;text-align:left;color:var(--md-sys-color-on-surface-variant, #5a5d67)}.praxis-chart-accessible-data th,.praxis-chart-accessible-data td{padding:8px;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline, #c5c7ce) 44%,transparent);text-align:left}.praxis-chart-accessible-data thead th{font-weight:600}.praxis-chart-point-action{appearance:none;padding:4px 6px;border:0;border-radius:4px;color:var(--md-sys-color-primary, #1263b4);background:transparent;font:inherit;font-weight:600;text-align:left;cursor:pointer}.praxis-chart-point-action:hover{background:color-mix(in srgb,var(--md-sys-color-primary, #1263b4) 10%,transparent)}.praxis-chart-point-action:focus-visible{outline:3px solid var(--md-sys-color-primary, #1263b4);outline-offset:2px}.praxis-chart-point-action[aria-pressed=true]{color:var(--md-sys-color-on-primary-container, #001b3f);background:var(--md-sys-color-primary-container, #d7e3ff)}.praxis-chart-host{width:100%;height:100%;min-height:inherit}.praxis-chart-state{height:100%;min-height:min(240px,100%);display:grid;align-content:center;justify-items:center;gap:14px;padding:24px;text-align:center}.praxis-chart-state-copy{display:grid;gap:6px;justify-items:center}.praxis-chart-state-title{font-size:1rem;font-weight:600;color:var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface, #1a1b20))}.praxis-chart-state-description{font-size:.925rem;color:color-mix(in srgb,var(--praxis-chart-config-text-color, var(--md-sys-color-on-surface-variant, #5a5d67)) 72%,transparent);max-width:36rem}.praxis-chart-loading-hero{width:min(100%,320px);display:grid;gap:14px}.praxis-chart-loading-summary{display:flex;gap:8px;justify-content:center}.praxis-chart-loading-chip,.praxis-chart-loading-bar{border-radius:999px;background:linear-gradient(90deg,#1263b414,#1263b438,#1263b414);background-size:200% 100%;animation:praxis-chart-loading-wave 1.2s ease-in-out infinite}.praxis-chart-loading-chip{display:block;width:104px;height:12px}.praxis-chart-loading-chip--short{width:64px}.praxis-chart-loading-plot{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));align-items:end;gap:10px;height:108px;padding:12px 8px 4px;border-radius:8px;background:color-mix(in srgb,var(--md-sys-color-surface-container, #eef3f8) 72%,transparent);border:1px solid rgba(18,99,180,.08)}.praxis-chart-loading-bar{display:block;width:100%}.praxis-chart-loading-bar--1{height:32%}.praxis-chart-loading-bar--2{height:68%}.praxis-chart-loading-bar--3{height:48%}.praxis-chart-loading-bar--4{height:78%}.praxis-chart-loading-bar--5{height:56%}@keyframes praxis-chart-loading-wave{0%{background-position:100% 0}to{background-position:-100% 0}}\n"] }]
|
|
2882
3061
|
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], chartDocument: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartDocument", required: false }] }], filterCriteria: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterCriteria", required: false }] }], queryContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "queryContext", required: false }] }], remoteDataResolver: [{ type: i0.Input, args: [{ isSignal: true, alias: "remoteDataResolver", required: false }] }], enableCustomization: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableCustomization", required: false }] }], availableResources: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableResources", required: false }] }], availableFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableFields", required: false }] }], availableTargets: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableTargets", required: false }] }], pointClick: [{ type: i0.Output, args: ["pointClick"] }], pointAction: [{ type: i0.Output, args: ["pointAction"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], drillDown: [{ type: i0.Output, args: ["drillDown"] }], crossFilter: [{ type: i0.Output, args: ["crossFilter"] }], queryRequest: [{ type: i0.Output, args: ["queryRequest"] }], loadStateChange: [{ type: i0.Output, args: ["loadStateChange"] }], chartDocumentApplied: [{ type: i0.Output, args: ["chartDocumentApplied"] }], chartDocumentSaved: [{ type: i0.Output, args: ["chartDocumentSaved"] }], chartHost: [{ type: i0.ViewChild, args: ['chartHost', { isSignal: true }] }] } });
|
|
2883
3062
|
function mergeRemoteQueryContext(config, queryContext, runtimeFilters) {
|
|
2884
3063
|
const dataSource = config.dataSource;
|
|
@@ -2923,6 +3102,111 @@ function resolveUnsupportedStatsFilterExpressionDiagnostic(queryContext) {
|
|
|
2923
3102
|
: '';
|
|
2924
3103
|
return `Praxis Charts received a governed queryContext.filterExpression, but praxis.stats execution currently accepts only flat statsRequest.filter criteria. The expression was rejected instead of being flattened into an unsafe AND filter.${decision}${reason}`;
|
|
2925
3104
|
}
|
|
3105
|
+
function buildAccessibleChartPoints(config, transformed, formatValue, pointFallback, seriesFallback) {
|
|
3106
|
+
if (transformed.mode === 'gauge') {
|
|
3107
|
+
const gauge = transformed.gauge;
|
|
3108
|
+
if (!gauge) {
|
|
3109
|
+
return [];
|
|
3110
|
+
}
|
|
3111
|
+
const series = config.series[0];
|
|
3112
|
+
return [createAccessiblePoint({
|
|
3113
|
+
id: gauge.id,
|
|
3114
|
+
config,
|
|
3115
|
+
seriesId: series?.id,
|
|
3116
|
+
seriesName: series?.name ?? series?.metric?.label,
|
|
3117
|
+
category: gauge.name,
|
|
3118
|
+
value: gauge.value,
|
|
3119
|
+
data: gauge.data,
|
|
3120
|
+
index: 0,
|
|
3121
|
+
formatValue,
|
|
3122
|
+
pointFallback,
|
|
3123
|
+
seriesFallback,
|
|
3124
|
+
})];
|
|
3125
|
+
}
|
|
3126
|
+
if (transformed.mode === 'pie' || transformed.mode === 'funnel' || transformed.mode === 'treemap') {
|
|
3127
|
+
const series = config.series[0];
|
|
3128
|
+
return transformed.slices.map((slice, index) => createAccessiblePoint({
|
|
3129
|
+
id: slice.id,
|
|
3130
|
+
config,
|
|
3131
|
+
seriesId: series?.id,
|
|
3132
|
+
seriesName: series?.name ?? series?.metric?.label,
|
|
3133
|
+
category: slice.name,
|
|
3134
|
+
value: slice.value,
|
|
3135
|
+
data: slice.data,
|
|
3136
|
+
index,
|
|
3137
|
+
formatValue,
|
|
3138
|
+
pointFallback,
|
|
3139
|
+
seriesFallback,
|
|
3140
|
+
}));
|
|
3141
|
+
}
|
|
3142
|
+
return transformed.series.flatMap((series) => series.points.flatMap((point, index) => {
|
|
3143
|
+
const value = accessiblePointValue(point);
|
|
3144
|
+
if (value === null || value === undefined) {
|
|
3145
|
+
return [];
|
|
3146
|
+
}
|
|
3147
|
+
const data = accessiblePointData(point, transformed.categories[index], value);
|
|
3148
|
+
const category = transformed.categories[index]
|
|
3149
|
+
?? accessibleCategoryFromData(config, data)
|
|
3150
|
+
?? pointFallback(index);
|
|
3151
|
+
return [createAccessiblePoint({
|
|
3152
|
+
id: `${series.id}:${index}:${category}`,
|
|
3153
|
+
config,
|
|
3154
|
+
seriesId: series.id,
|
|
3155
|
+
seriesName: series.name,
|
|
3156
|
+
category,
|
|
3157
|
+
value,
|
|
3158
|
+
data,
|
|
3159
|
+
index,
|
|
3160
|
+
formatValue,
|
|
3161
|
+
pointFallback,
|
|
3162
|
+
seriesFallback,
|
|
3163
|
+
})];
|
|
3164
|
+
}));
|
|
3165
|
+
}
|
|
3166
|
+
function createAccessiblePoint(options) {
|
|
3167
|
+
const categoryLabel = options.category?.trim() || options.pointFallback(options.index);
|
|
3168
|
+
const seriesLabel = options.seriesName?.trim()
|
|
3169
|
+
|| options.seriesId?.trim()
|
|
3170
|
+
|| options.seriesFallback();
|
|
3171
|
+
return {
|
|
3172
|
+
id: options.id,
|
|
3173
|
+
chartId: options.config.id,
|
|
3174
|
+
seriesId: options.seriesId,
|
|
3175
|
+
seriesName: options.seriesName,
|
|
3176
|
+
category: options.category,
|
|
3177
|
+
value: options.value,
|
|
3178
|
+
data: options.data ?? {
|
|
3179
|
+
category: options.category,
|
|
3180
|
+
value: options.value,
|
|
3181
|
+
},
|
|
3182
|
+
categoryLabel,
|
|
3183
|
+
seriesLabel,
|
|
3184
|
+
valueLabel: options.formatValue(options.value),
|
|
3185
|
+
};
|
|
3186
|
+
}
|
|
3187
|
+
function accessiblePointValue(point) {
|
|
3188
|
+
if (Array.isArray(point)) {
|
|
3189
|
+
return point.length > 1 ? point[1] : point[0];
|
|
3190
|
+
}
|
|
3191
|
+
if (point && typeof point === 'object' && 'value' in point) {
|
|
3192
|
+
return accessiblePointValue(point['value']);
|
|
3193
|
+
}
|
|
3194
|
+
return point;
|
|
3195
|
+
}
|
|
3196
|
+
function accessiblePointData(point, category, value) {
|
|
3197
|
+
if (point && typeof point === 'object' && !Array.isArray(point)) {
|
|
3198
|
+
return point;
|
|
3199
|
+
}
|
|
3200
|
+
return { category, value };
|
|
3201
|
+
}
|
|
3202
|
+
function accessibleCategoryFromData(config, data) {
|
|
3203
|
+
const categoryField = config.axes?.x?.field
|
|
3204
|
+
?? config.series.find((series) => series.categoryField)?.categoryField;
|
|
3205
|
+
const value = categoryField ? data[categoryField] : data['category'];
|
|
3206
|
+
return value === null || value === undefined || value === ''
|
|
3207
|
+
? undefined
|
|
3208
|
+
: String(value);
|
|
3209
|
+
}
|
|
2926
3210
|
function normalizeRemoteDataResolverResult$1(result) {
|
|
2927
3211
|
if (Array.isArray(result)) {
|
|
2928
3212
|
return of(result);
|
|
@@ -4427,11 +4711,13 @@ const CARTESIAN_GRID_BOTTOM_WITHOUT_LEGEND = 40;
|
|
|
4427
4711
|
const DEFAULT_VALUE_LOCALE = 'pt-BR';
|
|
4428
4712
|
class EChartsOptionBuilderService {
|
|
4429
4713
|
transformer;
|
|
4714
|
+
i18n = inject(PraxisI18nService);
|
|
4430
4715
|
constructor(transformer) {
|
|
4431
4716
|
this.transformer = transformer;
|
|
4432
4717
|
}
|
|
4433
4718
|
build(config, rows) {
|
|
4434
4719
|
const transformed = this.transformer.transform(config, rows);
|
|
4720
|
+
const accessibility = this.buildAccessibility(config, transformed);
|
|
4435
4721
|
const palette = config.theme?.palette?.length ? config.theme.palette : PRAXIS_CHART_DEFAULT_PALETTE;
|
|
4436
4722
|
const tooltipEnabled = config.theme?.tooltip?.enabled ?? true;
|
|
4437
4723
|
const legendVisible = config.theme?.legend?.visible ?? true;
|
|
@@ -4501,6 +4787,7 @@ class EChartsOptionBuilderService {
|
|
|
4501
4787
|
}],
|
|
4502
4788
|
};
|
|
4503
4789
|
return {
|
|
4790
|
+
aria: accessibility,
|
|
4504
4791
|
backgroundColor: config.theme?.backgroundColor,
|
|
4505
4792
|
color: palette,
|
|
4506
4793
|
title: this.buildTitle(config, 'center', textColor),
|
|
@@ -4545,6 +4832,7 @@ class EChartsOptionBuilderService {
|
|
|
4545
4832
|
})),
|
|
4546
4833
|
};
|
|
4547
4834
|
return {
|
|
4835
|
+
aria: accessibility,
|
|
4548
4836
|
backgroundColor: config.theme?.backgroundColor,
|
|
4549
4837
|
color: palette,
|
|
4550
4838
|
title: this.buildTitle(config, 'center', textColor),
|
|
@@ -4595,6 +4883,7 @@ class EChartsOptionBuilderService {
|
|
|
4595
4883
|
})),
|
|
4596
4884
|
};
|
|
4597
4885
|
return {
|
|
4886
|
+
aria: accessibility,
|
|
4598
4887
|
backgroundColor: config.theme?.backgroundColor,
|
|
4599
4888
|
color: palette,
|
|
4600
4889
|
title: this.buildTitle(config, 'center', textColor),
|
|
@@ -4638,6 +4927,7 @@ class EChartsOptionBuilderService {
|
|
|
4638
4927
|
})),
|
|
4639
4928
|
};
|
|
4640
4929
|
return {
|
|
4930
|
+
aria: accessibility,
|
|
4641
4931
|
backgroundColor: config.theme?.backgroundColor,
|
|
4642
4932
|
color: palette,
|
|
4643
4933
|
title: this.buildTitle(config, 'center', textColor),
|
|
@@ -4667,6 +4957,7 @@ class EChartsOptionBuilderService {
|
|
|
4667
4957
|
data: series.points,
|
|
4668
4958
|
}));
|
|
4669
4959
|
return {
|
|
4960
|
+
aria: accessibility,
|
|
4670
4961
|
backgroundColor: config.theme?.backgroundColor,
|
|
4671
4962
|
color: palette,
|
|
4672
4963
|
title: this.buildTitle(config, 'left', textColor),
|
|
@@ -4713,6 +5004,7 @@ class EChartsOptionBuilderService {
|
|
|
4713
5004
|
? 'time'
|
|
4714
5005
|
: config.axes?.x?.type ?? 'category';
|
|
4715
5006
|
return {
|
|
5007
|
+
aria: accessibility,
|
|
4716
5008
|
backgroundColor: config.theme?.backgroundColor,
|
|
4717
5009
|
color: palette,
|
|
4718
5010
|
title: this.buildTitle(config, 'left', textColor),
|
|
@@ -4799,6 +5091,57 @@ class EChartsOptionBuilderService {
|
|
|
4799
5091
|
}
|
|
4800
5092
|
return undefined;
|
|
4801
5093
|
}
|
|
5094
|
+
buildAccessibility(config, transformed) {
|
|
5095
|
+
const title = this.i18n.resolve(config.title).trim();
|
|
5096
|
+
const seriesCount = transformed.mode === 'gauge'
|
|
5097
|
+
? transformed.gauge ? 1 : 0
|
|
5098
|
+
: transformed.slices.length
|
|
5099
|
+
? 1
|
|
5100
|
+
: transformed.series.length;
|
|
5101
|
+
const pointCount = transformed.mode === 'gauge'
|
|
5102
|
+
? transformed.gauge ? 1 : 0
|
|
5103
|
+
: transformed.slices.length
|
|
5104
|
+
? transformed.slices.length
|
|
5105
|
+
: transformed.series.reduce((total, series) => total + series.points.length, 0);
|
|
5106
|
+
const params = {
|
|
5107
|
+
title,
|
|
5108
|
+
type: this.chartTypeLabel(config.type),
|
|
5109
|
+
seriesCount,
|
|
5110
|
+
pointCount,
|
|
5111
|
+
};
|
|
5112
|
+
const description = title
|
|
5113
|
+
? this.t('praxis.charts.runtime.accessibility.ariaDescriptionWithTitle', 'Chart "{{ title }}". Type: {{ type }}. Series: {{ seriesCount }}. Points: {{ pointCount }}. Complete values are available under "Show chart data".', params)
|
|
5114
|
+
: this.t('praxis.charts.runtime.accessibility.ariaDescriptionWithoutTitle', 'Chart. Type: {{ type }}. Series: {{ seriesCount }}. Points: {{ pointCount }}. Complete values are available under "Show chart data".', params);
|
|
5115
|
+
return {
|
|
5116
|
+
enabled: true,
|
|
5117
|
+
label: {
|
|
5118
|
+
enabled: true,
|
|
5119
|
+
description,
|
|
5120
|
+
},
|
|
5121
|
+
};
|
|
5122
|
+
}
|
|
5123
|
+
chartTypeLabel(type) {
|
|
5124
|
+
const fallbacks = {
|
|
5125
|
+
bar: 'Bar',
|
|
5126
|
+
'horizontal-bar': 'Horizontal bar',
|
|
5127
|
+
line: 'Line',
|
|
5128
|
+
area: 'Area',
|
|
5129
|
+
'stacked-bar': 'Stacked bar',
|
|
5130
|
+
'stacked-area': 'Stacked area',
|
|
5131
|
+
combo: 'Combination',
|
|
5132
|
+
pie: 'Pie',
|
|
5133
|
+
donut: 'Donut',
|
|
5134
|
+
scatter: 'Scatter',
|
|
5135
|
+
funnel: 'Funnel',
|
|
5136
|
+
pyramid: 'Pyramid',
|
|
5137
|
+
treemap: 'Treemap',
|
|
5138
|
+
gauge: 'Gauge',
|
|
5139
|
+
};
|
|
5140
|
+
return this.t(`praxis.charts.runtime.accessibility.chartType.${type}`, fallbacks[type]);
|
|
5141
|
+
}
|
|
5142
|
+
t(key, fallback, params) {
|
|
5143
|
+
return this.i18n.t(key, params, fallback, PRAXIS_CHARTS_I18N_NAMESPACE);
|
|
5144
|
+
}
|
|
4802
5145
|
resolveTextColor(config) {
|
|
4803
5146
|
return config.theme?.textColor ?? '#4b5563';
|
|
4804
5147
|
}
|
|
@@ -5458,6 +5801,33 @@ const PRAXIS_CHARTS_EN_US = {
|
|
|
5458
5801
|
'praxis.charts.runtime.gaugeValueInvalid': 'The gauge requires one finite metric value.',
|
|
5459
5802
|
'praxis.charts.runtime.gaugeValueOutOfRange': 'The gauge value is outside the configured scale. Review the metric and scale instead of clamping the value.',
|
|
5460
5803
|
'praxis.charts.runtime.booleanFalseLabel': 'Not {{ label }}',
|
|
5804
|
+
'praxis.charts.runtime.accessibility.showData': 'Show chart data',
|
|
5805
|
+
'praxis.charts.runtime.accessibility.hideData': 'Hide chart data',
|
|
5806
|
+
'praxis.charts.runtime.accessibility.dataTitle': 'Chart data',
|
|
5807
|
+
'praxis.charts.runtime.accessibility.dataDescription': 'Structured alternative for the values represented in the chart.',
|
|
5808
|
+
'praxis.charts.runtime.accessibility.category': 'Category',
|
|
5809
|
+
'praxis.charts.runtime.accessibility.series': 'Series',
|
|
5810
|
+
'praxis.charts.runtime.accessibility.value': 'Value',
|
|
5811
|
+
'praxis.charts.runtime.accessibility.pointFallback': 'Point {{ index }}',
|
|
5812
|
+
'praxis.charts.runtime.accessibility.seriesFallback': 'Series',
|
|
5813
|
+
'praxis.charts.runtime.accessibility.notAvailable': 'Not available',
|
|
5814
|
+
'praxis.charts.runtime.accessibility.activatePoint': 'Activate {{ category }}, {{ series }}: {{ value }}',
|
|
5815
|
+
'praxis.charts.runtime.accessibility.ariaDescriptionWithTitle': 'Chart "{{ title }}". Type: {{ type }}. Series: {{ seriesCount }}. Points: {{ pointCount }}. Complete values are available under "Show chart data".',
|
|
5816
|
+
'praxis.charts.runtime.accessibility.ariaDescriptionWithoutTitle': 'Chart. Type: {{ type }}. Series: {{ seriesCount }}. Points: {{ pointCount }}. Complete values are available under "Show chart data".',
|
|
5817
|
+
'praxis.charts.runtime.accessibility.chartType.bar': 'Bar',
|
|
5818
|
+
'praxis.charts.runtime.accessibility.chartType.horizontal-bar': 'Horizontal bar',
|
|
5819
|
+
'praxis.charts.runtime.accessibility.chartType.line': 'Line',
|
|
5820
|
+
'praxis.charts.runtime.accessibility.chartType.area': 'Area',
|
|
5821
|
+
'praxis.charts.runtime.accessibility.chartType.stacked-bar': 'Stacked bar',
|
|
5822
|
+
'praxis.charts.runtime.accessibility.chartType.stacked-area': 'Stacked area',
|
|
5823
|
+
'praxis.charts.runtime.accessibility.chartType.combo': 'Combination',
|
|
5824
|
+
'praxis.charts.runtime.accessibility.chartType.pie': 'Pie',
|
|
5825
|
+
'praxis.charts.runtime.accessibility.chartType.donut': 'Donut',
|
|
5826
|
+
'praxis.charts.runtime.accessibility.chartType.scatter': 'Scatter',
|
|
5827
|
+
'praxis.charts.runtime.accessibility.chartType.funnel': 'Funnel',
|
|
5828
|
+
'praxis.charts.runtime.accessibility.chartType.pyramid': 'Pyramid',
|
|
5829
|
+
'praxis.charts.runtime.accessibility.chartType.treemap': 'Treemap',
|
|
5830
|
+
'praxis.charts.runtime.accessibility.chartType.gauge': 'Gauge',
|
|
5461
5831
|
'praxis.charts.runtime.comparisonCurrent': 'Current',
|
|
5462
5832
|
'praxis.charts.runtime.comparisonPrevious': 'Previous',
|
|
5463
5833
|
'praxis.charts.widget.missingDocument': 'This widget does not have a canonical chart document yet. Runtime inputs are preserved until a canonical chartDocument is provided by the host.',
|
|
@@ -5693,6 +6063,33 @@ const PRAXIS_CHARTS_PT_BR = {
|
|
|
5693
6063
|
'praxis.charts.runtime.gaugeValueInvalid': 'O velocímetro exige um único valor numérico finito.',
|
|
5694
6064
|
'praxis.charts.runtime.gaugeValueOutOfRange': 'O valor do velocímetro está fora da escala configurada. Revise a métrica e a escala em vez de limitar o valor silenciosamente.',
|
|
5695
6065
|
'praxis.charts.runtime.booleanFalseLabel': 'Não {{ label }}',
|
|
6066
|
+
'praxis.charts.runtime.accessibility.showData': 'Exibir dados do gráfico',
|
|
6067
|
+
'praxis.charts.runtime.accessibility.hideData': 'Ocultar dados do gráfico',
|
|
6068
|
+
'praxis.charts.runtime.accessibility.dataTitle': 'Dados do gráfico',
|
|
6069
|
+
'praxis.charts.runtime.accessibility.dataDescription': 'Alternativa estruturada para os valores representados no gráfico.',
|
|
6070
|
+
'praxis.charts.runtime.accessibility.category': 'Categoria',
|
|
6071
|
+
'praxis.charts.runtime.accessibility.series': 'Série',
|
|
6072
|
+
'praxis.charts.runtime.accessibility.value': 'Valor',
|
|
6073
|
+
'praxis.charts.runtime.accessibility.pointFallback': 'Ponto {{ index }}',
|
|
6074
|
+
'praxis.charts.runtime.accessibility.seriesFallback': 'Série',
|
|
6075
|
+
'praxis.charts.runtime.accessibility.notAvailable': 'Não disponível',
|
|
6076
|
+
'praxis.charts.runtime.accessibility.activatePoint': 'Ativar {{ category }}, {{ series }}: {{ value }}',
|
|
6077
|
+
'praxis.charts.runtime.accessibility.ariaDescriptionWithTitle': 'Gráfico "{{ title }}". Tipo: {{ type }}. Séries: {{ seriesCount }}. Pontos: {{ pointCount }}. Os valores completos estão disponíveis em "Exibir dados do gráfico".',
|
|
6078
|
+
'praxis.charts.runtime.accessibility.ariaDescriptionWithoutTitle': 'Gráfico. Tipo: {{ type }}. Séries: {{ seriesCount }}. Pontos: {{ pointCount }}. Os valores completos estão disponíveis em "Exibir dados do gráfico".',
|
|
6079
|
+
'praxis.charts.runtime.accessibility.chartType.bar': 'Barras',
|
|
6080
|
+
'praxis.charts.runtime.accessibility.chartType.horizontal-bar': 'Barras horizontais',
|
|
6081
|
+
'praxis.charts.runtime.accessibility.chartType.line': 'Linhas',
|
|
6082
|
+
'praxis.charts.runtime.accessibility.chartType.area': 'Área',
|
|
6083
|
+
'praxis.charts.runtime.accessibility.chartType.stacked-bar': 'Barras empilhadas',
|
|
6084
|
+
'praxis.charts.runtime.accessibility.chartType.stacked-area': 'Área empilhada',
|
|
6085
|
+
'praxis.charts.runtime.accessibility.chartType.combo': 'Combinado',
|
|
6086
|
+
'praxis.charts.runtime.accessibility.chartType.pie': 'Pizza',
|
|
6087
|
+
'praxis.charts.runtime.accessibility.chartType.donut': 'Rosca',
|
|
6088
|
+
'praxis.charts.runtime.accessibility.chartType.scatter': 'Dispersão',
|
|
6089
|
+
'praxis.charts.runtime.accessibility.chartType.funnel': 'Funil',
|
|
6090
|
+
'praxis.charts.runtime.accessibility.chartType.pyramid': 'Pirâmide',
|
|
6091
|
+
'praxis.charts.runtime.accessibility.chartType.treemap': 'Mapa de árvore',
|
|
6092
|
+
'praxis.charts.runtime.accessibility.chartType.gauge': 'Velocímetro',
|
|
5696
6093
|
'praxis.charts.runtime.comparisonCurrent': 'Atual',
|
|
5697
6094
|
'praxis.charts.runtime.comparisonPrevious': 'Anterior',
|
|
5698
6095
|
'praxis.charts.widget.missingDocument': 'Este widget ainda não possui um documento canônico de gráfico. Os inputs runtime são preservados até o host fornecer um chartDocument canônico.',
|
|
@@ -9557,6 +9954,7 @@ function provideChartEngineFactory(options) {
|
|
|
9557
9954
|
function providePraxisCharts(options = {}) {
|
|
9558
9955
|
return [
|
|
9559
9956
|
...providePraxisChartsI18n(),
|
|
9957
|
+
EChartsOptionBuilderService,
|
|
9560
9958
|
provideChartEngineFactory(options),
|
|
9561
9959
|
providePraxisChartsMetadata(),
|
|
9562
9960
|
providePraxisChartDrilldownPanelMetadata(),
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/charts",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.40",
|
|
4
4
|
"description": "Metadata-driven charts library for Praxis UI Angular with engine adapters and Apache ECharts as the initial renderer.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
|
7
7
|
"@angular/core": "^21.0.0",
|
|
8
|
-
"@praxisui/core": "^9.0.
|
|
8
|
+
"@praxisui/core": "^9.0.40",
|
|
9
9
|
"@angular/forms": "^21.0.0",
|
|
10
10
|
"@angular/material": "^21.0.0",
|
|
11
|
-
"@praxisui/table": "^9.0.
|
|
11
|
+
"@praxisui/table": "^9.0.40",
|
|
12
12
|
"rxjs": "~7.8.0"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
@@ -547,6 +547,12 @@ interface ChartEditorTargetOption {
|
|
|
547
547
|
events?: ChartEditorEventKey[];
|
|
548
548
|
}
|
|
549
549
|
|
|
550
|
+
interface PraxisChartAccessiblePoint extends PraxisChartPointEvent {
|
|
551
|
+
id: string;
|
|
552
|
+
categoryLabel: string;
|
|
553
|
+
seriesLabel: string;
|
|
554
|
+
valueLabel: string;
|
|
555
|
+
}
|
|
550
556
|
declare class PraxisChartComponent {
|
|
551
557
|
readonly config: _angular_core.InputSignal<PraxisChartConfig>;
|
|
552
558
|
readonly data: _angular_core.InputSignal<PraxisChartDataRow[] | null>;
|
|
@@ -592,6 +598,9 @@ declare class PraxisChartComponent {
|
|
|
592
598
|
private readonly mappedRuntimeConfig;
|
|
593
599
|
private readonly chartDocumentMappingError;
|
|
594
600
|
private readonly activeSelectionSignature;
|
|
601
|
+
readonly showAccessibleData: _angular_core.WritableSignal<boolean>;
|
|
602
|
+
readonly accessibilityPanelId: string;
|
|
603
|
+
readonly accessibilityPanelTitleId: string;
|
|
595
604
|
private readonly fillContainerHeight;
|
|
596
605
|
private readonly renderAttempt;
|
|
597
606
|
private resizeFrameId;
|
|
@@ -620,16 +629,24 @@ declare class PraxisChartComponent {
|
|
|
620
629
|
readonly surfaceTextColor: _angular_core.Signal<string | null>;
|
|
621
630
|
readonly renderConfig: _angular_core.Signal<PraxisChartConfig>;
|
|
622
631
|
readonly loadingLabel: _angular_core.Signal<string>;
|
|
623
|
-
readonly transformedData: _angular_core.Signal<
|
|
632
|
+
readonly transformedData: _angular_core.Signal<PraxisChartTransformedData>;
|
|
633
|
+
readonly accessiblePoints: _angular_core.Signal<PraxisChartAccessiblePoint[]>;
|
|
624
634
|
readonly dataDiagnostic: _angular_core.Signal<PraxisChartDataDiagnostic | null>;
|
|
625
635
|
readonly emptyTitle: _angular_core.Signal<string>;
|
|
626
636
|
readonly emptyDescription: _angular_core.Signal<string>;
|
|
627
637
|
readonly errorTitle: _angular_core.Signal<string>;
|
|
628
638
|
readonly errorDescription: _angular_core.Signal<string>;
|
|
629
639
|
readonly editChartLabel: _angular_core.Signal<string>;
|
|
640
|
+
readonly accessibleDataToggleLabel: _angular_core.Signal<string>;
|
|
641
|
+
readonly accessibleDataTitle: _angular_core.Signal<string>;
|
|
642
|
+
readonly accessibleDataDescription: _angular_core.Signal<string>;
|
|
643
|
+
readonly accessibleCategoryHeading: _angular_core.Signal<string>;
|
|
644
|
+
readonly accessibleSeriesHeading: _angular_core.Signal<string>;
|
|
645
|
+
readonly accessibleValueHeading: _angular_core.Signal<string>;
|
|
630
646
|
readonly loadState: _angular_core.Signal<PraxisChartLoadState>;
|
|
631
647
|
constructor();
|
|
632
648
|
private resolveDataDiagnosticDescription;
|
|
649
|
+
private formatAccessibleValue;
|
|
633
650
|
private t;
|
|
634
651
|
canOpenConfigEditor(): boolean;
|
|
635
652
|
openConfigEditor(): Promise<void>;
|
|
@@ -638,6 +655,10 @@ declare class PraxisChartComponent {
|
|
|
638
655
|
private isConfigEditorContextResult;
|
|
639
656
|
private asRecord;
|
|
640
657
|
private handlePointClick;
|
|
658
|
+
toggleAccessibleData(): void;
|
|
659
|
+
activateAccessiblePoint(point: PraxisChartAccessiblePoint): void;
|
|
660
|
+
accessiblePointPressed(point: PraxisChartAccessiblePoint): string | null;
|
|
661
|
+
accessiblePointActionLabel(point: PraxisChartAccessiblePoint): string;
|
|
641
662
|
private buildSelectionEvent;
|
|
642
663
|
private buildPointSelectionSignature;
|
|
643
664
|
private buildSelectionScopeSignature;
|