mirror of https://github.com/grafana/grafana
Docs for developing plugins (#7475)
* docs(plugins): new developing plugins section Creates new section called Developing Plugins in the plugin section of the docs. 1. Some changes to the Development guide page 2. Converted defaults/editor mode blog post to new page 3. Converted snapshots blog post to new page 4. Adds new code styleguide page 5. Updates to apps and datasources pages 6. Adds plugin.json schema * docs(links): fixes broken links Fixes broken links to other pages as well as broken image links.pull/7491/head
parent
3398c28ab2
commit
abd9233f86
@ -1,24 +0,0 @@ |
||||
--- |
||||
page_title: App plugin |
||||
page_description: App plugin for Grafana |
||||
page_keywords: grafana, plugins, documentation |
||||
--- |
||||
|
||||
|
||||
# Apps |
||||
|
||||
App plugins is a new kind of grafana plugin that can bundle datasource and panel plugins within one package. It also enable the plugin author to create custom pages within grafana. The custom pages enables the plugin author to include things like documentation, sign up forms or controlling other services using HTTP requests. |
||||
|
||||
Datasource and panel plugins will show up like normal plugins. The app pages will be available in the main menu. |
||||
|
||||
<img class="no-shadow" src="/img/v3/app-in-main-menu.png"> |
||||
|
||||
## Enabling app plugins |
||||
After installing an app it have to be enabled before it show up as an datasource or panel. You can do that on the app page in the config tab. |
||||
|
||||
### Develop your own App |
||||
|
||||
> Our goal is not to have a very extensive documentation but rather have actual |
||||
> code that people can look at. An example implementation of an app can be found |
||||
> in this [example app repo](https://github.com/grafana/example-app) |
||||
|
||||
@ -0,0 +1,63 @@ |
||||
+++ |
||||
title = "Developing App Plugins" |
||||
keywords = ["grafana", "plugins", "documentation"] |
||||
type = "docs" |
||||
[menu.docs] |
||||
name = "Developing App Plugins" |
||||
parent = "developing" |
||||
weight = 6 |
||||
+++ |
||||
|
||||
# Grafana Apps |
||||
|
||||
App plugins are a new kind of grafana plugin that can bundle datasource and panel plugins within one package. It also enable the plugin author to create custom pages within grafana. The custom pages enable the plugin author to include things like documentation, sign up forms or controlling other services using HTTP requests. |
||||
|
||||
Datasource and panel plugins will show up like normal plugins. The app pages will be available in the main menu. |
||||
|
||||
{{< imgbox img="/img/docs/v3/app-in-main-menu.png" caption="App in Main Menu" >}} |
||||
|
||||
## Enabling app plugins |
||||
|
||||
After installing an app, it has to be enabled before it shows up as a datasource or panel. You can do that on the app page in the config tab. |
||||
|
||||
## Developing an App Plugin |
||||
|
||||
An App is a bundle of panels, dashboards and/or data source(s). There is nothing different about developing panels and data sources for an app. |
||||
|
||||
Apps have to be enabled in Grafana and should import any included dashboards when the user enables it. A ConfigCtrl class should be created and the dashboards imported in the postUpdate hook. See example below: |
||||
|
||||
```javascript |
||||
export class ConfigCtrl { |
||||
/** @ngInject */ |
||||
constructor($scope, $injector, $q) { |
||||
this.$q = $q; |
||||
this.enabled = false; |
||||
this.appEditCtrl.setPostUpdateHook(this.postUpdate.bind(this)); |
||||
} |
||||
|
||||
postUpdate() { |
||||
if (!this.appModel.enabled) { |
||||
return this.$q.resolve(); |
||||
} |
||||
return this.appEditCtrl.importDashboards().then(() => { |
||||
this.enabled = true; |
||||
return { |
||||
url: "plugins/raintank-kubernetes-app/page/clusters", |
||||
message: "Kubernetes App enabled!" |
||||
}; |
||||
}); |
||||
} |
||||
} |
||||
ConfigCtrl.templateUrl = 'components/config/config.html'; |
||||
``` |
||||
|
||||
If possible a link to a dashboard or custom page should be shown after enabling the app to guide the user to the appropriate place. |
||||
|
||||
{{< imgbox img="/img/docs/app_plugin_after_enable.png" caption="After enabling" >}} |
||||
|
||||
### Develop your own App |
||||
|
||||
> Our goal is not to have a very extensive documentation but rather have actual |
||||
> code that people can look at. An example implementation of an app can be found |
||||
> in this [example app repo](https://github.com/grafana/example-app) |
||||
|
||||
@ -0,0 +1,182 @@ |
||||
+++ |
||||
title = "Plugin Code Styleguide" |
||||
type = "docs" |
||||
[menu.docs] |
||||
name = "Plugin Code Styleguide" |
||||
parent = "developing" |
||||
weight = 2 |
||||
+++ |
||||
|
||||
# Grafana Plugin Code Styleguide |
||||
|
||||
This guide has two parts. The first part describes the metadata and the second part is a styleguide for HTML/CSS and JavaScript in Grafana plugins and applies if you are using ES6 in your plugin. If using TypeScript then the [Angular TypeScript styleguide](https://angular.io/styleguide) is recommended. |
||||
|
||||
## Metadata |
||||
|
||||
The plugin metadata consists of a plugin.json file and the README.md file. These two files are used by Grafana and Grafana.net. |
||||
|
||||
### Plugin.json (mandatory) |
||||
|
||||
The plugin.json file is the same concept as the package.json file for an npm package. When Grafana starts it will scan the plugin folders and mount every folder that contains a plugin.json file unless the folder contains a subfolder named `dist`. In that case grafana will mount the `dist` folder instead. |
||||
|
||||
The most important fields are the first three, especially the id. The convention for the plugin id is **[github username/org]-[plugin name]-[datasource|app|panel]** and it has to be unique. |
||||
|
||||
Examples: |
||||
|
||||
``` |
||||
raintank-worldping-app |
||||
grafana-simple-json-datasource |
||||
grafana-piechart-panel |
||||
mtanda-histogram-panel |
||||
``` |
||||
|
||||
The full file format for plugin.json is described [here]({{< relref "plugin.json.md" >}}). |
||||
|
||||
Minimal plugin.json: |
||||
|
||||
```javascript |
||||
{ |
||||
"type": "panel", |
||||
"name": "Clock", |
||||
"id": "yourorg-clock-panel", |
||||
|
||||
"info": { |
||||
"description": "Clock panel for grafana", |
||||
"author": { |
||||
"name": "Raintank Inc.", |
||||
"url": "http://raintank.io" |
||||
}, |
||||
"keywords": ["clock", "panel"], |
||||
"version": "1.0.0", |
||||
"updated": "2015-03-24" |
||||
}, |
||||
|
||||
"dependencies": { |
||||
"grafanaVersion": "3.x.x", |
||||
"plugins": [ ] |
||||
} |
||||
} |
||||
``` |
||||
|
||||
### README.md |
||||
|
||||
The README.md file is rendered both on Grafana.net and in the plugins section in Grafana. The only difference from how GitHub renders markdown is that html is not allowed. |
||||
|
||||
## File and Directory Structure Conventions |
||||
|
||||
Here is a typical directory structure for a plugin. |
||||
|
||||
``` |
||||
johnnyb-awesome-datasource |
||||
|-- dist |
||||
|-- spec |
||||
| |-- datasource_spec.js |
||||
| |-- query_ctrl_spec.js |
||||
| |-- test-main.js |
||||
|-- src |
||||
| |-- img |
||||
| | |-- logo.svg |
||||
| |-- partials |
||||
| | |-- annotations.editor.html |
||||
| | |-- config.html |
||||
| | |-- query.editor.html |
||||
| |-- datasource.js |
||||
| |-- module.js |
||||
| |-- plugin.json |
||||
| |-- query_ctrl.js |
||||
|-- Gruntfile.js |
||||
|-- LICENSE |
||||
|-- package.json |
||||
|-- README.md |
||||
``` |
||||
|
||||
Most JavaScript projects have a build step and most Grafana plugins are built using Babel and ES6. The generated JavaScript should be placed in the `dist` directory and the source code in the `src` directory. We recommend that the plugin.json file be placed in the src directory and then copied over to the dist directory when building. The `README.md` can be placed in the root or in the dist directory. |
||||
|
||||
Directories: |
||||
|
||||
- `src/` contains plugin source files. |
||||
- `src/partials` contains html templates. |
||||
- `src/img` contains plugin logos and other images. |
||||
- `spec/` contains tests (optional). |
||||
- `dist/` contains built content. |
||||
|
||||
## HTML and CSS |
||||
|
||||
For the HTML on editor tabs, we recommend using the inbuilt Grafana styles rather than defining your own. This makes plugins feel like a more natural part of Grafana. If done correctly, the html will also be responsive and adapt to smaller screens. The `gf-form` css classes should be used for labels and inputs. |
||||
|
||||
Below is a minimal example of an editor row with one form group and two fields, a dropdown and a text input: |
||||
|
||||
```html |
||||
<div class="editor-row"> |
||||
<div class="section gf-form-group"> |
||||
<h5 class="section-heading">My Plugin Options</h5> |
||||
<div class="gf-form"> |
||||
<label class="gf-form-label width-10">Label1</label> |
||||
<div class="gf-form-select-wrapper max-width-10"> |
||||
<select class="input-small gf-form-input" ng-model="ctrl.panel.mySelectProperty" ng-options="t for t in ['option1', 'option2', 'option3']" ng-change="ctrl.onSelectChange()"></select> |
||||
</div> |
||||
<div class="gf-form"> |
||||
<label class="gf-form-label width-10">Label2</label> |
||||
<input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.myProperty" ng-change="ctrl.onFieldChange()" placeholder="suggestion for user" ng-model-onblur /> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
``` |
||||
|
||||
Use the `width-x` and `max-width-x` classes to control the width of your labels and input fields. Try to get labels and input fields to line up neatly by having the same width for all the labels in a group and the same width for all inputs in a group if possible. |
||||
|
||||
## Build Scripts |
||||
|
||||
Our recommendation is to use whatever you usually use - Grunt, Gulp or npm scripts. Most plugins seems to use Grunt so that is probably the easiest to get started with if you do not have a preferred build system. The only requirement is that it supports systemjs which is required by Grafana to load plugins. |
||||
|
||||
## Linting |
||||
|
||||
We recommend that you use a linter for your JavaScript. For ES6, the standard linter is [eslint](http://eslint.org/). Rules for linting are described in an .eslintrc that is placed in the root directory. [Here is an example](https://github.com/grafana/worldmap-panel/blob/master/.eslintrc) of linting rules in a plugin. |
||||
|
||||
### ES6 features |
||||
|
||||
1. Use `const` if a variable is not going to be reassigned. |
||||
2. Prefer to use `let` instead `var` ([Exploring ES6](http://exploringjs.com/es6/ch_core-features.html#_from-var-to-letconst)) |
||||
3. Use arrow functions, which don’t shadow `this` ([Exploring ES6](http://exploringjs.com/es6/ch_core-features.html#_from-function-expressions-to-arrow-functions)): |
||||
|
||||
```js |
||||
testDatasource() { |
||||
return this.getServerStatus() |
||||
.then(status => { |
||||
return this.doSomething(status); |
||||
}) |
||||
} |
||||
``` |
||||
|
||||
better than |
||||
|
||||
```js |
||||
testDatasource() { |
||||
var self = this; |
||||
return this.getServerStatus() |
||||
.then(function(status) { |
||||
return self.doSomething(status); |
||||
}) |
||||
} |
||||
``` |
||||
4. Use native _Promise_ object: |
||||
|
||||
```js |
||||
metricFindQuery(query) { |
||||
if (!query) { |
||||
return Promise.resolve([]); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
better than |
||||
|
||||
```js |
||||
metricFindQuery(query) { |
||||
if (!query) { |
||||
return this.$q.when([]); |
||||
} |
||||
} |
||||
``` |
||||
5. If using Lodash, then be consequent and prefer that to the native ES6 array functions. |
||||
@ -0,0 +1,120 @@ |
||||
+++ |
||||
title = "Developer Guide" |
||||
type = "docs" |
||||
aliases = ["/plugins/development/", "/plugins/datasources/", "/plugins/apps/", "/plugins/panels/"] |
||||
[menu.docs] |
||||
name = "Developer Guide" |
||||
parent = "developing" |
||||
weight = 1 |
||||
+++ |
||||
|
||||
# Developer Guide |
||||
|
||||
From grafana 3.0 it's very easy to develop your own plugins and share them with other grafana users. |
||||
|
||||
There are two blog posts about authoring a plugin that might also be of interest to any plugin authors, [Timing is Everything. Writing the Clock Panel Plugin for Grafana 3.0- part 1](http://grafana.org/blog/2016/04/08/timing-is-everything.-writing-the-clock-panel-plugin-for-grafana-3.0/) and [Timing is Everything. Editor Mode in Grafana 3.0 for the Clock Panel Plugin](http://grafana.org/blog/2016/04/15/timing-is-everything.-editor-mode-in-grafana-3.0-for-the-clock-panel-plugin/). |
||||
|
||||
## Short version |
||||
|
||||
1. [Setup grafana](http://docs.grafana.org/project/building_from_source/) |
||||
2. Clone an example plugin into ```/var/lib/grafana/plugins``` or `data/plugins` (relative to grafana git repo if your running development version from source dir) |
||||
3. Code away! |
||||
|
||||
## What languages? |
||||
|
||||
Since everything turns into javascript it's up to you to choose which language you want. That said it's probably a good idea to choose es6 or typescript since we use es6 classes in Grafana. So it's easier to get inspiration from the Grafana repo is you choose one of those languages. |
||||
|
||||
## Buildscript |
||||
|
||||
You can use any build system you like that support systemjs. All the built content should end up in a folder named ```dist``` and committed to the repository.By committing the dist folder the person who installs your plugin does not have to run any buildscript. |
||||
|
||||
All our example plugins have build scripted configured. |
||||
|
||||
## Metadata |
||||
|
||||
See the [coding styleguide]({{< relref "code-styleguide.md" >}}) for details on the metadata. |
||||
|
||||
## module.(js|ts) |
||||
|
||||
This is the entry point for every plugin. This is the place where you should export |
||||
your plugin implementation. Depending on what kind of plugin you are developing you |
||||
will be expected to export different things. You can find what's expected for [datasource]({{< relref "datasources.md" >}}), [panels]({{< relref "panels.md" >}}) |
||||
and [apps]({{< relref "apps.md" >}}) plugins in the documentation. |
||||
|
||||
The Grafana SDK is quite small so far and can be found here: |
||||
|
||||
- [SDK file in Grafana](https://github.com/grafana/grafana/blob/master/public/app/plugins/sdk.ts) |
||||
- [SDK Readme](https://github.com/grafana/grafana/blob/master/public/app/plugins/plugin_api.md) |
||||
|
||||
The SDK contains three different plugin classes: PanelCtrl, MetricsPanelCtrl and QueryCtrl. For plugins of the panel type, the module.js file should export one of these. There are some extra classes for [data sources]({{< relref "datasources.md" >}}). |
||||
|
||||
Example: |
||||
|
||||
```javascript |
||||
import {ClockCtrl} from './clock_ctrl'; |
||||
|
||||
export { |
||||
ClockCtrl as PanelCtrl |
||||
}; |
||||
``` |
||||
|
||||
The module class is also where css for the dark and light themes is imported: |
||||
|
||||
```javascript |
||||
import {loadPluginCss} from 'app/plugins/sdk'; |
||||
import WorldmapCtrl from './worldmap_ctrl'; |
||||
|
||||
loadPluginCss({ |
||||
dark: 'plugins/grafana-worldmap-panel/css/worldmap.dark.css', |
||||
light: 'plugins/grafana-worldmap-panel/css/worldmap.light.css' |
||||
}); |
||||
|
||||
export { |
||||
WorldmapCtrl as PanelCtrl |
||||
}; |
||||
``` |
||||
|
||||
## Start developing your plugin |
||||
|
||||
There are three ways that you can start developing a Grafana plugin. |
||||
|
||||
1. Setup a Grafana development environment. [(described here)](http://docs.grafana.org/project/building_from_source/) and place your plugin in the ```data/plugins``` folder. |
||||
2. Install Grafana and place your plugin in the plugins directory which is set in your [config file](/installation/configuration). By default this is `/var/lib/grafana/plugins` on Linux systems. |
||||
3. Place your plugin directory anywhere you like and specify it grafana.ini. |
||||
|
||||
We encourage people to setup the full Grafana environment so that you can get inspiration from the rest of grafana code base. |
||||
|
||||
When Grafana starts it will scan the plugin folders and mount every folder that contains a plugin.json file unless |
||||
the folder contains a subfolder named dist. In that case grafana will mount the dist folder instead. |
||||
This makes it possible to have both built and src content in the same plugin git repo. |
||||
|
||||
## Grafana Events |
||||
|
||||
There are a number of Grafana events that a plugin can hook into: |
||||
|
||||
- `init-edit-mode` can be used to add tabs when editing a panel |
||||
- `panel-teardown` can be used for clean up |
||||
- `data-received` is an event in that is triggered on data refresh and can be hooked into |
||||
- `data-snapshot-load` is an event triggered to load data when in snapshot mode. |
||||
- `data-error` is used to handle errors on dashboard refresh. |
||||
|
||||
If a panel receives data and hooks into the `data-received` event then it should handle snapshot mode too. Otherwise the panel will not work if saved as a snapshot. [Getting Plugins to work in Snapshot Mode]({{< relref "snapshot-mode.md" >}}) describes how to add support for this. |
||||
|
||||
## Examples |
||||
|
||||
We currently have three different examples that you can fork/download to get started developing your grafana plugin. |
||||
|
||||
- [simple-json-datasource](https://github.com/grafana/simple-json-datasource) (small datasource plugin for querying json data from backends) |
||||
- [example-app](https://github.com/grafana/example-app) |
||||
- [clock-panel](https://github.com/grafana/clock-panel) |
||||
- [singlestat-panel](https://github.com/grafana/grafana/blob/master/public/app/plugins/panel/singlestat/module.ts) |
||||
- [piechart-panel](https://github.com/grafana/piechart-panel) |
||||
|
||||
## Other Articles |
||||
|
||||
- [Getting Plugins to work in Snapshot Mode]({{< relref "snapshot-mode.md" >}}) |
||||
- [Plugin Defaults and Editor Mode]({{< relref "defaults-and-editor-mode.md" >}}) |
||||
- [Grafana Plugin Code Styleguide]({{< relref "code-styleguide.md" >}}) |
||||
- [Grafana Apps]({{< relref "apps.md" >}}) |
||||
- [Grafana Datasources]({{< relref "datasources.md" >}}) |
||||
- [plugin.json Schema]({{< relref "plugin.json.md" >}}) |
||||
@ -0,0 +1,8 @@ |
||||
+++ |
||||
title = "Developing Plugins" |
||||
type = "docs" |
||||
[menu.docs] |
||||
parent = "plugins" |
||||
identifier = "developing" |
||||
weight = 3 |
||||
+++ |
||||
@ -0,0 +1,28 @@ |
||||
+++ |
||||
title = "plugin.json Schema" |
||||
keywords = ["grafana", "plugins", "documentation"] |
||||
type = "docs" |
||||
[menu.docs] |
||||
name = "plugin.json Schema" |
||||
parent = "developing" |
||||
weight = 6 |
||||
+++ |
||||
|
||||
# Plugin.json |
||||
|
||||
The plugin.json file is mandatory for all plugins. When Grafana starts it will scan the plugin folders and mount every folder that contains a plugin.json file unless the folder contains a subfolder named `dist`. In that case grafana will mount the `dist` folder instead. |
||||
|
||||
## Plugin JSON Schema |
||||
|
||||
| Property | Description | |
||||
| ------------- |-------------| |
||||
| id | unique name of the plugin - [conventions described in styleguide]({{< relref "code-styleguide.md" >}}) | |
||||
| type | panel/datasource/app | |
||||
| name | Human readable name of the plugin | |
||||
| info.description | Description of plugin. Used for searching grafana net plugins | |
||||
| info.author | | |
||||
| info.keywords | plugin keywords. Used for search on grafana net| |
||||
| info.logos | link to project logos | |
||||
| info.version | project version of this commit. Must be semver | |
||||
| dependencies.grafanaVersion | Required grafana backend version for this plugin | |
||||
| dependencies.plugins | required plugins for this plugin. | |
||||
@ -0,0 +1,79 @@ |
||||
+++ |
||||
title = "Snapshot Mode" |
||||
type = "docs" |
||||
[menu.docs] |
||||
name = "Snapshot Mode" |
||||
parent = "developing" |
||||
weight = 6 |
||||
+++ |
||||
|
||||
# Getting Plugins to work in Snapshot Mode |
||||
|
||||
{{< imgbox img="/img/docs/Grafana-snapshot-example.png" caption="A dashboard using snapshot data and not live data." >}} |
||||
|
||||
Grafana has this great feature where you can [save a snapshot of your dashboard](http://docs.grafana.org/reference/sharing/). Instead of sending a screenshot of a dashboard to someone, you can send them a working, interactive Grafana dashboard with the snapshot data embedded inside it. The snapshot can be saved on your Grafana server and is available to all your co-workers. Raintank also hosts a [snapshot server](http://snapshot.raintank.io/) if you want to send the snapshot to someone who does not have access to your Grafana server. |
||||
|
||||
{{< imgbox img="/img/docs/animated_gifs/snapshots.gif" caption="Selecting a snapshot" >}} |
||||
|
||||
This all works because Grafana saves a snapshot of the current data in the dashboard json instead of fetching the data from a data source. However, if you are building a custom panel plugin then this will not work straight out of the box. You will need to make some small (and easy!) changes first. |
||||
|
||||
## Enabling support for loading snapshot data |
||||
|
||||
Grafana automatically saves data from data sources in the dashboard json when the snapshot is created so we do not have to write any code for that. Enabling snapshot support for reading time series data is very simple. First in the constructor, we need to add an event handler for `data-snapshot-load`. This event is triggered by Grafana when the snapshot data is loaded from the dashboard json. |
||||
|
||||
```javascript |
||||
constructor($scope, $injector, contextSrv) { |
||||
super($scope, $injector); |
||||
... |
||||
this.events.on('init-edit-mode', this.onInitEditMode.bind(this)); |
||||
this.events.on('data-received', this.onDataReceived.bind(this)); |
||||
this.events.on('panel-teardown', this.onPanelTeardown.bind(this)); |
||||
this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this)); |
||||
``` |
||||
|
||||
Then we need to create a simple event handler that just forwards the data on to our regular `data-received` handler: |
||||
|
||||
```javascript |
||||
onDataSnapshotLoad(snapshotData) { |
||||
this.onDataReceived(snapshotData); |
||||
} |
||||
``` |
||||
|
||||
This will cover most use cases for snapshot support. Sometimes you will want to save data that is not time series data from a Grafana data source and then you have to do a bit more work to get snapshot support. |
||||
|
||||
## Saving custom data for snapshots |
||||
|
||||
Data that is not time series data from a Grafana data source is not saved automatically by Grafana. Saving custom data for snapshot mode has to be done manually. |
||||
|
||||
{{< imgbox img="/img/docs/Grafana-save-snapshot.png" caption="Save snapshot" >}} |
||||
|
||||
Grafana gives us a chance to save data to the dashboard json when it is creating a snapshot. In the 'data-received' event handler, you can check the snapshot flag on the dashboard object. If this is true, then Grafana is creating a snapshot and you can manually save custom data to the panel json. In the example, a new field called snapshotLocationData in the panel json is initialized with a snapshot of the custom data. |
||||
|
||||
```javascript |
||||
onDataReceived(dataList) { |
||||
if (!dataList) return; |
||||
|
||||
if (this.dashboard.snapshot && this.locations) { |
||||
this.panel.snapshotLocationData = this.locations; |
||||
} |
||||
``` |
||||
|
||||
Now the location data is saved in the dashboard json but we will have to load it manually as well. |
||||
|
||||
## Loading custom data for snapshots |
||||
|
||||
The example below shows a function that loads the custom data. The data source for the custom data (an external api in this case) is not available in snapshot mode so a guard check is made to see if there is any snapshot data available first. If there is, then the snapshot data is used instead of trying to load the data from the external api. |
||||
|
||||
```javascript |
||||
loadLocationDataFromFile(reload) { |
||||
if (this.map && !reload) return; |
||||
|
||||
if (this.panel.snapshotLocationData) { |
||||
this.locations = this.panel.snapshotLocationData; |
||||
return; |
||||
} |
||||
``` |
||||
|
||||
It is really easy to forget to add this support but it enables a great feature and can be used to demo your panel. |
||||
|
||||
If there is a panel plugin that you would like to be installed on the Raintank Snapshot server then please contact us via [Slack](https://raintank.slack.com) or [GitHub](https://github.com/grafana/grafana). |
||||
@ -1,60 +0,0 @@ |
||||
+++ |
||||
title = "Developer Guide" |
||||
type = "docs" |
||||
aliases = ["/plugins/datasources/", "/plugins/apps/", "/plugins/panels/"] |
||||
[menu.docs] |
||||
name = "Developer Guide" |
||||
parent = "plugins" |
||||
weight = 5 |
||||
+++ |
||||
|
||||
# Developer Guide |
||||
|
||||
From grafana 3.0 it's very easy to develop your own plugins and share them with other grafana users. |
||||
|
||||
## Short version |
||||
|
||||
1. [Setup grafana](http://docs.grafana.org/project/building_from_source/) |
||||
2. Clone an example plugin into ```/var/lib/grafana/plugins``` or `data/plugins` (relative to grafana git repo if your running development version from source dir) |
||||
3. Code away! |
||||
|
||||
## What languages? |
||||
|
||||
Since everything turns into javascript it's up to you to choose which language you want. That said it's probably a good idea to choose es6 or typescript since we use es6 classes in Grafana. So it's easier to get inspiration from the Grafana repo is you choose one of those languages. |
||||
|
||||
## Buildscript |
||||
|
||||
You can use any build system you like that support systemjs. All the built content should end up in a folder named ```dist``` and committed to the repository.By committing the dist folder the person who installs your plugin does not have to run any buildscript. |
||||
|
||||
All our example plugins have build scripted configured. |
||||
|
||||
## module.(js|ts) |
||||
|
||||
This is the entry point for every plugin. This is the place where you should export |
||||
your plugin implementation. Depending on what kind of plugin you are developing you |
||||
will be expected to export different things. You can find what's expected for [datasource](./datasources.md), [panels](./panels.md) |
||||
and [apps](./apps.md) plugins in the documentation. |
||||
|
||||
## Start developing your plugin |
||||
|
||||
There are three ways that you can start developing a Grafana plugin. |
||||
|
||||
1. Setup a Grafana development environment. [(described here)](http://docs.grafana.org/project/building_from_source/) and place your plugin in the ```data/plugins``` folder. |
||||
2. Install Grafana and place your plugin in the plugins directory which is set in your [config file](../installation/configuration.md). By default this is `/var/lib/grafana/plugins` on Linux systems. |
||||
3. Place your plugin directory anywhere you like and specify it grafana.ini. |
||||
|
||||
We encourage people to setup the full Grafana environment so that you can get inspiration from the rest of grafana code base. |
||||
|
||||
When Grafana starts it will scan the plugin folders and mount every folder that contains a plugin.json file unless |
||||
the folder contains a subfolder named dist. In that case grafana will mount the dist folder instead. |
||||
This makes it possible to have both built and src content in the same plugin git repo. |
||||
|
||||
## Examples |
||||
|
||||
We currently have three different examples that you can fork/download to get started developing your grafana plugin. |
||||
|
||||
- [simple-json-datasource](https://github.com/grafana/simple-json-datasource) (small datasource plugin for querying json data from backends) |
||||
- [example-app](https://github.com/grafana/example-app) |
||||
- [clock-panel](https://github.com/grafana/clock-panel) |
||||
- [singlestat-panel](https://github.com/grafana/grafana/blob/master/public/app/plugins/panel/singlestat/module.ts) |
||||
- [piechart-panel](https://github.com/grafana/piechart-panel) |
||||
@ -1,10 +0,0 @@ |
||||
--- |
||||
page_title: Plugin json file |
||||
page_description: Plugin json for Grafana |
||||
page_keywords: grafana, plugins, documentation |
||||
--- |
||||
|
||||
# Plugin.json |
||||
|
||||
TODO |
||||
|
||||
Loading…
Reference in new issue