@praxisui/charts 9.0.34 → 9.0.36
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 +1 -1
- package/ai/component-registry.json +6 -6
- package/fesm2022/praxisui-charts.mjs +66 -34
- package/package.json +3 -3
- package/types/praxisui-charts.d.ts +5 -0
package/README.md
CHANGED
|
@@ -125,7 +125,7 @@ Use the component with either local data or governed remote execution:
|
|
|
125
125
|
- `pointClick`: raw renderer-neutral point evidence. Configured click actions are emitted separately through `pointAction`.
|
|
126
126
|
- For categorical `praxis.stats` points, `data.key` remains the canonical bucket identity while `label` and the category field remain presentation evidence, including when distinct buckets share the same display label.
|
|
127
127
|
- For time-series `praxis.stats` points, `data.start` (falling back to a valid temporal `data.key`) drives the time coordinate, `data.end` preserves the inclusive bucket boundary, and `data.label` remains presentation evidence. After the target is grounded from the governed filter schema, Page Builder composition can materialize a range input as `[data.start, data.end]`, guarded on both boundaries. Repeated labels therefore do not collapse distinct periods.
|
|
128
|
-
- `selectionChange`: single-point selection evidence with canonical filters.
|
|
128
|
+
- `selectionChange`: single-point selection evidence with canonical filters. A repeated click on the active point emits `selected: false` with empty filters; clicking another point replaces the selection. Multi-select is not advertised by this runtime contract.
|
|
129
129
|
- `drillDown` and `crossFilter`: structured action/filter payloads intended for Page Builder composition links and governed host orchestration.
|
|
130
130
|
- Analytics projections with `crossFilter=true` must publish `bindings.primaryDimension.keyFilterField`. The analytics adapter maps the preserved raw row `key` to that public request field and fails closed when the binding is absent; labels and dimension naming conventions are never used as filter identity.
|
|
131
131
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-08-
|
|
3
|
+
"generatedAt": "2026-08-29T20:24:51.350Z",
|
|
4
4
|
"packageName": "@praxisui/charts",
|
|
5
|
-
"packageVersion": "9.0.
|
|
5
|
+
"packageVersion": "9.0.36",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 3,
|
|
@@ -720,7 +720,7 @@
|
|
|
720
720
|
"label": "Selection Change",
|
|
721
721
|
"direction": "output",
|
|
722
722
|
"semanticKind": "event",
|
|
723
|
-
"description": "Canonical
|
|
723
|
+
"description": "Canonical single-point selection payload. Repeating the active point emits selected=false with empty filters; selecting another point replaces it.",
|
|
724
724
|
"cardinality": "stream",
|
|
725
725
|
"schema": {
|
|
726
726
|
"id": "PraxisChartSelectionEvent",
|
|
@@ -2541,7 +2541,7 @@
|
|
|
2541
2541
|
"mapping-target-invalid",
|
|
2542
2542
|
"unsafe-event-action"
|
|
2543
2543
|
],
|
|
2544
|
-
"description": "Configures selectionChange as single-point selection evidence whose event key is governed by the operation."
|
|
2544
|
+
"description": "Configures selectionChange as single-point selection evidence whose event key is governed by the operation. Repeating the active point clears the selection and emits empty filters; selecting another point replaces it."
|
|
2545
2545
|
}
|
|
2546
2546
|
}
|
|
2547
2547
|
],
|
|
@@ -3305,9 +3305,9 @@
|
|
|
3305
3305
|
{
|
|
3306
3306
|
"chunkIndex": 20,
|
|
3307
3307
|
"chunkKind": "authoring_manifest",
|
|
3308
|
-
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.4.0\",\"componentId\":\"praxis-chart\",\"ownerPackage\":\"@praxisui/charts\",\"configSchemaId\":\"PraxisXUiChartContract\",\"chunkSection\":\"operations\",\"operations\":[{\"operationId\":\"pointClick.configure\",\"title\":\"Configure chart point click\",\"scope\":\"eventMapping\",\"targetKind\":\"pointClick\",\"target\":{\"kind\":\"pointClick\",\"resolver\":\"x-ui-chart-events-point-click\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"chart-event-point-click-configure\",\"handlerContract\":{\"reads\":[\"chartDocument.events.pointClick\",\"chartDocument.dimensions[]\",\"availableTargets[]\"],\"writes\":[\"chartDocument.events.pointClick\"],\"identityKeys\":[\"availableTargets[].id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"failureModes\":[\"target-not-in-catalog\",\"mapping-source-field-missing\",\"mapping-target-invalid\",\"unsafe-event-action\"],\"description\":\"Configures pointClick through the pointAction output while keeping pointClick as raw point evidence.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"point-click-action-structured\",\"event-target-governed\",\"event-mapping-fields-exist\",\"event-action-supported\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.events.pointClick\"],\"submissionImpact\":\"affects-schema-backed-data\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"crossFilter.configure\",\"title\":\"Configure chart cross-filter\",\"scope\":\"eventMapping\",\"targetKind\":\"crossFilter\",\"target\":{\"kind\":\"crossFilter\",\"resolver\":\"x-ui-chart-events-cross-filter\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"chart-event-cross-filter-configure\",\"handlerContract\":{\"reads\":[\"chartDocument.events.crossFilter\",\"chartDocument.dimensions[]\",\"availableTargets[]\"],\"writes\":[\"chartDocument.events.crossFilter\"],\"identityKeys\":[\"availableTargets[].id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"failureModes\":[\"target-not-in-catalog\",\"mapping-source-field-missing\",\"mapping-target-invalid\",\"unsafe-event-action\"],\"description\":\"Configures crossFilter as a structured event action emitted through the crossFilter output with safe query-context filters to a governed target. For praxis.stats rows, key is governed bucket identity and label is presentation evidence; mappings may use key when the target schema accepts that identity.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"cross-filter-output-structured\",\"event-target-governed\",\"event-mapping-fields-exist\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.events.crossFilter\"],\"submissionImpact\":\"affects-schema-backed-data\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"drilldown.configure\",\"title\":\"Configure chart drilldown\",\"scope\":\"eventMapping\",\"targetKind\":\"drilldown\",\"target\":{\"kind\":\"drilldown\",\"resolver\":\"x-ui-chart-events-drill-down\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"chart-event-drilldown-configure\",\"handlerContract\":{\"reads\":[\"chartDocument.events.drillDown\",\"chartDocument.dimensions[]\",\"availableTargets[]\"],\"writes\":[\"chartDocument.events.drillDown\"],\"identityKeys\":[\"availableTargets[].id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"failureModes\":[\"target-not-in-catalog\",\"mapping-source-field-missing\",\"drilldown-target-invalid\",\"unsafe-event-action\"],\"description\":\"Configures drillDown through the dedicated drillDown output with governed route/widget targets and structured field mappings.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"drilldown-target-governed\",\"event-mapping-fields-exist\",\"event-action-supported\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.events.drillDown\"],\"submissionImpact\":\"config-only\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"selection.configure\",\"title\":\"Configure chart selection\",\"scope\":\"selection\",\"targetKind\":\"selection\",\"target\":{\"kind\":\"selection\",\"resolver\":\"x-ui-chart-events-selection-change\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"chart-event-selection-configure\",\"handlerContract\":{\"reads\":[\"chartDocument.events.selectionChange\",\"chartDocument.dimensions[]\",\"availableTargets[]\"],\"writes\":[\"chartDocument.events.selectionChange\"],\"identityKeys\":[\"availableTargets[].id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"failureModes\":[\"target-not-in-catalog\",\"mapping-source-field-missing\",\"mapping-target-invalid\",\"unsafe-event-action\"],\"description\":\"Configures selectionChange as single-point selection evidence whose event key is governed by the operation.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"selection-output-structured\",\"event-target-governed\",\"event-mapping-fields-exist\",\"event-action-supported\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.events.selectionChange\"],\"submissionImpact\":\"affects-schema-backed-data\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"legend.configure\",\"title\":\"Configure chart legend\",\"scope\":\"skin\",\"targetKind\":\"legend\",\"target\":{\"kind\":\"legend\",\"resolver\":\"x-ui-chart-legend-feature\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"enabled\"],\"properties\":{\"enabled\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"set-value\",\"path\":\"chartDocument.legend\"}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"feature-toggle-valid\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.legend\"],\"submissionImpact\":\"visual-only\",\"preconditions\":[\"config-initialized\"]}]}",
|
|
3308
|
+
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.4.0\",\"componentId\":\"praxis-chart\",\"ownerPackage\":\"@praxisui/charts\",\"configSchemaId\":\"PraxisXUiChartContract\",\"chunkSection\":\"operations\",\"operations\":[{\"operationId\":\"pointClick.configure\",\"title\":\"Configure chart point click\",\"scope\":\"eventMapping\",\"targetKind\":\"pointClick\",\"target\":{\"kind\":\"pointClick\",\"resolver\":\"x-ui-chart-events-point-click\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"chart-event-point-click-configure\",\"handlerContract\":{\"reads\":[\"chartDocument.events.pointClick\",\"chartDocument.dimensions[]\",\"availableTargets[]\"],\"writes\":[\"chartDocument.events.pointClick\"],\"identityKeys\":[\"availableTargets[].id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"failureModes\":[\"target-not-in-catalog\",\"mapping-source-field-missing\",\"mapping-target-invalid\",\"unsafe-event-action\"],\"description\":\"Configures pointClick through the pointAction output while keeping pointClick as raw point evidence.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"point-click-action-structured\",\"event-target-governed\",\"event-mapping-fields-exist\",\"event-action-supported\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.events.pointClick\"],\"submissionImpact\":\"affects-schema-backed-data\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"crossFilter.configure\",\"title\":\"Configure chart cross-filter\",\"scope\":\"eventMapping\",\"targetKind\":\"crossFilter\",\"target\":{\"kind\":\"crossFilter\",\"resolver\":\"x-ui-chart-events-cross-filter\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"chart-event-cross-filter-configure\",\"handlerContract\":{\"reads\":[\"chartDocument.events.crossFilter\",\"chartDocument.dimensions[]\",\"availableTargets[]\"],\"writes\":[\"chartDocument.events.crossFilter\"],\"identityKeys\":[\"availableTargets[].id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"failureModes\":[\"target-not-in-catalog\",\"mapping-source-field-missing\",\"mapping-target-invalid\",\"unsafe-event-action\"],\"description\":\"Configures crossFilter as a structured event action emitted through the crossFilter output with safe query-context filters to a governed target. For praxis.stats rows, key is governed bucket identity and label is presentation evidence; mappings may use key when the target schema accepts that identity.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"cross-filter-output-structured\",\"event-target-governed\",\"event-mapping-fields-exist\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.events.crossFilter\"],\"submissionImpact\":\"affects-schema-backed-data\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"drilldown.configure\",\"title\":\"Configure chart drilldown\",\"scope\":\"eventMapping\",\"targetKind\":\"drilldown\",\"target\":{\"kind\":\"drilldown\",\"resolver\":\"x-ui-chart-events-drill-down\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"chart-event-drilldown-configure\",\"handlerContract\":{\"reads\":[\"chartDocument.events.drillDown\",\"chartDocument.dimensions[]\",\"availableTargets[]\"],\"writes\":[\"chartDocument.events.drillDown\"],\"identityKeys\":[\"availableTargets[].id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"failureModes\":[\"target-not-in-catalog\",\"mapping-source-field-missing\",\"drilldown-target-invalid\",\"unsafe-event-action\"],\"description\":\"Configures drillDown through the dedicated drillDown output with governed route/widget targets and structured field mappings.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"drilldown-target-governed\",\"event-mapping-fields-exist\",\"event-action-supported\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.events.drillDown\"],\"submissionImpact\":\"config-only\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"selection.configure\",\"title\":\"Configure chart selection\",\"scope\":\"selection\",\"targetKind\":\"selection\",\"target\":{\"kind\":\"selection\",\"resolver\":\"x-ui-chart-events-selection-change\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"chart-event-selection-configure\",\"handlerContract\":{\"reads\":[\"chartDocument.events.selectionChange\",\"chartDocument.dimensions[]\",\"availableTargets[]\"],\"writes\":[\"chartDocument.events.selectionChange\"],\"identityKeys\":[\"availableTargets[].id\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"action\"],\"properties\":{\"action\":{\"enum\":[\"filter-widget\",\"open-detail\",\"navigate\",\"update-context\",\"emit\"]},\"target\":{\"type\":\"string\"},\"mapping\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}},\"failureModes\":[\"target-not-in-catalog\",\"mapping-source-field-missing\",\"mapping-target-invalid\",\"unsafe-event-action\"],\"description\":\"Configures selectionChange as single-point selection evidence whose event key is governed by the operation. Repeating the active point clears the selection and emits empty filters; selecting another point replaces it.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"selection-output-structured\",\"event-target-governed\",\"event-mapping-fields-exist\",\"event-action-supported\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.events.selectionChange\"],\"submissionImpact\":\"affects-schema-backed-data\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"legend.configure\",\"title\":\"Configure chart legend\",\"scope\":\"skin\",\"targetKind\":\"legend\",\"target\":{\"kind\":\"legend\",\"resolver\":\"x-ui-chart-legend-feature\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"enabled\"],\"properties\":{\"enabled\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"set-value\",\"path\":\"chartDocument.legend\"}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"feature-toggle-valid\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"chartDocument.legend\"],\"submissionImpact\":\"visual-only\",\"preconditions\":[\"config-initialized\"]}]}",
|
|
3309
3309
|
"sourcePointer": "projects/praxis-charts/src/lib/ai/praxis-charts-authoring-manifest.ts",
|
|
3310
|
-
"contentHash": "
|
|
3310
|
+
"contentHash": "86035e3cd9743a4412118dc65c4da27402520fd20b4540380941c2400fcc5024",
|
|
3311
3311
|
"sourceKind": "component_definition",
|
|
3312
3312
|
"sourceId": "praxis-chart",
|
|
3313
3313
|
"corpusVersion": "1.0.0"
|
|
@@ -482,6 +482,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
482
482
|
args: [{ providedIn: 'root' }]
|
|
483
483
|
}] });
|
|
484
484
|
|
|
485
|
+
const PRAXIS_CHARTS_I18N_NAMESPACE = 'charts';
|
|
486
|
+
|
|
485
487
|
class ChartContractNormalizerService {
|
|
486
488
|
normalize(input) {
|
|
487
489
|
let document = structuredClone(input);
|
|
@@ -1564,7 +1566,7 @@ class PraxisChartCanonicalContractMapperService {
|
|
|
1564
1566
|
? 'praxis.charts.runtime.comparisonCurrent'
|
|
1565
1567
|
: 'praxis.charts.runtime.comparisonPrevious';
|
|
1566
1568
|
const fallback = period === 'current' ? 'Current' : 'Previous';
|
|
1567
|
-
return this.i18n?.t(key, undefined, fallback,
|
|
1569
|
+
return this.i18n?.t(key, undefined, fallback, PRAXIS_CHARTS_I18N_NAMESPACE) ?? fallback;
|
|
1568
1570
|
}
|
|
1569
1571
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisChartCanonicalContractMapperService, deps: [{ token: ChartContractNormalizerService }, { token: ChartContractValidationService }, { token: i1.PraxisI18nService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1570
1572
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisChartCanonicalContractMapperService, providedIn: 'root' });
|
|
@@ -1675,7 +1677,7 @@ class PraxisChartStatsApiService {
|
|
|
1675
1677
|
}
|
|
1676
1678
|
return value
|
|
1677
1679
|
? axisLabel
|
|
1678
|
-
: this.i18n.t('praxis.charts.runtime.booleanFalseLabel', { label: axisLabel }, `Não ${axisLabel}`,
|
|
1680
|
+
: this.i18n.t('praxis.charts.runtime.booleanFalseLabel', { label: axisLabel }, `Não ${axisLabel}`, PRAXIS_CHARTS_I18N_NAMESPACE);
|
|
1679
1681
|
}
|
|
1680
1682
|
readBooleanBucketValue(bucket) {
|
|
1681
1683
|
if (typeof bucket.key === 'boolean') {
|
|
@@ -1875,6 +1877,7 @@ class PraxisChartComponent {
|
|
|
1875
1877
|
runtimeChartDocument = signal(null, ...(ngDevMode ? [{ debugName: "runtimeChartDocument" }] : /* istanbul ignore next */ []));
|
|
1876
1878
|
mappedRuntimeConfig = signal(null, ...(ngDevMode ? [{ debugName: "mappedRuntimeConfig" }] : /* istanbul ignore next */ []));
|
|
1877
1879
|
chartDocumentMappingError = signal(null, ...(ngDevMode ? [{ debugName: "chartDocumentMappingError" }] : /* istanbul ignore next */ []));
|
|
1880
|
+
activeSelectionSignature = signal(null, ...(ngDevMode ? [{ debugName: "activeSelectionSignature" }] : /* istanbul ignore next */ []));
|
|
1878
1881
|
fillContainerHeight = signal(false, ...(ngDevMode ? [{ debugName: "fillContainerHeight" }] : /* istanbul ignore next */ []));
|
|
1879
1882
|
renderAttempt = signal(0, ...(ngDevMode ? [{ debugName: "renderAttempt" }] : /* istanbul ignore next */ []));
|
|
1880
1883
|
resizeFrameId = null;
|
|
@@ -1887,6 +1890,7 @@ class PraxisChartComponent {
|
|
|
1887
1890
|
editorSessionSubscriptions = [];
|
|
1888
1891
|
remoteRequestSubscription = null;
|
|
1889
1892
|
remoteRequestSequence = 0;
|
|
1893
|
+
previousSelectionScopeSignature = null;
|
|
1890
1894
|
effectiveConfig = computed(() => {
|
|
1891
1895
|
const base = this.applyInheritedTheme(this.mappedRuntimeConfig() ?? this.config(), this.inheritedTheme());
|
|
1892
1896
|
const runtimeQueryContext = normalizePraxisDataQueryContext(this.queryContext());
|
|
@@ -2010,33 +2014,18 @@ class PraxisChartComponent {
|
|
|
2010
2014
|
emptyTitle = computed(() => this.i18n.resolve(this.renderConfig().emptyState?.title), ...(ngDevMode ? [{ debugName: "emptyTitle" }] : /* istanbul ignore next */ []));
|
|
2011
2015
|
emptyDescription = computed(() => this.i18n.resolve(this.renderConfig().emptyState?.description), ...(ngDevMode ? [{ debugName: "emptyDescription" }] : /* istanbul ignore next */ []));
|
|
2012
2016
|
errorTitle = computed(() => this.chartDocumentMappingError()
|
|
2013
|
-
? this.
|
|
2014
|
-
key: 'praxis.charts.runtime.invalidDocumentTitle',
|
|
2015
|
-
text: 'Chart configuration is invalid',
|
|
2016
|
-
})
|
|
2017
|
+
? this.t('praxis.charts.runtime.invalidDocumentTitle', 'Chart configuration is invalid')
|
|
2017
2018
|
: this.dataDiagnostic()
|
|
2018
|
-
? this.
|
|
2019
|
-
key: 'praxis.charts.runtime.invalidDataTitle',
|
|
2020
|
-
text: 'Chart data is incompatible with its canonical configuration',
|
|
2021
|
-
})
|
|
2019
|
+
? this.t('praxis.charts.runtime.invalidDataTitle', 'Chart data is incompatible with its canonical configuration')
|
|
2022
2020
|
: this.i18n.resolve(this.renderConfig().state?.error?.title)
|
|
2023
|
-
|| this.
|
|
2024
|
-
key: 'praxis.charts.runtime.remoteErrorTitle',
|
|
2025
|
-
text: 'Não foi possível carregar os dados do gráfico',
|
|
2026
|
-
}), ...(ngDevMode ? [{ debugName: "errorTitle" }] : /* istanbul ignore next */ []));
|
|
2021
|
+
|| this.t('praxis.charts.runtime.remoteErrorTitle', 'Não foi possível carregar os dados do gráfico'), ...(ngDevMode ? [{ debugName: "errorTitle" }] : /* istanbul ignore next */ []));
|
|
2027
2022
|
errorDescription = computed(() => this.chartDocumentMappingError()
|
|
2028
|
-
? this.
|
|
2029
|
-
key: 'praxis.charts.runtime.invalidDocumentDescription',
|
|
2030
|
-
text: 'The canonical chart document could not be mapped to the Praxis chart runtime. Review the chart contract before continuing.',
|
|
2031
|
-
})
|
|
2023
|
+
? this.t('praxis.charts.runtime.invalidDocumentDescription', 'The canonical chart document could not be mapped to the Praxis chart runtime. Review the chart contract before continuing.')
|
|
2032
2024
|
: this.dataDiagnostic()
|
|
2033
2025
|
? this.resolveDataDiagnosticDescription(this.dataDiagnostic())
|
|
2034
2026
|
: this.i18n.resolve(this.renderConfig().state?.error?.description)
|
|
2035
|
-
|| this.
|
|
2036
|
-
|
|
2037
|
-
text: 'Revise a fonte de dados e os filtros antes de continuar.',
|
|
2038
|
-
}), ...(ngDevMode ? [{ debugName: "errorDescription" }] : /* istanbul ignore next */ []));
|
|
2039
|
-
editChartLabel = computed(() => this.i18n.resolve({ key: 'praxis.charts.runtime.editChart', text: 'Edit chart settings' }), ...(ngDevMode ? [{ debugName: "editChartLabel" }] : /* istanbul ignore next */ []));
|
|
2027
|
+
|| this.t('praxis.charts.runtime.remoteErrorDescription', 'Revise a fonte de dados e os filtros antes de continuar.'), ...(ngDevMode ? [{ debugName: "errorDescription" }] : /* istanbul ignore next */ []));
|
|
2028
|
+
editChartLabel = computed(() => this.t('praxis.charts.runtime.editChart', 'Edit chart settings'), ...(ngDevMode ? [{ debugName: "editChartLabel" }] : /* istanbul ignore next */ []));
|
|
2040
2029
|
loadState = computed(() => {
|
|
2041
2030
|
if (this.chartDocumentMappingError()) {
|
|
2042
2031
|
return 'error';
|
|
@@ -2114,6 +2103,14 @@ class PraxisChartComponent {
|
|
|
2114
2103
|
this.remoteRuntimeState.set('idle');
|
|
2115
2104
|
this.remoteTechnicalError.set(null);
|
|
2116
2105
|
});
|
|
2106
|
+
effect(() => {
|
|
2107
|
+
const signature = this.buildSelectionScopeSignature();
|
|
2108
|
+
if (signature === this.previousSelectionScopeSignature) {
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
this.previousSelectionScopeSignature = signature;
|
|
2112
|
+
this.activeSelectionSignature.set(null);
|
|
2113
|
+
});
|
|
2117
2114
|
effect(() => {
|
|
2118
2115
|
const nextState = this.loadState();
|
|
2119
2116
|
if (this.currentLoadState() !== nextState) {
|
|
@@ -2232,7 +2229,11 @@ class PraxisChartComponent {
|
|
|
2232
2229
|
text: 'The gauge value is outside the configured scale. Review the metric and scale instead of clamping the value.',
|
|
2233
2230
|
},
|
|
2234
2231
|
};
|
|
2235
|
-
|
|
2232
|
+
const description = descriptions[diagnostic.code];
|
|
2233
|
+
return this.t(description.key, description.text);
|
|
2234
|
+
}
|
|
2235
|
+
t(key, fallback) {
|
|
2236
|
+
return this.i18n.t(key, undefined, fallback, PRAXIS_CHARTS_I18N_NAMESPACE);
|
|
2236
2237
|
}
|
|
2237
2238
|
canOpenConfigEditor() {
|
|
2238
2239
|
return this.enableCustomization() && !!this.settingsPanel && !!this.runtimeChartDocument();
|
|
@@ -2371,7 +2372,9 @@ class PraxisChartComponent {
|
|
|
2371
2372
|
const crossFilterAction = interactions.eventActions?.crossFilter;
|
|
2372
2373
|
this.crossFilter.emit({
|
|
2373
2374
|
chartId: config.id ?? event.chartId,
|
|
2374
|
-
filters:
|
|
2375
|
+
filters: selectionEvent.selected
|
|
2376
|
+
? this.buildEventFilters(config, event, crossFilterAction?.mapping)
|
|
2377
|
+
: {},
|
|
2375
2378
|
target: crossFilterAction?.target,
|
|
2376
2379
|
action: crossFilterAction,
|
|
2377
2380
|
source: selectionEvent,
|
|
@@ -2381,15 +2384,43 @@ class PraxisChartComponent {
|
|
|
2381
2384
|
buildSelectionEvent(config, event) {
|
|
2382
2385
|
const action = config.interactions?.eventActions?.selectionChange;
|
|
2383
2386
|
const filters = this.buildEventFilters(config, event, action?.mapping);
|
|
2387
|
+
const signature = this.buildPointSelectionSignature(config, event);
|
|
2388
|
+
const selected = this.activeSelectionSignature() !== signature;
|
|
2389
|
+
this.activeSelectionSignature.set(selected ? signature : null);
|
|
2384
2390
|
return {
|
|
2385
2391
|
...event,
|
|
2386
2392
|
chartId: config.id ?? event.chartId,
|
|
2387
|
-
selected
|
|
2393
|
+
selected,
|
|
2388
2394
|
mode: 'single',
|
|
2389
|
-
filters,
|
|
2395
|
+
filters: selected ? filters : {},
|
|
2390
2396
|
action,
|
|
2391
2397
|
};
|
|
2392
2398
|
}
|
|
2399
|
+
buildPointSelectionSignature(config, event) {
|
|
2400
|
+
const sourceValues = Object.entries(this.extractPointSourceValues(config, event))
|
|
2401
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
2402
|
+
return JSON.stringify({
|
|
2403
|
+
chartId: config.id ?? event.chartId,
|
|
2404
|
+
seriesId: event.seriesId,
|
|
2405
|
+
seriesName: event.seriesName,
|
|
2406
|
+
category: event.category,
|
|
2407
|
+
sourceValues,
|
|
2408
|
+
});
|
|
2409
|
+
}
|
|
2410
|
+
buildSelectionScopeSignature() {
|
|
2411
|
+
const config = this.renderConfig();
|
|
2412
|
+
return JSON.stringify({
|
|
2413
|
+
id: config.id,
|
|
2414
|
+
type: config.type,
|
|
2415
|
+
axes: config.axes,
|
|
2416
|
+
series: config.series,
|
|
2417
|
+
dataSource: config.dataSource,
|
|
2418
|
+
interactions: config.interactions,
|
|
2419
|
+
filterCriteria: this.filterCriteria(),
|
|
2420
|
+
queryContext: normalizePraxisDataQueryContext(this.queryContext()),
|
|
2421
|
+
data: this.resolvedData(),
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2393
2424
|
buildEventFilters(config, event, mapping) {
|
|
2394
2425
|
const sourceValues = this.extractPointSourceValues(config, event);
|
|
2395
2426
|
if (!mapping || !Object.keys(mapping).length) {
|
|
@@ -4133,7 +4164,7 @@ class AnalyticsChartConfigAdapterService {
|
|
|
4133
4164
|
? 'praxis.charts.runtime.comparisonCurrent'
|
|
4134
4165
|
: 'praxis.charts.runtime.comparisonPrevious';
|
|
4135
4166
|
const fallback = period === 'current' ? 'Current' : 'Previous';
|
|
4136
|
-
return this.i18n?.t(key, undefined, fallback,
|
|
4167
|
+
return this.i18n?.t(key, undefined, fallback, PRAXIS_CHARTS_I18N_NAMESPACE) ?? fallback;
|
|
4137
4168
|
}
|
|
4138
4169
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AnalyticsChartConfigAdapterService, deps: [{ token: i1.PraxisI18nService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4139
4170
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: AnalyticsChartConfigAdapterService, providedIn: 'root' });
|
|
@@ -4365,7 +4396,7 @@ class PraxisAnalyticsPresentationComponent {
|
|
|
4365
4396
|
return resolved || null;
|
|
4366
4397
|
}
|
|
4367
4398
|
t(key, fallback) {
|
|
4368
|
-
return this.i18n.t(key, undefined, fallback,
|
|
4399
|
+
return this.i18n.t(key, undefined, fallback, PRAXIS_CHARTS_I18N_NAMESPACE);
|
|
4369
4400
|
}
|
|
4370
4401
|
message(key, fallback, values) {
|
|
4371
4402
|
return Object.entries(values).reduce((message, [name, value]) => message.replaceAll(`{${name}}`, value), this.t(key, fallback));
|
|
@@ -5902,7 +5933,7 @@ function createPraxisChartsI18nConfig(options = {}) {
|
|
|
5902
5933
|
locale: options.locale,
|
|
5903
5934
|
fallbackLocale: options.fallbackLocale ?? 'pt-BR',
|
|
5904
5935
|
namespaces: {
|
|
5905
|
-
|
|
5936
|
+
[PRAXIS_CHARTS_I18N_NAMESPACE]: localeDictionaries,
|
|
5906
5937
|
},
|
|
5907
5938
|
};
|
|
5908
5939
|
}
|
|
@@ -7874,7 +7905,7 @@ class PraxisChartConfigEditor {
|
|
|
7874
7905
|
return `${issue.code}:${issue.field}`;
|
|
7875
7906
|
}
|
|
7876
7907
|
t(key, fallback) {
|
|
7877
|
-
return this.i18n.
|
|
7908
|
+
return this.i18n.t(key, undefined, fallback, PRAXIS_CHARTS_I18N_NAMESPACE);
|
|
7878
7909
|
}
|
|
7879
7910
|
doc() {
|
|
7880
7911
|
return this.currentDocument();
|
|
@@ -8305,7 +8336,7 @@ class PraxisChartWidgetConfigEditor {
|
|
|
8305
8336
|
this.updateValidity();
|
|
8306
8337
|
}
|
|
8307
8338
|
t(key, fallback) {
|
|
8308
|
-
return this.i18n.
|
|
8339
|
+
return this.i18n.t(key, undefined, fallback, PRAXIS_CHARTS_I18N_NAMESPACE);
|
|
8309
8340
|
}
|
|
8310
8341
|
contextDiagnosticText(diagnostic) {
|
|
8311
8342
|
switch (diagnostic.code) {
|
|
@@ -8688,7 +8719,7 @@ const PRAXIS_CHART_PHASE1_PORTS = [
|
|
|
8688
8719
|
label: 'Selection Change',
|
|
8689
8720
|
direction: 'output',
|
|
8690
8721
|
semanticKind: 'event',
|
|
8691
|
-
description: 'Canonical
|
|
8722
|
+
description: 'Canonical single-point selection payload. Repeating the active point emits selected=false with empty filters; selecting another point replaces it.',
|
|
8692
8723
|
cardinality: 'stream',
|
|
8693
8724
|
schema: {
|
|
8694
8725
|
id: 'PraxisChartSelectionEvent',
|
|
@@ -9515,6 +9546,7 @@ function provideChartEngineFactory(options) {
|
|
|
9515
9546
|
}
|
|
9516
9547
|
function providePraxisCharts(options = {}) {
|
|
9517
9548
|
return [
|
|
9549
|
+
...providePraxisChartsI18n(),
|
|
9518
9550
|
provideChartEngineFactory(options),
|
|
9519
9551
|
providePraxisChartsMetadata(),
|
|
9520
9552
|
providePraxisChartDrilldownPanelMetadata(),
|
|
@@ -11467,7 +11499,7 @@ const PRAXIS_CHARTS_AUTHORING_MANIFEST = {
|
|
|
11467
11499
|
identityKeys: ['availableTargets[].id'],
|
|
11468
11500
|
inputSchema: { type: 'object', required: ['action'], properties: { action: { enum: ['filter-widget', 'open-detail', 'navigate', 'update-context', 'emit'] }, target: { type: 'string' }, mapping: { type: 'object', additionalProperties: { type: 'string' } } } },
|
|
11469
11501
|
failureModes: ['target-not-in-catalog', 'mapping-source-field-missing', 'mapping-target-invalid', 'unsafe-event-action'],
|
|
11470
|
-
description: 'Configures selectionChange as single-point selection evidence whose event key is governed by the operation.',
|
|
11502
|
+
description: 'Configures selectionChange as single-point selection evidence whose event key is governed by the operation. Repeating the active point clears the selection and emits empty filters; selecting another point replaces it.',
|
|
11471
11503
|
} }],
|
|
11472
11504
|
destructive: false,
|
|
11473
11505
|
requiresConfirmation: false,
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/charts",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.36",
|
|
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.36",
|
|
9
9
|
"@angular/forms": "^21.0.0",
|
|
10
10
|
"@angular/material": "^21.0.0",
|
|
11
|
-
"@praxisui/table": "^9.0.
|
|
11
|
+
"@praxisui/table": "^9.0.36",
|
|
12
12
|
"rxjs": "~7.8.0"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
@@ -590,6 +590,7 @@ declare class PraxisChartComponent {
|
|
|
590
590
|
private readonly runtimeChartDocument;
|
|
591
591
|
private readonly mappedRuntimeConfig;
|
|
592
592
|
private readonly chartDocumentMappingError;
|
|
593
|
+
private readonly activeSelectionSignature;
|
|
593
594
|
private readonly fillContainerHeight;
|
|
594
595
|
private readonly renderAttempt;
|
|
595
596
|
private resizeFrameId;
|
|
@@ -602,6 +603,7 @@ declare class PraxisChartComponent {
|
|
|
602
603
|
private editorSessionSubscriptions;
|
|
603
604
|
private remoteRequestSubscription;
|
|
604
605
|
private remoteRequestSequence;
|
|
606
|
+
private previousSelectionScopeSignature;
|
|
605
607
|
readonly effectiveConfig: _angular_core.Signal<PraxisChartConfig>;
|
|
606
608
|
readonly resolvedData: _angular_core.Signal<PraxisChartDataRow[]>;
|
|
607
609
|
readonly resolvedHeight: _angular_core.Signal<string>;
|
|
@@ -627,6 +629,7 @@ declare class PraxisChartComponent {
|
|
|
627
629
|
readonly loadState: _angular_core.Signal<PraxisChartLoadState>;
|
|
628
630
|
constructor();
|
|
629
631
|
private resolveDataDiagnosticDescription;
|
|
632
|
+
private t;
|
|
630
633
|
canOpenConfigEditor(): boolean;
|
|
631
634
|
openConfigEditor(): Promise<void>;
|
|
632
635
|
private resolveConfigEditorContext;
|
|
@@ -635,6 +638,8 @@ declare class PraxisChartComponent {
|
|
|
635
638
|
private asRecord;
|
|
636
639
|
private handlePointClick;
|
|
637
640
|
private buildSelectionEvent;
|
|
641
|
+
private buildPointSelectionSignature;
|
|
642
|
+
private buildSelectionScopeSignature;
|
|
638
643
|
private buildEventFilters;
|
|
639
644
|
private extractPointSourceValues;
|
|
640
645
|
private extractPointMetricValue;
|