diff --git a/src/plots/cartesian/axes.js b/src/plots/cartesian/axes.js index 4e1556f119e..287fe2c5662 100644 --- a/src/plots/cartesian/axes.js +++ b/src/plots/cartesian/axes.js @@ -32,6 +32,7 @@ var MINUS_SIGN = constants.MINUS_SIGN; var BADNUM = constants.BADNUM; var MID_SHIFT = require('../../constants/alignment').MID_SHIFT; +var LINE_SPACING = require('../../constants/alignment').LINE_SPACING; var axes = module.exports = {}; @@ -2039,6 +2040,26 @@ axes.doTicks = function(gd, axid, skipTitle) { }); } + // How much to shift a multi-line label to center it vertically. + function getAnchorHeight(lineCount, lineHeight, angle) { + var h = (lineCount - 1) * lineHeight; + if(axLetter === 'x') { + if(angle < -60 || 60 < angle) { + return -0.5 * h; + } else if(axside === 'top') { + return -h; + } + } else { + angle *= axside === 'left' ? 1 : -1; + if(angle < -30) { + return -h; + } else if(angle < 30) { + return -0.5 * h; + } + } + return 0; + } + function positionLabels(s, angle) { s.each(function(d) { var anchor = labelanchor(angle, d); @@ -2049,6 +2070,13 @@ axes.doTicks = function(gd, axid, skipTitle) { (' rotate(' + angle + ',' + labelx(d) + ',' + (labely(d) - d.fontSize / 2) + ')') : ''); + var anchorHeight = getAnchorHeight( + svgTextUtils.lineCount(thisLabel), + LINE_SPACING * d.fontSize, + isNumeric(angle) ? +angle : 0); + if(anchorHeight) { + transform += ' translate(0, ' + anchorHeight + ')'; + } if(mathjaxGroup.empty()) { thisLabel.select('text').attr({ transform: transform, diff --git a/test/image/baselines/bar_multiline_labels.png b/test/image/baselines/bar_multiline_labels.png new file mode 100644 index 00000000000..7788b298bd8 Binary files /dev/null and b/test/image/baselines/bar_multiline_labels.png differ diff --git a/test/image/baselines/benchmarks.png b/test/image/baselines/benchmarks.png index c04e854f6f0..c2186f5ed1f 100644 Binary files a/test/image/baselines/benchmarks.png and b/test/image/baselines/benchmarks.png differ diff --git a/test/image/baselines/cliponaxis_false-dates-log.png b/test/image/baselines/cliponaxis_false-dates-log.png index 12979eb1763..37af1d51d69 100644 Binary files a/test/image/baselines/cliponaxis_false-dates-log.png and b/test/image/baselines/cliponaxis_false-dates-log.png differ diff --git a/test/image/baselines/gl2d_date_axes.png b/test/image/baselines/gl2d_date_axes.png index 35a016d6f19..072cbe9d151 100644 Binary files a/test/image/baselines/gl2d_date_axes.png and b/test/image/baselines/gl2d_date_axes.png differ diff --git a/test/image/baselines/world-cals.png b/test/image/baselines/world-cals.png index 200ed69241a..cb846f1df20 100644 Binary files a/test/image/baselines/world-cals.png and b/test/image/baselines/world-cals.png differ diff --git a/test/image/mocks/bar_multiline_labels.json b/test/image/mocks/bar_multiline_labels.json new file mode 100644 index 00000000000..aa9744a0236 --- /dev/null +++ b/test/image/mocks/bar_multiline_labels.json @@ -0,0 +1,161 @@ +{ + "data":[ + { + "type": "bar", + "x":["x 1","multiple
lines","one
two
three"], + "y":["y 1","multiple
lines","one
two
three"] + }, + { + "type": "bar", + "x":["x 2","multiple
lines","one
two
three"], + "y":["y 2","multiple
lines","one
two
three"], + "xaxis": "x2", + "yaxis": "y2" + }, + { + "type": "bar", + "x":["x 3","multiple
lines","one
two
three"], + "y":["y 3","multiple
lines","one
two
three"], + "xaxis": "x3", + "yaxis": "y3" + }, + { + "type": "bar", + "x":["x 4","multiple
lines","one
two
three"], + "y":["y 4","multiple
lines","one
two
three"], + "xaxis": "x4", + "yaxis": "y4" + }, + { + "type": "bar", + "orientation": "h", + "x":["x 5","multiple
lines","one
two
three"], + "y":["y 5","multiple
lines","one
two
three"], + "xaxis": "x5", + "yaxis": "y5" + }, + { + "type": "bar", + "orientation": "h", + "x":["x 6","multiple
lines","one
two
three"], + "y":["y 6","multiple
lines","one
two
three"], + "xaxis": "x6", + "yaxis": "y6" + }, + { + "type": "scatter", + "x":["x 7","multiple
lines","one
two
three"], + "y":["y 7","multiple
lines","one
two
three"], + "xaxis": "x7", + "yaxis": "y7" + }, + { + "type": "scatter", + "x":["x 8","multiple
lines","one
two
three"], + "y":["y 8","multiple
lines","one
two
three"], + "xaxis": "x8", + "yaxis": "y8" + } + ], + "layout":{ + "showlegend": false, + "xaxis": { + "ticks": "outside", + "domain": [0, 0.4] + }, + "yaxis": { + "ticks": "outside", + "domain": [0, 0.4] + }, + "xaxis2": { + "ticks": "outside", + "domain": [0, 0.4], + "side": "top", + "anchor": "y2", + "tickangle": 90 + }, + "yaxis2": { + "ticks": "outside", + "domain": [0, 0.4], + "side": "right", + "tickangle": 90 + }, + "xaxis3": { + "ticks": "outside", + "domain": [0.6, 1], + "tickangle": 90 + }, + "yaxis3": { + "ticks": "outside", + "domain": [0, 0.4], + "anchor": "x3", + "tickangle": 90 + }, + "xaxis4": { + "ticks": "outside", + "domain": [0.6, 1], + "side": "top" + }, + "yaxis4": { + "ticks": "outside", + "domain": [0, 0.4], + "side": "right", + "anchor": "x4" + }, + "xaxis5": { + "ticks": "outside", + "domain": [0, 0.4], + "anchor": "y5", + "tickangle": 45 + }, + "yaxis5": { + "ticks": "outside", + "domain": [0.6, 1], + "anchor": "x5", + "tickangle": 45 + }, + "xaxis6": { + "ticks": "outside", + "domain": [0, 0.4], + "side": "top", + "anchor": "y6", + "tickangle": -90 + }, + "yaxis6": { + "ticks": "outside", + "domain": [0.6, 1], + "anchor": "x6", + "side": "right", + "tickangle": -90 + }, + "xaxis7": { + "ticks": "outside", + "domain": [0.6, 1], + "anchor": "y7", + "tickangle": -90 + }, + "yaxis7": { + "ticks": "outside", + "domain": [0.6, 1], + "anchor": "x7", + "tickangle": -90 + }, + "xaxis8": { + "ticks": "outside", + "domain": [0.6, 1], + "side": "top", + "anchor": "y8", + "tickangle": -45 + }, + "yaxis8": { + "ticks": "outside", + "domain": [0.6, 1], + "side": "right", + "anchor": "x8", + "tickangle": 45 + }, + "legend": "none", + "height":800, + "width":800 + } +}