NewGauge: Adds scale labels (threshold labels) (#112517)
* Progress on scale label * Progress * Progress on labels * Progress * fix for segments * Update * Fix * Update * Some basic unit tests * fixes * fixes
This commit is contained in:
Vendored
+305
-15
@@ -91,6 +91,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -171,6 +172,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -251,6 +253,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -331,6 +334,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -411,6 +415,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": true
|
||||
},
|
||||
@@ -491,6 +496,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -571,6 +577,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -664,6 +671,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -744,6 +752,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -824,6 +833,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -904,6 +914,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1001,6 +1012,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1079,8 +1091,9 @@
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 37,
|
||||
"segmentSpacing": 0.19,
|
||||
"segmentSpacing": 0.31,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1159,8 +1172,9 @@
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 46,
|
||||
"segmentSpacing": 0.19,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1219,10 +1233,10 @@
|
||||
"x": 0,
|
||||
"y": 27
|
||||
},
|
||||
"id": 27,
|
||||
"id": 30,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"barWidthFactor": 0.43,
|
||||
"barWidthFactor": 0.9,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
@@ -1239,8 +1253,9 @@
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.19,
|
||||
"shape": "circle",
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1257,7 +1272,7 @@
|
||||
"stringInput": "1,20,90,30,5,70"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds circle",
|
||||
"title": "Plain thresholds",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
@@ -1319,8 +1334,9 @@
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 62,
|
||||
"segmentSpacing": 0.19,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1348,6 +1364,274 @@
|
||||
"x": 0,
|
||||
"y": 34
|
||||
},
|
||||
"id": 31,
|
||||
"panels": [],
|
||||
"title": "Threshold labels",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "semi-dark-yellow",
|
||||
"value": 40
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 65
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 85
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 7,
|
||||
"x": 0,
|
||||
"y": 35
|
||||
},
|
||||
"id": 32,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"barWidthFactor": 0.9,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
},
|
||||
"gradient": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 62,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": true,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
"pluginVersion": "12.2.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "1",
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,70"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds labels",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "semi-dark-yellow",
|
||||
"value": 40
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 65
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 85
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 7,
|
||||
"x": 7,
|
||||
"y": 35
|
||||
},
|
||||
"id": 34,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"barWidthFactor": 0.9,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
},
|
||||
"gradient": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 62,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": true,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
"pluginVersion": "12.2.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "1",
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,70"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds labels only",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "semi-dark-yellow",
|
||||
"value": 40
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 65
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 85
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 6,
|
||||
"x": 14,
|
||||
"y": 35
|
||||
},
|
||||
"id": 33,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"barWidthFactor": 0.9,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
},
|
||||
"gradient": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 80,
|
||||
"segmentSpacing": 0.59,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": true,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
"pluginVersion": "12.2.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "1",
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,70"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds labels + circle",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 45
|
||||
},
|
||||
"id": 6,
|
||||
"panels": [],
|
||||
"title": "Gradient modes",
|
||||
@@ -1389,7 +1673,7 @@
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 35
|
||||
"y": 46
|
||||
},
|
||||
"id": 9,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1415,6 +1699,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1476,7 +1761,7 @@
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 41
|
||||
"y": 52
|
||||
},
|
||||
"id": 11,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1502,6 +1787,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": true,
|
||||
"spotlight": true
|
||||
@@ -1533,7 +1819,7 @@
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 47
|
||||
"y": 58
|
||||
},
|
||||
"id": 12,
|
||||
"panels": [],
|
||||
@@ -1577,7 +1863,7 @@
|
||||
"h": 7,
|
||||
"w": 4,
|
||||
"x": 0,
|
||||
"y": 48
|
||||
"y": 59
|
||||
},
|
||||
"id": 13,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1603,6 +1889,7 @@
|
||||
"segmentCount": 8,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1665,7 +1952,7 @@
|
||||
"h": 7,
|
||||
"w": 5,
|
||||
"x": 4,
|
||||
"y": 48
|
||||
"y": 59
|
||||
},
|
||||
"id": 14,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1692,6 +1979,7 @@
|
||||
"segmentCount": 12,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1753,7 +2041,7 @@
|
||||
"h": 7,
|
||||
"w": 5,
|
||||
"x": 9,
|
||||
"y": 48
|
||||
"y": 59
|
||||
},
|
||||
"id": 15,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1779,6 +2067,7 @@
|
||||
"segmentCount": 39,
|
||||
"segmentSpacing": 0.76,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1840,7 +2129,7 @@
|
||||
"h": 7,
|
||||
"w": 6,
|
||||
"x": 14,
|
||||
"y": 48
|
||||
"y": 59
|
||||
},
|
||||
"id": 16,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1866,6 +2155,7 @@
|
||||
"segmentCount": 81,
|
||||
"segmentSpacing": 0.28,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -167,6 +168,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -245,6 +247,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -323,6 +326,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -401,6 +405,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": true
|
||||
},
|
||||
@@ -479,6 +484,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -557,6 +563,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -648,6 +655,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -726,6 +734,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -804,6 +813,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -882,6 +892,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -977,6 +988,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1053,8 +1065,9 @@
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 37,
|
||||
"segmentSpacing": 0.19,
|
||||
"segmentSpacing": 0.31,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1131,8 +1144,9 @@
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 46,
|
||||
"segmentSpacing": 0.19,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1191,10 +1205,10 @@
|
||||
"x": 0,
|
||||
"y": 27
|
||||
},
|
||||
"id": 27,
|
||||
"id": 30,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"barWidthFactor": 0.43,
|
||||
"barWidthFactor": 0.9,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
@@ -1209,8 +1223,9 @@
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.19,
|
||||
"shape": "circle",
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1227,7 +1242,7 @@
|
||||
"stringInput": "1,20,90,30,5,70"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds circle",
|
||||
"title": "Plain thresholds",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
@@ -1287,8 +1302,9 @@
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 62,
|
||||
"segmentSpacing": 0.19,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
@@ -1316,6 +1332,268 @@
|
||||
"x": 0,
|
||||
"y": 34
|
||||
},
|
||||
"id": 31,
|
||||
"panels": [],
|
||||
"title": "Threshold labels",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "semi-dark-yellow",
|
||||
"value": 40
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 65
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 85
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 7,
|
||||
"x": 0,
|
||||
"y": 35
|
||||
},
|
||||
"id": 32,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"barWidthFactor": 0.9,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
},
|
||||
"gradient": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 62,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": true,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
"pluginVersion": "12.2.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "1",
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,70"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds labels",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "semi-dark-yellow",
|
||||
"value": 40
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 65
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 85
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 7,
|
||||
"x": 7,
|
||||
"y": 35
|
||||
},
|
||||
"id": 34,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"barWidthFactor": 0.9,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
},
|
||||
"gradient": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 62,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": true,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false
|
||||
},
|
||||
"pluginVersion": "12.2.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "1",
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,70"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds labels only",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "semi-dark-yellow",
|
||||
"value": 40
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 65
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 85
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 10,
|
||||
"w": 6,
|
||||
"x": 14,
|
||||
"y": 35
|
||||
},
|
||||
"id": 33,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"barWidthFactor": 0.9,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
},
|
||||
"gradient": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"segmentCount": 80,
|
||||
"segmentSpacing": 0.59,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": true,
|
||||
"showThresholdMarkers": true,
|
||||
"sparkline": false
|
||||
},
|
||||
"pluginVersion": "12.2.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "1",
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource",
|
||||
"uid": "PD8C576611E62080A"
|
||||
},
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,70"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds labels + circle",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 45
|
||||
},
|
||||
"id": 6,
|
||||
"panels": [],
|
||||
"title": "Gradient modes",
|
||||
@@ -1357,7 +1635,7 @@
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 35
|
||||
"y": 46
|
||||
},
|
||||
"id": 9,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1381,6 +1659,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1442,7 +1721,7 @@
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 41
|
||||
"y": 52
|
||||
},
|
||||
"id": 11,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1466,6 +1745,7 @@
|
||||
"segmentCount": 1,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "gauge",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": true,
|
||||
"spotlight": true
|
||||
@@ -1497,7 +1777,7 @@
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 47
|
||||
"y": 58
|
||||
},
|
||||
"id": 12,
|
||||
"panels": [],
|
||||
@@ -1541,7 +1821,7 @@
|
||||
"h": 7,
|
||||
"w": 4,
|
||||
"x": 0,
|
||||
"y": 48
|
||||
"y": 59
|
||||
},
|
||||
"id": 13,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1565,6 +1845,7 @@
|
||||
"segmentCount": 8,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1627,7 +1908,7 @@
|
||||
"h": 7,
|
||||
"w": 5,
|
||||
"x": 4,
|
||||
"y": 48
|
||||
"y": 59
|
||||
},
|
||||
"id": 14,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1652,6 +1933,7 @@
|
||||
"segmentCount": 12,
|
||||
"segmentSpacing": 0.3,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1713,7 +1995,7 @@
|
||||
"h": 7,
|
||||
"w": 5,
|
||||
"x": 9,
|
||||
"y": 48
|
||||
"y": 59
|
||||
},
|
||||
"id": 15,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1737,6 +2019,7 @@
|
||||
"segmentCount": 39,
|
||||
"segmentSpacing": 0.76,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1798,7 +2081,7 @@
|
||||
"h": 7,
|
||||
"w": 6,
|
||||
"x": 14,
|
||||
"y": 48
|
||||
"y": 59
|
||||
},
|
||||
"id": 16,
|
||||
"maxDataPoints": 20,
|
||||
@@ -1822,6 +2105,7 @@
|
||||
"segmentCount": 81,
|
||||
"segmentSpacing": 0.28,
|
||||
"shape": "circle",
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": false,
|
||||
"sparkline": false,
|
||||
"spotlight": true
|
||||
@@ -1862,5 +2146,5 @@
|
||||
"timezone": "browser",
|
||||
"title": "Panel tests - Gauge (new)",
|
||||
"uid": "panel-tests-gauge-new",
|
||||
"version": 1
|
||||
"version": 6
|
||||
}
|
||||
|
||||
+2
@@ -33,6 +33,7 @@ export interface Options extends common.SingleStatBaseOptions {
|
||||
segmentCount: number;
|
||||
segmentSpacing: number;
|
||||
shape: ('circle' | 'gauge');
|
||||
showThresholdLabels: boolean;
|
||||
showThresholdMarkers: boolean;
|
||||
sparkline?: boolean;
|
||||
}
|
||||
@@ -44,6 +45,7 @@ export const defaultOptions: Partial<Options> = {
|
||||
segmentCount: 1,
|
||||
segmentSpacing: 0.3,
|
||||
shape: 'gauge',
|
||||
showThresholdLabels: false,
|
||||
showThresholdMarkers: true,
|
||||
sparkline: false,
|
||||
};
|
||||
|
||||
@@ -484,6 +484,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
overflow: 'hidden',
|
||||
|
||||
'.always-show': {
|
||||
background: 'none',
|
||||
|
||||
@@ -40,7 +40,7 @@ export function RadialBarSegmented({
|
||||
const angleValue = ((max - min) / segmentCountAdjusted) * i;
|
||||
const angleColor = colorDefs.getSegmentColor(angleValue);
|
||||
const segmentAngle = startAngle + (angleRange / segmentCountAdjusted) * i + 0.01;
|
||||
const segmentColor = angleValue > value ? theme.colors.action.hover : angleColor;
|
||||
const segmentColor = angleValue >= value ? theme.colors.action.hover : angleColor;
|
||||
|
||||
segments.push(
|
||||
<RadialArcPath
|
||||
@@ -65,7 +65,7 @@ export function RadialBarSegmented({
|
||||
export function getAngleBetweenSegments(segmentSpacing: number, segmentCount: number, range: number) {
|
||||
// Max spacing is 8 degrees between segments
|
||||
// Changing this constant could be considered a breaking change
|
||||
const maxAngleBetweenSegments = Math.max(range / 4 / segmentCount, 2);
|
||||
const maxAngleBetweenSegments = Math.max(range / 1.5 / segmentCount, 2);
|
||||
return segmentSpacing * maxAngleBetweenSegments;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface RadialColorDefsOptions {
|
||||
displayProcessor: DisplayProcessor;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-prefer-function-component/react-prefer-function-component
|
||||
export class RadialColorDefs {
|
||||
private colorToIds: Record<string, string> = {};
|
||||
private defs: React.ReactNode[] = [];
|
||||
|
||||
@@ -45,7 +45,7 @@ const meta: Meta<StoryProps> = {
|
||||
gradient: 'none',
|
||||
seriesCount: 1,
|
||||
segmentCount: 0,
|
||||
segmentSpacing: 0.4,
|
||||
segmentSpacing: 0.2,
|
||||
roundedBars: false,
|
||||
thresholdsBar: false,
|
||||
colorScheme: FieldColorModeId.Thresholds,
|
||||
@@ -97,28 +97,69 @@ export const Basic: StoryFn<StoryProps> = (args) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const Examples: StoryFn = (args) => {
|
||||
export const Examples: StoryFn<StoryProps> = (args) => {
|
||||
return (
|
||||
<Stack direction={'column'} gap={3} wrap="wrap">
|
||||
<div>Bar width</div>
|
||||
<Stack direction="row" alignItems="center" gap={3} wrap="wrap">
|
||||
<RadialGaugeExample seriesName="0.1" value={60} color="blue" barWidthFactor={0.1} />
|
||||
<RadialGaugeExample seriesName="0.4" value={60} color="green" barWidthFactor={0.4} />
|
||||
<RadialGaugeExample seriesName="0.6" value={60} color="red" barWidthFactor={0.6} />
|
||||
<RadialGaugeExample seriesName="0.8" value={60} color="purple" barWidthFactor={0.8} />
|
||||
<RadialGaugeExample
|
||||
seriesName="0.1"
|
||||
value={args.value ?? 30}
|
||||
color="blue"
|
||||
gradient="auto"
|
||||
barWidthFactor={0.1}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
seriesName="0.4"
|
||||
value={args.value ?? 40}
|
||||
color="green"
|
||||
gradient="auto"
|
||||
barWidthFactor={0.4}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
seriesName="0.6"
|
||||
value={args.value ?? 60}
|
||||
color="red"
|
||||
gradient="auto"
|
||||
barWidthFactor={0.6}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
seriesName="0.8"
|
||||
value={args.value ?? 70}
|
||||
color="purple"
|
||||
gradient="auto"
|
||||
barWidthFactor={0.8}
|
||||
/>
|
||||
</Stack>
|
||||
<div>Effects</div>
|
||||
<Stack direction="row" alignItems="center" gap={3} wrap="wrap">
|
||||
<RadialGaugeExample value={30} spotlight glowBar glowCenter color="blue" gradient="auto" />
|
||||
<RadialGaugeExample value={40} spotlight glowBar glowCenter color="green" gradient="auto" />
|
||||
<RadialGaugeExample value={60} spotlight glowBar glowCenter color="red" gradient="auto" roundedBars />
|
||||
<RadialGaugeExample value={70} spotlight glowBar glowCenter color="purple" gradient="auto" roundedBars />
|
||||
<RadialGaugeExample value={args.value ?? 30} spotlight glowBar glowCenter color="blue" gradient="auto" />
|
||||
<RadialGaugeExample value={args.value ?? 40} spotlight glowBar glowCenter color="green" gradient="auto" />
|
||||
<RadialGaugeExample
|
||||
value={args.value ?? 60}
|
||||
spotlight
|
||||
glowBar
|
||||
glowCenter
|
||||
color="red"
|
||||
gradient="auto"
|
||||
roundedBars
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={args.value ?? 70}
|
||||
spotlight
|
||||
glowBar
|
||||
glowCenter
|
||||
color="purple"
|
||||
gradient="auto"
|
||||
roundedBars
|
||||
/>
|
||||
</Stack>
|
||||
<div>Shape: Gauge & color scale</div>
|
||||
<Stack direction="row" alignItems="center" gap={3} wrap="wrap">
|
||||
<RadialGaugeExample
|
||||
value={40}
|
||||
shape="gauge"
|
||||
width={250}
|
||||
gradient="auto"
|
||||
colorScheme={FieldColorModeId.ContinuousGrYlRd}
|
||||
glowCenter={true}
|
||||
@@ -127,6 +168,7 @@ export const Examples: StoryFn = (args) => {
|
||||
<RadialGaugeExample
|
||||
colorScheme={FieldColorModeId.ContinuousGrYlRd}
|
||||
gradient="auto"
|
||||
width={250}
|
||||
value={90}
|
||||
barWidthFactor={0.6}
|
||||
roundedBars={false}
|
||||
@@ -138,10 +180,9 @@ export const Examples: StoryFn = (args) => {
|
||||
<div>Sparklines</div>
|
||||
<Stack direction={'row'} gap={3}>
|
||||
<RadialGaugeExample
|
||||
value={70}
|
||||
value={args.value ?? 70}
|
||||
color="blue"
|
||||
shape="gauge"
|
||||
{...args}
|
||||
gradient="auto"
|
||||
sparkline={true}
|
||||
spotlight
|
||||
@@ -150,10 +191,9 @@ export const Examples: StoryFn = (args) => {
|
||||
barWidthFactor={0.2}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={30}
|
||||
value={args.value ?? 30}
|
||||
color="green"
|
||||
shape="gauge"
|
||||
{...args}
|
||||
gradient="auto"
|
||||
sparkline={true}
|
||||
spotlight
|
||||
@@ -162,9 +202,8 @@ export const Examples: StoryFn = (args) => {
|
||||
barWidthFactor={0.8}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={50}
|
||||
value={args.value ?? 50}
|
||||
color="red"
|
||||
{...args}
|
||||
shape="gauge"
|
||||
width={250}
|
||||
gradient="auto"
|
||||
@@ -175,9 +214,8 @@ export const Examples: StoryFn = (args) => {
|
||||
barWidthFactor={0.2}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={50}
|
||||
value={args.value ?? 50}
|
||||
color="red"
|
||||
{...args}
|
||||
width={250}
|
||||
shape="gauge"
|
||||
gradient="auto"
|
||||
@@ -191,39 +229,36 @@ export const Examples: StoryFn = (args) => {
|
||||
<div>Segmented</div>
|
||||
<Stack direction={'row'} gap={3}>
|
||||
<RadialGaugeExample
|
||||
value={70}
|
||||
value={args.value ?? 70}
|
||||
color="green"
|
||||
{...args}
|
||||
gradient="auto"
|
||||
glowCenter={true}
|
||||
segmentCount={8}
|
||||
segmentSpacing={0.1}
|
||||
barWidthFactor={0.4}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={30}
|
||||
color="green"
|
||||
{...args}
|
||||
value={args.value ?? 30}
|
||||
color="purple"
|
||||
gradient="auto"
|
||||
segmentCount={20}
|
||||
segmentCount={30}
|
||||
glowCenter={true}
|
||||
barWidthFactor={0.5}
|
||||
barWidthFactor={0.6}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={50}
|
||||
value={args.value ?? 50}
|
||||
color="red"
|
||||
{...args}
|
||||
gradient="auto"
|
||||
segmentCount={40}
|
||||
glowCenter={true}
|
||||
barWidthFactor={0.7}
|
||||
segmentSpacing={0.4}
|
||||
barWidthFactor={1}
|
||||
segmentSpacing={0.6}
|
||||
/>
|
||||
</Stack>
|
||||
<div>Segmented color scale</div>
|
||||
<Stack direction={'row'} gap={3}>
|
||||
<RadialGaugeExample
|
||||
value={70}
|
||||
{...args}
|
||||
value={args.value ?? 80}
|
||||
colorScheme={FieldColorModeId.ContinuousGrYlRd}
|
||||
spotlight
|
||||
glowBar={true}
|
||||
@@ -232,24 +267,25 @@ export const Examples: StoryFn = (args) => {
|
||||
barWidthFactor={0.4}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={70}
|
||||
{...args}
|
||||
value={args.value ?? 80}
|
||||
width={250}
|
||||
colorScheme={FieldColorModeId.ContinuousGrYlRd}
|
||||
spotlight
|
||||
shape="gauge"
|
||||
gradient="auto"
|
||||
glowBar={true}
|
||||
glowCenter={true}
|
||||
segmentCount={20}
|
||||
barWidthFactor={0.4}
|
||||
segmentCount={40}
|
||||
segmentSpacing={0.5}
|
||||
barWidthFactor={0.8}
|
||||
/>
|
||||
</Stack>
|
||||
<div>Thresholds</div>
|
||||
<Stack direction={'row'} gap={3}>
|
||||
<RadialGaugeExample
|
||||
value={70}
|
||||
{...args}
|
||||
value={args.value ?? 70}
|
||||
colorScheme={FieldColorModeId.Thresholds}
|
||||
gradient="auto"
|
||||
thresholdsBar={true}
|
||||
roundedBars={false}
|
||||
spotlight
|
||||
@@ -257,10 +293,10 @@ export const Examples: StoryFn = (args) => {
|
||||
barWidthFactor={0.7}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={70}
|
||||
{...args}
|
||||
value={args.value ?? 70}
|
||||
width={250}
|
||||
colorScheme={FieldColorModeId.Thresholds}
|
||||
gradient="auto"
|
||||
glowCenter={true}
|
||||
thresholdsBar={true}
|
||||
roundedBars={false}
|
||||
@@ -268,14 +304,15 @@ export const Examples: StoryFn = (args) => {
|
||||
barWidthFactor={0.7}
|
||||
/>
|
||||
<RadialGaugeExample
|
||||
value={70}
|
||||
{...args}
|
||||
value={args.value ?? 70}
|
||||
width={250}
|
||||
colorScheme={FieldColorModeId.Thresholds}
|
||||
gradient="auto"
|
||||
glowCenter={true}
|
||||
thresholdsBar={true}
|
||||
roundedBars={false}
|
||||
segmentCount={40}
|
||||
segmentSpacing={0.2}
|
||||
segmentSpacing={0.3}
|
||||
shape="gauge"
|
||||
barWidthFactor={0.7}
|
||||
/>
|
||||
@@ -340,6 +377,7 @@ interface ExampleProps {
|
||||
thresholdsBar?: boolean;
|
||||
colorScheme?: FieldColorModeId;
|
||||
decimals?: number;
|
||||
showScaleLabels?: boolean;
|
||||
}
|
||||
|
||||
export function RadialGaugeExample({
|
||||
@@ -366,6 +404,7 @@ export function RadialGaugeExample({
|
||||
thresholdsBar = false,
|
||||
colorScheme = FieldColorModeId.Thresholds,
|
||||
decimals = 0,
|
||||
showScaleLabels,
|
||||
}: ExampleProps) {
|
||||
const theme = useTheme2();
|
||||
|
||||
@@ -450,6 +489,7 @@ export function RadialGaugeExample({
|
||||
segmentSpacing={segmentSpacing}
|
||||
roundedBars={roundedBars}
|
||||
thresholdsBar={thresholdsBar}
|
||||
showScaleLabels={showScaleLabels}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,4 +8,11 @@ describe('RadialGauge', () => {
|
||||
|
||||
expect(screen.getByRole('img')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render threshold labels', () => {
|
||||
render(<RadialGaugeExample showScaleLabels={true} />);
|
||||
|
||||
expect(screen.getByRole('img')).toBeInTheDocument();
|
||||
expect(screen.getByLabelText('Threshold 85')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,10 +6,12 @@ import { DisplayValueAlignmentFactors, FieldDisplay, getDisplayProcessor, Grafan
|
||||
import { t } from '@grafana/i18n';
|
||||
|
||||
import { useStyles2, useTheme2 } from '../../themes/ThemeContext';
|
||||
import { getFormattedThresholds } from '../Gauge/utils';
|
||||
|
||||
import { RadialBar } from './RadialBar';
|
||||
import { RadialBarSegmented } from './RadialBarSegmented';
|
||||
import { RadialColorDefs } from './RadialColorDefs';
|
||||
import { RadialScaleLabels } from './RadialScaleLabels';
|
||||
import { RadialSparkline } from './RadialSparkline';
|
||||
import { RadialText } from './RadialText';
|
||||
import { ThresholdsBar } from './ThresholdsBar';
|
||||
@@ -61,6 +63,7 @@ export interface RadialGaugeProps {
|
||||
nameManualFontSize?: number;
|
||||
/** Specify which text should be visible */
|
||||
textMode?: RadialTextMode;
|
||||
showScaleLabels?: boolean;
|
||||
}
|
||||
|
||||
export type RadialGradientMode = 'none' | 'auto';
|
||||
@@ -83,6 +86,7 @@ export function RadialGauge(props: RadialGaugeProps) {
|
||||
segmentSpacing = 0.1,
|
||||
roundedBars = true,
|
||||
thresholdsBar = false,
|
||||
showScaleLabels = false,
|
||||
values,
|
||||
} = props;
|
||||
const theme = useTheme2();
|
||||
@@ -108,7 +112,8 @@ export function RadialGauge(props: RadialGaugeProps) {
|
||||
roundedBars,
|
||||
barWidthFactor,
|
||||
barIndex,
|
||||
thresholdsBar
|
||||
thresholdsBar,
|
||||
showScaleLabels
|
||||
);
|
||||
|
||||
const displayProcessor = getFieldDisplayProcessor(displayValue);
|
||||
@@ -177,22 +182,6 @@ export function RadialGauge(props: RadialGaugeProps) {
|
||||
graphics.push(<MiddleCircleGlow key="center-glow" gaugeId={gaugeId} color={color} dimensions={dimensions} />);
|
||||
}
|
||||
|
||||
if (thresholdsBar) {
|
||||
graphics.push(
|
||||
<ThresholdsBar
|
||||
key="thresholds-bar"
|
||||
dimensions={dimensions}
|
||||
fieldDisplay={displayValue}
|
||||
startAngle={startAngle}
|
||||
endAngle={endAngle}
|
||||
angleRange={angleRange}
|
||||
roundedBars={roundedBars}
|
||||
glowFilter={`url(#${glowFilterId})`}
|
||||
colorDefs={colorDefs}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
graphics.push(
|
||||
<RadialText
|
||||
key="radial-text"
|
||||
@@ -207,6 +196,43 @@ export function RadialGauge(props: RadialGaugeProps) {
|
||||
/>
|
||||
);
|
||||
|
||||
if (showScaleLabels || thresholdsBar) {
|
||||
const decimals = displayValue.field.decimals ?? 2;
|
||||
const thresholds = getFormattedThresholds(decimals, displayValue.field, theme);
|
||||
|
||||
if (showScaleLabels) {
|
||||
graphics.push(
|
||||
<RadialScaleLabels
|
||||
key="radial-scale-labels"
|
||||
thresholds={thresholds}
|
||||
fieldDisplay={displayValue}
|
||||
angleRange={angleRange}
|
||||
theme={theme}
|
||||
dimensions={dimensions}
|
||||
startAngle={startAngle}
|
||||
endAngle={endAngle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (thresholdsBar) {
|
||||
graphics.push(
|
||||
<ThresholdsBar
|
||||
key="thresholds-bar"
|
||||
thresholds={thresholds}
|
||||
dimensions={dimensions}
|
||||
fieldDisplay={displayValue}
|
||||
startAngle={startAngle}
|
||||
endAngle={endAngle}
|
||||
angleRange={angleRange}
|
||||
roundedBars={roundedBars}
|
||||
glowFilter={`url(#${glowFilterId})`}
|
||||
colorDefs={colorDefs}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (displayValue.sparkline) {
|
||||
sparklineElement = (
|
||||
<RadialSparkline
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import { FieldDisplay, GrafanaTheme2, Threshold } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
|
||||
import { measureText } from '../../utils/measureText';
|
||||
|
||||
import { GaugeDimensions, toCartesian } from './utils';
|
||||
|
||||
interface RadialScaleLabelsProps {
|
||||
fieldDisplay: FieldDisplay;
|
||||
theme: GrafanaTheme2;
|
||||
thresholds: Threshold[];
|
||||
dimensions: GaugeDimensions;
|
||||
startAngle: number;
|
||||
endAngle: number;
|
||||
angleRange: number;
|
||||
}
|
||||
|
||||
export function RadialScaleLabels({
|
||||
fieldDisplay,
|
||||
thresholds,
|
||||
theme,
|
||||
dimensions,
|
||||
startAngle,
|
||||
endAngle,
|
||||
angleRange,
|
||||
}: RadialScaleLabelsProps) {
|
||||
const { centerX, centerY, scaleLabelsFontSize, scaleLabelsRadius } = dimensions;
|
||||
|
||||
const fieldConfig = fieldDisplay.field;
|
||||
const min = fieldConfig.min ?? 0;
|
||||
const max = fieldConfig.max ?? 100;
|
||||
|
||||
const fontSize = scaleLabelsFontSize;
|
||||
const textLineHeight = scaleLabelsFontSize * 1.2;
|
||||
const radius = scaleLabelsRadius - textLineHeight;
|
||||
|
||||
function getTextPosition(text: string, value: number, index: number) {
|
||||
const isLast = index === thresholds.length - 1;
|
||||
const isFirst = index === 0;
|
||||
|
||||
let valueDeg = ((value - min) / (max - min)) * angleRange;
|
||||
let finalAngle = startAngle + valueDeg;
|
||||
|
||||
// Now adjust the final angle based on the label text width and the labels position on the arc
|
||||
let measure = measureText(text, fontSize, theme.typography.fontWeightMedium);
|
||||
let textWidthAngle = (measure.width / (2 * Math.PI * radius)) * angleRange;
|
||||
|
||||
// the centering is different for gauge or circle shapes for some reason
|
||||
finalAngle -= endAngle < 180 ? textWidthAngle : textWidthAngle / 2;
|
||||
|
||||
// For circle gauges we need to shift the first label more
|
||||
if (isFirst) {
|
||||
finalAngle += textWidthAngle;
|
||||
}
|
||||
|
||||
// For circle gauges we need to shift the last label more
|
||||
if (isLast && endAngle === 360) {
|
||||
finalAngle -= textWidthAngle;
|
||||
}
|
||||
|
||||
const position = toCartesian(centerX, centerY, radius, finalAngle);
|
||||
|
||||
return { ...position, transform: `rotate(${finalAngle}, ${position.x}, ${position.y})` };
|
||||
}
|
||||
|
||||
return (
|
||||
<g>
|
||||
{thresholds.map((threshold, index) => {
|
||||
const labelPos = getTextPosition(String(threshold.value), threshold.value, index);
|
||||
|
||||
return (
|
||||
<text
|
||||
key={index}
|
||||
x={labelPos.x}
|
||||
y={labelPos.y}
|
||||
fontSize={fontSize}
|
||||
fill={theme.colors.text.primary}
|
||||
transform={labelPos.transform}
|
||||
aria-label={t(`gauge.threshold`, 'Threshold {{value}}', { value: threshold.value })}
|
||||
>
|
||||
{threshold.value}
|
||||
</text>
|
||||
);
|
||||
})}
|
||||
</g>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
import { FieldDisplay } from '@grafana/data';
|
||||
|
||||
import { useTheme2 } from '../../themes/ThemeContext';
|
||||
import { getFormattedThresholds } from '../Gauge/utils';
|
||||
import { FieldDisplay, Threshold } from '@grafana/data';
|
||||
|
||||
import { RadialArcPath } from './RadialArcPath';
|
||||
import { RadialColorDefs } from './RadialColorDefs';
|
||||
@@ -16,6 +13,7 @@ export interface Props {
|
||||
roundedBars?: boolean;
|
||||
glowFilter?: string;
|
||||
colorDefs: RadialColorDefs;
|
||||
thresholds: Threshold[];
|
||||
}
|
||||
export function ThresholdsBar({
|
||||
dimensions,
|
||||
@@ -25,19 +23,16 @@ export function ThresholdsBar({
|
||||
roundedBars,
|
||||
glowFilter,
|
||||
colorDefs,
|
||||
thresholds,
|
||||
}: Props) {
|
||||
const theme = useTheme2();
|
||||
const fieldConfig = fieldDisplay.field;
|
||||
const decimals = fieldConfig.decimals ?? 2;
|
||||
const min = fieldConfig.min ?? 0;
|
||||
const max = fieldConfig.max ?? 100;
|
||||
const thresholds = getFormattedThresholds(decimals, fieldConfig, theme);
|
||||
|
||||
const outerRadius = dimensions.radius + dimensions.barWidth / 2;
|
||||
const thresholdDimensions = {
|
||||
...dimensions,
|
||||
barWidth: dimensions.thresholdsBarWidth,
|
||||
radius: outerRadius + dimensions.thresholdsBarWidth / 2 + dimensions.thresholdsBarSpacing,
|
||||
radius: dimensions.thresholdsBarRadius,
|
||||
};
|
||||
|
||||
let currentStart = startAngle;
|
||||
|
||||
@@ -13,7 +13,8 @@ describe('RadialGauge utils', () => {
|
||||
overrides.roundedBars ?? false,
|
||||
overrides.barWidthFactor ?? 0.4,
|
||||
overrides.barIndex ?? 0,
|
||||
overrides.thresholdsBar ?? false
|
||||
overrides.thresholdsBar ?? false,
|
||||
overrides.showScaleLabels ?? false
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,6 +100,14 @@ describe('RadialGauge utils', () => {
|
||||
expect(gauge.radius).toBeCloseTo(93.33, 1);
|
||||
expect(gauge.centerY).toBeCloseTo(132.89, 1); // centerY can be much lower when shape is a semi circle
|
||||
});
|
||||
|
||||
it('should give space for scale labels', () => {
|
||||
const gauge = calc({ width: 200, height: 200, shape: 'gauge', showScaleLabels: true, thresholdsBar: true });
|
||||
|
||||
expect(gauge.radius).toBeCloseTo(72, 1);
|
||||
expect(gauge.thresholdsBarRadius).toBeCloseTo(82.66, 1);
|
||||
expect(gauge.scaleLabelsFontSize).toBeCloseTo(10, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toRad', () => {
|
||||
|
||||
@@ -32,8 +32,13 @@ export interface GaugeDimensions {
|
||||
barWidth: number;
|
||||
endAngle?: number;
|
||||
barIndex: number;
|
||||
thresholdsBarRadius: number;
|
||||
thresholdsBarWidth: number;
|
||||
thresholdsBarSpacing: number;
|
||||
showScaleLabels?: boolean;
|
||||
scaleLabelsFontSize: number;
|
||||
scaleLabelsSpacing: number;
|
||||
scaleLabelsRadius: number;
|
||||
}
|
||||
|
||||
export function calculateDimensions(
|
||||
@@ -44,41 +49,72 @@ export function calculateDimensions(
|
||||
roundedBars: boolean,
|
||||
barWidthFactor: number,
|
||||
barIndex: number,
|
||||
thresholdBar?: boolean
|
||||
thresholdBar?: boolean,
|
||||
showScaleLabels?: boolean
|
||||
): GaugeDimensions {
|
||||
const yMaxAngle = endAngle > 180 ? 180 : endAngle;
|
||||
let margin = 0;
|
||||
|
||||
if (glow) {
|
||||
margin = 0.02 * Math.min(width, height);
|
||||
}
|
||||
|
||||
// Max radius based on width
|
||||
let maxRadiusH = width / 2 - margin;
|
||||
let maxRadiusW = width / 2 - margin;
|
||||
|
||||
// Max radius based on height
|
||||
let heightRatioV = Math.sin(toRad(yMaxAngle));
|
||||
let maxRadiusV = (height - margin * 2) / (1 + heightRatioV);
|
||||
let maxRadiusH = (height - margin * 2) / (1 + heightRatioV);
|
||||
|
||||
let maxRadius = Math.min(maxRadiusH, maxRadiusV);
|
||||
let maxRadius = Math.min(maxRadiusW, maxRadiusH);
|
||||
let maxRadiusIsLimitedByHeight = maxRadiusH === maxRadius;
|
||||
let outerRadius = maxRadius;
|
||||
|
||||
const barWidth = Math.max(barWidthFactor * (maxRadius / 3), 2);
|
||||
const thresholdsToBarWidth = 0.2 * Math.pow(barWidth, 0.92);
|
||||
const thresholdsBarWidth = thresholdBar ? Math.min(Math.max(thresholdsToBarWidth, 4), 12) : 0;
|
||||
const thresholdsBarSpacing = Math.min(Math.max(thresholdsBarWidth / 2, 2), 12);
|
||||
|
||||
let outerRadius = maxRadius;
|
||||
|
||||
// If rounded bars is enabled they need a bit more vertical space
|
||||
if (yMaxAngle < 180 && roundedBars) {
|
||||
outerRadius -= barWidth;
|
||||
maxRadiusH -= barWidth;
|
||||
maxRadiusW -= barWidth;
|
||||
}
|
||||
|
||||
// Scale labels
|
||||
let scaleLabelsFontSize = 0;
|
||||
let scaleLabelsSpacing = 0;
|
||||
let scaleLabelsRadius = 0;
|
||||
|
||||
if (showScaleLabels) {
|
||||
scaleLabelsRadius = outerRadius;
|
||||
const radiusToFontSizeFactor = 0.12;
|
||||
scaleLabelsFontSize = Math.max(radiusToFontSizeFactor * Math.pow(outerRadius, 0.92), 10);
|
||||
scaleLabelsSpacing = scaleLabelsFontSize / 3;
|
||||
const labelsSize = scaleLabelsFontSize * 1.2 + scaleLabelsSpacing;
|
||||
outerRadius -= labelsSize;
|
||||
maxRadiusW -= labelsSize;
|
||||
maxRadiusH -= labelsSize;
|
||||
|
||||
// For gauges the max label needs a bit more vertical space so that it does not get clipped
|
||||
if (maxRadiusIsLimitedByHeight && endAngle < 180) {
|
||||
const amount = outerRadius * 0.07;
|
||||
scaleLabelsRadius -= amount;
|
||||
maxRadiusH -= amount;
|
||||
maxRadiusW -= amount;
|
||||
outerRadius -= amount;
|
||||
}
|
||||
}
|
||||
|
||||
// Thresholds bar
|
||||
const thresholdsToBarWidth = 0.2 * Math.pow(barWidth, 0.92);
|
||||
const thresholdsBarWidth = thresholdBar ? Math.min(Math.max(thresholdsToBarWidth, 4), 12) : 0;
|
||||
const thresholdsBarSpacing = Math.min(Math.max(thresholdsBarWidth / 2, 2), 12);
|
||||
let thresholdsBarRadius = 0;
|
||||
|
||||
if (thresholdsBarWidth > 0) {
|
||||
thresholdsBarRadius = outerRadius - thresholdsBarWidth / 2;
|
||||
maxRadiusW -= thresholdsBarWidth + thresholdsBarSpacing;
|
||||
maxRadiusH -= thresholdsBarWidth + thresholdsBarSpacing;
|
||||
maxRadiusV -= thresholdsBarWidth + thresholdsBarSpacing;
|
||||
outerRadius = Math.min(maxRadiusH, maxRadiusV);
|
||||
}
|
||||
|
||||
if (glow) {
|
||||
margin = 0.04 * outerRadius;
|
||||
outerRadius -= (margin * 2) / (1 + heightRatioV);
|
||||
outerRadius = Math.min(maxRadiusW, maxRadiusH);
|
||||
}
|
||||
|
||||
let innerRadius = outerRadius - barWidth / 2;
|
||||
@@ -101,5 +137,17 @@ export function calculateDimensions(
|
||||
barIndex,
|
||||
thresholdsBarWidth,
|
||||
thresholdsBarSpacing,
|
||||
thresholdsBarRadius,
|
||||
scaleLabelsFontSize,
|
||||
scaleLabelsSpacing,
|
||||
scaleLabelsRadius,
|
||||
};
|
||||
}
|
||||
|
||||
export function toCartesian(centerX: number, centerY: number, radius: number, angleInDegrees: number) {
|
||||
let radian = ((angleInDegrees - 90) * Math.PI) / 180.0;
|
||||
return {
|
||||
x: centerX + radius * Math.cos(radian),
|
||||
y: centerY + radius * Math.sin(radian),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ export function RadialBarPanel({
|
||||
segmentCount={options.segmentCount}
|
||||
segmentSpacing={options.segmentSpacing}
|
||||
thresholdsBar={options.showThresholdMarkers}
|
||||
showScaleLabels={options.showThresholdLabels}
|
||||
alignmentFactors={valueProps.alignmentFactors}
|
||||
valueManualFontSize={options.text?.valueSize}
|
||||
nameManualFontSize={options.text?.titleSize}
|
||||
|
||||
@@ -94,6 +94,13 @@ export const plugin = new PanelPlugin<Options>(RadialBarPanel)
|
||||
defaultValue: defaultOptions.showThresholdMarkers,
|
||||
});
|
||||
|
||||
builder.addBooleanSwitch({
|
||||
path: 'showThresholdLabels',
|
||||
name: t('radialbar.config.threshold-labels', 'Show threshold labels'),
|
||||
category,
|
||||
defaultValue: defaultOptions.showThresholdLabels,
|
||||
});
|
||||
|
||||
builder.addCustomEditor({
|
||||
id: 'radialbar-effects',
|
||||
path: 'effects',
|
||||
|
||||
@@ -35,6 +35,7 @@ composableKinds: PanelCfg: {
|
||||
Options: {
|
||||
common.SingleStatBaseOptions
|
||||
showThresholdMarkers: bool | *true
|
||||
showThresholdLabels: bool | *false
|
||||
segmentCount: number | *1
|
||||
segmentSpacing: number | *0.3
|
||||
sparkline?: bool | *false
|
||||
|
||||
@@ -31,6 +31,7 @@ export interface Options extends common.SingleStatBaseOptions {
|
||||
segmentCount: number;
|
||||
segmentSpacing: number;
|
||||
shape: ('circle' | 'gauge');
|
||||
showThresholdLabels: boolean;
|
||||
showThresholdMarkers: boolean;
|
||||
sparkline?: boolean;
|
||||
}
|
||||
@@ -42,6 +43,7 @@ export const defaultOptions: Partial<Options> = {
|
||||
segmentCount: 1,
|
||||
segmentSpacing: 0.3,
|
||||
shape: 'gauge',
|
||||
showThresholdLabels: false,
|
||||
showThresholdMarkers: true,
|
||||
sparkline: false,
|
||||
};
|
||||
|
||||
@@ -7699,7 +7699,8 @@
|
||||
"name-neutral": "Neutral",
|
||||
"name-show-threshold-labels": "Show threshold labels",
|
||||
"name-show-threshold-markers": "Show threshold markers",
|
||||
"placeholder-neutral": "auto"
|
||||
"placeholder-neutral": "auto",
|
||||
"threshold": "Threshold {{value}}"
|
||||
},
|
||||
"gen-ai": {
|
||||
"apply-suggestion": "Apply",
|
||||
@@ -12076,6 +12077,7 @@
|
||||
"shape-circle": "Circle",
|
||||
"shape-gauge": "Gauge",
|
||||
"sparkline": "Show sparkline",
|
||||
"threshold-labels": "Show threshold labels",
|
||||
"threshold-markers": "Show thresholds"
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user