@@ -1632,7 +1632,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
1632
1632
// set scaling to pixels
1633
1633
ax . setScale ( ) ;
1634
1634
1635
- var axletter = axid . charAt ( 0 ) ,
1635
+ var axLetter = axid . charAt ( 0 ) ,
1636
1636
counterLetter = axes . counterLetter ( axid ) ,
1637
1637
vals = axes . calcTicks ( ax ) ,
1638
1638
datafn = function ( d ) { return [ d . text , d . x , ax . mirror ] . join ( '_' ) ; } ,
@@ -1646,7 +1646,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
1646
1646
gridWidth = Drawing . crispRound ( gd , ax . gridwidth , 1 ) ,
1647
1647
zeroLineWidth = Drawing . crispRound ( gd , ax . zerolinewidth , gridWidth ) ,
1648
1648
tickWidth = Drawing . crispRound ( gd , ax . tickwidth , 1 ) ,
1649
- sides , transfn , tickpathfn ,
1649
+ sides , transfn , tickpathfn , subplots ,
1650
1650
i ;
1651
1651
1652
1652
if ( ax . _counterangle && ax . ticks === 'outside' ) {
@@ -1656,7 +1656,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
1656
1656
}
1657
1657
1658
1658
// positioning arguments for x vs y axes
1659
- if ( axletter === 'x' ) {
1659
+ if ( axLetter === 'x' ) {
1660
1660
sides = [ 'bottom' , 'top' ] ;
1661
1661
transfn = function ( d ) {
1662
1662
return 'translate(' + ax . l2p ( d . x ) + ',0)' ;
@@ -1669,7 +1669,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
1669
1669
else return 'M0,' + shift + 'v' + len ;
1670
1670
} ;
1671
1671
}
1672
- else if ( axletter === 'y' ) {
1672
+ else if ( axLetter === 'y' ) {
1673
1673
sides = [ 'left' , 'right' ] ;
1674
1674
transfn = function ( d ) {
1675
1675
return 'translate(0,' + ax . l2p ( d . x ) + ')' ;
@@ -1690,7 +1690,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
1690
1690
// which direction do the side[0], side[1], and free ticks go?
1691
1691
// then we flip if outside XOR y axis
1692
1692
ticksign = [ - 1 , 1 , axside === sides [ 1 ] ? 1 : - 1 ] ;
1693
- if ( ( ax . ticks !== 'inside' ) === ( axletter === 'x' ) ) {
1693
+ if ( ( ax . ticks !== 'inside' ) === ( axLetter === 'x' ) ) {
1694
1694
ticksign = ticksign . map ( function ( v ) { return - v ; } ) ;
1695
1695
}
1696
1696
@@ -1724,12 +1724,12 @@ axes.doTicks = function(gd, axid, skipTitle) {
1724
1724
var tickLabels = container . selectAll ( 'g.' + tcls ) . data ( vals , datafn ) ;
1725
1725
if ( ! ax . showticklabels || ! isNumeric ( position ) ) {
1726
1726
tickLabels . remove ( ) ;
1727
- drawAxTitle ( axid ) ;
1727
+ drawAxTitle ( ) ;
1728
1728
return ;
1729
1729
}
1730
1730
1731
1731
var labelx , labely , labelanchor , labelpos0 , flipit ;
1732
- if ( axletter === 'x' ) {
1732
+ if ( axLetter === 'x' ) {
1733
1733
flipit = ( axside === 'bottom' ) ? 1 : - 1 ;
1734
1734
labelx = function ( d ) { return d . dx + labelShift * flipit ; } ;
1735
1735
labelpos0 = position + ( labelStandoff + pad ) * flipit ;
@@ -1845,7 +1845,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
1845
1845
// check for auto-angling if x labels overlap
1846
1846
// don't auto-angle at all for log axes with
1847
1847
// base and digit format
1848
- if ( axletter === 'x' && ! isNumeric ( ax . tickangle ) &&
1848
+ if ( axLetter === 'x' && ! isNumeric ( ax . tickangle ) &&
1849
1849
( ax . type !== 'log' || String ( ax . dtick ) . charAt ( 0 ) !== 'D' ) ) {
1850
1850
var lbbArray = [ ] ;
1851
1851
tickLabels . each ( function ( d ) {
@@ -1890,12 +1890,59 @@ axes.doTicks = function(gd, axid, skipTitle) {
1890
1890
// (so it can move out of the way if needed)
1891
1891
// TODO: separate out scoot so we don't need to do
1892
1892
// a full redraw of the title (mostly relevant for MathJax)
1893
- drawAxTitle ( axid ) ;
1893
+ drawAxTitle ( ) ;
1894
1894
return axid + ' done' ;
1895
1895
}
1896
1896
1897
1897
function calcBoundingBox ( ) {
1898
- ax . _boundingBox = container . node ( ) . getBoundingClientRect ( ) ;
1898
+ var bBox = container . node ( ) . getBoundingClientRect ( ) ;
1899
+ var gdBB = gd . getBoundingClientRect ( ) ;
1900
+
1901
+ /*
1902
+ * the way we're going to use this, the positioning that matters
1903
+ * is relative to the origin of gd. This is important particularly
1904
+ * if gd is scrollable, and may have been scrolled between the time
1905
+ * we calculate this and the time we use it
1906
+ */
1907
+ var bbFinal = ax . _boundingBox = {
1908
+ width : bBox . width ,
1909
+ height : bBox . height ,
1910
+ left : bBox . left - gdBB . left ,
1911
+ right : bBox . right - gdBB . left ,
1912
+ top : bBox . top - gdBB . top ,
1913
+ bottom : bBox . bottom - gdBB . top
1914
+ } ;
1915
+
1916
+ /*
1917
+ * for spikelines: what's the full domain of positions in the
1918
+ * opposite direction that are associated with this axis?
1919
+ * This means any axes that we make a subplot with, plus the
1920
+ * position of the axis itself if it's free.
1921
+ */
1922
+ if ( subplots ) {
1923
+ var fullRange = ax . _counterSpan = [ Infinity , - Infinity ] ;
1924
+
1925
+ for ( i = 0 ; i < subplots . length ; i ++ ) {
1926
+ var subplot = fullLayout . _plots [ subplots [ i ] ] ;
1927
+ var counterAxis = subplot [ ( axLetter === 'x' ) ? 'yaxis' : 'xaxis' ] ;
1928
+
1929
+ extendRange ( fullRange , [
1930
+ counterAxis . _offset ,
1931
+ counterAxis . _offset + counterAxis . _length
1932
+ ] ) ;
1933
+ }
1934
+
1935
+ if ( ax . anchor === 'free' ) {
1936
+ extendRange ( fullRange , ( axLetter === 'x' ) ?
1937
+ [ ax . _boundingBox . bottom , ax . _boundingBox . top ] :
1938
+ [ ax . _boundingBox . right , ax . _boundingBox . left ] ) ;
1939
+ }
1940
+ }
1941
+
1942
+ function extendRange ( range , newRange ) {
1943
+ range [ 0 ] = Math . min ( range [ 0 ] , newRange [ 0 ] ) ;
1944
+ range [ 1 ] = Math . max ( range [ 1 ] , newRange [ 1 ] ) ;
1945
+ }
1899
1946
}
1900
1947
1901
1948
var done = Lib . syncOrAsync ( [
@@ -1907,7 +1954,7 @@ axes.doTicks = function(gd, axid, skipTitle) {
1907
1954
return done ;
1908
1955
}
1909
1956
1910
- function drawAxTitle ( axid ) {
1957
+ function drawAxTitle ( ) {
1911
1958
if ( skipTitle ) return ;
1912
1959
1913
1960
// now this only applies to regular cartesian axes; colorbars and
@@ -1978,16 +2025,16 @@ axes.doTicks = function(gd, axid, skipTitle) {
1978
2025
1979
2026
function traceHasBarsOrFill ( trace , subplot ) {
1980
2027
if ( trace . visible !== true || trace . xaxis + trace . yaxis !== subplot ) return false ;
1981
- if ( Registry . traceIs ( trace , 'bar' ) && trace . orientation === { x : 'h' , y : 'v' } [ axletter ] ) return true ;
1982
- return trace . fill && trace . fill . charAt ( trace . fill . length - 1 ) === axletter ;
2028
+ if ( Registry . traceIs ( trace , 'bar' ) && trace . orientation === { x : 'h' , y : 'v' } [ axLetter ] ) return true ;
2029
+ return trace . fill && trace . fill . charAt ( trace . fill . length - 1 ) === axLetter ;
1983
2030
}
1984
2031
1985
2032
function drawGrid ( plotinfo , counteraxis , subplot ) {
1986
2033
var gridcontainer = plotinfo . gridlayer ,
1987
2034
zlcontainer = plotinfo . zerolinelayer ,
1988
- gridvals = plotinfo [ 'hidegrid' + axletter ] ? [ ] : valsClipped ,
2035
+ gridvals = plotinfo [ 'hidegrid' + axLetter ] ? [ ] : valsClipped ,
1989
2036
gridpath = ax . _gridpath ||
1990
- 'M0,0' + ( ( axletter === 'x' ) ? 'v' : 'h' ) + counteraxis . _length ,
2037
+ 'M0,0' + ( ( axLetter === 'x' ) ? 'v' : 'h' ) + counteraxis . _length ,
1991
2038
grid = gridcontainer . selectAll ( 'path.' + gcls )
1992
2039
. data ( ( ax . showgrid === false ) ? [ ] : gridvals , datafn ) ;
1993
2040
grid . enter ( ) . append ( 'path' ) . classed ( gcls , 1 )
@@ -2041,12 +2088,13 @@ axes.doTicks = function(gd, axid, skipTitle) {
2041
2088
return drawLabels ( ax . _axislayer , ax . _pos ) ;
2042
2089
}
2043
2090
else {
2044
- var alldone = axes . getSubplots ( gd , ax ) . map ( function ( subplot ) {
2091
+ subplots = axes . getSubplots ( gd , ax ) ;
2092
+ var alldone = subplots . map ( function ( subplot ) {
2045
2093
var plotinfo = fullLayout . _plots [ subplot ] ;
2046
2094
2047
2095
if ( ! fullLayout . _has ( 'cartesian' ) ) return ;
2048
2096
2049
- var container = plotinfo [ axletter + 'axislayer' ] ,
2097
+ var container = plotinfo [ axLetter + 'axislayer' ] ,
2050
2098
2051
2099
// [bottom or left, top or right, free, main]
2052
2100
linepositions = ax . _linepositions [ subplot ] || [ ] ,
0 commit comments