Dashboard Migrations v17: Convert minSpan to maxPerRow in panels (#109592)
* Migration to be verified: v17 Convert minSpan to maxPerRow in panels * Address review comments: use Go idiom for variable naming and sort.Ints for sorting
This commit is contained in:
@@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
MIN_VERSION = 17
|
||||
MIN_VERSION = 16
|
||||
LATEST_VERSION = 41
|
||||
)
|
||||
|
||||
@@ -38,6 +38,7 @@ type PanelPluginInfoProvider interface {
|
||||
|
||||
func GetMigrations(dsInfoProvider DataSourceInfoProvider, panelProvider PanelPluginInfoProvider) map[int]SchemaVersionMigrationFunc {
|
||||
return map[int]SchemaVersionMigrationFunc{
|
||||
17: V17,
|
||||
18: V18,
|
||||
19: V19,
|
||||
20: V20,
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// V17 migrates panel minSpan property to maxPerRow property.
|
||||
// This migration converts the deprecated minSpan property to the newer maxPerRow property
|
||||
// which controls how many panels can be displayed in a single row.
|
||||
//
|
||||
// The conversion algorithm:
|
||||
// 1. Calculate max = GRID_COLUMN_COUNT / panel.minSpan
|
||||
// 2. Get all factors of GRID_COLUMN_COUNT (24): [1, 2, 3, 4, 6, 8, 12, 24]
|
||||
// 3. Find the first factor greater than max
|
||||
// 4. Use the previous factor as maxPerRow
|
||||
//
|
||||
// Example before migration:
|
||||
//
|
||||
// "panels": [
|
||||
// {
|
||||
// "id": 1,
|
||||
// "type": "graph",
|
||||
// "minSpan": 8
|
||||
// }
|
||||
// ]
|
||||
//
|
||||
// Example after migration:
|
||||
//
|
||||
// "panels": [
|
||||
// {
|
||||
// "id": 1,
|
||||
// "type": "graph",
|
||||
// "maxPerRow": 3
|
||||
// }
|
||||
// ]
|
||||
//
|
||||
// The minSpan property is removed after conversion.
|
||||
func V17(dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 17
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, p := range panels {
|
||||
panel, ok := p.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
migrateMinSpanToMaxPerRow(panel)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// migrateMinSpanToMaxPerRow converts minSpan to maxPerRow using the same algorithm as the frontend.
|
||||
func migrateMinSpanToMaxPerRow(panel map[string]interface{}) {
|
||||
minSpanValue, ok := panel["minSpan"]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Convert minSpan to a number (could be int, float64, etc.)
|
||||
var minSpan float64
|
||||
switch v := minSpanValue.(type) {
|
||||
case int:
|
||||
minSpan = float64(v)
|
||||
case float64:
|
||||
minSpan = v
|
||||
case int64:
|
||||
minSpan = float64(v)
|
||||
default:
|
||||
// If we can't convert minSpan to a number, just delete it and return
|
||||
delete(panel, "minSpan")
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure minSpan is positive to avoid division by zero
|
||||
if minSpan <= 0 {
|
||||
delete(panel, "minSpan")
|
||||
return
|
||||
}
|
||||
|
||||
const gridColumnCount = 24
|
||||
max := gridColumnCount / minSpan
|
||||
factors := getFactors(gridColumnCount)
|
||||
|
||||
// Find the first factor greater than max
|
||||
factorIndex := -1
|
||||
for i, factor := range factors {
|
||||
if float64(factor) > max {
|
||||
factorIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Use the previous factor as maxPerRow
|
||||
if factorIndex > 0 {
|
||||
panel["maxPerRow"] = factors[factorIndex-1]
|
||||
} else if factorIndex == 0 {
|
||||
// If the first factor is already greater than max, use 1
|
||||
panel["maxPerRow"] = 1
|
||||
} else {
|
||||
// If no factor is greater than max, use the largest factor
|
||||
panel["maxPerRow"] = factors[len(factors)-1]
|
||||
}
|
||||
|
||||
// Remove the minSpan property
|
||||
delete(panel, "minSpan")
|
||||
}
|
||||
|
||||
// getFactors returns all factors of a number
|
||||
// Example: getFactors(24) returns [1, 2, 3, 4, 6, 8, 12, 24]
|
||||
func getFactors(num int) []int {
|
||||
factors := []int{}
|
||||
for i := 1; i <= int(math.Sqrt(float64(num))); i++ {
|
||||
if num%i == 0 {
|
||||
factors = append(factors, i)
|
||||
if i != num/i {
|
||||
factors = append(factors, num/i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort factors in ascending order
|
||||
sort.Ints(factors)
|
||||
|
||||
return factors
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
package schemaversion_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
)
|
||||
|
||||
func TestV17(t *testing.T) {
|
||||
tests := []migrationTestCase{
|
||||
{
|
||||
name: "panel with minSpan 8 gets converted to maxPerRow 3",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 MinSpan to MaxPerRow Migration Test Dashboard",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 1,
|
||||
"type": "graph",
|
||||
"title": "Test Panel",
|
||||
"minSpan": 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 MinSpan to MaxPerRow Migration Test Dashboard",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 1,
|
||||
"type": "graph",
|
||||
"title": "Test Panel",
|
||||
"maxPerRow": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with minSpan 4 gets converted to maxPerRow 6",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"type": "singlestat",
|
||||
"title": "Single Stat Panel",
|
||||
"minSpan": 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"type": "singlestat",
|
||||
"title": "Single Stat Panel",
|
||||
"maxPerRow": 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with minSpan 2 gets converted to maxPerRow 12",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"type": "graph",
|
||||
"title": "Wide Panel",
|
||||
"minSpan": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"type": "graph",
|
||||
"title": "Wide Panel",
|
||||
"maxPerRow": 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with minSpan 12 gets converted to maxPerRow 2",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 4,
|
||||
"type": "graph",
|
||||
"title": "Narrow Panel",
|
||||
"minSpan": 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 4,
|
||||
"type": "graph",
|
||||
"title": "Narrow Panel",
|
||||
"maxPerRow": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with minSpan 24 gets converted to maxPerRow 1",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 5,
|
||||
"type": "graph",
|
||||
"title": "Full Width Panel",
|
||||
"minSpan": 24,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 5,
|
||||
"type": "graph",
|
||||
"title": "Full Width Panel",
|
||||
"maxPerRow": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with minSpan 1 gets converted to maxPerRow 24",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 6,
|
||||
"type": "graph",
|
||||
"title": "Tiny Panel",
|
||||
"minSpan": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 MinSpan Migration Test",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 6,
|
||||
"type": "graph",
|
||||
"title": "Tiny Panel",
|
||||
"maxPerRow": 24,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple panels with different minSpan values",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 Multiple Panels Migration Test",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 1,
|
||||
"type": "graph",
|
||||
"title": "Panel 1",
|
||||
"minSpan": 8,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"type": "singlestat",
|
||||
"title": "Panel 2",
|
||||
"minSpan": 4,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"type": "table",
|
||||
"title": "Panel 3 - No minSpan",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 Multiple Panels Migration Test",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 1,
|
||||
"type": "graph",
|
||||
"title": "Panel 1",
|
||||
"maxPerRow": 3,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"type": "singlestat",
|
||||
"title": "Panel 2",
|
||||
"maxPerRow": 6,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"type": "table",
|
||||
"title": "Panel 3 - No minSpan",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with invalid minSpan gets cleaned up",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 Invalid MinSpan Test",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 1,
|
||||
"type": "graph",
|
||||
"title": "Invalid MinSpan Panel",
|
||||
"minSpan": "invalid",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"type": "graph",
|
||||
"title": "Zero MinSpan Panel",
|
||||
"minSpan": 0,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"type": "graph",
|
||||
"title": "Negative MinSpan Panel",
|
||||
"minSpan": -5,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 Invalid MinSpan Test",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 1,
|
||||
"type": "graph",
|
||||
"title": "Invalid MinSpan Panel",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"type": "graph",
|
||||
"title": "Zero MinSpan Panel",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"type": "graph",
|
||||
"title": "Negative MinSpan Panel",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with no panels",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 No Panels Test",
|
||||
"schemaVersion": 16,
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 No Panels Test",
|
||||
"schemaVersion": 17,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with empty panels array",
|
||||
input: map[string]interface{}{
|
||||
"title": "V17 Empty Panels Test",
|
||||
"schemaVersion": 16,
|
||||
"panels": []interface{}{},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V17 Empty Panels Test",
|
||||
"schemaVersion": 17,
|
||||
"panels": []interface{}{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
runMigrationTests(t, tests, schemaversion.V17)
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"title": "V17 MinSpan to MaxPerRow Migration Test Dashboard",
|
||||
"schemaVersion": 16,
|
||||
"panels": [
|
||||
{
|
||||
"id": 1,
|
||||
"type": "graph",
|
||||
"title": "Panel with minSpan 8",
|
||||
"minSpan": 8,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type": "singlestat",
|
||||
"title": "Panel with minSpan 4",
|
||||
"minSpan": 4,
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"type": "table",
|
||||
"title": "Panel with minSpan 2",
|
||||
"minSpan": 2,
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"type": "graph",
|
||||
"title": "Panel with minSpan 12",
|
||||
"minSpan": 12,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"type": "gauge",
|
||||
"title": "Panel with minSpan 24",
|
||||
"minSpan": 24,
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 18
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"type": "stat",
|
||||
"title": "Panel with minSpan 1",
|
||||
"minSpan": 1,
|
||||
"gridPos": {
|
||||
"h": 3,
|
||||
"w": 4,
|
||||
"x": 6,
|
||||
"y": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"type": "graph",
|
||||
"title": "Panel without minSpan",
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
"w": 8,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"type": "text",
|
||||
"title": "Panel with invalid minSpan",
|
||||
"minSpan": "invalid",
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 18,
|
||||
"y": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"type": "graph",
|
||||
"title": "Panel with zero minSpan",
|
||||
"minSpan": 0,
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 0,
|
||||
"y": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"type": "graph",
|
||||
"title": "Panel with negative minSpan",
|
||||
"minSpan": -5,
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 6,
|
||||
"y": 22
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"maxPerRow": 3,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with minSpan 8",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 2,
|
||||
"maxPerRow": 6,
|
||||
"options": {
|
||||
"colorMode": "none",
|
||||
"graphMode": "none",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "horizontal",
|
||||
"percentChangeColorMode": "standard",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"mean"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"showPercentChange": false,
|
||||
"textMode": "auto",
|
||||
"wideLayout": true
|
||||
},
|
||||
"pluginVersion": "1.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with minSpan 4",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 12
|
||||
},
|
||||
"id": 3,
|
||||
"maxPerRow": 12,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with minSpan 2",
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 4,
|
||||
"maxPerRow": 2,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with minSpan 12",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 18
|
||||
},
|
||||
"id": 5,
|
||||
"maxPerRow": 1,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with minSpan 24",
|
||||
"type": "gauge"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 3,
|
||||
"w": 4,
|
||||
"x": 6,
|
||||
"y": 8
|
||||
},
|
||||
"id": 6,
|
||||
"maxPerRow": 24,
|
||||
"options": {
|
||||
"justifyMode": "auto",
|
||||
"percentChangeColorMode": "standard",
|
||||
"showPercentChange": false,
|
||||
"textMode": "auto",
|
||||
"wideLayout": true
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with minSpan 1",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
"w": 8,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
},
|
||||
"id": 7,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel without minSpan",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 18,
|
||||
"y": 8
|
||||
},
|
||||
"id": 8,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with invalid minSpan",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 0,
|
||||
"y": 22
|
||||
},
|
||||
"id": 9,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with zero minSpan",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 6,
|
||||
"y": 22
|
||||
},
|
||||
"id": 10,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Panel with negative minSpan",
|
||||
"type": "graph"
|
||||
}
|
||||
],
|
||||
"refresh": "",
|
||||
"schemaVersion": 41,
|
||||
"title": "V17 MinSpan to MaxPerRow Migration Test Dashboard"
|
||||
}
|
||||
Reference in New Issue
Block a user