@praxisui/charts 9.0.35 → 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
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"
|
|
@@ -1877,6 +1877,7 @@ class PraxisChartComponent {
|
|
|
1877
1877
|
runtimeChartDocument = signal(null, ...(ngDevMode ? [{ debugName: "runtimeChartDocument" }] : /* istanbul ignore next */ []));
|
|
1878
1878
|
mappedRuntimeConfig = signal(null, ...(ngDevMode ? [{ debugName: "mappedRuntimeConfig" }] : /* istanbul ignore next */ []));
|
|
1879
1879
|
chartDocumentMappingError = signal(null, ...(ngDevMode ? [{ debugName: "chartDocumentMappingError" }] : /* istanbul ignore next */ []));
|
|
1880
|
+
activeSelectionSignature = signal(null, ...(ngDevMode ? [{ debugName: "activeSelectionSignature" }] : /* istanbul ignore next */ []));
|
|
1880
1881
|
fillContainerHeight = signal(false, ...(ngDevMode ? [{ debugName: "fillContainerHeight" }] : /* istanbul ignore next */ []));
|
|
1881
1882
|
renderAttempt = signal(0, ...(ngDevMode ? [{ debugName: "renderAttempt" }] : /* istanbul ignore next */ []));
|
|
1882
1883
|
resizeFrameId = null;
|
|
@@ -1889,6 +1890,7 @@ class PraxisChartComponent {
|
|
|
1889
1890
|
editorSessionSubscriptions = [];
|
|
1890
1891
|
remoteRequestSubscription = null;
|
|
1891
1892
|
remoteRequestSequence = 0;
|
|
1893
|
+
previousSelectionScopeSignature = null;
|
|
1892
1894
|
effectiveConfig = computed(() => {
|
|
1893
1895
|
const base = this.applyInheritedTheme(this.mappedRuntimeConfig() ?? this.config(), this.inheritedTheme());
|
|
1894
1896
|
const runtimeQueryContext = normalizePraxisDataQueryContext(this.queryContext());
|
|
@@ -2101,6 +2103,14 @@ class PraxisChartComponent {
|
|
|
2101
2103
|
this.remoteRuntimeState.set('idle');
|
|
2102
2104
|
this.remoteTechnicalError.set(null);
|
|
2103
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
|
+
});
|
|
2104
2114
|
effect(() => {
|
|
2105
2115
|
const nextState = this.loadState();
|
|
2106
2116
|
if (this.currentLoadState() !== nextState) {
|
|
@@ -2362,7 +2372,9 @@ class PraxisChartComponent {
|
|
|
2362
2372
|
const crossFilterAction = interactions.eventActions?.crossFilter;
|
|
2363
2373
|
this.crossFilter.emit({
|
|
2364
2374
|
chartId: config.id ?? event.chartId,
|
|
2365
|
-
filters:
|
|
2375
|
+
filters: selectionEvent.selected
|
|
2376
|
+
? this.buildEventFilters(config, event, crossFilterAction?.mapping)
|
|
2377
|
+
: {},
|
|
2366
2378
|
target: crossFilterAction?.target,
|
|
2367
2379
|
action: crossFilterAction,
|
|
2368
2380
|
source: selectionEvent,
|
|
@@ -2372,15 +2384,43 @@ class PraxisChartComponent {
|
|
|
2372
2384
|
buildSelectionEvent(config, event) {
|
|
2373
2385
|
const action = config.interactions?.eventActions?.selectionChange;
|
|
2374
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);
|
|
2375
2390
|
return {
|
|
2376
2391
|
...event,
|
|
2377
2392
|
chartId: config.id ?? event.chartId,
|
|
2378
|
-
selected
|
|
2393
|
+
selected,
|
|
2379
2394
|
mode: 'single',
|
|
2380
|
-
filters,
|
|
2395
|
+
filters: selected ? filters : {},
|
|
2381
2396
|
action,
|
|
2382
2397
|
};
|
|
2383
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
|
+
}
|
|
2384
2424
|
buildEventFilters(config, event, mapping) {
|
|
2385
2425
|
const sourceValues = this.extractPointSourceValues(config, event);
|
|
2386
2426
|
if (!mapping || !Object.keys(mapping).length) {
|
|
@@ -8679,7 +8719,7 @@ const PRAXIS_CHART_PHASE1_PORTS = [
|
|
|
8679
8719
|
label: 'Selection Change',
|
|
8680
8720
|
direction: 'output',
|
|
8681
8721
|
semanticKind: 'event',
|
|
8682
|
-
description: 'Canonical
|
|
8722
|
+
description: 'Canonical single-point selection payload. Repeating the active point emits selected=false with empty filters; selecting another point replaces it.',
|
|
8683
8723
|
cardinality: 'stream',
|
|
8684
8724
|
schema: {
|
|
8685
8725
|
id: 'PraxisChartSelectionEvent',
|
|
@@ -11459,7 +11499,7 @@ const PRAXIS_CHARTS_AUTHORING_MANIFEST = {
|
|
|
11459
11499
|
identityKeys: ['availableTargets[].id'],
|
|
11460
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' } } } },
|
|
11461
11501
|
failureModes: ['target-not-in-catalog', 'mapping-source-field-missing', 'mapping-target-invalid', 'unsafe-event-action'],
|
|
11462
|
-
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.',
|
|
11463
11503
|
} }],
|
|
11464
11504
|
destructive: false,
|
|
11465
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>;
|
|
@@ -636,6 +638,8 @@ declare class PraxisChartComponent {
|
|
|
636
638
|
private asRecord;
|
|
637
639
|
private handlePointClick;
|
|
638
640
|
private buildSelectionEvent;
|
|
641
|
+
private buildPointSelectionSignature;
|
|
642
|
+
private buildSelectionScopeSignature;
|
|
639
643
|
private buildEventFilters;
|
|
640
644
|
private extractPointSourceValues;
|
|
641
645
|
private extractPointMetricValue;
|