mirror of https://github.com/grafana/grafana.git
Canvas: Dynamic connection direction (#108423)
This commit is contained in:
parent
e49230d3eb
commit
25c13c55c0
|
@ -25,7 +25,6 @@
|
||||||
"fiscalYearStartMonth": 0,
|
"fiscalYearStartMonth": 0,
|
||||||
"graphTooltip": 0,
|
"graphTooltip": 0,
|
||||||
"links": [],
|
"links": [],
|
||||||
"liveNow": false,
|
|
||||||
"panels": [
|
"panels": [
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
|
@ -42,7 +41,7 @@
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"color": "green",
|
"color": "green",
|
||||||
"value": null
|
"value": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "red",
|
"color": "red",
|
||||||
|
@ -156,11 +155,19 @@
|
||||||
"x": -0.8229007633587786,
|
"x": -0.8229007633587786,
|
||||||
"y": 0.27741935483870966
|
"y": 0.27741935483870966
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1223.8335877862596,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 1.0112359550561798,
|
"x": 1.0112359550561798,
|
||||||
"y": -0.012987012987012988
|
"y": -0.012987012987012988
|
||||||
},
|
},
|
||||||
"targetName": "Element 20",
|
"targetName": "Element 20",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 990,
|
||||||
|
"y": 474
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": -0.18181818181818182,
|
"x": -0.18181818181818182,
|
||||||
|
@ -191,11 +198,19 @@
|
||||||
"x": -0.3068702290076336,
|
"x": -0.3068702290076336,
|
||||||
"y": -0.47419354838709676
|
"y": -0.47419354838709676
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1401.090076335878,
|
||||||
|
"y": 533
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 1.0112359550561798,
|
"x": 1.0112359550561798,
|
||||||
"y": -0.4805194805194805
|
"y": -0.4805194805194805
|
||||||
},
|
},
|
||||||
"targetName": "Element 20",
|
"targetName": "Element 20",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 990,
|
||||||
|
"y": 492
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0.415,
|
"x": 0.415,
|
||||||
|
@ -227,11 +242,19 @@
|
||||||
"x": 0.7903930131004366,
|
"x": 0.7903930131004366,
|
||||||
"y": -0.36935483870967745
|
"y": -0.36935483870967745
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1778,
|
||||||
|
"y": 500.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 1.0120481927710843,
|
"x": 1.0120481927710843,
|
||||||
"y": 0.024691358024691357
|
"y": 0.024691358024691357
|
||||||
},
|
},
|
||||||
"targetName": "Element 35",
|
"targetName": "Element 35",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1523,
|
||||||
|
"y": 177
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": -0.1607843137254902,
|
"x": -0.1607843137254902,
|
||||||
|
@ -518,11 +541,19 @@
|
||||||
"x": 0.8876404494382022,
|
"x": 0.8876404494382022,
|
||||||
"y": 0.2597402597402597
|
"y": 0.2597402597402597
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 741,
|
||||||
|
"y": 356.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.9775280898876404,
|
"x": -0.9775280898876404,
|
||||||
"y": -0.012987012987012988
|
"y": -0.012987012987012988
|
||||||
},
|
},
|
||||||
"targetName": "Element 19"
|
"targetName": "Element 19",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 813,
|
||||||
|
"y": 358
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -614,11 +645,19 @@
|
||||||
"x": 0.8876404494382022,
|
"x": 0.8876404494382022,
|
||||||
"y": 0.2597402597402597
|
"y": 0.2597402597402597
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 741,
|
||||||
|
"y": 239.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.9887640449438202,
|
"x": -0.9887640449438202,
|
||||||
"y": -0.06493506493506493
|
"y": -0.06493506493506493
|
||||||
},
|
},
|
||||||
"targetName": "Element 18"
|
"targetName": "Element 18",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 812,
|
||||||
|
"y": 242
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -673,11 +712,19 @@
|
||||||
"x": -0.2247191011235955,
|
"x": -0.2247191011235955,
|
||||||
"y": -0.4805194805194805
|
"y": -0.4805194805194805
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 342,
|
||||||
|
"y": 395
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 0.011235955056179775,
|
"x": 0.011235955056179775,
|
||||||
"y": 0.922077922077922
|
"y": 0.922077922077922
|
||||||
},
|
},
|
||||||
"targetName": "Element 12"
|
"targetName": "Element 12",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 343,
|
||||||
|
"y": 458
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": {
|
"color": {
|
||||||
|
@ -693,11 +740,19 @@
|
||||||
"x": 0.7752808988764045,
|
"x": 0.7752808988764045,
|
||||||
"y": 0.5194805194805194
|
"y": 0.5194805194805194
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 431,
|
||||||
|
"y": 356.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1.0833333333333333,
|
"x": -1.0833333333333333,
|
||||||
"y": 0.020618556701030927
|
"y": 0.020618556701030927
|
||||||
},
|
},
|
||||||
"targetName": "Element 15"
|
"targetName": "Element 15",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 526,
|
||||||
|
"y": 356
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -888,11 +943,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 431,
|
||||||
|
"y": 337.25
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1.0112359550561798,
|
"x": -1.0112359550561798,
|
||||||
"y": -0.012987012987012988
|
"y": -0.012987012987012988
|
||||||
},
|
},
|
||||||
"targetName": "Element 16",
|
"targetName": "Element 16",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 562,
|
||||||
|
"y": 240
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0.42748091603053434,
|
"x": 0.42748091603053434,
|
||||||
|
@ -963,11 +1026,19 @@
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": -1
|
"y": -1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 150,
|
||||||
|
"y": 223
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.5168539325842697,
|
"x": -0.5168539325842697,
|
||||||
"y": 1
|
"y": 1
|
||||||
},
|
},
|
||||||
"targetName": "Element 6",
|
"targetName": "Element 6",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 296,
|
||||||
|
"y": 318
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0,
|
"x": 0,
|
||||||
|
@ -996,11 +1067,19 @@
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 1
|
"y": 1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 150,
|
||||||
|
"y": 148
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1.0112359550561798,
|
"x": -1.0112359550561798,
|
||||||
"y": -0.012987012987012988
|
"y": -0.012987012987012988
|
||||||
},
|
},
|
||||||
"targetName": "Element 30",
|
"targetName": "Element 30",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 563,
|
||||||
|
"y": 82
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0,
|
"x": 0,
|
||||||
|
@ -1062,11 +1141,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 216,
|
||||||
|
"y": 356.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1.0112359550561798,
|
"x": -1.0112359550561798,
|
||||||
"y": -0.012987012987012988
|
"y": -0.012987012987012988
|
||||||
},
|
},
|
||||||
"targetName": "Element 6"
|
"targetName": "Element 6",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 252,
|
||||||
|
"y": 357
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -1121,11 +1208,19 @@
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": -1
|
"y": -1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 342,
|
||||||
|
"y": 223
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 0.011235955056179775,
|
"x": 0.011235955056179775,
|
||||||
"y": 1.025974025974026
|
"y": 1.025974025974026
|
||||||
},
|
},
|
||||||
"targetName": "Element 6"
|
"targetName": "Element 6",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 343,
|
||||||
|
"y": 317
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -1218,11 +1313,19 @@
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 38,
|
||||||
|
"y": 493.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1.0224719101123596,
|
"x": -1.0224719101123596,
|
||||||
"y": 0.013333333333333334
|
"y": 0.013333333333333334
|
||||||
},
|
},
|
||||||
"targetName": "Element 9",
|
"targetName": "Element 9",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 59,
|
||||||
|
"y": 185
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": -0.9523809523809523,
|
"x": -0.9523809523809523,
|
||||||
|
@ -1399,11 +1502,19 @@
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 563,
|
||||||
|
"y": 473.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 1.0224719101123596,
|
"x": 1.0224719101123596,
|
||||||
"y": -0.45454545454545453
|
"y": -0.45454545454545453
|
||||||
},
|
},
|
||||||
"targetName": "Element 6",
|
"targetName": "Element 6",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 433,
|
||||||
|
"y": 374
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0.5692307692307692,
|
"x": 0.5692307692307692,
|
||||||
|
@ -1468,11 +1579,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 989,
|
||||||
|
"y": 239.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.96,
|
"x": -0.96,
|
||||||
"y": 0.4583333333333333
|
"y": 0.4583333333333333
|
||||||
},
|
},
|
||||||
"targetName": "Element 2",
|
"targetName": "Element 2",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1392,
|
||||||
|
"y": 487
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0.3349875930521092,
|
"x": 0.3349875930521092,
|
||||||
|
@ -1506,11 +1625,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": -0.5
|
"y": -0.5
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 989,
|
||||||
|
"y": 258.75
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.9761904761904762,
|
"x": -0.9761904761904762,
|
||||||
"y": 0.5263157894736842
|
"y": 0.5263157894736842
|
||||||
},
|
},
|
||||||
"targetName": "Element 34",
|
"targetName": "Element 34",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1138,
|
||||||
|
"y": 290
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0.5033557046979866,
|
"x": 0.5033557046979866,
|
||||||
|
@ -1612,11 +1739,19 @@
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 811,
|
||||||
|
"y": 473.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 1.0112359550561798,
|
"x": 1.0112359550561798,
|
||||||
"y": 0.012987012987012988
|
"y": 0.012987012987012988
|
||||||
},
|
},
|
||||||
"targetName": "Element 17"
|
"targetName": "Element 17",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 742,
|
||||||
|
"y": 473
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -1671,11 +1806,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": -0.5
|
"y": -0.5
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1025.5,
|
||||||
|
"y": 382.25
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1.0238095238095237,
|
"x": -1.0238095238095237,
|
||||||
"y": 0.10526315789473684
|
"y": 0.10526315789473684
|
||||||
},
|
},
|
||||||
"targetName": "Element 33"
|
"targetName": "Element 33",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1136,
|
||||||
|
"y": 384
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": {
|
"color": {
|
||||||
|
@ -1691,11 +1834,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1025.5,
|
||||||
|
"y": 333.75
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": 0.05263157894736842
|
"y": 0.05263157894736842
|
||||||
},
|
},
|
||||||
"targetName": "Element 34",
|
"targetName": "Element 34",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1137,
|
||||||
|
"y": 299
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0.5246636771300448,
|
"x": 0.5246636771300448,
|
||||||
|
@ -1721,11 +1872,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1025.5,
|
||||||
|
"y": 358
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.98,
|
"x": -0.98,
|
||||||
"y": -0.10416666666666667
|
"y": -0.10416666666666667
|
||||||
},
|
},
|
||||||
"targetName": "Element 2",
|
"targetName": "Element 2",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1391,
|
||||||
|
"y": 514
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0.7564979480164159,
|
"x": 0.7564979480164159,
|
||||||
|
@ -1792,11 +1951,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 742,
|
||||||
|
"y": 81.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1.0112359550561798,
|
"x": -1.0112359550561798,
|
||||||
"y": -0.012987012987012988
|
"y": -0.012987012987012988
|
||||||
},
|
},
|
||||||
"targetName": "Element 31"
|
"targetName": "Element 31",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 811,
|
||||||
|
"y": 82
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": {
|
"color": {
|
||||||
|
@ -1818,11 +1985,19 @@
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 1
|
"y": 1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 653,
|
||||||
|
"y": 43
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.029411764705882353,
|
"x": -0.029411764705882353,
|
||||||
"y": 1
|
"y": 1
|
||||||
},
|
},
|
||||||
"targetName": "Element 38",
|
"targetName": "Element 38",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1673,
|
||||||
|
"y": 249
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0,
|
"x": 0,
|
||||||
|
@ -1892,11 +2067,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 990,
|
||||||
|
"y": 81.5
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.9939759036144579,
|
"x": -0.9939759036144579,
|
||||||
"y": 0.5061728395061729
|
"y": 0.5061728395061729
|
||||||
},
|
},
|
||||||
"targetName": "Element 35",
|
"targetName": "Element 35",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1190,
|
||||||
|
"y": 138
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 0.48,
|
"x": 0.48,
|
||||||
|
@ -1961,11 +2144,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1221,
|
||||||
|
"y": 386
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 1.0337078651685394,
|
"x": 1.0337078651685394,
|
||||||
"y": 0.45454545454545453
|
"y": 0.45454545454545453
|
||||||
},
|
},
|
||||||
"targetName": "Element 20",
|
"targetName": "Element 20",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 992,
|
||||||
|
"y": 456
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": -0.05240174672489083,
|
"x": -0.05240174672489083,
|
||||||
|
@ -2067,11 +2258,19 @@
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1189,
|
||||||
|
"y": 179
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 0.19444444444444445,
|
"x": 0.19444444444444445,
|
||||||
"y": 0.9896907216494846
|
"y": 0.9896907216494846
|
||||||
},
|
},
|
||||||
"targetName": "Element 29",
|
"targetName": "Element 29",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1011,
|
||||||
|
"y": 310
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 1,
|
"x": 1,
|
||||||
|
@ -2169,11 +2368,19 @@
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 1574,
|
||||||
|
"y": 308
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.4977168949771689,
|
"x": -0.4977168949771689,
|
||||||
"y": 1.017467248908297
|
"y": 1.017467248908297
|
||||||
},
|
},
|
||||||
"targetName": "Element 36",
|
"targetName": "Element 36",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 1450,
|
||||||
|
"y": 384
|
||||||
|
},
|
||||||
"vertices": [
|
"vertices": [
|
||||||
{
|
{
|
||||||
"x": 1,
|
"x": 1,
|
||||||
|
@ -2208,7 +2415,7 @@
|
||||||
},
|
},
|
||||||
"showAdvancedTypes": true
|
"showAdvancedTypes": true
|
||||||
},
|
},
|
||||||
"pluginVersion": "11.1.0-pre",
|
"pluginVersion": "12.1.0-pre",
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
|
@ -2236,7 +2443,8 @@
|
||||||
"mode": "absolute",
|
"mode": "absolute",
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"color": "green"
|
"color": "green",
|
||||||
|
"value": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#6ED0E0",
|
"color": "#6ED0E0",
|
||||||
|
@ -2260,7 +2468,7 @@
|
||||||
"h": 11,
|
"h": 11,
|
||||||
"w": 15,
|
"w": 15,
|
||||||
"x": 5,
|
"x": 5,
|
||||||
"y": 22
|
"y": 36
|
||||||
},
|
},
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"options": {
|
"options": {
|
||||||
|
@ -2320,11 +2528,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 216,
|
||||||
|
"y": 192
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1.02020202020202,
|
"x": -1.02020202020202,
|
||||||
"y": 0.041666666666666664
|
"y": 0.041666666666666664
|
||||||
},
|
},
|
||||||
"targetName": "Element 2"
|
"targetName": "Element 2",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 326,
|
||||||
|
"y": 191
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -2377,11 +2593,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 1
|
"y": 1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 426,
|
||||||
|
"y": 168
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.9797979797979798,
|
"x": -0.9797979797979798,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
"targetName": "Element 3"
|
"targetName": "Element 3",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 549,
|
||||||
|
"y": 93
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": {
|
"color": {
|
||||||
|
@ -2398,11 +2622,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": -1
|
"y": -1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 426,
|
||||||
|
"y": 216
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": 0.041666666666666664
|
"y": 0.041666666666666664
|
||||||
},
|
},
|
||||||
"targetName": "Element 4"
|
"targetName": "Element 4",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 549,
|
||||||
|
"y": 297
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -2455,11 +2687,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 647,
|
||||||
|
"y": 93
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.9595959595959596,
|
"x": -0.9595959595959596,
|
||||||
"y": -0.041666666666666664
|
"y": -0.041666666666666664
|
||||||
},
|
},
|
||||||
"targetName": "Element 11"
|
"targetName": "Element 11",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 799,
|
||||||
|
"y": 94
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -2512,11 +2752,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 648,
|
||||||
|
"y": 298
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.9797979797979798,
|
"x": -0.9797979797979798,
|
||||||
"y": 0.041666666666666664
|
"y": 0.041666666666666664
|
||||||
},
|
},
|
||||||
"targetName": "Element 5"
|
"targetName": "Element 5",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 798,
|
||||||
|
"y": 299
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -2838,7 +3086,7 @@
|
||||||
},
|
},
|
||||||
"showAdvancedTypes": false
|
"showAdvancedTypes": false
|
||||||
},
|
},
|
||||||
"pluginVersion": "11.1.0-pre",
|
"pluginVersion": "12.1.0-pre",
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"csvContent": "gateway, product-details, product-reviews, reviews-ratings, details-checkout\n100, 56, 44, 22, 28",
|
"csvContent": "gateway, product-details, product-reviews, reviews-ratings, details-checkout\n100, 56, 44, 22, 28",
|
||||||
|
@ -2873,7 +3121,8 @@
|
||||||
"mode": "absolute",
|
"mode": "absolute",
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"color": "green"
|
"color": "green",
|
||||||
|
"value": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "blue",
|
"color": "blue",
|
||||||
|
@ -2897,7 +3146,7 @@
|
||||||
"h": 15,
|
"h": 15,
|
||||||
"w": 15,
|
"w": 15,
|
||||||
"x": 5,
|
"x": 5,
|
||||||
"y": 33
|
"y": 47
|
||||||
},
|
},
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"options": {
|
"options": {
|
||||||
|
@ -2949,6 +3198,10 @@
|
||||||
"field": "server_database2",
|
"field": "server_database2",
|
||||||
"fixed": "white"
|
"fixed": "white"
|
||||||
},
|
},
|
||||||
|
"direction": {
|
||||||
|
"field": "server_database2",
|
||||||
|
"mode": "field"
|
||||||
|
},
|
||||||
"path": "straight",
|
"path": "straight",
|
||||||
"size": {
|
"size": {
|
||||||
"fixed": 2,
|
"fixed": 2,
|
||||||
|
@ -2959,17 +3212,29 @@
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": -1
|
"y": -1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 468,
|
||||||
|
"y": 125
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 0.030303030303030304,
|
"x": 0.030303030303030304,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
"targetName": "Element 11"
|
"targetName": "Element 11",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 285,
|
||||||
|
"y": 170
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": {
|
"color": {
|
||||||
"field": "server_database",
|
"field": "server_database",
|
||||||
"fixed": "white"
|
"fixed": "white"
|
||||||
},
|
},
|
||||||
|
"direction": {
|
||||||
|
"field": "server_database",
|
||||||
|
"mode": "field"
|
||||||
|
},
|
||||||
"path": "straight",
|
"path": "straight",
|
||||||
"size": {
|
"size": {
|
||||||
"fixed": 2,
|
"fixed": 2,
|
||||||
|
@ -2980,17 +3245,29 @@
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": -1
|
"y": -1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 468,
|
||||||
|
"y": 125
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": 0.09090909090909091,
|
"x": 0.09090909090909091,
|
||||||
"y": 0.16666666666666666
|
"y": 0.16666666666666666
|
||||||
},
|
},
|
||||||
"targetName": "Element 12"
|
"targetName": "Element 12",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 390,
|
||||||
|
"y": 264
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": {
|
"color": {
|
||||||
"field": "server_region",
|
"field": "server_region",
|
||||||
"fixed": "white"
|
"fixed": "white"
|
||||||
},
|
},
|
||||||
|
"direction": {
|
||||||
|
"field": "server_region",
|
||||||
|
"mode": "field"
|
||||||
|
},
|
||||||
"path": "straight",
|
"path": "straight",
|
||||||
"size": {
|
"size": {
|
||||||
"fixed": 2,
|
"fixed": 2,
|
||||||
|
@ -3001,11 +3278,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": -1
|
"y": -1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 588.9921875,
|
||||||
|
"y": 125
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.2727272727272727,
|
"x": -0.2727272727272727,
|
||||||
"y": 0.4166666666666667
|
"y": 0.4166666666666667
|
||||||
},
|
},
|
||||||
"targetName": "Element 13"
|
"targetName": "Element 13",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 658,
|
||||||
|
"y": 259
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -3050,6 +3335,10 @@
|
||||||
"field": "database_server",
|
"field": "database_server",
|
||||||
"fixed": "white"
|
"fixed": "white"
|
||||||
},
|
},
|
||||||
|
"direction": {
|
||||||
|
"field": "database_server",
|
||||||
|
"mode": "field"
|
||||||
|
},
|
||||||
"path": "straight",
|
"path": "straight",
|
||||||
"size": {
|
"size": {
|
||||||
"fixed": 2,
|
"fixed": 2,
|
||||||
|
@ -3060,11 +3349,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 1
|
"y": 1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 328,
|
||||||
|
"y": 367
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.15151515151515152,
|
"x": -0.15151515151515152,
|
||||||
"y": -0.16666666666666666
|
"y": -0.16666666666666666
|
||||||
},
|
},
|
||||||
"targetName": "Element 12"
|
"targetName": "Element 12",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 386,
|
||||||
|
"y": 268
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -3109,6 +3406,10 @@
|
||||||
"field": "region_server",
|
"field": "region_server",
|
||||||
"fixed": "white"
|
"fixed": "white"
|
||||||
},
|
},
|
||||||
|
"direction": {
|
||||||
|
"field": "region_server",
|
||||||
|
"mode": "field"
|
||||||
|
},
|
||||||
"path": "straight",
|
"path": "straight",
|
||||||
"size": {
|
"size": {
|
||||||
"fixed": 2,
|
"fixed": 2,
|
||||||
|
@ -3119,11 +3420,19 @@
|
||||||
"x": -1,
|
"x": -1,
|
||||||
"y": 1
|
"y": 1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 699,
|
||||||
|
"y": 365
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.21212121212121213,
|
"x": -0.21212121212121213,
|
||||||
"y": 0.08333333333333333
|
"y": 0.08333333333333333
|
||||||
},
|
},
|
||||||
"targetName": "Element 13"
|
"targetName": "Element 13",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 659,
|
||||||
|
"y": 263
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -3212,6 +3521,10 @@
|
||||||
"field": "database2_server",
|
"field": "database2_server",
|
||||||
"fixed": "white"
|
"fixed": "white"
|
||||||
},
|
},
|
||||||
|
"direction": {
|
||||||
|
"field": "database2_server",
|
||||||
|
"mode": "field"
|
||||||
|
},
|
||||||
"path": "straight",
|
"path": "straight",
|
||||||
"size": {
|
"size": {
|
||||||
"fixed": 2,
|
"fixed": 2,
|
||||||
|
@ -3222,11 +3535,19 @@
|
||||||
"x": 1,
|
"x": 1,
|
||||||
"y": 1
|
"y": 1
|
||||||
},
|
},
|
||||||
|
"sourceOriginal": {
|
||||||
|
"x": 172,
|
||||||
|
"y": 191
|
||||||
|
},
|
||||||
"target": {
|
"target": {
|
||||||
"x": -0.3333333333333333,
|
"x": -0.3333333333333333,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
"targetName": "Element 11"
|
"targetName": "Element 11",
|
||||||
|
"targetOriginal": {
|
||||||
|
"x": 279,
|
||||||
|
"y": 170
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"constraint": {
|
"constraint": {
|
||||||
|
@ -3605,7 +3926,7 @@
|
||||||
},
|
},
|
||||||
"showAdvancedTypes": false
|
"showAdvancedTypes": false
|
||||||
},
|
},
|
||||||
"pluginVersion": "11.1.0-pre",
|
"pluginVersion": "12.1.0-pre",
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"csvContent": "database_server, server_database, server_region, region_server, database2_server, server_database2\n10, 53, 35, 12, 22, 81",
|
"csvContent": "database_server, server_database, server_region, region_server, database2_server, server_database2\n10, 53, 35, 12, 22, 81",
|
||||||
|
@ -3620,9 +3941,9 @@
|
||||||
"type": "canvas"
|
"type": "canvas"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"preload": false,
|
||||||
"refresh": "",
|
"refresh": "",
|
||||||
"revision": 1,
|
"schemaVersion": 41,
|
||||||
"schemaVersion": 39,
|
|
||||||
"tags": ["gdev", "panel-tests", "canvas"],
|
"tags": ["gdev", "panel-tests", "canvas"],
|
||||||
"templating": {
|
"templating": {
|
||||||
"list": []
|
"list": []
|
||||||
|
@ -3631,11 +3952,9 @@
|
||||||
"from": "now-6h",
|
"from": "now-6h",
|
||||||
"to": "now"
|
"to": "now"
|
||||||
},
|
},
|
||||||
"timeRangeUpdatedDuringEditOrView": false,
|
|
||||||
"timepicker": {},
|
"timepicker": {},
|
||||||
"timezone": "",
|
"timezone": "",
|
||||||
"title": "Panel Tests - Canvas Connection Examples",
|
"title": "Panel Tests - Canvas Connection Examples",
|
||||||
"uid": "Pu8lwQAVz",
|
"uid": "Pu8lwQAVz",
|
||||||
"version": 6,
|
"version": 15
|
||||||
"weekStart": ""
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,12 +481,19 @@ You can style the selected connection using the following options:
|
||||||
- **Color** - Set the connection color.
|
- **Color** - Set the connection color.
|
||||||
- **Size** - Control the size of the connection by entering a number in the **Value** field.
|
- **Size** - Control the size of the connection by entering a number in the **Value** field.
|
||||||
- **Radius** - Add curve to the connection by entering a value to represent the degree.
|
- **Radius** - Add curve to the connection by entering a value to represent the degree.
|
||||||
- **Arrow Direction** - Control the appearance of the arrow head. Choose from:
|
- **Direction** - Control the appearance of the arrow head. Choose your source from **Fixed** or **Field**. The default value is **Forward** regardless of the source type.
|
||||||
|
|
||||||
|
If the direction source is **Fixed**, choose from:
|
||||||
- **Forward** - The arrow head points in the direction in which the connection was drawn.
|
- **Forward** - The arrow head points in the direction in which the connection was drawn.
|
||||||
- **Reverse** - The arrow head points in the opposite direction of which the connection was drawn.
|
- **Reverse** - The arrow head points in the opposite direction of which the connection was drawn.
|
||||||
- **Both** - Adds arrow heads to both ends of the connection.
|
- **Both** - Adds arrow heads to both ends of the connection.
|
||||||
- **None** - Removes the arrow head.
|
- **None** - Removes the arrow head.
|
||||||
|
|
||||||
|
If the direction source is **Field**, select a field that contains numeric values:
|
||||||
|
- **Positive values** - Display forward arrows.
|
||||||
|
- **Negative values** - Display reverse arrows.
|
||||||
|
- **Zero** - Display no arrow heads.
|
||||||
|
|
||||||
- **Line style** - Choose from the following line styles: **Solid**, **Dashed**, and **Dotted**.
|
- **Line style** - Choose from the following line styles: **Solid**, **Dashed**, and **Dotted**.
|
||||||
|
|
||||||
### Standard options
|
### Standard options
|
||||||
|
|
|
@ -111,6 +111,26 @@ export enum ResourceDimensionMode {
|
||||||
Mapping = 'mapping',
|
Mapping = 'mapping',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links to a resource (image/svg path)
|
||||||
|
*/
|
||||||
|
export interface ResourceDimensionConfig extends BaseDimensionConfig {
|
||||||
|
fixed?: string;
|
||||||
|
mode: ResourceDimensionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ConnectionDirection {
|
||||||
|
Both = 'both',
|
||||||
|
Forward = 'forward',
|
||||||
|
None = 'none',
|
||||||
|
Reverse = 'reverse',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum DirectionDimensionMode {
|
||||||
|
Field = 'field',
|
||||||
|
Fixed = 'fixed',
|
||||||
|
}
|
||||||
|
|
||||||
export interface MapLayerOptions {
|
export interface MapLayerOptions {
|
||||||
/**
|
/**
|
||||||
* Custom options depending on the type
|
* Custom options depending on the type
|
||||||
|
@ -899,12 +919,9 @@ export interface DataSourceRef {
|
||||||
uid?: string;
|
uid?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export interface DirectionDimensionConfig extends BaseDimensionConfig {
|
||||||
* Links to a resource (image/svg path)
|
fixed?: ConnectionDirection;
|
||||||
*/
|
mode: DirectionDimensionMode;
|
||||||
export interface ResourceDimensionConfig extends BaseDimensionConfig {
|
|
||||||
fixed?: string;
|
|
||||||
mode: ResourceDimensionMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FrameGeometrySource {
|
export interface FrameGeometrySource {
|
||||||
|
|
|
@ -47,3 +47,12 @@ ResourceDimensionConfig: {
|
||||||
fixed?: string
|
fixed?: string
|
||||||
}@cuetsy(kind="interface")
|
}@cuetsy(kind="interface")
|
||||||
|
|
||||||
|
ConnectionDirection: "forward" | "reverse" | "both" | "none" @cuetsy(kind="enum", memberNames="Forward|Reverse|Both|None")
|
||||||
|
|
||||||
|
DirectionDimensionMode: "fixed" | "field" @cuetsy(kind="enum")
|
||||||
|
|
||||||
|
DirectionDimensionConfig: {
|
||||||
|
BaseDimensionConfig
|
||||||
|
mode: DirectionDimensionMode
|
||||||
|
fixed?: ConnectionDirection
|
||||||
|
}@cuetsy(kind="interface")
|
||||||
|
|
|
@ -80,6 +80,7 @@ export enum ConnectionPath {
|
||||||
|
|
||||||
export interface CanvasConnection {
|
export interface CanvasConnection {
|
||||||
color?: ui.ColorDimensionConfig;
|
color?: ui.ColorDimensionConfig;
|
||||||
|
direction?: ui.DirectionDimensionConfig;
|
||||||
path: ConnectionPath;
|
path: ConnectionPath;
|
||||||
size?: ui.ScaleDimensionConfig;
|
size?: ui.ScaleDimensionConfig;
|
||||||
source: ConnectionCoordinates;
|
source: ConnectionCoordinates;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { ComponentType } from 'react';
|
||||||
|
|
||||||
import { DataLink, RegistryItem, Action } from '@grafana/data';
|
import { DataLink, RegistryItem, Action } from '@grafana/data';
|
||||||
import { PanelOptionsSupplier } from '@grafana/data/internal';
|
import { PanelOptionsSupplier } from '@grafana/data/internal';
|
||||||
import { ColorDimensionConfig, ScaleDimensionConfig } from '@grafana/schema';
|
import { ColorDimensionConfig, ScaleDimensionConfig, DirectionDimensionConfig } from '@grafana/schema';
|
||||||
import { config } from 'app/core/config';
|
import { config } from 'app/core/config';
|
||||||
import { BackgroundConfig, Constraint, LineConfig, Placement } from 'app/plugins/panel/canvas/panelcfg.gen';
|
import { BackgroundConfig, Constraint, LineConfig, Placement } from 'app/plugins/panel/canvas/panelcfg.gen';
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ export interface CanvasConnection {
|
||||||
lineStyle?: LineStyleConfig;
|
lineStyle?: LineStyleConfig;
|
||||||
vertices?: ConnectionCoordinates[];
|
vertices?: ConnectionCoordinates[];
|
||||||
radius?: ScaleDimensionConfig;
|
radius?: ScaleDimensionConfig;
|
||||||
direction?: ConnectionDirection;
|
direction?: DirectionDimensionConfig;
|
||||||
sourceOriginal?: ConnectionCoordinates;
|
sourceOriginal?: ConnectionCoordinates;
|
||||||
targetOriginal?: ConnectionCoordinates;
|
targetOriginal?: ConnectionCoordinates;
|
||||||
// See https://github.com/anseki/leader-line#options for more examples of more properties
|
// See https://github.com/anseki/leader-line#options for more examples of more properties
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
ScaleDimensionConfig,
|
ScaleDimensionConfig,
|
||||||
TextDimensionConfig,
|
TextDimensionConfig,
|
||||||
TooltipDisplayMode,
|
TooltipDisplayMode,
|
||||||
|
DirectionDimensionConfig,
|
||||||
} from '@grafana/schema';
|
} from '@grafana/schema';
|
||||||
import { Portal } from '@grafana/ui';
|
import { Portal } from '@grafana/ui';
|
||||||
import { config } from 'app/core/config';
|
import { config } from 'app/core/config';
|
||||||
|
@ -24,6 +25,7 @@ import {
|
||||||
getScalarDimensionFromData,
|
getScalarDimensionFromData,
|
||||||
getScaleDimensionFromData,
|
getScaleDimensionFromData,
|
||||||
getTextDimensionFromData,
|
getTextDimensionFromData,
|
||||||
|
getDirectionDimensionFromData,
|
||||||
} from 'app/features/dimensions/utils';
|
} from 'app/features/dimensions/utils';
|
||||||
import { CanvasContextMenu } from 'app/plugins/panel/canvas/components/CanvasContextMenu';
|
import { CanvasContextMenu } from 'app/plugins/panel/canvas/components/CanvasContextMenu';
|
||||||
import { CanvasTooltip } from 'app/plugins/panel/canvas/components/CanvasTooltip';
|
import { CanvasTooltip } from 'app/plugins/panel/canvas/components/CanvasTooltip';
|
||||||
|
@ -207,6 +209,7 @@ export class Scene {
|
||||||
getScalar: (scalar: ScalarDimensionConfig) => getScalarDimensionFromData(this.data, scalar),
|
getScalar: (scalar: ScalarDimensionConfig) => getScalarDimensionFromData(this.data, scalar),
|
||||||
getText: (text: TextDimensionConfig) => getTextDimensionFromData(this.data, text),
|
getText: (text: TextDimensionConfig) => getTextDimensionFromData(this.data, text),
|
||||||
getResource: (res: ResourceDimensionConfig) => getResourceDimensionFromData(this.data, res),
|
getResource: (res: ResourceDimensionConfig) => getResourceDimensionFromData(this.data, res),
|
||||||
|
getDirection: (direction: DirectionDimensionConfig) => getDirectionDimensionFromData(this.data, direction),
|
||||||
getPanelData: () => this.data,
|
getPanelData: () => this.data,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,15 +5,24 @@ import {
|
||||||
ScalarDimensionConfig,
|
ScalarDimensionConfig,
|
||||||
ScaleDimensionConfig,
|
ScaleDimensionConfig,
|
||||||
TextDimensionConfig,
|
TextDimensionConfig,
|
||||||
|
DirectionDimensionConfig,
|
||||||
|
ConnectionDirection,
|
||||||
} from '@grafana/schema';
|
} from '@grafana/schema';
|
||||||
|
|
||||||
import { DimensionSupplier } from './types';
|
import { DimensionSupplier } from './types';
|
||||||
|
|
||||||
export interface DimensionContext {
|
export interface DimensionContext {
|
||||||
getColor(color: ColorDimensionConfig): DimensionSupplier<string>;
|
getColor(color: ColorDimensionConfig): DimensionSupplier<string>;
|
||||||
|
|
||||||
getScale(scale: ScaleDimensionConfig): DimensionSupplier<number>;
|
getScale(scale: ScaleDimensionConfig): DimensionSupplier<number>;
|
||||||
|
|
||||||
getScalar(scalar: ScalarDimensionConfig): DimensionSupplier<number>;
|
getScalar(scalar: ScalarDimensionConfig): DimensionSupplier<number>;
|
||||||
|
|
||||||
getText(text: TextDimensionConfig): DimensionSupplier<string>;
|
getText(text: TextDimensionConfig): DimensionSupplier<string>;
|
||||||
|
|
||||||
getResource(resource: ResourceDimensionConfig): DimensionSupplier<string>;
|
getResource(resource: ResourceDimensionConfig): DimensionSupplier<string>;
|
||||||
|
|
||||||
|
getDirection(direction: DirectionDimensionConfig): DimensionSupplier<ConnectionDirection>;
|
||||||
|
|
||||||
getPanelData(): PanelData | undefined;
|
getPanelData(): PanelData | undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { DataFrame, Field } from '@grafana/data';
|
||||||
|
import { ConnectionDirection, DirectionDimensionConfig, DirectionDimensionMode } from '@grafana/schema';
|
||||||
|
|
||||||
|
import { DimensionSupplier } from './types';
|
||||||
|
import { findField, getLastNotNullFieldValue } from './utils';
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// Direction dimension
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
export function getDirectionDimension(
|
||||||
|
frame: DataFrame | undefined,
|
||||||
|
config: DirectionDimensionConfig
|
||||||
|
): DimensionSupplier<ConnectionDirection> {
|
||||||
|
return getDirectionDimensionForField(findField(frame, config.field), config);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDirectionDimensionForField(
|
||||||
|
field: Field | undefined,
|
||||||
|
config: DirectionDimensionConfig
|
||||||
|
): DimensionSupplier<ConnectionDirection> {
|
||||||
|
const mode = config.mode ?? DirectionDimensionMode.Fixed;
|
||||||
|
|
||||||
|
if (mode === DirectionDimensionMode.Fixed || !field) {
|
||||||
|
const v = config.fixed ?? ConnectionDirection.Forward;
|
||||||
|
return {
|
||||||
|
isAssumed: Boolean(config.field?.length) || !config.fixed,
|
||||||
|
fixed: v,
|
||||||
|
value: () => v,
|
||||||
|
get: () => v,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDirectionFromValue = (value: unknown): ConnectionDirection => {
|
||||||
|
if (value == null) {
|
||||||
|
return ConnectionDirection.Forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
const numValue = Number(value);
|
||||||
|
if (isNaN(numValue)) {
|
||||||
|
return ConnectionDirection.Forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numValue > 0) {
|
||||||
|
return ConnectionDirection.Forward;
|
||||||
|
} else if (numValue < 0) {
|
||||||
|
return ConnectionDirection.Reverse;
|
||||||
|
} else {
|
||||||
|
return ConnectionDirection.None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
field,
|
||||||
|
get: (index: number): ConnectionDirection => getDirectionFromValue(field.values[index]),
|
||||||
|
value: () => getDirectionFromValue(getLastNotNullFieldValue(field)),
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
FieldNamePickerConfigSettings,
|
||||||
|
SelectableValue,
|
||||||
|
StandardEditorProps,
|
||||||
|
StandardEditorsRegistryItem,
|
||||||
|
} from '@grafana/data';
|
||||||
|
import { t } from '@grafana/i18n';
|
||||||
|
import { DirectionDimensionMode, DirectionDimensionConfig, ConnectionDirection } from '@grafana/schema';
|
||||||
|
import { InlineField, InlineFieldRow, RadioButtonGroup, Select } from '@grafana/ui';
|
||||||
|
import { FieldNamePicker } from '@grafana/ui/internal';
|
||||||
|
|
||||||
|
import { DirectionDimensionOptions } from '../types';
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
|
const dummyFieldSettings = {
|
||||||
|
settings: {},
|
||||||
|
} as StandardEditorsRegistryItem<string, FieldNamePickerConfigSettings>;
|
||||||
|
|
||||||
|
type Props = StandardEditorProps<DirectionDimensionConfig, DirectionDimensionOptions>;
|
||||||
|
|
||||||
|
export const DirectionDimensionEditor = ({ value, context, onChange }: Props) => {
|
||||||
|
const directionOptions = [
|
||||||
|
{
|
||||||
|
label: t('dimensions.direction-dimension-editor.label-fixed', 'Fixed'),
|
||||||
|
value: DirectionDimensionMode.Fixed,
|
||||||
|
description: t('dimensions.direction-dimension-editor.description-fixed', 'Fixed direction value'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('dimensions.direction-dimension-editor.label-field', 'Field'),
|
||||||
|
value: DirectionDimensionMode.Field,
|
||||||
|
description: t('dimensions.direction-dimension-editor.description-field', 'Direction based on field value'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const fixedDirectionOptions: Array<SelectableValue<ConnectionDirection>> = [
|
||||||
|
{ value: ConnectionDirection.Forward, label: t('canvas.connection.direction-options.label-forward', 'Forward') },
|
||||||
|
{ value: ConnectionDirection.Reverse, label: t('canvas.connection.direction-options.label-reverse', 'Reverse') },
|
||||||
|
{ value: ConnectionDirection.Both, label: t('canvas.connection.direction-options.label-both', 'Both') },
|
||||||
|
{ value: ConnectionDirection.None, label: t('canvas.connection.direction-options.label-none', 'None') },
|
||||||
|
];
|
||||||
|
|
||||||
|
const labelWidth = 9;
|
||||||
|
|
||||||
|
const onModeChange = useCallback(
|
||||||
|
(mode: DirectionDimensionMode) => {
|
||||||
|
onChange({
|
||||||
|
...value,
|
||||||
|
mode,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[onChange, value]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onFieldChange = useCallback(
|
||||||
|
(field?: string) => {
|
||||||
|
onChange({
|
||||||
|
...value,
|
||||||
|
field,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[onChange, value]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onFixedChange = useCallback(
|
||||||
|
(selection: SelectableValue<ConnectionDirection>) => {
|
||||||
|
onChange({
|
||||||
|
...value,
|
||||||
|
field: undefined,
|
||||||
|
fixed: selection.value ?? ConnectionDirection.Forward,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[onChange, value]
|
||||||
|
);
|
||||||
|
|
||||||
|
const mode = value?.mode ?? DirectionDimensionMode.Fixed;
|
||||||
|
const selectedDirection = fixedDirectionOptions.find((opt) => opt.value === value?.fixed) || fixedDirectionOptions[0];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<InlineFieldRow>
|
||||||
|
<InlineField
|
||||||
|
label={t('dimensions.direction-dimension-editor.label-source', 'Source')}
|
||||||
|
labelWidth={labelWidth}
|
||||||
|
grow={true}
|
||||||
|
>
|
||||||
|
<RadioButtonGroup value={mode} options={directionOptions} onChange={onModeChange} fullWidth />
|
||||||
|
</InlineField>
|
||||||
|
</InlineFieldRow>
|
||||||
|
|
||||||
|
{mode === DirectionDimensionMode.Field && (
|
||||||
|
<InlineFieldRow>
|
||||||
|
<InlineField
|
||||||
|
label={t('dimensions.direction-dimension-editor.label-field', 'Field')}
|
||||||
|
labelWidth={labelWidth}
|
||||||
|
grow={true}
|
||||||
|
>
|
||||||
|
<FieldNamePicker
|
||||||
|
context={context}
|
||||||
|
value={value?.field ?? ''}
|
||||||
|
onChange={onFieldChange}
|
||||||
|
item={dummyFieldSettings}
|
||||||
|
/>
|
||||||
|
</InlineField>
|
||||||
|
</InlineFieldRow>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{mode === DirectionDimensionMode.Fixed && (
|
||||||
|
<InlineFieldRow>
|
||||||
|
<InlineField
|
||||||
|
label={t('dimensions.direction-dimension-editor.label-direction', 'Direction')}
|
||||||
|
labelWidth={labelWidth}
|
||||||
|
grow={true}
|
||||||
|
>
|
||||||
|
<Select value={selectedDirection} options={fixedDirectionOptions} onChange={onFixedChange} />
|
||||||
|
</InlineField>
|
||||||
|
</InlineFieldRow>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -85,3 +85,5 @@ export enum ResourcePickerSize {
|
||||||
SMALL = 'small',
|
SMALL = 'small',
|
||||||
NORMAL = 'normal',
|
NORMAL = 'normal',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DirectionDimensionOptions {}
|
||||||
|
|
|
@ -6,9 +6,12 @@ import {
|
||||||
TextDimensionConfig,
|
TextDimensionConfig,
|
||||||
ColorDimensionConfig,
|
ColorDimensionConfig,
|
||||||
ScalarDimensionConfig,
|
ScalarDimensionConfig,
|
||||||
|
DirectionDimensionConfig,
|
||||||
|
ConnectionDirection,
|
||||||
} from '@grafana/schema';
|
} from '@grafana/schema';
|
||||||
|
|
||||||
import { getColorDimension } from './color';
|
import { getColorDimension } from './color';
|
||||||
|
import { getDirectionDimension } from './direction';
|
||||||
import { getResourceDimension } from './resource';
|
import { getResourceDimension } from './resource';
|
||||||
import { getScalarDimension } from './scalar';
|
import { getScalarDimension } from './scalar';
|
||||||
import { getScaledDimension } from './scale';
|
import { getScaledDimension } from './scale';
|
||||||
|
@ -30,6 +33,21 @@ export function getColorDimensionFromData(
|
||||||
return getColorDimension(undefined, cfg, config.theme2);
|
return getColorDimension(undefined, cfg, config.theme2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getDirectionDimensionFromData(
|
||||||
|
data: PanelData | undefined,
|
||||||
|
cfg: DirectionDimensionConfig
|
||||||
|
): DimensionSupplier<ConnectionDirection> {
|
||||||
|
if (data?.series && cfg.field) {
|
||||||
|
for (const frame of data.series) {
|
||||||
|
const d = getDirectionDimension(frame, cfg);
|
||||||
|
if (!d.isAssumed || data.series.length === 1) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getDirectionDimension(undefined, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
export function getScaleDimensionFromData(
|
export function getScaleDimensionFromData(
|
||||||
data: PanelData | undefined,
|
data: PanelData | undefined,
|
||||||
cfg: ScaleDimensionConfig
|
cfg: ScaleDimensionConfig
|
||||||
|
|
|
@ -2,9 +2,9 @@ import { css } from '@emotion/css';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { DirectionDimensionConfig, DirectionDimensionMode, ConnectionDirection } from '@grafana/schema';
|
||||||
import { useStyles2 } from '@grafana/ui';
|
import { useStyles2 } from '@grafana/ui';
|
||||||
import { config } from 'app/core/config';
|
import { config } from 'app/core/config';
|
||||||
import { ConnectionDirection } from 'app/features/canvas/element';
|
|
||||||
import { Scene } from 'app/features/canvas/runtime/scene';
|
import { Scene } from 'app/features/canvas/runtime/scene';
|
||||||
|
|
||||||
import { ConnectionCoordinates } from '../../panelcfg.gen';
|
import { ConnectionCoordinates } from '../../panelcfg.gen';
|
||||||
|
@ -47,7 +47,10 @@ export const ConnectionSVG = ({
|
||||||
const EDITOR_HEAD_ID = useMemo(() => `editorHead-${headId}`, [headId]);
|
const EDITOR_HEAD_ID = useMemo(() => `editorHead-${headId}`, [headId]);
|
||||||
const defaultArrowColor = config.theme2.colors.text.primary;
|
const defaultArrowColor = config.theme2.colors.text.primary;
|
||||||
const defaultArrowSize = 2;
|
const defaultArrowSize = 2;
|
||||||
const defaultArrowDirection = ConnectionDirection.Forward;
|
const defaultArrowDirection: DirectionDimensionConfig = {
|
||||||
|
mode: DirectionDimensionMode.Fixed,
|
||||||
|
fixed: ConnectionDirection.Forward,
|
||||||
|
};
|
||||||
const maximumVertices = 10;
|
const maximumVertices = 10;
|
||||||
|
|
||||||
const [selectedConnection, setSelectedConnection] = useState<ConnectionState | undefined>(undefined);
|
const [selectedConnection, setSelectedConnection] = useState<ConnectionState | undefined>(undefined);
|
||||||
|
@ -162,7 +165,12 @@ export const ConnectionSVG = ({
|
||||||
const yDist = yEnd - yStart;
|
const yDist = yEnd - yStart;
|
||||||
|
|
||||||
const { strokeColor, strokeWidth, strokeRadius, arrowDirection, lineStyle, shouldAnimate } =
|
const { strokeColor, strokeWidth, strokeRadius, arrowDirection, lineStyle, shouldAnimate } =
|
||||||
getConnectionStyles(info, scene, defaultArrowSize, defaultArrowDirection);
|
getConnectionStyles(
|
||||||
|
info,
|
||||||
|
scene,
|
||||||
|
defaultArrowSize,
|
||||||
|
defaultArrowDirection.fixed ?? ConnectionDirection.Forward
|
||||||
|
);
|
||||||
|
|
||||||
const isSelected = selectedConnection === v && scene.panel.context.instanceState.selectedConnection;
|
const isSelected = selectedConnection === v && scene.panel.context.instanceState.selectedConnection;
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ import { css } from '@emotion/css';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { DirectionDimensionConfig, DirectionDimensionMode, ConnectionDirection } from '@grafana/schema';
|
||||||
import { useStyles2 } from '@grafana/ui';
|
import { useStyles2 } from '@grafana/ui';
|
||||||
import { config } from 'app/core/config';
|
import { config } from 'app/core/config';
|
||||||
import { ConnectionDirection } from 'app/features/canvas/element';
|
|
||||||
import { Scene } from 'app/features/canvas/runtime/scene';
|
import { Scene } from 'app/features/canvas/runtime/scene';
|
||||||
|
|
||||||
import { ConnectionCoordinates } from '../../panelcfg.gen';
|
import { ConnectionCoordinates } from '../../panelcfg.gen';
|
||||||
|
@ -38,7 +38,10 @@ export const ConnectionSVG = ({ setLineRef, setVertexPathRef, setVertexRef, setC
|
||||||
const EDITOR_HEAD_ID = useMemo(() => `editorHead-${headId}`, [headId]);
|
const EDITOR_HEAD_ID = useMemo(() => `editorHead-${headId}`, [headId]);
|
||||||
const defaultArrowColor = config.theme2.colors.text.primary;
|
const defaultArrowColor = config.theme2.colors.text.primary;
|
||||||
const defaultArrowSize = 2;
|
const defaultArrowSize = 2;
|
||||||
const defaultArrowDirection = ConnectionDirection.Forward;
|
const defaultArrowDirection: DirectionDimensionConfig = {
|
||||||
|
mode: DirectionDimensionMode.Fixed,
|
||||||
|
fixed: ConnectionDirection.Forward,
|
||||||
|
};
|
||||||
const maximumVertices = 10;
|
const maximumVertices = 10;
|
||||||
|
|
||||||
const [selectedConnection, setSelectedConnection] = useState<ConnectionState | undefined>(undefined);
|
const [selectedConnection, setSelectedConnection] = useState<ConnectionState | undefined>(undefined);
|
||||||
|
@ -152,7 +155,12 @@ export const ConnectionSVG = ({ setLineRef, setVertexPathRef, setVertexRef, setC
|
||||||
const yDist = yEnd - yStart;
|
const yDist = yEnd - yStart;
|
||||||
|
|
||||||
const { strokeColor, strokeWidth, strokeRadius, arrowDirection, lineStyle, shouldAnimate } =
|
const { strokeColor, strokeWidth, strokeRadius, arrowDirection, lineStyle, shouldAnimate } =
|
||||||
getConnectionStyles(info, scene, defaultArrowSize, defaultArrowDirection);
|
getConnectionStyles(
|
||||||
|
info,
|
||||||
|
scene,
|
||||||
|
defaultArrowSize,
|
||||||
|
defaultArrowDirection.fixed ?? ConnectionDirection.Forward
|
||||||
|
);
|
||||||
|
|
||||||
const isSelected = selectedConnection === v && scene.panel.context.instanceState.selectedConnection;
|
const isSelected = selectedConnection === v && scene.panel.context.instanceState.selectedConnection;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { FieldType } from '@grafana/data';
|
import { FieldType } from '@grafana/data';
|
||||||
import { PanelOptionsSupplier } from '@grafana/data/internal';
|
import { PanelOptionsSupplier } from '@grafana/data/internal';
|
||||||
import { t } from '@grafana/i18n';
|
import { t } from '@grafana/i18n';
|
||||||
import { ConnectionDirection } from 'app/features/canvas/element';
|
import { ConnectionDirection, DirectionDimensionMode } from '@grafana/schema';
|
||||||
import { SVGElements } from 'app/features/canvas/runtime/element';
|
import { SVGElements } from 'app/features/canvas/runtime/element';
|
||||||
import { BackgroundSizeEditor } from 'app/features/dimensions/editors/BackgroundSizeEditor';
|
import { BackgroundSizeEditor } from 'app/features/dimensions/editors/BackgroundSizeEditor';
|
||||||
import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimensionEditor';
|
import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimensionEditor';
|
||||||
|
import { DirectionDimensionEditor } from 'app/features/dimensions/editors/DirectionDimensionEditor';
|
||||||
import { ResourceDimensionEditor } from 'app/features/dimensions/editors/ResourceDimensionEditor';
|
import { ResourceDimensionEditor } from 'app/features/dimensions/editors/ResourceDimensionEditor';
|
||||||
import { ScaleDimensionEditor } from 'app/features/dimensions/editors/ScaleDimensionEditor';
|
import { ScaleDimensionEditor } from 'app/features/dimensions/editors/ScaleDimensionEditor';
|
||||||
|
|
||||||
|
@ -181,20 +182,18 @@ export const optionBuilder: OptionSuppliers = {
|
||||||
},
|
},
|
||||||
|
|
||||||
addDirection: (builder, context) => {
|
addDirection: (builder, context) => {
|
||||||
const category = [t('canvas.category-arrow-direction', 'Arrow Direction')];
|
const category = [t('canvas.category-arrow-direction', 'Direction')];
|
||||||
builder.addRadio({
|
builder.addCustomEditor({
|
||||||
category,
|
category,
|
||||||
|
id: 'direction',
|
||||||
path: 'direction',
|
path: 'direction',
|
||||||
name: t('canvas.label-direction', 'Direction'),
|
name: t('canvas.label-direction', 'Direction'),
|
||||||
settings: {
|
editor: DirectionDimensionEditor,
|
||||||
options: [
|
settings: {},
|
||||||
{ value: undefined, label: t('canvas.direction-options.label-forward', 'Forward') },
|
defaultValue: {
|
||||||
{ value: ConnectionDirection.Reverse, label: t('canvas.direction-options.label-reverse', 'Reverse') },
|
mode: DirectionDimensionMode.Fixed,
|
||||||
{ value: ConnectionDirection.Both, label: t('canvas.direction-options.label-both', 'Both') },
|
fixed: ConnectionDirection.Forward,
|
||||||
{ value: ConnectionDirection.None, label: t('canvas.direction-options.label-none', 'None') },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
defaultValue: ConnectionDirection.Forward,
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -42,4 +42,57 @@ describe('Canvas migration', () => {
|
||||||
expect(panel.options.root.elements[0].links[0].oneClick).toBe(true);
|
expect(panel.options.root.elements[0].links[0].oneClick).toBe(true);
|
||||||
expect(panel.options.root.elements[0].actions[0].fetch.url).toBe('http://test.com');
|
expect(panel.options.root.elements[0].actions[0].fetch.url).toBe('http://test.com');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should migrate connection direction from string to object format', () => {
|
||||||
|
const panel = {
|
||||||
|
type: 'canvas',
|
||||||
|
options: {
|
||||||
|
root: {
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
name: 'Element 1',
|
||||||
|
type: 'rectangle',
|
||||||
|
connections: [
|
||||||
|
{
|
||||||
|
direction: 'forward',
|
||||||
|
target: 'element2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
direction: 'reverse',
|
||||||
|
target: 'element3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
direction: 'both',
|
||||||
|
target: 'element4',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
target: 'element5',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pluginVersion: '12.1',
|
||||||
|
} as unknown as PanelModel;
|
||||||
|
|
||||||
|
panel.options = canvasMigrationHandler(panel);
|
||||||
|
|
||||||
|
const connectionsElement1 = panel.options.root.elements[0].connections;
|
||||||
|
|
||||||
|
expect(connectionsElement1[0].direction).toEqual({
|
||||||
|
mode: 'fixed',
|
||||||
|
fixed: 'forward',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(connectionsElement1[1].direction).toEqual({
|
||||||
|
mode: 'fixed',
|
||||||
|
fixed: 'reverse',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(connectionsElement1[2].direction).toEqual({
|
||||||
|
mode: 'fixed',
|
||||||
|
fixed: 'both',
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -76,5 +76,28 @@ export const canvasMigrationHandler = (panel: PanelModel): Partial<Options> => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// migrate connection direction
|
||||||
|
if (parseFloat(pluginVersion) <= 12.2) {
|
||||||
|
const root = panel.options?.root;
|
||||||
|
if (root?.elements) {
|
||||||
|
for (const element of root.elements) {
|
||||||
|
for (const connection of element.connections || []) {
|
||||||
|
if (connection.direction && typeof connection.direction === 'string') {
|
||||||
|
// convert old direction to new format
|
||||||
|
connection.direction = {
|
||||||
|
mode: 'fixed',
|
||||||
|
fixed: connection.direction,
|
||||||
|
};
|
||||||
|
} else if (!connection.direction) {
|
||||||
|
connection.direction = {
|
||||||
|
mode: 'fixed',
|
||||||
|
fixed: 'forward',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return panel.options;
|
return panel.options;
|
||||||
};
|
};
|
||||||
|
|
|
@ -97,7 +97,10 @@ export const plugin = new PanelPlugin<Options>(CanvasPanel)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.setMigrationHandler(canvasMigrationHandler)
|
.setMigrationHandler(canvasMigrationHandler, (panel) => {
|
||||||
|
const pluginVersion = panel?.pluginVersion ?? '';
|
||||||
|
return parseFloat(pluginVersion) <= 12.2;
|
||||||
|
})
|
||||||
.setPanelOptions((builder, context) => {
|
.setPanelOptions((builder, context) => {
|
||||||
const state: InstanceState = context.instanceState;
|
const state: InstanceState = context.instanceState;
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ composableKinds: PanelCfg: {
|
||||||
path: ConnectionPath
|
path: ConnectionPath
|
||||||
color?: ui.ColorDimensionConfig
|
color?: ui.ColorDimensionConfig
|
||||||
size?: ui.ScaleDimensionConfig
|
size?: ui.ScaleDimensionConfig
|
||||||
|
direction?: ui.DirectionDimensionConfig
|
||||||
vertices?: [...ConnectionCoordinates]
|
vertices?: [...ConnectionCoordinates]
|
||||||
sourceOriginal?: ConnectionCoordinates
|
sourceOriginal?: ConnectionCoordinates
|
||||||
targetOriginal?: ConnectionCoordinates
|
targetOriginal?: ConnectionCoordinates
|
||||||
|
|
|
@ -78,6 +78,7 @@ export enum ConnectionPath {
|
||||||
|
|
||||||
export interface CanvasConnection {
|
export interface CanvasConnection {
|
||||||
color?: ui.ColorDimensionConfig;
|
color?: ui.ColorDimensionConfig;
|
||||||
|
direction?: ui.DirectionDimensionConfig;
|
||||||
path: ConnectionPath;
|
path: ConnectionPath;
|
||||||
size?: ui.ScaleDimensionConfig;
|
size?: ui.ScaleDimensionConfig;
|
||||||
source: ConnectionCoordinates;
|
source: ConnectionCoordinates;
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
import { isNumber, isString } from 'lodash';
|
import { isNumber, isString } from 'lodash';
|
||||||
|
|
||||||
import { DataFrame, Field, AppEvents, getFieldDisplayName, PluginState, SelectableValue } from '@grafana/data';
|
import { DataFrame, Field, AppEvents, getFieldDisplayName, PluginState, SelectableValue } from '@grafana/data';
|
||||||
|
import { ConnectionDirection } from '@grafana/schema';
|
||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
import { hasAlphaPanels, config } from 'app/core/config';
|
import { hasAlphaPanels, config } from 'app/core/config';
|
||||||
import {
|
import { CanvasConnection, CanvasElementItem, CanvasElementOptions } from 'app/features/canvas/element';
|
||||||
CanvasConnection,
|
|
||||||
CanvasElementItem,
|
|
||||||
CanvasElementOptions,
|
|
||||||
ConnectionDirection,
|
|
||||||
} from 'app/features/canvas/element';
|
|
||||||
import { notFoundItem } from 'app/features/canvas/elements/notFound';
|
import { notFoundItem } from 'app/features/canvas/elements/notFound';
|
||||||
import { advancedElementItems, canvasElementRegistry, defaultElementItems } from 'app/features/canvas/registry';
|
import { advancedElementItems, canvasElementRegistry, defaultElementItems } from 'app/features/canvas/registry';
|
||||||
import { ElementState } from 'app/features/canvas/runtime/element';
|
import { ElementState } from 'app/features/canvas/runtime/element';
|
||||||
|
@ -107,6 +103,7 @@ export function onAddItem(sel: SelectableValue<string>, rootLayer: FrameState |
|
||||||
export function isConnectionSource(element: ElementState) {
|
export function isConnectionSource(element: ElementState) {
|
||||||
return element.options.connections && element.options.connections.length > 0;
|
return element.options.connections && element.options.connections.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isConnectionTarget(element: ElementState, sceneByName: Map<string, ElementState>) {
|
export function isConnectionTarget(element: ElementState, sceneByName: Map<string, ElementState>) {
|
||||||
const connections = getConnections(sceneByName);
|
const connections = getConnections(sceneByName);
|
||||||
return connections.some((connection) => connection.target === element);
|
return connections.some((connection) => connection.target === element);
|
||||||
|
@ -347,7 +344,9 @@ export const getConnectionStyles = (
|
||||||
const strokeColor = info.color ? scene.context.getColor(info.color).value() : defaultArrowColor;
|
const strokeColor = info.color ? scene.context.getColor(info.color).value() : defaultArrowColor;
|
||||||
const strokeWidth = info.size ? scene.context.getScale(info.size).get(lastRowIndex) : defaultArrowSize;
|
const strokeWidth = info.size ? scene.context.getScale(info.size).get(lastRowIndex) : defaultArrowSize;
|
||||||
const strokeRadius = info.radius ? scene.context.getScale(info.radius).get(lastRowIndex) : 0;
|
const strokeRadius = info.radius ? scene.context.getScale(info.radius).get(lastRowIndex) : 0;
|
||||||
const arrowDirection = info.direction ? info.direction : defaultArrowDirection;
|
const arrowDirection = info.direction
|
||||||
|
? scene.context.getDirection(info.direction).get(lastRowIndex)
|
||||||
|
: defaultArrowDirection;
|
||||||
const lineStyle = getLineStyle(info.lineStyle?.style);
|
const lineStyle = getLineStyle(info.lineStyle?.style);
|
||||||
const shouldAnimate = info.lineStyle?.animate;
|
const shouldAnimate = info.lineStyle?.animate;
|
||||||
|
|
||||||
|
|
|
@ -3755,7 +3755,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"category-arrow-direction": "Arrow Direction",
|
"category-arrow-direction": "Direction",
|
||||||
"category-background": "Background",
|
"category-background": "Background",
|
||||||
"category-border": "Border",
|
"category-border": "Border",
|
||||||
"category-canvas": "Canvas",
|
"category-canvas": "Canvas",
|
||||||
|
@ -3787,15 +3787,17 @@
|
||||||
"auto": "Auto"
|
"auto": "Auto"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description-experimental-types": "Enable selection of experimental element types",
|
"connection": {
|
||||||
"description-inline-editing": "Enable editing the panel directly",
|
|
||||||
"description-pan-zoom": "Enable pan and zoom",
|
|
||||||
"direction-options": {
|
"direction-options": {
|
||||||
"label-both": "Both",
|
"label-both": "Both",
|
||||||
"label-forward": "Forward",
|
"label-forward": "Forward",
|
||||||
"label-none": "None",
|
"label-none": "None",
|
||||||
"label-reverse": "Reverse"
|
"label-reverse": "Reverse"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
"description-experimental-types": "Enable selection of experimental element types",
|
||||||
|
"description-inline-editing": "Enable editing the panel directly",
|
||||||
|
"description-pan-zoom": "Enable pan and zoom",
|
||||||
"drone-front-item": {
|
"drone-front-item": {
|
||||||
"category-drone-front": "Drone Front",
|
"category-drone-front": "Drone Front",
|
||||||
"name-roll-angle": "Roll Angle"
|
"name-roll-angle": "Roll Angle"
|
||||||
|
@ -6671,6 +6673,14 @@
|
||||||
"label-fixed-color": "Fixed color",
|
"label-fixed-color": "Fixed color",
|
||||||
"noOptionsMessage-no-fields-found": "No fields found"
|
"noOptionsMessage-no-fields-found": "No fields found"
|
||||||
},
|
},
|
||||||
|
"direction-dimension-editor": {
|
||||||
|
"description-field": "Direction based on field value",
|
||||||
|
"description-fixed": "Fixed direction value",
|
||||||
|
"label-direction": "Direction",
|
||||||
|
"label-field": "Field",
|
||||||
|
"label-fixed": "Fixed",
|
||||||
|
"label-source": "Source"
|
||||||
|
},
|
||||||
"file-dropzone-custom-children": {
|
"file-dropzone-custom-children": {
|
||||||
"upload": "Upload"
|
"upload": "Upload"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue