');
+
+ elem.mouseleave(function () {
+ if(scope.panel.tooltip.shared) {
+ var plot = elem.data().plot;
+ $tooltip.detach();
+ plot.clearCrosshair();
+ plot.unhighlight();
+ }
+ });
+
+ function findHoverIndex(posX, series) {
+ for (var j = 0; j < series.data.length; j++) {
+ if (series.data[j][0] > posX) {
+ return Math.max(j - 1, 0);
+ }
+ }
+ return j - 1;
+ }
+
+ elem.bind("plothover", function (event, pos, item) {
+ var plot = elem.data().plot;
+ var data = plot.getData();
+ var group, value, timestamp, seriesInfo, format, i, series, hoverIndex, seriesHtml;
+
+ if (scope.panel.tooltip.shared) {
+ plot.unhighlight();
+
+ //check if all series has same length if so, only one x index will
+ //be checked and only for exact timestamp values
+ var pointCount = data[0].data.length;
+ for (i = 1; i < data.length; i++) {
+ if (data[i].data.length !== pointCount) {
+ console.log('WARNING: tootltip shared can not be shown becouse of series points do not align, different point counts');
+ $tooltip.detach();
+ return;
+ }
+ }
+
+ seriesHtml = '';
+ series = data[0];
+ hoverIndex = findHoverIndex(pos.x, series);
+
+ //now we know the current X (j) position for X and Y values
+ timestamp = dashboard.formatDate(series.data[hoverIndex][0]);
+ var last_value = 0; //needed for stacked values
+
+ for (i = data.length-1; i >= 0; --i) {
+ //stacked values should be added in reverse order
+ series = data[i];
+ 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];
+ } else {
+ last_value += series.data[hoverIndex][1];
+ value = last_value;
+ }
+
+ value = kbn.valueFormats[format](value, series.yaxis.tickDecimals);
+
+ if (seriesInfo.alias) {
+ group = '
' + seriesInfo.alias;
+ } else {
+ group = kbn.query_color_dot(series.color, 15) + ' ';
+ }
+
+ //pre-pending new values
+ seriesHtml = group + ':
' + value + '' + seriesHtml;
+
+ plot.highlight(i, hoverIndex);
+ }
+
+ $tooltip.html('
')
+ .place_tt(pos.pageX + 20, pos.pageY);
+ return;
+ }
+ if (item) {
+ seriesInfo = item.series.info;
+ format = scope.panel.y_formats[seriesInfo.yaxis - 1];
+
+ if (seriesInfo.alias) {
+ group = '
' +
+ '' + ' ' +
+ seriesInfo.alias +
+ '';
+ } else {
+ group = kbn.query_color_dot(item.series.color, 15) + ' ';
+ }
+
+ if (scope.panel.stack && scope.panel.tooltip.value_type === 'individual') {
+ value = item.datapoint[1] - item.datapoint[2];
+ }
+ else {
+ value = item.datapoint[1];
+ }
+
+ value = kbn.valueFormats[format](value, item.series.yaxis.tickDecimals);
+ timestamp = dashboard.formatDate(item.datapoint[0]);
+
+ $tooltip.html(group + value + " @ " + timestamp).place_tt(pos.pageX, pos.pageY);
+ } else {
+ $tooltip.detach();
+ }
+ });
+
+ }
+
+ return {
+ register: registerTooltipFeatures
+ };
+});
diff --git a/src/app/panels/graph/module.js b/src/app/panels/graph/module.js
index bbe64d10c37..bc15b851f9d 100644
--- a/src/app/panels/graph/module.js
+++ b/src/app/panels/graph/module.js
@@ -161,7 +161,7 @@ function (angular, app, $, _, kbn, moment, TimeSeries) {
tooltip : {
value_type: 'cumulative',
- query_as_alias: true
+ shared: false,
},
targets: [{}],
diff --git a/src/css/less/graph.less b/src/css/less/graph.less
index d53c55345c7..92f57dbfc71 100644
--- a/src/css/less/graph.less
+++ b/src/css/less/graph.less
@@ -166,3 +166,19 @@
float: left;
}
}
+
+.graph-tooltip {
+ .graph-tooltip-time {
+ text-align: center;
+ font-weight: bold;
+ position: relative;
+ top: -3px;
+ }
+
+ .graph-tooltip-value {
+ font-weight: bold;
+ float: right;
+ padding-left: 10px;
+ }
+
+}
diff --git a/src/test/specs/graph-tooltip-specs.js b/src/test/specs/graph-tooltip-specs.js
new file mode 100644
index 00000000000..2ca3ec85cac
--- /dev/null
+++ b/src/test/specs/graph-tooltip-specs.js
@@ -0,0 +1,56 @@
+define([
+ 'jquery',
+ 'directives/grafanaGraph.tooltip'
+], function($, tooltip) {
+ 'use strict';
+
+ describe('graph tooltip', function() {
+ var elem = $('
');
+ var dashboard = {
+ formatDate: sinon.stub().returns('date'),
+ };
+ var scope = {
+ panel: {
+ tooltip: {
+ shared: true
+ },
+ y_formats: ['ms', 'none'],
+ }
+ };
+
+ var data = [
+ {
+ data: [[10,10], [12,20]],
+ info: { yaxis: 1 },
+ yaxis: { tickDecimals: 2 },
+ },
+ {
+ data: [[10,10], [12,20]],
+ info: { yaxis: 1 },
+ yaxis: { tickDecimals: 2 },
+ }
+ ];
+
+ var plot = {
+ getData: sinon.stub().returns(data),
+ highlight: sinon.stub(),
+ unhighlight: sinon.stub()
+ };
+
+ elem.data('plot', plot);
+
+ beforeEach(function() {
+ tooltip.register(elem, dashboard, scope);
+ elem.trigger('plothover', [{}, {x: 13}, {}]);
+ });
+
+ it('should add tooltip', function() {
+ var tooltipHtml = $(".graph-tooltip").text();
+ expect(tooltipHtml).to.be('date : 40.00 ms : 20.00 ms');
+ });
+
+ });
+
+});
+
+
diff --git a/src/test/test-main.js b/src/test/test-main.js
index f60cdb87da4..6862c9fa8ae 100644
--- a/src/test/test-main.js
+++ b/src/test/test-main.js
@@ -129,6 +129,7 @@ require([
'specs/influxdb-datasource-specs',
'specs/graph-ctrl-specs',
'specs/grafanaGraph-specs',
+ 'specs/graph-tooltip-specs',
'specs/seriesOverridesCtrl-specs',
'specs/timeSrv-specs',
'specs/templateSrv-specs',