Skip to content

Commit d1b50b1

Browse files
committed
Apply polar coordinates to move text inside the slice during sunburst transitions
- rename pxtxt to textPosAngle and other cleanups - keep textPosAngle inside transform
1 parent 2a31685 commit d1b50b1

File tree

2 files changed

+31
-24
lines changed

2 files changed

+31
-24
lines changed

src/traces/pie/plot.js

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -175,16 +175,12 @@ function plot(gd, cdModule) {
175175

176176
transform = transformOutsideText(textBB, pt);
177177
}
178-
179-
if(transform.pxtxt) {
180-
// copy text position if not at the middle
181-
pt.pxtxt = transform.pxtxt;
182-
}
183178
}
184179

185-
var pxtxt = pt.pxtxt || pt.pxmid;
186-
transform.targetX = cx + pxtxt[0] * transform.rCenter + (transform.x || 0);
187-
transform.targetY = cy + pxtxt[1] * transform.rCenter + (transform.y || 0);
180+
var textPosAngle = transform.textPosAngle;
181+
var textXY = textPosAngle === undefined ? pt.pxmid : getCoords(cd0.r, textPosAngle);
182+
transform.targetX = cx + textXY[0] * transform.rCenter + (transform.x || 0);
183+
transform.targetY = cy + textXY[1] * transform.rCenter + (transform.y || 0);
188184
computeTransform(transform, textBB);
189185

190186
// save some stuff to use later ensure no labels overlap
@@ -572,6 +568,7 @@ function transformInsideText(textBB, pt, cd0) {
572568
var isAuto = orientation === 'auto';
573569
var isCircle = (ring === 1) && (Math.abs(pt.startangle - pt.stopangle) === Math.PI * 2);
574570
var allTransforms = [];
571+
var newT;
575572

576573
if(!isAuto) {
577574
// max size if text is placed (horizontally) at the top or bottom of the arc
@@ -583,13 +580,12 @@ function transformInsideText(textBB, pt, cd0) {
583580

584581
var closestEdge = dStart < dStop ? dStart : dStop;
585582

586-
var newT;
587583
if(key === 'tan') {
588584
newT = calcTanTransform(textBB, r, ring, closestEdge, 0);
589585
} else { // case of 'rad'
590586
newT = calcRadTransform(textBB, r, ring, closestEdge, Math.PI / 2);
591587
}
592-
newT.pxtxt = getCoords(r, angle);
588+
newT.textPosAngle = angle;
593589

594590
allTransforms.push(newT);
595591
}
@@ -616,25 +612,30 @@ function transformInsideText(textBB, pt, cd0) {
616612
// this inscribes the text rectangle in a circle, which is then inscribed
617613
// in the slice, so it will be an underestimate, which some day we may want
618614
// to improve so this case can get more use
619-
var transform = {
615+
newT = {
620616
scale: rInscribed * r * 2 / textDiameter,
621617

622618
// and the center position and rotation in this case
623619
rCenter: 1 - rInscribed,
624620
rotate: 0
625621
};
626622

627-
if(transform.scale >= 1) return transform;
623+
newT.textPosAngle = (pt.startangle + pt.stopangle) / 2;
624+
if(newT.scale >= 1) return newT;
628625

629-
allTransforms.push(transform);
626+
allTransforms.push(newT);
630627
}
631628

632629
if(isAuto || isRadial) {
633-
allTransforms.push(calcRadTransform(textBB, r, ring, halfAngle, midAngle));
630+
newT = calcRadTransform(textBB, r, ring, halfAngle, midAngle);
631+
newT.textPosAngle = (pt.startangle + pt.stopangle) / 2;
632+
allTransforms.push(newT);
634633
}
635634

636635
if(isAuto || isTangential) {
637-
allTransforms.push(calcTanTransform(textBB, r, ring, halfAngle, midAngle));
636+
newT = calcTanTransform(textBB, r, ring, halfAngle, midAngle);
637+
newT.textPosAngle = (pt.startangle + pt.stopangle) / 2;
638+
allTransforms.push(newT);
638639
}
639640

640641
var id = 0;

src/traces/sunburst/plot.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ function plotOne(gd, cd, element, transitionOpts) {
151151
var pathSlice = function(d) { return Lib.pathAnnulus(d.rpx0, d.rpx1, d.x0, d.x1, cx, cy); };
152152
// slice text translate x/y
153153

154-
var getTargetX = function(d) { return cx + (d.pxtxt || d.pxmid)[0] * d.transform.rCenter + (d.transform.x || 0); };
155-
var getTargetY = function(d) { return cy + (d.pxtxt || d.pxmid)[1] * d.transform.rCenter + (d.transform.y || 0); };
154+
var getTargetX = function(d) { return cx + getTextXY(d)[0] * d.transform.rCenter + (d.transform.x || 0); };
155+
var getTargetY = function(d) { return cy + getTextXY(d)[1] * d.transform.rCenter + (d.transform.y || 0); };
156156

157157
slices = slices.data(sliceData, helpers.getPtId);
158158

@@ -264,11 +264,6 @@ function plotOne(gd, cd, element, transitionOpts) {
264264
// position the text relative to the slice
265265
var textBB = Drawing.bBox(sliceText.node());
266266
pt.transform = transformInsideText(textBB, pt, cd0);
267-
if(pt.transform.pxtxt) {
268-
// copy text position if not at the middle
269-
pt.pxtxt = pt.transform.pxtxt;
270-
}
271-
272267
pt.transform.targetX = getTargetX(pt);
273268
pt.transform.targetY = getTargetY(pt);
274269

@@ -382,6 +377,7 @@ function plotOne(gd, cd, element, transitionOpts) {
382377
prev = {
383378
rpx1: pt.rpx1,
384379
transform: {
380+
textPosAngle: transform.textPosAngle,
385381
scale: 0,
386382
rotate: transform.rotate,
387383
rCenter: transform.rCenter,
@@ -414,6 +410,7 @@ function plotOne(gd, cd, element, transitionOpts) {
414410
}
415411
}
416412

413+
var textPosAngleFn = d3.interpolate(prev.transform.textPosAngle, pt.transform.textPosAngle);
417414
var rpx1Fn = d3.interpolate(prev.rpx1, pt.rpx1);
418415
var x0Fn = d3.interpolate(prev.x0, pt.x0);
419416
var x1Fn = d3.interpolate(prev.x1, pt.x1);
@@ -434,11 +431,13 @@ function plotOne(gd, cd, element, transitionOpts) {
434431
var x1 = x1Fn(t);
435432
var rCenter = rCenterFn(t);
436433
var pxmid = rx2px(rpx1, (x0 + x1) / 2);
434+
var textPosAngle = textPosAngleFn(t);
437435

438436
var d = {
439-
pxtxt: pt.pxtxt || pxmid,
440437
pxmid: pxmid,
438+
rpx1: rpx1,
441439
transform: {
440+
textPosAngle: textPosAngle,
442441
rCenter: rCenter,
443442
x: transform.x,
444443
y: transform.y
@@ -447,7 +446,6 @@ function plotOne(gd, cd, element, transitionOpts) {
447446

448447
recordMinTextSize(trace.type, transform, fullLayout);
449448
return {
450-
rpx1: rpx1Fn(t),
451449
transform: {
452450
targetX: getTargetX(d),
453451
targetY: getTargetY(d),
@@ -613,3 +611,11 @@ function getInscribedRadiusFraction(pt) {
613611
));
614612
}
615613
}
614+
615+
function getTextXY(d) {
616+
return getCoords(d.rpx1, d.transform.textPosAngle);
617+
}
618+
619+
function getCoords(r, angle) {
620+
return [r * Math.sin(angle), -r * Math.cos(angle)];
621+
}

0 commit comments

Comments
 (0)