@@ -4065,9 +4065,7 @@ function approxTitleDepth(ax) {
40654065 var fontSize = ax . title . font . size ;
40664066 var extraLines = ( ax . title . text . match ( svgTextUtils . BR_TAG_ALL ) || [ ] ) . length ;
40674067 if ( ax . title . hasOwnProperty ( 'standoff' ) ) {
4068- return extraLines ?
4069- fontSize * ( CAP_SHIFT + ( extraLines * LINE_SPACING ) ) :
4070- fontSize * CAP_SHIFT ;
4068+ return fontSize * ( CAP_SHIFT + ( extraLines * LINE_SPACING ) ) ;
40714069 } else {
40724070 return extraLines ?
40734071 fontSize * ( extraLines + 1 ) * LINE_SPACING :
@@ -4098,9 +4096,20 @@ function drawTitle(gd, ax) {
40984096 var axLetter = axId . charAt ( 0 ) ;
40994097 var fontSize = ax . title . font . size ;
41004098 var titleStandoff ;
4099+ var extraLines = ( ax . title . text . match ( svgTextUtils . BR_TAG_ALL ) || [ ] ) . length ;
41014100
41024101 if ( ax . title . hasOwnProperty ( 'standoff' ) ) {
4103- titleStandoff = ax . _depth + ax . title . standoff + approxTitleDepth ( ax ) ;
4102+ // With ax._depth the initial drawing baseline is at the outer axis border (where the
4103+ // ticklabels are drawn). Since the title text will be drawn above the baseline,
4104+ // bottom/right axes must be shifted by 1 text line to draw below ticklabels instead of on
4105+ // top of them, whereas for top/left axes, the first line would be drawn
4106+ // before the ticklabels, but we need an offset for the descender portion of the first line
4107+ // and all subsequent lines.
4108+ if ( ax . side === 'bottom' || ax . side === 'right' ) {
4109+ titleStandoff = ax . _depth + ax . title . standoff + fontSize * CAP_SHIFT ;
4110+ } else if ( ax . side === 'top' || ax . side === 'left' ) {
4111+ titleStandoff = ax . _depth + ax . title . standoff + fontSize * ( MID_SHIFT + ( extraLines * LINE_SPACING ) ) ;
4112+ }
41044113 } else {
41054114 var isInside = insideTicklabelposition ( ax ) ;
41064115
0 commit comments