1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-23 02:38:53 -05:00

Merge branch 'master' into master

This commit is contained in:
Evan Pezent 2020-04-30 09:09:32 -05:00 committed by GitHub
commit d32567fe15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 31 deletions

View File

@ -1,7 +1,10 @@
# ImPlot # ImPlot
ImPlot is an immediate mode plotting widget for [Dear ImGui](https://github.com/ocornut/imgui). It aims to provide a first-class API that will make ImGui users feel right at home. ImPlot is well suited for visualizing program data in real-time and requires minimal code to integrate. Just like ImGui, it does not burden the end user with GUI state managment, avoids STL containers and C++ headers, and has no external dependencies except for ImGui itself. ImPlot is an immediate mode plotting widget for [Dear ImGui](https://github.com/ocornut/imgui). It aims to provide a first-class API that will make ImGui users feel right at home. ImPlot is well suited for visualizing program data in real-time and requires minimal code to integrate. Just like ImGui, it does not burden the end user with GUI state managment, avoids STL containers and C++ headers, and has no external dependencies except for ImGui itself.
<img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/zoom_pan.gif" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/controls.gif" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/dnd.gif" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/controls.gif" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/dnd.gif" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/log.gif" width="285">
<img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/bar.gif" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/query.gif" width="285">
<img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/views.gif" width="285">
## Features ## Features
@ -39,10 +42,6 @@ Consult `implot_demo.cpp` for a comprehensive example of ImPlot's features.
Just add `implot.h`, `implot.cpp`, and optionally `implot_demo.cpp` to your sources. This assumes you already have an ImGui-ready environment. If not, consider trying [mahi-gui](https://github.com/mahilab/mahi-gui), which bundles ImGui, ImPlot, and several other packages for you. Just add `implot.h`, `implot.cpp`, and optionally `implot_demo.cpp` to your sources. This assumes you already have an ImGui-ready environment. If not, consider trying [mahi-gui](https://github.com/mahilab/mahi-gui), which bundles ImGui, ImPlot, and several other packages for you.
## Special Notes
- By default, no anti-aliasing is done on line plots for performance reasons. If you use 4x MSAA, then you likely won't even notice. However, you can re-enable AA with the `ImPlotFlags_AntiAliased` flag.
- If you plan to render several thousands lines or points, then you should consider enabling 32-bit indices by uncommenting `#define ImDrawIdx unsigned int` in your `imconfig.h` file, OR handling the `ImGuiBackendFlags_RendererHasVtxOffset` flag in your renderer (the official OpenGL3 renderer supports this). If you fail to do this, then you may at some point hit the maximum number of indices that can be rendered.
## FAQ ## FAQ
**Q: Why?** **Q: Why?**
@ -81,8 +80,6 @@ A: Not currently. Use your OS's screen capturing mechanisms if you need to captu
A: Yes, you can use the C binding, [cimplot](https://github.com/cimgui/cimplot) with most high level languages. A: Yes, you can use the C binding, [cimplot](https://github.com/cimgui/cimplot) with most high level languages.
## Gallery ## Special Notes
- By default, no anti-aliasing is done on line plots for performance reasons. If you use 4x MSAA, then you likely won't even notice. However, you can re-enable AA with the `ImPlotFlags_AntiAliased` flag.
<img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/line_plot.png" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/scatter_plot.png" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/bar_plot.png" width="285"> - If you plan to render several thousands lines or points, then you should consider enabling 32-bit indices by uncommenting `#define ImDrawIdx unsigned int` in your `imconfig.h` file, OR handling the `ImGuiBackendFlags_RendererHasVtxOffset` flag in your renderer (the official OpenGL3 renderer supports this). If you fail to do this, then you may at some point hit the maximum number of indices that can be rendered.
<img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/log_plot.png" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/error_bars.png" width="285"> <img src="https://raw.githubusercontent.com/wiki/epezent/implot/screenshots/markers.png" width="285">

View File

@ -260,6 +260,7 @@ struct ImNextPlotData {
struct ImPlotContext { struct ImPlotContext {
ImPlotContext() { ImPlotContext() {
CurrentPlot = NULL; CurrentPlot = NULL;
FitThisFrame = FitX = FitY = false;
RestorePlotPalette(); RestorePlotPalette();
} }
/// ALl Plots /// ALl Plots
@ -388,7 +389,7 @@ struct ImPlotContext {
// Data extents // Data extents
ImRect Extents; ImRect Extents;
bool FitThisFrame; bool FitThisFrame; bool FitX; bool FitY;
int VisibleItemCount; int VisibleItemCount;
// Render flags // Render flags
bool RenderX, RenderY; bool RenderX, RenderY;
@ -864,10 +865,17 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// DOUBLE CLICK ----------------------------------------------------------- // DOUBLE CLICK -----------------------------------------------------------
if ( IO.MouseDoubleClicked[0] && gp.Hov_Frame && gp.Hov_Grid && !hov_legend && !hov_query)
if ( IO.MouseDoubleClicked[0] && gp.Hov_Frame && (hov_x_axis_region || hov_y_axis_region) && !hov_legend && !hov_query) {
gp.FitThisFrame = true; gp.FitThisFrame = true;
else gp.FitX = hov_x_axis_region;
gp.FitY = hov_y_axis_region;
}
else {
gp.FitThisFrame = false; gp.FitThisFrame = false;
gp.FitX = false;
gp.FitY = false;
}
// FOCUS ------------------------------------------------------------------ // FOCUS ------------------------------------------------------------------
@ -1241,13 +1249,13 @@ void EndPlot() {
// FIT DATA -------------------------------------------------------------- // FIT DATA --------------------------------------------------------------
if (gp.FitThisFrame && (gp.VisibleItemCount > 0 || plot.Queried)) { if (gp.FitThisFrame && (gp.VisibleItemCount > 0 || plot.Queried)) {
if (!HasFlag(plot.XAxis.Flags, ImAxisFlags_LockMin) && !NanOrInf(gp.Extents.Min.x)) if (gp.FitX && !HasFlag(plot.XAxis.Flags, ImAxisFlags_LockMin) && !NanOrInf(gp.Extents.Min.x))
plot.XAxis.Min = gp.Extents.Min.x; plot.XAxis.Min = gp.Extents.Min.x;
if (!HasFlag(plot.XAxis.Flags, ImAxisFlags_LockMax) && !NanOrInf(gp.Extents.Max.x)) if (gp.FitX && !HasFlag(plot.XAxis.Flags, ImAxisFlags_LockMax) && !NanOrInf(gp.Extents.Max.x))
plot.XAxis.Max = gp.Extents.Max.x; plot.XAxis.Max = gp.Extents.Max.x;
if (!HasFlag(plot.YAxis.Flags, ImAxisFlags_LockMin) && !NanOrInf(gp.Extents.Min.y)) if (gp.FitY && !HasFlag(plot.YAxis.Flags, ImAxisFlags_LockMin) && !NanOrInf(gp.Extents.Min.y))
plot.YAxis.Min = gp.Extents.Min.y; plot.YAxis.Min = gp.Extents.Min.y;
if (!HasFlag(plot.YAxis.Flags, ImAxisFlags_LockMax) && !NanOrInf(gp.Extents.Max.y)) if (gp.FitY && !HasFlag(plot.YAxis.Flags, ImAxisFlags_LockMax) && !NanOrInf(gp.Extents.Max.y))
plot.YAxis.Max = gp.Extents.Max.y; plot.YAxis.Max = gp.Extents.Max.y;
} }

View File

@ -23,11 +23,16 @@
// ImPlot v0.1 WIP // ImPlot v0.1 WIP
#include <implot.h> #include <implot.h>
#include <imgui_internal.h> #include <math.h>
#include <iostream> #include <stdio.h>
namespace { namespace {
float RandomRange( float min, float max ) {
float scale = rand() / (float) RAND_MAX;
return min + scale * ( max - min );
}
struct ScrollingData { struct ScrollingData {
int MaxSize = 1000; int MaxSize = 1000;
int Offset = 0; int Offset = 0;
@ -54,18 +59,28 @@ struct RollingData {
ImVector<ImVec2> Data; ImVector<ImVec2> Data;
RollingData() { Data.reserve(1000); } RollingData() { Data.reserve(1000); }
void AddPoint(float x, float y) { void AddPoint(float x, float y) {
float xmod = ImFmod(x, Span); float xmod = fmodf(x, Span);
if (!Data.empty() && xmod < Data.back().x) if (!Data.empty() && xmod < Data.back().x)
Data.shrink(0); Data.shrink(0);
Data.push_back(ImVec2(xmod, y)); Data.push_back(ImVec2(xmod, y));
} }
}; };
// Put big data here struct BenchmarkItem {
struct DemoData { BenchmarkItem() {
DemoData() { float y = RandomRange(0,1);
Xs = new float[1000];
Ys = new float[1000];
for (int i = 0; i < 1000; ++i) {
Xs[i] = i*0.001f;
Ys[i] = y + RandomRange(-0.01f,0.01f);
} }
Col = ImVec4(RandomRange(0,1),RandomRange(0,1),RandomRange(0,1),1);
}
~BenchmarkItem() { delete Xs; delete Ys; }
float* Xs;
float* Ys;
ImVec4 Col;
}; };
} }
@ -84,9 +99,13 @@ void ShowImPlotDemoWindow(bool* p_open) {
if (ImGui::CollapsingHeader("Help")) { if (ImGui::CollapsingHeader("Help")) {
ImGui::Text("USER GUIDE:"); ImGui::Text("USER GUIDE:");
ImGui::BulletText("Left click and drag within the plot area to pan X and Y axes."); ImGui::BulletText("Left click and drag within the plot area to pan X and Y axes.");
ImGui::Indent();
ImGui::BulletText("Left click and drag on an axis to pan an individual axis."); ImGui::BulletText("Left click and drag on an axis to pan an individual axis.");
ImGui::Unindent();
ImGui::BulletText("Scroll in the plot area to zoom both X any Y axes."); ImGui::BulletText("Scroll in the plot area to zoom both X any Y axes.");
ImGui::Indent();
ImGui::BulletText("Scroll on an axis to zoom an individual axis."); ImGui::BulletText("Scroll on an axis to zoom an individual axis.");
ImGui::Unindent();
ImGui::BulletText("Right click and drag to box select data."); ImGui::BulletText("Right click and drag to box select data.");
ImGui::Indent(); ImGui::Indent();
ImGui::BulletText("Hold Alt to expand box selection horizontally."); ImGui::BulletText("Hold Alt to expand box selection horizontally.");
@ -99,6 +118,9 @@ void ShowImPlotDemoWindow(bool* p_open) {
ImGui::BulletText("Hold Shift to expand query vertically."); ImGui::BulletText("Hold Shift to expand query vertically.");
ImGui::Unindent(); ImGui::Unindent();
ImGui::BulletText("Double left click to fit all visible data."); ImGui::BulletText("Double left click to fit all visible data.");
ImGui::Indent();
ImGui::BulletText("Double left click on an axis to fit the individual axis.");
ImGui::Unindent();
ImGui::BulletText("Double right click to open the plot context menu."); ImGui::BulletText("Double right click to open the plot context menu.");
ImGui::BulletText("Click legend label icons to show/hide plot items."); ImGui::BulletText("Click legend label icons to show/hide plot items.");
} }
@ -201,6 +223,7 @@ void ShowImPlotDemoWindow(bool* p_open) {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Realtime Plots")) { if (ImGui::CollapsingHeader("Realtime Plots")) {
ImGui::BulletText("Move your mouse to change the data!"); ImGui::BulletText("Move your mouse to change the data!");
ImGui::BulletText("This example assumes 60 FPS. Higher FPS requires larger buffer size.");
static bool paused = false; static bool paused = false;
static ScrollingData sdata1, sdata2; static ScrollingData sdata1, sdata2;
static RollingData rdata1, rdata2; static RollingData rdata1, rdata2;
@ -654,9 +677,22 @@ void ShowImPlotDemoWindow(bool* p_open) {
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// if (ImGui::CollapsingHeader("Benchmark")) { if (ImGui::CollapsingHeader("Benchmark")) {
static const int n_items = 100;
// } static BenchmarkItem items[n_items];
ImGui::BulletText("Make sure VSync is disabled.");
ImGui::BulletText("%d lines with %d points each @ %.3f FPS.",n_items,1000,ImGui::GetIO().Framerate);
if (ImGui::BeginPlot("##Bench",NULL,NULL,{-1,300})) {
char buff[16];
for (int i = 0; i < 100; ++i) {
sprintf(buff, "item_%d",i);
ImGui::PushPlotColor(ImPlotCol_Line, items[i].Col);
ImGui::Plot(buff, items[i].Xs, items[i].Ys, 1000);
ImGui::PopPlotColor();
}
ImGui::EndPlot();
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
ImGui::End(); ImGui::End();