XYChart: Add support for x=time (#106459)
Actionlint / Lint GitHub Actions files (push) Waiting to run Details
Backend Code Checks / Validate Backend Configs (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Backend Unit Tests / Grafana (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Backend Unit Tests / Grafana Enterprise (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Backend Unit Tests / All backend unit tests complete (push) Blocked by required conditions Details
CodeQL checks / Analyze (actions) (push) Waiting to run Details
CodeQL checks / Analyze (go) (push) Waiting to run Details
CodeQL checks / Analyze (javascript) (push) Waiting to run Details
Lint Frontend / Verify i18n (push) Waiting to run Details
Lint Frontend / Lint (push) Waiting to run Details
Lint Frontend / Typecheck (push) Waiting to run Details
Lint Frontend / Betterer (push) Waiting to run Details
Documentation / Build & Verify Docs (push) Waiting to run Details
End-to-end tests / Build & Package Grafana (push) Waiting to run Details
End-to-end tests / Build E2E test runner (push) Waiting to run Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/dashboards-suite, dashboards-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/panels-suite, panels-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/smoke-tests-suite, smoke-tests-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (--flags="--env dashboardScene=false", e2e/old-arch/various-suite, various-suite (old arch)) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/dashboards-suite, dashboards-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/panels-suite, panels-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/smoke-tests-suite, smoke-tests-suite) (push) Blocked by required conditions Details
End-to-end tests / ${{ matrix.suite }} (e2e/various-suite, various-suite) (push) Blocked by required conditions Details
End-to-end tests / All E2E tests complete (push) Blocked by required conditions Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (1) (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (2) (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (3) (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (4) (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (5) (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (6) (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (7) (push) Waiting to run Details
Frontend tests / Unit tests (${{ matrix.chunk }} / 8) (8) (push) Waiting to run Details
Frontend tests / All frontend unit tests complete (push) Blocked by required conditions Details
Integration Tests / Sqlite (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / Sqlite (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / MySQL (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (1/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (2/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (3/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (4/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (5/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (6/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (7/8) (push) Waiting to run Details
Integration Tests / Postgres (${{ matrix.shard }}) (8/8) (push) Waiting to run Details
Integration Tests / All backend integration tests complete (push) Blocked by required conditions Details
publish-technical-documentation-next / sync (push) Waiting to run Details
Reject GitHub secrets / reject-gh-secrets (push) Waiting to run Details
Build Release Packages / setup (push) Waiting to run Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:darwin/amd64, darwin-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:darwin/arm64, darwin-arm64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/amd64,deb:grafana:linux/amd64,rpm:grafana:linux/amd64,docker:grafana:linux/amd64,docker:grafana:linux/amd64:ubuntu,npm:grafana,storybook, linux-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm/v6,deb:grafana:linux/arm/v6, linux-armv6) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm/v7,deb:grafana:linux/arm/v7,docker:grafana:linux/arm/v7,docker:grafana:linux/arm/v7:ubuntu, linux-armv7) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/arm64,deb:grafana:linux/arm64,rpm:grafana:linux/arm64,docker:grafana:linux/arm64,docker:grafana:linux/arm64:ubuntu, linux-arm64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:linux/s390x,deb:grafana:linux/s390x,rpm:grafana:linux/s390x,docker:grafana:linux/s390x,docker:grafana:linux/s390x:ubuntu, linux-s390x) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:windows/amd64,zip:grafana:windows/amd64,msi:grafana:windows/amd64, windows-amd64) (push) Blocked by required conditions Details
Build Release Packages / ${{ needs.setup.outputs.version }} / ${{ matrix.name }} (targz:grafana:windows/arm64,zip:grafana:windows/arm64, windows-arm64) (push) Blocked by required conditions Details
Run dashboard schema v2 e2e / dashboard-schema-v2-e2e (push) Waiting to run Details
Shellcheck / Shellcheck scripts (push) Waiting to run Details
Verify Storybook / Verify Storybook (push) Waiting to run Details
Swagger generated code / Verify committed API specs match (push) Waiting to run Details
Dispatch sync to mirror / dispatch-job (push) Waiting to run Details

* XYChart: Add support for x=time

* prettier

* Add time axis demo to provisioned dashboard for XY

* Add details about time fields to the documentation

---------

Co-authored-by: Kristina Durivage <kristina.durivage@grafana.com>
This commit is contained in:
Leon Sorokin 2025-06-23 18:13:28 -05:00 committed by GitHub
parent 17952d45e4
commit cf8e3bf7d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 1495 additions and 1342 deletions

View File

@ -24,9 +24,8 @@
"editable": true, "editable": true,
"fiscalYearStartMonth": 0, "fiscalYearStartMonth": 0,
"graphTooltip": 0, "graphTooltip": 0,
"id": 1064, "id": 22754,
"links": [], "links": [],
"liveNow": false,
"panels": [ "panels": [
{ {
"datasource": { "datasource": {
@ -44,6 +43,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -65,7 +65,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -154,11 +155,12 @@
} }
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"csvFileName": "automobiles.csv", "csvFileName": "automobiles.csv",
@ -200,6 +202,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -221,7 +224,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -282,11 +286,12 @@
{} {}
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"csvFileName": "weight_height.csv", "csvFileName": "weight_height.csv",
@ -328,6 +333,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -348,7 +354,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -391,11 +398,12 @@
} }
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"datasource": { "datasource": {
@ -427,6 +435,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -448,7 +457,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -503,11 +513,12 @@
} }
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"csvFileName": "flight_info_by_state.csv", "csvFileName": "flight_info_by_state.csv",
@ -538,6 +549,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -559,7 +571,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -648,11 +661,12 @@
} }
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"csvFileName": "automobiles.csv", "csvFileName": "automobiles.csv",
@ -694,6 +708,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -715,7 +730,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -770,11 +786,12 @@
} }
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"csvFileName": "flight_info_by_state.csv", "csvFileName": "flight_info_by_state.csv",
@ -806,6 +823,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -837,7 +855,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
} }
] ]
} }
@ -888,11 +907,12 @@
} }
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"csvFileName": "flight_info_by_state.csv", "csvFileName": "flight_info_by_state.csv",
@ -924,6 +944,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -947,7 +968,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -996,11 +1018,12 @@
} }
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"csvFileName": "flight_info_by_state.csv", "csvFileName": "flight_info_by_state.csv",
@ -1032,6 +1055,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -1053,7 +1077,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -1102,11 +1127,12 @@
} }
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"csvContent": "X,Y\n725.1,435.6\n734.1,497.2\n714.3,527.7\n683.5,548.7\n601.8,594.0\n598.5,621.7\n573.9,644.7\n525.7,695.7\n477.2,732.8\n411.8,755.3\n353.6,758.3\n422.6,736.5\n455.3,724.1\n479.2,699.2\n474.0,673.8\n434.5,662.1\n362.2,679.8\n311.2,698.8\n260.1,728.9\n213.4,771.1\n176.2,818.0\n211.2,742.6\n253.9,707.9\n309.9,668.8\n374.7,643.2\n322.8,629.9\n277.1,607.1\n237.0,616.8\n188.9,613.9\n143.0,594.1\n101.8,566.4\n178.1,590.2\n222.2,575.9\n187.9,549.1\n161.5,517.5\n128.6,506.8\n97.3,488.3\n62.4,436.0\n99.6,473.8\n138.3,477.0\n125.0,396.7\n95.6,359.2\n83.6,322.1\n81.0,289.7\n104.0,343.8\n129.3,358.4\n151.2,291.1\n124.0,242.6\n126.3,170.2\n133.7,212.8\n148.4,243.3\n167.9,262.7\n209.1,205.7\n230.1,150.3\n231.4,120.1\n316.0,120.1\n400.6,120.1\n485.2,120.1\n569.8,120.1\n569.3,166.4\n553.0,205.5\n489.2,265.7\n422.2,309.1\n353.7,343.1\n328.2,386.3\n321.6,432.6\n334.1,473.1\n357.6,500.3\n389.9,508.5\n418.8,479.9\n447.9,413.3\n480.0,379.0\n521.6,354.2\n583.9,351.6\n549.7,357.7\n571.6,376.0\n517.1,380.8\n550.3,393.2\n504.3,402.3\n489.5,425.8\n527.5,425.8\n472.7,457.2\n447.1,523.8\n538.6,435.7\n598.4,403.7\n697.8,349.1\n645.3,390.4\n712.3,373.8\n586.0,424.1\n526.9,463.3\n469.5,538.0\n540.6,477.5\n531.2,528.4\n598.6,460.1\n594.5,509.0\n651.2,460.1\n649.9,502.6\n699.4,446.1\n707.6,477.1\n722.0,442.9", "csvContent": "X,Y\n725.1,435.6\n734.1,497.2\n714.3,527.7\n683.5,548.7\n601.8,594.0\n598.5,621.7\n573.9,644.7\n525.7,695.7\n477.2,732.8\n411.8,755.3\n353.6,758.3\n422.6,736.5\n455.3,724.1\n479.2,699.2\n474.0,673.8\n434.5,662.1\n362.2,679.8\n311.2,698.8\n260.1,728.9\n213.4,771.1\n176.2,818.0\n211.2,742.6\n253.9,707.9\n309.9,668.8\n374.7,643.2\n322.8,629.9\n277.1,607.1\n237.0,616.8\n188.9,613.9\n143.0,594.1\n101.8,566.4\n178.1,590.2\n222.2,575.9\n187.9,549.1\n161.5,517.5\n128.6,506.8\n97.3,488.3\n62.4,436.0\n99.6,473.8\n138.3,477.0\n125.0,396.7\n95.6,359.2\n83.6,322.1\n81.0,289.7\n104.0,343.8\n129.3,358.4\n151.2,291.1\n124.0,242.6\n126.3,170.2\n133.7,212.8\n148.4,243.3\n167.9,262.7\n209.1,205.7\n230.1,150.3\n231.4,120.1\n316.0,120.1\n400.6,120.1\n485.2,120.1\n569.8,120.1\n569.3,166.4\n553.0,205.5\n489.2,265.7\n422.2,309.1\n353.7,343.1\n328.2,386.3\n321.6,432.6\n334.1,473.1\n357.6,500.3\n389.9,508.5\n418.8,479.9\n447.9,413.3\n480.0,379.0\n521.6,354.2\n583.9,351.6\n549.7,357.7\n571.6,376.0\n517.1,380.8\n550.3,393.2\n504.3,402.3\n489.5,425.8\n527.5,425.8\n472.7,457.2\n447.1,523.8\n538.6,435.7\n598.4,403.7\n697.8,349.1\n645.3,390.4\n712.3,373.8\n586.0,424.1\n526.9,463.3\n469.5,538.0\n540.6,477.5\n531.2,528.4\n598.6,460.1\n594.5,509.0\n651.2,460.1\n649.9,502.6\n699.4,446.1\n707.6,477.1\n722.0,442.9",
@ -1138,6 +1164,7 @@
"axisColorMode": "text", "axisColorMode": "text",
"axisLabel": "", "axisLabel": "",
"axisPlacement": "auto", "axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": { "hideFrom": {
"legend": false, "legend": false,
"tooltip": false, "tooltip": false,
@ -1159,7 +1186,8 @@
"mode": "absolute", "mode": "absolute",
"steps": [ "steps": [
{ {
"color": "green" "color": "green",
"value": 0
}, },
{ {
"color": "red", "color": "red",
@ -1268,11 +1296,12 @@
{} {}
], ],
"tooltip": { "tooltip": {
"hideZeros": false,
"mode": "single", "mode": "single",
"sort": "none" "sort": "none"
} }
}, },
"pluginVersion": "11.1.0-pre", "pluginVersion": "12.1.0-pre",
"targets": [ "targets": [
{ {
"alias": "", "alias": "",
@ -1314,10 +1343,123 @@
], ],
"title": "Function Plots", "title": "Function Plots",
"type": "xychart" "type": "xychart"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"fillOpacity": 50,
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"pointShape": "circle",
"pointSize": {
"fixed": 5
},
"pointStrokeWidth": 1,
"scaleDistribution": {
"type": "linear"
},
"show": "points"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 39
},
"id": 15,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"mapping": "auto",
"series": [
{
"frame": {
"matcher": {
"id": "byIndex",
"options": 0
}
},
"x": {
"matcher": {
"id": "byName",
"options": "created_at"
}
}
} }
], ],
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"csvContent": "rating_score,created_at,name\n3.5,2022-01-15 16:52:15,apple juice\n3.5,2022-05-04 15:32:03,beet juice\n4.5,2023-04-08 11:27:23,pineapple juice\n2.5,2024-03-23 15:02:17,cranberry juice\n2.75,2024-12-08 12:49:26,orange juice\n2,2024-12-24 15:31:05,grape juice\n4,2025-01-10 21:30:19,apple juice\n4.75,2025-04-05 14:05:03,tomato juice\n3.5,2025-05-02 16:59:34,pomegranate juice\n4.5,2025-06-01 18:10:25,orange juice",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "XY with time",
"transformations": [
{
"id": "convertFieldType",
"options": {
"conversions": [
{
"dateFormat": "YYYY-MM-DD hh:mm:ss",
"destinationType": "time",
"targetField": "created_at"
}
],
"fields": {}
}
}
],
"type": "xychart"
}
],
"preload": false,
"refresh": "", "refresh": "",
"schemaVersion": 39, "schemaVersion": 41,
"tags": [ "tags": [
"gdev", "gdev",
"panel-tests", "panel-tests",
@ -1335,6 +1477,5 @@
"timezone": "", "timezone": "",
"title": "Panel Tests - XY Chart Demo", "title": "Panel Tests - XY Chart Demo",
"uid": "fdn48fmz8f94wc", "uid": "fdn48fmz8f94wc",
"version": 8, "version": 1
"weekStart": "" }
}

View File

@ -65,7 +65,7 @@ XY charts provide a way to visualize arbitrary x and y values in a graph so that
## Supported data formats ## Supported data formats
You can use any type of tabular data with at least two numeric fields in an xy chart. This type of visualization doesn't require time data. You can use any type of tabular data with at least two numeric fields in an xy chart. The x field can be a time field. This type of visualization doesn't require time data, but it can be used.
## Configuration options ## Configuration options
@ -117,7 +117,7 @@ When you select **Auto** as your series mapping mode, the following options are
| Option | Description | | Option | Description |
| ------ | ----------- | | ------ | ----------- |
| Frame | By default, an xy chart displays all data frames. You can filter to select only one frame. | | Frame | By default, an xy chart displays all data frames. You can filter to select only one frame. |
| [X field](#x-field) | Select which field or fields x represents. By default, this is the first number field in each data frame. For an example of this in **Auto** mode, refer to the [X field section](#x-field). | | [X field](#x-field) | Select which field or fields x represents. By default, this is the first number or time field in each data frame. For an example of this in **Auto** mode, refer to the [X field section](#x-field). |
| [Y field](#y-field) | After the x-field is set, by default, all the remaining number fields in the data frame are designated as the y-fields. You can use this option to explicitly choose which fields to use for y. For more information on how to use this in **Auto** mode, refer to the [Y field section](#y-field). | | [Y field](#y-field) | After the x-field is set, by default, all the remaining number fields in the data frame are designated as the y-fields. You can use this option to explicitly choose which fields to use for y. For more information on how to use this in **Auto** mode, refer to the [Y field section](#y-field). |
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -145,7 +145,7 @@ In **Manual** mode, these fields are required:
#### X field #### X field
In **Auto** series mapping mode, select which field or fields x represents. By default, this is the first number field in each data frame. For example, you enter the following CSV content: In **Auto** series mapping mode, select which field or fields x represents. By default, this is the first number or time field in each data frame. For example, you enter the following CSV content:
| a | b | c | | a | b | c |
| --- | --- | --- | | --- | --- | --- |

View File

@ -8,6 +8,7 @@ import { PlotConfigBuilder } from '../types';
export interface ScaleProps { export interface ScaleProps {
scaleKey: string; scaleKey: string;
isTime?: boolean; isTime?: boolean;
auto?: boolean;
min?: number | null; min?: number | null;
max?: number | null; max?: number | null;
softMin?: number | null; softMin?: number | null;
@ -32,6 +33,7 @@ export class UPlotScaleBuilder extends PlotConfigBuilder<ScaleProps, Scale> {
getConfig(): Scale { getConfig(): Scale {
let { let {
isTime, isTime,
auto,
scaleKey, scaleKey,
min: hardMin, min: hardMin,
max: hardMax, max: hardMax,
@ -256,7 +258,7 @@ export class UPlotScaleBuilder extends PlotConfigBuilder<ScaleProps, Scale> {
return minMax; return minMax;
}; };
let auto = !isTime && !hasFixedRange; auto ??= !isTime && !hasFixedRange;
if (isBooleanUnit(scaleKey)) { if (isBooleanUnit(scaleKey)) {
auto = false; auto = false;

View File

@ -182,10 +182,11 @@ export const SeriesEditor = ({
filter: (field) => filter: (field) =>
(mapping === SeriesMapping.Auto || (mapping === SeriesMapping.Auto ||
field.state?.origin?.frameIndex === series.frame?.matcher.options) && field.state?.origin?.frameIndex === series.frame?.matcher.options) &&
field.type === FieldType.number && (field.type === FieldType.number || field.type === FieldType.time) &&
!field.config.custom?.hideFrom?.viz, !field.config.custom?.hideFrom?.viz,
baseNameMode, baseNameMode,
placeholderText: mapping === SeriesMapping.Auto ? 'First number field in each frame' : undefined, placeholderText:
mapping === SeriesMapping.Auto ? 'First number or time field in each frame' : undefined,
}, },
}} }}
/> />

View File

@ -298,6 +298,7 @@ export const prepConfig = (xySeries: XYSeries[], theme: GrafanaTheme2) => {
builder.setMode(2); builder.setMode(2);
let xField = xySeries[0].x.field; let xField = xySeries[0].x.field;
let xIsTime = xField.type === FieldType.time;
let fieldConfig = xField.config; let fieldConfig = xField.config;
let customConfig = fieldConfig.custom; let customConfig = fieldConfig.custom;
@ -305,7 +306,8 @@ export const prepConfig = (xySeries: XYSeries[], theme: GrafanaTheme2) => {
builder.addScale({ builder.addScale({
scaleKey: 'x', scaleKey: 'x',
isTime: false, isTime: xIsTime,
auto: true,
orientation: ScaleOrientation.Horizontal, orientation: ScaleOrientation.Horizontal,
direction: ScaleDirection.Right, direction: ScaleDirection.Right,
distribution: scaleDistr?.type, distribution: scaleDistr?.type,
@ -317,6 +319,7 @@ export const prepConfig = (xySeries: XYSeries[], theme: GrafanaTheme2) => {
softMax: customConfig?.axisSoftMax, softMax: customConfig?.axisSoftMax,
centeredZero: customConfig?.axisCenteredZero, centeredZero: customConfig?.axisCenteredZero,
decimals: fieldConfig.decimals, decimals: fieldConfig.decimals,
range: xIsTime ? (u, min, max) => [min, max] : undefined,
}); });
// why does this fall back to '' instead of null or undef? // why does this fall back to '' instead of null or undef?
@ -339,13 +342,14 @@ export const prepConfig = (xySeries: XYSeries[], theme: GrafanaTheme2) => {
builder.addAxis({ builder.addAxis({
scaleKey: 'x', scaleKey: 'x',
isTime: xIsTime,
placement: customConfig?.axisPlacement !== AxisPlacement.Hidden ? AxisPlacement.Bottom : AxisPlacement.Hidden, placement: customConfig?.axisPlacement !== AxisPlacement.Hidden ? AxisPlacement.Bottom : AxisPlacement.Hidden,
show: customConfig?.axisPlacement !== AxisPlacement.Hidden, show: customConfig?.axisPlacement !== AxisPlacement.Hidden,
grid: { show: customConfig?.axisGridShow }, grid: { show: customConfig?.axisGridShow },
border: { show: customConfig?.axisBorderShow }, border: { show: customConfig?.axisBorderShow },
theme, theme,
label: xAxisLabel, label: xAxisLabel,
formatValue: (v, decimals) => formattedValueToString(xField.display!(v, decimals)), formatValue: xIsTime ? undefined : (v, decimals) => formattedValueToString(xField.display!(v, decimals)),
}); });
xySeries.forEach((s, si) => { xySeries.forEach((s, si) => {

View File

@ -62,8 +62,8 @@ export function prepSeries(
let xMatcher = getFieldMatcher( let xMatcher = getFieldMatcher(
seriesCfg.x?.matcher ?? { seriesCfg.x?.matcher ?? {
id: FieldMatcherID.byType, id: FieldMatcherID.byTypes,
options: 'number', options: new Set(['number', 'time']),
} }
); );
let yMatcher = getFieldMatcher( let yMatcher = getFieldMatcher(
@ -89,11 +89,16 @@ export function prepSeries(
let frameSeries: XYSeries[] = []; let frameSeries: XYSeries[] = [];
// only grabbing number fields (exclude time, string, enum, other) let onlyNumTimeFields = frame.fields.filter(
let onlyNumFields = frame.fields.filter((field) => field.type === FieldType.number); (field) => field.type === FieldType.number || field.type === FieldType.time
);
// only one of these per frame // only one of these per frame
let x = onlyNumFields.find((field) => xMatcher(field, frame, frames)); let x = onlyNumTimeFields.find((field) => xMatcher(field, frame, frames));
// only grabbing number fields (exclude time, string, enum, other)
let onlyNumFields = onlyNumTimeFields.filter((field) => field.type === FieldType.number);
let color = let color =
colorMatcher != null colorMatcher != null
? onlyNumFields.find((field) => field !== x && colorMatcher!(field, frame, frames)) ? onlyNumFields.find((field) => field !== x && colorMatcher!(field, frame, frames))