Skip to main content

External JavaScript and CSS

Version

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.

Loading Google Material CSS and JS files from an external resource.
Loading Google Material CSS and JS files from an external resource.
Sanitization

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

Alternative way to load an external llibrary.
Alternative way to load an external llibrary.

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
info

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

Option 1. Use that option when the data source is set to return nothing.
Option 1. Use that option when the data source is set to return nothing.

Use the Content

Option 2. Use that option when the data source is set to return something.
Option 2. Use that option when the data source is set to return something.

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
docs/volkovlabs-dynamictext-panel/js/plotly.js
loading...

Mermaid

Mermaid is a popular JavaScript-based diagramming and charting tool that dynamically creates and modifies diagrams using Markdown-defined text definitions.

info

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.

Mermaid diagrams displayed using the Dynamic Text Panel plugin.
Mermaid diagrams displayed using the Dynamic Text Panel plugin.

Example

Mermaid diagrams example.
Mermaid diagrams 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!

Chart.js diagrams displayed using the Dynamic Text Panel plugin.
Chart.js diagrams displayed using the Dynamic Text Panel plugin.

Example

Chart.js diagram example.
Chart.js diagram 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

Delivering Flowchart libraries to a Grafana dashboard using the Dynamic Text plugin.
Delivering Flowchart libraries to a Grafana dashboard using the Dynamic Text plugin.

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');
Render template parameter

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.

How to configure the Dynamic Text plugin to display a YouTube video.
How to configure the Dynamic Text plugin to display a YouTube video.

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.

Use the Dynamic Text plugin to display YouTube videos on your Grafana dashboard.
Use the Dynamic Text plugin to display YouTube videos on your Grafana dashboard.

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.

How to configure the Dynamic Text plugin to display Leaflet.js maps.
How to configure the Dynamic Text plugin to display Leaflet.js maps.

The map on the dashboard from this example looks like in the illustration below.

The Leaflet.js map on the dashboard.
The Leaflet.js map on the dashboard.

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 &copy; <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;
}