1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-26 20:28:50 -05:00

prototyping tooltip support

This commit is contained in:
epezent 2020-12-03 22:57:20 -06:00
parent 24b543839b
commit ab59051864
3 changed files with 97 additions and 3 deletions

View File

@ -2842,6 +2842,83 @@ bool DragPoint(const char* id, double* x, double* y, bool show_label, const ImVe
return dragging; return dragging;
} }
//-----------------------------------------------------------------------------
// TOOLTIPS
//-----------------------------------------------------------------------------
template <typename T>
T GetClosest(T val1, T val2, T target) {
if (target - val1 >= val2 - target)
return val2;
else
return val1;
}
template <typename T>
int FindClosestIdx(const T* arr, int n, T target) {
if (target <= arr[0])
return 0;
if (target >= arr[n - 1])
return n - 1;
int i = 0, j = n, mid = 0;
while (i < j) {
mid = (i + j) / 2;
if (arr[mid] == target)
return mid;
if (target < arr[mid]) {
if (mid > 0 && target > arr[mid - 1])
return (target - arr[mid - 1] >= arr[mid] - target) ? mid : mid - 1;
j = mid;
}
else {
if (mid < n - 1 && target < arr[mid + 1])
return (target - arr[mid] >= arr[mid+1] - target) ? mid + 1 : mid;
i = mid + 1;
}
}
return mid;
}
// bool BeginTooltip(const double* xs_mono, const double* ys, int* idx_out = NULL);
bool BeginTooltipX(const double* xs_mono, const double* ys, int count, int* idx_out) {
if (ImPlot::IsPlotHovered()) {
double mouse_x = ImPlot::GetPlotMousePos().x;
if (mouse_x < (double)xs_mono[0] || mouse_x > (double)xs_mono[count-1])
return false;
const int idx = FindClosestIdx(xs_mono, count, mouse_x);
PushPlotClipRect();
ImVec2 pos = PlotToPixels(xs_mono[idx], ys[idx]);
ImVec4 col = GetLastItemColor();
GetPlotDrawList()->AddCircleFilled(pos, 6, ImGui::ColorConvertFloat4ToU32(col));
PopPlotClipRect();
if (idx_out == NULL) {
ImGui::BeginTooltip();
ImGui::PushStyleColor(ImGuiCol_Text, col);
ImGui::Text("%.3f,%.3f",xs_mono[idx], ys[idx]);
ImGui::PopStyleColor();
ImGui::EndTooltip();
}
else {
*idx_out = idx;
}
return true;
}
return false;
}
void EndTooltip() {
}
// bool BeginTooltipY(const double* xs, const double* ys_mono, int* idx_out = NULL);
//-----------------------------------------------------------------------------
// LEGEND UTILS
//-----------------------------------------------------------------------------
void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation, bool outside) { void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation, bool outside) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "SetLegendLocation() needs to be called between BeginPlot() and EndPlot()!"); IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "SetLegendLocation() needs to be called between BeginPlot() and EndPlot()!");

View File

@ -531,6 +531,17 @@ IMPLOT_API bool DragLineY(const char* id, double* y_value, bool show_label = tru
// Shows a draggable point at x,y. #col defaults to ImGuiCol_Text. // Shows a draggable point at x,y. #col defaults to ImGuiCol_Text.
IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float radius = 4); IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float radius = 4);
// Facilitates adding hover tooltips to plots. If #idx_out is NULL, a default tooltip will be rendered. Otherwise, the value will be set to the hovered idx,
// and it becomes YOUR responsibility to render tooltip information using regular ImGui functions. You MUST make a matching call to EndTooltip if these
// functions return true!
IMPLOT_API bool BeginTooltip(const double* xs_mono, const double* ys, int count, int* idx_out = NULL);
// This variant is optimized to search along monotonically increasing x values (this is the one you want for time-series plots).
IMPLOT_API bool BeginTooltipX(const double* xs_mono, const double* ys, int count, int* idx_out = NULL);
// This variant is optimized to search along monotonically increasing y values.
IMPLOT_API bool BeginTooltipY(const double* xs, const double* ys_mono, int count, int* idx_out = NULL);
// Only call EndTooltip if BeginTooltip returns true! e.g. if (BeginTooltipX(...)) { ... EndTooltip(); }
IMPLOT_API void EndTooltip();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Legend Utils and Tools // Legend Utils and Tools
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -233,10 +233,10 @@ void ShowDemoWindow(bool* p_open) {
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Line Plots")) { if (ImGui::CollapsingHeader("Line Plots")) {
static float xs1[1001], ys1[1001]; static double xs1[1001], ys1[1001];
for (int i = 0; i < 1001; ++i) { for (int i = 0; i < 1001; ++i) {
xs1[i] = i * 0.001f; xs1[i] = i * 0.001f;
ys1[i] = 0.5f + 0.5f * sinf(50 * (xs1[i] + (float)DEMO_TIME / 10)); ys1[i] = 0.5 + 0.5 * sin(50 * (xs1[i] + (double)DEMO_TIME / 10));
} }
static double xs2[11], ys2[11]; static double xs2[11], ys2[11];
for (int i = 0; i < 11; ++i) { for (int i = 0; i < 11; ++i) {
@ -246,8 +246,12 @@ void ShowDemoWindow(bool* p_open) {
ImGui::BulletText("Anti-aliasing can be enabled from the plot's context menu (see Help)."); ImGui::BulletText("Anti-aliasing can be enabled from the plot's context menu (see Help).");
if (ImPlot::BeginPlot("Line Plot", "x", "f(x)")) { if (ImPlot::BeginPlot("Line Plot", "x", "f(x)")) {
ImPlot::PlotLine("sin(x)", xs1, ys1, 1001); ImPlot::PlotLine("sin(x)", xs1, ys1, 1001);
if (ImPlot::BeginTooltipX(xs1,ys1,1001))
ImPlot::EndTooltip();
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle); ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
ImPlot::PlotLine("x^2", xs2, ys2, 11); ImPlot::PlotLine("x^2", xs2, ys2, 11);
if (ImPlot::BeginTooltipX(xs2,ys2,11))
ImPlot::EndTooltip();
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
} }
@ -314,7 +318,7 @@ void ShowDemoWindow(bool* p_open) {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Scatter Plots")) { if (ImGui::CollapsingHeader("Scatter Plots")) {
srand(0); srand(0);
static float xs1[100], ys1[100]; static double xs1[100], ys1[100];
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
xs1[i] = i * 0.01f; xs1[i] = i * 0.01f;
ys1[i] = xs1[i] + 0.1f * ((float)rand() / (float)RAND_MAX); ys1[i] = xs1[i] + 0.1f * ((float)rand() / (float)RAND_MAX);
@ -327,6 +331,8 @@ void ShowDemoWindow(bool* p_open) {
if (ImPlot::BeginPlot("Scatter Plot", NULL, NULL)) { if (ImPlot::BeginPlot("Scatter Plot", NULL, NULL)) {
ImPlot::PlotScatter("Data 1", xs1, ys1, 100); ImPlot::PlotScatter("Data 1", xs1, ys1, 100);
if (ImPlot::BeginTooltipX(xs1,ys1,100))
ImPlot::EndTooltip();
ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f); ImPlot::PushStyleVar(ImPlotStyleVar_FillAlpha, 0.25f);
ImPlot::SetNextMarkerStyle(ImPlotMarker_Square, 6, ImVec4(0,1,0,0.5f), IMPLOT_AUTO, ImVec4(0,1,0,1)); ImPlot::SetNextMarkerStyle(ImPlotMarker_Square, 6, ImVec4(0,1,0,0.5f), IMPLOT_AUTO, ImVec4(0,1,0,1));
ImPlot::PlotScatter("Data 2", xs2, ys2, 50); ImPlot::PlotScatter("Data 2", xs2, ys2, 50);