Skip to content

Commit b234d7a

Browse files
committed
implement uniformtext for bar-like traces as well as funnelarea and treemap
1 parent c095271 commit b234d7a

File tree

11 files changed

+192
-79
lines changed

11 files changed

+192
-79
lines changed

src/traces/bar/plot.js

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -237,14 +237,14 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
237237
Registry.getComponentMethod('errorbars', 'plot')(gd, bartraces, plotinfo, opts);
238238
}
239239

240-
function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, makeOnCompleteCallback) {
240+
function appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, opts, makeOnCompleteCallback) {
241241
var xa = plotinfo.xaxis;
242242
var ya = plotinfo.yaxis;
243243

244244
var fullLayout = gd._fullLayout;
245245
var textPosition;
246246

247-
function appendTextNode(bar, text, textFont) {
247+
function appendTextNode(bar, text, font) {
248248
var textSelection = Lib.ensureSingle(bar, 'text')
249249
.text(text)
250250
.attr({
@@ -254,25 +254,25 @@ function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, ma
254254
// tex and regular text together
255255
'data-notex': 1
256256
})
257-
.call(Drawing.font, textFont)
257+
.call(Drawing.font, font)
258258
.call(svgTextUtils.convertToTspans, gd);
259259

260260
return textSelection;
261261
}
262262

263263
// get trace attributes
264-
var trace = calcTrace[0].trace;
264+
var trace = cd[0].trace;
265265
var isHorizontal = (trace.orientation === 'h');
266266

267-
var text = getText(fullLayout, calcTrace, i, xa, ya);
267+
var text = getText(fullLayout, cd, i, xa, ya);
268268
textPosition = getTextPosition(trace, i);
269269

270270
// compute text position
271271
var inStackOrRelativeMode =
272272
opts.mode === 'stack' ||
273273
opts.mode === 'relative';
274274

275-
var calcBar = calcTrace[i];
275+
var calcBar = cd[i];
276276
var isOutmostBar = !inStackOrRelativeMode || calcBar._outmost;
277277

278278
if(!text ||
@@ -285,7 +285,7 @@ function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, ma
285285
}
286286

287287
var layoutFont = fullLayout.font;
288-
var barColor = style.getBarColor(calcTrace[i], trace);
288+
var barColor = style.getBarColor(cd[i], trace);
289289
var insideTextFont = style.getInsideTextFont(trace, i, layoutFont, barColor);
290290
var outsideTextFont = style.getOutsideTextFont(trace, i, layoutFont);
291291

@@ -318,6 +318,7 @@ function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, ma
318318
var textBB;
319319
var textWidth;
320320
var textHeight;
321+
var font;
321322

322323
if(textPosition === 'outside') {
323324
if(!isOutmostBar && !calcBar.hasB) textPosition = 'inside';
@@ -327,7 +328,11 @@ function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, ma
327328
if(isOutmostBar) {
328329
// draw text using insideTextFont and check if it fits inside bar
329330
textPosition = 'inside';
330-
textSelection = appendTextNode(bar, text, insideTextFont);
331+
332+
font = Lib.extendFlat({}, insideTextFont, {});
333+
font.size = Math.max(font.size, fullLayout.uniformtext.minsize || 0);
334+
335+
textSelection = appendTextNode(bar, text, font);
331336

332337
textBB = Drawing.bBox(textSelection.node()),
333338
textWidth = textBB.width,
@@ -357,9 +362,10 @@ function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, ma
357362
}
358363

359364
if(!textSelection) {
360-
textSelection = appendTextNode(bar, text,
361-
(textPosition === 'outside') ?
362-
outsideTextFont : insideTextFont);
365+
font = Lib.extendFlat({}, (textPosition === 'outside') ? outsideTextFont : insideTextFont, {});
366+
font.size = Math.max(font.size, fullLayout.uniformtext.minsize || 0);
367+
368+
textSelection = appendTextNode(bar, text, font);
363369

364370
var currentTransform = textSelection.attr('transform');
365371
textSelection.attr('transform', '');
@@ -374,32 +380,61 @@ function appendBarText(gd, plotinfo, bar, calcTrace, i, x0, x1, y0, y1, opts, ma
374380
}
375381
}
376382

383+
var angle = trace.textangle;
384+
377385
// compute text transform
378386
var transform, constrained;
379387
if(textPosition === 'outside') {
380388
constrained =
381389
trace.constraintext === 'both' ||
382390
trace.constraintext === 'outside';
383391

384-
transform = Lib.getTextTransform(toMoveOutsideBar(x0, x1, y0, y1, textBB, {
392+
transform = toMoveOutsideBar(x0, x1, y0, y1, textBB, {
385393
isHorizontal: isHorizontal,
386394
constrained: constrained,
387-
angle: trace.textangle
388-
}));
395+
angle: angle
396+
});
389397
} else {
390398
constrained =
391399
trace.constraintext === 'both' ||
392400
trace.constraintext === 'inside';
393401

394-
transform = Lib.getTextTransform(toMoveInsideBar(x0, x1, y0, y1, textBB, {
402+
transform = toMoveInsideBar(x0, x1, y0, y1, textBB, {
395403
isHorizontal: isHorizontal,
396404
constrained: constrained,
397-
angle: trace.textangle,
405+
angle: angle,
398406
anchor: trace.insidetextanchor
399-
}));
407+
});
400408
}
401409

402-
transition(textSelection, opts, makeOnCompleteCallback).attr('transform', transform);
410+
transform.fontSize = font.size;
411+
recordMinTextSize(trace.type, transform, fullLayout);
412+
calcBar.transform = transform;
413+
414+
transition(textSelection, opts, makeOnCompleteCallback)
415+
.attr('transform', Lib.getTextTransform(transform));
416+
}
417+
418+
function recordMinTextSize(
419+
traceType, // in
420+
transform, // inout
421+
fullLayout // inout
422+
) {
423+
if(fullLayout.uniformtext.mode) {
424+
var minKey = '_' + traceType + 'Text_minsize';
425+
var minSize = fullLayout.uniformtext.minsize;
426+
var size = transform.scale * transform.fontSize;
427+
428+
transform.hide = size < minSize;
429+
430+
fullLayout[minKey] = fullLayout[minKey] || Infinity;
431+
if(!transform.hide) {
432+
fullLayout[minKey] = Math.min(
433+
fullLayout[minKey],
434+
Math.max(size, minSize)
435+
);
436+
}
437+
}
403438
}
404439

405440
function getRotateFromAngle(angle) {
@@ -549,15 +584,15 @@ function toMoveOutsideBar(x0, x1, y0, y1, textBB, opts) {
549584
};
550585
}
551586

552-
function getText(fullLayout, calcTrace, index, xa, ya) {
553-
var trace = calcTrace[0].trace;
587+
function getText(fullLayout, cd, index, xa, ya) {
588+
var trace = cd[0].trace;
554589
var texttemplate = trace.texttemplate;
555590

556591
var value;
557592
if(texttemplate) {
558-
value = calcTexttemplate(fullLayout, calcTrace, index, xa, ya);
593+
value = calcTexttemplate(fullLayout, cd, index, xa, ya);
559594
} else if(trace.textinfo) {
560-
value = calcTextinfo(calcTrace, index, xa, ya);
595+
value = calcTextinfo(cd, index, xa, ya);
561596
} else {
562597
value = helpers.getValue(trace.text, index);
563598
}
@@ -570,8 +605,8 @@ function getTextPosition(trace, index) {
570605
return helpers.coerceEnumerated(attributeTextPosition, value);
571606
}
572607

573-
function calcTexttemplate(fullLayout, calcTrace, index, xa, ya) {
574-
var trace = calcTrace[0].trace;
608+
function calcTexttemplate(fullLayout, cd, index, xa, ya) {
609+
var trace = cd[0].trace;
575610
var texttemplate = Lib.castOption(trace, index, 'texttemplate');
576611
if(!texttemplate) return '';
577612
var isWaterfall = (trace.type === 'waterfall');
@@ -599,7 +634,7 @@ function calcTexttemplate(fullLayout, calcTrace, index, xa, ya) {
599634
return tickText(vAxis, +v, true).text;
600635
}
601636

602-
var cdi = calcTrace[index];
637+
var cdi = cd[index];
603638
var obj = {};
604639

605640
obj.label = cdi.p;
@@ -640,8 +675,8 @@ function calcTexttemplate(fullLayout, calcTrace, index, xa, ya) {
640675
return Lib.texttemplateString(texttemplate, obj, fullLayout._d3locale, pt, obj, trace._meta || {});
641676
}
642677

643-
function calcTextinfo(calcTrace, index, xa, ya) {
644-
var trace = calcTrace[0].trace;
678+
function calcTextinfo(cd, index, xa, ya) {
679+
var trace = cd[0].trace;
645680
var isHorizontal = (trace.orientation === 'h');
646681
var isWaterfall = (trace.type === 'waterfall');
647682
var isFunnel = (trace.type === 'funnel');
@@ -657,7 +692,7 @@ function calcTextinfo(calcTrace, index, xa, ya) {
657692
}
658693

659694
var textinfo = trace.textinfo;
660-
var cdi = calcTrace[index];
695+
var cdi = cd[index];
661696

662697
var parts = textinfo.split('+');
663698
var text = [];
@@ -666,7 +701,7 @@ function calcTextinfo(calcTrace, index, xa, ya) {
666701
var hasFlag = function(flag) { return parts.indexOf(flag) !== -1; };
667702

668703
if(hasFlag('label')) {
669-
text.push(formatLabel(calcTrace[index].p));
704+
text.push(formatLabel(cd[index].p));
670705
}
671706

672707
if(hasFlag('text')) {
@@ -717,5 +752,5 @@ function calcTextinfo(calcTrace, index, xa, ya) {
717752
module.exports = {
718753
plot: plot,
719754
toMoveInsideBar: toMoveInsideBar,
720-
toMoveOutsideBar: toMoveOutsideBar
755+
recordMinTextSize: recordMinTextSize
721756
};

src/traces/bar/style.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,46 @@ var attributeInsideTextFont = attributes.insidetextfont;
2020
var attributeOutsideTextFont = attributes.outsidetextfont;
2121
var helpers = require('./helpers');
2222

23+
function resizeText(gd, gTrace, traceType) {
24+
var fullLayout = gd._fullLayout;
25+
var minSize = fullLayout['_' + traceType + 'Text_minsize'];
26+
if(minSize) {
27+
var shouldHide = fullLayout.uniformtext.mode === 'hide';
28+
29+
var t;
30+
switch(traceType) {
31+
case 'funnelarea' :
32+
case 'pie' :
33+
case 'sunburst' :
34+
case 'treemap' :
35+
t = gTrace.selectAll('g.slicetext').selectAll('text');
36+
break;
37+
default :
38+
t = gTrace.selectAll('g.points').selectAll('g.point').selectAll('text');
39+
}
40+
41+
var isCenter = (
42+
traceType === 'pie' ||
43+
traceType === 'sunburst'
44+
);
45+
46+
t.each(function(d) {
47+
var transform = d.transform;
48+
49+
transform.scale = minSize / transform.fontSize;
50+
d3.select(this).attr('transform', Lib.getTextTransform(transform, isCenter));
51+
52+
if(shouldHide && transform.hide) {
53+
d3.select(this).text(' ');
54+
}
55+
});
56+
}
57+
}
58+
2359
function style(gd) {
2460
var s = d3.select(gd).selectAll('g.barlayer').selectAll('g.trace');
61+
resizeText(gd, s, 'bar');
62+
2563
var barcount = s.size();
2664
var fullLayout = gd._fullLayout;
2765

@@ -57,7 +95,9 @@ function stylePoints(sel, trace, gd) {
5795
function styleTextPoints(sel, trace, gd) {
5896
sel.selectAll('text').each(function(d) {
5997
var tx = d3.select(this);
60-
var font = determineFont(tx, d, trace, gd);
98+
var font = Lib.extendFlat({}, determineFont(tx, d, trace, gd), {});
99+
font.size = Math.max(font.size, gd._fullLayout.uniformtext.minsize || 0);
100+
61101
Drawing.font(tx, font);
62102
});
63103
}
@@ -85,6 +125,7 @@ function styleTextInSelectionMode(txs, trace, gd) {
85125

86126
if(d.selected) {
87127
font = Lib.extendFlat({}, determineFont(tx, d, trace, gd));
128+
font.size = Math.max(font.size, gd._fullLayout.uniformtext.minsize || 0);
88129

89130
var selectedFontColor = trace.selected.textfont && trace.selected.textfont.color;
90131
if(selectedFontColor) {
@@ -171,5 +212,6 @@ module.exports = {
171212
styleOnSelect: styleOnSelect,
172213
getInsideTextFont: getInsideTextFont,
173214
getOutsideTextFont: getOutsideTextFont,
174-
getBarColor: getBarColor
215+
getBarColor: getBarColor,
216+
resizeText: resizeText
175217
};

src/traces/funnel/style.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ var d3 = require('d3');
1313
var Drawing = require('../../components/drawing');
1414
var Color = require('../../components/color');
1515
var DESELECTDIM = require('../../constants/interactions').DESELECTDIM;
16-
17-
var styleTextPoints = require('../bar/style').styleTextPoints;
16+
var barStyle = require('../bar/style');
17+
var resizeText = barStyle.resizeText;
18+
var styleTextPoints = barStyle.styleTextPoints;
1819

1920
function style(gd, cd, sel) {
2021
var s = sel ? sel : d3.select(gd).selectAll('g.funnellayer').selectAll('g.trace');
22+
resizeText(gd, s, 'funnel');
2123

2224
s.style('opacity', function(d) { return d[0].trace.opacity; });
2325

0 commit comments

Comments
 (0)