@@ -1433,6 +1433,38 @@ plots.autoMargin = function(gd, id, o) {
1433
1433
}
1434
1434
} ;
1435
1435
1436
+ plots . calculateTextMeasurements = function ( text , font , angle , axisName ) {
1437
+ if ( typeof ( font ) !== "string" ) {
1438
+ font = font . size + "px " + font . family ;
1439
+ }
1440
+
1441
+ var tag = document . createElement ( "div" ) ;
1442
+ tag . style . position = "absolute" ;
1443
+ tag . style . left = "-999em" ;
1444
+ tag . style . whiteSpace = "nowrap" ;
1445
+ tag . style . font = font ;
1446
+ tag . innerHTML = text ;
1447
+
1448
+
1449
+ if ( angle == 'auto' && axisName == 'x' ) {
1450
+ angle = 90
1451
+ }
1452
+
1453
+ if ( ! isNaN ( + angle ) ) {
1454
+ tag . style . transform = 'rotate(' + angle + 'deg)' ;
1455
+ }
1456
+
1457
+ document . body . appendChild ( tag ) ;
1458
+ var rec = tag . getBoundingClientRect ( ) ;
1459
+
1460
+ var width = rec . width ;
1461
+ var height = rec . height ;
1462
+
1463
+ document . body . removeChild ( tag ) ;
1464
+
1465
+ return { width : width , height : height } ;
1466
+ }
1467
+
1436
1468
plots . doAutoMargin = function ( gd ) {
1437
1469
var fullLayout = gd . _fullLayout ;
1438
1470
if ( ! fullLayout . _size ) fullLayout . _size = { } ;
@@ -1441,13 +1473,84 @@ plots.doAutoMargin = function(gd) {
1441
1473
var gs = fullLayout . _size ,
1442
1474
oldmargins = JSON . stringify ( gs ) ;
1443
1475
1476
+ //Lets adjust the layout margin to account for the axis tick label positions to prevent overflow issues and overlapping of labels
1477
+ var adjustLeftMargin = [ ] , adjustRightMargin = [ ] , adjustTopMargin = [ ] , adjustBottomMargin = [ ] ;
1478
+ var layers = [ 'yaxis' , 'xaxis' , 'xaxis2' ] //these are the only layers I want to adjust the layout margin
1479
+ var axes = Plotly . Axes ;
1480
+ var measurementKeys = { 'left' : 'width' , 'right' : 'width' , 'top' : 'height' , 'bottom' : 'height' } ;
1481
+
1482
+ layers . forEach ( function ( layerName ) {
1483
+ var axisLayer = fullLayout [ layerName ] ;
1484
+ if ( axisLayer && axisLayer . _length ) {
1485
+ var axisRange = axes . calcTicks ( axisLayer ) ;
1486
+ var largestVal = { text :'' }
1487
+ var axisName = axisLayer . _id . charAt ( 0 ) ;
1488
+
1489
+ //find the largest label. this can be optimize.. but considering that the data is small; I'm not going to worry about it
1490
+ for ( var i = 0 ; i < axisRange . length ; i ++ ) {
1491
+ if ( axisRange [ i ] . text . length >= largestVal . text . length ) {
1492
+ largestVal = axisRange [ i ] ;
1493
+ }
1494
+ }
1495
+
1496
+ var measurement = plots . calculateTextMeasurements ( largestVal . text , axisLayer . tickfont , axisLayer . tickangle , axisName ) ;
1497
+ //separate for readablity
1498
+ var key = measurementKeys [ axisLayer . side || ( axisName == 'x' ? 'bottom' : 'left' ) ] ;
1499
+ var adjustedMargin = measurement [ key ] ;
1500
+ //Ideally we should calculate the title's deminsion base on its angle.. but I dont know where that info is stored.. so lets use the axis name to determine its angle
1501
+ var angle = ( axisName == 'y' ? 90 : 0 ) ;
1502
+ measurement = plots . calculateTextMeasurements ( axisLayer . title , axisLayer . titlefont , angle ) ;
1503
+ if ( axisName == 'y' ) {
1504
+ //Most likely the text will be rotated 90degees on the Y-axis.. in that case we care about the width of the text.
1505
+ //So the width of the title + the largest tick's width would give us the adjusted margin
1506
+ adjustedMargin += measurement . width ;
1507
+ } else {
1508
+ //rotated height of tick + height of title
1509
+ adjustedMargin += measurement . height ;
1510
+ }
1511
+
1512
+ switch ( axisLayer . side ) {
1513
+ case 'left' :
1514
+ adjustLeftMargin . push ( adjustedMargin ) ;
1515
+ break ;
1516
+ case 'right' :
1517
+ adjustRightMargin . push ( adjustedMargin ) ;
1518
+ break ;
1519
+ case 'top' :
1520
+ adjustTopMargin . push ( adjustedMargin ) ;
1521
+ break ;
1522
+ case 'bottom' :
1523
+ adjustBottomMargin . push ( adjustedMargin ) ;
1524
+ break ;
1525
+ }
1526
+ }
1527
+ } ) ;
1528
+
1529
+ if ( ! adjustLeftMargin . length ) {
1530
+ adjustLeftMargin . push ( fullLayout . margin . l || 0 ) ;
1531
+ }
1532
+ if ( ! adjustRightMargin . length ) {
1533
+ adjustRightMargin . push ( fullLayout . margin . r || 0 ) ;
1534
+ }
1535
+ if ( ! adjustTopMargin . length ) {
1536
+ adjustTopMargin . push ( fullLayout . margin . t || 0 ) ;
1537
+ }
1538
+ if ( ! adjustBottomMargin . length ) {
1539
+ adjustBottomMargin . push ( fullLayout . margin . b || 0 ) ;
1540
+ }
1541
+
1542
+ adjustLeftMargin . push ( 0 ) ;
1543
+ adjustRightMargin . push ( 0 ) ;
1544
+ adjustTopMargin . push ( 0 ) ;
1545
+ adjustBottomMargin . push ( 0 ) ;
1546
+
1444
1547
// adjust margins for outside components
1445
1548
// fullLayout.margin is the requested margin,
1446
1549
// fullLayout._size has margins and plotsize after adjustment
1447
- var ml = Math . max ( fullLayout . margin . l || 0 , 0 ) ,
1448
- mr = Math . max ( fullLayout . margin . r || 0 , 0 ) ,
1449
- mt = Math . max ( fullLayout . margin . t || 0 , 0 ) ,
1450
- mb = Math . max ( fullLayout . margin . b || 0 , 0 ) ,
1550
+ var ml = Math . max . apply ( null , adjustLeftMargin ) ,
1551
+ mr = Math . max . apply ( null , adjustRightMargin ) ,
1552
+ mt = Math . max . apply ( null , adjustTopMargin ) ,
1553
+ mb = Math . max . apply ( null , adjustBottomMargin ) ,
1451
1554
pm = fullLayout . _pushmargin ;
1452
1555
1453
1556
if ( fullLayout . margin . autoexpand !== false ) {
0 commit comments