mirror of
https://github.com/gwm17/implot.git
synced 2025-01-30 19:08:51 -05:00
code cleanup, define magic numbers, add minimum plot size constraint, misc improvements to tick mark labels
This commit is contained in:
parent
0926677b52
commit
53c867f414
242
implot.cpp
242
implot.cpp
|
@ -231,7 +231,7 @@ void Reset(ImPlotContext* ctx) {
|
|||
ctx->FitX = false;
|
||||
ctx->ExtentsX.Min = HUGE_VAL;
|
||||
ctx->ExtentsX.Max = -HUGE_VAL;
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
ctx->ExtentsY[i].Min = HUGE_VAL;
|
||||
ctx->ExtentsY[i].Max = -HUGE_VAL;
|
||||
ctx->FitY[i] = false;
|
||||
|
@ -278,7 +278,7 @@ void FitPoint(const ImPlotPoint& p) {
|
|||
void UpdateTransformCache() {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
// get pixels for transforms
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
gp.PixelRange[i] = ImRect(ImHasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_Invert) ? gp.BB_Plot.Max.x : gp.BB_Plot.Min.x,
|
||||
ImHasFlag(gp.CurrentPlot->YAxis[i].Flags, ImPlotAxisFlags_Invert) ? gp.BB_Plot.Min.y : gp.BB_Plot.Max.y,
|
||||
ImHasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_Invert) ? gp.BB_Plot.Min.x : gp.BB_Plot.Max.x,
|
||||
|
@ -287,7 +287,7 @@ void UpdateTransformCache() {
|
|||
gp.My[i] = (gp.PixelRange[i].Max.y - gp.PixelRange[i].Min.y) / gp.CurrentPlot->YAxis[i].Range.Size();
|
||||
}
|
||||
gp.LogDenX = ImLog10(gp.CurrentPlot->XAxis.Range.Max / gp.CurrentPlot->XAxis.Range.Min);
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
gp.LogDenY[i] = ImLog10(gp.CurrentPlot->YAxis[i].Range.Max / gp.CurrentPlot->YAxis[i].Range.Min);
|
||||
}
|
||||
gp.Mx = (gp.PixelRange[0].Max.x - gp.PixelRange[0].Min.x) / gp.CurrentPlot->XAxis.Range.Size();
|
||||
|
@ -416,7 +416,7 @@ void AddDefaultTicks(const ImPlotRange& range, int nMajor, int nMinor, bool logs
|
|||
double major2 = ImPow(10, (double)(e + 1));
|
||||
double interval = (major2 - major1) / 9;
|
||||
if (major1 >= (range.Min - DBL_EPSILON) && major1 <= (range.Max + DBL_EPSILON))
|
||||
out.push_back(ImPlotTick(major1, true));
|
||||
out.push_back(ImPlotTick(major1, true, true));
|
||||
for (int i = 1; i < 9; ++i) {
|
||||
double minor = major1 + i * interval;
|
||||
if (minor >= (range.Min - DBL_EPSILON) && minor <= (range.Max + DBL_EPSILON))
|
||||
|
@ -425,17 +425,17 @@ void AddDefaultTicks(const ImPlotRange& range, int nMajor, int nMinor, bool logs
|
|||
}
|
||||
}
|
||||
else {
|
||||
const double nice_range = NiceNum(range.Size() * 0.99, 0);
|
||||
const double interval = NiceNum(nice_range / (nMajor - 1), 1);
|
||||
const double nice_range = NiceNum(range.Size() * 0.99, false);
|
||||
const double interval = NiceNum(nice_range / (nMajor - 1), true);
|
||||
const double graphmin = floor(range.Min / interval) * interval;
|
||||
const double graphmax = ceil(range.Max / interval) * interval;
|
||||
for (double major = graphmin; major < graphmax + 0.5 * interval; major += interval) {
|
||||
if (major >= range.Min && major <= range.Max)
|
||||
out.push_back(ImPlotTick(major, true));
|
||||
if (range.Contains(major))
|
||||
out.push_back(ImPlotTick(major, true, true));
|
||||
for (int i = 1; i < nMinor; ++i) {
|
||||
double minor = major + i * interval / nMinor;
|
||||
if (minor >= range.Min && minor <= range.Max)
|
||||
out.push_back(ImPlotTick(minor, false));
|
||||
if (range.Contains(minor))
|
||||
out.push_back(ImPlotTick(minor, false, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -443,11 +443,11 @@ void AddDefaultTicks(const ImPlotRange& range, int nMajor, int nMinor, bool logs
|
|||
|
||||
void AddCustomTicks(const double* values, const char** labels, int n, ImVector<ImPlotTick>& ticks, ImGuiTextBuffer& buffer) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
ImPlotTick tick(values[i],false);
|
||||
tick.TextOffset = buffer.size();
|
||||
ImPlotTick tick(values[i],false, true);
|
||||
tick.BufferOffset = buffer.size();
|
||||
if (labels != NULL) {
|
||||
buffer.append(labels[i], labels[i] + strlen(labels[i]) + 1);
|
||||
tick.Size = ImGui::CalcTextSize(labels[i]);
|
||||
tick.LabelSize = ImGui::CalcTextSize(labels[i]);
|
||||
tick.Labeled = true;
|
||||
}
|
||||
ticks.push_back(tick);
|
||||
|
@ -458,26 +458,40 @@ void LabelTicks(ImVector<ImPlotTick> &ticks, bool scientific, ImGuiTextBuffer& b
|
|||
char temp[32];
|
||||
for (int t = 0; t < ticks.Size; t++) {
|
||||
ImPlotTick *tk = &ticks[t];
|
||||
if (tk->RenderLabel && !tk->Labeled) {
|
||||
tk->TextOffset = buffer.size();
|
||||
if (tk->ShowLabel && !tk->Labeled) {
|
||||
tk->BufferOffset = buffer.size();
|
||||
if (scientific)
|
||||
sprintf(temp, "%.0e", tk->PlotPos);
|
||||
else
|
||||
sprintf(temp, "%.10g", tk->PlotPos);
|
||||
buffer.append(temp, temp + strlen(temp) + 1);
|
||||
tk->Size = ImGui::CalcTextSize(buffer.Buf.Data + tk->TextOffset);
|
||||
tk->LabelSize = ImGui::CalcTextSize(buffer.Buf.Data + tk->BufferOffset);
|
||||
tk->Labeled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float MaxTickLabelWidth(ImVector<ImPlotTick>& ticks) {
|
||||
float MaxTickLabelWidth(const ImVector<ImPlotTick>& ticks) {
|
||||
float w = 0;
|
||||
for (int i = 0; i < ticks.Size; ++i)
|
||||
w = ticks[i].Size.x > w ? ticks[i].Size.x : w;
|
||||
w = (ticks[i].ShowLabel && ticks[i].LabelSize.x > w) ? ticks[i].LabelSize.x : w;
|
||||
return w;
|
||||
}
|
||||
|
||||
float SumTickLabelWidth(const ImVector<ImPlotTick>& ticks) {
|
||||
float sum = 0;
|
||||
for (int i = 0; i < ticks.Size; ++i)
|
||||
sum += ticks[i].ShowLabel ? ticks[i].LabelSize.x : 0;
|
||||
return sum;
|
||||
}
|
||||
|
||||
float SumTickLabelHeight(const ImVector<ImPlotTick>& ticks) {
|
||||
float sum = 0;
|
||||
for (int i = 0; i < ticks.Size; ++i)
|
||||
sum += ticks[i].ShowLabel ? ticks[i].LabelSize.y : 0;
|
||||
return sum;
|
||||
}
|
||||
|
||||
class YPadCalculator {
|
||||
public:
|
||||
YPadCalculator(const ImPlotAxisState* axis_states, const float* max_label_widths, float txt_off)
|
||||
|
@ -512,10 +526,11 @@ class YPadCalculator {
|
|||
|
||||
void UpdateAxisColor(int axis_flag, ImPlotAxisColor* col) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
const ImVec4 col_Axis = gp.Style.Colors[axis_flag].w == -1 ? ImGui::GetStyle().Colors[ImGuiCol_Text] * ImVec4(1, 1, 1, 0.25f) : gp.Style.Colors[axis_flag];
|
||||
col->Major = ImGui::GetColorU32(col_Axis);
|
||||
col->Minor = ImGui::GetColorU32(col_Axis * ImVec4(1, 1, 1, 0.25f));
|
||||
col->Txt = ImGui::GetColorU32(ImVec4(col_Axis.x, col_Axis.y, col_Axis.z, 1));
|
||||
const ImVec4 col_axis = gp.Style.Colors[axis_flag].w == -1 ? ImGui::GetStyle().Colors[ImGuiCol_Text] * ImVec4(1, 1, 1, 0.25f) : gp.Style.Colors[axis_flag];
|
||||
col->Major = ImGui::GetColorU32(col_axis);
|
||||
col->Minor = ImGui::GetColorU32(col_axis * ImVec4(1, 1, 1, 0.25f));
|
||||
col->MajTxt = ImGui::GetColorU32(ImVec4(col_axis.x, col_axis.y, col_axis.z, 1));
|
||||
col->MinTxt = ImGui::GetColorU32(ImVec4(col_axis.x, col_axis.y, col_axis.z, 0.8f));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -541,7 +556,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
const ImGuiIO & IO = ImGui::GetIO();
|
||||
|
||||
bool just_created = gp.Plots.GetByKey(ID) == NULL;
|
||||
gp.CurrentPlot = gp.Plots.GetOrAddByKey(ID);
|
||||
gp.CurrentPlot = gp.Plots.GetOrAddByKey(ID);
|
||||
ImPlotState &plot = *gp.CurrentPlot;
|
||||
|
||||
plot.CurrentYAxis = 0;
|
||||
|
@ -573,10 +588,8 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
plot.YAxis[2].PreviousFlags = y3_flags;
|
||||
|
||||
// capture scroll with a child region
|
||||
const float default_w = 400;
|
||||
const float default_h = 300;
|
||||
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoChild)) {
|
||||
ImGui::BeginChild(title, ImVec2(size.x == 0 ? default_w : size.x, size.y == 0 ? default_h : size.y));
|
||||
ImGui::BeginChild(title, ImVec2(size.x == 0 ? IMPLOT_DEFAULT_W : size.x, size.y == 0 ? IMPLOT_DEFAULT_H : size.y));
|
||||
Window = ImGui::GetCurrentWindow();
|
||||
Window->ScrollMax.y = 1.0f;
|
||||
gp.ChildWindowMade = true;
|
||||
|
@ -590,16 +603,14 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
// NextPlotData -----------------------------------------------------------
|
||||
|
||||
if (gp.NextPlotData.HasXRange) {
|
||||
if (just_created || gp.NextPlotData.XRangeCond == ImGuiCond_Always)
|
||||
{
|
||||
if (just_created || gp.NextPlotData.XRangeCond == ImGuiCond_Always) {
|
||||
plot.XAxis.Range = gp.NextPlotData.X;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (gp.NextPlotData.HasYRange[i]) {
|
||||
if (just_created || gp.NextPlotData.YRangeCond[i] == ImGuiCond_Always)
|
||||
{
|
||||
if (just_created || gp.NextPlotData.YRangeCond[i] == ImGuiCond_Always) {
|
||||
plot.YAxis[i].Range = gp.NextPlotData.Y[i];
|
||||
}
|
||||
}
|
||||
|
@ -609,9 +620,9 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
gp.X = ImPlotAxisState(&plot.XAxis, gp.NextPlotData.HasXRange, gp.NextPlotData.XRangeCond, true, 0);
|
||||
gp.Y[0] = ImPlotAxisState(&plot.YAxis[0], gp.NextPlotData.HasYRange[0], gp.NextPlotData.YRangeCond[0], true, 0);
|
||||
gp.Y[1] = ImPlotAxisState(&plot.YAxis[1], gp.NextPlotData.HasYRange[1], gp.NextPlotData.YRangeCond[1],
|
||||
ImHasFlag(plot.Flags, ImPlotFlags_YAxis2), gp.Y[0].PresentSoFar);
|
||||
ImHasFlag(plot.Flags, ImPlotFlags_YAxis2), gp.Y[0].PresentSoFar);
|
||||
gp.Y[2] = ImPlotAxisState(&plot.YAxis[2], gp.NextPlotData.HasYRange[2], gp.NextPlotData.YRangeCond[2],
|
||||
ImHasFlag(plot.Flags, ImPlotFlags_YAxis3), gp.Y[1].PresentSoFar);
|
||||
ImHasFlag(plot.Flags, ImPlotFlags_YAxis3), gp.Y[1].PresentSoFar);
|
||||
|
||||
gp.LockPlot = gp.X.Lock && gp.Y[0].Lock && gp.Y[1].Lock && gp.Y[2].Lock;
|
||||
|
||||
|
@ -619,7 +630,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
|
||||
plot.XAxis.Range.Min = ConstrainNan(ConstrainInf(plot.XAxis.Range.Min));
|
||||
plot.XAxis.Range.Max = ConstrainNan(ConstrainInf(plot.XAxis.Range.Max));
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
plot.YAxis[i].Range.Min = ConstrainNan(ConstrainInf(plot.YAxis[i].Range.Min));
|
||||
plot.YAxis[i].Range.Max = ConstrainNan(ConstrainInf(plot.YAxis[i].Range.Max));
|
||||
}
|
||||
|
@ -628,7 +639,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
plot.XAxis.Range.Min = ConstrainLog(plot.XAxis.Range.Min);
|
||||
if (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LogScale))
|
||||
plot.XAxis.Range.Max = ConstrainLog(plot.XAxis.Range.Max);
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LogScale))
|
||||
plot.YAxis[i].Range.Min = ConstrainLog(plot.YAxis[i].Range.Min);
|
||||
if (ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LogScale))
|
||||
|
@ -637,7 +648,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
|
||||
if (plot.XAxis.Range.Max <= plot.XAxis.Range.Min)
|
||||
plot.XAxis.Range.Max = plot.XAxis.Range.Min + DBL_EPSILON;
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (plot.YAxis[i].Range.Max <= plot.YAxis[i].Range.Min)
|
||||
plot.YAxis[i].Range.Max = plot.YAxis[i].Range.Min + DBL_EPSILON;
|
||||
}
|
||||
|
@ -663,7 +674,11 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
// BB AND HOVER -----------------------------------------------------------
|
||||
|
||||
// frame
|
||||
const ImVec2 frame_size = ImGui::CalcItemSize(size, default_w, default_h);
|
||||
ImVec2 frame_size = ImGui::CalcItemSize(size, IMPLOT_DEFAULT_W, IMPLOT_DEFAULT_H);
|
||||
if (frame_size.x < IMPLOT_MIN_W && size.x < 0.0f)
|
||||
frame_size.x = IMPLOT_MIN_W;
|
||||
if (frame_size.y < IMPLOT_MIN_H && size.y < 0.0f)
|
||||
frame_size.y = IMPLOT_MIN_H;
|
||||
gp.BB_Frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + frame_size);
|
||||
ImGui::ItemSize(gp.BB_Frame);
|
||||
if (!ImGui::ItemAdd(gp.BB_Frame, 0, &gp.BB_Frame)) {
|
||||
|
@ -678,15 +693,15 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
|
||||
// adaptive divisions
|
||||
int x_divisions = ImMax(2, (int)IM_ROUND(0.003 * gp.BB_Canvas.GetWidth()));
|
||||
int y_divisions[MAX_Y_AXES];
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
int y_divisions[IMPLOT_Y_AXES];
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
y_divisions[i] = ImMax(2, (int)IM_ROUND(0.003 * gp.BB_Canvas.GetHeight()));
|
||||
}
|
||||
|
||||
gp.RenderX = (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_GridLines) ||
|
||||
ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickMarks) ||
|
||||
ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels)) && x_divisions > 1;
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickMarks) ||
|
||||
ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels)) && x_divisions > 1;
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
gp.RenderY[i] =
|
||||
gp.Y[i].Present &&
|
||||
(ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_GridLines) ||
|
||||
|
@ -695,10 +710,10 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
}
|
||||
// get ticks
|
||||
if (gp.RenderX && gp.NextPlotData.ShowDefaultTicksX)
|
||||
AddDefaultTicks(plot.XAxis.Range, x_divisions, 10, ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LogScale), gp.XTicks);
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
AddDefaultTicks(plot.XAxis.Range, x_divisions, IMPLOT_SUB_DIV, ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LogScale), gp.XTicks);
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (gp.RenderY[i] && gp.NextPlotData.ShowDefaultTicksY[i]) {
|
||||
AddDefaultTicks(plot.YAxis[i].Range, y_divisions[i], 10, ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LogScale), gp.YTicks[i]);
|
||||
AddDefaultTicks(plot.YAxis[i].Range, y_divisions[i], IMPLOT_SUB_DIV, ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LogScale), gp.YTicks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -706,8 +721,8 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
if (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels))
|
||||
LabelTicks(gp.XTicks, ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_Scientific), gp.XTickLabels);
|
||||
|
||||
float max_label_width[MAX_Y_AXES] = {};
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
float max_label_width[IMPLOT_Y_AXES] = {};
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (gp.Y[i].Present && ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickLabels)) {
|
||||
LabelTicks(gp.YTicks[i], ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_Scientific), gp.YTickLabels[i]);
|
||||
max_label_width[i] = MaxTickLabelWidth(gp.YTicks[i]);
|
||||
|
@ -716,12 +731,11 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
|
||||
// grid bb
|
||||
const ImVec2 title_size = ImGui::CalcTextSize(title, NULL, true);
|
||||
const float txt_off = 5;
|
||||
const float txt_height = ImGui::GetTextLineHeight();
|
||||
const float pad_top = title_size.x > 0.0f ? txt_height + txt_off : 0;
|
||||
const float pad_bot = (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels) ? txt_height + txt_off : 0) + (x_label ? txt_height + txt_off : 0);
|
||||
YPadCalculator y_axis_pad(gp.Y, max_label_width, txt_off);
|
||||
const float pad_left = y_axis_pad(0) + (y_label ? txt_height + txt_off : 0);
|
||||
const float pad_top = title_size.x > 0.0f ? txt_height + IMPLOT_LABEL_PAD : 0;
|
||||
const float pad_bot = (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels) ? txt_height + IMPLOT_LABEL_PAD : 0) + (x_label ? txt_height + IMPLOT_LABEL_PAD : 0);
|
||||
YPadCalculator y_axis_pad(gp.Y, max_label_width, IMPLOT_LABEL_PAD);
|
||||
const float pad_left = y_axis_pad(0) + (y_label ? txt_height + IMPLOT_LABEL_PAD : 0);
|
||||
const float pad_right = y_axis_pad(1) + y_axis_pad(2);
|
||||
gp.BB_Plot = ImRect(gp.BB_Canvas.Min + ImVec2(pad_left, pad_top), gp.BB_Canvas.Max - ImVec2(pad_right, pad_bot));
|
||||
gp.Hov_Plot = gp.BB_Plot.Contains(IO.MousePos);
|
||||
|
@ -742,7 +756,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
gp.BB_Plot.Max.x :
|
||||
(gp.AxisLabelReference[1] + y_axis_pad(1) + 6);
|
||||
|
||||
ImRect yAxisRegion_bb[MAX_Y_AXES];
|
||||
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 + 6, gp.BB_Plot.Max.y - 10));
|
||||
// The auxiliary y axes are off to the right of the BB grid.
|
||||
yAxisRegion_bb[1] = ImRect(ImVec2(gp.BB_Plot.Max.x - 6, gp.BB_Plot.Min.y), gp.BB_Plot.Max + ImVec2(y_axis_pad(1), -10));
|
||||
|
@ -793,9 +807,9 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
plot.XAxis.Dragging = false;
|
||||
G.IO.MouseDragMaxDistanceSqr[0] = 0;
|
||||
}
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (plot.YAxis[i].Dragging && (IO.MouseReleased[gp.InputMap.PanButton] || !IO.MouseDown[gp.InputMap.PanButton])) {
|
||||
plot.YAxis[i].Dragging = false;
|
||||
plot.YAxis[i].Dragging = false;
|
||||
G.IO.MouseDragMaxDistanceSqr[0] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -812,7 +826,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
if (!gp.X.LockMax)
|
||||
plot.XAxis.Range.Max = gp.X.Invert ? plot_tl.x : plot_br.x;
|
||||
}
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (!gp.Y[i].Lock && plot.YAxis[i].Dragging) {
|
||||
ImPlotPoint plot_tl = PixelsToPlot(gp.BB_Plot.Min - IO.MouseDelta, i);
|
||||
ImPlotPoint plot_br = PixelsToPlot(gp.BB_Plot.Max - IO.MouseDelta, i);
|
||||
|
@ -828,7 +842,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
if (!gp.X.Lock && plot.XAxis.Dragging) {
|
||||
direction |= (1 << 1);
|
||||
}
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (!gp.Y[i].Present) { continue; }
|
||||
if (!gp.Y[i].Lock && plot.YAxis[i].Dragging) {
|
||||
direction |= (1 << 2);
|
||||
|
@ -836,18 +850,14 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
}
|
||||
}
|
||||
if (IO.MouseDragMaxDistanceSqr[0] > 5) {
|
||||
if (direction == 0) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed);
|
||||
}
|
||||
else if (direction == (1 << 1)) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||
}
|
||||
else if (direction == (1 << 2)) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
||||
}
|
||||
else {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
|
||||
}
|
||||
if (direction == 0)
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed);
|
||||
else if (direction == (1 << 1))
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||
else if (direction == (1 << 2))
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
||||
else
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
|
||||
}
|
||||
}
|
||||
// start drag
|
||||
|
@ -855,7 +865,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
if (plot.XAxis.Hovered) {
|
||||
plot.XAxis.Dragging = true;
|
||||
}
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (plot.YAxis[i].Hovered) {
|
||||
plot.YAxis[i].Dragging = true;
|
||||
}
|
||||
|
@ -866,7 +876,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
|
||||
if (gp.Hov_Frame && (plot.XAxis.Hovered || any_hov_y_axis_region) && IO.MouseWheel != 0) {
|
||||
UpdateTransformCache();
|
||||
float zoom_rate = 0.1f;
|
||||
float zoom_rate = IMPLOT_ZOOM_RATE;
|
||||
if (IO.MouseWheel > 0)
|
||||
zoom_rate = (-zoom_rate) / (1.0f + (2.0f * zoom_rate));
|
||||
float tx = ImRemap(IO.MousePos.x, gp.BB_Plot.Min.x, gp.BB_Plot.Max.x, 0.0f, 1.0f);
|
||||
|
@ -881,7 +891,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
if (!gp.X.LockMax)
|
||||
plot.XAxis.Range.Max = gp.X.Invert ? plot_tl.x : plot_br.x;
|
||||
}
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (plot.YAxis[i].Hovered && !gp.Y[i].Lock) {
|
||||
ImPlotAxisScale axis_scale(i, tx, ty, zoom_rate);
|
||||
const ImPlotPoint& plot_tl = axis_scale.Min;
|
||||
|
@ -907,7 +917,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
plot.XAxis.Range.Min = ImMin(p1.x, p2.x);
|
||||
if (!gp.X.LockMax && IO.KeyMods != gp.InputMap.HorizontalMod)
|
||||
plot.XAxis.Range.Max = ImMax(p1.x, p2.x);
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
p1 = PixelsToPlot(plot.SelectStart, i);
|
||||
p2 = PixelsToPlot(IO.MousePos, i);
|
||||
if (!gp.Y[i].LockMin && IO.KeyMods != gp.InputMap.VerticalMod)
|
||||
|
@ -945,12 +955,10 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
// end query
|
||||
if (plot.Querying && (IO.MouseReleased[gp.InputMap.QueryButton] || IO.MouseReleased[gp.InputMap.BoxSelectButton])) {
|
||||
plot.Querying = false;
|
||||
if (plot.QueryRect.GetWidth() > 2 && plot.QueryRect.GetHeight() > 2) {
|
||||
plot.Queried = true;
|
||||
}
|
||||
else {
|
||||
plot.Queried = false;
|
||||
}
|
||||
if (plot.QueryRect.GetWidth() > 2 && plot.QueryRect.GetHeight() > 2)
|
||||
plot.Queried = true;
|
||||
else
|
||||
plot.Queried = false;
|
||||
}
|
||||
|
||||
// begin query
|
||||
|
@ -980,16 +988,14 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
if ( IO.MouseDoubleClicked[gp.InputMap.FitButton] && gp.Hov_Frame && (plot.XAxis.Hovered || any_hov_y_axis_region) && !hov_legend && !hov_query) {
|
||||
gp.FitThisFrame = true;
|
||||
gp.FitX = plot.XAxis.Hovered;
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
gp.FitY[i] = plot.YAxis[i].Hovered;
|
||||
}
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++)
|
||||
gp.FitY[i] = plot.YAxis[i].Hovered;
|
||||
}
|
||||
else {
|
||||
gp.FitThisFrame = false;
|
||||
gp.FitX = false;
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
gp.FitY[i] = false;
|
||||
}
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++)
|
||||
gp.FitY[i] = false;
|
||||
}
|
||||
|
||||
// FOCUS ------------------------------------------------------------------
|
||||
|
@ -1001,7 +1007,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
UpdateTransformCache();
|
||||
|
||||
// set mouse position
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
gp.LastMousePos[i] = PixelsToPlot(IO.MousePos, i);
|
||||
}
|
||||
|
||||
|
@ -1020,7 +1026,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
xt->PixelPos = PlotToPixels(xt->PlotPos, 0, 0).x;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (gp.RenderY[i]) {
|
||||
for (int t = 0; t < gp.YTicks[i].Size; t++) {
|
||||
ImPlotTick *yt = &gp.YTicks[i][t];
|
||||
|
@ -1037,7 +1043,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (gp.Y[i].Present && ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_GridLines)) {
|
||||
for (int t = 0; t < gp.YTicks[i].Size; t++) {
|
||||
ImPlotTick *yt = &gp.YTicks[i][t];
|
||||
|
@ -1058,8 +1064,8 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
ImGui::PushClipRect(gp.BB_Frame.Min, gp.BB_Frame.Max, true);
|
||||
for (int t = 0; t < gp.XTicks.Size; t++) {
|
||||
ImPlotTick *xt = &gp.XTicks[t];
|
||||
if (xt->RenderLabel && xt->PixelPos >= gp.BB_Plot.Min.x - 1 && xt->PixelPos <= gp.BB_Plot.Max.x + 1)
|
||||
DrawList.AddText(ImVec2(xt->PixelPos - xt->Size.x * 0.5f, gp.BB_Plot.Max.y + txt_off), gp.Col_X.Txt, gp.XTickLabels.Buf.Data + xt->TextOffset);
|
||||
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 + IMPLOT_LABEL_PAD), xt->Major ? gp.Col_X.MajTxt : gp.Col_X.MinTxt, gp.XTickLabels.Buf.Data + xt->BufferOffset);
|
||||
}
|
||||
ImGui::PopClipRect();
|
||||
}
|
||||
|
@ -1067,17 +1073,17 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
const ImVec2 xLabel_size = ImGui::CalcTextSize(x_label);
|
||||
const ImVec2 xLabel_pos(gp.BB_Plot.GetCenter().x - xLabel_size.x * 0.5f,
|
||||
gp.BB_Canvas.Max.y - txt_height);
|
||||
DrawList.AddText(xLabel_pos, gp.Col_X.Txt, x_label);
|
||||
DrawList.AddText(xLabel_pos, gp.Col_X.MajTxt, x_label);
|
||||
}
|
||||
ImGui::PushClipRect(gp.BB_Frame.Min, gp.BB_Frame.Max, true);
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (gp.Y[i].Present && ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickLabels)) {
|
||||
for (int t = 0; t < gp.YTicks[i].Size; t++) {
|
||||
const float x_start = gp.AxisLabelReference[i] + (i == 0 ? (-txt_off - gp.YTicks[i][t].Size.x) : txt_off);
|
||||
const float x_start = gp.AxisLabelReference[i] + (i == 0 ? (-IMPLOT_LABEL_PAD - gp.YTicks[i][t].LabelSize.x) : IMPLOT_LABEL_PAD);
|
||||
ImPlotTick *yt = &gp.YTicks[i][t];
|
||||
if (yt->RenderLabel && 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->Size.y);
|
||||
DrawList.AddText(start, gp.Col_Y[i].Txt, gp.YTickLabels[i].Buf.Data + yt->TextOffset);
|
||||
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.YTickLabels[i].Buf.Data + yt->BufferOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1086,7 +1092,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
|
|||
if (y_label) {
|
||||
const ImVec2 yLabel_size = CalcTextSizeVertical(y_label);
|
||||
const ImVec2 yLabel_pos(gp.BB_Canvas.Min.x, gp.BB_Plot.GetCenter().y + yLabel_size.y * 0.5f);
|
||||
AddTextVertical(&DrawList, y_label, yLabel_pos, gp.Col_Y[0].Txt);
|
||||
AddTextVertical(&DrawList, y_label, yLabel_pos, gp.Col_Y[0].MajTxt);
|
||||
}
|
||||
|
||||
// push plot ID into stack
|
||||
|
@ -1179,7 +1185,7 @@ void PlotContextMenu(ImPlotState& plot) {
|
|||
ImGui::PopID();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (i == 1 && !ImHasFlag(plot.Flags, ImPlotFlags_YAxis2)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1241,13 +1247,13 @@ void PlotContextMenu(ImPlotState& plot) {
|
|||
|
||||
void EndPlot() {
|
||||
IM_ASSERT_USER_ERROR(GImPlot != NULL, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "Mismatched BeginPlot()/EndPlot()!");
|
||||
ImGuiContext &G = *GImGui;
|
||||
ImPlotState &plot = *gp.CurrentPlot;
|
||||
ImGuiWindow * Window = G.CurrentWindow;
|
||||
ImGuiContext &G = *GImGui;
|
||||
ImPlotState &plot = *gp.CurrentPlot;
|
||||
ImGuiWindow * Window = G.CurrentWindow;
|
||||
ImDrawList & DrawList = *Window->DrawList;
|
||||
const ImGuiIO & IO = ImGui::GetIO();
|
||||
const ImGuiIO & IO = ImGui::GetIO();
|
||||
|
||||
// AXIS STATES ------------------------------------------------------------
|
||||
|
||||
|
@ -1262,14 +1268,14 @@ void EndPlot() {
|
|||
if (ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickMarks)) {
|
||||
for (int t = 0; t < gp.XTicks.Size; t++) {
|
||||
ImPlotTick *xt = &gp.XTicks[t];
|
||||
DrawList.AddLine(ImVec2(xt->PixelPos, gp.BB_Plot.Max.y),ImVec2(xt->PixelPos, gp.BB_Plot.Max.y - (xt->Major ? 10.0f : 5.0f)), gp.Col_Border, 1);
|
||||
DrawList.AddLine(ImVec2(xt->PixelPos, gp.BB_Plot.Max.y),ImVec2(xt->PixelPos, gp.BB_Plot.Max.y - (xt->Major ? IMPLOT_MAJOR_SIZE : IMPLOT_MINOR_SIZE)), gp.Col_Border, 1);
|
||||
}
|
||||
}
|
||||
PopPlotClipRect();
|
||||
|
||||
ImGui::PushClipRect(gp.BB_Plot.Min, ImVec2(gp.BB_Frame.Max.x, gp.BB_Plot.Max.y), true);
|
||||
int axis_count = 0;
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (!gp.Y[i].Present) { continue; }
|
||||
axis_count++;
|
||||
|
||||
|
@ -1277,14 +1283,13 @@ void EndPlot() {
|
|||
if (ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickMarks)) {
|
||||
float direction = (i == 0) ? 1.0f : -1.0f;
|
||||
bool no_major = axis_count >= 3;
|
||||
|
||||
for (int t = 0; t < gp.YTicks[i].Size; t++) {
|
||||
ImPlotTick *yt = &gp.YTicks[i][t];
|
||||
ImVec2 start = ImVec2(x_start, yt->PixelPos);
|
||||
|
||||
DrawList.AddLine(
|
||||
start,
|
||||
start + ImVec2(direction * ((!no_major && yt->Major) ? 10.0f : 5.0f), 0),
|
||||
start + ImVec2(direction * ((!no_major && yt->Major) ? IMPLOT_MAJOR_SIZE : IMPLOT_MINOR_SIZE), 0),
|
||||
gp.Col_Border, 1);
|
||||
}
|
||||
}
|
||||
|
@ -1304,7 +1309,7 @@ void EndPlot() {
|
|||
ImRect bb_plot_pad = gp.BB_Plot;
|
||||
bb_plot_pad.Min.x += 5; bb_plot_pad.Max.x -= 5;
|
||||
if (!bb_plot_pad.Contains(IO.MousePos)) {
|
||||
for (int i = 0; i < MAX_Y_AXES; ++i) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
|
||||
if (plot.YAxis[i].Hovered) {
|
||||
float x_loc = gp.AxisLabelReference[i];
|
||||
ImVec2 p1(x_loc - 5, gp.BB_Plot.Min.y - 5);
|
||||
|
@ -1315,7 +1320,6 @@ void EndPlot() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
PushPlotClipRect();
|
||||
// render selection/query
|
||||
if (plot.Selecting) {
|
||||
|
@ -1472,7 +1476,7 @@ void EndPlot() {
|
|||
if (gp.FitX && !ImHasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LockMax) && !NanOrInf(gp.ExtentsX.Max)) {
|
||||
plot.XAxis.Range.Max = gp.ExtentsX.Max;
|
||||
}
|
||||
for (int i = 0; i < MAX_Y_AXES; i++) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; i++) {
|
||||
if (gp.FitY[i] && !ImHasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LockMin) && !NanOrInf(gp.ExtentsY[i].Min)) {
|
||||
plot.YAxis[i].Range.Min = gp.ExtentsY[i].Min;
|
||||
}
|
||||
|
@ -1530,7 +1534,7 @@ void SetNextPlotLimitsX(double x_min, double x_max, ImGuiCond cond) {
|
|||
void SetNextPlotLimitsY(double y_min, double y_max, ImGuiCond cond, int 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 < MAX_Y_AXES, "y_axis needs to be between 0 and MAX_Y_AXES");
|
||||
IM_ASSERT_USER_ERROR(y_axis >= 0 && y_axis < IMPLOT_Y_AXES, "y_axis needs to be between 0 and IMPLOT_Y_AXES");
|
||||
IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
|
||||
gp.NextPlotData.HasYRange[y_axis] = true;
|
||||
gp.NextPlotData.YRangeCond[y_axis] = cond;
|
||||
|
@ -1555,7 +1559,7 @@ void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char** lab
|
|||
void SetNextPlotTicksY(const double* values, int n_ticks, const char** labels, bool show_default, int 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 < MAX_Y_AXES, "y_axis needs to be between 0 and MAX_Y_AXES");
|
||||
IM_ASSERT_USER_ERROR(y_axis >= 0 && y_axis < IMPLOT_Y_AXES, "y_axis needs to be between 0 and IMPLOT_Y_AXES");
|
||||
gp.NextPlotData.ShowDefaultTicksY[y_axis] = show_default;
|
||||
AddCustomTicks(values, labels, n_ticks, gp.YTicks[y_axis], gp.YTickLabels[y_axis]);
|
||||
}
|
||||
|
@ -1570,7 +1574,7 @@ void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char** lab
|
|||
void SetPlotYAxis(int 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 < MAX_Y_AXES, "y_axis needs to be between 0 and MAX_Y_AXES");
|
||||
IM_ASSERT_USER_ERROR(y_axis >= 0 && y_axis < IMPLOT_Y_AXES, "y_axis needs to be between 0 and IMPLOT_Y_AXES");
|
||||
gp.CurrentPlot->CurrentYAxis = y_axis;
|
||||
}
|
||||
|
||||
|
@ -1611,7 +1615,7 @@ bool IsPlotXAxisHovered() {
|
|||
|
||||
bool IsPlotYAxisHovered(int y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(y_axis_in >= -1 && y_axis_in < MAX_Y_AXES, "y_axis needs to between -1 and MAX_Y_AXES");
|
||||
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;
|
||||
ImRect bb_plot_pad = gp.BB_Plot;
|
||||
|
@ -1621,7 +1625,7 @@ bool IsPlotYAxisHovered(int y_axis_in) {
|
|||
|
||||
ImPlotPoint GetPlotMousePos(int y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(y_axis_in >= -1 && y_axis_in < MAX_Y_AXES, "y_axis needs to between -1 and MAX_Y_AXES");
|
||||
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;
|
||||
return gp.LastMousePos[y_axis];
|
||||
|
@ -1630,7 +1634,7 @@ ImPlotPoint GetPlotMousePos(int y_axis_in) {
|
|||
|
||||
ImPlotLimits GetPlotLimits(int y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(y_axis_in >= -1 && y_axis_in < MAX_Y_AXES, "y_axis needs to between -1 and MAX_Y_AXES");
|
||||
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;
|
||||
|
||||
|
@ -1649,7 +1653,7 @@ bool IsPlotQueried() {
|
|||
|
||||
ImPlotLimits GetPlotQuery(int y_axis_in) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(y_axis_in >= -1 && y_axis_in < MAX_Y_AXES, "y_axis needs to between -1 and MAX_Y_AXES");
|
||||
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()!");
|
||||
ImPlotState& plot = *gp.CurrentPlot;
|
||||
const int y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
|
||||
|
@ -1843,7 +1847,7 @@ void ShowColormapScale(double scale_min, double scale_max, float height) {
|
|||
LabelTicks(ticks, false, txt_buff);
|
||||
float max_width = 0;
|
||||
for (int i = 0; i < ticks.Size; ++i)
|
||||
max_width = ticks[i].Size.x > max_width ? ticks[i].Size.x : max_width;
|
||||
max_width = ticks[i].LabelSize.x > max_width ? ticks[i].LabelSize.x : max_width;
|
||||
|
||||
ImGuiContext &G = *GImGui;
|
||||
ImGuiWindow * Window = G.CurrentWindow;
|
||||
|
@ -1877,7 +1881,7 @@ void ShowColormapScale(double scale_min, double scale_max, float height) {
|
|||
float ypos = ImRemap((float)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[i].Major ? 10.0f : 5.0f), ypos), col_border, 1.0f);
|
||||
DrawList.AddText(ImVec2(bb_grad.Max.x-1, ypos) + ImVec2(txt_off, -ticks[i].Size.y * 0.5f), ImGui::GetColorU32(ImGuiCol_Text), txt_buff.Buf.Data + ticks[i].TextOffset);
|
||||
DrawList.AddText(ImVec2(bb_grad.Max.x-1, ypos) + ImVec2(txt_off, -ticks[i].LabelSize.y * 0.5f), ImGui::GetColorU32(ImGuiCol_Text), txt_buff.Buf.Data + ticks[i].BufferOffset);
|
||||
}
|
||||
ImGui::PopClipRect();
|
||||
|
||||
|
|
5
implot.h
5
implot.h
|
@ -151,8 +151,9 @@ struct ImPlotPoint {
|
|||
struct ImPlotRange {
|
||||
double Min, Max;
|
||||
ImPlotRange();
|
||||
bool Contains(double value) const { return value >= Min && value <= Max; };
|
||||
double Size() const { return Max - Min; };
|
||||
ImPlotRange(double _min, double _max) { Min = _min; Max = _max; }
|
||||
bool Contains(double value) const { return value >= Min && value <= Max; };
|
||||
double Size() const { return Max - Min; };
|
||||
};
|
||||
|
||||
// Combination of two ranges for X and Y axes.
|
||||
|
|
|
@ -762,7 +762,7 @@ void ShowDemoWindow(bool* p_open) {
|
|||
}
|
||||
}
|
||||
ImPlot::SetNextPlotLimitsX((double)t - 10, t, paused ? ImGuiCond_Once : ImGuiCond_Always);
|
||||
if (ImPlot::BeginPlot("##DND", NULL, NULL, ImVec2(-1,0), ImPlotFlags_Legend | ImPlotFlags_Highlight | ImPlotFlags_BoxSelect | ImPlotFlags_ContextMenu | ImPlotFlags_NoChild | ImPlotFlags_YAxis2 | ImPlotFlags_YAxis3)) {
|
||||
if (ImPlot::BeginPlot("##DND", NULL, NULL, ImVec2(-1,0), ImPlotFlags_Legend | ImPlotFlags_Highlight | ImPlotFlags_BoxSelect | ImPlotFlags_ContextMenu | ImPlotFlags_YAxis2 | ImPlotFlags_YAxis3)) {
|
||||
for (int i = 0; i < K_CHANNELS; ++i) {
|
||||
if (show[i] && data[i].Data.size() > 0) {
|
||||
char label[K_CHANNELS];
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
// don't provide any guarantee of forward compatibility!
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Header mess
|
||||
// [SECTION] Header Mess
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
@ -42,7 +42,7 @@
|
|||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Forward declarations
|
||||
// [SECTION] Forward Declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImPlotTick;
|
||||
|
@ -54,20 +54,40 @@ struct ImPlotState;
|
|||
struct ImPlotNextPlotData;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Context pointer
|
||||
// [SECTION] Context Pointer
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern ImPlotContext* GImPlot; // Current implicit context pointer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Macros
|
||||
// [SECTION] Macros and Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Constants can be changed unless stated otherwise
|
||||
|
||||
// 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
|
||||
// Minimum plot frame width when requested width is to edge (i.e. -1). This is not the plot area width!
|
||||
#define IMPLOT_MIN_W 300
|
||||
// Minimum plot frame height when requested height is to edge (i.e. -1). This is not the plot area height!
|
||||
#define IMPLOT_MIN_H 225
|
||||
// The maximum number of supported y-axes (DO NOT CHANGE THIS)
|
||||
#define MAX_Y_AXES 3
|
||||
#define IMPLOT_Y_AXES 3
|
||||
// The number of times to subdivided grid divisions (best if a multiple of 1, 2, and 5)
|
||||
#define IMPLOT_SUB_DIV 10
|
||||
// Pixel padding used for labels/titles
|
||||
#define IMPLOT_LABEL_PAD 5
|
||||
// Major tick size in pixels
|
||||
#define IMPLOT_MAJOR_SIZE 10
|
||||
// Minor tick size in pixels
|
||||
#define IMPLOT_MINOR_SIZE 5
|
||||
// Zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click)
|
||||
#define IMPLOT_ZOOM_RATE 0.1f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Generic helpers
|
||||
// [SECTION] Generic Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Computes the common (base-10) logarithm
|
||||
|
@ -151,17 +171,17 @@ struct ImPlotTick
|
|||
{
|
||||
double PlotPos;
|
||||
float PixelPos;
|
||||
ImVec2 Size;
|
||||
int TextOffset;
|
||||
ImVec2 LabelSize;
|
||||
int BufferOffset;
|
||||
bool Major;
|
||||
bool RenderLabel;
|
||||
bool ShowLabel;
|
||||
bool Labeled;
|
||||
|
||||
ImPlotTick(double value, bool major, bool render_label = true) {
|
||||
PlotPos = value;
|
||||
Major = major;
|
||||
RenderLabel = render_label;
|
||||
Labeled = false;
|
||||
ImPlotTick(double value, bool major, bool show_label) {
|
||||
PlotPos = value;
|
||||
Major = major;
|
||||
ShowLabel = show_label;
|
||||
Labeled = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -213,8 +233,8 @@ struct ImPlotAxisState
|
|||
|
||||
struct ImPlotAxisColor
|
||||
{
|
||||
ImU32 Major, Minor, Txt;
|
||||
ImPlotAxisColor() { Major = Minor = Txt = 0; }
|
||||
ImU32 Major, Minor, MajTxt, MinTxt;
|
||||
ImPlotAxisColor() { Major = Minor = MajTxt = MinTxt = 0; }
|
||||
};
|
||||
|
||||
// State information for Plot items
|
||||
|
@ -245,7 +265,7 @@ struct ImPlotState
|
|||
ImPlotFlags Flags;
|
||||
ImPlotFlags PreviousFlags;
|
||||
ImPlotAxis XAxis;
|
||||
ImPlotAxis YAxis[MAX_Y_AXES];
|
||||
ImPlotAxis YAxis[IMPLOT_Y_AXES];
|
||||
ImPool<ImPlotItem> Items;
|
||||
ImVec2 SelectStart;
|
||||
ImVec2 QueryStart;
|
||||
|
@ -270,18 +290,18 @@ struct ImPlotState
|
|||
struct ImPlotNextPlotData
|
||||
{
|
||||
ImGuiCond XRangeCond;
|
||||
ImGuiCond YRangeCond[MAX_Y_AXES];
|
||||
ImGuiCond YRangeCond[IMPLOT_Y_AXES];
|
||||
ImPlotRange X;
|
||||
ImPlotRange Y[MAX_Y_AXES];
|
||||
ImPlotRange Y[IMPLOT_Y_AXES];
|
||||
bool HasXRange;
|
||||
bool HasYRange[MAX_Y_AXES];
|
||||
bool HasYRange[IMPLOT_Y_AXES];
|
||||
bool ShowDefaultTicksX;
|
||||
bool ShowDefaultTicksY[MAX_Y_AXES];
|
||||
bool ShowDefaultTicksY[IMPLOT_Y_AXES];
|
||||
|
||||
ImPlotNextPlotData() {
|
||||
HasXRange = false;
|
||||
ShowDefaultTicksX = true;
|
||||
for (int i = 0; i < MAX_Y_AXES; ++i) {
|
||||
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
|
||||
HasYRange[i] = false;
|
||||
ShowDefaultTicksY[i] = true;
|
||||
}
|
||||
|
@ -316,30 +336,30 @@ struct ImPlotContext {
|
|||
|
||||
// Axis States
|
||||
ImPlotAxisColor Col_X;
|
||||
ImPlotAxisColor Col_Y[MAX_Y_AXES];
|
||||
ImPlotAxisColor Col_Y[IMPLOT_Y_AXES];
|
||||
ImPlotAxisState X;
|
||||
ImPlotAxisState Y[MAX_Y_AXES];
|
||||
ImPlotAxisState Y[IMPLOT_Y_AXES];
|
||||
|
||||
// Tick Marks and Labels
|
||||
ImVector<ImPlotTick> XTicks;
|
||||
ImVector<ImPlotTick> YTicks[MAX_Y_AXES];
|
||||
ImVector<ImPlotTick> YTicks[IMPLOT_Y_AXES];
|
||||
ImGuiTextBuffer XTickLabels;
|
||||
ImGuiTextBuffer YTickLabels[MAX_Y_AXES];
|
||||
float AxisLabelReference[MAX_Y_AXES];
|
||||
ImGuiTextBuffer YTickLabels[IMPLOT_Y_AXES];
|
||||
float AxisLabelReference[IMPLOT_Y_AXES];
|
||||
|
||||
// Transformations and Data Extents
|
||||
ImRect PixelRange[MAX_Y_AXES];
|
||||
ImRect PixelRange[IMPLOT_Y_AXES];
|
||||
double Mx;
|
||||
double My[MAX_Y_AXES];
|
||||
double My[IMPLOT_Y_AXES];
|
||||
double LogDenX;
|
||||
double LogDenY[MAX_Y_AXES];
|
||||
double LogDenY[IMPLOT_Y_AXES];
|
||||
ImPlotRange ExtentsX;
|
||||
ImPlotRange ExtentsY[MAX_Y_AXES];
|
||||
ImPlotRange ExtentsY[IMPLOT_Y_AXES];
|
||||
|
||||
// Data Fitting Flags
|
||||
bool FitThisFrame;
|
||||
bool FitX;
|
||||
bool FitY[MAX_Y_AXES];
|
||||
bool FitY[IMPLOT_Y_AXES];
|
||||
|
||||
// Hover states
|
||||
bool Hov_Frame;
|
||||
|
@ -347,7 +367,7 @@ struct ImPlotContext {
|
|||
|
||||
// Axis Rendering Flags
|
||||
bool RenderX;
|
||||
bool RenderY[MAX_Y_AXES];
|
||||
bool RenderY[IMPLOT_Y_AXES];
|
||||
|
||||
// Axis Locking Flags
|
||||
bool LockPlot;
|
||||
|
@ -366,7 +386,7 @@ struct ImPlotContext {
|
|||
int DigitalPlotOffset;
|
||||
ImPlotNextPlotData NextPlotData;
|
||||
ImPlotInputMap InputMap;
|
||||
ImPlotPoint LastMousePos[MAX_Y_AXES];
|
||||
ImPlotPoint LastMousePos[IMPLOT_Y_AXES];
|
||||
};
|
||||
|
||||
struct ImPlotAxisScale
|
||||
|
@ -422,8 +442,13 @@ void AddDefaultTicks(const ImPlotRange& range, int nMajor, int nMinor, bool logs
|
|||
void AddCustomTicks(const double* values, const char** labels, int n, ImVector<ImPlotTick>& ticks, ImGuiTextBuffer& buffer);
|
||||
// Creates label information for a list of ImPlotTick
|
||||
void LabelTicks(ImVector<ImPlotTick> &ticks, bool scientific, ImGuiTextBuffer& buffer);
|
||||
// Calculates the maximum width of a list of ImPlotTick
|
||||
float MaxTickLabelWidth(ImVector<ImPlotTick>& ticks);
|
||||
// Gets the widest visible (i.e. ShowLabel = true) label size from a list of ticks
|
||||
float MaxTickLabelWidth(const ImVector<ImPlotTick>& ticks);
|
||||
// Sums the widths of visible ticks (i.e. ShowLabel = true) ticks
|
||||
float SumTickLabelWidth(const ImVector<ImPlotTick>& ticks);
|
||||
// Sums the heights of visible (i.e. ShowLabel = true) ticks
|
||||
float SumTickLabelHeight(const ImVector<ImPlotTick>& ticks);
|
||||
|
||||
// Rounds x to powers of 2,5 and 10 for generating axis labels (from Graphics Gems 1 Chapter 11.2)
|
||||
double NiceNum(double x, bool round);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user