@@ -2429,6 +2429,45 @@ function cleanPoint(d, hovermode) {
24292429 return d ;
24302430}
24312431
2432+ /**
2433+ * Get the pixel span of a spike with spikemode 'across'.
2434+ *
2435+ * @param gd - the graph div
2436+ * @param ax - the full axis that shows the spike
2437+ * @param gs - the plot size, `fullLayout._size`
2438+ * @returns [start, end] in pixels: left to right for a y axis spike, top to bottom for an x axis spike
2439+ */
2440+ function getAcrossSpikeSpan ( gd , ax , gs ) {
2441+ const isY = ax . _id . charAt ( 0 ) === 'y' ;
2442+ let start = Infinity ;
2443+ let end = - Infinity ;
2444+
2445+ for ( const counterId of ax . _counterAxes || [ ] ) {
2446+ const counterAx = Axes . getFromId ( gd , counterId ) ;
2447+ if ( ! counterAx ) continue ;
2448+
2449+ const padStart = counterAx . _padStart || 0 ;
2450+ const padEnd = counterAx . _padEnd || 0 ;
2451+
2452+ if ( isY ) {
2453+ start = Math . min ( start , gs . l + counterAx . domain [ 0 ] * gs . w + padStart ) ;
2454+ end = Math . max ( end , gs . l + counterAx . domain [ 1 ] * gs . w - padEnd ) ;
2455+ } else {
2456+ start = Math . min ( start , gs . t + ( 1 - counterAx . domain [ 1 ] ) * gs . h + padStart ) ;
2457+ end = Math . max ( end , gs . t + ( 1 - counterAx . domain [ 0 ] ) * gs . h - padEnd ) ;
2458+ }
2459+ }
2460+
2461+ // a free axis sits outside the plot areas, and the spike must also reach that axis
2462+ if ( ax . anchor === 'free' ) {
2463+ const position = isY ? gs . l + ax . position * gs . w : gs . t + ( 1 - ax . position ) * gs . h ;
2464+ start = Math . min ( start , position ) ;
2465+ end = Math . max ( end , position ) ;
2466+ }
2467+
2468+ return [ start , end ] ;
2469+ }
2470+
24322471function createSpikelines ( gd , closestPoints , opts ) {
24332472 var container = opts . container ;
24342473 var fullLayout = opts . fullLayout ;
@@ -2478,14 +2517,9 @@ function createSpikelines(gd, closestPoints, opts) {
24782517 xEndSpike = hLinePointX ;
24792518 }
24802519 if ( yMode . indexOf ( 'across' ) !== - 1 ) {
2481- var xAcross0 = ya . _counterDomainMin ;
2482- var xAcross1 = ya . _counterDomainMax ;
2483- if ( ya . anchor === 'free' ) {
2484- xAcross0 = Math . min ( xAcross0 , ya . position ) ;
2485- xAcross1 = Math . max ( xAcross1 , ya . position ) ;
2486- }
2487- xBase = gs . l + xAcross0 * gs . w ;
2488- xEndSpike = gs . l + xAcross1 * gs . w ;
2520+ const xSpan = getAcrossSpikeSpan ( gd , ya , gs ) ;
2521+ xBase = xSpan [ 0 ] ;
2522+ xEndSpike = xSpan [ 1 ] ;
24892523 }
24902524
24912525 // Foreground horizontal line (to y-axis)
@@ -2563,14 +2597,9 @@ function createSpikelines(gd, closestPoints, opts) {
25632597 yEndSpike = vLinePointY ;
25642598 }
25652599 if ( xMode . indexOf ( 'across' ) !== - 1 ) {
2566- var yAcross0 = xa . _counterDomainMin ;
2567- var yAcross1 = xa . _counterDomainMax ;
2568- if ( xa . anchor === 'free' ) {
2569- yAcross0 = Math . min ( yAcross0 , xa . position ) ;
2570- yAcross1 = Math . max ( yAcross1 , xa . position ) ;
2571- }
2572- yBase = gs . t + ( 1 - yAcross1 ) * gs . h ;
2573- yEndSpike = gs . t + ( 1 - yAcross0 ) * gs . h ;
2600+ const ySpan = getAcrossSpikeSpan ( gd , xa , gs ) ;
2601+ yBase = ySpan [ 0 ] ;
2602+ yEndSpike = ySpan [ 1 ] ;
25742603 }
25752604
25762605 // Foreground vertical line (to x-axis)
0 commit comments