mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
Merge branch 'master' into alerting
This commit is contained in:
commit
4fd8b2ace4
@ -7,7 +7,7 @@
|
||||
* **Templating**: Update panel repeats for variables that change on time refresh, closes [#5021](https://github.com/grafana/grafana/issues/5021)
|
||||
* **Elasticsearch**: Support to set Precision Threshold for Unique Count metric, closes [#4689](https://github.com/grafana/grafana/issues/4689)
|
||||
|
||||
# 3.1.1 (unreleased / v3.1.x branch)
|
||||
# 3.1.1 (2016-08-01)
|
||||
* **IFrame embedding**: Fixed issue of using full iframe height, fixes [#5605](https://github.com/grafana/grafana/issues/5606)
|
||||
* **Panel PNG rendering**: Fixed issue detecting render completion, fixes [#5605](https://github.com/grafana/grafana/issues/5606)
|
||||
* **Elasticsearch**: Fixed issue with templating query and json parse error, fixes [#5615](https://github.com/grafana/grafana/issues/5615)
|
||||
@ -15,6 +15,7 @@
|
||||
* **Graphite**: Fixed issue with mixed data sources and Graphite, fixes [#5617](https://github.com/grafana/grafana/issues/5617)
|
||||
* **Templating**: Fixed issue with template variable query was issued multiple times during dashboard load, fixes [#5637](https://github.com/grafana/grafana/issues/5637)
|
||||
* **Zoom**: Fixed issues with zoom in and out on embedded (iframed) panel, fixes [#4489](https://github.com/grafana/grafana/issues/4489), [#5666](https://github.com/grafana/grafana/issues/5666)
|
||||
* **Templating**: Row/Panel repeat issue when saving dashboard caused dupes to appear, fixes [#5591](https://github.com/grafana/grafana/issues/5591)
|
||||
|
||||
# 3.1.0 stable (2016-07-12)
|
||||
|
||||
|
@ -18,15 +18,13 @@ dependencies:
|
||||
|
||||
test:
|
||||
override:
|
||||
# FMT
|
||||
- test -z "$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"
|
||||
# GO VET
|
||||
- go vet ./pkg/...
|
||||
# Go test
|
||||
- godep go test -v ./pkg/...
|
||||
# js tests
|
||||
# JS tests
|
||||
- npm test
|
||||
- npm run coveralls
|
||||
# GO tests
|
||||
- godep go test -v ./pkg/...
|
||||
|
||||
deployment:
|
||||
master:
|
||||
|
@ -378,7 +378,7 @@ interval_seconds = 60
|
||||
# Send internal Grafana metrics to graphite
|
||||
; [metrics.graphite]
|
||||
; address = localhost:2003
|
||||
; prefix = prod.grafana.%(instance_name)s.
|
||||
; prefix = service.grafana.%(instance_name)s
|
||||
|
||||
[grafana_net]
|
||||
url = https://grafana.net
|
||||
|
@ -298,7 +298,7 @@ check_for_updates = true
|
||||
# Metrics available at HTTP API Url /api/metrics
|
||||
[metrics]
|
||||
# Disable / Enable internal metrics
|
||||
;enabled = true
|
||||
enabled = true
|
||||
|
||||
# Publish interval
|
||||
;interval_seconds = 10
|
||||
@ -306,7 +306,7 @@ check_for_updates = true
|
||||
# Send internal metrics to Graphite
|
||||
; [metrics.graphite]
|
||||
; address = localhost:2003
|
||||
; prefix = prod.grafana.%(instance_name)s.
|
||||
; prefix = service.grafana.%(instance_name)s
|
||||
|
||||
#################################### Internal Grafana Metrics ##########################
|
||||
# Url used to to import dashboards directly from Grafana.net
|
||||
|
@ -5,7 +5,7 @@ page_keywords: grafana, guide, documentation
|
||||
---
|
||||
|
||||
# Getting started
|
||||
This guide will help you get started and acquainted with Grafana. It assumes you have a working Grafana 2.x instance, and have added at least one [Data Source](/datasources/overview).
|
||||
This guide will help you get started and acquainted with Grafana. It assumes you have a working Grafana server up and running and have added at least one [Data Source](/datasources/overview).
|
||||
|
||||
## Beginner guides
|
||||
Watch the 10min [beginners guide to building dashboards](https://www.youtube.com/watch?v=sKNZMtoSHN4&index=7&list=PLDGkOdUX1Ujo3wHw9-z5Vo12YLqXRjzg2) to get a quick intro to setting up Dashboards and Panels.
|
||||
|
@ -76,7 +76,7 @@ The IP address to bind to. If empty will bind to all interfaces
|
||||
The port to bind to, defaults to `3000`. To use port 80 you need to
|
||||
either give the Grafana binary permission for example:
|
||||
|
||||
$ sudo setcap 'cap_net_bind_service=+ep' /opt/grafana/current/grafana
|
||||
$ sudo setcap 'cap_net_bind_service=+ep' /usr/sbin/grafana-server
|
||||
|
||||
Or redirect port 80 to the Grafana port using:
|
||||
|
||||
@ -477,3 +477,14 @@ Format `<Hostname or ip>`:port
|
||||
### prefix
|
||||
Graphite metric prefix. Defaults to `prod.grafana.%(instance_name)s.`
|
||||
|
||||
## [snapshots]
|
||||
|
||||
### external_enabled
|
||||
Set to false to disable external snapshot publish endpoint (default true)
|
||||
|
||||
### external_snapshot_url
|
||||
Set root url to a Grafana instance where you want to publish external snapshots (defaults to https://snapshots-origin.raintank.io)
|
||||
|
||||
### external_snapshot_name
|
||||
Set name for external snapshot button. Defaults to `Publish to snapshot.raintank.io`
|
||||
|
||||
|
@ -10,13 +10,13 @@ page_keywords: grafana, installation, debian, ubuntu, guide
|
||||
|
||||
Description | Download
|
||||
------------ | -------------
|
||||
Stable .deb for Debian-based Linux | [3.1.0](https://grafanarel.s3.amazonaws.com/builds/grafana_3.1.0-1468321182_amd64.deb)
|
||||
Stable .deb for Debian-based Linux | [3.1.1 (x86-64 deb)](https://grafanarel.s3.amazonaws.com/builds/grafana_3.1.1-1470047149_amd64.deb)
|
||||
|
||||
## Install Stable
|
||||
|
||||
$ wget https://grafanarel.s3.amazonaws.com/builds/grafana_3.1.0-1468321182_amd64.deb
|
||||
$ wget https://grafanarel.s3.amazonaws.com/builds/grafana_3.1.1-1470047149_amd64.deb
|
||||
$ sudo apt-get install -y adduser libfontconfig
|
||||
$ sudo dpkg -i grafana_3.1.0-1468321182_amd64.deb
|
||||
$ sudo dpkg -i grafana_3.1.1-1470047149_amd64.deb
|
||||
|
||||
## APT Repository
|
||||
|
||||
|
@ -11,28 +11,17 @@ Installation can be done using [homebrew](http://brew.sh/)
|
||||
Install latest stable:
|
||||
|
||||
```
|
||||
brew install grafana/grafana/grafana
|
||||
brew update
|
||||
brew install grafana
|
||||
```
|
||||
|
||||
To start grafana look at the command printed after the homebrew install completes.
|
||||
|
||||
You can also add the grafana as tap.
|
||||
|
||||
```
|
||||
brew tap grafana/grafana
|
||||
brew install grafana
|
||||
```
|
||||
|
||||
Install latest unstable from master:
|
||||
|
||||
```
|
||||
brew install --HEAD grafana/grafana/grafana
|
||||
```
|
||||
|
||||
To upgrade use the reinstall command
|
||||
|
||||
```
|
||||
brew reinstall --HEAD grafana/grafana/grafana
|
||||
brew update
|
||||
brew reinstall grafana
|
||||
```
|
||||
|
||||
|
||||
|
@ -10,24 +10,24 @@ page_keywords: grafana, installation, centos, fedora, opensuse, redhat, guide
|
||||
|
||||
Description | Download
|
||||
------------ | -------------
|
||||
Stable .RPM for CentOS / Fedora / OpenSuse / Redhat Linux | [3.1.0 (x86-64 rpm)](https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.0-1468321182.x86_64.rpm)
|
||||
Stable .RPM for CentOS / Fedora / OpenSuse / Redhat Linux | [3.1.1 (x86-64 rpm)](https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.1-1470047149.x86_64.rpm)
|
||||
|
||||
## Install Latest Stable
|
||||
|
||||
You can install Grafana using Yum directly.
|
||||
|
||||
$ sudo yum install https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.0-1468321182.x86_64.rpm
|
||||
$ sudo yum install https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.1-1470047149.x86_64.rpm
|
||||
|
||||
Or install manually using `rpm`.
|
||||
|
||||
#### On CentOS / Fedora / Redhat:
|
||||
|
||||
$ sudo yum install initscripts fontconfig
|
||||
$ sudo rpm -Uvh grafana-3.1.0-1468321182.x86_64.rpm
|
||||
$ sudo rpm -Uvh grafana-3.1.1-1470047149.x86_64.rpm
|
||||
|
||||
#### On OpenSuse:
|
||||
|
||||
$ sudo rpm -i --nodeps grafana-3.1.0-1468321182.x86_64.rpm
|
||||
$ sudo rpm -i --nodeps grafana-3.1.1-1470047149.x86_64.rpm
|
||||
|
||||
## Install via YUM Repository
|
||||
|
||||
|
@ -10,7 +10,7 @@ page_keywords: grafana, installation, windows guide
|
||||
|
||||
Description | Download
|
||||
------------ | -------------
|
||||
Stable Zip package for Windows | [grafana.3.1.0.windows-x64.zip](https://grafanarel.s3.amazonaws.com/winbuilds/dist/grafana-3.1.0.windows-x64.zip)
|
||||
Stable Zip package for Windows | [grafana.3.1.1.windows-x64.zip](https://grafanarel.s3.amazonaws.com/winbuilds/dist/grafana-3.1.1.windows-x64.zip)
|
||||
|
||||
## Configure
|
||||
|
||||
|
@ -14,7 +14,7 @@ Since Grafana automatically scales Dashboards to any resolution they're perfect
|
||||
|
||||
The Playlist feature can be accessed from Grafana's sidemenu. Click the 'Playlist' button from the sidemenu to access the Playlist functionality. When 'Playlist' button is clicked, playlist view will open up showing saved playlists and an option to create new playlists.
|
||||
|
||||
<img src="/img/v2/dashboard_search.png" class="no-shadow">
|
||||
<img src="/img/v3/playlist.png" class="no-shadow">
|
||||
|
||||
Click on "New Playlist" button to create a new playlist. Firstly, name your playlist and configure a time interval for Grafana to wait on a particular Dashboard before advancing to the next one on the Playlist.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"stable": "3.1.0",
|
||||
"testing": "3.1.0"
|
||||
"stable": "3.1.1",
|
||||
"testing": "3.1.1"
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
deb_ver=3.1.0-1466666977beta1
|
||||
rpm_ver=3.1.0-1466666977beta1
|
||||
deb_ver=3.1.1-1470047149
|
||||
rpm_ver=3.1.1-1470047149
|
||||
|
||||
# wget https://grafanarel.s3.amazonaws.com/builds/grafana_${deb_ver}_amd64.deb
|
||||
wget https://grafanarel.s3.amazonaws.com/builds/grafana_${deb_ver}_amd64.deb
|
||||
|
||||
# package_cloud push grafana/stable/debian/jessie grafana_${deb_ver}_amd64.deb
|
||||
# package_cloud push grafana/stable/debian/wheezy grafana_${deb_ver}_amd64.deb
|
||||
package_cloud push grafana/stable/debian/jessie grafana_${deb_ver}_amd64.deb
|
||||
package_cloud push grafana/stable/debian/wheezy grafana_${deb_ver}_amd64.deb
|
||||
|
||||
package_cloud push grafana/testing/debian/jessie grafana_${deb_ver}_amd64.deb
|
||||
package_cloud push grafana/testing/debian/wheezy grafana_${deb_ver}_amd64.deb
|
||||
|
||||
# wget https://grafanarel.s3.amazonaws.com/builds/grafana-${rpm_ver}.x86_64.rpm
|
||||
wget https://grafanarel.s3.amazonaws.com/builds/grafana-${rpm_ver}.x86_64.rpm
|
||||
|
||||
package_cloud push grafana/testing/el/6 grafana-${rpm_ver}.x86_64.rpm
|
||||
package_cloud push grafana/testing/el/7 grafana-${rpm_ver}.x86_64.rpm
|
||||
|
||||
# package_cloud push grafana/stable/el/7 grafana-${rpm_ver}.x86_64.rpm
|
||||
# package_cloud push grafana/stable/el/6 grafana-${rpm_ver}.x86_64.rpm
|
||||
package_cloud push grafana/stable/el/7 grafana-${rpm_ver}.x86_64.rpm
|
||||
package_cloud push grafana/stable/el/6 grafana-${rpm_ver}.x86_64.rpm
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
@ -20,14 +21,22 @@ type GraphitePublisher struct {
|
||||
func CreateGraphitePublisher() (*GraphitePublisher, error) {
|
||||
graphiteSection, err := setting.Cfg.GetSection("metrics.graphite")
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
publisher := &GraphitePublisher{}
|
||||
publisher.prevCounts = make(map[string]int64)
|
||||
publisher.protocol = "tcp"
|
||||
publisher.address = graphiteSection.Key("address").MustString("localhost:2003")
|
||||
publisher.prefix = graphiteSection.Key("prefix").MustString("service.grafana.%(instance_name)s")
|
||||
|
||||
safeInstanceName := strings.Replace(setting.InstanceName, ".", "_", -1)
|
||||
prefix := graphiteSection.Key("prefix").Value()
|
||||
|
||||
if prefix == "" {
|
||||
prefix = "service.grafana.%(instance_name)s"
|
||||
}
|
||||
|
||||
publisher.prefix = strings.Replace(prefix, "%(instance_name)s", safeInstanceName, -1)
|
||||
|
||||
return publisher, nil
|
||||
}
|
||||
|
55
pkg/metrics/graphite_test.go
Normal file
55
pkg/metrics/graphite_test.go
Normal file
@ -0,0 +1,55 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestGraphitePublisher(t *testing.T) {
|
||||
|
||||
Convey("Test graphite prefix replacement", t, func() {
|
||||
var err error
|
||||
err = setting.NewConfigContext(&setting.CommandLineArgs{
|
||||
HomePath: "../../",
|
||||
})
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
sec, err := setting.Cfg.NewSection("metrics.graphite")
|
||||
sec.NewKey("prefix", "service.grafana.%(instance_name)s")
|
||||
sec.NewKey("address", "localhost:2003")
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
setting.InstanceName = "hostname.with.dots.com"
|
||||
publisher, err := CreateGraphitePublisher()
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(publisher, ShouldNotBeNil)
|
||||
|
||||
So(publisher.prefix, ShouldEqual, "service.grafana.hostname_with_dots_com")
|
||||
})
|
||||
|
||||
Convey("Test graphite publisher default values", t, func() {
|
||||
var err error
|
||||
err = setting.NewConfigContext(&setting.CommandLineArgs{
|
||||
HomePath: "../../",
|
||||
})
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = setting.Cfg.NewSection("metrics.graphite")
|
||||
|
||||
setting.InstanceName = "hostname.with.dots.com"
|
||||
publisher, err := CreateGraphitePublisher()
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(publisher, ShouldNotBeNil)
|
||||
|
||||
So(publisher.prefix, ShouldEqual, "service.grafana.hostname_with_dots_com")
|
||||
So(publisher.address, ShouldEqual, "localhost:2003")
|
||||
})
|
||||
}
|
@ -1,182 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
],
|
||||
function (angular, _) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
|
||||
module.service('dynamicDashboardSrv', function() {
|
||||
var self = this;
|
||||
|
||||
this.init = function(dashboard) {
|
||||
if (dashboard.snapshot) { return; }
|
||||
|
||||
this.iteration = new Date().getTime();
|
||||
this.process(dashboard);
|
||||
};
|
||||
|
||||
this.update = function(dashboard) {
|
||||
if (dashboard.snapshot) { return; }
|
||||
|
||||
this.iteration = this.iteration + 1;
|
||||
this.process(dashboard);
|
||||
};
|
||||
|
||||
this.process = function(dashboard) {
|
||||
if (dashboard.templating.list.length === 0) { return; }
|
||||
this.dashboard = dashboard;
|
||||
|
||||
var i, j, row, panel;
|
||||
for (i = 0; i < this.dashboard.rows.length; i++) {
|
||||
row = this.dashboard.rows[i];
|
||||
// handle row repeats
|
||||
if (row.repeat) {
|
||||
this.repeatRow(row, i);
|
||||
}
|
||||
// clean up old left overs
|
||||
else if (row.repeatRowId && row.repeatIteration !== this.iteration) {
|
||||
this.dashboard.rows.splice(i, 1);
|
||||
i = i - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// repeat panels
|
||||
for (j = 0; j < row.panels.length; j++) {
|
||||
panel = row.panels[j];
|
||||
if (panel.repeat) {
|
||||
this.repeatPanel(panel, row);
|
||||
}
|
||||
// clean up old left overs
|
||||
else if (panel.repeatPanelId && panel.repeatIteration !== this.iteration) {
|
||||
row.panels = _.without(row.panels, panel);
|
||||
j = j - 1;
|
||||
} else if (row.repeat || row.repeatRowId) {
|
||||
continue;
|
||||
} else if (!_.isEmpty(panel.scopedVars) && panel.repeatIteration !== this.iteration) {
|
||||
panel.scopedVars = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// returns a new row clone or reuses a clone from previous iteration
|
||||
this.getRowClone = function(sourceRow, repeatIndex, sourceRowIndex) {
|
||||
if (repeatIndex === 0) {
|
||||
return sourceRow;
|
||||
}
|
||||
|
||||
var i, panel, row, copy;
|
||||
var sourceRowId = sourceRowIndex + 1;
|
||||
|
||||
// look for row to reuse
|
||||
for (i = 0; i < this.dashboard.rows.length; i++) {
|
||||
row = this.dashboard.rows[i];
|
||||
if (row.repeatRowId === sourceRowId && row.repeatIteration !== this.iteration) {
|
||||
copy = row;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!copy) {
|
||||
copy = angular.copy(sourceRow);
|
||||
this.dashboard.rows.splice(sourceRowIndex + repeatIndex, 0, copy);
|
||||
|
||||
// set new panel ids
|
||||
for (i = 0; i < copy.panels.length; i++) {
|
||||
panel = copy.panels[i];
|
||||
panel.id = this.dashboard.getNextPanelId();
|
||||
}
|
||||
}
|
||||
|
||||
copy.repeat = null;
|
||||
copy.repeatRowId = sourceRowId;
|
||||
copy.repeatIteration = this.iteration;
|
||||
return copy;
|
||||
};
|
||||
|
||||
// returns a new row clone or reuses a clone from previous iteration
|
||||
this.repeatRow = function(row, rowIndex) {
|
||||
var variables = this.dashboard.templating.list;
|
||||
var variable = _.findWhere(variables, {name: row.repeat});
|
||||
if (!variable) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selected, copy, i, panel;
|
||||
if (variable.current.text === 'All') {
|
||||
selected = variable.options.slice(1, variable.options.length);
|
||||
} else {
|
||||
selected = _.filter(variable.options, {selected: true});
|
||||
}
|
||||
|
||||
_.each(selected, function(option, index) {
|
||||
copy = self.getRowClone(row, index, rowIndex);
|
||||
copy.scopedVars = {};
|
||||
copy.scopedVars[variable.name] = option;
|
||||
|
||||
for (i = 0; i < copy.panels.length; i++) {
|
||||
panel = copy.panels[i];
|
||||
panel.scopedVars = {};
|
||||
panel.scopedVars[variable.name] = option;
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
this.getPanelClone = function(sourcePanel, row, index) {
|
||||
// if first clone return source
|
||||
if (index === 0) {
|
||||
return sourcePanel;
|
||||
}
|
||||
|
||||
var i, tmpId, panel, clone;
|
||||
|
||||
// first try finding an existing clone to use
|
||||
for (i = 0; i < row.panels.length; i++) {
|
||||
panel = row.panels[i];
|
||||
if (panel.repeatIteration !== this.iteration && panel.repeatPanelId === sourcePanel.id) {
|
||||
clone = panel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!clone) {
|
||||
clone = { id: this.dashboard.getNextPanelId() };
|
||||
row.panels.push(clone);
|
||||
}
|
||||
|
||||
// save id
|
||||
tmpId = clone.id;
|
||||
// copy properties from source
|
||||
angular.copy(sourcePanel, clone);
|
||||
// restore id
|
||||
clone.id = tmpId;
|
||||
clone.repeatIteration = this.iteration;
|
||||
clone.repeatPanelId = sourcePanel.id;
|
||||
clone.repeat = null;
|
||||
return clone;
|
||||
};
|
||||
|
||||
this.repeatPanel = function(panel, row) {
|
||||
var variables = this.dashboard.templating.list;
|
||||
var variable = _.findWhere(variables, {name: panel.repeat});
|
||||
if (!variable) { return; }
|
||||
|
||||
var selected;
|
||||
if (variable.current.text === 'All') {
|
||||
selected = variable.options.slice(1, variable.options.length);
|
||||
} else {
|
||||
selected = _.filter(variable.options, {selected: true});
|
||||
}
|
||||
|
||||
_.each(selected, function(option, index) {
|
||||
var copy = self.getPanelClone(panel, row, index);
|
||||
copy.span = Math.max(12 / selected.length, panel.minSpan);
|
||||
copy.scopedVars = copy.scopedVars || {};
|
||||
copy.scopedVars[variable.name] = option;
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
});
|
@ -10,10 +10,6 @@ export class DynamicDashboardSrv {
|
||||
iteration: number;
|
||||
dashboard: any;
|
||||
|
||||
constructor() {
|
||||
this.iteration = new Date().getTime();
|
||||
}
|
||||
|
||||
init(dashboard) {
|
||||
if (dashboard.snapshot) { return; }
|
||||
this.process(dashboard, {});
|
||||
@ -21,14 +17,14 @@ export class DynamicDashboardSrv {
|
||||
|
||||
update(dashboard) {
|
||||
if (dashboard.snapshot) { return; }
|
||||
|
||||
this.iteration = this.iteration + 1;
|
||||
this.process(dashboard, {});
|
||||
}
|
||||
|
||||
process(dashboard, options) {
|
||||
if (dashboard.templating.list.length === 0) { return; }
|
||||
|
||||
this.dashboard = dashboard;
|
||||
this.iteration = (this.iteration || new Date().getTime()) + 1;
|
||||
|
||||
var cleanUpOnly = options.cleanUpOnly;
|
||||
|
||||
|
@ -20,12 +20,13 @@ define([
|
||||
|
||||
this.dashboard = dashboard;
|
||||
this.time = dashboard.time;
|
||||
this.refresh = dashboard.refresh;
|
||||
|
||||
this._initTimeFromUrl();
|
||||
this._parseTime();
|
||||
|
||||
if(this.dashboard.refresh) {
|
||||
this.setAutoRefresh(this.dashboard.refresh);
|
||||
if(this.refresh) {
|
||||
this.setAutoRefresh(this.refresh);
|
||||
}
|
||||
};
|
||||
|
||||
@ -65,6 +66,9 @@ define([
|
||||
if ($routeParams.to) {
|
||||
this.time.to = this._parseUrlParam($routeParams.to) || this.time.to;
|
||||
}
|
||||
if ($routeParams.refresh) {
|
||||
this.refresh = $routeParams.refresh || this.refresh;
|
||||
}
|
||||
};
|
||||
|
||||
this.setAutoRefresh = function (interval) {
|
||||
|
@ -166,7 +166,9 @@ function (angular, _, $, kbn) {
|
||||
if (otherVariable === updatedVariable) {
|
||||
return;
|
||||
}
|
||||
if (templateSrv.containsVariable(otherVariable.query, updatedVariable.name) ||
|
||||
if ((otherVariable.type === "datasource" &&
|
||||
templateSrv.containsVariable(otherVariable.regex, updatedVariable.name)) ||
|
||||
templateSrv.containsVariable(otherVariable.query, updatedVariable.name) ||
|
||||
templateSrv.containsVariable(otherVariable.datasource, updatedVariable.name)) {
|
||||
return self.updateOptions(otherVariable);
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ describe('ElasticDatasource', function() {
|
||||
|
||||
ctx.ds.query({
|
||||
range: {
|
||||
from: moment([2015, 4, 30, 10]),
|
||||
to: moment([2015, 5, 1, 10])
|
||||
from: moment.utc([2015, 4, 30, 10]),
|
||||
to: moment.utc([2015, 5, 1, 10])
|
||||
},
|
||||
targets: [{ bucketAggs: [], metrics: [], query: 'escape\\:test' }]
|
||||
});
|
||||
|
@ -1,7 +1,8 @@
|
||||
define([
|
||||
'jquery',
|
||||
'lodash'
|
||||
],
|
||||
function ($) {
|
||||
function ($, _) {
|
||||
'use strict';
|
||||
|
||||
function GraphTooltip(elem, dashboard, scope, getSeriesFn) {
|
||||
@ -40,7 +41,7 @@ function ($) {
|
||||
};
|
||||
|
||||
this.getMultiSeriesPlotHoverInfo = function(seriesList, pos) {
|
||||
var value, i, series, hoverIndex;
|
||||
var value, i, series, hoverIndex, hoverDistance, pointTime;
|
||||
var results = [];
|
||||
|
||||
//now we know the current X (j) position for X and Y values
|
||||
@ -60,7 +61,8 @@ function ($) {
|
||||
}
|
||||
|
||||
hoverIndex = this.findHoverIndexFromData(pos.x, series);
|
||||
results.time = series.data[hoverIndex][0];
|
||||
hoverDistance = Math.abs(pos.x - series.data[hoverIndex][0]);
|
||||
pointTime = series.data[hoverIndex][0];
|
||||
|
||||
if (series.stack) {
|
||||
if (panel.tooltip.value_type === 'individual') {
|
||||
@ -80,13 +82,23 @@ function ($) {
|
||||
// stacked and steppedLine plots can have series with different length.
|
||||
// Stacked series can increase its length on each new stacked serie if null points found,
|
||||
// to speed the index search we begin always on the last found hoverIndex.
|
||||
var newhoverIndex = this.findHoverIndexFromDataPoints(pos.x, series, hoverIndex);
|
||||
results.push({ value: value, hoverIndex: newhoverIndex, color: series.color, label: series.label });
|
||||
} else {
|
||||
results.push({ value: value, hoverIndex: hoverIndex, color: series.color, label: series.label });
|
||||
hoverIndex = this.findHoverIndexFromDataPoints(pos.x, series, hoverIndex);
|
||||
hoverDistance = Math.abs(pos.x - series.data[hoverIndex][0]);
|
||||
}
|
||||
|
||||
results.push({
|
||||
value: value,
|
||||
hoverIndex: hoverIndex,
|
||||
color: series.color,
|
||||
label: series.label,
|
||||
time: pointTime,
|
||||
distance: hoverDistance
|
||||
});
|
||||
}
|
||||
|
||||
// Find point which closer to pointer
|
||||
results.time = _.min(results, 'distance').time;
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
|
@ -60,8 +60,8 @@ $page-bg: $white;
|
||||
$body-color: $gray-1;
|
||||
$text-color: $gray-1;
|
||||
$text-color-strong: $white;
|
||||
$text-color-weak: $gray-2;
|
||||
$text-color-faint: $gray-3;
|
||||
$text-color-weak: $gray-3;
|
||||
$text-color-faint: $gray-4;
|
||||
$text-color-emphasis: $dark-5;
|
||||
|
||||
$text-shadow-strong: none;
|
||||
|
@ -64,7 +64,7 @@ $switch-height: 1.5rem;
|
||||
input + label::before {
|
||||
font-family: 'FontAwesome';
|
||||
content: "\f096"; // square-o
|
||||
color: $text-color-faint;
|
||||
color: $text-color-weak;
|
||||
transition: transform 0.4s;
|
||||
backface-visibility: hidden;
|
||||
text-shadow: $text-shadow-faint;
|
||||
|
@ -113,8 +113,6 @@ div.flot-text {
|
||||
.panel {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel-margin {
|
||||
|
@ -1,5 +1,5 @@
|
||||
define([
|
||||
'app/features/dashboard/dynamicDashboardSrv',
|
||||
'app/features/dashboard/dynamic_dashboard_srv',
|
||||
'app/features/dashboard/dashboardSrv'
|
||||
], function() {
|
||||
'use strict';
|
||||
@ -12,6 +12,7 @@ define([
|
||||
ctx.setup = function (setupFunc) {
|
||||
|
||||
beforeEach(module('grafana.services'));
|
||||
beforeEach(module('grafana.core'));
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('contextSrv', {
|
||||
user: { timezone: 'utc'}
|
||||
|
@ -55,7 +55,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://grafana.org/community" target="_blank">
|
||||
<a href="http://grafana.org/community" target="_blank">
|
||||
<i class="fa fa-comments-o"></i>
|
||||
Community
|
||||
</a>
|
||||
|
Loading…
Reference in New Issue
Block a user