-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
add 'tickformatstops' #1965
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
add 'tickformatstops' #1965
Conversation
|
Looking solid so far! Thanks very much @apalchys 🎉
At first glance, that sounds right to me. 👍
Yes please!
😏 |
tasks/util/strict_d3.js
Outdated
|
|
||
| if(pathIn === 'd3' && opts.file !== pathToStrictD3Module) { | ||
| pathOut = 'require(\'' + pathToStrictD3Module + '\')'; | ||
| pathOut = 'require(\'' + pathToStrictD3Module.replace(/\\/g, '/') + '\')'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need it for windows users. I've updated the code and added comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
| ].join(' ') | ||
| }, | ||
| tickformatstops: { | ||
| valType: 'any', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do better here.
See for example the layout.slider declaration here. The steps array container is declared using the ✨ special ✨ _isLinkedToArray.
So, this here should look like:
tickformatstops: {
_isLinkedToArray: 'tickformatstop',
dtickrange: {
valType: 'info_array',
// ... declared just like 'range' above
},
values: {
valType: 'any',
// ...
}
}|
|
||
| if(axType !== 'category') { | ||
| var tickFormat = coerce('tickformat'); | ||
| coerce('tickformatstops'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not category?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... also, you'll need to a little more work coercing tickformatstop after having addressed https://github.com/plotly/plotly.js/pull/1965/files#r134489590 - see the layout.slider defaults for an example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not category?
Since dtick is always 1 for category axis type (at least all my tests show it), I still have no idea how tickformatstops should work for it 🤔 Maybe you have any thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, dtickrange wouldn't make sense for category axes. I'm thinking for category axes each tickformatstop item would have:
{
ticktext: [/* */],
tickvals: [/* */]
}just like regular axis-level tickvals and ticktext offering a solution for #1812
The range of each tickformatstop is determined by the tickvals[0] and tickvals[1].
My apologies, I thought I had written that down somewhere before 😏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, but not sure that I got everything right :)
Let's confirm expected behaviour. For example:
I have the following categories:
['a', 'b', 'c', 'd', 'e']
https://codepen.io/anon/pen/brQwjG
then I define tickformatstops:
tickformatstops: [{
ticktext: ['a-c'],
tickvals: ['a', 'c']
}, {
ticktext: ['d-e'],
tickvals: ['d', 'e']
}]
and as result I get only 2 ticks:
['a-c', 'd-e']
Is it correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @apalchys
This seems reasonable.
Question: does this need to be defined manually, or could it be automatically extracted from the values? For example, if we have 300 categories, that there would be a value setting to show only 30 categories at most. And if we are at a zoom level with many of the categories, it would spread them across the axis.
(I apologies if what I say makes little sense in this context. I more often deal with higher level implementations)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@talgalili I see what you say but not sure how to fit it into the proposed API. I am quite new in Plotly community.
@etpinard maybe you have any idea?
Also is my assumption above correct? If yes, I can start the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@apalchys checking about this further with @cpsievert - it appears that what I'm looking for is
the ability to have something like nticks to be respected when tickmode='array'
(see the discussion here: talgalili/heatmaply#78 (comment) )
Is there a way the current work would be extended to deal with this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try to think some more about this issue at some point this week. Sorry for the wait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@etpinard have you had a chance to look into it?
|
Thanks @apalchys - I'm very excited about this feature being added. |
|
Added support for |
| _isLinkedToArray: 'tickformatstop', | ||
|
|
||
| dtickrange: { | ||
| valType: 'data_array', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
info_array please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... just like range
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed, thanks.
| coerce('dtickrange'); | ||
| coerce('value'); | ||
|
|
||
| valuesOut.push(valueOut); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done. Thanks!
🎉
src/traces/carpet/axis_attributes.js
Outdated
| '*%H~%M~%S.%2f* would display *09~15~23.46*' | ||
| ].join(' ') | ||
| }, | ||
| tickformatstops: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind DRYing this up by adding
var axesAttrs = require('../../plots/cartesian/layout_attributes')
// ....
tickformatstops: axesAtttrs.tickformatstops,
// ...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks.
ecda2d4 to
304d96b
Compare
|
added tests |
Great. Are you planning on addressing #1965 (comment) ? |
Yep. I will try to fix everything by tomorrow. |
|
moving discussion to the root level from #1965 (comment)
It seems I am stuck here and not sure what to do next :) where Also for me adding a special logic for |
|
@apalchys who (in this repo) do you think could help you solve this? |
|
@talgalili not sure I know the answer to your question. it is my first PR and @etpinard is my first reviewer. |
|
@apalchys apologies for letting this languish. I'm looking at the open pieces now. In merging master it looks like the issue you encountered with |
I would actually prefer to take the first matching entry. Seems to me this is easier for users to parse, easier and more flexible to generate (you can start from the lowest and specify |
|
TBH I'm not sure what the goal is with adding
@talgalili mentioned:
That to me seems like a separate issue from what we're dealing with here. This PR is about how to format the ticks, not about which ticks to show. There's another long-neglected PR #303 that may be what you're interested in for this purpose: setting a minimum pixel distance between ticks. I think that's probably the only way you can solve this for the |
src/plots/cartesian/axes.js
Outdated
| return getRangeWidth(stop.dtickrange, convertToMs) > getRangeWidth(acc.dtickrange, convertToMs) ? stop : acc; | ||
| } | ||
| }, null); | ||
| tickstop = ax.tickformatstops.find(function(stop) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice and clean - unfortunately it doesn't look like IE supports Array.find, not even in IE11
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
We've also tended to gravitate toward for loops over Array methods for performance reasons. Not a big deal here as this array will be fairly small, but it should still help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, just switched from the project where is supported and don't care about IE11 support.
Replaced with for loop and fixed tests.
Yes, it does. Thanks.
Updated |
|
@apalchys great, thanks for the changes! I linted and updated the baseline image for the new "first" logic. I think this is ready to go (assuming tests pass this time - ignore appveyor) but we're going to wait a few days to merge to master, so we can give v1.31 any bugfixes it needs before adding features (which will go in v1.32.0) |
| }, | ||
| value: { | ||
| valType: 'string', | ||
| dflt: '', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is axis.tickformat: '' a valid format? More precisely, could
tickformatstop: [{
dtickrange: [/* */],
value: ''
}]be used to hide tick labels for some dtick range?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, tickformat: '' gives our default formatting. I suppose we could imagine making our own "hide" tickformat (for date axes you can already hack this with tickformat: ' ' but that doesn't work for numbers) but it seems a bit of a kludgy way to handle a very esoteric edge case.
|
|
||
| var mock = require('@mocks/tickformatstops.json'); | ||
|
|
||
| function getZoomInButton(gd) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we merge this file into axes_test.js? I don't see the need to break src file / test file symmetry here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in 0e6747f
|
|
Related to #1946
This PR adds
tickformatstopsaxis config attribute. The purpose of new attribute is to help customize formatting of axis ticks by dtick value aka "zoom level". The following types of axis support tickformatstops:Usage example:
dtickrangeshould be specified using 2-value array with dtick values.Also it is possible to use
nullas value if start/end of range is not defined. In this case it will be interpred as absolute mix/max value.The
valueshould be validtickformatstringI will add tests later if the implementation looks good.
Question to discuss:
If ranges overlaps, the code takes max applicable range. For example we have the following
dtickrangesReorganization [part 1] #1 [86400000, "M1"]
Reorganization [part 2] #2 ["M1", "M12"]
README and CONTRIBUTING updates #3 ["M12", null]
M1is specified in ranges#1and#2and the code will apply a format string associated with range #2.Is it ok?
logaxis?