-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
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
@@ -18,7 +18,7 @@ module.exports = transformTools.makeRequireTransform('requireTransform', | |||
var pathOut; | |||
|
|||
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!
@@ -448,6 +448,18 @@ module.exports = { | |||
'*%H~%M~%S.%2f* would display *09~15~23.46*' | |||
].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',
// ...
}
}
@@ -40,6 +40,7 @@ module.exports = function handleTickLabelDefaults(containerIn, containerOut, coe | |||
|
|||
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
@@ -265,6 +265,26 @@ module.exports = { | |||
'*%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
tickformatstops
axis 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:
dtickrange
should be specified using 2-value array with dtick values.Also it is possible to use
null
as value if start/end of range is not defined. In this case it will be interpred as absolute mix/max value.The
value
should be validtickformat
stringI 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
dtickranges
Reorganization [part 1] #1 [86400000, "M1"]
Reorganization [part 2] #2 ["M1", "M12"]
README and CONTRIBUTING updates #3 ["M12", null]
M1
is specified in ranges#1
and#2
and the code will apply a format string associated with range #2.Is it ok?
log
axis?