@@ -15,6 +15,7 @@ var map1dArray = require('./map_1d_array');
1515var makepath = require ( './makepath' ) ;
1616var orientText = require ( './orient_text' ) ;
1717var svgTextUtils = require ( '../../lib/svg_text_utils' ) ;
18+ var alignmentConstants = require ( '../../constants/alignment' ) ;
1819
1920module . exports = function plot ( gd , plotinfo , cdcarpet ) {
2021 for ( var i = 0 ; i < cdcarpet . length ; i ++ ) {
@@ -58,10 +59,10 @@ function plotOne(gd, plotinfo, cd) {
5859 drawGridLines ( xa , ya , boundaryLayer , aax , 'a-boundary' , aax . _boundarylines ) ;
5960 drawGridLines ( xa , ya , boundaryLayer , bax , 'b-boundary' , bax . _boundarylines ) ;
6061
61- var maxAExtent = drawAxisLabels ( gd , xa , ya , trace , t , labelLayer , aax . _labels , 'a-label' ) ;
62- var maxBExtent = drawAxisLabels ( gd , xa , ya , trace , t , labelLayer , bax . _labels , 'b-label' ) ;
62+ var labelOrientationA = drawAxisLabels ( gd , xa , ya , trace , t , labelLayer , aax . _labels , 'a-label' ) ;
63+ var labelOrientationB = drawAxisLabels ( gd , xa , ya , trace , t , labelLayer , bax . _labels , 'b-label' ) ;
6364
64- drawAxisTitles ( gd , labelLayer , trace , t , xa , ya , maxAExtent , maxBExtent ) ;
65+ drawAxisTitles ( gd , labelLayer , trace , t , xa , ya , labelOrientationA , labelOrientationB ) ;
6566
6667 drawClipPath ( trace , t , clipLayer , xa , ya ) ;
6768}
@@ -131,8 +132,9 @@ function drawAxisLabels(gd, xaxis, yaxis, trace, t, layer, labels, labelClass) {
131132 . classed ( labelClass , true ) ;
132133
133134 var maxExtent = 0 ;
135+ var labelOrientation ;
134136
135- labelJoin . each ( function ( label ) {
137+ labelJoin . each ( function ( label , i ) {
136138 // Most of the positioning is done in calc_labels. Only the parts that depend upon
137139 // the screen space representation of the x and y axes are here:
138140 var orientation ;
@@ -142,6 +144,11 @@ function drawAxisLabels(gd, xaxis, yaxis, trace, t, layer, labels, labelClass) {
142144 var angle = ( label . axis . tickangle + 180.0 ) * Math . PI / 180.0 ;
143145 orientation = orientText ( trace , xaxis , yaxis , label . xy , [ Math . cos ( angle ) , Math . sin ( angle ) ] ) ;
144146 }
147+
148+ if ( ! i ) {
149+ // TODO: offsetMultiplier? Not currently used anywhere...
150+ labelOrientation = { angle : orientation . angle , flip : orientation . flip } ;
151+ }
145152 var direction = ( label . endAnchor ? - 1 : 1 ) * orientation . flip ;
146153
147154 var labelEl = d3 . select ( this )
@@ -169,29 +176,34 @@ function drawAxisLabels(gd, xaxis, yaxis, trace, t, layer, labels, labelClass) {
169176
170177 labelJoin . exit ( ) . remove ( ) ;
171178
172- return maxExtent ;
179+ labelOrientation . maxExtent = maxExtent ;
180+ return labelOrientation ;
173181}
174182
175- function drawAxisTitles ( gd , layer , trace , t , xa , ya , maxAExtent , maxBExtent ) {
183+ function drawAxisTitles ( gd , layer , trace , t , xa , ya , labelOrientationA , labelOrientationB ) {
176184 var a , b , xy , dxy ;
177185
178186 a = 0.5 * ( trace . a [ 0 ] + trace . a [ trace . a . length - 1 ] ) ;
179187 b = trace . b [ 0 ] ;
180188 xy = trace . ab2xy ( a , b , true ) ;
181189 dxy = trace . dxyda_rough ( a , b ) ;
182- drawAxisTitle ( gd , layer , trace , t , xy , dxy , trace . aaxis , xa , ya , maxAExtent , 'a-title' ) ;
190+ drawAxisTitle ( gd , layer , trace , t , xy , dxy , trace . aaxis , xa , ya , labelOrientationA , 'a-title' ) ;
183191
184192 a = trace . a [ 0 ] ;
185193 b = 0.5 * ( trace . b [ 0 ] + trace . b [ trace . b . length - 1 ] ) ;
186194 xy = trace . ab2xy ( a , b , true ) ;
187195 dxy = trace . dxydb_rough ( a , b ) ;
188- drawAxisTitle ( gd , layer , trace , t , xy , dxy , trace . baxis , xa , ya , maxBExtent , 'b-title' ) ;
196+ drawAxisTitle ( gd , layer , trace , t , xy , dxy , trace . baxis , xa , ya , labelOrientationB , 'b-title' ) ;
189197}
190198
191- function drawAxisTitle ( gd , layer , trace , t , xy , dxy , axis , xa , ya , offset , labelClass ) {
199+ var lineSpacing = alignmentConstants . LINE_SPACING ;
200+ var midShift = ( ( 1 - alignmentConstants . MID_SHIFT ) / lineSpacing ) + 1 ;
201+
202+ function drawAxisTitle ( gd , layer , trace , t , xy , dxy , axis , xa , ya , labelOrientation , labelClass ) {
192203 var data = [ ] ;
193204 if ( axis . title ) data . push ( axis . title ) ;
194205 var titleJoin = layer . selectAll ( 'text.' + labelClass ) . data ( data ) ;
206+ var offset = labelOrientation . maxExtent ;
195207
196208 titleJoin . enter ( ) . append ( 'text' )
197209 . classed ( labelClass , true ) ;
@@ -205,14 +217,23 @@ function drawAxisTitle(gd, layer, trace, t, xy, dxy, axis, xa, ya, offset, label
205217 }
206218
207219 // In addition to the size of the labels, add on some extra padding:
208- offset += axis . titlefont . size + axis . titleoffset ;
220+ var titleSize = axis . titlefont . size ;
221+ offset += titleSize + axis . titleoffset ;
209222
223+ var labelNorm = labelOrientation . angle + ( labelOrientation . flip < 0 ? 180 : 0 ) ;
224+ var angleDiff = ( labelNorm - orientation . angle + 450 ) % 360 ;
225+ var reverseTitle = angleDiff > 90 && angleDiff < 270 ;
210226
211227 var el = d3 . select ( this ) ;
212228
213229 el . text ( axis . title || '' )
214- . call ( svgTextUtils . convertToTspans , gd )
215- . attr ( 'transform' ,
230+ . call ( svgTextUtils . convertToTspans , gd ) ;
231+
232+ if ( reverseTitle ) {
233+ offset = ( - svgTextUtils . lineCount ( el ) + midShift ) * lineSpacing * titleSize - offset ;
234+ }
235+
236+ el . attr ( 'transform' ,
216237 'translate(' + orientation . p [ 0 ] + ',' + orientation . p [ 1 ] + ') ' +
217238 'rotate(' + orientation . angle + ') ' +
218239 'translate(0,' + offset + ')'
0 commit comments