mirror of
https://github.com/gwm17/implot.git
synced 2024-11-26 12:18:52 -05:00
add annotation API
This commit is contained in:
parent
a7ae1bca53
commit
13e430a9e5
288
implot.cpp
288
implot.cpp
|
@ -95,29 +95,31 @@ ImPlotInputMap::ImPlotInputMap() {
|
||||||
|
|
||||||
ImPlotStyle::ImPlotStyle() {
|
ImPlotStyle::ImPlotStyle() {
|
||||||
|
|
||||||
LineWeight = 1;
|
LineWeight = 1;
|
||||||
Marker = ImPlotMarker_None;
|
Marker = ImPlotMarker_None;
|
||||||
MarkerSize = 4;
|
MarkerSize = 4;
|
||||||
MarkerWeight = 1;
|
MarkerWeight = 1;
|
||||||
FillAlpha = 1;
|
FillAlpha = 1;
|
||||||
ErrorBarSize = 5;
|
ErrorBarSize = 5;
|
||||||
ErrorBarWeight = 1.5f;
|
ErrorBarWeight = 1.5f;
|
||||||
DigitalBitHeight = 8;
|
DigitalBitHeight = 8;
|
||||||
DigitalBitGap = 4;
|
DigitalBitGap = 4;
|
||||||
|
|
||||||
PlotBorderSize = 1;
|
PlotBorderSize = 1;
|
||||||
MinorAlpha = 0.25f;
|
MinorAlpha = 0.25f;
|
||||||
MajorTickLen = ImVec2(10,10);
|
MajorTickLen = ImVec2(10,10);
|
||||||
MinorTickLen = ImVec2(5,5);
|
MinorTickLen = ImVec2(5,5);
|
||||||
MajorTickSize = ImVec2(1,1);
|
MajorTickSize = ImVec2(1,1);
|
||||||
MinorTickSize = ImVec2(1,1);
|
MinorTickSize = ImVec2(1,1);
|
||||||
MajorGridSize = ImVec2(1,1);
|
MajorGridSize = ImVec2(1,1);
|
||||||
MinorGridSize = ImVec2(1,1);
|
MinorGridSize = ImVec2(1,1);
|
||||||
PlotPadding = ImVec2(8,8);
|
PlotPadding = ImVec2(8,8);
|
||||||
LabelPadding = ImVec2(5,5);
|
LabelPadding = ImVec2(5,5);
|
||||||
LegendPadding = ImVec2(10,10);
|
LegendPadding = ImVec2(10,10);
|
||||||
InfoPadding = ImVec2(10,10);
|
InfoPadding = ImVec2(10,10);
|
||||||
PlotMinSize = ImVec2(300,225);
|
AnnotationPadding = ImVec2(2,2);
|
||||||
|
AnnotationOffset = ImVec2(10,10);
|
||||||
|
PlotMinSize = ImVec2(300,225);
|
||||||
|
|
||||||
ImPlot::StyleColorsAuto(this);
|
ImPlot::StyleColorsAuto(this);
|
||||||
|
|
||||||
|
@ -215,29 +217,31 @@ struct ImPlotStyleVarInfo {
|
||||||
|
|
||||||
static const ImPlotStyleVarInfo GPlotStyleVarInfo[] =
|
static const ImPlotStyleVarInfo GPlotStyleVarInfo[] =
|
||||||
{
|
{
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight
|
||||||
{ ImGuiDataType_S32, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, Marker) }, // ImPlotStyleVar_Marker
|
{ ImGuiDataType_S32, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, Marker) }, // ImPlotStyleVar_Marker
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerSize) }, // ImPlotStyleVar_MarkerSize
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerSize) }, // ImPlotStyleVar_MarkerSize
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, FillAlpha) }, // ImPlotStyleVar_FillAlpha
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, FillAlpha) }, // ImPlotStyleVar_FillAlpha
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarSize) }, // ImPlotStyleVar_ErrorBarSize
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarSize) }, // ImPlotStyleVar_ErrorBarSize
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarWeight) }, // ImPlotStyleVar_ErrorBarWeight
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, ErrorBarWeight) }, // ImPlotStyleVar_ErrorBarWeight
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitHeight) }, // ImPlotStyleVar_DigitalBitHeight
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitHeight) }, // ImPlotStyleVar_DigitalBitHeight
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitGap) }, // ImPlotStyleVar_DigitalBitGap
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, DigitalBitGap) }, // ImPlotStyleVar_DigitalBitGap
|
||||||
|
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotBorderSize) }, // ImPlotStyleVar_PlotBorderSize
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotBorderSize) }, // ImPlotStyleVar_PlotBorderSize
|
||||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorAlpha) }, // ImPlotStyleVar_MinorAlpha
|
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorAlpha) }, // ImPlotStyleVar_MinorAlpha
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorTickLen) }, // ImPlotStyleVar_MajorTickLen
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorTickLen) }, // ImPlotStyleVar_MajorTickLen
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorTickLen) }, // ImPlotStyleVar_MinorTickLen
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorTickLen) }, // ImPlotStyleVar_MinorTickLen
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorTickSize) }, // ImPlotStyleVar_MajorTickSize
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorTickSize) }, // ImPlotStyleVar_MajorTickSize
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorTickSize) }, // ImPlotStyleVar_MinorTickSize
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorTickSize) }, // ImPlotStyleVar_MinorTickSize
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorGridSize) }, // ImPlotStyleVar_MajorGridSize
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MajorGridSize) }, // ImPlotStyleVar_MajorGridSize
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorGridSize) }, // ImPlotStyleVar_MinorGridSize
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MinorGridSize) }, // ImPlotStyleVar_MinorGridSize
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotPadding) }, // ImPlotStyleVar_PlotPadding
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotPadding) }, // ImPlotStyleVar_PlotPadding
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LabelPadding) }, // ImPlotStyleVar_LabelPaddine
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LabelPadding) }, // ImPlotStyleVar_LabelPaddine
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LegendPadding) }, // ImPlotStyleVar_LegendPadding
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LegendPadding) }, // ImPlotStyleVar_LegendPadding
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, InfoPadding) }, // ImPlotStyleVar_InfoPadding
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, InfoPadding) }, // ImPlotStyleVar_InfoPadding
|
||||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotMinSize) } // ImPlotStyleVar_PlotMinSize
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, AnnotationPadding) }, // ImPlotStyleVar_AnnotationPadding
|
||||||
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, AnnotationOffset) }, // ImPlotStyleVar_AnnotationOffset
|
||||||
|
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotMinSize) } // ImPlotStyleVar_PlotMinSize
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ImPlotStyleVarInfo* GetPlotStyleVarInfo(ImPlotStyleVar idx) {
|
static const ImPlotStyleVarInfo* GetPlotStyleVarInfo(ImPlotStyleVar idx) {
|
||||||
|
@ -364,6 +368,8 @@ void Reset(ImPlotContext* ctx) {
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
ctx->YTicks[i].Reset();
|
ctx->YTicks[i].Reset();
|
||||||
}
|
}
|
||||||
|
// reset labels
|
||||||
|
ctx->Annotations.Reset();
|
||||||
// reset extents/fit
|
// reset extents/fit
|
||||||
ctx->FitThisFrame = false;
|
ctx->FitThisFrame = false;
|
||||||
ctx->FitX = false;
|
ctx->FitX = false;
|
||||||
|
@ -378,8 +384,9 @@ void Reset(ImPlotContext* ctx) {
|
||||||
ctx->DigitalPlotItemCnt = 0;
|
ctx->DigitalPlotItemCnt = 0;
|
||||||
ctx->DigitalPlotOffset = 0;
|
ctx->DigitalPlotOffset = 0;
|
||||||
// nullify plot
|
// nullify plot
|
||||||
ctx->CurrentPlot = NULL;
|
ctx->CurrentPlot = NULL;
|
||||||
ctx->CurrentItem = NULL;
|
ctx->CurrentItem = NULL;
|
||||||
|
ctx->PreviousItem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -516,20 +523,20 @@ const char* GetLegendLabel(int i) {
|
||||||
void LabelTickDefault(ImPlotTick& tick, ImGuiTextBuffer& buffer) {
|
void LabelTickDefault(ImPlotTick& tick, ImGuiTextBuffer& buffer) {
|
||||||
char temp[32];
|
char temp[32];
|
||||||
if (tick.ShowLabel) {
|
if (tick.ShowLabel) {
|
||||||
tick.BufferOffset = buffer.size();
|
tick.TextOffset = buffer.size();
|
||||||
snprintf(temp, 32, "%.10g", tick.PlotPos);
|
snprintf(temp, 32, "%.10g", tick.PlotPos);
|
||||||
buffer.append(temp, temp + strlen(temp) + 1);
|
buffer.append(temp, temp + strlen(temp) + 1);
|
||||||
tick.LabelSize = ImGui::CalcTextSize(buffer.Buf.Data + tick.BufferOffset);
|
tick.LabelSize = ImGui::CalcTextSize(buffer.Buf.Data + tick.TextOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LabelTickScientific(ImPlotTick& tick, ImGuiTextBuffer& buffer) {
|
void LabelTickScientific(ImPlotTick& tick, ImGuiTextBuffer& buffer) {
|
||||||
char temp[32];
|
char temp[32];
|
||||||
if (tick.ShowLabel) {
|
if (tick.ShowLabel) {
|
||||||
tick.BufferOffset = buffer.size();
|
tick.TextOffset = buffer.size();
|
||||||
snprintf(temp, 32, "%.0E", tick.PlotPos);
|
snprintf(temp, 32, "%.0E", tick.PlotPos);
|
||||||
buffer.append(temp, temp + strlen(temp) + 1);
|
buffer.append(temp, temp + strlen(temp) + 1);
|
||||||
tick.LabelSize = ImGui::CalcTextSize(buffer.Buf.Data + tick.BufferOffset);
|
tick.LabelSize = ImGui::CalcTextSize(buffer.Buf.Data + tick.TextOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,11 +547,11 @@ void AddTicksDefault(const ImPlotRange& range, int nMajor, int nMinor, ImPlotTic
|
||||||
const double graphmax = ceil(range.Max / interval) * interval;
|
const double graphmax = ceil(range.Max / interval) * interval;
|
||||||
for (double major = graphmin; major < graphmax + 0.5 * interval; major += interval) {
|
for (double major = graphmin; major < graphmax + 0.5 * interval; major += interval) {
|
||||||
if (range.Contains(major))
|
if (range.Contains(major))
|
||||||
ticks.AddTick(major, true, true, LabelTickDefault);
|
ticks.Append(major, true, true, LabelTickDefault);
|
||||||
for (int i = 1; i < nMinor; ++i) {
|
for (int i = 1; i < nMinor; ++i) {
|
||||||
double minor = major + i * interval / nMinor;
|
double minor = major + i * interval / nMinor;
|
||||||
if (range.Contains(minor))
|
if (range.Contains(minor))
|
||||||
ticks.AddTick(minor, false, true, LabelTickDefault);
|
ticks.Append(minor, false, true, LabelTickDefault);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,7 +573,7 @@ void AddTicksLogarithmic(const ImPlotRange& range, int nMajor, ImPlotTickCollect
|
||||||
double major2 = ImPow(10, (double)(e + 1));
|
double major2 = ImPow(10, (double)(e + 1));
|
||||||
double interval = (major2 - major1) / 9;
|
double interval = (major2 - major1) / 9;
|
||||||
if (major1 >= (range.Min - DBL_EPSILON) && major1 <= (range.Max + DBL_EPSILON))
|
if (major1 >= (range.Min - DBL_EPSILON) && major1 <= (range.Max + DBL_EPSILON))
|
||||||
ticks.AddTick(major1, true, true, LabelTickScientific);
|
ticks.Append(major1, true, true, LabelTickScientific);
|
||||||
for (int j = 0; j < exp_step; ++j) {
|
for (int j = 0; j < exp_step; ++j) {
|
||||||
major1 = ImPow(10, (double)(e+j));
|
major1 = ImPow(10, (double)(e+j));
|
||||||
major2 = ImPow(10, (double)(e+j+1));
|
major2 = ImPow(10, (double)(e+j+1));
|
||||||
|
@ -574,7 +581,7 @@ void AddTicksLogarithmic(const ImPlotRange& range, int nMajor, ImPlotTickCollect
|
||||||
for (int i = 1; i < (9 + (int)(j < (exp_step - 1))); ++i) {
|
for (int i = 1; i < (9 + (int)(j < (exp_step - 1))); ++i) {
|
||||||
double minor = major1 + i * interval;
|
double minor = major1 + i * interval;
|
||||||
if (minor >= (range.Min - DBL_EPSILON) && minor <= (range.Max + DBL_EPSILON))
|
if (minor >= (range.Min - DBL_EPSILON) && minor <= (range.Max + DBL_EPSILON))
|
||||||
ticks.AddTick(minor, false, false, LabelTickScientific);
|
ticks.Append(minor, false, false, LabelTickScientific);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -585,14 +592,14 @@ void AddTicksCustom(const double* values, const char* const labels[], int n, ImP
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
ImPlotTick tick(values[i], false, true);
|
ImPlotTick tick(values[i], false, true);
|
||||||
if (labels != NULL) {
|
if (labels != NULL) {
|
||||||
tick.BufferOffset = ticks.Labels.size();
|
tick.TextOffset = ticks.TextBuffer.size();
|
||||||
ticks.Labels.append(labels[i], labels[i] + strlen(labels[i]) + 1);
|
ticks.TextBuffer.append(labels[i], labels[i] + strlen(labels[i]) + 1);
|
||||||
tick.LabelSize = ImGui::CalcTextSize(labels[i]);
|
tick.LabelSize = ImGui::CalcTextSize(labels[i]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LabelTickDefault(tick, ticks.Labels);
|
LabelTickDefault(tick, ticks.TextBuffer);
|
||||||
}
|
}
|
||||||
ticks.AddTick(tick);
|
ticks.Append(tick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,10 +966,10 @@ void PrintTime(const ImPlotTime& t, ImPlotTimeFmt fmt) {
|
||||||
inline void LabelTickTime(ImPlotTick& tick, ImGuiTextBuffer& buffer, const ImPlotTime& t, ImPlotTimeFmt fmt, bool hour24) {
|
inline void LabelTickTime(ImPlotTick& tick, ImGuiTextBuffer& buffer, const ImPlotTime& t, ImPlotTimeFmt fmt, bool hour24) {
|
||||||
char temp[32];
|
char temp[32];
|
||||||
if (tick.ShowLabel) {
|
if (tick.ShowLabel) {
|
||||||
tick.BufferOffset = buffer.size();
|
tick.TextOffset = buffer.size();
|
||||||
hour24 ? FormatTime24(t, temp, 32, fmt) : FormatTime12(t, temp, 32, fmt);
|
hour24 ? FormatTime24(t, temp, 32, fmt) : FormatTime12(t, temp, 32, fmt);
|
||||||
buffer.append(temp, temp + strlen(temp) + 1);
|
buffer.append(temp, temp + strlen(temp) + 1);
|
||||||
tick.LabelSize = ImGui::CalcTextSize(buffer.Buf.Data + tick.BufferOffset);
|
tick.LabelSize = ImGui::CalcTextSize(buffer.Buf.Data + tick.TextOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,17 +1060,17 @@ void AddTicksTime(const ImPlotRange& range, float plot_width, bool hour24, ImPlo
|
||||||
// minor level 0 tick
|
// minor level 0 tick
|
||||||
ImPlotTick tick_min(t1.ToDouble(),true,true);
|
ImPlotTick tick_min(t1.ToDouble(),true,true);
|
||||||
tick_min.Level = 0;
|
tick_min.Level = 0;
|
||||||
LabelTickTime(tick_min,ticks.Labels,t1,fmt0,hour24);
|
LabelTickTime(tick_min,ticks.TextBuffer,t1,fmt0,hour24);
|
||||||
ticks.AddTick(tick_min);
|
ticks.Append(tick_min);
|
||||||
// major level 1 tick
|
// major level 1 tick
|
||||||
ImPlotTick tick_maj(t1.ToDouble(),true,true);
|
ImPlotTick tick_maj(t1.ToDouble(),true,true);
|
||||||
tick_maj.Level = 1;
|
tick_maj.Level = 1;
|
||||||
LabelTickTime(tick_maj,ticks.Labels,t1, last_major == NULL ? fmtf : fmt1,hour24);
|
LabelTickTime(tick_maj,ticks.TextBuffer,t1, last_major == NULL ? fmtf : fmt1,hour24);
|
||||||
const char* this_major = ticks.Labels.Buf.Data + tick_maj.BufferOffset;
|
const char* this_major = ticks.TextBuffer.Buf.Data + tick_maj.TextOffset;
|
||||||
if (last_major && TimeLabelSame(last_major,this_major))
|
if (last_major && TimeLabelSame(last_major,this_major))
|
||||||
tick_maj.ShowLabel = false;
|
tick_maj.ShowLabel = false;
|
||||||
last_major = this_major;
|
last_major = this_major;
|
||||||
ticks.AddTick(tick_maj);
|
ticks.Append(tick_maj);
|
||||||
}
|
}
|
||||||
// add minor ticks up until next major
|
// add minor ticks up until next major
|
||||||
if (minor_per_major > 1 && (t_min <= t2 && t1 <= t_max)) {
|
if (minor_per_major > 1 && (t_min <= t2 && t1 <= t_max)) {
|
||||||
|
@ -1073,14 +1080,14 @@ void AddTicksTime(const ImPlotRange& range, float plot_width, bool hour24, ImPlo
|
||||||
if (t12 >= t_min && t12 <= t_max) {
|
if (t12 >= t_min && t12 <= t_max) {
|
||||||
ImPlotTick tick(t12.ToDouble(),false,px_to_t2 >= fmt0_width);
|
ImPlotTick tick(t12.ToDouble(),false,px_to_t2 >= fmt0_width);
|
||||||
tick.Level = 0;
|
tick.Level = 0;
|
||||||
LabelTickTime(tick,ticks.Labels,t12,fmt0,hour24);
|
LabelTickTime(tick,ticks.TextBuffer,t12,fmt0,hour24);
|
||||||
ticks.AddTick(tick);
|
ticks.Append(tick);
|
||||||
if (last_major == NULL && px_to_t2 >= fmt0_width && px_to_t2 >= (fmt1_width + fmtf_width) / 2) {
|
if (last_major == NULL && px_to_t2 >= fmt0_width && px_to_t2 >= (fmt1_width + fmtf_width) / 2) {
|
||||||
ImPlotTick tick_maj(t12.ToDouble(),true,true);
|
ImPlotTick tick_maj(t12.ToDouble(),true,true);
|
||||||
tick_maj.Level = 1;
|
tick_maj.Level = 1;
|
||||||
LabelTickTime(tick_maj,ticks.Labels,t12,fmtf,hour24);
|
LabelTickTime(tick_maj,ticks.TextBuffer,t12,fmtf,hour24);
|
||||||
last_major = ticks.Labels.Buf.Data + tick_maj.BufferOffset;
|
last_major = ticks.TextBuffer.Buf.Data + tick_maj.TextOffset;
|
||||||
ticks.AddTick(tick_maj);
|
ticks.Append(tick_maj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t12 = AddTime(t12, unit0, step);
|
t12 = AddTime(t12, unit0, step);
|
||||||
|
@ -1106,8 +1113,8 @@ void AddTicksTime(const ImPlotRange& range, float plot_width, bool hour24, ImPlo
|
||||||
if (t >= t_min && t <= t_max) {
|
if (t >= t_min && t <= t_max) {
|
||||||
ImPlotTick tick(t.ToDouble(), true, true);
|
ImPlotTick tick(t.ToDouble(), true, true);
|
||||||
tick.Level = 0;
|
tick.Level = 0;
|
||||||
LabelTickTime(tick, ticks.Labels, t, TimeFormatLevel0[ImPlotTimeUnit_Yr], hour24);
|
LabelTickTime(tick, ticks.TextBuffer, t, TimeFormatLevel0[ImPlotTimeUnit_Yr], hour24);
|
||||||
ticks.AddTick(tick);
|
ticks.Append(tick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1707,7 +1714,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
ImPlotTick *xt = &gp.XTicks.Ticks[t];
|
ImPlotTick *xt = &gp.XTicks.Ticks[t];
|
||||||
if (xt->ShowLabel && xt->PixelPos >= gp.BB_Plot.Min.x - 1 && xt->PixelPos <= gp.BB_Plot.Max.x + 1)
|
if (xt->ShowLabel && xt->PixelPos >= gp.BB_Plot.Min.x - 1 && xt->PixelPos <= gp.BB_Plot.Max.x + 1)
|
||||||
DrawList.AddText(ImVec2(xt->PixelPos - xt->LabelSize.x * 0.5f, gp.BB_Plot.Max.y + gp.Style.LabelPadding.y + xt->Level * (txt_height + gp.Style.LabelPadding.y)),
|
DrawList.AddText(ImVec2(xt->PixelPos - xt->LabelSize.x * 0.5f, gp.BB_Plot.Max.y + gp.Style.LabelPadding.y + xt->Level * (txt_height + gp.Style.LabelPadding.y)),
|
||||||
xt->Major ? gp.Col_X.MajTxt : gp.Col_X.MinTxt, gp.XTicks.GetLabel(t));
|
xt->Major ? gp.Col_X.MajTxt : gp.Col_X.MinTxt, gp.XTicks.GetText(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||||
|
@ -1717,7 +1724,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
||||||
ImPlotTick *yt = &gp.YTicks[i].Ticks[t];
|
ImPlotTick *yt = &gp.YTicks[i].Ticks[t];
|
||||||
if (yt->ShowLabel && yt->PixelPos >= gp.BB_Plot.Min.y - 1 && yt->PixelPos <= gp.BB_Plot.Max.y + 1) {
|
if (yt->ShowLabel && yt->PixelPos >= gp.BB_Plot.Min.y - 1 && yt->PixelPos <= gp.BB_Plot.Max.y + 1) {
|
||||||
ImVec2 start(x_start, yt->PixelPos - 0.5f * yt->LabelSize.y);
|
ImVec2 start(x_start, yt->PixelPos - 0.5f * yt->LabelSize.y);
|
||||||
DrawList.AddText(start, yt->Major ? gp.Col_Y[i].MajTxt : gp.Col_Y[i].MinTxt, gp.YTicks[i].GetLabel(t));
|
DrawList.AddText(start, yt->Major ? gp.Col_Y[i].MajTxt : gp.Col_Y[i].MinTxt, gp.YTicks[i].GetText(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1930,8 +1937,8 @@ void ShowPlotContextMenu(ImPlotState& plot) {
|
||||||
ImGui::LabelText("Plots", "%d", gp.Plots.GetSize());
|
ImGui::LabelText("Plots", "%d", gp.Plots.GetSize());
|
||||||
ImGui::LabelText("Color Mods", "%d", gp.ColorModifiers.size());
|
ImGui::LabelText("Color Mods", "%d", gp.ColorModifiers.size());
|
||||||
ImGui::LabelText("Style Mods", "%d", gp.StyleModifiers.size());
|
ImGui::LabelText("Style Mods", "%d", gp.StyleModifiers.size());
|
||||||
ImGui::TextUnformatted(gp.XTicks.Labels.Buf.Data, gp.XTicks.Labels.Buf.Data + gp.XTicks.Labels.size());
|
ImGui::TextUnformatted(gp.XTicks.TextBuffer.Buf.Data, gp.XTicks.TextBuffer.Buf.Data + gp.XTicks.TextBuffer.size());
|
||||||
ImGui::TextUnformatted(gp.YTicks[0].Labels.Buf.Data, gp.YTicks[0].Labels.Buf.Data + gp.YTicks[0].Labels.size());
|
ImGui::TextUnformatted(gp.YTicks[0].TextBuffer.Buf.Data, gp.YTicks[0].TextBuffer.Buf.Data + gp.YTicks[0].TextBuffer.size());
|
||||||
// ImGui::TextUnformatted(gp.YTicks[1].Labels.Buf.Data, gp.YTicks[1].Labels.Buf.Data + gp.YTicks[1].Labels.size());
|
// ImGui::TextUnformatted(gp.YTicks[1].Labels.Buf.Data, gp.YTicks[1].Labels.Buf.Data + gp.YTicks[1].Labels.size());
|
||||||
// ImGui::TextUnformatted(gp.YTicks[2].Labels.Buf.Data, gp.YTicks[2].Labels.Buf.Data + gp.YTicks[2].Labels.size());
|
// ImGui::TextUnformatted(gp.YTicks[2].Labels.Buf.Data, gp.YTicks[2].Labels.Buf.Data + gp.YTicks[2].Labels.size());
|
||||||
|
|
||||||
|
@ -2008,6 +2015,47 @@ void EndPlot() {
|
||||||
}
|
}
|
||||||
ImGui::PopClipRect();
|
ImGui::PopClipRect();
|
||||||
|
|
||||||
|
// render annotations
|
||||||
|
PushPlotClipRect();
|
||||||
|
for (int i = 0; i < gp.Annotations.Size; ++i) {
|
||||||
|
const char* txt = gp.Annotations.GetText(i);
|
||||||
|
ImPlotAnnotation& an = gp.Annotations.Annotations[i];
|
||||||
|
const ImVec2 txt_size = ImGui::CalcTextSize(txt);
|
||||||
|
const ImVec2 size = txt_size + gp.Style.AnnotationPadding * 2;
|
||||||
|
ImVec2 pos = an.Pos;
|
||||||
|
if (an.Offset.x == 0)
|
||||||
|
pos.x -= size.x / 2;
|
||||||
|
else if (an.Offset.x > 0)
|
||||||
|
pos.x += an.Offset.x;
|
||||||
|
else
|
||||||
|
pos.x -= size.x - an.Offset.x;
|
||||||
|
if (an.Offset.y == 0)
|
||||||
|
pos.y -= size.y / 2;
|
||||||
|
else if (an.Offset.y > 0)
|
||||||
|
pos.y += an.Offset.y;
|
||||||
|
else
|
||||||
|
pos.y -= size.y - an.Offset.y;
|
||||||
|
if (an.Clamp)
|
||||||
|
pos = ClampLabelPos(pos, size, gp.BB_Plot.Min, gp.BB_Plot.Max);
|
||||||
|
ImRect rect(pos,pos+size);
|
||||||
|
if (an.Offset.x != 0 || an.Offset.y != 0) {
|
||||||
|
ImVec2 corners[4] = {rect.GetTL(), rect.GetTR(), rect.GetBR(), rect.GetBL()};
|
||||||
|
int min_corner = 0;
|
||||||
|
float min_len = FLT_MAX;
|
||||||
|
for (int c = 0; c < 4; ++c) {
|
||||||
|
float len = ImLengthSqr(an.Pos - corners[c]);
|
||||||
|
if (len < min_len) {
|
||||||
|
min_corner = c;
|
||||||
|
min_len = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DrawList.AddLine(an.Pos, corners[min_corner], an.ColorBg);
|
||||||
|
}
|
||||||
|
DrawList.AddRectFilled(rect.Min, rect.Max, an.ColorBg);
|
||||||
|
DrawList.AddText(pos + gp.Style.AnnotationPadding, an.ColorFg, txt);
|
||||||
|
}
|
||||||
|
PopPlotClipRect();
|
||||||
|
|
||||||
// render y-axis drag/drop hover
|
// render y-axis drag/drop hover
|
||||||
if ((gp.Y[1].Present || gp.Y[2].Present) && ImGui::IsDragDropPayloadBeingAccepted()) {
|
if ((gp.Y[1].Present || gp.Y[2].Present) && ImGui::IsDragDropPayloadBeingAccepted()) {
|
||||||
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
|
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
|
||||||
|
@ -2483,6 +2531,43 @@ ImPlotLimits GetPlotQuery(int y_axis_in) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnnotateEx(double x, double y, bool clamp, const ImVec4& col, const ImVec2& off, const char* fmt, va_list args) {
|
||||||
|
ImPlotContext& gp = *GImPlot;
|
||||||
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "Annotate() needs to be called between BeginPlot() and EndPlot()!");
|
||||||
|
ImVec2 pos = PlotToPixels(x,y);
|
||||||
|
ImU32 bg = ImGui::GetColorU32(col);
|
||||||
|
ImU32 fg = col.w == 0 ? GetStyleColorU32(ImPlotCol_InlayText) : CalcTextColor(col);
|
||||||
|
gp.Annotations.AppendV(pos, off, bg, fg, clamp, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Annotate(double x, double y, const char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
AnnotateEx(x,y,false,ImVec4(0,0,0,0),GImPlot->Style.AnnotationOffset,fmt,args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Annotate(double x, double y, const ImVec4& col, const char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
AnnotateEx(x,y,false,col,GImPlot->Style.AnnotationOffset,fmt,args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnnotateClamped(double x, double y, const char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
AnnotateEx(x,y,true,ImVec4(0,0,0,0),GImPlot->Style.AnnotationOffset,fmt,args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnnotateClamped(double x, double y, const ImVec4& col, const char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
AnnotateEx(x,y,true,col,GImPlot->Style.AnnotationOffset,fmt,args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
bool DragLineX(const char* id, double* value, bool show_label, const ImVec4& col, float thickness) {
|
bool DragLineX(const char* id, double* value, bool show_label, const ImVec4& col, float thickness) {
|
||||||
ImPlotContext& gp = *GImPlot;
|
ImPlotContext& gp = *GImPlot;
|
||||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "DragLineX() needs to be called between BeginPlot() and EndPlot()!");
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "DragLineX() needs to be called between BeginPlot() and EndPlot()!");
|
||||||
|
@ -2509,22 +2594,12 @@ bool DragLineX(const char* id, double* value, bool show_label, const ImVec4& col
|
||||||
ImGui::GetCurrentWindow()->DC.CursorPos = new_cursor_pos;
|
ImGui::GetCurrentWindow()->DC.CursorPos = new_cursor_pos;
|
||||||
ImGui::InvisibleButton(id, ImVec2(grab_size, yb-yt));
|
ImGui::InvisibleButton(id, ImVec2(grab_size, yb-yt));
|
||||||
ImGui::GetCurrentWindow()->DC.CursorPos = old_cursor_pos;
|
ImGui::GetCurrentWindow()->DC.CursorPos = old_cursor_pos;
|
||||||
if (ImGui::IsItemHovered() || ImGui::IsItemActive()) {
|
if (ImGui::IsItemHovered() || ImGui::IsItemActive()) {
|
||||||
gp.Hov_Plot = false;
|
gp.Hov_Plot = false;
|
||||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||||
if (show_label) {
|
if (show_label) {
|
||||||
PushPlotClipRect();
|
|
||||||
double range_x = gp.XTicks.Size > 1 ? (gp.XTicks.Ticks[1].PlotPos - gp.XTicks.Ticks[0].PlotPos) : gp.CurrentPlot->XAxis.Range.Size();
|
double range_x = gp.XTicks.Size > 1 ? (gp.XTicks.Ticks[1].PlotPos - gp.XTicks.Ticks[0].PlotPos) : gp.CurrentPlot->XAxis.Range.Size();
|
||||||
char buf[32];
|
gp.Annotations.Append(ImVec2(x,yb),ImVec2(0,0),col32,CalcTextColor(color),true,"%s = %.*f", id, Precision(range_x), *value);
|
||||||
snprintf(buf, 32, "%s = %.*f", id, Precision(range_x), *value);
|
|
||||||
ImVec2 size = ImGui::CalcTextSize(buf);
|
|
||||||
const int pad = 2;
|
|
||||||
ImVec2 label_pos = ImVec2(x - size.x/2 - pad, yb - size.y - 2*pad);
|
|
||||||
ImVec2 label_size = size + ImVec2(pad*2,pad*2);
|
|
||||||
label_pos = ClampLabelPos(label_pos, label_size, gp.BB_Plot.Min, gp.BB_Plot.Max);
|
|
||||||
DrawList.AddRectFilled(label_pos, label_pos + label_size, col32);
|
|
||||||
DrawList.AddText(label_pos + ImVec2(pad,pad),CalcTextColor(color),buf);
|
|
||||||
PopPlotClipRect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool dragging = false;
|
bool dragging = false;
|
||||||
|
@ -2568,27 +2643,8 @@ bool DragLineY(const char* id, double* value, bool show_label, const ImVec4& col
|
||||||
gp.Hov_Plot = false;
|
gp.Hov_Plot = false;
|
||||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
||||||
if (show_label) {
|
if (show_label) {
|
||||||
PushPlotClipRect();
|
|
||||||
double range_y = gp.YTicks[yax].Size > 1 ? (gp.YTicks[yax].Ticks[1].PlotPos - gp.YTicks[yax].Ticks[0].PlotPos) : gp.CurrentPlot->YAxis[yax].Range.Size();
|
double range_y = gp.YTicks[yax].Size > 1 ? (gp.YTicks[yax].Ticks[1].PlotPos - gp.YTicks[yax].Ticks[0].PlotPos) : gp.CurrentPlot->YAxis[yax].Range.Size();
|
||||||
char buf[32];
|
gp.Annotations.Append(ImVec2(yax == 0 ? xl : xr,y), ImVec2(0,0), col32, CalcTextColor(color), true, "%s = %.*f", id, Precision(range_y), *value);
|
||||||
snprintf(buf, 32, "%s = %.*f", id, Precision(range_y), *value);
|
|
||||||
ImVec2 size = ImGui::CalcTextSize(buf);
|
|
||||||
const int pad = 2;
|
|
||||||
if (yax == 0) {
|
|
||||||
ImVec2 label_pos = ImVec2(xl,y-pad-size.y/2);
|
|
||||||
ImVec2 label_size = size + ImVec2(pad*2,pad*2);
|
|
||||||
label_pos = ClampLabelPos(label_pos, label_size, gp.BB_Plot.Min, gp.BB_Plot.Max);
|
|
||||||
DrawList.AddRectFilled(label_pos, label_pos + label_size, col32);
|
|
||||||
DrawList.AddText(label_pos + ImVec2(pad,pad),CalcTextColor(color),buf);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ImVec2 label_pos = ImVec2(xr-size.x-2*pad,y-pad-size.y/2);
|
|
||||||
ImVec2 label_size = size + ImVec2(pad*2,pad*2);
|
|
||||||
label_pos = ClampLabelPos(label_pos, label_size, gp.BB_Plot.Min, gp.BB_Plot.Max);
|
|
||||||
DrawList.AddRectFilled(label_pos, label_pos + label_size, col32);
|
|
||||||
DrawList.AddText(label_pos + ImVec2(pad,pad),CalcTextColor(color),buf);
|
|
||||||
}
|
|
||||||
PopPlotClipRect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool dragging = false;
|
bool dragging = false;
|
||||||
|
@ -2624,18 +2680,10 @@ bool DragPoint(const char* id, double* x, double* y, bool show_label, const ImVe
|
||||||
gp.Hov_Plot = false;
|
gp.Hov_Plot = false;
|
||||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
|
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
|
||||||
if (show_label) {
|
if (show_label) {
|
||||||
PushPlotClipRect();
|
|
||||||
double range_x = gp.XTicks.Size > 1 ? (gp.XTicks.Ticks[1].PlotPos - gp.XTicks.Ticks[0].PlotPos) : gp.CurrentPlot->XAxis.Range.Size();
|
double range_x = gp.XTicks.Size > 1 ? (gp.XTicks.Ticks[1].PlotPos - gp.XTicks.Ticks[0].PlotPos) : gp.CurrentPlot->XAxis.Range.Size();
|
||||||
double range_y = gp.YTicks[yax].Size > 1 ? (gp.YTicks[yax].Ticks[1].PlotPos - gp.YTicks[yax].Ticks[0].PlotPos) : gp.CurrentPlot->YAxis[yax].Range.Size();
|
double range_y = gp.YTicks[yax].Size > 1 ? (gp.YTicks[yax].Ticks[1].PlotPos - gp.YTicks[yax].Ticks[0].PlotPos) : gp.CurrentPlot->YAxis[yax].Range.Size();
|
||||||
char buf[64];
|
|
||||||
const float yb = gp.BB_Plot.Max.y;
|
|
||||||
snprintf(buf, 64, "%s = %.*f,%.*f", id, Precision(range_x), *x, Precision(range_y), *y);
|
|
||||||
ImVec2 label_pos = pos + ImVec2(16 * GImGui->Style.MouseCursorScale, 8 * GImGui->Style.MouseCursorScale);
|
ImVec2 label_pos = pos + ImVec2(16 * GImGui->Style.MouseCursorScale, 8 * GImGui->Style.MouseCursorScale);
|
||||||
ImVec2 label_size = ImGui::CalcTextSize(buf) + ImVec2(4,4);
|
gp.Annotations.Append(label_pos, ImVec2(0.0001f,0.00001f), col32, CalcTextColor(color), true, "%s = %.*f,%.*f", id, Precision(range_x), *x, Precision(range_y), *y);
|
||||||
label_pos = ClampLabelPos(label_pos, label_size, gp.BB_Plot.Min, gp.BB_Plot.Max);
|
|
||||||
DrawList.AddRectFilled(label_pos, label_pos + label_size, col32);
|
|
||||||
DrawList.AddText(label_pos + ImVec2(2,2), CalcTextColor(color), buf);
|
|
||||||
PopPlotClipRect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool dragging = false;
|
bool dragging = false;
|
||||||
|
@ -3133,7 +3181,7 @@ void ShowColormapScale(double scale_min, double scale_max, float height) {
|
||||||
float ypos = ImRemap((float)ticks.Ticks[i].PlotPos, (float)range.Max, (float)range.Min, bb_grad.Min.y, bb_grad.Max.y);
|
float ypos = ImRemap((float)ticks.Ticks[i].PlotPos, (float)range.Max, (float)range.Min, bb_grad.Min.y, bb_grad.Max.y);
|
||||||
if (ypos < bb_grad.Max.y - 2 && ypos > bb_grad.Min.y + 2)
|
if (ypos < bb_grad.Max.y - 2 && ypos > bb_grad.Min.y + 2)
|
||||||
DrawList.AddLine(ImVec2(bb_grad.Max.x-1, ypos), ImVec2(bb_grad.Max.x - (ticks.Ticks[i].Major ? 10.0f : 5.0f), ypos), col_tick, 1.0f);
|
DrawList.AddLine(ImVec2(bb_grad.Max.x-1, ypos), ImVec2(bb_grad.Max.x - (ticks.Ticks[i].Major ? 10.0f : 5.0f), ypos), col_tick, 1.0f);
|
||||||
DrawList.AddText(ImVec2(bb_grad.Max.x-1, ypos) + ImVec2(txt_off, -ticks.Ticks[i].LabelSize.y * 0.5f), GetStyleColorU32(ImPlotCol_TitleText), ticks.GetLabel(i));
|
DrawList.AddText(ImVec2(bb_grad.Max.x-1, ypos) + ImVec2(txt_off, -ticks.Ticks[i].LabelSize.y * 0.5f), GetStyleColorU32(ImPlotCol_TitleText), ticks.GetText(i));
|
||||||
}
|
}
|
||||||
ImGui::PopClipRect();
|
ImGui::PopClipRect();
|
||||||
|
|
||||||
|
@ -3221,12 +3269,14 @@ void ShowStyleEditor(ImPlotStyle* ref) {
|
||||||
ImGui::SliderFloat2("MinorTickSize", (float*)&style.MinorTickSize, 0.0f, 2.0f, "%.1f");
|
ImGui::SliderFloat2("MinorTickSize", (float*)&style.MinorTickSize, 0.0f, 2.0f, "%.1f");
|
||||||
ImGui::SliderFloat2("MajorGridSize", (float*)&style.MajorGridSize, 0.0f, 2.0f, "%.1f");
|
ImGui::SliderFloat2("MajorGridSize", (float*)&style.MajorGridSize, 0.0f, 2.0f, "%.1f");
|
||||||
ImGui::SliderFloat2("MinorGridSize", (float*)&style.MinorGridSize, 0.0f, 2.0f, "%.1f");
|
ImGui::SliderFloat2("MinorGridSize", (float*)&style.MinorGridSize, 0.0f, 2.0f, "%.1f");
|
||||||
|
ImGui::SliderFloat2("PlotMinSize", (float*)&style.PlotMinSize, 0.0f, 300, "%.0f");
|
||||||
ImGui::Text("Plot Padding");
|
ImGui::Text("Plot Padding");
|
||||||
ImGui::SliderFloat2("PlotPadding", (float*)&style.PlotPadding, 0.0f, 20.0f, "%.0f");
|
ImGui::SliderFloat2("PlotPadding", (float*)&style.PlotPadding, 0.0f, 20.0f, "%.0f");
|
||||||
ImGui::SliderFloat2("LabelPadding", (float*)&style.LabelPadding, 0.0f, 20.0f, "%.0f");
|
ImGui::SliderFloat2("LabelPadding", (float*)&style.LabelPadding, 0.0f, 20.0f, "%.0f");
|
||||||
ImGui::SliderFloat2("LegendPadding", (float*)&style.LegendPadding, 0.0f, 20.0f, "%.0f");
|
ImGui::SliderFloat2("LegendPadding", (float*)&style.LegendPadding, 0.0f, 20.0f, "%.0f");
|
||||||
ImGui::SliderFloat2("InfoPadding", (float*)&style.InfoPadding, 0.0f, 20.0f, "%.0f");
|
ImGui::SliderFloat2("InfoPadding", (float*)&style.InfoPadding, 0.0f, 20.0f, "%.0f");
|
||||||
ImGui::SliderFloat2("PlotMinSize", (float*)&style.PlotMinSize, 0.0f, 300, "%.0f");
|
ImGui::SliderFloat2("AnnotationPadding", (float*)&style.AnnotationPadding, 0.0f, 5.0f, "%.0f");
|
||||||
|
ImGui::SliderFloat2("AnnotationOffset", (float*)&style.AnnotationOffset, -20.0f, 20.0f, "%.0f");
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("Colors")) {
|
if (ImGui::BeginTabItem("Colors")) {
|
||||||
|
|
74
implot.h
74
implot.h
|
@ -125,29 +125,31 @@ enum ImPlotCol_ {
|
||||||
// Plot styling variables.
|
// Plot styling variables.
|
||||||
enum ImPlotStyleVar_ {
|
enum ImPlotStyleVar_ {
|
||||||
// item styling variables
|
// item styling variables
|
||||||
ImPlotStyleVar_LineWeight, // float, plot item line weight in pixels
|
ImPlotStyleVar_LineWeight, // float, plot item line weight in pixels
|
||||||
ImPlotStyleVar_Marker, // int, marker specification
|
ImPlotStyleVar_Marker, // int, marker specification
|
||||||
ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius")
|
ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius")
|
||||||
ImPlotStyleVar_MarkerWeight, // float, plot outline weight of markers in pixels
|
ImPlotStyleVar_MarkerWeight, // float, plot outline weight of markers in pixels
|
||||||
ImPlotStyleVar_FillAlpha, // float, alpha modifier applied to all plot item fills
|
ImPlotStyleVar_FillAlpha, // float, alpha modifier applied to all plot item fills
|
||||||
ImPlotStyleVar_ErrorBarSize, // float, error bar whisker width in pixels
|
ImPlotStyleVar_ErrorBarSize, // float, error bar whisker width in pixels
|
||||||
ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels
|
ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels
|
||||||
ImPlotStyleVar_DigitalBitHeight, // float, digital channels bit height (at 1) in pixels
|
ImPlotStyleVar_DigitalBitHeight, // float, digital channels bit height (at 1) in pixels
|
||||||
ImPlotStyleVar_DigitalBitGap, // float, digital channels bit padding gap in pixels
|
ImPlotStyleVar_DigitalBitGap, // float, digital channels bit padding gap in pixels
|
||||||
// plot styling variables
|
// plot styling variables
|
||||||
ImPlotStyleVar_PlotBorderSize, // float, thickness of border around plot area
|
ImPlotStyleVar_PlotBorderSize, // float, thickness of border around plot area
|
||||||
ImPlotStyleVar_MinorAlpha, // float, alpha multiplier applied to minor axis grid lines
|
ImPlotStyleVar_MinorAlpha, // float, alpha multiplier applied to minor axis grid lines
|
||||||
ImPlotStyleVar_MajorTickLen, // ImVec2, major tick lengths for X and Y axes
|
ImPlotStyleVar_MajorTickLen, // ImVec2, major tick lengths for X and Y axes
|
||||||
ImPlotStyleVar_MinorTickLen, // ImVec2, minor tick lengths for X and Y axes
|
ImPlotStyleVar_MinorTickLen, // ImVec2, minor tick lengths for X and Y axes
|
||||||
ImPlotStyleVar_MajorTickSize, // ImVec2, line thickness of major ticks
|
ImPlotStyleVar_MajorTickSize, // ImVec2, line thickness of major ticks
|
||||||
ImPlotStyleVar_MinorTickSize, // ImVec2, line thickness of minor ticks
|
ImPlotStyleVar_MinorTickSize, // ImVec2, line thickness of minor ticks
|
||||||
ImPlotStyleVar_MajorGridSize, // ImVec2, line thickness of major grid lines
|
ImPlotStyleVar_MajorGridSize, // ImVec2, line thickness of major grid lines
|
||||||
ImPlotStyleVar_MinorGridSize, // ImVec2, line thickness of minor grid lines
|
ImPlotStyleVar_MinorGridSize, // ImVec2, line thickness of minor grid lines
|
||||||
ImPlotStyleVar_PlotPadding, // ImVec2, padding between widget frame and plot area and/or labels
|
ImPlotStyleVar_PlotPadding, // ImVec2, padding between widget frame and plot area and/or labels
|
||||||
ImPlotStyleVar_LabelPadding, // ImVec2, padding between axes labels, tick labels, and plot edge
|
ImPlotStyleVar_LabelPadding, // ImVec2, padding between axes labels, tick labels, and plot edge
|
||||||
ImPlotStyleVar_LegendPadding, // ImVec2, legend padding from top-left of plot
|
ImPlotStyleVar_LegendPadding, // ImVec2, legend padding from top-left of plot
|
||||||
ImPlotStyleVar_InfoPadding, // ImVec2, padding between plot edge and interior info text
|
ImPlotStyleVar_InfoPadding, // ImVec2, padding between plot edge and interior info text
|
||||||
ImPlotStyleVar_PlotMinSize, // ImVec2, minimum size plot frame can be when shrunk
|
ImPlotStyleVar_AnnotationPadding, // ImVec2, text padding around annotation labels
|
||||||
|
ImPlotStyleVar_AnnotationOffset, // ImVec2, annotation label offset in pixels (0,0 will center the label)
|
||||||
|
ImPlotStyleVar_PlotMinSize, // ImVec2, minimum size plot frame can be when shrunk
|
||||||
ImPlotStyleVar_COUNT
|
ImPlotStyleVar_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,6 +240,8 @@ struct ImPlotStyle {
|
||||||
ImVec2 LabelPadding; // = 5,5 padding between axes labels, tick labels, and plot edge
|
ImVec2 LabelPadding; // = 5,5 padding between axes labels, tick labels, and plot edge
|
||||||
ImVec2 LegendPadding; // = 10,10 legend padding from top-left of plot
|
ImVec2 LegendPadding; // = 10,10 legend padding from top-left of plot
|
||||||
ImVec2 InfoPadding; // = 10,10 padding between plot edge and interior info text
|
ImVec2 InfoPadding; // = 10,10 padding between plot edge and interior info text
|
||||||
|
ImVec2 AnnotationPadding; // = 2,2 text padding around annotation labels
|
||||||
|
ImVec2 AnnotationOffset; // = 10,10 annotation label offset in pixels (0,0 will center the label)
|
||||||
ImVec2 PlotMinSize; // = 300,225 minimum size plot frame can be when shrunk
|
ImVec2 PlotMinSize; // = 300,225 minimum size plot frame can be when shrunk
|
||||||
// colors
|
// colors
|
||||||
ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors
|
ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors
|
||||||
|
@ -398,7 +402,7 @@ template <typename T> IMPLOT_API void PlotDigital(const char* label_id, const T*
|
||||||
IMPLOT_API void PlotImage(const char* label_id, ImTextureID user_texture_id, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max, const ImVec2& uv0=ImVec2(0,0), const ImVec2& uv1=ImVec2(1,1), const ImVec4& tint_col=ImVec4(1,1,1,1));
|
IMPLOT_API void PlotImage(const char* label_id, ImTextureID user_texture_id, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max, const ImVec2& uv0=ImVec2(0,0), const ImVec2& uv1=ImVec2(1,1), const ImVec4& tint_col=ImVec4(1,1,1,1));
|
||||||
|
|
||||||
// Plots a centered text label at point x,y with optional pixel offset. Text color can be changed with ImPlot::PushStyleColor(ImPlotCol_InlayText, ...).
|
// Plots a centered text label at point x,y with optional pixel offset. Text color can be changed with ImPlot::PushStyleColor(ImPlotCol_InlayText, ...).
|
||||||
IMPLOT_API void PlotText(const char* text, double x, double y, bool vertical=false, const ImVec2& pixel_offset=ImVec2(0,0));
|
IMPLOT_API void PlotText(const char* text, double x, double y, bool vertical=false, const ImVec2& pix_offset=ImVec2(0,0));
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Plot Utils
|
// Plot Utils
|
||||||
|
@ -453,10 +457,22 @@ IMPLOT_API ImPlotPoint GetPlotMousePos(int y_axis = IMPLOT_AUTO);
|
||||||
// Returns the current plot axis range. A negative y_axis uses the current value of SetPlotYAxis (0 initially).
|
// Returns the current plot axis range. A negative y_axis uses the current value of SetPlotYAxis (0 initially).
|
||||||
IMPLOT_API ImPlotLimits GetPlotLimits(int y_axis = IMPLOT_AUTO);
|
IMPLOT_API ImPlotLimits GetPlotLimits(int y_axis = IMPLOT_AUTO);
|
||||||
|
|
||||||
|
// Returns true if the current plot is being queried. Query must be enabled with ImPlotFlags_Query.
|
||||||
|
IMPLOT_API bool IsPlotQueried();
|
||||||
|
// Returns the current plot query bounds. Query must be enabled with ImPlotFlags_Query.
|
||||||
|
IMPLOT_API ImPlotLimits GetPlotQuery(int y_axis = IMPLOT_AUTO);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Plot Tools
|
// Plot Tools
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Shows an annotation callout at a chosen point. Annotations can be offset or centered with ImPlotStyleVar_AnnotationOffset.
|
||||||
|
IMPLOT_API void Annotate(double x, double y, const char* fmt, ...) IM_FMTARGS(3);
|
||||||
|
IMPLOT_API void Annotate(double x, double y, const ImVec4& color, const char* fmt, ...) IM_FMTARGS(4);
|
||||||
|
// Same as above, but the annotation will always be clamped to stay inside the plot area.
|
||||||
|
IMPLOT_API void AnnotateClamped(double x, double y, const char* fmt, ...) IM_FMTARGS(3);
|
||||||
|
IMPLOT_API void AnnotateClamped(double x, double y, const ImVec4& color, const char* fmt, ...) IM_FMTARGS(4);
|
||||||
|
|
||||||
// Shows a draggable vertical guide line at an x-value. #col defaults to ImGuiCol_Text.
|
// Shows a draggable vertical guide line at an x-value. #col defaults to ImGuiCol_Text.
|
||||||
IMPLOT_API bool DragLineX(const char* id, double* x_value, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
|
IMPLOT_API bool DragLineX(const char* id, double* x_value, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
|
||||||
// Shows a draggable horizontal guide line at a y-value. #col defaults to ImGuiCol_Text.
|
// Shows a draggable horizontal guide line at a y-value. #col defaults to ImGuiCol_Text.
|
||||||
|
@ -464,11 +480,6 @@ IMPLOT_API bool DragLineY(const char* id, double* y_value, bool show_label = tru
|
||||||
// Shows a draggable point at x,y. #col defaults to ImGuiCol_Text.
|
// Shows a draggable point at x,y. #col defaults to ImGuiCol_Text.
|
||||||
IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float radius = 4);
|
IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float radius = 4);
|
||||||
|
|
||||||
// Returns true if the current plot is being queried. Query must be enabled with ImPlotFlags_Query.
|
|
||||||
IMPLOT_API bool IsPlotQueried();
|
|
||||||
// Returns the current plot query bounds. Query must be enabled with ImPlotFlags_Query.
|
|
||||||
IMPLOT_API ImPlotLimits GetPlotQuery(int y_axis = IMPLOT_AUTO);
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Legend Utils and Tools
|
// Legend Utils and Tools
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -533,10 +544,13 @@ IMPLOT_API void SetNextMarkerStyle(ImPlotMarker marker = IMPLOT_AUTO, float size
|
||||||
// Set the error bar style for the next item only.
|
// Set the error bar style for the next item only.
|
||||||
IMPLOT_API void SetNextErrorBarStyle(const ImVec4& col = IMPLOT_AUTO_COL, float size = IMPLOT_AUTO, float weight = IMPLOT_AUTO);
|
IMPLOT_API void SetNextErrorBarStyle(const ImVec4& col = IMPLOT_AUTO_COL, float size = IMPLOT_AUTO, float weight = IMPLOT_AUTO);
|
||||||
|
|
||||||
|
// Gets the last item primary color (i.e. its legend icon color)
|
||||||
|
IMPLOT_API ImVec4 GetLastItemColor();
|
||||||
|
|
||||||
// Returns the null terminated string name for an ImPlotCol.
|
// Returns the null terminated string name for an ImPlotCol.
|
||||||
IMPLOT_API const char* GetStyleColorName(ImPlotCol color);
|
IMPLOT_API const char* GetStyleColorName(ImPlotCol idx);
|
||||||
// Returns the null terminated string name for an ImPlotMarker.
|
// Returns the null terminated string name for an ImPlotMarker.
|
||||||
IMPLOT_API const char* GetMarkerName(ImPlotMarker marker);
|
IMPLOT_API const char* GetMarkerName(ImPlotMarker idx);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Colormaps
|
// Colormaps
|
||||||
|
|
|
@ -659,6 +659,7 @@ void ShowDemoWindow(bool* p_open) {
|
||||||
double t_now = (double)time(0);
|
double t_now = (double)time(0);
|
||||||
double y_now = HugeTimeData::GetY(t_now);
|
double y_now = HugeTimeData::GetY(t_now);
|
||||||
ImPlot::PlotScatter("Now",&t_now,&y_now,1);
|
ImPlot::PlotScatter("Now",&t_now,&y_now,1);
|
||||||
|
ImPlot::Annotate(t_now,y_now,ImPlot::GetLastItemColor(),"Now");
|
||||||
ImPlot::EndPlot();
|
ImPlot::EndPlot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -857,6 +858,39 @@ void ShowDemoWindow(bool* p_open) {
|
||||||
ImPlot::EndPlot();
|
ImPlot::EndPlot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ImGui::CollapsingHeader("Annotations")) {
|
||||||
|
static bool clamp = false;
|
||||||
|
ImGui::Checkbox("Clamp",&clamp);
|
||||||
|
ImPlot::SetNextPlotLimits(0,2,0,1);
|
||||||
|
if (ImPlot::BeginPlot("##Annotations")) {
|
||||||
|
|
||||||
|
static float p[] = {0.25f, 0.25f, 0.75f, 0.75f, 0.25f};
|
||||||
|
ImPlot::PlotScatter("##Points",&p[0],&p[1],4);
|
||||||
|
ImVec4 col = GetLastItemColor();
|
||||||
|
ImPlot::PushStyleVar(ImPlotStyleVar_AnnotationOffset, ImVec2(-15,15));
|
||||||
|
clamp ? ImPlot::AnnotateClamped(0.25,0.25,col,"BL") : ImPlot::Annotate(0.25,0.25,col,"BL");
|
||||||
|
ImPlot::PushStyleVar(ImPlotStyleVar_AnnotationOffset, ImVec2(15,15));
|
||||||
|
clamp ? ImPlot::AnnotateClamped(0.75,0.25,col,"BR") : ImPlot::Annotate(0.75,0.25,col,"BR");
|
||||||
|
ImPlot::PushStyleVar(ImPlotStyleVar_AnnotationOffset, ImVec2(15,-15));
|
||||||
|
clamp ? ImPlot::AnnotateClamped(0.75,0.75,col,"TR") : ImPlot::Annotate(0.75,0.75,col,"TR");
|
||||||
|
ImPlot::PushStyleVar(ImPlotStyleVar_AnnotationOffset, ImVec2(-15,-15));
|
||||||
|
clamp ? ImPlot::AnnotateClamped(0.25,0.75,col,"TL") : ImPlot::Annotate(0.25,0.75,col,"TL");
|
||||||
|
ImPlot::PushStyleVar(ImPlotStyleVar_AnnotationOffset, ImVec2(0,0));
|
||||||
|
clamp ? ImPlot::AnnotateClamped(0.5,0.5,col,"Center") : ImPlot::Annotate(0.5,0.5,col,"Center");
|
||||||
|
ImPlot::PopStyleVar(5);
|
||||||
|
|
||||||
|
float bx[] = {1.2f,1.5f,1.8f};
|
||||||
|
float by[] = {0.25f, 0.5f, 0.75f};
|
||||||
|
ImPlot::PlotBars("##Bars",bx,by,4,0.2);
|
||||||
|
ImPlot::PushStyleVar(ImPlotStyleVar_AnnotationOffset, ImVec2(0,-5));
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
ImPlot::Annotate(bx[i],by[i],"B[%d]=%.2f",i,by[i]);
|
||||||
|
}
|
||||||
|
ImPlot::PopStyleVar();
|
||||||
|
|
||||||
|
ImPlot::EndPlot();
|
||||||
|
}
|
||||||
|
}
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
if (ImGui::CollapsingHeader("Drag and Drop")) {
|
if (ImGui::CollapsingHeader("Drag and Drop")) {
|
||||||
const int K_CHANNELS = 9;
|
const int K_CHANNELS = 9;
|
||||||
|
|
|
@ -77,9 +77,9 @@ extern IMPLOT_API ImPlotContext* GImPlot; // Current implicit context pointer
|
||||||
#define IMPLOT_SUB_DIV 10
|
#define IMPLOT_SUB_DIV 10
|
||||||
// Zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click)
|
// Zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click)
|
||||||
#define IMPLOT_ZOOM_RATE 0.1f
|
#define IMPLOT_ZOOM_RATE 0.1f
|
||||||
// Maximum allowable timestamp value 01/01/3000 @ 12:00am (UTC)
|
// Mimimum allowable timestamp value 01/01/1970 @ 12:00am (UTC) (DO NOT DECREASE THIS)
|
||||||
#define IMPLOT_MIN_TIME 0
|
#define IMPLOT_MIN_TIME 0
|
||||||
// Maximum allowable timestamp value 01/01/3000 @ 12:00am (UTC)
|
// Maximum allowable timestamp value 01/01/3000 @ 12:00am (UTC) (DO NOT INCREASE THIS)
|
||||||
#define IMPLOT_MAX_TIME 32503680000
|
#define IMPLOT_MAX_TIME 32503680000
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -135,7 +135,7 @@ struct ImBufferWriter
|
||||||
Pos = 0;
|
Pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write(const char* fmt, ...) IM_FMTARGS(2) {
|
void Write(const char* fmt, ...) {
|
||||||
va_list argp;
|
va_list argp;
|
||||||
va_start(argp, fmt);
|
va_start(argp, fmt);
|
||||||
const int written = ::vsnprintf(&Buffer[Pos], Size - Pos - 1, fmt, argp);
|
const int written = ::vsnprintf(&Buffer[Pos], Size - Pos - 1, fmt, argp);
|
||||||
|
@ -247,19 +247,68 @@ struct ImPlotColormapMod {
|
||||||
struct ImPlotPointError
|
struct ImPlotPointError
|
||||||
{
|
{
|
||||||
double X, Y, Neg, Pos;
|
double X, Y, Neg, Pos;
|
||||||
|
|
||||||
ImPlotPointError(double x, double y, double neg, double pos) {
|
ImPlotPointError(double x, double y, double neg, double pos) {
|
||||||
X = x; Y = y; Neg = neg; Pos = pos;
|
X = x; Y = y; Neg = neg; Pos = pos;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Interior plot label/annotation
|
||||||
|
struct ImPlotAnnotation {
|
||||||
|
ImVec2 Pos;
|
||||||
|
ImVec2 Offset;
|
||||||
|
ImU32 ColorBg;
|
||||||
|
ImU32 ColorFg;
|
||||||
|
int TextOffset;
|
||||||
|
bool Clamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Collection of plot labels
|
||||||
|
struct ImPlotAnnotationCollection {
|
||||||
|
|
||||||
|
ImVector<ImPlotAnnotation> Annotations;
|
||||||
|
ImGuiTextBuffer TextBuffer;
|
||||||
|
int Size;
|
||||||
|
|
||||||
|
ImPlotAnnotationCollection() { Reset(); }
|
||||||
|
|
||||||
|
void AppendV(const ImVec2& pos, const ImVec2& off, ImU32 bg, ImU32 fg, bool clamp, const char* fmt, va_list args) IM_FMTLIST(7) {
|
||||||
|
ImPlotAnnotation an;
|
||||||
|
an.Pos = pos; an.Offset = off;
|
||||||
|
an.ColorBg = bg; an.ColorFg = fg;
|
||||||
|
an.TextOffset = TextBuffer.size();
|
||||||
|
an.Clamp = clamp;
|
||||||
|
Annotations.push_back(an);
|
||||||
|
TextBuffer.appendfv(fmt, args);
|
||||||
|
const char nul[] = "";
|
||||||
|
TextBuffer.append(nul,nul+1);
|
||||||
|
Size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append(const ImVec2& pos, const ImVec2& off, ImU32 bg, ImU32 fg, bool clamp, const char* fmt, ...) IM_FMTARGS(7) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
AppendV(pos, off, bg, fg, clamp, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* GetText(int idx) {
|
||||||
|
return TextBuffer.Buf.Data + Annotations[idx].TextOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() {
|
||||||
|
Annotations.shrink(0);
|
||||||
|
TextBuffer.Buf.shrink(0);
|
||||||
|
Size = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Tick mark info
|
// Tick mark info
|
||||||
struct ImPlotTick
|
struct ImPlotTick
|
||||||
{
|
{
|
||||||
double PlotPos;
|
double PlotPos;
|
||||||
float PixelPos;
|
float PixelPos;
|
||||||
ImVec2 LabelSize;
|
ImVec2 LabelSize;
|
||||||
int BufferOffset;
|
int TextOffset;
|
||||||
bool Major;
|
bool Major;
|
||||||
bool ShowLabel;
|
bool ShowLabel;
|
||||||
int Level;
|
int Level;
|
||||||
|
@ -268,7 +317,7 @@ struct ImPlotTick
|
||||||
PlotPos = value;
|
PlotPos = value;
|
||||||
Major = major;
|
Major = major;
|
||||||
ShowLabel = show_label;
|
ShowLabel = show_label;
|
||||||
BufferOffset = -1;
|
TextOffset = -1;
|
||||||
Level = 0;
|
Level = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -276,14 +325,16 @@ struct ImPlotTick
|
||||||
// Collection of ticks
|
// Collection of ticks
|
||||||
struct ImPlotTickCollection {
|
struct ImPlotTickCollection {
|
||||||
ImVector<ImPlotTick> Ticks;
|
ImVector<ImPlotTick> Ticks;
|
||||||
ImGuiTextBuffer Labels;
|
ImGuiTextBuffer TextBuffer;
|
||||||
float TotalWidth;
|
float TotalWidth;
|
||||||
float TotalHeight;
|
float TotalHeight;
|
||||||
float MaxWidth;
|
float MaxWidth;
|
||||||
float MaxHeight;
|
float MaxHeight;
|
||||||
int Size;
|
int Size;
|
||||||
|
|
||||||
void AddTick(const ImPlotTick& tick) {
|
ImPlotTickCollection() { Reset(); }
|
||||||
|
|
||||||
|
void Append(const ImPlotTick& tick) {
|
||||||
if (tick.ShowLabel) {
|
if (tick.ShowLabel) {
|
||||||
TotalWidth += tick.ShowLabel ? tick.LabelSize.x : 0;
|
TotalWidth += tick.ShowLabel ? tick.LabelSize.x : 0;
|
||||||
TotalHeight += tick.ShowLabel ? tick.LabelSize.y : 0;
|
TotalHeight += tick.ShowLabel ? tick.LabelSize.y : 0;
|
||||||
|
@ -294,24 +345,23 @@ struct ImPlotTickCollection {
|
||||||
Size++;
|
Size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTick(double value, bool major, bool show_label, void (*labeler)(ImPlotTick& tick, ImGuiTextBuffer& buf)) {
|
void Append(double value, bool major, bool show_label, void (*labeler)(ImPlotTick& tick, ImGuiTextBuffer& buf)) {
|
||||||
ImPlotTick tick(value, major, show_label);
|
ImPlotTick tick(value, major, show_label);
|
||||||
if (labeler)
|
if (labeler)
|
||||||
labeler(tick, Labels);
|
labeler(tick, TextBuffer);
|
||||||
AddTick(tick);
|
Append(tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GetLabel(int idx) {
|
const char* GetText(int idx) {
|
||||||
return Labels.Buf.Data + Ticks[idx].BufferOffset;
|
return TextBuffer.Buf.Data + Ticks[idx].TextOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
Ticks.shrink(0);
|
Ticks.shrink(0);
|
||||||
Labels.Buf.shrink(0);
|
TextBuffer.Buf.shrink(0);
|
||||||
TotalWidth = TotalHeight = MaxWidth = MaxHeight = 0;
|
TotalWidth = TotalHeight = MaxWidth = MaxHeight = 0;
|
||||||
Size = 0;
|
Size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Axis state information that must persist after EndPlot
|
// Axis state information that must persist after EndPlot
|
||||||
|
@ -544,6 +594,7 @@ struct ImPlotContext {
|
||||||
ImPool<ImPlotState> Plots;
|
ImPool<ImPlotState> Plots;
|
||||||
ImPlotState* CurrentPlot;
|
ImPlotState* CurrentPlot;
|
||||||
ImPlotItem* CurrentItem;
|
ImPlotItem* CurrentItem;
|
||||||
|
ImPlotItem* PreviousItem;
|
||||||
|
|
||||||
// Legend
|
// Legend
|
||||||
ImVector<int> LegendIndices;
|
ImVector<int> LegendIndices;
|
||||||
|
@ -565,6 +616,9 @@ struct ImPlotContext {
|
||||||
ImPlotTickCollection YTicks[IMPLOT_Y_AXES];
|
ImPlotTickCollection YTicks[IMPLOT_Y_AXES];
|
||||||
float YAxisReference[IMPLOT_Y_AXES];
|
float YAxisReference[IMPLOT_Y_AXES];
|
||||||
|
|
||||||
|
// Annotation and User Labels
|
||||||
|
ImPlotAnnotationCollection Annotations;
|
||||||
|
|
||||||
// Transformations and Data Extents
|
// Transformations and Data Extents
|
||||||
ImPlotScale Scales[IMPLOT_Y_AXES];
|
ImPlotScale Scales[IMPLOT_Y_AXES];
|
||||||
ImRect PixelRange[IMPLOT_Y_AXES];
|
ImRect PixelRange[IMPLOT_Y_AXES];
|
||||||
|
|
|
@ -125,6 +125,13 @@ void SetNextErrorBarStyle(const ImVec4& col, float size, float weight) {
|
||||||
gp.NextItemData.ErrorBarWeight = weight;
|
gp.NextItemData.ErrorBarWeight = weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImVec4 GetLastItemColor() {
|
||||||
|
ImPlotContext& gp = *GImPlot;
|
||||||
|
if (gp.PreviousItem)
|
||||||
|
return gp.PreviousItem->Color;
|
||||||
|
return ImVec4();
|
||||||
|
}
|
||||||
|
|
||||||
void HideNextItem(bool hidden, ImGuiCond cond) {
|
void HideNextItem(bool hidden, ImGuiCond cond) {
|
||||||
ImPlotContext& gp = *GImPlot;
|
ImPlotContext& gp = *GImPlot;
|
||||||
gp.NextItemData.HasHidden = true;
|
gp.NextItemData.HasHidden = true;
|
||||||
|
@ -151,29 +158,29 @@ bool BeginItem(const char* label_id, ImPlotCol recolor_from) {
|
||||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotX() needs to be called between BeginPlot() and EndPlot()!");
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotX() needs to be called between BeginPlot() and EndPlot()!");
|
||||||
bool just_created;
|
bool just_created;
|
||||||
ImPlotItem* item = RegisterOrGetItem(label_id, &just_created);
|
ImPlotItem* item = RegisterOrGetItem(label_id, &just_created);
|
||||||
|
// set current item
|
||||||
|
gp.CurrentItem = item;
|
||||||
|
ImPlotNextItemData& s = gp.NextItemData;
|
||||||
|
// override item color
|
||||||
|
if (recolor_from != -1) {
|
||||||
|
if (!IsColorAuto(s.Colors[recolor_from]))
|
||||||
|
item->Color = s.Colors[recolor_from];
|
||||||
|
else if (!IsColorAuto(gp.Style.Colors[recolor_from]))
|
||||||
|
item->Color = gp.Style.Colors[recolor_from];
|
||||||
|
}
|
||||||
// hide/show item
|
// hide/show item
|
||||||
if (gp.NextItemData.HasHidden) {
|
if (gp.NextItemData.HasHidden) {
|
||||||
if (just_created || gp.NextItemData.HiddenCond == ImGuiCond_Always)
|
if (just_created || gp.NextItemData.HiddenCond == ImGuiCond_Always)
|
||||||
item->Show = !gp.NextItemData.Hidden;
|
item->Show = !gp.NextItemData.Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item->Show) {
|
if (!item->Show) {
|
||||||
// reset next item data
|
// reset next item data
|
||||||
gp.NextItemData = ImPlotNextItemData();
|
gp.NextItemData = ImPlotNextItemData();
|
||||||
|
gp.PreviousItem = item;
|
||||||
|
gp.CurrentItem = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// set current item
|
|
||||||
gp.CurrentItem = item;
|
|
||||||
ImPlotNextItemData& s = gp.NextItemData;
|
|
||||||
// override item color
|
|
||||||
if (recolor_from != -1) {
|
|
||||||
if (!IsColorAuto(s.Colors[recolor_from]))
|
|
||||||
item->Color = s.Colors[recolor_from];
|
|
||||||
else if (!IsColorAuto(gp.Style.Colors[recolor_from]))
|
|
||||||
item->Color = gp.Style.Colors[recolor_from];
|
|
||||||
}
|
|
||||||
// stage next item colors
|
// stage next item colors
|
||||||
s.Colors[ImPlotCol_Line] = IsColorAuto(s.Colors[ImPlotCol_Line]) ? ( IsColorAuto(ImPlotCol_Line) ? item->Color : gp.Style.Colors[ImPlotCol_Line] ) : s.Colors[ImPlotCol_Line];
|
s.Colors[ImPlotCol_Line] = IsColorAuto(s.Colors[ImPlotCol_Line]) ? ( IsColorAuto(ImPlotCol_Line) ? item->Color : gp.Style.Colors[ImPlotCol_Line] ) : s.Colors[ImPlotCol_Line];
|
||||||
s.Colors[ImPlotCol_Fill] = IsColorAuto(s.Colors[ImPlotCol_Fill]) ? ( IsColorAuto(ImPlotCol_Fill) ? item->Color : gp.Style.Colors[ImPlotCol_Fill] ) : s.Colors[ImPlotCol_Fill];
|
s.Colors[ImPlotCol_Fill] = IsColorAuto(s.Colors[ImPlotCol_Fill]) ? ( IsColorAuto(ImPlotCol_Fill) ? item->Color : gp.Style.Colors[ImPlotCol_Fill] ) : s.Colors[ImPlotCol_Fill];
|
||||||
|
@ -218,7 +225,8 @@ void EndItem() {
|
||||||
// reset next item data
|
// reset next item data
|
||||||
gp.NextItemData = ImPlotNextItemData();
|
gp.NextItemData = ImPlotNextItemData();
|
||||||
// set current item
|
// set current item
|
||||||
gp.CurrentItem = NULL;
|
gp.PreviousItem = gp.CurrentItem;
|
||||||
|
gp.CurrentItem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue
Block a user