Skip to content

Instantly share code, notes, and snippets.

@denisb411
Last active September 1, 2022 08:15
Show Gist options
  • Save denisb411/87dfb3d094d5abd3dbe50619c604aaa7 to your computer and use it in GitHub Desktop.
Save denisb411/87dfb3d094d5abd3dbe50619c604aaa7 to your computer and use it in GitHub Desktop.
Grafana dashboard script with postMessage communication
/* global _ */
/*
* Complex scripted dashboard
* This script generates a dashboard object that Grafana can load. It also takes a number of user
* supplied URL parameters (in the ARGS variable)
*
* Return a dashboard object, or a function
*
* For async scripts, return a function, this function must take a single callback function as argument,
* call this callback function with the dashboard object (look at scripted_async.js for an example)
*/
'use strict'
// accessible variables in this scope
var window, document, ARGS, $, jQuery, moment, kbn
console.log('ALL SCOPE VARS', window, document, ARGS, $, jQuery, moment, kbn)
// Setup some variables
var dashboard
// All url parameters are available via the ARGS object
var ARGS
// Initialize a skeleton with nothing but a rows array and service object
dashboard = {
rows: []
}
// Initialize args data and elasticseach data
var rows = 1
var seriesName = 'argName'
var scenario_id = ''
var scenario_name = ''
var response = ''
var cell_id = '41S01SMCON8701_S01SMCON87'
var theme = 'dark'
var apiUrl = 'http://localhost:5000/'
if (!_.isUndefined(ARGS.rows)) {
rows = parseInt(ARGS.rows, 10)
}
if (!_.isUndefined(ARGS.apiurl)) {
apiUrl = ARGS.apiurl
}
if (!_.isUndefined(ARGS.theme)) {
theme = ARGS.theme
}
if (!_.isUndefined(ARGS.name)) {
seriesName = ARGS.name
}
if (!_.isUndefined(ARGS.scenario_name)) {
scenario_name = ARGS.scenario_name
}
if (!_.isUndefined(ARGS.scenario_id)) {
scenario_id = ARGS.scenario_id
}
if (!_.isUndefined(ARGS.cell_id)) {
cell_id = ARGS.cell_id
}
// mode options
var fill = 1
var lineWidth = 1
var staircase = false
var pointRadius = 2
if (!_.isUndefined(ARGS.fill)) {
fill = parseInt(ARGS.fill)
}
if (!_.isUndefined(ARGS.lineWidth)) {
lineWidth = parseInt(ARGS.lineWidth)
}
if (!_.isUndefined(ARGS.staircase)) {
if (ARGS.staircase == 'false') {
staircase = false
} else if (ARGS.staircase == 'true') {
staircase = true
}
}
if (!_.isUndefined(ARGS.pointRadius)) {
pointRadius = parseFloat(ARGS.pointRadius)
}
// stacking and null value
var stack = false
var nullValue = 'null'
if (!_.isUndefined(ARGS.stack)) {
if (ARGS.stack == 'false') {
stack = false
console.log(ARGS.stack)
} else if (ARGS.stack == 'true') {
stack = true
}
}
if (!_.isUndefined(ARGS.nullValue)) {
if (
ARGS.nullValue == 'null' ||
ARGS.nullValue == 'null as zero' ||
ARGS.nullValue == 'connected'
) {
nullValue = ARGS.nullValue
}
}
// draw modes
var bars = false
var lines = true
var points = true
if (!_.isUndefined(ARGS.bars)) {
if (ARGS.bars == 'false') {
bars = false
} else if (ARGS.bars == 'true') {
bars = true
}
}
if (!_.isUndefined(ARGS.lines)) {
if (ARGS.lines == 'false') {
lines = false
} else if (ARGS.lines == 'true') {
lines = true
}
}
if (!_.isUndefined(ARGS.points)) {
if (ARGS.points == 'false') {
points = false
} else if (ARGS.points == 'true') {
points = true
}
}
// yaxis
var showYAxis = true
var scale = 1
var yMin = null
var yMax = null
if (!_.isUndefined(ARGS.showYAxis)) {
if (ARGS.showYAxis == 'false') {
showYAxis = false
} else if (ARGS.showYAxis == 'true') {
showYAxis = true
}
}
if (!_.isUndefined(ARGS.scale)) {
if (ARGS.scale == 'linear') {
scale = 1
} else if (ARGS.scale == 'log (base 2)') {
scale = 2
} else if (ARGS.scale == 'log (base 10)') {
scale = 10
} else if (ARGS.scale == 'log (base 32)') {
scale = 32
} else if (ARGS.scale == 'log (base 1024)') {
scale = 1024
}
}
if (!_.isUndefined(ARGS.yMin)) {
if (ARGS.yMin == 'null') {
yMin = null
} else {
yMin = parseFloat(ARGS.yMin)
}
}
if (!_.isUndefined(ARGS.yMax)) {
if (ARGS.yMax == 'null') {
yMax = null
} else {
yMax = parseFloat(ARGS.yMax)
}
}
// legend
var legend = {
alignAsTable: false,
avg: false,
rightSide: false,
current: false,
max: false,
min: false,
show: true,
total: false,
values: false
}
if (!_.isUndefined(ARGS.asTable)) {
if (ARGS.asTable == 'false') {
legend.alignAsTable = false
} else if (ARGS.asTable == 'true') {
legend.alignAsTable = true
}
}
if (!_.isUndefined(ARGS.toTheRight)) {
if (ARGS.toTheRight == 'false') {
legend.rightSide = false
} else if (ARGS.toTheRight == 'true') {
legend.rightSide = true
}
}
if (!_.isUndefined(ARGS.legendAvg)) {
if (ARGS.legendAvg == 'false') {
legend.avg = false
legend.values = true
} else if (ARGS.legendAvg == 'true') {
legend.avg = true
legend.values = true
}
}
if (!_.isUndefined(ARGS.legendCurrent)) {
if (ARGS.legendCurrent == 'false') {
legend.current = false
legend.values = true
} else if (ARGS.legendCurrent == 'true') {
legend.current = true
legend.values = true
}
}
if (!_.isUndefined(ARGS.legendMax)) {
if (ARGS.legendMax == 'false') {
legend.max = false
legend.values = true
} else if (ARGS.legendMax == 'true') {
legend.max = true
legend.values = true
}
}
if (!_.isUndefined(ARGS.legendMin)) {
if (ARGS.legendMin == 'false') {
legend.min = false
legend.values = true
} else if (ARGS.legendMin == 'true') {
legend.min = true
legend.values = true
}
}
if (!_.isUndefined(ARGS.showLegend)) {
if (ARGS.showLegend == 'false') {
legend.show = false
legend.values = true
} else if (ARGS.showLegend == 'true') {
legend.show = true
legend.values = true
}
}
if (!_.isUndefined(ARGS.legendTotal)) {
if (ARGS.legendTotal == 'false') {
legend.total = false
legend.values = true
} else if (ARGS.legendTotal == 'true') {
legend.total = true
legend.values = true
}
}
var decimals = 2
if (!_.isUndefined(ARGS.decimals)) {
decimals = parseInt(ARGS.decimals)
}
var interval = '15m'
if (!_.isUndefined(ARGS.interval)) {
interval = ARGS.interval
}
var xmlHttp = new XMLHttpRequest()
xmlHttp.open(
'GET',
apiUrl + 'scenarios/' + scenario_id,
false
) // false for synchronous request
xmlHttp.send(null)
response = JSON.parse(xmlHttp.responseText)
dashboard.uid = response.id
// Set a title
dashboard.title = 'Data Analysis'
// dashboard.uid = 'e49LTL9iz'
dashboard.timezone = 'utc'
dashboard.templating = {
list: [
{
allValue: null,
current: {
isNone: true,
tags: [],
text: cell_id,
value: cell_id
},
datasource: '-- Grafana --',
definition: '',
hide: 2,
includeAll: false,
label: 'Cell ID',
multi: false,
name: 'cell_id',
options: [
{
isNone: true,
selected: true,
text: 'None',
value: ''
}
],
query: '',
refresh: 0,
regex: '',
skipUrlSync: false,
sort: 0,
tagValuesQuery: '',
tags: [],
tagsQuery: '',
type: 'query',
useTags: false
},
{
allValue: null,
current: {
isNone: true,
tags: [],
text: scenario_id,
value: scenario_id
},
datasource: '-- Grafana --',
definition: '',
hide: 2,
includeAll: false,
label: 'SCENARIO_ID',
multi: false,
name: 'scenario_id',
options: [
{
isNone: true,
selected: true,
text: 'None',
value: ''
}
],
query: '',
refresh: 0,
regex: '',
skipUrlSync: false,
sort: 0,
tagValuesQuery: '',
tags: [],
tagsQuery: '',
type: 'query',
useTags: false
},
{
allValue: null,
current: {
isNone: true,
tags: [],
text: scenario_name,
value: scenario_name
},
datasource: '-- Grafana --',
definition: '',
hide: 2,
includeAll: false,
label: 'SCENARIO_NAME',
multi: false,
name: 'scenario_name',
options: [
{
isNone: true,
selected: true,
text: 'None',
value: ''
}
],
query: '',
refresh: 0,
regex: '',
skipUrlSync: false,
sort: 0,
tagValuesQuery: '',
tags: [],
tagsQuery: '',
type: 'query',
useTags: false
}
]
}
dashboard.links = [
{
icon: 'external link',
tags: [],
type: 'dashboards'
}
]
dashboard.annotations = {
list: [
{
builtIn: 1,
datasource: '-- Grafana --',
enable: true,
hide: true,
iconColor: 'rgba(0, 211, 255, 1)',
limit: 100,
name: 'Annotations & Alerts',
showIn: 0,
type: 'dashboard'
}
]
}
dashboard.editable = true
dashboard.gnetId = null
dashboard.graphTooltip = 0
dashboard.id = 1
dashboard.iteration = 1554385724770
dashboard.refresh = '5s'
// dashboard.schemaVersion = 16
dashboard.style = 'dark'
dashboard.tags = []
dashboard.timepicker = {
refresh_intervals: [
'5s',
'10s',
'30s',
'1m',
'5m',
'15m',
'30m',
'1h',
'2h',
'1d'
],
time_options: ['5m', '15m', '1h', '6h', '12h', '24h', '2d', '7d', '30d']
}
dashboard.version = 1
// Set default time
// time can be overridden in the url using from/to parameters, but this is
// handled automatically in grafana core during dashboard initialization
dashboard.time = {
from: 'now/y',
to: 'now'
}
var color_list = ['#7eb26d', '#cca300', '#bf1b00']
var primary_counter_color = {}
var primary_counter = {}
var primary_counter_target = []
for (var i = 0; i < response.primary_counters.length; i++) {
primary_counter_color['Average ' + response.primary_counters[i]] =
color_list[i]
primary_counter = {
bucketAggs: [
{
field: 'time',
id: '1',
settings: {
interval: interval,
min_doc_count: 0,
trimEdges: 0
},
type: 'date_histogram'
}
],
metrics: [
{
field: response.primary_counters[i],
id: '1',
meta: {},
settings: {},
type: 'avg'
}
],
query: 'cell_id:$cell_id',
refId: 'A',
timeField: 'time'
}
primary_counter_target.push(primary_counter)
}
var other_counter_color = {}
var other_counter = {}
var other_counter_target = []
for (var i = 0; i < response.secondary_counters.length; i++) {
other_counter_color['Average ' + response.secondary_counters[i]] =
color_list[i]
other_counter = {
bucketAggs: [
{
field: 'time',
id: '2',
settings: {
interval: interval,
min_doc_count: 0,
trimEdges: 0
},
type: 'date_histogram'
}
],
metrics: [
{
field: response.secondary_counters[i],
id: '2',
meta: {},
settings: {},
type: 'avg'
}
],
query: 'cell_id:$cell_id',
refId: 'A',
timeField: 'time'
}
other_counter_target.push(other_counter)
}
var text_panel = {
height: '110px',
content:
'<center><h1>$cell_id - $scenario_name</h1></center>\n<form target="_blank" action="http://localhost:5000/execute_procedures" method="get">\n <input type="hidden" name="cell_id" value="$cell_id">\n <input type="hidden" name="scenario" value="$scenario_name">\n <center>\n <button style="color:black; font-size: 15px; background-color: white" type="submit">Execute procedures</button><center>\n</form>',
gridPos: {
h: 4,
w: 24,
x: 0,
y: 0
},
id: 8,
links: [],
mode: 'html',
title: 'Cell ID - Scenario',
type: 'text',
span: 12
}
var primary_panel = {
height: '340px',
aliasColors: primary_counter_color,
bars: bars,
dashLength: 10,
dashes: false,
datasource: 'Elasticsearch',
fill: fill,
span: 12,
gridPos: {
h: 12,
w: 24,
x: 0,
y: 4
},
id: 1,
legend: legend,
lines: lines,
linewidth: lineWidth,
links: [],
nullPointMode: nullValue,
percentage: false,
pointradius: pointRadius,
points: points,
renderer: 'flot',
seriesOverrides: [
{
alias: 'Average degradated',
yaxis: 1
}
],
spaceLength: 10,
stack: stack,
steppedLine: staircase,
targets: primary_counter_target,
timeFrom: null,
timeRegions: [],
timeShift: null,
title: 'Primary Counters',
tooltip: {
shared: true,
sort: 0,
value_type: 'individual'
},
type: 'graph',
xaxis: {
buckets: null,
mode: 'time',
name: null,
show: true,
values: []
},
transparent: true,
yaxes: [
{
format: 'short',
label: null,
logBase: scale,
max: yMax,
min: yMin,
show: showYAxis,
decimals: decimals
},
{
format: 'short',
label: null,
logBase: scale,
max: yMax,
min: yMin,
show: showYAxis,
decimals: decimals
}
],
yaxis: {
align: false,
alignLevel: null
}
}
var secondary_panel = {
height: '340px',
aliasColors: other_counter_color,
bars: bars,
dashLength: 10,
dashes: false,
datasource: 'Elasticsearch',
fill: fill,
span: 12,
gridPos: {
h: 12,
w: 24,
x: 0,
y: 4
},
id: 2,
legend: legend,
lines: lines,
linewidth: lineWidth,
links: [],
nullPointMode: nullValue,
percentage: false,
pointradius: pointRadius,
points: points,
renderer: 'flot',
seriesOverrides: [
{
alias: 'Average degradated',
yaxis: 1
}
],
spaceLength: 10,
stack: stack,
steppedLine: staircase,
targets: other_counter_target,
timeFrom: null,
timeRegions: [],
timeShift: null,
title: 'Secondary Counters',
tooltip: {
shared: true,
sort: 0,
value_type: 'individual'
},
type: 'graph',
xaxis: {
buckets: null,
mode: 'time',
name: null,
show: true,
values: []
},
transparent: true,
yaxes: [
{
format: 'short',
label: null,
logBase: scale,
max: yMax,
min: yMin,
show: showYAxis,
decimals: decimals
},
{
format: 'short',
label: null,
logBase: scale,
max: yMax,
min: yMin,
show: showYAxis,
decimals: decimals
}
],
yaxis: {
align: false,
alignLevel: null
}
}
var panel_list = []
panel_list.push(text_panel)
panel_list.push(primary_panel)
if (response.secondary_counters.length > 0) {
panel_list.push(secondary_panel)
}
for (var i = 0; i < rows; i++) {
dashboard.rows.push({
panels: panel_list,
schemaVersion: 16
})
}
var userReference
var source
function processMessage (event) {
console.log(event)
if (event.data == null) {
userReference = event.origin
source = event.source
console.log(event.data)
console.log(userReference)
console.log(source)
}
// var message;
// origin = event.origin;
// event.source.postMessage(JSON.stringify({from: dashboard.time.from, to: dashboard.time.to}),
// event.origin);
// console.log(dashboard.rows[0].panels[1]);
// dashboard.rows[0].panels[1].bars = !dashboard.rows[0].panels[1].bars
// console.log('message received');
// console.log(dashboard.rows[0].panels[1]);
}
window.addEventListener('message', processMessage, false)
function sendTimeUpdated () {
source.postMessage(
JSON.stringify({
message: 'graph_time_updated',
from: dashboard.time.from,
to: dashboard.time.to,
panelId: ARGS.panelId
}),
userReference
)
}
document
.getElementsByClassName('main-view')
.item(0)
.addEventListener('dblclick', function () {
console.log('DOUBLE CLICK DETECTED')
sendTimeUpdated();
})
var timer
var longPressing = false
document
.getElementsByClassName('main-view')
.item(0)
.addEventListener(
'mouseup',
function () {
clearTimeout(timer)
if (longPressing) {
console.log('LONG PRESS DETECTED')
setTimeout(sendTimeUpdated, 100);
longPressing = false
}
},
false
)
document
.getElementsByClassName('main-view')
.item(0)
.addEventListener(
'mousedown',
function () {
timer = setTimeout(function () {
longPressing = true
}, 100)
},
false
)
if (theme == 'light') {
document.getElementsByClassName('scroll-canvas')[0].style.backgroundColor =
'#f2f2f2'
document.getElementsByClassName('scroll-canvas')[0].style.border =
'1px solid #dadada'
} else {
document.getElementsByClassName('scroll-canvas')[0].style.backgroundColor =
'#242424'
document.getElementsByClassName('scroll-canvas')[0].style.border =
'1px solid rgb(75, 75, 75)'
}
return dashboard
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment