diff --git a/implot.cpp b/implot.cpp index 9ef88b2..d2ab549 100644 --- a/implot.cpp +++ b/implot.cpp @@ -579,7 +579,7 @@ void AddTicksLogarithmic(const ImPlotRange& range, int nMajor, ImPlotTickCollect } } -void AddTicksCustom(const double* values, const char** labels, int n, ImPlotTickCollection& ticks) { +void AddTicksCustom(const double* values, const char* const labels[], int n, ImPlotTickCollection& ticks) { for (int i = 0; i < n; ++i) { ImPlotTick tick(values[i], false, true); if (labels != NULL) { @@ -2201,21 +2201,21 @@ void FitNextPlotAxes(bool x, bool y, bool y2, bool y3) { gp.NextPlotData.FitY[2] = y3; } -void SetNextPlotTicksX(const double* values, int n_ticks, const char** labels, bool show_default) { +void SetNextPlotTicksX(const double* values, int n_ticks, const char* const labels[], bool show_default) { ImPlotContext& gp = *GImPlot; IM_ASSERT_USER_ERROR(gp.CurrentPlot == NULL, "SetNextPlotTicksX() needs to be called before BeginPlot()!"); gp.NextPlotData.ShowDefaultTicksX = show_default; AddTicksCustom(values, labels, n_ticks, gp.XTicks); } -void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char** labels, bool show_default) { +void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char* const labels[], bool show_default) { IM_ASSERT_USER_ERROR(n_ticks > 1, "The number of ticks must be greater than 1"); static ImVector buffer; FillRange(buffer, n_ticks, x_min, x_max); SetNextPlotTicksX(&buffer[0], n_ticks, labels, show_default); } -void SetNextPlotTicksY(const double* values, int n_ticks, const char** labels, bool show_default, int y_axis) { +void SetNextPlotTicksY(const double* values, int n_ticks, const char* const 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 < IMPLOT_Y_AXES, "y_axis needs to be between 0 and IMPLOT_Y_AXES"); @@ -2223,7 +2223,7 @@ void SetNextPlotTicksY(const double* values, int n_ticks, const char** labels, b AddTicksCustom(values, labels, n_ticks, gp.YTicks[y_axis]); } -void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char** 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, int y_axis) { IM_ASSERT_USER_ERROR(n_ticks > 1, "The number of ticks must be greater than 1"); static ImVector buffer; FillRange(buffer, n_ticks, y_min, y_max); diff --git a/implot.h b/implot.h index 6fabd6a..e92cf52 100644 --- a/implot.h +++ b/implot.h @@ -351,8 +351,8 @@ void PlotStems(const char* label_id, const float* xs, const float* ys, int count void PlotStems(const char* label_id, const double* xs, const double* ys, int count, double y_ref = 0, int offset = 0, int stride = sizeof(double)); // Plots a pie chart. If the sum of values > 1 or normalize is true, each value will be normalized. Center and radius are in plot units. #label_fmt can be set to NULL for no labels. -void PlotPieChart(const char** label_ids, const float* values, int count, float x, float y, float radius, bool normalize = false, const char* label_fmt = "%.1f", float angle0 = 90); -void PlotPieChart(const char** label_ids, const double* values, int count, double x, double y, double radius, bool normalize = false, const char* label_fmt = "%.1f", double angle0 = 90); +void PlotPieChart(const char* const label_ids[], const float* values, int count, float x, float y, float radius, bool normalize = false, const char* label_fmt = "%.1f", float angle0 = 90); +void PlotPieChart(const char* const label_ids[], const double* values, int count, double x, double y, double radius, bool normalize = false, const char* label_fmt = "%.1f", double angle0 = 90); // Plots a 2D heatmap chart. Values are expected to be in row-major order. #label_fmt can be set to NULL for no labels. void PlotHeatmap(const char* label_id, const float* values, int rows, int cols, float scale_min, float scale_max, const char* label_fmt = "%.1f", const ImPlotPoint& bounds_min = ImPlotPoint(0,0), const ImPlotPoint& bounds_max = ImPlotPoint(1,1)); @@ -383,12 +383,12 @@ void LinkNextPlotLimits(double* xmin, double* xmax, double* ymin, double* ymax, void FitNextPlotAxes(bool x = true, bool y = true, bool y2 = true, bool y3 = true); // Set the X axis ticks and optionally the labels for the next plot. -void SetNextPlotTicksX(const double* values, int n_ticks, const char** labels = NULL, bool show_default = false); -void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const char** labels = NULL, bool show_default = false); +void SetNextPlotTicksX(const double* values, int n_ticks, const char* const labels[] = NULL, bool show_default = false); +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. -void SetNextPlotTicksY(const double* values, int n_ticks, const char** labels = NULL, bool show_default = false, int y_axis = 0); -void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char** labels = NULL, bool show_default = false, int y_axis = 0); +void SetNextPlotTicksY(const double* values, int n_ticks, const char* const labels[] = NULL, bool show_default = false, int y_axis = 0); +void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char* const labels[] = NULL, bool show_default = false, int y_axis = 0); // 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. void SetPlotYAxis(int y_axis); diff --git a/implot_demo.cpp b/implot_demo.cpp index 767a6ef..4b8d8f6 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -1406,8 +1406,12 @@ void PlotCandlestick(const char* label_id, const double* xs, const double* opens namespace ImPlot { -struct BenchmarkItem { - BenchmarkItem() { +//----------------------------------------------------------------------------- +// BENCHMARK +//----------------------------------------------------------------------------- + +struct BenchData { + BenchData() { float y = (float)RandomRange(0,1); Data = new float[1000]; for (int i = 0; i < 1000; ++i) { @@ -1415,34 +1419,49 @@ struct BenchmarkItem { } Col = ImVec4((float)RandomRange(0,1),(float)RandomRange(0,1),(float)RandomRange(0,1),1); } - ~BenchmarkItem() { delete[] Data; } + ~BenchData() { delete[] Data; } float* Data; ImVec4 Col; }; +enum BenchMode { + Line = 0, + Shaded = 1, + Scatter = 2, + Bars = 3 +}; + +struct BenchRecord { + int Mode; + bool AA; + ImVector Data; +}; + void ShowBenchmarkTool() { - static const int max_lines = 500; - static BenchmarkItem items[max_lines]; + static const int max_items = 500; + static BenchData items[max_items]; static bool running = false; static int frames = 60; static int L = 0; static int F = 0; static double t1, t2; + static int mode = BenchMode::Line; + const char* names[] = {"Line","Shaded","Scatter","Bars"}; - static ImVector> records; + static ImVector records; if (running) { F++; if (F == frames) { t2 = ImGui::GetTime(); - records.back().push_back(ImPlotPoint(L, frames / (t2 - t1))); + records.back().Data.push_back(ImPlotPoint(L, frames / (t2 - t1))); L += 5; F = 0; t1 = ImGui::GetTime(); } - if (L > max_lines) { + if (L > max_items) { running = false; - L = max_lines; + L = max_items; } } @@ -1460,35 +1479,67 @@ void ShowBenchmarkTool() { if (ImGui::Button("Benchmark")) { running = true; L = F = 0; - records.push_back(ImVector()); - records.back().reserve(max_lines + 1); + records.push_back(BenchRecord()); + records.back().Data.reserve(max_items+1); + records.back().Mode = mode; + records.back().AA = ImPlot::GetStyle().AntiAliasedLines; t1 = ImGui::GetTime(); } ImGui::SameLine(); + ImGui::SetNextItemWidth(200); + ImGui::Combo("##Mode",&mode,names,4); + ImGui::SameLine(); + ImGui::Checkbox("Anti-Aliased Lines", &ImPlot::GetStyle().AntiAliasedLines); if (was_running) { ImGui::PopItemFlag(); ImGui::PopStyleVar(); } - ImGui::ProgressBar((float)L / (float)(max_lines - 1)); + ImGui::ProgressBar((float)L / (float)(max_items - 1)); ImPlot::SetNextPlotLimits(0,1000,0,1,ImGuiCond_Always); - if (ImPlot::BeginPlot("##Bench",NULL,NULL,ImVec2(-1,0),ImPlotFlags_NoChild,0,0,0,0)) { + if (ImPlot::BeginPlot("##Bench",NULL,NULL,ImVec2(-1,0),ImPlotFlags_NoChild | ImPlotFlags_CanvasOnly,ImPlotAxisFlags_NoDecorations,ImPlotAxisFlags_NoDecorations)) { if (running) { - for (int i = 0; i < L; ++i) { - ImGui::PushID(i); - ImPlot::SetNextLineStyle(items[i].Col); - ImPlot::PlotLine("##item", items[i].Data, 1000); - ImGui::PopID(); + if (mode == BenchMode::Line) { + for (int i = 0; i < L; ++i) { + ImGui::PushID(i); + ImPlot::SetNextLineStyle(items[i].Col); + ImPlot::PlotLine("##item", items[i].Data, 1000); + ImGui::PopID(); + } + } + else if (mode == BenchMode::Shaded) { + for (int i = 0; i < L; ++i) { + ImGui::PushID(i); + ImPlot::SetNextFillStyle(items[i].Col,0.5f); + ImPlot::PlotShaded("##item", items[i].Data, 1000); + ImGui::PopID(); + } + } + else if (mode == BenchMode::Scatter) { + for (int i = 0; i < L; ++i) { + ImGui::PushID(i); + ImPlot::SetNextLineStyle(items[i].Col); + ImPlot::PlotScatter("##item", items[i].Data, 1000); + ImGui::PopID(); + } + } + else if (mode == BenchMode::Bars) { + for (int i = 0; i < L; ++i) { + ImGui::PushID(i); + ImPlot::SetNextFillStyle(items[i].Col,0.5f); + ImPlot::PlotBars("##item", items[i].Data, 1000); + ImGui::PopID(); + } } } ImPlot::EndPlot(); } ImPlot::SetNextPlotLimits(0,500,0,500,ImGuiCond_Always); - static char buffer[8]; - if (ImPlot::BeginPlot("##Stats", "Lines (1,000 pts each)", "Framerate (Hz)", ImVec2(-1,0), ImPlotFlags_NoChild)) { + static char buffer[64]; + if (ImPlot::BeginPlot("##Stats", "Items (1,000 pts each)", "Framerate (Hz)", ImVec2(-1,0), ImPlotFlags_NoChild)) { for (int run = 0; run < records.size(); ++run) { - sprintf(buffer, "Run %d", run + 1); - ImPlot::PlotLine(buffer, records[run].Data, records[run].Size); + sprintf(buffer, "B%d-%s%s", run + 1, names[records[run].Mode], records[run].AA ? "-AA" : ""); + ImPlot::PlotLine(buffer, records[run].Data.Data, records[run].Data.Size); } ImPlot::EndPlot(); } diff --git a/implot_internal.h b/implot_internal.h index 757d084..29f3150 100644 --- a/implot_internal.h +++ b/implot_internal.h @@ -715,7 +715,7 @@ void AddTicksLogarithmic(const ImPlotRange& range, int nMajor, ImPlotTickCollect // Populates a list of ImPlotTicks with time formatted ticks. void AddTicksTime(const ImPlotRange& range, int nMajor, ImPlotTickCollection& ticks); // Populates a list of ImPlotTicks with custom spaced and labeled ticks -void AddTicksCustom(const double* values, const char** labels, int n, ImPlotTickCollection& ticks); +void AddTicksCustom(const double* values, const char* const labels[], int n, ImPlotTickCollection& ticks); //----------------------------------------------------------------------------- // [SECTION] Styling Utils diff --git a/implot_items.cpp b/implot_items.cpp index 87e3b6e..d2f119d 100644 --- a/implot_items.cpp +++ b/implot_items.cpp @@ -1427,7 +1427,7 @@ inline void RenderPieSlice(ImDrawList& DrawList, const ImPlotPoint& center, doub } template -void PlotPieChartEx(const char** label_ids, const T* values, int count, T x, T y, T radius, bool normalize, const char* fmt, T angle0) { +void PlotPieChartEx(const char* const label_ids[], const T* values, int count, T x, T y, T radius, bool normalize, const char* fmt, T angle0) { IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != NULL, "PlotPieChart() needs to be called between BeginPlot() and EndPlot()!"); ImDrawList & DrawList = *GetPlotDrawList(); T sum = 0; @@ -1477,12 +1477,12 @@ void PlotPieChartEx(const char** label_ids, const T* values, int count, T x, T y } // float -void PlotPieChart(const char** label_ids, const float* values, int count, float x, float y, float radius, bool normalize, const char* fmt, float angle0) { +void PlotPieChart(const char* const label_ids[], const float* values, int count, float x, float y, float radius, bool normalize, const char* fmt, float angle0) { return PlotPieChartEx(label_ids, values, count, x, y, radius, normalize, fmt, angle0); } // double -void PlotPieChart(const char** label_ids, const double* values, int count, double x, double y, double radius, bool normalize, const char* fmt, double angle0) { +void PlotPieChart(const char* const label_ids[], const double* values, int count, double x, double y, double radius, bool normalize, const char* fmt, double angle0) { return PlotPieChartEx(label_ids, values, count, x, y, radius, normalize, fmt, angle0); }