From 7170da86b2a5c352bdaa723afce51680142f627e Mon Sep 17 00:00:00 2001 From: Ruixiang Du Date: Sun, 27 Oct 2024 00:20:54 +0800 Subject: [PATCH] widget: added implot real-time line plot widget --- src/imview/CMakeLists.txt | 3 +- .../imview/buffer/buffer_interface.hpp | 4 + .../include/imview/buffer/double_buffer.hpp | 2 + .../include/imview/buffer/ring_buffer.hpp | 2 +- ...a_buffer.hpp => scrolling_plot_buffer.hpp} | 16 +-- .../imview/widget/rt_line_plot_widget.hpp | 63 +++++++++ src/imview/src/buffer/data_buffer.cpp | 50 ------- .../src/buffer/scrolling_plot_buffer.cpp | 48 +++++++ src/imview/src/widget/rt_line_plot_widget.cpp | 126 ++++++++++++++++++ src/imview/test/feature/CMakeLists.txt | 3 + src/imview/test/feature/test_cairo_widget.cpp | 4 - .../test/feature/test_implot_widget.cpp | 95 +++++++++++++ src/third_party/imcore/CMakeLists.txt | 1 + .../imcore/sample/implot_sample.cpp | 88 ++++++------ 14 files changed, 397 insertions(+), 108 deletions(-) rename src/imview/include/imview/buffer/{data_buffer.hpp => scrolling_plot_buffer.hpp} (71%) create mode 100644 src/imview/include/imview/widget/rt_line_plot_widget.hpp delete mode 100644 src/imview/src/buffer/data_buffer.cpp create mode 100644 src/imview/src/buffer/scrolling_plot_buffer.cpp create mode 100644 src/imview/src/widget/rt_line_plot_widget.cpp create mode 100644 src/imview/test/feature/test_implot_widget.cpp diff --git a/src/imview/CMakeLists.txt b/src/imview/CMakeLists.txt index a403e97..293a655 100644 --- a/src/imview/CMakeLists.txt +++ b/src/imview/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(imview src/box.cpp src/layer.cpp # src/popup.cpp - # src/data_buffer.cpp + src/buffer/scrolling_plot_buffer.cpp # utils src/utils/image_utils.cpp # widgets @@ -28,6 +28,7 @@ add_library(imview src/widget/cairo_widget.cpp src/widget/cairo/cairo_context.cpp src/widget/cairo/cairo_draw.cpp + src/widget/rt_line_plot_widget.cpp # data buffer src/buffer/buffer_registry.cpp # event handling diff --git a/src/imview/include/imview/buffer/buffer_interface.hpp b/src/imview/include/imview/buffer/buffer_interface.hpp index cbda649..555b485 100644 --- a/src/imview/include/imview/buffer/buffer_interface.hpp +++ b/src/imview/include/imview/buffer/buffer_interface.hpp @@ -21,6 +21,10 @@ class BufferBase { template class BufferInterface : public BufferBase { public: + /// \brief Get the number of bytes that can be read from the buffer + /// \return number of bytes that can be read + virtual std::size_t GetOccupiedSize() const = 0; + /// \brief Read data from the buffer /// \param data /// \return 0 if failed, otherwise the number of bytes read (1) diff --git a/src/imview/include/imview/buffer/double_buffer.hpp b/src/imview/include/imview/buffer/double_buffer.hpp index 220f8e1..aa59719 100644 --- a/src/imview/include/imview/buffer/double_buffer.hpp +++ b/src/imview/include/imview/buffer/double_buffer.hpp @@ -21,6 +21,8 @@ class DoubleBuffer : public BufferInterface { public: DoubleBuffer() : write_index_(0), ready_(false) {} + std::size_t GetOccupiedSize() const override { return ready_.load() ? 1 : 0; } + std::size_t Write(const T& data) { { std::lock_guard lock(mutex_); diff --git a/src/imview/include/imview/buffer/ring_buffer.hpp b/src/imview/include/imview/buffer/ring_buffer.hpp index 4e36dea..8cc43d4 100644 --- a/src/imview/include/imview/buffer/ring_buffer.hpp +++ b/src/imview/include/imview/buffer/ring_buffer.hpp @@ -99,7 +99,7 @@ class RingBuffer : public BufferInterface { return N - 1 - ((write_index_ - read_index_) & size_mask_); } - std::size_t GetOccupiedSize() const { + std::size_t GetOccupiedSize() const override { std::lock_guard lock(buffer_mutex_); return (write_index_ - read_index_) & size_mask_; }; diff --git a/src/imview/include/imview/buffer/data_buffer.hpp b/src/imview/include/imview/buffer/scrolling_plot_buffer.hpp similarity index 71% rename from src/imview/include/imview/buffer/data_buffer.hpp rename to src/imview/include/imview/buffer/scrolling_plot_buffer.hpp index 3fd264f..20f6266 100644 --- a/src/imview/include/imview/buffer/data_buffer.hpp +++ b/src/imview/include/imview/buffer/scrolling_plot_buffer.hpp @@ -1,5 +1,5 @@ /* - * data_buffer.hpp + * scrolling_plot_buffer.hpp * * Created on: Mar 25, 2021 14:29 * Description: adapted from class ScrollingBuffer from implot_demo.cpp @@ -7,8 +7,8 @@ * Copyright (c) 2021 Ruixiang Du (rdu) */ -#ifndef PLOT_BUFFER_HPP -#define PLOT_BUFFER_HPP +#ifndef SCROLLING_PLOT_BUFFER_HPP +#define SCROLLING_PLOT_BUFFER_HPP #include #include @@ -17,10 +17,9 @@ #include "imgui.h" namespace quickviz { -namespace swviz { -class DataBuffer { +class ScrollingPlotBuffer { public: - DataBuffer(uint32_t size = 2048); + ScrollingPlotBuffer(uint32_t size = 2048); void Resize(uint32_t size); std::size_t GetSize() const; @@ -36,7 +35,6 @@ class DataBuffer { uint32_t buffer_size_ = 0; uint32_t offset_ = 0; }; -} // namespace swviz -} // namespace xmotion +} // namespace quickviz -#endif /* PLOT_BUFFER_HPP */ +#endif /* SCROLLING_PLOT_BUFFER_HPP */ diff --git a/src/imview/include/imview/widget/rt_line_plot_widget.hpp b/src/imview/include/imview/widget/rt_line_plot_widget.hpp new file mode 100644 index 0000000..026d80e --- /dev/null +++ b/src/imview/include/imview/widget/rt_line_plot_widget.hpp @@ -0,0 +1,63 @@ +/* + * @file rt_line_plot_widget.hpp + * @date 10/26/24 + * @brief this LinePlotWidget serves as an example of how to create a custom + * widget that plots data in real-time + * + * @copyright Copyright (c) 2024 Ruixiang Du (rdu) + */ + +#ifndef QUICKVIZ_RT_LINE_PLOT_WIDGET_HPP +#define QUICKVIZ_RT_LINE_PLOT_WIDGET_HPP + +#include + +#include "imview/panel.hpp" +#include "imview/buffer/buffer_registry.hpp" +#include "imview/buffer/scrolling_plot_buffer.hpp" + +namespace quickviz { +class RtLinePlotWidget : public Panel { + public: + struct DataPoint { + float x; // time + float y; // value + }; + + public: + RtLinePlotWidget(const std::string& widget_name); + ~RtLinePlotWidget() = default; + + // public methods + void SetPlotTransparency(float alpha); + void SetAxisLabels(const std::string& x_label, const std::string& y_label); + void SetAxisUnits(const std::string& x_unit, const std::string& y_unit); + void SetFixedHistory(float history); + void SetYAxisRange(float min, float max); + void AddLine(const std::string& line_name, const std::string& buffer_name); + + // for internal use + void Draw() override; + + private: + struct PlotSpecs { + std::string name; + ScrollingPlotBuffer internal_buffer; + std::shared_ptr> input_buffer; + }; + + float alpha_ = 1.0f; + std::string x_label_; + std::string y_label_; + std::string x_unit_; + std::string y_unit_; + float t_ = 0; + bool fixed_history_ = true; + float history_ = 10.0f; + float y_min_ = 0; + float y_max_ = 1; + std::unordered_map line_specs_; +}; +} // namespace quickviz + +#endif // QUICKVIZ_RT_LINE_PLOT_WIDGET_HPP \ No newline at end of file diff --git a/src/imview/src/buffer/data_buffer.cpp b/src/imview/src/buffer/data_buffer.cpp deleted file mode 100644 index c3185e1..0000000 --- a/src/imview/src/buffer/data_buffer.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * data_buffer.cpp - * - * Created on: Mar 25, 2021 17:39 - * Description: - * - * Copyright (c) 2021 Ruixiang Du (rdu) - */ - -#include "imview/data_buffer.hpp" - -#include - -namespace quickviz { -namespace swviz { -DataBuffer::DataBuffer(uint32_t size) : buffer_size_(size) { - data_.reserve(size); -} - -void DataBuffer::Resize(uint32_t size) { - data_.reserve(size); - buffer_size_ = size; -} - -std::size_t DataBuffer::GetSize() const { return data_.size(); } - -std::size_t DataBuffer::GetOffset() const { return offset_; } - -void DataBuffer::Erase() { - if (data_.size() > 0) { - data_.shrink(0); - offset_ = 0; - } -} - -void DataBuffer::AddPoint(float x, float y) { - if (data_.size() < buffer_size_) - data_.push_back(ImVec2(x, y)); - else { - data_[offset_] = ImVec2(x, y); - offset_ = (offset_ + 1) % buffer_size_; - } -} - -ImVec2 &DataBuffer::operator[](std::size_t index) { - assert(index < data_.size()); - return data_[index]; -} -} // namespace swviz -} // namespace xmotion \ No newline at end of file diff --git a/src/imview/src/buffer/scrolling_plot_buffer.cpp b/src/imview/src/buffer/scrolling_plot_buffer.cpp new file mode 100644 index 0000000..bc2c5ba --- /dev/null +++ b/src/imview/src/buffer/scrolling_plot_buffer.cpp @@ -0,0 +1,48 @@ +/* + * scrolling_plot_buffer.cpp + * + * Created on: Mar 25, 2021 17:39 + * Description: + * + * Copyright (c) 2021 Ruixiang Du (rdu) + */ + +#include "imview/buffer/scrolling_plot_buffer.hpp" + +#include + +namespace quickviz { +ScrollingPlotBuffer::ScrollingPlotBuffer(uint32_t size) : buffer_size_(size) { + data_.reserve(size); +} + +void ScrollingPlotBuffer::Resize(uint32_t size) { + data_.reserve(size); + buffer_size_ = size; +} + +std::size_t ScrollingPlotBuffer::GetSize() const { return data_.size(); } + +std::size_t ScrollingPlotBuffer::GetOffset() const { return offset_; } + +void ScrollingPlotBuffer::Erase() { + if (data_.size() > 0) { + data_.shrink(0); + offset_ = 0; + } +} + +void ScrollingPlotBuffer::AddPoint(float x, float y) { + if (data_.size() < buffer_size_) + data_.push_back(ImVec2(x, y)); + else { + data_[offset_] = ImVec2(x, y); + offset_ = (offset_ + 1) % buffer_size_; + } +} + +ImVec2 &ScrollingPlotBuffer::operator[](std::size_t index) { + assert(index < data_.size()); + return data_[index]; +} +} // namespace quickviz \ No newline at end of file diff --git a/src/imview/src/widget/rt_line_plot_widget.cpp b/src/imview/src/widget/rt_line_plot_widget.cpp new file mode 100644 index 0000000..6c82d85 --- /dev/null +++ b/src/imview/src/widget/rt_line_plot_widget.cpp @@ -0,0 +1,126 @@ +/* + * @file line_plot_widget.cpp + * @date 10/26/24 + * @brief + * + * @copyright Copyright (c) 2024 Ruixiang Du (rdu) + */ + +#include "imview/widget/rt_line_plot_widget.hpp" + +#include +#include + +#include "implot/implot.h" + +namespace quickviz { +RtLinePlotWidget::RtLinePlotWidget(const std::string& widget_name) + : Panel(widget_name) { + this->SetAutoLayout(false); + this->SetWindowNoMenuButton(); + this->SetNoBackground(true); +} + +void RtLinePlotWidget::SetPlotTransparency(float alpha) { alpha_ = alpha; } + +void RtLinePlotWidget::SetAxisLabels(const std::string& x_label, + const std::string& y_label) { + x_label_ = x_label; + y_label_ = y_label; +} + +void RtLinePlotWidget::SetAxisUnits(const std::string& x_unit, + const std::string& y_unit) { + x_unit_ = x_unit; + y_unit_ = y_unit; +} + +void RtLinePlotWidget::SetFixedHistory(float history) { + fixed_history_ = true; + history_ = history; +} + +void RtLinePlotWidget::SetYAxisRange(float min, float max) { + y_min_ = min; + y_max_ = max; +} + +void RtLinePlotWidget::AddLine(const std::string& line_name, + const std::string& buffer_name) { + line_specs_[line_name].name = line_name; + line_specs_[line_name].internal_buffer = ScrollingPlotBuffer(); + auto& buffer_registry = BufferRegistry::GetInstance(); + line_specs_[line_name].input_buffer = + buffer_registry.GetBuffer(buffer_name); +} + +void RtLinePlotWidget::Draw() { + Begin(); + { + ImVec2 contentSize = ImGui::GetContentRegionAvail(); + float width = contentSize.x; + float height = contentSize.y; + + // fetch data from buffer and find the latest time + for (auto& line : line_specs_) { + auto& spec = line.second; + auto size = spec.input_buffer->GetOccupiedSize(); + for (int i = 0; i < size; i++) { + DataPoint pt; + if (spec.input_buffer->Read(pt) != 0) { + if (pt.x > t_) t_ = pt.x; + spec.internal_buffer.AddPoint(pt.x, pt.y); + } + } + } + + static ImPlotAxisFlags flags = + ImPlotAxisFlags_None; // ImPlotAxisFlags_NoTickLabels; + + auto frame_bg = ImGui::GetStyleColorVec4(ImGuiCol_FrameBg); + auto plot_bg = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg); + auto popup_bg = ImGui::GetStyleColorVec4(ImGuiCol_PopupBg); + frame_bg.w = alpha_; + plot_bg.w = alpha_; + popup_bg.w = alpha_; + ImPlot::PushStyleColor(ImPlotCol_FrameBg, frame_bg); + ImPlot::PushStyleColor(ImPlotCol_PlotBg, plot_bg); + ImPlot::PushStyleColor(ImPlotCol_LegendBg, popup_bg); + { + float plot_height = height - ImGui::GetFrameHeight() * 1.4; + if (fixed_history_) plot_height = height; + if (ImPlot::BeginPlot(("##" + GetName()).c_str(), + ImVec2(-1, plot_height))) { + char* x_label = nullptr; + char* y_label = nullptr; + if (!x_label_.empty()) x_label = &x_label_[0]; + if (!y_label_.empty()) y_label = &y_label_[0]; + ImPlot::SetupAxes(x_label, y_label, flags, flags); + if (!x_unit_.empty()) + ImPlot::SetupAxisFormat(ImAxis_X1, ("%g " + x_unit_).c_str()); + if (!y_unit_.empty()) + ImPlot::SetupAxisFormat(ImAxis_Y1, ("%g " + y_unit_).c_str()); + ImPlot::SetupAxisLimits(ImAxis_X1, t_ - history_, t_, ImGuiCond_Always); + ImPlot::SetupAxisLimits(ImAxis_Y1, y_min_, y_max_); + + for (auto& line : line_specs_) { + auto& spec = line.second; + if (spec.internal_buffer.GetSize() == 0) continue; + ImPlot::PlotLine(spec.name.c_str(), &spec.internal_buffer[0].x, + &spec.internal_buffer[0].y, + spec.internal_buffer.GetSize(), 0, + spec.internal_buffer.GetOffset(), 2 * sizeof(float)); + } + ImPlot::EndPlot(); + } + + if (!fixed_history_) { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 60); + ImGui::SliderFloat("History", &history_, 1, 30, "%.1f s"); + } + } + ImPlot::PopStyleColor(3); + } + End(); +} +} // namespace quickviz \ No newline at end of file diff --git a/src/imview/test/feature/CMakeLists.txt b/src/imview/test/feature/CMakeLists.txt index e01e040..eeb5854 100644 --- a/src/imview/test/feature/CMakeLists.txt +++ b/src/imview/test/feature/CMakeLists.txt @@ -12,3 +12,6 @@ target_link_libraries(test_buffered_cv_image_widget PRIVATE imview) add_executable(test_cairo_widget test_cairo_widget.cpp) target_link_libraries(test_cairo_widget PRIVATE imview) + +add_executable(test_implot_widget test_implot_widget.cpp) +target_link_libraries(test_implot_widget PRIVATE imview) diff --git a/src/imview/test/feature/test_cairo_widget.cpp b/src/imview/test/feature/test_cairo_widget.cpp index e1b3fe5..8b842a7 100644 --- a/src/imview/test/feature/test_cairo_widget.cpp +++ b/src/imview/test/feature/test_cairo_widget.cpp @@ -15,8 +15,6 @@ #include "imview/viewer.hpp" #include "imview/widget/cairo_widget.hpp" -#include "scene_objects/gl_triangle_scene_object.hpp" - using namespace quickviz; void PaintUnifiedCoordinate(cairo_t* cr, float aspect_ratio) { @@ -69,8 +67,6 @@ void Paint(cairo_t* cr, float aspect_ratio) { int main(int argc, char* argv[]) { Viewer viewer; -// auto gl_triangle = std::make_shared(); -// viewer.AddSceneObject(gl_triangle); auto cairo_widget = std::make_shared("cairo_unified", true); cairo_widget->OnResize(300, 200); diff --git a/src/imview/test/feature/test_implot_widget.cpp b/src/imview/test/feature/test_implot_widget.cpp new file mode 100644 index 0000000..424f7ad --- /dev/null +++ b/src/imview/test/feature/test_implot_widget.cpp @@ -0,0 +1,95 @@ +/* + * test_cairo_widget.cpp + * + * Created on: Jul 27, 2021 09:07 + * Description: + * + * Copyright (c) 2021 Ruixiang Du (rdu) + */ + +#include +#include + +#include + +#include "imview/buffer/buffer_registry.hpp" +#include "imview/buffer/ring_buffer.hpp" + +#include "imview/viewer.hpp" +#include "imview/widget/rt_line_plot_widget.hpp" +#include "scene_objects/gl_triangle_scene_object.hpp" + +using namespace quickviz; + +bool keep_running = true; + +std::string pt_buffer_name = "data_buffer"; +std::string pt_buffer_sin_name = "sin_data_buffer"; + +void DataGenerator() { + auto& buffer_registry = BufferRegistry::GetInstance(); + auto pt_buffer = + buffer_registry.GetBuffer(pt_buffer_name); + auto pt_buffer_sin = buffer_registry.GetBuffer( + pt_buffer_sin_name); + + static float t = 0; + int period_ms = 1000 / 60; + while (keep_running) { + ImVec2 mouse = ImGui::GetMousePos(); + t += period_ms / 1000.0; + + RtLinePlotWidget::DataPoint pt; + { + pt.x = t; + pt.y = mouse.x * 0.0005f; + pt_buffer->Write(pt); + } + { + pt.x = t; + pt.y = 0.5f + 0.5f * std::sin(2 * 3.1415926 * t); + pt_buffer_sin->Write(pt); + } + std::this_thread::sleep_for(std::chrono::milliseconds(period_ms)); + } +} + +int main(int argc, char* argv[]) { + // set up buffer first + auto& buffer_registry = BufferRegistry::GetInstance(); + std::shared_ptr> pt_buffer = + std::make_shared>(); + std::shared_ptr> pt_buffer_sin = + std::make_shared>(); + buffer_registry.AddBuffer(pt_buffer_name, pt_buffer); + buffer_registry.AddBuffer(pt_buffer_sin_name, pt_buffer_sin); + + // set up consumer + // note: viewer needs to be created before the data thread because this demo + // uses ImGui::GetMousePos() to generate data + Viewer viewer; + + // set up producer + std::thread data_thread(DataGenerator); + + // used as background for transparency test + auto gl_triangle = std::make_shared(); + viewer.AddSceneObject(gl_triangle); + + auto widget = std::make_shared("line_plot"); + widget->OnResize(300, 200); + widget->SetAxisLabels("x-axis", "y-axis"); + widget->SetAxisUnits("s", "m"); + widget->SetPlotTransparency(0.5); + widget->SetFixedHistory(5); + widget->SetYAxisRange(-0.5, 1.5); + widget->AddLine("line1", pt_buffer_name); + widget->AddLine("line2", pt_buffer_sin_name); + viewer.AddSceneObject(widget); + viewer.Show(); + + keep_running = false; + data_thread.join(); + + return 0; +} \ No newline at end of file diff --git a/src/third_party/imcore/CMakeLists.txt b/src/third_party/imcore/CMakeLists.txt index e02b87d..7621c39 100644 --- a/src/third_party/imcore/CMakeLists.txt +++ b/src/third_party/imcore/CMakeLists.txt @@ -21,6 +21,7 @@ set(GL_LOADER_SRC set(IMPLOT_SRC implot/implot.cpp implot/implot_items.cpp + implot/implot_demo.cpp ) add_library(imcore ${IMGUI_CORE_SRC} ${IMGUI_BACKEND_SRC} ${IMPLOT_SRC}) target_link_libraries(imcore PUBLIC glfw OpenGL::GL ${GLFW3_LIBRARY} ${CMAKE_DL_LIBS}) diff --git a/src/third_party/imcore/sample/implot_sample.cpp b/src/third_party/imcore/sample/implot_sample.cpp index 4abe5cd..aaef927 100644 --- a/src/third_party/imcore/sample/implot_sample.cpp +++ b/src/third_party/imcore/sample/implot_sample.cpp @@ -109,53 +109,55 @@ int main(int, char**) ImGui::NewFrame(); // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). - if (show_demo_window) - ImGui::ShowDemoWindow(&show_demo_window); +// if (show_demo_window) +// ImGui::ShowDemoWindow(&show_demo_window); // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. - { - static float f = 0.0f; - static int counter = 0; - - ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. - - ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) - ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state - ImGui::Checkbox("Another Window", &show_another_window); - - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f - ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color - - if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) - counter++; - ImGui::SameLine(); - ImGui::Text("counter = %d", counter); - - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - ImGui::End(); - } +// { +// static float f = 0.0f; +// static int counter = 0; +// +// ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. +// +// ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) +// ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state +// ImGui::Checkbox("Another Window", &show_another_window); +// +// ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f +// ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color +// +// if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) +// counter++; +// ImGui::SameLine(); +// ImGui::Text("counter = %d", counter); +// +// ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); +// ImGui::End(); +// } // 3. Show another simple window. - if (show_another_window) - { - ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) - ImGui::Text("Hello from another window!"); - if (ImGui::Button("Close Me")) - show_another_window = false; - ImGui::End(); - } - - int bar_data[11] = {0x11,0x22,0x33,0x44}; - float x_data[1000] = {0}; - float y_data[1000] = {0}; - - ImGui::Begin("My Window"); - if (ImPlot::BeginPlot("My Plot")) { - ImPlot::PlotBars("My Bar Plot", bar_data, 11); - ImPlot::PlotLine("My Line Plot", x_data, y_data, 1000); - ImPlot::EndPlot(); - } - ImGui::End(); +// if (show_another_window) +// { +// ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) +// ImGui::Text("Hello from another window!"); +// if (ImGui::Button("Close Me")) +// show_another_window = false; +// ImGui::End(); +// } + +// int bar_data[11] = {0x11,0x22,0x33,0x44}; +// float x_data[1000] = {0}; +// float y_data[1000] = {0}; + +// ImGui::Begin("My Window"); +// if (ImPlot::BeginPlot("My Plot")) { +// ImPlot::PlotBars("My Bar Plot", bar_data, 11); +// ImPlot::PlotLine("My Line Plot", x_data, y_data, 1000); +// ImPlot::EndPlot(); +// } +// ImGui::End(); + + ImPlot::ShowDemoWindow(); // Rendering ImGui::Render();