Skip to content

Commit

Permalink
Merge pull request #3276 from plotly/882-chart-title-alignment
Browse files Browse the repository at this point in the history
882 - Chart Title Alignment
  • Loading branch information
rmoestl committed Nov 29, 2018
2 parents e930009 + 2b26746 commit db66ff1
Show file tree
Hide file tree
Showing 57 changed files with 2,121 additions and 344 deletions.
65 changes: 50 additions & 15 deletions src/components/colorbar/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,21 +175,56 @@ module.exports = overrideAll({
exponentformat: axesAttrs.exponentformat,
showexponent: axesAttrs.showexponent,
title: {
valType: 'string',
role: 'info',
description: 'Sets the title of the color bar.'
text: {
valType: 'string',
role: 'info',
description: [
'Sets the title of the color bar.',
'Note that before the existence of `title.text`, the title\'s',
'contents used to be defined as the `title` attribute itself.',
'This behavior has been deprecated.'
].join(' ')
},
font: fontAttrs({
description: [
'Sets this color bar\'s title font.',
'Note that the title\'s font used to be set',
'by the now deprecated `titlefont` attribute.'
].join(' ')
}),
side: {
valType: 'enumerated',
values: ['right', 'top', 'bottom'],
role: 'style',
dflt: 'top',
description: [
'Determines the location of color bar\'s title',
'with respect to the color bar.',
'Note that the title\'s location used to be set',
'by the now deprecated `titleside` attribute.'
].join(' ')
}
},
titlefont: fontAttrs({
description: 'Sets this color bar\'s title font.'
}),
titleside: {
valType: 'enumerated',
values: ['right', 'top', 'bottom'],
role: 'style',
dflt: 'top',
description: [
'Determines the location of the colorbar title',
'with respect to the color bar.'
].join(' ')

_deprecated: {
title: {
valType: 'string',
role: 'info',
description: [
'Deprecated in favor of color bar\'s `title.text`.',
'Note that value of color bar\'s `title` is no longer a simple',
'*string* but a set of sub-attributes.'
].join(' ')
},
titlefont: fontAttrs({
description: 'Deprecated in favor of color bar\'s `title.font`.'
}),
titleside: {
valType: 'enumerated',
values: ['right', 'top', 'bottom'],
role: 'style',
dflt: 'top',
description: 'Deprecated in favor of color bar\'s `title.side`.'
}
}
}, 'colorbars', 'from-root');
6 changes: 3 additions & 3 deletions src/components/colorbar/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ module.exports = function colorbarDefaults(containerIn, containerOut, layout) {
handleTickLabelDefaults(colorbarIn, colorbarOut, coerce, 'linear', opts);
handleTickMarkDefaults(colorbarIn, colorbarOut, coerce, 'linear', opts);

coerce('title', layout._dfltTitle.colorbar);
Lib.coerceFont(coerce, 'titlefont', layout.font);
coerce('titleside');
coerce('title.text', layout._dfltTitle.colorbar);
Lib.coerceFont(coerce, 'title.font', layout.font);
coerce('title.side');
};
29 changes: 14 additions & 15 deletions src/components/colorbar/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ module.exports = function draw(gd, id) {
showticksuffix: opts.showticksuffix,
ticksuffix: opts.ticksuffix,
title: opts.title,
titlefont: opts.titlefont,
showline: true,
anchor: 'free',
side: 'right',
Expand Down Expand Up @@ -219,11 +218,11 @@ module.exports = function draw(gd, id) {
// save for other callers to access this axis
component.axis = cbAxisOut;

if(['top', 'bottom'].indexOf(opts.titleside) !== -1) {
cbAxisOut.titleside = opts.titleside;
if(['top', 'bottom'].indexOf(opts.title.side) !== -1) {
cbAxisOut.title.side = opts.title.side;
cbAxisOut.titlex = opts.x + xpadFrac;
cbAxisOut.titley = yBottomFrac +
(opts.titleside === 'top' ? lenFrac - ypadFrac : ypadFrac);
(opts.title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
}

if(opts.line.color && opts.tickmode === 'auto') {
Expand Down Expand Up @@ -286,15 +285,15 @@ module.exports = function draw(gd, id) {
var axisLayer = container.select('.cbaxis');

var titleHeight = 0;
if(['top', 'bottom'].indexOf(opts.titleside) !== -1) {
if(['top', 'bottom'].indexOf(opts.title.side) !== -1) {
// draw the title so we know how much room it needs
// when we squish the axis. This one only applies to
// top or bottom titles, not right side.
var x = gs.l + (opts.x + xpadFrac) * gs.w,
fontSize = cbAxisOut.titlefont.size,
fontSize = cbAxisOut.title.font.size,
y;

if(opts.titleside === 'top') {
if(opts.title.side === 'top') {
y = (1 - (yBottomFrac + lenFrac - ypadFrac)) * gs.h +
gs.t + 3 + fontSize * 0.75;
}
Expand All @@ -308,7 +307,7 @@ module.exports = function draw(gd, id) {
}

function drawAxis() {
if(['top', 'bottom'].indexOf(opts.titleside) !== -1) {
if(['top', 'bottom'].indexOf(opts.title.side) !== -1) {
// squish the axis top to make room for the title
var titleGroup = container.select('.cbtitle'),
titleText = titleGroup.select('text'),
Expand Down Expand Up @@ -339,7 +338,7 @@ module.exports = function draw(gd, id) {
// TODO: configurable
titleHeight += 5;

if(opts.titleside === 'top') {
if(opts.title.side === 'top') {
cbAxisOut.domain[1] -= titleHeight / gs.h;
titleTrans[1] *= -1;
}
Expand Down Expand Up @@ -460,8 +459,8 @@ module.exports = function draw(gd, id) {
});
},
function() {
if(['top', 'bottom'].indexOf(opts.titleside) === -1) {
var fontSize = cbAxisOut.titlefont.size,
if(['top', 'bottom'].indexOf(opts.title.side) === -1) {
var fontSize = cbAxisOut.title.font.size,
y = cbAxisOut._offset + cbAxisOut._length / 2,
x = gs.l + (cbAxisOut.position || 0) * gs.w + ((cbAxisOut.side === 'right') ?
10 + fontSize * ((cbAxisOut.showticklabels ? 1 : 0.5)) :
Expand All @@ -473,7 +472,7 @@ module.exports = function draw(gd, id) {
drawTitle('h' + cbAxisOut._id + 'title', {
avoid: {
selection: d3.select(gd).selectAll('g.' + cbAxisOut._id + 'tick'),
side: opts.titleside,
side: opts.title.side,
offsetLeft: gs.l,
offsetTop: 0,
maxShift: fullLayout.width
Expand Down Expand Up @@ -526,11 +525,11 @@ module.exports = function draw(gd, id) {
.node(),
titleWidth;
if(mathJaxNode &&
['top', 'bottom'].indexOf(opts.titleside) !== -1) {
['top', 'bottom'].indexOf(opts.title.side) !== -1) {
titleWidth = Drawing.bBox(mathJaxNode).width;
}
else {
// note: the formula below works for all titlesides,
// note: the formula below works for all title sides,
// (except for top/bottom mathjax, above)
// but the weird gs.l is because the titleunshift
// transform gets removed by Drawing.bBox
Expand Down Expand Up @@ -559,7 +558,7 @@ module.exports = function draw(gd, id) {
container.selectAll('.cboutline').attr({
x: xLeft,
y: yTopPx + opts.ypad +
(opts.titleside === 'top' ? titleHeight : 0),
(opts.title.side === 'top' ? titleHeight : 0),
width: Math.max(thickPx, 2),
height: Math.max(outerheight - 2 * opts.ypad - titleHeight, 2)
})
Expand Down
21 changes: 10 additions & 11 deletions src/components/legend/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ var FROM_BR = alignmentConstants.FROM_BR;
var getLegendData = require('./get_legend_data');
var style = require('./style');
var helpers = require('./helpers');
var anchorUtils = require('./anchor_utils');

var DBLCLICKDELAY = interactConstants.DBLCLICKDELAY;

Expand Down Expand Up @@ -154,17 +153,17 @@ module.exports = function draw(gd) {
lx = gs.l + gs.w * opts.x,
ly = gs.t + gs.h * (1 - opts.y);

if(anchorUtils.isRightAnchor(opts)) {
if(Lib.isRightAnchor(opts)) {
lx -= opts._width;
}
else if(anchorUtils.isCenterAnchor(opts)) {
else if(Lib.isCenterAnchor(opts)) {
lx -= opts._width / 2;
}

if(anchorUtils.isBottomAnchor(opts)) {
if(Lib.isBottomAnchor(opts)) {
ly -= opts._height;
}
else if(anchorUtils.isMiddleAnchor(opts)) {
else if(Lib.isMiddleAnchor(opts)) {
ly -= opts._height / 2;
}

Expand Down Expand Up @@ -700,18 +699,18 @@ function expandMargin(gd) {
opts = fullLayout.legend;

var xanchor = 'left';
if(anchorUtils.isRightAnchor(opts)) {
if(Lib.isRightAnchor(opts)) {
xanchor = 'right';
}
else if(anchorUtils.isCenterAnchor(opts)) {
else if(Lib.isCenterAnchor(opts)) {
xanchor = 'center';
}

var yanchor = 'top';
if(anchorUtils.isBottomAnchor(opts)) {
if(Lib.isBottomAnchor(opts)) {
yanchor = 'bottom';
}
else if(anchorUtils.isMiddleAnchor(opts)) {
else if(Lib.isMiddleAnchor(opts)) {
yanchor = 'middle';
}

Expand All @@ -731,10 +730,10 @@ function expandHorizontalMargin(gd) {
opts = fullLayout.legend;

var xanchor = 'left';
if(anchorUtils.isRightAnchor(opts)) {
if(Lib.isRightAnchor(opts)) {
xanchor = 'right';
}
else if(anchorUtils.isCenterAnchor(opts)) {
else if(Lib.isCenterAnchor(opts)) {
xanchor = 'center';
}

Expand Down
9 changes: 4 additions & 5 deletions src/components/rangeselector/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ var Drawing = require('../drawing');
var Lib = require('../../lib');
var svgTextUtils = require('../../lib/svg_text_utils');
var axisIds = require('../../plots/cartesian/axis_ids');
var anchorUtils = require('../legend/anchor_utils');

var alignmentConstants = require('../../constants/alignment');
var LINE_SPACING = alignmentConstants.LINE_SPACING;
Expand Down Expand Up @@ -218,21 +217,21 @@ function reposition(gd, buttons, opts, axName, selector) {
var ly = graphSize.t + graphSize.h * (1 - opts.y);

var xanchor = 'left';
if(anchorUtils.isRightAnchor(opts)) {
if(Lib.isRightAnchor(opts)) {
lx -= width;
xanchor = 'right';
}
if(anchorUtils.isCenterAnchor(opts)) {
if(Lib.isCenterAnchor(opts)) {
lx -= width / 2;
xanchor = 'center';
}

var yanchor = 'top';
if(anchorUtils.isBottomAnchor(opts)) {
if(Lib.isBottomAnchor(opts)) {
ly -= height;
yanchor = 'bottom';
}
if(anchorUtils.isMiddleAnchor(opts)) {
if(Lib.isMiddleAnchor(opts)) {
ly -= height / 2;
yanchor = 'middle';
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/rangeslider/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ module.exports = function(gd) {
placeholder: fullLayout._dfltTitle.x,
attributes: {
x: axisOpts._offset + axisOpts._length / 2,
y: y + opts._height + opts._offsetShift + 10 + 1.5 * axisOpts.titlefont.size,
y: y + opts._height + opts._offsetShift + 10 + 1.5 * axisOpts.title.font.size,
'text-anchor': 'middle'
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/components/sliders/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ module.exports = overrideAll(templatedArray('slider', {
role: 'style',
description: 'Sets the x position (in normalized coordinates) of the slider.'
},
pad: extendDeepAll({}, padAttrs, {
pad: extendDeepAll(padAttrs({editType: 'arraydraw'}), {
description: 'Set the padding of the slider component along each side.'
}, {t: {dflt: 20}}),
xanchor: {
Expand Down
9 changes: 4 additions & 5 deletions src/components/sliders/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ var Color = require('../color');
var Drawing = require('../drawing');
var Lib = require('../../lib');
var svgTextUtils = require('../../lib/svg_text_utils');
var anchorUtils = require('../legend/anchor_utils');
var arrayEditor = require('../../plot_api/plot_template').arrayEditor;

var constants = require('./constants');
Expand Down Expand Up @@ -207,21 +206,21 @@ function findDimensions(gd, sliderOpts) {
dims.height = dims.currentValueTotalHeight + constants.tickOffset + sliderOpts.ticklen + constants.labelOffset + dims.labelHeight + sliderOpts.pad.t + sliderOpts.pad.b;

var xanchor = 'left';
if(anchorUtils.isRightAnchor(sliderOpts)) {
if(Lib.isRightAnchor(sliderOpts)) {
dims.lx -= dims.outerLength;
xanchor = 'right';
}
if(anchorUtils.isCenterAnchor(sliderOpts)) {
if(Lib.isCenterAnchor(sliderOpts)) {
dims.lx -= dims.outerLength / 2;
xanchor = 'center';
}

var yanchor = 'top';
if(anchorUtils.isBottomAnchor(sliderOpts)) {
if(Lib.isBottomAnchor(sliderOpts)) {
dims.ly -= dims.height;
yanchor = 'bottom';
}
if(anchorUtils.isMiddleAnchor(sliderOpts)) {
if(Lib.isMiddleAnchor(sliderOpts)) {
dims.ly -= dims.height / 2;
yanchor = 'middle';
}
Expand Down
16 changes: 9 additions & 7 deletions src/components/titles/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,21 @@ function draw(gd, titleClass, options) {
var group = options.containerGroup;

var fullLayout = gd._fullLayout;
var titlefont = cont.titlefont || {};
var font = titlefont.family;
var fontSize = titlefont.size;
var fontColor = titlefont.color;

var opacity = 1;
var isplaceholder = false;
var txt = (cont.title || '').trim();
var title = cont.title;
var txt = (title && title.text ? title.text : '').trim();

var font = title && title.font ? title.font : {};
var fontFamily = font.family;
var fontSize = font.size;
var fontColor = font.color;

// only make this title editable if we positively identify its property
// as one that has editing enabled.
var editAttr;
if(prop === 'title') editAttr = 'titleText';
if(prop === 'title.text') editAttr = 'titleText';
else if(prop.indexOf('axis') !== -1) editAttr = 'axisTitleText';
else if(prop.indexOf('colorbar' !== -1)) editAttr = 'colorbarTitleText';
var editable = gd._context.edits[editAttr];
Expand Down Expand Up @@ -137,7 +139,7 @@ function draw(gd, titleClass, options) {
titleEl.attr('transform', transformVal);

titleEl.style({
'font-family': font,
'font-family': fontFamily,
'font-size': d3.round(fontSize, 2) + 'px',
fill: Color.rgb(fontColor),
opacity: opacity * Color.opacity(fontColor),
Expand Down
2 changes: 1 addition & 1 deletion src/components/updatemenus/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ module.exports = overrideAll(templatedArray('updatemenu', {
].join(' ')
},

pad: extendFlat({}, padAttrs, {
pad: extendFlat(padAttrs({editType: 'arraydraw'}), {
description: 'Sets the padding around the buttons or dropdown menu.'
}),

Expand Down
Loading

0 comments on commit db66ff1

Please sign in to comment.