Skip to content

Consistent text mode for bar-like & pie-like traces and feature to control text orientation inside pie/sunburst slices #4420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Dec 23, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0d3e289
add uniformtext attributes to layout
archmoj Dec 12, 2019
c095271
simplify transform function and expand to reuse in pie and sunburst
archmoj Dec 12, 2019
b234d7a
implement uniformtext for bar-like traces as well as funnelarea and t…
archmoj Dec 12, 2019
f0ac957
implement uniformtext and insidetext-orientation for pie and sunburst
archmoj Dec 12, 2019
4d5fb3d
add new mocks to test insidetextorientation and uniformtext
archmoj Dec 12, 2019
a27dc29
Consider first review
archmoj Dec 13, 2019
1479943
make tangential go towards noon and 6 and make radial go towards 3 and 9
archmoj Dec 16, 2019
eab205a
rewrite uniform text style
archmoj Dec 16, 2019
5348c58
add new mocks cases by Nicolas
archmoj Dec 18, 2019
15ce24d
apply zero scale for hiding text elements
archmoj Dec 19, 2019
0840d82
add new mocks using both inside-text-orientation and uniformtext
archmoj Dec 19, 2019
328ffd0
move reposition logic outside pie transformInsideText function
archmoj Dec 19, 2019
2a31685
apply next text position when it is not at the center
archmoj Dec 19, 2019
d1b50b1
Apply polar coordinates to move text inside the slice during sunburst…
archmoj Dec 19, 2019
2cb5687
sunburst handle no text when using various inside-text-orientation op…
archmoj Dec 20, 2019
beed042
add react tests for treemap and pie uniform text as well as inside te…
archmoj Dec 20, 2019
51d7e1b
add tests for updating text positions using different inside-text-pos…
archmoj Dec 20, 2019
603e0cc
wip
etpinard Dec 20, 2019
8784274
first attempt at fixing tests on etpinard's laptop
etpinard Dec 23, 2019
2686c46
Fix funnelarea, pie, sunburst and treemap tests
archmoj Dec 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
apply zero scale for hiding text elements
- bypass points without text
- add react tests for bar, waterfall, funnel, funnelarea, pie uniform-text options
- add react tests for pie inside-text-orientation options
  • Loading branch information
archmoj committed Dec 19, 2019
commit 15ce24d17eb7415a5bc04ee7dafa6797db6c7c81
9 changes: 5 additions & 4 deletions src/traces/bar/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ function resizeText(gd, gTrace, traceType) {

t.each(function(d) {
var transform = d.transform;
transform.scale = minSize / transform.fontSize;
if(transform) {
transform.scale = (shouldHide && transform.hide) ? 0 : minSize / transform.fontSize;

var el = d3.select(this).select('text');
el.attr('transform', Lib.getTextTransform(transform));
el.attr('display', shouldHide && transform.hide ? 'none' : null);
var el = d3.select(this).select('text');
el.attr('transform', Lib.getTextTransform(transform));
}
});
}
}
Expand Down
120 changes: 120 additions & 0 deletions test/jasmine/tests/bar_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2787,3 +2787,123 @@ describe('bar tweening', function() {
.then(done);
});
});

describe('bar uniformtext', function() {
'use strict';

var gd;

beforeEach(function() {
gd = createGraphDiv();
});

afterEach(destroyGraphDiv);

function assertTextSizes(msg, opts) {
return function() {
var selection = d3.selectAll(BAR_TEXT_SELECTOR);
var size = selection.size();
['fontsizes', 'scales'].forEach(function(e) {
expect(size).toBe(opts[e].length, 'length for ' + e + ' does not match with the number of elements');
});

selection.each(function(d, i) {
var fontSize = this.style.fontSize;
expect(fontSize).toBe(opts.fontsizes[i] + 'px', 'fontSize for element ' + i, msg);
});

for(var i = 0; i < selection[0].length; i++) {
var transform = selection[0][i].getAttribute('transform');
var pos0 = transform.indexOf('scale(');
var scale = 1;
if(pos0 !== -1) {
pos0 += 'scale'.length;
var pos1 = transform.indexOf(')', pos0);
scale = +(transform.substring(pos0 + 1, pos1 - 1));
}

expect(opts.scales[i]).toBeCloseTo(scale, 1, 'scale for element ' + i, msg);
}
};
}

it('should be able to react with new uniform text options', function(done) {
var fig = {
data: [{
type: 'bar',
orientation: 'h',
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],

// no text element would be created for null and empty string
text: [
'long lablel',
'$',
'=',
'|',
'.',
' ',
'',
null,
'<br>',
0
],

textinfo: 'text',
textposition: 'inside',
textangle: 0
}],
layout: {
width: 500,
height: 500
}
};

Plotly.plot(gd, fig)
.then(assertTextSizes('without uniformtext', {
fontsizes: [12, 12, 12, 12, 12, 12, 12],
scales: [0.48, 1, 1, 1, 1, 1, 1],
}))
.then(function() {
fig.layout.uniformtext = {mode: 'hide'}; // default with minsize=0
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using mode: "hide"', {
fontsizes: [12, 12, 12, 12, 12, 12, 12],
scales: [0.48, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48],
}))
.then(function() {
fig.layout.uniformtext.minsize = 9; // set a minsize less than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 9', {
fontsizes: [12, 12, 12, 12, 12, 12, 12],
scales: [0, 0.48, 0.48, 0.48, 0.48, 0.48, 0.48],
}))
.then(function() {
fig.layout.uniformtext.minsize = 32; // set a minsize greater than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 32', {
fontsizes: [32, 32, 32, 32, 32, 32, 32],
scales: [0, 0, 0, 0, 0, 0, 0],
}))
.then(function() {
fig.layout.uniformtext.minsize = 16; // set a minsize greater than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 16', {
fontsizes: [16, 16, 16, 16, 16, 16, 16],
scales: [0, 0.36, 0.36, 0.36, 0.36, 0.36, 0.36],
}))
.then(function() {
fig.layout.uniformtext.mode = 'show';
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using mode: "show"', {
fontsizes: [16, 16, 16, 16, 16, 16, 16],
scales: [0.36, 0.36, 0.36, 0.36, 0.36, 0.36, 0.36],
}))
.catch(failTest)
.then(done);
});
});
119 changes: 119 additions & 0 deletions test/jasmine/tests/funnel_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1610,3 +1610,122 @@ function assertTraceField(calcData, prop, expectation) {

expect(values).toBeCloseToArray(expectation, undefined, '(field ' + prop + ')');
}

describe('funnel uniformtext', function() {
'use strict';

var gd;

beforeEach(function() {
gd = createGraphDiv();
});

afterEach(destroyGraphDiv);

function assertTextSizes(msg, opts) {
return function() {
var selection = d3.selectAll(FUNNEL_TEXT_SELECTOR);
var size = selection.size();
['fontsizes', 'scales'].forEach(function(e) {
expect(size).toBe(opts[e].length, 'length for ' + e + ' does not match with the number of elements');
});

selection.each(function(d, i) {
var fontSize = this.style.fontSize;
expect(fontSize).toBe(opts.fontsizes[i] + 'px', 'fontSize for element ' + i, msg);
});

for(var i = 0; i < selection[0].length; i++) {
var transform = selection[0][i].getAttribute('transform');
var pos0 = transform.indexOf('scale(');
var scale = 1;
if(pos0 !== -1) {
pos0 += 'scale'.length;
var pos1 = transform.indexOf(')', pos0);
scale = +(transform.substring(pos0 + 1, pos1 - 1));
}

expect(opts.scales[i]).toBeCloseTo(scale, 1, 'scale for element ' + i, msg);
}
};
}

it('should be able to react with new uniform text options', function(done) {
var fig = {
data: [{
type: 'funnel',
orientation: 'h',
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],

text: [
'long lablel',
'$',
'=',
'|',
'.',
' ',
'',
null,
'<br>',
0
],

textinfo: 'text',
textposition: 'inside',
textangle: 0
}],
layout: {
width: 500,
height: 500
}
};

Plotly.plot(gd, fig)
.then(assertTextSizes('without uniformtext', {
fontsizes: [12, 12, 12, 12, 12, 12, 12],
scales: [0.44, 1, 1, 1, 1, 1, 1],
}))
.then(function() {
fig.layout.uniformtext = {mode: 'hide'}; // default with minsize=0
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using mode: "hide"', {
fontsizes: [12, 12, 12, 12, 12, 12, 12],
scales: [0.44, 0.44, 0.44, 0.44, 0.44, 0.44, 0.44],
}))
.then(function() {
fig.layout.uniformtext.minsize = 9; // set a minsize less than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 9', {
fontsizes: [12, 12, 12, 12, 12, 12, 12],
scales: [0, 0.44, 0.44, 0.44, 0.44, 0.44, 0.44],
}))
.then(function() {
fig.layout.uniformtext.minsize = 32; // set a minsize greater than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 32', {
fontsizes: [32, 32, 32, 32, 32, 32, 32],
scales: [0, 0, 0, 0, 0, 0, 0],
}))
.then(function() {
fig.layout.uniformtext.minsize = 16; // set a minsize greater than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 16', {
fontsizes: [16, 16, 16, 16, 16, 16, 16],
scales: [0, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33],
}))
.then(function() {
fig.layout.uniformtext.mode = 'show';
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using mode: "show"', {
fontsizes: [16, 16, 16, 16, 16, 16, 16],
scales: [0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33],
}))
.catch(failTest)
.then(done);
});
});
120 changes: 120 additions & 0 deletions test/jasmine/tests/funnelarea_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1711,3 +1711,123 @@ describe('Test funnelarea calculated areas with scalegroup on various domain rat
});
});
});

describe('funnelarea uniformtext', function() {
'use strict';

var gd;

beforeEach(function() {
gd = createGraphDiv();
});

afterEach(destroyGraphDiv);

function assertTextSizes(msg, opts) {
return function() {
var selection = d3.selectAll(SLICES_TEXT_SELECTOR);
var size = selection.size();
['fontsizes', 'scales'].forEach(function(e) {
expect(size).toBe(opts[e].length, 'length for ' + e + ' does not match with the number of elements');
});

selection.each(function(d, i) {
var fontSize = this.style.fontSize;
expect(fontSize).toBe(opts.fontsizes[i] + 'px', 'fontSize for element ' + i, msg);
});

for(var i = 0; i < selection[0].length; i++) {
var transform = selection[0][i].getAttribute('transform');
var pos0 = transform.indexOf('scale(');
var scale = 1;
if(pos0 !== -1) {
pos0 += 'scale'.length;
var pos1 = transform.indexOf(')', pos0);
scale = +(transform.substring(pos0 + 1, pos1 - 1));
}

expect(opts.scales[i]).toBeCloseTo(scale, 1, 'scale for element ' + i, msg);
}
};
}

it('should be able to react with new uniform text options', function(done) {
var fig = {
data: [{
type: 'funnelarea',
lables: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
values: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
sort: false,

text: [
0,
'<br>',
null,
'',
' ',
'.',
'|',
'=',
'$',
'long lablel'
],

textinfo: 'text',
textangle: 0,
showlegend: false
}],
layout: {
width: 350,
height: 350
}
};

Plotly.plot(gd, fig)
.then(assertTextSizes('without uniformtext', {
fontsizes: [12, 12, 12, 12, 12, 12, 12, 12],
scales: [0.40, 1, 0.62, 0.70, 0.82, 0.98, 1, 0.91],
}))
.then(function() {
fig.layout.uniformtext = {mode: 'hide'}; // default with minsize=0
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using mode: "hide"', {
fontsizes: [12, 12, 12, 12, 12, 12, 12, 12],
scales: [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4],
}))
.then(function() {
fig.layout.uniformtext.minsize = 9; // set a minsize less than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 9', {
fontsizes: [12, 12, 12, 12, 12, 12, 12, 12],
scales: [0, 0.4, 0, 0, 0.4, 0.4, 0.4, 0.4],
}))
.then(function() {
fig.layout.uniformtext.minsize = 32; // set a minsize greater than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 32', {
fontsizes: [32, 32, 32, 32, 32, 32, 32, 32],
scales: [0, 0.15, 0, 0, 0, 0, 0, 0],
}))
.then(function() {
fig.layout.uniformtext.minsize = 16; // set a minsize greater than trace font size
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using minsize: 16', {
fontsizes: [16, 16, 16, 16, 16, 16, 16, 16],
scales: [0, 0.3, 0, 0, 0, 0, 0.3, 0],
}))
.then(function() {
fig.layout.uniformtext.mode = 'show';
return Plotly.react(gd, fig);
})
.then(assertTextSizes('using mode: "show"', {
fontsizes: [16, 16, 16, 16, 16, 16, 16, 16],
scales: [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3],
}))
.catch(failTest)
.then(done);
});
});
Loading