瀏覽代碼

feat(graph): refactoring shared tooltip PR #6274

Torkel Ödegaard 9 年之前
父節點
當前提交
fa393c282a

+ 1 - 0
public/app/core/services/keybindingSrv.ts

@@ -89,6 +89,7 @@ export class KeybindingSrv {
 
     this.bind('mod+o', () => {
       dashboard.sharedCrosshair = !dashboard.sharedCrosshair;
+      appEvents.emit('graph-hover-clear');
       scope.broadcastRefresh();
     });
 

+ 4 - 4
public/app/features/dashboard/import/dash_import.html

@@ -123,11 +123,11 @@
       </div>
 
       <div class="gf-form-button-row">
-        <button type="button" class="btn gf-form-btn btn-success width-10" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
-          <i class="fa fa-save"></i> Save &amp; Open
+        <button type="button" class="btn gf-form-btn btn-success width-12" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
+          <i class="fa fa-save"></i> Import
         </button>
-        <button type="button" class="btn gf-form-btn btn-danger width-10" ng-click="ctrl.saveDashboard()" ng-show="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
-          <i class="fa fa-save"></i> Overwrite &amp; Open
+        <button type="button" class="btn gf-form-btn btn-danger width-12" ng-click="ctrl.saveDashboard()" ng-show="ctrl.nameExists" ng-disabled="!ctrl.inputsValid">
+          <i class="fa fa-save"></i> Import (Overwrite)
         </button>
         <a class="btn btn-link" ng-click="dismiss()">Cancel</a>
         <a class="btn btn-link" ng-click="ctrl.back()">Back</a>

+ 0 - 2
public/app/features/dashboard/model.ts

@@ -19,7 +19,6 @@ export class DashboardModel {
   timezone: any;
   editable: any;
   sharedCrosshair: any;
-  sharedTooltip: any;
   rows: DashboardRow[];
   time: any;
   timepicker: any;
@@ -53,7 +52,6 @@ export class DashboardModel {
     this.timezone = data.timezone || '';
     this.editable = data.editable !== false;
     this.sharedCrosshair = data.sharedCrosshair || false;
-    this.sharedTooltip = data.sharedTooltip || false;
     this.hideControls = data.hideControls || false;
     this.time = data.time || { from: 'now-6h', to: 'now' };
     this.timepicker = data.timepicker || {};

+ 3 - 9
public/app/features/dashboard/partials/settings.html

@@ -57,20 +57,14 @@
         </gf-form-switch>
 				<gf-form-switch class="gf-form"
                         label="Hide Controls"
-                        tooltip="Hide row controls. Shortcut: CTRL+H"
+                        tooltip="Hide row controls. Shortcut: CTRL+H or CMD+H"
                         checked="dashboard.hideControls"
                         label-class="width-11">
         </gf-form-switch>
-        <gf-form-switch class="gf-form"
-                        label="Shared Crosshair"
-                        tooltip="Shared Crosshair line on all graphs. Shortcut: CTRL+O"
-                        checked="dashboard.sharedCrosshair"
-                        label-class="width-11">
-        </gf-form-switch>
         <gf-form-switch class="gf-form"
                         label="Shared Tooltip"
-                        tooltip="Shared Tooltip on all graphs."
-                        checked="dashboard.sharedTooltip"
+                        tooltip="Shared Tooltip on all graphs. Shortcut: CTRL+O or CMD+O"
+                        checked="dashboard.sharedCrosshair"
                         label-class="width-11">
         </gf-form-switch>
       </div>

+ 26 - 37
public/app/plugins/panel/graph/graph.ts

@@ -9,18 +9,17 @@ import 'jquery.flot.fillbelow';
 import 'jquery.flot.crosshair';
 import './jquery.flot.events';
 
-import angular from 'angular';
 import $ from 'jquery';
-import moment from 'moment';
 import _ from 'lodash';
+import moment from 'moment';
 import kbn from   'app/core/utils/kbn';
+import {appEvents, coreModule} from 'app/core/core';
 import GraphTooltip from './graph_tooltip';
 import {ThresholdManager} from './threshold_manager';
 
-var module = angular.module('grafana.directives');
 var labelWidthCache = {};
 
-module.directive('grafanaGraph', function($rootScope, timeSrv) {
+coreModule.directive('grafanaGraph', function($rootScope, timeSrv) {
   return {
     restrict: 'A',
     template: '',
@@ -28,7 +27,9 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
       var ctrl = scope.ctrl;
       var dashboard = ctrl.dashboard;
       var panel = ctrl.panel;
-      var data, annotations;
+      var data;
+      var annotations;
+      var plot;
       var sortedSeries;
       var legendSideLastValue = null;
       var rootScope = scope.$root;
@@ -37,8 +38,8 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
       var tooltip = new GraphTooltip(elem, dashboard, scope, function() {
         return sortedSeries;
       });
-      var plot;
 
+      // panel events
       ctrl.events.on('panel-teardown', () => {
         thresholdManager = null;
 
@@ -48,47 +49,35 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
         }
       });
 
-      rootScope.onAppEvent('setCrosshair', function(event, info) {
-        // do not need to to this if event is from this panel
-        if (info.scope === scope) {
+      ctrl.events.on('render', function(renderData) {
+        data = renderData || data;
+        if (!data) {
           return;
         }
+        annotations = ctrl.annotations;
+        render_panel();
+      });
 
-        if (dashboard.sharedCrosshair) {
-          if (plot) {
-            plot.setCrosshair({ x: info.pos.x, y: info.pos.y });
-          }
-        }
-      }, scope);
-
-      rootScope.onAppEvent('clearCrosshair', function() {
-        if (plot) {
-          plot.clearCrosshair();
+      // global events
+      appEvents.on('graph-hover', function(evt) {
+        // ignore other graph hover events if shared tooltip is disabled
+        if (!dashboard.sharedCrosshair) {
+          return;
         }
-      }, scope);
 
-      rootScope.onAppEvent('setTooltip', function(event, info) {
-        // do not need to to this if event is from this panel
-        // or another panel is in fullscreen mode
-        if (info.scope === scope || ctrl.otherPanelInFullscreenMode()) {
+        // ignore if we are the emitter
+        if (!plot || evt.panel.id === panel.id || ctrl.otherPanelInFullscreenMode()) {
           return;
         }
-        tooltip.setTooltip(info.pos);
-      }, scope);
 
-      rootScope.onAppEvent('clearTooltip', function() {
-        tooltip.clearTooltip();
+        tooltip.show(evt.pos);
       }, scope);
 
-      // Receive render events
-      ctrl.events.on('render', function(renderData) {
-        data = renderData || data;
-        if (!data) {
-          return;
+      appEvents.on('graph-hover-clear', function(event, info) {
+        if (plot) {
+          tooltip.clear(plot);
         }
-        annotations = ctrl.annotations;
-        render_panel();
-      });
+      }, scope);
 
       function getLegendHeight(panelHeight) {
         if (!panel.legend.show || panel.legend.rightSide) {
@@ -288,7 +277,7 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
             color: '#666'
           },
           crosshair: {
-            mode: panel.tooltip.shared || dashboard.sharedCrosshair ? "x" : null
+            mode: 'x'
           }
         };
 

+ 20 - 25
public/app/plugins/panel/graph/graph_tooltip.js

@@ -1,10 +1,12 @@
 define([
   'jquery',
-  'lodash'
+  'app/core/core',
 ],
-function ($) {
+function ($, core) {
   'use strict';
 
+  var appEvents = core.appEvents;
+
   function GraphTooltip(elem, dashboard, scope, getSeriesFn) {
     var self = this;
     var ctrl = scope.ctrl;
@@ -41,7 +43,7 @@ function ($) {
       return j - 1;
     };
 
-    this.showTooltip = function(absoluteTime, innerHtml, pos, xMode) {
+    this.renderAndShow = function(absoluteTime, innerHtml, pos, xMode) {
       if (xMode === 'time') {
         innerHtml = '<div class="graph-tooltip-time">'+ absoluteTime + '</div>' + innerHtml;
       }
@@ -140,43 +142,34 @@ function ($) {
           plot.unhighlight();
         }
       }
-
-      if (dashboard.sharedTooltip) {
-        ctrl.publishAppEvent('clearTooltip');
-      }
-
-      if (dashboard.sharedCrosshair) {
-        ctrl.publishAppEvent('clearCrosshair');
-      }
+      appEvents.emit('graph-hover-clear');
     });
 
     elem.bind("plothover", function (event, pos, item) {
-      if (dashboard.sharedCrosshair) {
-        ctrl.publishAppEvent('setCrosshair', {pos: pos, scope: scope});
-      }
+      self.show(pos, item);
 
-      if (dashboard.sharedTooltip) {
-        pos.panelRelY = (pos.pageY - elem.offset().top) / elem.height();
-        ctrl.publishAppEvent('setTooltip', {pos: pos, scope: scope});
-      }
-      self.setTooltip(pos, item);
+      // broadcast to other graph panels that we are hovering!
+      pos.panelRelY = (pos.pageY - elem.offset().top) / elem.height();
+      appEvents.emit('graph-hover', {pos: pos, panel: panel});
     });
 
-    this.clearTooltip = function() {
+    this.clear = function(plot) {
       $tooltip.detach();
+      plot.clearCrosshair();
     };
 
-    this.setTooltip = function(pos, item) {
+    this.show = function(pos, item) {
       var plot = elem.data().plot;
       var plotData = plot.getData();
       var xAxes = plot.getXAxes();
       var xMode = xAxes[0].options.mode;
       var seriesList = getSeriesFn();
+      var allSeriesMode = panel.tooltip.shared;
       var group, value, absoluteTime, hoverInfo, i, series, seriesHtml, tooltipFormat;
 
       // if panelRelY is defined another panel wants us to show a tooltip
       // get pageX from position on x axis and pageY from relative position in original panel
-      if (pos.panelRelY !== undefined) {
+      if (pos.panelRelY) {
         var pointOffset = plot.pointOffset({x: pos.x});
         if (Number.isNaN(pointOffset.left) || pointOffset.left < 0) {
           $tooltip.detach();
@@ -184,6 +177,8 @@ function ($) {
         }
         pos.pageX = elem.offset().left + pointOffset.left;
         pos.pageY = elem.offset().top + elem.height() * pos.panelRelY;
+        plot.setCrosshair(pos);
+        allSeriesMode = true;
       }
 
       if (seriesList.length === 0) {
@@ -196,7 +191,7 @@ function ($) {
         tooltipFormat = 'YYYY-MM-DD HH:mm:ss';
       }
 
-      if (panel.tooltip.shared) {
+      if (allSeriesMode) {
         plot.unhighlight();
 
         var seriesHoverInfo = self.getMultiSeriesPlotHoverInfo(plotData, pos);
@@ -239,7 +234,7 @@ function ($) {
           plot.highlight(hoverInfo.index, hoverInfo.hoverIndex);
         }
 
-        self.showTooltip(absoluteTime, seriesHtml, pos, xMode);
+        self.renderAndShow(absoluteTime, seriesHtml, pos, xMode);
       }
       // single series tooltip
       else if (item) {
@@ -260,7 +255,7 @@ function ($) {
 
         group += '<div class="graph-tooltip-value">' + value + '</div>';
 
-        self.showTooltip(absoluteTime, group, pos, xMode);
+        self.renderAndShow(absoluteTime, group, pos, xMode);
       }
       // no hit
       else {

+ 0 - 1
public/app/plugins/panel/graph/module.ts

@@ -96,7 +96,6 @@ class GraphCtrl extends MetricsPanelCtrl {
       value_type: 'individual',
       shared: true,
       sort: 0,
-      msResolution: false,
     },
     // time overrides
     timeFrom: null,

+ 1 - 1
public/app/plugins/panel/graph/specs/graph_specs.ts

@@ -12,7 +12,7 @@ import {Emitter} from 'app/core/core';
 
 describe('grafanaGraph', function() {
 
-  beforeEach(angularMocks.module('grafana.directives'));
+  beforeEach(angularMocks.module('grafana.core'));
 
   function graphScenario(desc, func, elementWidth = 500)  {
     describe(desc, function() {

+ 1 - 1
public/app/plugins/panel/graph/tab_display.html

@@ -48,7 +48,7 @@
 			</div>
 		</div>
 		<div class="section gf-form-group">
-			<h5 class="section-heading">Hover info</h5>
+			<h5 class="section-heading">Hover tooltip</h5>
 			<div class="gf-form">
 				<label class="gf-form-label width-9">Mode</label>
 				<div class="gf-form-select-wrapper max-width-8">