mirror of
https://github.com/gwm17/implot.git
synced 2024-11-23 02:38:53 -05:00
Configurable Legend Locations (#135)
* add support for ISO 8601 timestamps * clean up work on ISO 8601 * legend location proto * location docs * add horizontal legends, and ability to position mouse location * add ShowAltLegend * add ShowAltLegend * default sizing for ShowAltLegend * finish up legend locations
This commit is contained in:
parent
f9a15a7147
commit
587c8b6221
425
implot.cpp
425
implot.cpp
|
@ -31,6 +31,7 @@ Below is a change-log of API breaking changes only. If you are using one of the
|
|||
When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all implot files.
|
||||
You can read releases logs https://github.com/epezent/implot/releases for more details.
|
||||
|
||||
- 2020/10/16 (0.8) - ImPlotStyleVar_InfoPadding was changed to ImPlotStyleVar_MousePosPadding
|
||||
- 2020/09/10 (0.8) - The single array versions of PlotLine, PlotScatter, PlotStems, and PlotShaded were given additional arguments for x-scale and x0.
|
||||
- 2020/09/07 (0.8) - Plotting functions which accept a custom getter function pointer have been post-fixed with a G (e.g. PlotLineG)
|
||||
- 2020/09/06 (0.7) - Several flags under ImPlotFlags and ImPlotAxisFlags were inverted (e.g. ImPlotFlags_Legend -> ImPlotFlags_NoLegend) so that the default flagset
|
||||
|
@ -113,11 +114,14 @@ ImPlotStyle::ImPlotStyle() {
|
|||
MinorTickSize = ImVec2(1,1);
|
||||
MajorGridSize = ImVec2(1,1);
|
||||
MinorGridSize = ImVec2(1,1);
|
||||
PlotPadding = ImVec2(8,8);
|
||||
PlotPadding = ImVec2(10,10);
|
||||
LabelPadding = ImVec2(5,5);
|
||||
LegendPadding = ImVec2(10,10);
|
||||
InfoPadding = ImVec2(10,10);
|
||||
LegendInnerPadding = ImVec2(5,5);
|
||||
LegendSpacing = ImVec2(0,0);
|
||||
MousePosPadding = ImVec2(10,10);
|
||||
AnnotationPadding = ImVec2(2,2);
|
||||
PlotDefaultSize = ImVec2(400,300);
|
||||
PlotMinSize = ImVec2(300,225);
|
||||
|
||||
ImPlot::StyleColorsAuto(this);
|
||||
|
@ -128,6 +132,20 @@ ImPlotStyle::ImPlotStyle() {
|
|||
UseISO8601 = false;
|
||||
}
|
||||
|
||||
ImPlotItem* ImPlotLegend::GetItem(int i) {
|
||||
return Plot->Items.GetByIndex(Indices[i]);
|
||||
}
|
||||
|
||||
const char* ImPlotLegend::GetLabel(int i) {
|
||||
ImPlotItem* item = GetItem(i);
|
||||
IM_ASSERT(item->NameOffset != -1 && item->NameOffset < Labels.Buf.Size);
|
||||
return Labels.Buf.Data + item->NameOffset;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Style
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace ImPlot {
|
||||
|
||||
const char* GetStyleColorName(ImPlotCol col) {
|
||||
|
@ -238,8 +256,12 @@ static const ImPlotStyleVarInfo GPlotStyleVarInfo[] =
|
|||
{ 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, LegendInnerPadding) }, // ImPlotStyleVar_LegendInnerPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, LegendSpacing) }, // ImPlotStyleVar_LegendSpacing
|
||||
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, MousePosPadding) }, // ImPlotStyleVar_MousePosPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, AnnotationPadding) }, // ImPlotStyleVar_AnnotationPadding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotDefaultSize) }, // ImPlotStyleVar_PlotDefaultSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlotStyle, PlotMinSize) } // ImPlotStyleVar_PlotMinSize
|
||||
};
|
||||
|
||||
|
@ -359,14 +381,10 @@ void Reset(ImPlotContext* ctx) {
|
|||
ctx->NextItemData = ImPlotNextItemData();
|
||||
// reset items count
|
||||
ctx->VisibleItemCount = 0;
|
||||
// reset legend items
|
||||
ctx->LegendIndices.shrink(0);
|
||||
ctx->LegendLabels.Buf.shrink(0);
|
||||
// reset ticks/labels
|
||||
ctx->XTicks.Reset();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
ctx->YTicks[i].Reset();
|
||||
}
|
||||
// reset labels
|
||||
ctx->Annotations.Reset();
|
||||
// reset extents/fit
|
||||
|
@ -408,7 +426,7 @@ void BustPlotCache() {
|
|||
|
||||
void FitPoint(const ImPlotPoint& p) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
const int y_axis = gp.CurrentPlot->CurrentYAxis;
|
||||
const ImPlotYAxis y_axis = gp.CurrentPlot->CurrentYAxis;
|
||||
ImPlotRange& ex_x = gp.ExtentsX;
|
||||
ImPlotRange& ex_y = gp.ExtentsY[y_axis];
|
||||
const bool log_x = ImHasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_LogScale);
|
||||
|
@ -453,10 +471,10 @@ void UpdateTransformCache() {
|
|||
gp.Mx = (gp.PixelRange[0].Max.x - gp.PixelRange[0].Min.x) / gp.CurrentPlot->XAxis.Range.Size();
|
||||
}
|
||||
|
||||
ImPlotPoint PixelsToPlot(float x, float y, int y_axis_in) {
|
||||
ImPlotPoint PixelsToPlot(float x, float y, ImPlotYAxis y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PixelsToPlot() needs to be called between BeginPlot() and EndPlot()!");
|
||||
const int y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
ImPlotPoint plt;
|
||||
plt.x = (x - gp.PixelRange[y_axis].Min.x) / gp.Mx + gp.CurrentPlot->XAxis.Range.Min;
|
||||
plt.y = (y - gp.PixelRange[y_axis].Min.y) / gp.My[y_axis] + gp.CurrentPlot->YAxis[y_axis].Range.Min;
|
||||
|
@ -471,15 +489,15 @@ ImPlotPoint PixelsToPlot(float x, float y, int y_axis_in) {
|
|||
return plt;
|
||||
}
|
||||
|
||||
ImPlotPoint PixelsToPlot(const ImVec2& pix, int y_axis) {
|
||||
ImPlotPoint PixelsToPlot(const ImVec2& pix, ImPlotYAxis y_axis) {
|
||||
return PixelsToPlot(pix.x, pix.y, y_axis);
|
||||
}
|
||||
|
||||
// This function is convenient but should not be used to process a high volume of points. Use the Transformer structs below instead.
|
||||
ImVec2 PlotToPixels(double x, double y, int y_axis_in) {
|
||||
ImVec2 PlotToPixels(double x, double y, ImPlotYAxis y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotToPixels() needs to be called between BeginPlot() and EndPlot()!");
|
||||
const int y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
ImVec2 pix;
|
||||
if (ImHasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_LogScale)) {
|
||||
double t = ImLog10(x / gp.CurrentPlot->XAxis.Range.Min) / gp.LogDenX;
|
||||
|
@ -495,7 +513,7 @@ ImVec2 PlotToPixels(double x, double y, int y_axis_in) {
|
|||
}
|
||||
|
||||
// This function is convenient but should not be used to process a high volume of points. Use the Transformer structs below instead.
|
||||
ImVec2 PlotToPixels(const ImPlotPoint& plt, int y_axis) {
|
||||
ImVec2 PlotToPixels(const ImPlotPoint& plt, ImPlotYAxis y_axis) {
|
||||
return PlotToPixels(plt.x, plt.y, y_axis);
|
||||
}
|
||||
|
||||
|
@ -503,16 +521,98 @@ ImVec2 PlotToPixels(const ImPlotPoint& plt, int y_axis) {
|
|||
// Legend Utils
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int GetLegendCount() {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
return gp.LegendIndices.size();
|
||||
ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation loc, const ImVec2& pad) {
|
||||
ImVec2 pos;
|
||||
if (ImHasFlag(loc, ImPlotLocation_West) && !ImHasFlag(loc, ImPlotLocation_East))
|
||||
pos.x = outer_rect.Min.x + pad.x;
|
||||
else if (!ImHasFlag(loc, ImPlotLocation_West) && ImHasFlag(loc, ImPlotLocation_East))
|
||||
pos.x = outer_rect.Max.x - pad.x - inner_size.x;
|
||||
else
|
||||
pos.x = outer_rect.GetCenter().x - inner_size.x * 0.5f;
|
||||
// legend reference point y
|
||||
if (ImHasFlag(loc, ImPlotLocation_North) && !ImHasFlag(loc, ImPlotLocation_South))
|
||||
pos.y = outer_rect.Min.y + pad.y;
|
||||
else if (!ImHasFlag(loc, ImPlotLocation_North) && ImHasFlag(loc, ImPlotLocation_South))
|
||||
pos.y = outer_rect.Max.y - pad.y - inner_size.y;
|
||||
else
|
||||
pos.y = outer_rect.GetCenter().y - inner_size.y * 0.5f;
|
||||
pos.x = IM_ROUND(pos.x);
|
||||
pos.y = IM_ROUND(pos.y);
|
||||
return pos;
|
||||
}
|
||||
|
||||
const char* GetLegendLabel(int i) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImPlotItem* item = gp.CurrentPlot->Items.GetByIndex(gp.LegendIndices[i]);
|
||||
IM_ASSERT(item->NameOffset != -1 && item->NameOffset < gp.LegendLabels.Buf.Size);
|
||||
return gp.LegendLabels.Buf.Data + item->NameOffset;
|
||||
ImVec2 CalcLegendSize(ImPlotLegend& legend, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orn) {
|
||||
// vars
|
||||
const int nItems = legend.Count();
|
||||
const float txt_ht = ImGui::GetTextLineHeight();
|
||||
const float icon_size = txt_ht;
|
||||
// get label max width
|
||||
float max_label_width = 0;
|
||||
float sum_label_width = 0;
|
||||
for (int i = 0; i < nItems; ++i) {
|
||||
const char* label = legend.GetLabel(i);
|
||||
const float label_width = ImGui::CalcTextSize(label, NULL, true).x;
|
||||
max_label_width = label_width > max_label_width ? label_width : max_label_width;
|
||||
sum_label_width += label_width;
|
||||
}
|
||||
// calc legend size
|
||||
const ImVec2 legend_size = orn == ImPlotOrientation_Vertical ?
|
||||
ImVec2(pad.x * 2 + icon_size + max_label_width, pad.y * 2 + nItems * txt_ht + (nItems - 1) * spacing.y) :
|
||||
ImVec2(pad.x * 2 + icon_size * nItems + sum_label_width + (nItems - 1) * spacing.x, pad.y * 2 + txt_ht);
|
||||
return legend_size;
|
||||
}
|
||||
|
||||
void ShowLegendEntries(ImPlotLegend& legend, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orn, ImDrawList& DrawList) {
|
||||
ImGuiIO& IO = ImGui::GetIO();
|
||||
// vars
|
||||
const float txt_ht = ImGui::GetTextLineHeight();
|
||||
const float icon_size = txt_ht;
|
||||
const float icon_shrink = 2;
|
||||
ImVec4 col_txt = GetStyleColorVec4(ImPlotCol_LegendText);
|
||||
ImU32 col_txt_dis = ImGui::GetColorU32(col_txt * ImVec4(1,1,1,0.25f));
|
||||
// render each legend item
|
||||
float sum_label_width = 0;
|
||||
for (int i = 0; i < legend.Count(); ++i) {
|
||||
ImPlotItem* item = legend.GetItem(i);
|
||||
const char* label = legend.GetLabel(i);
|
||||
const float label_width = ImGui::CalcTextSize(label, NULL, true).x;
|
||||
const ImVec2 top_left = orn == ImPlotOrientation_Vertical ?
|
||||
legend_bb.Min + pad + ImVec2(0, i * (txt_ht + spacing.y)) :
|
||||
legend_bb.Min + pad + ImVec2(i * (icon_size + spacing.x) + sum_label_width, 0);
|
||||
sum_label_width += label_width;
|
||||
ImRect icon_bb;
|
||||
icon_bb.Min = top_left + ImVec2(icon_shrink,icon_shrink);
|
||||
icon_bb.Max = top_left + ImVec2(icon_size - icon_shrink, icon_size - icon_shrink);
|
||||
ImRect label_bb;
|
||||
label_bb.Min = top_left;
|
||||
label_bb.Max = top_left + ImVec2(label_width + icon_size, icon_size);
|
||||
ImU32 col_hl_txt;
|
||||
if (interactable && (icon_bb.Contains(IO.MousePos) || label_bb.Contains(IO.MousePos))) {
|
||||
item->LegendHovered = true;
|
||||
col_hl_txt = ImGui::GetColorU32(ImLerp(col_txt, item->Color, 0.25f));
|
||||
}
|
||||
else {
|
||||
// item->LegendHovered = false;
|
||||
col_hl_txt = ImGui::GetColorU32(col_txt);
|
||||
}
|
||||
ImU32 iconColor;
|
||||
ImVec4 item_color = item->Color;
|
||||
item_color.w = 1;
|
||||
if (interactable && icon_bb.Contains(IO.MousePos)) {
|
||||
ImVec4 colAlpha = item_color;
|
||||
colAlpha.w = 0.5f;
|
||||
iconColor = item->Show ? ImGui::GetColorU32(colAlpha) : ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.5f);
|
||||
if (IO.MouseClicked[0])
|
||||
item->Show = !item->Show;
|
||||
}
|
||||
else {
|
||||
iconColor = item->Show ? ImGui::GetColorU32(item_color) : col_txt_dis;
|
||||
}
|
||||
DrawList.AddRectFilled(icon_bb.Min, icon_bb.Max, iconColor, 1);
|
||||
const char* text_display_end = ImGui::FindRenderedTextEnd(label, NULL);
|
||||
if (label != text_display_end)
|
||||
DrawList.AddText(top_left + ImVec2(icon_size, 0), item->Show ? col_hl_txt : col_txt_dis, label, text_display_end);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -881,7 +981,7 @@ int FormatDate(const ImPlotTime& t, char* buffer, int size, ImPlotDateFmt fmt, b
|
|||
case ImPlotDateFmt_DayMo: return snprintf(buffer, size, "--%02d-%02d", mon, day);
|
||||
case ImPlotDateFmt_DayMoYr: return snprintf(buffer, size, "%d-%02d-%02d", year, mon, day);
|
||||
case ImPlotDateFmt_MoYr: return snprintf(buffer, size, "%d-%02d", year, mon);
|
||||
case ImPlotDateFmt_Mo: return snprintf(buffer, size, "--%02d-01", mon);
|
||||
case ImPlotDateFmt_Mo: return snprintf(buffer, size, "--%02d", mon);
|
||||
case ImPlotDateFmt_Yr: return snprintf(buffer, size, "%d", year);
|
||||
default: return 0;
|
||||
}
|
||||
|
@ -1092,7 +1192,7 @@ int LabelAxisValue(const ImPlotAxis& axis, const ImPlotTickCollection& ticks, do
|
|||
return snprintf(buff, size, "%.3E", value);
|
||||
}
|
||||
else if (ImHasFlag(axis.Flags, ImPlotAxisFlags_Time)) {
|
||||
ImPlotTimeUnit unit = (axis.Direction == ImPlotDirection_Horizontal)
|
||||
ImPlotTimeUnit unit = (axis.Direction == ImPlotOrientation_Horizontal)
|
||||
? GetUnitForRange(axis.Range.Size() / (gp.BB_Plot.GetWidth() / 100))
|
||||
: GetUnitForRange(axis.Range.Size() / (gp.BB_Plot.GetHeight() / 100));
|
||||
return FormatDateTime(ImPlotTime::FromDouble(value), buff, size, GetDateTimeFmt(TimeFormatMouseCursor, unit));
|
||||
|
@ -1174,7 +1274,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
|
||||
// capture scroll with a child region
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoChild)) {
|
||||
ImGui::BeginChild(title, ImVec2(size.x == 0 ? IMPLOT_DEFAULT_W : size.x, size.y == 0 ? IMPLOT_DEFAULT_H : size.y), false, ImGuiWindowFlags_NoScrollbar);
|
||||
ImGui::BeginChild(title, ImVec2(size.x == 0 ? gp.Style.PlotDefaultSize.x : size.x, size.y == 0 ? gp.Style.PlotDefaultSize.y : size.y), false, ImGuiWindowFlags_NoScrollbar);
|
||||
Window = ImGui::GetCurrentWindow();
|
||||
Window->ScrollMax.y = 1.0f;
|
||||
gp.ChildWindowMade = true;
|
||||
|
@ -1244,7 +1344,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
// BB, PADDING, HOVER -----------------------------------------------------------
|
||||
|
||||
// frame
|
||||
ImVec2 frame_size = ImGui::CalcItemSize(size, IMPLOT_DEFAULT_W, IMPLOT_DEFAULT_H);
|
||||
ImVec2 frame_size = ImGui::CalcItemSize(size, gp.Style.PlotDefaultSize.x, gp.Style.PlotDefaultSize.y);
|
||||
if (frame_size.x < gp.Style.PlotMinSize.x && size.x < 0.0f)
|
||||
frame_size.x = gp.Style.PlotMinSize.x;
|
||||
if (frame_size.y < gp.Style.PlotMinSize.y && size.y < 0.0f)
|
||||
|
@ -1261,8 +1361,35 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
ImGui::SetItemAllowOverlap();
|
||||
ImGui::RenderFrame(gp.BB_Frame.Min, gp.BB_Frame.Max, GetStyleColorU32(ImPlotCol_FrameBg), true, Style.FrameRounding);
|
||||
|
||||
// canvas bb
|
||||
// canvas/axes bb
|
||||
gp.BB_Canvas = ImRect(gp.BB_Frame.Min + gp.Style.PlotPadding, gp.BB_Frame.Max - gp.Style.PlotPadding);
|
||||
gp.BB_Axes = gp.BB_Frame;
|
||||
|
||||
// outside legend adjustments
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoLegend) && plot.Legend.Count() > 0 && plot.LegendOutside) {
|
||||
const ImVec2 legend_size = CalcLegendSize(plot.Legend, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, plot.LegendOrientation);
|
||||
const bool west = ImHasFlag(plot.LegendLocation, ImPlotLocation_West) && !ImHasFlag(plot.LegendLocation, ImPlotLocation_East);
|
||||
const bool east = ImHasFlag(plot.LegendLocation, ImPlotLocation_East) && !ImHasFlag(plot.LegendLocation, ImPlotLocation_West);
|
||||
const bool north = ImHasFlag(plot.LegendLocation, ImPlotLocation_North) && !ImHasFlag(plot.LegendLocation, ImPlotLocation_South);
|
||||
const bool south = ImHasFlag(plot.LegendLocation, ImPlotLocation_South) && !ImHasFlag(plot.LegendLocation, ImPlotLocation_North);
|
||||
const bool horz = plot.LegendOrientation == ImPlotOrientation_Horizontal;
|
||||
if ((west && !horz) || (west && horz && !north && !south)) {
|
||||
gp.BB_Canvas.Min.x += (legend_size.x + gp.Style.LegendPadding.x);
|
||||
gp.BB_Axes.Min.x += (legend_size.x + gp.Style.PlotPadding.x);
|
||||
}
|
||||
if ((east && !horz) || (east && horz && !north && !south)) {
|
||||
gp.BB_Canvas.Max.x -= (legend_size.x + gp.Style.LegendPadding.x);
|
||||
gp.BB_Axes.Max.x -= (legend_size.x + gp.Style.PlotPadding.x);
|
||||
}
|
||||
if ((north && horz) || (north && !horz && !west && !east)) {
|
||||
gp.BB_Canvas.Min.y += (legend_size.y + gp.Style.LegendPadding.y);
|
||||
gp.BB_Axes.Min.y += (legend_size.y + gp.Style.PlotPadding.y);
|
||||
}
|
||||
if ((south && horz) || (south && !horz && !west && !east)) {
|
||||
gp.BB_Canvas.Max.y -= (legend_size.y + gp.Style.LegendPadding.y);
|
||||
gp.BB_Axes.Max.y -= (legend_size.y + gp.Style.PlotPadding.y);
|
||||
}
|
||||
}
|
||||
|
||||
gp.RenderX = (!ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_NoGridLines) ||
|
||||
!ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_NoTickMarks) ||
|
||||
|
@ -1320,8 +1447,8 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
gp.Hov_Plot = gp.BB_Plot.Contains(IO.MousePos) && gp.Hov_Frame;
|
||||
|
||||
// x axis region bb and hover
|
||||
const ImRect xAxisRegion_bb(gp.BB_Plot.GetBL(), ImVec2(gp.BB_Plot.Max.x, gp.BB_Frame.Max.y));
|
||||
plot.XAxis.HoveredExt = xAxisRegion_bb.Contains(IO.MousePos);
|
||||
gp.BB_X = ImRect(gp.BB_Plot.GetBL(), ImVec2(gp.BB_Plot.Max.x, gp.BB_Axes.Max.y));
|
||||
plot.XAxis.HoveredExt = gp.BB_X.Contains(IO.MousePos);
|
||||
plot.XAxis.HoveredTot = plot.XAxis.HoveredExt || gp.Hov_Plot;
|
||||
|
||||
// axis label reference
|
||||
|
@ -1330,34 +1457,20 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
gp.YAxisReference[2] = !gp.Y[1].Present ? gp.BB_Plot.Max.x : (gp.YAxisReference[1] + (gp.Y[1].HasLabels ? gp.Style.LabelPadding.x + gp.YTicks[1].MaxWidth : 0) + gp.Style.LabelPadding.x + gp.Style.MinorTickLen.y);
|
||||
|
||||
// y axis regions bb and hover
|
||||
ImRect yAxisRegion_bb[IMPLOT_Y_AXES];
|
||||
yAxisRegion_bb[0] = ImRect(ImVec2(gp.BB_Frame.Min.x, gp.BB_Plot.Min.y), ImVec2(gp.BB_Plot.Min.x, gp.BB_Plot.Max.y));
|
||||
yAxisRegion_bb[1] = gp.Y[2].Present
|
||||
gp.BB_Y[0] = ImRect(ImVec2(gp.BB_Axes.Min.x, gp.BB_Plot.Min.y), ImVec2(gp.BB_Plot.Min.x, gp.BB_Plot.Max.y));
|
||||
gp.BB_Y[1] = gp.Y[2].Present
|
||||
? ImRect(gp.BB_Plot.GetTR(), ImVec2(gp.YAxisReference[2], gp.BB_Plot.Max.y))
|
||||
: ImRect(gp.BB_Plot.GetTR(), ImVec2(gp.BB_Frame.Max.x, gp.BB_Plot.Max.y));
|
||||
: ImRect(gp.BB_Plot.GetTR(), ImVec2(gp.BB_Axes.Max.x, gp.BB_Plot.Max.y));
|
||||
|
||||
yAxisRegion_bb[2] = ImRect(ImVec2(gp.YAxisReference[2], gp.BB_Plot.Min.y), ImVec2(gp.BB_Frame.Max.x, gp.BB_Plot.Max.y));
|
||||
gp.BB_Y[2] = ImRect(ImVec2(gp.YAxisReference[2], gp.BB_Plot.Min.y), ImVec2(gp.BB_Axes.Max.x, gp.BB_Plot.Max.y));
|
||||
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
|
||||
plot.YAxis[i].HoveredExt = gp.Y[i].Present && yAxisRegion_bb[i].Contains(IO.MousePos);
|
||||
plot.YAxis[i].HoveredExt = gp.Y[i].Present && gp.BB_Y[i].Contains(IO.MousePos);
|
||||
plot.YAxis[i].HoveredTot = plot.YAxis[i].HoveredExt || gp.Hov_Plot;
|
||||
}
|
||||
|
||||
#if 0
|
||||
ImGui::GetForegroundDrawList()->AddRect(gp.BB_Canvas.Min, gp.BB_Canvas.Max, IM_COL32_WHITE);
|
||||
ImGui::GetForegroundDrawList()->AddRectFilled(xAxisRegion_bb.Min, xAxisRegion_bb.Max, IM_COL32(255,0,0,plot.XAxis.HoveredTot ? 128 : 64));
|
||||
ImGui::GetForegroundDrawList()->AddRectFilled(yAxisRegion_bb[0].Min, yAxisRegion_bb[0].Max, IM_COL32(255,255,0,plot.YAxis[0].HoveredTot ? 128 : 64));
|
||||
if (gp.Y[1].Present)
|
||||
ImGui::GetForegroundDrawList()->AddRectFilled(yAxisRegion_bb[1].Min, yAxisRegion_bb[1].Max, IM_COL32(0,255,0,plot.YAxis[1].HoveredTot ? 128 : 64));
|
||||
if (gp.Y[2].Present)
|
||||
ImGui::GetForegroundDrawList()->AddRectFilled(yAxisRegion_bb[2].Min, yAxisRegion_bb[2].Max, IM_COL32(0,0,255,plot.YAxis[2].HoveredTot ? 128 : 64));
|
||||
#endif
|
||||
|
||||
const bool any_hov_y_axis_region = plot.YAxis[0].HoveredTot || plot.YAxis[1].HoveredTot || plot.YAxis[2].HoveredTot;
|
||||
|
||||
// legend hovered from last frame
|
||||
const bool hov_legend = !ImHasFlag(plot.Flags, ImPlotFlags_NoLegend) ? gp.Hov_Frame && plot.BB_Legend.Contains(IO.MousePos) : false;
|
||||
|
||||
bool hov_query = false;
|
||||
if (gp.Hov_Frame && gp.Hov_Plot && plot.Queried && !plot.Querying) {
|
||||
ImRect bb_query = plot.QueryRect;
|
||||
|
@ -1377,7 +1490,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
plot.QueryRect.Min += IO.MouseDelta;
|
||||
plot.QueryRect.Max += IO.MouseDelta;
|
||||
}
|
||||
if (gp.Hov_Frame && gp.Hov_Plot && hov_query && !plot.DraggingQuery && !plot.Selecting && !hov_legend) {
|
||||
if (gp.Hov_Frame && gp.Hov_Plot && hov_query && !plot.DraggingQuery && !plot.Selecting && !plot.LegendHovered) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
|
||||
const bool any_y_dragging = plot.YAxis[0].Dragging || plot.YAxis[1].Dragging || plot.YAxis[2].Dragging;
|
||||
if (IO.MouseDown[gp.InputMap.PanButton] && !plot.XAxis.Dragging && !any_y_dragging) {
|
||||
|
@ -1445,7 +1558,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
}
|
||||
}
|
||||
// start drag
|
||||
if (!drag_in_progress && gp.Hov_Frame && IO.MouseClicked[gp.InputMap.PanButton] && ImHasFlag(IO.KeyMods, gp.InputMap.PanMod) && !plot.Selecting && !hov_legend && !hov_query && !plot.DraggingQuery) {
|
||||
if (!drag_in_progress && gp.Hov_Frame && IO.MouseClicked[gp.InputMap.PanButton] && ImHasFlag(IO.KeyMods, gp.InputMap.PanMod) && !plot.Selecting && !plot.LegendHovered && !hov_query && !plot.DraggingQuery) {
|
||||
if (plot.XAxis.HoveredTot) {
|
||||
plot.XAxis.Dragging = true;
|
||||
}
|
||||
|
@ -1576,7 +1689,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
// FIT -----------------------------------------------------------
|
||||
|
||||
// fit from double click
|
||||
if ( IO.MouseDoubleClicked[gp.InputMap.FitButton] && gp.Hov_Frame && (plot.XAxis.HoveredTot || any_hov_y_axis_region) && !hov_legend && !hov_query ) {
|
||||
if ( IO.MouseDoubleClicked[gp.InputMap.FitButton] && gp.Hov_Frame && (plot.XAxis.HoveredTot || any_hov_y_axis_region) && !plot.LegendHovered && !hov_query ) {
|
||||
gp.FitThisFrame = true;
|
||||
gp.FitX = plot.XAxis.HoveredTot;
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++)
|
||||
|
@ -1708,6 +1821,8 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
}
|
||||
}
|
||||
ImGui::PopClipRect();
|
||||
// clear legend
|
||||
plot.Legend.Reset();
|
||||
// push plot ID into stack
|
||||
ImGui::PushID(ID);
|
||||
return true;
|
||||
|
@ -1915,11 +2030,15 @@ void ShowPlotContextMenu(ImPlotPlot& 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.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());
|
||||
|
||||
bool f = false;
|
||||
ImGui::Selectable("BB_Frame",&f); if (ImGui::IsItemHovered()) ImGui::GetForegroundDrawList()->AddRect(gp.BB_Frame.Min, gp.BB_Frame.Max, IM_COL32(255,255,0,255));
|
||||
ImGui::Selectable("BB_Canvas",&f); if (ImGui::IsItemHovered()) ImGui::GetForegroundDrawList()->AddRect(gp.BB_Canvas.Min, gp.BB_Canvas.Max, IM_COL32(255,255,0,255));
|
||||
ImGui::Selectable("BB_Plot",&f); if (ImGui::IsItemHovered()) ImGui::GetForegroundDrawList()->AddRect(gp.BB_Plot.Min, gp.BB_Plot.Max, IM_COL32(255,255,0,255));
|
||||
ImGui::Selectable("BB_Axes",&f); if (ImGui::IsItemHovered()) ImGui::GetForegroundDrawList()->AddRect(gp.BB_Axes.Min, gp.BB_Axes.Max, IM_COL32(255,255,0,255));
|
||||
ImGui::Selectable("BB_X",&f); if (ImGui::IsItemHovered()) ImGui::GetForegroundDrawList()->AddRect(gp.BB_X.Min, gp.BB_X.Max, IM_COL32(255,255,0,255));
|
||||
ImGui::Selectable("BB_Y[0]",&f); if (ImGui::IsItemHovered()) ImGui::GetForegroundDrawList()->AddRect(gp.BB_Y[0].Min, gp.BB_Y[0].Max, IM_COL32(255,255,0,255));
|
||||
ImGui::Selectable("BB_Y[1]",&f); if (ImGui::IsItemHovered()) ImGui::GetForegroundDrawList()->AddRect(gp.BB_Y[1].Min, gp.BB_Y[1].Max, IM_COL32(255,255,0,255));
|
||||
ImGui::Selectable("BB_Y[2]",&f); if (ImGui::IsItemHovered()) ImGui::GetForegroundDrawList()->AddRect(gp.BB_Y[2].Min, gp.BB_Y[2].Max, IM_COL32(255,255,0,255));
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
@ -2096,75 +2215,9 @@ void EndPlot() {
|
|||
}
|
||||
}
|
||||
|
||||
// render legend
|
||||
const float txt_ht = ImGui::GetTextLineHeight();
|
||||
const ImVec2 legend_offset = gp.Style.LegendPadding;
|
||||
const ImVec2 legend_spacing(5, 5);
|
||||
const float legend_icon_size = txt_ht;
|
||||
ImRect legend_content_bb;
|
||||
int nItems = GetLegendCount();
|
||||
bool hov_legend = false;
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoLegend) && nItems > 0) {
|
||||
// get max width
|
||||
float max_label_width = 0;
|
||||
for (int i = 0; i < nItems; ++i) {
|
||||
const char* label = GetLegendLabel(i);
|
||||
ImVec2 labelWidth = ImGui::CalcTextSize(label, NULL, true);
|
||||
max_label_width = labelWidth.x > max_label_width ? labelWidth.x : max_label_width;
|
||||
}
|
||||
legend_content_bb = ImRect(gp.BB_Plot.Min + legend_offset, gp.BB_Plot.Min + legend_offset + ImVec2(max_label_width, nItems * txt_ht));
|
||||
plot.BB_Legend = ImRect(legend_content_bb.Min, legend_content_bb.Max + legend_spacing * 2 + ImVec2(legend_icon_size, 0));
|
||||
hov_legend = !ImHasFlag(plot.Flags, ImPlotFlags_NoLegend) ? gp.Hov_Frame && plot.BB_Legend.Contains(IO.MousePos) : false;
|
||||
// render legend box
|
||||
ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
||||
ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
||||
ImVec4 col_txt = GetStyleColorVec4(ImPlotCol_LegendText);
|
||||
ImU32 col_txt_dis = ImGui::GetColorU32(col_txt * ImVec4(1,1,1,0.25f));
|
||||
DrawList.AddRectFilled(plot.BB_Legend.Min, plot.BB_Legend.Max, col_bg);
|
||||
DrawList.AddRect(plot.BB_Legend.Min, plot.BB_Legend.Max, col_bd);
|
||||
// render each legend item
|
||||
for (int i = 0; i < nItems; ++i) {
|
||||
ImPlotItem* item = GetItem(i);
|
||||
ImRect icon_bb;
|
||||
icon_bb.Min = legend_content_bb.Min + legend_spacing + ImVec2(0, i * txt_ht) + ImVec2(2, 2);
|
||||
icon_bb.Max = legend_content_bb.Min + legend_spacing + ImVec2(0, i * txt_ht) + ImVec2(legend_icon_size - 2, legend_icon_size - 2);
|
||||
ImRect label_bb;
|
||||
label_bb.Min = legend_content_bb.Min + legend_spacing + ImVec2(0, i * txt_ht) + ImVec2(2, 2);
|
||||
label_bb.Max = legend_content_bb.Min + legend_spacing + ImVec2(0, i * txt_ht) + ImVec2(legend_content_bb.Max.x, legend_icon_size - 2);
|
||||
ImU32 col_hl_txt;
|
||||
if (hov_legend && (icon_bb.Contains(IO.MousePos) || label_bb.Contains(IO.MousePos))) {
|
||||
item->LegendHovered = true;
|
||||
col_hl_txt = ImGui::GetColorU32(ImLerp(col_txt, item->Color, 0.25f));
|
||||
}
|
||||
else
|
||||
{
|
||||
item->LegendHovered = false;
|
||||
col_hl_txt = ImGui::GetColorU32(col_txt);
|
||||
}
|
||||
ImU32 iconColor;
|
||||
ImVec4 item_color = item->Color;
|
||||
item_color.w = 1;
|
||||
if (hov_legend && icon_bb.Contains(IO.MousePos)) {
|
||||
ImVec4 colAlpha = item_color;
|
||||
colAlpha.w = 0.5f;
|
||||
iconColor = item->Show ? ImGui::GetColorU32(colAlpha)
|
||||
: ImGui::GetColorU32(ImGuiCol_TextDisabled, 0.5f);
|
||||
if (IO.MouseClicked[0])
|
||||
item->Show = !item->Show;
|
||||
} else {
|
||||
iconColor = item->Show ? ImGui::GetColorU32(item_color) : col_txt_dis;
|
||||
}
|
||||
DrawList.AddRectFilled(icon_bb.Min, icon_bb.Max, iconColor, 1);
|
||||
const char* label = GetLegendLabel(i);
|
||||
const char* text_display_end = ImGui::FindRenderedTextEnd(label, NULL);
|
||||
if (label != text_display_end)
|
||||
DrawList.AddText(legend_content_bb.Min + legend_spacing + ImVec2(legend_icon_size, i * txt_ht), item->Show ? col_hl_txt : col_txt_dis, label, text_display_end);
|
||||
}
|
||||
}
|
||||
|
||||
// render crosshairs
|
||||
if (ImHasFlag(plot.Flags, ImPlotFlags_Crosshairs) && gp.Hov_Plot && gp.Hov_Frame &&
|
||||
!(plot.XAxis.Dragging || any_y_dragging) && !plot.Selecting && !plot.Querying && !hov_legend) {
|
||||
!(plot.XAxis.Dragging || any_y_dragging) && !plot.Selecting && !plot.Querying && !plot.LegendHovered) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_None);
|
||||
ImVec2 xy = IO.MousePos;
|
||||
ImVec2 h1(gp.BB_Plot.Min.x, xy.y);
|
||||
|
@ -2229,13 +2282,43 @@ void EndPlot() {
|
|||
writer.Write(",(%.*f)", Precision(range_y), gp.MousePos[2].y);
|
||||
}
|
||||
}
|
||||
ImVec2 size = ImGui::CalcTextSize(buffer);
|
||||
ImVec2 pos = gp.BB_Plot.Max - size - gp.Style.InfoPadding;
|
||||
const ImVec2 size = ImGui::CalcTextSize(buffer);
|
||||
const ImVec2 pos = GetLocationPos(gp.BB_Plot, size, plot.MousePosLocation, gp.Style.MousePosPadding);
|
||||
DrawList.AddText(pos, GetStyleColorU32(ImPlotCol_InlayText), buffer);
|
||||
}
|
||||
|
||||
PopPlotClipRect();
|
||||
|
||||
// reset legend hovers
|
||||
plot.LegendHovered = false;
|
||||
for (int i = 0; i < plot.Items.GetSize(); ++i)
|
||||
plot.Items.GetByIndex(i)->LegendHovered = false;
|
||||
// render legend
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoLegend) && plot.Legend.Count() > 0) {
|
||||
const ImVec2 legend_size = CalcLegendSize(plot.Legend, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, plot.LegendOrientation);
|
||||
const ImVec2 legend_pos = GetLocationPos(plot.LegendOutside ? gp.BB_Frame : gp.BB_Plot,
|
||||
legend_size,
|
||||
plot.LegendLocation,
|
||||
plot.LegendOutside ? gp.Style.PlotPadding : gp.Style.LegendPadding);
|
||||
const ImRect legend_bb(legend_pos, legend_pos + legend_size);
|
||||
// test hover
|
||||
plot.LegendHovered = gp.Hov_Frame && legend_bb.Contains(IO.MousePos);
|
||||
|
||||
if (plot.LegendOutside)
|
||||
ImGui::PushClipRect(gp.BB_Frame.Min, gp.BB_Frame.Max, true);
|
||||
else
|
||||
PushPlotClipRect();
|
||||
ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
||||
ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
||||
DrawList.AddRectFilled(legend_bb.Min, legend_bb.Max, col_bg);
|
||||
DrawList.AddRect(legend_bb.Min, legend_bb.Max, col_bd);
|
||||
ShowLegendEntries(plot.Legend, legend_bb, plot.LegendHovered, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, plot.LegendOrientation, DrawList);
|
||||
ImGui::PopClipRect();
|
||||
}
|
||||
if (plot.LegendFlipSide) {
|
||||
plot.LegendOutside = !plot.LegendOutside;
|
||||
plot.LegendFlipSide = false;
|
||||
}
|
||||
|
||||
// render border
|
||||
if (gp.Style.PlotBorderSize > 0)
|
||||
DrawList.AddRect(gp.BB_Plot.Min, gp.BB_Plot.Max, GetStyleColorU32(ImPlotCol_PlotBorder), 0, ImDrawCornerFlags_All, gp.Style.PlotBorderSize);
|
||||
|
@ -2271,14 +2354,14 @@ void EndPlot() {
|
|||
|
||||
// CONTEXT MENUS -----------------------------------------------------------
|
||||
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && gp.Hov_Frame && gp.Hov_Plot && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !hov_legend)
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && gp.Hov_Frame && gp.Hov_Plot && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !plot.LegendHovered)
|
||||
ImGui::OpenPopup("##PlotContext");
|
||||
if (ImGui::BeginPopup("##PlotContext")) {
|
||||
ShowPlotContextMenu(plot);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && gp.Hov_Frame && plot.XAxis.HoveredExt && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !hov_legend)
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && gp.Hov_Frame && plot.XAxis.HoveredExt && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !plot.LegendHovered)
|
||||
ImGui::OpenPopup("##XContext");
|
||||
if (ImGui::BeginPopup("##XContext")) {
|
||||
ImGui::Text("X-Axis"); ImGui::Separator();
|
||||
|
@ -2288,7 +2371,7 @@ void EndPlot() {
|
|||
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
|
||||
ImGui::PushID(i);
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && gp.Hov_Frame && plot.YAxis[i].HoveredExt && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !hov_legend)
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && gp.Hov_Frame && plot.YAxis[i].HoveredExt && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !plot.LegendHovered)
|
||||
ImGui::OpenPopup("##YContext");
|
||||
if (ImGui::BeginPopup("##YContext")) {
|
||||
if (i == 0) {
|
||||
|
@ -2347,7 +2430,7 @@ void SetNextPlotLimitsX(double x_min, double x_max, ImGuiCond cond) {
|
|||
gp.NextPlotData.X.Max = x_max;
|
||||
}
|
||||
|
||||
void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond, int y_axis) {
|
||||
void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond, ImPlotYAxis y_axis) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "SetNextPlotLimitsY() needs to be called before BeginPlot()!");
|
||||
IM_ASSERT_USER_ERROR(y_axis >= 0 && y_axis < IMPLOT_Y_AXES, "y_axis needs to be between 0 and IMPLOT_Y_AXES");
|
||||
|
@ -2393,7 +2476,7 @@ void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char* cons
|
|||
SetNextPlotTicksX(&buffer[0], n_ticks, labels, show_default);
|
||||
}
|
||||
|
||||
void SetNextPlotTicksY(const double* values, int n_ticks, const char* const labels[], bool show_default, int y_axis) {
|
||||
void SetNextPlotTicksY(const double* values, int n_ticks, const char* const labels[], bool show_default, ImPlotYAxis y_axis) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "SetNextPlotTicksY() needs to be called before BeginPlot()!");
|
||||
IM_ASSERT_USER_ERROR(y_axis >= 0 && y_axis < IMPLOT_Y_AXES, "y_axis needs to be between 0 and IMPLOT_Y_AXES");
|
||||
|
@ -2401,14 +2484,14 @@ void SetNextPlotTicksY(const double* values, int n_ticks, const char* const labe
|
|||
AddTicksCustom(values, labels, n_ticks, gp.YTicks[y_axis]);
|
||||
}
|
||||
|
||||
void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char* const labels[], bool show_default, int y_axis) {
|
||||
void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char* const labels[], bool show_default, ImPlotYAxis y_axis) {
|
||||
IM_ASSERT_USER_ERROR(n_ticks > 1, "The number of ticks must be greater than 1");
|
||||
static ImVector<double> buffer;
|
||||
FillRange(buffer, n_ticks, y_min, y_max);
|
||||
SetNextPlotTicksY(&buffer[0], n_ticks, labels, show_default,y_axis);
|
||||
}
|
||||
|
||||
void SetPlotYAxis(int y_axis) {
|
||||
void SetPlotYAxis(ImPlotYAxis y_axis) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "SetPlotYAxis() needs to be called between BeginPlot() and EndPlot()!");
|
||||
IM_ASSERT_USER_ERROR(y_axis >= 0 && y_axis < IMPLOT_Y_AXES, "y_axis needs to be between 0 and IMPLOT_Y_AXES");
|
||||
|
@ -2453,28 +2536,28 @@ bool IsPlotXAxisHovered() {
|
|||
return gp.CurrentPlot->XAxis.HoveredExt;
|
||||
}
|
||||
|
||||
bool IsPlotYAxisHovered(int y_axis_in) {
|
||||
bool IsPlotYAxisHovered(ImPlotYAxis y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(y_axis_in >= -1 && y_axis_in < IMPLOT_Y_AXES, "y_axis needs to between -1 and IMPLOT_Y_AXES");
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "IsPlotYAxisHovered() needs to be called between BeginPlot() and EndPlot()!");
|
||||
const int y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
return gp.CurrentPlot->YAxis[y_axis].HoveredExt;
|
||||
}
|
||||
|
||||
ImPlotPoint GetPlotMousePos(int y_axis_in) {
|
||||
ImPlotPoint GetPlotMousePos(ImPlotYAxis y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(y_axis_in >= -1 && y_axis_in < IMPLOT_Y_AXES, "y_axis needs to between -1 and IMPLOT_Y_AXES");
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "GetPlotMousePos() needs to be called between BeginPlot() and EndPlot()!");
|
||||
const int y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
return gp.MousePos[y_axis];
|
||||
}
|
||||
|
||||
|
||||
ImPlotLimits GetPlotLimits(int y_axis_in) {
|
||||
ImPlotLimits GetPlotLimits(ImPlotYAxis y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(y_axis_in >= -1 && y_axis_in < IMPLOT_Y_AXES, "y_axis needs to between -1 and IMPLOT_Y_AXES");
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "GetPlotLimits() needs to be called between BeginPlot() and EndPlot()!");
|
||||
const int y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
|
||||
ImPlotPlot& plot = *gp.CurrentPlot;
|
||||
ImPlotLimits limits;
|
||||
|
@ -2489,12 +2572,12 @@ bool IsPlotQueried() {
|
|||
return gp.CurrentPlot->Queried;
|
||||
}
|
||||
|
||||
ImPlotLimits GetPlotQuery(int y_axis_in) {
|
||||
ImPlotLimits GetPlotQuery(ImPlotYAxis y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(y_axis_in >= -1 && y_axis_in < IMPLOT_Y_AXES, "y_axis needs to between -1 and IMPLOT_Y_AXES");
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "GetPlotQuery() needs to be called between BeginPlot() and EndPlot()!");
|
||||
ImPlotPlot& plot = *gp.CurrentPlot;
|
||||
const int y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
const ImPlotYAxis y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
|
||||
UpdateTransformCache();
|
||||
ImPlotPoint p1 = PixelsToPlot(plot.QueryRect.Min + gp.BB_Plot.Min, y_axis);
|
||||
|
@ -2694,6 +2777,21 @@ bool DragPoint(const char* id, double* x, double* y, bool show_label, const ImVe
|
|||
return dragging;
|
||||
}
|
||||
|
||||
void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation, bool outside) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "SetLegendLocation() needs to be called between BeginPlot() and EndPlot()!");
|
||||
gp.CurrentPlot->LegendLocation = location;
|
||||
gp.CurrentPlot->LegendOrientation = orientation;
|
||||
if (gp.CurrentPlot->LegendOutside != outside)
|
||||
gp.CurrentPlot->LegendFlipSide = true;
|
||||
}
|
||||
|
||||
void SetMousePosLocation(ImPlotLocation location) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "SetMousePosLocation() needs to be called between BeginPlot() and EndPlot()!");
|
||||
gp.CurrentPlot->MousePosLocation = location;
|
||||
}
|
||||
|
||||
bool IsLegendEntryHovered(const char* label_id) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "IsPlotItemHighlight() needs to be called between BeginPlot() and EndPlot()!");
|
||||
|
@ -2790,6 +2888,42 @@ void EndLegendPopup() {
|
|||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
void ShowAltLegend(const char* title_id, ImPlotOrientation orientation, const ImVec2 size, bool interactable) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImGuiContext &G = *GImGui;
|
||||
ImGuiWindow * Window = G.CurrentWindow;
|
||||
if (Window->SkipItems)
|
||||
return;
|
||||
ImDrawList &DrawList = *Window->DrawList;
|
||||
ImPlotPlot* plot = GetPlot(title_id);
|
||||
ImVec2 legend_size;
|
||||
ImVec2 default_size = gp.Style.LegendPadding * 2;
|
||||
if (plot != NULL) {
|
||||
legend_size = CalcLegendSize(plot->Legend, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, orientation);
|
||||
default_size = legend_size + gp.Style.LegendPadding * 2;
|
||||
}
|
||||
ImVec2 frame_size = ImGui::CalcItemSize(size, default_size.x, default_size.y);
|
||||
ImRect bb_frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + frame_size);
|
||||
ImGui::ItemSize(bb_frame);
|
||||
if (!ImGui::ItemAdd(bb_frame, 0, &bb_frame))
|
||||
return;
|
||||
ImGui::RenderFrame(bb_frame.Min, bb_frame.Max, GetStyleColorU32(ImPlotCol_FrameBg), true, G.Style.FrameRounding);
|
||||
DrawList.PushClipRect(bb_frame.Min, bb_frame.Max, true);
|
||||
if (plot != NULL) {
|
||||
const ImVec2 legend_pos = GetLocationPos(bb_frame, legend_size, 0, gp.Style.LegendPadding);
|
||||
const ImRect legend_bb(legend_pos, legend_pos + legend_size);
|
||||
interactable = interactable && bb_frame.Contains(ImGui::GetIO().MousePos);
|
||||
// render legend box
|
||||
ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
||||
ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
||||
DrawList.AddRectFilled(legend_bb.Min, legend_bb.Max, col_bg);
|
||||
DrawList.AddRect(legend_bb.Min, legend_bb.Max, col_bd);
|
||||
// render entries
|
||||
ShowLegendEntries(plot->Legend, legend_bb, interactable, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, orientation, DrawList);
|
||||
}
|
||||
DrawList.PopClipRect();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// STYLING
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -3154,7 +3288,7 @@ void ShowColormapScale(double scale_min, double scale_max, float height) {
|
|||
ImGui::ItemSize(bb_frame);
|
||||
if (!ImGui::ItemAdd(bb_frame, 0, &bb_frame))
|
||||
return;
|
||||
ImGui::RenderFrame(bb_frame.Min, bb_frame.Max, GetStyleColorU32(ImPlotCol_FrameBg));
|
||||
ImGui::RenderFrame(bb_frame.Min, bb_frame.Max, GetStyleColorU32(ImPlotCol_FrameBg), true, G.Style.FrameRounding);
|
||||
ImRect bb_grad(bb_frame.Min + gp.Style.PlotPadding, bb_frame.Min + ImVec2(bar_w + gp.Style.PlotPadding.x, height - gp.Style.PlotPadding.y));
|
||||
|
||||
int num_cols = GetColormapSize();
|
||||
|
@ -3280,12 +3414,15 @@ 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("PlotDefaultSize", (float*)&style.PlotDefaultSize, 0.0f, 1000, "%.0f");
|
||||
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("LegendInnerPadding", (float*)&style.LegendInnerPadding, 0.0f, 10.0f, "%.0f");
|
||||
ImGui::SliderFloat2("LegendSpacing", (float*)&style.LegendSpacing, 0.0f, 5.0f, "%.0f");
|
||||
ImGui::SliderFloat2("MousePosPadding", (float*)&style.MousePosPadding, 0.0f, 20.0f, "%.0f");
|
||||
ImGui::SliderFloat2("AnnotationPadding", (float*)&style.AnnotationPadding, 0.0f, 5.0f, "%.0f");
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
|
98
implot.h
98
implot.h
|
@ -58,6 +58,9 @@ typedef int ImPlotCol; // -> enum ImPlotCol_
|
|||
typedef int ImPlotStyleVar; // -> enum ImPlotStyleVar_
|
||||
typedef int ImPlotMarker; // -> enum ImPlotMarker_
|
||||
typedef int ImPlotColormap; // -> enum ImPlotColormap_
|
||||
typedef int ImPlotLocation; // -> enum ImPlotLocation_
|
||||
typedef int ImPlotOrientation; // -> enum ImPlotOrientation_
|
||||
typedef int ImPlotYAxis; // -> enum ImPlotYAxis_;
|
||||
|
||||
// Options for plots.
|
||||
enum ImPlotFlags_ {
|
||||
|
@ -65,7 +68,7 @@ enum ImPlotFlags_ {
|
|||
ImPlotFlags_NoLegend = 1 << 0, // the top-left legend will not be displayed
|
||||
ImPlotFlags_NoMenus = 1 << 1, // the user will not be able to open context menus with double-right click
|
||||
ImPlotFlags_NoBoxSelect = 1 << 2, // the user will not be able to box-select with right-mouse
|
||||
ImPlotFlags_NoMousePos = 1 << 3, // the mouse position, in plot coordinates, will not be displayed in the bottom-right
|
||||
ImPlotFlags_NoMousePos = 1 << 3, // the mouse position, in plot coordinates, will not be displayed inside of the plot
|
||||
ImPlotFlags_NoHighlight = 1 << 4, // plot items will not be highlighted when their legend entry is hovered
|
||||
ImPlotFlags_NoChild = 1 << 5, // a child window region will not be used to capture mouse scroll (can boost performance for single ImGui window applications)
|
||||
ImPlotFlags_YAxis2 = 1 << 6, // enable a 2nd y-axis on the right side
|
||||
|
@ -143,11 +146,14 @@ enum ImPlotStyleVar_ {
|
|||
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_PlotPadding, // ImVec2, padding between widget frame and plot area, labels, or outside legends (i.e. main padding)
|
||||
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_LegendPadding, // ImVec2, legend padding from plot edges
|
||||
ImPlotStyleVar_LegendInnerPadding, // ImVec2, legend inner padding from legend edges
|
||||
ImPlotStyleVar_LegendSpacing, // ImVec2, spacing between legend entries
|
||||
ImPlotStyleVar_MousePosPadding, // ImVec2, padding between plot edge and interior info text
|
||||
ImPlotStyleVar_AnnotationPadding, // ImVec2, text padding around annotation labels
|
||||
ImPlotStyleVar_PlotDefaultSize, // ImVec2, default size used when ImVec2(0,0) is passed to BeginPlot
|
||||
ImPlotStyleVar_PlotMinSize, // ImVec2, minimum size plot frame can be when shrunk
|
||||
ImPlotStyleVar_COUNT
|
||||
};
|
||||
|
@ -184,6 +190,32 @@ enum ImPlotColormap_ {
|
|||
ImPlotColormap_COUNT
|
||||
};
|
||||
|
||||
// Used to position items on a plot (e.g. legends, labels, etc.)
|
||||
enum ImPlotLocation_ {
|
||||
ImPlotLocation_Center = 0, // center-center
|
||||
ImPlotLocation_North = 1 << 0, // top-center
|
||||
ImPlotLocation_South = 1 << 1, // bottom-center
|
||||
ImPlotLocation_West = 1 << 2, // center-left
|
||||
ImPlotLocation_East = 1 << 3, // center-right
|
||||
ImPlotLocation_NorthWest = ImPlotLocation_North | ImPlotLocation_West, // top-left
|
||||
ImPlotLocation_NorthEast = ImPlotLocation_North | ImPlotLocation_East, // top-right
|
||||
ImPlotLocation_SouthWest = ImPlotLocation_South | ImPlotLocation_West, // bottom-left
|
||||
ImPlotLocation_SouthEast = ImPlotLocation_South | ImPlotLocation_East // bottom-right
|
||||
};
|
||||
|
||||
// Used to orient items on a plot (e.g. legends, labels, etc.)
|
||||
enum ImPlotOrientation_ {
|
||||
ImPlotOrientation_Horizontal, // left/right
|
||||
ImPlotOrientation_Vertical // up/down
|
||||
};
|
||||
|
||||
// Enums for different y-axes.
|
||||
enum ImPlotYAxis_ {
|
||||
ImPlotYAxis_1 = 0, // left (default)
|
||||
ImPlotYAxis_2 = 1, // first on right side
|
||||
ImPlotYAxis_3 = 2 // second on right side
|
||||
};
|
||||
|
||||
// Double precision version of ImVec2 used by ImPlot. Extensible by end users.
|
||||
struct ImPlotPoint {
|
||||
double x, y;
|
||||
|
@ -235,11 +267,14 @@ struct ImPlotStyle {
|
|||
ImVec2 MinorTickSize; // = 1,1 line thickness of minor ticks
|
||||
ImVec2 MajorGridSize; // = 1,1 line thickness of major grid lines
|
||||
ImVec2 MinorGridSize; // = 1,1 line thickness of minor grid lines
|
||||
ImVec2 PlotPadding; // = 8,8 padding between widget frame and plot area and/or labels
|
||||
ImVec2 PlotPadding; // = 10,10 padding between widget frame and plot area, labels, or outside legends (i.e. main padding)
|
||||
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 LegendPadding; // = 10,10 legend padding from plot edges
|
||||
ImVec2 LegendInnerPadding; // = 5,5 legend inner padding from legend edges
|
||||
ImVec2 LegendSpacing; // = 0,0 spacing between legend entries
|
||||
ImVec2 MousePosPadding; // = 10,10 padding between plot edge and interior mouse location text
|
||||
ImVec2 AnnotationPadding; // = 2,2 text padding around annotation labels
|
||||
ImVec2 PlotDefaultSize; // = 400,300 default size used when ImVec2(0,0) is passed to BeginPlot
|
||||
ImVec2 PlotMinSize; // = 300,225 minimum size plot frame can be when shrunk
|
||||
// colors
|
||||
ImVec4 Colors[ImPlotCol_COUNT]; // array of plot specific colors
|
||||
|
@ -247,7 +282,7 @@ struct ImPlotStyle {
|
|||
bool AntiAliasedLines; // = false, enable global anti-aliasing on plot lines (overrides ImPlotFlags_AntiAliased)
|
||||
bool UseLocalTime; // = false, axis labels will be formatted for your timezone when ImPlotAxisFlag_Time is enabled
|
||||
bool UseISO8601; // = false, dates will be formatted according to ISO 8601 where applicable (e.g. YYYY-MM-DD, YYYY-MM, --MM-DD, etc.)
|
||||
bool Use24HourClock; // = false, times will be formatted using 24 hour clock
|
||||
bool Use24HourClock; // = false, times will be formatted using a 24 hour clock
|
||||
IMPLOT_API ImPlotStyle();
|
||||
};
|
||||
|
||||
|
@ -403,6 +438,9 @@ IMPLOT_API void PlotImage(const char* label_id, ImTextureID user_texture_id, con
|
|||
// 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& pix_offset=ImVec2(0,0));
|
||||
|
||||
// Plots an dummy item (i.e. adds a legend entry colored by ImPlotCol_Line)
|
||||
IMPLOT_API void PlotDummy(const char* label_id);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plot Utils
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -414,7 +452,7 @@ IMPLOT_API void SetNextPlotLimits(double xmin, double xmax, double ymin, double
|
|||
// Set the X axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the X axis limits will be locked.
|
||||
IMPLOT_API void SetNextPlotLimitsX(double xmin, double xmax, ImGuiCond cond = ImGuiCond_Once);
|
||||
// Set the Y axis range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the Y axis limits will be locked.
|
||||
IMPLOT_API void SetNextPlotLimitsY(double ymin, double ymax, ImGuiCond cond = ImGuiCond_Once, int y_axis = 0);
|
||||
IMPLOT_API void SetNextPlotLimitsY(double ymin, double ymax, ImGuiCond cond = ImGuiCond_Once, ImPlotYAxis y_axis = 0);
|
||||
// Links the next plot limits to external values. Set to NULL for no linkage. The pointer data must remain valid until the matching call EndPlot.
|
||||
IMPLOT_API void LinkNextPlotLimits(double* xmin, double* xmax, double* ymin, double* ymax, double* ymin2 = NULL, double* ymax2 = NULL, double* ymin3 = NULL, double* ymax3 = NULL);
|
||||
// Fits the next plot axes to all plotted data if they are unlocked (equivalent to double-clicks).
|
||||
|
@ -425,22 +463,22 @@ IMPLOT_API void SetNextPlotTicksX(const double* values, int n_ticks, const char*
|
|||
IMPLOT_API void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char* const labels[] = NULL, bool show_default = false);
|
||||
|
||||
// Set the Y axis ticks and optionally the labels for the next plot.
|
||||
IMPLOT_API void SetNextPlotTicksY(const double* values, int n_ticks, const char* const labels[] = NULL, bool show_default = false, int y_axis = 0);
|
||||
IMPLOT_API void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char* const labels[] = NULL, bool show_default = false, int y_axis = 0);
|
||||
IMPLOT_API void SetNextPlotTicksY(const double* values, int n_ticks, const char* const labels[] = NULL, bool show_default = false, ImPlotYAxis y_axis = 0);
|
||||
IMPLOT_API void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char* const labels[] = NULL, bool show_default = false, ImPlotYAxis y_axis = 0);
|
||||
|
||||
// The following functions MUST be called between Begin/EndPlot!
|
||||
|
||||
// Select which Y axis will be used for subsequent plot elements. The default is '0', or the first (left) Y axis. Enable 2nd and 3rd axes with ImPlotFlags_YAxisX.
|
||||
IMPLOT_API void SetPlotYAxis(int y_axis);
|
||||
// Hides or shows the next plot item (i.e. as if it were toggled from the legend). Use ImGuiCond_Always if you need to change this every frame.
|
||||
// Select which Y axis will be used for subsequent plot elements. The default is ImPlotYAxis_1, or the first (left) Y axis. Enable 2nd and 3rd axes with ImPlotFlags_YAxisX.
|
||||
IMPLOT_API void SetPlotYAxis(ImPlotYAxis y_axis);
|
||||
// Hides or shows the next plot item (i.e. as if it were toggled from the legend). Use ImGuiCond_Always if you need to forcefully set this every frame.
|
||||
IMPLOT_API void HideNextItem(bool hidden = true, ImGuiCond cond = ImGuiCond_Once);
|
||||
|
||||
// Convert pixels to a position in the current plot's coordinate system. A negative y_axis uses the current value of SetPlotYAxis (0 initially).
|
||||
IMPLOT_API ImPlotPoint PixelsToPlot(const ImVec2& pix, int y_axis = IMPLOT_AUTO);
|
||||
IMPLOT_API ImPlotPoint PixelsToPlot(float x, float y, int y_axis = IMPLOT_AUTO);
|
||||
// Convert a position in the current plot's coordinate system to pixels. A negative y_axis uses the current value of SetPlotYAxis (0 initially).
|
||||
IMPLOT_API ImVec2 PlotToPixels(const ImPlotPoint& plt, int y_axis = IMPLOT_AUTO);
|
||||
IMPLOT_API ImVec2 PlotToPixels(double x, double y, int y_axis = IMPLOT_AUTO);
|
||||
// Convert pixels to a position in the current plot's coordinate system. A negative y_axis uses the current value of SetPlotYAxis (ImPlotYAxis_1 initially).
|
||||
IMPLOT_API ImPlotPoint PixelsToPlot(const ImVec2& pix, ImPlotYAxis y_axis = IMPLOT_AUTO);
|
||||
IMPLOT_API ImPlotPoint PixelsToPlot(float x, float y, ImPlotYAxis y_axis = IMPLOT_AUTO);
|
||||
// Convert a position in the current plot's coordinate system to pixels. A negative y_axis uses the current value of SetPlotYAxis (ImPlotYAxis_1 initially).
|
||||
IMPLOT_API ImVec2 PlotToPixels(const ImPlotPoint& plt, ImPlotYAxis y_axis = IMPLOT_AUTO);
|
||||
IMPLOT_API ImVec2 PlotToPixels(double x, double y, ImPlotYAxis y_axis = IMPLOT_AUTO);
|
||||
// Get the current Plot position (top-left) in pixels.
|
||||
IMPLOT_API ImVec2 GetPlotPos();
|
||||
// Get the curent Plot size in pixels.
|
||||
|
@ -450,21 +488,23 @@ IMPLOT_API bool IsPlotHovered();
|
|||
// Returns true if the XAxis plot area in the current plot is hovered.
|
||||
IMPLOT_API bool IsPlotXAxisHovered();
|
||||
// Returns true if the YAxis[n] plot area in the current plot is hovered.
|
||||
IMPLOT_API bool IsPlotYAxisHovered(int y_axis = 0);
|
||||
// Returns the mouse position in x,y coordinates of the current plot. A negative y_axis uses the current value of SetPlotYAxis (0 initially).
|
||||
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);
|
||||
IMPLOT_API bool IsPlotYAxisHovered(ImPlotYAxis y_axis = 0);
|
||||
// Returns the mouse position in x,y coordinates of the current plot. A negative y_axis uses the current value of SetPlotYAxis (ImPlotYAxis_1 initially).
|
||||
IMPLOT_API ImPlotPoint GetPlotMousePos(ImPlotYAxis y_axis = IMPLOT_AUTO);
|
||||
// Returns the current plot axis range. A negative y_axis uses the current value of SetPlotYAxis (ImPlotYAxis_1 initially).
|
||||
IMPLOT_API ImPlotLimits GetPlotLimits(ImPlotYAxis 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);
|
||||
IMPLOT_API ImPlotLimits GetPlotQuery(ImPlotYAxis y_axis = IMPLOT_AUTO);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Plot Tools
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The following functions MUST be called between Begin/EndPlot!
|
||||
|
||||
// Shows an annotation callout at a chosen point.
|
||||
IMPLOT_API void Annotate(double x, double y, const ImVec2& pix_offset, const char* fmt, ...) IM_FMTARGS(4);
|
||||
IMPLOT_API void Annotate(double x, double y, const ImVec2& pix_offset, const ImVec4& color, const char* fmt, ...) IM_FMTARGS(5);
|
||||
|
@ -488,6 +528,12 @@ IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label
|
|||
// Legend Utils and Tools
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The following functions MUST be called between Begin/EndPlot!
|
||||
|
||||
// Set the location of the current plot's legend.
|
||||
IMPLOT_API void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation = ImPlotOrientation_Vertical, bool outside = false);
|
||||
// Set the locaton of the current plot's mouse position text (default = South|East).
|
||||
IMPLOT_API void SetMousePosLocation(ImPlotLocation location);
|
||||
// Returns true if a plot item legend entry is hovered.
|
||||
IMPLOT_API bool IsLegendEntryHovered(const char* label_id);
|
||||
// Begin a drag and drop source from a legend entry. The only supported flag is SourceNoPreviewTooltip
|
||||
|
|
|
@ -350,11 +350,13 @@ void ShowDemoWindow(bool* p_open) {
|
|||
ImVec2(-1,0), 0, 0, horz ? ImPlotAxisFlags_Invert : 0))
|
||||
{
|
||||
if (horz) {
|
||||
ImPlot::SetLegendLocation(ImPlotLocation_West, ImPlotOrientation_Vertical);
|
||||
ImPlot::PlotBarsH("Midterm Exam", midtm, 10, 0.2, -0.2);
|
||||
ImPlot::PlotBarsH("Final Exam", final, 10, 0.2, 0);
|
||||
ImPlot::PlotBarsH("Course Grade", grade, 10, 0.2, 0.2);
|
||||
}
|
||||
else {
|
||||
ImPlot::SetLegendLocation(ImPlotLocation_South, ImPlotOrientation_Horizontal);
|
||||
ImPlot::PlotBars("Midterm Exam", midtm, 10, 0.2, -0.2);
|
||||
ImPlot::PlotBars("Final Exam", final, 10, 0.2, 0);
|
||||
ImPlot::PlotBars("Course Grade", grade, 10, 0.2, 0.2);
|
||||
|
@ -686,11 +688,11 @@ void ShowDemoWindow(bool* p_open) {
|
|||
ImPlot::PlotLine("f(x) = x", xs, xs, 1001);
|
||||
ImPlot::PlotLine("f(x) = sin(x)*3+1", xs, ys1, 1001);
|
||||
if (y2_axis) {
|
||||
ImPlot::SetPlotYAxis(1);
|
||||
ImPlot::SetPlotYAxis(ImPlotYAxis_2);
|
||||
ImPlot::PlotLine("f(x) = cos(x)*.2+.5 (Y2)", xs, ys2, 1001);
|
||||
}
|
||||
if (y3_axis) {
|
||||
ImPlot::SetPlotYAxis(2);
|
||||
ImPlot::SetPlotYAxis(ImPlotYAxis_3);
|
||||
ImPlot::PlotLine("f(x) = sin(x+.5)*100+200 (Y3)", xs2, ys3, 1001);
|
||||
}
|
||||
ImPlot::EndPlot();
|
||||
|
@ -797,6 +799,41 @@ void ShowDemoWindow(bool* p_open) {
|
|||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
if (ImGui::CollapsingHeader("Legend")) {
|
||||
static bool n = false; static bool s = false; static bool w = false; static bool e = true;
|
||||
static bool h = false; static bool o = true;
|
||||
|
||||
ImGui::Checkbox("North", &n); ImGui::SameLine();
|
||||
ImGui::Checkbox("South", &s); ImGui::SameLine();
|
||||
ImGui::Checkbox("West", &w); ImGui::SameLine();
|
||||
ImGui::Checkbox("East", &e); ImGui::SameLine();
|
||||
ImGui::Checkbox("Horizontal", &h); ImGui::SameLine();
|
||||
ImGui::Checkbox("Outside", &o);
|
||||
|
||||
ImPlotLocation loc = 0;
|
||||
loc = n ? loc | ImPlotLocation_North : loc;
|
||||
loc = s ? loc | ImPlotLocation_South : loc;
|
||||
loc = w ? loc | ImPlotLocation_West : loc;
|
||||
loc = e ? loc | ImPlotLocation_East : loc;
|
||||
|
||||
ImGui::SliderFloat2("LegendPadding", (float*)&GetStyle().LegendPadding, 0.0f, 20.0f, "%.0f");
|
||||
ImGui::SliderFloat2("LegendInnerPadding", (float*)&GetStyle().LegendInnerPadding, 0.0f, 10.0f, "%.0f");
|
||||
ImGui::SliderFloat2("LegendSpacing", (float*)&GetStyle().LegendSpacing, 0.0f, 5.0f, "%.0f");
|
||||
|
||||
if (ImPlot::BeginPlot("##Legend","x","y",ImVec2(-1,0))) {
|
||||
ImPlot::SetLegendLocation(loc, h ? ImPlotOrientation_Horizontal : ImPlotOrientation_Vertical, o);
|
||||
static MyImPlot::WaveData data1(0.001, 0.2, 2, 0.75);
|
||||
static MyImPlot::WaveData data2(0.001, 0.2, 4, 0.25);
|
||||
static MyImPlot::WaveData data3(0.001, 0.2, 6, 0.5);
|
||||
ImPlot::PlotLineG("Item 1", MyImPlot::SineWave, &data1, 1000); // "Item 1" added to legend
|
||||
ImPlot::PlotLineG("Item 2##IDText", MyImPlot::SawWave, &data2, 1000); // "Item 2" added to legend, text after ## used for ID only
|
||||
ImPlot::PlotLineG("##NotDisplayed", MyImPlot::SawWave, &data3, 1000); // plotted, but not added to legend
|
||||
ImPlot::PlotLineG("Item 3", MyImPlot::SineWave, &data1, 1000); // "Item 3" added to legend
|
||||
ImPlot::PlotLineG("Item 3", MyImPlot::SawWave, &data2, 1000); // combined with previous "Item 3"
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
if (ImGui::CollapsingHeader("Drag Lines and Points")) {
|
||||
ImGui::BulletText("Click and drag the horizontal and vertical lines.");
|
||||
static double x1 = 0.2;
|
||||
|
@ -817,7 +854,7 @@ void ShowDemoWindow(bool* p_open) {
|
|||
ys[i] = (y1+y2)/2+abs(y2-y1)/2*sin(f*i/10);
|
||||
}
|
||||
ImPlot::PlotLine("Interactive Data", xs, ys, 1000);
|
||||
ImPlot::SetPlotYAxis(1);
|
||||
ImPlot::SetPlotYAxis(ImPlotYAxis_2);
|
||||
ImPlot::DragLineY("f",&f,show_labels,ImVec4(1,0.5f,1,1));
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
|
@ -1402,7 +1439,7 @@ void StyleSeaborn() {
|
|||
style.PlotPadding = ImVec2(12,12);
|
||||
style.LabelPadding = ImVec2(5,5);
|
||||
style.LegendPadding = ImVec2(5,5);
|
||||
style.InfoPadding = ImVec2(5,5);
|
||||
style.MousePosPadding = ImVec2(5,5);
|
||||
style.PlotMinSize = ImVec2(300,225);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ struct ImPlotAxis;
|
|||
struct ImPlotAxisState;
|
||||
struct ImPlotAxisColor;
|
||||
struct ImPlotItem;
|
||||
struct ImPlotLegend;
|
||||
struct ImPlotPlot;
|
||||
struct ImPlotNextPlotData;
|
||||
|
||||
|
@ -67,10 +68,6 @@ extern IMPLOT_API ImPlotContext* GImPlot; // Current implicit context pointer
|
|||
// Constants can be changed unless stated otherwise. We may move some of these
|
||||
// to ImPlotStyleVar_ over time.
|
||||
|
||||
// Default plot frame width when requested width is auto (i.e. 0). This is not the plot area width!
|
||||
#define IMPLOT_DEFAULT_W 400
|
||||
// Default plot frame height when requested height is auto (i.e. 0). This is not the plot area height!
|
||||
#define IMPLOT_DEFAULT_H 300
|
||||
// The maximum number of supported y-axes (DO NOT CHANGE THIS)
|
||||
#define IMPLOT_Y_AXES 3
|
||||
// The number of times to subdivided grid divisions (best if a multiple of 1, 2, and 5)
|
||||
|
@ -158,18 +155,11 @@ struct ImPlotPointArray {
|
|||
// [SECTION] ImPlot Enums
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef int ImPlotDirection; // -> enum ImPlotDirection_
|
||||
typedef int ImPlotScale; // -> enum ImPlotScale_
|
||||
typedef int ImPlotTimeUnit; // -> enum ImPlotTimeUnit_
|
||||
typedef int ImPlotDateFmt; // -> enum ImPlotDateFmt_
|
||||
typedef int ImPlotTimeFmt; // -> enum ImPlotTimeFmt_
|
||||
|
||||
// Axis direction
|
||||
enum ImPlotDirection_ {
|
||||
ImPlotDirection_Horizontal, // left/right
|
||||
ImPlotDirection_Vertical // up/down
|
||||
};
|
||||
|
||||
// XY axes scaling combinations
|
||||
enum ImPlotScale_ {
|
||||
ImPlotScale_LinLin, // linear x, linear y
|
||||
|
@ -195,7 +185,7 @@ enum ImPlotDateFmt_ { // default [ ISO 8601 ]
|
|||
ImPlotDateFmt_DayMo, // 10/3 [ --10-03 ]
|
||||
ImPlotDateFmt_DayMoYr, // 10/3/91 [ 1991-10-03 ]
|
||||
ImPlotDateFmt_MoYr, // Oct 1991 [ 1991-10 ]
|
||||
ImPlotDateFmt_Mo, // Oct [ --10-01 ]
|
||||
ImPlotDateFmt_Mo, // Oct [ --10 ]
|
||||
ImPlotDateFmt_Yr // 1991 [ 1991 ]
|
||||
};
|
||||
|
||||
|
@ -392,7 +382,7 @@ struct ImPlotAxis
|
|||
ImPlotAxisFlags Flags;
|
||||
ImPlotAxisFlags PreviousFlags;
|
||||
ImPlotRange Range;
|
||||
ImPlotDirection Direction;
|
||||
ImPlotOrientation Direction;
|
||||
bool Dragging;
|
||||
bool HoveredExt;
|
||||
bool HoveredTot;
|
||||
|
@ -524,6 +514,20 @@ struct ImPlotItem
|
|||
~ImPlotItem() { ID = 0; }
|
||||
};
|
||||
|
||||
// Holds Legend state labels and item references
|
||||
struct ImPlotLegend
|
||||
{
|
||||
ImPlotPlot* Plot;
|
||||
ImVector<int> Indices;
|
||||
ImGuiTextBuffer Labels;
|
||||
|
||||
ImPlotLegend(ImPlotPlot* plot) { Plot = plot; }
|
||||
void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); }
|
||||
int Count() const { return Indices.size(); }
|
||||
ImPlotItem* GetItem(int i);
|
||||
const char* GetLabel(int i);
|
||||
};
|
||||
|
||||
// Holds Plot state information that must persist after EndPlot
|
||||
struct ImPlotPlot
|
||||
{
|
||||
|
@ -531,27 +535,37 @@ struct ImPlotPlot
|
|||
ImPlotFlags PreviousFlags;
|
||||
ImPlotAxis XAxis;
|
||||
ImPlotAxis YAxis[IMPLOT_Y_AXES];
|
||||
ImPlotLegend Legend;
|
||||
ImPool<ImPlotItem> Items;
|
||||
ImVec2 SelectStart;
|
||||
ImVec2 QueryStart;
|
||||
ImRect QueryRect;
|
||||
ImRect BB_Legend;
|
||||
bool Selecting;
|
||||
bool Querying;
|
||||
bool Queried;
|
||||
bool DraggingQuery;
|
||||
bool LegendHovered;
|
||||
bool LegendOutside;
|
||||
bool LegendFlipSide;
|
||||
int ColormapIdx;
|
||||
int CurrentYAxis;
|
||||
ImPlotLocation MousePosLocation;
|
||||
ImPlotLocation LegendLocation;
|
||||
ImPlotOrientation LegendOrientation;
|
||||
|
||||
ImPlotPlot() {
|
||||
ImPlotPlot() : Legend(this) {
|
||||
Flags = PreviousFlags = ImPlotFlags_None;
|
||||
XAxis.Direction = ImPlotDirection_Horizontal;
|
||||
XAxis.Direction = ImPlotOrientation_Horizontal;
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; ++i)
|
||||
YAxis[i].Direction = ImPlotDirection_Vertical;
|
||||
YAxis[i].Direction = ImPlotOrientation_Vertical;
|
||||
SelectStart = QueryStart = ImVec2(0,0);
|
||||
Selecting = Querying = Queried = DraggingQuery = false;
|
||||
Selecting = Querying = Queried = DraggingQuery = LegendHovered = LegendOutside = LegendFlipSide = false;
|
||||
ColormapIdx = CurrentYAxis = 0;
|
||||
LegendLocation = ImPlotLocation_North | ImPlotLocation_West;
|
||||
LegendOrientation = ImPlotOrientation_Vertical;
|
||||
MousePosLocation = ImPlotLocation_South | ImPlotLocation_East;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Temporary data storage for upcoming plot
|
||||
|
@ -622,14 +636,13 @@ struct ImPlotContext {
|
|||
ImPlotItem* CurrentItem;
|
||||
ImPlotItem* PreviousItem;
|
||||
|
||||
// Legend
|
||||
ImVector<int> LegendIndices;
|
||||
ImGuiTextBuffer LegendLabels;
|
||||
|
||||
// Bounding Boxes
|
||||
ImRect BB_Frame;
|
||||
ImRect BB_Canvas;
|
||||
ImRect BB_Plot;
|
||||
ImRect BB_Axes;
|
||||
ImRect BB_X;
|
||||
ImRect BB_Y[IMPLOT_Y_AXES];
|
||||
|
||||
// Axis States
|
||||
ImPlotAxisColor Col_X;
|
||||
|
@ -743,15 +756,11 @@ IMPLOT_API bool BeginItem(const char* label_id, ImPlotCol recolor_from = -1);
|
|||
// Ends an item (call only if BeginItem returns true). Pops PlotClipRect.
|
||||
IMPLOT_API void EndItem();
|
||||
|
||||
// Register or get an existing item from the current plot
|
||||
// Register or get an existing item from the current plot.
|
||||
IMPLOT_API ImPlotItem* RegisterOrGetItem(const char* label_id, bool* just_created = NULL);
|
||||
// Get the ith plot item from the current plot
|
||||
IMPLOT_API ImPlotItem* GetItem(int i);
|
||||
// Get a plot item from the current plot
|
||||
// Get a plot item from the current plot.
|
||||
IMPLOT_API ImPlotItem* GetItem(const char* label_id);
|
||||
// Gets a plot item from a specific plot
|
||||
IMPLOT_API ImPlotItem* GetItem(const char* plot_title, const char* item_label_id);
|
||||
// Gets the current item
|
||||
// Gets the current item.
|
||||
IMPLOT_API ImPlotItem* GetCurrentItem();
|
||||
// Busts the cache for every item for every plot in the current context.
|
||||
IMPLOT_API void BustItemCache();
|
||||
|
@ -791,10 +800,14 @@ IMPLOT_API void ShowAxisContextMenu(ImPlotAxisState& state, bool time_allowed =
|
|||
// [SECTION] Legend Utils
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Returns the number of entries in the current legend
|
||||
IMPLOT_API int GetLegendCount();
|
||||
// Gets the ith entry string for the current legend
|
||||
IMPLOT_API const char* GetLegendLabel(int i);
|
||||
// Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
|
||||
IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0));
|
||||
// Calculates the bounding box size of a legend
|
||||
IMPLOT_API ImVec2 CalcLegendSize(ImPlotLegend& legend, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orientation);
|
||||
// Renders legend entries into a bounding box
|
||||
IMPLOT_API void ShowLegendEntries(ImPlotLegend& legend, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orientation, ImDrawList& DrawList);
|
||||
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window!).
|
||||
IMPLOT_API void ShowAltLegend(const char* title_id, ImPlotOrientation orientation = ImPlotOrientation_Vertical, const ImVec2 size = ImVec2(0,0), bool interactable = true);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Tick Utils
|
||||
|
|
|
@ -60,9 +60,9 @@ ImPlotItem* RegisterOrGetItem(const char* label_id, bool* just_created) {
|
|||
int idx = gp.CurrentPlot->Items.GetIndex(item);
|
||||
item->ID = id;
|
||||
if (ImGui::FindRenderedTextEnd(label_id, NULL) != label_id) {
|
||||
gp.LegendIndices.push_back(idx);
|
||||
item->NameOffset = gp.LegendLabels.size();
|
||||
gp.LegendLabels.append(label_id, label_id + strlen(label_id) + 1);
|
||||
gp.CurrentPlot->Legend.Indices.push_back(idx);
|
||||
item->NameOffset = gp.CurrentPlot->Legend.Labels.size();
|
||||
gp.CurrentPlot->Legend.Labels.append(label_id, label_id + strlen(label_id) + 1);
|
||||
}
|
||||
else {
|
||||
item->Show = true;
|
||||
|
@ -72,26 +72,12 @@ ImPlotItem* RegisterOrGetItem(const char* label_id, bool* just_created) {
|
|||
return item;
|
||||
}
|
||||
|
||||
ImPlotItem* GetItem(int i) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
return gp.CurrentPlot->Items.GetByIndex(gp.LegendIndices[i]);
|
||||
}
|
||||
|
||||
ImPlotItem* GetItem(const char* label_id) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImGuiID id = ImGui::GetID(label_id);
|
||||
return gp.CurrentPlot->Items.GetByKey(id);
|
||||
}
|
||||
|
||||
ImPlotItem* GetItem(const char* plot_title, const char* item_label_id) {
|
||||
ImPlotPlot* plot = GetPlot(plot_title);
|
||||
if (plot) {
|
||||
ImGuiID id = ImGui::GetID(item_label_id);
|
||||
return plot->Items.GetByKey(id);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ImPlotItem* GetCurrentItem() {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
return gp.CurrentItem;
|
||||
|
@ -1756,4 +1742,13 @@ void PlotText(const char* text, double x, double y, bool vertical, const ImVec2&
|
|||
PopPlotClipRect();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PLOT DUMMY
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PlotDummy(const char* label_id) {
|
||||
if (BeginItem(label_id, ImPlotCol_Line))
|
||||
EndItem();
|
||||
}
|
||||
|
||||
} // namespace ImPlot
|
Loading…
Reference in New Issue
Block a user