1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-23 02:38:53 -05:00

fix up time format demo

This commit is contained in:
epezent 2020-09-06 14:48:16 -05:00
parent d23bd30a44
commit 901f0558b1
4 changed files with 122 additions and 25 deletions

View File

@ -107,7 +107,6 @@ ImPlotStyle::ImPlotStyle() {
ErrorBarWeight = 1.5f;
DigitalBitHeight = 8;
DigitalBitGap = 4;
AntiAliasedLines = false;
PlotBorderSize = 1;
MinorAlpha = 0.25f;
@ -124,6 +123,9 @@ ImPlotStyle::ImPlotStyle() {
PlotMinSize = ImVec2(300,225);
ImPlot::StyleColorsAuto(this);
AntiAliasedLines = false;
UseLocalTime = false;
}
namespace ImPlot {
@ -646,7 +648,7 @@ inline int GetTimeStep(int max_divs, ImPlotTimeUnit unit) {
return 0;
}
inline time_t MakeGmTime(const struct tm *ptm) {
ImPlotTime MkGmtTime(struct tm *ptm) {
time_t secs = 0;
int year = ptm->tm_year + 1900;
for (int y = 1970; y < year; ++y)
@ -657,21 +659,52 @@ inline time_t MakeGmTime(const struct tm *ptm) {
secs += ptm->tm_hour * 3600;
secs += ptm->tm_min * 60;
secs += ptm->tm_sec;
return secs;
return ImPlotTime(secs,0);
}
inline tm* GetGmTime(const time_t* time, tm* tm)
tm* GetGmtTime(const ImPlotTime& t, tm* ptm)
{
#ifdef _WIN32
if (gmtime_s(tm, time) == 0)
return tm;
if (gmtime_s(ptm, &t.S) == 0)
return ptm;
else
return NULL;
#else
return gmtime_r(time, tm);
return gmtime_r(&t.S, ptm);
#endif
}
ImPlotTime MkLocTime(struct tm *ptm) {
ImPlotTime t;
t.S = mktime(ptm);
return t;
}
tm* GetLocTime(const ImPlotTime& t, tm* ptm) {
#ifdef _WIN32
if (localtime_s(ptm, &t.S) == 0)
return ptm;
else
return NULL;
#else
return localtime_r(&t.S, ptm);
#endif
}
inline ImPlotTime MkTime(struct tm *ptm) {
if (GetStyle().UseLocalTime)
return MkLocTime(ptm);
else
return MkGmtTime(ptm);
}
inline tm* GetTime(const ImPlotTime& t, tm* ptm) {
if (GetStyle().UseLocalTime)
return GetLocTime(t,ptm);
else
return GetGmtTime(t,ptm);
}
ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count) {
tm& Tm = GImPlot->Tm;
ImPlotTime t_out = t;
@ -683,7 +716,7 @@ ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count) {
case ImPlotTimeUnit_Hr: t_out.S += count * 3600; break;
case ImPlotTimeUnit_Day: t_out.S += count * 86400; break;
case ImPlotTimeUnit_Mo: for (int i = 0; i < count; ++i) { // this might have a bug
GetGmTime(&t.S, &Tm);
GetTime(t_out, &Tm);
t_out.S += 86400 * GetDaysInMonth(Tm.tm_year + 1900, Tm.tm_mon);
}
break;
@ -701,8 +734,7 @@ ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count) {
}
ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
GetGmTime(&t.S, &GImPlot->Tm);
GImPlot->Tm.tm_isdst = -1;
GetTime(t, &GImPlot->Tm);
switch (unit) {
case ImPlotTimeUnit_S: return ImPlotTime(t.S, 0);
case ImPlotTimeUnit_Ms: return ImPlotTime(t.S, (t.Us / 1000) * 1000);
@ -714,7 +746,7 @@ ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
case ImPlotTimeUnit_Min: GImPlot->Tm.tm_sec = 0; break;
default: return t;
}
return ImPlotTime(MakeGmTime(&GImPlot->Tm),0);
return MkTime(&GImPlot->Tm);
}
ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
@ -731,7 +763,7 @@ ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
int GetYear(const ImPlotTime& t) {
tm& Tm = GImPlot->Tm;
GetGmTime(&t.S, &Tm);
GetTime(t, &Tm);
return Tm.tm_year + 1900;
}
@ -747,14 +779,12 @@ ImPlotTime MakeYear(int year) {
Tm.tm_mon = 0;
Tm.tm_year = yr;
Tm.tm_sec = 0;
Tm.tm_isdst = -1;
time_t s = MakeGmTime(&Tm);
return ImPlotTime(s);
return MkTime(&Tm);
}
int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt) {
tm& Tm = GImPlot->Tm;
GetGmTime(&t.S, &Tm);
GetTime(t, &Tm);
const char* ap = Tm.tm_hour < 12 ? "am" : "pm";
const int us = t.Us % 1000;

View File

@ -217,7 +217,6 @@ struct ImPlotStyle {
float DigitalBitHeight; // = 8, digital channels bit height (at y = 1.0f) in pixels
float DigitalBitGap; // = 4, digital channels bit padding gap in pixels
// plot styling variables
bool AntiAliasedLines; // = false, enable global anti-aliasing on plot lines (overrides ImPlotFlags_AntiAliased)
float PlotBorderSize; // = 1, line thickness of border around plot area
float MinorAlpha; // = 0.25 alpha multiplier applied to minor axis grid lines
ImVec2 MajorTickLen; // = 10,10 major tick lengths for X and Y axes
@ -231,7 +230,11 @@ struct ImPlotStyle {
ImVec2 LegendPadding; // = 10,10 legend padding from top-left of plot
ImVec2 InfoPadding; // = 10,10 padding between plot edge and interior info text
ImVec2 PlotMinSize; // = 300,225 minimum size plot frame can be when shrunk
// colors
ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors
// settings/flags
bool AntiAliasedLines; // = false, enable global anti-aliasing on plot lines (overrides ImPlotFlags_AntiAliased)
bool UseLocalTime; // = false, axis labels will be formatted for your timezone when ImPlotAxisFlag_Time is enabled
ImPlotStyle();
};

View File

@ -26,6 +26,7 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _MSC_VER
#define sprintf sprintf_s
@ -124,6 +125,25 @@ struct RollingBuffer {
}
};
// Huge data used by Time Formatting example (~500 MB allocation!)
struct HugeTimeData {
HugeTimeData(double min) {
Ts = new double[Size];
Ys = new double[Size];
for (int i = 0; i < Size; ++i) {
Ts[i] = min + i;
Ys[i] = GetY(Ts[i]);
}
}
~HugeTimeData() { delete[] Ts; delete[] Ys; }
static double GetY(double t) {
return 0.5 + 0.25 * sin(t/86400/12) + 0.005 * sin(t/3600);
}
double* Ts;
double* Ys;
static const int Size = 60*60*24*366;
};
void ShowDemoWindow(bool* p_open) {
t_float DEMO_TIME = (t_float)ImGui::GetTime();
static bool show_imgui_metrics = false;
@ -591,11 +611,42 @@ void ShowDemoWindow(bool* p_open) {
}
}
if (ImGui::CollapsingHeader("Time Formatted Axes")) {
static double min = 1577836800; // 01/01/2020 @ 12:00:00am (UTC)
static double max = 1609459200; // 01/01/2021 @ 12:00:00am (UTC)
ImPlot::SetNextPlotLimits(min,max,0,1);
if (ImPlot::BeginPlot("##Time", "UTC Time", "Y-Axis", ImVec2(-1,0), 0, ImPlotAxisFlags_Time)) {
static double t_min = 1577836800; // 01/01/2020 @ 12:00:00am (UTC)
static double t_max = 1609459200; // 01/01/2021 @ 12:00:00am (UTC)
ImGui::BulletText("When ImPlotAxisFlags_Time is enabled on the X-Axis, values are interpreted as\n"
"UNIX timestamps in seconds and axis labels are formated as date/time.");
ImGui::BulletText("By default, labels are in UTC time but can be set to use local time instead.");
ImGui::Checkbox("Use Local Time",&ImPlot::GetStyle().UseLocalTime);
static HugeTimeData* data = NULL;
if (data == NULL) {
ImGui::SameLine();
if (ImGui::Button("Generate Huge Data (~500MB!)")) {
static HugeTimeData sdata(t_min);
data = &sdata;
}
}
ImPlot::SetNextPlotLimits(t_min,t_max,0,1);
if (ImPlot::BeginPlot("##Time", "Time", "Value", ImVec2(-1,0), 0, ImPlotAxisFlags_Time)) {
if (data != NULL) {
// downsample our data
int downsample = (int)ImPlot::GetPlotLimits().X.Size() / 1000 + 1;
int start = (int)(ImPlot::GetPlotLimits().X.Min - t_min);
start = start < 0 ? 0 : start > HugeTimeData::Size - 1 ? HugeTimeData::Size - 1 : start;
int end = (int)(ImPlot::GetPlotLimits().X.Max - t_min) + 1000;
end = end < 0 ? 0 : end > HugeTimeData::Size - 1 ? HugeTimeData::Size - 1 : end;
int size = (end - start)/downsample;
// plot it
ImPlot::PlotLine("Time Series", &data->Ts[start], &data->Ys[start], size, 0, sizeof(double)*downsample);
}
// plot time now
double t_now = (double)time(0);
double y_now = HugeTimeData::GetY(t_now);
ImPlot::PlotScatter("Now",&t_now,&y_now,1);
ImPlot::EndPlot();
}
}
@ -1133,8 +1184,9 @@ void ShowDemoWindow(bool* p_open) {
static ImVec4 bearCol = ImVec4(0.853f, 0.050f, 0.310f, 1.000f);
ImGui::SameLine(); ImGui::ColorEdit4("##Bull", &bullCol.x, ImGuiColorEditFlags_NoInputs);
ImGui::SameLine(); ImGui::ColorEdit4("##Bear", &bearCol.x, ImGuiColorEditFlags_NoInputs);
ImPlot::GetStyle().UseLocalTime = false;
ImPlot::SetNextPlotLimits(1546300800, 1571961600, 1250, 1600);
if (ImPlot::BeginPlot("Candlestick Chart","Day","USD",ImVec2(-1,-1),0,ImPlotAxisFlags_Time)) {
if (ImPlot::BeginPlot("Candlestick Chart","Day","USD",ImVec2(-1,0),0,ImPlotAxisFlags_Time)) {
MyImPlot::PlotCandlestick("GOOGL",dates, opens, closes, lows, highs, 218, tooltip, 0.25f, bullCol, bearCol);
ImPlot::EndPlot();
}

View File

@ -577,7 +577,7 @@ struct ImPlotAxisScale
}
};
/// Two part time struct.
/// Two part timestamp struct.
struct ImPlotTime {
time_t S; // second part
int Us; // microsecond part
@ -777,8 +777,7 @@ inline T OffsetAndStride(const T* data, int idx, int count, int offset, int stri
// Time Utils
//-----------------------------------------------------------------------------
// NB: These functions only work if there is a current ImPlotContext because the
// internal tm struct is owned by the context!
// Returns true if year is leap year (366 days long)
inline bool IsLeapYear(int year) {
@ -793,6 +792,19 @@ inline int GetDaysInMonth(int year, int month) {
return days[month] + (int)(month == 1 && IsLeapYear(year));
}
// Make a timestamp from a tm struct expressed as a UTC time (i.e. GMT timezone).
ImPlotTime MkGmtTime(struct tm *ptm);
// Make a tm struct from a timestamp expressed as a UTC time (i.e. GMT timezone).
tm* GetGmtTime(const ImPlotTime& t, tm* ptm);
// Make a timestamp from a tm struct expressed as a local time.
ImPlotTime MkLocTime(struct tm *ptm);
// Make a tm struct from a timestamp expressed as a local time.
tm* GetLocTime(const ImPlotTime& t, tm* ptm);
// NB: These functions only work if there is a current ImPlotContext because the
// internal tm struct is owned by the context!
// Adds time to a timestamp. #count must be positive!
ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count);
// Rounds a timestamp down to nearest.