1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-22 10:18:52 -05:00

Add ImPlotLegendFlags_Sort (#404)

* add ImPlotLegendFlags_Sort

* replace qsort_s with qsort
This commit is contained in:
Evan Pezent 2022-09-17 14:23:26 -05:00 committed by GitHub
parent 4ba42f200a
commit 3e13c95986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 28 deletions

View File

@ -31,7 +31,6 @@ The list below represents a combination of high-priority work, nice-to-have feat
## Legend
- `ImPlotLegendFlags_SortItems`
- `ImPlotLegendFlags_Scroll`
- improve legend icons (e.g. adopt markers, gradients, etc)
- make legend frame use ButtonBehavior (maybe impossible)

View File

@ -580,8 +580,8 @@ ImVec2 CalcLegendSize(ImPlotItemGroup& items, const ImVec2& pad, const ImVec2& s
return legend_size;
}
int LegendSortingComp(void* _items, const void* _a, const void* _b) {
ImPlotItemGroup* items = (ImPlotItemGroup*)_items;
int LegendSortingComp(const void* _a, const void* _b) {
ImPlotItemGroup* items = GImPlot->SortItems;
const int a = *(const int*)_a;
const int b = *(const int*)_b;
const char* label_a = items->GetLegendLabel(a);
@ -603,18 +603,18 @@ bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool hov
const int num_items = items.GetLegendCount();
if (num_items < 1)
return hovered;
// ImVector<int>& indices = GImPlot->TempInt1;
// indices.resize(num_items);
// // bool sort = true;
// // if (sort && num_items > 1) {
// // qsort_s(indices.Data, num_items, sizeof(int), LegendSortingComp, &items);
// // }
// // else {
// // for (int i = 0; i < num_items; ++i)
// // indices[i] = i;
// // }
// build render order
ImVector<int>& indices = GImPlot->TempInt1;
indices.resize(num_items);
for (int i = 0; i < num_items; ++i)
indices[i] = i;
if (ImHasFlag(items.Legend.Flags, ImPlotLegendFlags_Sort) && num_items > 1) {
GImPlot->SortItems = &items;
qsort(indices.Data, num_items, sizeof(int), LegendSortingComp);
}
// render
for (int i = 0; i < num_items; ++i) {
const int idx = i; //indices[i];
const int idx = indices[i];
ImPlotItem* item = items.GetLegendItem(idx);
const char* label = items.GetLegendLabel(idx);
const float label_width = ImGui::CalcTextSize(label, NULL, true).x;

View File

@ -191,6 +191,7 @@ enum ImPlotLegendFlags_ {
ImPlotLegendFlags_NoMenus = 1 << 3, // the user will not be able to open context menus with right-click
ImPlotLegendFlags_Outside = 1 << 4, // legend will be rendered outside of the plot area
ImPlotLegendFlags_Horizontal = 1 << 5, // legend entries will be displayed horizontally
ImPlotLegendFlags_Sort = 1 << 6, // legend entries will be displayed in alphabetical order
};
// Options for mouse hover text (see SetupMouseText)

View File

@ -1361,31 +1361,35 @@ void Demo_SubplotAxisLinking() {
void Demo_LegendOptions() {
static ImPlotLocation loc = ImPlotLocation_East;
static bool h = false; static bool o = true;
ImGui::CheckboxFlags("North", (unsigned int*)&loc, ImPlotLocation_North); ImGui::SameLine();
ImGui::CheckboxFlags("South", (unsigned int*)&loc, ImPlotLocation_South); ImGui::SameLine();
ImGui::CheckboxFlags("West", (unsigned int*)&loc, ImPlotLocation_West); ImGui::SameLine();
ImGui::CheckboxFlags("East", (unsigned int*)&loc, ImPlotLocation_East); ImGui::SameLine();
ImGui::Checkbox("Horizontal##2", &h); ImGui::SameLine();
ImGui::Checkbox("Outside", &o);
ImGui::CheckboxFlags("East", (unsigned int*)&loc, ImPlotLocation_East);
static ImPlotLegendFlags flags = 0;
CHECKBOX_FLAG(flags, ImPlotLegendFlags_Horizontal);
CHECKBOX_FLAG(flags, ImPlotLegendFlags_Outside);
CHECKBOX_FLAG(flags, ImPlotLegendFlags_Sort);
ImGui::SliderFloat2("LegendPadding", (float*)&GetStyle().LegendPadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("LegendInnerPadding", (float*)&GetStyle().LegendInnerPadding, 0.0f, 10.0f, "%.0f");
ImGui::SliderFloat2("LegendSpacing", (float*)&GetStyle().LegendSpacing, 0.0f, 5.0f, "%.0f");
if (ImPlot::BeginPlot("##Legend",ImVec2(-1,0))) {
ImPlotLegendFlags flags = ImPlotLegendFlags_None;
if (h) flags |= ImPlotLegendFlags_Horizontal;
if (o) flags |= ImPlotLegendFlags_Outside;
ImPlot::SetupLegend(loc, flags);
static MyImPlot::WaveData data1(0.001, 0.2, 2, 0.75);
static MyImPlot::WaveData data2(0.001, 0.2, 4, 0.25);
static MyImPlot::WaveData data3(0.001, 0.2, 6, 0.5);
ImPlot::PlotLineG("Item 1", MyImPlot::SineWave, &data1, 1000); // "Item 1" added to legend
ImPlot::PlotLineG("Item 2##IDText", MyImPlot::SawWave, &data2, 1000); // "Item 2" added to legend, text after ## used for ID only
static MyImPlot::WaveData data1(0.001, 0.2, 4, 0.2);
static MyImPlot::WaveData data2(0.001, 0.2, 4, 0.4);
static MyImPlot::WaveData data3(0.001, 0.2, 4, 0.6);
static MyImPlot::WaveData data4(0.001, 0.2, 4, 0.8);
static MyImPlot::WaveData data5(0.001, 0.2, 4, 1.0);
ImPlot::PlotLineG("Item B", MyImPlot::SawWave, &data1, 1000); // "Item B" added to legend
ImPlot::PlotLineG("Item A##IDText", MyImPlot::SawWave, &data2, 1000); // "Item A" added to legend, text after ## used for ID only
ImPlot::PlotLineG("##NotListed", MyImPlot::SawWave, &data3, 1000); // plotted, but not added to legend
ImPlot::PlotLineG("Item 3", MyImPlot::SineWave, &data1, 1000); // "Item 3" added to legend
ImPlot::PlotLineG("Item 3", MyImPlot::SawWave, &data2, 1000); // combined with previous "Item 3"
ImPlot::PlotLineG("Item C", MyImPlot::SawWave, &data4, 1000); // "Item C" added to legend
ImPlot::PlotLineG("Item C", MyImPlot::SawWave, &data5, 1000); // combined with previous "Item C"
ImPlot::EndPlot();
}
}

View File

@ -1244,6 +1244,7 @@ struct ImPlotContext {
ImPlotInputMap InputMap;
bool OpenContextThisFrame;
ImGuiTextBuffer MousePosStringBuilder;
ImPlotItemGroup* SortItems;
// Align plots
ImPool<ImPlotAlignmentData> AlignmentData;