Skip to content
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

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

Merged
merged 20 commits into from
Dec 23, 2019

Conversation

archmoj
Copy link
Contributor

@archmoj archmoj commented Dec 12, 2019

Resolves #4247 and
resolves #3590

In addition to simplifying (e.g. removing extra translations) and unifying transformations between bar-like and pie-like traces, this PR adds a new layout attribute called uniformtext with mode (false | 'hide' | 'show'). By enabling this option the text within traces of the same type (namely bar, waterfall, funnel, funnelarea, pie, sunburst and treemap) would be filtered and displayed with an identical text size greater or equal than the value defined by the minsize.

Also this PR adds a new attribute called insidetextorientation to pie and sunburst traces which allows more control over the orientation of text within the slices.

Keeping text consistent during transitions is not within the scope of this PR; but it may be addressed by a separated PR.

simple demo
sunburst text orientation demo

@plotly/plotly_js
cc: @nicolaskruchten

@archmoj archmoj added this to the v1.52.0 milestone Dec 12, 2019
src/lib/index.js Outdated Show resolved Hide resolved
src/traces/bar/style.js Outdated Show resolved Hide resolved
@@ -57,7 +95,9 @@ function stylePoints(sel, trace, gd) {
function styleTextPoints(sel, trace, gd) {
sel.selectAll('text').each(function(d) {
var tx = d3.select(this);
var font = determineFont(tx, d, trace, gd);
var font = Lib.extendFlat({}, determineFont(tx, d, trace, gd), {});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a typo.

var font = determineFont(tx, d, trace, gd);

should be good enough, right? If not then, we should move the extendFlat call to determineFont.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A copy is needed since the font.size may be replaced by minsize.

Copy link
Contributor

@etpinard etpinard Dec 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok that explains the

 var font = Lib.extendFlat({}, determineFont(tx, d, trace, gd));

part, but isn't the third argument in

var font = Lib.extendFlat({}, determineFont(tx, d, trace, gd), {});

useless?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. We could/should drop that.
I can make a centralize function for those font getters.
Should uniform text.minsize override the font.size(s) defined by traces? If not we could use the minimum among them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should uniform text.minsize override the font.size(s) defined by traces?

Like override them in gd.data[i] and gd._fullData[i]? If so, then the answer is NO. We shouldn't mutate that.

If not we could use the minimum among them.

That sounds about right. Adding something like

Lib.applyUniformtext = function(gd, baseFont) {
  var out = Lib.extendFlat({}, baseFont);
  out.size = Math.max(baseFont.size, gd._fullLayout.uniformtext.minsize || 0);
  return out;
}

could be a big win!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the hint.
Would you please clarify which size should be used in the scenario below?
When one of the traces defined its font size to be e.g. 8; while the uniform.minsize is set to 16.
In the current implementation 16 wins over 8.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When one of the traces defined its font size to be e.g. 8; while the uniform.minsize is set to 16.

That's a hard one. I can see arguments for both ways. On one hard, it would make things more flexible if we allow users to override the uniform-text-size results. But then again, if they really want that, they can set all the textfont.size in the traces manually w/o even touching uniformtext.

src/traces/pie/plot.js Outdated Show resolved Hide resolved
src/traces/pie/plot.js Outdated Show resolved Hide resolved
Comment on lines 154 to 155
var getTargetX = function(d) { return cx + (d.pxtxt || d.pxmid)[0] * d.transform.rCenter + (d.transform.x || 0); };
var getTargetY = function(d) { return cy + (d.pxtxt || d.pxmid)[1] * d.transform.rCenter + (d.transform.y || 0); };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this new d.pxtxt for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When fitting horizontal text in pie and sunburst the best position may not be the middle point of the arc. So pxtxt keeps the position of text if it is moved form the middle.

uniformtext_pie_8_horizontal

sunburst

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are really nice... loving the consistent alignment of labels in the sunburst :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(well, semi-consistent!) We should maybe special-case the noon and 6 o'clock positions as 'preferred' if they result in the same size as 12:05 or 6:15, say :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Done in 1479943.

@etpinard
Copy link
Contributor

@archmoj I still need to try to understand your new insidetextorientation logic and explore all the details you're locking down in the test mocks, but nonetheless here's a first review.

Writing what we discussed a week ago: in a not-so-distant future (i.e. whenever we'll attempt to implement #2000) we should try to compute the bounding boxes of all the trace text items before plotting them. In brief, this means adding logic to the calc or crossTraceCalc step - which would unfortunately make them async in general to support MathJax (unless we decide to ditch MathJax for e.g. KaTeX before doing this). Not having to resize the text elements during style would essentially eliminate the transition problems you're referring to in the PR header (example here: https://codepen.io/MojtabaSamimi/pen/NWPrzOG?editors=1000). Personally, these transition problems are minor enough at the moment that I'd vote keeping them as is until we tweak the pipeline.


Before thinking about merging this PR, I'd like to see some jasmine tests to see how things behave when calling relayout (sorry) react with changes in the uniformtext.* attributes.

@etpinard
Copy link
Contributor

Moreover, @archmoj could you share a JSON mock or a codepen of a simple case that uses uniformtext? Your test mocks are great for locking multiple things down in one go, but they are a little hard grasp for reviewers.

@archmoj
Copy link
Contributor Author

archmoj commented Dec 12, 2019

Moreover, @archmoj could you share a JSON mock or a codepen of a simple case that uses uniformtext? Your test mocks are great for locking multiple things down in one go, but they are a little hard grasp for reviewers.

Here is a simple demo which also added to the PR description.

src/traces/pie/plot.js Outdated Show resolved Hide resolved
src/traces/pie/plot.js Outdated Show resolved Hide resolved
src/traces/pie/plot.js Outdated Show resolved Hide resolved
- make pie insidetextorientation coerce condition more readable
- no need for extra check before recompute bounding box
- revise uniformtext attribute descriptions
- remove boolean from getTextTransform arguments
- add js doc description
- create and use Lib.ensureUniformFontSize
- make the hide/show logic independent of _module.plot
- refactor textposition coerce logic
- add test for inside-text-orientation coerce logic with various textposition scenarios
- use radial tangential and horizontal in inside-text-orientation keys
- 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
@archmoj
Copy link
Contributor Author

archmoj commented Dec 19, 2019

Before thinking about merging this PR, I'd like to see some jasmine tests to see how things behave when calling relayout (sorry) react with changes in the uniformtext.* attributes.

Good call. React tests for uniformtext mode and minsize for bar, watrefall, funnel, funnelarea and pie as well as insidetextorientation for pie are added in 15ce24d.

@etpinard
Copy link
Contributor

etpinard commented Dec 23, 2019

Awesome work @archmoj - this PR looks good to merge 💃


To sum up, this PR:

  • adds new layout attributes uniformtext.mode and uniformtext.minsize which determines how the font size for various text elements are uniformed between each trace type
  • add new pie and sunburst attribute insidetextorientation which determines the orientation of text inside slices

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging this pull request may close these issues.

consistent text mode [feature-request] pie/sunburst label text direction
3 participants