Skip to content

Commit 66a8154

Browse files
committed
Implement basic chart title alignment options [882]
- Not cleaned up. - Padding attributes missing. - `auto` values missing.
1 parent 4d21886 commit 66a8154

File tree

5 files changed

+374
-12
lines changed

5 files changed

+374
-12
lines changed

src/constants/alignment.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,17 @@ module.exports = {
4141
// multiple of fontSize to get the vertical offset between lines
4242
LINE_SPACING: 1.3,
4343

44-
// multiple of fontSize to shift from the baseline to the midline
44+
// multiple of fontSize to shift from the baseline
45+
// to the cap (captical letter) line
4546
// (to use when we don't calculate this shift from Drawing.bBox)
46-
// To be precise this should be half the cap height (capital letter)
47-
// of the font, and according to wikipedia:
47+
// This is an approximation since in reality cap height can differ
48+
// from font to font. However, according to Wikipedia
4849
// an "average" font might have a cap height of 70% of the em
4950
// https://en.wikipedia.org/wiki/Em_(typography)#History
51+
CAP_SHIFT: 0.70,
52+
53+
// half the cap height (distance between baseline and cap line)
54+
// of an "average" font (for more info see above).
5055
MID_SHIFT: 0.35,
5156

5257
OPPOSITE_SIDE: {

src/plot_api/subroutines.js

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,19 +449,61 @@ function findCounterAxisLineWidth(ax, side, counterAx, axList) {
449449

450450
exports.drawMainTitle = function(gd) {
451451
var fullLayout = gd._fullLayout;
452+
var textAnchorDict = {
453+
'left': 'start',
454+
'center': 'middle',
455+
'right': 'end',
456+
'auto': 'middle' // TODO That needs to be calculated based on x
457+
};
458+
var dyDict = {
459+
'top': alignmentConstants.CAP_SHIFT + 'em',
460+
'middle': alignmentConstants.MID_SHIFT + 'em',
461+
'bottom': '0em',
462+
};
452463

453464
Titles.draw(gd, 'gtitle', {
454465
propContainer: fullLayout,
455466
propName: 'title.text',
456467
placeholder: fullLayout._dfltTitle.plot,
457468
attributes: {
458-
x: fullLayout.width / 2,
459-
y: fullLayout._size.t / 2,
460-
'text-anchor': 'middle'
469+
x: getMainTitleX(fullLayout),
470+
y: getMainTitleY(fullLayout),
471+
'text-anchor': textAnchorDict[fullLayout.title.xanchor],
472+
dy: dyDict[fullLayout.title.yanchor]
461473
}
462474
});
463475
};
464476

477+
function getMainTitleX(fullLayout) {
478+
var title = fullLayout.title;
479+
var _size = fullLayout._size;
480+
481+
switch(title.xref) {
482+
case 'paper':
483+
return _size.l + _size.w * title.x;
484+
case 'container':
485+
default:
486+
return fullLayout.width * title.x;
487+
}
488+
}
489+
490+
function getMainTitleY(fullLayout) {
491+
var title = fullLayout.title;
492+
var _size = fullLayout._size;
493+
494+
if(title.y === 'auto') {
495+
return _size.t / 2;
496+
} else {
497+
switch(title.yref) {
498+
case 'paper':
499+
return _size.t + _size.h - _size.h * title.y;
500+
case 'container':
501+
default:
502+
return fullLayout.height - fullLayout.height * title.y;
503+
}
504+
}
505+
}
506+
465507
exports.doTraceStyle = function(gd) {
466508
var calcdata = gd.calcdata;
467509
var editStyleCalls = [];

src/plots/layout_attributes.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,70 @@ module.exports = {
3838
editType: 'layoutstyle',
3939
description: 'Sets the title font.'
4040
}),
41+
xref: {
42+
valType: 'enumerated',
43+
dflt: 'container',
44+
values: ['container', 'paper'],
45+
role: 'info',
46+
editType: 'layoutstyle',
47+
description: [
48+
'Some',
49+
'docu', // TODO document
50+
].join(' ')
51+
},
52+
yref: {
53+
valType: 'enumerated',
54+
dflt: 'container',
55+
values: ['container', 'paper'],
56+
role: 'info',
57+
editType: 'layoutstyle',
58+
description: [
59+
'Some',
60+
'docu', // TODO document
61+
].join(' ')
62+
},
63+
x: {
64+
valType: 'number',
65+
dflt: '0.5',
66+
role: 'style',
67+
editType: 'layoutstyle',
68+
description: [
69+
'Some',
70+
'docu', // TODO document
71+
].join(' ')
72+
},
73+
y: {
74+
valType: 'any',
75+
dflt: 'auto',
76+
role: 'style',
77+
editType: 'layoutstyle',
78+
description: [
79+
'Some',
80+
'docu',
81+
].join(' ')
82+
},
83+
xanchor: {
84+
valType: 'enumerated',
85+
dflt: 'auto',
86+
values: ['auto', 'left', 'center', 'right'],
87+
role: 'info',
88+
editType: 'layoutstyle',
89+
description: [
90+
'Some',
91+
'docu', // TODO document
92+
].join(' ')
93+
},
94+
yanchor: {
95+
valType: 'enumerated',
96+
dflt: 'auto',
97+
values: ['auto', 'top', 'middle', 'bottom'],
98+
role: 'info',
99+
editType: 'layoutstyle',
100+
description: [
101+
'Some',
102+
'docu', // TODO document
103+
].join(' ')
104+
},
41105
editType: 'layoutstyle'
42106
},
43107
autosize: {

src/plots/plots.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,13 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut, formatObj) {
13321332
color: globalFont.color
13331333
});
13341334

1335+
coerce('title.xref');
1336+
coerce('title.yref');
1337+
coerce('title.x'); // TODO restrict to [-2, 3]?
1338+
coerce('title.y'); // TODO restrict to [-2, 3]?
1339+
coerce('title.xanchor');
1340+
coerce('title.yanchor');
1341+
13351342
// Make sure that autosize is defaulted to *true*
13361343
// on layouts with no set width and height for backward compatibly,
13371344
// in particular https://plot.ly/javascript/responsive-fluid-layout/

0 commit comments

Comments
 (0)