@@ -7105,3 +7105,100 @@ describe('hover on traces with (x|y)hoverformat', function() {
71057105 . then ( done , done . fail ) ;
71067106 } ) ;
71077107} ) ;
7108+
7109+ describe ( 'hoverlabel.showarrow' , function ( ) {
7110+ 'use strict' ;
7111+
7112+ var gd ;
7113+
7114+ beforeEach ( function ( ) {
7115+ gd = createGraphDiv ( ) ;
7116+ } ) ;
7117+
7118+ afterEach ( destroyGraphDiv ) ;
7119+
7120+ function _hover ( x , y ) {
7121+ mouseEvent ( 'mousemove' , x , y ) ;
7122+ Lib . clearThrottle ( ) ;
7123+ }
7124+
7125+ function getHoverPath ( ) {
7126+ var hoverLabels = d3SelectAll ( 'g.hovertext' ) ;
7127+ if ( hoverLabels . size ( ) === 0 ) return null ;
7128+ return hoverLabels . select ( 'path' ) . attr ( 'd' ) ;
7129+ }
7130+
7131+ it ( 'should show hover arrow by default' , function ( done ) {
7132+ Plotly . newPlot ( gd , [ {
7133+ x : [ 1 , 2 , 3 ] ,
7134+ y : [ 1 , 2 , 1 ] ,
7135+ type : 'scatter' ,
7136+ mode : 'markers'
7137+ } ] , {
7138+ width : 400 ,
7139+ height : 400 ,
7140+ margin : { l : 50 , t : 50 , r : 50 , b : 50 }
7141+ } )
7142+ . then ( function ( ) {
7143+ _hover ( 200 , 70 ) ; // Hover over middle point
7144+ } )
7145+ . then ( delay ( HOVERMINTIME * 1.1 ) )
7146+ . then ( function ( ) {
7147+ var pathD = getHoverPath ( ) ;
7148+ expect ( pathD ) . not . toBeNull ( 'hover path should exist' ) ;
7149+ // Arrow paths contain 'L' commands starting from 0,0
7150+ expect ( pathD ) . toMatch ( / ^ M 0 , 0 L / , 'path should contain arrow (L command from 0,0)' ) ;
7151+ } )
7152+ . then ( done , done . fail ) ;
7153+ } ) ;
7154+
7155+ it ( 'should hide hover arrow when showarrow is false' , function ( done ) {
7156+ Plotly . newPlot ( gd , [ {
7157+ x : [ 1 , 2 , 3 ] ,
7158+ y : [ 1 , 2 , 1 ] ,
7159+ type : 'scatter' ,
7160+ mode : 'markers'
7161+ } ] , {
7162+ width : 400 ,
7163+ height : 400 ,
7164+ margin : { l : 50 , t : 50 , r : 50 , b : 50 } ,
7165+ hoverlabel : { showarrow : false }
7166+ } )
7167+ . then ( function ( ) {
7168+ _hover ( 200 , 70 ) ; // Hover over middle point
7169+ } )
7170+ . then ( delay ( HOVERMINTIME * 1.1 ) )
7171+ . then ( function ( ) {
7172+ var pathD = getHoverPath ( ) ;
7173+ expect ( pathD ) . not . toBeNull ( 'hover path should exist' ) ;
7174+ // No-arrow paths should be simple rectangles (no 'L' commands starting at 0,0))
7175+ expect ( pathD ) . not . toMatch ( / ^ M 0 , 0 L / , 'path should not start at 0,0' ) ;
7176+ expect ( pathD ) . toMatch ( / ^ M [ \d . - ] + , [ \d . - ] + h / , 'path should start with some numeric point and move horizontally' ) ;
7177+ } )
7178+ . then ( done , done . fail ) ;
7179+ } ) ;
7180+
7181+ it ( 'should work at trace level' , function ( done ) {
7182+ Plotly . newPlot ( gd , [ {
7183+ x : [ 1 , 2 , 3 ] ,
7184+ y : [ 1 , 2 , 1 ] ,
7185+ type : 'scatter' ,
7186+ mode : 'markers' ,
7187+ hoverlabel : { showarrow : false }
7188+ } ] , {
7189+ width : 400 ,
7190+ height : 400 ,
7191+ margin : { l : 50 , t : 50 , r : 50 , b : 50 }
7192+ } )
7193+ . then ( function ( ) {
7194+ _hover ( 200 , 70 ) ; // Hover over middle point
7195+ } )
7196+ . then ( delay ( HOVERMINTIME * 1.1 ) )
7197+ . then ( function ( ) {
7198+ var pathD = getHoverPath ( ) ;
7199+ expect ( pathD ) . not . toBeNull ( 'hover path should exist' ) ;
7200+ expect ( pathD ) . not . toMatch ( / ^ M 0 , 0 L / , 'trace-level showarrow:false should hide arrow' ) ;
7201+ } )
7202+ . then ( done , done . fail ) ;
7203+ } ) ;
7204+ } ) ;
0 commit comments