mirror of
https://github.com/gwm17/implot.git
synced 2024-11-13 22:48:50 -05:00
convert to ImPlotTime usage
This commit is contained in:
parent
f92625a462
commit
d3ea373cc7
140
implot.cpp
140
implot.cpp
|
@ -617,9 +617,9 @@ inline int LowerBoundStep(int max_divs, const int* divs, const int* step, int si
|
||||||
|
|
||||||
inline int GetTimeStep(int max_divs, ImPlotTimeUnit unit) {
|
inline int GetTimeStep(int max_divs, ImPlotTimeUnit unit) {
|
||||||
if (unit == ImPlotTimeUnit_Ms || unit == ImPlotTimeUnit_Us) {
|
if (unit == ImPlotTimeUnit_Ms || unit == ImPlotTimeUnit_Us) {
|
||||||
static const int step[] = {500,250,200,100,50,25,20,10,5};
|
static const int step[] = {500,250,200,100,50,25,20,10,5,2,1};
|
||||||
static const int divs[] = {2,4,5,10,20,40,50,100,200};
|
static const int divs[] = {2,4,5,10,20,40,50,100,200,500,1000};
|
||||||
return LowerBoundStep(max_divs, divs, step, 9);
|
return LowerBoundStep(max_divs, divs, step, 11);
|
||||||
}
|
}
|
||||||
if (unit == ImPlotTimeUnit_S || unit == ImPlotTimeUnit_Min) {
|
if (unit == ImPlotTimeUnit_S || unit == ImPlotTimeUnit_Min) {
|
||||||
static const int step[] = {30,15,10,5,1};
|
static const int step[] = {30,15,10,5,1};
|
||||||
|
@ -670,34 +670,34 @@ inline tm* GetGmTime(const time_t* time, tm* tm)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
double AddTime(double t, ImPlotTimeUnit unit, int count) {
|
ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count) {
|
||||||
|
ImPlotTime t_out = t;
|
||||||
switch(unit) {
|
switch(unit) {
|
||||||
case ImPlotTimeUnit_Us: return t + count * 0.000001;
|
case ImPlotTimeUnit_Us: return ImPlotTime(t.S, t.Us + count);
|
||||||
case ImPlotTimeUnit_Ms: return t + count * 0.001;
|
case ImPlotTimeUnit_Ms: return ImPlotTime(t.S, t.Us + count * 1000);
|
||||||
case ImPlotTimeUnit_S: return t + count;
|
case ImPlotTimeUnit_S: t_out.S += count; break;
|
||||||
case ImPlotTimeUnit_Min: return t + count * 60;
|
case ImPlotTimeUnit_Min: t_out.S += count * 60; break;
|
||||||
case ImPlotTimeUnit_Hr: return t + count * 3600;
|
case ImPlotTimeUnit_Hr: t_out.S += count * 3600; break;
|
||||||
case ImPlotTimeUnit_Day: return t + count * 86400;
|
case ImPlotTimeUnit_Day: t_out.S += count * 86400; break;
|
||||||
case ImPlotTimeUnit_Yr: count *= 12; // fall-through
|
case ImPlotTimeUnit_Yr: count *= 12; // fall-through
|
||||||
case ImPlotTimeUnit_Mo: for (int i = 0; i < count; ++i) {
|
case ImPlotTimeUnit_Mo: for (int i = 0; i < count; ++i) {
|
||||||
time_t s = (time_t)t;
|
GetGmTime(&t.S, &GImPlot->Tm);
|
||||||
GetGmTime(&s, &GImPlot->Tm);
|
|
||||||
int days = GetDaysInMonth(GImPlot->Tm.tm_year, GImPlot->Tm.tm_mon);
|
int days = GetDaysInMonth(GImPlot->Tm.tm_year, GImPlot->Tm.tm_mon);
|
||||||
t = AddTime(t, ImPlotTimeUnit_Day, days);
|
t_out = AddTime(t_out, ImPlotTimeUnit_Day, days);
|
||||||
}
|
}
|
||||||
return t;
|
break;
|
||||||
default: return t;
|
default: break;
|
||||||
}
|
}
|
||||||
|
return t_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
double FloorTime(double t, ImPlotTimeUnit unit) {
|
ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
|
||||||
time_t s = (time_t)t;
|
GetGmTime(&t.S, &GImPlot->Tm);
|
||||||
GetGmTime(&s, &GImPlot->Tm);
|
|
||||||
GImPlot->Tm.tm_isdst = -1;
|
GImPlot->Tm.tm_isdst = -1;
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case ImPlotTimeUnit_S: return (double)s;
|
case ImPlotTimeUnit_S: return ImPlotTime(t.S, 0);
|
||||||
case ImPlotTimeUnit_Ms: return floor(t * 1000) / 1000;
|
case ImPlotTimeUnit_Ms: return ImPlotTime(t.S, (t.Us / 1000) * 1000);
|
||||||
case ImPlotTimeUnit_Us: return floor(t * 1000000) / 1000000;
|
case ImPlotTimeUnit_Us: return t;
|
||||||
case ImPlotTimeUnit_Yr: GImPlot->Tm.tm_mon = 0; // fall-through
|
case ImPlotTimeUnit_Yr: GImPlot->Tm.tm_mon = 0; // fall-through
|
||||||
case ImPlotTimeUnit_Mo: GImPlot->Tm.tm_mday = 1; // fall-through
|
case ImPlotTimeUnit_Mo: GImPlot->Tm.tm_mday = 1; // fall-through
|
||||||
case ImPlotTimeUnit_Day: GImPlot->Tm.tm_hour = 0; // fall-through
|
case ImPlotTimeUnit_Day: GImPlot->Tm.tm_hour = 0; // fall-through
|
||||||
|
@ -705,28 +705,28 @@ double FloorTime(double t, ImPlotTimeUnit unit) {
|
||||||
case ImPlotTimeUnit_Min: GImPlot->Tm.tm_sec = 0; break;
|
case ImPlotTimeUnit_Min: GImPlot->Tm.tm_sec = 0; break;
|
||||||
default: return t;
|
default: return t;
|
||||||
}
|
}
|
||||||
s = MakeGmTime(&GImPlot->Tm);
|
return ImPlotTime(MakeGmTime(&GImPlot->Tm),0);
|
||||||
return (double)s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double CeilTime(double t, ImPlotTimeUnit unit) {
|
ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
|
||||||
return AddTime(FloorTime(t, unit), unit, 1);
|
return AddTime(FloorTime(t, unit), unit, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
double RoundTime(double t, ImPlotTimeUnit unit) {
|
ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
|
||||||
double t1 = FloorTime(t, unit);
|
ImPlotTime t1 = FloorTime(t, unit);
|
||||||
double t2 = AddTime(t1,unit,1);
|
ImPlotTime t2 = AddTime(t1,unit,1);
|
||||||
return t - t1 < t2 - t ? t1 : t2;
|
if (t1.S == t2.S)
|
||||||
|
return t.Us - t1.Us < t2.Us - t.Us ? t1 : t2;
|
||||||
|
return t.S - t1.S < t2.S - t.S ? t1 : t2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetYear(double t) {
|
int GetYear(const ImPlotTime& t) {
|
||||||
time_t s = (time_t)t;
|
|
||||||
tm& Tm = GImPlot->Tm;
|
tm& Tm = GImPlot->Tm;
|
||||||
GetGmTime(&s, &Tm);
|
GetGmTime(&t.S, &Tm);
|
||||||
return Tm.tm_year + 1900;
|
return Tm.tm_year + 1900;
|
||||||
}
|
}
|
||||||
|
|
||||||
double MakeYear(int year) {
|
ImPlotTime MakeYear(int year) {
|
||||||
int yr = year - 1900;
|
int yr = year - 1900;
|
||||||
if (yr < 0)
|
if (yr < 0)
|
||||||
yr = 0;
|
yr = 0;
|
||||||
|
@ -739,17 +739,13 @@ double MakeYear(int year) {
|
||||||
return (double)s;
|
return (double)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FormatTime(double t, char* buffer, int size, ImPlotTimeFmt fmt) {
|
int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt) {
|
||||||
printf("%.6f\n",t);
|
|
||||||
time_t s = (time_t)t;
|
|
||||||
int ms = (int)(t * 1000 - floor(t) * 1000);
|
|
||||||
ms = ms % 10 == 9 ? ms + 1 : ms; // don't like this
|
|
||||||
int us = (int)(t * 1000000 - floor(t) * 1000000);
|
|
||||||
us = us % 10 == 9 ? us + 1 : us; // don't like this
|
|
||||||
tm& Tm = GImPlot->Tm;
|
tm& Tm = GImPlot->Tm;
|
||||||
GetGmTime(&s, &Tm);
|
GetGmTime(&t.S, &Tm);
|
||||||
|
|
||||||
const char* ap = Tm.tm_hour < 12 ? "am" : "pm";
|
const char* ap = Tm.tm_hour < 12 ? "am" : "pm";
|
||||||
|
const int us = t.Us % 1000;
|
||||||
|
const int ms = t.Us / 1000;
|
||||||
const int sec = Tm.tm_sec;
|
const int sec = Tm.tm_sec;
|
||||||
const int min = Tm.tm_min;
|
const int min = Tm.tm_min;
|
||||||
const int hr = (Tm.tm_hour == 0 || Tm.tm_hour == 12) ? 12 : Tm.tm_hour % 12;
|
const int hr = (Tm.tm_hour == 0 || Tm.tm_hour == 12) ? 12 : Tm.tm_hour % 12;
|
||||||
|
@ -761,8 +757,8 @@ int FormatTime(double t, char* buffer, int size, ImPlotTimeFmt fmt) {
|
||||||
static const char mnames[12][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
|
static const char mnames[12][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
|
||||||
|
|
||||||
switch(fmt) {
|
switch(fmt) {
|
||||||
case ImPlotTimeFmt_Us: return snprintf(buffer, size, ".%06d", us);
|
case ImPlotTimeFmt_Us: return snprintf(buffer, size, ".%03d %03d", ms, us);
|
||||||
case ImPlotTimeFmt_SUs: return snprintf(buffer, size, ":%02d.%06d", sec, us);
|
case ImPlotTimeFmt_SUs: return snprintf(buffer, size, ":%02d.%03d %03d", sec, ms, us);
|
||||||
case ImPlotTimeFmt_SMs: return snprintf(buffer, size, ":%02d.%03d", sec, ms);
|
case ImPlotTimeFmt_SMs: return snprintf(buffer, size, ":%02d.%03d", sec, ms);
|
||||||
case ImPlotTimeFmt_S: return snprintf(buffer, size, ":%02d", sec);
|
case ImPlotTimeFmt_S: return snprintf(buffer, size, ":%02d", sec);
|
||||||
case ImPlotTimeFmt_HrMinS: return snprintf(buffer, size, "%d:%02d:%02d%s", hr, min, sec, ap);
|
case ImPlotTimeFmt_HrMinS: return snprintf(buffer, size, "%d:%02d:%02d%s", hr, min, sec, ap);
|
||||||
|
@ -773,6 +769,7 @@ int FormatTime(double t, char* buffer, int size, ImPlotTimeFmt fmt) {
|
||||||
case ImPlotTimeFmt_DayMoYr: return snprintf(buffer, size, "%d/%d/%d", mon, day, yr);
|
case ImPlotTimeFmt_DayMoYr: return snprintf(buffer, size, "%d/%d/%d", mon, day, yr);
|
||||||
case ImPlotTimeFmt_DayMoYrHrMin: return snprintf(buffer, size, "%d/%d/%d %u:%02d%s", mon, day, yr, hr, min, ap);
|
case ImPlotTimeFmt_DayMoYrHrMin: return snprintf(buffer, size, "%d/%d/%d %u:%02d%s", mon, day, yr, hr, min, ap);
|
||||||
case ImPlotTimeFmt_DayMoYrHrMinS: return snprintf(buffer, size, "%d/%d/%d %u:%02d:%02d%s", mon, day, yr, hr, min, sec, ap);
|
case ImPlotTimeFmt_DayMoYrHrMinS: return snprintf(buffer, size, "%d/%d/%d %u:%02d:%02d%s", mon, day, yr, hr, min, sec, ap);
|
||||||
|
case ImPlotTimeFmt_MoYr: return snprintf(buffer, size, "%s %d", mnames[Tm.tm_mon], year);
|
||||||
case ImPlotTimeFmt_Mo: return snprintf(buffer, size, "%s", mnames[Tm.tm_mon]);
|
case ImPlotTimeFmt_Mo: return snprintf(buffer, size, "%s", mnames[Tm.tm_mon]);
|
||||||
case ImPlotTimeFmt_Yr: return snprintf(buffer, size, "%d", year);
|
case ImPlotTimeFmt_Yr: return snprintf(buffer, size, "%d", year);
|
||||||
default: return 0;
|
default: return 0;
|
||||||
|
@ -800,6 +797,7 @@ inline float GetTimeLabelWidth(ImPlotTimeFmt fmt) {
|
||||||
case ImPlotTimeFmt_DayMoYr: return ImGui::CalcTextSize("88/88/88").x; // 10/3/1991
|
case ImPlotTimeFmt_DayMoYr: return ImGui::CalcTextSize("88/88/88").x; // 10/3/1991
|
||||||
case ImPlotTimeFmt_DayMoYrHrMin: return ImGui::CalcTextSize("88/88/88 88:88pm").x; // 10/3/91 7:21pm
|
case ImPlotTimeFmt_DayMoYrHrMin: return ImGui::CalcTextSize("88/88/88 88:88pm").x; // 10/3/91 7:21pm
|
||||||
case ImPlotTimeFmt_DayMoYrHrMinS: return ImGui::CalcTextSize("88/88/88 88:88:88pm").x; // 10/3/91 7:21:29pm
|
case ImPlotTimeFmt_DayMoYrHrMinS: return ImGui::CalcTextSize("88/88/88 88:88:88pm").x; // 10/3/91 7:21:29pm
|
||||||
|
case ImPlotTimeFmt_MoYr: return ImGui::CalcTextSize("MMM 8888").x; // Oct 1991
|
||||||
case ImPlotTimeFmt_Mo: return ImGui::CalcTextSize("MMM").x; // Oct
|
case ImPlotTimeFmt_Mo: return ImGui::CalcTextSize("MMM").x; // Oct
|
||||||
case ImPlotTimeFmt_Yr: return ImGui::CalcTextSize("8888").x; // 1991
|
case ImPlotTimeFmt_Yr: return ImGui::CalcTextSize("8888").x; // 1991
|
||||||
default: return 0;
|
default: return 0;
|
||||||
|
@ -834,7 +832,7 @@ static const ImPlotTimeFmt TimeFormatLevel1[ImPlotTimeUnit_COUNT] = {
|
||||||
ImPlotTimeFmt_HrMin,
|
ImPlotTimeFmt_HrMin,
|
||||||
ImPlotTimeFmt_DayMo,
|
ImPlotTimeFmt_DayMo,
|
||||||
ImPlotTimeFmt_DayMo,
|
ImPlotTimeFmt_DayMo,
|
||||||
ImPlotTimeFmt_Yr,
|
ImPlotTimeFmt_MoYr,
|
||||||
ImPlotTimeFmt_Yr
|
ImPlotTimeFmt_Yr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -845,7 +843,7 @@ static const ImPlotTimeFmt TimeFormatLevel1First[ImPlotTimeUnit_COUNT] = {
|
||||||
ImPlotTimeFmt_DayMoYrHrMin,
|
ImPlotTimeFmt_DayMoYrHrMin,
|
||||||
ImPlotTimeFmt_DayMoYr,
|
ImPlotTimeFmt_DayMoYr,
|
||||||
ImPlotTimeFmt_DayMoYr,
|
ImPlotTimeFmt_DayMoYr,
|
||||||
ImPlotTimeFmt_Yr,
|
ImPlotTimeFmt_MoYr,
|
||||||
ImPlotTimeFmt_Yr
|
ImPlotTimeFmt_Yr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -859,10 +857,16 @@ void AddTicksTime(const ImPlotRange& range, float plot_width, ImPlotTickCollecti
|
||||||
const ImPlotTimeFmt fmt1 = TimeFormatLevel1[unit1];
|
const ImPlotTimeFmt fmt1 = TimeFormatLevel1[unit1];
|
||||||
const ImPlotTimeFmt fmtf = TimeFormatLevel1First[unit1];
|
const ImPlotTimeFmt fmtf = TimeFormatLevel1First[unit1];
|
||||||
|
|
||||||
|
const ImPlotTime t_min(range.Min);
|
||||||
|
const ImPlotTime t_max(range.Max);
|
||||||
|
|
||||||
// maximum allowable density of labels
|
// maximum allowable density of labels
|
||||||
const float max_density = 0.5f;
|
const float max_density = 0.5f;
|
||||||
|
|
||||||
|
// book keeping
|
||||||
bool first = true;
|
bool first = true;
|
||||||
const char* last_major = NULL;
|
const char* last_major = NULL;
|
||||||
|
|
||||||
if (unit0 != ImPlotTimeUnit_Yr) {
|
if (unit0 != ImPlotTimeUnit_Yr) {
|
||||||
// pixels per major (level 1) division
|
// pixels per major (level 1) division
|
||||||
const float pix_per_major_div = plot_width / (float)(range.Size() / TimeUnitSpans[unit1]);
|
const float pix_per_major_div = plot_width / (float)(range.Size() / TimeUnitSpans[unit1]);
|
||||||
|
@ -873,16 +877,17 @@ void AddTicksTime(const ImPlotRange& range, float plot_width, ImPlotTickCollecti
|
||||||
// the minor step size (level 0)
|
// the minor step size (level 0)
|
||||||
const int step = GetTimeStep(minor_per_major, unit0);
|
const int step = GetTimeStep(minor_per_major, unit0);
|
||||||
// generate ticks
|
// generate ticks
|
||||||
double t1 = FloorTime(range.Min, unit1);
|
ImPlotTime t1 = FloorTime(ImPlotTime(range.Min), unit1);
|
||||||
while (t1 < range.Max) {
|
t1 = t1;
|
||||||
if (range.Contains(t1)) {
|
while (t1 < t_max) {
|
||||||
|
if (t1 >= t_min && t1 <= t_max) {
|
||||||
// minor level 0 tick
|
// minor level 0 tick
|
||||||
ImPlotTick tick_min(t1,true,true);
|
ImPlotTick tick_min(t1.ToDouble(),true,true);
|
||||||
tick_min.Level = 0;
|
tick_min.Level = 0;
|
||||||
LabelTickTime(tick_min,ticks.Labels,fmt0);
|
LabelTickTime(tick_min,ticks.Labels,fmt0);
|
||||||
ticks.AddTick(tick_min);
|
ticks.AddTick(tick_min);
|
||||||
// major level 1 tick
|
// major level 1 tick
|
||||||
ImPlotTick tick_maj(t1,true,true);
|
ImPlotTick tick_maj(t1.ToDouble(),true,true);
|
||||||
tick_maj.Level = 1;
|
tick_maj.Level = 1;
|
||||||
LabelTickTime(tick_maj,ticks.Labels,first ? fmtf : fmt1);
|
LabelTickTime(tick_maj,ticks.Labels,first ? fmtf : fmt1);
|
||||||
const char* this_major = ticks.Labels.Buf.Data + tick_maj.BufferOffset;
|
const char* this_major = ticks.Labels.Buf.Data + tick_maj.BufferOffset;
|
||||||
|
@ -897,14 +902,13 @@ void AddTicksTime(const ImPlotRange& range, float plot_width, ImPlotTickCollecti
|
||||||
if (first) first = false;
|
if (first) first = false;
|
||||||
}
|
}
|
||||||
// add minor ticks up until next major
|
// add minor ticks up until next major
|
||||||
const double t2 = AddTime(t1, unit1, 1);
|
const ImPlotTime t2 = AddTime(t1, unit1, 1);
|
||||||
const ImPlotRange r12(t1,t2);
|
if (minor_per_major > 1 && (t_min <= t2 && t1 <= t_max)) {
|
||||||
if (minor_per_major > 1 && RangesOverlap(range,r12)) {
|
ImPlotTime t12 = AddTime(t1, unit0, step);
|
||||||
double t12 = AddTime(t1, unit0, step);
|
|
||||||
while (t12 < t2) {
|
while (t12 < t2) {
|
||||||
float px_to_t2 = (float)((t2 - t12)/range.Size()) * plot_width;
|
float px_to_t2 = (float)((t2 - t12).ToDouble()/range.Size()) * plot_width;
|
||||||
if (range.Contains(t12)) {
|
if (t12 >= t_min && t12 <= t_max) {
|
||||||
ImPlotTick tick(t12,false,px_to_t2 >= minor_label_width);
|
ImPlotTick tick(t12.ToDouble(),false,px_to_t2 >= minor_label_width);
|
||||||
tick.Level = 0;
|
tick.Level = 0;
|
||||||
LabelTickTime(tick,ticks.Labels,fmt0);
|
LabelTickTime(tick,ticks.Labels,fmt0);
|
||||||
ticks.AddTick(tick);
|
ticks.AddTick(tick);
|
||||||
|
@ -931,10 +935,10 @@ void AddTicksTime(const ImPlotRange& range, float plot_width, ImPlotTickCollecti
|
||||||
const double interval = NiceNum(nice_range / (max_labels - 1), true);
|
const double interval = NiceNum(nice_range / (max_labels - 1), true);
|
||||||
const int graphmin = (int)(floor(year_min / interval) * interval);
|
const int graphmin = (int)(floor(year_min / interval) * interval);
|
||||||
const int step = (int)interval <= 0 ? 1 : (int)interval;
|
const int step = (int)interval <= 0 ? 1 : (int)interval;
|
||||||
double t1 = MakeYear(graphmin);
|
ImPlotTime t1 = MakeYear(graphmin);
|
||||||
while (t1 < range.Max) {
|
while (t1 < range.Max) {
|
||||||
if (range.Contains(t1)) {
|
if (t1 >= t_min && t1 <= t_max) {
|
||||||
ImPlotTick tick(t1, true, true);
|
ImPlotTick tick(t1.ToDouble(), true, true);
|
||||||
tick.Level = 0;
|
tick.Level = 0;
|
||||||
LabelTickTime(tick, ticks.Labels, TimeFormatLevel0[ImPlotTimeUnit_Yr]);
|
LabelTickTime(tick, ticks.Labels, TimeFormatLevel0[ImPlotTimeUnit_Yr]);
|
||||||
ticks.AddTick(tick);
|
ticks.AddTick(tick);
|
||||||
|
@ -1028,18 +1032,14 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
// NextPlotData -----------------------------------------------------------
|
// NextPlotData -----------------------------------------------------------
|
||||||
|
|
||||||
if (gp.NextPlotData.HasXRange) {
|
if (gp.NextPlotData.HasXRange) {
|
||||||
if (just_created || gp.NextPlotData.XRangeCond == ImGuiCond_Always) {
|
if (just_created || gp.NextPlotData.XRangeCond == ImGuiCond_Always)
|
||||||
plot.XAxis.Range = gp.NextPlotData.X;
|
plot.XAxis.SetRange(gp.NextPlotData.X);
|
||||||
plot.XAxis.Constrain();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||||
if (gp.NextPlotData.HasYRange[i]) {
|
if (gp.NextPlotData.HasYRange[i]) {
|
||||||
if (just_created || gp.NextPlotData.YRangeCond[i] == ImGuiCond_Always) {
|
if (just_created || gp.NextPlotData.YRangeCond[i] == ImGuiCond_Always)
|
||||||
plot.YAxis[i].Range = gp.NextPlotData.Y[i];
|
plot.YAxis[i].SetRange(gp.NextPlotData.Y[i]);
|
||||||
plot.YAxis[i].Constrain();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1236,7 +1236,6 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
plot.XAxis.SetMin(gp.X.Invert ? plot_br.x : plot_tl.x);
|
plot.XAxis.SetMin(gp.X.Invert ? plot_br.x : plot_tl.x);
|
||||||
if (!gp.X.LockMax)
|
if (!gp.X.LockMax)
|
||||||
plot.XAxis.SetMax(gp.X.Invert ? plot_tl.x : plot_br.x);
|
plot.XAxis.SetMax(gp.X.Invert ? plot_tl.x : plot_br.x);
|
||||||
// ConstrainAxis(plot.XAxis);
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||||
if (!gp.Y[i].Lock && plot.YAxis[i].Dragging) {
|
if (!gp.Y[i].Lock && plot.YAxis[i].Dragging) {
|
||||||
|
@ -1246,7 +1245,6 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
plot.YAxis[i].SetMin(gp.Y[i].Invert ? plot_tl.y : plot_br.y);
|
plot.YAxis[i].SetMin(gp.Y[i].Invert ? plot_tl.y : plot_br.y);
|
||||||
if (!gp.Y[i].LockMax)
|
if (!gp.Y[i].LockMax)
|
||||||
plot.YAxis[i].SetMax(gp.Y[i].Invert ? plot_br.y : plot_tl.y);
|
plot.YAxis[i].SetMax(gp.Y[i].Invert ? plot_br.y : plot_tl.y);
|
||||||
// ConstrainAxis(plot.YAxis[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set the mouse cursor based on which axes are moving.
|
// Set the mouse cursor based on which axes are moving.
|
||||||
|
@ -1301,7 +1299,6 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
plot.XAxis.SetMin(gp.X.Invert ? plot_br.x : plot_tl.x);
|
plot.XAxis.SetMin(gp.X.Invert ? plot_br.x : plot_tl.x);
|
||||||
if (!gp.X.LockMax)
|
if (!gp.X.LockMax)
|
||||||
plot.XAxis.SetMax(gp.X.Invert ? plot_tl.x : plot_br.x);
|
plot.XAxis.SetMax(gp.X.Invert ? plot_tl.x : plot_br.x);
|
||||||
// ConstrainAxis(plot.XAxis);
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||||
if (plot.YAxis[i].HoveredTot && !gp.Y[i].Lock) {
|
if (plot.YAxis[i].HoveredTot && !gp.Y[i].Lock) {
|
||||||
|
@ -1312,7 +1309,6 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
plot.YAxis[i].SetMin(gp.Y[i].Invert ? plot_tl.y : plot_br.y);
|
plot.YAxis[i].SetMin(gp.Y[i].Invert ? plot_tl.y : plot_br.y);
|
||||||
if (!gp.Y[i].LockMax)
|
if (!gp.Y[i].LockMax)
|
||||||
plot.YAxis[i].SetMax(gp.Y[i].Invert ? plot_br.y : plot_tl.y);
|
plot.YAxis[i].SetMax(gp.Y[i].Invert ? plot_br.y : plot_tl.y);
|
||||||
// ConstrainAxis(plot.YAxis[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1977,7 +1973,6 @@ void EndPlot() {
|
||||||
plot.XAxis.Range.Min -= FLT_EPSILON;
|
plot.XAxis.Range.Min -= FLT_EPSILON;
|
||||||
}
|
}
|
||||||
plot.XAxis.Constrain();
|
plot.XAxis.Constrain();
|
||||||
// ConstrainAxis(plot.XAxis);
|
|
||||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||||
if (gp.FitY[i] && !ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LockMin) && !ImNanOrInf(gp.ExtentsY[i].Min)) {
|
if (gp.FitY[i] && !ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LockMin) && !ImNanOrInf(gp.ExtentsY[i].Min)) {
|
||||||
plot.YAxis[i].Range.Min = (gp.ExtentsY[i].Min);
|
plot.YAxis[i].Range.Min = (gp.ExtentsY[i].Min);
|
||||||
|
@ -1990,7 +1985,6 @@ void EndPlot() {
|
||||||
plot.YAxis[i].Range.Min -= FLT_EPSILON;
|
plot.YAxis[i].Range.Min -= FLT_EPSILON;
|
||||||
}
|
}
|
||||||
plot.YAxis[i].Constrain();
|
plot.YAxis[i].Constrain();
|
||||||
// ConstrainAxis(plot.YAxis[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1271,7 +1271,8 @@ void StyleSeaborn() {
|
||||||
|
|
||||||
namespace MyImPlot {
|
namespace MyImPlot {
|
||||||
|
|
||||||
int BinarySearch(const double* arr, int l, int r, double x) {
|
template <typename T>
|
||||||
|
int BinarySearch(const T* arr, int l, int r, T x) {
|
||||||
if (r >= l) {
|
if (r >= l) {
|
||||||
int mid = l + (r - l) / 2;
|
int mid = l + (r - l) / 2;
|
||||||
if (arr[mid] == x)
|
if (arr[mid] == x)
|
||||||
|
@ -1284,40 +1285,23 @@ int BinarySearch(const double* arr, int l, int r, double x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlotCandlestick(const char* label_id, const double* xs, const double* opens, const double* closes, const double* lows, const double* highs, int count, bool tooltip, float width_percent, ImVec4 bullCol, ImVec4 bearCol) {
|
void PlotCandlestick(const char* label_id, const double* xs, const double* opens, const double* closes, const double* lows, const double* highs, int count, bool tooltip, float width_percent, ImVec4 bullCol, ImVec4 bearCol) {
|
||||||
// begin plot item
|
|
||||||
if (ImPlot::BeginItem(label_id)) {
|
|
||||||
// override legend icon color
|
|
||||||
ImPlot::GetCurrentItem()->Color = ImVec4(0.25f,0.25f,0.25f,1);
|
|
||||||
// fit data if requested
|
|
||||||
if (ImPlot::FitThisFrame()) {
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
ImPlot::FitPoint(ImPlotPoint(xs[i], lows[i]));
|
|
||||||
ImPlot::FitPoint(ImPlotPoint(xs[i], highs[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// get ImGui window DrawList
|
// get ImGui window DrawList
|
||||||
ImDrawList* draw_list = ImPlot::GetPlotDrawList();
|
ImDrawList* draw_list = ImPlot::GetPlotDrawList();
|
||||||
// calc real value width
|
// calc real value width
|
||||||
double half_width = count > 1 ? (xs[1] - xs[0]) * width_percent : width_percent;
|
double half_width = count > 1 ? (xs[1] - xs[0]) * width_percent : width_percent;
|
||||||
// render data
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
ImVec2 open_pos = ImPlot::PlotToPixels(xs[i] - half_width, opens[i]);
|
|
||||||
ImVec2 close_pos = ImPlot::PlotToPixels(xs[i] + half_width, closes[i]);
|
|
||||||
ImVec2 low_pos = ImPlot::PlotToPixels(xs[i], lows[i]);
|
|
||||||
ImVec2 high_pos = ImPlot::PlotToPixels(xs[i], highs[i]);
|
|
||||||
ImU32 color = ImGui::GetColorU32(opens[i] > closes[i] ? bearCol : bullCol);
|
|
||||||
draw_list->AddLine(low_pos, high_pos, color);
|
|
||||||
draw_list->AddRectFilled(open_pos, close_pos, color);
|
|
||||||
}
|
|
||||||
// custom tool
|
// custom tool
|
||||||
if (ImPlot::IsPlotHovered() && tooltip) {
|
if (ImPlot::IsPlotHovered() && tooltip) {
|
||||||
ImPlotPoint mouse = ImPlot::GetPlotMousePos();
|
ImPlotPoint mouse = ImPlot::GetPlotMousePos();
|
||||||
mouse.x = ImPlot::RoundTime(mouse.x, ImPlotTimeUnit_Day);
|
mouse.x = ImPlot::RoundTime(ImPlotTime(mouse.x), ImPlotTimeUnit_Day).ToDouble();
|
||||||
float tool_l = ImPlot::PlotToPixels(mouse.x - half_width * 1.5, mouse.y).x;
|
float tool_l = ImPlot::PlotToPixels(mouse.x - half_width * 1.5, mouse.y).x;
|
||||||
float tool_r = ImPlot::PlotToPixels(mouse.x + half_width * 1.5, mouse.y).x;
|
float tool_r = ImPlot::PlotToPixels(mouse.x + half_width * 1.5, mouse.y).x;
|
||||||
float tool_t = ImPlot::GetPlotPos().y;
|
float tool_t = ImPlot::GetPlotPos().y;
|
||||||
float tool_b = tool_t + ImPlot::GetPlotSize().y;
|
float tool_b = tool_t + ImPlot::GetPlotSize().y;
|
||||||
draw_list->AddRectFilled(ImVec2(tool_l, tool_t), ImVec2(tool_r, tool_b), IM_COL32(0,255,255,64));
|
ImPlot::PushPlotClipRect();
|
||||||
|
draw_list->AddRectFilled(ImVec2(tool_l, tool_t), ImVec2(tool_r, tool_b), IM_COL32(128,128,128,64));
|
||||||
|
ImPlot::PopPlotClipRect();
|
||||||
// find mouse location index
|
// find mouse location index
|
||||||
int idx = BinarySearch(xs, 0, count - 1, mouse.x);
|
int idx = BinarySearch(xs, 0, count - 1, mouse.x);
|
||||||
// render tool tip (won't be affected by plot clip rect)
|
// render tool tip (won't be affected by plot clip rect)
|
||||||
|
@ -1333,6 +1317,29 @@ void PlotCandlestick(const char* label_id, const double* xs, const double* opens
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// begin plot item
|
||||||
|
if (ImPlot::BeginItem(label_id)) {
|
||||||
|
// override legend icon color
|
||||||
|
ImPlot::GetCurrentItem()->Color = ImVec4(0.25f,0.25f,0.25f,1);
|
||||||
|
// fit data if requested
|
||||||
|
if (ImPlot::FitThisFrame()) {
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
ImPlot::FitPoint(ImPlotPoint(xs[i], lows[i]));
|
||||||
|
ImPlot::FitPoint(ImPlotPoint(xs[i], highs[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// render data
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
ImVec2 open_pos = ImPlot::PlotToPixels(xs[i] - half_width, opens[i]);
|
||||||
|
ImVec2 close_pos = ImPlot::PlotToPixels(xs[i] + half_width, closes[i]);
|
||||||
|
ImVec2 low_pos = ImPlot::PlotToPixels(xs[i], lows[i]);
|
||||||
|
ImVec2 high_pos = ImPlot::PlotToPixels(xs[i], highs[i]);
|
||||||
|
ImU32 color = ImGui::GetColorU32(opens[i] > closes[i] ? bearCol : bullCol);
|
||||||
|
draw_list->AddLine(low_pos, high_pos, color);
|
||||||
|
draw_list->AddRectFilled(open_pos, close_pos, color);
|
||||||
|
}
|
||||||
|
|
||||||
// end plot item
|
// end plot item
|
||||||
ImPlot::EndItem();
|
ImPlot::EndItem();
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,6 +195,7 @@ enum ImPlotTimeFmt_ {
|
||||||
ImPlotTimeFmt_DayMoYr, // 10/3/91
|
ImPlotTimeFmt_DayMoYr, // 10/3/91
|
||||||
ImPlotTimeFmt_DayMoYrHrMin, // 10/3/91 7:21pm
|
ImPlotTimeFmt_DayMoYrHrMin, // 10/3/91 7:21pm
|
||||||
ImPlotTimeFmt_DayMoYrHrMinS, // 10/3/91 7:21:29pm
|
ImPlotTimeFmt_DayMoYrHrMinS, // 10/3/91 7:21:29pm
|
||||||
|
ImPlotTimeFmt_MoYr, // Oct 1991
|
||||||
ImPlotTimeFmt_Mo, // Oct
|
ImPlotTimeFmt_Mo, // Oct
|
||||||
ImPlotTimeFmt_Yr // 1991
|
ImPlotTimeFmt_Yr // 1991
|
||||||
};
|
};
|
||||||
|
@ -307,11 +308,8 @@ struct ImPlotAxis
|
||||||
_min = ImConstrainNan(ImConstrainInf(_min));
|
_min = ImConstrainNan(ImConstrainInf(_min));
|
||||||
if (ImHasFlag(Flags, ImPlotAxisFlags_LogScale))
|
if (ImHasFlag(Flags, ImPlotAxisFlags_LogScale))
|
||||||
_min = ImConstrainLog(_min);
|
_min = ImConstrainLog(_min);
|
||||||
if (ImHasFlag(Flags, ImPlotAxisFlags_Time)) {
|
if (ImHasFlag(Flags, ImPlotAxisFlags_Time))
|
||||||
_min = ImConstrainTime(_min);
|
_min = ImConstrainTime(_min);
|
||||||
if ((Range.Max - _min) < 0.0001)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (_min >= Range.Max)
|
if (_min >= Range.Max)
|
||||||
return false;
|
return false;
|
||||||
Range.Min = _min;
|
Range.Min = _min;
|
||||||
|
@ -322,17 +320,24 @@ struct ImPlotAxis
|
||||||
_max = ImConstrainNan(ImConstrainInf(_max));
|
_max = ImConstrainNan(ImConstrainInf(_max));
|
||||||
if (ImHasFlag(Flags, ImPlotAxisFlags_LogScale))
|
if (ImHasFlag(Flags, ImPlotAxisFlags_LogScale))
|
||||||
_max = ImConstrainLog(_max);
|
_max = ImConstrainLog(_max);
|
||||||
if (ImHasFlag(Flags, ImPlotAxisFlags_Time)) {
|
if (ImHasFlag(Flags, ImPlotAxisFlags_Time))
|
||||||
_max = ImConstrainTime(_max);
|
_max = ImConstrainTime(_max);
|
||||||
if ((_max - Range.Min) < 0.0001)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (_max <= Range.Min)
|
if (_max <= Range.Min)
|
||||||
return false;
|
return false;
|
||||||
Range.Max = _max;
|
Range.Max = _max;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void SetRange(double _min, double _max) {
|
||||||
|
Range.Min = _min;
|
||||||
|
Range.Max = _max;
|
||||||
|
Constrain();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRange(const ImPlotRange& range) {
|
||||||
|
SetRange(range.Min, range.Max);
|
||||||
|
}
|
||||||
|
|
||||||
void Constrain() {
|
void Constrain() {
|
||||||
Range.Min = ImConstrainNan(ImConstrainInf(Range.Min));
|
Range.Min = ImConstrainNan(ImConstrainInf(Range.Min));
|
||||||
Range.Max = ImConstrainNan(ImConstrainInf(Range.Max));
|
Range.Max = ImConstrainNan(ImConstrainInf(Range.Max));
|
||||||
|
@ -343,8 +348,6 @@ struct ImPlotAxis
|
||||||
if (ImHasFlag(Flags, ImPlotAxisFlags_Time)) {
|
if (ImHasFlag(Flags, ImPlotAxisFlags_Time)) {
|
||||||
Range.Min = ImConstrainTime(Range.Min);
|
Range.Min = ImConstrainTime(Range.Min);
|
||||||
Range.Max = ImConstrainTime(Range.Max);
|
Range.Max = ImConstrainTime(Range.Max);
|
||||||
if (Range.Size() < 0.0001)
|
|
||||||
Range.Max = Range.Min + 0.0001; // TBD
|
|
||||||
}
|
}
|
||||||
if (Range.Max <= Range.Min)
|
if (Range.Max <= Range.Min)
|
||||||
Range.Max = Range.Min + DBL_EPSILON;
|
Range.Max = Range.Min + DBL_EPSILON;
|
||||||
|
@ -576,14 +579,33 @@ struct ImPlotAxisScale
|
||||||
/// Two part time struct.
|
/// Two part time struct.
|
||||||
struct ImPlotTime {
|
struct ImPlotTime {
|
||||||
time_t S;
|
time_t S;
|
||||||
time_t Us;
|
int Us;
|
||||||
ImPlotTime(time_t s, time_t us) { S = s; Us = us;}
|
ImPlotTime(time_t s, int us) {
|
||||||
|
S = s + us / 1000000;
|
||||||
|
Us = us % 1000000;
|
||||||
|
}
|
||||||
ImPlotTime(double t) {
|
ImPlotTime(double t) {
|
||||||
S = (time_t)t;
|
S = (time_t)t;
|
||||||
Us = (int)(t * 1000000 - floor(t) * 1000000);
|
Us = (int)(t * 1000000 - floor(t) * 1000000);
|
||||||
}
|
}
|
||||||
|
double ToDouble() const { return (double)S + (double)Us / 1000000.0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline ImPlotTime operator+(const ImPlotTime& lhs, const ImPlotTime& rhs)
|
||||||
|
{ return ImPlotTime(lhs.S + rhs.S, lhs.Us + rhs.Us); }
|
||||||
|
static inline ImPlotTime operator-(const ImPlotTime& lhs, const ImPlotTime& rhs)
|
||||||
|
{ return ImPlotTime(lhs.S - rhs.S, lhs.Us - rhs.Us); }
|
||||||
|
static inline bool operator==(const ImPlotTime& lhs, const ImPlotTime& rhs)
|
||||||
|
{ return lhs.S == rhs.S && lhs.Us == rhs.Us; }
|
||||||
|
static inline bool operator<(const ImPlotTime& lhs, const ImPlotTime& rhs)
|
||||||
|
{ return lhs.S == rhs.S ? lhs.Us < rhs.Us : lhs.S < rhs.S; }
|
||||||
|
static inline bool operator>(const ImPlotTime& lhs, const ImPlotTime& rhs)
|
||||||
|
{ return rhs < lhs; }
|
||||||
|
static inline bool operator<=(const ImPlotTime& lhs, const ImPlotTime& rhs)
|
||||||
|
{ return lhs < rhs || lhs == rhs; }
|
||||||
|
static inline bool operator>=(const ImPlotTime& lhs, const ImPlotTime& rhs)
|
||||||
|
{ return lhs > rhs || lhs == rhs; }
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Internal API
|
// [SECTION] Internal API
|
||||||
// No guarantee of forward compatibility here!
|
// No guarantee of forward compatibility here!
|
||||||
|
@ -653,7 +675,8 @@ inline bool FitThisFrame() { return GImPlot->FitThisFrame; }
|
||||||
void FitPoint(const ImPlotPoint& p);
|
void FitPoint(const ImPlotPoint& p);
|
||||||
|
|
||||||
// Returns true if two ranges overlap
|
// Returns true if two ranges overlap
|
||||||
inline bool RangesOverlap(const ImPlotRange& r1, const ImPlotRange& r2) { return r1.Min <= r2.Max && r2.Min <= r1.Max; }
|
inline bool RangesOverlap(const ImPlotRange& r1, const ImPlotRange& r2)
|
||||||
|
{ return r1.Min <= r2.Max && r2.Min <= r1.Max; }
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Legend Utils
|
// [SECTION] Legend Utils
|
||||||
|
@ -771,23 +794,23 @@ inline int GetDaysInMonth(int year, int month) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds time to a timestamp. #count must be positive!
|
// Adds time to a timestamp. #count must be positive!
|
||||||
double AddTime(double t, ImPlotTimeUnit unit, int count);
|
ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count);
|
||||||
// Rounds a timestamp down to nearest.
|
// Rounds a timestamp down to nearest.
|
||||||
double FloorTime(double t, ImPlotTimeUnit unit);
|
ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit);
|
||||||
// Rounds a timestamp up to the nearest unit.
|
// Rounds a timestamp up to the nearest unit.
|
||||||
double CeilTime(double t, ImPlotTimeUnit unit);
|
ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit);
|
||||||
// Rounds a timestamp up or down to the nearest unit.
|
// Rounds a timestamp up or down to the nearest unit.
|
||||||
double RoundTime(double t, ImPlotTimeUnit unit);
|
ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit);
|
||||||
|
|
||||||
// Get year from timestamp
|
// Get year from timestamp
|
||||||
int GetYear(double t);
|
int GetYear(const ImPlotTime& t);
|
||||||
// Make a timestamp starting at the first day of a year
|
// Make a timestamp starting at the first day of a year
|
||||||
double MakeYear(int year);
|
ImPlotTime MakeYear(int year);
|
||||||
|
|
||||||
// Formates a timestamp t into a buffer according to fmt.
|
// Formates a timestamp t into a buffer according to fmt.
|
||||||
int FormatTime(double t, char* buffer, int size, ImPlotTimeFmt fmt);
|
int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt);
|
||||||
// Prints a timestamp to console
|
// Prints a timestamp to console
|
||||||
void PrintTime(double t, ImPlotTimeFmt fmt);
|
void PrintTime(const ImPlotTime& t, ImPlotTimeFmt fmt);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Internal / Experimental Plotters
|
// [SECTION] Internal / Experimental Plotters
|
||||||
|
|
Loading…
Reference in New Issue
Block a user