Skip to content

Commit 36771a8

Browse files
committed
change default xanchor and yanchor behavior
1 parent 822fe0d commit 36771a8

File tree

3 files changed

+58
-24
lines changed

3 files changed

+58
-24
lines changed

src/components/shapes/attributes.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,19 @@ module.exports = templatedArray('shape', {
258258
'the default textangle is 0 (horizontal).'
259259
].join(' ')
260260
},
261-
xanchor: extendFlat({}, annAttrs.xanchor, {
261+
xanchor: {
262+
valType: 'enumerated',
263+
values: ['auto', 'left', 'center', 'right'],
264+
dflt: 'auto',
265+
editType: 'calc+arraydraw',
262266
description: 'Sets the text box\'s horizontal position anchor.',
263-
}),
264-
yanchor: extendFlat({}, annAttrs.yanchor, {
267+
},
268+
yanchor: {
269+
valType: 'enumerated',
270+
values: ['top', 'middle', 'bottom'],
271+
editType: 'calc+arraydraw',
265272
description: 'Sets the text box\'s vertical position anchor.',
266-
}),
273+
},
267274
padding: {
268275
valType: 'number',
269276
dflt: 3,

src/components/shapes/defaults.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut) {
1515
});
1616
};
1717

18+
function dfltLabelYanchor(shapeType, labelTextPosition) {
19+
var dfltYanchor;
20+
if(shapeType === 'line') {
21+
dfltYanchor = 'bottom';
22+
} else {
23+
if(labelTextPosition.indexOf('top') !== -1) {
24+
dfltYanchor = 'top';
25+
} else if(labelTextPosition.indexOf('bottom') !== -1) {
26+
dfltYanchor = 'bottom';
27+
} else {
28+
dfltYanchor = 'middle';
29+
}
30+
}
31+
return dfltYanchor;
32+
}
33+
1834
function handleShapeDefaults(shapeIn, shapeOut, fullLayout) {
1935
function coerce(attr, dflt) {
2036
return Lib.coerce(shapeIn, shapeOut, attributes, attr, dflt);
@@ -119,10 +135,14 @@ function handleShapeDefaults(shapeIn, shapeOut, fullLayout) {
119135

120136
// Label options
121137
coerce('label.text');
122-
coerce('label.xanchor');
123-
coerce('label.yanchor');
124138
coerce('label.textangle', shapeType === 'line' ? 'auto' : 0);
125-
coerce('label.textposition', shapeType === 'line' ? 'middle' : 'middle center');
139+
var labelTextPosition = coerce(
140+
'label.textposition',
141+
shapeType === 'line' ? 'middle' : 'middle center'
142+
);
143+
coerce('label.xanchor');
144+
// Default yanchor value depends on shape type and label textposition
145+
coerce('label.yanchor', dfltLabelYanchor(shapeType, labelTextPosition));
126146
coerce('label.padding');
127147
Lib.coerceFont(coerce, 'label.font', fullLayout.font);
128148
}

src/components/shapes/draw.js

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ function calcTextAngle(shapex0, shapey0, shapex1, shapey1) {
731731

732732
function calcTextPosition(shapex0, shapey0, shapex1, shapey1, shapeOptions, actualTextAngle, textBB) {
733733
var textPosition = shapeOptions.label.textposition;
734+
var textAngle = shapeOptions.label.textangle;
734735
var textPadding = shapeOptions.label.padding;
735736
var shapeType = shapeOptions.type;
736737
var textAngleRad = Math.PI / 180 * actualTextAngle;
@@ -745,24 +746,27 @@ function calcTextPosition(shapex0, shapey0, shapex1, shapey1, shapeOptions, actu
745746
if(textPosition.indexOf('start') !== -1) {
746747
textx = shapex0;
747748
texty = shapey0;
748-
if(xanchor === 'auto') xanchor = (shapex1 >= shapex0) ? 'right' : 'left';
749+
if(xanchor === 'auto') {
750+
if(textAngle === 'auto') xanchor = (shapex1 >= shapex0) ? 'left' : 'right';
751+
else xanchor = (shapex1 >= shapex0) ? 'right' : 'left';
752+
}
749753
} else if(textPosition.indexOf('end') !== -1) {
750754
textx = shapex1;
751755
texty = shapey1;
752-
if(xanchor === 'auto') xanchor = (shapex1 >= shapex0) ? 'left' : 'right';
756+
if(xanchor === 'auto') {
757+
if(textAngle === 'auto') xanchor = (shapex1 >= shapex0) ? 'right' : 'left';
758+
else xanchor = (shapex1 >= shapex0) ? 'left' : 'right';
759+
}
753760
} else { // Default: center
754761
textx = (shapex0 + shapex1) / 2;
755762
texty = (shapey0 + shapey1) / 2;
756763
if(xanchor === 'auto') xanchor = 'center';
757764
}
758765

759-
// Default yanchor is 'bottom' for lines (should handle in defaults.js)
760-
if(yanchor === 'auto') yanchor = 'bottom';
761-
762766
// Special case for padding when angle is 'auto' for lines
763767
// Padding should be treated as an orthogonal offset in this case
764768
// Otherwise, padding is just a simple x and y offset
765-
if(shapeOptions.label.textangle === 'auto') {
769+
if(textAngle === 'auto') {
766770
// Set direction to apply padding (based on `yanchor` only)
767771
var paddingDirection = { bottom: 1, middle: 0, top: -1 }[yanchor];
768772
paddingX = textPadding * Math.sin(textAngleRad) * paddingDirection;
@@ -782,27 +786,30 @@ function calcTextPosition(shapex0, shapey0, shapex1, shapey1, shapeOptions, actu
782786
// Horizontal needs a little extra padding to look balanced
783787
paddingX = textPadding + 3;
784788
if(textPosition.indexOf('right') !== -1) {
785-
textx = Math.max(shapex0, shapex1) + paddingX;
786-
if(xanchor === 'auto') xanchor = 'left';
787-
} else if(textPosition.indexOf('left') !== -1) {
788-
textx = Math.min(shapex0, shapex1) - paddingX;
789+
textx = Math.max(shapex0, shapex1) - paddingX;
789790
if(xanchor === 'auto') xanchor = 'right';
791+
} else if(textPosition.indexOf('left') !== -1) {
792+
textx = Math.min(shapex0, shapex1) + paddingX;
793+
if(xanchor === 'auto') xanchor = 'left';
790794
} else { // Default: center
791795
textx = (shapex0 + shapex1) / 2;
792796
if(xanchor === 'auto') xanchor = 'center';
793797
}
794798

795799
// calc vertical position
796-
paddingY = textPadding;
797800
if(textPosition.indexOf('top') !== -1) {
798-
texty = Math.min(shapey0, shapey1) - paddingY;
799-
if(yanchor === 'auto') yanchor = 'bottom';
801+
texty = Math.min(shapey0, shapey1);
800802
} else if(textPosition.indexOf('bottom') !== -1) {
801-
texty = Math.max(shapey0, shapey1) + paddingY;
802-
if(yanchor === 'auto') yanchor = 'top';
803-
} else { // Default: middle
803+
texty = Math.max(shapey0, shapey1);
804+
} else {
804805
texty = (shapey0 + shapey1) / 2;
805-
if(yanchor === 'auto') yanchor = 'middle';
806+
}
807+
// Apply padding
808+
paddingY = textPadding;
809+
if(yanchor === 'bottom') {
810+
texty = texty - paddingY;
811+
} else if(yanchor === 'top') {
812+
texty = texty + paddingY;
806813
}
807814
}
808815

0 commit comments

Comments
 (0)