diff --git a/implot.cpp b/implot.cpp index 98a3a17..23de207 100644 --- a/implot.cpp +++ b/implot.cpp @@ -814,6 +814,21 @@ ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit) { return t.S - t1.S < t2.S - t.S ? t1 : t2; } +ImPlotTime CombineDateTime(const ImPlotTime& date_part, const ImPlotTime& tod_part) { + tm& Tm = GImPlot->Tm; + GetTime(date_part, &GImPlot->Tm); + int y = Tm.tm_year; + int m = Tm.tm_mon; + int d = Tm.tm_mday; + GetTime(tod_part, &GImPlot->Tm); + Tm.tm_year = y; + Tm.tm_mon = m; + Tm.tm_mday = d; + ImPlotTime t = MkTime(&Tm); + t.Us = tod_part.Us; + return t; +} + int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt) { tm& Tm = GImPlot->Tm; GetTime(t, &Tm); @@ -1685,7 +1700,7 @@ inline void EndDisabledControls(bool cond) { } } -inline void ShowAxisContextMenu(ImPlotAxisState& state, bool time_allowed) { +void ShowAxisContextMenu(ImPlotAxisState& state, bool time_allowed) { ImGui::PushItemWidth(75); ImPlotAxis& axis = *state.Axis; @@ -1708,12 +1723,17 @@ inline void ShowAxisContextMenu(ImPlotAxisState& state, bool time_allowed) { ImGui::SameLine(); BeginDisabledControls(state.LockMin); if (ImGui::BeginMenu("Min Time")) { - if (ShowDatePicker("minpick",&axis.PickerLevel,&axis.PickerTimeMin,&tmin,&tmax)) { - if (axis.PickerTimeMin >= tmax) { - tmax = AddTime(axis.PickerTimeMin, ImPlotTimeUnit_Day, 1); - axis.SetMax(tmax.ToDouble()); - } - axis.SetMin(axis.PickerTimeMin.ToDouble()); + if (ShowTimePicker("mintime", &tmin)) { + if (tmin >= tmax) + tmax = AddTime(tmin, ImPlotTimeUnit_S, 1); + axis.SetRange(tmin.ToDouble(),tmax.ToDouble()); + } + ImGui::Separator(); + if (ShowDatePicker("mindate",&axis.PickerLevel,&axis.PickerTimeMin,&tmin,&tmax)) { + tmin = CombineDateTime(axis.PickerTimeMin, tmin); + if (tmin >= tmax) + tmax = AddTime(tmin, ImPlotTimeUnit_S, 1); + axis.SetRange(tmin.ToDouble(), tmax.ToDouble()); } ImGui::EndMenu(); } @@ -1726,12 +1746,17 @@ inline void ShowAxisContextMenu(ImPlotAxisState& state, bool time_allowed) { ImGui::SameLine(); BeginDisabledControls(state.LockMax); if (ImGui::BeginMenu("Max Time")) { - if (ShowDatePicker("macpick",&axis.PickerLevel,&axis.PickerTimeMax,&tmin,&tmax)) { - if (axis.PickerTimeMax <= tmin) { - tmin = AddTime(axis.PickerTimeMax, ImPlotTimeUnit_Day, -1); - axis.SetMin(tmin.ToDouble()); - } - axis.SetMax(axis.PickerTimeMax.ToDouble()); + if (ShowTimePicker("maxtime", &tmax)) { + if (tmax <= tmin) + tmin = AddTime(tmax, ImPlotTimeUnit_S, -1); + axis.SetRange(tmin.ToDouble(),tmax.ToDouble()); + } + ImGui::Separator(); + if (ShowDatePicker("maxdate",&axis.PickerLevel,&axis.PickerTimeMax,&tmin,&tmax)) { + tmax = CombineDateTime(axis.PickerTimeMax, tmax); + if (tmax <= tmin) + tmin = AddTime(tmax, ImPlotTimeUnit_S, -1); + axis.SetRange(tmin.ToDouble(), tmax.ToDouble()); } ImGui::EndMenu(); } diff --git a/implot_demo.cpp b/implot_demo.cpp index 5237bce..064451b 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -623,7 +623,7 @@ void ShowDemoWindow(bool* p_open) { } ImPlot::SetNextPlotLimits(t_min,t_max,0,1); - if (ImPlot::BeginPlot("##Time", "Time", "Value", ImVec2(-1,0), 0, ImPlotAxisFlags_Time)) { + if (ImPlot::BeginPlot("##Time", NULL, NULL, ImVec2(-1,0), 0, ImPlotAxisFlags_Time)) { if (data != NULL) { // downsample our data int downsample = (int)ImPlot::GetPlotLimits().X.Size() / 1000 + 1; diff --git a/implot_internal.h b/implot_internal.h index 6d7fbf7..4341286 100644 --- a/implot_internal.h +++ b/implot_internal.h @@ -196,7 +196,7 @@ enum ImPlotTimeFmt_ { ImPlotTimeFmt_DayMoYr, // 10/3/91 ImPlotTimeFmt_DayMoYrHrMin, // 10/3/91 7:21pm ImPlotTimeFmt_DayMoYrHrMinS, // 10/3/91 7:21:29pm - ImPlotTimeFmt_DayMoYrHrMinSUs, // 10/3/91 7:21:29.123456pm + ImPlotTimeFmt_DayMoYrHrMinSUs, // 10/3/1991 7:21:29.123456pm ImPlotTimeFmt_MoYr, // Oct 1991 ImPlotTimeFmt_Mo, // Oct ImPlotTimeFmt_Yr // 1991 @@ -646,6 +646,9 @@ IMPLOT_API ImPlotState* GetCurrentPlot(); // Busts the cache for every plot in the current context IMPLOT_API void BustPlotCache(); +// Shows a plot's context menu. +IMPLOT_API void ShowPlotContextMenu(ImPlotState& plot); + //----------------------------------------------------------------------------- // [SECTION] Item Utils //----------------------------------------------------------------------------- @@ -696,6 +699,9 @@ IMPLOT_API void PushLinkedAxis(ImPlotAxis& axis); // Updates axis internal range from points for linked axes. IMPLOT_API void PullLinkedAxis(ImPlotAxis& axis); +// Shows an axis's context menu. +IMPLOT_API void ShowAxisContextMenu(ImPlotAxisState& state, bool time_allowed = false); + //----------------------------------------------------------------------------- // [SECTION] Legend Utils //----------------------------------------------------------------------------- @@ -829,16 +835,18 @@ IMPLOT_API ImPlotTime MakeYear(int year); // Get year component from timestamp [1970-3000] IMPLOT_API int GetYear(const ImPlotTime& t); -// Adds time to a timestamp. #count must be positive! +// Adds or subtracts time from a timestamp. #count > 0 to add, < 0 to subtract. IMPLOT_API ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count); -// Rounds a timestamp down to nearest. +// Rounds a timestamp down to nearest unit. IMPLOT_API ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit); // Rounds a timestamp up to the nearest unit. IMPLOT_API ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit); // Rounds a timestamp up or down to the nearest unit. IMPLOT_API ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit); +// Combines the date of one timestamp with the time-of-day of another timestamp. +IMPLOT_API ImPlotTime CombineDateTime(const ImPlotTime& date_part, const ImPlotTime& tod_part); -// Formates a timestamp t into a buffer according to fmt. +// Formulates a timestamp t into a buffer according to fmt. IMPLOT_API int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt); // Prints a timestamp to console IMPLOT_API void PrintTime(const ImPlotTime& t, ImPlotTimeFmt fmt = ImPlotTimeFmt_DayMoYrHrMinSUs);