@praxisui/charts 9.0.0-beta.22 → 9.0.0-beta.26
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/ai/component-registry.json +7 -7
- package/fesm2022/praxisui-charts.mjs +614 -14
- package/package.json +3 -3
- package/types/praxisui-charts.d.ts +31 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-
|
|
3
|
+
"generatedAt": "2026-07-01T18:24:10.710Z",
|
|
4
4
|
"packageName": "@praxisui/charts",
|
|
5
|
-
"packageVersion": "9.0.0-beta.
|
|
5
|
+
"packageVersion": "9.0.0-beta.26",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 2,
|
|
@@ -970,7 +970,7 @@
|
|
|
970
970
|
"affectedPaths": [
|
|
971
971
|
"queryContext"
|
|
972
972
|
],
|
|
973
|
-
"submissionImpact": "
|
|
973
|
+
"submissionImpact": "affects-schema-backed-data",
|
|
974
974
|
"preconditions": [
|
|
975
975
|
"config-initialized"
|
|
976
976
|
]
|
|
@@ -1093,7 +1093,7 @@
|
|
|
1093
1093
|
"affectedPaths": [
|
|
1094
1094
|
"chartDocument.events.crossFilter"
|
|
1095
1095
|
],
|
|
1096
|
-
"submissionImpact": "
|
|
1096
|
+
"submissionImpact": "affects-schema-backed-data",
|
|
1097
1097
|
"preconditions": [
|
|
1098
1098
|
"config-initialized"
|
|
1099
1099
|
]
|
|
@@ -1284,7 +1284,7 @@
|
|
|
1284
1284
|
"affectedPaths": [
|
|
1285
1285
|
"chartDocument.events.selectionChange"
|
|
1286
1286
|
],
|
|
1287
|
-
"submissionImpact": "
|
|
1287
|
+
"submissionImpact": "affects-schema-backed-data",
|
|
1288
1288
|
"preconditions": [
|
|
1289
1289
|
"config-initialized"
|
|
1290
1290
|
]
|
|
@@ -1753,9 +1753,9 @@
|
|
|
1753
1753
|
{
|
|
1754
1754
|
"chunkIndex": 1,
|
|
1755
1755
|
"chunkKind": "authoring_manifest",
|
|
1756
|
-
"content": "{\n \"schemaVersion\": \"1.0.0\",\n \"componentId\": \"praxis-chart\",\n \"ownerPackage\": \"@praxisui/charts\",\n \"configSchemaId\": \"PraxisXUiChartContract\",\n \"manifestVersion\": \"1.0.0\",\n \"runtimeInputs\": [\n {\n \"name\": \"chartDocument\",\n \"type\": \"PraxisXUiChartContract | null\",\n \"description\": \"Canonical x-ui.chart document used as the authoring source of truth.\"\n },\n {\n \"name\": \"config\",\n \"type\": \"PraxisChartConfig\",\n \"description\": \"Runtime chart configuration mapped from or supplied beside the canonical chart document.\"\n },\n {\n \"name\": \"queryContext\",\n \"type\": \"PraxisChartQueryContext | null\",\n \"description\": \"Declarative query context merged into remote datasource requests.\"\n },\n {\n \"name\": \"remoteDataResolver\",\n \"type\": \"PraxisChartRemoteDataResolver | null\",\n \"description\": \"Host-governed remote row resolver for integrations outside the default praxis.stats client.\"\n },\n {\n \"name\": \"availableResources\",\n \"type\": \"ChartEditorResourceOption[]\",\n \"description\": \"Governed remote resource catalog exposed to the config editor.\"\n },\n {\n \"name\": \"availableFields\",\n \"type\": \"ChartEditorFieldOption[]\",\n \"description\": \"Governed semantic field catalog exposed to the config editor.\"\n },\n {\n \"name\": \"availableTargets\",\n \"type\": \"ChartEditorTargetOption[]\",\n \"description\": \"Governed widget or route targets exposed to chart event authoring.\"\n }\n ],\n \"editableTargets\": [\n {\n \"kind\": \"chartType\",\n \"resolver\": \"x-ui-chart-kind\",\n \"description\": \"Canonical `kind` field in PraxisXUiChartContract.\"\n },\n {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"description\": \"Metric-backed series definition in `metrics[]`, keyed by field.\"\n },\n {\n \"kind\": \"axis\",\n \"resolver\": \"x-ui-chart-dimension-or-metric-axis\",\n \"description\": \"Dimension role, metric axis and chart orientation semantics.\"\n },\n {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-source-and-field-catalog\",\n \"description\": \"Source, dimensions, metrics and resource/field bindings.\"\n },\n {\n \"kind\": \"queryContext\",\n \"resolver\": \"praxis-chart-query-context\",\n \"description\": \"Runtime queryContext contract for filters, sort, limit and page.\"\n },\n {\n \"kind\": \"crossFilter\",\n \"resolver\": \"x-ui-chart-events-cross-filter\",\n \"description\": \"Cross-filter event mapping emitted as structured query-context filters.\"\n },\n {\n \"kind\": \"drilldown\",\n \"resolver\": \"x-ui-chart-events-drill-down\",\n \"description\": \"Drilldown event mapping and governed target.\"\n },\n {\n \"kind\": \"selection\",\n \"resolver\": \"x-ui-chart-events-selection-change\",\n \"description\": \"Selection event enablement and mapping semantics.\"\n },\n {\n \"kind\": \"legend\",\n \"resolver\": \"x-ui-chart-legend-feature\",\n \"description\": \"Legend visibility through boolean or toggleable feature object.\"\n },\n {\n \"kind\": \"tooltip\",\n \"resolver\": \"x-ui-chart-tooltip-feature\",\n \"description\": \"Tooltip visibility through boolean or toggleable feature object.\"\n }\n ],\n \"operations\": [\n {\n \"operationId\": \"chart.document.set\",\n \"title\": \"Set chart document\",\n \"scope\": \"global\",\n \"targetKind\": \"dataBinding\",\n \"target\": {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-document-root\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"kind\",\n \"source\"\n ],\n \"properties\": {\n \"version\": {\n \"const\": \"0.1.0\"\n },\n \"kind\": {\n \"enum\": [\n \"bar\",\n \"combo\",\n \"horizontal-bar\",\n \"line\",\n \"pie\",\n \"donut\",\n \"area\",\n \"stacked-bar\",\n \"stacked-area\",\n \"scatter\"\n ]\n },\n \"chartId\": {\n \"type\": \"string\"\n },\n \"title\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"subtitle\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"source\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"options\": {\n \"type\": \"object\"\n }\n }\n },\n \"dimensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"metrics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"events\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"chart-document-shape\",\n \"chart-version-supported\",\n \"chart-type-series-axis-compatible\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"chart.type.set\",\n \"title\": \"Set chart type\",\n \"scope\": \"global\",\n \"targetKind\": \"chartType\",\n \"target\": {\n \"kind\": \"chartType\",\n \"resolver\": \"x-ui-chart-kind\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"bar\",\n \"combo\",\n \"horizontal-bar\",\n \"line\",\n \"pie\",\n \"donut\",\n \"area\",\n \"stacked-bar\",\n \"stacked-area\",\n \"scatter\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-object\",\n \"path\": \"chartDocument\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"chart-type-supported\",\n \"chart-type-series-axis-compatible\",\n \"pie-single-metric\",\n \"combo-minimum-series\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.kind\",\n \"chartDocument.orientation\",\n \"chartDocument.metrics[]\",\n \"chartDocument.dimensions[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"series.add\",\n \"title\": \"Add chart series\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"series\",\n \"target\": {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-series-add\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.kind\",\n \"chartDocument.metrics[]\",\n \"availableFields[]\"\n ],\n \"writes\": [\n \"chartDocument.metrics[]\"\n ],\n \"identityKeys\": [\n \"chartDocument.metrics[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n },\n \"failureModes\": [\n \"field-not-in-catalog\",\n \"duplicate-series-field\",\n \"aggregation-not-supported\",\n \"chart-type-series-incompatible\"\n ],\n \"description\": \"Adds a metric-backed series by semantic field, validating it against availableFields and chart kind compatibility before patching metrics[].\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"series-field-exists\",\n \"series-field-aggregable\",\n \"series-id-unique\",\n \"chart-type-series-axis-compatible\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"series.remove\",\n \"title\": \"Remove chart series\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"series\",\n \"target\": {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"replacementField\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"remove-by-key\",\n \"path\": \"chartDocument.metrics[]\",\n \"key\": \"field\"\n }\n ],\n \"destructive\": true,\n \"requiresConfirmation\": true,\n \"validators\": [\n \"series-exists\",\n \"destructive-series-removal-confirmed\",\n \"chart-keeps-required-metric\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-series-exists\",\n \"confirmation-collected\"\n ]\n },\n {\n \"operationId\": \"axis.configure\",\n \"title\": \"Configure chart axis\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"axis\",\n \"target\": {\n \"kind\": \"axis\",\n \"resolver\": \"x-ui-chart-dimension-or-metric-axis\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"dimensionField\": {\n \"type\": \"string\"\n },\n \"dimensionRole\": {\n \"enum\": [\n \"category\",\n \"series\",\n \"segment\",\n \"time\",\n \"value\"\n ]\n },\n \"metricField\": {\n \"type\": \"string\"\n },\n \"metricAxis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-axis-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.kind\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\",\n \"availableFields[]\"\n ],\n \"writes\": [\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\",\n \"chartDocument.orientation\"\n ],\n \"identityKeys\": [\n \"chartDocument.dimensions[].field\",\n \"chartDocument.metrics[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"dimensionField\": {\n \"type\": \"string\"\n },\n \"dimensionRole\": {\n \"enum\": [\n \"category\",\n \"series\",\n \"segment\",\n \"time\",\n \"value\"\n ]\n },\n \"metricField\": {\n \"type\": \"string\"\n },\n \"metricAxis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"failureModes\": [\n \"field-not-in-catalog\",\n \"secondary-axis-non-combo\",\n \"missing-required-dimension\",\n \"axis-role-incompatible\"\n ],\n \"description\": \"Configures dimensions and metric axes using semantic fields, preserving combo-only secondary axis constraints.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"axis-field-exists\",\n \"secondary-axis-combo-only\",\n \"cartesian-dimension-required\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[].axis\",\n \"chartDocument.orientation\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"data.resource.bind\",\n \"title\": \"Bind chart data resource\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"dataBinding\",\n \"target\": {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-source-and-field-catalog\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"sourceKind\"\n ],\n \"properties\": {\n \"sourceKind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"dimensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"role\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"metrics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-data-resource-bind\",\n \"handlerContract\": {\n \"reads\": [\n \"availableResources[]\",\n \"availableFields[]\",\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"writes\": [\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"identityKeys\": [\n \"availableResources[].path\",\n \"availableResources[].id\",\n \"availableFields[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"sourceKind\"\n ],\n \"properties\": {\n \"sourceKind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"dimensions\": {\n \"type\": \"array\"\n },\n \"metrics\": {\n \"type\": \"array\"\n }\n }\n },\n \"failureModes\": [\n \"resource-not-in-api-metadata\",\n \"field-not-in-schema\",\n \"stats-operation-not-supported\",\n \"remote-binding-incomplete\"\n ],\n \"description\": \"Binds a derived or praxis.stats source using the governed resource and field catalogs instead of free-form prompt examples.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"remote-resource-in-api-metadata\",\n \"bound-fields-exist\",\n \"stats-operation-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"affects-remote-binding\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"queryContext.set\",\n \"title\": \"Set chart query context\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"queryContext\",\n \"target\": {\n \"kind\": \"queryContext\",\n \"resolver\": \"praxis-chart-query-context\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"filters\": {\n \"type\": \"object\"\n },\n \"sort\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"limit\": {\n \"type\": \"number\"\n },\n \"page\": {\n \"type\": \"object\"\n },\n \"meta\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"queryContext\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"query-context-structured\",\n \"query-context-fields-exist\",\n \"query-context-safe-values\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"queryContext\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"crossFilter.configure\",\n \"title\": \"Configure chart cross-filter\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"crossFilter\",\n \"target\": {\n \"kind\": \"crossFilter\",\n \"resolver\": \"x-ui-chart-events-cross-filter\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-cross-filter-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.crossFilter\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.crossFilter\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"mapping-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures crossFilter as a structured event action that emits safe query-context filters to a governed target.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"cross-filter-output-structured\",\n \"event-target-governed\",\n \"event-mapping-fields-exist\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.crossFilter\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"drilldown.configure\",\n \"title\": \"Configure chart drilldown\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"drilldown\",\n \"target\": {\n \"kind\": \"drilldown\",\n \"resolver\": \"x-ui-chart-events-drill-down\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-drilldown-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.drillDown\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.drillDown\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"drilldown-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures drillDown through governed route/widget targets and structured field mappings.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"drilldown-target-governed\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.drillDown\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"selection.configure\",\n \"title\": \"Configure chart selection\",\n \"scope\": \"selection\",\n \"targetKind\": \"selection\",\n \"target\": {\n \"kind\": \"selection\",\n \"resolver\": \"x-ui-chart-events-selection-change\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-object\",\n \"path\": \"chartDocument.events.selectionChange\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"selection-output-structured\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.selectionChange\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"legend.configure\",\n \"title\": \"Configure chart legend\",\n \"scope\": \"skin\",\n \"targetKind\": \"legend\",\n \"target\": {\n \"kind\": \"legend\",\n \"resolver\": \"x-ui-chart-legend-feature\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument.legend\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"feature-toggle-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.legend\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"tooltip.configure\",\n \"title\": \"Configure chart tooltip\",\n \"scope\": \"skin\",\n \"targetKind\": \"tooltip\",\n \"target\": {\n \"kind\": \"tooltip\",\n \"resolver\": \"x-ui-chart-tooltip-feature\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument.tooltip\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"feature-toggle-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.tooltip\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n }\n ],\n \"validators\": [\n {\n \"validatorId\": \"chart-document-shape\",\n \"level\": \"error\",\n \"code\": \"CHART_DOCUMENT_SHAPE\",\n \"description\": \"Document must conform to PraxisXUiChartContract.\"\n },\n {\n \"validatorId\": \"chart-version-supported\",\n \"level\": \"error\",\n \"code\": \"CHART_VERSION_SUPPORTED\",\n \"description\": \"Only x-ui.chart version 0.1.0 is authorable.\"\n },\n {\n \"validatorId\": \"chart-type-supported\",\n \"level\": \"error\",\n \"code\": \"CHART_TYPE_SUPPORTED\",\n \"description\": \"Chart kind must be supported by @praxisui/charts.\"\n },\n {\n \"validatorId\": \"chart-type-series-axis-compatible\",\n \"level\": \"error\",\n \"code\": \"CHART_TYPE_SERIES_AXIS_COMPATIBLE\",\n \"description\": \"Chart kind, dimensions, metrics and axes must be compatible.\"\n },\n {\n \"validatorId\": \"pie-single-metric\",\n \"level\": \"error\",\n \"code\": \"PIE_SINGLE_METRIC\",\n \"description\": \"Pie and donut charts support a single metric.\"\n },\n {\n \"validatorId\": \"combo-minimum-series\",\n \"level\": \"error\",\n \"code\": \"COMBO_MINIMUM_SERIES\",\n \"description\": \"Combo charts require at least two metrics.\"\n },\n {\n \"validatorId\": \"series-field-exists\",\n \"level\": \"error\",\n \"code\": \"SERIES_FIELD_EXISTS\",\n \"description\": \"Series field must exist in availableFields or schema context.\"\n },\n {\n \"validatorId\": \"series-field-aggregable\",\n \"level\": \"error\",\n \"code\": \"SERIES_FIELD_AGGREGABLE\",\n \"description\": \"Metric fields must support the requested aggregation.\"\n },\n {\n \"validatorId\": \"series-id-unique\",\n \"level\": \"error\",\n \"code\": \"SERIES_ID_UNIQUE\",\n \"description\": \"Metric/series identity must be stable and unique by field.\"\n },\n {\n \"validatorId\": \"series-exists\",\n \"level\": \"error\",\n \"code\": \"SERIES_EXISTS\",\n \"description\": \"Series removal target must exist.\"\n },\n {\n \"validatorId\": \"destructive-series-removal-confirmed\",\n \"level\": \"error\",\n \"code\": \"DESTRUCTIVE_SERIES_REMOVAL_CONFIRMED\",\n \"description\": \"Removing a series requires explicit confirmation.\"\n },\n {\n \"validatorId\": \"chart-keeps-required-metric\",\n \"level\": \"error\",\n \"code\": \"CHART_KEEPS_REQUIRED_METRIC\",\n \"description\": \"A chart cannot be left without required metrics.\"\n },\n {\n \"validatorId\": \"axis-field-exists\",\n \"level\": \"error\",\n \"code\": \"AXIS_FIELD_EXISTS\",\n \"description\": \"Axis/dimension fields must exist in availableFields or schema context.\"\n },\n {\n \"validatorId\": \"secondary-axis-combo-only\",\n \"level\": \"error\",\n \"code\": \"SECONDARY_AXIS_COMBO_ONLY\",\n \"description\": \"Secondary axis is supported only for combo charts.\"\n },\n {\n \"validatorId\": \"cartesian-dimension-required\",\n \"level\": \"error\",\n \"code\": \"CARTESIAN_DIMENSION_REQUIRED\",\n \"description\": \"Cartesian charts require at least one dimension.\"\n },\n {\n \"validatorId\": \"remote-resource-in-api-metadata\",\n \"level\": \"error\",\n \"code\": \"REMOTE_RESOURCE_IN_API_METADATA\",\n \"description\": \"Remote praxis.stats resource must come from the governed API metadata/resource catalog.\"\n },\n {\n \"validatorId\": \"bound-fields-exist\",\n \"level\": \"error\",\n \"code\": \"BOUND_FIELDS_EXIST\",\n \"description\": \"Bound dimensions and metrics must exist in the schema/data context.\"\n },\n {\n \"validatorId\": \"stats-operation-supported\",\n \"level\": \"error\",\n \"code\": \"STATS_OPERATION_SUPPORTED\",\n \"description\": \"Remote datasource operation must be supported by the stats backend.\"\n },\n {\n \"validatorId\": \"query-context-structured\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_STRUCTURED\",\n \"description\": \"queryContext must use structured filters, sort, limit and page fields.\"\n },\n {\n \"validatorId\": \"query-context-fields-exist\",\n \"level\": \"warning\",\n \"code\": \"QUERY_CONTEXT_FIELDS_EXIST\",\n \"description\": \"queryContext filter fields should exist in the schema/data context.\"\n },\n {\n \"validatorId\": \"query-context-safe-values\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_SAFE_VALUES\",\n \"description\": \"queryContext values must be serializable safe data.\"\n },\n {\n \"validatorId\": \"cross-filter-output-structured\",\n \"level\": \"error\",\n \"code\": \"CROSS_FILTER_OUTPUT_STRUCTURED\",\n \"description\": \"Cross-filter output must be structured as query-context filters.\"\n },\n {\n \"validatorId\": \"event-target-governed\",\n \"level\": \"error\",\n \"code\": \"EVENT_TARGET_GOVERNED\",\n \"description\": \"Event targets must be selected from availableTargets or an approved host catalog.\"\n },\n {\n \"validatorId\": \"event-mapping-fields-exist\",\n \"level\": \"error\",\n \"code\": \"EVENT_MAPPING_FIELDS_EXIST\",\n \"description\": \"Event mapping source fields must exist in chart data context.\"\n },\n {\n \"validatorId\": \"event-action-supported\",\n \"level\": \"error\",\n \"code\": \"EVENT_ACTION_SUPPORTED\",\n \"description\": \"Event action must be one of the supported structured action kinds.\"\n },\n {\n \"validatorId\": \"drilldown-target-governed\",\n \"level\": \"error\",\n \"code\": \"DRILLDOWN_TARGET_GOVERNED\",\n \"description\": \"Drilldown target must be a governed route or widget target.\"\n },\n {\n \"validatorId\": \"selection-output-structured\",\n \"level\": \"error\",\n \"code\": \"SELECTION_OUTPUT_STRUCTURED\",\n \"description\": \"Selection output must resolve selected point filters deterministically.\"\n },\n {\n \"validatorId\": \"feature-toggle-valid\",\n \"level\": \"error\",\n \"code\": \"FEATURE_TOGGLE_VALID\",\n \"description\": \"Legend and tooltip feature values must be boolean or toggleable feature objects.\"\n },\n {\n \"validatorId\": \"editor-runtime-round-trip\",\n \"level\": \"error\",\n \"code\": \"EDITOR_RUNTIME_ROUND_TRIP\",\n \"description\": \"PraxisChartConfigEditor must save/reopen the same canonical document that runtime consumes.\"\n }\n ],\n \"roundTripRequirements\": [\n \"The canonical saved shape is PraxisXUiChartContract, not raw ECharts options.\",\n \"PraxisChartConfigEditor must preserve chart kind, source, dimensions, metrics, events, legend and tooltip across apply/save/reset/reopen.\",\n \"Remote bindings must be resolved from availableResources/API metadata and availableFields/schema context.\",\n \"Cross-filter, drilldown and selection authoring must persist structured event actions, not prompt examples or command strings.\"\n ],\n \"examples\": [\n {\n \"id\": \"set-bar-chart\",\n \"request\": \"Use a bar chart for employees by department.\",\n \"operationId\": \"chart.type.set\",\n \"params\": {\n \"kind\": \"bar\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"add-salary-series\",\n \"request\": \"Add salary as a summed metric.\",\n \"operationId\": \"series.add\",\n \"params\": {\n \"field\": \"salary\",\n \"aggregation\": \"sum\",\n \"label\": \"Salary\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"remove-old-series\",\n \"request\": \"Remove the old cost series.\",\n \"operationId\": \"series.remove\",\n \"target\": \"cost\",\n \"params\": {\n \"field\": \"cost\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-secondary-axis\",\n \"request\": \"Put margin on a secondary axis for the combo chart.\",\n \"operationId\": \"axis.configure\",\n \"params\": {\n \"metricField\": \"margin\",\n \"metricAxis\": \"secondary\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"bind-stats-resource\",\n \"request\": \"Bind this chart to payroll stats grouped by department.\",\n \"operationId\": \"data.resource.bind\",\n \"params\": {\n \"sourceKind\": \"praxis.stats\",\n \"resource\": \"/api/stats/payroll\",\n \"operation\": \"group-by\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"set-query-context\",\n \"request\": \"Limit the chart to active employees and sort by total descending.\",\n \"operationId\": \"queryContext.set\",\n \"params\": {\n \"filters\": {\n \"status\": \"ACTIVE\"\n },\n \"sort\": [\n \"total,desc\"\n ],\n \"limit\": 10\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-cross-filter\",\n \"request\": \"Use selected department to filter the employee table.\",\n \"operationId\": \"crossFilter.configure\",\n \"params\": {\n \"event\": \"crossFilter\",\n \"action\": \"filter-widget\",\n \"target\": \"employeesTable\",\n \"mapping\": {\n \"department\": \"department\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-drilldown\",\n \"request\": \"Open the department detail when a point is clicked.\",\n \"operationId\": \"drilldown.configure\",\n \"params\": {\n \"event\": \"drillDown\",\n \"action\": \"navigate\",\n \"target\": \"/departments/detail\",\n \"mapping\": {\n \"department\": \"departmentId\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-selection\",\n \"request\": \"Emit selected department as a structured selection event.\",\n \"operationId\": \"selection.configure\",\n \"params\": {\n \"event\": \"selectionChange\",\n \"action\": \"emit\",\n \"mapping\": {\n \"department\": \"department\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"toggle-legend\",\n \"request\": \"Show the legend.\",\n \"operationId\": \"legend.configure\",\n \"params\": {\n \"enabled\": true\n },\n \"isPositive\": true\n },\n {\n \"id\": \"toggle-tooltip\",\n \"request\": \"Disable tooltips.\",\n \"operationId\": \"tooltip.configure\",\n \"params\": {\n \"enabled\": false\n },\n \"isPositive\": true\n },\n {\n \"id\": \"round-trip-editor-runtime\",\n \"request\": \"Save this chart in the editor and reopen it without changing the runtime chart document.\",\n \"operationId\": \"chart.document.set\",\n \"params\": {\n \"version\": \"0.1.0\",\n \"kind\": \"bar\",\n \"source\": {\n \"kind\": \"derived\"\n },\n \"dimensions\": [\n {\n \"field\": \"department\"\n }\n ],\n \"metrics\": [\n {\n \"field\": \"total\",\n \"aggregation\": \"count\"\n }\n ]\n },\n \"isPositive\": true\n },\n {\n \"id\": \"reject-ambiguous-series-target\",\n \"request\": \"Remove total when more than one chart series resolves to total.\",\n \"operationId\": \"series.remove\",\n \"target\": \"total\",\n \"params\": {\n \"field\": \"total\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-prompt-routing\",\n \"request\": \"Use the prompt example text to decide which backend endpoint to call.\",\n \"operationId\": \"data.resource.bind\",\n \"params\": {\n \"sourceKind\": \"praxis.stats\",\n \"resource\": \"from prompt example\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-unsafe-target\",\n \"request\": \"Navigate to javascript:alert(1) on drilldown.\",\n \"operationId\": \"drilldown.configure\",\n \"params\": {\n \"event\": \"drillDown\",\n \"action\": \"navigate\",\n \"target\": \"javascript:alert(1)\"\n },\n \"isPositive\": false\n }\n ]\n}",
|
|
1756
|
+
"content": "{\n \"schemaVersion\": \"1.0.0\",\n \"componentId\": \"praxis-chart\",\n \"ownerPackage\": \"@praxisui/charts\",\n \"configSchemaId\": \"PraxisXUiChartContract\",\n \"manifestVersion\": \"1.0.0\",\n \"runtimeInputs\": [\n {\n \"name\": \"chartDocument\",\n \"type\": \"PraxisXUiChartContract | null\",\n \"description\": \"Canonical x-ui.chart document used as the authoring source of truth.\"\n },\n {\n \"name\": \"config\",\n \"type\": \"PraxisChartConfig\",\n \"description\": \"Runtime chart configuration mapped from or supplied beside the canonical chart document.\"\n },\n {\n \"name\": \"queryContext\",\n \"type\": \"PraxisChartQueryContext | null\",\n \"description\": \"Declarative query context merged into remote datasource requests.\"\n },\n {\n \"name\": \"remoteDataResolver\",\n \"type\": \"PraxisChartRemoteDataResolver | null\",\n \"description\": \"Host-governed remote row resolver for integrations outside the default praxis.stats client.\"\n },\n {\n \"name\": \"availableResources\",\n \"type\": \"ChartEditorResourceOption[]\",\n \"description\": \"Governed remote resource catalog exposed to the config editor.\"\n },\n {\n \"name\": \"availableFields\",\n \"type\": \"ChartEditorFieldOption[]\",\n \"description\": \"Governed semantic field catalog exposed to the config editor.\"\n },\n {\n \"name\": \"availableTargets\",\n \"type\": \"ChartEditorTargetOption[]\",\n \"description\": \"Governed widget or route targets exposed to chart event authoring.\"\n }\n ],\n \"editableTargets\": [\n {\n \"kind\": \"chartType\",\n \"resolver\": \"x-ui-chart-kind\",\n \"description\": \"Canonical `kind` field in PraxisXUiChartContract.\"\n },\n {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"description\": \"Metric-backed series definition in `metrics[]`, keyed by field.\"\n },\n {\n \"kind\": \"axis\",\n \"resolver\": \"x-ui-chart-dimension-or-metric-axis\",\n \"description\": \"Dimension role, metric axis and chart orientation semantics.\"\n },\n {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-source-and-field-catalog\",\n \"description\": \"Source, dimensions, metrics and resource/field bindings.\"\n },\n {\n \"kind\": \"queryContext\",\n \"resolver\": \"praxis-chart-query-context\",\n \"description\": \"Runtime queryContext contract for filters, sort, limit and page.\"\n },\n {\n \"kind\": \"crossFilter\",\n \"resolver\": \"x-ui-chart-events-cross-filter\",\n \"description\": \"Cross-filter event mapping emitted as structured query-context filters.\"\n },\n {\n \"kind\": \"drilldown\",\n \"resolver\": \"x-ui-chart-events-drill-down\",\n \"description\": \"Drilldown event mapping and governed target.\"\n },\n {\n \"kind\": \"selection\",\n \"resolver\": \"x-ui-chart-events-selection-change\",\n \"description\": \"Selection event enablement and mapping semantics.\"\n },\n {\n \"kind\": \"legend\",\n \"resolver\": \"x-ui-chart-legend-feature\",\n \"description\": \"Legend visibility through boolean or toggleable feature object.\"\n },\n {\n \"kind\": \"tooltip\",\n \"resolver\": \"x-ui-chart-tooltip-feature\",\n \"description\": \"Tooltip visibility through boolean or toggleable feature object.\"\n }\n ],\n \"operations\": [\n {\n \"operationId\": \"chart.document.set\",\n \"title\": \"Set chart document\",\n \"scope\": \"global\",\n \"targetKind\": \"dataBinding\",\n \"target\": {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-document-root\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"kind\",\n \"source\"\n ],\n \"properties\": {\n \"version\": {\n \"const\": \"0.1.0\"\n },\n \"kind\": {\n \"enum\": [\n \"bar\",\n \"combo\",\n \"horizontal-bar\",\n \"line\",\n \"pie\",\n \"donut\",\n \"area\",\n \"stacked-bar\",\n \"stacked-area\",\n \"scatter\"\n ]\n },\n \"chartId\": {\n \"type\": \"string\"\n },\n \"title\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"subtitle\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"source\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"options\": {\n \"type\": \"object\"\n }\n }\n },\n \"dimensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"metrics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"events\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"chart-document-shape\",\n \"chart-version-supported\",\n \"chart-type-series-axis-compatible\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"chart.type.set\",\n \"title\": \"Set chart type\",\n \"scope\": \"global\",\n \"targetKind\": \"chartType\",\n \"target\": {\n \"kind\": \"chartType\",\n \"resolver\": \"x-ui-chart-kind\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"kind\"\n ],\n \"properties\": {\n \"kind\": {\n \"enum\": [\n \"bar\",\n \"combo\",\n \"horizontal-bar\",\n \"line\",\n \"pie\",\n \"donut\",\n \"area\",\n \"stacked-bar\",\n \"stacked-area\",\n \"scatter\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-object\",\n \"path\": \"chartDocument\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"chart-type-supported\",\n \"chart-type-series-axis-compatible\",\n \"pie-single-metric\",\n \"combo-minimum-series\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.kind\",\n \"chartDocument.orientation\",\n \"chartDocument.metrics[]\",\n \"chartDocument.dimensions[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"series.add\",\n \"title\": \"Add chart series\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"series\",\n \"target\": {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-series-add\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.kind\",\n \"chartDocument.metrics[]\",\n \"availableFields[]\"\n ],\n \"writes\": [\n \"chartDocument.metrics[]\"\n ],\n \"identityKeys\": [\n \"chartDocument.metrics[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n },\n \"failureModes\": [\n \"field-not-in-catalog\",\n \"duplicate-series-field\",\n \"aggregation-not-supported\",\n \"chart-type-series-incompatible\"\n ],\n \"description\": \"Adds a metric-backed series by semantic field, validating it against availableFields and chart kind compatibility before patching metrics[].\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"series-field-exists\",\n \"series-field-aggregable\",\n \"series-id-unique\",\n \"chart-type-series-axis-compatible\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"series.remove\",\n \"title\": \"Remove chart series\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"series\",\n \"target\": {\n \"kind\": \"series\",\n \"resolver\": \"x-ui-chart-metric-by-field\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"replacementField\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"remove-by-key\",\n \"path\": \"chartDocument.metrics[]\",\n \"key\": \"field\"\n }\n ],\n \"destructive\": true,\n \"requiresConfirmation\": true,\n \"validators\": [\n \"series-exists\",\n \"destructive-series-removal-confirmed\",\n \"chart-keeps-required-metric\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-series-exists\",\n \"confirmation-collected\"\n ]\n },\n {\n \"operationId\": \"axis.configure\",\n \"title\": \"Configure chart axis\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"axis\",\n \"target\": {\n \"kind\": \"axis\",\n \"resolver\": \"x-ui-chart-dimension-or-metric-axis\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"dimensionField\": {\n \"type\": \"string\"\n },\n \"dimensionRole\": {\n \"enum\": [\n \"category\",\n \"series\",\n \"segment\",\n \"time\",\n \"value\"\n ]\n },\n \"metricField\": {\n \"type\": \"string\"\n },\n \"metricAxis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-axis-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.kind\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\",\n \"availableFields[]\"\n ],\n \"writes\": [\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\",\n \"chartDocument.orientation\"\n ],\n \"identityKeys\": [\n \"chartDocument.dimensions[].field\",\n \"chartDocument.metrics[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"dimensionField\": {\n \"type\": \"string\"\n },\n \"dimensionRole\": {\n \"enum\": [\n \"category\",\n \"series\",\n \"segment\",\n \"time\",\n \"value\"\n ]\n },\n \"metricField\": {\n \"type\": \"string\"\n },\n \"metricAxis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"orientation\": {\n \"enum\": [\n \"vertical\",\n \"horizontal\"\n ]\n }\n }\n },\n \"failureModes\": [\n \"field-not-in-catalog\",\n \"secondary-axis-non-combo\",\n \"missing-required-dimension\",\n \"axis-role-incompatible\"\n ],\n \"description\": \"Configures dimensions and metric axes using semantic fields, preserving combo-only secondary axis constraints.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"axis-field-exists\",\n \"secondary-axis-combo-only\",\n \"cartesian-dimension-required\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[].axis\",\n \"chartDocument.orientation\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"data.resource.bind\",\n \"title\": \"Bind chart data resource\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"dataBinding\",\n \"target\": {\n \"kind\": \"dataBinding\",\n \"resolver\": \"x-ui-chart-source-and-field-catalog\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"sourceKind\"\n ],\n \"properties\": {\n \"sourceKind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"dimensions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"role\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"metrics\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"field\"\n ],\n \"properties\": {\n \"field\": {\n \"type\": \"string\"\n },\n \"label\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"object\"\n }\n ]\n },\n \"aggregation\": {\n \"enum\": [\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n \"count\",\n \"distinct-count\"\n ]\n },\n \"seriesKind\": {\n \"enum\": [\n \"bar\",\n \"line\",\n \"area\"\n ]\n },\n \"axis\": {\n \"enum\": [\n \"primary\",\n \"secondary\"\n ]\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"format\": {\n \"type\": \"string\"\n },\n \"afterField\": {\n \"type\": \"string\"\n }\n }\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-data-resource-bind\",\n \"handlerContract\": {\n \"reads\": [\n \"availableResources[]\",\n \"availableFields[]\",\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"writes\": [\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"identityKeys\": [\n \"availableResources[].path\",\n \"availableResources[].id\",\n \"availableFields[].field\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"sourceKind\"\n ],\n \"properties\": {\n \"sourceKind\": {\n \"enum\": [\n \"praxis.stats\",\n \"derived\"\n ]\n },\n \"resource\": {\n \"type\": \"string\"\n },\n \"operation\": {\n \"enum\": [\n \"group-by\",\n \"timeseries\",\n \"distribution\"\n ]\n },\n \"dimensions\": {\n \"type\": \"array\"\n },\n \"metrics\": {\n \"type\": \"array\"\n }\n }\n },\n \"failureModes\": [\n \"resource-not-in-api-metadata\",\n \"field-not-in-schema\",\n \"stats-operation-not-supported\",\n \"remote-binding-incomplete\"\n ],\n \"description\": \"Binds a derived or praxis.stats source using the governed resource and field catalogs instead of free-form prompt examples.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"remote-resource-in-api-metadata\",\n \"bound-fields-exist\",\n \"stats-operation-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.source\",\n \"chartDocument.dimensions[]\",\n \"chartDocument.metrics[]\"\n ],\n \"submissionImpact\": \"affects-remote-binding\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"queryContext.set\",\n \"title\": \"Set chart query context\",\n \"scope\": \"dataBinding\",\n \"targetKind\": \"queryContext\",\n \"target\": {\n \"kind\": \"queryContext\",\n \"resolver\": \"praxis-chart-query-context\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"filters\": {\n \"type\": \"object\"\n },\n \"sort\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"limit\": {\n \"type\": \"number\"\n },\n \"page\": {\n \"type\": \"object\"\n },\n \"meta\": {\n \"type\": \"object\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"queryContext\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"query-context-structured\",\n \"query-context-fields-exist\",\n \"query-context-safe-values\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"queryContext\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"crossFilter.configure\",\n \"title\": \"Configure chart cross-filter\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"crossFilter\",\n \"target\": {\n \"kind\": \"crossFilter\",\n \"resolver\": \"x-ui-chart-events-cross-filter\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-cross-filter-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.crossFilter\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.crossFilter\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"mapping-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures crossFilter as a structured event action that emits safe query-context filters to a governed target.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"cross-filter-output-structured\",\n \"event-target-governed\",\n \"event-mapping-fields-exist\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.crossFilter\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"drilldown.configure\",\n \"title\": \"Configure chart drilldown\",\n \"scope\": \"eventMapping\",\n \"targetKind\": \"drilldown\",\n \"target\": {\n \"kind\": \"drilldown\",\n \"resolver\": \"x-ui-chart-events-drill-down\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"chart-event-drilldown-configure\",\n \"handlerContract\": {\n \"reads\": [\n \"chartDocument.events.drillDown\",\n \"chartDocument.dimensions[]\",\n \"availableTargets[]\"\n ],\n \"writes\": [\n \"chartDocument.events.drillDown\"\n ],\n \"identityKeys\": [\n \"availableTargets[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"failureModes\": [\n \"target-not-in-catalog\",\n \"mapping-source-field-missing\",\n \"drilldown-target-invalid\",\n \"unsafe-event-action\"\n ],\n \"description\": \"Configures drillDown through governed route/widget targets and structured field mappings.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"drilldown-target-governed\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.drillDown\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"selection.configure\",\n \"title\": \"Configure chart selection\",\n \"scope\": \"selection\",\n \"targetKind\": \"selection\",\n \"target\": {\n \"kind\": \"selection\",\n \"resolver\": \"x-ui-chart-events-selection-change\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"event\",\n \"action\"\n ],\n \"properties\": {\n \"event\": {\n \"enum\": [\n \"pointClick\",\n \"selectionChange\",\n \"drillDown\",\n \"crossFilter\"\n ]\n },\n \"action\": {\n \"enum\": [\n \"filter-widget\",\n \"open-detail\",\n \"navigate\",\n \"update-context\",\n \"emit\"\n ]\n },\n \"target\": {\n \"type\": \"string\"\n },\n \"mapping\": {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-object\",\n \"path\": \"chartDocument.events.selectionChange\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"selection-output-structured\",\n \"event-mapping-fields-exist\",\n \"event-action-supported\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.events.selectionChange\"\n ],\n \"submissionImpact\": \"affects-schema-backed-data\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"legend.configure\",\n \"title\": \"Configure chart legend\",\n \"scope\": \"skin\",\n \"targetKind\": \"legend\",\n \"target\": {\n \"kind\": \"legend\",\n \"resolver\": \"x-ui-chart-legend-feature\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument.legend\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"feature-toggle-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.legend\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"tooltip.configure\",\n \"title\": \"Configure chart tooltip\",\n \"scope\": \"skin\",\n \"targetKind\": \"tooltip\",\n \"target\": {\n \"kind\": \"tooltip\",\n \"resolver\": \"x-ui-chart-tooltip-feature\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"set-value\",\n \"path\": \"chartDocument.tooltip\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"feature-toggle-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"chartDocument.tooltip\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n }\n ],\n \"validators\": [\n {\n \"validatorId\": \"chart-document-shape\",\n \"level\": \"error\",\n \"code\": \"CHART_DOCUMENT_SHAPE\",\n \"description\": \"Document must conform to PraxisXUiChartContract.\"\n },\n {\n \"validatorId\": \"chart-version-supported\",\n \"level\": \"error\",\n \"code\": \"CHART_VERSION_SUPPORTED\",\n \"description\": \"Only x-ui.chart version 0.1.0 is authorable.\"\n },\n {\n \"validatorId\": \"chart-type-supported\",\n \"level\": \"error\",\n \"code\": \"CHART_TYPE_SUPPORTED\",\n \"description\": \"Chart kind must be supported by @praxisui/charts.\"\n },\n {\n \"validatorId\": \"chart-type-series-axis-compatible\",\n \"level\": \"error\",\n \"code\": \"CHART_TYPE_SERIES_AXIS_COMPATIBLE\",\n \"description\": \"Chart kind, dimensions, metrics and axes must be compatible.\"\n },\n {\n \"validatorId\": \"pie-single-metric\",\n \"level\": \"error\",\n \"code\": \"PIE_SINGLE_METRIC\",\n \"description\": \"Pie and donut charts support a single metric.\"\n },\n {\n \"validatorId\": \"combo-minimum-series\",\n \"level\": \"error\",\n \"code\": \"COMBO_MINIMUM_SERIES\",\n \"description\": \"Combo charts require at least two metrics.\"\n },\n {\n \"validatorId\": \"series-field-exists\",\n \"level\": \"error\",\n \"code\": \"SERIES_FIELD_EXISTS\",\n \"description\": \"Series field must exist in availableFields or schema context.\"\n },\n {\n \"validatorId\": \"series-field-aggregable\",\n \"level\": \"error\",\n \"code\": \"SERIES_FIELD_AGGREGABLE\",\n \"description\": \"Metric fields must support the requested aggregation.\"\n },\n {\n \"validatorId\": \"series-id-unique\",\n \"level\": \"error\",\n \"code\": \"SERIES_ID_UNIQUE\",\n \"description\": \"Metric/series identity must be stable and unique by field.\"\n },\n {\n \"validatorId\": \"series-exists\",\n \"level\": \"error\",\n \"code\": \"SERIES_EXISTS\",\n \"description\": \"Series removal target must exist.\"\n },\n {\n \"validatorId\": \"destructive-series-removal-confirmed\",\n \"level\": \"error\",\n \"code\": \"DESTRUCTIVE_SERIES_REMOVAL_CONFIRMED\",\n \"description\": \"Removing a series requires explicit confirmation.\"\n },\n {\n \"validatorId\": \"chart-keeps-required-metric\",\n \"level\": \"error\",\n \"code\": \"CHART_KEEPS_REQUIRED_METRIC\",\n \"description\": \"A chart cannot be left without required metrics.\"\n },\n {\n \"validatorId\": \"axis-field-exists\",\n \"level\": \"error\",\n \"code\": \"AXIS_FIELD_EXISTS\",\n \"description\": \"Axis/dimension fields must exist in availableFields or schema context.\"\n },\n {\n \"validatorId\": \"secondary-axis-combo-only\",\n \"level\": \"error\",\n \"code\": \"SECONDARY_AXIS_COMBO_ONLY\",\n \"description\": \"Secondary axis is supported only for combo charts.\"\n },\n {\n \"validatorId\": \"cartesian-dimension-required\",\n \"level\": \"error\",\n \"code\": \"CARTESIAN_DIMENSION_REQUIRED\",\n \"description\": \"Cartesian charts require at least one dimension.\"\n },\n {\n \"validatorId\": \"remote-resource-in-api-metadata\",\n \"level\": \"error\",\n \"code\": \"REMOTE_RESOURCE_IN_API_METADATA\",\n \"description\": \"Remote praxis.stats resource must come from the governed API metadata/resource catalog.\"\n },\n {\n \"validatorId\": \"bound-fields-exist\",\n \"level\": \"error\",\n \"code\": \"BOUND_FIELDS_EXIST\",\n \"description\": \"Bound dimensions and metrics must exist in the schema/data context.\"\n },\n {\n \"validatorId\": \"stats-operation-supported\",\n \"level\": \"error\",\n \"code\": \"STATS_OPERATION_SUPPORTED\",\n \"description\": \"Remote datasource operation must be supported by the stats backend.\"\n },\n {\n \"validatorId\": \"query-context-structured\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_STRUCTURED\",\n \"description\": \"queryContext must use structured filters, sort, limit and page fields.\"\n },\n {\n \"validatorId\": \"query-context-fields-exist\",\n \"level\": \"warning\",\n \"code\": \"QUERY_CONTEXT_FIELDS_EXIST\",\n \"description\": \"queryContext filter fields should exist in the schema/data context.\"\n },\n {\n \"validatorId\": \"query-context-safe-values\",\n \"level\": \"error\",\n \"code\": \"QUERY_CONTEXT_SAFE_VALUES\",\n \"description\": \"queryContext values must be serializable safe data.\"\n },\n {\n \"validatorId\": \"cross-filter-output-structured\",\n \"level\": \"error\",\n \"code\": \"CROSS_FILTER_OUTPUT_STRUCTURED\",\n \"description\": \"Cross-filter output must be structured as query-context filters.\"\n },\n {\n \"validatorId\": \"event-target-governed\",\n \"level\": \"error\",\n \"code\": \"EVENT_TARGET_GOVERNED\",\n \"description\": \"Event targets must be selected from availableTargets or an approved host catalog.\"\n },\n {\n \"validatorId\": \"event-mapping-fields-exist\",\n \"level\": \"error\",\n \"code\": \"EVENT_MAPPING_FIELDS_EXIST\",\n \"description\": \"Event mapping source fields must exist in chart data context.\"\n },\n {\n \"validatorId\": \"event-action-supported\",\n \"level\": \"error\",\n \"code\": \"EVENT_ACTION_SUPPORTED\",\n \"description\": \"Event action must be one of the supported structured action kinds.\"\n },\n {\n \"validatorId\": \"drilldown-target-governed\",\n \"level\": \"error\",\n \"code\": \"DRILLDOWN_TARGET_GOVERNED\",\n \"description\": \"Drilldown target must be a governed route or widget target.\"\n },\n {\n \"validatorId\": \"selection-output-structured\",\n \"level\": \"error\",\n \"code\": \"SELECTION_OUTPUT_STRUCTURED\",\n \"description\": \"Selection output must resolve selected point filters deterministically.\"\n },\n {\n \"validatorId\": \"feature-toggle-valid\",\n \"level\": \"error\",\n \"code\": \"FEATURE_TOGGLE_VALID\",\n \"description\": \"Legend and tooltip feature values must be boolean or toggleable feature objects.\"\n },\n {\n \"validatorId\": \"editor-runtime-round-trip\",\n \"level\": \"error\",\n \"code\": \"EDITOR_RUNTIME_ROUND_TRIP\",\n \"description\": \"PraxisChartConfigEditor must save/reopen the same canonical document that runtime consumes.\"\n }\n ],\n \"roundTripRequirements\": [\n \"The canonical saved shape is PraxisXUiChartContract, not raw ECharts options.\",\n \"PraxisChartConfigEditor must preserve chart kind, source, dimensions, metrics, events, legend and tooltip across apply/save/reset/reopen.\",\n \"Remote bindings must be resolved from availableResources/API metadata and availableFields/schema context.\",\n \"Cross-filter, drilldown and selection authoring must persist structured event actions, not prompt examples or command strings.\"\n ],\n \"examples\": [\n {\n \"id\": \"set-bar-chart\",\n \"request\": \"Use a bar chart for employees by department.\",\n \"operationId\": \"chart.type.set\",\n \"params\": {\n \"kind\": \"bar\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"add-salary-series\",\n \"request\": \"Add salary as a summed metric.\",\n \"operationId\": \"series.add\",\n \"params\": {\n \"field\": \"salary\",\n \"aggregation\": \"sum\",\n \"label\": \"Salary\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"remove-old-series\",\n \"request\": \"Remove the old cost series.\",\n \"operationId\": \"series.remove\",\n \"target\": \"cost\",\n \"params\": {\n \"field\": \"cost\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-secondary-axis\",\n \"request\": \"Put margin on a secondary axis for the combo chart.\",\n \"operationId\": \"axis.configure\",\n \"params\": {\n \"metricField\": \"margin\",\n \"metricAxis\": \"secondary\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"bind-stats-resource\",\n \"request\": \"Bind this chart to payroll stats grouped by department.\",\n \"operationId\": \"data.resource.bind\",\n \"params\": {\n \"sourceKind\": \"praxis.stats\",\n \"resource\": \"/api/stats/payroll\",\n \"operation\": \"group-by\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"set-query-context\",\n \"request\": \"Limit the chart to active employees and sort by total descending.\",\n \"operationId\": \"queryContext.set\",\n \"params\": {\n \"filters\": {\n \"status\": \"ACTIVE\"\n },\n \"sort\": [\n \"total,desc\"\n ],\n \"limit\": 10\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-cross-filter\",\n \"request\": \"Use selected department to filter the employee table.\",\n \"operationId\": \"crossFilter.configure\",\n \"params\": {\n \"event\": \"crossFilter\",\n \"action\": \"filter-widget\",\n \"target\": \"employeesTable\",\n \"mapping\": {\n \"department\": \"department\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-drilldown\",\n \"request\": \"Open the department detail when a point is clicked.\",\n \"operationId\": \"drilldown.configure\",\n \"params\": {\n \"event\": \"drillDown\",\n \"action\": \"navigate\",\n \"target\": \"/departments/detail\",\n \"mapping\": {\n \"department\": \"departmentId\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"configure-selection\",\n \"request\": \"Emit selected department as a structured selection event.\",\n \"operationId\": \"selection.configure\",\n \"params\": {\n \"event\": \"selectionChange\",\n \"action\": \"emit\",\n \"mapping\": {\n \"department\": \"department\"\n }\n },\n \"isPositive\": true\n },\n {\n \"id\": \"toggle-legend\",\n \"request\": \"Show the legend.\",\n \"operationId\": \"legend.configure\",\n \"params\": {\n \"enabled\": true\n },\n \"isPositive\": true\n },\n {\n \"id\": \"toggle-tooltip\",\n \"request\": \"Disable tooltips.\",\n \"operationId\": \"tooltip.configure\",\n \"params\": {\n \"enabled\": false\n },\n \"isPositive\": true\n },\n {\n \"id\": \"round-trip-editor-runtime\",\n \"request\": \"Save this chart in the editor and reopen it without changing the runtime chart document.\",\n \"operationId\": \"chart.document.set\",\n \"params\": {\n \"version\": \"0.1.0\",\n \"kind\": \"bar\",\n \"source\": {\n \"kind\": \"derived\"\n },\n \"dimensions\": [\n {\n \"field\": \"department\"\n }\n ],\n \"metrics\": [\n {\n \"field\": \"total\",\n \"aggregation\": \"count\"\n }\n ]\n },\n \"isPositive\": true\n },\n {\n \"id\": \"reject-ambiguous-series-target\",\n \"request\": \"Remove total when more than one chart series resolves to total.\",\n \"operationId\": \"series.remove\",\n \"target\": \"total\",\n \"params\": {\n \"field\": \"total\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-prompt-routing\",\n \"request\": \"Use the prompt example text to decide which backend endpoint to call.\",\n \"operationId\": \"data.resource.bind\",\n \"params\": {\n \"sourceKind\": \"praxis.stats\",\n \"resource\": \"from prompt example\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-unsafe-target\",\n \"request\": \"Navigate to javascript:alert(1) on drilldown.\",\n \"operationId\": \"drilldown.configure\",\n \"params\": {\n \"event\": \"drillDown\",\n \"action\": \"navigate\",\n \"target\": \"javascript:alert(1)\"\n },\n \"isPositive\": false\n }\n ]\n}",
|
|
1757
1757
|
"sourcePointer": "praxis-ui-angular/projects/praxis-charts/src/lib/ai/praxis-charts-authoring-manifest.ts",
|
|
1758
|
-
"contentHash": "
|
|
1758
|
+
"contentHash": "ac5ab33ce5501ff1fb3f9de4b45f09b72e6ede7b1ea74050d36bfef0a8380d9c",
|
|
1759
1759
|
"sourceKind": "component_definition",
|
|
1760
1760
|
"sourceId": "praxis-chart",
|
|
1761
1761
|
"corpusVersion": "1.0.0"
|
|
@@ -2940,6 +2940,12 @@ const SUPPORTED_KINDS = new Set([
|
|
|
2940
2940
|
'stackedBar',
|
|
2941
2941
|
'bullet',
|
|
2942
2942
|
'delta',
|
|
2943
|
+
'radial',
|
|
2944
|
+
'harveyBall',
|
|
2945
|
+
'line',
|
|
2946
|
+
'area',
|
|
2947
|
+
'column',
|
|
2948
|
+
'processFlow',
|
|
2943
2949
|
]);
|
|
2944
2950
|
class PraxisMicroVisualizationComponent {
|
|
2945
2951
|
visualizationInput = input(null, { ...(ngDevMode ? { debugName: "visualizationInput" } : /* istanbul ignore next */ {}), alias: 'visualization' });
|
|
@@ -3025,10 +3031,180 @@ class PraxisMicroVisualizationComponent {
|
|
|
3025
3031
|
return typeof value === 'number' && max > 0 ? clampPercent((Math.max(value, 0) / max) * 100) : 0;
|
|
3026
3032
|
}
|
|
3027
3033
|
formatNumber(value) {
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3034
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
3035
|
+
return '';
|
|
3036
|
+
}
|
|
3037
|
+
return new Intl.NumberFormat(undefined, {
|
|
3038
|
+
maximumFractionDigits: Math.abs(value) < 10 ? 2 : 0,
|
|
3039
|
+
}).format(value);
|
|
3031
3040
|
}
|
|
3041
|
+
radialPercent = computed(() => {
|
|
3042
|
+
const config = this.visualization();
|
|
3043
|
+
if (!config)
|
|
3044
|
+
return 0;
|
|
3045
|
+
const val = typeof config.value === 'number' ? config.value : 0;
|
|
3046
|
+
const total = config.total && config.total > 0 ? config.total : 100;
|
|
3047
|
+
return clampPercent((val / total) * 100);
|
|
3048
|
+
}, ...(ngDevMode ? [{ debugName: "radialPercent" }] : /* istanbul ignore next */ []));
|
|
3049
|
+
radialDashArray = computed(() => {
|
|
3050
|
+
return `${this.radialPercent().toFixed(1)}, 100`;
|
|
3051
|
+
}, ...(ngDevMode ? [{ debugName: "radialDashArray" }] : /* istanbul ignore next */ []));
|
|
3052
|
+
radialText = computed(() => `${Math.round(this.radialPercent())}%`, ...(ngDevMode ? [{ debugName: "radialText" }] : /* istanbul ignore next */ []));
|
|
3053
|
+
harveyPercent = computed(() => {
|
|
3054
|
+
const config = this.visualization();
|
|
3055
|
+
if (!config)
|
|
3056
|
+
return 0;
|
|
3057
|
+
const val = typeof config.value === 'number' ? config.value : 0;
|
|
3058
|
+
const total = config.total && config.total > 0 ? config.total : 100;
|
|
3059
|
+
return clampPercent((val / total) * 100);
|
|
3060
|
+
}, ...(ngDevMode ? [{ debugName: "harveyPercent" }] : /* istanbul ignore next */ []));
|
|
3061
|
+
harveyDashArray = computed(() => {
|
|
3062
|
+
const len = this.harveyPercent() * 0.50265;
|
|
3063
|
+
return `${len.toFixed(3)} 50.265`;
|
|
3064
|
+
}, ...(ngDevMode ? [{ debugName: "harveyDashArray" }] : /* istanbul ignore next */ []));
|
|
3065
|
+
harveyText = computed(() => `${Math.round(this.harveyPercent())}%`, ...(ngDevMode ? [{ debugName: "harveyText" }] : /* istanbul ignore next */ []));
|
|
3066
|
+
firstPoint = computed(() => {
|
|
3067
|
+
const points = this.visualization()?.points ?? [];
|
|
3068
|
+
return points.length > 0 ? points[0] : null;
|
|
3069
|
+
}, ...(ngDevMode ? [{ debugName: "firstPoint" }] : /* istanbul ignore next */ []));
|
|
3070
|
+
lastPoint = computed(() => {
|
|
3071
|
+
const points = this.visualization()?.points ?? [];
|
|
3072
|
+
return points.length > 0 ? points[points.length - 1] : null;
|
|
3073
|
+
}, ...(ngDevMode ? [{ debugName: "lastPoint" }] : /* istanbul ignore next */ []));
|
|
3074
|
+
minPointIndex = computed(() => {
|
|
3075
|
+
const points = this.visualization()?.points ?? [];
|
|
3076
|
+
if (points.length === 0)
|
|
3077
|
+
return -1;
|
|
3078
|
+
let minIdx = 0;
|
|
3079
|
+
for (let i = 1; i < points.length; i++) {
|
|
3080
|
+
if (points[i].value < points[minIdx].value) {
|
|
3081
|
+
minIdx = i;
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
return minIdx;
|
|
3085
|
+
}, ...(ngDevMode ? [{ debugName: "minPointIndex" }] : /* istanbul ignore next */ []));
|
|
3086
|
+
maxPointIndex = computed(() => {
|
|
3087
|
+
const points = this.visualization()?.points ?? [];
|
|
3088
|
+
if (points.length === 0)
|
|
3089
|
+
return -1;
|
|
3090
|
+
let maxIdx = 0;
|
|
3091
|
+
for (let i = 1; i < points.length; i++) {
|
|
3092
|
+
if (points[i].value > points[maxIdx].value) {
|
|
3093
|
+
maxIdx = i;
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
return maxIdx;
|
|
3097
|
+
}, ...(ngDevMode ? [{ debugName: "maxPointIndex" }] : /* istanbul ignore next */ []));
|
|
3098
|
+
trendMarkers = computed(() => {
|
|
3099
|
+
const coords = this.trendCoords();
|
|
3100
|
+
const points = this.visualization()?.points ?? [];
|
|
3101
|
+
if (coords.length === 0)
|
|
3102
|
+
return [];
|
|
3103
|
+
const markers = [];
|
|
3104
|
+
const minIdx = this.minPointIndex();
|
|
3105
|
+
const maxIdx = this.maxPointIndex();
|
|
3106
|
+
const tone = this.visualization()?.tone ?? 'info';
|
|
3107
|
+
// Add first point
|
|
3108
|
+
markers.push({
|
|
3109
|
+
x: coords[0].x,
|
|
3110
|
+
y: coords[0].y,
|
|
3111
|
+
tone: points[0].tone ?? tone,
|
|
3112
|
+
label: `First: ${points[0].value}`,
|
|
3113
|
+
});
|
|
3114
|
+
// Add last point
|
|
3115
|
+
if (coords.length > 1) {
|
|
3116
|
+
markers.push({
|
|
3117
|
+
x: coords[coords.length - 1].x,
|
|
3118
|
+
y: coords[coords.length - 1].y,
|
|
3119
|
+
tone: points[points.length - 1].tone ?? tone,
|
|
3120
|
+
label: `Last: ${points[points.length - 1].value}`,
|
|
3121
|
+
});
|
|
3122
|
+
}
|
|
3123
|
+
// Add min point (if not first/last)
|
|
3124
|
+
if (minIdx !== 0 && minIdx !== coords.length - 1 && minIdx !== -1) {
|
|
3125
|
+
markers.push({
|
|
3126
|
+
x: coords[minIdx].x,
|
|
3127
|
+
y: coords[minIdx].y,
|
|
3128
|
+
tone: points[minIdx].tone ?? 'danger',
|
|
3129
|
+
label: `Min: ${points[minIdx].value}`,
|
|
3130
|
+
});
|
|
3131
|
+
}
|
|
3132
|
+
// Add max point (if not first/last)
|
|
3133
|
+
if (maxIdx !== 0 && maxIdx !== coords.length - 1 && maxIdx !== -1) {
|
|
3134
|
+
markers.push({
|
|
3135
|
+
x: coords[maxIdx].x,
|
|
3136
|
+
y: coords[maxIdx].y,
|
|
3137
|
+
tone: points[maxIdx].tone ?? 'success',
|
|
3138
|
+
label: `Max: ${points[maxIdx].value}`,
|
|
3139
|
+
});
|
|
3140
|
+
}
|
|
3141
|
+
return markers;
|
|
3142
|
+
}, ...(ngDevMode ? [{ debugName: "trendMarkers" }] : /* istanbul ignore next */ []));
|
|
3143
|
+
trendCoords = computed(() => {
|
|
3144
|
+
const config = this.visualization();
|
|
3145
|
+
const points = config?.points ?? [];
|
|
3146
|
+
if (points.length < 2)
|
|
3147
|
+
return [];
|
|
3148
|
+
const width = 100;
|
|
3149
|
+
const height = 30;
|
|
3150
|
+
const padding = 4;
|
|
3151
|
+
const values = points.map(p => p.value);
|
|
3152
|
+
const minVal = Math.min(...values);
|
|
3153
|
+
const maxVal = Math.max(...values);
|
|
3154
|
+
const valRange = maxVal - minVal === 0 ? 1 : maxVal - minVal;
|
|
3155
|
+
return points.map((p, index) => {
|
|
3156
|
+
const x = padding + (index / (points.length - 1)) * (width - 2 * padding);
|
|
3157
|
+
const y = height - padding - ((p.value - minVal) / valRange) * (height - 2 * padding);
|
|
3158
|
+
return { x, y };
|
|
3159
|
+
});
|
|
3160
|
+
}, ...(ngDevMode ? [{ debugName: "trendCoords" }] : /* istanbul ignore next */ []));
|
|
3161
|
+
trendPathD = computed(() => {
|
|
3162
|
+
const coords = this.trendCoords();
|
|
3163
|
+
if (coords.length < 2)
|
|
3164
|
+
return '';
|
|
3165
|
+
return coords.map((c, i) => `${i === 0 ? 'M' : 'L'} ${c.x.toFixed(1)} ${c.y.toFixed(1)}`).join(' ');
|
|
3166
|
+
}, ...(ngDevMode ? [{ debugName: "trendPathD" }] : /* istanbul ignore next */ []));
|
|
3167
|
+
trendAreaD = computed(() => {
|
|
3168
|
+
const pathD = this.trendPathD();
|
|
3169
|
+
const coords = this.trendCoords();
|
|
3170
|
+
if (!pathD || coords.length < 2)
|
|
3171
|
+
return '';
|
|
3172
|
+
const height = 30;
|
|
3173
|
+
const firstX = coords[0].x.toFixed(1);
|
|
3174
|
+
const lastX = coords[coords.length - 1].x.toFixed(1);
|
|
3175
|
+
return `${pathD} L ${lastX} ${height} L ${firstX} ${height} Z`;
|
|
3176
|
+
}, ...(ngDevMode ? [{ debugName: "trendAreaD" }] : /* istanbul ignore next */ []));
|
|
3177
|
+
trendColumns = computed(() => {
|
|
3178
|
+
const config = this.visualization();
|
|
3179
|
+
const points = config?.points ?? [];
|
|
3180
|
+
if (points.length === 0)
|
|
3181
|
+
return [];
|
|
3182
|
+
const width = 100;
|
|
3183
|
+
const height = 30;
|
|
3184
|
+
const padding = 4;
|
|
3185
|
+
const values = points.map(p => p.value);
|
|
3186
|
+
const maxVal = Math.max(...values, 0);
|
|
3187
|
+
const minVal = Math.min(...values, 0);
|
|
3188
|
+
const valRange = maxVal - minVal === 0 ? 1 : maxVal - minVal;
|
|
3189
|
+
const colWidth = Math.max(2, (width - 2 * padding) / points.length - 2);
|
|
3190
|
+
const tone = config?.tone ?? 'info';
|
|
3191
|
+
return points.map((p, i) => {
|
|
3192
|
+
const x = padding + i * ((width - 2 * padding) / points.length) + 1;
|
|
3193
|
+
const rectHeight = Math.max(2, ((p.value - minVal) / valRange) * (height - 2 * padding));
|
|
3194
|
+
const rectY = height - padding - rectHeight;
|
|
3195
|
+
return {
|
|
3196
|
+
x: x.toFixed(1),
|
|
3197
|
+
y: rectY.toFixed(1),
|
|
3198
|
+
width: colWidth.toFixed(1),
|
|
3199
|
+
height: rectHeight.toFixed(1),
|
|
3200
|
+
tone: p.tone ?? tone,
|
|
3201
|
+
};
|
|
3202
|
+
});
|
|
3203
|
+
}, ...(ngDevMode ? [{ debugName: "trendColumns" }] : /* istanbul ignore next */ []));
|
|
3204
|
+
processSteps = computed(() => {
|
|
3205
|
+
const config = this.visualization();
|
|
3206
|
+
return config?.items ?? [];
|
|
3207
|
+
}, ...(ngDevMode ? [{ debugName: "processSteps" }] : /* istanbul ignore next */ []));
|
|
3032
3208
|
resolveBulletMax() {
|
|
3033
3209
|
const config = this.visualization();
|
|
3034
3210
|
const values = [
|
|
@@ -3050,7 +3226,7 @@ class PraxisMicroVisualizationComponent {
|
|
|
3050
3226
|
@switch (config.kind) {
|
|
3051
3227
|
@case ('comparison') {
|
|
3052
3228
|
<div class="prx-micro-comparison">
|
|
3053
|
-
|
|
3229
|
+
@for (item of comparisonItems(); track item.label ?? $index) {
|
|
3054
3230
|
<div class="prx-micro-comparison__row">
|
|
3055
3231
|
@if (item.label) {
|
|
3056
3232
|
<span class="prx-micro-comparison__label">{{ item.label }}</span>
|
|
@@ -3088,7 +3264,19 @@ class PraxisMicroVisualizationComponent {
|
|
|
3088
3264
|
}
|
|
3089
3265
|
|
|
3090
3266
|
@case ('bullet') {
|
|
3091
|
-
<div class="prx-micro-bullet">
|
|
3267
|
+
<div class="prx-micro-bullet-container">
|
|
3268
|
+
@if (!isTableCell()) {
|
|
3269
|
+
<div class="prx-micro-bullet__top">
|
|
3270
|
+
<span class="prx-micro-bullet__label">{{ config.fallbackText }}</span>
|
|
3271
|
+
<span class="prx-micro-bullet__value" [attr.data-tone]="config.tone || null">
|
|
3272
|
+
{{ formatNumber(config.value) }}
|
|
3273
|
+
@if (config.target !== undefined) {
|
|
3274
|
+
<span class="prx-micro-bullet__target-val">/ Target: {{ formatNumber(config.target) }}</span>
|
|
3275
|
+
}
|
|
3276
|
+
</span>
|
|
3277
|
+
</div>
|
|
3278
|
+
}
|
|
3279
|
+
|
|
3092
3280
|
<div class="prx-micro-bullet__track" aria-hidden="true">
|
|
3093
3281
|
@for (band of bulletBands(); track band.label ?? $index) {
|
|
3094
3282
|
<span
|
|
@@ -3110,8 +3298,12 @@ class PraxisMicroVisualizationComponent {
|
|
|
3110
3298
|
></span>
|
|
3111
3299
|
}
|
|
3112
3300
|
</div>
|
|
3301
|
+
|
|
3113
3302
|
@if (!isTableCell()) {
|
|
3114
|
-
<
|
|
3303
|
+
<div class="prx-micro-bullet__bottom">
|
|
3304
|
+
<span class="prx-micro-bullet__scale-min">{{ formatNumber(config.baseline ?? 0) }}</span>
|
|
3305
|
+
<span class="prx-micro-bullet__scale-max">{{ formatNumber(config.total ?? 100) }}</span>
|
|
3306
|
+
</div>
|
|
3115
3307
|
}
|
|
3116
3308
|
</div>
|
|
3117
3309
|
}
|
|
@@ -3128,12 +3320,208 @@ class PraxisMicroVisualizationComponent {
|
|
|
3128
3320
|
<span class="prx-micro-delta__value">{{ deltaText() }}</span>
|
|
3129
3321
|
</div>
|
|
3130
3322
|
}
|
|
3323
|
+
|
|
3324
|
+
@case ('radial') {
|
|
3325
|
+
<div class="prx-micro-radial" [attr.data-tone]="config.tone || null">
|
|
3326
|
+
<svg class="prx-micro-radial__svg" viewBox="0 0 36 36">
|
|
3327
|
+
<circle class="prx-micro-radial__track" cx="18" cy="18" r="15.9155" />
|
|
3328
|
+
<circle
|
|
3329
|
+
class="prx-micro-radial__bar"
|
|
3330
|
+
cx="18"
|
|
3331
|
+
cy="18"
|
|
3332
|
+
r="15.9155"
|
|
3333
|
+
[style.strokeDasharray]="radialDashArray()"
|
|
3334
|
+
/>
|
|
3335
|
+
<text x="18" y="21" class="prx-micro-radial__svg-text prx-micro-radial__value">{{ radialText() }}</text>
|
|
3336
|
+
</svg>
|
|
3337
|
+
</div>
|
|
3338
|
+
}
|
|
3339
|
+
|
|
3340
|
+
@case ('harveyBall') {
|
|
3341
|
+
<div class="prx-micro-harvey" [attr.data-tone]="config.tone || null">
|
|
3342
|
+
<svg class="prx-micro-harvey__svg" viewBox="0 0 36 36">
|
|
3343
|
+
<circle class="prx-micro-harvey__track" cx="18" cy="18" r="16" />
|
|
3344
|
+
<circle
|
|
3345
|
+
class="prx-micro-harvey__bar"
|
|
3346
|
+
cx="18"
|
|
3347
|
+
cy="18"
|
|
3348
|
+
r="8"
|
|
3349
|
+
[style.strokeDasharray]="harveyDashArray()"
|
|
3350
|
+
/>
|
|
3351
|
+
</svg>
|
|
3352
|
+
<span class="prx-micro-harvey__fraction">
|
|
3353
|
+
<strong class="prx-micro-harvey__value">{{ formatNumber(config.value) }}</strong>
|
|
3354
|
+
<span class="prx-micro-harvey__separator">/</span>
|
|
3355
|
+
<span class="prx-micro-harvey__total">{{ formatNumber(config.total) }}</span>
|
|
3356
|
+
</span>
|
|
3357
|
+
</div>
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
@case ('line') {
|
|
3361
|
+
<div class="prx-micro-trend-container">
|
|
3362
|
+
@if (!isTableCell() && firstPoint()) {
|
|
3363
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--start">
|
|
3364
|
+
<span class="prx-micro-trend__value">{{ formatNumber(firstPoint()?.value) }}</span>
|
|
3365
|
+
<span class="prx-micro-trend__label">{{ firstPoint()?.label }}</span>
|
|
3366
|
+
</div>
|
|
3367
|
+
}
|
|
3368
|
+
|
|
3369
|
+
<div class="prx-micro-trend__chart">
|
|
3370
|
+
<div class="prx-micro-line" [attr.data-tone]="config.tone || null">
|
|
3371
|
+
<svg class="prx-micro-line__svg" viewBox="0 0 100 30">
|
|
3372
|
+
<path
|
|
3373
|
+
class="prx-micro-line__path"
|
|
3374
|
+
[attr.d]="trendPathD()"
|
|
3375
|
+
fill="none"
|
|
3376
|
+
stroke="currentColor"
|
|
3377
|
+
stroke-width="2"
|
|
3378
|
+
stroke-linecap="round"
|
|
3379
|
+
stroke-linejoin="round"
|
|
3380
|
+
/>
|
|
3381
|
+
@for (marker of trendMarkers(); track $index) {
|
|
3382
|
+
<circle
|
|
3383
|
+
[attr.cx]="marker.x"
|
|
3384
|
+
[attr.cy]="marker.y"
|
|
3385
|
+
r="2.5"
|
|
3386
|
+
class="prx-micro-trend__marker"
|
|
3387
|
+
[attr.data-tone]="marker.tone || null"
|
|
3388
|
+
[attr.title]="marker.label"
|
|
3389
|
+
/>
|
|
3390
|
+
}
|
|
3391
|
+
</svg>
|
|
3392
|
+
</div>
|
|
3393
|
+
</div>
|
|
3394
|
+
|
|
3395
|
+
@if (!isTableCell() && lastPoint()) {
|
|
3396
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--end">
|
|
3397
|
+
<span class="prx-micro-trend__value">{{ formatNumber(lastPoint()?.value) }}</span>
|
|
3398
|
+
<span class="prx-micro-trend__label">{{ lastPoint()?.label }}</span>
|
|
3399
|
+
</div>
|
|
3400
|
+
}
|
|
3401
|
+
</div>
|
|
3402
|
+
}
|
|
3403
|
+
|
|
3404
|
+
@case ('area') {
|
|
3405
|
+
<div class="prx-micro-trend-container">
|
|
3406
|
+
@if (!isTableCell() && firstPoint()) {
|
|
3407
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--start">
|
|
3408
|
+
<span class="prx-micro-trend__value">{{ formatNumber(firstPoint()?.value) }}</span>
|
|
3409
|
+
<span class="prx-micro-trend__label">{{ firstPoint()?.label }}</span>
|
|
3410
|
+
</div>
|
|
3411
|
+
}
|
|
3412
|
+
|
|
3413
|
+
<div class="prx-micro-trend__chart">
|
|
3414
|
+
<div class="prx-micro-area" [attr.data-tone]="config.tone || null">
|
|
3415
|
+
<svg class="prx-micro-area__svg" viewBox="0 0 100 30">
|
|
3416
|
+
<path
|
|
3417
|
+
class="prx-micro-area__fill"
|
|
3418
|
+
[attr.d]="trendAreaD()"
|
|
3419
|
+
fill="currentColor"
|
|
3420
|
+
fill-opacity="0.15"
|
|
3421
|
+
/>
|
|
3422
|
+
<path
|
|
3423
|
+
class="prx-micro-area__path"
|
|
3424
|
+
[attr.d]="trendPathD()"
|
|
3425
|
+
fill="none"
|
|
3426
|
+
stroke="currentColor"
|
|
3427
|
+
stroke-width="2"
|
|
3428
|
+
stroke-linecap="round"
|
|
3429
|
+
stroke-linejoin="round"
|
|
3430
|
+
/>
|
|
3431
|
+
@for (marker of trendMarkers(); track $index) {
|
|
3432
|
+
<circle
|
|
3433
|
+
[attr.cx]="marker.x"
|
|
3434
|
+
[attr.cy]="marker.y"
|
|
3435
|
+
r="2.5"
|
|
3436
|
+
class="prx-micro-trend__marker"
|
|
3437
|
+
[attr.data-tone]="marker.tone || null"
|
|
3438
|
+
[attr.title]="marker.label"
|
|
3439
|
+
/>
|
|
3440
|
+
}
|
|
3441
|
+
</svg>
|
|
3442
|
+
</div>
|
|
3443
|
+
</div>
|
|
3444
|
+
|
|
3445
|
+
@if (!isTableCell() && lastPoint()) {
|
|
3446
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--end">
|
|
3447
|
+
<span class="prx-micro-trend__value">{{ formatNumber(lastPoint()?.value) }}</span>
|
|
3448
|
+
<span class="prx-micro-trend__label">{{ lastPoint()?.label }}</span>
|
|
3449
|
+
</div>
|
|
3450
|
+
}
|
|
3451
|
+
</div>
|
|
3452
|
+
}
|
|
3453
|
+
|
|
3454
|
+
@case ('column') {
|
|
3455
|
+
<div class="prx-micro-trend-container">
|
|
3456
|
+
@if (!isTableCell() && firstPoint()) {
|
|
3457
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--start">
|
|
3458
|
+
<span class="prx-micro-trend__value">{{ formatNumber(firstPoint()?.value) }}</span>
|
|
3459
|
+
<span class="prx-micro-trend__label">{{ firstPoint()?.label }}</span>
|
|
3460
|
+
</div>
|
|
3461
|
+
}
|
|
3462
|
+
|
|
3463
|
+
<div class="prx-micro-trend__chart">
|
|
3464
|
+
<div class="prx-micro-column" [attr.data-tone]="config.tone || null">
|
|
3465
|
+
<svg class="prx-micro-column__svg" viewBox="0 0 100 30">
|
|
3466
|
+
@for (col of trendColumns(); track $index) {
|
|
3467
|
+
<rect
|
|
3468
|
+
class="prx-micro-column__bar"
|
|
3469
|
+
[attr.x]="col.x"
|
|
3470
|
+
[attr.y]="col.y"
|
|
3471
|
+
[attr.width]="col.width"
|
|
3472
|
+
[attr.height]="col.height"
|
|
3473
|
+
[attr.data-tone]="col.tone || null"
|
|
3474
|
+
/>
|
|
3475
|
+
}
|
|
3476
|
+
</svg>
|
|
3477
|
+
</div>
|
|
3478
|
+
</div>
|
|
3479
|
+
|
|
3480
|
+
@if (!isTableCell() && lastPoint()) {
|
|
3481
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--end">
|
|
3482
|
+
<span class="prx-micro-trend__value">{{ formatNumber(lastPoint()?.value) }}</span>
|
|
3483
|
+
<span class="prx-micro-trend__label">{{ lastPoint()?.label }}</span>
|
|
3484
|
+
</div>
|
|
3485
|
+
}
|
|
3486
|
+
</div>
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3489
|
+
@case ('processFlow') {
|
|
3490
|
+
<div class="prx-micro-process">
|
|
3491
|
+
@for (item of processSteps(); track item.id ?? $index) {
|
|
3492
|
+
<div class="prx-micro-process__step" [class.prx-micro-process__step--last]="$last">
|
|
3493
|
+
<div class="prx-micro-process__node-wrapper">
|
|
3494
|
+
<span
|
|
3495
|
+
class="prx-micro-process__node"
|
|
3496
|
+
[attr.data-tone]="item.tone || null"
|
|
3497
|
+
[attr.title]="item.label || null"
|
|
3498
|
+
>
|
|
3499
|
+
@if (item.icon) {
|
|
3500
|
+
<span class="material-icons prx-micro-process__icon" aria-hidden="true">{{ item.icon }}</span>
|
|
3501
|
+
} @else {
|
|
3502
|
+
{{ $index + 1 }}
|
|
3503
|
+
}
|
|
3504
|
+
</span>
|
|
3505
|
+
@if (item.label) {
|
|
3506
|
+
<span class="prx-micro-process__label" [attr.title]="item.label">{{ item.label }}</span>
|
|
3507
|
+
}
|
|
3508
|
+
</div>
|
|
3509
|
+
@if (!$last) {
|
|
3510
|
+
<span
|
|
3511
|
+
class="prx-micro-process__connector"
|
|
3512
|
+
[attr.data-tone]="item.tone || null"
|
|
3513
|
+
></span>
|
|
3514
|
+
}
|
|
3515
|
+
</div>
|
|
3516
|
+
}
|
|
3517
|
+
</div>
|
|
3518
|
+
}
|
|
3131
3519
|
}
|
|
3132
3520
|
</figure>
|
|
3133
3521
|
} @else {
|
|
3134
3522
|
<span class="prx-micro-visualization-fallback">{{ fallbackText() }}</span>
|
|
3135
3523
|
}
|
|
3136
|
-
`, isInline: true, styles: [":host{display:inline-block;min-width:0;max-width:100%;color:var(--prx-micro-text-color, var(--md-sys-color-on-surface, #1f2937))}.prx-micro-visualization{display:block;min-width:0;margin:0}:host([data-size=\"xs\"]) .prx-micro-visualization{inline-size:var(--prx-micro-xs-width, 96px)}:host([data-size=\"sm\"]) .prx-micro-visualization{inline-size:var(--prx-micro-sm-width, 136px)}:host([data-size=\"md\"]) .prx-micro-visualization,:host([data-size=\"responsive\"]) .prx-micro-visualization{inline-size:100%}:host(.prx-micro-visualization--table-cell) .prx-micro-visualization{inline-size:var(--prx-micro-table-cell-width, 112px)}.prx-micro-comparison{display:grid;gap:3px}.prx-micro-comparison__row{display:grid;grid-template-columns:minmax(0,48px) minmax(32px,1fr) auto;align-items:center;gap:6px;min-block-size:12px}.prx-micro-comparison__label,.prx-micro-comparison__value,.prx-micro-visualization__caption,.prx-micro-visualization-fallback{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--prx-micro-font-size, 11px);line-height:1.2}.prx-micro-comparison__label{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563))}.prx-micro-comparison__value{justify-self:end;font-variant-numeric:tabular-nums}.prx-micro-comparison__track,.prx-micro-stacked__track,.prx-micro-bullet__track{position:relative;display:block;overflow:hidden;border-radius:var(--prx-micro-track-radius, 999px);background:var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb))}.prx-micro-comparison__track{block-size:5px}.prx-micro-comparison__bar,.prx-micro-stacked__segment,.prx-micro-bullet__range,.prx-micro-bullet__actual{display:block;min-inline-size:1px;background:var(--prx-micro-tone-neutral, var(--md-sys-color-secondary, #64748b))}.prx-micro-comparison__bar{block-size:100%}.prx-micro-stacked__track{display:flex;block-size:8px}.prx-micro-stacked__segment{block-size:100%}.prx-micro-bullet__track{block-size:10px}.prx-micro-bullet__range{position:absolute;inset-block:0;display:block;block-size:100%;opacity:.32}.prx-micro-bullet__actual{position:absolute;inset-block-start:3px;inset-inline-start:0;block-size:4px;border-radius:inherit}.prx-micro-bullet__target{position:absolute;inset-block:0;inline-size:2px;background:var(--prx-micro-target-color, var(--md-sys-color-on-surface, #111827))}.prx-micro-delta{display:inline-flex;align-items:center;gap:4px;min-inline-size:0;font-size:var(--prx-micro-font-size, 12px);line-height:1.2;font-variant-numeric:tabular-nums}.prx-micro-delta__icon{flex:0 0 auto}.prx-micro-delta__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prx-micro-visualization__caption{display:block;margin-block-start:4px;color:var(--prx-micro-caption-color, var(--md-sys-color-on-surface-variant, #4b5563))}[data-tone=info]{background:var(--prx-micro-tone-info, var(--md-sys-color-primary, #2563eb));color:var(--prx-micro-tone-info-text, var(--md-sys-color-primary, #2563eb))}[data-tone=success]{background:var(--prx-micro-tone-success, #15803d);color:var(--prx-micro-tone-success-text, #15803d)}[data-tone=warning]{background:var(--prx-micro-tone-warning, #ca8a04);color:var(--prx-micro-tone-warning-text, #ca8a04)}[data-tone=danger],[data-tone=critical]{background:var(--prx-micro-tone-danger, var(--md-sys-color-error, #dc2626));color:var(--prx-micro-tone-danger-text, var(--md-sys-color-error, #dc2626))}.prx-micro-delta--positive{color:var(--prx-micro-tone-success-text, #15803d)}.prx-micro-delta--negative{color:var(--prx-micro-tone-danger-text, var(--md-sys-color-error, #dc2626))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3524
|
+
`, isInline: true, styles: [":host{display:inline-block;min-width:0;max-width:100%;color:var(--prx-micro-text-color, var(--md-sys-color-on-surface, #1f2937))}.prx-micro-visualization{display:block;min-width:0;margin:0}:host([data-size=\"xs\"]) .prx-micro-visualization{inline-size:var(--prx-micro-xs-width, 96px)}:host([data-size=\"sm\"]) .prx-micro-visualization{inline-size:var(--prx-micro-sm-width, 136px)}:host([data-size=\"md\"]) .prx-micro-visualization,:host([data-size=\"responsive\"]) .prx-micro-visualization{inline-size:100%}:host(.prx-micro-visualization--table-cell) .prx-micro-visualization{inline-size:var(--prx-micro-table-cell-width, 112px)}.prx-micro-comparison{display:grid;gap:3px}.prx-micro-comparison__row{display:grid;grid-template-columns:minmax(0,52px) minmax(32px,1fr) auto;align-items:center;gap:6px;min-block-size:12px}.prx-micro-comparison__label,.prx-micro-comparison__value,.prx-micro-visualization__caption,.prx-micro-visualization-fallback{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--prx-micro-font-size, 11px);line-height:1.2}.prx-micro-comparison__label{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563))}.prx-micro-comparison__value{justify-self:end;font-variant-numeric:tabular-nums}.prx-micro-comparison__track,.prx-micro-stacked__track,.prx-micro-bullet__track{position:relative;display:block;overflow:hidden;border-radius:var(--prx-micro-track-radius, 999px);background:var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb))}.prx-micro-comparison__track{block-size:5px}.prx-micro-comparison__bar,.prx-micro-stacked__segment,.prx-micro-bullet__range,.prx-micro-bullet__actual{display:block;min-inline-size:1px;background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-neutral, var(--md-sys-color-secondary, #5c6b73)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-neutral, var(--md-sys-color-secondary, #5c6b73)) 84%,#111827))}.prx-micro-comparison__bar{block-size:100%}.prx-micro-stacked__track{display:flex;block-size:8px}.prx-micro-stacked__segment{block-size:100%}.prx-micro-bullet__track{block-size:10px}.prx-micro-bullet__range{position:absolute;inset-block:0;display:block;block-size:100%;opacity:.32}.prx-micro-bullet__actual{position:absolute;inset-block-start:3px;inset-inline-start:0;block-size:4px;border-radius:inherit}.prx-micro-bullet__target{position:absolute;inset-block:0;inline-size:2px;background:var(--prx-micro-target-color, var(--md-sys-color-on-surface, #111827))}.prx-micro-delta{display:inline-flex;align-items:center;gap:4px;min-inline-size:0;font-size:var(--prx-micro-font-size, 12px);line-height:1.2;font-variant-numeric:tabular-nums}.prx-micro-delta__icon{flex:0 0 auto}.prx-micro-delta__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prx-micro-visualization__caption{display:block;margin-block-start:4px;color:var(--prx-micro-caption-color, var(--md-sys-color-on-surface-variant, #4b5563))}.prx-micro-bullet-container{display:flex;flex-direction:column;gap:4px;width:100%}.prx-micro-bullet__top{display:flex;justify-content:space-between;align-items:baseline;font-size:var(--prx-micro-font-size, 11px)}.prx-micro-bullet__label{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563));font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prx-micro-bullet__value{font-weight:700;color:currentColor;font-variant-numeric:tabular-nums;flex-shrink:0}.prx-micro-bullet__target-val{font-weight:400;font-size:10px;color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563));margin-left:4px}.prx-micro-bullet__bottom{display:flex;justify-content:space-between;font-size:9px;color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563))}[data-tone=info]{color:var(--prx-micro-tone-info-text, var(--md-sys-color-primary, #0a6eb4))}.prx-micro-comparison__bar[data-tone=info],.prx-micro-stacked__segment[data-tone=info],.prx-micro-bullet__range[data-tone=info],.prx-micro-bullet__actual[data-tone=info],.prx-micro-process__node[data-tone=info],.prx-micro-process__connector[data-tone=info]{background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 84%,#111827))}[data-tone=success]{color:var(--prx-micro-tone-success-text, #1b7a43)}.prx-micro-comparison__bar[data-tone=success],.prx-micro-stacked__segment[data-tone=success],.prx-micro-bullet__range[data-tone=success],.prx-micro-bullet__actual[data-tone=success],.prx-micro-process__node[data-tone=success],.prx-micro-process__connector[data-tone=success]{background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 84%,#111827))}[data-tone=warning]{color:var(--prx-micro-tone-warning-text, #d97706)}.prx-micro-comparison__bar[data-tone=warning],.prx-micro-stacked__segment[data-tone=warning],.prx-micro-bullet__range[data-tone=warning],.prx-micro-bullet__actual[data-tone=warning],.prx-micro-process__node[data-tone=warning],.prx-micro-process__connector[data-tone=warning]{background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 84%,#111827))}[data-tone=danger],[data-tone=critical]{color:var(--prx-micro-tone-danger-text, var(--md-sys-color-error, #c62828))}.prx-micro-comparison__bar[data-tone=danger],.prx-micro-comparison__bar[data-tone=critical],.prx-micro-stacked__segment[data-tone=danger],.prx-micro-stacked__segment[data-tone=critical],.prx-micro-bullet__range[data-tone=danger],.prx-micro-bullet__range[data-tone=critical],.prx-micro-bullet__actual[data-tone=danger],.prx-micro-bullet__actual[data-tone=critical],.prx-micro-process__node[data-tone=danger],.prx-micro-process__node[data-tone=critical],.prx-micro-process__connector[data-tone=danger],.prx-micro-process__connector[data-tone=critical]{background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 84%,#111827))}.prx-micro-delta--positive{color:var(--prx-micro-tone-success-text, #1b7a43)}.prx-micro-delta--negative{color:var(--prx-micro-tone-danger-text, var(--md-sys-color-error, #c62828))}.prx-micro-radial{display:inline-flex;align-items:center;justify-content:center;position:relative}.prx-micro-radial__svg{width:24px;height:24px;overflow:visible;flex-shrink:0;display:block}.prx-micro-radial__track{fill:none;stroke:var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb));stroke-width:3}.prx-micro-radial__bar{fill:none;stroke:currentColor;stroke-width:3;stroke-linecap:round;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dasharray .35s ease}.prx-micro-radial__svg-text{font-size:8px;font-weight:700;text-anchor:middle;fill:currentColor;font-family:var(--md-sys-typescale-body-medium-font-family, sans-serif)}.prx-micro-harvey{display:inline-flex;align-items:center;gap:0}.prx-micro-harvey__svg{width:18px;height:18px;overflow:visible;flex-shrink:0}.prx-micro-harvey__track{fill:none;stroke:var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb));stroke-width:2}.prx-micro-harvey__bar{fill:none;stroke:currentColor;stroke-width:16;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dasharray .35s ease}.prx-micro-harvey__fraction{display:inline-flex;align-items:center;font-size:var(--prx-micro-font-size, 11px);font-variant-numeric:tabular-nums;margin-left:6px;font-family:var(--md-sys-typescale-body-medium-font-family, sans-serif)}.prx-micro-harvey__value{color:currentColor;font-weight:700}.prx-micro-harvey__separator{opacity:.6;color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563));margin-inline:2px}.prx-micro-harvey__total{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563))}.prx-micro-trend-container{display:flex;align-items:center;gap:8px;width:100%}.prx-micro-trend__label-col{display:flex;flex-direction:column;justify-content:center;font-size:var(--prx-micro-font-size, 11px);line-height:1.2;flex-shrink:0;min-width:24px;font-family:var(--md-sys-typescale-body-medium-font-family, sans-serif)}.prx-micro-trend__label-col--start{align-items:flex-end;text-align:right}.prx-micro-trend__label-col--end{align-items:flex-start;text-align:left}.prx-micro-trend__value{font-weight:700;color:var(--md-sys-color-on-surface, #1f2937)}.prx-micro-trend__label{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563));font-size:9px}.prx-micro-trend__chart{flex:1 1 auto;height:30px;min-width:48px;overflow:visible}.prx-micro-line,.prx-micro-area,.prx-micro-column{display:block;width:100%;height:30px;overflow:visible}.prx-micro-line__svg,.prx-micro-area__svg,.prx-micro-column__svg{width:100%;height:100%;display:block;overflow:visible}.prx-micro-line__path,.prx-micro-area__path{stroke:currentColor}.prx-micro-area__fill,.prx-micro-column__bar{fill:currentColor}.prx-micro-trend__marker{fill:currentColor;stroke:var(--md-sys-color-surface, #ffffff);stroke-width:1.5px}.prx-micro-process{display:flex;align-items:flex-start;width:100%;min-width:0;padding-block:6px 2px;overflow-x:auto;-webkit-overflow-scrolling:touch}.prx-micro-process__step{display:grid;grid-template-columns:minmax(42px,auto) minmax(14px,1fr);align-items:start;flex:1 1 0%;min-width:0}.prx-micro-process__step--last{grid-template-columns:minmax(42px,auto);flex:0 0 auto}.prx-micro-process__node-wrapper{display:flex;flex-direction:column;align-items:center;position:relative;flex-shrink:0;min-width:42px}.prx-micro-process__node{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;font-size:12px;font-weight:700;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-surface-container-high, #e5e7eb) 92%,#ffffff),color-mix(in srgb,var(--md-sys-color-surface-container-high, #e5e7eb) 82%,#111827));color:var(--md-sys-color-on-surface, #1f2937);box-shadow:inset 0 0 0 1px color-mix(in srgb,currentColor 16%,transparent);transition:background-color .2s ease,color .2s ease}.prx-micro-process__icon{font-size:14px;line-height:1}.prx-micro-process__label{display:-webkit-box;inline-size:56px;max-width:56px;margin-top:5px;overflow:hidden;overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;color:var(--md-sys-color-on-surface-variant, #4b5563);font-size:9px;font-weight:600;line-height:1.15;text-align:center}.prx-micro-process__connector{flex:1 1 auto;height:2px;background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb)) 78%,transparent),color-mix(in srgb,var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb)) 42%,transparent));margin-block-start:11px;margin-inline:6px;min-width:14px;border-radius:999px;opacity:.85}:host(.prx-micro-visualization--table-cell) .prx-micro-process{align-items:center;min-width:112px;padding-block:0;overflow:hidden}:host(.prx-micro-visualization--table-cell) .prx-micro-process__step{display:flex;align-items:center;flex:0 1 auto}:host(.prx-micro-visualization--table-cell) .prx-micro-process__node-wrapper{min-width:0}:host(.prx-micro-visualization--table-cell) .prx-micro-process__node{width:22px;height:22px}:host(.prx-micro-visualization--table-cell) .prx-micro-process__label{display:none}:host(.prx-micro-visualization--table-cell) .prx-micro-process__connector{flex:0 1 22px;min-width:10px;max-width:26px;margin-block-start:0;margin-inline:5px}.prx-micro-process__node[data-tone=info]{background:linear-gradient(135deg,color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 82%,#111827));color:#fff}.prx-micro-process__node[data-tone=success]{background:linear-gradient(135deg,color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 82%,#111827));color:#fff}.prx-micro-process__node[data-tone=warning]{background:linear-gradient(135deg,color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 82%,#111827));color:#fff}.prx-micro-process__node[data-tone=danger],.prx-micro-process__node[data-tone=critical]{background:linear-gradient(135deg,color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 82%,#111827));color:#fff}.prx-micro-process__connector[data-tone=info]{background:linear-gradient(90deg,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)),color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 38%,transparent))}.prx-micro-process__connector[data-tone=success]{background:linear-gradient(90deg,var(--prx-micro-tone-success, #1b7a43),color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 38%,transparent))}.prx-micro-process__connector[data-tone=warning]{background:linear-gradient(90deg,var(--prx-micro-tone-warning, #d97706),color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 38%,transparent))}.prx-micro-process__connector[data-tone=danger],.prx-micro-process__connector[data-tone=critical]{background:linear-gradient(90deg,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)),color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 38%,transparent))}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3137
3525
|
}
|
|
3138
3526
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisMicroVisualizationComponent, decorators: [{
|
|
3139
3527
|
type: Component,
|
|
@@ -3152,7 +3540,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3152
3540
|
@switch (config.kind) {
|
|
3153
3541
|
@case ('comparison') {
|
|
3154
3542
|
<div class="prx-micro-comparison">
|
|
3155
|
-
|
|
3543
|
+
@for (item of comparisonItems(); track item.label ?? $index) {
|
|
3156
3544
|
<div class="prx-micro-comparison__row">
|
|
3157
3545
|
@if (item.label) {
|
|
3158
3546
|
<span class="prx-micro-comparison__label">{{ item.label }}</span>
|
|
@@ -3190,7 +3578,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3190
3578
|
}
|
|
3191
3579
|
|
|
3192
3580
|
@case ('bullet') {
|
|
3193
|
-
<div class="prx-micro-bullet">
|
|
3581
|
+
<div class="prx-micro-bullet-container">
|
|
3582
|
+
@if (!isTableCell()) {
|
|
3583
|
+
<div class="prx-micro-bullet__top">
|
|
3584
|
+
<span class="prx-micro-bullet__label">{{ config.fallbackText }}</span>
|
|
3585
|
+
<span class="prx-micro-bullet__value" [attr.data-tone]="config.tone || null">
|
|
3586
|
+
{{ formatNumber(config.value) }}
|
|
3587
|
+
@if (config.target !== undefined) {
|
|
3588
|
+
<span class="prx-micro-bullet__target-val">/ Target: {{ formatNumber(config.target) }}</span>
|
|
3589
|
+
}
|
|
3590
|
+
</span>
|
|
3591
|
+
</div>
|
|
3592
|
+
}
|
|
3593
|
+
|
|
3194
3594
|
<div class="prx-micro-bullet__track" aria-hidden="true">
|
|
3195
3595
|
@for (band of bulletBands(); track band.label ?? $index) {
|
|
3196
3596
|
<span
|
|
@@ -3212,8 +3612,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3212
3612
|
></span>
|
|
3213
3613
|
}
|
|
3214
3614
|
</div>
|
|
3615
|
+
|
|
3215
3616
|
@if (!isTableCell()) {
|
|
3216
|
-
<
|
|
3617
|
+
<div class="prx-micro-bullet__bottom">
|
|
3618
|
+
<span class="prx-micro-bullet__scale-min">{{ formatNumber(config.baseline ?? 0) }}</span>
|
|
3619
|
+
<span class="prx-micro-bullet__scale-max">{{ formatNumber(config.total ?? 100) }}</span>
|
|
3620
|
+
</div>
|
|
3217
3621
|
}
|
|
3218
3622
|
</div>
|
|
3219
3623
|
}
|
|
@@ -3230,12 +3634,208 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
3230
3634
|
<span class="prx-micro-delta__value">{{ deltaText() }}</span>
|
|
3231
3635
|
</div>
|
|
3232
3636
|
}
|
|
3637
|
+
|
|
3638
|
+
@case ('radial') {
|
|
3639
|
+
<div class="prx-micro-radial" [attr.data-tone]="config.tone || null">
|
|
3640
|
+
<svg class="prx-micro-radial__svg" viewBox="0 0 36 36">
|
|
3641
|
+
<circle class="prx-micro-radial__track" cx="18" cy="18" r="15.9155" />
|
|
3642
|
+
<circle
|
|
3643
|
+
class="prx-micro-radial__bar"
|
|
3644
|
+
cx="18"
|
|
3645
|
+
cy="18"
|
|
3646
|
+
r="15.9155"
|
|
3647
|
+
[style.strokeDasharray]="radialDashArray()"
|
|
3648
|
+
/>
|
|
3649
|
+
<text x="18" y="21" class="prx-micro-radial__svg-text prx-micro-radial__value">{{ radialText() }}</text>
|
|
3650
|
+
</svg>
|
|
3651
|
+
</div>
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
@case ('harveyBall') {
|
|
3655
|
+
<div class="prx-micro-harvey" [attr.data-tone]="config.tone || null">
|
|
3656
|
+
<svg class="prx-micro-harvey__svg" viewBox="0 0 36 36">
|
|
3657
|
+
<circle class="prx-micro-harvey__track" cx="18" cy="18" r="16" />
|
|
3658
|
+
<circle
|
|
3659
|
+
class="prx-micro-harvey__bar"
|
|
3660
|
+
cx="18"
|
|
3661
|
+
cy="18"
|
|
3662
|
+
r="8"
|
|
3663
|
+
[style.strokeDasharray]="harveyDashArray()"
|
|
3664
|
+
/>
|
|
3665
|
+
</svg>
|
|
3666
|
+
<span class="prx-micro-harvey__fraction">
|
|
3667
|
+
<strong class="prx-micro-harvey__value">{{ formatNumber(config.value) }}</strong>
|
|
3668
|
+
<span class="prx-micro-harvey__separator">/</span>
|
|
3669
|
+
<span class="prx-micro-harvey__total">{{ formatNumber(config.total) }}</span>
|
|
3670
|
+
</span>
|
|
3671
|
+
</div>
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3674
|
+
@case ('line') {
|
|
3675
|
+
<div class="prx-micro-trend-container">
|
|
3676
|
+
@if (!isTableCell() && firstPoint()) {
|
|
3677
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--start">
|
|
3678
|
+
<span class="prx-micro-trend__value">{{ formatNumber(firstPoint()?.value) }}</span>
|
|
3679
|
+
<span class="prx-micro-trend__label">{{ firstPoint()?.label }}</span>
|
|
3680
|
+
</div>
|
|
3681
|
+
}
|
|
3682
|
+
|
|
3683
|
+
<div class="prx-micro-trend__chart">
|
|
3684
|
+
<div class="prx-micro-line" [attr.data-tone]="config.tone || null">
|
|
3685
|
+
<svg class="prx-micro-line__svg" viewBox="0 0 100 30">
|
|
3686
|
+
<path
|
|
3687
|
+
class="prx-micro-line__path"
|
|
3688
|
+
[attr.d]="trendPathD()"
|
|
3689
|
+
fill="none"
|
|
3690
|
+
stroke="currentColor"
|
|
3691
|
+
stroke-width="2"
|
|
3692
|
+
stroke-linecap="round"
|
|
3693
|
+
stroke-linejoin="round"
|
|
3694
|
+
/>
|
|
3695
|
+
@for (marker of trendMarkers(); track $index) {
|
|
3696
|
+
<circle
|
|
3697
|
+
[attr.cx]="marker.x"
|
|
3698
|
+
[attr.cy]="marker.y"
|
|
3699
|
+
r="2.5"
|
|
3700
|
+
class="prx-micro-trend__marker"
|
|
3701
|
+
[attr.data-tone]="marker.tone || null"
|
|
3702
|
+
[attr.title]="marker.label"
|
|
3703
|
+
/>
|
|
3704
|
+
}
|
|
3705
|
+
</svg>
|
|
3706
|
+
</div>
|
|
3707
|
+
</div>
|
|
3708
|
+
|
|
3709
|
+
@if (!isTableCell() && lastPoint()) {
|
|
3710
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--end">
|
|
3711
|
+
<span class="prx-micro-trend__value">{{ formatNumber(lastPoint()?.value) }}</span>
|
|
3712
|
+
<span class="prx-micro-trend__label">{{ lastPoint()?.label }}</span>
|
|
3713
|
+
</div>
|
|
3714
|
+
}
|
|
3715
|
+
</div>
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
@case ('area') {
|
|
3719
|
+
<div class="prx-micro-trend-container">
|
|
3720
|
+
@if (!isTableCell() && firstPoint()) {
|
|
3721
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--start">
|
|
3722
|
+
<span class="prx-micro-trend__value">{{ formatNumber(firstPoint()?.value) }}</span>
|
|
3723
|
+
<span class="prx-micro-trend__label">{{ firstPoint()?.label }}</span>
|
|
3724
|
+
</div>
|
|
3725
|
+
}
|
|
3726
|
+
|
|
3727
|
+
<div class="prx-micro-trend__chart">
|
|
3728
|
+
<div class="prx-micro-area" [attr.data-tone]="config.tone || null">
|
|
3729
|
+
<svg class="prx-micro-area__svg" viewBox="0 0 100 30">
|
|
3730
|
+
<path
|
|
3731
|
+
class="prx-micro-area__fill"
|
|
3732
|
+
[attr.d]="trendAreaD()"
|
|
3733
|
+
fill="currentColor"
|
|
3734
|
+
fill-opacity="0.15"
|
|
3735
|
+
/>
|
|
3736
|
+
<path
|
|
3737
|
+
class="prx-micro-area__path"
|
|
3738
|
+
[attr.d]="trendPathD()"
|
|
3739
|
+
fill="none"
|
|
3740
|
+
stroke="currentColor"
|
|
3741
|
+
stroke-width="2"
|
|
3742
|
+
stroke-linecap="round"
|
|
3743
|
+
stroke-linejoin="round"
|
|
3744
|
+
/>
|
|
3745
|
+
@for (marker of trendMarkers(); track $index) {
|
|
3746
|
+
<circle
|
|
3747
|
+
[attr.cx]="marker.x"
|
|
3748
|
+
[attr.cy]="marker.y"
|
|
3749
|
+
r="2.5"
|
|
3750
|
+
class="prx-micro-trend__marker"
|
|
3751
|
+
[attr.data-tone]="marker.tone || null"
|
|
3752
|
+
[attr.title]="marker.label"
|
|
3753
|
+
/>
|
|
3754
|
+
}
|
|
3755
|
+
</svg>
|
|
3756
|
+
</div>
|
|
3757
|
+
</div>
|
|
3758
|
+
|
|
3759
|
+
@if (!isTableCell() && lastPoint()) {
|
|
3760
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--end">
|
|
3761
|
+
<span class="prx-micro-trend__value">{{ formatNumber(lastPoint()?.value) }}</span>
|
|
3762
|
+
<span class="prx-micro-trend__label">{{ lastPoint()?.label }}</span>
|
|
3763
|
+
</div>
|
|
3764
|
+
}
|
|
3765
|
+
</div>
|
|
3766
|
+
}
|
|
3767
|
+
|
|
3768
|
+
@case ('column') {
|
|
3769
|
+
<div class="prx-micro-trend-container">
|
|
3770
|
+
@if (!isTableCell() && firstPoint()) {
|
|
3771
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--start">
|
|
3772
|
+
<span class="prx-micro-trend__value">{{ formatNumber(firstPoint()?.value) }}</span>
|
|
3773
|
+
<span class="prx-micro-trend__label">{{ firstPoint()?.label }}</span>
|
|
3774
|
+
</div>
|
|
3775
|
+
}
|
|
3776
|
+
|
|
3777
|
+
<div class="prx-micro-trend__chart">
|
|
3778
|
+
<div class="prx-micro-column" [attr.data-tone]="config.tone || null">
|
|
3779
|
+
<svg class="prx-micro-column__svg" viewBox="0 0 100 30">
|
|
3780
|
+
@for (col of trendColumns(); track $index) {
|
|
3781
|
+
<rect
|
|
3782
|
+
class="prx-micro-column__bar"
|
|
3783
|
+
[attr.x]="col.x"
|
|
3784
|
+
[attr.y]="col.y"
|
|
3785
|
+
[attr.width]="col.width"
|
|
3786
|
+
[attr.height]="col.height"
|
|
3787
|
+
[attr.data-tone]="col.tone || null"
|
|
3788
|
+
/>
|
|
3789
|
+
}
|
|
3790
|
+
</svg>
|
|
3791
|
+
</div>
|
|
3792
|
+
</div>
|
|
3793
|
+
|
|
3794
|
+
@if (!isTableCell() && lastPoint()) {
|
|
3795
|
+
<div class="prx-micro-trend__label-col prx-micro-trend__label-col--end">
|
|
3796
|
+
<span class="prx-micro-trend__value">{{ formatNumber(lastPoint()?.value) }}</span>
|
|
3797
|
+
<span class="prx-micro-trend__label">{{ lastPoint()?.label }}</span>
|
|
3798
|
+
</div>
|
|
3799
|
+
}
|
|
3800
|
+
</div>
|
|
3801
|
+
}
|
|
3802
|
+
|
|
3803
|
+
@case ('processFlow') {
|
|
3804
|
+
<div class="prx-micro-process">
|
|
3805
|
+
@for (item of processSteps(); track item.id ?? $index) {
|
|
3806
|
+
<div class="prx-micro-process__step" [class.prx-micro-process__step--last]="$last">
|
|
3807
|
+
<div class="prx-micro-process__node-wrapper">
|
|
3808
|
+
<span
|
|
3809
|
+
class="prx-micro-process__node"
|
|
3810
|
+
[attr.data-tone]="item.tone || null"
|
|
3811
|
+
[attr.title]="item.label || null"
|
|
3812
|
+
>
|
|
3813
|
+
@if (item.icon) {
|
|
3814
|
+
<span class="material-icons prx-micro-process__icon" aria-hidden="true">{{ item.icon }}</span>
|
|
3815
|
+
} @else {
|
|
3816
|
+
{{ $index + 1 }}
|
|
3817
|
+
}
|
|
3818
|
+
</span>
|
|
3819
|
+
@if (item.label) {
|
|
3820
|
+
<span class="prx-micro-process__label" [attr.title]="item.label">{{ item.label }}</span>
|
|
3821
|
+
}
|
|
3822
|
+
</div>
|
|
3823
|
+
@if (!$last) {
|
|
3824
|
+
<span
|
|
3825
|
+
class="prx-micro-process__connector"
|
|
3826
|
+
[attr.data-tone]="item.tone || null"
|
|
3827
|
+
></span>
|
|
3828
|
+
}
|
|
3829
|
+
</div>
|
|
3830
|
+
}
|
|
3831
|
+
</div>
|
|
3832
|
+
}
|
|
3233
3833
|
}
|
|
3234
3834
|
</figure>
|
|
3235
3835
|
} @else {
|
|
3236
3836
|
<span class="prx-micro-visualization-fallback">{{ fallbackText() }}</span>
|
|
3237
3837
|
}
|
|
3238
|
-
`, styles: [":host{display:inline-block;min-width:0;max-width:100%;color:var(--prx-micro-text-color, var(--md-sys-color-on-surface, #1f2937))}.prx-micro-visualization{display:block;min-width:0;margin:0}:host([data-size=\"xs\"]) .prx-micro-visualization{inline-size:var(--prx-micro-xs-width, 96px)}:host([data-size=\"sm\"]) .prx-micro-visualization{inline-size:var(--prx-micro-sm-width, 136px)}:host([data-size=\"md\"]) .prx-micro-visualization,:host([data-size=\"responsive\"]) .prx-micro-visualization{inline-size:100%}:host(.prx-micro-visualization--table-cell) .prx-micro-visualization{inline-size:var(--prx-micro-table-cell-width, 112px)}.prx-micro-comparison{display:grid;gap:3px}.prx-micro-comparison__row{display:grid;grid-template-columns:minmax(0,48px) minmax(32px,1fr) auto;align-items:center;gap:6px;min-block-size:12px}.prx-micro-comparison__label,.prx-micro-comparison__value,.prx-micro-visualization__caption,.prx-micro-visualization-fallback{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--prx-micro-font-size, 11px);line-height:1.2}.prx-micro-comparison__label{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563))}.prx-micro-comparison__value{justify-self:end;font-variant-numeric:tabular-nums}.prx-micro-comparison__track,.prx-micro-stacked__track,.prx-micro-bullet__track{position:relative;display:block;overflow:hidden;border-radius:var(--prx-micro-track-radius, 999px);background:var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb))}.prx-micro-comparison__track{block-size:5px}.prx-micro-comparison__bar,.prx-micro-stacked__segment,.prx-micro-bullet__range,.prx-micro-bullet__actual{display:block;min-inline-size:1px;background:var(--prx-micro-tone-neutral, var(--md-sys-color-secondary, #64748b))}.prx-micro-comparison__bar{block-size:100%}.prx-micro-stacked__track{display:flex;block-size:8px}.prx-micro-stacked__segment{block-size:100%}.prx-micro-bullet__track{block-size:10px}.prx-micro-bullet__range{position:absolute;inset-block:0;display:block;block-size:100%;opacity:.32}.prx-micro-bullet__actual{position:absolute;inset-block-start:3px;inset-inline-start:0;block-size:4px;border-radius:inherit}.prx-micro-bullet__target{position:absolute;inset-block:0;inline-size:2px;background:var(--prx-micro-target-color, var(--md-sys-color-on-surface, #111827))}.prx-micro-delta{display:inline-flex;align-items:center;gap:4px;min-inline-size:0;font-size:var(--prx-micro-font-size, 12px);line-height:1.2;font-variant-numeric:tabular-nums}.prx-micro-delta__icon{flex:0 0 auto}.prx-micro-delta__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prx-micro-visualization__caption{display:block;margin-block-start:4px;color:var(--prx-micro-caption-color, var(--md-sys-color-on-surface-variant, #4b5563))}[data-tone=info]{background:var(--prx-micro-tone-info, var(--md-sys-color-primary, #2563eb));color:var(--prx-micro-tone-info-text, var(--md-sys-color-primary, #2563eb))}[data-tone=success]{background:var(--prx-micro-tone-success, #15803d);color:var(--prx-micro-tone-success-text, #15803d)}[data-tone=warning]{background:var(--prx-micro-tone-warning, #ca8a04);color:var(--prx-micro-tone-warning-text, #ca8a04)}[data-tone=danger],[data-tone=critical]{background:var(--prx-micro-tone-danger, var(--md-sys-color-error, #dc2626));color:var(--prx-micro-tone-danger-text, var(--md-sys-color-error, #dc2626))}.prx-micro-delta--positive{color:var(--prx-micro-tone-success-text, #15803d)}.prx-micro-delta--negative{color:var(--prx-micro-tone-danger-text, var(--md-sys-color-error, #dc2626))}\n"] }]
|
|
3838
|
+
`, styles: [":host{display:inline-block;min-width:0;max-width:100%;color:var(--prx-micro-text-color, var(--md-sys-color-on-surface, #1f2937))}.prx-micro-visualization{display:block;min-width:0;margin:0}:host([data-size=\"xs\"]) .prx-micro-visualization{inline-size:var(--prx-micro-xs-width, 96px)}:host([data-size=\"sm\"]) .prx-micro-visualization{inline-size:var(--prx-micro-sm-width, 136px)}:host([data-size=\"md\"]) .prx-micro-visualization,:host([data-size=\"responsive\"]) .prx-micro-visualization{inline-size:100%}:host(.prx-micro-visualization--table-cell) .prx-micro-visualization{inline-size:var(--prx-micro-table-cell-width, 112px)}.prx-micro-comparison{display:grid;gap:3px}.prx-micro-comparison__row{display:grid;grid-template-columns:minmax(0,52px) minmax(32px,1fr) auto;align-items:center;gap:6px;min-block-size:12px}.prx-micro-comparison__label,.prx-micro-comparison__value,.prx-micro-visualization__caption,.prx-micro-visualization-fallback{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--prx-micro-font-size, 11px);line-height:1.2}.prx-micro-comparison__label{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563))}.prx-micro-comparison__value{justify-self:end;font-variant-numeric:tabular-nums}.prx-micro-comparison__track,.prx-micro-stacked__track,.prx-micro-bullet__track{position:relative;display:block;overflow:hidden;border-radius:var(--prx-micro-track-radius, 999px);background:var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb))}.prx-micro-comparison__track{block-size:5px}.prx-micro-comparison__bar,.prx-micro-stacked__segment,.prx-micro-bullet__range,.prx-micro-bullet__actual{display:block;min-inline-size:1px;background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-neutral, var(--md-sys-color-secondary, #5c6b73)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-neutral, var(--md-sys-color-secondary, #5c6b73)) 84%,#111827))}.prx-micro-comparison__bar{block-size:100%}.prx-micro-stacked__track{display:flex;block-size:8px}.prx-micro-stacked__segment{block-size:100%}.prx-micro-bullet__track{block-size:10px}.prx-micro-bullet__range{position:absolute;inset-block:0;display:block;block-size:100%;opacity:.32}.prx-micro-bullet__actual{position:absolute;inset-block-start:3px;inset-inline-start:0;block-size:4px;border-radius:inherit}.prx-micro-bullet__target{position:absolute;inset-block:0;inline-size:2px;background:var(--prx-micro-target-color, var(--md-sys-color-on-surface, #111827))}.prx-micro-delta{display:inline-flex;align-items:center;gap:4px;min-inline-size:0;font-size:var(--prx-micro-font-size, 12px);line-height:1.2;font-variant-numeric:tabular-nums}.prx-micro-delta__icon{flex:0 0 auto}.prx-micro-delta__value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prx-micro-visualization__caption{display:block;margin-block-start:4px;color:var(--prx-micro-caption-color, var(--md-sys-color-on-surface-variant, #4b5563))}.prx-micro-bullet-container{display:flex;flex-direction:column;gap:4px;width:100%}.prx-micro-bullet__top{display:flex;justify-content:space-between;align-items:baseline;font-size:var(--prx-micro-font-size, 11px)}.prx-micro-bullet__label{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563));font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.prx-micro-bullet__value{font-weight:700;color:currentColor;font-variant-numeric:tabular-nums;flex-shrink:0}.prx-micro-bullet__target-val{font-weight:400;font-size:10px;color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563));margin-left:4px}.prx-micro-bullet__bottom{display:flex;justify-content:space-between;font-size:9px;color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563))}[data-tone=info]{color:var(--prx-micro-tone-info-text, var(--md-sys-color-primary, #0a6eb4))}.prx-micro-comparison__bar[data-tone=info],.prx-micro-stacked__segment[data-tone=info],.prx-micro-bullet__range[data-tone=info],.prx-micro-bullet__actual[data-tone=info],.prx-micro-process__node[data-tone=info],.prx-micro-process__connector[data-tone=info]{background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 84%,#111827))}[data-tone=success]{color:var(--prx-micro-tone-success-text, #1b7a43)}.prx-micro-comparison__bar[data-tone=success],.prx-micro-stacked__segment[data-tone=success],.prx-micro-bullet__range[data-tone=success],.prx-micro-bullet__actual[data-tone=success],.prx-micro-process__node[data-tone=success],.prx-micro-process__connector[data-tone=success]{background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 84%,#111827))}[data-tone=warning]{color:var(--prx-micro-tone-warning-text, #d97706)}.prx-micro-comparison__bar[data-tone=warning],.prx-micro-stacked__segment[data-tone=warning],.prx-micro-bullet__range[data-tone=warning],.prx-micro-bullet__actual[data-tone=warning],.prx-micro-process__node[data-tone=warning],.prx-micro-process__connector[data-tone=warning]{background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 84%,#111827))}[data-tone=danger],[data-tone=critical]{color:var(--prx-micro-tone-danger-text, var(--md-sys-color-error, #c62828))}.prx-micro-comparison__bar[data-tone=danger],.prx-micro-comparison__bar[data-tone=critical],.prx-micro-stacked__segment[data-tone=danger],.prx-micro-stacked__segment[data-tone=critical],.prx-micro-bullet__range[data-tone=danger],.prx-micro-bullet__range[data-tone=critical],.prx-micro-bullet__actual[data-tone=danger],.prx-micro-bullet__actual[data-tone=critical],.prx-micro-process__node[data-tone=danger],.prx-micro-process__node[data-tone=critical],.prx-micro-process__connector[data-tone=danger],.prx-micro-process__connector[data-tone=critical]{background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 84%,#111827))}.prx-micro-delta--positive{color:var(--prx-micro-tone-success-text, #1b7a43)}.prx-micro-delta--negative{color:var(--prx-micro-tone-danger-text, var(--md-sys-color-error, #c62828))}.prx-micro-radial{display:inline-flex;align-items:center;justify-content:center;position:relative}.prx-micro-radial__svg{width:24px;height:24px;overflow:visible;flex-shrink:0;display:block}.prx-micro-radial__track{fill:none;stroke:var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb));stroke-width:3}.prx-micro-radial__bar{fill:none;stroke:currentColor;stroke-width:3;stroke-linecap:round;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dasharray .35s ease}.prx-micro-radial__svg-text{font-size:8px;font-weight:700;text-anchor:middle;fill:currentColor;font-family:var(--md-sys-typescale-body-medium-font-family, sans-serif)}.prx-micro-harvey{display:inline-flex;align-items:center;gap:0}.prx-micro-harvey__svg{width:18px;height:18px;overflow:visible;flex-shrink:0}.prx-micro-harvey__track{fill:none;stroke:var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb));stroke-width:2}.prx-micro-harvey__bar{fill:none;stroke:currentColor;stroke-width:16;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dasharray .35s ease}.prx-micro-harvey__fraction{display:inline-flex;align-items:center;font-size:var(--prx-micro-font-size, 11px);font-variant-numeric:tabular-nums;margin-left:6px;font-family:var(--md-sys-typescale-body-medium-font-family, sans-serif)}.prx-micro-harvey__value{color:currentColor;font-weight:700}.prx-micro-harvey__separator{opacity:.6;color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563));margin-inline:2px}.prx-micro-harvey__total{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563))}.prx-micro-trend-container{display:flex;align-items:center;gap:8px;width:100%}.prx-micro-trend__label-col{display:flex;flex-direction:column;justify-content:center;font-size:var(--prx-micro-font-size, 11px);line-height:1.2;flex-shrink:0;min-width:24px;font-family:var(--md-sys-typescale-body-medium-font-family, sans-serif)}.prx-micro-trend__label-col--start{align-items:flex-end;text-align:right}.prx-micro-trend__label-col--end{align-items:flex-start;text-align:left}.prx-micro-trend__value{font-weight:700;color:var(--md-sys-color-on-surface, #1f2937)}.prx-micro-trend__label{color:var(--prx-micro-label-color, var(--md-sys-color-on-surface-variant, #4b5563));font-size:9px}.prx-micro-trend__chart{flex:1 1 auto;height:30px;min-width:48px;overflow:visible}.prx-micro-line,.prx-micro-area,.prx-micro-column{display:block;width:100%;height:30px;overflow:visible}.prx-micro-line__svg,.prx-micro-area__svg,.prx-micro-column__svg{width:100%;height:100%;display:block;overflow:visible}.prx-micro-line__path,.prx-micro-area__path{stroke:currentColor}.prx-micro-area__fill,.prx-micro-column__bar{fill:currentColor}.prx-micro-trend__marker{fill:currentColor;stroke:var(--md-sys-color-surface, #ffffff);stroke-width:1.5px}.prx-micro-process{display:flex;align-items:flex-start;width:100%;min-width:0;padding-block:6px 2px;overflow-x:auto;-webkit-overflow-scrolling:touch}.prx-micro-process__step{display:grid;grid-template-columns:minmax(42px,auto) minmax(14px,1fr);align-items:start;flex:1 1 0%;min-width:0}.prx-micro-process__step--last{grid-template-columns:minmax(42px,auto);flex:0 0 auto}.prx-micro-process__node-wrapper{display:flex;flex-direction:column;align-items:center;position:relative;flex-shrink:0;min-width:42px}.prx-micro-process__node{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;font-size:12px;font-weight:700;background:linear-gradient(135deg,color-mix(in srgb,var(--md-sys-color-surface-container-high, #e5e7eb) 92%,#ffffff),color-mix(in srgb,var(--md-sys-color-surface-container-high, #e5e7eb) 82%,#111827));color:var(--md-sys-color-on-surface, #1f2937);box-shadow:inset 0 0 0 1px color-mix(in srgb,currentColor 16%,transparent);transition:background-color .2s ease,color .2s ease}.prx-micro-process__icon{font-size:14px;line-height:1}.prx-micro-process__label{display:-webkit-box;inline-size:56px;max-width:56px;margin-top:5px;overflow:hidden;overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;color:var(--md-sys-color-on-surface-variant, #4b5563);font-size:9px;font-weight:600;line-height:1.15;text-align:center}.prx-micro-process__connector{flex:1 1 auto;height:2px;background:linear-gradient(90deg,color-mix(in srgb,var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb)) 78%,transparent),color-mix(in srgb,var(--prx-micro-track-color, var(--md-sys-color-surface-container-high, #e5e7eb)) 42%,transparent));margin-block-start:11px;margin-inline:6px;min-width:14px;border-radius:999px;opacity:.85}:host(.prx-micro-visualization--table-cell) .prx-micro-process{align-items:center;min-width:112px;padding-block:0;overflow:hidden}:host(.prx-micro-visualization--table-cell) .prx-micro-process__step{display:flex;align-items:center;flex:0 1 auto}:host(.prx-micro-visualization--table-cell) .prx-micro-process__node-wrapper{min-width:0}:host(.prx-micro-visualization--table-cell) .prx-micro-process__node{width:22px;height:22px}:host(.prx-micro-visualization--table-cell) .prx-micro-process__label{display:none}:host(.prx-micro-visualization--table-cell) .prx-micro-process__connector{flex:0 1 22px;min-width:10px;max-width:26px;margin-block-start:0;margin-inline:5px}.prx-micro-process__node[data-tone=info]{background:linear-gradient(135deg,color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 82%,#111827));color:#fff}.prx-micro-process__node[data-tone=success]{background:linear-gradient(135deg,color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 82%,#111827));color:#fff}.prx-micro-process__node[data-tone=warning]{background:linear-gradient(135deg,color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 82%,#111827));color:#fff}.prx-micro-process__node[data-tone=danger],.prx-micro-process__node[data-tone=critical]{background:linear-gradient(135deg,color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 88%,#ffffff),color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 82%,#111827));color:#fff}.prx-micro-process__connector[data-tone=info]{background:linear-gradient(90deg,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)),color-mix(in srgb,var(--prx-micro-tone-info, var(--md-sys-color-primary, #0a6eb4)) 38%,transparent))}.prx-micro-process__connector[data-tone=success]{background:linear-gradient(90deg,var(--prx-micro-tone-success, #1b7a43),color-mix(in srgb,var(--prx-micro-tone-success, #1b7a43) 38%,transparent))}.prx-micro-process__connector[data-tone=warning]{background:linear-gradient(90deg,var(--prx-micro-tone-warning, #d97706),color-mix(in srgb,var(--prx-micro-tone-warning, #d97706) 38%,transparent))}.prx-micro-process__connector[data-tone=danger],.prx-micro-process__connector[data-tone=critical]{background:linear-gradient(90deg,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)),color-mix(in srgb,var(--prx-micro-tone-danger, var(--md-sys-color-error, #c62828)) 38%,transparent))}\n"] }]
|
|
3239
3839
|
}], propDecorators: { visualizationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "visualization", required: false }] }], fallbackInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallbackText", required: false }] }] } });
|
|
3240
3840
|
function clampPercent(value) {
|
|
3241
3841
|
if (!Number.isFinite(value)) {
|
|
@@ -7428,7 +8028,7 @@ const PRAXIS_CHARTS_AUTHORING_MANIFEST = {
|
|
|
7428
8028
|
requiresConfirmation: false,
|
|
7429
8029
|
validators: ['query-context-structured', 'query-context-fields-exist', 'query-context-safe-values', 'editor-runtime-round-trip'],
|
|
7430
8030
|
affectedPaths: ['queryContext'],
|
|
7431
|
-
submissionImpact: '
|
|
8031
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
7432
8032
|
preconditions: ['config-initialized'],
|
|
7433
8033
|
},
|
|
7434
8034
|
{
|
|
@@ -7450,7 +8050,7 @@ const PRAXIS_CHARTS_AUTHORING_MANIFEST = {
|
|
|
7450
8050
|
requiresConfirmation: false,
|
|
7451
8051
|
validators: ['cross-filter-output-structured', 'event-target-governed', 'event-mapping-fields-exist', 'editor-runtime-round-trip'],
|
|
7452
8052
|
affectedPaths: ['chartDocument.events.crossFilter'],
|
|
7453
|
-
submissionImpact: '
|
|
8053
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
7454
8054
|
preconditions: ['config-initialized'],
|
|
7455
8055
|
},
|
|
7456
8056
|
{
|
|
@@ -7487,7 +8087,7 @@ const PRAXIS_CHARTS_AUTHORING_MANIFEST = {
|
|
|
7487
8087
|
requiresConfirmation: false,
|
|
7488
8088
|
validators: ['selection-output-structured', 'event-mapping-fields-exist', 'event-action-supported', 'editor-runtime-round-trip'],
|
|
7489
8089
|
affectedPaths: ['chartDocument.events.selectionChange'],
|
|
7490
|
-
submissionImpact: '
|
|
8090
|
+
submissionImpact: 'affects-schema-backed-data',
|
|
7491
8091
|
preconditions: ['config-initialized'],
|
|
7492
8092
|
},
|
|
7493
8093
|
{
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/charts",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.26",
|
|
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.0-beta.
|
|
8
|
+
"@praxisui/core": "^9.0.0-beta.26",
|
|
9
9
|
"@angular/forms": "^21.0.0",
|
|
10
10
|
"@angular/material": "^21.0.0",
|
|
11
|
-
"@praxisui/table": "^9.0.0-beta.
|
|
11
|
+
"@praxisui/table": "^9.0.0-beta.26",
|
|
12
12
|
"rxjs": "~7.8.0"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
@@ -557,7 +557,37 @@ declare class PraxisMicroVisualizationComponent {
|
|
|
557
557
|
itemPercent(value: PraxisPresentationVisualizationPoint['value']): number;
|
|
558
558
|
segmentPercent(value: PraxisPresentationVisualizationSegment['value']): number;
|
|
559
559
|
valuePercent(value: unknown): number;
|
|
560
|
-
formatNumber(value:
|
|
560
|
+
formatNumber(value: unknown): string;
|
|
561
|
+
readonly radialPercent: _angular_core.Signal<number>;
|
|
562
|
+
readonly radialDashArray: _angular_core.Signal<string>;
|
|
563
|
+
readonly radialText: _angular_core.Signal<string>;
|
|
564
|
+
readonly harveyPercent: _angular_core.Signal<number>;
|
|
565
|
+
readonly harveyDashArray: _angular_core.Signal<string>;
|
|
566
|
+
readonly harveyText: _angular_core.Signal<string>;
|
|
567
|
+
readonly firstPoint: _angular_core.Signal<PraxisPresentationVisualizationPoint | null>;
|
|
568
|
+
readonly lastPoint: _angular_core.Signal<PraxisPresentationVisualizationPoint | null>;
|
|
569
|
+
readonly minPointIndex: _angular_core.Signal<number>;
|
|
570
|
+
readonly maxPointIndex: _angular_core.Signal<number>;
|
|
571
|
+
readonly trendMarkers: _angular_core.Signal<{
|
|
572
|
+
x: number;
|
|
573
|
+
y: number;
|
|
574
|
+
tone?: string;
|
|
575
|
+
label?: string;
|
|
576
|
+
}[]>;
|
|
577
|
+
readonly trendCoords: _angular_core.Signal<{
|
|
578
|
+
x: number;
|
|
579
|
+
y: number;
|
|
580
|
+
}[]>;
|
|
581
|
+
readonly trendPathD: _angular_core.Signal<string>;
|
|
582
|
+
readonly trendAreaD: _angular_core.Signal<string>;
|
|
583
|
+
readonly trendColumns: _angular_core.Signal<{
|
|
584
|
+
x: string;
|
|
585
|
+
y: string;
|
|
586
|
+
width: string;
|
|
587
|
+
height: string;
|
|
588
|
+
tone: _praxisui_core.PraxisPresentationVisualizationTone;
|
|
589
|
+
}[]>;
|
|
590
|
+
readonly processSteps: _angular_core.Signal<_praxisui_core.PraxisPresentationVisualizationItem[]>;
|
|
561
591
|
private resolveBulletMax;
|
|
562
592
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisMicroVisualizationComponent, never>;
|
|
563
593
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisMicroVisualizationComponent, "praxis-micro-visualization", never, { "visualizationInput": { "alias": "visualization"; "required": false; "isSignal": true; }; "fallbackInput": { "alias": "fallbackText"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|