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

Address SAM issue 289 - ignore leap years in timeseries axis #179

Merged
merged 6 commits into from
Nov 8, 2024
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 41 additions & 17 deletions src/plot/plaxis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,14 +669,25 @@ void wxPLTimeAxis::RecalculateTicksAndLabel() {
//We need to figure out whether we are looking at hours, days, or months, and label the graph appropriately.
wxDateTime timeKeeper(1, wxDateTime::Jan, 1971, 0, 0, 0); // works all time zones


double world_len = m_max - m_min;
double time = m_min;

// to skip leap years (SAM issue 289) - scale to first year
int m_min_offset = m_min / 8760;
double m_min_scaled = (double)((int)m_min % 8760); // m_min and m_max always based on 8760 (365 days with no leap years)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Likely a different issue, but there's hopes to actually handle leap days in the calculations this year. This would likely require an additional flag to this function to scale to 8784 if a leap year is detected, and base each year on a leap year instead (8784 * timesteps_per_hour * nyears).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Likely a different issue, but there's hopes to actually handle leap days in the calculations this year. This would likely require an additional flag to this function to scale to 8784 if a leap year is detected, and base each year on a leap year instead (8784 * timesteps_per_hour * nyears).

Good catch and way to use existing code. If we do leap years, we can probably assign a base year and then use the full wxDateTime class to handle as it was designed.

double m_max_scaled = (double)((int)m_max % 8760); // m_min and m_max always based on 8760 (365 days with no leap years)
if (m_max_scaled <= m_min_scaled) m_max_scaled += 8760; // handle year end points

time = m_min_scaled;

timeKeeper.Add(wxTimeSpan::Minutes(60 * time));

// Handle DST.
if (timeKeeper.IsDST())
timeKeeper.Subtract(wxTimeSpan::Hour());


if (world_len <= 72) {
if (floor(time) != time) {
timeKeeper.Add(wxTimeSpan::Minutes(60 * (floor(time) + 2 - time)));
Expand All @@ -694,17 +705,18 @@ void wxPLTimeAxis::RecalculateTicksAndLabel() {
// Less than 2 days. Need to label time.

wxDateTime timeKeeper2(timeKeeper.GetTicks());
timeKeeper2.Add(wxTimeSpan::Minutes(60 * world_len));
timeKeeper2.Add(wxTimeSpan::Minutes(60 * world_len)); // TODO 289 - check scaling
sjanzou marked this conversation as resolved.
Show resolved Hide resolved
timeKeeper2.Subtract(wxTimeSpan::Minute()); //If it is 0:00 the next day, its really the same day.
if (timeKeeper.IsDST() && !timeKeeper2.IsDST()) {
timeKeeper.Add(wxTimeSpan::Hour());
timeKeeper2.Add(wxTimeSpan::Hour());
}

if (timeKeeper.GetDay() == timeKeeper2.GetDay())
m_timeLabel = timeKeeper.Format("%b %d");
else if (timeKeeper.GetMonth() == timeKeeper2.GetMonth())
m_timeLabel = timeKeeper.Format("%b %d") + "-" + timeKeeper2.Format("%d"); // TODO fix year 2 Feb 28-01 (always been the case)
sjanzou marked this conversation as resolved.
Show resolved Hide resolved
else
m_timeLabel = timeKeeper.Format("%b %d") + "-" + timeKeeper2.Format("%d");
m_timeLabel = timeKeeper.Format("%b %d") + "-" + timeKeeper2.Format("%b %d");

do {
m_tickList.push_back(TickData(time, timeKeeper.Format("%H"), TickData::LARGE));
Expand Down Expand Up @@ -741,13 +753,18 @@ void wxPLTimeAxis::RecalculateTicksAndLabel() {
}

do {
m_tickList.push_back(TickData(time, timeKeeper.Format("%b %d"), TickData::NONE));
auto str = timeKeeper.Format("%b %d");
// m_tickList.push_back(TickData(time, str, TickData::NONE));
m_tickList.push_back(TickData(time + m_min_offset*8760, str, TickData::NONE));
time += 12;
if (time < m_max)
m_tickList.push_back(TickData(time, wxEmptyString, TickData::LARGE)); // midnight
// if (time < m_max)
if (time < m_max_scaled)
m_tickList.push_back(TickData(time + m_min_offset * 8760, wxEmptyString, TickData::LARGE)); // midnight
// m_tickList.push_back(TickData(time, wxEmptyString, TickData::LARGE)); // midnight
time += 12;
timeKeeper.Add(wxTimeSpan::Hours(24));
} while (time < m_max);
} while (time < m_max_scaled);
// } while (time < m_max);
} else {
//Assume day endpoints.
//Only Label Months
Expand All @@ -763,13 +780,16 @@ void wxPLTimeAxis::RecalculateTicksAndLabel() {
timeKeeper2.Add(wxTimeSpan::Day());
}

m_tickList.push_back(TickData(time + daysVisibleInMonth * 24.0f, wxEmptyString, TickData::LARGE));
int endMonthHours = time + daysVisibleInMonth * 24.0f; //00:00 on first of next month.
// m_tickList.push_back(TickData(time + daysVisibleInMonth * 24.0f, wxEmptyString, TickData::LARGE));
m_tickList.push_back(TickData(time + daysVisibleInMonth * 24.0f + m_min_offset * 8760, wxEmptyString, TickData::LARGE));
int endMonthHours = time + m_min_offset * 8760 + daysVisibleInMonth * 24.0f; //00:00 on first of next month.

if (daysVisibleInMonth >= 7) {
//Label the month if it has more than seven days visible.
// m_tickList.push_back(
// TickData(time + (daysVisibleInMonth * 24.0f / 2.0f), timeKeeper.Format("%b"), TickData::NONE));
m_tickList.push_back(
TickData(time + (daysVisibleInMonth * 24.0f / 2.0f), timeKeeper.Format("%b"), TickData::NONE));
TickData(time + (daysVisibleInMonth * 24.0f / 2.0f) + m_min_offset * 8760, timeKeeper.Format("%b"), TickData::NONE));
}

timeKeeper2.SetDay(wxDateTime::GetNumberOfDays(timeKeeper2.GetMonth()) / 2); //Middle of the second month.
Expand All @@ -779,24 +799,27 @@ void wxPLTimeAxis::RecalculateTicksAndLabel() {
//Loop, labeling months
//While end of month is visible.
do {
m_tickList.push_back(TickData(time, timeKeeper2.Format("%b"), TickData::NONE));
// m_tickList.push_back(TickData(time, timeKeeper2.Format("%b"), TickData::NONE));
m_tickList.push_back(TickData(time + m_min_offset * 8760, timeKeeper2.Format("%b"), TickData::NONE));
timeKeeper.Set(timeKeeper2.GetTicks()); //timeKeeper is position of last label.
timeKeeper2.Add(wxDateSpan::Month());
timeKeeper2.SetDay(1); //timeKeeper2 is day 1 of next month.

m_tickList.push_back(TickData(time + timeKeeper2.Subtract(timeKeeper).GetHours(), wxEmptyString,
TickData::LARGE)); //Adds tick at this pos. (start-month)
// m_tickList.push_back(TickData(time + timeKeeper2.Subtract(timeKeeper).GetHours(), wxEmptyString,
// TickData::LARGE)); //Adds tick at this pos. (start-month)
m_tickList.push_back(TickData(time + timeKeeper2.Subtract(timeKeeper).GetHours() + m_min_offset * 8760, wxEmptyString,
TickData::LARGE)); //Adds tick at this pos. (start-month)
timeKeeper2.SetDay(wxDateTime::GetNumberOfDays(timeKeeper2.GetMonth()) / 2); //timeKeeper2 mid month
time += timeKeeper2.Subtract(timeKeeper).GetHours(); //hours midMonth.
endMonthHours += 24 * wxDateTime::GetNumberOfDays(timeKeeper2.GetMonth());
// } while (endMonthHours < m_max_scaled);
} while (endMonthHours < m_max);

//timeKeeper holds the middle of last month we actually labelled.
//We still need to label the last month if it has more than 7 days showing.
timeKeeper.Add(wxDateSpan::Month());
timeKeeper.SetDay(1); // First not-yet-labeled month
time = endMonthHours -
24 * wxDateTime::GetNumberOfDays(timeKeeper.GetMonth()); //00:00 on first of not-yet-labeled month.
time = endMonthHours - 24 * wxDateTime::GetNumberOfDays(timeKeeper.GetMonth()); //00:00 on first of not-yet-labeled month.

//Take care of fractional days at the max.
timeKeeper2 = wxDateTime(01, wxDateTime::Jan, 1970, 00, 00, 00);
Expand All @@ -808,15 +831,16 @@ void wxPLTimeAxis::RecalculateTicksAndLabel() {
time += daysVisibleInMonth * 24.0f;
timeKeeper2.Add(wxTimeSpan::Minutes(daysVisibleInMonth * 24.0f * 60.0f));
while (time < m_max && timeKeeper2.GetMonth() == timeKeeper.GetMonth()) {
// while (time < m_max_scaled && timeKeeper2.GetMonth() == timeKeeper.GetMonth()) {
daysVisibleInMonth += 1;
timeKeeper2.Add(wxTimeSpan::Day());
time += 24;
}

if (daysVisibleInMonth >= 7) {
//Label the month if it has more than seven days visible.
m_tickList.push_back(
TickData(time - (daysVisibleInMonth * 24.0f / 2.0f), timeKeeper.Format("%b"), TickData::NONE));
m_tickList.push_back(TickData(time - (daysVisibleInMonth * 24.0f / 2.0f), timeKeeper.Format("%b"), TickData::NONE));
// m_tickList.push_back(TickData(time - (daysVisibleInMonth * 24.0f / 2.0f) + m_min_offset * 8760, timeKeeper.Format("%b third"), TickData::NONE));
}
}

Expand Down