2022-05-26 23:06:25 +08:00
---
title: Add support for variables in plugins
---
2020-05-12 05:26:10 +08:00
# Add support for variables in plugins
2023-05-13 02:33:49 +08:00
Variables are placeholders for values, and you can use them to create templated queries, and dashboard or panel links. For more information on variables, refer to [Templates and variables ]({{< relref "../../dashboards/variables/" >}} ).
2020-05-12 05:26:10 +08:00
2023-05-13 02:33:49 +08:00
In this guide, you'll see how you can turn a query string like this:
2020-05-12 05:26:10 +08:00
```sql
SELECT * FROM services WHERE id = "$service"
```
into
```sql
SELECT * FROM services WHERE id = "auth-api"
```
Grafana provides a couple of helper functions to interpolate variables in a string template. Let's see how you can use them in your plugin.
## Interpolate variables in panel plugins
2023-05-13 02:33:49 +08:00
For panels, the `replaceVariables` function is available in the `PanelProps` .
2020-05-12 05:26:10 +08:00
2023-05-13 02:33:49 +08:00
Add `replaceVariables` to the argument list, and pass a user-defined template string to it:
2020-05-12 05:26:10 +08:00
```ts
2022-08-25 04:54:34 +08:00
export function SimplePanel({ options, data, width, height, replaceVariables }: Props) {
2021-08-06 21:52:36 +08:00
const query = replaceVariables('Now displaying $service');
2020-05-12 05:26:10 +08:00
2021-08-06 21:52:36 +08:00
return < div > {query}< / div > ;
2022-08-25 04:54:34 +08:00
}
2020-05-12 05:26:10 +08:00
```
## Interpolate variables in data source plugins
2023-05-13 02:33:49 +08:00
For data sources, you need to use the `getTemplateSrv` , which returns an instance of `TemplateSrv` .
2020-05-12 05:26:10 +08:00
2023-05-13 02:33:49 +08:00
1. Import `getTemplateSrv` from the `runtime` package:
2020-05-12 05:26:10 +08:00
```ts
import { getTemplateSrv } from '@grafana/runtime';
```
2023-05-13 02:33:49 +08:00
1. In your `query` method, call the `replace` method with a user-defined template string:
2020-05-12 05:26:10 +08:00
```ts
async query(options: DataQueryRequest< MyQuery > ): Promise< DataQueryResponse > {
2020-08-18 22:42:24 +08:00
const query = getTemplateSrv().replace('SELECT * FROM services WHERE id = "$service"', options.scopedVars);
2020-05-12 05:26:10 +08:00
const data = makeDbQuery(query);
return { data };
}
```
2020-08-17 18:00:33 +08:00
2020-08-18 22:42:24 +08:00
## Format multi-value variables
2023-05-13 02:33:49 +08:00
When a user selects multiple values for a variable, the value of the interpolated variable depends on the [variable format ]({{< relref "../../dashboards/variables/variable-syntax/#advanced-variable-format-options" >}} ).
2020-08-18 22:42:24 +08:00
2023-05-13 02:33:49 +08:00
A data source plugin can define the default format option when no format is specified by adding a third argument to the interpolation function.
2020-08-18 22:42:24 +08:00
Let's change the SQL query to use CSV format by default:
```ts
2021-08-06 21:52:36 +08:00
getTemplateSrv().replace('SELECT * FROM services WHERE id IN ($service)', options.scopedVars, 'csv');
2020-08-18 22:42:24 +08:00
```
Now, when users write `$service` , the query looks like this:
```sql
SELECT * FROM services WHERE id IN (admin,auth,billing)
```
2022-09-09 21:38:17 +08:00
For more information on the available variable formats, refer to [Advanced variable format options ]({{< relref "../../dashboards/variables/variable-syntax/#advanced-variable-format-options" >}} ).
2020-08-18 22:42:24 +08:00
2020-08-28 17:09:35 +08:00
## Set a variable from your plugin
2022-02-07 16:37:56 +08:00
Not only can you read the value of a variable, you can also update the variable from your plugin. Use `locationService.partial(query, replace)` .
2020-08-28 17:09:35 +08:00
The following example shows how to update a variable called `service` .
2023-05-13 02:33:49 +08:00
- `query` contains the query parameters you want to update. The query parameters that control variables are prefixed with `var-` .
- `replace: true` tells Grafana to update the current URL state rather than creating a new history entry.
2020-08-28 17:09:35 +08:00
```ts
2022-02-07 16:37:56 +08:00
import { locationService } from '@grafana/runtime';
2020-08-28 17:09:35 +08:00
```
```ts
2022-02-07 16:37:56 +08:00
locationService.partial({ 'var-service': 'billing' }, true);
2020-08-28 17:09:35 +08:00
```
> **Note:** Grafana queries your data source whenever you update a variable. Excessive updates to variables can slow down Grafana and lead to a poor user experience.
2020-08-17 18:00:33 +08:00
## Add support for query variables to your data source
2023-05-13 02:33:49 +08:00
A [query variable ]({{< relref "../../dashboards/variables/add-template-variables/#add-a-query-variable" >}} ) is a type of variable that allows you to query a data source for the values. By adding support for query variables to your data source plugin, users can create dynamic dashboards based on data from your data source.
2020-08-17 18:00:33 +08:00
2023-05-13 02:33:49 +08:00
Let's start by defining a query model for the variable query:
2020-08-17 18:00:33 +08:00
```ts
export interface MyVariableQuery {
namespace: string;
rawQuery: string;
}
```
2023-05-13 02:33:49 +08:00
For a data source to support query variables, override the `metricFindQuery` in your `DataSourceApi` class. The `metricFindQuery` function returns an array of `MetricFindValue` which has a single property, `text` :
2020-08-17 18:00:33 +08:00
```ts
async metricFindQuery(query: MyVariableQuery, options?: any) {
// Retrieve DataQueryResponse based on query.
const response = await this.fetchMetricNames(query.namespace, query.rawQuery);
// Convert query results to a MetricFindValue[]
const values = response.data.map(frame => ({ text: frame.name }));
return values;
}
```
2023-05-13 02:33:49 +08:00
> **Note:** By default, Grafana provides a basic query model and editor for simple text queries. If that's all you need, then leave the query type as `string`:
```ts
async metricFindQuery(query: string, options?: any)
```
2020-08-17 18:00:33 +08:00
Let's create a custom query editor to allow the user to edit the query model.
2023-05-13 02:33:49 +08:00
1. Create a `VariableQueryEditor` component:
2020-08-17 18:00:33 +08:00
```ts
import React, { useState } from 'react';
import { MyVariableQuery } from './types';
interface VariableQueryProps {
query: MyVariableQuery;
onChange: (query: MyVariableQuery, definition: string) => void;
}
2023-03-15 22:56:09 +08:00
export const VariableQueryEditor = ({ onChange, query }: VariableQueryProps) => {
2020-08-17 18:00:33 +08:00
const [state, setState] = useState(query);
const saveQuery = () => {
onChange(state, `${state.query} (${state.namespace})` );
};
const handleChange = (event: React.FormEvent< HTMLInputElement > ) =>
setState({
...state,
[event.currentTarget.name]: event.currentTarget.value,
});
return (
< >
< div className = "gf-form" >
< span className = "gf-form-label width-10" > Namespace< / span >
< input
name="namespace"
className="gf-form-input"
onBlur={saveQuery}
onChange={handleChange}
value={state.namespace}
/>
< / div >
< div className = "gf-form" >
< span className = "gf-form-label width-10" > Query< / span >
2021-08-06 21:52:36 +08:00
< input
name="rawQuery"
className="gf-form-input"
onBlur={saveQuery}
onChange={handleChange}
value={state.rawQuery}
/>
2020-08-17 18:00:33 +08:00
< / div >
< />
);
};
```
Grafana saves the query model whenever one of the text fields loses focus (`onBlur`) and then previews the values returned by `metricFindQuery` .
2023-05-13 02:33:49 +08:00
The second argument to `onChange` allows you to set a text representation of the query that will appear next to the name of the variable in the variables list.
2020-08-17 18:00:33 +08:00
2023-05-13 02:33:49 +08:00
1. Configure your plugin to use the query editor:
2020-08-17 18:00:33 +08:00
```ts
import { VariableQueryEditor } from './VariableQueryEditor';
export const plugin = new DataSourcePlugin< DataSource , MyQuery , MyDataSourceOptions > (DataSource)
.setQueryEditor(QueryEditor)
.setVariableQueryEditor(VariableQueryEditor);
```
2022-09-09 21:38:17 +08:00
That's it! You can now try out the plugin by adding a [query variable ]({{< relref "../../dashboards/variables/add-template-variables/#add-a-query-variable" >}} ) to your dashboard.