@@ -1110,49 +1110,32 @@ describe('hover info', function() {
1110
1110
1111
1111
} ) ;
1112
1112
1113
- describe ( 'centered' , function ( ) {
1114
- var trace1 = {
1115
- x : [ 'giraffes' ] ,
1116
- y : [ 5 ] ,
1117
- name : 'LA Zoo' ,
1118
- type : 'bar' ,
1119
- text : [ 'Way too long hover info!' ]
1120
- } ;
1121
- var trace2 = {
1122
- x : [ 'giraffes' ] ,
1123
- y : [ 5 ] ,
1124
- name : 'SF Zoo' ,
1125
- type : 'bar' ,
1126
- text : [ 'San Francisco' ]
1127
- } ;
1128
- var data = [ trace1 , trace2 ] ;
1129
- var layout = { width : 600 , height : 300 , barmode : 'stack' } ;
1130
-
1131
- var gd ;
1132
-
1133
- beforeEach ( function ( done ) {
1134
- gd = createGraphDiv ( ) ;
1135
- Plotly . plot ( gd , data , layout ) . then ( done ) ;
1113
+ function hoverInfoNodes ( traceName ) {
1114
+ var g = d3 . selectAll ( 'g.hoverlayer g.hovertext' ) . filter ( function ( ) {
1115
+ return ! d3 . select ( this ) . select ( '[data-unformatted="' + traceName + '"]' ) . empty ( ) ;
1136
1116
} ) ;
1137
1117
1138
- function centeredHoverInfoNodes ( ) {
1139
- var g = d3 . selectAll ( 'g.hoverlayer g.hovertext' ) . filter ( function ( ) {
1140
- return ! d3 . select ( this ) . select ( '[data-unformatted="LA Zoo"]' ) . empty ( ) ;
1141
- } ) ;
1118
+ return {
1119
+ primaryText : g . select ( 'text:not([data-unformatted="' + traceName + '"])' ) . node ( ) ,
1120
+ primaryBox : g . select ( 'path' ) . node ( ) ,
1121
+ secondaryText : g . select ( '[data-unformatted="' + traceName + '"]' ) . node ( ) ,
1122
+ secondaryBox : g . select ( 'rect' ) . node ( )
1123
+ } ;
1124
+ }
1142
1125
1143
- return {
1144
- primaryText : g . select ( 'text:not([data-unformatted="LA Zoo"])' ) . node ( ) ,
1145
- primaryBox : g . select ( 'path' ) . node ( ) ,
1146
- secondaryText : g . select ( '[data-unformatted="LA Zoo"]' ) . node ( ) ,
1147
- secondaryBox : g . select ( 'rect' ) . node ( )
1148
- } ;
1149
- }
1126
+ function ensureCentered ( hoverInfoNodes ) {
1127
+ expect ( hoverInfoNodes . primaryText . getAttribute ( 'text-anchor' ) ) . toBe ( 'middle' ) ;
1128
+ expect ( hoverInfoNodes . secondaryText . getAttribute ( 'text-anchor' ) ) . toBe ( 'middle' ) ;
1129
+ return hoverInfoNodes ;
1130
+ }
1150
1131
1151
- function ensureCentered ( hoverInfoNodes ) {
1152
- expect ( hoverInfoNodes . primaryText . getAttribute ( 'text-anchor' ) ) . toBe ( 'middle' ) ;
1153
- expect ( hoverInfoNodes . secondaryText . getAttribute ( 'text-anchor' ) ) . toBe ( 'middle' ) ;
1154
- return hoverInfoNodes ;
1155
- }
1132
+ function assertLabelsInsideBoxes ( nodes , msgPrefix ) {
1133
+ var msgPrefixFmt = msgPrefix ? '[' + msgPrefix + '] ' : '' ;
1134
+
1135
+ assertElemInside ( nodes . primaryText , nodes . primaryBox ,
1136
+ msgPrefixFmt + 'Primary text inside box' ) ;
1137
+ assertElemInside ( nodes . secondaryText , nodes . secondaryBox ,
1138
+ msgPrefixFmt + 'Secondary text inside box' ) ;
1156
1139
1157
1140
function assertElemInside ( elem , container , msg ) {
1158
1141
var elemBB = elem . getBoundingClientRect ( ) ;
@@ -1162,14 +1145,23 @@ describe('hover info', function() {
1162
1145
contBB . top < elemBB . top &&
1163
1146
contBB . bottom > elemBB . bottom ) . toBe ( true , msg ) ;
1164
1147
}
1148
+ }
1149
+
1150
+ function assertSecondaryRightToPrimaryBox ( nodes , msgPrefix ) {
1151
+ var msgPrefixFmt = msgPrefix ? '[' + msgPrefix + '] ' : '' ;
1152
+
1153
+ assertElemRightTo ( nodes . secondaryBox , nodes . primaryBox ,
1154
+ msgPrefixFmt + 'Secondary box right to primary box' ) ;
1155
+ assertElemTopsAligned ( nodes . secondaryBox , nodes . primaryBox ,
1156
+ msgPrefixFmt + 'Top edges of primary and secondary boxes aligned' ) ;
1165
1157
1166
1158
function assertElemRightTo ( elem , refElem , msg ) {
1167
1159
var elemBB = elem . getBoundingClientRect ( ) ;
1168
1160
var refElemBB = refElem . getBoundingClientRect ( ) ;
1169
1161
expect ( elemBB . left >= refElemBB . right ) . toBe ( true , msg ) ;
1170
1162
}
1171
1163
1172
- function assertTopsAligned ( elem1 , elem2 , msg ) {
1164
+ function assertElemTopsAligned ( elem1 , elem2 , msg ) {
1173
1165
var elem1BB = elem1 . getBoundingClientRect ( ) ;
1174
1166
var elem2BB = elem2 . getBoundingClientRect ( ) ;
1175
1167
@@ -1178,21 +1170,105 @@ describe('hover info', function() {
1178
1170
var tolerance = 1.1 ;
1179
1171
expect ( elem1BB . top - elem2BB . top ) . toBeWithin ( 0 , tolerance , msg ) ;
1180
1172
}
1173
+ }
1174
+
1175
+ describe ( 'centered' , function ( ) {
1176
+ var trace1 = {
1177
+ x : [ 'giraffes' ] ,
1178
+ y : [ 5 ] ,
1179
+ name : 'LA Zoo' ,
1180
+ type : 'bar' ,
1181
+ text : [ 'Way too long hover info!' ]
1182
+ } ;
1183
+ var trace2 = {
1184
+ x : [ 'giraffes' ] ,
1185
+ y : [ 5 ] ,
1186
+ name : 'SF Zoo' ,
1187
+ type : 'bar' ,
1188
+ text : [ 'San Francisco' ]
1189
+ } ;
1190
+ var data = [ trace1 , trace2 ] ;
1191
+ var layout = { width : 600 , height : 300 , barmode : 'stack' } ;
1192
+
1193
+ var gd ;
1194
+
1195
+ beforeEach ( function ( done ) {
1196
+ gd = createGraphDiv ( ) ;
1197
+ Plotly . plot ( gd , data , layout ) . then ( done ) ;
1198
+ } ) ;
1181
1199
1182
1200
it ( 'renders labels inside boxes' , function ( ) {
1183
1201
_hover ( gd , 300 , 150 ) ;
1184
1202
1185
- var nodes = ensureCentered ( centeredHoverInfoNodes ( ) ) ;
1186
- assertElemInside ( nodes . primaryText , nodes . primaryBox , 'Primary text inside box' ) ;
1187
- assertElemInside ( nodes . secondaryText , nodes . secondaryBox , 'Secondary text inside box' ) ;
1203
+ var nodes = ensureCentered ( hoverInfoNodes ( 'LA Zoo' ) ) ;
1204
+ assertLabelsInsideBoxes ( nodes ) ;
1188
1205
} ) ;
1189
1206
1190
1207
it ( 'renders secondary info box right to primary info box' , function ( ) {
1191
1208
_hover ( gd , 300 , 150 ) ;
1192
1209
1193
- var nodes = ensureCentered ( centeredHoverInfoNodes ( ) ) ;
1194
- assertElemRightTo ( nodes . secondaryBox , nodes . primaryBox , 'Secondary box right to primary box' ) ;
1195
- assertTopsAligned ( nodes . secondaryBox , nodes . primaryBox , 'Top edges of primary and secondary boxes aligned' ) ;
1210
+ var nodes = ensureCentered ( hoverInfoNodes ( 'LA Zoo' ) ) ;
1211
+ assertSecondaryRightToPrimaryBox ( nodes ) ;
1212
+ } ) ;
1213
+ } ) ;
1214
+
1215
+ describe ( 'centered' , function ( ) {
1216
+ var trace1 = {
1217
+ x : [ 'giraffes' ] ,
1218
+ y : [ 5 ] ,
1219
+ name : 'LA Zoo' ,
1220
+ type : 'bar' ,
1221
+ text : [ 'Way too long hover info!' ]
1222
+ } ;
1223
+ var trace2 = {
1224
+ x : [ 'giraffes' ] ,
1225
+ y : [ 5 ] ,
1226
+ name : 'SF Zoo' ,
1227
+ type : 'bar' ,
1228
+ text : [ 'Way too looooong hover info!' ]
1229
+ } ;
1230
+ var trace3 = {
1231
+ x : [ 'giraffes' ] ,
1232
+ y : [ 5 ] ,
1233
+ name : 'NY Zoo' ,
1234
+ type : 'bar' ,
1235
+ text : [ 'New York' ]
1236
+ } ;
1237
+ var data = [ trace1 , trace2 , trace3 ] ;
1238
+ var layout = { width : 600 , height : 300 } ;
1239
+
1240
+ var gd ;
1241
+
1242
+ beforeEach ( function ( done ) {
1243
+ gd = createGraphDiv ( ) ;
1244
+ Plotly . plot ( gd , data , layout ) . then ( done ) ;
1245
+ } ) ;
1246
+
1247
+ function calcLineOverlap ( minA , maxA , minB , maxB ) {
1248
+ expect ( minA ) . toBeLessThan ( maxA ) ;
1249
+ expect ( minB ) . toBeLessThan ( maxB ) ;
1250
+
1251
+ var overlap = Math . min ( maxA , maxB ) - Math . max ( minA , minB ) ;
1252
+ return Math . max ( 0 , overlap ) ;
1253
+ }
1254
+
1255
+ it ( 'stacks nicely upon each other' , function ( ) {
1256
+ _hover ( gd , 300 , 150 ) ;
1257
+
1258
+ var nodesLA = ensureCentered ( hoverInfoNodes ( 'LA Zoo' ) ) ;
1259
+ var nodesSF = ensureCentered ( hoverInfoNodes ( 'SF Zoo' ) ) ;
1260
+
1261
+ // Ensure layout correct
1262
+ assertLabelsInsideBoxes ( nodesLA , 'LA Zoo' ) ;
1263
+ assertLabelsInsideBoxes ( nodesSF , 'SF Zoo' ) ;
1264
+ assertSecondaryRightToPrimaryBox ( nodesLA , 'LA Zoo' ) ;
1265
+ assertSecondaryRightToPrimaryBox ( nodesSF , 'SF Zoo' ) ;
1266
+
1267
+ // Ensure stacking, finally
1268
+ var boxLABB = nodesLA . primaryBox . getBoundingClientRect ( ) ;
1269
+ var boxSFBB = nodesSF . primaryBox . getBoundingClientRect ( ) ;
1270
+ expect ( calcLineOverlap ( boxLABB . top , boxLABB . bottom , boxSFBB . top , boxSFBB . bottom ) )
1271
+ . toBeWithin ( 0 , 1 ) ; // Be robust against floating point arithmetic and subtle future layout changes
1196
1272
} ) ;
1197
1273
} ) ;
1198
1274
} ) ;
0 commit comments