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

Handle weekday strings in rangebreaks #4661

Merged
merged 9 commits into from
Mar 19, 2020
Merged

Conversation

archmoj
Copy link
Contributor

@archmoj archmoj commented Mar 18, 2020

Follow up of #4614 and #4655

  • convert string bounds e.g. Monday (or 'mon`) to day of week indices between [0, 6].
  • auto default to day of week when using day strings e.g. Monday or 'mon`.
  • update description
  • add jasmine tests

Demo.

@plotly/plotly_js

@archmoj archmoj added this to the v1.53.0 milestone Mar 18, 2020
@@ -161,6 +163,27 @@ function rangebreaksDefaults(itemIn, itemOut, containerOut) {
itemOut.bounds = itemOut.bounds.slice(0, 2);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think you have to do this slice(0, 2) - coerce for info_array already does this.
But if somehow I'm mistaken about that, you'd need to also shorten bnds so you don't lengthen itemOut.bounds again in the loops below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see any place where itemOut.bounds.length is changed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

itemOut.bounds[i] = bnds[i] = q;

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. I revised the new logic in 550a375.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Again, you don't need to worry about the length of bnds at all - coerce handles that so bnds (and itemOut.bounds) is either undefined (since it has no default value) or it's an array of length 2 - or less, I just tested this, if you pass in a shorter array coerce isn't going to pad it since the inner values don't have defaults either, but that's OK, it'll just look like undefined for missing values and get filtered out in the type checks.

Can you please take all these length checks out? We put a lot of effort into making coerce do the right thing so the individual supplyDefaults functions could be simple and readable.

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. Addressed in 84c2a6f.


function indexOfDay(v) {
var str = String(v).substr(0, 3).toLowerCase();
return weekSTR.indexOf(str);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be sped up a bit with an object lookup rather than indexOf

var dayStrToNum = {
    sun: 0,
    mon: 1,
    ...
}

return dayStrToNum[str];

Copy link
Collaborator

Choose a reason for hiding this comment

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

and possibly bail out early if v isn't already a string, rather than converting to a string only to discard it later.

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 calls! Done in db2c3a3.
Curious to know if there is a good article on this?
At the moment, there are quite a number of places that indexOf !== -1 is applied, so please feel free to open an issue for that.
Thanks.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure about an article... you find a lot of people saying "hash lookup is O(1) but indexOf is O(n)" but that's as far as it usually goes.

Here's a jsperf showing the general trends: https://jsperf.com/array-indexof-vs-object-key-lookup2/12 - basically, object lookups hardly scale with the number of keys but indexOf scales linearly. So indexOf can be a nice way to simplify if (a===b || a===c || a===d) -> if ([b,c,d].indexOf(a) !== -1) - but more than a few items and it's better to turn the problem into an object lookup.

Also of course object lookups only support strings... looking forward to when we stop supporting IE and can use Set!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@alexcjohnson thank you!!

@@ -189,3 +210,21 @@ function rangebreaksDefaults(itemIn, itemOut, containerOut) {
}
}
}

// these numbers are one more than what bounds would be mapped to
Copy link
Collaborator

Choose a reason for hiding this comment

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

clever way to avoid having to distinguish 0 from undefined :)

archmoj and others added 2 commits March 18, 2020 14:24
Co-Authored-By: alexcjohnson <johnson.alex.c@gmail.com>
@nicolaskruchten
Copy link
Contributor

I <3 this!! cc @chriddyp

image

case DAY_OF_WEEK :
if(isNumeric(q)) q = Math.floor(q);

q = Math.floor(+q);
Copy link
Collaborator

Choose a reason for hiding this comment

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

redundant - and dangerous - q='' would be turned into 0 for example. We should only cast to number when the value has already passed isNumeric (but might be a numeric string).

Also I don't think we should floor, we should just discard values that aren't integers (ie enabled=false). For one thing, that way if we ever add support for fractional days it won't break any existing behavior.

Can't this numeric validation be pushed into the if(pattern === DAY_OF_WEEK) loop above, and only executed if we didn't already convert from a day name to integer?

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. Fixed in 9a0416a.

Copy link
Collaborator

@alexcjohnson alexcjohnson left a comment

Choose a reason for hiding this comment

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

Alright, I think we've got it! 💃

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.

3 participants