Skip to content

Commit 30b172a

Browse files
committed
fixup textangle algo - added test for outside text
1 parent a744689 commit 30b172a

File tree

6 files changed

+163
-21
lines changed

6 files changed

+163
-21
lines changed

src/traces/bar/plot.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,8 @@ function getTransformToMoveInsideBar(x0, x1, y0, y1, textBB, isHorizontal, const
375375
lx = tmp;
376376
}
377377

378-
var absSin = Math.abs(Math.sin(rotation));
379-
var absCos = Math.abs(Math.cos(rotation));
378+
var absSin = Math.abs(Math.sin(Math.PI / 180 * rotation));
379+
var absCos = Math.abs(Math.cos(Math.PI / 180 * rotation));
380380

381381
// compute and apply text padding
382382
var dx = Math.max(lx * absCos, ly * absSin);
@@ -401,10 +401,11 @@ function getTransformToMoveInsideBar(x0, x1, y0, y1, textBB, isHorizontal, const
401401
var targetY = (y0 + y1) / 2;
402402

403403
if(anchor !== 'middle') { // case of 'start' or 'end'
404-
var flip = xor(!isHorizontal, isAutoRotated);
405-
var side = (flip) ? textBB.width : textBB.height;
406-
var offset = (0.5 * scale * side) +
407-
textpad * (1 + Math.min(absCos, absSin));
404+
var targetWidth = scale * (isHorizontal !== isAutoRotated ? textHeight : textWidth);
405+
var targetHeight = scale * (isHorizontal !== isAutoRotated ? textWidth : textHeight);
406+
var move = targetWidth * absSin + targetHeight * absCos;
407+
408+
var offset = textpad + move / 2;
408409

409410
if(isHorizontal) {
410411
offset *= dirSign(x0, x1);
@@ -424,21 +425,21 @@ function getTransformToMoveInsideBar(x0, x1, y0, y1, textBB, isHorizontal, const
424425
return getTransform(textX, textY, targetX, targetY, scale, rotation);
425426
}
426427

427-
function xor(a, b) {
428-
return (a && b) || !(a || b);
429-
}
430-
431428
function getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB, isHorizontal, constrained, angle) {
432429
var barWidth = (isHorizontal) ?
433430
Math.abs(y1 - y0) :
434431
Math.abs(x1 - x0);
435-
var textpad;
436432

433+
var rotation = getRotationFromAngle(angle);
434+
435+
var textpad = 0;
437436
// Keep the padding so the text doesn't sit right against
438437
// the bars, but don't factor it into barWidth
439438
if(barWidth > 2 * TEXTPAD) {
440439
textpad = TEXTPAD;
441440
}
441+
var absSin = Math.abs(Math.sin(Math.PI / 180 * rotation));
442+
var absCos = Math.abs(Math.cos(Math.PI / 180 * rotation));
442443

443444
// compute rotation and scale
444445
var scale = 1;
@@ -455,6 +456,8 @@ function getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB, isHorizontal, cons
455456
var targetWidth = scale * textBB.width;
456457
var targetHeight = scale * textBB.height;
457458

459+
textpad += 0.5 * Math.min(absSin * targetHeight, absCos * targetWidth);
460+
458461
var targetX = (x0 + x1) / 2;
459462
var targetY = (y0 + y1) / 2;
460463

@@ -464,8 +467,6 @@ function getTransformToMoveOutsideBar(x0, x1, y0, y1, textBB, isHorizontal, cons
464467
targetY = y1 + (textpad + targetHeight / 2) * dirSign(y0, y1);
465468
}
466469

467-
var rotation = getRotationFromAngle(angle);
468-
469470
return getTransform(textX, textY, targetX, targetY, scale, rotation);
470471
}
471472

3.7 KB
Loading
86.3 KB
Loading
52.7 KB
Loading
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
{
2+
"data": [
3+
{
4+
"type": "funnel",
5+
"orientation": "v",
6+
"x": [
7+
"A",
8+
"B",
9+
"C"
10+
],
11+
"y": [
12+
3,
13+
2,
14+
1
15+
],
16+
"textposition": "outside",
17+
"cliponaxis": false,
18+
"textangle": -15,
19+
"textinfo": "value+percent initial+percent previous+percent total"
20+
},
21+
{
22+
"type": "funnel",
23+
"orientation": "v",
24+
"x": [
25+
"A",
26+
"B",
27+
"C"
28+
],
29+
"y": [
30+
300,
31+
200,
32+
100
33+
],
34+
"textposition": "outside",
35+
"cliponaxis": false,
36+
"textangle": 135,
37+
"textinfo": "value+percent initial+percent previous+percent total",
38+
"xaxis": "x2",
39+
"yaxis": "y2"
40+
},
41+
{
42+
"type": "funnel",
43+
"orientation": "h",
44+
"x": [
45+
30000,
46+
20000,
47+
10000
48+
],
49+
"y": [
50+
"A",
51+
"B",
52+
"C"
53+
],
54+
"textposition": "outside",
55+
"cliponaxis": false,
56+
"textangle": 30,
57+
"textinfo": "value+percent initial+percent previous+percent total",
58+
"xaxis": "x3",
59+
"yaxis": "y3"
60+
},
61+
{
62+
"type": "funnel",
63+
"orientation": "h",
64+
"x": [
65+
3000000,
66+
2000000,
67+
1000000
68+
],
69+
"y": [
70+
"A",
71+
"B",
72+
"C"
73+
],
74+
"textposition": "outside",
75+
"cliponaxis": false,
76+
"textangle": -90,
77+
"textinfo": "value+percent initial+percent previous+percent total",
78+
"xaxis": "x4",
79+
"yaxis": "y4"
80+
}
81+
],
82+
"layout": {
83+
"width": 800,
84+
"height": 800,
85+
"dragmode": "pan",
86+
"xaxis": {
87+
"domain": [
88+
0,
89+
0.48
90+
]
91+
},
92+
"xaxis2": {
93+
"anchor": "y2",
94+
"domain": [
95+
0.52,
96+
1
97+
]
98+
},
99+
"xaxis3": {
100+
"anchor": "y3",
101+
"domain": [
102+
0,
103+
0.48
104+
]
105+
},
106+
"xaxis4": {
107+
"anchor": "y4",
108+
"domain": [
109+
0.52,
110+
1
111+
]
112+
},
113+
"yaxis": {
114+
"domain": [
115+
0,
116+
0.48
117+
]
118+
},
119+
"yaxis2": {
120+
"anchor": "x2",
121+
"domain": [
122+
0.52,
123+
1
124+
]
125+
},
126+
"yaxis3": {
127+
"anchor": "x3",
128+
"domain": [
129+
0.52,
130+
1
131+
]
132+
},
133+
"yaxis4": {
134+
"anchor": "x4",
135+
"domain": [
136+
0,
137+
0.48
138+
]
139+
}
140+
}
141+
}

test/image/mocks/funnel_axis_textangle_start-end.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"insidetextanchor": "start",
1717
"textposition": "inside",
1818
"textangle": "auto",
19-
"textinfo": "value+percent initial"
19+
"textinfo": "value+percent initial+percent previous+percent total"
2020
},
2121
{
2222
"type": "funnel",
@@ -33,7 +33,7 @@
3333
],
3434
"insidetextanchor": "end",
3535
"textposition": "inside",
36-
"textinfo": "value+percent initial"
36+
"textinfo": "value+percent initial+percent previous+percent total"
3737
},
3838
{
3939
"type": "funnel",
@@ -51,7 +51,7 @@
5151
"insidetextanchor": "start",
5252
"textposition": "inside",
5353
"textangle": 45,
54-
"textinfo": "value+percent initial",
54+
"textinfo": "value+percent initial+percent previous+percent total",
5555
"xaxis": "x2",
5656
"yaxis": "y2"
5757
},
@@ -71,7 +71,7 @@
7171
"insidetextanchor": "end",
7272
"textposition": "inside",
7373
"textangle": -45,
74-
"textinfo": "value+percent initial",
74+
"textinfo": "value+percent initial+percent previous+percent total",
7575
"xaxis": "x2",
7676
"yaxis": "y2"
7777
},
@@ -91,7 +91,7 @@
9191
"insidetextanchor": "start",
9292
"textposition": "inside",
9393
"textangle": 45,
94-
"textinfo": "value+percent initial",
94+
"textinfo": "value+percent initial+percent previous+percent total",
9595
"xaxis": "x3",
9696
"yaxis": "y3"
9797
},
@@ -111,7 +111,7 @@
111111
"insidetextanchor": "end",
112112
"textposition": "inside",
113113
"textangle": -45,
114-
"textinfo": "value+percent initial",
114+
"textinfo": "value+percent initial+percent previous+percent total",
115115
"xaxis": "x3",
116116
"yaxis": "y3"
117117
},
@@ -132,7 +132,7 @@
132132
"textposition": "inside",
133133
"cliponaxis": false,
134134
"textangle": 90,
135-
"textinfo": "value+percent initial",
135+
"textinfo": "value+percent initial+percent previous+percent total",
136136
"xaxis": "x4",
137137
"yaxis": "y4"
138138
},
@@ -153,7 +153,7 @@
153153
"textposition": "inside",
154154
"cliponaxis": false,
155155
"textangle": -90,
156-
"textinfo": "value+percent initial",
156+
"textinfo": "value+percent initial+percent previous+percent total",
157157
"xaxis": "x4",
158158
"yaxis": "y4"
159159
}

0 commit comments

Comments
 (0)