mirror of
https://github.com/gwm17/implot.git
synced 2024-11-23 02:38:53 -05:00
prototyping tooltip support
This commit is contained in:
parent
24b543839b
commit
ab59051864
77
implot.cpp
77
implot.cpp
|
@ -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()!");
|
||||||
|
|
11
implot.h
11
implot.h
|
@ -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
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user