Commit 4fd8b2ac by Torkel Ödegaard

Merge branch 'master' into alerting

parents 61756d2a a56cf9d6
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* **Templating**: Update panel repeats for variables that change on time refresh, closes [#5021](https://github.com/grafana/grafana/issues/5021) * **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) * **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) * **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) * **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) * **Elasticsearch**: Fixed issue with templating query and json parse error, fixes [#5615](https://github.com/grafana/grafana/issues/5615)
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* **Graphite**: Fixed issue with mixed data sources and Graphite, fixes [#5617](https://github.com/grafana/grafana/issues/5617) * **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) * **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) * **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) # 3.1.0 stable (2016-07-12)
......
...@@ -18,15 +18,13 @@ dependencies: ...@@ -18,15 +18,13 @@ dependencies:
test: test:
override: override:
# FMT
- test -z "$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)" - test -z "$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"
# GO VET
- go vet ./pkg/... - go vet ./pkg/...
# Go test # JS tests
- godep go test -v ./pkg/...
# js tests
- npm test - npm test
- npm run coveralls - npm run coveralls
# GO tests
- godep go test -v ./pkg/...
deployment: deployment:
master: master:
......
...@@ -378,7 +378,7 @@ interval_seconds = 60 ...@@ -378,7 +378,7 @@ interval_seconds = 60
# Send internal Grafana metrics to graphite # Send internal Grafana metrics to graphite
; [metrics.graphite] ; [metrics.graphite]
; address = localhost:2003 ; address = localhost:2003
; prefix = prod.grafana.%(instance_name)s. ; prefix = service.grafana.%(instance_name)s
[grafana_net] [grafana_net]
url = https://grafana.net url = https://grafana.net
......
...@@ -298,7 +298,7 @@ check_for_updates = true ...@@ -298,7 +298,7 @@ check_for_updates = true
# Metrics available at HTTP API Url /api/metrics # Metrics available at HTTP API Url /api/metrics
[metrics] [metrics]
# Disable / Enable internal metrics # Disable / Enable internal metrics
;enabled = true enabled = true
# Publish interval # Publish interval
;interval_seconds = 10 ;interval_seconds = 10
...@@ -306,7 +306,7 @@ check_for_updates = true ...@@ -306,7 +306,7 @@ check_for_updates = true
# Send internal metrics to Graphite # Send internal metrics to Graphite
; [metrics.graphite] ; [metrics.graphite]
; address = localhost:2003 ; address = localhost:2003
; prefix = prod.grafana.%(instance_name)s. ; prefix = service.grafana.%(instance_name)s
#################################### Internal Grafana Metrics ########################## #################################### Internal Grafana Metrics ##########################
# Url used to to import dashboards directly from Grafana.net # Url used to to import dashboards directly from Grafana.net
......
...@@ -5,7 +5,7 @@ page_keywords: grafana, guide, documentation ...@@ -5,7 +5,7 @@ page_keywords: grafana, guide, documentation
--- ---
# Getting started # 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 ## 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. 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 ...@@ -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 The port to bind to, defaults to `3000`. To use port 80 you need to
either give the Grafana binary permission for example: 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: Or redirect port 80 to the Grafana port using:
...@@ -477,3 +477,14 @@ Format `<Hostname or ip>`:port ...@@ -477,3 +477,14 @@ Format `<Hostname or ip>`:port
### prefix ### prefix
Graphite metric prefix. Defaults to `prod.grafana.%(instance_name)s.` 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 ...@@ -10,13 +10,13 @@ page_keywords: grafana, installation, debian, ubuntu, guide
Description | Download 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 ## 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 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 ## APT Repository
......
...@@ -11,28 +11,17 @@ Installation can be done using [homebrew](http://brew.sh/) ...@@ -11,28 +11,17 @@ Installation can be done using [homebrew](http://brew.sh/)
Install latest stable: Install latest stable:
``` ```
brew install grafana/grafana/grafana brew update
```
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 brew install grafana
``` ```
Install latest unstable from master: To start grafana look at the command printed after the homebrew install completes.
```
brew install --HEAD grafana/grafana/grafana
```
To upgrade use the reinstall command 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 ...@@ -10,24 +10,24 @@ page_keywords: grafana, installation, centos, fedora, opensuse, redhat, guide
Description | Download 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 ## Install Latest Stable
You can install Grafana using Yum directly. 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`. Or install manually using `rpm`.
#### On CentOS / Fedora / Redhat: #### On CentOS / Fedora / Redhat:
$ sudo yum install initscripts fontconfig $ 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: #### 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 ## Install via YUM Repository
......
...@@ -10,7 +10,7 @@ page_keywords: grafana, installation, windows guide ...@@ -10,7 +10,7 @@ page_keywords: grafana, installation, windows guide
Description | Download 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 ## Configure
......
...@@ -14,7 +14,7 @@ Since Grafana automatically scales Dashboards to any resolution they're perfect ...@@ -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. 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. 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.
......
{ {
"stable": "3.1.0", "stable": "3.1.1",
"testing": "3.1.0" "testing": "3.1.1"
} }
#! /usr/bin/env bash #! /usr/bin/env bash
deb_ver=3.1.0-1466666977beta1 deb_ver=3.1.1-1470047149
rpm_ver=3.1.0-1466666977beta1 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/jessie grafana_${deb_ver}_amd64.deb
# package_cloud push grafana/stable/debian/wheezy 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/jessie grafana_${deb_ver}_amd64.deb
package_cloud push grafana/testing/debian/wheezy 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/6 grafana-${rpm_ver}.x86_64.rpm
package_cloud push grafana/testing/el/7 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/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/6 grafana-${rpm_ver}.x86_64.rpm
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"net" "net"
"strings"
"time" "time"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
...@@ -20,14 +21,22 @@ type GraphitePublisher struct { ...@@ -20,14 +21,22 @@ type GraphitePublisher struct {
func CreateGraphitePublisher() (*GraphitePublisher, error) { func CreateGraphitePublisher() (*GraphitePublisher, error) {
graphiteSection, err := setting.Cfg.GetSection("metrics.graphite") graphiteSection, err := setting.Cfg.GetSection("metrics.graphite")
if err != nil { if err != nil {
return nil, nil return nil, err
} }
publisher := &GraphitePublisher{} publisher := &GraphitePublisher{}
publisher.prevCounts = make(map[string]int64) publisher.prevCounts = make(map[string]int64)
publisher.protocol = "tcp" publisher.protocol = "tcp"
publisher.address = graphiteSection.Key("address").MustString("localhost:2003") 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 return publisher, nil
} }
......
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")
})
}
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 { ...@@ -10,10 +10,6 @@ export class DynamicDashboardSrv {
iteration: number; iteration: number;
dashboard: any; dashboard: any;
constructor() {
this.iteration = new Date().getTime();
}
init(dashboard) { init(dashboard) {
if (dashboard.snapshot) { return; } if (dashboard.snapshot) { return; }
this.process(dashboard, {}); this.process(dashboard, {});
...@@ -21,14 +17,14 @@ export class DynamicDashboardSrv { ...@@ -21,14 +17,14 @@ export class DynamicDashboardSrv {
update(dashboard) { update(dashboard) {
if (dashboard.snapshot) { return; } if (dashboard.snapshot) { return; }
this.iteration = this.iteration + 1;
this.process(dashboard, {}); this.process(dashboard, {});
} }
process(dashboard, options) { process(dashboard, options) {
if (dashboard.templating.list.length === 0) { return; } if (dashboard.templating.list.length === 0) { return; }
this.dashboard = dashboard; this.dashboard = dashboard;
this.iteration = (this.iteration || new Date().getTime()) + 1;
var cleanUpOnly = options.cleanUpOnly; var cleanUpOnly = options.cleanUpOnly;
......
...@@ -20,12 +20,13 @@ define([ ...@@ -20,12 +20,13 @@ define([
this.dashboard = dashboard; this.dashboard = dashboard;
this.time = dashboard.time; this.time = dashboard.time;
this.refresh = dashboard.refresh;
this._initTimeFromUrl(); this._initTimeFromUrl();
this._parseTime(); this._parseTime();
if(this.dashboard.refresh) { if(this.refresh) {
this.setAutoRefresh(this.dashboard.refresh); this.setAutoRefresh(this.refresh);
} }
}; };
...@@ -65,6 +66,9 @@ define([ ...@@ -65,6 +66,9 @@ define([
if ($routeParams.to) { if ($routeParams.to) {
this.time.to = this._parseUrlParam($routeParams.to) || this.time.to; this.time.to = this._parseUrlParam($routeParams.to) || this.time.to;
} }
if ($routeParams.refresh) {
this.refresh = $routeParams.refresh || this.refresh;
}
}; };
this.setAutoRefresh = function (interval) { this.setAutoRefresh = function (interval) {
......
...@@ -166,7 +166,9 @@ function (angular, _, $, kbn) { ...@@ -166,7 +166,9 @@ function (angular, _, $, kbn) {
if (otherVariable === updatedVariable) { if (otherVariable === updatedVariable) {
return; 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)) { templateSrv.containsVariable(otherVariable.datasource, updatedVariable.name)) {
return self.updateOptions(otherVariable); return self.updateOptions(otherVariable);
} }
......
...@@ -59,8 +59,8 @@ describe('ElasticDatasource', function() { ...@@ -59,8 +59,8 @@ describe('ElasticDatasource', function() {
ctx.ds.query({ ctx.ds.query({
range: { range: {
from: moment([2015, 4, 30, 10]), from: moment.utc([2015, 4, 30, 10]),
to: moment([2015, 5, 1, 10]) to: moment.utc([2015, 5, 1, 10])
}, },
targets: [{ bucketAggs: [], metrics: [], query: 'escape\\:test' }] targets: [{ bucketAggs: [], metrics: [], query: 'escape\\:test' }]
}); });
......
define([ define([
'jquery', 'jquery',
'lodash'
], ],
function ($) { function ($, _) {
'use strict'; 'use strict';
function GraphTooltip(elem, dashboard, scope, getSeriesFn) { function GraphTooltip(elem, dashboard, scope, getSeriesFn) {
...@@ -40,7 +41,7 @@ function ($) { ...@@ -40,7 +41,7 @@ function ($) {
}; };
this.getMultiSeriesPlotHoverInfo = function(seriesList, pos) { this.getMultiSeriesPlotHoverInfo = function(seriesList, pos) {
var value, i, series, hoverIndex; var value, i, series, hoverIndex, hoverDistance, pointTime;
var results = []; var results = [];
//now we know the current X (j) position for X and Y values //now we know the current X (j) position for X and Y values
...@@ -60,7 +61,8 @@ function ($) { ...@@ -60,7 +61,8 @@ function ($) {
} }
hoverIndex = this.findHoverIndexFromData(pos.x, series); 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 (series.stack) {
if (panel.tooltip.value_type === 'individual') { if (panel.tooltip.value_type === 'individual') {
...@@ -80,13 +82,23 @@ function ($) { ...@@ -80,13 +82,23 @@ function ($) {
// stacked and steppedLine plots can have series with different length. // 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, // 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. // to speed the index search we begin always on the last found hoverIndex.
var newhoverIndex = this.findHoverIndexFromDataPoints(pos.x, series, hoverIndex); hoverIndex = this.findHoverIndexFromDataPoints(pos.x, series, hoverIndex);
results.push({ value: value, hoverIndex: newhoverIndex, color: series.color, label: series.label }); hoverDistance = Math.abs(pos.x - series.data[hoverIndex][0]);
} else {
results.push({ value: value, hoverIndex: hoverIndex, color: series.color, label: series.label });
} }
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; return results;
}; };
......
...@@ -60,8 +60,8 @@ $page-bg: $white; ...@@ -60,8 +60,8 @@ $page-bg: $white;
$body-color: $gray-1; $body-color: $gray-1;
$text-color: $gray-1; $text-color: $gray-1;
$text-color-strong: $white; $text-color-strong: $white;
$text-color-weak: $gray-2; $text-color-weak: $gray-3;
$text-color-faint: $gray-3; $text-color-faint: $gray-4;
$text-color-emphasis: $dark-5; $text-color-emphasis: $dark-5;
$text-shadow-strong: none; $text-shadow-strong: none;
......
...@@ -64,7 +64,7 @@ $switch-height: 1.5rem; ...@@ -64,7 +64,7 @@ $switch-height: 1.5rem;
input + label::before { input + label::before {
font-family: 'FontAwesome'; font-family: 'FontAwesome';
content: "\f096"; // square-o content: "\f096"; // square-o
color: $text-color-faint; color: $text-color-weak;
transition: transform 0.4s; transition: transform 0.4s;
backface-visibility: hidden; backface-visibility: hidden;
text-shadow: $text-shadow-faint; text-shadow: $text-shadow-faint;
......
...@@ -113,8 +113,6 @@ div.flot-text { ...@@ -113,8 +113,6 @@ div.flot-text {
.panel { .panel {
display: inline-block; display: inline-block;
float: left; float: left;
vertical-align: top;
position: relative;
} }
.panel-margin { .panel-margin {
......
define([ define([
'app/features/dashboard/dynamicDashboardSrv', 'app/features/dashboard/dynamic_dashboard_srv',
'app/features/dashboard/dashboardSrv' 'app/features/dashboard/dashboardSrv'
], function() { ], function() {
'use strict'; 'use strict';
...@@ -12,6 +12,7 @@ define([ ...@@ -12,6 +12,7 @@ define([
ctx.setup = function (setupFunc) { ctx.setup = function (setupFunc) {
beforeEach(module('grafana.services')); beforeEach(module('grafana.services'));
beforeEach(module('grafana.core'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
$provide.value('contextSrv', { $provide.value('contextSrv', {
user: { timezone: 'utc'} user: { timezone: 'utc'}
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
</a> </a>
</li> </li>
<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> <i class="fa fa-comments-o"></i>
Community Community
</a> </a>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment