Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
1b0cddfa
Commit
1b0cddfa
authored
Oct 06, 2014
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Graph: Tooltip refactoring for testability
parent
231a599f
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
205 additions
and
128 deletions
+205
-128
src/app/components/kbn.js
+16
-0
src/app/components/timeSeries.js
+13
-5
src/app/directives/grafanaGraph.js
+3
-2
src/app/directives/grafanaGraph.tooltip.js
+101
-89
src/app/panels/graph/module.js
+0
-0
src/css/less/graph.less
+2
-0
src/test/specs/graph-tooltip-specs.js
+70
-32
No files found.
src/app/components/kbn.js
View file @
1b0cddfa
...
@@ -316,6 +316,10 @@ function($, _, moment) {
...
@@ -316,6 +316,10 @@ function($, _, moment) {
kbn
.
formatFuncCreator
=
function
(
factor
,
extArray
)
{
kbn
.
formatFuncCreator
=
function
(
factor
,
extArray
)
{
return
function
(
size
,
decimals
,
scaledDecimals
)
{
return
function
(
size
,
decimals
,
scaledDecimals
)
{
if
(
size
===
null
)
{
return
""
;
}
var
steps
=
0
;
var
steps
=
0
;
while
(
Math
.
abs
(
size
)
>=
factor
)
{
while
(
Math
.
abs
(
size
)
>=
factor
)
{
...
@@ -331,6 +335,10 @@ function($, _, moment) {
...
@@ -331,6 +335,10 @@ function($, _, moment) {
};
};
kbn
.
toFixed
=
function
(
value
,
decimals
)
{
kbn
.
toFixed
=
function
(
value
,
decimals
)
{
if
(
value
===
null
)
{
return
""
;
}
var
factor
=
decimals
?
Math
.
pow
(
10
,
decimals
)
:
1
;
var
factor
=
decimals
?
Math
.
pow
(
10
,
decimals
)
:
1
;
var
formatted
=
String
(
Math
.
round
(
value
*
factor
)
/
factor
);
var
formatted
=
String
(
Math
.
round
(
value
*
factor
)
/
factor
);
...
@@ -359,6 +367,8 @@ function($, _, moment) {
...
@@ -359,6 +367,8 @@ function($, _, moment) {
kbn
.
valueFormats
.
none
=
kbn
.
toFixed
;
kbn
.
valueFormats
.
none
=
kbn
.
toFixed
;
kbn
.
valueFormats
.
ms
=
function
(
size
,
decimals
,
scaledDecimals
)
{
kbn
.
valueFormats
.
ms
=
function
(
size
,
decimals
,
scaledDecimals
)
{
if
(
size
===
null
)
{
return
""
;
}
if
(
Math
.
abs
(
size
)
<
1000
)
{
if
(
Math
.
abs
(
size
)
<
1000
)
{
return
kbn
.
toFixed
(
size
,
decimals
)
+
" ms"
;
return
kbn
.
toFixed
(
size
,
decimals
)
+
" ms"
;
}
}
...
@@ -383,6 +393,8 @@ function($, _, moment) {
...
@@ -383,6 +393,8 @@ function($, _, moment) {
};
};
kbn
.
valueFormats
.
s
=
function
(
size
,
decimals
,
scaledDecimals
)
{
kbn
.
valueFormats
.
s
=
function
(
size
,
decimals
,
scaledDecimals
)
{
if
(
size
===
null
)
{
return
""
;
}
if
(
Math
.
abs
(
size
)
<
600
)
{
if
(
Math
.
abs
(
size
)
<
600
)
{
return
kbn
.
toFixed
(
size
,
decimals
)
+
" s"
;
return
kbn
.
toFixed
(
size
,
decimals
)
+
" s"
;
}
}
...
@@ -407,6 +419,8 @@ function($, _, moment) {
...
@@ -407,6 +419,8 @@ function($, _, moment) {
};
};
kbn
.
valueFormats
[
'µs'
]
=
function
(
size
,
decimals
,
scaledDecimals
)
{
kbn
.
valueFormats
[
'µs'
]
=
function
(
size
,
decimals
,
scaledDecimals
)
{
if
(
size
===
null
)
{
return
""
;
}
if
(
Math
.
abs
(
size
)
<
1000
)
{
if
(
Math
.
abs
(
size
)
<
1000
)
{
return
kbn
.
toFixed
(
size
,
decimals
)
+
" µs"
;
return
kbn
.
toFixed
(
size
,
decimals
)
+
" µs"
;
}
}
...
@@ -419,6 +433,8 @@ function($, _, moment) {
...
@@ -419,6 +433,8 @@ function($, _, moment) {
};
};
kbn
.
valueFormats
.
ns
=
function
(
size
,
decimals
,
scaledDecimals
)
{
kbn
.
valueFormats
.
ns
=
function
(
size
,
decimals
,
scaledDecimals
)
{
if
(
size
===
null
)
{
return
""
;
}
if
(
Math
.
abs
(
size
)
<
1000
)
{
if
(
Math
.
abs
(
size
)
<
1000
)
{
return
kbn
.
toFixed
(
size
,
decimals
)
+
" ns"
;
return
kbn
.
toFixed
(
size
,
decimals
)
+
" ns"
;
}
}
...
...
src/app/components/timeSeries.js
View file @
1b0cddfa
...
@@ -5,10 +5,15 @@ define([
...
@@ -5,10 +5,15 @@ define([
function
(
_
,
kbn
)
{
function
(
_
,
kbn
)
{
'use strict'
;
'use strict'
;
function
defaultValueFormater
(
value
)
{
return
kbn
.
valueFormats
.
none
(
value
,
2
,
2
);
}
function
TimeSeries
(
opts
)
{
function
TimeSeries
(
opts
)
{
this
.
datapoints
=
opts
.
datapoints
;
this
.
datapoints
=
opts
.
datapoints
;
this
.
info
=
opts
.
info
;
this
.
info
=
opts
.
info
;
this
.
label
=
opts
.
info
.
alias
;
this
.
label
=
opts
.
info
.
alias
;
this
.
valueFormater
=
defaultValueFormater
;
}
}
function
matchSeriesOverride
(
aliasOrRegex
,
seriesAlias
)
{
function
matchSeriesOverride
(
aliasOrRegex
,
seriesAlias
)
{
...
@@ -108,11 +113,14 @@ function (_, kbn) {
...
@@ -108,11 +113,14 @@ function (_, kbn) {
};
};
TimeSeries
.
prototype
.
updateLegendValues
=
function
(
formater
,
decimals
,
scaledDecimals
)
{
TimeSeries
.
prototype
.
updateLegendValues
=
function
(
formater
,
decimals
,
scaledDecimals
)
{
this
.
info
.
avg
=
this
.
info
.
avg
!=
null
?
formater
(
this
.
info
.
avg
,
decimals
,
scaledDecimals
)
:
null
;
this
.
valueFormater
=
function
(
value
)
{
this
.
info
.
current
=
this
.
info
.
current
!=
null
?
formater
(
this
.
info
.
current
,
decimals
,
scaledDecimals
)
:
null
;
return
formater
(
value
,
decimals
,
scaledDecimals
);
this
.
info
.
min
=
this
.
info
.
min
!=
null
?
formater
(
this
.
info
.
min
,
decimals
,
scaledDecimals
)
:
null
;
};
this
.
info
.
max
=
this
.
info
.
max
!=
null
?
formater
(
this
.
info
.
max
,
decimals
,
scaledDecimals
)
:
null
;
this
.
info
.
avg
=
this
.
valueFormater
(
this
.
info
.
avg
);
this
.
info
.
total
=
this
.
info
.
total
!=
null
?
formater
(
this
.
info
.
total
,
decimals
,
scaledDecimals
)
:
null
;
this
.
info
.
current
=
this
.
valueFormater
(
this
.
info
.
current
);
this
.
info
.
min
=
this
.
valueFormater
(
this
.
info
.
min
);
this
.
info
.
max
=
this
.
valueFormater
(
this
.
info
.
max
);
this
.
info
.
total
=
this
.
valueFormater
(
this
.
info
.
total
);
};
};
return
TimeSeries
;
return
TimeSeries
;
...
...
src/app/directives/grafanaGraph.js
View file @
1b0cddfa
...
@@ -6,7 +6,7 @@ define([
...
@@ -6,7 +6,7 @@ define([
'lodash'
,
'lodash'
,
'./grafanaGraph.tooltip'
'./grafanaGraph.tooltip'
],
],
function
(
angular
,
$
,
kbn
,
moment
,
_
,
g
raphTooltip
)
{
function
(
angular
,
$
,
kbn
,
moment
,
_
,
G
raphTooltip
)
{
'use strict'
;
'use strict'
;
var
module
=
angular
.
module
(
'grafana.directives'
);
var
module
=
angular
.
module
(
'grafana.directives'
);
...
@@ -105,6 +105,7 @@ function (angular, $, kbn, moment, _, graphTooltip) {
...
@@ -105,6 +105,7 @@ function (angular, $, kbn, moment, _, graphTooltip) {
function
updateLegendValues
(
plot
)
{
function
updateLegendValues
(
plot
)
{
var
yaxis
=
plot
.
getYAxes
();
var
yaxis
=
plot
.
getYAxes
();
console
.
log
(
"value"
);
for
(
var
i
=
0
;
i
<
data
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
data
.
length
;
i
++
)
{
var
series
=
data
[
i
];
var
series
=
data
[
i
];
...
@@ -416,7 +417,7 @@ function (angular, $, kbn, moment, _, graphTooltip) {
...
@@ -416,7 +417,7 @@ function (angular, $, kbn, moment, _, graphTooltip) {
elem
.
html
(
'<img src="'
+
url
+
'"></img>'
);
elem
.
html
(
'<img src="'
+
url
+
'"></img>'
);
}
}
graphTooltip
.
register
(
elem
,
dashboard
,
scope
,
$rootS
cope
);
new
GraphTooltip
(
elem
,
dashboard
,
s
cope
);
elem
.
bind
(
"plotselected"
,
function
(
event
,
ranges
)
{
elem
.
bind
(
"plotselected"
,
function
(
event
,
ranges
)
{
scope
.
$apply
(
function
()
{
scope
.
$apply
(
function
()
{
...
...
src/app/directives/grafanaGraph.tooltip.js
View file @
1b0cddfa
define
([
define
([
'jquery'
,
'jquery'
,
'kbn'
,
],
],
function
(
$
,
kbn
)
{
function
(
$
)
{
'use strict'
;
'use strict'
;
function
registerTooltipFeatures
(
elem
,
dashboard
,
scope
)
{
function
GraphTooltip
(
elem
,
dashboard
,
scope
)
{
var
self
=
this
;
var
$tooltip
=
$
(
'<div id="tooltip">'
);
var
$tooltip
=
$
(
'<div id="tooltip">'
);
elem
.
mouseleave
(
function
()
{
this
.
findHoverIndexFromDataPoints
=
function
(
posX
,
series
,
last
)
{
if
(
scope
.
panel
.
tooltip
.
shared
||
dashboard
.
sharedCrosshair
)
{
var
ps
=
series
.
datapoints
.
pointsize
;
var
plot
=
elem
.
data
().
plot
;
var
initial
=
last
*
ps
;
if
(
plot
)
{
var
len
=
series
.
datapoints
.
points
.
length
;
$tooltip
.
detach
();
for
(
var
j
=
initial
;
j
<
len
;
j
+=
ps
)
{
plot
.
unhighlight
();
scope
.
appEvent
(
'clearCrosshair'
);
}
}
});
function
findHoverIndexFromDataPoints
(
posX
,
series
,
last
)
{
var
ps
=
series
.
datapoints
.
pointsize
;
var
initial
=
last
*
ps
;
for
(
var
j
=
initial
;
j
<
series
.
datapoints
.
points
.
length
;
j
+=
ps
)
{
if
(
series
.
datapoints
.
points
[
j
]
>
posX
)
{
if
(
series
.
datapoints
.
points
[
j
]
>
posX
)
{
return
Math
.
max
(
j
-
ps
,
0
)
/
ps
;
return
Math
.
max
(
j
-
ps
,
0
)
/
ps
;
}
}
}
}
return
j
/
ps
-
1
;
return
j
/
ps
-
1
;
}
}
;
function
findHoverIndexFromData
(
posX
,
series
)
{
this
.
findHoverIndexFromData
=
function
(
posX
,
series
)
{
for
(
var
j
=
0
;
j
<
series
.
data
.
length
;
j
++
)
{
var
len
=
series
.
data
.
length
;
for
(
var
j
=
0
;
j
<
len
;
j
++
)
{
if
(
series
.
data
[
j
][
0
]
>
posX
)
{
if
(
series
.
data
[
j
][
0
]
>
posX
)
{
return
Math
.
max
(
j
-
1
,
0
);
return
Math
.
max
(
j
-
1
,
0
);
}
}
}
}
return
j
-
1
;
return
j
-
1
;
}
}
;
function
showTooltip
(
title
,
innerHtml
,
pos
)
{
this
.
showTooltip
=
function
(
title
,
innerHtml
,
pos
)
{
var
body
=
'<div class="graph-tooltip small"><div class="graph-tooltip-time">'
+
title
+
'</div> '
;
var
body
=
'<div class="graph-tooltip small"><div class="graph-tooltip-time">'
+
title
+
'</div> '
;
body
+=
innerHtml
+
'</div>'
;
body
+=
innerHtml
+
'</div>'
;
$tooltip
.
html
(
body
).
place_tt
(
pos
.
pageX
+
20
,
pos
.
pageY
);
$tooltip
.
html
(
body
).
place_tt
(
pos
.
pageX
+
20
,
pos
.
pageY
);
}
};
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
(
dashboard
.
sharedCrosshair
){
scope
.
appEvent
(
'setCrosshair'
,
{
pos
:
pos
,
scope
:
scope
});
}
if
(
scope
.
panel
.
tooltip
.
shared
)
{
this
.
getMultiSeriesPlotHoverInfo
=
function
(
seriesList
,
pos
)
{
plot
.
unhighlight
();
var
value
,
seriesInfo
,
i
,
series
,
hoverIndex
;
var
results
=
[];
//check if all series has same length if so, only one x index will
var
pointCount
=
seriesList
[
0
].
data
.
length
;
//be checked and only for exact timestamp values
for
(
i
=
1
;
i
<
seriesList
.
length
;
i
++
)
{
var
pointCount
=
data
[
0
].
data
.
length
;
if
(
seriesList
[
i
].
data
.
length
!==
pointCount
)
{
for
(
i
=
1
;
i
<
data
.
length
;
i
++
)
{
results
.
pointCountMismatch
=
true
;
if
(
data
[
i
].
data
.
length
!==
pointCount
)
{
return
results
;
showTooltip
(
'Shared tooltip error'
,
'<ul>'
+
'<li>Series point counts are not the same</li>'
+
'<li>Set null point mode to null or null as zero</li>'
+
'<li>For influxdb users set fill(0) in your query</li></ul>'
,
pos
);
return
;
}
}
}
}
seriesHtml
=
''
;
series
=
seriesList
[
0
];
series
=
data
[
0
];
hoverIndex
=
this
.
findHoverIndexFromData
(
pos
.
x
,
series
);
hoverIndex
=
findHoverIndexFromData
(
pos
.
x
,
series
);
var
lasthoverIndex
=
0
;
var
lasthoverIndex
=
0
;
if
(
!
scope
.
panel
.
steppedLine
)
{
if
(
!
scope
.
panel
.
steppedLine
)
{
lasthoverIndex
=
hoverIndex
;
lasthoverIndex
=
hoverIndex
;
}
}
//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
timestamp
=
dashboard
.
formatDate
(
series
.
data
[
hoverIndex
][
0
])
;
results
.
time
=
series
.
data
[
hoverIndex
][
0
]
;
var
last_value
=
0
;
//needed for stacked values
var
last_value
=
0
;
//needed for stacked values
for
(
i
=
0
;
i
<
data
.
length
;
i
++
)
{
for
(
i
=
0
;
i
<
seriesList
.
length
;
i
++
)
{
series
=
data
[
i
];
series
=
seriesList
[
i
];
seriesInfo
=
series
.
info
;
seriesInfo
=
series
.
info
;
format
=
scope
.
panel
.
y_formats
[
seriesInfo
.
yaxis
-
1
];
if
(
scope
.
panel
.
stack
)
{
if
(
scope
.
panel
.
stack
)
{
if
(
scope
.
panel
.
tooltip
.
value_type
===
'individual'
)
{
if
(
scope
.
panel
.
tooltip
.
value_type
===
'individual'
)
{
...
@@ -99,45 +75,82 @@ function ($, kbn) {
...
@@ -99,45 +75,82 @@ function ($, kbn) {
value
=
series
.
data
[
hoverIndex
][
1
];
value
=
series
.
data
[
hoverIndex
][
1
];
}
}
value
=
kbn
.
valueFormats
[
format
](
value
,
series
.
yaxis
.
tickDecimals
);
// Highlighting multiple Points depending on the plot type
if
(
scope
.
panel
.
steppedLine
||
(
scope
.
panel
.
stack
&&
scope
.
panel
.
nullPointMode
==
"null"
))
{
// 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 las found hoverIndex.
var
newhoverIndex
=
this
.
findHoverIndexFromDataPoints
(
pos
.
x
,
series
,
lasthoverIndex
);
// update lasthoverIndex depends also on the plot type.
if
(
!
scope
.
panel
.
steppedLine
)
{
// on stacked graphs new will be always greater than last
lasthoverIndex
=
newhoverIndex
;
}
else
{
// if steppeLine, not always series increases its length, so we should begin
// to search correct index from the original hoverIndex on each serie.
lasthoverIndex
=
hoverIndex
;
}
if
(
seriesInfo
.
alias
)
{
results
.
push
({
value
:
value
,
hoverIndex
:
newhoverIndex
});
group
=
'<i class="icon-minus" style="color:'
+
series
.
color
+
';"></i> '
+
seriesInfo
.
alias
;
}
else
{
}
else
{
group
=
kbn
.
query_color_dot
(
series
.
color
,
15
)
+
' '
;
results
.
push
({
value
:
value
,
hoverIndex
:
hoverIndex
});
}
}
}
//pre-pending new values
return
results
;
seriesHtml
=
group
+
': <span class="graph-tooltip-value">'
+
value
+
'</span><br>'
+
seriesHtml
;
}
;
//Highlighting multiple Points depending on the plot type
elem
.
mouseleave
(
function
()
{
if
(
scope
.
panel
.
steppedLine
||
(
scope
.
panel
.
stack
&&
scope
.
panel
.
nullPointMode
==
"null"
))
{
if
(
scope
.
panel
.
tooltip
.
shared
||
dashboard
.
sharedCrosshair
)
{
//stacked and steppedLine plots can have series with different length.
var
plot
=
elem
.
data
().
plot
;
//Stacked series can increase its length on each new stacked serie if null points found,
if
(
plot
)
{
//to speed the index search we begin always on the las found hoverIndex.
$tooltip
.
detach
();
var
newhoverIndex
=
findHoverIndexFromDataPoints
(
pos
.
x
,
series
,
lasthoverIndex
);
plot
.
unhighlight
();
//update lasthoverIndex depends also on the plot type.
scope
.
appEvent
(
'clearCrosshair'
);
if
(
!
scope
.
panel
.
steppedLine
)
{
//on stacked graphs new will be always greater than last
lasthoverIndex
=
newhoverIndex
;
}
else
{
//if steppeLine, not always series increases its length, so we should begin
//to search correct index from the original hoverIndex on each serie.
lasthoverIndex
=
hoverIndex
;
}
}
plot
.
highlight
(
i
,
newhoverIndex
);
}
else
{
plot
.
highlight
(
i
,
hoverIndex
);
}
}
});
elem
.
bind
(
"plothover"
,
function
(
event
,
pos
,
item
)
{
var
plot
=
elem
.
data
().
plot
;
var
data
=
plot
.
getData
();
var
group
,
value
,
timestamp
,
hoverInfo
,
i
,
series
,
seriesHtml
;
if
(
dashboard
.
sharedCrosshair
){
scope
.
appEvent
(
'setCrosshair'
,
{
pos
:
pos
,
scope
:
scope
});
}
}
showTooltip
(
timestamp
,
seriesHtml
,
pos
);
if
(
scope
.
panel
.
tooltip
.
shared
)
{
plot
.
unhighlight
();
var
seriesHoverInfo
=
self
.
getMultiSeriesPlotHoverInfo
(
data
,
pos
);
if
(
seriesHoverInfo
.
pointCountMismatch
)
{
self
.
showTooltip
(
'Shared tooltip error'
,
'<ul>'
+
'<li>Series point counts are not the same</li>'
+
'<li>Set null point mode to null or null as zero</li>'
+
'<li>For influxdb users set fill(0) in your query</li></ul>'
,
pos
);
return
;
return
;
}
}
if
(
item
)
{
seriesInfo
=
item
.
series
.
info
;
seriesHtml
=
''
;
format
=
scope
.
panel
.
y_formats
[
seriesInfo
.
yaxis
-
1
];
timestamp
=
dashboard
.
formatDate
(
seriesHoverInfo
.
time
);
group
=
'<i class="icon-minus" style="color:'
+
item
.
series
.
color
+
';"></i> '
+
seriesInfo
.
alias
;
for
(
i
=
0
;
i
<
seriesHoverInfo
.
length
;
i
++
)
{
series
=
data
[
i
];
hoverInfo
=
seriesHoverInfo
[
i
];
value
=
series
.
valueFormater
(
hoverInfo
.
value
);
group
=
'<i class="icon-minus" style="color:'
+
series
.
color
+
';"></i> '
+
series
.
label
;
seriesHtml
=
group
+
': <span class="graph-tooltip-value">'
+
value
+
'</span><br>'
+
seriesHtml
;
plot
.
highlight
(
i
,
hoverInfo
.
hoverIndex
);
}
self
.
showTooltip
(
timestamp
,
seriesHtml
,
pos
);
}
// single series tooltip
else
if
(
item
)
{
series
=
item
.
series
;
group
=
'<i class="icon-minus" style="color:'
+
item
.
series
.
color
+
';"></i> '
+
series
.
label
;
if
(
scope
.
panel
.
stack
&&
scope
.
panel
.
tooltip
.
value_type
===
'individual'
)
{
if
(
scope
.
panel
.
stack
&&
scope
.
panel
.
tooltip
.
value_type
===
'individual'
)
{
value
=
item
.
datapoint
[
1
]
-
item
.
datapoint
[
2
];
value
=
item
.
datapoint
[
1
]
-
item
.
datapoint
[
2
];
...
@@ -146,19 +159,18 @@ function ($, kbn) {
...
@@ -146,19 +159,18 @@ function ($, kbn) {
value
=
item
.
datapoint
[
1
];
value
=
item
.
datapoint
[
1
];
}
}
value
=
kbn
.
valueFormats
[
format
](
value
,
item
.
series
.
yaxis
.
tickDecimals
);
value
=
series
.
valueFormater
(
value
);
timestamp
=
dashboard
.
formatDate
(
item
.
datapoint
[
0
]);
timestamp
=
dashboard
.
formatDate
(
item
.
datapoint
[
0
]);
group
+=
': <span class="graph-tooltip-value">'
+
value
+
'</span>'
;
group
+=
': <span class="graph-tooltip-value">'
+
value
+
'</span>'
;
showTooltip
(
timestamp
,
group
,
pos
);
self
.
showTooltip
(
timestamp
,
group
,
pos
);
}
else
{
}
// no hit
else
{
$tooltip
.
detach
();
$tooltip
.
detach
();
}
}
});
});
}
}
return
{
return
GraphTooltip
;
register
:
registerTooltipFeatures
};
});
});
src/app/panels/graph/module.js
View file @
1b0cddfa
src/css/less/graph.less
View file @
1b0cddfa
...
@@ -169,6 +169,8 @@
...
@@ -169,6 +169,8 @@
}
}
.graph-tooltip {
.graph-tooltip {
white-space: nowrap;
.graph-tooltip-time {
.graph-tooltip-time {
text-align: center;
text-align: center;
font-weight: bold;
font-weight: bold;
...
...
src/test/specs/graph-tooltip-specs.js
View file @
1b0cddfa
define
([
define
([
'jquery'
,
'jquery'
,
'directives/grafanaGraph.tooltip'
'directives/grafanaGraph.tooltip'
],
function
(
$
,
t
ooltip
)
{
],
function
(
$
,
GraphT
ooltip
)
{
'use strict'
;
'use strict'
;
describe
(
'graph tooltip'
,
function
()
{
var
elem
=
$
(
'<div></div>'
);
var
dashboard
=
{
formatDate
:
sinon
.
stub
().
returns
(
'date'
),
};
var
scope
=
{
var
scope
=
{
appEvent
:
sinon
.
spy
(),
appEvent
:
sinon
.
spy
(),
onAppEvent
:
sinon
.
spy
(),
onAppEvent
:
sinon
.
spy
(),
panel
:
{
};
var
elem
=
$
(
'<div></div>'
);
var
dashboard
=
{
};
function
describeSharedTooltip
(
desc
,
fn
)
{
var
ctx
=
{};
ctx
.
scope
=
scope
;
ctx
.
scope
.
panel
=
{
tooltip
:
{
tooltip
:
{
shared
:
true
shared
:
true
},
},
y_formats
:
[
'ms'
,
'none'
],
stack
:
false
stack
:
true
}
};
};
var
data
=
[
ctx
.
setup
=
function
(
setupFn
)
{
{
ctx
.
setupFn
=
setupFn
;
data
:
[[
10
,
10
],
[
12
,
20
]],
};
info
:
{
yaxis
:
1
},
yaxis
:
{
tickDecimals
:
2
},
describe
(
desc
,
function
()
{
},
beforeEach
(
function
()
{
{
ctx
.
setupFn
();
data
:
[[
10
,
10
],
[
12
,
20
]],
var
tooltip
=
new
GraphTooltip
(
elem
,
dashboard
,
scope
);
info
:
{
yaxis
:
1
},
ctx
.
results
=
tooltip
.
getMultiSeriesPlotHoverInfo
(
ctx
.
data
,
ctx
.
pos
);
yaxis
:
{
tickDecimals
:
2
},
});
fn
(
ctx
);
});
}
}
describeSharedTooltip
(
"steppedLine false, stack false"
,
function
(
ctx
)
{
ctx
.
setup
(
function
()
{
ctx
.
data
=
[
{
data
:
[[
10
,
15
],
[
12
,
20
]],
},
{
data
:
[[
10
,
2
],
[
12
,
3
]],
}
];
];
ctx
.
pos
=
{
x
:
11
};
});
var
plot
=
{
it
(
'should return 2 series'
,
function
()
{
getData
:
sinon
.
stub
().
returns
(
data
),
expect
(
ctx
.
results
.
length
).
to
.
be
(
2
);
highlight
:
sinon
.
stub
(),
});
unhighlight
:
sinon
.
stub
()
it
(
'should add time to results array'
,
function
()
{
};
expect
(
ctx
.
results
.
time
).
to
.
be
(
10
);
});
it
(
'should set value and hoverIndex'
,
function
()
{
expect
(
ctx
.
results
[
0
].
value
).
to
.
be
(
15
);
expect
(
ctx
.
results
[
1
].
value
).
to
.
be
(
2
);
expect
(
ctx
.
results
[
0
].
hoverIndex
).
to
.
be
(
0
);
});
});
describeSharedTooltip
(
"steppedLine false, stack true, individual false"
,
function
(
ctx
)
{
ctx
.
setup
(
function
()
{
ctx
.
data
=
[
{
data
:
[[
10
,
15
],
[
12
,
20
]],
},
{
data
:
[[
10
,
2
],
[
12
,
3
]],
}
];
ctx
.
scope
.
panel
.
stack
=
true
;
ctx
.
pos
=
{
x
:
11
};
});
elem
.
data
(
'plot'
,
plot
);
it
(
'should show stacked value'
,
function
()
{
expect
(
ctx
.
results
[
1
].
value
).
to
.
be
(
17
);
});
beforeEach
(
function
()
{
tooltip
.
register
(
elem
,
dashboard
,
scope
);
elem
.
trigger
(
'plothover'
,
[{},
{
x
:
13
},
{}]);
});
});
it
(
'should add tooltip'
,
function
()
{
describeSharedTooltip
(
"steppedLine false, stack true, individual true"
,
function
(
ctx
)
{
var
tooltipHtml
=
$
(
".graph-tooltip"
).
text
();
ctx
.
setup
(
function
()
{
expect
(
tooltipHtml
).
to
.
be
(
'date : 40.00 ms : 20.00 ms'
);
ctx
.
data
=
[
{
data
:
[[
10
,
15
],
[
12
,
20
]],
},
{
data
:
[[
10
,
2
],
[
12
,
3
]],
}
];
ctx
.
scope
.
panel
.
stack
=
true
;
ctx
.
scope
.
panel
.
tooltip
.
value_type
=
'individual'
;
ctx
.
pos
=
{
x
:
11
};
});
it
(
'should not show stacked value'
,
function
()
{
expect
(
ctx
.
results
[
1
].
value
).
to
.
be
(
2
);
});
});
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment