1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-10-09 23:57:26 -04:00

C++11 extensions update after enums with ImPlot

This commit is contained in:
ozlb 2020-05-13 17:23:01 +02:00 committed by GitHub
parent 280cbf5cd4
commit 36e0aa3ce1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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. 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. You can read releases logs https://github.com/epezent/implot/releases for more details.
- 2020/05/13 (0.2) - ImMarker was change to ImPlotMarker and ImAxisFlags was changed to ImPlotAxisFlags
- 2020/05/11 (0.2) - ImPlotFlags_Selection was changed to ImPlotFlags_BoxSelect - 2020/05/11 (0.2) - ImPlotFlags_Selection was changed to ImPlotFlags_BoxSelect
- 2020/05/11 (0.2) - The namespace ImGui:: was replaced with ImPlot::. As a result, the following additional changes were made: - 2020/05/11 (0.2) - The namespace ImGui:: was replaced with ImPlot::. As a result, the following additional changes were made:
- Functions that were prefixed or decorated with the word "Plot" have been truncated. E.g., `ImGui::PlotBar` is now just `ImPlot::Bar`. - Functions that were prefixed or decorated with the word "Plot" have been truncated. E.g., `ImGui::PlotBar` is now just `ImPlot::Bar`.
@ -80,7 +81,7 @@ You can read releases logs https://github.com/epezent/implot/releases for more d
ImPlotStyle::ImPlotStyle() { ImPlotStyle::ImPlotStyle() {
LineWeight = 1; LineWeight = 1;
Marker = ImMarker_None; Marker = ImPlotMarker_None;
MarkerSize = 5; MarkerSize = 5;
MarkerWeight = 1; MarkerWeight = 1;
ErrorBarSize = 5; ErrorBarSize = 5;
@ -276,13 +277,13 @@ struct ImPlotAxis {
Range.Max = 1; Range.Max = 1;
Divisions = 3; Divisions = 3;
Subdivisions = 10; Subdivisions = 10;
Flags = PreviousFlags = ImAxisFlags_Default; Flags = PreviousFlags = ImPlotAxisFlags_Default;
} }
bool Dragging; bool Dragging;
ImPlotRange Range; ImPlotRange Range;
int Divisions; int Divisions;
int Subdivisions; int Subdivisions;
ImAxisFlags Flags, PreviousFlags; ImPlotAxisFlags Flags, PreviousFlags;
}; };
/// Holds Plot state information that must persist between frames /// Holds Plot state information that must persist between frames
@ -314,7 +315,6 @@ struct ImPlotState {
}; };
struct ImNextPlotData { struct ImNextPlotData {
//ImNextPlotData() : HasXRange{}, HasYRange{} {}
ImGuiCond XRangeCond; ImGuiCond XRangeCond;
ImGuiCond YRangeCond[MAX_Y_AXES]; ImGuiCond YRangeCond[MAX_Y_AXES];
bool HasXRange; bool HasXRange;
@ -426,10 +426,10 @@ inline void UpdateTransformCache() {
// get pixels for transforms // get pixels for transforms
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
gp.PixelRange[i] = ImRect(HasFlag(gp.CurrentPlot->XAxis.Flags, ImAxisFlags_Invert) ? gp.BB_Grid.Max.x : gp.BB_Grid.Min.x, gp.PixelRange[i] = ImRect(HasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_Invert) ? gp.BB_Grid.Max.x : gp.BB_Grid.Min.x,
HasFlag(gp.CurrentPlot->YAxis[i].Flags, ImAxisFlags_Invert) ? gp.BB_Grid.Min.y : gp.BB_Grid.Max.y, HasFlag(gp.CurrentPlot->YAxis[i].Flags, ImPlotAxisFlags_Invert) ? gp.BB_Grid.Min.y : gp.BB_Grid.Max.y,
HasFlag(gp.CurrentPlot->XAxis.Flags, ImAxisFlags_Invert) ? gp.BB_Grid.Min.x : gp.BB_Grid.Max.x, HasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_Invert) ? gp.BB_Grid.Min.x : gp.BB_Grid.Max.x,
HasFlag(gp.CurrentPlot->YAxis[i].Flags, ImAxisFlags_Invert) ? gp.BB_Grid.Max.y : gp.BB_Grid.Min.y); HasFlag(gp.CurrentPlot->YAxis[i].Flags, ImPlotAxisFlags_Invert) ? gp.BB_Grid.Max.y : gp.BB_Grid.Min.y);
gp.My[i] = (gp.PixelRange[i].Max.y - gp.PixelRange[i].Min.y) / gp.CurrentPlot->YAxis[i].Range.Size(); gp.My[i] = (gp.PixelRange[i].Max.y - gp.PixelRange[i].Min.y) / gp.CurrentPlot->YAxis[i].Range.Size();
} }
@ -446,11 +446,11 @@ inline ImVec2 PixelsToPlot(float x, float y, int y_axis_in = -1) {
ImVec2 plt; ImVec2 plt;
plt.x = (x - gp.PixelRange[y_axis].Min.x) / gp.Mx + gp.CurrentPlot->XAxis.Range.Min; 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; plt.y = (y - gp.PixelRange[y_axis].Min.y) / gp.My[y_axis] + gp.CurrentPlot->YAxis[y_axis].Range.Min;
if (HasFlag(gp.CurrentPlot->XAxis.Flags, ImAxisFlags_LogScale)) { if (HasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_LogScale)) {
float t = (plt.x - gp.CurrentPlot->XAxis.Range.Min) / gp.CurrentPlot->XAxis.Range.Size(); float t = (plt.x - gp.CurrentPlot->XAxis.Range.Min) / gp.CurrentPlot->XAxis.Range.Size();
plt.x = pow(10.0f, t * gp.LogDenX) * gp.CurrentPlot->XAxis.Range.Min; plt.x = pow(10.0f, t * gp.LogDenX) * gp.CurrentPlot->XAxis.Range.Min;
} }
if (HasFlag(gp.CurrentPlot->YAxis[y_axis].Flags, ImAxisFlags_LogScale)) { if (HasFlag(gp.CurrentPlot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale)) {
float t = (plt.y - gp.CurrentPlot->YAxis[y_axis].Range.Min) / gp.CurrentPlot->YAxis[y_axis].Range.Size(); float t = (plt.y - gp.CurrentPlot->YAxis[y_axis].Range.Min) / gp.CurrentPlot->YAxis[y_axis].Range.Size();
plt.y = pow(10.0f, t * gp.LogDenY[y_axis]) * gp.CurrentPlot->YAxis[y_axis].Range.Min; plt.y = pow(10.0f, t * gp.LogDenY[y_axis]) * gp.CurrentPlot->YAxis[y_axis].Range.Min;
} }
@ -461,11 +461,11 @@ inline ImVec2 PlotToPixels(float x, float y, int y_axis_in = -1) {
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotToPixels() Needs to be called between BeginPlot() and EndPlot()!"); 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 int y_axis = y_axis_in >= 0 ? y_axis_in : gp.CurrentPlot->CurrentYAxis;
ImVec2 pix; ImVec2 pix;
if (HasFlag(gp.CurrentPlot->XAxis.Flags, ImAxisFlags_LogScale)) { if (HasFlag(gp.CurrentPlot->XAxis.Flags, ImPlotAxisFlags_LogScale)) {
float t = log10(x / gp.CurrentPlot->XAxis.Range.Min) / gp.LogDenX; float t = log10(x / gp.CurrentPlot->XAxis.Range.Min) / gp.LogDenX;
x = ImLerp(gp.CurrentPlot->XAxis.Range.Min, gp.CurrentPlot->XAxis.Range.Max, t); x = ImLerp(gp.CurrentPlot->XAxis.Range.Min, gp.CurrentPlot->XAxis.Range.Max, t);
} }
if (HasFlag(gp.CurrentPlot->YAxis[y_axis].Flags, ImAxisFlags_LogScale)) { if (HasFlag(gp.CurrentPlot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale)) {
float t = log10(y / gp.CurrentPlot->YAxis[y_axis].Range.Min) / gp.LogDenY[y_axis]; float t = log10(y / gp.CurrentPlot->YAxis[y_axis].Range.Min) / gp.LogDenY[y_axis];
y = ImLerp(gp.CurrentPlot->YAxis[y_axis].Range.Min, gp.CurrentPlot->YAxis[y_axis].Range.Max, t); y = ImLerp(gp.CurrentPlot->YAxis[y_axis].Range.Min, gp.CurrentPlot->YAxis[y_axis].Range.Max, t);
} }
@ -646,9 +646,9 @@ struct AxisState {
range_cond(range_cond_in), range_cond(range_cond_in),
present(present_in), present(present_in),
present_so_far(previous_present + (present ? 1 : 0)), present_so_far(previous_present + (present ? 1 : 0)),
flip(HasFlag(axis->Flags, ImAxisFlags_Invert)), flip(HasFlag(axis->Flags, ImPlotAxisFlags_Invert)),
lock_min(HasFlag(axis->Flags, ImAxisFlags_LockMin)), lock_min(HasFlag(axis->Flags, ImPlotAxisFlags_LockMin)),
lock_max(HasFlag(axis->Flags, ImAxisFlags_LockMax)), lock_max(HasFlag(axis->Flags, ImPlotAxisFlags_LockMax)),
lock(present && ((lock_min && lock_max) || (has_range && range_cond == ImGuiCond_Always))) {} lock(present && ((lock_min && lock_max) || (has_range && range_cond == ImGuiCond_Always))) {}
AxisState() AxisState()
@ -690,7 +690,7 @@ class YPadCalculator {
if (AxisStates[y_axis].present_so_far >= 3) { if (AxisStates[y_axis].present_so_far >= 3) {
pad_result += 6.0f; pad_result += 6.0f;
} }
if (!HasFlag(plot.YAxis[y_axis].Flags, ImAxisFlags_TickLabels)) { if (!HasFlag(plot.YAxis[y_axis].Flags, ImPlotAxisFlags_TickLabels)) {
return pad_result; return pad_result;
} }
pad_result += MaxLabelWidths[y_axis] + TxtOff; pad_result += MaxLabelWidths[y_axis] + TxtOff;
@ -708,7 +708,7 @@ class YPadCalculator {
// BeginPlot() // BeginPlot()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool BeginPlot(const char* title, const char* x_label, const char* y_label, const ImVec2& size, ImPlotFlags flags, ImAxisFlags x_flags, ImAxisFlags y_flags, ImAxisFlags y2_flags, ImAxisFlags y3_flags) { bool BeginPlot(const char* title, const char* x_label, const char* y_label, const ImVec2& size, ImPlotFlags flags, ImPlotAxisFlags x_flags, ImPlotAxisFlags y_flags, ImPlotAxisFlags y2_flags, ImPlotAxisFlags y3_flags) {
IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "Mismatched BeginPlot()/EndPlot()!"); IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "Mismatched BeginPlot()/EndPlot()!");
@ -804,14 +804,14 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
plot.YAxis[i].Range.Max = ConstrainNan(ConstrainInf(plot.YAxis[i].Range.Max)); plot.YAxis[i].Range.Max = ConstrainNan(ConstrainInf(plot.YAxis[i].Range.Max));
} }
if (HasFlag(plot.XAxis.Flags, ImAxisFlags_LogScale)) if (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LogScale))
plot.XAxis.Range.Min = ConstrainLog(plot.XAxis.Range.Min); plot.XAxis.Range.Min = ConstrainLog(plot.XAxis.Range.Min);
if (HasFlag(plot.XAxis.Flags, ImAxisFlags_LogScale)) if (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LogScale))
plot.XAxis.Range.Max = ConstrainLog(plot.XAxis.Range.Max); plot.XAxis.Range.Max = ConstrainLog(plot.XAxis.Range.Max);
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
if (HasFlag(plot.YAxis[i].Flags, ImAxisFlags_LogScale)) if (HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LogScale))
plot.YAxis[i].Range.Min = ConstrainLog(plot.YAxis[i].Range.Min); plot.YAxis[i].Range.Min = ConstrainLog(plot.YAxis[i].Range.Min);
if (HasFlag(plot.YAxis[i].Flags, ImAxisFlags_LogScale)) if (HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LogScale))
plot.YAxis[i].Range.Max = ConstrainLog(plot.YAxis[i].Range.Max); plot.YAxis[i].Range.Max = ConstrainLog(plot.YAxis[i].Range.Max);
} }
@ -823,13 +823,13 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
} }
// adaptive divisions // adaptive divisions
if (HasFlag(plot.XAxis.Flags, ImAxisFlags_Adaptive)) { if (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_Adaptive)) {
plot.XAxis.Divisions = (int)IM_ROUND(0.003 * gp.BB_Canvas.GetWidth()); plot.XAxis.Divisions = (int)IM_ROUND(0.003 * gp.BB_Canvas.GetWidth());
if (plot.XAxis.Divisions < 2) if (plot.XAxis.Divisions < 2)
plot.XAxis.Divisions = 2; plot.XAxis.Divisions = 2;
} }
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
if (HasFlag(plot.YAxis[i].Flags, ImAxisFlags_Adaptive)) { if (HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_Adaptive)) {
plot.YAxis[i].Divisions = (int)IM_ROUND(0.003 * gp.BB_Canvas.GetHeight()); plot.YAxis[i].Divisions = (int)IM_ROUND(0.003 * gp.BB_Canvas.GetHeight());
if (plot.YAxis[i].Divisions < 2) if (plot.YAxis[i].Divisions < 2)
plot.YAxis[i].Divisions = 2; plot.YAxis[i].Divisions = 2;
@ -873,34 +873,34 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// canvas bb // canvas bb
gp.BB_Canvas = ImRect(gp.BB_Frame.Min + Style.WindowPadding, gp.BB_Frame.Max - Style.WindowPadding); gp.BB_Canvas = ImRect(gp.BB_Frame.Min + Style.WindowPadding, gp.BB_Frame.Max - Style.WindowPadding);
gp.RenderX = (HasFlag(plot.XAxis.Flags, ImAxisFlags_GridLines) || gp.RenderX = (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_GridLines) ||
HasFlag(plot.XAxis.Flags, ImAxisFlags_TickMarks) || HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickMarks) ||
HasFlag(plot.XAxis.Flags, ImAxisFlags_TickLabels)) && plot.XAxis.Divisions > 1; HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels)) && plot.XAxis.Divisions > 1;
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
gp.RenderY[i] = gp.RenderY[i] =
y[i].present && y[i].present &&
(HasFlag(plot.YAxis[i].Flags, ImAxisFlags_GridLines) || (HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_GridLines) ||
HasFlag(plot.YAxis[i].Flags, ImAxisFlags_TickMarks) || HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickMarks) ||
HasFlag(plot.YAxis[i].Flags, ImAxisFlags_TickLabels)) && plot.YAxis[i].Divisions > 1; HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickLabels)) && plot.YAxis[i].Divisions > 1;
} }
// get ticks // get ticks
if (gp.RenderX) if (gp.RenderX)
GetTicks(plot.XAxis.Range, plot.XAxis.Divisions, plot.XAxis.Subdivisions, HasFlag(plot.XAxis.Flags, ImAxisFlags_LogScale), gp.XTicks); GetTicks(plot.XAxis.Range, plot.XAxis.Divisions, plot.XAxis.Subdivisions, HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LogScale), gp.XTicks);
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
if (gp.RenderY[i]) { if (gp.RenderY[i]) {
GetTicks(plot.YAxis[i].Range, plot.YAxis[i].Divisions, plot.YAxis[i].Subdivisions, HasFlag(plot.YAxis[i].Flags, ImAxisFlags_LogScale), gp.YTicks[i]); GetTicks(plot.YAxis[i].Range, plot.YAxis[i].Divisions, plot.YAxis[i].Subdivisions, HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LogScale), gp.YTicks[i]);
} }
} }
// label ticks // label ticks
if (HasFlag(plot.XAxis.Flags, ImAxisFlags_TickLabels)) if (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels))
LabelTicks(gp.XTicks, HasFlag(plot.XAxis.Flags, ImAxisFlags_Scientific), gp.XTickLabels); LabelTicks(gp.XTicks, HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_Scientific), gp.XTickLabels);
float max_label_width[MAX_Y_AXES] = {}; float max_label_width[MAX_Y_AXES] = {};
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
if (y[i].present && HasFlag(plot.YAxis[i].Flags, ImAxisFlags_TickLabels)) { if (y[i].present && HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickLabels)) {
LabelTicks(gp.YTicks[i], HasFlag(plot.YAxis[i].Flags, ImAxisFlags_Scientific), gp.YTickLabels[i]); LabelTicks(gp.YTicks[i], HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_Scientific), gp.YTickLabels[i]);
for (int t = 0; t < gp.YTicks[i].Size; t++) { for (int t = 0; t < gp.YTicks[i].Size; t++) {
ImTick *yt = &gp.YTicks[i][t]; ImTick *yt = &gp.YTicks[i][t];
max_label_width[i] = yt->Size.x > max_label_width[i] ? yt->Size.x : max_label_width[i]; max_label_width[i] = yt->Size.x > max_label_width[i] ? yt->Size.x : max_label_width[i];
@ -913,7 +913,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
const float txt_off = 5; const float txt_off = 5;
const float txt_height = ImGui::GetTextLineHeight(); const float txt_height = ImGui::GetTextLineHeight();
const float pad_top = title_size.x > 0.0f ? txt_height + txt_off : 0; const float pad_top = title_size.x > 0.0f ? txt_height + txt_off : 0;
const float pad_bot = (HasFlag(plot.XAxis.Flags, ImAxisFlags_TickLabels) ? txt_height + txt_off : 0) + (x_label ? txt_height + txt_off : 0); const float pad_bot = (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels) ? txt_height + txt_off : 0) + (x_label ? txt_height + txt_off : 0);
YPadCalculator y_axis_pad(y, max_label_width, txt_off); YPadCalculator y_axis_pad(y, max_label_width, txt_off);
const float pad_left = y_axis_pad(0) + (y_label ? txt_height + txt_off : 0); const float pad_left = y_axis_pad(0) + (y_label ? txt_height + txt_off : 0);
const float pad_right = y_axis_pad(1) + y_axis_pad(2); const float pad_right = y_axis_pad(1) + y_axis_pad(2);
@ -1225,7 +1225,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
} }
// render grid // render grid
if (HasFlag(plot.XAxis.Flags, ImAxisFlags_GridLines)) { if (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_GridLines)) {
for (int t = 0; t < gp.XTicks.Size; t++) { for (int t = 0; t < gp.XTicks.Size; t++) {
ImTick *xt = &gp.XTicks[t]; ImTick *xt = &gp.XTicks[t];
DrawList.AddLine(ImVec2(xt->PixelPos, gp.BB_Grid.Min.y), ImVec2(xt->PixelPos, gp.BB_Grid.Max.y), xt->Major ? gp.Col_X.Major : gp.Col_X.Minor, 1); DrawList.AddLine(ImVec2(xt->PixelPos, gp.BB_Grid.Min.y), ImVec2(xt->PixelPos, gp.BB_Grid.Max.y), xt->Major ? gp.Col_X.Major : gp.Col_X.Minor, 1);
@ -1233,7 +1233,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 < MAX_Y_AXES; i++) {
if (y[i].present && HasFlag(plot.YAxis[i].Flags, ImAxisFlags_GridLines)) { if (y[i].present && HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_GridLines)) {
for (int t = 0; t < gp.YTicks[i].Size; t++) { for (int t = 0; t < gp.YTicks[i].Size; t++) {
ImTick *yt = &gp.YTicks[i][t]; ImTick *yt = &gp.YTicks[i][t];
DrawList.AddLine(ImVec2(gp.BB_Grid.Min.x, yt->PixelPos), ImVec2(gp.BB_Grid.Max.x, yt->PixelPos), yt->Major ? gp.Col_Y[i].Major : gp.Col_Y[i].Minor, 1); DrawList.AddLine(ImVec2(gp.BB_Grid.Min.x, yt->PixelPos), ImVec2(gp.BB_Grid.Max.x, yt->PixelPos), yt->Major ? gp.Col_Y[i].Major : gp.Col_Y[i].Minor, 1);
@ -1249,7 +1249,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
} }
// render labels // render labels
if (HasFlag(plot.XAxis.Flags, ImAxisFlags_TickLabels)) { if (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickLabels)) {
ImGui::PushClipRect(gp.BB_Frame.Min, gp.BB_Frame.Max, true); ImGui::PushClipRect(gp.BB_Frame.Min, gp.BB_Frame.Max, true);
for (int t = 0; t < gp.XTicks.Size; t++) { for (int t = 0; t < gp.XTicks.Size; t++) {
ImTick *xt = &gp.XTicks[t]; ImTick *xt = &gp.XTicks[t];
@ -1266,7 +1266,7 @@ 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); 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 < MAX_Y_AXES; i++) {
if (y[i].present && HasFlag(plot.YAxis[i].Flags, ImAxisFlags_TickLabels)) { if (y[i].present && HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickLabels)) {
const float x_start = const float x_start =
gp.AxisLabelReference[i] + gp.AxisLabelReference[i] +
((i == 0) ? ((i == 0) ?
@ -1315,15 +1315,15 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
inline void AxisMenu(ImPlotAxis& Axis) { inline void AxisMenu(ImPlotAxis& Axis) {
ImGui::PushItemWidth(75); ImGui::PushItemWidth(75);
bool lock_min = HasFlag(Axis.Flags, ImAxisFlags_LockMin); bool lock_min = HasFlag(Axis.Flags, ImPlotAxisFlags_LockMin);
bool lock_max = HasFlag(Axis.Flags, ImAxisFlags_LockMax); bool lock_max = HasFlag(Axis.Flags, ImPlotAxisFlags_LockMax);
bool invert = HasFlag(Axis.Flags, ImAxisFlags_Invert); bool invert = HasFlag(Axis.Flags, ImPlotAxisFlags_Invert);
bool logscale = HasFlag(Axis.Flags, ImAxisFlags_LogScale); bool logscale = HasFlag(Axis.Flags, ImPlotAxisFlags_LogScale);
bool grid = HasFlag(Axis.Flags, ImAxisFlags_GridLines); bool grid = HasFlag(Axis.Flags, ImPlotAxisFlags_GridLines);
bool ticks = HasFlag(Axis.Flags, ImAxisFlags_TickMarks); bool ticks = HasFlag(Axis.Flags, ImPlotAxisFlags_TickMarks);
bool labels = HasFlag(Axis.Flags, ImAxisFlags_TickLabels); bool labels = HasFlag(Axis.Flags, ImPlotAxisFlags_TickLabels);
if (ImGui::Checkbox("##LockMin", &lock_min)) if (ImGui::Checkbox("##LockMin", &lock_min))
FlipFlag(Axis.Flags, ImAxisFlags_LockMin); FlipFlag(Axis.Flags, ImPlotAxisFlags_LockMin);
ImGui::SameLine(); ImGui::SameLine();
if (lock_min) { if (lock_min) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
@ -1335,7 +1335,7 @@ inline void AxisMenu(ImPlotAxis& Axis) {
ImGui::PopStyleVar(); } ImGui::PopStyleVar(); }
if (ImGui::Checkbox("##LockMax", &lock_max)) if (ImGui::Checkbox("##LockMax", &lock_max))
FlipFlag(Axis.Flags, ImAxisFlags_LockMax); FlipFlag(Axis.Flags, ImPlotAxisFlags_LockMax);
ImGui::SameLine(); ImGui::SameLine();
if (lock_max) { if (lock_max) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
@ -1347,16 +1347,16 @@ inline void AxisMenu(ImPlotAxis& Axis) {
} }
ImGui::Separator(); ImGui::Separator();
if (ImGui::Checkbox("Invert", &invert)) if (ImGui::Checkbox("Invert", &invert))
FlipFlag(Axis.Flags, ImAxisFlags_Invert); FlipFlag(Axis.Flags, ImPlotAxisFlags_Invert);
if (ImGui::Checkbox("Log Scale", &logscale)) if (ImGui::Checkbox("Log Scale", &logscale))
FlipFlag(Axis.Flags, ImAxisFlags_LogScale); FlipFlag(Axis.Flags, ImPlotAxisFlags_LogScale);
ImGui::Separator(); ImGui::Separator();
if (ImGui::Checkbox("Grid Lines", &grid)) if (ImGui::Checkbox("Grid Lines", &grid))
FlipFlag(Axis.Flags, ImAxisFlags_GridLines); FlipFlag(Axis.Flags, ImPlotAxisFlags_GridLines);
if (ImGui::Checkbox("Tick Marks", &ticks)) if (ImGui::Checkbox("Tick Marks", &ticks))
FlipFlag(Axis.Flags, ImAxisFlags_TickMarks); FlipFlag(Axis.Flags, ImPlotAxisFlags_TickMarks);
if (ImGui::Checkbox("Labels", &labels)) if (ImGui::Checkbox("Labels", &labels))
FlipFlag(Axis.Flags, ImAxisFlags_TickLabels); FlipFlag(Axis.Flags, ImPlotAxisFlags_TickLabels);
} }
void PlotContextMenu(ImPlotState& plot) { void PlotContextMenu(ImPlotState& plot) {
@ -1481,7 +1481,7 @@ void EndPlot() {
// render ticks // render ticks
PushPlotClipRect(); PushPlotClipRect();
if (HasFlag(plot.XAxis.Flags, ImAxisFlags_TickMarks)) { if (HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_TickMarks)) {
for (int t = 0; t < gp.XTicks.Size; t++) { for (int t = 0; t < gp.XTicks.Size; t++) {
ImTick *xt = &gp.XTicks[t]; ImTick *xt = &gp.XTicks[t];
DrawList.AddLine(ImVec2(xt->PixelPos, gp.BB_Grid.Max.y),ImVec2(xt->PixelPos, gp.BB_Grid.Max.y - (xt->Major ? 10.0f : 5.0f)), gp.Col_Border, 1); DrawList.AddLine(ImVec2(xt->PixelPos, gp.BB_Grid.Max.y),ImVec2(xt->PixelPos, gp.BB_Grid.Max.y - (xt->Major ? 10.0f : 5.0f)), gp.Col_Border, 1);
@ -1495,7 +1495,7 @@ void EndPlot() {
if (!y[i].present) { continue; } if (!y[i].present) { continue; }
axis_count++; axis_count++;
if (!HasFlag(plot.YAxis[i].Flags, ImAxisFlags_TickMarks)) { continue; } if (!HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_TickMarks)) { continue; }
float x_start = gp.AxisLabelReference[i]; float x_start = gp.AxisLabelReference[i];
float direction = (i == 0) ? 1.0f : -1.0f; float direction = (i == 0) ? 1.0f : -1.0f;
@ -1664,17 +1664,17 @@ void EndPlot() {
// FIT DATA -------------------------------------------------------------- // FIT DATA --------------------------------------------------------------
if (gp.FitThisFrame && (gp.VisibleItemCount > 0 || plot.Queried)) { if (gp.FitThisFrame && (gp.VisibleItemCount > 0 || plot.Queried)) {
if (gp.FitX && !HasFlag(plot.XAxis.Flags, ImAxisFlags_LockMin) && !NanOrInf(gp.ExtentsX.Min)) { if (gp.FitX && !HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LockMin) && !NanOrInf(gp.ExtentsX.Min)) {
plot.XAxis.Range.Min = gp.ExtentsX.Min; plot.XAxis.Range.Min = gp.ExtentsX.Min;
} }
if (gp.FitX && !HasFlag(plot.XAxis.Flags, ImAxisFlags_LockMax) && !NanOrInf(gp.ExtentsX.Max)) { if (gp.FitX && !HasFlag(plot.XAxis.Flags, ImPlotAxisFlags_LockMax) && !NanOrInf(gp.ExtentsX.Max)) {
plot.XAxis.Range.Max = gp.ExtentsX.Max; plot.XAxis.Range.Max = gp.ExtentsX.Max;
} }
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
if (gp.FitY[i] && !HasFlag(plot.YAxis[i].Flags, ImAxisFlags_LockMin) && !NanOrInf(gp.ExtentsY[i].Min)) { if (gp.FitY[i] && !HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LockMin) && !NanOrInf(gp.ExtentsY[i].Min)) {
plot.YAxis[i].Range.Min = gp.ExtentsY[i].Min; plot.YAxis[i].Range.Min = gp.ExtentsY[i].Min;
} }
if (gp.FitY[i] && !HasFlag(plot.YAxis[i].Flags, ImAxisFlags_LockMax) && !NanOrInf(gp.ExtentsY[i].Max)) { if (gp.FitY[i] && !HasFlag(plot.YAxis[i].Flags, ImPlotAxisFlags_LockMax) && !NanOrInf(gp.ExtentsY[i].Max)) {
plot.YAxis[i].Range.Max = gp.ExtentsY[i].Max; plot.YAxis[i].Range.Max = gp.ExtentsY[i].Max;
} }
} }
@ -2033,25 +2033,25 @@ int idx = offset;
idx = (idx + 1) % count; idx = (idx + 1) % count;
if (!cull || gp.BB_Grid.Contains(c)) { if (!cull || gp.BB_Grid.Contains(c)) {
// TODO: Optimize the loop and if statements, this is atrocious // TODO: Optimize the loop and if statements, this is atrocious
if (HasFlag(gp.Style.Marker, ImMarker_Circle)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Circle))
MarkerCircle(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerCircle(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Square)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Square))
MarkerSquare(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerSquare(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Diamond)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Diamond))
MarkerDiamond(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerDiamond(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Up)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Up))
MarkerUp(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerUp(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Down)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Down))
MarkerDown(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerDown(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Left)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Left))
MarkerLeft(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerLeft(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Right)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Right))
MarkerRight(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerRight(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Cross)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Cross))
MarkerCross(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerCross(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Plus)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Plus))
MarkerPlus(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerPlus(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
if (HasFlag(gp.Style.Marker, ImMarker_Asterisk)) if (HasFlag(gp.Style.Marker, ImPlotMarker_Asterisk))
MarkerAsterisk(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); MarkerAsterisk(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight);
} }
} }
@ -2096,34 +2096,43 @@ inline void RenderLineAA(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p
} }
template <typename Transformer, typename Getter> template <typename Transformer, typename Getter>
inline void RenderLines(Transformer transformer, ImDrawList& DrawList, Getter getter, int count, int offset, float line_weight, ImU32 col_line, bool cull) { inline void RenderLineStrip(Transformer transformer, ImDrawList& DrawList, Getter getter, int count, int offset, float line_weight, ImU32 col_line, bool cull) {
// render line segments // render line segments
offset %= count;
if (offset < 0) offset += count; // shift negative offset to positive range
int i_start = offset + 1;
if (i_start >= count ) i_start -= count;
int i_end = offset + count;
if (i_end >= count) i_end -= count;
const int segments = count - 1; const int segments = count - 1;
int i1 = offset; ImVec2 p1 = transformer(getter(offset));
ImVec2 p1, p2; bool test1 = !cull || gp.BB_Grid.Contains(p1);
if (HasFlag(gp.CurrentPlot->Flags, ImPlotFlags_AntiAliased)) { if (HasFlag(gp.CurrentPlot->Flags, ImPlotFlags_AntiAliased)) {
for (int s = 0; s < segments; ++s) { for (int i1 = i_start; i1 != i_end; i1 = i1 + 1 < count ? i1 + 1 : i1 + 1 - count)
const int i2 = (i1 + 1) % count; {
p1 = transformer(getter(i1)); ImVec2 p2 = transformer(getter(i1));
p2 = transformer(getter(i2)); bool test2 = !cull || gp.BB_Grid.Contains(p2);
i1 = i2; if (test1 | test2)
if (!cull || gp.BB_Grid.Contains(p1) || gp.BB_Grid.Contains(p2))
RenderLineAA(DrawList, p1, p2, line_weight, col_line); RenderLineAA(DrawList, p1, p2, line_weight, col_line);
p1 = p2;
test1 = test2;
} }
} }
else { else {
const ImVec2 uv = DrawList._Data->TexUvWhitePixel; const ImVec2 uv = DrawList._Data->TexUvWhitePixel;
DrawList.PrimReserve(segments * 6, segments * 4); DrawList.PrimReserve(segments * 6, segments * 4);
int segments_culled = 0; int segments_culled = 0;
for (int s = 0; s < segments; ++s) { for (int i1 = i_start; i1 != i_end; i1 = i1 + 1 < count ? i1 + 1 : i1 + 1 - count)
const int i2 = (i1 + 1) % count; {
p1 = transformer(getter(i1)); ImVec2 p2 = transformer(getter(i1));
p2 = transformer(getter(i2)); bool test2 = !cull || gp.BB_Grid.Contains(p2);
i1 = i2; if (test1 | test2)
if (!cull || gp.BB_Grid.Contains(p1) || gp.BB_Grid.Contains(p2)) RenderLine(DrawList, p1, p2, line_weight, col_line, uv);
RenderLine(DrawList, p1, p2, line_weight, col_line, uv); else
else segments_culled++;
segments_culled++; p1 = p2;
test1 = test2;
} }
if (segments_culled > 0) if (segments_culled > 0)
DrawList.PrimUnreserve(segments_culled * 6, segments_culled * 4); DrawList.PrimUnreserve(segments_culled * 6, segments_culled * 4);
@ -2218,22 +2227,22 @@ inline void PlotEx(const char* label_id, Getter getter, int count, int offset)
} }
PushPlotClipRect(); PushPlotClipRect();
if (count > 1 && rend_line) { if (count > 1 && rend_line) {
if (HasFlag(plot->XAxis.Flags, ImAxisFlags_LogScale) && HasFlag(plot->YAxis[y_axis].Flags, ImAxisFlags_LogScale)) if (HasFlag(plot->XAxis.Flags, ImPlotAxisFlags_LogScale) && HasFlag(plot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale))
RenderLines(Plt2PixLogLog(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); RenderLineStrip(Plt2PixLogLog(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull);
else if (HasFlag(plot->XAxis.Flags, ImAxisFlags_LogScale)) else if (HasFlag(plot->XAxis.Flags, ImPlotAxisFlags_LogScale))
RenderLines(Plt2PixLogLin(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); RenderLineStrip(Plt2PixLogLin(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull);
else if (HasFlag(plot->YAxis[y_axis].Flags, ImAxisFlags_LogScale)) else if (HasFlag(plot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale))
RenderLines(Plt2PixLinLog(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); RenderLineStrip(Plt2PixLinLog(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull);
else else
RenderLines(Plt2PixLinLin(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); RenderLineStrip(Plt2PixLinLin(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull);
} }
// render markers // render markers
if (gp.Style.Marker != ImMarker_None) { if (gp.Style.Marker != ImPlotMarker_None) {
if (HasFlag(plot->XAxis.Flags, ImAxisFlags_LogScale) && HasFlag(plot->YAxis[y_axis].Flags, ImAxisFlags_LogScale)) if (HasFlag(plot->XAxis.Flags, ImPlotAxisFlags_LogScale) && HasFlag(plot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale))
RenderMarkers(Plt2PixLogLog(y_axis), DrawList, getter, count, offset, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, cull); RenderMarkers(Plt2PixLogLog(y_axis), DrawList, getter, count, offset, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, cull);
else if (HasFlag(plot->XAxis.Flags, ImAxisFlags_LogScale)) else if (HasFlag(plot->XAxis.Flags, ImPlotAxisFlags_LogScale))
RenderMarkers(Plt2PixLogLin(y_axis), DrawList, getter, count, offset, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, cull); RenderMarkers(Plt2PixLogLin(y_axis), DrawList, getter, count, offset, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, cull);
else if (HasFlag(plot->YAxis[y_axis].Flags, ImAxisFlags_LogScale)) else if (HasFlag(plot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale))
RenderMarkers(Plt2PixLinLog(y_axis), DrawList, getter, count, offset, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, cull); RenderMarkers(Plt2PixLinLog(y_axis), DrawList, getter, count, offset, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, cull);
else else
RenderMarkers(Plt2PixLinLin(y_axis), DrawList, getter, count, offset, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, cull); RenderMarkers(Plt2PixLinLin(y_axis), DrawList, getter, count, offset, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, cull);
@ -2578,6 +2587,14 @@ inline void PlotDigitalEx(const char* label_id, Getter getter, int count, int of
if (gp.Style.Colors[ImPlotCol_Line].w != -1) if (gp.Style.Colors[ImPlotCol_Line].w != -1)
item->Color = gp.Style.Colors[ImPlotCol_Line]; item->Color = gp.Style.Colors[ImPlotCol_Line];
// find data extents
if (gp.FitThisFrame) {
for (int i = 0; i < count; ++i) {
ImVec2 p = getter(i);
FitPoint(ImVec2(p.x, 0));
}
}
ImGui::PushClipRect(gp.BB_Grid.Min, gp.BB_Grid.Max, true); ImGui::PushClipRect(gp.BB_Grid.Min, gp.BB_Grid.Max, true);
bool cull = HasFlag(gp.CurrentPlot->Flags, ImPlotFlags_CullData); bool cull = HasFlag(gp.CurrentPlot->Flags, ImPlotFlags_CullData);