@@ -1802,14 +1802,11 @@ axes.drawOne = function(gd, ax, opts) {
18021802 // TODO: mirror labels, esp for subplots
18031803
18041804 seq . push ( function ( ) {
1805- var labelFns = axes . makeLabelFns ( ax , mainLinePosition ) ;
18061805 return axes . drawLabels ( gd , ax , {
18071806 vals : vals ,
18081807 layer : mainAxLayer ,
18091808 transFn : transFn ,
1810- labelXFn : labelFns . labelXFn ,
1811- labelYFn : labelFns . labelYFn ,
1812- labelAnchorFn : labelFns . labelAnchorFn ,
1809+ labelFns : axes . makeLabelFns ( ax , mainLinePosition )
18131810 } ) ;
18141811 } ) ;
18151812
@@ -1821,8 +1818,6 @@ axes.drawOne = function(gd, ax, opts) {
18211818 seq . push ( function ( ) {
18221819 labelLength += getLabelLevelSpan ( ax , axId + 'tick' ) + pad ;
18231820 labelLength += ax . _tickAngles [ axId + 'tick' ] ? ax . tickfont . size * LINE_SPACING : 0 ;
1824- var secondaryPosition = mainLinePosition + labelLength * sgn ;
1825- var secondaryLabelFns = axes . makeLabelFns ( ax , secondaryPosition ) ;
18261821
18271822 return axes . drawLabels ( gd , ax , {
18281823 vals : getSecondaryLabelVals ( ax , vals ) ,
@@ -1831,9 +1826,7 @@ axes.drawOne = function(gd, ax, opts) {
18311826 repositionOnUpdate : true ,
18321827 secondary : true ,
18331828 transFn : transFn ,
1834- labelXFn : secondaryLabelFns . labelXFn ,
1835- labelYFn : secondaryLabelFns . labelYFn ,
1836- labelAnchorFn : secondaryLabelFns . labelAnchorFn ,
1829+ labelFns : axes . makeLabelFns ( ax , mainLinePosition + labelLength * sgn )
18371830 } ) ;
18381831 } ) ;
18391832
@@ -2178,66 +2171,79 @@ axes.makeTickPath = function(ax, shift, sgn, len) {
21782171 * @param {number } shift
21792172 * @param {number } angle [in degrees] ...
21802173 * @return {object }
2181- * - {fn} labelXFn
2182- * - {fn} labelYFn
2183- * - {fn} labelAnchorFn
2184- * - {number} labelStandoff
2185- * - {number} labelShift
2174+ * - {fn} xFn
2175+ * - {fn} yFn
2176+ * - {fn} anchorFn
2177+ * - {fn} heightFn
2178+ * - {number} labelStandoff (gap parallel to ticks)
2179+ * - {number} labelShift (gap perpendicular to ticks)
21862180 */
21872181axes . makeLabelFns = function ( ax , shift , angle ) {
21882182 var axLetter = ax . _id . charAt ( 0 ) ;
2189- var pad = ( ax . linewidth || 1 ) / 2 ;
21902183 var ticksOnOutsideLabels = ax . tickson !== 'boundaries' && ax . ticks === 'outside' ;
21912184
2192- var labelStandoff = ticksOnOutsideLabels ? ax . ticklen : 0 ;
2185+ var labelStandoff = 0 ;
21932186 var labelShift = 0 ;
21942187
2188+ if ( ticksOnOutsideLabels ) {
2189+ labelStandoff += ax . ticklen ;
2190+ }
21952191 if ( angle && ax . ticks === 'outside' ) {
21962192 var rad = Lib . deg2rad ( angle ) ;
21972193 labelStandoff = ax . ticklen * Math . cos ( rad ) + 1 ;
21982194 labelShift = ax . ticklen * Math . sin ( rad ) ;
21992195 }
2200-
22012196 if ( ax . showticklabels && ( ticksOnOutsideLabels || ax . showline ) ) {
22022197 labelStandoff += 0.2 * ax . tickfont . size ;
22032198 }
2199+ labelStandoff += ( ax . linewidth || 1 ) / 2 ;
22042200
2205- // Used in polar angular label x/y functions
2206- // TODO generalize makeLabelFns so that it just work for angular axes
22072201 var out = {
22082202 labelStandoff : labelStandoff ,
22092203 labelShift : labelShift
22102204 } ;
22112205
22122206 var x0 , y0 , ff , flipIt ;
2207+
22132208 if ( axLetter === 'x' ) {
22142209 flipIt = ax . side === 'bottom' ? 1 : - 1 ;
22152210 x0 = labelShift * flipIt ;
2216- y0 = shift + ( labelStandoff + pad ) * flipIt ;
2211+ y0 = shift + labelStandoff * flipIt ;
22172212 ff = ax . side === 'bottom' ? 1 : - 0.2 ;
22182213
2219- out . labelXFn = function ( d ) { return d . dx + x0 ; } ;
2220- out . labelYFn = function ( d ) { return d . dy + y0 + d . fontSize * ff ; } ;
2221- out . labelAnchorFn = function ( a ) {
2214+ out . xFn = function ( d ) { return d . dx + x0 ; } ;
2215+ out . yFn = function ( d ) { return d . dy + y0 + d . fontSize * ff ; } ;
2216+ out . anchorFn = function ( d , a ) {
22222217 if ( ! isNumeric ( a ) || a === 0 || a === 180 ) {
22232218 return 'middle' ;
22242219 }
22252220 return ( a * flipIt < 0 ) ? 'end' : 'start' ;
22262221 } ;
2222+ out . heightFn = function ( d , a , h ) {
2223+ return ( a < - 60 || a > 60 ) ? - 0.5 * h :
2224+ ax . side === 'top' ? - h :
2225+ 0 ;
2226+ } ;
22272227 } else if ( axLetter === 'y' ) {
22282228 flipIt = ax . side === 'right' ? 1 : - 1 ;
2229- x0 = labelStandoff + pad ;
2229+ x0 = labelStandoff ;
22302230 y0 = - labelShift * flipIt ;
22312231 ff = Math . abs ( ax . tickangle ) === 90 ? 0.5 : 0 ;
22322232
2233- out . labelXFn = function ( d ) { return d . dx + shift + ( x0 + d . fontSize * ff ) * flipIt ; } ;
2234- out . labelYFn = function ( d ) { return d . dy + y0 + d . fontSize * MID_SHIFT ; } ;
2235- out . labelAnchorFn = function ( a ) {
2233+ out . xFn = function ( d ) { return d . dx + shift + ( x0 + d . fontSize * ff ) * flipIt ; } ;
2234+ out . yFn = function ( d ) { return d . dy + y0 + d . fontSize * MID_SHIFT ; } ;
2235+ out . anchorFn = function ( d , a ) {
22362236 if ( isNumeric ( a ) && Math . abs ( a ) === 90 ) {
22372237 return 'middle' ;
22382238 }
22392239 return ax . side === 'right' ? 'start' : 'end' ;
22402240 } ;
2241+ out . heightFn = function ( d , a , h ) {
2242+ a *= ax . side === 'left' ? 1 : - 1 ;
2243+ return a < - 30 ? - h :
2244+ a < 30 ? - 0.5 * h :
2245+ 0 ;
2246+ } ;
22412247 }
22422248
22432249 return out ;
@@ -2412,9 +2418,11 @@ axes.drawZeroLine = function(gd, ax, opts) {
24122418 * - {boolean} repositionOnUpdate (set to true to reposition update selection)
24132419 * - {boolean} secondary
24142420 * - {fn} transFn
2415- * - {fn} labelXFn
2416- * - {fn} labelYFn
2417- * - {fn} labelAnchorFn
2421+ * - {object} labelFns
2422+ * + {fn} xFn
2423+ * + {fn} yFn
2424+ * + {fn} anchorFn
2425+ * + {fn} heightFn
24182426 */
24192427axes . drawLabels = function ( gd , ax , opts ) {
24202428 opts = opts || { } ;
@@ -2423,9 +2431,7 @@ axes.drawLabels = function(gd, ax, opts) {
24232431 var axLetter = axId . charAt ( 0 ) ;
24242432 var cls = opts . cls || axId + 'tick' ;
24252433 var vals = opts . vals ;
2426- var labelXFn = opts . labelXFn ;
2427- var labelYFn = opts . labelYFn ;
2428- var labelAnchorFn = opts . labelAnchorFn ;
2434+ var labelFns = opts . labelFns ;
24292435 var tickAngle = opts . secondary ? 0 : ax . tickangle ;
24302436 var lastAngle = ( ax . _tickAngles || { } ) [ cls ] ;
24312437
@@ -2445,7 +2451,7 @@ axes.drawLabels = function(gd, ax, opts) {
24452451 var newPromise = gd . _promises . length ;
24462452
24472453 thisLabel
2448- . call ( svgTextUtils . positionText , labelXFn ( d ) , labelYFn ( d ) )
2454+ . call ( svgTextUtils . positionText , labelFns . xFn ( d ) , labelFns . yFn ( d ) )
24492455 . call ( Drawing . font , d . font , d . fontSize , d . fontColor )
24502456 . text ( d . text )
24512457 . call ( svgTextUtils . convertToTspans , gd ) ;
@@ -2469,47 +2475,26 @@ axes.drawLabels = function(gd, ax, opts) {
24692475 if ( opts . repositionOnUpdate ) {
24702476 tickLabels . each ( function ( d ) {
24712477 d3 . select ( this ) . select ( 'text' )
2472- . call ( svgTextUtils . positionText , labelXFn ( d ) , labelYFn ( d ) ) ;
2478+ . call ( svgTextUtils . positionText , labelFns . xFn ( d ) , labelFns . yFn ( d ) ) ;
24732479 } ) ;
24742480 }
24752481
2476- // How much to shift a multi-line label to center it vertically.
2477- function getAnchorHeight ( lineCount , lineHeight , angle ) {
2478- var h = ( lineCount - 1 ) * lineHeight ;
2479- if ( axLetter === 'x' ) {
2480- if ( angle < - 60 || 60 < angle ) {
2481- return - 0.5 * h ;
2482- } else if ( ax . side === 'top' ) {
2483- return - h ;
2484- }
2485- } else {
2486- angle *= ax . side === 'left' ? 1 : - 1 ;
2487- if ( angle < - 30 ) {
2488- return - h ;
2489- } else if ( angle < 30 ) {
2490- return - 0.5 * h ;
2491- }
2492- }
2493- return 0 ;
2494- }
2495-
24962482 function positionLabels ( s , angle ) {
24972483 s . each ( function ( d ) {
24982484 var thisLabel = d3 . select ( this ) ;
24992485 var mathjaxGroup = thisLabel . select ( '.text-math-group' ) ;
2500- var anchor = labelAnchorFn ( angle , d ) ;
2486+ var anchor = labelFns . anchorFn ( d , angle ) ;
25012487
25022488 var transform = opts . transFn . call ( thisLabel . node ( ) , d ) +
25032489 ( ( isNumeric ( angle ) && + angle !== 0 ) ?
2504- ( ' rotate(' + angle + ',' + labelXFn ( d ) + ',' +
2505- ( labelYFn ( d ) - d . fontSize / 2 ) + ')' ) :
2490+ ( ' rotate(' + angle + ',' + labelFns . xFn ( d ) + ',' +
2491+ ( labelFns . yFn ( d ) - d . fontSize / 2 ) + ')' ) :
25062492 '' ) ;
25072493
2508- var anchorHeight = getAnchorHeight (
2509- svgTextUtils . lineCount ( thisLabel ) ,
2510- LINE_SPACING * d . fontSize ,
2511- isNumeric ( angle ) ? + angle : 0
2512- ) ;
2494+ // how much to shift a multi-line label to center it vertically.
2495+ var nLines = svgTextUtils . lineCount ( thisLabel ) ;
2496+ var lineHeight = LINE_SPACING * d . fontSize ;
2497+ var anchorHeight = labelFns . heightFn ( d , isNumeric ( angle ) ? + angle : 0 , ( nLines - 1 ) * lineHeight ) ;
25132498
25142499 if ( anchorHeight ) {
25152500 transform += ' translate(0, ' + anchorHeight + ')' ;
0 commit comments