diff --git a/implot.cpp b/implot.cpp index c32aaeb..6dc76a9 100644 --- a/implot.cpp +++ b/implot.cpp @@ -206,7 +206,7 @@ void SetCurrentContext(ImPlotContext* ctx) { void Initialize(ImPlotContext* ctx) { Reset(ctx); - SetColormapEx(ImPlotColormap_Default, 0, ctx); + ctx->Colormap = GetColormap(ImPlotColormap_Default, &ctx->ColormapSize); } void Reset(ImPlotContext* ctx) { @@ -1842,98 +1842,58 @@ void PopStyleVar(int count) { // COLORMAPS //------------------------------------------------------------------------------ -// Returns the size of the current colormap -int GetColormapSize() { + +void PushColormap(ImPlotColormap colormap) { ImPlotContext& gp = *GImPlot; - return gp.ColormapSize; + gp.ColormapModifiers.push_back(ImPlotColormapMod(gp.Colormap, gp.ColormapSize)); + gp.Colormap = GetColormap(colormap, &gp.ColormapSize); } -// Returns a color from the Color map given an index > 0 -ImVec4 GetColormapColor(int index) { +void PushColormap(const ImVec4* colormap, int size) { ImPlotContext& gp = *GImPlot; - IM_ASSERT_USER_ERROR(index >= 0, "The Colormap index must be greater than zero!"); - return gp.Colormap[index % gp.ColormapSize]; + gp.ColormapModifiers.push_back(ImPlotColormapMod(gp.Colormap, gp.ColormapSize)); + gp.Colormap = colormap; + gp.ColormapSize = size; } -ImVec4 LerpColormap(float t) { +void PopColormap(int count) { ImPlotContext& gp = *GImPlot; - float tc = ImClamp(t,0.0f,1.0f); - int i1 = (int)((gp.ColormapSize -1 ) * tc); - int i2 = i1 + 1; - if (i2 == gp.ColormapSize) - return gp.Colormap[i1]; - float t1 = (float)i1 / (float)(gp.ColormapSize - 1); - float t2 = (float)i2 / (float)(gp.ColormapSize - 1); - float tr = ImRemap(t, t1, t2, 0.0f, 1.0f); - return ImLerp(gp.Colormap[i1], gp.Colormap[i2], tr); -} - -ImVec4 NextColormapColor() { - ImPlotContext& gp = *GImPlot; - ImVec4 col = gp.Colormap[gp.CurrentPlot->ColormapIdx % gp.ColormapSize]; - gp.CurrentPlot->ColormapIdx++; - return col; -} - -void ShowColormapScale(double scale_min, double scale_max, float height) { - ImPlotContext& gp = *GImPlot; - static ImVector ticks; - static ImGuiTextBuffer txt_buff; - ImPlotRange range; - range.Min = scale_min; - range.Max = scale_max; - ticks.shrink(0); - txt_buff.Buf.shrink(0); - AddDefaultTicks(range, 10, 0, false, ticks); - LabelTicks(ticks, false, txt_buff); - float max_width = 0; - for (int i = 0; i < ticks.Size; ++i) - max_width = ticks[i].LabelSize.x > max_width ? ticks[i].LabelSize.x : max_width; - - ImGuiContext &G = *GImGui; - ImGuiWindow * Window = G.CurrentWindow; - if (Window->SkipItems) - return; - const ImGuiStyle &Style = G.Style; - const float txt_off = 5; - const float bar_w = 20; - - ImDrawList &DrawList = *Window->DrawList; - ImVec2 size(bar_w + txt_off + max_width + 2 * gp.Style.PlotPadding.x, height); - ImRect bb_frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + size); - ImGui::ItemSize(bb_frame); - if (!ImGui::ItemAdd(bb_frame, 0, &bb_frame)) - return; - ImGui::RenderFrame(bb_frame.Min, bb_frame.Max, ImGui::GetColorU32(ImGuiCol_FrameBg)); - ImRect bb_grad(bb_frame.Min + gp.Style.PlotPadding, bb_frame.Min + ImVec2(bar_w + gp.Style.PlotPadding.x, height - gp.Style.PlotPadding.y)); - - int num_cols = GetColormapSize(); - float h_step = (height - 2 * gp.Style.PlotPadding.y) / (num_cols - 1); - for (int i = 0; i < num_cols-1; ++i) { - ImRect rect(bb_grad.Min.x, bb_grad.Min.y + h_step * i, bb_grad.Max.x, bb_grad.Min.y + h_step * (i + 1)); - ImU32 col1 = ImGui::GetColorU32(GetColormapColor(num_cols - 1 - i)); - ImU32 col2 = ImGui::GetColorU32(GetColormapColor(num_cols - 1 - (i+1))); - DrawList.AddRectFilledMultiColor(rect.Min, rect.Max, col1, col1, col2, col2); + while (count > 0) { + const ImPlotColormapMod& backup = gp.ColormapModifiers.back(); + gp.Colormap = backup.Colormap; + gp.ColormapSize = backup.ColormapSize; + gp.ColormapModifiers.pop_back(); + count--; } - ImU32 col_border = gp.Style.Colors[ImPlotCol_PlotBorder].w == -1 ? ImGui::GetColorU32(ImGuiCol_Text, 0.5f) : ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_PlotBorder]); - - ImGui::PushClipRect(bb_frame.Min, bb_frame.Max, true); - for (int i = 0; i < ticks.Size; ++i) { - 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].LabelSize.y * 0.5f), ImGui::GetColorU32(ImGuiCol_Text), txt_buff.Buf.Data + ticks[i].BufferOffset); - } - ImGui::PopClipRect(); - - DrawList.AddRect(bb_grad.Min, bb_grad.Max, col_border); - } -void SetColormapEx(ImPlotColormap colormap, int samples, ImPlotContext* ctx) { - static int csizes[ImPlotColormap_COUNT] = {10,9,9,12,11,11,11,11,11,11}; - static ImOffsetCalculator coffs(csizes); - static ImVec4 cdata[] = { +void SetColormap(ImPlotColormap colormap, int samples) { + ImPlotContext& gp = *GImPlot; + gp.Colormap = GetColormap(colormap, &gp.ColormapSize); + if (samples > 1) { + static ImVector resampled; + resampled.resize(samples); + ResampleColormap(gp.Colormap, gp.ColormapSize, &resampled[0], samples); + SetColormap(&resampled[0], samples); + } +} + +void SetColormap(const ImVec4* colors, int size) { + ImPlotContext& gp = *GImPlot; + IM_ASSERT_USER_ERROR(size > 1, "The number of colors must be greater than 1!"); + static ImVector user_colormap; + user_colormap.shrink(0); + user_colormap.reserve(size); + for (int i = 0; i < size; ++i) + user_colormap.push_back(colors[i]); + gp.Colormap = &user_colormap[0]; + gp.ColormapSize = size; +} + +const ImVec4* GetColormap(ImPlotColormap colormap, int* size_out) { + static const int csizes[ImPlotColormap_COUNT] = {10,9,9,12,11,11,11,11,11,11}; + static const ImOffsetCalculator coffs(csizes); + static const ImVec4 cdata[] = { // ImPlotColormap_Default // X11 Named Colors ImVec4(0.0f, 0.7490196228f, 1.0f, 1.0f), // Blues::DeepSkyBlue, ImVec4(1.0f, 0.0f, 0.0f, 1.0f), // Reds::Red, @@ -2051,36 +2011,106 @@ void SetColormapEx(ImPlotColormap colormap, int samples, ImPlotContext* ctx) { ImVec4(1.0000f, 0.3333f, 0.f, 1.0f), ImVec4(1.0000f, 0.f, 0.f, 1.0f) }; - ctx->Colormap = &cdata[coffs.Offsets[colormap]]; - ctx->ColormapSize = csizes[colormap]; - if (samples > 1) { - static ImVector resampled; - resampled.resize(samples); - for (int i = 0; i < samples; ++i) { - float t = i * 1.0f / (samples - 1); - resampled[i] = LerpColormap(t); - } - SetColormapEx(&resampled[0], samples, ctx); + *size_out = csizes[colormap]; + return &cdata[coffs.Offsets[colormap]]; +} + +void ResampleColormap(const ImVec4* colormap_in, int size_in, ImVec4* colormap_out, int size_out) { + for (int i = 0; i < size_out; ++i) { + float t = i * 1.0f / (size_out - 1); + colormap_out[i] = LerpColormap(colormap_in, size_in, t); } } -void SetColormapEx(const ImVec4* colors, int num_colors, ImPlotContext* ctx) { - IM_ASSERT_USER_ERROR(num_colors > 1, "The number of colors must be greater than 1!"); - static ImVector user_colormap; - user_colormap.shrink(0); - user_colormap.reserve(num_colors); - for (int i = 0; i < num_colors; ++i) - user_colormap.push_back(colors[i]); - ctx->Colormap = &user_colormap[0]; - ctx->ColormapSize = num_colors; +int GetColormapSize() { + ImPlotContext& gp = *GImPlot; + return gp.ColormapSize; } -void SetColormap(ImPlotColormap colormap, int samples) { - SetColormapEx(colormap, samples, GImPlot); +ImVec4 GetColormapColor(int index) { + ImPlotContext& gp = *GImPlot; + IM_ASSERT_USER_ERROR(index >= 0, "The Colormap index must be greater than zero!"); + return gp.Colormap[index % gp.ColormapSize]; } -void SetColormap(const ImVec4* colors, int num_colors) { - SetColormapEx(colors, num_colors, GImPlot); +ImVec4 LerpColormap(const ImVec4* colormap, int size, float t) { + float tc = ImClamp(t,0.0f,1.0f); + int i1 = (int)((size -1 ) * tc); + int i2 = i1 + 1; + if (i2 == size) + return colormap[i1]; + float t1 = (float)i1 / (float)(size - 1); + float t2 = (float)i2 / (float)(size - 1); + float tr = ImRemap(t, t1, t2, 0.0f, 1.0f); + return ImLerp(colormap[i1], colormap[i2], tr); } +ImVec4 LerpColormap(float t) { + ImPlotContext& gp = *GImPlot; + return LerpColormap(gp.Colormap, gp.ColormapSize, t); +} + +ImVec4 NextColormapColor() { + ImPlotContext& gp = *GImPlot; + IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "NextColormapColor() needs to be called between BeginPlot() and EndPlot()!"); + ImVec4 col = gp.Colormap[gp.CurrentPlot->ColormapIdx % gp.ColormapSize]; + gp.CurrentPlot->ColormapIdx++; + return col; +} + +void ShowColormapScale(double scale_min, double scale_max, float height) { + ImPlotContext& gp = *GImPlot; + static ImVector ticks; + static ImGuiTextBuffer txt_buff; + ImPlotRange range; + range.Min = scale_min; + range.Max = scale_max; + ticks.shrink(0); + txt_buff.Buf.shrink(0); + AddDefaultTicks(range, 10, 0, false, ticks); + LabelTicks(ticks, false, txt_buff); + float max_width = 0; + for (int i = 0; i < ticks.Size; ++i) + max_width = ticks[i].LabelSize.x > max_width ? ticks[i].LabelSize.x : max_width; + + ImGuiContext &G = *GImGui; + ImGuiWindow * Window = G.CurrentWindow; + if (Window->SkipItems) + return; + const ImGuiStyle &Style = G.Style; + const float txt_off = 5; + const float bar_w = 20; + + ImDrawList &DrawList = *Window->DrawList; + ImVec2 size(bar_w + txt_off + max_width + 2 * gp.Style.PlotPadding.x, height); + ImRect bb_frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + size); + ImGui::ItemSize(bb_frame); + if (!ImGui::ItemAdd(bb_frame, 0, &bb_frame)) + return; + ImGui::RenderFrame(bb_frame.Min, bb_frame.Max, ImGui::GetColorU32(ImGuiCol_FrameBg)); + ImRect bb_grad(bb_frame.Min + gp.Style.PlotPadding, bb_frame.Min + ImVec2(bar_w + gp.Style.PlotPadding.x, height - gp.Style.PlotPadding.y)); + + int num_cols = GetColormapSize(); + float h_step = (height - 2 * gp.Style.PlotPadding.y) / (num_cols - 1); + for (int i = 0; i < num_cols-1; ++i) { + ImRect rect(bb_grad.Min.x, bb_grad.Min.y + h_step * i, bb_grad.Max.x, bb_grad.Min.y + h_step * (i + 1)); + ImU32 col1 = ImGui::GetColorU32(GetColormapColor(num_cols - 1 - i)); + ImU32 col2 = ImGui::GetColorU32(GetColormapColor(num_cols - 1 - (i+1))); + DrawList.AddRectFilledMultiColor(rect.Min, rect.Max, col1, col1, col2, col2); + } + ImU32 col_border = gp.Style.Colors[ImPlotCol_PlotBorder].w == -1 ? ImGui::GetColorU32(ImGuiCol_Text, 0.5f) : ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_PlotBorder]); + + ImGui::PushClipRect(bb_frame.Min, bb_frame.Max, true); + for (int i = 0; i < ticks.Size; ++i) { + 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].LabelSize.y * 0.5f), ImGui::GetColorU32(ImGuiCol_Text), txt_buff.Buf.Data + ticks[i].BufferOffset); + } + ImGui::PopClipRect(); + + DrawList.AddRect(bb_grad.Min, bb_grad.Max, col_border); +} + + } // namespace ImPlot diff --git a/implot.h b/implot.h index 6d67842..f00e7e6 100644 --- a/implot.h +++ b/implot.h @@ -267,6 +267,7 @@ void PlotShaded(const char* label_id, const float* xs, const float* ys, int coun void PlotShaded(const char* label_id, const double* xs, const double* ys, int count, double y_ref = 0, int offset = 0, int stride = sizeof(double)); void PlotShaded(const char* label_id, const float* xs, const float* ys1, const float* ys2, int count, int offset = 0, int stride = sizeof(float)); void PlotShaded(const char* label_id, const double* xs, const double* ys1, const double* ys2, int count, int offset = 0, int stride = sizeof(double)); +void PlotShaded(const char* label_id, ImPlotPoint (*getter1)(void* data, int idx), void* data1, ImPlotPoint (*getter2)(void* data, int idx), void* data2, int count, int offset = 0); // Plots a vertical bar graph. #width and #shift are in X units. void PlotBars(const char* label_id, const float* values, int count, float width = 0.67f, float shift = 0, int offset = 0, int stride = sizeof(float)); @@ -340,7 +341,7 @@ bool IsLegendEntryHovered(const char* label_id); ImPlotInputMap& GetInputMap(); //----------------------------------------------------------------------------- -// Plot Styling and Behaviour +// Plot Styling and Colormaps //----------------------------------------------------------------------------- // Provides access to plot style structure for permanant modifications to colors, sizes, etc. @@ -365,17 +366,24 @@ void PushStyleVar(ImPlotStyleVar idx, const ImVec2& val); // Undo temporary style modification. void PopStyleVar(int count = 1); -// Switch to one of the built-in colormaps. If samples is greater than 1, the map will be linearly resampled. +// Temporarily switch to one of the built-in colormaps. +void PushColormap(ImPlotColormap colormap); +// Temporarily switch to your custom colormap. The pointer data must persist until the matching call to PopColormap. +void PushColormap(const ImVec4* colormap, int size); +// Undo temporary colormap modification. +void PopColormap(int count = 1); +// Permanently sets a custom colormap. The colors will be copied to internal memory. Prefer PushColormap instead of calling this each frame. +void SetColormap(const ImVec4* colormap, int size); +// Permanently switch to one of the built-in colormaps. If samples is greater than 1, the map will be linearly resampled. Don't call this each frame. void SetColormap(ImPlotColormap colormap, int samples = 0); -// Sets a custom colormap. -void SetColormap(const ImVec4* colors, int num_colors); + // Returns the size of the current colormap. int GetColormapSize(); // Returns a color from the Color map given an index >= 0 (modulo will be performed) ImVec4 GetColormapColor(int index); // Linearly interpolates a color from the current colormap given t between 0 and 1. ImVec4 LerpColormap(float t); -// Returns the next unused colormap color and advances the colormap. Can be used to skip colors if desired. +// Returns the next unused colormap color and advances the colormap. Can be used to skip colors if desired. Call between BeginPlot/EndPlot. ImVec4 NextColormapColor(); //----------------------------------------------------------------------------- diff --git a/implot_demo.cpp b/implot_demo.cpp index d1303d8..dede5cb 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -375,7 +375,7 @@ void ShowDemoWindow(bool* p_open) { ImPlot::EndPlot(); } ImGui::SameLine(); - ImPlot::SetColormap(ImPlotColormap_Cool, 5); + ImPlot::PushColormap(ImPlotColormap_Pastel); SetNextPlotLimits(0,1,0,1,ImGuiCond_Always); static const char* labels2[] = {"A","B","C","D","E"}; static t_float data2[] = {1,1,2,3,5}; @@ -383,7 +383,7 @@ void ShowDemoWindow(bool* p_open) { ImPlot::PlotPieChart(labels2, data2, 5, 0.5f, 0.5f, 0.4f, true, "%.0f", 180); ImPlot::EndPlot(); } - ImPlot::SetColormap(ImPlotColormap_Default); + ImPlot::PopColormap(); } //------------------------------------------------------------------------- if (ImGui::CollapsingHeader("Heatmaps")) { @@ -403,7 +403,7 @@ void ShowDemoWindow(bool* p_open) { static ImPlotColormap map = ImPlotColormap_Viridis; if (ImGui::Button("Change Colormap",ImVec2(225,0))) map = (map + 1) % ImPlotColormap_COUNT; - ImPlot::SetColormap(map); + ImPlot::PushColormap(map); ImGui::SameLine(); ImGui::LabelText("##Colormap Index", "%s", cmap_names[map]); ImGui::SetNextItemWidth(225); @@ -421,17 +421,17 @@ void ShowDemoWindow(bool* p_open) { } ImGui::SameLine(); ImPlot::ShowColormapScale(scale_min, scale_max, 225); - ImPlot::SetColormap(ImPlotColormap_Default); + ImPlot::PopColormap(); ImGui::SameLine(); static ImVec4 gray[2] = {ImVec4(0,0,0,1), ImVec4(1,1,1,1)}; - ImPlot::SetColormap(&gray[0], 2); + ImPlot::PushColormap(&gray[0], 2); ImPlot::SetNextPlotLimits(-1,1,-1,1); if (ImPlot::BeginPlot("##Heatmap2",NULL,NULL,ImVec2(225,225),ImPlotFlags_ContextMenu,0,0)) { ImPlot::PlotHeatmap("heat1",values2,100,100,0,1,NULL); ImPlot::PlotHeatmap("heat2",values2,100,100,0,1,NULL, ImPlotPoint(-1,-1), ImPlotPoint(0,0)); ImPlot::EndPlot(); } - ImPlot::SetColormap(ImPlotColormap_Default); + ImPlot::PopColormap(); } //------------------------------------------------------------------------- if (ImGui::CollapsingHeader("Realtime Plots")) { @@ -485,7 +485,7 @@ void ShowDemoWindow(bool* p_open) { if (ImPlot::BeginPlot("##MarkerStyles", NULL, NULL, ImVec2(-1,0), 0, 0, 0)) { ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, mk_size); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerWeight, mk_weight); - ImPlot::SetColormap(map); + ImPlot::PushColormap(map); t_float xs[2] = {1,4}; t_float ys[2] = {10,11}; // filled @@ -558,7 +558,7 @@ void ShowDemoWindow(bool* p_open) { ImPlot::PlotText("Fancy Markers", 5.0f, 6.0f, true); ImGui::PopStyleColor(); - ImPlot::SetColormap(ImPlotColormap_Default); + ImPlot::PopColormap(); ImPlot::EndPlot(); } @@ -932,7 +932,7 @@ void ShowDemoWindow(bool* p_open) { ImGui::TableSetupColumn("Voltage", ImGuiTableColumnFlags_WidthFixed, 75.0f); ImGui::TableSetupColumn("EMG Signal"); ImGui::TableAutoHeaders(); - ImPlot::SetColormap(ImPlotColormap_Cool, 10); + ImPlot::PushColormap(ImPlotColormap_Cool); for (int row = 0; row < 10; row++) { @@ -950,7 +950,7 @@ void ShowDemoWindow(bool* p_open) { MyImPlot::Sparkline("##spark",data,100,0,11.0f,offset,ImPlot::GetColormapColor(row),ImVec2(-1, 35)); ImGui::PopID(); } - ImPlot::SetColormap(ImPlotColormap_Default); + ImPlot::PopColormap(); ImGui::EndTable(); } #else @@ -979,14 +979,14 @@ void ShowDemoWindow(bool* p_open) { ImGui::BulletText("Offsets can be negative and/or larger than the actual data count."); ImGui::SliderInt("Offset", &offset, -2*k_points_per, 2*k_points_per); if (ImPlot::BeginPlot("##strideoffset")) { - ImPlot::SetColormap(ImPlotColormap_Jet); + ImPlot::PushColormap(ImPlotColormap_Jet); char buff[16]; for (int c = 0; c < k_circles; ++c) { sprintf(buff, "Circle %d", c); ImPlot::PlotLine(buff, &interleaved_data[c*2 + 0], &interleaved_data[c*2 + 1], k_points_per, offset, 2*k_circles*sizeof(t_float)); } ImPlot::EndPlot(); - ImPlot::SetColormap(ImPlotColormap_Default); + ImPlot::PopColormap(); } // offset++; uncomment for animation! } @@ -1024,7 +1024,7 @@ void ShowDemoWindow(bool* p_open) { ImVec4(0.996f, 0.278f, 0.380f, 1.0f), ImVec4(0.1176470593f, 0.5647059083f, 1.0f, 1.0f), }; - ImPlot::SetColormap(my_map, 3); + ImPlot::PushColormap(my_map, 3); ImPlot::PushStyleColor(ImPlotCol_FrameBg, IM_COL32(32,51,77,255)); ImPlot::PushStyleColor(ImPlotCol_PlotBg, ImVec4(0,0,0,0)); ImPlot::PushStyleColor(ImPlotCol_PlotBorder, ImVec4(0,0,0,0)); @@ -1046,7 +1046,7 @@ void ShowDemoWindow(bool* p_open) { } ImPlot::PopStyleColor(5); ImPlot::PopStyleVar(); - ImPlot::SetColormap(ImPlotColormap_Default); + ImPlot::PopColormap(); } //------------------------------------------------------------------------- if (ImGui::CollapsingHeader("Custom Rendering")) { diff --git a/implot_internal.h b/implot_internal.h index de076dd..9314c16 100644 --- a/implot_internal.h +++ b/implot_internal.h @@ -113,7 +113,7 @@ inline int ImPosMod(int l, int r) { return (l % r + r) % r; } // Offset calculator helper template struct ImOffsetCalculator { - ImOffsetCalculator(int* sizes) { + ImOffsetCalculator(const int* sizes) { Offsets[0] = 0; for (int i = 1; i < Count; ++i) Offsets[i] = Offsets[i-1] + sizes[i-1]; @@ -157,6 +157,16 @@ struct ImArray { // [SECTION] ImPlot Structs //----------------------------------------------------------------------------- +// Storage for colormap modifiers +struct ImPlotColormapMod { + ImPlotColormapMod(const ImVec4* colormap, int colormap_size) { + Colormap = colormap; + ColormapSize = colormap_size; + } + const ImVec4* Colormap; + int ColormapSize; +}; + // ImPlotPoint with positive/negative error values struct ImPlotPointError { @@ -381,11 +391,12 @@ struct ImPlotContext { bool ChildWindowMade; // Style and Colormaps - ImPlotStyle Style; - ImVector ColorModifiers; - ImVector StyleModifiers; - ImVec4* Colormap; - int ColormapSize; + ImPlotStyle Style; + ImVector ColorModifiers; + ImVector StyleModifiers; + const ImVec4* Colormap; + int ColormapSize; + ImVector ColormapModifiers; // Misc int VisibleItemCount; @@ -458,13 +469,8 @@ float SumTickLabelHeight(const ImVector& 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); - // Updates axis ticks, lins, and label colors void UpdateAxisColor(int axis_flag, ImPlotAxisColor* col); -// Sets the colormap for a particular ImPlotContext -void SetColormapEx(ImPlotColormap colormap, int samples, ImPlotContext* ctx); -void SetColormapEx(const ImVec4* colors, int num_colors, ImPlotContext* ctx); - // Draws vertical text. The position is the bottom left of the text rect. void AddTextVertical(ImDrawList *DrawList, const char *text, ImVec2 pos, ImU32 text_color); // Calculates the size of vertical text @@ -513,10 +519,15 @@ inline T OffsetAndStride(const T* data, int idx, int count, int offset, int stri return *(const T*)(const void*)((const unsigned char*)data + (size_t)idx * stride); } +// Get built-in colormap data and size +const ImVec4* GetColormap(ImPlotColormap colormap, int* size_out); +// Linearly interpolates a color from the current colormap given t between 0 and 1. +ImVec4 LerpColormap(const ImVec4* colormap, int size, float t); +// Resamples a colormap. #size_out must be greater than 1. +void ResampleColormap(const ImVec4* colormap_in, int size_in, ImVec4* colormap_out, int size_out); + // Returns true if a style color is set to be automaticaly determined -inline bool ColorIsAuto(ImPlotCol idx) { - return GImPlot->Style.Colors[idx].w == -1; -} +inline bool ColorIsAuto(ImPlotCol idx) { return GImPlot->Style.Colors[idx].w == -1; } // Recolors an item legend icon from an the current ImPlotCol if it is not automatic (i.e. alpha != -1) inline void TryRecolorItem(ImPlotItem* item, ImPlotCol idx) { diff --git a/implot_items.cpp b/implot_items.cpp index a97a4dc..fb74700 100644 --- a/implot_items.cpp +++ b/implot_items.cpp @@ -847,6 +847,13 @@ void PlotShaded(const char* label_id, const double* xs, const double* ys, int co PlotShadedEx(label_id, getter1, getter2); } +// custom +void PlotShaded(const char* label_id, ImPlotPoint (*g1)(void* data, int idx), void* data1, ImPlotPoint (*g2)(void* data, int idx), void* data2, int count, int offset) { + GetterFuncPtrImPlotPoint getter1(g1, data1, count, offset); + GetterFuncPtrImPlotPoint getter2(g2, data2, count, offset); + PlotShadedEx(label_id, getter1, getter2); +} + //----------------------------------------------------------------------------- // PLOT BAR V //-----------------------------------------------------------------------------