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:
ozlb 2020-05-04 11:14:44 +02:00 committed by GitHub
commit 9b157783c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 858 additions and 606 deletions

View File

@ -1,5 +1,5 @@
# 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 management, 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/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/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">
@ -8,7 +8,13 @@ ImPlot is an immediate mode plotting widget for [Dear ImGui](https://github.com/
## Features ## Features
- multiple plot types: line, scatter, vertical/horizontal bars, error bars, with more likely to come - multiple plot types:
- line
- scatter
- vertical/horizontal bars
- error bars
- pie charts
- and more likely to come
- mix/match multiple plot items on a single plot - mix/match multiple plot items on a single plot
- configurable axes ranges and scaling (linear/log) - configurable axes ranges and scaling (linear/log)
- reversible and lockable axes - reversible and lockable axes
@ -46,7 +52,7 @@ Just add `implot.h`, `implot.cpp`, and optionally `implot_demo.cpp` to your sour
**Q: Why?** **Q: Why?**
A: ImGui is an incredibly powerful tool for rapid prototyping and development, but provides only limited mechanisms for data visualation. Two dimensional plots are ubiquitous and useful to almost any application. Being able to visualize your data in real-time will give you insight and better understanding of your application. A: ImGui is an incredibly powerful tool for rapid prototyping and development, but provides only limited mechanisms for data visualization. Two dimensional plots are ubiquitous and useful to almost any application. Being able to visualize your data in real-time will give you insight and better understanding of your application.
**Q: Is ImPlot suitable for real-time plotting?** **Q: Is ImPlot suitable for real-time plotting?**
@ -54,13 +60,13 @@ A: Yes, within reason. You can plot tens to hundreds of thousands of points with
**Q: Can plot styles be modified?** **Q: Can plot styles be modified?**
A: Yes. Plot colors, palletes, and various styling variables can be pushed/popped or modified permantly on startup. A: Yes. Plot colors, palettes, and various styling variables can be pushed/popped or modified permanently on startup.
**Q: Does ImPlot support logarithmic scaling?** **Q: Does ImPlot support logarithmic scaling?**
A: Yep! A: Yep!
**Q: Does ImPlot support X plot types?** **Q: Does ImPlot support [insert plot type]?**
A: Maybe. Check the gallery and demo to see if your desired plot type is shown. If not, consider submitting an issue or better yet, a PR! A: Maybe. Check the gallery and demo to see if your desired plot type is shown. If not, consider submitting an issue or better yet, a PR!
@ -83,3 +89,8 @@ A: Yes, you can use the C binding, [cimplot](https://github.com/cimgui/cimplot)
## Special Notes ## 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. - 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. - 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.
## See Also
[ImPlot discussion](https://github.com/ocornut/imgui/issues/3173) - ImPlot discussion issue at the official ImGui repository
[imgui-plot](https://github.com/soulthreads/imgui-plot) - an alternate plotting widget by soulthreads

1356
implot.cpp

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@
// ImPlot v0.1 WIP // ImPlot v0.1 WIP
#pragma once #pragma once
#include "imgui.h" #include <imgui.h>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Basic types and flags // Basic types and flags
@ -47,7 +47,8 @@ enum ImPlotFlags_ {
ImPlotFlags_Crosshairs = 1 << 7, // the default mouse cursor will be replaced with a crosshair when hovered ImPlotFlags_Crosshairs = 1 << 7, // the default mouse cursor will be replaced with a crosshair when hovered
ImPlotFlags_CullData = 1 << 8, // plot data outside the plot area will be culled from rendering ImPlotFlags_CullData = 1 << 8, // plot data outside the plot area will be culled from rendering
ImPlotFlags_AntiAliased = 1 << 9, // lines and fills will be anti-aliased (not recommended) ImPlotFlags_AntiAliased = 1 << 9, // lines and fills will be anti-aliased (not recommended)
ImPlotFlags_Default = ImPlotFlags_MousePos | ImPlotFlags_Legend | ImPlotFlags_Highlight | ImPlotFlags_Selection | ImPlotFlags_ContextMenu | ImPlotFlags_Cursors | ImPlotFlags_CullData ImPlotFlags_NoChild = 1 << 10, // a child window region will not be used to capture mouse scroll (can boost performance for single ImGui window applications)
ImPlotFlags_Default = ImPlotFlags_MousePos | ImPlotFlags_Legend | ImPlotFlags_Highlight | ImPlotFlags_Selection | ImPlotFlags_ContextMenu | ImPlotFlags_CullData
}; };
// Options for plot axes (X and Y) // Options for plot axes (X and Y)
@ -158,6 +159,7 @@ void EndPlot();
// Plots a standard 2D line and/or scatter plot . // Plots a standard 2D line and/or scatter plot .
void Plot(const char* label_id, const float* values, int count, int offset = 0, int stride = sizeof(float)); void Plot(const char* label_id, const float* values, int count, int offset = 0, int stride = sizeof(float));
void Plot(const char* label_id, const float* xs, const float* ys, int count, int offset = 0, int stride = sizeof(float)); void Plot(const char* label_id, const float* xs, const float* ys, int count, int offset = 0, int stride = sizeof(float));
void Plot(const char* label_id, const ImVec2* data, int count, int offset = 0);
void Plot(const char* label_id, ImVec2 (*getter)(void* data, int idx), void* data, int count, int offset = 0); void Plot(const char* label_id, ImVec2 (*getter)(void* data, int idx), void* data, int count, int offset = 0);
// Plots vertical bars. // Plots vertical bars.
void PlotBar(const char* label_id, const float* values, int count, float width = 0.67f, float shift = 0, int offset = 0, int stride = sizeof(float)); void PlotBar(const char* label_id, const float* values, int count, float width = 0.67f, float shift = 0, int offset = 0, int stride = sizeof(float));
@ -171,6 +173,8 @@ void PlotBarH(const char* label_id, ImVec2 (*getter)(void* data, int idx), void*
void PlotErrorBars(const char* label_id, const float* xs, const float* ys, const float* err, int count, int offset = 0, int stride = sizeof(float)); void PlotErrorBars(const char* label_id, const float* xs, const float* ys, const float* err, int count, int offset = 0, int stride = sizeof(float));
void PlotErrorBars(const char* label_id, const float* xs, const float* ys, const float* neg, const float* pos, int count, int offset = 0, int stride = sizeof(float)); void PlotErrorBars(const char* label_id, const float* xs, const float* ys, const float* neg, const float* pos, int count, int offset = 0, int stride = sizeof(float));
void PlotErrorBars(const char* label_id, ImVec4 (*getter)(void* data, int idx), void* data, int count, int offset = 0); void PlotErrorBars(const char* label_id, ImVec4 (*getter)(void* data, int idx), void* data, int count, int offset = 0);
// Plots a pie chart. If the sum of values > 1, each value will be normalized. Center and radius are in plot coordinates.
void PlotPieChart(char** label_ids, float* values, int count, const ImVec2& center, float radius, bool show_percents = true, float angle0 = 90);
// Plots a text label at point x,y. // Plots a text label at point x,y.
void PlotLabel(const char* text, float x, float y, bool vertical = false, const ImVec2& pixel_offset = ImVec2(0,0)); void PlotLabel(const char* text, float x, float y, bool vertical = false, const ImVec2& pixel_offset = ImVec2(0,0));
// Plots digital channels. // Plots digital channels.

View File

@ -22,9 +22,9 @@
// 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 {
@ -59,7 +59,7 @@ 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));
@ -69,17 +69,15 @@ struct RollingData {
struct BenchmarkItem { struct BenchmarkItem {
BenchmarkItem() { BenchmarkItem() {
float y = RandomRange(0,1); float y = RandomRange(0,1);
Xs = new float[1000]; Data = new ImVec2[1000];
Ys = new float[1000];
for (int i = 0; i < 1000; ++i) { for (int i = 0; i < 1000; ++i) {
Xs[i] = i*0.001f; Data[i].x = i*0.001f;
Ys[i] = y + RandomRange(-0.01f,0.01f); Data[i].y = y + RandomRange(-0.01f,0.01f);
} }
Col = ImVec4(RandomRange(0,1),RandomRange(0,1),RandomRange(0,1),1); Col = ImVec4(RandomRange(0,1),RandomRange(0,1),RandomRange(0,1),1);
} }
~BenchmarkItem() { delete Xs; delete Ys; } ~BenchmarkItem() { delete Data; }
float* Xs; ImVec2* Data;
float* Ys;
ImVec4 Col; ImVec4 Col;
}; };
@ -89,11 +87,9 @@ namespace ImGui {
void ShowImPlotDemoWindow(bool* p_open) { void ShowImPlotDemoWindow(bool* p_open) {
//static DemoData data;
//ImVec2 main_viewport_pos = ImGui::GetMainViewport()->Pos; //ImVec2 main_viewport_pos = ImGui::GetMainViewport()->Pos;
//ImGui::SetNextWindowPos(ImVec2(main_viewport_pos.x + 650, main_viewport_pos.y + 20), ImGuiCond_FirstUseEver); ImGui::SetNextWindowPos(ImVec2(50, 50), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(520, 750), ImGuiCond_FirstUseEver);
ImGui::Begin("ImPlot Demo", p_open); ImGui::Begin("ImPlot Demo", p_open);
ImGui::Text("ImPlot says hello. (0.1 WIP)"); ImGui::Text("ImPlot says hello. (0.1 WIP)");
if (ImGui::CollapsingHeader("Help")) { if (ImGui::CollapsingHeader("Help")) {
@ -201,8 +197,8 @@ void ShowImPlotDemoWindow(bool* p_open) {
float xs[5] = {1,2,3,4,5}; float xs[5] = {1,2,3,4,5};
float lin[5] = {8,8,9,7,8}; float lin[5] = {8,8,9,7,8};
float bar[5] = {1,2,5,3,4}; float bar[5] = {1,2,5,3,4};
float err1[5] = {0.2, 0.4, 0.2, 0.6, 0.4}; float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f};
float err2[5] = {0.4, 0.2, 0.4, 0.8, 0.6}; float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f};
ImGui::SetNextPlotRange(0, 6, 0, 10); ImGui::SetNextPlotRange(0, 6, 0, 10);
if (ImGui::BeginPlot("##ErrorBars",NULL,NULL,ImVec2(-1,300))) { if (ImGui::BeginPlot("##ErrorBars",NULL,NULL,ImVec2(-1,300))) {
@ -220,6 +216,38 @@ void ShowImPlotDemoWindow(bool* p_open) {
ImGui::EndPlot(); ImGui::EndPlot();
} }
} }
//-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Pie Charts")) {
static char* labels1[] = {"Frogs","Hogs","Dogs","Logs"};
static float pre_normalized[] = {0.15f, 0.30f, 0.45f, 0.10f};
ImVec2 center(0.5f,0.5f); // in plot units, not pixels
float radius = 0.4f; // in plot units, not pixels
SetNextPlotRange(0,1,0,1,ImGuiCond_Always);
if (ImGui::BeginPlot("##Pie1", NULL, NULL, ImVec2(250,250), ImPlotFlags_Legend, 0, 0)) {
ImGui::PlotPieChart(labels1, pre_normalized, 4, center, radius);
ImGui::EndPlot();
}
ImGui::SameLine();
static ImVec4 YlOrRd[5] = {
{1.0000f, 1.0000f, 0.8000f, 1.0f},
{0.9961f, 0.8510f, 0.4627f, 1.0f},
{0.9961f, 0.6314f, 0.2627f, 1.0f},
{0.9882f, 0.3059f, 0.1647f, 1.0f},
{0.7412f, 0.0f, 0.1490f, 1.0f},
};
ImGui::SetPlotPalette(YlOrRd, 5);
SetNextPlotRange(0,1,0,1,ImGuiCond_Always);
static char* labels2[] = {"One","Two","Three","Four","Five"};
static float not_normalized[] = {1,2,3,4,5};
if (ImGui::BeginPlot("##Pie2", NULL, NULL, ImVec2(250,250), ImPlotFlags_Legend, 0, 0)) {
ImGui::PlotPieChart(labels2, not_normalized, 5, center, radius);
ImGui::EndPlot();
}
ImGui::RestorePlotPalette();
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
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!");
@ -682,12 +710,13 @@ void ShowImPlotDemoWindow(bool* p_open) {
static BenchmarkItem items[n_items]; static BenchmarkItem items[n_items];
ImGui::BulletText("Make sure VSync is disabled."); ImGui::BulletText("Make sure VSync is disabled.");
ImGui::BulletText("%d lines with %d points each @ %.3f FPS.",n_items,1000,ImGui::GetIO().Framerate); ImGui::BulletText("%d lines with %d points each @ %.3f FPS.",n_items,1000,ImGui::GetIO().Framerate);
if (ImGui::BeginPlot("##Bench",NULL,NULL,{-1,300})) { SetNextPlotRange(0,1,0,1, ImGuiCond_Always);
if (ImGui::BeginPlot("##Bench",NULL,NULL,{-1,300},ImPlotFlags_Default | ImPlotFlags_NoChild)) {
char buff[16]; char buff[16];
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
sprintf(buff, "item_%d",i); sprintf(buff, "item_%d",i);
ImGui::PushPlotColor(ImPlotCol_Line, items[i].Col); ImGui::PushPlotColor(ImPlotCol_Line, items[i].Col);
ImGui::Plot(buff, items[i].Xs, items[i].Ys, 1000, 0, 2 * sizeof(float)); ImGui::Plot(buff, items[i].Data, 1000);
ImGui::PopPlotColor(); ImGui::PopPlotColor();
} }
ImGui::EndPlot(); ImGui::EndPlot();