diff --git a/src/lib/index.js b/src/lib/index.js
index f7f9434597f..6039e420d2b 100644
--- a/src/lib/index.js
+++ b/src/lib/index.js
@@ -1184,6 +1184,13 @@ lib.isHidden = function(gd) {
/** Return transform text for bar bar-like rectangles and pie-like slices
* @param {object} transform
+ * - targetX: desired position on the x-axis
+ * - targetY: desired position on the y-axis
+ * - textX: width of text
+ * - textY: height of text
+ * - scale: (optional) scale applied after translate
+ * - rotate: (optional) rotation applied after scale
+ * - noCenter: when defined no extra arguments needed in rotation
*/
lib.getTextTransform = function(transform) {
var noCenter = transform.noCenter;
diff --git a/src/traces/pie/plot.js b/src/traces/pie/plot.js
index ca4490608b6..f1b06621126 100644
--- a/src/traces/pie/plot.js
+++ b/src/traces/pie/plot.js
@@ -568,25 +568,7 @@ function transformInsideText(textBB, pt, cd0) {
var isCircle = (ring === 1) && (Math.abs(pt.startangle - pt.stopangle) === Math.PI * 2);
var allTransforms = [];
- if(isCircle || isAuto || isHorizontal) {
- // max size text can be inserted inside without rotating it
- // this inscribes the text rectangle in a circle, which is then inscribed
- // in the slice, so it will be an underestimate, which some day we may want
- // to improve so this case can get more use
- var transform = {
- scale: rInscribed * r * 2 / textDiameter,
-
- // and the center position and rotation in this case
- rCenter: 1 - rInscribed,
- rotate: 0
- };
-
- if(transform.scale >= 1) return transform;
-
- allTransforms.push(transform);
- }
-
- if(isHorizontal) {
+ if(!isAuto) {
// max size if text is placed (horizontally) at the top or bottom of the arc
var considerCrossing = function(angle, key) {
@@ -608,12 +590,40 @@ function transformInsideText(textBB, pt, cd0) {
}
};
- for(var i = 3; i >= -3; i--) { // to cover all cases with trace.rotation added
- considerCrossing(Math.PI * i, 'tan');
- considerCrossing(Math.PI * (i + 0.5), 'rad');
+ // to cover all cases with trace.rotation added
+ var i;
+ if(isHorizontal || isTangential) {
+ // top
+ for(i = 4; i >= -4; i -= 2) considerCrossing(Math.PI * i, 'tan');
+ // bottom
+ for(i = 4; i >= -4; i -= 2) considerCrossing(Math.PI * (i + 1), 'tan');
+ }
+ if(isHorizontal || isRadial) {
+ // left
+ for(i = 4; i >= -4; i -= 2) considerCrossing(Math.PI * (i + 1.5), 'rad');
+ // right
+ for(i = 4; i >= -4; i -= 2) considerCrossing(Math.PI * (i + 0.5), 'rad');
}
}
+ if(isCircle || isAuto || isHorizontal) {
+ // max size text can be inserted inside without rotating it
+ // this inscribes the text rectangle in a circle, which is then inscribed
+ // in the slice, so it will be an underestimate, which some day we may want
+ // to improve so this case can get more use
+ var transform = {
+ scale: rInscribed * r * 2 / textDiameter,
+
+ // and the center position and rotation in this case
+ rCenter: 1 - rInscribed,
+ rotate: 0
+ };
+
+ if(transform.scale >= 1) return transform;
+
+ allTransforms.push(transform);
+ }
+
if(isAuto || isRadial) {
allTransforms.push(calcRadTransform(textBB, r, ring, halfAngle, midAngle));
}
@@ -622,16 +632,29 @@ function transformInsideText(textBB, pt, cd0) {
allTransforms.push(calcTanTransform(textBB, r, ring, halfAngle, midAngle));
}
- var maxScaleTransform = allTransforms.sort(function(a, b) {
- return b.scale - a.scale;
- })[0];
+ var id = 0;
+ var maxScale = 0;
+ for(var k = 0; k < allTransforms.length; k++) {
+ var s = allTransforms[k].scale;
+ if(maxScale < s) {
+ maxScale = s;
+ id = k;
+ }
+
+ if(!isAuto && maxScale >= 1) {
+ // respect test order for non-auto options
+ break;
+ }
+ }
+
+ var selTransform = allTransforms[id];
- if(maxScaleTransform.pxtxt) {
+ if(selTransform.pxtxt) {
// copy text position if not at the middle
- pt.pxtxt = maxScaleTransform.pxtxt;
+ pt.pxtxt = selTransform.pxtxt;
}
- return maxScaleTransform;
+ return selTransform;
}
function isCrossing(pt, angle) {
diff --git a/test/image/baselines/sunburst_inside-text-orientation.png b/test/image/baselines/sunburst_inside-text-orientation.png
index fbdc988d3f7..a77ba3102ea 100644
Binary files a/test/image/baselines/sunburst_inside-text-orientation.png and b/test/image/baselines/sunburst_inside-text-orientation.png differ
diff --git a/test/image/baselines/sunburst_inside-text-orientation_clock.png b/test/image/baselines/sunburst_inside-text-orientation_clock.png
new file mode 100644
index 00000000000..28ab975ef98
Binary files /dev/null and b/test/image/baselines/sunburst_inside-text-orientation_clock.png differ
diff --git a/test/image/baselines/sunburst_with-without_values.png b/test/image/baselines/sunburst_with-without_values.png
index 80263d41d03..a00afc950f4 100644
Binary files a/test/image/baselines/sunburst_with-without_values.png and b/test/image/baselines/sunburst_with-without_values.png differ
diff --git a/test/image/baselines/uniformtext_pie_8_horizontal.png b/test/image/baselines/uniformtext_pie_8_horizontal.png
index f043dd63df2..8847a079d5f 100644
Binary files a/test/image/baselines/uniformtext_pie_8_horizontal.png and b/test/image/baselines/uniformtext_pie_8_horizontal.png differ
diff --git a/test/image/baselines/uniformtext_pie_8_radial.png b/test/image/baselines/uniformtext_pie_8_radial.png
new file mode 100644
index 00000000000..67ab4369d93
Binary files /dev/null and b/test/image/baselines/uniformtext_pie_8_radial.png differ
diff --git a/test/image/baselines/uniformtext_pie_8_tangential.png b/test/image/baselines/uniformtext_pie_8_tangential.png
new file mode 100644
index 00000000000..d8b2075be3b
Binary files /dev/null and b/test/image/baselines/uniformtext_pie_8_tangential.png differ
diff --git a/test/image/baselines/uniformtext_sunburst_treemap.png b/test/image/baselines/uniformtext_sunburst_treemap.png
index 48a5679d48e..eb00334ba3e 100644
Binary files a/test/image/baselines/uniformtext_sunburst_treemap.png and b/test/image/baselines/uniformtext_sunburst_treemap.png differ
diff --git a/test/image/mocks/sunburst_inside-text-orientation_clock.json b/test/image/mocks/sunburst_inside-text-orientation_clock.json
new file mode 100644
index 00000000000..59bd9976ae0
--- /dev/null
+++ b/test/image/mocks/sunburst_inside-text-orientation_clock.json
@@ -0,0 +1,402 @@
+{
+ "data": [
+ {
+ "name": "horizontal",
+ "insidetextorientation": "horizontal",
+ "type": "sunburst",
+ "parents": [
+ "",
+ "A",
+ "A",
+ "C",
+ "C",
+ "C",
+ "F",
+ "F",
+ "F",
+ "F",
+ "J",
+ "J",
+ "J",
+ "J",
+ "J",
+ "O",
+ "O",
+ "O",
+ "O",
+ "O",
+ "O",
+ "U",
+ "U",
+ "U",
+ "U",
+ "U",
+ "U"
+ ],
+ "labels": [
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z"
+ ],
+ "textinfo": "label+value",
+ "domain": {
+ "x": [
+ 0.5,
+ 1
+ ],
+ "y": [
+ 0.5,
+ 1
+ ]
+ }
+ },
+ {
+ "name": "radial",
+ "insidetextorientation": "radial",
+ "type": "sunburst",
+ "parents": [
+ "",
+ "A",
+ "A",
+ "C",
+ "C",
+ "C",
+ "F",
+ "F",
+ "F",
+ "F",
+ "J",
+ "J",
+ "J",
+ "J",
+ "J",
+ "O",
+ "O",
+ "O",
+ "O",
+ "O",
+ "O",
+ "U",
+ "U",
+ "U",
+ "U",
+ "U",
+ "U"
+ ],
+ "labels": [
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z"
+ ],
+ "textinfo": "label+value",
+ "domain": {
+ "x": [
+ 0.5,
+ 1
+ ],
+ "y": [
+ 0,
+ 0.5
+ ]
+ }
+ },
+ {
+ "name": "tangential",
+ "insidetextorientation": "tangential",
+ "type": "sunburst",
+ "parents": [
+ "",
+ "A",
+ "A",
+ "C",
+ "C",
+ "C",
+ "F",
+ "F",
+ "F",
+ "F",
+ "J",
+ "J",
+ "J",
+ "J",
+ "J",
+ "O",
+ "O",
+ "O",
+ "O",
+ "O",
+ "O",
+ "U",
+ "U",
+ "U",
+ "U",
+ "U",
+ "U"
+ ],
+ "labels": [
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z"
+ ],
+ "textinfo": "label+value",
+ "domain": {
+ "x": [
+ 0,
+ 0.5
+ ],
+ "y": [
+ 0,
+ 0.5
+ ]
+ }
+ },
+ {
+ "name": "auto",
+ "insidetextorientation": "auto",
+ "type": "sunburst",
+ "parents": [
+ "",
+ "A",
+ "A",
+ "C",
+ "C",
+ "C",
+ "F",
+ "F",
+ "F",
+ "F",
+ "J",
+ "J",
+ "J",
+ "J",
+ "J",
+ "O",
+ "O",
+ "O",
+ "O",
+ "O",
+ "O",
+ "U",
+ "U",
+ "U",
+ "U",
+ "U",
+ "U"
+ ],
+ "labels": [
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z"
+ ],
+ "textinfo": "label+value",
+ "domain": {
+ "x": [
+ 0,
+ 0.5
+ ],
+ "y": [
+ 0.5,
+ 1
+ ]
+ }
+ }
+ ],
+ "layout": {
+ "width": 800,
+ "height": 800,
+ "margin": {
+ "t": 10,
+ "b": 10,
+ "l": 10,
+ "r": 10
+ },
+ "legend": {
+ "title": {
+ "text": "inside text orientation"
+ }
+ },
+ "font": {
+ "size": 14
+ },
+ "shapes": [
+ {
+ "type": "rect",
+ "layer": "below",
+ "x0": 0,
+ "x1": 0.5,
+ "y0": 0,
+ "y1": 0.5
+ },
+ {
+ "type": "rect",
+ "layer": "below",
+ "x0": 0.5,
+ "x1": 1,
+ "y0": 0,
+ "y1": 0.5
+ },
+ {
+ "type": "rect",
+ "layer": "below",
+ "x0": 0.5,
+ "x1": 1,
+ "y0": 0.5,
+ "y1": 1
+ },
+ {
+ "type": "rect",
+ "layer": "below",
+ "x0": 0,
+ "x1": 0.5,
+ "y0": 0.5,
+ "y1": 1
+ }
+ ],
+ "annotations": [
+ {
+ "text": "auto",
+ "showarrow": false,
+ "xref": "paper",
+ "yref": "paper",
+ "xanchor": "right",
+ "yanchor": "bottom",
+ "x": 0.5,
+ "y": 0.5,
+ "font": {
+ "size": 20
+ }
+ },
+ {
+ "text": "tangential",
+ "showarrow": false,
+ "xref": "paper",
+ "yref": "paper",
+ "xanchor": "right",
+ "yanchor": "bottom",
+ "x": 0.5,
+ "y": 0,
+ "font": {
+ "size": 20
+ }
+ },
+ {
+ "text": "radial",
+ "showarrow": false,
+ "xref": "paper",
+ "yref": "paper",
+ "xanchor": "right",
+ "yanchor": "bottom",
+ "x": 1,
+ "y": 0,
+ "font": {
+ "size": 20
+ }
+ },
+ {
+ "text": "horizontal",
+ "showarrow": false,
+ "xref": "paper",
+ "yref": "paper",
+ "xanchor": "right",
+ "yanchor": "bottom",
+ "x": 1,
+ "y": 0.5,
+ "font": {
+ "size": 20
+ }
+ }
+ ]
+ }
+}
diff --git a/test/image/mocks/uniformtext_pie_8_radial.json b/test/image/mocks/uniformtext_pie_8_radial.json
new file mode 100644
index 00000000000..037c522214e
--- /dev/null
+++ b/test/image/mocks/uniformtext_pie_8_radial.json
@@ -0,0 +1,248 @@
+{
+ "data": [
+ {
+ "rotation": -360,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L O N G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "radial",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0,
+ 0.24
+ ],
+ "y": [
+ 0,
+ 0.49
+ ]
+ }
+ },
+ {
+ "rotation": -360,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L
O
N
G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "radial",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.25,
+ 0.49
+ ],
+ "y": [
+ 0,
+ 0.49
+ ]
+ }
+ },
+ {
+ "rotation": 180,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L O N G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "radial",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0,
+ 0.24
+ ],
+ "y": [
+ 0.5,
+ 0.99
+ ]
+ }
+ },
+ {
+ "rotation": 180,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L
O
N
G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "radial",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.25,
+ 0.49
+ ],
+ "y": [
+ 0.5,
+ 0.99
+ ]
+ }
+ },
+ {
+ "rotation": -270,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L O N G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "radial",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.5,
+ 0.74
+ ],
+ "y": [
+ 0,
+ 0.49
+ ]
+ }
+ },
+ {
+ "rotation": -270,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L
O
N
G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "radial",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.75,
+ 0.99
+ ],
+ "y": [
+ 0,
+ 0.49
+ ]
+ }
+ },
+ {
+ "rotation": 270,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L O N G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "radial",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.5,
+ 0.74
+ ],
+ "y": [
+ 0.5,
+ 0.99
+ ]
+ }
+ },
+ {
+ "rotation": 270,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L
O
N
G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "radial",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.75,
+ 0.99
+ ],
+ "y": [
+ 0.5,
+ 0.99
+ ]
+ }
+ }
+ ],
+ "layout": {
+ "width": 800,
+ "height": 500,
+ "margin": {
+ "t": 10,
+ "b": 10,
+ "l": 10,
+ "r": 10
+ },
+ "legend": {
+ "orientation": "h",
+ "title": {
+ "text": "pie uniform text
with radial orientation
minsize=8"
+ }
+ },
+ "uniformtext": {
+ "mode": "hide",
+ "minsize": 8
+ }
+ }
+}
diff --git a/test/image/mocks/uniformtext_pie_8_tangential.json b/test/image/mocks/uniformtext_pie_8_tangential.json
new file mode 100644
index 00000000000..3490e845771
--- /dev/null
+++ b/test/image/mocks/uniformtext_pie_8_tangential.json
@@ -0,0 +1,248 @@
+{
+ "data": [
+ {
+ "rotation": -360,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L O N G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "tangential",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0,
+ 0.24
+ ],
+ "y": [
+ 0,
+ 0.49
+ ]
+ }
+ },
+ {
+ "rotation": -360,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L
O
N
G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "tangential",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.25,
+ 0.49
+ ],
+ "y": [
+ 0,
+ 0.49
+ ]
+ }
+ },
+ {
+ "rotation": 180,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L O N G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "tangential",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0,
+ 0.24
+ ],
+ "y": [
+ 0.5,
+ 0.99
+ ]
+ }
+ },
+ {
+ "rotation": 180,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L
O
N
G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "tangential",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.25,
+ 0.49
+ ],
+ "y": [
+ 0.5,
+ 0.99
+ ]
+ }
+ },
+ {
+ "rotation": -270,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L O N G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "tangential",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.5,
+ 0.74
+ ],
+ "y": [
+ 0,
+ 0.49
+ ]
+ }
+ },
+ {
+ "rotation": -270,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L
O
N
G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "tangential",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.75,
+ 0.99
+ ],
+ "y": [
+ 0,
+ 0.49
+ ]
+ }
+ },
+ {
+ "rotation": 270,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L O N G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "tangential",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.5,
+ 0.74
+ ],
+ "y": [
+ 0.5,
+ 0.99
+ ]
+ }
+ },
+ {
+ "rotation": 270,
+ "values": [
+ 7,
+ 0.9,
+ 0.1
+ ],
+ "text": [
+ "L
O
N
G",
+ "text",
+ "invisible"
+ ],
+ "type": "pie",
+ "textinfo": "text",
+ "insidetextorientation": "tangential",
+ "textposition": "inside",
+ "hole": 0.5,
+ "domain": {
+ "x": [
+ 0.75,
+ 0.99
+ ],
+ "y": [
+ 0.5,
+ 0.99
+ ]
+ }
+ }
+ ],
+ "layout": {
+ "width": 800,
+ "height": 500,
+ "margin": {
+ "t": 10,
+ "b": 10,
+ "l": 10,
+ "r": 10
+ },
+ "legend": {
+ "orientation": "h",
+ "title": {
+ "text": "pie uniform text
with tangential orientation
minsize=8"
+ }
+ },
+ "uniformtext": {
+ "mode": "hide",
+ "minsize": 8
+ }
+ }
+}