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

Period positioning for Cartesian traces #5074

Merged
merged 35 commits into from
Sep 29, 2020
Merged

Period positioning for Cartesian traces #5074

merged 35 commits into from
Sep 29, 2020

Conversation

archmoj
Copy link
Contributor

@archmoj archmoj commented Aug 13, 2020

Resolves #4912 | Demo

Implementing (x|y)period, (x|y)period0, (x|y)periodalignment on date axes for Cartesian traces namely:
scatter, scattergl, bar, funnel, waterfall, ohlc, candlestick, box, contour, heatmap.

i.e. to position marks along date axes not at a particular instant in time, but at the start/midpoint/end of a well-defined period.

New trace-level attributes:
(x|y)period: Standard duration notation like ‘m’ or millis
(x|y)period0: A specific boundary point timestamp which is used to compute all boundaries.
(x|y)periodalignment: start/middle/end

update:
Please note that this feature is unimplemented for histogram* traces by #5175; whereas one could simply use bins.

@plotly/plotly_js

@nicolaskruchten
Copy link
Member

add (x|y)period0 attributes if needed

These will be needed in the near future for sure but if it makes sense to do them in a separate PR I'm fine with that for now :) The main use-case is for weekly data i.e. xperiod: 1000*60*60*24*7 ... right now is this sunday to sunday or monday to monday or arbitrary? There is also the case of offset quarters i.e. xperiod: 'M3' but with Q1 being Feb/Mar/Apr rather than Jan/Feb/Mar.

@nicolaskruchten
Copy link
Member

Could we please add a mock and CodePen that has the following settings?

  • a bar trace with: points for 2020 Feb 5/Jun 6/Sept 7/Dec 8, xperiod=M3, xperiod0=1990-02-01, xperiodposition=middle
  • a scatter trace with: points for every Monday in 2020, xperiod=72460601000, xperiod0=2020-09-14, xperiodposition=end
  • xaxis: ticklabelmode=period, dtick=M3, tickformat="Q%q"

@archmoj
Copy link
Contributor Author

archmoj commented Sep 14, 2020

  • a bar trace with: points for 2020 Feb 5/Jun 6/Sept 7/Dec 8, xperiod=M3, xperiod0=1990-02-01, xperiodposition=middle

demo1

@nicolaskruchten
Copy link
Member

Excellent, thank you :)

@archmoj
Copy link
Contributor Author

archmoj commented Sep 14, 2020

  • a scatter trace with: points for every Monday in 2020, xperiod=7_24_60_60_1000, xperiod0=2020-09-14, xperiodposition=end

demo2

@archmoj
Copy link
Contributor Author

archmoj commented Sep 14, 2020

  • xaxis: ticklabelmode=period, dtick=M3, tickformat="Q%q"

The codepen in the PR description (as well as other mocks) cover this case.

@alexcjohnson
Copy link
Collaborator

Whew, that's a lot of trace types! Great image tests, then it seems to me we need a hover test with a very detailed hoverformat for each type to show that we get the original date info in hover, rather than the shifted dates.

@archmoj
Copy link
Contributor Author

archmoj commented Sep 17, 2020

Whew, that's a lot of trace types! Great image tests, then it seems to me we need a hover test with a very detailed hoverformat for each type to show that we get the original date info in hover, rather than the shifted dates.

Thanks!
We could possibly support splom & heatmapgl as well.
As discussed the hover labels after 94a164e display the start & end of period of each point. For scatter and bar-like traces (only) one may use hovertemplate to show the original position of each point.

var d = new Date(dateStr);
var year = d.getUTCFullYear();
var month = d.getUTCMonth();
var day = d.getUTCDate();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this approach is still going to have problems with time zones - specifically, I think the day will be wrong this way if you're in the eastern hemisphere.

There would be ways around this, but we've already solved these problems and all sorts of other edge cases with functions in lib/dates so you never directly need Date objects again and all your processing is with millisecond numbers. What I was thinking of in #5074 (comment) was something like:

var v = vals[i];
// guess at how many periods away from base we are
var nEstimated = Math.round((v - base) / (mPeriod * ONEAVGMONTH));
var endTime = incrementMonth(base, mPeriod * nEstimated, calendar);

// iterate to get the exact bounds before and after v
// there may be ways to make this faster, but most of the time
// you'll only execute each loop zero or one time.
while (endTime > v) {
    endTime = incrementMonth(endTime, -mPeriod, calendar);
}
while (endTime <= v) {
    endTime = incrementMonth(endTime, mPeriod, calendar);
}

// now we know endTime is the boundary immediately after v
// so startTime is obtained by incrementing backward one period.
var startTime = incrementMonth(endTime, -mPeriod, calendar);

newVals[i] = (
    isStart ? startTime :
    isEnd ? endTime :
    (startTime + endTime) / 2;
)

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 your review.
Revised in 83b22a0.


function getPeriod0Dflt(period, calendar) {
var n = period / ONEWEEK;
return dateTick0(calendar, Math.round(n) === n);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not blocking, but you can also do (period / ONEWEEK) % 1 === 0

@alexcjohnson
Copy link
Collaborator

Something funny in period_positioning2
Screen Shot 2020-09-28 at 9 24 59 PM
Why doesn't a label appear for 2001? In period_positioning (which has contour instead of histogram2dcontour) the 2001 label does appear.

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.

Looks great. Just a minor question about some missing labels #5074 (comment), and I'd be happy to come back to that later if it's not an easy fix. 💃

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

Successfully merging this pull request may close these issues.

period positioning
3 participants