diff --git a/CHANGELOG.md b/CHANGELOG.md index c0f1625ac12..7999a964064 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ # 1.8.1 (unreleased) **Fixes** +- [Issue #855](https://github.com/grafana/grafana/issues/855). Graph: Fix for scroll issue in graph edit mode when dropdown goes below screen - [Issue #847](https://github.com/grafana/grafana/issues/847). Graph: Fix for series draw order not being the same after hiding/unhiding series - [Issue #851](https://github.com/grafana/grafana/issues/851). Annotations: Fix for annotations not reloaded when switching between 2 dashboards with annotations - [Issue #846](https://github.com/grafana/grafana/issues/846). Edit panes: Issue when open row or json editor when scrolled down the page, unable to scroll and you did not see editor diff --git a/package.json b/package.json index 8369d640c62..90983011688 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "company": "Coding Instinct AB" }, "name": "grafana", - "version": "1.8.1", + "version": "1.9.0", "repository": { "type": "git", "url": "http://github.com/torkelo/grafana.git" diff --git a/src/app/directives/grafanaGraph.js b/src/app/directives/grafanaGraph.js index 42ef1b91cb5..685ac7e0b83 100755 --- a/src/app/directives/grafanaGraph.js +++ b/src/app/directives/grafanaGraph.js @@ -19,8 +19,30 @@ function (angular, $, kbn, moment, _, graphTooltip) { var dashboard = scope.dashboard; var data, annotations; var legendSideLastValue = null; + scope.crosshairEmiter = false; - scope.$on('refresh',function() { + scope.onAppEvent('setCrosshair', function(event, info) { + // do not need to to this if event is from this panel + if (info.scope === scope) { + return; + } + + if(dashboard.sharedCrosshair) { + var plot = elem.data().plot; + if (plot) { + plot.setCrosshair({ x: info.pos.x, y: info.pos.y }); + } + } + }); + + scope.onAppEvent('clearCrosshair', function() { + var plot = elem.data().plot; + if (plot) { + plot.clearCrosshair(); + } + }); + + scope.$on('refresh', function() { scope.get_data(); }); @@ -147,7 +169,7 @@ function (angular, $, kbn, moment, _, graphTooltip) { color: '#666' }, crosshair: { - mode: panel.tooltip.shared ? "x" : null + mode: panel.tooltip.shared || dashboard.sharedCrosshair ? "x" : null } }; @@ -394,7 +416,7 @@ function (angular, $, kbn, moment, _, graphTooltip) { elem.html(''); } - graphTooltip.register(elem, dashboard, scope); + graphTooltip.register(elem, dashboard, scope, $rootScope); elem.bind("plotselected", function (event, ranges) { scope.$apply(function() { diff --git a/src/app/directives/grafanaGraph.tooltip.js b/src/app/directives/grafanaGraph.tooltip.js index 513d7126985..0d8fafe498a 100644 --- a/src/app/directives/grafanaGraph.tooltip.js +++ b/src/app/directives/grafanaGraph.tooltip.js @@ -10,11 +10,13 @@ function ($, kbn) { var $tooltip = $('
'); elem.mouseleave(function () { - if(scope.panel.tooltip.shared) { + if (scope.panel.tooltip.shared || dashboard.sharedCrosshair) { var plot = elem.data().plot; - $tooltip.detach(); - plot.clearCrosshair(); - plot.unhighlight(); + if (plot) { + $tooltip.detach(); + plot.unhighlight(); + scope.appEvent('clearCrosshair'); + } } }); @@ -32,6 +34,10 @@ function ($, kbn) { var data = plot.getData(); var group, value, timestamp, seriesInfo, format, i, series, hoverIndex, seriesHtml; + if(dashboard.sharedCrosshair){ + scope.appEvent('setCrosshair', { pos: pos, scope: scope }); + } + if (scope.panel.tooltip.shared) { plot.unhighlight(); @@ -60,11 +66,15 @@ function ($, kbn) { seriesInfo = series.info; format = scope.panel.y_formats[seriesInfo.yaxis - 1]; - if (scope.panel.stack && scope.panel.tooltip.value_type === 'individual') { - value = series.data[hoverIndex][1]; + if (scope.panel.stack) { + if (scope.panel.stack && scope.panel.tooltip.value_type === 'individual') { + value = series.data[hoverIndex][1]; + } else { + last_value += series.data[hoverIndex][1]; + value = last_value; + } } else { - last_value += series.data[hoverIndex][1]; - value = last_value; + value = series.data[hoverIndex][1]; } value = kbn.valueFormats[format](value, series.yaxis.tickDecimals); diff --git a/src/app/panels/graph/styleEditor.html b/src/app/panels/graph/styleEditor.html index 345e4165f96..07e72c93f15 100644 --- a/src/app/panels/graph/styleEditor.html +++ b/src/app/panels/graph/styleEditor.html @@ -33,11 +33,7 @@ -
- - -
-
+
@@ -55,7 +51,12 @@
Tooltip
- + + +
+
+ +
@@ -88,7 +89,7 @@ {{option.name}}: {{option.value}} diff --git a/src/app/partials/dasheditor.html b/src/app/partials/dasheditor.html index ae8608b97d1..9802ab75004 100644 --- a/src/app/partials/dasheditor.html +++ b/src/app/partials/dasheditor.html @@ -74,6 +74,7 @@ + diff --git a/src/app/services/dashboard/dashboardKeyBindings.js b/src/app/services/dashboard/dashboardKeyBindings.js index 11d5e2d4787..987bb5a71ad 100644 --- a/src/app/services/dashboard/dashboardKeyBindings.js +++ b/src/app/services/dashboard/dashboardKeyBindings.js @@ -18,6 +18,7 @@ function(angular, $) { keyboardManager.unbind('ctrl+s'); keyboardManager.unbind('ctrl+r'); keyboardManager.unbind('ctrl+z'); + keyboardManager.unbind('ctrl+o'); keyboardManager.unbind('esc'); }); @@ -25,6 +26,12 @@ function(angular, $) { scope.appEvent('show-dash-editor', { src: 'app/partials/search.html' }); }, { inputDisabled: true }); + keyboardManager.bind('ctrl+o', function() { + var current = scope.dashboard.sharedCrosshair; + scope.dashboard.sharedCrosshair = !current; + scope.dashboard.emit_refresh('refresh'); + }, { inputDisabled: true }); + keyboardManager.bind('ctrl+h', function() { var current = scope.dashboard.hideControls; scope.dashboard.hideControls = !current; diff --git a/src/app/services/dashboard/dashboardSrv.js b/src/app/services/dashboard/dashboardSrv.js index 17313a207d5..40d9b5df55f 100644 --- a/src/app/services/dashboard/dashboardSrv.js +++ b/src/app/services/dashboard/dashboardSrv.js @@ -27,6 +27,7 @@ function (angular, $, kbn, _, moment) { this.timezone = data.timezone || 'browser'; this.editable = data.editable === false ? false : true; this.hideControls = data.hideControls || false; + this.sharedCrosshair = data.sharedCrosshair || false; this.rows = data.rows || []; this.nav = data.nav || []; this.time = data.time || { from: 'now-6h', to: 'now' }; diff --git a/src/css/less/grafana.less b/src/css/less/grafana.less index 2e852c8a585..4df24c22658 100644 --- a/src/css/less/grafana.less +++ b/src/css/less/grafana.less @@ -120,6 +120,10 @@ .panel-content { padding-bottom: 130px; } + + .dropdown-menu { + margin-bottom: 70px; + } } .dashboard-fullscreen { diff --git a/src/test/specs/grafanaGraph-specs.js b/src/test/specs/grafanaGraph-specs.js index 159a923cc7c..c5659ba8825 100644 --- a/src/test/specs/grafanaGraph-specs.js +++ b/src/test/specs/grafanaGraph-specs.js @@ -14,10 +14,13 @@ define([ function graphScenario(desc, func) { describe(desc, function() { var ctx = {}; + ctx.setup = function (setupFunc) { + beforeEach(module(function($provide) { $provide.value("timeSrv", new helpers.TimeSrvStub()); })); + beforeEach(inject(function($rootScope, $compile) { var scope = $rootScope.$new(); var element = angular.element("
"); @@ -28,10 +31,13 @@ define([ grid: {}, y_formats: [], seriesOverrides: [], - tooltip: { + tooltip: { shared: true } }; + + scope.appEvent = sinon.spy(); + scope.onAppEvent = sinon.spy(); scope.hiddenSeries = {}; scope.dashboard = { timezone: 'browser' }; scope.range = { diff --git a/src/test/specs/graph-tooltip-specs.js b/src/test/specs/graph-tooltip-specs.js index 2ca3ec85cac..7f20ad8dbc9 100644 --- a/src/test/specs/graph-tooltip-specs.js +++ b/src/test/specs/graph-tooltip-specs.js @@ -10,11 +10,14 @@ define([ formatDate: sinon.stub().returns('date'), }; var scope = { + appEvent: sinon.spy(), + onAppEvent: sinon.spy(), panel: { tooltip: { shared: true }, y_formats: ['ms', 'none'], + stack: true } }; diff --git a/src/test/specs/sharePanelCtrl-specs.js b/src/test/specs/sharePanelCtrl-specs.js index 4c36e8fe156..8c4eb2a2443 100644 --- a/src/test/specs/sharePanelCtrl-specs.js +++ b/src/test/specs/sharePanelCtrl-specs.js @@ -26,16 +26,16 @@ define([ it('should generate share url absolute time', function() { ctx.$location.path('/test'); ctx.scope.panel = { id: 22 }; - ctx.timeSrv.time = { from: new Date(2012,1,1), to: new Date(2014,3,5) }; + ctx.timeSrv.time = { from: new Date(1362178800000), to: new Date(1396648800000) }; ctx.scope.buildUrl(); - expect(ctx.scope.shareUrl).to.be('http://server/#/test?from=1328050800000&to=1396648800000&panelId=22&fullscreen'); + expect(ctx.scope.shareUrl).to.be('http://server/#/test?from=1362178800000&to=1396648800000&panelId=22&fullscreen'); }); it('should generate share url with time as JSON strings', function() { ctx.$location.path('/test'); ctx.scope.panel = { id: 22 }; - ctx.timeSrv.time = { from: new Date(2012,1,1).toJSON(), to: new Date(2014,3,5).toJSON() }; + ctx.timeSrv.time = { from: "2012-01-31T23:00:00.000Z", to: "2014-04-04T22:00:00.000Z" }; ctx.scope.buildUrl(); expect(ctx.scope.shareUrl).to.be('http://server/#/test?from=1328050800000&to=1396648800000&panelId=22&fullscreen');