External JavaScript and CSS
The Dynamic Text Panel supports the external resources since version 4.1.0.
Dynamic Text Panel enables the loading of additional JavaScript and CSS resources using external URLs like CDN (Content Delivery Network).
Use that functionality to include additional visual elements and execute JavaScript functions in the JavaScript Code editor.
To prevent the loading of third-party URLs, you can store CSS and JS files in the public folder on your Grafana instance.
You need to disable the sanitization configuration to see external resources in the plugin options.
Manual scripts
In the event when a library can not be referenced as an external script, you always can reference and initiate it directly in the JavaScript->After Content Ready
Content
Into the Content:
<pre class="mermaid">
graph LR
A --- B
B-->C[fa:fa-ban {{data.0.test}}]
B-->D(fa:fa-spinner);
</pre>
JavaScript
Into the JavaScript->After Content Ready:
const script = document.createElement("script");
script.src = "https://cdn.jsdelivr.net/npm/mermaid@10.6.1/dist/mermaid.min.js";
document.body.appendChild(script);
mermaid.initialize({ startOnLoad: true });
mermaid.run({
querySelector: ".mermaid",
suppressErrors: false,
});
External JavaScript resources
Below you can find a collection of breathtaking use cases for the external JavaScript resources in the Dynamic Text plugin.
Plotly 3D Scatter
Thanks to our community member Josiah Solomon for the provided solution.
Use the following external Plotly's 3D Scatter chart library:
https://cdn.plot.ly/plotly-2.24.1.min.js
Grafana's edit mode might prevent displaying Plotly charts. Save and check the result on the dashboard.
You can run this example in two ways:
- inserting the provided code from the below into the Default content
- inserting the provided code from the below into the Content
Use the Default Content
Use the Content
Code to copy
Into the Content or Default Content:
<body>
<div id="addisAbeba">
<!-- Plotly chart will be rendered inside this DIV -->
</div>
</body>
Into the JavaScript->Before Content Rendering:
JavaScript code for Plotly example
loading...
Mermaid
Mermaid is a popular JavaScript-based diagramming and charting tool that dynamically creates and modifies diagrams using Markdown-defined text definitions.
Previously we maintained two Dynamic Text plugin builds. One with embedded Mermaid Library and the other without.
The main reason being the Mermaid Library size. After we added the External Resources feature, the need to maintain two builds has vanished. Now, anyone who needs the Mermaid library can simply load it as an external resource.
Example
Use the following external library
https://cdn.jsdelivr.net/npm/mermaid@10.6.1/dist/mermaid.min.js
Code to copy
Use the following for the Content (when your data source is set to return something) or in the Default Content (when your data source returns nothing):
flowchart LR
<pre class="mermaid">
graph LR
A --- B
B-->C[fa:fa-ban {{data.0.test}}]
B-->D(fa:fa-spinner);
</pre>
Use the following for the JavaScript->After Content Ready:
mermaid.initialize({ startOnLoad: true });
mermaid.run({
querySelector: ".mermaid",
suppressErrors: false,
});
Chart.js
Chart.js is one of the popular open-source charting libraries. The Dynamic Text plugin makes using chart.js in Grafana possible!
Example
Use the following external library
https://cdn.jsdelivr.net/npm/chart.js
Code to copy
Use the following for the Content:
<canvas id="myChart"></canvas>
Use the following for the JavaScript->After Content Ready:
const ctx = document.getElementById("myChart");
new Chart(ctx, {
type: "bar",
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "# of Votes",
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
},
],
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
Flowchart
Thank you Josiah Solomon for exploring an epic Flowchart return to Grafana! We are happy to share your example with the world.
Below you can find how the beloved by many Flowchart libraries can be implemented using the Dynamic Text plugin.
Simply, add two external libraries and then write your code addressing the Flowchart libraries directly.
Example
External Resources
https://flowchart.js.org/flowchart-latest.js
https://cdnjs.cloudflare.com/ajax/libs/raphael/2.3.0/raphael.min.js
Content to copy
<div id="addisAbeba"></div>
JavaScript code to copy
var flow = `
st=>start: Start:>http://www.google.com[blank]
e=>end:>http://www.google.com
op1=>operation: My Operation
sub1=>subroutine: My Subroutine
cond=>condition: Yes
or No?:>http://www.google.com
io=>inputoutput: catch something...
para=>parallel: parallel tasks
in=>input: some in
out=>output: some out
st->op1->cond
cond(yes)->io->e
cond(no)->para
para(path1, bottom)->sub1(right)->op1
para(path2, top)->op1
para(path3, right)->in->out->e`
var diagram = flowchart.parse(flow);
diagram.drawSVG('addisAbeba');
Use All rows or All data template to execute template only once. With Every row, the Content will be applied to every row of retrieved data. Even though the data frames of the specified data source are not used, still the plugin runs the code as many times as the number of rows is retrieved.
Youtube video
This idea comes from the GitHub issue opened by Raphealtony. The Dynamic Text plugin can be used to display YouTube videos on your Grafana dashboard.
External Resources
https://www.youtube.com/iframe_api
Content to copy
<h1>Volkov Labs Latest videos</h1>
<div id="player"></div>
JavaScript code to copy
const videoList = ["AcQi-6GCrNU", "1ogv2jstrlI", "vky-7-DfvXE"];
const randomVideoId = videoList[Math.floor(Math.random() * videoList.length)];
const onPlayerReady = (event) => event.target.playVideo();
const onPlayerStateChange = (event) => {
if (event.data === YT.PlayerState.ENDED) {
var newRandomVideoId =
videoList[Math.floor(Math.random() * videoList.length)];
event.target.loadVideoById(newRandomVideoId);
}
};
const player = new YT.Player("player", {
height: "360",
width: "640",
videoId: randomVideoId,
events: {
onReady: onPlayerReady,
onStateChange: onPlayerStateChange,
},
});
Below is an example of a dashboard displaying a YouTube video.
Leaflet.js interactive maps
This is another great example of external resource usages in the Dynamic Text Plugin. The idea comes from BlinderMiri and Josiah Solomon. Follow the below outlined steps to display Leaflet.js maps on your Grafana dashboard.
The map on the dashboard from this example looks like in the illustration below.
Data can be set using Static Data Source
{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [125.6, 10.1] }, "properties": { "name": "Dinagat Islands" } }
External Resources
https://unpkg.com/leaflet@1.9.4/dist/leaflet.css
https://unpkg.com/leaflet@1.9.4/dist/leaflet.js
Content
<div id="map"></div>
JavaScript code
// This data is coming from the data source.
// const geojson = JSON.parse(context.data[0][0].data);
//Addis Abeba centered
const map = L.map("map").setView([9.024857, 38.737607], 13);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
maxZoom: 18,
}).addTo(map);
//if you want to use inline data
const geojson = {
type: "FeatureCollection",
crs: { type: "name", properties: { name: "urn:ogc:def:crs:OGC:1.3:CRS84" } },
features: [
{
type: "Feature",
properties: { AOIs: "bbb", daily: "33" },
geometry: {
type: "Polygon",
coordinates: [
[
[33.5, 32.0],
[33.5, 29.0],
[36.0, 29.0],
[36.0, 27.5],
[33.5, 27.5],
[32.5, 27.5],
[29.0, 27.5],
[29.0, 32.0],
[33.5, 32.0],
],
],
},
},
{
type: "Feature",
properties: { AOIs: "aaa", daily: "23" },
geometry: {
type: "Polygon",
coordinates: [
[
[34.5, 32.5],
[36.0, 32.5],
[36.0, 29.0],
[33.5, 29.0],
[33.5, 32.0],
[33.5, 32.5],
[34.5, 32.5],
],
],
},
},
],
};
var myStyle = {
color: "black",
weight: 10,
};
var geojsonLayer = L.geoJSON(geojson).addTo(map);
CSS styles
#map {
height: 480px;
display: flex;
flex-direction: row;
}