Skip to content
This repository was archived by the owner on Aug 4, 2025. It is now read-only.

Commit f827cfd

Browse files
authored
Merge pull request #11 from hoptical/issue9
add variable support for query string
2 parents fc81af7 + 22a1933 commit f827cfd

4 files changed

Lines changed: 35 additions & 27 deletions

File tree

README.md

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,43 @@
22

33
[![Build](https://github.com/grafana/grafana-starter-datasource/workflows/CI/badge.svg)](https://github.com/grafana/grafana-starter-datasource/actions?query=workflow%3A%22CI%22)
44

5-
This plugin provides a datasource to connect a REST API to [nodegraph](https://grafana.com/docs/grafana/latest/visualizations/node-graph/) panel of Grafana.
5+
This plugin provides a data source to connect a REST API to [nodegraph](https://grafana.com/docs/grafana/latest/visualizations/node-graph/) panel of Grafana.
66

77
![Graph Example](src/img/graph-example.png)
88

9-
## What is Grafana Data Source Plugin?
10-
11-
Grafana supports a wide range of data sources, including Prometheus, MySQL, and even Datadog. There’s a good chance you can already visualize metrics from the systems you have set up. In some cases, though, you already have an in-house metrics solution that you’d like to add to your Grafana dashboards. Grafana Data Source Plugins enables integrating such solutions with Grafana.
12-
139
## Getting started
1410

1511
1. Use Grafana 7.4 or higher
1612

17-
- Download and place the datasouce in grafana/plugins directory.
13+
- Download and place the data source in `grafana/plugins` directory.
1814

19-
This plugin is not signed yet, Grafana will not allow loading it by default. you should enable it by adding:
15+
This plugin is not signed yet; Grafana will not allow loading it by default. You have to enable it by adding:
2016

2117
for example, if you are using Grafana with containers, add:
2218

2319
```yaml
2420
-e "GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=hamedkarbasi93-nodegraphapi-datasource"
2521
```
2622

27-
2. You can now add the the data source. Just enter the url of your API app and push "Save & Test". You will get an error in case of connection failure.
23+
2. You can now add the data source. Just enter the URL of your API app and push "Save & Test." You will get an error in case of connection failure.
2824

29-
> Note: The browser should have access to the application not the grafana server.
25+
> Note: The browser should have access to the application, not the Grafana server.
3026
3127
![Add Datasource](src/img/add-datasource.png)
3228

33-
3. In grafana dashboard, pick the Nodegraph panel and have the graph visualization.
29+
3. In the Grafana dashboard, pick the Nodegraph panel and visualize the graph.
3430

3531
## API Configuration
3632

37-
You REST API application should return data in the following format:
33+
The REST API application should return data in the following format:
3834

39-
> Note: You API application should handle CORS policy. Otherwise you will face CORS-Policy error in Grafana.
35+
> Note: Your API application should handle CORS policy. Otherwise, you will face a CORS-Policy error in Grafana.
4036
4137
### Fetch Graph Fields
4238

4339
This route returns the nodes and edges fields defined in the [parameter tables](https://grafana.com/docs/grafana/latest/visualizations/node-graph/#data-api).
44-
This would help the plugin to create desired parameters for the graph.
45-
For nodes, `id` and for edges, `id`, `source` and `target` fields are required and the other fields are optional.
40+
It would help the plugin to create desired parameters for the graph.
41+
For nodes, `id` and for edges, `id`, `source`, and `target` fields are required. Other fields are optional.
4642

4743
endpoint: `/api/graph/fields`
4844

@@ -110,7 +106,7 @@ content format example:
110106

111107
### Fetch Graph Data
112108

113-
This route returns the graph data which is intended to visualize.
109+
This route returns the graph data, which is intended to visualize.
114110

115111
endpoint: `/api/graph/data`
116112

@@ -151,12 +147,12 @@ Data Format example:
151147
}
152148
```
153149

154-
For more detail of the variables please visit [here](https://grafana.com/docs/grafana/latest/visualizations/node-graph/#data-api).
150+
For more detail of the variables, please visit [here](https://grafana.com/docs/grafana/latest/visualizations/node-graph/#data-api).
155151

156152
### Health
157153

158-
This route is for testing the health of the API which is used by the *Save & Test* action while adding the plugin.[(Part 2 of the Getting Started Section)](#getting-started).
159-
Currently, it only needs to return `200` status code in case of a success connection.
154+
This route is for testing the health of the API, which is used by the *Save & Test* action while adding the plugin.[(Part 2 of the Getting Started Section)](#getting-started).
155+
Currently, it only needs to return the `200` status code in case of a successful connection.
160156

161157
endpoint: `/api/health`
162158

@@ -166,7 +162,7 @@ success status code: `200`
166162

167163
## API Example
168164

169-
In `example` folder you can find a simple API application in Python Flask.
165+
In the `example` folder, you can find a simple API application in Python Flask.
170166

171167
### Requirements:
172168

@@ -180,6 +176,12 @@ python run.py
180176
```
181177
The application will be started on `http://localhost:5000`
182178

179+
## Query Configuration
180+
You can pass a query string to apply for the data endpoint of the graph via *Query String*. Like any other query, you can utilize variables too:
181+
182+
![Add Datasource](src/img/query-string.png)
183+
With variable `$service` defined as `processors`, above query will produce this endpoint:
184+
`/api/graph/data?query=text1&service=processors`
183185
## Compiling the data source by yourself
184186

185187
1. Install dependencies
@@ -215,7 +217,7 @@ The application will be started on `http://localhost:5000`
215217

216218
## Contributing
217219

218-
Thank you for considering contributing! If you find an issue, or have a better way to do something, feel free to open an issue, or a PR.
220+
Thank you for considering contributing! If you find an issue or have a better way to do something, feel free to open an issue or a PR.
219221

220222
## License
221223

src/QueryEditor.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ export class QueryEditor extends PureComponent<Props> {
2323
<div className="gf-form">
2424
<FormField
2525
labelWidth={8}
26+
inputWidth={20}
2627
value={queryText || ''}
2728
onChange={this.onQueryTextChange}
28-
label="Query Text"
29-
tooltip="Not used yet"
29+
label="Query String"
30+
tooltip="The query string for data endpoint of the node graph api; i.e. /api/graph/data?query=sometext"
3031
/>
3132
</div>
3233
);

src/datasource.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ import {
88
MutableDataFrame,
99
FieldType,
1010
FieldColorModeId,
11-
//QueryResultMeta,
1211
} from '@grafana/data';
1312

1413
import { getBackendSrv } from '@grafana/runtime';
1514

15+
import { getTemplateSrv } from '@grafana/runtime';
16+
1617
import { MyQuery, MyDataSourceOptions, defaultQuery } from './types';
1718

1819
export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
@@ -26,10 +27,11 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
2627
async query(options: DataQueryRequest<MyQuery>): Promise<DataQueryResponse> {
2728
const promises = options.targets.map(async target => {
2829
const query = defaults(target, defaultQuery);
30+
const dataQuery = getTemplateSrv().replace(query.queryText, options.scopedVars);
2931
// fetch graph fields from api
30-
const responseGraphFields = await this.doRequest('/api/graph/fields', `query=${query.queryText}`);
32+
const responseGraphFields = await this.doRequest('/api/graph/fields', `${dataQuery}`);
3133
// fetch graph data from api
32-
const responseGraphData = await this.doRequest('/api/graph/data', `query=${query.queryText}`);
34+
const responseGraphData = await this.doRequest('/api/graph/data', `${dataQuery}`);
3335
// extract fields of the nodes and edges in the graph fields object
3436
const nodeFieldsResponse = responseGraphFields.data.nodes_fields;
3537
const edgeFieldsResponse = responseGraphFields.data.edges_fields;
@@ -96,11 +98,14 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
9698
return Promise.all(promises).then(data => ({ data: data[0] }));
9799
}
98100
async doRequest(endpoint: string, params?: string) {
99-
const result = await getBackendSrv().datasourceRequest({
101+
// const result = await getBackendSrv().datasourceRequest({
102+
// method: 'GET',
103+
// url: `${this.baseUrl}${endpoint}${`?${params}`}`,
104+
// });
105+
const result = getBackendSrv().datasourceRequest({
100106
method: 'GET',
101107
url: `${this.baseUrl}${endpoint}${params?.length ? `?${params}` : ''}`,
102108
});
103-
104109
return result;
105110
}
106111

src/img/query-string.png

22.9 KB
Loading

0 commit comments

Comments
 (0)