Create advanced, interactive charts in Grafana using Plotly.js.
- Flexible chart creation with full Plotly.js capabilities
- YAML/JSON support for easy configuration
- Dark/light theme compatibility
- Automatic and manual timezone adjustment
- Cross-trace data application
- Expandable code editors for customization
- Grafana variable integration
- Comprehensive error handling
- High-resolution image export in multiple formats (SVG, PNG, JPEG, WebP)
For a complete list of recent updates, please refer to our changelog.
The Plotly Panel, developed by nLine, offers enhanced control over data visualization in Grafana. It uses a component-based approach, allowing you to modify chart elements independently without complex JavaScript interactions.
The panel configuration consists of five main components:
- allData: Applied across all traces on the Plotly chart
- data: Defines the chart's data series (traces)
- layout: Controls the chart's appearance and axes
- config: Sets chart-wide options
- frames: (Optional) For animated charts
These components follow the Plotly.js schema. You can configure them using YAML or JSON in the panel options.
You can transform your data before rendering using a custom script. The script has access to:
data
: Raw data from your Grafana data sourcevariables
: Grafana dashboard and system variablesoptions
: Current panel configurationutils
: Helper functions (e.g., timezone conversion, dayjs for date manipulation)
The script has access to several context variables that provide useful information and functionality:
This object contains Grafana's dashboard variables and native Grafana variables. Native variables take precedence over dashboard variables with the same name.
Key native variables include:
__from
and__to
: Start and end timestamps of the current time range__interval
and__interval_ms
: The interval in string format (e.g., "1h") and in milliseconds__timezone
: The current dashboard timezone__timeFilter
: A function to generate time range filter expressions__dashboard
: The current dashboard object
The utils
object provides several utility functions and services to assist with data manipulation and panel interactions:
timeZone
: The dashboard timezonedayjs
: A lightweight date manipulation librarymatchTimezone
: A convenience function to convert timeseries data to the user's timezonelocationService
: Grafana's location service for URL manipulationgetTemplateSrv
: Grafana's template service for variable substitutionreplaceVariables
: A function to substitute Grafana variables in strings
The script must return an object that defines the chart configuration. This object can include one or more of the following properties:
data
: An array of trace objects defining the chart's data serieslayout
: An object controlling the chart's appearance and axesconfig
: An object setting chart-wide optionsframes
: An array of frame objects for animated charts
Note: The data
and frames
properties should be arrays of objects. The "Cross-trace Data" field can be an object, which will apply the parameters to all returned traces in the Script section. Objects are merged with script objects given priority (e.g., data
from script > allData
> data
).
The script is defined in the "Processing Script" editor.
// Example: Basic timeseries plot
const { data, variables, options, utils } = arguments;
let series = data.series[0];
let x = series.fields[0];
let y = series.fields[1];
return {
data: [
{
x: x.values || x.values.buffer,
y: y.values || y.values.buffer,
type: 'scatter',
mode: 'lines',
name: x.name,
},
],
layout: {
xaxis: { title: x.name },
yaxis: { title: y.name },
},
};
The panel supports click, select, and zoom events. You can define custom behavior for these events using the "On-event Trigger" editor.
// Event handling
const { type: eventType, data: eventData } = event;
const { timeZone, dayjs, locationService, getTemplateSrv } = utils;
switch (eventType) {
case 'click':
console.log('Click event:', eventData.points);
break;
case 'select':
console.log('Selection event:', eventData.range);
break;
case 'zoom':
console.log('Zoom event:', eventData);
break;
}
For screenshots, please see the src/img
folder.