diff --git a/devenv/dev-dashboards/panel-canvas/canvas-datalinks.json b/devenv/dev-dashboards/panel-canvas/canvas-datalinks.json new file mode 100644 index 00000000000..8cbe54eb83e --- /dev/null +++ b/devenv/dev-dashboards/panel-canvas/canvas-datalinks.json @@ -0,0 +1,2940 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 740, + "links": [], + "panels": [ + { + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A-hehwzd" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "A-series data link", + "url": "http://localhost:3000/d/dddouk2ygsb9cc/6114e28a-4041-5fbd-878f-b98718a90c4d?${__url_time_range}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Count (transformation)" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Count data link", + "url": "http://localhost:3000/d/dddouk2ygsb9cc/6114e28a-4041-5fbd-878f-b98718a90c4d${__data.fields.A-series}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 30, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "inlineEditing": false, + "panZoom": false, + "root": { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + }, + "width": 0 + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "elements": [ + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 24, + "text": { + "fixed": "Metric Value" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 1", + "placement": { + "height": 50, + "left": 38, + "top": 23, + "width": 144 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "#D9D9D9" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "#000000" + }, + "size": 20, + "text": { + "field": "A-hehwzd", + "fixed": "", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 2", + "placement": { + "height": 50, + "left": 16, + "top": 91, + "width": 188 + }, + "type": "metric-value" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "field": "A-hehwzd", + "fixed": "#000000" + }, + "size": 20, + "text": { + "fixed": "Text color", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 3", + "placement": { + "height": 50, + "left": 16, + "top": 170, + "width": 188 + }, + "type": "metric-value" + }, + { + "background": { + "color": { + "fixed": "transparent" + }, + "image": { + "field": "Count (transformation)", + "mode": "field" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 20, + "text": { + "fixed": "Background image", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 4", + "placement": { + "height": 50, + "left": 16, + "top": 249, + "width": 188 + }, + "type": "metric-value" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "field": "A-hehwzd", + "fixed": "dark-green" + }, + "width": 2 + }, + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 20, + "text": { + "fixed": "Border", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 5", + "placement": { + "height": 50, + "left": 16, + "top": 328, + "width": 188 + }, + "type": "metric-value" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 16, + "text": { + "field": "A-hehwzd", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 6", + "placement": { + "height": 50, + "left": 262, + "top": 91, + "width": 188 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "transparent" + }, + "image": { + "fixed": "" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "field": "A-hehwzd", + "fixed": "rgb(204, 204, 220)" + }, + "size": 16, + "text": { + "fixed": "Text color" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 7", + "placement": { + "height": 50, + "left": 262, + "top": 170, + "width": 188 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "transparent" + }, + "image": { + "field": "Count (transformation)", + "mode": "field" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 16, + "text": { + "fixed": "Background image" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 8", + "placement": { + "height": 50, + "left": 262, + "top": 249, + "width": 188 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "field": "A-hehwzd", + "fixed": "dark-green" + }, + "width": 2 + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 16, + "text": { + "fixed": "Border" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 9", + "placement": { + "height": 50, + "left": 262, + "top": 328, + "width": 188 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 24, + "text": { + "fixed": "Text" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 10", + "placement": { + "height": 50, + "left": 284, + "top": 23, + "width": 144 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "backgroundColor": { + "fixed": "#D9D9D9" + }, + "borderColor": { + "fixed": "transparent" + }, + "color": { + "fixed": "#000000" + }, + "text": { + "field": "A-hehwzd", + "mode": "field" + }, + "valign": "middle", + "width": 1 + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 11", + "placement": { + "height": 50, + "left": 530, + "top": 91, + "width": 188 + }, + "type": "ellipse" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "backgroundColor": { + "fixed": "#D9D9D9" + }, + "borderColor": { + "fixed": "transparent" + }, + "color": { + "field": "A-hehwzd", + "fixed": "#000000" + }, + "text": { + "fixed": "Text color" + }, + "valign": "middle", + "width": 1 + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 12", + "placement": { + "height": 50, + "left": 530, + "top": 170, + "width": 188 + }, + "type": "ellipse" + }, + { + "background": { + "color": { + "fixed": "transparent" + }, + "image": { + "field": "Count (transformation)", + "mode": "field" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "backgroundColor": { + "fixed": "#D9D9D9" + }, + "borderColor": { + "fixed": "transparent" + }, + "color": { + "fixed": "#000000" + }, + "text": { + "fixed": "Background image" + }, + "valign": "middle", + "width": 1 + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 13", + "placement": { + "height": 50, + "left": 530, + "top": 249, + "width": 188 + }, + "type": "ellipse" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "field": "A-hehwzd", + "fixed": "dark-green" + }, + "width": 2 + }, + "config": { + "align": "center", + "backgroundColor": { + "fixed": "#D9D9D9" + }, + "borderColor": { + "fixed": "transparent" + }, + "color": { + "fixed": "#000000" + }, + "text": { + "fixed": "Border" + }, + "valign": "middle", + "width": 1 + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 14", + "placement": { + "height": 50, + "left": 530, + "top": 328, + "width": 188 + }, + "type": "ellipse" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 24, + "text": { + "fixed": "Ellipse" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 15", + "placement": { + "height": 50, + "left": 552, + "top": 23, + "width": 144 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "#D9D9D9" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "#000000" + }, + "text": { + "field": "A-hehwzd", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 16", + "placement": { + "height": 50, + "left": 798, + "top": 91, + "width": 188 + }, + "type": "rectangle" + }, + { + "background": { + "color": { + "fixed": "#D9D9D9" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "field": "A-hehwzd", + "fixed": "#000000" + }, + "text": { + "fixed": "Text color" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 17", + "placement": { + "height": 50, + "left": 798, + "top": 170, + "width": 188 + }, + "type": "rectangle" + }, + { + "background": { + "color": { + "fixed": "#D9D9D9" + }, + "image": { + "field": "Count (transformation)", + "mode": "field" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "#000000" + }, + "text": { + "fixed": "Background image" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 18", + "placement": { + "height": 50, + "left": 798, + "top": 249, + "width": 188 + }, + "type": "rectangle" + }, + { + "background": { + "color": { + "fixed": "#D9D9D9" + } + }, + "border": { + "color": { + "field": "A-hehwzd", + "fixed": "dark-green" + }, + "width": 2 + }, + "config": { + "align": "center", + "color": { + "fixed": "#000000" + }, + "text": { + "fixed": "Border" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 19", + "placement": { + "height": 50, + "left": 798, + "top": 328, + "width": 188 + }, + "type": "rectangle" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 24, + "text": { + "fixed": "Rectangle" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 20", + "placement": { + "height": 50, + "left": 820, + "top": 23, + "width": 144 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "fill": { + "fixed": "#D9D9D9" + }, + "path": { + "field": "A-hehwzd", + "fixed": "img/icons/unicons/question-circle.svg", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 21", + "placement": { + "height": 50, + "left": 1066, + "top": 91, + "width": 188 + }, + "type": "icon" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "fill": { + "field": "A-hehwzd", + "fixed": "#D9D9D9" + }, + "path": { + "fixed": "img/icons/unicons/question-circle.svg", + "mode": "fixed" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 22", + "placement": { + "height": 50, + "left": 1066, + "top": 170, + "width": 188 + }, + "type": "icon" + }, + { + "background": { + "color": { + "fixed": "transparent" + }, + "image": { + "field": "Count (transformation)", + "mode": "field" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "fill": { + "fixed": "#D9D9D9" + }, + "path": { + "fixed": "img/icons/unicons/question-circle.svg", + "mode": "fixed" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 23", + "placement": { + "height": 50, + "left": 1066, + "top": 249, + "width": 188 + }, + "type": "icon" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "field": "A-hehwzd", + "fixed": "dark-green" + }, + "width": 2 + }, + "config": { + "fill": { + "fixed": "#D9D9D9" + }, + "path": { + "fixed": "img/icons/unicons/question-circle.svg", + "mode": "fixed" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 24", + "placement": { + "height": 50, + "left": 1066, + "top": 328, + "width": 188 + }, + "type": "icon" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 24, + "text": { + "fixed": "Icon" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 25", + "placement": { + "height": 50, + "left": 1088, + "top": 23, + "width": 144 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "statusColor": { + "field": "A-hehwzd" + }, + "type": "Single" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 26", + "placement": { + "height": 90, + "left": 65, + "top": 516, + "width": 90 + }, + "type": "server" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "field": "A-hehwzd", + "fixed": "dark-green" + }, + "width": 2 + }, + "config": { + "type": "Single" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 29", + "placement": { + "height": 90, + "left": 65, + "top": 870, + "width": 90 + }, + "type": "server" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 24, + "text": { + "fixed": "Server" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 30", + "placement": { + "height": 50, + "left": 38, + "top": 438, + "width": 144 + }, + "type": "text" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "bulbColor": { + "field": "A-hehwzd" + }, + "statusColor": { + "fixed": "transparent" + }, + "type": "Single" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 31", + "placement": { + "height": 90, + "left": 65, + "top": 634, + "width": 90 + }, + "type": "server" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "blinkRate": { + "field": "A-hehwzd" + }, + "bulbColor": { + "fixed": "#000000" + }, + "statusColor": { + "fixed": "transparent" + }, + "type": "Single" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 32", + "placement": { + "height": 90, + "left": 65, + "top": 752, + "width": 90 + }, + "type": "server" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "rpm": { + "field": "A-hehwzd" + }, + "statusColor": { + "field": "A-hehwzd" + }, + "type": "Single" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 33", + "placement": { + "height": 55, + "left": 329, + "top": 516, + "width": 55 + }, + "type": "windTurbine" + }, + { + "background": { + "color": { + "fixed": "transparent" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "align": "center", + "color": { + "fixed": "rgb(204, 204, 220)" + }, + "size": 24, + "text": { + "fixed": "Wind Turbine" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 35", + "placement": { + "height": 50, + "left": 270, + "top": 438, + "width": 172 + }, + "type": "text" + }, + { + "background": { + "color": { + "field": "A-hehwzd", + "fixed": "transparent" + }, + "image": { + "field": "Count (transformation)", + "mode": "field" + } + }, + "border": { + "color": { + "fixed": "dark-green" + } + }, + "config": { + "bulbColor": { + "field": "A-hehwzd" + }, + "statusColor": { + "fixed": "transparent" + }, + "type": "Single" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 36", + "placement": { + "height": 55, + "left": 329, + "top": 633, + "width": 55 + }, + "type": "windTurbine" + }, + { + "background": { + "color": { + "field": "Count (transformation)", + "fixed": "transparent" + }, + "image": { + "field": "A-hehwzd", + "mode": "field" + } + }, + "border": { + "color": { + "fixed": "dark-green" + }, + "width": 0 + }, + "config": { + "type": "Single" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 38", + "placement": { + "height": 90, + "left": 65, + "top": 988, + "width": 90 + }, + "type": "server" + }, + { + "background": { + "color": { + "fixed": "transparent" + }, + "image": { + "field": "", + "mode": "field" + } + }, + "border": { + "color": { + "field": "A-hehwzd", + "fixed": "dark-green" + }, + "width": 1 + }, + "config": { + "bulbColor": { + "field": "A-hehwzd" + }, + "statusColor": { + "fixed": "transparent" + }, + "type": "Single" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Element 37", + "placement": { + "height": 55, + "left": 329, + "top": 752, + "width": 55 + }, + "type": "windTurbine" + } + ], + "name": "Element 1708700648848", + "placement": { + "height": 100, + "left": 0, + "top": 0, + "width": 100 + }, + "type": "frame" + }, + "showAdvancedTypes": true + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "queryType": "snapshot", + "refId": "A", + "snapshot": [ + { + "data": { + "values": [ + [ + 1708679336805, + 1708679366805, + 1708679396805, + 1708679426805, + 1708679456805, + 1708679486805, + 1708679516805, + 1708679546805, + 1708679576805, + 1708679606805, + 1708679636805, + 1708679666805, + 1708679696805, + 1708679726805, + 1708679756805, + 1708679786805, + 1708679816805, + 1708679846805, + 1708679876805, + 1708679906805, + 1708679936805, + 1708679966805, + 1708679996805, + 1708680026805, + 1708680056805, + 1708680086805, + 1708680116805, + 1708680146805, + 1708680176805, + 1708680206805, + 1708680236805, + 1708680266805, + 1708680296805, + 1708680326805, + 1708680356805, + 1708680386805, + 1708680416805, + 1708680446805, + 1708680476805, + 1708680506805, + 1708680536805, + 1708680566805, + 1708680596805, + 1708680626805, + 1708680656805, + 1708680686805, + 1708680716805, + 1708680746805, + 1708680776805, + 1708680806805, + 1708680836805, + 1708680866805, + 1708680896805, + 1708680926805, + 1708680956805, + 1708680986805, + 1708681016805, + 1708681046805, + 1708681076805, + 1708681106805, + 1708681136805, + 1708681166805, + 1708681196805, + 1708681226805, + 1708681256805, + 1708681286805, + 1708681316805, + 1708681346805, + 1708681376805, + 1708681406805, + 1708681436805, + 1708681466805, + 1708681496805, + 1708681526805, + 1708681556805, + 1708681586805, + 1708681616805, + 1708681646805, + 1708681676805, + 1708681706805, + 1708681736805, + 1708681766805, + 1708681796805, + 1708681826805, + 1708681856805, + 1708681886805, + 1708681916805, + 1708681946805, + 1708681976805, + 1708682006805, + 1708682036805, + 1708682066805, + 1708682096805, + 1708682126805, + 1708682156805, + 1708682186805, + 1708682216805, + 1708682246805, + 1708682276805, + 1708682306805, + 1708682336805, + 1708682366805, + 1708682396805, + 1708682426805, + 1708682456805, + 1708682486805, + 1708682516805, + 1708682546805, + 1708682576805, + 1708682606805, + 1708682636805, + 1708682666805, + 1708682696805, + 1708682726805, + 1708682756805, + 1708682786805, + 1708682816805, + 1708682846805, + 1708682876805, + 1708682906805, + 1708682936805, + 1708682966805, + 1708682996805, + 1708683026805, + 1708683056805, + 1708683086805, + 1708683116805, + 1708683146805, + 1708683176805, + 1708683206805, + 1708683236805, + 1708683266805, + 1708683296805, + 1708683326805, + 1708683356805, + 1708683386805, + 1708683416805, + 1708683446805, + 1708683476805, + 1708683506805, + 1708683536805, + 1708683566805, + 1708683596805, + 1708683626805, + 1708683656805, + 1708683686805, + 1708683716805, + 1708683746805, + 1708683776805, + 1708683806805, + 1708683836805, + 1708683866805, + 1708683896805, + 1708683926805, + 1708683956805, + 1708683986805, + 1708684016805, + 1708684046805, + 1708684076805, + 1708684106805, + 1708684136805, + 1708684166805, + 1708684196805, + 1708684226805, + 1708684256805, + 1708684286805, + 1708684316805, + 1708684346805, + 1708684376805, + 1708684406805, + 1708684436805, + 1708684466805, + 1708684496805, + 1708684526805, + 1708684556805, + 1708684586805, + 1708684616805, + 1708684646805, + 1708684676805, + 1708684706805, + 1708684736805, + 1708684766805, + 1708684796805, + 1708684826805, + 1708684856805, + 1708684886805, + 1708684916805, + 1708684946805, + 1708684976805, + 1708685006805, + 1708685036805, + 1708685066805, + 1708685096805, + 1708685126805, + 1708685156805, + 1708685186805, + 1708685216805, + 1708685246805, + 1708685276805, + 1708685306805, + 1708685336805, + 1708685366805, + 1708685396805, + 1708685426805, + 1708685456805, + 1708685486805, + 1708685516805, + 1708685546805, + 1708685576805, + 1708685606805, + 1708685636805, + 1708685666805, + 1708685696805, + 1708685726805, + 1708685756805, + 1708685786805, + 1708685816805, + 1708685846805, + 1708685876805, + 1708685906805, + 1708685936805, + 1708685966805, + 1708685996805, + 1708686026805, + 1708686056805, + 1708686086805, + 1708686116805, + 1708686146805, + 1708686176805, + 1708686206805, + 1708686236805, + 1708686266805, + 1708686296805, + 1708686326805, + 1708686356805, + 1708686386805, + 1708686416805, + 1708686446805, + 1708686476805, + 1708686506805, + 1708686536805, + 1708686566805, + 1708686596805, + 1708686626805, + 1708686656805, + 1708686686805, + 1708686716805, + 1708686746805, + 1708686776805, + 1708686806805, + 1708686836805, + 1708686866805, + 1708686896805, + 1708686926805, + 1708686956805, + 1708686986805, + 1708687016805, + 1708687046805, + 1708687076805, + 1708687106805, + 1708687136805, + 1708687166805, + 1708687196805, + 1708687226805, + 1708687256805, + 1708687286805, + 1708687316805, + 1708687346805, + 1708687376805, + 1708687406805, + 1708687436805, + 1708687466805, + 1708687496805, + 1708687526805, + 1708687556805, + 1708687586805, + 1708687616805, + 1708687646805, + 1708687676805, + 1708687706805, + 1708687736805, + 1708687766805, + 1708687796805, + 1708687826805, + 1708687856805, + 1708687886805, + 1708687916805, + 1708687946805, + 1708687976805, + 1708688006805, + 1708688036805, + 1708688066805, + 1708688096805, + 1708688126805, + 1708688156805, + 1708688186805, + 1708688216805, + 1708688246805, + 1708688276805, + 1708688306805, + 1708688336805, + 1708688366805, + 1708688396805, + 1708688426805, + 1708688456805, + 1708688486805, + 1708688516805, + 1708688546805, + 1708688576805, + 1708688606805, + 1708688636805, + 1708688666805, + 1708688696805, + 1708688726805, + 1708688756805, + 1708688786805, + 1708688816805, + 1708688846805, + 1708688876805, + 1708688906805, + 1708688936805, + 1708688966805, + 1708688996805, + 1708689026805, + 1708689056805, + 1708689086805, + 1708689116805, + 1708689146805, + 1708689176805, + 1708689206805, + 1708689236805, + 1708689266805, + 1708689296805, + 1708689326805, + 1708689356805, + 1708689386805, + 1708689416805, + 1708689446805, + 1708689476805, + 1708689506805, + 1708689536805, + 1708689566805, + 1708689596805, + 1708689626805, + 1708689656805, + 1708689686805, + 1708689716805, + 1708689746805, + 1708689776805, + 1708689806805, + 1708689836805, + 1708689866805, + 1708689896805, + 1708689926805, + 1708689956805, + 1708689986805, + 1708690016805, + 1708690046805, + 1708690076805, + 1708690106805, + 1708690136805, + 1708690166805, + 1708690196805, + 1708690226805, + 1708690256805, + 1708690286805, + 1708690316805, + 1708690346805, + 1708690376805, + 1708690406805, + 1708690436805, + 1708690466805, + 1708690496805, + 1708690526805, + 1708690556805, + 1708690586805, + 1708690616805, + 1708690646805, + 1708690676805, + 1708690706805, + 1708690736805, + 1708690766805, + 1708690796805, + 1708690826805, + 1708690856805, + 1708690886805, + 1708690916805, + 1708690946805, + 1708690976805, + 1708691006805, + 1708691036805, + 1708691066805, + 1708691096805, + 1708691126805, + 1708691156805, + 1708691186805, + 1708691216805, + 1708691246805, + 1708691276805, + 1708691306805, + 1708691336805, + 1708691366805, + 1708691396805, + 1708691426805, + 1708691456805, + 1708691486805, + 1708691516805, + 1708691546805, + 1708691576805, + 1708691606805, + 1708691636805, + 1708691666805, + 1708691696805, + 1708691726805, + 1708691756805, + 1708691786805, + 1708691816805, + 1708691846805, + 1708691876805, + 1708691906805, + 1708691936805, + 1708691966805, + 1708691996805, + 1708692026805, + 1708692056805, + 1708692086805, + 1708692116805, + 1708692146805, + 1708692176805, + 1708692206805, + 1708692236805, + 1708692266805, + 1708692296805, + 1708692326805, + 1708692356805, + 1708692386805, + 1708692416805, + 1708692446805, + 1708692476805, + 1708692506805, + 1708692536805, + 1708692566805, + 1708692596805, + 1708692626805, + 1708692656805, + 1708692686805, + 1708692716805, + 1708692746805, + 1708692776805, + 1708692806805, + 1708692836805, + 1708692866805, + 1708692896805, + 1708692926805, + 1708692956805, + 1708692986805, + 1708693016805, + 1708693046805, + 1708693076805, + 1708693106805, + 1708693136805, + 1708693166805, + 1708693196805, + 1708693226805, + 1708693256805, + 1708693286805, + 1708693316805, + 1708693346805, + 1708693376805, + 1708693406805, + 1708693436805, + 1708693466805, + 1708693496805, + 1708693526805, + 1708693556805, + 1708693586805, + 1708693616805, + 1708693646805, + 1708693676805, + 1708693706805, + 1708693736805, + 1708693766805, + 1708693796805, + 1708693826805, + 1708693856805, + 1708693886805, + 1708693916805, + 1708693946805, + 1708693976805, + 1708694006805, + 1708694036805, + 1708694066805, + 1708694096805, + 1708694126805, + 1708694156805, + 1708694186805, + 1708694216805, + 1708694246805, + 1708694276805, + 1708694306805, + 1708694336805, + 1708694366805, + 1708694396805, + 1708694426805, + 1708694456805, + 1708694486805, + 1708694516805, + 1708694546805, + 1708694576805, + 1708694606805, + 1708694636805, + 1708694666805, + 1708694696805, + 1708694726805, + 1708694756805, + 1708694786805, + 1708694816805, + 1708694846805, + 1708694876805, + 1708694906805, + 1708694936805, + 1708694966805, + 1708694996805, + 1708695026805, + 1708695056805, + 1708695086805, + 1708695116805, + 1708695146805, + 1708695176805, + 1708695206805, + 1708695236805, + 1708695266805, + 1708695296805, + 1708695326805, + 1708695356805, + 1708695386805, + 1708695416805, + 1708695446805, + 1708695476805, + 1708695506805, + 1708695536805, + 1708695566805, + 1708695596805, + 1708695626805, + 1708695656805, + 1708695686805, + 1708695716805, + 1708695746805, + 1708695776805, + 1708695806805, + 1708695836805, + 1708695866805, + 1708695896805, + 1708695926805, + 1708695956805, + 1708695986805, + 1708696016805, + 1708696046805, + 1708696076805, + 1708696106805, + 1708696136805, + 1708696166805, + 1708696196805, + 1708696226805, + 1708696256805, + 1708696286805, + 1708696316805, + 1708696346805, + 1708696376805, + 1708696406805, + 1708696436805, + 1708696466805, + 1708696496805, + 1708696526805, + 1708696556805, + 1708696586805, + 1708696616805, + 1708696646805, + 1708696676805, + 1708696706805, + 1708696736805, + 1708696766805, + 1708696796805, + 1708696826805, + 1708696856805, + 1708696886805, + 1708696916805, + 1708696946805, + 1708696976805, + 1708697006805, + 1708697036805, + 1708697066805, + 1708697096805, + 1708697126805, + 1708697156805, + 1708697186805, + 1708697216805, + 1708697246805, + 1708697276805, + 1708697306805, + 1708697336805, + 1708697366805, + 1708697396805, + 1708697426805, + 1708697456805, + 1708697486805, + 1708697516805, + 1708697546805, + 1708697576805, + 1708697606805, + 1708697636805, + 1708697666805, + 1708697696805, + 1708697726805, + 1708697756805, + 1708697786805, + 1708697816805, + 1708697846805, + 1708697876805, + 1708697906805, + 1708697936805, + 1708697966805, + 1708697996805, + 1708698026805, + 1708698056805, + 1708698086805, + 1708698116805, + 1708698146805, + 1708698176805, + 1708698206805, + 1708698236805, + 1708698266805, + 1708698296805, + 1708698326805, + 1708698356805, + 1708698386805, + 1708698416805, + 1708698446805, + 1708698476805, + 1708698506805, + 1708698536805, + 1708698566805, + 1708698596805, + 1708698626805, + 1708698656805, + 1708698686805, + 1708698716805, + 1708698746805, + 1708698776805, + 1708698806805, + 1708698836805, + 1708698866805, + 1708698896805, + 1708698926805, + 1708698956805, + 1708698986805, + 1708699016805, + 1708699046805, + 1708699076805, + 1708699106805, + 1708699136805, + 1708699166805, + 1708699196805, + 1708699226805, + 1708699256805, + 1708699286805, + 1708699316805, + 1708699346805, + 1708699376805, + 1708699406805, + 1708699436805, + 1708699466805, + 1708699496805, + 1708699526805, + 1708699556805, + 1708699586805, + 1708699616805, + 1708699646805, + 1708699676805, + 1708699706805, + 1708699736805, + 1708699766805, + 1708699796805, + 1708699826805, + 1708699856805, + 1708699886805, + 1708699916805, + 1708699946805, + 1708699976805, + 1708700006805, + 1708700036805, + 1708700066805, + 1708700096805, + 1708700126805, + 1708700156805, + 1708700186805, + 1708700216805, + 1708700246805, + 1708700276805, + 1708700306805, + 1708700336805, + 1708700366805, + 1708700396805, + 1708700426805, + 1708700456805, + 1708700486805, + 1708700516805, + 1708700546805, + 1708700576805, + 1708700606805, + 1708700636805, + 1708700666805, + 1708700696805, + 1708700726805, + 1708700756805, + 1708700786805, + 1708700816805, + 1708700846805, + 1708700876805, + 1708700906805 + ], + [ + 61.7880220958275, + 61.81270791445456, + 61.829208768453746, + 61.3952804521061, + 61.54378204663586, + 61.793292376739025, + 61.89508181687579, + 62.032346031223305, + 62.090954811114734, + 61.788446359641156, + 61.34681406228381, + 61.37147422434034, + 61.40948125782848, + 61.69144945060843, + 61.790001610516114, + 61.9726511399688, + 62.17186395369245, + 61.841593279449114, + 61.81351577982158, + 61.774548608665306, + 61.45071912098117, + 61.837381696515884, + 61.65059114296433, + 61.1939165193637, + 61.251406089255795, + 60.90456801094042, + 60.56801269725712, + 60.79736902333104, + 60.9367183948152, + 61.40785835680261, + 61.621326272755965, + 61.53478423246078, + 61.616180375313114, + 61.56950269911591, + 61.419724817297585, + 61.76631225002593, + 62.12897242834343, + 62.123394668856335, + 61.84384351878861, + 61.784342739352965, + 61.946359707479985, + 62.00854561243485, + 61.949378148238175, + 61.83251536870273, + 62.10046102360543, + 62.51955528279164, + 62.43194543555232, + 61.93563724102479, + 61.61222776112464, + 61.706572968014584, + 61.25653135192282, + 61.356339636867965, + 61.699918128409436, + 61.700832273918536, + 61.48680261436916, + 61.23885493750151, + 60.88064816100224, + 60.8061115971784, + 60.48689168723215, + 60.55420316390225, + 60.78326551379002, + 60.71763616746389, + 61.0384027799684, + 61.361681117105356, + 61.819694140841825, + 61.60303629180282, + 61.13531779096821, + 61.59247554276454, + 62.073700396192514, + 62.257393021269124, + 62.433793965222456, + 62.250955190991135, + 61.85027922321473, + 61.991414140632, + 62.103475488499456, + 62.1675085033716, + 61.81759701584563, + 61.44204189561965, + 61.39004247589699, + 61.84841370788845, + 62.01982884908544, + 62.29261477385842, + 62.1881407732118, + 61.77974858108549, + 61.30269030921595, + 61.72885233653658, + 62.160061928899516, + 62.13127060574461, + 61.99860014382346, + 62.2713524353439, + 62.45360209624644, + 62.45033536766769, + 62.74579940152534, + 62.652379007396135, + 62.50461375528075, + 62.4923739782267, + 62.87608071230181, + 62.979684959589086, + 63.376138214369306, + 63.66354651661235, + 63.77873383844567, + 64.02365055931571, + 63.57333739418103, + 63.569251641994995, + 63.51940188659398, + 63.81887126104792, + 64.10808860762592, + 64.26214829221084, + 63.81353904099011, + 63.792123977174654, + 64.09459044217124, + 64.49651926575704, + 64.87380353415439, + 65.22102686208456, + 65.49078940759729, + 65.83529933530703, + 66.06313506256244, + 66.36902912666964, + 66.78048161957578, + 66.85326316970041, + 67.14736719324404, + 67.55927886414139, + 67.497025942169, + 67.84593513490577, + 67.47441764273138, + 67.94871645670011, + 68.32729017349827, + 68.0857872436968, + 67.93500201308075, + 67.75781760651351, + 67.62321694227796, + 67.87687655718156, + 68.03974600191707, + 67.82627187210018, + 68.29863099170737, + 67.95842239244082, + 67.56173819267319, + 67.11089985276264, + 67.58721546400895, + 67.43817707268052, + 67.63734474285276, + 67.8608900819446, + 68.2491098921388, + 68.64222598287019, + 68.93436090180123, + 68.58516897681044, + 68.88556663186037, + 68.82509258379442, + 68.43122435581691, + 68.01151775860062, + 68.31539501569645, + 68.01224489043588, + 68.21383479637454, + 67.85864255481124, + 67.85285437130011, + 67.68770174333852, + 67.78834746198736, + 68.07096889676643, + 68.06340992932907, + 68.37116739265392, + 68.25606363201948, + 68.0308569092854, + 68.0279418148109, + 67.68837311892736, + 67.98015788941186, + 68.39001231797856, + 68.55810426314746, + 68.67055538403375, + 68.24669275435873, + 68.3542775530211, + 67.99792233705742, + 67.93848132742042, + 67.54327434886798, + 67.86541640645122, + 67.63715332453567, + 67.44863373545599, + 67.54029786855584, + 67.3799227903252, + 67.272800723832, + 67.65752571426705, + 67.27217330871126, + 67.36259068699385, + 67.6920166495926, + 67.99237921892899, + 68.00526928940994, + 67.67665255949264, + 67.82106088034847, + 68.22225474161398, + 68.17103508007338, + 68.1016199190692, + 67.9715626706774, + 68.32706440829391, + 67.87634330533211, + 67.97207720874553, + 67.87493382264455, + 67.38357737752105, + 66.94768029712087, + 66.67493510394992, + 66.48367657533245, + 66.77035937087237, + 66.87685661575208, + 66.68590889792685, + 67.11545823298368, + 67.39896920212514, + 67.34979904565203, + 67.19769898467558, + 67.45512207826779, + 67.07906680752531, + 67.41541723819202, + 67.15472798048341, + 67.15672773264464, + 67.6290223056695, + 68.11240707910342, + 68.40594352628086, + 67.92798893549167, + 67.46919856375305, + 67.4835115803936, + 67.63236807133978, + 67.17328415938867, + 67.24458272746313, + 66.84593455247185, + 67.01430262963748, + 67.05291762336604, + 67.23817875420809, + 66.98941509949245, + 66.68717338595964, + 67.12826784930103, + 66.74586515933792, + 67.12397362624425, + 66.91465424208462, + 66.68655917540693, + 66.19881496899525, + 66.68817057925634, + 66.37134623059349, + 66.596971028669, + 67.08641642499875, + 67.12758650919066, + 67.38518121414808, + 67.46997153732326, + 67.33145553844577, + 67.65363406004056, + 67.45595043797628, + 67.24978988019829, + 67.39677514651268, + 67.5978323405599, + 67.96140308646021, + 68.00477049936622, + 67.75104436464927, + 67.99988077010511, + 68.19366044789288, + 68.49848829432483, + 68.25947149341026, + 68.6317723773926, + 68.91668608614779, + 68.8159923502771, + 69.17513974647629, + 69.23356802652235, + 69.25309375298245, + 69.21125949874141, + 69.20726323550102, + 68.78019883289588, + 69.24667107728621, + 69.1153426259508, + 69.56206231608063, + 69.72141422867662, + 69.541238907092, + 69.81884141217625, + 69.53432369593423, + 69.43315031151812, + 69.01688148574168, + 68.90923934889648, + 69.13664462290991, + 69.31984528071725, + 69.14875943039056, + 69.48885652654923, + 69.88297168977773, + 69.42462273878934, + 69.12679413148601, + 68.98123233159377, + 68.7762758442149, + 68.48846507574687, + 68.02689832504595, + 68.02852643078998, + 67.555096330903, + 67.4639788904284, + 67.61277291577984, + 67.70121565906206, + 67.66817331556194, + 67.84767253849441, + 68.18538578924706, + 68.29860737971661, + 68.53693780239855, + 68.59722904625475, + 68.72061222893264, + 68.6709989466837, + 69.09400533816238, + 69.20295511428635, + 69.04258759148102, + 68.77139467473914, + 68.57756213054044, + 68.67449080482191, + 68.60860533532343, + 69.01676017621124, + 69.3052161196497, + 68.89017381442457, + 68.87423335356772, + 68.94718162265079, + 69.07199142609447, + 68.79769510366016, + 68.65106890757201, + 68.77703094552813, + 68.28258034480257, + 68.39479364216955, + 68.34220719427985, + 68.64253416645396, + 68.87725555362057, + 68.5131252571485, + 68.89127035251008, + 68.67886068136877, + 68.4447624537287, + 68.00181105736998, + 68.16998112143412, + 68.43591872875314, + 68.02705208136817, + 68.45211203302853, + 68.53289570629535, + 68.58200283313724, + 68.25718933019785, + 68.36370956465593, + 68.05020228727913, + 68.50658655636543, + 68.66449948753682, + 68.2241732330651, + 68.09791466418139, + 67.88940531760399, + 68.36978817923638, + 67.96433264274425, + 68.36349840881765, + 68.48435193949715, + 68.79844380614031, + 69.02017361165895, + 68.52624119834393, + 68.74005315812674, + 68.76067653657759, + 68.27918960695276, + 68.65714329915559, + 68.42872809873309, + 67.98192094490678, + 68.02723949195821, + 68.36423058076824, + 68.71132274325691, + 68.6730162618873, + 68.2039400216969, + 67.86554691576616, + 67.49988053949725, + 67.16307215146469, + 67.0353669125758, + 67.25486895820083, + 66.95629780399439, + 67.11477592840751, + 66.64323746050167, + 66.20269172026232, + 66.48026858749327, + 66.4824015740555, + 66.09931551662274, + 66.52915019033718, + 66.45576884782787, + 66.24667785942938, + 65.81418399593981, + 65.5611498094969, + 65.3398959293035, + 65.77646026507297, + 65.39346792956597, + 65.41692492067247, + 65.80888038895401, + 66.01134945900266, + 65.80681809031556, + 65.32295296805074, + 65.37373854104783, + 64.93533382859144, + 64.7705026812803, + 65.17813748381224, + 65.361732144628, + 64.9021692008158, + 64.7544901225187, + 64.89471070898715, + 64.74868721773261, + 65.00087272748908, + 65.13124433830268, + 64.86532668113782, + 64.51108629312537, + 64.48208116580882, + 64.86340417937541, + 64.5927354669956, + 64.1183990008181, + 63.66603997870095, + 63.670535114339415, + 63.179312479687646, + 62.71414451358941, + 62.349677869382184, + 62.73321111245177, + 62.63668992149067, + 62.246656820357686, + 62.12151749467506, + 62.09114940207692, + 62.13652644719604, + 62.59170540130276, + 62.28435878005047, + 62.62555470862962, + 62.73559453227453, + 62.63492310358647, + 62.99493118502586, + 63.2621260239913, + 62.99279716454684, + 62.8629723908099, + 63.01324605242161, + 63.27456767760901, + 63.11585082867133, + 63.04279509050621, + 63.10999097814922, + 63.544265738869036, + 63.11822935137409, + 63.01523903936018, + 63.20403674621687, + 62.83896086980938, + 62.41843196460615, + 62.11985404869429, + 62.07986319614809, + 61.99277704632526, + 61.668764434861785, + 61.24484474074755, + 61.461440830656386, + 61.276838934561326, + 61.190724244624434, + 61.55613660124493, + 61.12078454699415, + 61.3276958600818, + 61.6042219184118, + 61.25513892816126, + 61.31664892177688, + 61.688070650858535, + 62.01190639528168, + 62.08869564629636, + 61.97211569824653, + 62.06419901170042, + 62.32586483758532, + 62.23902878995992, + 62.10813808603461, + 61.85578175807045, + 62.23028871528028, + 62.632050281179744, + 62.94816419819628, + 62.73043921369783, + 62.23627146727455, + 62.584832680453275, + 62.62993353336442, + 62.8749075179418, + 62.48040775408503, + 62.21373335340891, + 61.79955494265226, + 61.833015907179636, + 61.39273179502193, + 61.269508387088344, + 61.72530078527864, + 62.09495330426252, + 62.151597131318645, + 62.03375578347783, + 62.417839543433374, + 62.857582366978384, + 62.57434410206618, + 63.025461247334185, + 62.891637883802545, + 62.74129737438404, + 62.686344200077194, + 62.74668907124072, + 62.8988624768576, + 62.60573732388666, + 63.025949401766745, + 62.67167444177004, + 62.90064380635685, + 62.864966632927896, + 62.75573606469665, + 62.64819512833622, + 62.568258206957815, + 62.60577268655998, + 62.15762551315059, + 62.567239861872935, + 62.2060758300364, + 62.31900525191699, + 62.28916506290531, + 62.44905922260444, + 62.461296429876256, + 62.500385909925505, + 62.650801268022704, + 62.56666212391569, + 62.40046878730333, + 62.094243157050244, + 62.53663695990193, + 62.42300679544488, + 62.36921559899188, + 62.24670139180489, + 62.569517596988945, + 62.66647211282815, + 62.665771463959715, + 62.876380887882625, + 62.45928337880216, + 62.909344895815984, + 62.792949925824054, + 62.83068709163355, + 62.69318202524612, + 62.87621607310353, + 63.31283919698538, + 63.25629003985129, + 63.705604438529726, + 63.273909526061956, + 63.5892070912608, + 63.25172069842234, + 63.29295380191922, + 63.37827406047424, + 63.40692971848919, + 62.91617622008834, + 62.78539371994352, + 62.67023463643756, + 62.778172553545886, + 62.47010093156481, + 62.73229570857713, + 62.59545419552364, + 63.021765325598885, + 63.12625341655425, + 62.78539970673421, + 62.48947067386955, + 62.50019409861797, + 62.27827076256643, + 62.32133231940964, + 62.28201148707485, + 62.75074499118775, + 62.2850034814543, + 62.11551149639342, + 62.19275216451308, + 61.99131816833137, + 61.53708598957499, + 61.935909883441674, + 61.982544659526965, + 62.47356745991423, + 62.54325753022373, + 62.146857201138765, + 62.189218538018835, + 62.06268691181029, + 62.33603183556959, + 62.82869197777662, + 63.18597742858942, + 63.032993740715966, + 63.5325845753775, + 63.562424373715885, + 63.50147245681481, + 63.9167851513779, + 64.41348447594058, + 64.47641931732102, + 64.00422787602398, + 63.84372934402268, + 63.57536630107787, + 64.06767133087304, + 63.857109831163605, + 63.594856285335126, + 64.01811161431772, + 64.07634398750827, + 64.53914449236566, + 64.0503925198368, + 63.65098131727389, + 63.68701372362301, + 63.69177696813634, + 63.37477814620089, + 62.9056011078514, + 62.51297543133976, + 62.59250225336332, + 62.80712544689635, + 62.841367040210486, + 63.01245999144349, + 63.05987075936997, + 62.7064932753452, + 62.53562962324097, + 62.31063278405174, + 62.266535846784436, + 62.302218124559445, + 62.342098988884466, + 61.85031656038063, + 62.236466943962625, + 62.38666354433638, + 62.50448443527158, + 62.2386149786552, + 62.43706094747305, + 62.48167927367151, + 62.53256313135768, + 62.78282604117919, + 62.610692060658806, + 62.60559562844521, + 62.522478905756024, + 62.11039441006909, + 62.455676051055406, + 62.12208142671207, + 62.08989132214651, + 61.60556028504288, + 61.72080384449528, + 61.67203415718332, + 61.300028102691506, + 61.2882234681282, + 61.67414171824772, + 61.663919195939215, + 61.82126261684866, + 62.14747753168045, + 61.90000454947883, + 61.550477655414085, + 61.823665895055534, + 62.2914692558774, + 61.97827489307881, + 62.373656454593686, + 62.77509964777066, + 63.03123026432718, + 62.71959998560016, + 62.798641799535915, + 62.36309802737797, + 62.187803490902276, + 61.86629603436246, + 61.51332614924758, + 61.670529134596514, + 62.01614193494398, + 62.42759829956865, + 62.04049015814663, + 62.4879050225676, + 62.534578908118796, + 62.53729183335963, + 62.507213724278294, + 62.91741156445245, + 62.80078558969012, + 62.89530940332275, + 62.82952275179085, + 62.931001539540134, + 62.715893011718826, + 63.176668587903144, + 63.25804897932602, + 63.715274804489724, + 63.25110762353138, + 63.703759539930466, + 63.9121877763375, + 63.74483403967367, + 63.278090432146044, + 63.25689283100131, + 63.5587547259249, + 63.99611056226184, + 63.711033213960846, + 63.61430481648302, + 63.37762519043254, + 63.825084284030204, + 63.65971618383464, + 64.11513361026066, + 64.55773804769903, + 64.72114634405787, + 64.92113863156139, + 64.74299967907277, + 64.58315181550863, + 64.53895512079164, + 64.29203322638713, + 64.35539787981175, + 64.51347297698413, + 64.41240397641245, + 64.37002365296716, + 64.54885534394022, + 65.0387758477243, + 64.77700441309366, + 65.18362739291737, + 65.05949296204716, + 64.57684960686204, + 64.47443633413799, + 64.25660237904727, + 64.56848853603353, + 64.13857108098799, + 63.779464548765795, + 63.940686810035814, + 63.47280572727399, + 63.75027671584932, + 63.72842205520389, + 63.28631208752196, + 63.54806381048302, + 63.89145142689777, + 63.77801877620565, + 64.22035568724904, + 63.99613288560804, + 64.03027098363421, + 64.45100338093056, + 64.4954103610469, + 64.0379570128468, + 64.509809400983, + 64.24776908391132, + 64.18308085450447, + 64.02686567211323, + 64.00949969057655, + 64.08790624904579, + 64.44413148646105, + 64.436667344197, + 64.925560935662, + 64.4380208837763, + 64.63611397061874, + 64.53720467943039, + 64.89043109965093, + 65.02933526203901, + 65.38083597755491, + 65.63733460002958, + 66.04889884599933, + 66.15611674378638, + 66.58017724018646, + 66.13733327264003, + 65.69321107501534, + 65.92059175869956, + 65.73905913370584, + 65.39714875503125, + 65.31355908128221, + 65.75886616744013, + 66.05775873128395, + 65.93022978097021, + 66.3107650269844 + ] + ] + }, + "schema": { + "fields": [ + { + "config": { + "interval": 30000 + }, + "name": "time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": {}, + "name": "A-hehwzd", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "meta": { + "custom": { + "customStat": 10 + }, + "typeVersion": [ + 0, + 0 + ] + }, + "refId": "A" + } + } + ] + } + ], + "title": "Canvas Enhanced Data Links", + "transformations": [ + { + "id": "calculateField", + "options": { + "alias": "Count (transformation)", + "mode": "reduceRow", + "reduce": { + "include": [ + "A-series" + ], + "reducer": "count" + } + } + } + ], + "type": "canvas" + } + ], + "schemaVersion": 39, + "tags": [ + "gdev", + "panel-tests", + "canvas" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timeRangeUpdatedDuringEditOrView": false, + "timepicker": {}, + "timezone": "browser", + "title": "Panel Tests - Canvas Datalinks", + "uid": "adf95uwu7w1s0e", + "version": 26, + "weekStart": "" +} \ No newline at end of file diff --git a/devenv/jsonnet/dev-dashboards.libsonnet b/devenv/jsonnet/dev-dashboards.libsonnet index d9fcd5ef9a5..695916ff1a8 100644 --- a/devenv/jsonnet/dev-dashboards.libsonnet +++ b/devenv/jsonnet/dev-dashboards.libsonnet @@ -21,6 +21,7 @@ "barchart-tooltips-legends": (import '../dev-dashboards/panel-barchart/barchart-tooltips-legends.json'), "candlestick": (import '../dev-dashboards/panel-candlestick/candlestick.json'), "canvas-connection-examples": (import '../dev-dashboards/panel-canvas/canvas-connection-examples.json'), + "canvas-datalinks": (import '../dev-dashboards/panel-canvas/canvas-datalinks.json'), "canvas-examples": (import '../dev-dashboards/panel-canvas/canvas-examples.json'), "color_modes": (import '../dev-dashboards/panel-common/color_modes.json'), "config-from-query": (import '../dev-dashboards/transforms/config-from-query.json'), diff --git a/public/app/features/canvas/element.ts b/public/app/features/canvas/element.ts index 0e51e4a8815..cdd1939f1a7 100644 --- a/public/app/features/canvas/element.ts +++ b/public/app/features/canvas/element.ts @@ -72,7 +72,7 @@ export interface CanvasElementItem extends RegistryI /** The default width/height to use when adding */ defaultSize?: Placement; - prepareData?: (ctx: DimensionContext, cfg: TConfig) => TData; + prepareData?: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => TData; /** Component used to draw */ display: ComponentType>; diff --git a/public/app/features/canvas/elements/button.tsx b/public/app/features/canvas/elements/button.tsx index 18cf97713a4..a6e8980e7c3 100644 --- a/public/app/features/canvas/elements/button.tsx +++ b/public/app/features/canvas/elements/button.tsx @@ -13,7 +13,7 @@ import { ButtonStyleConfig, ButtonStyleEditor } from 'app/plugins/panel/canvas/e import { callApi } from 'app/plugins/panel/canvas/editor/element/utils'; import { HttpRequestMethod } from 'app/plugins/panel/canvas/panelcfg.gen'; -import { CanvasElementItem, CanvasElementProps, defaultLightTextColor } from '../element'; +import { CanvasElementItem, CanvasElementOptions, CanvasElementProps, defaultLightTextColor } from '../element'; import { Align, TextConfig, TextData } from '../types'; interface ButtonData extends Omit { @@ -130,30 +130,32 @@ export const buttonItem: CanvasElementItem = { }), // Called when data changes - prepareData: (ctx: DimensionContext, cfg: ButtonConfig) => { - const getCfgApi = () => { - if (cfg?.api) { - cfg.api = { - ...cfg.api, - method: cfg.api.method ?? defaultApiConfig.method, - contentType: cfg.api.contentType ?? defaultApiConfig.contentType, + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const buttonConfig = elementOptions.config; + + const getAPIConfig = () => { + if (buttonConfig?.api) { + buttonConfig.api = { + ...buttonConfig.api, + method: buttonConfig.api.method ?? defaultApiConfig.method, + contentType: buttonConfig.api.contentType ?? defaultApiConfig.contentType, }; - return cfg.api; + return buttonConfig.api; } return undefined; }; const data: ButtonData = { - text: cfg?.text ? ctx.getText(cfg.text).value() : '', - align: cfg.align ?? Align.Center, - size: cfg.size ?? 14, - api: getCfgApi(), - style: cfg?.style ?? defaultStyleConfig, + text: buttonConfig?.text ? dimensionContext.getText(buttonConfig.text).value() : '', + align: buttonConfig?.align ?? Align.Center, + size: buttonConfig?.size ?? 14, + api: getAPIConfig(), + style: buttonConfig?.style ?? defaultStyleConfig, }; - if (cfg.color) { - data.color = ctx.getColor(cfg.color).value(); + if (buttonConfig?.color) { + data.color = dimensionContext.getColor(buttonConfig.color).value(); } return data; diff --git a/public/app/features/canvas/elements/droneFront.tsx b/public/app/features/canvas/elements/droneFront.tsx index 9ce31d8f8ac..d96ce3899e7 100644 --- a/public/app/features/canvas/elements/droneFront.tsx +++ b/public/app/features/canvas/elements/droneFront.tsx @@ -7,7 +7,7 @@ import { useStyles2 } from '@grafana/ui'; import { DimensionContext } from 'app/features/dimensions'; import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; -import { CanvasElementItem, CanvasElementProps, defaultBgColor } from '../element'; +import { CanvasElementItem, CanvasElementOptions, CanvasElementProps, defaultBgColor } from '../element'; interface DroneFrontData { rollAngle?: number; @@ -97,9 +97,11 @@ export const droneFrontItem: CanvasElementItem = { }), // Called when data changes - prepareData: (ctx: DimensionContext, cfg: DroneFrontConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const droneFrontConfig = elementOptions.config; + const data: DroneFrontData = { - rollAngle: cfg?.rollAngle ? ctx.getScalar(cfg.rollAngle).value() : 0, + rollAngle: droneFrontConfig?.rollAngle ? dimensionContext.getScalar(droneFrontConfig.rollAngle).value() : 0, }; return data; diff --git a/public/app/features/canvas/elements/droneSide.tsx b/public/app/features/canvas/elements/droneSide.tsx index 8ae6fcc6a21..cc1821ad63f 100644 --- a/public/app/features/canvas/elements/droneSide.tsx +++ b/public/app/features/canvas/elements/droneSide.tsx @@ -7,7 +7,7 @@ import { useStyles2 } from '@grafana/ui'; import { DimensionContext } from 'app/features/dimensions'; import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; -import { CanvasElementItem, CanvasElementProps, defaultBgColor } from '../element'; +import { CanvasElementItem, CanvasElementOptions, CanvasElementProps, defaultBgColor } from '../element'; interface DroneSideData { pitchAngle?: number; @@ -96,9 +96,11 @@ export const droneSideItem: CanvasElementItem = { }), // Called when data changes - prepareData: (ctx: DimensionContext, cfg: DroneSideConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const droneSideConfig = elementOptions.config; + const data: DroneSideData = { - pitchAngle: cfg?.pitchAngle ? ctx.getScalar(cfg.pitchAngle).value() : 0, + pitchAngle: droneSideConfig?.pitchAngle ? dimensionContext.getScalar(droneSideConfig.pitchAngle).value() : 0, }; return data; diff --git a/public/app/features/canvas/elements/droneTop.tsx b/public/app/features/canvas/elements/droneTop.tsx index d1fb4174cbb..f4c2bff38f7 100644 --- a/public/app/features/canvas/elements/droneTop.tsx +++ b/public/app/features/canvas/elements/droneTop.tsx @@ -7,7 +7,7 @@ import { useStyles2 } from '@grafana/ui'; import { DimensionContext } from 'app/features/dimensions'; import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; -import { CanvasElementItem, CanvasElementProps, defaultBgColor } from '../element'; +import { CanvasElementItem, CanvasElementOptions, CanvasElementProps, defaultBgColor } from '../element'; interface DroneTopData { bRightRotorRPM?: number; @@ -102,13 +102,23 @@ export const droneTopItem: CanvasElementItem = { }), // Called when data changes - prepareData: (ctx: DimensionContext, cfg: DroneTopConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const droneTopConfig = elementOptions.config; + const data: DroneTopData = { - bRightRotorRPM: cfg?.bRightRotorRPM ? ctx.getScalar(cfg.bRightRotorRPM).value() : 0, - bLeftRotorRPM: cfg?.bLeftRotorRPM ? ctx.getScalar(cfg.bLeftRotorRPM).value() : 0, - fRightRotorRPM: cfg?.fRightRotorRPM ? ctx.getScalar(cfg.fRightRotorRPM).value() : 0, - fLeftRotorRPM: cfg?.fLeftRotorRPM ? ctx.getScalar(cfg.fLeftRotorRPM).value() : 0, - yawAngle: cfg?.yawAngle ? ctx.getScalar(cfg.yawAngle).value() : 0, + bRightRotorRPM: droneTopConfig?.bRightRotorRPM + ? dimensionContext.getScalar(droneTopConfig.bRightRotorRPM).value() + : 0, + bLeftRotorRPM: droneTopConfig?.bLeftRotorRPM + ? dimensionContext.getScalar(droneTopConfig.bLeftRotorRPM).value() + : 0, + fRightRotorRPM: droneTopConfig?.fRightRotorRPM + ? dimensionContext.getScalar(droneTopConfig.fRightRotorRPM).value() + : 0, + fLeftRotorRPM: droneTopConfig?.fLeftRotorRPM + ? dimensionContext.getScalar(droneTopConfig.fLeftRotorRPM).value() + : 0, + yawAngle: droneTopConfig?.yawAngle ? dimensionContext.getScalar(droneTopConfig.yawAngle).value() : 0, }; return data; diff --git a/public/app/features/canvas/elements/ellipse.tsx b/public/app/features/canvas/elements/ellipse.tsx index c16b1cf057c..02663bb344e 100644 --- a/public/app/features/canvas/elements/ellipse.tsx +++ b/public/app/features/canvas/elements/ellipse.tsx @@ -8,7 +8,13 @@ import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimen import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor'; import { getDataLinks } from 'app/plugins/panel/canvas/utils'; -import { CanvasElementItem, CanvasElementProps, defaultBgColor, defaultTextColor } from '../element'; +import { + CanvasElementItem, + CanvasElementOptions, + CanvasElementProps, + defaultBgColor, + defaultTextColor, +} from '../element'; import { Align, VAlign, EllipseConfig, EllipseData } from '../types'; class EllipseDisplay extends PureComponent> { @@ -80,26 +86,28 @@ export const ellipseItem: CanvasElementItem = { }, }), - prepareData: (ctx: DimensionContext, cfg: EllipseConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const ellipseConfig = elementOptions.config; + const data: EllipseData = { - width: cfg.width, - text: cfg.text ? ctx.getText(cfg.text).value() : '', - align: cfg.align ?? Align.Center, - valign: cfg.valign ?? VAlign.Middle, - size: cfg.size, + width: ellipseConfig?.width, + text: ellipseConfig?.text ? dimensionContext.getText(ellipseConfig.text).value() : '', + align: ellipseConfig?.align ?? Align.Center, + valign: ellipseConfig?.valign ?? VAlign.Middle, + size: ellipseConfig?.size, }; - if (cfg.backgroundColor) { - data.backgroundColor = ctx.getColor(cfg.backgroundColor).value(); + if (ellipseConfig?.backgroundColor) { + data.backgroundColor = dimensionContext.getColor(ellipseConfig.backgroundColor).value(); } - if (cfg.borderColor) { - data.borderColor = ctx.getColor(cfg.borderColor).value(); + if (ellipseConfig?.borderColor) { + data.borderColor = dimensionContext.getColor(ellipseConfig.borderColor).value(); } - if (cfg.color) { - data.color = ctx.getColor(cfg.color).value(); + if (ellipseConfig?.color) { + data.color = dimensionContext.getColor(ellipseConfig.color).value(); } - data.links = getDataLinks(ctx, cfg, data.text); + data.links = getDataLinks(dimensionContext, elementOptions, data.text); return data; }, diff --git a/public/app/features/canvas/elements/icon.tsx b/public/app/features/canvas/elements/icon.tsx index 2f5eec04394..b64996b197a 100644 --- a/public/app/features/canvas/elements/icon.tsx +++ b/public/app/features/canvas/elements/icon.tsx @@ -2,13 +2,15 @@ import { css } from '@emotion/css'; import { isString } from 'lodash'; import React, { CSSProperties } from 'react'; +import { LinkModel } from '@grafana/data'; import { ColorDimensionConfig, ResourceDimensionConfig, ResourceDimensionMode } from '@grafana/schema'; import { SanitizedSVG } from 'app/core/components/SVG/SanitizedSVG'; import { getPublicOrAbsoluteUrl } from 'app/features/dimensions'; import { DimensionContext } from 'app/features/dimensions/context'; import { ColorDimensionEditor, ResourceDimensionEditor } from 'app/features/dimensions/editors'; +import { getDataLinks } from 'app/plugins/panel/canvas/utils'; -import { CanvasElementItem, CanvasElementProps, defaultBgColor } from '../element'; +import { CanvasElementItem, CanvasElementOptions, CanvasElementProps, defaultBgColor } from '../element'; import { LineConfig } from '../types'; export interface IconConfig { @@ -22,6 +24,7 @@ interface IconData { fill: string; strokeColor?: string; stroke?: number; + links?: LinkModel[]; } // When a stoke is defined, we want the path to be in page units @@ -80,10 +83,12 @@ export const iconItem: CanvasElementItem = { }), // Called when data changes - prepareData: (ctx: DimensionContext, cfg: IconConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const iconConfig = elementOptions.config; + let path: string | undefined = undefined; - if (cfg.path) { - path = ctx.getResource(cfg.path).value(); + if (iconConfig?.path) { + path = dimensionContext.getResource(iconConfig.path).value(); } if (!path || !isString(path)) { path = getPublicOrAbsoluteUrl('img/icons/unicons/question-circle.svg'); @@ -91,15 +96,18 @@ export const iconItem: CanvasElementItem = { const data: IconData = { path, - fill: cfg.fill ? ctx.getColor(cfg.fill).value() : defaultBgColor, + fill: iconConfig?.fill ? dimensionContext.getColor(iconConfig.fill).value() : defaultBgColor, }; - if (cfg.stroke?.width && cfg.stroke.color) { - if (cfg.stroke.width > 0) { - data.stroke = cfg.stroke?.width; - data.strokeColor = ctx.getColor(cfg.stroke.color).value(); + if (iconConfig?.stroke?.width && iconConfig?.stroke.color) { + if (iconConfig.stroke.width > 0) { + data.stroke = iconConfig.stroke?.width; + data.strokeColor = dimensionContext.getColor(iconConfig.stroke.color).value(); } } + + data.links = getDataLinks(dimensionContext, elementOptions, data.path); + return data; }, diff --git a/public/app/features/canvas/elements/metricValue.tsx b/public/app/features/canvas/elements/metricValue.tsx index 76ed7a01f1a..1bcc39f2808 100644 --- a/public/app/features/canvas/elements/metricValue.tsx +++ b/public/app/features/canvas/elements/metricValue.tsx @@ -13,7 +13,13 @@ import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimen import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor'; import { getDataLinks } from 'app/plugins/panel/canvas/utils'; -import { CanvasElementItem, CanvasElementProps, defaultBgColor, defaultTextColor } from '../element'; +import { + CanvasElementItem, + CanvasElementOptions, + CanvasElementProps, + defaultBgColor, + defaultTextColor, +} from '../element'; import { ElementState } from '../runtime/element'; import { Align, TextConfig, TextData, VAlign } from '../types'; @@ -171,19 +177,21 @@ export const metricValueItem: CanvasElementItem = { }, }), - prepareData: (ctx: DimensionContext, cfg: TextConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const textConfig = elementOptions.config; + const data: TextData = { - text: cfg.text ? ctx.getText(cfg.text).value() : '', - align: cfg.align ?? Align.Center, - valign: cfg.valign ?? VAlign.Middle, - size: cfg.size, + text: textConfig?.text ? dimensionContext.getText(textConfig.text).value() : '', + align: textConfig?.align ?? Align.Center, + valign: textConfig?.valign ?? VAlign.Middle, + size: textConfig?.size, }; - if (cfg.color) { - data.color = ctx.getColor(cfg.color).value(); + if (textConfig?.color) { + data.color = dimensionContext.getColor(textConfig.color).value(); } - data.links = getDataLinks(ctx, cfg, data.text); + data.links = getDataLinks(dimensionContext, elementOptions, data.text); return data; }, diff --git a/public/app/features/canvas/elements/rectangle.tsx b/public/app/features/canvas/elements/rectangle.tsx index c91e86dcf17..fcadaddc857 100644 --- a/public/app/features/canvas/elements/rectangle.tsx +++ b/public/app/features/canvas/elements/rectangle.tsx @@ -9,7 +9,13 @@ import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimen import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor'; import { getDataLinks } from 'app/plugins/panel/canvas/utils'; -import { CanvasElementItem, CanvasElementProps, defaultBgColor, defaultTextColor } from '../element'; +import { + CanvasElementItem, + CanvasElementOptions, + CanvasElementProps, + defaultBgColor, + defaultTextColor, +} from '../element'; import { Align, TextConfig, TextData, VAlign } from '../types'; class RectangleDisplay extends PureComponent> { @@ -70,19 +76,21 @@ export const rectangleItem: CanvasElementItem = { }), // Called when data changes - prepareData: (ctx: DimensionContext, cfg: TextConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const textConfig = elementOptions.config; + const data: TextData = { - text: cfg.text ? ctx.getText(cfg.text).value() : '', - align: cfg.align ?? Align.Center, - valign: cfg.valign ?? VAlign.Middle, - size: cfg.size, + text: textConfig?.text ? dimensionContext.getText(textConfig.text).value() : '', + align: textConfig?.align ?? Align.Center, + valign: textConfig?.valign ?? VAlign.Middle, + size: textConfig?.size, }; - if (cfg.color) { - data.color = ctx.getColor(cfg.color).value(); + if (textConfig?.color) { + data.color = dimensionContext.getColor(textConfig.color).value(); } - data.links = getDataLinks(ctx, cfg, data.text); + data.links = getDataLinks(dimensionContext, elementOptions, data.text); return data; }, diff --git a/public/app/features/canvas/elements/server/server.tsx b/public/app/features/canvas/elements/server/server.tsx index aaee1ea6336..dcd8c1393a0 100644 --- a/public/app/features/canvas/elements/server/server.tsx +++ b/public/app/features/canvas/elements/server/server.tsx @@ -1,13 +1,14 @@ import { css } from '@emotion/css'; import React from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; +import { GrafanaTheme2, LinkModel } from '@grafana/data'; import { ColorDimensionConfig, ScalarDimensionConfig } from '@grafana/schema'; import config from 'app/core/config'; import { DimensionContext } from 'app/features/dimensions'; import { ColorDimensionEditor, ScalarDimensionEditor } from 'app/features/dimensions/editors'; +import { getDataLinks } from 'app/plugins/panel/canvas/utils'; -import { CanvasElementItem, CanvasElementProps } from '../../element'; +import { CanvasElementItem, CanvasElementOptions, CanvasElementProps } from '../../element'; import { ServerDatabase } from './types/database'; import { ServerSingle } from './types/single'; @@ -26,6 +27,7 @@ export interface ServerData { statusColor?: string; bulbColor?: string; type: ServerType; + links?: LinkModel[]; } enum ServerType { @@ -85,14 +87,20 @@ export const serverItem: CanvasElementItem = { }), // Called when data changes - prepareData: (ctx: DimensionContext, cfg: ServerConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const serverConfig = elementOptions.config; + const data: ServerData = { - blinkRate: cfg?.blinkRate ? ctx.getScalar(cfg.blinkRate).value() : 0, - statusColor: cfg?.statusColor ? ctx.getColor(cfg.statusColor).value() : 'transparent', - bulbColor: cfg?.bulbColor ? ctx.getColor(cfg.bulbColor).value() : 'green', - type: cfg.type, + blinkRate: serverConfig?.blinkRate ? dimensionContext.getScalar(serverConfig.blinkRate).value() : 0, + statusColor: serverConfig?.statusColor + ? dimensionContext.getColor(serverConfig.statusColor).value() + : 'transparent', + bulbColor: serverConfig?.bulbColor ? dimensionContext.getColor(serverConfig.bulbColor).value() : 'green', + type: serverConfig?.type ?? ServerType.Single, }; + data.links = getDataLinks(dimensionContext, elementOptions, data.statusColor); + return data; }, diff --git a/public/app/features/canvas/elements/text.tsx b/public/app/features/canvas/elements/text.tsx index 3abd83d8d7c..5f6fb6078f3 100644 --- a/public/app/features/canvas/elements/text.tsx +++ b/public/app/features/canvas/elements/text.tsx @@ -10,7 +10,7 @@ import { ColorDimensionEditor } from 'app/features/dimensions/editors/ColorDimen import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor'; import { getDataLinks } from '../../../plugins/panel/canvas/utils'; -import { CanvasElementItem, CanvasElementProps, defaultThemeTextColor } from '../element'; +import { CanvasElementItem, CanvasElementOptions, CanvasElementProps, defaultThemeTextColor } from '../element'; import { ElementState } from '../runtime/element'; import { Align, TextConfig, TextData, VAlign } from '../types'; @@ -149,19 +149,21 @@ export const textItem: CanvasElementItem = { }, }), - prepareData: (ctx: DimensionContext, cfg: TextConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const textConfig = elementOptions.config; + const data: TextData = { - text: cfg.text ? ctx.getText(cfg.text).value() : '', - align: cfg.align ?? Align.Center, - valign: cfg.valign ?? VAlign.Middle, - size: cfg.size, + text: textConfig?.text ? dimensionContext.getText(textConfig.text).value() : '', + align: textConfig?.align ?? Align.Center, + valign: textConfig?.valign ?? VAlign.Middle, + size: textConfig?.size, }; - if (cfg.color) { - data.color = ctx.getColor(cfg.color).value(); + if (textConfig?.color) { + data.color = dimensionContext.getColor(textConfig.color).value(); } - data.links = getDataLinks(ctx, cfg, data.text); + data.links = getDataLinks(dimensionContext, elementOptions, data.text); return data; }, diff --git a/public/app/features/canvas/elements/windTurbine.tsx b/public/app/features/canvas/elements/windTurbine.tsx index 1d90339e204..1ea10e13a33 100644 --- a/public/app/features/canvas/elements/windTurbine.tsx +++ b/public/app/features/canvas/elements/windTurbine.tsx @@ -1,16 +1,18 @@ import { css } from '@emotion/css'; import React from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; +import { GrafanaTheme2, LinkModel } from '@grafana/data'; import { ScalarDimensionConfig } from '@grafana/schema'; import { useStyles2 } from '@grafana/ui'; import { DimensionContext } from 'app/features/dimensions'; import { ScalarDimensionEditor } from 'app/features/dimensions/editors'; +import { getDataLinks } from 'app/plugins/panel/canvas/utils'; -import { CanvasElementItem, CanvasElementProps, defaultBgColor } from '../element'; +import { CanvasElementItem, CanvasElementOptions, CanvasElementProps, defaultBgColor } from '../element'; interface WindTurbineData { rpm?: number; + links?: LinkModel[]; } interface WindTurbineConfig { @@ -92,11 +94,15 @@ export const windTurbineItem: CanvasElementItem = { }), // Called when data changes - prepareData: (ctx: DimensionContext, cfg: WindTurbineConfig) => { + prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions) => { + const windTurbineConfig = elementOptions.config; + const data: WindTurbineData = { - rpm: cfg?.rpm ? ctx.getScalar(cfg.rpm).value() : 0, + rpm: windTurbineConfig?.rpm ? dimensionContext.getScalar(windTurbineConfig.rpm).value() : 0, }; + data.links = getDataLinks(dimensionContext, elementOptions, `${data.rpm}`); + return data; }, diff --git a/public/app/features/canvas/runtime/element.tsx b/public/app/features/canvas/runtime/element.tsx index f78e7049d39..77d6158a47c 100644 --- a/public/app/features/canvas/runtime/element.tsx +++ b/public/app/features/canvas/runtime/element.tsx @@ -296,7 +296,7 @@ export class ElementState implements LayerElement { updateData(ctx: DimensionContext) { if (this.item.prepareData) { - this.data = this.item.prepareData(ctx, this.options.config); + this.data = this.item.prepareData(ctx, this.options); this.revId++; // rerender } diff --git a/public/app/plugins/panel/canvas/utils.ts b/public/app/plugins/panel/canvas/utils.ts index f55bfa6d1ed..e64f0e2177c 100644 --- a/public/app/plugins/panel/canvas/utils.ts +++ b/public/app/plugins/panel/canvas/utils.ts @@ -9,7 +9,6 @@ import { CanvasElementItem, canvasElementRegistry, CanvasElementOptions, - TextConfig, CanvasConnection, } from 'app/features/canvas'; import { notFoundItem } from 'app/features/canvas/elements/notFound'; @@ -107,28 +106,155 @@ export function onAddItem(sel: SelectableValue, rootLayer: FrameState | } } -export function getDataLinks(ctx: DimensionContext, cfg: TextConfig, textData: string | undefined): LinkModel[] { - const panelData = ctx.getPanelData(); +/* + * Provided a given field add any matching data links + * Mutates the links object in place which is then returned by the `getDataLinks` function downstream + */ +const addDataLinkForField = ( + field: Field, + data: string | undefined, + linkLookup: Set, + links: Array> +): void => { + if (field?.getLinks) { + const disp = field.display ? field.display(data) : { text: `${data}`, numeric: +data! }; + field.getLinks({ calculatedValue: disp }).forEach((link) => { + const key = `${link.title}/${link.href}`; + if (!linkLookup.has(key)) { + links.push(link); + linkLookup.add(key); + } + }); + } +}; + +// TODO: This could be refactored a fair amount, ideally the element specific config code should be owned by each element and not in this shared util file +export function getDataLinks( + dimensionContext: DimensionContext, + elementOptions: CanvasElementOptions, + data: string | undefined +): LinkModel[] { + const panelData = dimensionContext.getPanelData(); const frames = panelData?.series; const links: Array> = []; const linkLookup = new Set(); + const elementConfig = elementOptions.config; + frames?.forEach((frame) => { const visibleFields = frame.fields.filter((field) => !Boolean(field.config.custom?.hideFrom?.tooltip)); - if (cfg.text?.field && visibleFields.some((f) => getFieldDisplayName(f, frame) === cfg.text?.field)) { - const field = visibleFields.filter((field) => getFieldDisplayName(field, frame) === cfg.text?.field)[0]; - if (field?.getLinks) { - const disp = field.display ? field.display(textData) : { text: `${textData}`, numeric: +textData! }; - field.getLinks({ calculatedValue: disp }).forEach((link) => { - const key = `${link.title}/${link.href}`; - if (!linkLookup.has(key)) { - links.push(link); - linkLookup.add(key); - } - }); - } + // Text config + const isTextTiedToFieldData = + elementConfig.text?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementConfig.text?.field); + const isTextColorTiedToFieldData = + elementConfig.color?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementConfig.color?.field); + + // General element config + const isElementBackgroundColorTiedToFieldData = + elementOptions?.background?.color?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementOptions?.background?.color?.field); + const isElementBackgroundImageTiedToFieldData = + elementOptions?.background?.image?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementOptions?.background?.image?.field); + const isElementBorderColorTiedToFieldData = + elementOptions?.border?.color?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementOptions?.border?.color?.field); + + // Icon config + const isIconSVGTiedToFieldData = + elementConfig.path?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementConfig.path?.field); + const isIconColorTiedToFieldData = + elementConfig.fill?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementConfig.fill?.field); + + // Wind turbine config (maybe remove / not support this?) + const isWindTurbineRPMTiedToFieldData = + elementConfig.rpm?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementConfig.rpm?.field); + + // Server config + const isServerBlinkRateTiedToFieldData = + elementConfig.blinkRate?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementConfig.blinkRate?.field); + const isServerStatusColorTiedToFieldData = + elementConfig.statusColor?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementConfig.statusColor?.field); + const isServerBulbColorTiedToFieldData = + elementConfig.bulbColor?.field && + visibleFields.some((field) => getFieldDisplayName(field, frame) === elementConfig.bulbColor?.field); + + if (isTextTiedToFieldData) { + const field = visibleFields.filter((field) => getFieldDisplayName(field, frame) === elementConfig.text?.field)[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isTextColorTiedToFieldData) { + const field = visibleFields.filter( + (field) => getFieldDisplayName(field, frame) === elementConfig.color?.field + )[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isElementBackgroundColorTiedToFieldData) { + const field = visibleFields.filter( + (field) => getFieldDisplayName(field, frame) === elementOptions?.background?.color?.field + )[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isElementBackgroundImageTiedToFieldData) { + const field = visibleFields.filter( + (field) => getFieldDisplayName(field, frame) === elementOptions?.background?.image?.field + )[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isElementBorderColorTiedToFieldData) { + const field = visibleFields.filter( + (field) => getFieldDisplayName(field, frame) === elementOptions?.border?.color?.field + )[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isIconSVGTiedToFieldData) { + const field = visibleFields.filter((field) => getFieldDisplayName(field, frame) === elementConfig.path?.field)[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isIconColorTiedToFieldData) { + const field = visibleFields.filter((field) => getFieldDisplayName(field, frame) === elementConfig.fill?.field)[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isWindTurbineRPMTiedToFieldData) { + const field = visibleFields.filter((field) => getFieldDisplayName(field, frame) === elementConfig.rpm?.field)[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isServerBlinkRateTiedToFieldData) { + const field = visibleFields.filter( + (field) => getFieldDisplayName(field, frame) === elementConfig.blinkRate?.field + )[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isServerStatusColorTiedToFieldData) { + const field = visibleFields.filter( + (field) => getFieldDisplayName(field, frame) === elementConfig.statusColor?.field + )[0]; + addDataLinkForField(field, data, linkLookup, links); + } + + if (isServerBulbColorTiedToFieldData) { + const field = visibleFields.filter( + (field) => getFieldDisplayName(field, frame) === elementConfig.bulbColor?.field + )[0]; + addDataLinkForField(field, data, linkLookup, links); } });