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() {
|
||||
|
||||
LineWeight = 1;
|
||||
Marker = ImPlotMarker_None;
|
||||
MarkerSize = 4;
|
||||
MarkerWeight = 1;
|
||||
FillAlpha = 1;
|
||||
ErrorBarSize = 5;
|
||||
ErrorBarWeight = 1.5f;
|
||||
DigitalBitHeight = 8;
|
||||
DigitalBitGap = 4;
|
||||
LineWeight = 1;
|
||||
Marker = ImPlotMarker_None;
|
||||
MarkerSize = 4;
|
||||
MarkerWeight = 1;
|
||||
FillAlpha = 1;
|
||||
ErrorBarSize = 5;
|
||||
ErrorBarWeight = 1.5f;
|
||||
DigitalBitHeight = 8;
|
||||
DigitalBitGap = 4;
|
||||
|
||||
PlotBorderSize = 1;
|
||||
MinorAlpha = 0.25f;
|
||||
MajorTickLen = ImVec2(10,10);
|
||||
MinorTickLen = ImVec2(5,5);
|
||||
MajorTickSize = ImVec2(1,1);
|
||||
MinorTickSize = ImVec2(1,1);
|
||||
MajorGridSize = ImVec2(1,1);
|
||||
MinorGridSize = ImVec2(1,1);
|
||||
PlotPadding = ImVec2(8,8);
|
||||
LabelPadding = ImVec2(5,5);
|
||||
LegendPadding = ImVec2(10,10);
|
||||
InfoPadding = ImVec2(10,10);
|
||||
PlotMinSize = ImVec2(300,225);
|
||||
PlotBorderSize = 1;
|
||||
MinorAlpha = 0.25f;
|
||||
MajorTickLen = ImVec2(10,10);
|
||||
MinorTickLen = ImVec2(5,5);
|
||||
MajorTickSize = ImVec2(1,1);
|
||||
MinorTickSize = ImVec2(1,1);
|
||||
MajorGridSize = ImVec2(1,1);
|
||||
MinorGridSize = ImVec2(1,1);
|
||||
PlotPadding = ImVec2(8,8);
|
||||
LabelPadding = ImVec2(5,5);
|
||||
LegendPadding = ImVec2(10,10);
|
||||
InfoPadding = ImVec2(10,10);
|
||||
AnnotationPadding = ImVec2(2,2);
|
||||
AnnotationOffset = ImVec2(10,10);
|
||||
PlotMinSize = ImVec2(300,225);
|
||||
|
||||
ImPlot::StyleColorsAuto(this);
|
||||
|
||||
|
@ -215,29 +217,31 @@ struct ImPlotStyleVarInfo {
|
|||
|
||||
static const ImPlotStyleVarInfo GPlotStyleVarInfo[] =
|
||||
{
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, LineWeight) }, // ImPlotStyleVar_LineWeight
|
||||
{ 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, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight
|
||||
{ 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, ErrorBarWeight) }, // ImPlotStyleVar_ErrorBarWeight
|
||||
{ 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, LineWeight) }, // ImPlotStyleVar_LineWeight
|
||||
{ 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, MarkerWeight) }, // ImPlotStyleVar_MarkerWeight
|
||||
{ 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, ErrorBarWeight) }, // ImPlotStyleVar_ErrorBarWeight
|
||||
{ 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, PlotBorderSize) }, // ImPlotStyleVar_PlotBorderSize
|
||||
{ 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, MinorTickLen) }, // ImPlotStyleVar_MinorTickLen
|
||||
{ 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, MajorGridSize) }, // ImPlotStyleVar_MajorGridSize
|
||||
{ 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, LabelPadding) }, // ImPlotStyleVar_LabelPaddine
|
||||
{ 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, PlotMinSize) } // ImPlotStyleVar_PlotMinSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotBorderSize) }, // ImPlotStyleVar_PlotBorderSize
|
||||
{ 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, MinorTickLen) }, // ImPlotStyleVar_MinorTickLen
|
||||
{ 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, MajorGridSize) }, // ImPlotStyleVar_MajorGridSize
|
||||
{ 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, LabelPadding) }, // ImPlotStyleVar_LabelPaddine
|
||||
{ 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, 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) {
|
||||
|
@ -364,6 +368,8 @@ void Reset(ImPlotContext* ctx) {
|
|||
for (int i = 0; i < 3; ++i) {
|
||||
ctx->YTicks[i].Reset();
|
||||
}
|
||||
// reset labels
|
||||
ctx->Annotations.Reset();
|
||||
// reset extents/fit
|
||||
ctx->FitThisFrame = false;
|
||||
ctx->FitX = false;
|
||||
|
@ -378,8 +384,9 @@ void Reset(ImPlotContext* ctx) {
|
|||
ctx->DigitalPlotItemCnt = 0;
|
||||
ctx->DigitalPlotOffset = 0;
|
||||
// nullify plot
|
||||
ctx->CurrentPlot = NULL;
|
||||
ctx->CurrentItem = NULL;
|
||||
ctx->CurrentPlot = NULL;
|
||||
ctx->CurrentItem = NULL;
|
||||
ctx->PreviousItem = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -516,20 +523,20 @@ const char* GetLegendLabel(int i) {
|
|||
void LabelTickDefault(ImPlotTick& tick, ImGuiTextBuffer& buffer) {
|
||||
char temp[32];
|
||||
if (tick.ShowLabel) {
|
||||
tick.BufferOffset = buffer.size();
|
||||
tick.TextOffset = buffer.size();
|
||||
snprintf(temp, 32, "%.10g", tick.PlotPos);
|
||||
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) {
|
||||
char temp[32];
|
||||
if (tick.ShowLabel) {
|
||||
tick.BufferOffset = buffer.size();
|
||||
tick.TextOffset = buffer.size();
|
||||
snprintf(temp, 32, "%.0E", tick.PlotPos);
|
||||
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;
|
||||
for (double major = graphmin; major < graphmax + 0.5 * interval; major += interval) {
|
||||
if (range.Contains(major))
|
||||
ticks.AddTick(major, true, true, LabelTickDefault);
|
||||
ticks.Append(major, true, true, LabelTickDefault);
|
||||
for (int i = 1; i < nMinor; ++i) {
|
||||
double minor = major + i * interval / nMinor;
|
||||
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 interval = (major2 - major1) / 9;
|
||||
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) {
|
||||
major1 = ImPow(10, (double)(e+j));
|
||||
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) {
|
||||
double minor = major1 + i * interval;
|
||||
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) {
|
||||
ImPlotTick tick(values[i], false, true);
|
||||
if (labels != NULL) {
|
||||
tick.BufferOffset = ticks.Labels.size();
|
||||
ticks.Labels.append(labels[i], labels[i] + strlen(labels[i]) + 1);
|
||||
tick.TextOffset = ticks.TextBuffer.size();
|
||||
ticks.TextBuffer.append(labels[i], labels[i] + strlen(labels[i]) + 1);
|
||||
tick.LabelSize = ImGui::CalcTextSize(labels[i]);
|
||||
}
|
||||
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) {
|
||||
char temp[32];
|
||||
if (tick.ShowLabel) {
|
||||
tick.BufferOffset = buffer.size();
|
||||
tick.TextOffset = buffer.size();
|
||||
hour24 ? FormatTime24(t, temp, 32, fmt) : FormatTime12(t, temp, 32, fmt);
|
||||
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
|
||||
ImPlotTick tick_min(t1.ToDouble(),true,true);
|
||||
tick_min.Level = 0;
|
||||
LabelTickTime(tick_min,ticks.Labels,t1,fmt0,hour24);
|
||||
ticks.AddTick(tick_min);
|
||||
LabelTickTime(tick_min,ticks.TextBuffer,t1,fmt0,hour24);
|
||||
ticks.Append(tick_min);
|
||||
// major level 1 tick
|
||||
ImPlotTick tick_maj(t1.ToDouble(),true,true);
|
||||
tick_maj.Level = 1;
|
||||
LabelTickTime(tick_maj,ticks.Labels,t1, last_major == NULL ? fmtf : fmt1,hour24);
|
||||
const char* this_major = ticks.Labels.Buf.Data + tick_maj.BufferOffset;
|
||||
LabelTickTime(tick_maj,ticks.TextBuffer,t1, last_major == NULL ? fmtf : fmt1,hour24);
|
||||
const char* this_major = ticks.TextBuffer.Buf.Data + tick_maj.TextOffset;
|
||||
if (last_major && TimeLabelSame(last_major,this_major))
|
||||
tick_maj.ShowLabel = false;
|
||||
last_major = this_major;
|
||||
ticks.AddTick(tick_maj);
|
||||
ticks.Append(tick_maj);
|
||||
}
|
||||
// add minor ticks up until next major
|
||||
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) {
|
||||
ImPlotTick tick(t12.ToDouble(),false,px_to_t2 >= fmt0_width);
|
||||
tick.Level = 0;
|
||||
LabelTickTime(tick,ticks.Labels,t12,fmt0,hour24);
|
||||
ticks.AddTick(tick);
|
||||
LabelTickTime(tick,ticks.TextBuffer,t12,fmt0,hour24);
|
||||
ticks.Append(tick);
|
||||
if (last_major == NULL && px_to_t2 >= fmt0_width && px_to_t2 >= (fmt1_width + fmtf_width) / 2) {
|
||||
ImPlotTick tick_maj(t12.ToDouble(),true,true);
|
||||
tick_maj.Level = 1;
|
||||
LabelTickTime(tick_maj,ticks.Labels,t12,fmtf,hour24);
|
||||
last_major = ticks.Labels.Buf.Data + tick_maj.BufferOffset;
|
||||
ticks.AddTick(tick_maj);
|
||||
LabelTickTime(tick_maj,ticks.TextBuffer,t12,fmtf,hour24);
|
||||
last_major = ticks.TextBuffer.Buf.Data + tick_maj.TextOffset;
|
||||
ticks.Append(tick_maj);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
ImPlotTick tick(t.ToDouble(), true, true);
|
||||
tick.Level = 0;
|
||||
LabelTickTime(tick, ticks.Labels, t, TimeFormatLevel0[ImPlotTimeUnit_Yr], hour24);
|
||||
ticks.AddTick(tick);
|
||||
LabelTickTime(tick, ticks.TextBuffer, t, TimeFormatLevel0[ImPlotTimeUnit_Yr], hour24);
|
||||
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];
|
||||
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)),
|
||||
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++) {
|
||||
|
@ -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];
|
||||
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);
|
||||
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("Color Mods", "%d", gp.ColorModifiers.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.YTicks[0].Labels.Buf.Data, gp.YTicks[0].Labels.Buf.Data + gp.YTicks[0].Labels.size());
|
||||
ImGui::TextUnformatted(gp.XTicks.TextBuffer.Buf.Data, gp.XTicks.TextBuffer.Buf.Data + gp.XTicks.TextBuffer.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[2].Labels.Buf.Data, gp.YTicks[2].Labels.Buf.Data + gp.YTicks[2].Labels.size());
|
||||
|
||||
|
@ -2008,6 +2015,47 @@ void EndPlot() {
|
|||
}
|
||||
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
|
||||
if ((gp.Y[1].Present || gp.Y[2].Present) && ImGui::IsDragDropPayloadBeingAccepted()) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
|
||||
|
@ -2483,6 +2531,43 @@ ImPlotLimits GetPlotQuery(int y_axis_in) {
|
|||
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) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
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::InvisibleButton(id, ImVec2(grab_size, yb-yt));
|
||||
ImGui::GetCurrentWindow()->DC.CursorPos = old_cursor_pos;
|
||||
if (ImGui::IsItemHovered() || ImGui::IsItemActive()) {
|
||||
if (ImGui::IsItemHovered() || ImGui::IsItemActive()) {
|
||||
gp.Hov_Plot = false;
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||
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();
|
||||
char buf[32];
|
||||
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();
|
||||
gp.Annotations.Append(ImVec2(x,yb),ImVec2(0,0),col32,CalcTextColor(color),true,"%s = %.*f", id, Precision(range_x), *value);
|
||||
}
|
||||
}
|
||||
bool dragging = false;
|
||||
|
@ -2568,27 +2643,8 @@ bool DragLineY(const char* id, double* value, bool show_label, const ImVec4& col
|
|||
gp.Hov_Plot = false;
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
||||
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();
|
||||
char buf[32];
|
||||
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();
|
||||
gp.Annotations.Append(ImVec2(yax == 0 ? xl : xr,y), ImVec2(0,0), col32, CalcTextColor(color), true, "%s = %.*f", id, Precision(range_y), *value);
|
||||
}
|
||||
}
|
||||
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;
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
|
||||
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_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_size = ImGui::CalcTextSize(buf) + ImVec2(4,4);
|
||||
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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
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.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();
|
||||
|
||||
|
@ -3221,12 +3269,14 @@ void ShowStyleEditor(ImPlotStyle* ref) {
|
|||
ImGui::SliderFloat2("MinorTickSize", (float*)&style.MinorTickSize, 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("PlotMinSize", (float*)&style.PlotMinSize, 0.0f, 300, "%.0f");
|
||||
ImGui::Text("Plot Padding");
|
||||
ImGui::SliderFloat2("PlotPadding", (float*)&style.PlotPadding, 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("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();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Colors")) {
|
||||
|
|
74
implot.h
74
implot.h
|
@ -125,29 +125,31 @@ enum ImPlotCol_ {
|
|||
// Plot styling variables.
|
||||
enum ImPlotStyleVar_ {
|
||||
// item styling variables
|
||||
ImPlotStyleVar_LineWeight, // float, plot item line weight in pixels
|
||||
ImPlotStyleVar_Marker, // int, marker specification
|
||||
ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius")
|
||||
ImPlotStyleVar_MarkerWeight, // float, plot outline weight of markers in pixels
|
||||
ImPlotStyleVar_FillAlpha, // float, alpha modifier applied to all plot item fills
|
||||
ImPlotStyleVar_ErrorBarSize, // float, error bar whisker width in pixels
|
||||
ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels
|
||||
ImPlotStyleVar_DigitalBitHeight, // float, digital channels bit height (at 1) in pixels
|
||||
ImPlotStyleVar_DigitalBitGap, // float, digital channels bit padding gap in pixels
|
||||
ImPlotStyleVar_LineWeight, // float, plot item line weight in pixels
|
||||
ImPlotStyleVar_Marker, // int, marker specification
|
||||
ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius")
|
||||
ImPlotStyleVar_MarkerWeight, // float, plot outline weight of markers in pixels
|
||||
ImPlotStyleVar_FillAlpha, // float, alpha modifier applied to all plot item fills
|
||||
ImPlotStyleVar_ErrorBarSize, // float, error bar whisker width in pixels
|
||||
ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels
|
||||
ImPlotStyleVar_DigitalBitHeight, // float, digital channels bit height (at 1) in pixels
|
||||
ImPlotStyleVar_DigitalBitGap, // float, digital channels bit padding gap in pixels
|
||||
// plot styling variables
|
||||
ImPlotStyleVar_PlotBorderSize, // float, thickness of border around plot area
|
||||
ImPlotStyleVar_MinorAlpha, // float, alpha multiplier applied to minor axis grid lines
|
||||
ImPlotStyleVar_MajorTickLen, // ImVec2, major 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_MinorTickSize, // ImVec2, line thickness of minor ticks
|
||||
ImPlotStyleVar_MajorGridSize, // ImVec2, line thickness of major 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_LabelPadding, // ImVec2, padding between axes labels, tick labels, and plot edge
|
||||
ImPlotStyleVar_LegendPadding, // ImVec2, legend padding from top-left of plot
|
||||
ImPlotStyleVar_InfoPadding, // ImVec2, padding between plot edge and interior info text
|
||||
ImPlotStyleVar_PlotMinSize, // ImVec2, minimum size plot frame can be when shrunk
|
||||
ImPlotStyleVar_PlotBorderSize, // float, thickness of border around plot area
|
||||
ImPlotStyleVar_MinorAlpha, // float, alpha multiplier applied to minor axis grid lines
|
||||
ImPlotStyleVar_MajorTickLen, // ImVec2, major 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_MinorTickSize, // ImVec2, line thickness of minor ticks
|
||||
ImPlotStyleVar_MajorGridSize, // ImVec2, line thickness of major 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_LabelPadding, // ImVec2, padding between axes labels, tick labels, and plot edge
|
||||
ImPlotStyleVar_LegendPadding, // ImVec2, legend padding from top-left of plot
|
||||
ImPlotStyleVar_InfoPadding, // ImVec2, padding between plot edge and interior info text
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -238,6 +240,8 @@ struct ImPlotStyle {
|
|||
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 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
|
||||
// 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));
|
||||
|
||||
// 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
|
||||
|
@ -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).
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// 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.
|
||||
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.
|
||||
|
@ -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.
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -533,10 +544,13 @@ IMPLOT_API void SetNextMarkerStyle(ImPlotMarker marker = IMPLOT_AUTO, float size
|
|||
// 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);
|
||||
|
||||
// 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.
|
||||
IMPLOT_API const char* GetStyleColorName(ImPlotCol color);
|
||||
IMPLOT_API const char* GetStyleColorName(ImPlotCol idx);
|
||||
// Returns the null terminated string name for an ImPlotMarker.
|
||||
IMPLOT_API const char* GetMarkerName(ImPlotMarker marker);
|
||||
IMPLOT_API const char* GetMarkerName(ImPlotMarker idx);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Colormaps
|
||||
|
|
|
@ -659,6 +659,7 @@ void ShowDemoWindow(bool* p_open) {
|
|||
double t_now = (double)time(0);
|
||||
double y_now = HugeTimeData::GetY(t_now);
|
||||
ImPlot::PlotScatter("Now",&t_now,&y_now,1);
|
||||
ImPlot::Annotate(t_now,y_now,ImPlot::GetLastItemColor(),"Now");
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
|
@ -857,6 +858,39 @@ void ShowDemoWindow(bool* p_open) {
|
|||
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")) {
|
||||
const int K_CHANNELS = 9;
|
||||
|
|
|
@ -77,9 +77,9 @@ extern IMPLOT_API ImPlotContext* GImPlot; // Current implicit context pointer
|
|||
#define IMPLOT_SUB_DIV 10
|
||||
// Zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click)
|
||||
#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
|
||||
// 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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -135,7 +135,7 @@ struct ImBufferWriter
|
|||
Pos = 0;
|
||||
}
|
||||
|
||||
void Write(const char* fmt, ...) IM_FMTARGS(2) {
|
||||
void Write(const char* fmt, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
const int written = ::vsnprintf(&Buffer[Pos], Size - Pos - 1, fmt, argp);
|
||||
|
@ -247,19 +247,68 @@ struct ImPlotColormapMod {
|
|||
struct ImPlotPointError
|
||||
{
|
||||
double X, Y, Neg, Pos;
|
||||
|
||||
ImPlotPointError(double x, double y, double neg, double 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
|
||||
struct ImPlotTick
|
||||
{
|
||||
double PlotPos;
|
||||
float PixelPos;
|
||||
ImVec2 LabelSize;
|
||||
int BufferOffset;
|
||||
int TextOffset;
|
||||
bool Major;
|
||||
bool ShowLabel;
|
||||
int Level;
|
||||
|
@ -268,7 +317,7 @@ struct ImPlotTick
|
|||
PlotPos = value;
|
||||
Major = major;
|
||||
ShowLabel = show_label;
|
||||
BufferOffset = -1;
|
||||
TextOffset = -1;
|
||||
Level = 0;
|
||||
}
|
||||
};
|
||||
|
@ -276,14 +325,16 @@ struct ImPlotTick
|
|||
// Collection of ticks
|
||||
struct ImPlotTickCollection {
|
||||
ImVector<ImPlotTick> Ticks;
|
||||
ImGuiTextBuffer Labels;
|
||||
ImGuiTextBuffer TextBuffer;
|
||||
float TotalWidth;
|
||||
float TotalHeight;
|
||||
float MaxWidth;
|
||||
float MaxHeight;
|
||||
int Size;
|
||||
|
||||
void AddTick(const ImPlotTick& tick) {
|
||||
ImPlotTickCollection() { Reset(); }
|
||||
|
||||
void Append(const ImPlotTick& tick) {
|
||||
if (tick.ShowLabel) {
|
||||
TotalWidth += tick.ShowLabel ? tick.LabelSize.x : 0;
|
||||
TotalHeight += tick.ShowLabel ? tick.LabelSize.y : 0;
|
||||
|
@ -294,24 +345,23 @@ struct ImPlotTickCollection {
|
|||
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);
|
||||
if (labeler)
|
||||
labeler(tick, Labels);
|
||||
AddTick(tick);
|
||||
labeler(tick, TextBuffer);
|
||||
Append(tick);
|
||||
}
|
||||
|
||||
const char* GetLabel(int idx) {
|
||||
return Labels.Buf.Data + Ticks[idx].BufferOffset;
|
||||
const char* GetText(int idx) {
|
||||
return TextBuffer.Buf.Data + Ticks[idx].TextOffset;
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
Ticks.shrink(0);
|
||||
Labels.Buf.shrink(0);
|
||||
TextBuffer.Buf.shrink(0);
|
||||
TotalWidth = TotalHeight = MaxWidth = MaxHeight = 0;
|
||||
Size = 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Axis state information that must persist after EndPlot
|
||||
|
@ -544,6 +594,7 @@ struct ImPlotContext {
|
|||
ImPool<ImPlotState> Plots;
|
||||
ImPlotState* CurrentPlot;
|
||||
ImPlotItem* CurrentItem;
|
||||
ImPlotItem* PreviousItem;
|
||||
|
||||
// Legend
|
||||
ImVector<int> LegendIndices;
|
||||
|
@ -565,6 +616,9 @@ struct ImPlotContext {
|
|||
ImPlotTickCollection YTicks[IMPLOT_Y_AXES];
|
||||
float YAxisReference[IMPLOT_Y_AXES];
|
||||
|
||||
// Annotation and User Labels
|
||||
ImPlotAnnotationCollection Annotations;
|
||||
|
||||
// Transformations and Data Extents
|
||||
ImPlotScale Scales[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;
|
||||
}
|
||||
|
||||
ImVec4 GetLastItemColor() {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
if (gp.PreviousItem)
|
||||
return gp.PreviousItem->Color;
|
||||
return ImVec4();
|
||||
}
|
||||
|
||||
void HideNextItem(bool hidden, ImGuiCond cond) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
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()!");
|
||||
bool 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
|
||||
if (gp.NextItemData.HasHidden) {
|
||||
if (just_created || gp.NextItemData.HiddenCond == ImGuiCond_Always)
|
||||
item->Show = !gp.NextItemData.Hidden;
|
||||
}
|
||||
|
||||
if (!item->Show) {
|
||||
// reset next item data
|
||||
gp.NextItemData = ImPlotNextItemData();
|
||||
gp.PreviousItem = item;
|
||||
gp.CurrentItem = NULL;
|
||||
return false;
|
||||
}
|
||||
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
|
||||
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];
|
||||
|
@ -218,7 +225,8 @@ void EndItem() {
|
|||
// reset next item data
|
||||
gp.NextItemData = ImPlotNextItemData();
|
||||
// set current item
|
||||
gp.CurrentItem = NULL;
|
||||
gp.PreviousItem = gp.CurrentItem;
|
||||
gp.CurrentItem = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue
Block a user