@@ -34,6 +34,8 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
3434 var plotGroup = d3 . select ( this ) ;
3535 var cd0 = cd [ 0 ] ;
3636 var trace = cd0 . trace ;
37+ var xGap = trace . xgap || 0 ;
38+ var yGap = trace . ygap || 0 ;
3739
3840 var z = cd0 . z ;
3941 var x = cd0 . x ;
@@ -49,7 +51,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
4951 var xrev = false ;
5052 var yrev = false ;
5153
52- var left , right , temp , top , bottom , i , j ;
54+ var left , right , temp , top , bottom , i , j , k ;
5355
5456 // TODO: if there are multiple overlapping categorical heatmaps,
5557 // or if we allow category sorting, then the categories may not be
@@ -298,8 +300,6 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
298300 } else { // zsmooth = false -> filling potentially large bricks works fastest with fillRect
299301 // gaps do not need to be exact integers, but if they *are* we will get
300302 // cleaner edges by rounding at least one edge
301- var xGap = trace . xgap ;
302- var yGap = trace . ygap ;
303303 var xGapLeft = Math . floor ( xGap / 2 ) ;
304304 var yGapTop = Math . floor ( yGap / 2 ) ;
305305
@@ -432,8 +432,17 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
432432 var _t = Lib . texttemplateString ( texttemplate , obj , gd . _fullLayout . _d3locale , obj , trace . _meta || { } ) ;
433433 if ( ! _t ) continue ;
434434
435+ var lines = _t . split ( '<br>' ) ;
436+ var nL = lines . length ;
437+ var nC = 0 ;
438+ for ( k = 0 ; k < nL ; k ++ ) {
439+ nC = Math . max ( nC , lines [ k ] . length ) ;
440+ }
441+
435442 textData . push ( {
436- t : _t ,
443+ l : nL , // number of lines
444+ c : nC , // maximum number of chars in a line
445+ t : _t , // text
437446 x : _x ,
438447 y : _y ,
439448 z : zVal
@@ -444,10 +453,54 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
444453 var font = trace . textfont ;
445454 var fontFamily = font . family ;
446455 var fontSize = font . size ;
456+
457+ if ( ! fontSize || fontSize === 'auto' ) {
458+ var minW = Infinity ;
459+ var minH = Infinity ;
460+ var maxL = 0 ;
461+ var maxC = 0 ;
462+
463+ for ( k = 0 ; k < textData . length ; k ++ ) {
464+ var d = textData [ k ] ;
465+ maxL = Math . max ( maxL , d . l ) ;
466+ maxC = Math . max ( maxC , d . c ) ;
467+
468+ if ( k < textData . length - 1 ) {
469+ var nextD = textData [ k + 1 ] ;
470+ var dx = Math . abs ( nextD . x - d . x ) ;
471+ var dy = Math . abs ( nextD . y - d . y ) ;
472+
473+ if ( dx ) minW = Math . min ( minW , dx ) ;
474+ if ( dy ) minH = Math . min ( minH , dy ) ;
475+ }
476+ }
477+
478+ if (
479+ ! isFinite ( minW ) ||
480+ ! isFinite ( minH )
481+ ) {
482+ fontSize = 12 ;
483+ } else {
484+ minW -= xGap ;
485+ minH -= yGap ;
486+
487+ minW /= maxC ;
488+ minH /= maxL ;
489+
490+ minW /= LINE_SPACING / 2 ;
491+ minH /= LINE_SPACING ;
492+
493+ fontSize = Math . min (
494+ Math . floor ( minW ) ,
495+ Math . floor ( minH )
496+ ) ;
497+ }
498+ }
499+ if ( fontSize <= 0 || ! isFinite ( fontSize ) ) return ;
500+
447501 var xFn = function ( d ) { return d . x ; } ;
448502 var yFn = function ( d ) {
449- var nlines = d . t . split ( '<br>' ) . length ;
450- return d . y - fontSize * ( ( nlines * LINE_SPACING ) / 2 - 1 ) ;
503+ return d . y - fontSize * ( ( d . l * LINE_SPACING ) / 2 - 1 ) ;
451504 } ;
452505
453506 var labels = selectLabels ( plotGroup ) . data ( textData ) ;
@@ -462,7 +515,7 @@ module.exports = function(gd, plotinfo, cdheatmaps, heatmapLayer) {
462515 var thisLabel = d3 . select ( this ) ;
463516
464517 var fontColor = font . color ;
465- if ( ! fontColor ) {
518+ if ( ! fontColor || fontColor === 'auto' ) {
466519 fontColor = Color . contrast (
467520 'rgba(' +
468521 sclFunc ( d . z ) . join ( ) +
0 commit comments