Add support for variables in plugins

    This guide explains how to leverage template variables in your panel plugins and data source plugins.

    We’ll see how you can turn a string like this:

    into

    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.

    For panels, the replaceVariables function is available in the PanelProps.

    Add replaceVariables to the argument list, and pass it a user-defined template string.

    1. export const SimplePanel: React.FC<Props> = ({ options, data, width, height, replaceVariables }) => {
    2. const query = replaceVariables('Now displaying $service');
    3. return <div>{query}</div>;
    4. };

    For data sources, you need to use the getTemplateSrv, which returns an instance of TemplateSrv.

    1. Import getTemplateSrv from the runtime package.

      1. import { getTemplateSrv } from '@grafana/runtime';
    2. In your query method, call the replace method with a user-defined template string.

      1. async query(options: DataQueryRequest<MyQuery>): Promise<DataQueryResponse> {
      2. const query = getTemplateSrv().replace('SELECT * FROM services WHERE id = "$service"', options.scopedVars);
      3. const data = makeDbQuery(query);
      4. return { data };
      5. }

    A data source can define the default format option when no format is specified by adding a third argument to the interpolation function.

    Let’s change the SQL query to use CSV format by default:

    Now, when users write $service, the query looks like this:

    1. SELECT * FROM services WHERE id IN (admin,auth,billing)

    For more information on the available variable formats, refer to .

    Not only can you read the value of a variable, you can also update the variable from your plugin. Use LocationSrv.update()

    The following example shows how to update a variable called service.

    • query contains the query parameters you want to update. Query parameters controlling variables are prefixed with var-.
    • partial: true makes the update only affect the query parameters listed in query, and leaves the other query parameters unchanged.
    1. getLocationSrv().update({
    2. query: {
    3. 'var-service': 'billing',
    4. },
    5. partial: true,
    6. replace: true,
    7. });

    Query variables 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.

    Let’s start by defining a query model for the variable query.

    1. export interface MyVariableQuery {
    2. namespace: string;
    3. rawQuery: string;
    4. }

    Note: By default, Grafana provides a default query model and editor for simple text queries. If that’s all you need, then you can leave the query type as string.

    1. async metricFindQuery(query: string, options?: any)

    Let’s create a custom query editor to allow the user to edit the query model.

    1. Create a VariableQueryEditor component.

      ``` import React, { useState } from ‘react’; import { MyVariableQuery } from ‘./types’;

      interface VariableQueryProps { query: MyVariableQuery; onChange: (query: MyVariableQuery, definition: string) => void; }

      export const VariableQueryEditor: React.FC = ({ onChange, query }) => { const [state, setState] = useState(query);

      const saveQuery = () => {

      1. onChange(state, `${state.query} (${state.namespace})`);

      };

      const handleChange = (event: React.FormEvent) =>

      1. setState({
      2. ...state,
    1. [event.currentTarget.name]: event.currentTarget.value,
    2. });
    3. return (
    4. <>
    5. <span className="gf-form-label width-10">Namespace</span>
    6. name="namespace"
    7. className="gf-form-input"
    8. onBlur={saveQuery}
    9. onChange={handleChange}
    10. value={state.namespace}
    11. />
    12. </div>
    13. <div className="gf-form">
    14. <span className="gf-form-label width-10">Query</span>
    15. <input
    16. name="rawQuery"
    17. className="gf-form-input"
    18. onBlur={saveQuery}
    19. onChange={handleChange}
    20. value={state.rawQuery}
    21. />
    22. </div>
    23. </>
    24. );
    25. };
    26. ```
    27. Grafana saves the query model whenever one of the text fields loses focus (`onBlur`) and then previews the values returned by `metricFindQuery`.

    That’s it! You can now try out the plugin by adding a to your dashboard.