├── .github
├── CMakeLists.txt
├── example_implot.cpp
└── workflows
│ └── build.yml
├── LICENSE
├── README.md
├── TODO.md
├── implot.cpp
├── implot.h
├── implot_demo.cpp
├── implot_internal.h
└── implot_items.cpp
/.github/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # This build script is not meant for general use, it is for CI use only!
2 | cmake_minimum_required(VERSION 3.0)
3 | project(implot)
4 |
5 | #
6 | # Global options
7 | #
8 |
9 | # Same as Dear ImGui
10 | set(CMAKE_CXX_STANDARD 11)
11 |
12 | # Arch option for linux
13 | if (NOT APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU" AND DEFINED GCC_ARCH)
14 | if ("${GCC_ARCH}" MATCHES "Win32|x86|32")
15 | add_compile_options(-m32)
16 | add_link_options(-m32)
17 | elseif ("${GCC_ARCH}" MATCHES "Win64|x64|64")
18 | add_compile_options(-m64)
19 | add_link_options(-m64)
20 | endif ()
21 | endif ()
22 |
23 | # Arch option for Mac: arm64 for M1 or x86_64 for intel (32 bits build are deprecated on Mac)
24 | if(APPLE AND DEFINED OSX_ARCH)
25 | if ("${OSX_ARCH}" MATCHES "x86_64")
26 | set(CMAKE_OSX_ARCHITECTURES "x86_64")
27 | elseif ("${OSX_ARCH}" MATCHES "arm64")
28 | set(CMAKE_OSX_ARCHITECTURES "arm64")
29 | else()
30 | message(FATAL_ERROR "Unhandled OSX_ARCH=${OSX_ARCH}")
31 | endif()
32 | endif()
33 |
34 | #
35 | # Dear ImGui library with no backend
36 | #
37 |
38 | set(imgui_sources
39 | ../imgui/imconfig.h
40 | ../imgui/imgui.cpp
41 | ../imgui/imgui.h
42 | ../imgui/imgui_demo.cpp
43 | ../imgui/imgui_draw.cpp
44 | ../imgui/imgui_internal.h
45 | ../imgui/imgui_tables.cpp
46 | ../imgui/imgui_widgets.cpp
47 | ../imgui/imstb_rectpack.h
48 | ../imgui/imstb_textedit.h
49 | ../imgui/imstb_truetype.h
50 | )
51 | add_library(imgui ${imgui_sources})
52 | target_include_directories(imgui PUBLIC ../imgui)
53 |
54 | #
55 | # ImPlot library
56 | #
57 |
58 | file(GLOB SOURCE_CODE ../implot*.*)
59 | add_library(implot STATIC ${SOURCE_CODE})
60 |
61 | if(MSVC)
62 | target_compile_options(implot PRIVATE /W4 /WX)
63 | else()
64 | target_compile_options(implot PRIVATE -Wall -Werror -pedantic)
65 | endif()
66 |
67 | target_include_directories(implot PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..)
68 | target_link_libraries(implot PUBLIC imgui)
69 |
70 | if (UNIX)
71 | target_link_libraries(implot PUBLIC m stdc++)
72 | endif()
73 |
74 | # Define supported types via command line:
75 | # - With no choice all types are supported (so that the CI provides support for all known types)
76 | # - with -DIMPLOT_CUSTOM_NUMERIC_TYPES="default" the default set defined in implot_items.cpp is used
77 | # - with -DIMPLOT_CUSTOM_NUMERIC_TYPES="(int)(float)(double)" only int, float and double are supported
78 | if (NOT DEFINED IMPLOT_CUSTOM_NUMERIC_TYPES)
79 | set(IMPLOT_CUSTOM_NUMERIC_TYPES "all")
80 | endif()
81 | if ("${IMPLOT_CUSTOM_NUMERIC_TYPES}" STREQUAL "default")
82 | message("==== Compiling for default types ====")
83 | elseif("${IMPLOT_CUSTOM_NUMERIC_TYPES}" STREQUAL "all")
84 | message("==== Compiling for all types ====")
85 | target_compile_definitions(implot PRIVATE "IMPLOT_CUSTOM_NUMERIC_TYPES=(signed char)(unsigned char)(signed short)(unsigned short)(signed int)(unsigned int)(signed long)(unsigned long)(signed long long)(unsigned long long)(float)(double)(long double)")
86 | else()
87 | message("==== Compiling for custom types: ${IMPLOT_CUSTOM_NUMERIC_TYPES} ====")
88 | target_compile_definitions(implot PRIVATE "IMPLOT_CUSTOM_NUMERIC_TYPES=${IMPLOT_CUSTOM_NUMERIC_TYPES}")
89 | endif()
90 |
91 | #
92 | # implot example binary application (with no backend)
93 | #
94 | add_executable(example_implot example_implot.cpp)
95 | target_link_libraries(example_implot PRIVATE implot)
96 |
--------------------------------------------------------------------------------
/.github/example_implot.cpp:
--------------------------------------------------------------------------------
1 | // Sample app built with Dear ImGui and ImPlot
2 | // This app uses implot and imgui, but does not output to any backend! It only serves as a proof that an app can be built, linked, and run.
3 |
4 | #include "imgui.h"
5 | #include "implot.h"
6 | #include "stdio.h"
7 |
8 | int main(int, char**)
9 | {
10 | printf("sample_implot: start\n");
11 |
12 | IMGUI_CHECKVERSION();
13 | ImGui::CreateContext();
14 | ImPlot::CreateContext();
15 |
16 | // Additional imgui initialization needed when no backend is present
17 | ImGui::GetIO().DisplaySize = ImVec2(400.f, 400.f);
18 | ImGui::GetIO().Fonts->Build();
19 |
20 | // Render 500 frames
21 | for(int counter = 0; counter < 500; ++counter)
22 | {
23 | ImGui::NewFrame();
24 |
25 | if (ImGui::Begin("Hello, world!"))
26 | {
27 | ImGui::Text("Hello again");
28 |
29 | if (ImPlot::BeginPlot("My Plot"))
30 | {
31 | static double values[] = {1., 3., 5.};
32 | ImPlot::PlotLine("Values", values, 3);
33 | ImPlot::EndPlot();
34 | }
35 |
36 | #ifdef IMPLOT_INSTANTIATE_ALL_NUMERIC_TYPES
37 | if (ImPlot::BeginPlot("My Plot (long double)"))
38 | {
39 | static long double values[] = {1., 3., 5.};
40 | ImPlot::PlotLine("Values", values, 3);
41 | ImPlot::EndPlot();
42 | }
43 | #endif
44 |
45 | ImGui::End();
46 | }
47 |
48 | ImGui::Render();
49 | }
50 |
51 | ImPlot::DestroyContext();
52 | ImGui::DestroyContext();
53 | printf("sample_implot: end\n");
54 | return 0;
55 | }
56 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | pull_request:
6 |
7 | jobs:
8 | Linux:
9 | runs-on: ubuntu-22.04
10 |
11 | strategy:
12 | fail-fast: false
13 | matrix:
14 | build_type:
15 | - debug
16 | - release
17 | compiler:
18 | - gcc
19 | - clang
20 | arch:
21 | - x86
22 | - x64
23 |
24 | steps:
25 | - uses: actions/checkout@v3
26 |
27 | - uses: actions/checkout@v3
28 | with:
29 | repository: ocornut/imgui
30 | path: imgui
31 |
32 | - name: Dependencies
33 | run: sudo apt-get install g++-multilib
34 |
35 | - name: Configure
36 | run: cmake -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} -DCMAKE_C_COMPILER=${{ matrix.compiler }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DGCC_ARCH=${{ matrix.arch }} -B cmake-build -S .github
37 |
38 | - name: Build
39 | run: cmake --build cmake-build --parallel $(nproc)
40 |
41 | - name: Run
42 | run: |
43 | file cmake-build/example_implot
44 | cmake-build/example_implot
45 |
46 | MacOS:
47 | runs-on: macos-11
48 |
49 | strategy:
50 | fail-fast: false
51 | matrix:
52 | build_type:
53 | - debug
54 | - release
55 | arch:
56 | - x86_64
57 | - arm64
58 |
59 | steps:
60 | - uses: actions/checkout@v3
61 |
62 | - uses: actions/checkout@v3
63 | with:
64 | repository: ocornut/imgui
65 | path: imgui
66 |
67 | - name: Configure
68 | shell: bash
69 | run: cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DOSX_ARCH=${{ matrix.arch }} -B cmake-build -S .github
70 |
71 | - name: Build
72 | shell: bash
73 | run: cmake --build cmake-build --parallel $(sysctl -n hw.ncpu)
74 |
75 | - name: Run
76 | if: matrix.arch == 'x86_64' # github's CI hosts seem to be running intel and can not run ARM
77 | run: |
78 | file cmake-build/example_implot
79 | cmake-build/example_implot
80 |
81 | Windows_MSVC:
82 | runs-on: windows-2022
83 |
84 | strategy:
85 | fail-fast: false
86 | matrix:
87 | build_type:
88 | - debug
89 | - release
90 | arch:
91 | - Win32
92 | - x64
93 |
94 | steps:
95 | - uses: actions/checkout@v3
96 |
97 | - uses: actions/checkout@v3
98 | with:
99 | repository: ocornut/imgui
100 | path: imgui
101 |
102 | - name: Configure
103 | shell: bash
104 | run: cmake -G 'Visual Studio 17 2022' -A ${{ matrix.arch }} -B cmake-build -S .github
105 |
106 | - name: Build
107 | shell: bash
108 | run: cmake --build cmake-build -- -p:Configuration=${{ matrix.build_type }} -maxcpucount:$NUMBER_OF_PROCESSORS
109 |
110 | - name: Run
111 | run: .\cmake-build\${{matrix.build_type}}\example_implot.exe
112 |
113 | Windows_MingW: # MingW on Github CI does not fully support 32 bits: link fails when it tries to link 64 bits system libraries.
114 | runs-on: windows-2022
115 |
116 | strategy:
117 | fail-fast: false
118 | matrix:
119 | build_type:
120 | - debug
121 | - release
122 | arch:
123 | - x64
124 | # - Win32
125 |
126 | steps:
127 | - uses: actions/checkout@v3
128 |
129 | - uses: actions/checkout@v3
130 | with:
131 | repository: ocornut/imgui
132 | path: imgui
133 |
134 | - name: Configure
135 | shell: bash
136 | run: cmake -G 'MinGW Makefiles' -DGCC_ARCH=${{ matrix.arch }} -B cmake-build -S .github
137 |
138 | - name: Build
139 | shell: bash
140 | run: cmake --build cmake-build --parallel $NUMBER_OF_PROCESSORS
141 |
142 | - name: Run (MingW)
143 | run: .\cmake-build\example_implot.exe
144 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Evan Pezent
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ImPlot
2 | ImPlot is an immediate mode, GPU accelerated plotting library for [Dear ImGui](https://github.com/ocornut/imgui). It aims to provide a first-class API that ImGui fans will love. ImPlot is well suited for visualizing program data in real-time or creating interactive plots, 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.
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ## Features
16 |
17 | - GPU accelerated rendering
18 | - multiple plot types:
19 | - line plots
20 | - shaded plots
21 | - scatter plots
22 | - vertical/horizontal/stacked bars graphs
23 | - vertical/horizontal error bars
24 | - stem plots
25 | - stair plots
26 | - pie charts
27 | - heatmap charts
28 | - 1D/2D histograms
29 | - images
30 | - and more likely to come
31 | - mix/match multiple plot items on a single plot
32 | - configurable axes ranges and scaling (linear/log)
33 | - subplots
34 | - time formatted x-axes (US formatted or ISO 8601)
35 | - reversible and lockable axes
36 | - multiple x-axes and y-axes
37 | - controls for zooming, panning, box selection, and auto-fitting data
38 | - controls for creating persistent query ranges (see demo)
39 | - several plot styling options: 10 marker types, adjustable marker sizes, line weights, outline colors, fill colors, etc.
40 | - 16 built-in colormaps and support for and user-added colormaps
41 | - optional plot titles, axis labels, and grid labels
42 | - optional and configurable legends with toggle buttons to quickly show/hide plot items
43 | - default styling based on current ImGui theme, or completely custom plot styles
44 | - customizable data getters and data striding (just like ImGui:PlotLine)
45 | - accepts data as float, double, and 8, 16, 32, and 64-bit signed/unsigned integral types
46 | - and more! (see Announcements [2022](https://github.com/epezent/implot/discussions/370)/[2021](https://github.com/epezent/implot/issues/168)/[2020](https://github.com/epezent/implot/issues/48))
47 |
48 | ## Usage
49 |
50 | The API is used just like any other ImGui `BeginX`/`EndX` pair. First, start a new plot with `ImPlot::BeginPlot()`. Next, plot as many items as you want with the provided `PlotX` functions (e.g. `PlotLine()`, `PlotBars()`, `PlotScatter()`, etc). Finally, wrap things up with a call to `ImPlot::EndPlot()`. That's it!
51 |
52 | ```cpp
53 | int bar_data[11] = ...;
54 | float x_data[1000] = ...;
55 | float y_data[1000] = ...;
56 |
57 | ImGui::Begin("My Window");
58 | if (ImPlot::BeginPlot("My Plot")) {
59 | ImPlot::PlotBars("My Bar Plot", bar_data, 11);
60 | ImPlot::PlotLine("My Line Plot", x_data, y_data, 1000);
61 | ...
62 | ImPlot::EndPlot();
63 | }
64 | ImGui::End();
65 | ```
66 |
67 | 
68 |
69 |
70 | Of course, there's much more you can do with ImPlot...
71 |
72 | ## Demos
73 |
74 | A comprehensive example of ImPlot's features can be found in `implot_demo.cpp`. Add this file to your sources and call `ImPlot::ShowDemoWindow()` somewhere in your update loop. You are encouraged to use this file as a reference when needing to implement various plot types. The demo is always updated to show new plot types and features as they are added, so check back with each release!
75 |
76 | An online version of the demo is hosted [here](https://traineq.org/implot_demo/src/implot_demo.html). You can view the plots and the source code that generated them. Note that this demo may not always be up to date and is not as performant as a desktop implementation, but it should give you a general taste of what's possible with ImPlot. Special thanks to [pthom](https://github.com/pthom) for creating and hosting this!
77 |
78 | More sophisticated demos requiring lengthier code and/or third-party libraries can be found in a separate repository: [implot_demos](https://github.com/epezent/implot_demos). Here, you will find advanced signal processing and ImPlot usage in action. Please read the `Contributing` section of that repository if you have an idea for a new demo!
79 |
80 | ## Integration
81 |
82 | 0) Set up an [ImGui](https://github.com/ocornut/imgui) environment if you don't already have one.
83 | 1) Add `implot.h`, `implot_internal.h`, `implot.cpp`, `implot_items.cpp` and optionally `implot_demo.cpp` to your sources. Alternatively, you can get ImPlot using [vcpkg](https://github.com/microsoft/vcpkg/tree/master/ports/implot).
84 | 2) Create and destroy an `ImPlotContext` wherever you do so for your `ImGuiContext`:
85 |
86 | ```cpp
87 | ImGui::CreateContext();
88 | ImPlot::CreateContext();
89 | ...
90 | ImPlot::DestroyContext();
91 | ImGui::DestroyContext();
92 | ```
93 |
94 | You should be good to go!
95 |
96 | ## Installing ImPlot using vcpkg
97 |
98 | You can download and install ImPlot using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
99 |
100 | ```bash
101 | git clone https://github.com/Microsoft/vcpkg.git
102 | cd vcpkg
103 | ./bootstrap-vcpkg.sh
104 | ./vcpkg integrate install
105 | ./vcpkg install implot
106 | ```
107 |
108 | The ImPlot port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
109 |
110 | ## Extremely Important Note
111 |
112 | Dear ImGui uses **16-bit indexing by default**, so high-density ImPlot widgets like `ImPlot::PlotHeatmap()` may produce too many vertices into `ImDrawList`, which causes an assertion failure and will result in data truncation and/or visual glitches. Therefore, it is **HIGHLY** recommended that you EITHER:
113 |
114 | - **Option 1:** Enable 32-bit indices by uncommenting `#define ImDrawIdx unsigned int` in your ImGui [`imconfig.h`](https://github.com/ocornut/imgui/blob/master/imconfig.h#L89) file.
115 | - **Option 2:** Handle the `ImGuiBackendFlags_RendererHasVtxOffset` flag in your renderer if you must use 16-bit indices. Many of the default ImGui rendering backends already support `ImGuiBackendFlags_RendererHasVtxOffset`. Refer to [this issue](https://github.com/ocornut/imgui/issues/2591) for more information.
116 |
117 | ## FAQ
118 |
119 | **Q: Why?**
120 |
121 | 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.
122 |
123 | **Q: Is ImPlot the right plotting library for me?**
124 |
125 | A: If you're looking to generate publication quality plots and/or export plots to a file, ImPlot is NOT the library for you! ImPlot is geared toward plotting application data at realtime speeds with high levels of interactivity. ImPlot does its best to create pretty plots (indeed, there are quite a few styling options available), but it will always favor function over form.
126 |
127 | **Q: Where is the documentation?**
128 |
129 | A: The API is thoroughly commented in `implot.h`, and the demo in `implot_demo.cpp` should be more than enough to get you started. Also take a look at the [implot_demos](https://github.com/epezent/implot_demos) repository.
130 |
131 | **Q: Is ImPlot suitable for plotting large datasets?**
132 |
133 | A: Yes, within reason. You can plot tens to hundreds of thousands of points without issue, but don't expect millions to be a buttery smooth experience. That said, you can always downsample extremely large datasets by telling ImPlot to stride your data at larger intervals if needed. Also try the experimental `backends` branch which aims to provide GPU acceleration support.
134 |
135 | **Q: What data types can I plot?**
136 |
137 | A: ImPlot plotting functions accept most scalar types:
138 | `float`, `double`, `int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`, `int64`, `uint64`. Arrays of custom structs or classes (e.g. `Vector2f` or similar) are easily passed to ImPlot functions using the built-in striding features (see `implot.h` for documentation), and many plotters provide a "getter" overload which accepts data generating callbacks. You can fully customize the list of accepted types by defining `IMPLOT_CUSTOM_NUMERIC_TYPES` at compile time: see doc in `implot_items.cpp`.
139 |
140 | **Q: Can plot styles be modified?**
141 |
142 | A: Yes. Data colormaps and various styling colors and variables can be pushed/popped or modified permanently on startup. Three default styles are available, as well as an automatic style that attempts to match you ImGui style.
143 |
144 | **Q: Does ImPlot support logarithmic scaling or time formatting?**
145 |
146 | A: Yep! Both logscale and timescale are supported.
147 |
148 | **Q: Does ImPlot support multiple y-axes? x-axes?**
149 |
150 | A: Yes. Up to three x-axes and three y-axes can be enabled.
151 |
152 | **Q: Does ImPlot support [insert plot type]?**
153 |
154 | A: Maybe. Check the demo, gallery, or Announcements ([2020](https://github.com/epezent/implot/issues/48)/[2021](https://github.com/epezent/implot/issues/168))to see if your desired plot type is shown. If not, consider submitting an issue or better yet, a PR!
155 |
156 | **Q: Does ImPlot support 3D plots?**
157 |
158 | A: No, and likely never will since ImGui only deals in 2D rendering.
159 |
160 | **Q: Does ImPlot provide analytic tools?**
161 |
162 | A: Not exactly, but it does give you the ability to query plot sub-ranges, with which you can process your data however you like.
163 |
164 | **Q: Can plots be exported/saved to image?**
165 |
166 | A: Not currently. Use your OS's screen capturing mechanisms if you need to capture a plot. ImPlot is not suitable for rendering publication quality plots; it is only intended to be used as a visualization tool. Post-process your data with MATLAB or matplotlib for these purposes.
167 |
168 | **Q: Why are my plot lines showing aliasing?**
169 |
170 | A: You probably need to enable `ImGuiStyle::AntiAliasedLinesUseTex` (or possibly `ImGuiStyle:AntiAliasedLines`). If those settings are already enabled, then you must ensure your backend supports texture based anti-aliasing (i.e. uses bilinear sampling). Most of the default ImGui backends support this feature out of the box. Learn more [here](https://github.com/ocornut/imgui/issues/3245). Alternatively, you can enable MSAA at the application level if your hardware supports it (4x should do).
171 |
172 | **Q: Can I compile ImPlot as a dynamic library?**
173 |
174 | A: Like ImGui, it is recommended that you compile and link ImPlot as a *static* library or directly as a part of your sources. However, if you must and are compiling ImPlot and ImGui as separate DLLs, make sure you set the current *ImGui* context with `ImPlot::SetImGuiContext(ImGuiContext* ctx)`. This ensures that global ImGui variables are correctly shared across the DLL boundary.
175 |
176 | **Q: Can ImPlot be used with other languages/bindings?**
177 |
178 | A: Yes, you can use the generated C binding, [cimplot](https://github.com/cimgui/cimplot) with most high level languages. [DearPyGui](https://github.com/hoffstadt/DearPyGui) provides a Python wrapper, among other things. [DearImGui/DearImPlot](https://github.com/aybe/DearImGui) provides bindings for .NET. [imgui-java](https://github.com/SpaiR/imgui-java) provides bindings for Java. [ImPlot.jl](https://github.com/wsphillips/ImPlot.jl) provides bindings for Julia. A Rust binding, [implot-rs](https://github.com/4bb4/implot-rs), is currently in the works. An example using Emscripten can be found [here](https://github.com/pthom/implot_demo).
179 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | The list below represents a combination of high-priority work, nice-to-have features, and random ideas. We make no guarantees that all of this work will be completed or even started. If you see something that you need or would like to have, let us know, or better yet consider submitting a PR for the feature.
2 |
3 | ## API
4 |
5 | ## Axes
6 |
7 | - add flag to remove weekends on Time axis
8 | - pixel space scale (`ImPlotTransform_Display`), normalized space scale (`ImPlotTransform_Axes`), data space scale (`ImPlotTransform_Data`)
9 | - make ImPlotFlags_Equal not a flag -> `SetupEqual(ImPlotAxis x, ImPlotAxis y)`
10 | - allow inverted arguments `SetAxes` to transpose data?
11 | - `SetupAxisColors()`
12 | - `SetupAxisHome()`
13 |
14 | ## Plot Items
15 |
16 | - add `PlotBubbles` (see MATLAB bubble chart)
17 | - add non-zero references for `PlotBars` etc.
18 | - add exploding to `PlotPieChart` (on hover-highlight?)
19 | - fix appearance of `PlotBars` spacing
20 |
21 | ## Styling
22 |
23 | - support gradient and/or colormap sampled fills (e.g. ImPlotFillStyle_)
24 | - API for setting different fonts for plot elements
25 |
26 | ## Colormaps
27 |
28 | - gradient editing tool
29 | - `RemoveColormap`
30 | - `enum ImPlotColorRule_ { Solid, Faded, XValue, YValue, ZValue }`
31 |
32 | ## Legend
33 |
34 | - improve legend icons (e.g. adopt markers, gradients, etc)
35 | - generalize legend rendering for plots and subplots
36 | - add draggable scroll bar if users need it
37 |
38 | ## Tools / Misc.
39 |
40 | - add `IsPlotChanging` to detect change in limits
41 | - add ability to extend plot/axis context menus
42 | - add LTTB downsampling for lines
43 | - add box selection to axes
44 | - first frame render delay might fix "fit pop" effect
45 | - move some code to new `implot_tools.cpp`
46 | - ColormapSlider (see metrics)
47 | - FillAlpha should not affect markers?
48 | - fix mouse text for time axes
49 |
50 | ## Optimizations
51 |
52 | - find faster way to buffer data into ImDrawList (very slow)
53 | - reduce number of calls to `PushClipRect`
54 | - explore SIMD operations for high density plot items
55 |
56 | ## Plotter Pipeline
57 |
58 | Ideally every `PlotX` function should use our faster rendering pipeline when it is applicable.
59 |
60 | ` User Data > Getter > Fitter > Renderer > RenderPrimitives`
61 |
62 | |Plotter|Getter|Fitter|Renderer|RenderPrimitives|
63 | |---|:-:|:-:|:-:|:-:|
64 | |PlotLine|Yes|Yes|Yes|Yes|
65 | |PlotScatter|Yes|Yes|Yes|Yes|
66 | |PlotStairs|Yes|Yes|Yes|Yes|
67 | |PlotShaded|Yes|Yes|Yes|Yes|
68 | |PlotBars|Yes|Yes|Yes|Yes|
69 | |PlotBarGroups|:|:|:|:|
70 | |PlotHistogram|:|:|:|:|
71 | |PlotErrorBars|Yes|Yes|No|No|
72 | |PlotStems|Yes|Yes|Yes|Yes|
73 | |PlotInfLines|Yes|Yes|Yes|Yes|
74 | |PlotPieChart|No|No|No|No|
75 | |PlotHeatmap|Yes|No|Yes|Mixed|
76 | |PlotHistogram2D|:|:|:|:|
77 | |PlotDigital|Yes|No|No|No|
78 | |PlotImage|-|-|-|-|
79 | |PlotText|-|-|-|-|
80 | |PlotDummy|-|-|-|-|
81 |
82 | ## Completed
83 | - make BeginPlot take fewer args:
84 | - make query a tool -> `DragRect`
85 | - rework DragLine/Point to use ButtonBehavior
86 | - add support for multiple x-axes and don't limit count to 3
87 | - make axis side configurable (top/left, right/bottom) via new flag `ImPlotAxisFlags_Opposite`
88 | - add support for setting tick label strings via callback
89 | - give each axis an ID, remove ad-hoc DND solution
90 | - allow axis to be drag to opposite side (ala ImGui Table headers)
91 | - legend items can be hovered even if plot is not
92 | - fix frame delay on DragX tools
93 | - remove tag from drag line/point -> add `Tag` tool
94 | - add shortcut/legacy overloads for BeginPlot
95 | - `SetupAxisConstraints()`
96 | - `SetupAxisScale()`
97 | - add `ImPlotLineFlags`, `ImPlotBarsFlags`, etc. for each plot type
98 | - add `PlotBarGroups` wrapper that makes rendering groups of bars easier, with stacked bar support
99 | - `PlotBars` restore outlines
100 | - add hover/active color for plot axes
101 | - make legend frame use ButtonBehavior
102 | - `ImPlotLegendFlags_Scroll` (default behavior)
103 |
--------------------------------------------------------------------------------
/implot.h:
--------------------------------------------------------------------------------
1 | // MIT License
2 |
3 | // Copyright (c) 2023 Evan Pezent
4 |
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 |
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 |
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | // ImPlot v0.17
24 |
25 | // Table of Contents:
26 | //
27 | // [SECTION] Macros and Defines
28 | // [SECTION] Enums and Types
29 | // [SECTION] Callbacks
30 | // [SECTION] Contexts
31 | // [SECTION] Begin/End Plot
32 | // [SECTION] Begin/End Subplot
33 | // [SECTION] Setup
34 | // [SECTION] SetNext
35 | // [SECTION] Plot Items
36 | // [SECTION] Plot Tools
37 | // [SECTION] Plot Utils
38 | // [SECTION] Legend Utils
39 | // [SECTION] Drag and Drop
40 | // [SECTION] Styling
41 | // [SECTION] Colormaps
42 | // [SECTION] Input Mapping
43 | // [SECTION] Miscellaneous
44 | // [SECTION] Demo
45 | // [SECTION] Obsolete API
46 |
47 | #pragma once
48 | #include "imgui.h"
49 |
50 | //-----------------------------------------------------------------------------
51 | // [SECTION] Macros and Defines
52 | //-----------------------------------------------------------------------------
53 |
54 | // Define attributes of all API symbols declarations (e.g. for DLL under Windows)
55 | // Using ImPlot via a shared library is not recommended, because we don't guarantee
56 | // backward nor forward ABI compatibility and also function call overhead. If you
57 | // do use ImPlot as a DLL, be sure to call SetImGuiContext (see Miscellanous section).
58 | #ifndef IMPLOT_API
59 | #define IMPLOT_API
60 | #endif
61 |
62 | // ImPlot version string.
63 | #define IMPLOT_VERSION "0.17"
64 | // Indicates variable should deduced automatically.
65 | #define IMPLOT_AUTO -1
66 | // Special color used to indicate that a color should be deduced automatically.
67 | #define IMPLOT_AUTO_COL ImVec4(0,0,0,-1)
68 | // Macro for templated plotting functions; keeps header clean.
69 | #define IMPLOT_TMP template IMPLOT_API
70 |
71 | //-----------------------------------------------------------------------------
72 | // [SECTION] Enums and Types
73 | //-----------------------------------------------------------------------------
74 |
75 | // Forward declarations
76 | struct ImPlotContext; // ImPlot context (opaque struct, see implot_internal.h)
77 |
78 | // Enums/Flags
79 | typedef int ImAxis; // -> enum ImAxis_
80 | typedef int ImPlotFlags; // -> enum ImPlotFlags_
81 | typedef int ImPlotAxisFlags; // -> enum ImPlotAxisFlags_
82 | typedef int ImPlotSubplotFlags; // -> enum ImPlotSubplotFlags_
83 | typedef int ImPlotLegendFlags; // -> enum ImPlotLegendFlags_
84 | typedef int ImPlotMouseTextFlags; // -> enum ImPlotMouseTextFlags_
85 | typedef int ImPlotDragToolFlags; // -> ImPlotDragToolFlags_
86 | typedef int ImPlotColormapScaleFlags; // -> ImPlotColormapScaleFlags_
87 |
88 | typedef int ImPlotItemFlags; // -> ImPlotItemFlags_
89 | typedef int ImPlotLineFlags; // -> ImPlotLineFlags_
90 | typedef int ImPlotScatterFlags; // -> ImPlotScatterFlags
91 | typedef int ImPlotStairsFlags; // -> ImPlotStairsFlags_
92 | typedef int ImPlotShadedFlags; // -> ImPlotShadedFlags_
93 | typedef int ImPlotBarsFlags; // -> ImPlotBarsFlags_
94 | typedef int ImPlotBarGroupsFlags; // -> ImPlotBarGroupsFlags_
95 | typedef int ImPlotErrorBarsFlags; // -> ImPlotErrorBarsFlags_
96 | typedef int ImPlotStemsFlags; // -> ImPlotStemsFlags_
97 | typedef int ImPlotInfLinesFlags; // -> ImPlotInfLinesFlags_
98 | typedef int ImPlotPieChartFlags; // -> ImPlotPieChartFlags_
99 | typedef int ImPlotHeatmapFlags; // -> ImPlotHeatmapFlags_
100 | typedef int ImPlotHistogramFlags; // -> ImPlotHistogramFlags_
101 | typedef int ImPlotDigitalFlags; // -> ImPlotDigitalFlags_
102 | typedef int ImPlotImageFlags; // -> ImPlotImageFlags_
103 | typedef int ImPlotTextFlags; // -> ImPlotTextFlags_
104 | typedef int ImPlotDummyFlags; // -> ImPlotDummyFlags_
105 |
106 | typedef int ImPlotCond; // -> enum ImPlotCond_
107 | typedef int ImPlotCol; // -> enum ImPlotCol_
108 | typedef int ImPlotStyleVar; // -> enum ImPlotStyleVar_
109 | typedef int ImPlotScale; // -> enum ImPlotScale_
110 | typedef int ImPlotMarker; // -> enum ImPlotMarker_
111 | typedef int ImPlotColormap; // -> enum ImPlotColormap_
112 | typedef int ImPlotLocation; // -> enum ImPlotLocation_
113 | typedef int ImPlotBin; // -> enum ImPlotBin_
114 |
115 | // Axis indices. The values assigned may change; NEVER hardcode these.
116 | enum ImAxis_ {
117 | // horizontal axes
118 | ImAxis_X1 = 0, // enabled by default
119 | ImAxis_X2, // disabled by default
120 | ImAxis_X3, // disabled by default
121 | // vertical axes
122 | ImAxis_Y1, // enabled by default
123 | ImAxis_Y2, // disabled by default
124 | ImAxis_Y3, // disabled by default
125 | // bookeeping
126 | ImAxis_COUNT
127 | };
128 |
129 | // Options for plots (see BeginPlot).
130 | enum ImPlotFlags_ {
131 | ImPlotFlags_None = 0, // default
132 | ImPlotFlags_NoTitle = 1 << 0, // the plot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MyPlot")
133 | ImPlotFlags_NoLegend = 1 << 1, // the legend will not be displayed
134 | ImPlotFlags_NoMouseText = 1 << 2, // the mouse position, in plot coordinates, will not be displayed inside of the plot
135 | ImPlotFlags_NoInputs = 1 << 3, // the user will not be able to interact with the plot
136 | ImPlotFlags_NoMenus = 1 << 4, // the user will not be able to open context menus
137 | ImPlotFlags_NoBoxSelect = 1 << 5, // the user will not be able to box-select
138 | ImPlotFlags_NoFrame = 1 << 6, // the ImGui frame will not be rendered
139 | ImPlotFlags_Equal = 1 << 7, // x and y axes pairs will be constrained to have the same units/pixel
140 | ImPlotFlags_Crosshairs = 1 << 8, // the default mouse cursor will be replaced with a crosshair when hovered
141 | ImPlotFlags_CanvasOnly = ImPlotFlags_NoTitle | ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMouseText
142 | };
143 |
144 | // Options for plot axes (see SetupAxis).
145 | enum ImPlotAxisFlags_ {
146 | ImPlotAxisFlags_None = 0, // default
147 | ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels are also hidden if the supplied string name is nullptr)
148 | ImPlotAxisFlags_NoGridLines = 1 << 1, // no grid lines will be displayed
149 | ImPlotAxisFlags_NoTickMarks = 1 << 2, // no tick marks will be displayed
150 | ImPlotAxisFlags_NoTickLabels = 1 << 3, // no text labels will be displayed
151 | ImPlotAxisFlags_NoInitialFit = 1 << 4, // axis will not be initially fit to data extents on the first rendered frame
152 | ImPlotAxisFlags_NoMenus = 1 << 5, // the user will not be able to open context menus with right-click
153 | ImPlotAxisFlags_NoSideSwitch = 1 << 6, // the user will not be able to switch the axis side by dragging it
154 | ImPlotAxisFlags_NoHighlight = 1 << 7, // the axis will not have its background highlighted when hovered or held
155 | ImPlotAxisFlags_Opposite = 1 << 8, // axis ticks and labels will be rendered on the conventionally opposite side (i.e, right or top)
156 | ImPlotAxisFlags_Foreground = 1 << 9, // grid lines will be displayed in the foreground (i.e. on top of data) instead of the background
157 | ImPlotAxisFlags_Invert = 1 << 10, // the axis will be inverted
158 | ImPlotAxisFlags_AutoFit = 1 << 11, // axis will be auto-fitting to data extents
159 | ImPlotAxisFlags_RangeFit = 1 << 12, // axis will only fit points if the point is in the visible range of the **orthogonal** axis
160 | ImPlotAxisFlags_PanStretch = 1 << 13, // panning in a locked or constrained state will cause the axis to stretch if possible
161 | ImPlotAxisFlags_LockMin = 1 << 14, // the axis minimum value will be locked when panning/zooming
162 | ImPlotAxisFlags_LockMax = 1 << 15, // the axis maximum value will be locked when panning/zooming
163 | ImPlotAxisFlags_Lock = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax,
164 | ImPlotAxisFlags_NoDecorations = ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels,
165 | ImPlotAxisFlags_AuxDefault = ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_Opposite
166 | };
167 |
168 | // Options for subplots (see BeginSubplot)
169 | enum ImPlotSubplotFlags_ {
170 | ImPlotSubplotFlags_None = 0, // default
171 | ImPlotSubplotFlags_NoTitle = 1 << 0, // the subplot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MySubplot")
172 | ImPlotSubplotFlags_NoLegend = 1 << 1, // the legend will not be displayed (only applicable if ImPlotSubplotFlags_ShareItems is enabled)
173 | ImPlotSubplotFlags_NoMenus = 1 << 2, // the user will not be able to open context menus with right-click
174 | ImPlotSubplotFlags_NoResize = 1 << 3, // resize splitters between subplot cells will be not be provided
175 | ImPlotSubplotFlags_NoAlign = 1 << 4, // subplot edges will not be aligned vertically or horizontally
176 | ImPlotSubplotFlags_ShareItems = 1 << 5, // items across all subplots will be shared and rendered into a single legend entry
177 | ImPlotSubplotFlags_LinkRows = 1 << 6, // link the y-axis limits of all plots in each row (does not apply to auxiliary axes)
178 | ImPlotSubplotFlags_LinkCols = 1 << 7, // link the x-axis limits of all plots in each column (does not apply to auxiliary axes)
179 | ImPlotSubplotFlags_LinkAllX = 1 << 8, // link the x-axis limits in every plot in the subplot (does not apply to auxiliary axes)
180 | ImPlotSubplotFlags_LinkAllY = 1 << 9, // link the y-axis limits in every plot in the subplot (does not apply to auxiliary axes)
181 | ImPlotSubplotFlags_ColMajor = 1 << 10 // subplots are added in column major order instead of the default row major order
182 | };
183 |
184 | // Options for legends (see SetupLegend)
185 | enum ImPlotLegendFlags_ {
186 | ImPlotLegendFlags_None = 0, // default
187 | ImPlotLegendFlags_NoButtons = 1 << 0, // legend icons will not function as hide/show buttons
188 | ImPlotLegendFlags_NoHighlightItem = 1 << 1, // plot items will not be highlighted when their legend entry is hovered
189 | ImPlotLegendFlags_NoHighlightAxis = 1 << 2, // axes will not be highlighted when legend entries are hovered (only relevant if x/y-axis count > 1)
190 | ImPlotLegendFlags_NoMenus = 1 << 3, // the user will not be able to open context menus with right-click
191 | ImPlotLegendFlags_Outside = 1 << 4, // legend will be rendered outside of the plot area
192 | ImPlotLegendFlags_Horizontal = 1 << 5, // legend entries will be displayed horizontally
193 | ImPlotLegendFlags_Sort = 1 << 6, // legend entries will be displayed in alphabetical order
194 | };
195 |
196 | // Options for mouse hover text (see SetupMouseText)
197 | enum ImPlotMouseTextFlags_ {
198 | ImPlotMouseTextFlags_None = 0, // default
199 | ImPlotMouseTextFlags_NoAuxAxes = 1 << 0, // only show the mouse position for primary axes
200 | ImPlotMouseTextFlags_NoFormat = 1 << 1, // axes label formatters won't be used to render text
201 | ImPlotMouseTextFlags_ShowAlways = 1 << 2, // always display mouse position even if plot not hovered
202 | };
203 |
204 | // Options for DragPoint, DragLine, DragRect
205 | enum ImPlotDragToolFlags_ {
206 | ImPlotDragToolFlags_None = 0, // default
207 | ImPlotDragToolFlags_NoCursors = 1 << 0, // drag tools won't change cursor icons when hovered or held
208 | ImPlotDragToolFlags_NoFit = 1 << 1, // the drag tool won't be considered for plot fits
209 | ImPlotDragToolFlags_NoInputs = 1 << 2, // lock the tool from user inputs
210 | ImPlotDragToolFlags_Delayed = 1 << 3, // tool rendering will be delayed one frame; useful when applying position-constraints
211 | };
212 |
213 | // Flags for ColormapScale
214 | enum ImPlotColormapScaleFlags_ {
215 | ImPlotColormapScaleFlags_None = 0, // default
216 | ImPlotColormapScaleFlags_NoLabel = 1 << 0, // the colormap axis label will not be displayed
217 | ImPlotColormapScaleFlags_Opposite = 1 << 1, // render the colormap label and tick labels on the opposite side
218 | ImPlotColormapScaleFlags_Invert = 1 << 2, // invert the colormap bar and axis scale (this only affects rendering; if you only want to reverse the scale mapping, make scale_min > scale_max)
219 | };
220 |
221 | // Flags for ANY PlotX function
222 | enum ImPlotItemFlags_ {
223 | ImPlotItemFlags_None = 0,
224 | ImPlotItemFlags_NoLegend = 1 << 0, // the item won't have a legend entry displayed
225 | ImPlotItemFlags_NoFit = 1 << 1, // the item won't be considered for plot fits
226 | };
227 |
228 | // Flags for PlotLine
229 | enum ImPlotLineFlags_ {
230 | ImPlotLineFlags_None = 0, // default
231 | ImPlotLineFlags_Segments = 1 << 10, // a line segment will be rendered from every two consecutive points
232 | ImPlotLineFlags_Loop = 1 << 11, // the last and first point will be connected to form a closed loop
233 | ImPlotLineFlags_SkipNaN = 1 << 12, // NaNs values will be skipped instead of rendered as missing data
234 | ImPlotLineFlags_NoClip = 1 << 13, // markers (if displayed) on the edge of a plot will not be clipped
235 | ImPlotLineFlags_Shaded = 1 << 14, // a filled region between the line and horizontal origin will be rendered; use PlotShaded for more advanced cases
236 | };
237 |
238 | // Flags for PlotScatter
239 | enum ImPlotScatterFlags_ {
240 | ImPlotScatterFlags_None = 0, // default
241 | ImPlotScatterFlags_NoClip = 1 << 10, // markers on the edge of a plot will not be clipped
242 | };
243 |
244 | // Flags for PlotStairs
245 | enum ImPlotStairsFlags_ {
246 | ImPlotStairsFlags_None = 0, // default
247 | ImPlotStairsFlags_PreStep = 1 << 10, // the y value is continued constantly to the left from every x position, i.e. the interval (x[i-1], x[i]] has the value y[i]
248 | ImPlotStairsFlags_Shaded = 1 << 11 // a filled region between the stairs and horizontal origin will be rendered; use PlotShaded for more advanced cases
249 | };
250 |
251 | // Flags for PlotShaded (placeholder)
252 | enum ImPlotShadedFlags_ {
253 | ImPlotShadedFlags_None = 0 // default
254 | };
255 |
256 | // Flags for PlotBars
257 | enum ImPlotBarsFlags_ {
258 | ImPlotBarsFlags_None = 0, // default
259 | ImPlotBarsFlags_Horizontal = 1 << 10, // bars will be rendered horizontally on the current y-axis
260 | };
261 |
262 | // Flags for PlotBarGroups
263 | enum ImPlotBarGroupsFlags_ {
264 | ImPlotBarGroupsFlags_None = 0, // default
265 | ImPlotBarGroupsFlags_Horizontal = 1 << 10, // bar groups will be rendered horizontally on the current y-axis
266 | ImPlotBarGroupsFlags_Stacked = 1 << 11, // items in a group will be stacked on top of each other
267 | };
268 |
269 | // Flags for PlotErrorBars
270 | enum ImPlotErrorBarsFlags_ {
271 | ImPlotErrorBarsFlags_None = 0, // default
272 | ImPlotErrorBarsFlags_Horizontal = 1 << 10, // error bars will be rendered horizontally on the current y-axis
273 | };
274 |
275 | // Flags for PlotStems
276 | enum ImPlotStemsFlags_ {
277 | ImPlotStemsFlags_None = 0, // default
278 | ImPlotStemsFlags_Horizontal = 1 << 10, // stems will be rendered horizontally on the current y-axis
279 | };
280 |
281 | // Flags for PlotInfLines
282 | enum ImPlotInfLinesFlags_ {
283 | ImPlotInfLinesFlags_None = 0, // default
284 | ImPlotInfLinesFlags_Horizontal = 1 << 10 // lines will be rendered horizontally on the current y-axis
285 | };
286 |
287 | // Flags for PlotPieChart
288 | enum ImPlotPieChartFlags_ {
289 | ImPlotPieChartFlags_None = 0, // default
290 | ImPlotPieChartFlags_Normalize = 1 << 10, // force normalization of pie chart values (i.e. always make a full circle if sum < 0)
291 | ImPlotPieChartFlags_IgnoreHidden = 1 << 11 // ignore hidden slices when drawing the pie chart (as if they were not there)
292 | };
293 |
294 | // Flags for PlotHeatmap
295 | enum ImPlotHeatmapFlags_ {
296 | ImPlotHeatmapFlags_None = 0, // default
297 | ImPlotHeatmapFlags_ColMajor = 1 << 10, // data will be read in column major order
298 | };
299 |
300 | // Flags for PlotHistogram and PlotHistogram2D
301 | enum ImPlotHistogramFlags_ {
302 | ImPlotHistogramFlags_None = 0, // default
303 | ImPlotHistogramFlags_Horizontal = 1 << 10, // histogram bars will be rendered horizontally (not supported by PlotHistogram2D)
304 | ImPlotHistogramFlags_Cumulative = 1 << 11, // each bin will contain its count plus the counts of all previous bins (not supported by PlotHistogram2D)
305 | ImPlotHistogramFlags_Density = 1 << 12, // counts will be normalized, i.e. the PDF will be visualized, or the CDF will be visualized if Cumulative is also set
306 | ImPlotHistogramFlags_NoOutliers = 1 << 13, // exclude values outside the specifed histogram range from the count toward normalizing and cumulative counts
307 | ImPlotHistogramFlags_ColMajor = 1 << 14 // data will be read in column major order (not supported by PlotHistogram)
308 | };
309 |
310 | // Flags for PlotDigital (placeholder)
311 | enum ImPlotDigitalFlags_ {
312 | ImPlotDigitalFlags_None = 0 // default
313 | };
314 |
315 | // Flags for PlotImage (placeholder)
316 | enum ImPlotImageFlags_ {
317 | ImPlotImageFlags_None = 0 // default
318 | };
319 |
320 | // Flags for PlotText
321 | enum ImPlotTextFlags_ {
322 | ImPlotTextFlags_None = 0, // default
323 | ImPlotTextFlags_Vertical = 1 << 10 // text will be rendered vertically
324 | };
325 |
326 | // Flags for PlotDummy (placeholder)
327 | enum ImPlotDummyFlags_ {
328 | ImPlotDummyFlags_None = 0 // default
329 | };
330 |
331 | // Represents a condition for SetupAxisLimits etc. (same as ImGuiCond, but we only support a subset of those enums)
332 | enum ImPlotCond_
333 | {
334 | ImPlotCond_None = ImGuiCond_None, // No condition (always set the variable), same as _Always
335 | ImPlotCond_Always = ImGuiCond_Always, // No condition (always set the variable)
336 | ImPlotCond_Once = ImGuiCond_Once, // Set the variable once per runtime session (only the first call will succeed)
337 | };
338 |
339 | // Plot styling colors.
340 | enum ImPlotCol_ {
341 | // item styling colors
342 | ImPlotCol_Line, // plot line/outline color (defaults to next unused color in current colormap)
343 | ImPlotCol_Fill, // plot fill color for bars (defaults to the current line color)
344 | ImPlotCol_MarkerOutline, // marker outline color (defaults to the current line color)
345 | ImPlotCol_MarkerFill, // marker fill color (defaults to the current line color)
346 | ImPlotCol_ErrorBar, // error bar color (defaults to ImGuiCol_Text)
347 | // plot styling colors
348 | ImPlotCol_FrameBg, // plot frame background color (defaults to ImGuiCol_FrameBg)
349 | ImPlotCol_PlotBg, // plot area background color (defaults to ImGuiCol_WindowBg)
350 | ImPlotCol_PlotBorder, // plot area border color (defaults to ImGuiCol_Border)
351 | ImPlotCol_LegendBg, // legend background color (defaults to ImGuiCol_PopupBg)
352 | ImPlotCol_LegendBorder, // legend border color (defaults to ImPlotCol_PlotBorder)
353 | ImPlotCol_LegendText, // legend text color (defaults to ImPlotCol_InlayText)
354 | ImPlotCol_TitleText, // plot title text color (defaults to ImGuiCol_Text)
355 | ImPlotCol_InlayText, // color of text appearing inside of plots (defaults to ImGuiCol_Text)
356 | ImPlotCol_AxisText, // axis label and tick lables color (defaults to ImGuiCol_Text)
357 | ImPlotCol_AxisGrid, // axis grid color (defaults to 25% ImPlotCol_AxisText)
358 | ImPlotCol_AxisTick, // axis tick color (defaults to AxisGrid)
359 | ImPlotCol_AxisBg, // background color of axis hover region (defaults to transparent)
360 | ImPlotCol_AxisBgHovered, // axis hover color (defaults to ImGuiCol_ButtonHovered)
361 | ImPlotCol_AxisBgActive, // axis active color (defaults to ImGuiCol_ButtonActive)
362 | ImPlotCol_Selection, // box-selection color (defaults to yellow)
363 | ImPlotCol_Crosshairs, // crosshairs color (defaults to ImPlotCol_PlotBorder)
364 | ImPlotCol_COUNT
365 | };
366 |
367 | // Plot styling variables.
368 | enum ImPlotStyleVar_ {
369 | // item styling variables
370 | ImPlotStyleVar_LineWeight, // float, plot item line weight in pixels
371 | ImPlotStyleVar_Marker, // int, marker specification
372 | ImPlotStyleVar_MarkerSize, // float, marker size in pixels (roughly the marker's "radius")
373 | ImPlotStyleVar_MarkerWeight, // float, plot outline weight of markers in pixels
374 | ImPlotStyleVar_FillAlpha, // float, alpha modifier applied to all plot item fills
375 | ImPlotStyleVar_ErrorBarSize, // float, error bar whisker width in pixels
376 | ImPlotStyleVar_ErrorBarWeight, // float, error bar whisker weight in pixels
377 | ImPlotStyleVar_DigitalBitHeight, // float, digital channels bit height (at 1) in pixels
378 | ImPlotStyleVar_DigitalBitGap, // float, digital channels bit padding gap in pixels
379 | // plot styling variables
380 | ImPlotStyleVar_PlotBorderSize, // float, thickness of border around plot area
381 | ImPlotStyleVar_MinorAlpha, // float, alpha multiplier applied to minor axis grid lines
382 | ImPlotStyleVar_MajorTickLen, // ImVec2, major tick lengths for X and Y axes
383 | ImPlotStyleVar_MinorTickLen, // ImVec2, minor tick lengths for X and Y axes
384 | ImPlotStyleVar_MajorTickSize, // ImVec2, line thickness of major ticks
385 | ImPlotStyleVar_MinorTickSize, // ImVec2, line thickness of minor ticks
386 | ImPlotStyleVar_MajorGridSize, // ImVec2, line thickness of major grid lines
387 | ImPlotStyleVar_MinorGridSize, // ImVec2, line thickness of minor grid lines
388 | ImPlotStyleVar_PlotPadding, // ImVec2, padding between widget frame and plot area, labels, or outside legends (i.e. main padding)
389 | ImPlotStyleVar_LabelPadding, // ImVec2, padding between axes labels, tick labels, and plot edge
390 | ImPlotStyleVar_LegendPadding, // ImVec2, legend padding from plot edges
391 | ImPlotStyleVar_LegendInnerPadding, // ImVec2, legend inner padding from legend edges
392 | ImPlotStyleVar_LegendSpacing, // ImVec2, spacing between legend entries
393 | ImPlotStyleVar_MousePosPadding, // ImVec2, padding between plot edge and interior info text
394 | ImPlotStyleVar_AnnotationPadding, // ImVec2, text padding around annotation labels
395 | ImPlotStyleVar_FitPadding, // ImVec2, additional fit padding as a percentage of the fit extents (e.g. ImVec2(0.1f,0.1f) adds 10% to the fit extents of X and Y)
396 | ImPlotStyleVar_PlotDefaultSize, // ImVec2, default size used when ImVec2(0,0) is passed to BeginPlot
397 | ImPlotStyleVar_PlotMinSize, // ImVec2, minimum size plot frame can be when shrunk
398 | ImPlotStyleVar_COUNT
399 | };
400 |
401 | // Axis scale
402 | enum ImPlotScale_ {
403 | ImPlotScale_Linear = 0, // default linear scale
404 | ImPlotScale_Time, // date/time scale
405 | ImPlotScale_Log10, // base 10 logartithmic scale
406 | ImPlotScale_SymLog, // symmetric log scale
407 | };
408 |
409 | // Marker specifications.
410 | enum ImPlotMarker_ {
411 | ImPlotMarker_None = -1, // no marker
412 | ImPlotMarker_Circle, // a circle marker (default)
413 | ImPlotMarker_Square, // a square maker
414 | ImPlotMarker_Diamond, // a diamond marker
415 | ImPlotMarker_Up, // an upward-pointing triangle marker
416 | ImPlotMarker_Down, // an downward-pointing triangle marker
417 | ImPlotMarker_Left, // an leftward-pointing triangle marker
418 | ImPlotMarker_Right, // an rightward-pointing triangle marker
419 | ImPlotMarker_Cross, // a cross marker (not fillable)
420 | ImPlotMarker_Plus, // a plus marker (not fillable)
421 | ImPlotMarker_Asterisk, // a asterisk marker (not fillable)
422 | ImPlotMarker_COUNT
423 | };
424 |
425 | // Built-in colormaps
426 | enum ImPlotColormap_ {
427 | ImPlotColormap_Deep = 0, // a.k.a. seaborn deep (qual=true, n=10) (default)
428 | ImPlotColormap_Dark = 1, // a.k.a. matplotlib "Set1" (qual=true, n=9 )
429 | ImPlotColormap_Pastel = 2, // a.k.a. matplotlib "Pastel1" (qual=true, n=9 )
430 | ImPlotColormap_Paired = 3, // a.k.a. matplotlib "Paired" (qual=true, n=12)
431 | ImPlotColormap_Viridis = 4, // a.k.a. matplotlib "viridis" (qual=false, n=11)
432 | ImPlotColormap_Plasma = 5, // a.k.a. matplotlib "plasma" (qual=false, n=11)
433 | ImPlotColormap_Hot = 6, // a.k.a. matplotlib/MATLAB "hot" (qual=false, n=11)
434 | ImPlotColormap_Cool = 7, // a.k.a. matplotlib/MATLAB "cool" (qual=false, n=11)
435 | ImPlotColormap_Pink = 8, // a.k.a. matplotlib/MATLAB "pink" (qual=false, n=11)
436 | ImPlotColormap_Jet = 9, // a.k.a. MATLAB "jet" (qual=false, n=11)
437 | ImPlotColormap_Twilight = 10, // a.k.a. matplotlib "twilight" (qual=false, n=11)
438 | ImPlotColormap_RdBu = 11, // red/blue, Color Brewer (qual=false, n=11)
439 | ImPlotColormap_BrBG = 12, // brown/blue-green, Color Brewer (qual=false, n=11)
440 | ImPlotColormap_PiYG = 13, // pink/yellow-green, Color Brewer (qual=false, n=11)
441 | ImPlotColormap_Spectral = 14, // color spectrum, Color Brewer (qual=false, n=11)
442 | ImPlotColormap_Greys = 15, // white/black (qual=false, n=2 )
443 | };
444 |
445 | // Used to position items on a plot (e.g. legends, labels, etc.)
446 | enum ImPlotLocation_ {
447 | ImPlotLocation_Center = 0, // center-center
448 | ImPlotLocation_North = 1 << 0, // top-center
449 | ImPlotLocation_South = 1 << 1, // bottom-center
450 | ImPlotLocation_West = 1 << 2, // center-left
451 | ImPlotLocation_East = 1 << 3, // center-right
452 | ImPlotLocation_NorthWest = ImPlotLocation_North | ImPlotLocation_West, // top-left
453 | ImPlotLocation_NorthEast = ImPlotLocation_North | ImPlotLocation_East, // top-right
454 | ImPlotLocation_SouthWest = ImPlotLocation_South | ImPlotLocation_West, // bottom-left
455 | ImPlotLocation_SouthEast = ImPlotLocation_South | ImPlotLocation_East // bottom-right
456 | };
457 |
458 | // Enums for different automatic histogram binning methods (k = bin count or w = bin width)
459 | enum ImPlotBin_ {
460 | ImPlotBin_Sqrt = -1, // k = sqrt(n)
461 | ImPlotBin_Sturges = -2, // k = 1 + log2(n)
462 | ImPlotBin_Rice = -3, // k = 2 * cbrt(n)
463 | ImPlotBin_Scott = -4, // w = 3.49 * sigma / cbrt(n)
464 | };
465 |
466 | // Double precision version of ImVec2 used by ImPlot. Extensible by end users.
467 | IM_MSVC_RUNTIME_CHECKS_OFF
468 | struct ImPlotPoint {
469 | double x, y;
470 | constexpr ImPlotPoint() : x(0.0), y(0.0) { }
471 | constexpr ImPlotPoint(double _x, double _y) : x(_x), y(_y) { }
472 | constexpr ImPlotPoint(const ImVec2& p) : x((double)p.x), y((double)p.y) { }
473 | double& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((double*)(void*)(char*)this)[idx]; }
474 | double operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const double*)(const void*)(const char*)this)[idx]; }
475 | #ifdef IMPLOT_POINT_CLASS_EXTRA
476 | IMPLOT_POINT_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h
477 | // to convert back and forth between your math types and ImPlotPoint.
478 | #endif
479 | };
480 | IM_MSVC_RUNTIME_CHECKS_RESTORE
481 |
482 | // Range defined by a min/max value.
483 | struct ImPlotRange {
484 | double Min, Max;
485 | constexpr ImPlotRange() : Min(0.0), Max(0.0) { }
486 | constexpr ImPlotRange(double _min, double _max) : Min(_min), Max(_max) { }
487 | bool Contains(double value) const { return value >= Min && value <= Max; }
488 | double Size() const { return Max - Min; }
489 | double Clamp(double value) const { return (value < Min) ? Min : (value > Max) ? Max : value; }
490 | };
491 |
492 | // Combination of two range limits for X and Y axes. Also an AABB defined by Min()/Max().
493 | struct ImPlotRect {
494 | ImPlotRange X, Y;
495 | constexpr ImPlotRect() : X(0.0,0.0), Y(0.0,0.0) { }
496 | constexpr ImPlotRect(double x_min, double x_max, double y_min, double y_max) : X(x_min, x_max), Y(y_min, y_max) { }
497 | bool Contains(const ImPlotPoint& p) const { return Contains(p.x, p.y); }
498 | bool Contains(double x, double y) const { return X.Contains(x) && Y.Contains(y); }
499 | ImPlotPoint Size() const { return ImPlotPoint(X.Size(), Y.Size()); }
500 | ImPlotPoint Clamp(const ImPlotPoint& p) { return Clamp(p.x, p.y); }
501 | ImPlotPoint Clamp(double x, double y) { return ImPlotPoint(X.Clamp(x),Y.Clamp(y)); }
502 | ImPlotPoint Min() const { return ImPlotPoint(X.Min, Y.Min); }
503 | ImPlotPoint Max() const { return ImPlotPoint(X.Max, Y.Max); }
504 | };
505 |
506 | // Plot style structure
507 | struct ImPlotStyle {
508 | // item styling variables
509 | float LineWeight; // = 1, item line weight in pixels
510 | int Marker; // = ImPlotMarker_None, marker specification
511 | float MarkerSize; // = 4, marker size in pixels (roughly the marker's "radius")
512 | float MarkerWeight; // = 1, outline weight of markers in pixels
513 | float FillAlpha; // = 1, alpha modifier applied to plot fills
514 | float ErrorBarSize; // = 5, error bar whisker width in pixels
515 | float ErrorBarWeight; // = 1.5, error bar whisker weight in pixels
516 | float DigitalBitHeight; // = 8, digital channels bit height (at y = 1.0f) in pixels
517 | float DigitalBitGap; // = 4, digital channels bit padding gap in pixels
518 | // plot styling variables
519 | float PlotBorderSize; // = 1, line thickness of border around plot area
520 | float MinorAlpha; // = 0.25 alpha multiplier applied to minor axis grid lines
521 | ImVec2 MajorTickLen; // = 10,10 major tick lengths for X and Y axes
522 | ImVec2 MinorTickLen; // = 5,5 minor tick lengths for X and Y axes
523 | ImVec2 MajorTickSize; // = 1,1 line thickness of major ticks
524 | ImVec2 MinorTickSize; // = 1,1 line thickness of minor ticks
525 | ImVec2 MajorGridSize; // = 1,1 line thickness of major grid lines
526 | ImVec2 MinorGridSize; // = 1,1 line thickness of minor grid lines
527 | ImVec2 PlotPadding; // = 10,10 padding between widget frame and plot area, labels, or outside legends (i.e. main padding)
528 | ImVec2 LabelPadding; // = 5,5 padding between axes labels, tick labels, and plot edge
529 | ImVec2 LegendPadding; // = 10,10 legend padding from plot edges
530 | ImVec2 LegendInnerPadding; // = 5,5 legend inner padding from legend edges
531 | ImVec2 LegendSpacing; // = 5,0 spacing between legend entries
532 | ImVec2 MousePosPadding; // = 10,10 padding between plot edge and interior mouse location text
533 | ImVec2 AnnotationPadding; // = 2,2 text padding around annotation labels
534 | ImVec2 FitPadding; // = 0,0 additional fit padding as a percentage of the fit extents (e.g. ImVec2(0.1f,0.1f) adds 10% to the fit extents of X and Y)
535 | ImVec2 PlotDefaultSize; // = 400,300 default size used when ImVec2(0,0) is passed to BeginPlot
536 | ImVec2 PlotMinSize; // = 200,150 minimum size plot frame can be when shrunk
537 | // style colors
538 | ImVec4 Colors[ImPlotCol_COUNT]; // Array of styling colors. Indexable with ImPlotCol_ enums.
539 | // colormap
540 | ImPlotColormap Colormap; // The current colormap. Set this to either an ImPlotColormap_ enum or an index returned by AddColormap.
541 | // settings/flags
542 | bool UseLocalTime; // = false, axis labels will be formatted for your timezone when ImPlotAxisFlag_Time is enabled
543 | bool UseISO8601; // = false, dates will be formatted according to ISO 8601 where applicable (e.g. YYYY-MM-DD, YYYY-MM, --MM-DD, etc.)
544 | bool Use24HourClock; // = false, times will be formatted using a 24 hour clock
545 | IMPLOT_API ImPlotStyle();
546 | };
547 |
548 | // Support for legacy versions
549 | #if (IMGUI_VERSION_NUM < 18716) // Renamed in 1.88
550 | #define ImGuiMod_None 0
551 | #define ImGuiMod_Ctrl ImGuiKeyModFlags_Ctrl
552 | #define ImGuiMod_Shift ImGuiKeyModFlags_Shift
553 | #define ImGuiMod_Alt ImGuiKeyModFlags_Alt
554 | #define ImGuiMod_Super ImGuiKeyModFlags_Super
555 | #elif (IMGUI_VERSION_NUM < 18823) // Renamed in 1.89, sorry
556 | #define ImGuiMod_None 0
557 | #define ImGuiMod_Ctrl ImGuiModFlags_Ctrl
558 | #define ImGuiMod_Shift ImGuiModFlags_Shift
559 | #define ImGuiMod_Alt ImGuiModFlags_Alt
560 | #define ImGuiMod_Super ImGuiModFlags_Super
561 | #endif
562 |
563 | // Input mapping structure. Default values listed. See also MapInputDefault, MapInputReverse.
564 | struct ImPlotInputMap {
565 | ImGuiMouseButton Pan; // LMB enables panning when held,
566 | int PanMod; // none optional modifier that must be held for panning/fitting
567 | ImGuiMouseButton Fit; // LMB initiates fit when double clicked
568 | ImGuiMouseButton Select; // RMB begins box selection when pressed and confirms selection when released
569 | ImGuiMouseButton SelectCancel; // LMB cancels active box selection when pressed; cannot be same as Select
570 | int SelectMod; // none optional modifier that must be held for box selection
571 | int SelectHorzMod; // Alt expands active box selection horizontally to plot edge when held
572 | int SelectVertMod; // Shift expands active box selection vertically to plot edge when held
573 | ImGuiMouseButton Menu; // RMB opens context menus (if enabled) when clicked
574 | int OverrideMod; // Ctrl when held, all input is ignored; used to enable axis/plots as DND sources
575 | int ZoomMod; // none optional modifier that must be held for scroll wheel zooming
576 | float ZoomRate; // 0.1f zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click); make negative to invert
577 | IMPLOT_API ImPlotInputMap();
578 | };
579 |
580 | //-----------------------------------------------------------------------------
581 | // [SECTION] Callbacks
582 | //-----------------------------------------------------------------------------
583 |
584 | // Callback signature for axis tick label formatter.
585 | typedef int (*ImPlotFormatter)(double value, char* buff, int size, void* user_data);
586 |
587 | // Callback signature for data getter.
588 | typedef ImPlotPoint (*ImPlotGetter)(int idx, void* user_data);
589 |
590 | // Callback signature for axis transform.
591 | typedef double (*ImPlotTransform)(double value, void* user_data);
592 |
593 | namespace ImPlot {
594 |
595 | //-----------------------------------------------------------------------------
596 | // [SECTION] Contexts
597 | //-----------------------------------------------------------------------------
598 |
599 | // Creates a new ImPlot context. Call this after ImGui::CreateContext.
600 | IMPLOT_API ImPlotContext* CreateContext();
601 | // Destroys an ImPlot context. Call this before ImGui::DestroyContext. nullptr = destroy current context.
602 | IMPLOT_API void DestroyContext(ImPlotContext* ctx = nullptr);
603 | // Returns the current ImPlot context. nullptr if no context has ben set.
604 | IMPLOT_API ImPlotContext* GetCurrentContext();
605 | // Sets the current ImPlot context.
606 | IMPLOT_API void SetCurrentContext(ImPlotContext* ctx);
607 |
608 | // Sets the current **ImGui** context. This is ONLY necessary if you are compiling
609 | // ImPlot as a DLL (not recommended) separate from your ImGui compilation. It
610 | // sets the global variable GImGui, which is not shared across DLL boundaries.
611 | // See GImGui documentation in imgui.cpp for more details.
612 | IMPLOT_API void SetImGuiContext(ImGuiContext* ctx);
613 |
614 | //-----------------------------------------------------------------------------
615 | // [SECTION] Begin/End Plot
616 | //-----------------------------------------------------------------------------
617 |
618 | // Starts a 2D plotting context. If this function returns true, EndPlot() MUST
619 | // be called! You are encouraged to use the following convention:
620 | //
621 | // if (BeginPlot(...)) {
622 | // PlotLine(...);
623 | // ...
624 | // EndPlot();
625 | // }
626 | //
627 | // Important notes:
628 | //
629 | // - #title_id must be unique to the current ImGui ID scope. If you need to avoid ID
630 | // collisions or don't want to display a title in the plot, use double hashes
631 | // (e.g. "MyPlot##HiddenIdText" or "##NoTitle").
632 | // - #size is the **frame** size of the plot widget, not the plot area. The default
633 | // size of plots (i.e. when ImVec2(0,0)) can be modified in your ImPlotStyle.
634 | IMPLOT_API bool BeginPlot(const char* title_id, const ImVec2& size=ImVec2(-1,0), ImPlotFlags flags=0);
635 |
636 | // Only call EndPlot() if BeginPlot() returns true! Typically called at the end
637 | // of an if statement conditioned on BeginPlot(). See example above.
638 | IMPLOT_API void EndPlot();
639 |
640 | //-----------------------------------------------------------------------------
641 | // [SECTION] Begin/End Subplots
642 | //-----------------------------------------------------------------------------
643 |
644 | // Starts a subdivided plotting context. If the function returns true,
645 | // EndSubplots() MUST be called! Call BeginPlot/EndPlot AT MOST [rows*cols]
646 | // times in between the begining and end of the subplot context. Plots are
647 | // added in row major order.
648 | //
649 | // Example:
650 | //
651 | // if (BeginSubplots("My Subplot",2,3,ImVec2(800,400)) {
652 | // for (int i = 0; i < 6; ++i) {
653 | // if (BeginPlot(...)) {
654 | // ImPlot::PlotLine(...);
655 | // ...
656 | // EndPlot();
657 | // }
658 | // }
659 | // EndSubplots();
660 | // }
661 | //
662 | // Produces:
663 | //
664 | // [0] | [1] | [2]
665 | // ----|-----|----
666 | // [3] | [4] | [5]
667 | //
668 | // Important notes:
669 | //
670 | // - #title_id must be unique to the current ImGui ID scope. If you need to avoid ID
671 | // collisions or don't want to display a title in the plot, use double hashes
672 | // (e.g. "MySubplot##HiddenIdText" or "##NoTitle").
673 | // - #rows and #cols must be greater than 0.
674 | // - #size is the size of the entire grid of subplots, not the individual plots
675 | // - #row_ratios and #col_ratios must have AT LEAST #rows and #cols elements,
676 | // respectively. These are the sizes of the rows and columns expressed in ratios.
677 | // If the user adjusts the dimensions, the arrays are updated with new ratios.
678 | //
679 | // Important notes regarding BeginPlot from inside of BeginSubplots:
680 | //
681 | // - The #title_id parameter of _BeginPlot_ (see above) does NOT have to be
682 | // unique when called inside of a subplot context. Subplot IDs are hashed
683 | // for your convenience so you don't have call PushID or generate unique title
684 | // strings. Simply pass an empty string to BeginPlot unless you want to title
685 | // each subplot.
686 | // - The #size parameter of _BeginPlot_ (see above) is ignored when inside of a
687 | // subplot context. The actual size of the subplot will be based on the
688 | // #size value you pass to _BeginSubplots_ and #row/#col_ratios if provided.
689 |
690 | IMPLOT_API bool BeginSubplots(const char* title_id,
691 | int rows,
692 | int cols,
693 | const ImVec2& size,
694 | ImPlotSubplotFlags flags = 0,
695 | float* row_ratios = nullptr,
696 | float* col_ratios = nullptr);
697 |
698 | // Only call EndSubplots() if BeginSubplots() returns true! Typically called at the end
699 | // of an if statement conditioned on BeginSublots(). See example above.
700 | IMPLOT_API void EndSubplots();
701 |
702 | //-----------------------------------------------------------------------------
703 | // [SECTION] Setup
704 | //-----------------------------------------------------------------------------
705 |
706 | // The following API allows you to setup and customize various aspects of the
707 | // current plot. The functions should be called immediately after BeginPlot
708 | // and before any other API calls. Typical usage is as follows:
709 |
710 | // if (BeginPlot(...)) { 1) begin a new plot
711 | // SetupAxis(ImAxis_X1, "My X-Axis"); 2) make Setup calls
712 | // SetupAxis(ImAxis_Y1, "My Y-Axis");
713 | // SetupLegend(ImPlotLocation_North);
714 | // ...
715 | // SetupFinish(); 3) [optional] explicitly finish setup
716 | // PlotLine(...); 4) plot items
717 | // ...
718 | // EndPlot(); 5) end the plot
719 | // }
720 | //
721 | // Important notes:
722 | //
723 | // - Always call Setup code at the top of your BeginPlot conditional statement.
724 | // - Setup is locked once you start plotting or explicitly call SetupFinish.
725 | // Do NOT call Setup code after you begin plotting or after you make
726 | // any non-Setup API calls (e.g. utils like PlotToPixels also lock Setup)
727 | // - Calling SetupFinish is OPTIONAL, but probably good practice. If you do not
728 | // call it yourself, then the first subsequent plotting or utility function will
729 | // call it for you.
730 |
731 | // Enables an axis or sets the label and/or flags for an existing axis. Leave #label = nullptr for no label.
732 | IMPLOT_API void SetupAxis(ImAxis axis, const char* label=nullptr, ImPlotAxisFlags flags=0);
733 | // Sets an axis range limits. If ImPlotCond_Always is used, the axes limits will be locked. Inversion with v_min > v_max is not supported; use SetupAxisLimits instead.
734 | IMPLOT_API void SetupAxisLimits(ImAxis axis, double v_min, double v_max, ImPlotCond cond = ImPlotCond_Once);
735 | // Links an axis range limits to external values. Set to nullptr for no linkage. The pointer data must remain valid until EndPlot.
736 | IMPLOT_API void SetupAxisLinks(ImAxis axis, double* link_min, double* link_max);
737 | // Sets the format of numeric axis labels via formater specifier (default="%g"). Formated values will be double (i.e. use %f).
738 | IMPLOT_API void SetupAxisFormat(ImAxis axis, const char* fmt);
739 | // Sets the format of numeric axis labels via formatter callback. Given #value, write a label into #buff. Optionally pass user data.
740 | IMPLOT_API void SetupAxisFormat(ImAxis axis, ImPlotFormatter formatter, void* data=nullptr);
741 | // Sets an axis' ticks and optionally the labels. To keep the default ticks, set #keep_default=true.
742 | IMPLOT_API void SetupAxisTicks(ImAxis axis, const double* values, int n_ticks, const char* const labels[]=nullptr, bool keep_default=false);
743 | // Sets an axis' ticks and optionally the labels for the next plot. To keep the default ticks, set #keep_default=true.
744 | IMPLOT_API void SetupAxisTicks(ImAxis axis, double v_min, double v_max, int n_ticks, const char* const labels[]=nullptr, bool keep_default=false);
745 | // Sets an axis' scale using built-in options.
746 | IMPLOT_API void SetupAxisScale(ImAxis axis, ImPlotScale scale);
747 | // Sets an axis' scale using user supplied forward and inverse transfroms.
748 | IMPLOT_API void SetupAxisScale(ImAxis axis, ImPlotTransform forward, ImPlotTransform inverse, void* data=nullptr);
749 | // Sets an axis' limits constraints.
750 | IMPLOT_API void SetupAxisLimitsConstraints(ImAxis axis, double v_min, double v_max);
751 | // Sets an axis' zoom constraints.
752 | IMPLOT_API void SetupAxisZoomConstraints(ImAxis axis, double z_min, double z_max);
753 |
754 | // Sets the label and/or flags for primary X and Y axes (shorthand for two calls to SetupAxis).
755 | IMPLOT_API void SetupAxes(const char* x_label, const char* y_label, ImPlotAxisFlags x_flags=0, ImPlotAxisFlags y_flags=0);
756 | // Sets the primary X and Y axes range limits. If ImPlotCond_Always is used, the axes limits will be locked (shorthand for two calls to SetupAxisLimits).
757 | IMPLOT_API void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, ImPlotCond cond = ImPlotCond_Once);
758 |
759 | // Sets up the plot legend. This can also be called immediately after BeginSubplots when using ImPlotSubplotFlags_ShareItems.
760 | IMPLOT_API void SetupLegend(ImPlotLocation location, ImPlotLegendFlags flags=0);
761 | // Set the location of the current plot's mouse position text (default = South|East).
762 | IMPLOT_API void SetupMouseText(ImPlotLocation location, ImPlotMouseTextFlags flags=0);
763 |
764 | // Explicitly finalize plot setup. Once you call this, you cannot make anymore Setup calls for the current plot!
765 | // Note that calling this function is OPTIONAL; it will be called by the first subsequent setup-locking API call.
766 | IMPLOT_API void SetupFinish();
767 |
768 | //-----------------------------------------------------------------------------
769 | // [SECTION] SetNext
770 | //-----------------------------------------------------------------------------
771 |
772 | // Though you should default to the `Setup` API above, there are some scenarios
773 | // where (re)configuring a plot or axis before `BeginPlot` is needed (e.g. if
774 | // using a preceding button or slider widget to change the plot limits). In
775 | // this case, you can use the `SetNext` API below. While this is not as feature
776 | // rich as the Setup API, most common needs are provided. These functions can be
777 | // called anwhere except for inside of `Begin/EndPlot`. For example:
778 |
779 | // if (ImGui::Button("Center Plot"))
780 | // ImPlot::SetNextPlotLimits(-1,1,-1,1);
781 | // if (ImPlot::BeginPlot(...)) {
782 | // ...
783 | // ImPlot::EndPlot();
784 | // }
785 | //
786 | // Important notes:
787 | //
788 | // - You must still enable non-default axes with SetupAxis for these functions
789 | // to work properly.
790 |
791 | // Sets an upcoming axis range limits. If ImPlotCond_Always is used, the axes limits will be locked.
792 | IMPLOT_API void SetNextAxisLimits(ImAxis axis, double v_min, double v_max, ImPlotCond cond = ImPlotCond_Once);
793 | // Links an upcoming axis range limits to external values. Set to nullptr for no linkage. The pointer data must remain valid until EndPlot!
794 | IMPLOT_API void SetNextAxisLinks(ImAxis axis, double* link_min, double* link_max);
795 | // Set an upcoming axis to auto fit to its data.
796 | IMPLOT_API void SetNextAxisToFit(ImAxis axis);
797 |
798 | // Sets the upcoming primary X and Y axes range limits. If ImPlotCond_Always is used, the axes limits will be locked (shorthand for two calls to SetupAxisLimits).
799 | IMPLOT_API void SetNextAxesLimits(double x_min, double x_max, double y_min, double y_max, ImPlotCond cond = ImPlotCond_Once);
800 | // Sets all upcoming axes to auto fit to their data.
801 | IMPLOT_API void SetNextAxesToFit();
802 |
803 | //-----------------------------------------------------------------------------
804 | // [SECTION] Plot Items
805 | //-----------------------------------------------------------------------------
806 |
807 | // The main plotting API is provied below. Call these functions between
808 | // Begin/EndPlot and after any Setup API calls. Each plots data on the current
809 | // x and y axes, which can be changed with `SetAxis/Axes`.
810 | //
811 | // The templated functions are explicitly instantiated in implot_items.cpp.
812 | // They are not intended to be used generically with custom types. You will get
813 | // a linker error if you try! All functions support the following scalar types:
814 | //
815 | // float, double, ImS8, ImU8, ImS16, ImU16, ImS32, ImU32, ImS64, ImU64
816 | //
817 | //
818 | // If you need to plot custom or non-homogenous data you have a few options:
819 | //
820 | // 1. If your data is a simple struct/class (e.g. Vector2f), you can use striding.
821 | // This is the most performant option if applicable.
822 | //
823 | // struct Vector2f { float X, Y; };
824 | // ...
825 | // Vector2f data[42];
826 | // ImPlot::PlotLine("line", &data[0].x, &data[0].y, 42, 0, 0, sizeof(Vector2f));
827 | //
828 | // 2. Write a custom getter C function or C++ lambda and pass it and optionally your data to
829 | // an ImPlot function post-fixed with a G (e.g. PlotScatterG). This has a slight performance
830 | // cost, but probably not enough to worry about unless your data is very large. Examples:
831 | //
832 | // ImPlotPoint MyDataGetter(void* data, int idx) {
833 | // MyData* my_data = (MyData*)data;
834 | // ImPlotPoint p;
835 | // p.x = my_data->GetTime(idx);
836 | // p.y = my_data->GetValue(idx);
837 | // return p
838 | // }
839 | // ...
840 | // auto my_lambda = [](int idx, void*) {
841 | // double t = idx / 999.0;
842 | // return ImPlotPoint(t, 0.5+0.5*std::sin(2*PI*10*t));
843 | // };
844 | // ...
845 | // if (ImPlot::BeginPlot("MyPlot")) {
846 | // MyData my_data;
847 | // ImPlot::PlotScatterG("scatter", MyDataGetter, &my_data, my_data.Size());
848 | // ImPlot::PlotLineG("line", my_lambda, nullptr, 1000);
849 | // ImPlot::EndPlot();
850 | // }
851 | //
852 | // NB: All types are converted to double before plotting. You may lose information
853 | // if you try plotting extremely large 64-bit integral types. Proceed with caution!
854 |
855 | // Plots a standard 2D line plot.
856 | IMPLOT_TMP void PlotLine(const char* label_id, const T* values, int count, double xscale=1, double xstart=0, ImPlotLineFlags flags=0, int offset=0, int stride=sizeof(T));
857 | IMPLOT_TMP void PlotLine(const char* label_id, const T* xs, const T* ys, int count, ImPlotLineFlags flags=0, int offset=0, int stride=sizeof(T));
858 | IMPLOT_API void PlotLineG(const char* label_id, ImPlotGetter getter, void* data, int count, ImPlotLineFlags flags=0);
859 |
860 | // Plots a standard 2D scatter plot. Default marker is ImPlotMarker_Circle.
861 | IMPLOT_TMP void PlotScatter(const char* label_id, const T* values, int count, double xscale=1, double xstart=0, ImPlotScatterFlags flags=0, int offset=0, int stride=sizeof(T));
862 | IMPLOT_TMP void PlotScatter(const char* label_id, const T* xs, const T* ys, int count, ImPlotScatterFlags flags=0, int offset=0, int stride=sizeof(T));
863 | IMPLOT_API void PlotScatterG(const char* label_id, ImPlotGetter getter, void* data, int count, ImPlotScatterFlags flags=0);
864 |
865 | // Plots a a stairstep graph. The y value is continued constantly to the right from every x position, i.e. the interval [x[i], x[i+1]) has the value y[i]
866 | IMPLOT_TMP void PlotStairs(const char* label_id, const T* values, int count, double xscale=1, double xstart=0, ImPlotStairsFlags flags=0, int offset=0, int stride=sizeof(T));
867 | IMPLOT_TMP void PlotStairs(const char* label_id, const T* xs, const T* ys, int count, ImPlotStairsFlags flags=0, int offset=0, int stride=sizeof(T));
868 | IMPLOT_API void PlotStairsG(const char* label_id, ImPlotGetter getter, void* data, int count, ImPlotStairsFlags flags=0);
869 |
870 | // Plots a shaded (filled) region between two lines, or a line and a horizontal reference. Set yref to +/-INFINITY for infinite fill extents.
871 | IMPLOT_TMP void PlotShaded(const char* label_id, const T* values, int count, double yref=0, double xscale=1, double xstart=0, ImPlotShadedFlags flags=0, int offset=0, int stride=sizeof(T));
872 | IMPLOT_TMP void PlotShaded(const char* label_id, const T* xs, const T* ys, int count, double yref=0, ImPlotShadedFlags flags=0, int offset=0, int stride=sizeof(T));
873 | IMPLOT_TMP void PlotShaded(const char* label_id, const T* xs, const T* ys1, const T* ys2, int count, ImPlotShadedFlags flags=0, int offset=0, int stride=sizeof(T));
874 | IMPLOT_API void PlotShadedG(const char* label_id, ImPlotGetter getter1, void* data1, ImPlotGetter getter2, void* data2, int count, ImPlotShadedFlags flags=0);
875 |
876 | // Plots a bar graph. Vertical by default. #bar_size and #shift are in plot units.
877 | IMPLOT_TMP void PlotBars(const char* label_id, const T* values, int count, double bar_size=0.67, double shift=0, ImPlotBarsFlags flags=0, int offset=0, int stride=sizeof(T));
878 | IMPLOT_TMP void PlotBars(const char* label_id, const T* xs, const T* ys, int count, double bar_size, ImPlotBarsFlags flags=0, int offset=0, int stride=sizeof(T));
879 | IMPLOT_API void PlotBarsG(const char* label_id, ImPlotGetter getter, void* data, int count, double bar_size, ImPlotBarsFlags flags=0);
880 |
881 | // Plots a group of bars. #values is a row-major matrix with #item_count rows and #group_count cols. #label_ids should have #item_count elements.
882 | IMPLOT_TMP void PlotBarGroups(const char* const label_ids[], const T* values, int item_count, int group_count, double group_size=0.67, double shift=0, ImPlotBarGroupsFlags flags=0);
883 |
884 | // Plots vertical error bar. The label_id should be the same as the label_id of the associated line or bar plot.
885 | IMPLOT_TMP void PlotErrorBars(const char* label_id, const T* xs, const T* ys, const T* err, int count, ImPlotErrorBarsFlags flags=0, int offset=0, int stride=sizeof(T));
886 | IMPLOT_TMP void PlotErrorBars(const char* label_id, const T* xs, const T* ys, const T* neg, const T* pos, int count, ImPlotErrorBarsFlags flags=0, int offset=0, int stride=sizeof(T));
887 |
888 | // Plots stems. Vertical by default.
889 | IMPLOT_TMP void PlotStems(const char* label_id, const T* values, int count, double ref=0, double scale=1, double start=0, ImPlotStemsFlags flags=0, int offset=0, int stride=sizeof(T));
890 | IMPLOT_TMP void PlotStems(const char* label_id, const T* xs, const T* ys, int count, double ref=0, ImPlotStemsFlags flags=0, int offset=0, int stride=sizeof(T));
891 |
892 | // Plots infinite vertical or horizontal lines (e.g. for references or asymptotes).
893 | IMPLOT_TMP void PlotInfLines(const char* label_id, const T* values, int count, ImPlotInfLinesFlags flags=0, int offset=0, int stride=sizeof(T));
894 |
895 | // Plots a pie chart. Center and radius are in plot units. #label_fmt can be set to nullptr for no labels.
896 | IMPLOT_TMP void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void* fmt_data=nullptr, double angle0=90, ImPlotPieChartFlags flags=0);
897 | IMPLOT_TMP void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* label_fmt="%.1f", double angle0=90, ImPlotPieChartFlags flags=0);
898 |
899 | // Plots a 2D heatmap chart. Values are expected to be in row-major order by default. Leave #scale_min and scale_max both at 0 for automatic color scaling, or set them to a predefined range. #label_fmt can be set to nullptr for no labels.
900 | IMPLOT_TMP void PlotHeatmap(const char* label_id, const T* values, int rows, int cols, double scale_min=0, double scale_max=0, const char* label_fmt="%.1f", const ImPlotPoint& bounds_min=ImPlotPoint(0,0), const ImPlotPoint& bounds_max=ImPlotPoint(1,1), ImPlotHeatmapFlags flags=0);
901 |
902 | // Plots a horizontal histogram. #bins can be a positive integer or an ImPlotBin_ method. If #range is left unspecified, the min/max of #values will be used as the range.
903 | // Otherwise, outlier values outside of the range are not binned. The largest bin count or density is returned.
904 | IMPLOT_TMP double PlotHistogram(const char* label_id, const T* values, int count, int bins=ImPlotBin_Sturges, double bar_scale=1.0, ImPlotRange range=ImPlotRange(), ImPlotHistogramFlags flags=0);
905 |
906 | // Plots two dimensional, bivariate histogram as a heatmap. #x_bins and #y_bins can be a positive integer or an ImPlotBin. If #range is left unspecified, the min/max of
907 | // #xs an #ys will be used as the ranges. Otherwise, outlier values outside of range are not binned. The largest bin count or density is returned.
908 | IMPLOT_TMP double PlotHistogram2D(const char* label_id, const T* xs, const T* ys, int count, int x_bins=ImPlotBin_Sturges, int y_bins=ImPlotBin_Sturges, ImPlotRect range=ImPlotRect(), ImPlotHistogramFlags flags=0);
909 |
910 | // Plots digital data. Digital plots do not respond to y drag or zoom, and are always referenced to the bottom of the plot.
911 | IMPLOT_TMP void PlotDigital(const char* label_id, const T* xs, const T* ys, int count, ImPlotDigitalFlags flags=0, int offset=0, int stride=sizeof(T));
912 | IMPLOT_API void PlotDigitalG(const char* label_id, ImPlotGetter getter, void* data, int count, ImPlotDigitalFlags flags=0);
913 |
914 | // Plots an axis-aligned image. #bounds_min/bounds_max are in plot coordinates (y-up) and #uv0/uv1 are in texture coordinates (y-down).
915 | IMPLOT_API void PlotImage(const char* label_id, ImTextureID user_texture_id, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max, const ImVec2& uv0=ImVec2(0,0), const ImVec2& uv1=ImVec2(1,1), const ImVec4& tint_col=ImVec4(1,1,1,1), ImPlotImageFlags flags=0);
916 |
917 | // Plots a centered text label at point x,y with an optional pixel offset. Text color can be changed with ImPlot::PushStyleColor(ImPlotCol_InlayText, ...).
918 | IMPLOT_API void PlotText(const char* text, double x, double y, const ImVec2& pix_offset=ImVec2(0,0), ImPlotTextFlags flags=0);
919 |
920 | // Plots a dummy item (i.e. adds a legend entry colored by ImPlotCol_Line)
921 | IMPLOT_API void PlotDummy(const char* label_id, ImPlotDummyFlags flags=0);
922 |
923 | //-----------------------------------------------------------------------------
924 | // [SECTION] Plot Tools
925 | //-----------------------------------------------------------------------------
926 |
927 | // The following can be used to render interactive elements and/or annotations.
928 | // Like the item plotting functions above, they apply to the current x and y
929 | // axes, which can be changed with `SetAxis/SetAxes`. These functions return true
930 | // when user interaction causes the provided coordinates to change. Additional
931 | // user interactions can be retrieved through the optional output parameters.
932 |
933 | // Shows a draggable point at x,y. #col defaults to ImGuiCol_Text.
934 | IMPLOT_API bool DragPoint(int id, double* x, double* y, const ImVec4& col, float size = 4, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
935 | // Shows a draggable vertical guide line at an x-value. #col defaults to ImGuiCol_Text.
936 | IMPLOT_API bool DragLineX(int id, double* x, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
937 | // Shows a draggable horizontal guide line at a y-value. #col defaults to ImGuiCol_Text.
938 | IMPLOT_API bool DragLineY(int id, double* y, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
939 | // Shows a draggable and resizeable rectangle.
940 | IMPLOT_API bool DragRect(int id, double* x1, double* y1, double* x2, double* y2, const ImVec4& col, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
941 |
942 | // Shows an annotation callout at a chosen point. Clamping keeps annotations in the plot area. Annotations are always rendered on top.
943 | IMPLOT_API void Annotation(double x, double y, const ImVec4& col, const ImVec2& pix_offset, bool clamp, bool round = false);
944 | IMPLOT_API void Annotation(double x, double y, const ImVec4& col, const ImVec2& pix_offset, bool clamp, const char* fmt, ...) IM_FMTARGS(6);
945 | IMPLOT_API void AnnotationV(double x, double y, const ImVec4& col, const ImVec2& pix_offset, bool clamp, const char* fmt, va_list args) IM_FMTLIST(6);
946 |
947 | // Shows a x-axis tag at the specified coordinate value.
948 | IMPLOT_API void TagX(double x, const ImVec4& col, bool round = false);
949 | IMPLOT_API void TagX(double x, const ImVec4& col, const char* fmt, ...) IM_FMTARGS(3);
950 | IMPLOT_API void TagXV(double x, const ImVec4& col, const char* fmt, va_list args) IM_FMTLIST(3);
951 |
952 | // Shows a y-axis tag at the specified coordinate value.
953 | IMPLOT_API void TagY(double y, const ImVec4& col, bool round = false);
954 | IMPLOT_API void TagY(double y, const ImVec4& col, const char* fmt, ...) IM_FMTARGS(3);
955 | IMPLOT_API void TagYV(double y, const ImVec4& col, const char* fmt, va_list args) IM_FMTLIST(3);
956 |
957 | //-----------------------------------------------------------------------------
958 | // [SECTION] Plot Utils
959 | //-----------------------------------------------------------------------------
960 |
961 | // Select which axis/axes will be used for subsequent plot elements.
962 | IMPLOT_API void SetAxis(ImAxis axis);
963 | IMPLOT_API void SetAxes(ImAxis x_axis, ImAxis y_axis);
964 |
965 | // Convert pixels to a position in the current plot's coordinate system. Passing IMPLOT_AUTO uses the current axes.
966 | IMPLOT_API ImPlotPoint PixelsToPlot(const ImVec2& pix, ImAxis x_axis = IMPLOT_AUTO, ImAxis y_axis = IMPLOT_AUTO);
967 | IMPLOT_API ImPlotPoint PixelsToPlot(float x, float y, ImAxis x_axis = IMPLOT_AUTO, ImAxis y_axis = IMPLOT_AUTO);
968 |
969 | // Convert a position in the current plot's coordinate system to pixels. Passing IMPLOT_AUTO uses the current axes.
970 | IMPLOT_API ImVec2 PlotToPixels(const ImPlotPoint& plt, ImAxis x_axis = IMPLOT_AUTO, ImAxis y_axis = IMPLOT_AUTO);
971 | IMPLOT_API ImVec2 PlotToPixels(double x, double y, ImAxis x_axis = IMPLOT_AUTO, ImAxis y_axis = IMPLOT_AUTO);
972 |
973 | // Get the current Plot position (top-left) in pixels.
974 | IMPLOT_API ImVec2 GetPlotPos();
975 | // Get the curent Plot size in pixels.
976 | IMPLOT_API ImVec2 GetPlotSize();
977 |
978 | // Returns the mouse position in x,y coordinates of the current plot. Passing IMPLOT_AUTO uses the current axes.
979 | IMPLOT_API ImPlotPoint GetPlotMousePos(ImAxis x_axis = IMPLOT_AUTO, ImAxis y_axis = IMPLOT_AUTO);
980 | // Returns the current plot axis range.
981 | IMPLOT_API ImPlotRect GetPlotLimits(ImAxis x_axis = IMPLOT_AUTO, ImAxis y_axis = IMPLOT_AUTO);
982 |
983 | // Returns true if the plot area in the current plot is hovered.
984 | IMPLOT_API bool IsPlotHovered();
985 | // Returns true if the axis label area in the current plot is hovered.
986 | IMPLOT_API bool IsAxisHovered(ImAxis axis);
987 | // Returns true if the bounding frame of a subplot is hovered.
988 | IMPLOT_API bool IsSubplotsHovered();
989 |
990 | // Returns true if the current plot is being box selected.
991 | IMPLOT_API bool IsPlotSelected();
992 | // Returns the current plot box selection bounds. Passing IMPLOT_AUTO uses the current axes.
993 | IMPLOT_API ImPlotRect GetPlotSelection(ImAxis x_axis = IMPLOT_AUTO, ImAxis y_axis = IMPLOT_AUTO);
994 | // Cancels a the current plot box selection.
995 | IMPLOT_API void CancelPlotSelection();
996 |
997 | // Hides or shows the next plot item (i.e. as if it were toggled from the legend).
998 | // Use ImPlotCond_Always if you need to forcefully set this every frame.
999 | IMPLOT_API void HideNextItem(bool hidden = true, ImPlotCond cond = ImPlotCond_Once);
1000 |
1001 | // Use the following around calls to Begin/EndPlot to align l/r/t/b padding.
1002 | // Consider using Begin/EndSubplots first. They are more feature rich and
1003 | // accomplish the same behaviour by default. The functions below offer lower
1004 | // level control of plot alignment.
1005 |
1006 | // Align axis padding over multiple plots in a single row or column. #group_id must
1007 | // be unique. If this function returns true, EndAlignedPlots() must be called.
1008 | IMPLOT_API bool BeginAlignedPlots(const char* group_id, bool vertical = true);
1009 | // Only call EndAlignedPlots() if BeginAlignedPlots() returns true!
1010 | IMPLOT_API void EndAlignedPlots();
1011 |
1012 | //-----------------------------------------------------------------------------
1013 | // [SECTION] Legend Utils
1014 | //-----------------------------------------------------------------------------
1015 |
1016 | // Begin a popup for a legend entry.
1017 | IMPLOT_API bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button=1);
1018 | // End a popup for a legend entry.
1019 | IMPLOT_API void EndLegendPopup();
1020 | // Returns true if a plot item legend entry is hovered.
1021 | IMPLOT_API bool IsLegendEntryHovered(const char* label_id);
1022 |
1023 | //-----------------------------------------------------------------------------
1024 | // [SECTION] Drag and Drop
1025 | //-----------------------------------------------------------------------------
1026 |
1027 | // Turns the current plot's plotting area into a drag and drop target. Don't forget to call EndDragDropTarget!
1028 | IMPLOT_API bool BeginDragDropTargetPlot();
1029 | // Turns the current plot's X-axis into a drag and drop target. Don't forget to call EndDragDropTarget!
1030 | IMPLOT_API bool BeginDragDropTargetAxis(ImAxis axis);
1031 | // Turns the current plot's legend into a drag and drop target. Don't forget to call EndDragDropTarget!
1032 | IMPLOT_API bool BeginDragDropTargetLegend();
1033 | // Ends a drag and drop target (currently just an alias for ImGui::EndDragDropTarget).
1034 | IMPLOT_API void EndDragDropTarget();
1035 |
1036 | // NB: By default, plot and axes drag and drop *sources* require holding the Ctrl modifier to initiate the drag.
1037 | // You can change the modifier if desired. If ImGuiMod_None is provided, the axes will be locked from panning.
1038 |
1039 | // Turns the current plot's plotting area into a drag and drop source. You must hold Ctrl. Don't forget to call EndDragDropSource!
1040 | IMPLOT_API bool BeginDragDropSourcePlot(ImGuiDragDropFlags flags=0);
1041 | // Turns the current plot's X-axis into a drag and drop source. You must hold Ctrl. Don't forget to call EndDragDropSource!
1042 | IMPLOT_API bool BeginDragDropSourceAxis(ImAxis axis, ImGuiDragDropFlags flags=0);
1043 | // Turns an item in the current plot's legend into drag and drop source. Don't forget to call EndDragDropSource!
1044 | IMPLOT_API bool BeginDragDropSourceItem(const char* label_id, ImGuiDragDropFlags flags=0);
1045 | // Ends a drag and drop source (currently just an alias for ImGui::EndDragDropSource).
1046 | IMPLOT_API void EndDragDropSource();
1047 |
1048 | //-----------------------------------------------------------------------------
1049 | // [SECTION] Styling
1050 | //-----------------------------------------------------------------------------
1051 |
1052 | // Styling colors in ImPlot works similarly to styling colors in ImGui, but
1053 | // with one important difference. Like ImGui, all style colors are stored in an
1054 | // indexable array in ImPlotStyle. You can permanently modify these values through
1055 | // GetStyle().Colors, or temporarily modify them with Push/Pop functions below.
1056 | // However, by default all style colors in ImPlot default to a special color
1057 | // IMPLOT_AUTO_COL. The behavior of this color depends upon the style color to
1058 | // which it as applied:
1059 | //
1060 | // 1) For style colors associated with plot items (e.g. ImPlotCol_Line),
1061 | // IMPLOT_AUTO_COL tells ImPlot to color the item with the next unused
1062 | // color in the current colormap. Thus, every item will have a different
1063 | // color up to the number of colors in the colormap, at which point the
1064 | // colormap will roll over. For most use cases, you should not need to
1065 | // set these style colors to anything but IMPLOT_COL_AUTO; you are
1066 | // probably better off changing the current colormap. However, if you
1067 | // need to explicitly color a particular item you may either Push/Pop
1068 | // the style color around the item in question, or use the SetNextXXXStyle
1069 | // API below. If you permanently set one of these style colors to a specific
1070 | // color, or forget to call Pop, then all subsequent items will be styled
1071 | // with the color you set.
1072 | //
1073 | // 2) For style colors associated with plot styling (e.g. ImPlotCol_PlotBg),
1074 | // IMPLOT_AUTO_COL tells ImPlot to set that color from color data in your
1075 | // **ImGuiStyle**. The ImGuiCol_ that these style colors default to are
1076 | // detailed above, and in general have been mapped to produce plots visually
1077 | // consistent with your current ImGui style. Of course, you are free to
1078 | // manually set these colors to whatever you like, and further can Push/Pop
1079 | // them around individual plots for plot-specific styling (e.g. coloring axes).
1080 |
1081 | // Provides access to plot style structure for permanant modifications to colors, sizes, etc.
1082 | IMPLOT_API ImPlotStyle& GetStyle();
1083 |
1084 | // Style plot colors for current ImGui style (default).
1085 | IMPLOT_API void StyleColorsAuto(ImPlotStyle* dst = nullptr);
1086 | // Style plot colors for ImGui "Classic".
1087 | IMPLOT_API void StyleColorsClassic(ImPlotStyle* dst = nullptr);
1088 | // Style plot colors for ImGui "Dark".
1089 | IMPLOT_API void StyleColorsDark(ImPlotStyle* dst = nullptr);
1090 | // Style plot colors for ImGui "Light".
1091 | IMPLOT_API void StyleColorsLight(ImPlotStyle* dst = nullptr);
1092 |
1093 | // Use PushStyleX to temporarily modify your ImPlotStyle. The modification
1094 | // will last until the matching call to PopStyleX. You MUST call a pop for
1095 | // every push, otherwise you will leak memory! This behaves just like ImGui.
1096 |
1097 | // Temporarily modify a style color. Don't forget to call PopStyleColor!
1098 | IMPLOT_API void PushStyleColor(ImPlotCol idx, ImU32 col);
1099 | IMPLOT_API void PushStyleColor(ImPlotCol idx, const ImVec4& col);
1100 | // Undo temporary style color modification(s). Undo multiple pushes at once by increasing count.
1101 | IMPLOT_API void PopStyleColor(int count = 1);
1102 |
1103 | // Temporarily modify a style variable of float type. Don't forget to call PopStyleVar!
1104 | IMPLOT_API void PushStyleVar(ImPlotStyleVar idx, float val);
1105 | // Temporarily modify a style variable of int type. Don't forget to call PopStyleVar!
1106 | IMPLOT_API void PushStyleVar(ImPlotStyleVar idx, int val);
1107 | // Temporarily modify a style variable of ImVec2 type. Don't forget to call PopStyleVar!
1108 | IMPLOT_API void PushStyleVar(ImPlotStyleVar idx, const ImVec2& val);
1109 | // Undo temporary style variable modification(s). Undo multiple pushes at once by increasing count.
1110 | IMPLOT_API void PopStyleVar(int count = 1);
1111 |
1112 | // The following can be used to modify the style of the next plot item ONLY. They do
1113 | // NOT require calls to PopStyleX. Leave style attributes you don't want modified to
1114 | // IMPLOT_AUTO or IMPLOT_AUTO_COL. Automatic styles will be deduced from the current
1115 | // values in your ImPlotStyle or from Colormap data.
1116 |
1117 | // Set the line color and weight for the next item only.
1118 | IMPLOT_API void SetNextLineStyle(const ImVec4& col = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO);
1119 | // Set the fill color for the next item only.
1120 | IMPLOT_API void SetNextFillStyle(const ImVec4& col = IMPLOT_AUTO_COL, float alpha_mod = IMPLOT_AUTO);
1121 | // Set the marker style for the next item only.
1122 | IMPLOT_API void SetNextMarkerStyle(ImPlotMarker marker = IMPLOT_AUTO, float size = IMPLOT_AUTO, const ImVec4& fill = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO, const ImVec4& outline = IMPLOT_AUTO_COL);
1123 | // Set the error bar style for the next item only.
1124 | IMPLOT_API void SetNextErrorBarStyle(const ImVec4& col = IMPLOT_AUTO_COL, float size = IMPLOT_AUTO, float weight = IMPLOT_AUTO);
1125 |
1126 | // Gets the last item primary color (i.e. its legend icon color)
1127 | IMPLOT_API ImVec4 GetLastItemColor();
1128 |
1129 | // Returns the null terminated string name for an ImPlotCol.
1130 | IMPLOT_API const char* GetStyleColorName(ImPlotCol idx);
1131 | // Returns the null terminated string name for an ImPlotMarker.
1132 | IMPLOT_API const char* GetMarkerName(ImPlotMarker idx);
1133 |
1134 | //-----------------------------------------------------------------------------
1135 | // [SECTION] Colormaps
1136 | //-----------------------------------------------------------------------------
1137 |
1138 | // Item styling is based on colormaps when the relevant ImPlotCol_XXX is set to
1139 | // IMPLOT_AUTO_COL (default). Several built-in colormaps are available. You can
1140 | // add and then push/pop your own colormaps as well. To permanently set a colormap,
1141 | // modify the Colormap index member of your ImPlotStyle.
1142 |
1143 | // Colormap data will be ignored and a custom color will be used if you have done one of the following:
1144 | // 1) Modified an item style color in your ImPlotStyle to anything other than IMPLOT_AUTO_COL.
1145 | // 2) Pushed an item style color using PushStyleColor().
1146 | // 3) Set the next item style with a SetNextXXXStyle function.
1147 |
1148 | // Add a new colormap. The color data will be copied. The colormap can be used by pushing either the returned index or the
1149 | // string name with PushColormap. The colormap name must be unique and the size must be greater than 1. You will receive
1150 | // an assert otherwise! By default colormaps are considered to be qualitative (i.e. discrete). If you want to create a
1151 | // continuous colormap, set #qual=false. This will treat the colors you provide as keys, and ImPlot will build a linearly
1152 | // interpolated lookup table. The memory footprint of this table will be exactly ((size-1)*255+1)*4 bytes.
1153 | IMPLOT_API ImPlotColormap AddColormap(const char* name, const ImVec4* cols, int size, bool qual=true);
1154 | IMPLOT_API ImPlotColormap AddColormap(const char* name, const ImU32* cols, int size, bool qual=true);
1155 |
1156 | // Returns the number of available colormaps (i.e. the built-in + user-added count).
1157 | IMPLOT_API int GetColormapCount();
1158 | // Returns a null terminated string name for a colormap given an index. Returns nullptr if index is invalid.
1159 | IMPLOT_API const char* GetColormapName(ImPlotColormap cmap);
1160 | // Returns an index number for a colormap given a valid string name. Returns -1 if name is invalid.
1161 | IMPLOT_API ImPlotColormap GetColormapIndex(const char* name);
1162 |
1163 | // Temporarily switch to one of the built-in (i.e. ImPlotColormap_XXX) or user-added colormaps (i.e. a return value of AddColormap). Don't forget to call PopColormap!
1164 | IMPLOT_API void PushColormap(ImPlotColormap cmap);
1165 | // Push a colormap by string name. Use built-in names such as "Default", "Deep", "Jet", etc. or a string you provided to AddColormap. Don't forget to call PopColormap!
1166 | IMPLOT_API void PushColormap(const char* name);
1167 | // Undo temporary colormap modification(s). Undo multiple pushes at once by increasing count.
1168 | IMPLOT_API void PopColormap(int count = 1);
1169 |
1170 | // Returns the next color from the current colormap and advances the colormap for the current plot.
1171 | // Can also be used with no return value to skip colors if desired. You need to call this between Begin/EndPlot!
1172 | IMPLOT_API ImVec4 NextColormapColor();
1173 |
1174 | // Colormap utils. If cmap = IMPLOT_AUTO (default), the current colormap is assumed.
1175 | // Pass an explicit colormap index (built-in or user-added) to specify otherwise.
1176 |
1177 | // Returns the size of a colormap.
1178 | IMPLOT_API int GetColormapSize(ImPlotColormap cmap = IMPLOT_AUTO);
1179 | // Returns a color from a colormap given an index >= 0 (modulo will be performed).
1180 | IMPLOT_API ImVec4 GetColormapColor(int idx, ImPlotColormap cmap = IMPLOT_AUTO);
1181 | // Sample a color from the current colormap given t between 0 and 1.
1182 | IMPLOT_API ImVec4 SampleColormap(float t, ImPlotColormap cmap = IMPLOT_AUTO);
1183 |
1184 | // Shows a vertical color scale with linear spaced ticks using the specified color map. Use double hashes to hide label (e.g. "##NoLabel"). If scale_min > scale_max, the scale to color mapping will be reversed.
1185 | IMPLOT_API void ColormapScale(const char* label, double scale_min, double scale_max, const ImVec2& size = ImVec2(0,0), const char* format = "%g", ImPlotColormapScaleFlags flags = 0, ImPlotColormap cmap = IMPLOT_AUTO);
1186 | // Shows a horizontal slider with a colormap gradient background. Optionally returns the color sampled at t in [0 1].
1187 | IMPLOT_API bool ColormapSlider(const char* label, float* t, ImVec4* out = nullptr, const char* format = "", ImPlotColormap cmap = IMPLOT_AUTO);
1188 | // Shows a button with a colormap gradient brackground.
1189 | IMPLOT_API bool ColormapButton(const char* label, const ImVec2& size = ImVec2(0,0), ImPlotColormap cmap = IMPLOT_AUTO);
1190 |
1191 | // When items in a plot sample their color from a colormap, the color is cached and does not change
1192 | // unless explicitly overriden. Therefore, if you change the colormap after the item has already been plotted,
1193 | // item colors will NOT update. If you need item colors to resample the new colormap, then use this
1194 | // function to bust the cached colors. If #plot_title_id is nullptr, then every item in EVERY existing plot
1195 | // will be cache busted. Otherwise only the plot specified by #plot_title_id will be busted. For the
1196 | // latter, this function must be called in the same ImGui ID scope that the plot is in. You should rarely if ever
1197 | // need this function, but it is available for applications that require runtime colormap swaps (e.g. Heatmaps demo).
1198 | IMPLOT_API void BustColorCache(const char* plot_title_id = nullptr);
1199 |
1200 | //-----------------------------------------------------------------------------
1201 | // [SECTION] Input Mapping
1202 | //-----------------------------------------------------------------------------
1203 |
1204 | // Provides access to input mapping structure for permanant modifications to controls for pan, select, etc.
1205 | IMPLOT_API ImPlotInputMap& GetInputMap();
1206 |
1207 | // Default input mapping: pan = LMB drag, box select = RMB drag, fit = LMB double click, context menu = RMB click, zoom = scroll.
1208 | IMPLOT_API void MapInputDefault(ImPlotInputMap* dst = nullptr);
1209 | // Reverse input mapping: pan = RMB drag, box select = LMB drag, fit = LMB double click, context menu = RMB click, zoom = scroll.
1210 | IMPLOT_API void MapInputReverse(ImPlotInputMap* dst = nullptr);
1211 |
1212 | //-----------------------------------------------------------------------------
1213 | // [SECTION] Miscellaneous
1214 | //-----------------------------------------------------------------------------
1215 |
1216 | // Render icons similar to those that appear in legends (nifty for data lists).
1217 | IMPLOT_API void ItemIcon(const ImVec4& col);
1218 | IMPLOT_API void ItemIcon(ImU32 col);
1219 | IMPLOT_API void ColormapIcon(ImPlotColormap cmap);
1220 |
1221 | // Get the plot draw list for custom rendering to the current plot area. Call between Begin/EndPlot.
1222 | IMPLOT_API ImDrawList* GetPlotDrawList();
1223 | // Push clip rect for rendering to current plot area. The rect can be expanded or contracted by #expand pixels. Call between Begin/EndPlot.
1224 | IMPLOT_API void PushPlotClipRect(float expand=0);
1225 | // Pop plot clip rect. Call between Begin/EndPlot.
1226 | IMPLOT_API void PopPlotClipRect();
1227 |
1228 | // Shows ImPlot style selector dropdown menu.
1229 | IMPLOT_API bool ShowStyleSelector(const char* label);
1230 | // Shows ImPlot colormap selector dropdown menu.
1231 | IMPLOT_API bool ShowColormapSelector(const char* label);
1232 | // Shows ImPlot input map selector dropdown menu.
1233 | IMPLOT_API bool ShowInputMapSelector(const char* label);
1234 | // Shows ImPlot style editor block (not a window).
1235 | IMPLOT_API void ShowStyleEditor(ImPlotStyle* ref = nullptr);
1236 | // Add basic help/info block for end users (not a window).
1237 | IMPLOT_API void ShowUserGuide();
1238 | // Shows ImPlot metrics/debug information window.
1239 | IMPLOT_API void ShowMetricsWindow(bool* p_popen = nullptr);
1240 |
1241 | //-----------------------------------------------------------------------------
1242 | // [SECTION] Demo
1243 | //-----------------------------------------------------------------------------
1244 |
1245 | // Shows the ImPlot demo window (add implot_demo.cpp to your sources!)
1246 | IMPLOT_API void ShowDemoWindow(bool* p_open = nullptr);
1247 |
1248 | } // namespace ImPlot
1249 |
1250 | //-----------------------------------------------------------------------------
1251 | // [SECTION] Obsolete API
1252 | //-----------------------------------------------------------------------------
1253 |
1254 | // The following functions will be removed! Keep your copy of implot up to date!
1255 | // Occasionally set '#define IMPLOT_DISABLE_OBSOLETE_FUNCTIONS' to stay ahead.
1256 | // If you absolutely must use these functions and do not want to receive compiler
1257 | // warnings, set '#define IMPLOT_DISABLE_OBSOLETE_WARNINGS'.
1258 |
1259 | #ifndef IMPLOT_DISABLE_OBSOLETE_FUNCTIONS
1260 |
1261 | #ifndef IMPLOT_DISABLE_DEPRECATED_WARNINGS
1262 | #if __cplusplus > 201402L
1263 | #define IMPLOT_DEPRECATED(method) [[deprecated]] method
1264 | #elif defined( __GNUC__ ) && !defined( __INTEL_COMPILER ) && ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 1 ) )
1265 | #define IMPLOT_DEPRECATED(method) method __attribute__( ( deprecated ) )
1266 | #elif defined( _MSC_VER )
1267 | #define IMPLOT_DEPRECATED(method) __declspec(deprecated) method
1268 | #else
1269 | #define IMPLOT_DEPRECATED(method) method
1270 | #endif
1271 | #else
1272 | #define IMPLOT_DEPRECATED(method) method
1273 | #endif
1274 |
1275 | enum ImPlotFlagsObsolete_ {
1276 | ImPlotFlags_YAxis2 = 1 << 20,
1277 | ImPlotFlags_YAxis3 = 1 << 21,
1278 | };
1279 |
1280 | namespace ImPlot {
1281 |
1282 | // OBSOLETED in v0.13 -> PLANNED REMOVAL in v1.0
1283 | IMPLOT_DEPRECATED( IMPLOT_API bool BeginPlot(const char* title_id,
1284 | const char* x_label, // = nullptr,
1285 | const char* y_label, // = nullptr,
1286 | const ImVec2& size = ImVec2(-1,0),
1287 | ImPlotFlags flags = ImPlotFlags_None,
1288 | ImPlotAxisFlags x_flags = 0,
1289 | ImPlotAxisFlags y_flags = 0,
1290 | ImPlotAxisFlags y2_flags = ImPlotAxisFlags_AuxDefault,
1291 | ImPlotAxisFlags y3_flags = ImPlotAxisFlags_AuxDefault,
1292 | const char* y2_label = nullptr,
1293 | const char* y3_label = nullptr) );
1294 |
1295 | } // namespace ImPlot
1296 |
1297 | #endif
1298 |
--------------------------------------------------------------------------------
/implot_internal.h:
--------------------------------------------------------------------------------
1 | // MIT License
2 |
3 | // Copyright (c) 2023 Evan Pezent
4 |
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 |
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 |
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | // ImPlot v0.17
24 |
25 | // You may use this file to debug, understand or extend ImPlot features but we
26 | // don't provide any guarantee of forward compatibility!
27 |
28 | //-----------------------------------------------------------------------------
29 | // [SECTION] Header Mess
30 | //-----------------------------------------------------------------------------
31 |
32 | #pragma once
33 |
34 | #include
35 | #include "imgui_internal.h"
36 |
37 | #ifndef IMPLOT_VERSION
38 | #error Must include implot.h before implot_internal.h
39 | #endif
40 |
41 |
42 | // Support for pre-1.84 versions. ImPool's GetSize() -> GetBufSize()
43 | #if (IMGUI_VERSION_NUM < 18303)
44 | #define GetBufSize GetSize
45 | #endif
46 |
47 | //-----------------------------------------------------------------------------
48 | // [SECTION] Constants
49 | //-----------------------------------------------------------------------------
50 |
51 | // Constants can be changed unless stated otherwise. We may move some of these
52 | // to ImPlotStyleVar_ over time.
53 |
54 | // Mimimum allowable timestamp value 01/01/1970 @ 12:00am (UTC) (DO NOT DECREASE THIS)
55 | #define IMPLOT_MIN_TIME 0
56 | // Maximum allowable timestamp value 01/01/3000 @ 12:00am (UTC) (DO NOT INCREASE THIS)
57 | #define IMPLOT_MAX_TIME 32503680000
58 | // Default label format for axis labels
59 | #define IMPLOT_LABEL_FORMAT "%g"
60 | // Max character size for tick labels
61 | #define IMPLOT_LABEL_MAX_SIZE 32
62 |
63 | //-----------------------------------------------------------------------------
64 | // [SECTION] Macros
65 | //-----------------------------------------------------------------------------
66 |
67 | #define IMPLOT_NUM_X_AXES ImAxis_Y1
68 | #define IMPLOT_NUM_Y_AXES (ImAxis_COUNT - IMPLOT_NUM_X_AXES)
69 |
70 | // Split ImU32 color into RGB components [0 255]
71 | #define IM_COL32_SPLIT_RGB(col,r,g,b) \
72 | ImU32 r = ((col >> IM_COL32_R_SHIFT) & 0xFF); \
73 | ImU32 g = ((col >> IM_COL32_G_SHIFT) & 0xFF); \
74 | ImU32 b = ((col >> IM_COL32_B_SHIFT) & 0xFF);
75 |
76 | //-----------------------------------------------------------------------------
77 | // [SECTION] Forward Declarations
78 | //-----------------------------------------------------------------------------
79 |
80 | struct ImPlotTick;
81 | struct ImPlotAxis;
82 | struct ImPlotAxisColor;
83 | struct ImPlotItem;
84 | struct ImPlotLegend;
85 | struct ImPlotPlot;
86 | struct ImPlotNextPlotData;
87 | struct ImPlotTicker;
88 |
89 | //-----------------------------------------------------------------------------
90 | // [SECTION] Context Pointer
91 | //-----------------------------------------------------------------------------
92 |
93 | #ifndef GImPlot
94 | extern IMPLOT_API ImPlotContext* GImPlot; // Current implicit context pointer
95 | #endif
96 |
97 | //-----------------------------------------------------------------------------
98 | // [SECTION] Generic Helpers
99 | //-----------------------------------------------------------------------------
100 |
101 | // Computes the common (base-10) logarithm
102 | static inline float ImLog10(float x) { return log10f(x); }
103 | static inline double ImLog10(double x) { return log10(x); }
104 | static inline float ImSinh(float x) { return sinhf(x); }
105 | static inline double ImSinh(double x) { return sinh(x); }
106 | static inline float ImAsinh(float x) { return asinhf(x); }
107 | static inline double ImAsinh(double x) { return asinh(x); }
108 | // Returns true if a flag is set
109 | template
110 | static inline bool ImHasFlag(TSet set, TFlag flag) { return (set & flag) == flag; }
111 | // Flips a flag in a flagset
112 | template
113 | static inline void ImFlipFlag(TSet& set, TFlag flag) { ImHasFlag(set, flag) ? set &= ~flag : set |= flag; }
114 | // Linearly remaps x from [x0 x1] to [y0 y1].
115 | template
116 | static inline T ImRemap(T x, T x0, T x1, T y0, T y1) { return y0 + (x - x0) * (y1 - y0) / (x1 - x0); }
117 | // Linear rempas x from [x0 x1] to [0 1]
118 | template
119 | static inline T ImRemap01(T x, T x0, T x1) { return (x - x0) / (x1 - x0); }
120 | // Returns always positive modulo (assumes r != 0)
121 | static inline int ImPosMod(int l, int r) { return (l % r + r) % r; }
122 | // Returns true if val is NAN
123 | static inline bool ImNan(double val) { return isnan(val); }
124 | // Returns true if val is NAN or INFINITY
125 | static inline bool ImNanOrInf(double val) { return !(val >= -DBL_MAX && val <= DBL_MAX) || ImNan(val); }
126 | // Turns NANs to 0s
127 | static inline double ImConstrainNan(double val) { return ImNan(val) ? 0 : val; }
128 | // Turns infinity to floating point maximums
129 | static inline double ImConstrainInf(double val) { return val >= DBL_MAX ? DBL_MAX : val <= -DBL_MAX ? - DBL_MAX : val; }
130 | // Turns numbers less than or equal to 0 to 0.001 (sort of arbitrary, is there a better way?)
131 | static inline double ImConstrainLog(double val) { return val <= 0 ? 0.001f : val; }
132 | // Turns numbers less than 0 to zero
133 | static inline double ImConstrainTime(double val) { return val < IMPLOT_MIN_TIME ? IMPLOT_MIN_TIME : (val > IMPLOT_MAX_TIME ? IMPLOT_MAX_TIME : val); }
134 | // True if two numbers are approximately equal using units in the last place.
135 | static inline bool ImAlmostEqual(double v1, double v2, int ulp = 2) { return ImAbs(v1-v2) < DBL_EPSILON * ImAbs(v1+v2) * ulp || ImAbs(v1-v2) < DBL_MIN; }
136 | // Finds min value in an unsorted array
137 | template
138 | static inline T ImMinArray(const T* values, int count) { T m = values[0]; for (int i = 1; i < count; ++i) { if (values[i] < m) { m = values[i]; } } return m; }
139 | // Finds the max value in an unsorted array
140 | template
141 | static inline T ImMaxArray(const T* values, int count) { T m = values[0]; for (int i = 1; i < count; ++i) { if (values[i] > m) { m = values[i]; } } return m; }
142 | // Finds the min and max value in an unsorted array
143 | template
144 | static inline void ImMinMaxArray(const T* values, int count, T* min_out, T* max_out) {
145 | T Min = values[0]; T Max = values[0];
146 | for (int i = 1; i < count; ++i) {
147 | if (values[i] < Min) { Min = values[i]; }
148 | if (values[i] > Max) { Max = values[i]; }
149 | }
150 | *min_out = Min; *max_out = Max;
151 | }
152 | // Finds the sim of an array
153 | template
154 | static inline T ImSum(const T* values, int count) {
155 | T sum = 0;
156 | for (int i = 0; i < count; ++i)
157 | sum += values[i];
158 | return sum;
159 | }
160 | // Finds the mean of an array
161 | template
162 | static inline double ImMean(const T* values, int count) {
163 | double den = 1.0 / count;
164 | double mu = 0;
165 | for (int i = 0; i < count; ++i)
166 | mu += (double)values[i] * den;
167 | return mu;
168 | }
169 | // Finds the sample standard deviation of an array
170 | template
171 | static inline double ImStdDev(const T* values, int count) {
172 | double den = 1.0 / (count - 1.0);
173 | double mu = ImMean(values, count);
174 | double x = 0;
175 | for (int i = 0; i < count; ++i)
176 | x += ((double)values[i] - mu) * ((double)values[i] - mu) * den;
177 | return sqrt(x);
178 | }
179 | // Mix color a and b by factor s in [0 256]
180 | static inline ImU32 ImMixU32(ImU32 a, ImU32 b, ImU32 s) {
181 | #ifdef IMPLOT_MIX64
182 | const ImU32 af = 256-s;
183 | const ImU32 bf = s;
184 | const ImU64 al = (a & 0x00ff00ff) | (((ImU64)(a & 0xff00ff00)) << 24);
185 | const ImU64 bl = (b & 0x00ff00ff) | (((ImU64)(b & 0xff00ff00)) << 24);
186 | const ImU64 mix = (al * af + bl * bf);
187 | return ((mix >> 32) & 0xff00ff00) | ((mix & 0xff00ff00) >> 8);
188 | #else
189 | const ImU32 af = 256-s;
190 | const ImU32 bf = s;
191 | const ImU32 al = (a & 0x00ff00ff);
192 | const ImU32 ah = (a & 0xff00ff00) >> 8;
193 | const ImU32 bl = (b & 0x00ff00ff);
194 | const ImU32 bh = (b & 0xff00ff00) >> 8;
195 | const ImU32 ml = (al * af + bl * bf);
196 | const ImU32 mh = (ah * af + bh * bf);
197 | return (mh & 0xff00ff00) | ((ml & 0xff00ff00) >> 8);
198 | #endif
199 | }
200 |
201 | // Lerp across an array of 32-bit collors given t in [0.0 1.0]
202 | static inline ImU32 ImLerpU32(const ImU32* colors, int size, float t) {
203 | int i1 = (int)((size - 1 ) * t);
204 | int i2 = i1 + 1;
205 | if (i2 == size || size == 1)
206 | return colors[i1];
207 | float den = 1.0f / (size - 1);
208 | float t1 = i1 * den;
209 | float t2 = i2 * den;
210 | float tr = ImRemap01(t, t1, t2);
211 | return ImMixU32(colors[i1], colors[i2], (ImU32)(tr*256));
212 | }
213 |
214 | // Set alpha channel of 32-bit color from float in range [0.0 1.0]
215 | static inline ImU32 ImAlphaU32(ImU32 col, float alpha) {
216 | return col & ~((ImU32)((1.0f-alpha)*255)<
221 | static inline bool ImOverlaps(T min_a, T max_a, T min_b, T max_b) {
222 | return min_a <= max_b && min_b <= max_a;
223 | }
224 |
225 | //-----------------------------------------------------------------------------
226 | // [SECTION] ImPlot Enums
227 | //-----------------------------------------------------------------------------
228 |
229 | typedef int ImPlotTimeUnit; // -> enum ImPlotTimeUnit_
230 | typedef int ImPlotDateFmt; // -> enum ImPlotDateFmt_
231 | typedef int ImPlotTimeFmt; // -> enum ImPlotTimeFmt_
232 |
233 | enum ImPlotTimeUnit_ {
234 | ImPlotTimeUnit_Us, // microsecond
235 | ImPlotTimeUnit_Ms, // millisecond
236 | ImPlotTimeUnit_S, // second
237 | ImPlotTimeUnit_Min, // minute
238 | ImPlotTimeUnit_Hr, // hour
239 | ImPlotTimeUnit_Day, // day
240 | ImPlotTimeUnit_Mo, // month
241 | ImPlotTimeUnit_Yr, // year
242 | ImPlotTimeUnit_COUNT
243 | };
244 |
245 | enum ImPlotDateFmt_ { // default [ ISO 8601 ]
246 | ImPlotDateFmt_None = 0,
247 | ImPlotDateFmt_DayMo, // 10/3 [ --10-03 ]
248 | ImPlotDateFmt_DayMoYr, // 10/3/91 [ 1991-10-03 ]
249 | ImPlotDateFmt_MoYr, // Oct 1991 [ 1991-10 ]
250 | ImPlotDateFmt_Mo, // Oct [ --10 ]
251 | ImPlotDateFmt_Yr // 1991 [ 1991 ]
252 | };
253 |
254 | enum ImPlotTimeFmt_ { // default [ 24 Hour Clock ]
255 | ImPlotTimeFmt_None = 0,
256 | ImPlotTimeFmt_Us, // .428 552 [ .428 552 ]
257 | ImPlotTimeFmt_SUs, // :29.428 552 [ :29.428 552 ]
258 | ImPlotTimeFmt_SMs, // :29.428 [ :29.428 ]
259 | ImPlotTimeFmt_S, // :29 [ :29 ]
260 | ImPlotTimeFmt_MinSMs, // 21:29.428 [ 21:29.428 ]
261 | ImPlotTimeFmt_HrMinSMs, // 7:21:29.428pm [ 19:21:29.428 ]
262 | ImPlotTimeFmt_HrMinS, // 7:21:29pm [ 19:21:29 ]
263 | ImPlotTimeFmt_HrMin, // 7:21pm [ 19:21 ]
264 | ImPlotTimeFmt_Hr // 7pm [ 19:00 ]
265 | };
266 |
267 | //-----------------------------------------------------------------------------
268 | // [SECTION] Callbacks
269 | //-----------------------------------------------------------------------------
270 |
271 | typedef void (*ImPlotLocator)(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
272 |
273 | //-----------------------------------------------------------------------------
274 | // [SECTION] Structs
275 | //-----------------------------------------------------------------------------
276 |
277 | // Combined date/time format spec
278 | struct ImPlotDateTimeSpec {
279 | ImPlotDateTimeSpec() {}
280 | ImPlotDateTimeSpec(ImPlotDateFmt date_fmt, ImPlotTimeFmt time_fmt, bool use_24_hr_clk = false, bool use_iso_8601 = false) {
281 | Date = date_fmt;
282 | Time = time_fmt;
283 | UseISO8601 = use_iso_8601;
284 | Use24HourClock = use_24_hr_clk;
285 | }
286 | ImPlotDateFmt Date;
287 | ImPlotTimeFmt Time;
288 | bool UseISO8601;
289 | bool Use24HourClock;
290 | };
291 |
292 | // Two part timestamp struct.
293 | struct ImPlotTime {
294 | time_t S; // second part
295 | int Us; // microsecond part
296 | ImPlotTime() { S = 0; Us = 0; }
297 | ImPlotTime(time_t s, int us = 0) { S = s + us / 1000000; Us = us % 1000000; }
298 | void RollOver() { S = S + Us / 1000000; Us = Us % 1000000; }
299 | double ToDouble() const { return (double)S + (double)Us / 1000000.0; }
300 | static ImPlotTime FromDouble(double t) { return ImPlotTime((time_t)t, (int)(t * 1000000 - floor(t) * 1000000)); }
301 | };
302 |
303 | static inline ImPlotTime operator+(const ImPlotTime& lhs, const ImPlotTime& rhs)
304 | { return ImPlotTime(lhs.S + rhs.S, lhs.Us + rhs.Us); }
305 | static inline ImPlotTime operator-(const ImPlotTime& lhs, const ImPlotTime& rhs)
306 | { return ImPlotTime(lhs.S - rhs.S, lhs.Us - rhs.Us); }
307 | static inline bool operator==(const ImPlotTime& lhs, const ImPlotTime& rhs)
308 | { return lhs.S == rhs.S && lhs.Us == rhs.Us; }
309 | static inline bool operator<(const ImPlotTime& lhs, const ImPlotTime& rhs)
310 | { return lhs.S == rhs.S ? lhs.Us < rhs.Us : lhs.S < rhs.S; }
311 | static inline bool operator>(const ImPlotTime& lhs, const ImPlotTime& rhs)
312 | { return rhs < lhs; }
313 | static inline bool operator<=(const ImPlotTime& lhs, const ImPlotTime& rhs)
314 | { return lhs < rhs || lhs == rhs; }
315 | static inline bool operator>=(const ImPlotTime& lhs, const ImPlotTime& rhs)
316 | { return lhs > rhs || lhs == rhs; }
317 |
318 | // Colormap data storage
319 | struct ImPlotColormapData {
320 | ImVector Keys;
321 | ImVector KeyCounts;
322 | ImVector KeyOffsets;
323 | ImVector Tables;
324 | ImVector TableSizes;
325 | ImVector TableOffsets;
326 | ImGuiTextBuffer Text;
327 | ImVector TextOffsets;
328 | ImVector Quals;
329 | ImGuiStorage Map;
330 | int Count;
331 |
332 | ImPlotColormapData() { Count = 0; }
333 |
334 | int Append(const char* name, const ImU32* keys, int count, bool qual) {
335 | if (GetIndex(name) != -1)
336 | return -1;
337 | KeyOffsets.push_back(Keys.size());
338 | KeyCounts.push_back(count);
339 | Keys.reserve(Keys.size()+count);
340 | for (int i = 0; i < count; ++i)
341 | Keys.push_back(keys[i]);
342 | TextOffsets.push_back(Text.size());
343 | Text.append(name, name + strlen(name) + 1);
344 | Quals.push_back(qual);
345 | ImGuiID id = ImHashStr(name);
346 | int idx = Count++;
347 | Map.SetInt(id,idx);
348 | _AppendTable(idx);
349 | return idx;
350 | }
351 |
352 | void _AppendTable(ImPlotColormap cmap) {
353 | int key_count = GetKeyCount(cmap);
354 | const ImU32* keys = GetKeys(cmap);
355 | int off = Tables.size();
356 | TableOffsets.push_back(off);
357 | if (IsQual(cmap)) {
358 | Tables.reserve(key_count);
359 | for (int i = 0; i < key_count; ++i)
360 | Tables.push_back(keys[i]);
361 | TableSizes.push_back(key_count);
362 | }
363 | else {
364 | int max_size = 255 * (key_count-1) + 1;
365 | Tables.reserve(off + max_size);
366 | // ImU32 last = keys[0];
367 | // Tables.push_back(last);
368 | // int n = 1;
369 | for (int i = 0; i < key_count-1; ++i) {
370 | for (int s = 0; s < 255; ++s) {
371 | ImU32 a = keys[i];
372 | ImU32 b = keys[i+1];
373 | ImU32 c = ImMixU32(a,b,s);
374 | // if (c != last) {
375 | Tables.push_back(c);
376 | // last = c;
377 | // n++;
378 | // }
379 | }
380 | }
381 | ImU32 c = keys[key_count-1];
382 | // if (c != last) {
383 | Tables.push_back(c);
384 | // n++;
385 | // }
386 | // TableSizes.push_back(n);
387 | TableSizes.push_back(max_size);
388 | }
389 | }
390 |
391 | void RebuildTables() {
392 | Tables.resize(0);
393 | TableSizes.resize(0);
394 | TableOffsets.resize(0);
395 | for (int i = 0; i < Count; ++i)
396 | _AppendTable(i);
397 | }
398 |
399 | inline bool IsQual(ImPlotColormap cmap) const { return Quals[cmap]; }
400 | inline const char* GetName(ImPlotColormap cmap) const { return cmap < Count ? Text.Buf.Data + TextOffsets[cmap] : nullptr; }
401 | inline ImPlotColormap GetIndex(const char* name) const { ImGuiID key = ImHashStr(name); return Map.GetInt(key,-1); }
402 |
403 | inline const ImU32* GetKeys(ImPlotColormap cmap) const { return &Keys[KeyOffsets[cmap]]; }
404 | inline int GetKeyCount(ImPlotColormap cmap) const { return KeyCounts[cmap]; }
405 | inline ImU32 GetKeyColor(ImPlotColormap cmap, int idx) const { return Keys[KeyOffsets[cmap]+idx]; }
406 | inline void SetKeyColor(ImPlotColormap cmap, int idx, ImU32 value) { Keys[KeyOffsets[cmap]+idx] = value; RebuildTables(); }
407 |
408 | inline const ImU32* GetTable(ImPlotColormap cmap) const { return &Tables[TableOffsets[cmap]]; }
409 | inline int GetTableSize(ImPlotColormap cmap) const { return TableSizes[cmap]; }
410 | inline ImU32 GetTableColor(ImPlotColormap cmap, int idx) const { return Tables[TableOffsets[cmap]+idx]; }
411 |
412 | inline ImU32 LerpTable(ImPlotColormap cmap, float t) const {
413 | int off = TableOffsets[cmap];
414 | int siz = TableSizes[cmap];
415 | int idx = Quals[cmap] ? ImClamp((int)(siz*t),0,siz-1) : (int)((siz - 1) * t + 0.5f);
416 | return Tables[off + idx];
417 | }
418 | };
419 |
420 | // ImPlotPoint with positive/negative error values
421 | struct ImPlotPointError {
422 | double X, Y, Neg, Pos;
423 | ImPlotPointError(double x, double y, double neg, double pos) {
424 | X = x; Y = y; Neg = neg; Pos = pos;
425 | }
426 | };
427 |
428 | // Interior plot label/annotation
429 | struct ImPlotAnnotation {
430 | ImVec2 Pos;
431 | ImVec2 Offset;
432 | ImU32 ColorBg;
433 | ImU32 ColorFg;
434 | int TextOffset;
435 | bool Clamp;
436 | ImPlotAnnotation() {
437 | ColorBg = ColorFg = 0;
438 | TextOffset = 0;
439 | Clamp = false;
440 | }
441 | };
442 |
443 | // Collection of plot labels
444 | struct ImPlotAnnotationCollection {
445 |
446 | ImVector Annotations;
447 | ImGuiTextBuffer TextBuffer;
448 | int Size;
449 |
450 | ImPlotAnnotationCollection() { Reset(); }
451 |
452 | void AppendV(const ImVec2& pos, const ImVec2& off, ImU32 bg, ImU32 fg, bool clamp, const char* fmt, va_list args) IM_FMTLIST(7) {
453 | ImPlotAnnotation an;
454 | an.Pos = pos; an.Offset = off;
455 | an.ColorBg = bg; an.ColorFg = fg;
456 | an.TextOffset = TextBuffer.size();
457 | an.Clamp = clamp;
458 | Annotations.push_back(an);
459 | TextBuffer.appendfv(fmt, args);
460 | const char nul[] = "";
461 | TextBuffer.append(nul,nul+1);
462 | Size++;
463 | }
464 |
465 | void Append(const ImVec2& pos, const ImVec2& off, ImU32 bg, ImU32 fg, bool clamp, const char* fmt, ...) IM_FMTARGS(7) {
466 | va_list args;
467 | va_start(args, fmt);
468 | AppendV(pos, off, bg, fg, clamp, fmt, args);
469 | va_end(args);
470 | }
471 |
472 | const char* GetText(int idx) {
473 | return TextBuffer.Buf.Data + Annotations[idx].TextOffset;
474 | }
475 |
476 | void Reset() {
477 | Annotations.shrink(0);
478 | TextBuffer.Buf.shrink(0);
479 | Size = 0;
480 | }
481 | };
482 |
483 | struct ImPlotTag {
484 | ImAxis Axis;
485 | double Value;
486 | ImU32 ColorBg;
487 | ImU32 ColorFg;
488 | int TextOffset;
489 | };
490 |
491 | struct ImPlotTagCollection {
492 |
493 | ImVector Tags;
494 | ImGuiTextBuffer TextBuffer;
495 | int Size;
496 |
497 | ImPlotTagCollection() { Reset(); }
498 |
499 | void AppendV(ImAxis axis, double value, ImU32 bg, ImU32 fg, const char* fmt, va_list args) IM_FMTLIST(6) {
500 | ImPlotTag tag;
501 | tag.Axis = axis;
502 | tag.Value = value;
503 | tag.ColorBg = bg;
504 | tag.ColorFg = fg;
505 | tag.TextOffset = TextBuffer.size();
506 | Tags.push_back(tag);
507 | TextBuffer.appendfv(fmt, args);
508 | const char nul[] = "";
509 | TextBuffer.append(nul,nul+1);
510 | Size++;
511 | }
512 |
513 | void Append(ImAxis axis, double value, ImU32 bg, ImU32 fg, const char* fmt, ...) IM_FMTARGS(6) {
514 | va_list args;
515 | va_start(args, fmt);
516 | AppendV(axis, value, bg, fg, fmt, args);
517 | va_end(args);
518 | }
519 |
520 | const char* GetText(int idx) {
521 | return TextBuffer.Buf.Data + Tags[idx].TextOffset;
522 | }
523 |
524 | void Reset() {
525 | Tags.shrink(0);
526 | TextBuffer.Buf.shrink(0);
527 | Size = 0;
528 | }
529 | };
530 |
531 | // Tick mark info
532 | struct ImPlotTick
533 | {
534 | double PlotPos;
535 | float PixelPos;
536 | ImVec2 LabelSize;
537 | int TextOffset;
538 | bool Major;
539 | bool ShowLabel;
540 | int Level;
541 | int Idx;
542 |
543 | ImPlotTick(double value, bool major, int level, bool show_label) {
544 | PixelPos = 0;
545 | PlotPos = value;
546 | Major = major;
547 | ShowLabel = show_label;
548 | Level = level;
549 | TextOffset = -1;
550 | }
551 | };
552 |
553 | // Collection of ticks
554 | struct ImPlotTicker {
555 | ImVector Ticks;
556 | ImGuiTextBuffer TextBuffer;
557 | ImVec2 MaxSize;
558 | ImVec2 LateSize;
559 | int Levels;
560 |
561 | ImPlotTicker() {
562 | Reset();
563 | }
564 |
565 | ImPlotTick& AddTick(double value, bool major, int level, bool show_label, const char* label) {
566 | ImPlotTick tick(value, major, level, show_label);
567 | if (show_label && label != nullptr) {
568 | tick.TextOffset = TextBuffer.size();
569 | TextBuffer.append(label, label + strlen(label) + 1);
570 | tick.LabelSize = ImGui::CalcTextSize(TextBuffer.Buf.Data + tick.TextOffset);
571 | }
572 | return AddTick(tick);
573 | }
574 |
575 | ImPlotTick& AddTick(double value, bool major, int level, bool show_label, ImPlotFormatter formatter, void* data) {
576 | ImPlotTick tick(value, major, level, show_label);
577 | if (show_label && formatter != nullptr) {
578 | char buff[IMPLOT_LABEL_MAX_SIZE];
579 | tick.TextOffset = TextBuffer.size();
580 | formatter(tick.PlotPos, buff, sizeof(buff), data);
581 | TextBuffer.append(buff, buff + strlen(buff) + 1);
582 | tick.LabelSize = ImGui::CalcTextSize(TextBuffer.Buf.Data + tick.TextOffset);
583 | }
584 | return AddTick(tick);
585 | }
586 |
587 | inline ImPlotTick& AddTick(ImPlotTick tick) {
588 | if (tick.ShowLabel) {
589 | MaxSize.x = tick.LabelSize.x > MaxSize.x ? tick.LabelSize.x : MaxSize.x;
590 | MaxSize.y = tick.LabelSize.y > MaxSize.y ? tick.LabelSize.y : MaxSize.y;
591 | }
592 | tick.Idx = Ticks.size();
593 | Ticks.push_back(tick);
594 | return Ticks.back();
595 | }
596 |
597 | const char* GetText(int idx) const {
598 | return TextBuffer.Buf.Data + Ticks[idx].TextOffset;
599 | }
600 |
601 | const char* GetText(const ImPlotTick& tick) {
602 | return GetText(tick.Idx);
603 | }
604 |
605 | void OverrideSizeLate(const ImVec2& size) {
606 | LateSize.x = size.x > LateSize.x ? size.x : LateSize.x;
607 | LateSize.y = size.y > LateSize.y ? size.y : LateSize.y;
608 | }
609 |
610 | void Reset() {
611 | Ticks.shrink(0);
612 | TextBuffer.Buf.shrink(0);
613 | MaxSize = LateSize;
614 | LateSize = ImVec2(0,0);
615 | Levels = 1;
616 | }
617 |
618 | int TickCount() const {
619 | return Ticks.Size;
620 | }
621 | };
622 |
623 | // Axis state information that must persist after EndPlot
624 | struct ImPlotAxis
625 | {
626 | ImGuiID ID;
627 | ImPlotAxisFlags Flags;
628 | ImPlotAxisFlags PreviousFlags;
629 | ImPlotRange Range;
630 | ImPlotCond RangeCond;
631 | ImPlotScale Scale;
632 | ImPlotRange FitExtents;
633 | ImPlotAxis* OrthoAxis;
634 | ImPlotRange ConstraintRange;
635 | ImPlotRange ConstraintZoom;
636 |
637 | ImPlotTicker Ticker;
638 | ImPlotFormatter Formatter;
639 | void* FormatterData;
640 | char FormatSpec[16];
641 | ImPlotLocator Locator;
642 |
643 | double* LinkedMin;
644 | double* LinkedMax;
645 |
646 | int PickerLevel;
647 | ImPlotTime PickerTimeMin, PickerTimeMax;
648 |
649 | ImPlotTransform TransformForward;
650 | ImPlotTransform TransformInverse;
651 | void* TransformData;
652 | float PixelMin, PixelMax;
653 | double ScaleMin, ScaleMax;
654 | double ScaleToPixel;
655 | float Datum1, Datum2;
656 |
657 | ImRect HoverRect;
658 | int LabelOffset;
659 | ImU32 ColorMaj, ColorMin, ColorTick, ColorTxt, ColorBg, ColorHov, ColorAct, ColorHiLi;
660 |
661 | bool Enabled;
662 | bool Vertical;
663 | bool FitThisFrame;
664 | bool HasRange;
665 | bool HasFormatSpec;
666 | bool ShowDefaultTicks;
667 | bool Hovered;
668 | bool Held;
669 |
670 | ImPlotAxis() {
671 | ID = 0;
672 | Flags = PreviousFlags = ImPlotAxisFlags_None;
673 | Range.Min = 0;
674 | Range.Max = 1;
675 | Scale = ImPlotScale_Linear;
676 | TransformForward = TransformInverse = nullptr;
677 | TransformData = nullptr;
678 | FitExtents.Min = HUGE_VAL;
679 | FitExtents.Max = -HUGE_VAL;
680 | OrthoAxis = nullptr;
681 | ConstraintRange = ImPlotRange(-INFINITY,INFINITY);
682 | ConstraintZoom = ImPlotRange(DBL_MIN,INFINITY);
683 | LinkedMin = LinkedMax = nullptr;
684 | PickerLevel = 0;
685 | Datum1 = Datum2 = 0;
686 | PixelMin = PixelMax = 0;
687 | LabelOffset = -1;
688 | ColorMaj = ColorMin = ColorTick = ColorTxt = ColorBg = ColorHov = ColorAct = 0;
689 | ColorHiLi = IM_COL32_BLACK_TRANS;
690 | Formatter = nullptr;
691 | FormatterData = nullptr;
692 | Locator = nullptr;
693 | Enabled = Hovered = Held = FitThisFrame = HasRange = HasFormatSpec = false;
694 | ShowDefaultTicks = true;
695 | }
696 |
697 | inline void Reset() {
698 | Enabled = false;
699 | Scale = ImPlotScale_Linear;
700 | TransformForward = TransformInverse = nullptr;
701 | TransformData = nullptr;
702 | LabelOffset = -1;
703 | HasFormatSpec = false;
704 | Formatter = nullptr;
705 | FormatterData = nullptr;
706 | Locator = nullptr;
707 | ShowDefaultTicks = true;
708 | FitThisFrame = false;
709 | FitExtents.Min = HUGE_VAL;
710 | FitExtents.Max = -HUGE_VAL;
711 | OrthoAxis = nullptr;
712 | ConstraintRange = ImPlotRange(-INFINITY,INFINITY);
713 | ConstraintZoom = ImPlotRange(DBL_MIN,INFINITY);
714 | Ticker.Reset();
715 | }
716 |
717 | inline bool SetMin(double _min, bool force=false) {
718 | if (!force && IsLockedMin())
719 | return false;
720 | _min = ImConstrainNan(ImConstrainInf(_min));
721 | if (_min < ConstraintRange.Min)
722 | _min = ConstraintRange.Min;
723 | double z = Range.Max - _min;
724 | if (z < ConstraintZoom.Min)
725 | _min = Range.Max - ConstraintZoom.Min;
726 | if (z > ConstraintZoom.Max)
727 | _min = Range.Max - ConstraintZoom.Max;
728 | if (_min >= Range.Max)
729 | return false;
730 | Range.Min = _min;
731 | PickerTimeMin = ImPlotTime::FromDouble(Range.Min);
732 | UpdateTransformCache();
733 | return true;
734 | };
735 |
736 | inline bool SetMax(double _max, bool force=false) {
737 | if (!force && IsLockedMax())
738 | return false;
739 | _max = ImConstrainNan(ImConstrainInf(_max));
740 | if (_max > ConstraintRange.Max)
741 | _max = ConstraintRange.Max;
742 | double z = _max - Range.Min;
743 | if (z < ConstraintZoom.Min)
744 | _max = Range.Min + ConstraintZoom.Min;
745 | if (z > ConstraintZoom.Max)
746 | _max = Range.Min + ConstraintZoom.Max;
747 | if (_max <= Range.Min)
748 | return false;
749 | Range.Max = _max;
750 | PickerTimeMax = ImPlotTime::FromDouble(Range.Max);
751 | UpdateTransformCache();
752 | return true;
753 | };
754 |
755 | inline void SetRange(double v1, double v2) {
756 | Range.Min = ImMin(v1,v2);
757 | Range.Max = ImMax(v1,v2);
758 | Constrain();
759 | PickerTimeMin = ImPlotTime::FromDouble(Range.Min);
760 | PickerTimeMax = ImPlotTime::FromDouble(Range.Max);
761 | UpdateTransformCache();
762 | }
763 |
764 | inline void SetRange(const ImPlotRange& range) {
765 | SetRange(range.Min, range.Max);
766 | }
767 |
768 | inline void SetAspect(double unit_per_pix) {
769 | double new_size = unit_per_pix * PixelSize();
770 | double delta = (new_size - Range.Size()) * 0.5;
771 | if (IsLocked())
772 | return;
773 | else if (IsLockedMin() && !IsLockedMax())
774 | SetRange(Range.Min, Range.Max + 2*delta);
775 | else if (!IsLockedMin() && IsLockedMax())
776 | SetRange(Range.Min - 2*delta, Range.Max);
777 | else
778 | SetRange(Range.Min - delta, Range.Max + delta);
779 | }
780 |
781 | inline float PixelSize() const { return ImAbs(PixelMax - PixelMin); }
782 |
783 | inline double GetAspect() const { return Range.Size() / PixelSize(); }
784 |
785 | inline void Constrain() {
786 | Range.Min = ImConstrainNan(ImConstrainInf(Range.Min));
787 | Range.Max = ImConstrainNan(ImConstrainInf(Range.Max));
788 | if (Range.Min < ConstraintRange.Min)
789 | Range.Min = ConstraintRange.Min;
790 | if (Range.Max > ConstraintRange.Max)
791 | Range.Max = ConstraintRange.Max;
792 | double z = Range.Size();
793 | if (z < ConstraintZoom.Min) {
794 | double delta = (ConstraintZoom.Min - z) * 0.5;
795 | Range.Min -= delta;
796 | Range.Max += delta;
797 | }
798 | if (z > ConstraintZoom.Max) {
799 | double delta = (z - ConstraintZoom.Max) * 0.5;
800 | Range.Min += delta;
801 | Range.Max -= delta;
802 | }
803 | if (Range.Max <= Range.Min)
804 | Range.Max = Range.Min + DBL_EPSILON;
805 | }
806 |
807 | inline void UpdateTransformCache() {
808 | ScaleToPixel = (PixelMax - PixelMin) / Range.Size();
809 | if (TransformForward != nullptr) {
810 | ScaleMin = TransformForward(Range.Min, TransformData);
811 | ScaleMax = TransformForward(Range.Max, TransformData);
812 | }
813 | else {
814 | ScaleMin = Range.Min;
815 | ScaleMax = Range.Max;
816 | }
817 | }
818 |
819 | inline float PlotToPixels(double plt) const {
820 | if (TransformForward != nullptr) {
821 | double s = TransformForward(plt, TransformData);
822 | double t = (s - ScaleMin) / (ScaleMax - ScaleMin);
823 | plt = Range.Min + Range.Size() * t;
824 | }
825 | return (float)(PixelMin + ScaleToPixel * (plt - Range.Min));
826 | }
827 |
828 |
829 | inline double PixelsToPlot(float pix) const {
830 | double plt = (pix - PixelMin) / ScaleToPixel + Range.Min;
831 | if (TransformInverse != nullptr) {
832 | double t = (plt - Range.Min) / Range.Size();
833 | double s = t * (ScaleMax - ScaleMin) + ScaleMin;
834 | plt = TransformInverse(s, TransformData);
835 | }
836 | return plt;
837 | }
838 |
839 | inline void ExtendFit(double v) {
840 | if (!ImNanOrInf(v) && v >= ConstraintRange.Min && v <= ConstraintRange.Max) {
841 | FitExtents.Min = v < FitExtents.Min ? v : FitExtents.Min;
842 | FitExtents.Max = v > FitExtents.Max ? v : FitExtents.Max;
843 | }
844 | }
845 |
846 | inline void ExtendFitWith(ImPlotAxis& alt, double v, double v_alt) {
847 | if (ImHasFlag(Flags, ImPlotAxisFlags_RangeFit) && !alt.Range.Contains(v_alt))
848 | return;
849 | if (!ImNanOrInf(v) && v >= ConstraintRange.Min && v <= ConstraintRange.Max) {
850 | FitExtents.Min = v < FitExtents.Min ? v : FitExtents.Min;
851 | FitExtents.Max = v > FitExtents.Max ? v : FitExtents.Max;
852 | }
853 | }
854 |
855 | inline void ApplyFit(float padding) {
856 | const double ext_size = FitExtents.Size() * 0.5;
857 | FitExtents.Min -= ext_size * padding;
858 | FitExtents.Max += ext_size * padding;
859 | if (!IsLockedMin() && !ImNanOrInf(FitExtents.Min))
860 | Range.Min = FitExtents.Min;
861 | if (!IsLockedMax() && !ImNanOrInf(FitExtents.Max))
862 | Range.Max = FitExtents.Max;
863 | if (ImAlmostEqual(Range.Min, Range.Max)) {
864 | Range.Max += 0.5;
865 | Range.Min -= 0.5;
866 | }
867 | Constrain();
868 | UpdateTransformCache();
869 | }
870 |
871 | inline bool HasLabel() const { return LabelOffset != -1 && !ImHasFlag(Flags, ImPlotAxisFlags_NoLabel); }
872 | inline bool HasGridLines() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoGridLines); }
873 | inline bool HasTickLabels() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoTickLabels); }
874 | inline bool HasTickMarks() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoTickMarks); }
875 | inline bool WillRender() const { return Enabled && (HasGridLines() || HasTickLabels() || HasTickMarks()); }
876 | inline bool IsOpposite() const { return ImHasFlag(Flags, ImPlotAxisFlags_Opposite); }
877 | inline bool IsInverted() const { return ImHasFlag(Flags, ImPlotAxisFlags_Invert); }
878 | inline bool IsForeground() const { return ImHasFlag(Flags, ImPlotAxisFlags_Foreground); }
879 | inline bool IsAutoFitting() const { return ImHasFlag(Flags, ImPlotAxisFlags_AutoFit); }
880 | inline bool CanInitFit() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoInitialFit) && !HasRange && !LinkedMin && !LinkedMax; }
881 | inline bool IsRangeLocked() const { return HasRange && RangeCond == ImPlotCond_Always; }
882 | inline bool IsLockedMin() const { return !Enabled || IsRangeLocked() || ImHasFlag(Flags, ImPlotAxisFlags_LockMin); }
883 | inline bool IsLockedMax() const { return !Enabled || IsRangeLocked() || ImHasFlag(Flags, ImPlotAxisFlags_LockMax); }
884 | inline bool IsLocked() const { return IsLockedMin() && IsLockedMax(); }
885 | inline bool IsInputLockedMin() const { return IsLockedMin() || IsAutoFitting(); }
886 | inline bool IsInputLockedMax() const { return IsLockedMax() || IsAutoFitting(); }
887 | inline bool IsInputLocked() const { return IsLocked() || IsAutoFitting(); }
888 | inline bool HasMenus() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoMenus); }
889 |
890 | inline bool IsPanLocked(bool increasing) {
891 | if (ImHasFlag(Flags, ImPlotAxisFlags_PanStretch)) {
892 | return IsInputLocked();
893 | }
894 | else {
895 | if (IsLockedMin() || IsLockedMax() || IsAutoFitting())
896 | return false;
897 | if (increasing)
898 | return Range.Max == ConstraintRange.Max;
899 | else
900 | return Range.Min == ConstraintRange.Min;
901 | }
902 | }
903 |
904 | void PushLinks() {
905 | if (LinkedMin) { *LinkedMin = Range.Min; }
906 | if (LinkedMax) { *LinkedMax = Range.Max; }
907 | }
908 |
909 | void PullLinks() {
910 | if (LinkedMin && LinkedMax) { SetRange(*LinkedMin, *LinkedMax); }
911 | else if (LinkedMin) { SetMin(*LinkedMin,true); }
912 | else if (LinkedMax) { SetMax(*LinkedMax,true); }
913 | }
914 | };
915 |
916 | // Align plots group data
917 | struct ImPlotAlignmentData {
918 | bool Vertical;
919 | float PadA;
920 | float PadB;
921 | float PadAMax;
922 | float PadBMax;
923 | ImPlotAlignmentData() {
924 | Vertical = true;
925 | PadA = PadB = PadAMax = PadBMax = 0;
926 | }
927 | void Begin() { PadAMax = PadBMax = 0; }
928 | void Update(float& pad_a, float& pad_b, float& delta_a, float& delta_b) {
929 | float bak_a = pad_a; float bak_b = pad_b;
930 | if (PadAMax < pad_a) { PadAMax = pad_a; }
931 | if (PadBMax < pad_b) { PadBMax = pad_b; }
932 | if (pad_a < PadA) { pad_a = PadA; delta_a = pad_a - bak_a; } else { delta_a = 0; }
933 | if (pad_b < PadB) { pad_b = PadB; delta_b = pad_b - bak_b; } else { delta_b = 0; }
934 | }
935 | void End() { PadA = PadAMax; PadB = PadBMax; }
936 | void Reset() { PadA = PadB = PadAMax = PadBMax = 0; }
937 | };
938 |
939 | // State information for Plot items
940 | struct ImPlotItem
941 | {
942 | ImGuiID ID;
943 | ImU32 Color;
944 | ImRect LegendHoverRect;
945 | int NameOffset;
946 | bool Show;
947 | bool LegendHovered;
948 | bool SeenThisFrame;
949 |
950 | ImPlotItem() {
951 | ID = 0;
952 | Color = IM_COL32_WHITE;
953 | NameOffset = -1;
954 | Show = true;
955 | SeenThisFrame = false;
956 | LegendHovered = false;
957 | }
958 |
959 | ~ImPlotItem() { ID = 0; }
960 | };
961 |
962 | // Holds Legend state
963 | struct ImPlotLegend
964 | {
965 | ImPlotLegendFlags Flags;
966 | ImPlotLegendFlags PreviousFlags;
967 | ImPlotLocation Location;
968 | ImPlotLocation PreviousLocation;
969 | ImVec2 Scroll;
970 | ImVector Indices;
971 | ImGuiTextBuffer Labels;
972 | ImRect Rect;
973 | ImRect RectClamped;
974 | bool Hovered;
975 | bool Held;
976 | bool CanGoInside;
977 |
978 | ImPlotLegend() {
979 | Flags = PreviousFlags = ImPlotLegendFlags_None;
980 | CanGoInside = true;
981 | Hovered = Held = false;
982 | Location = PreviousLocation = ImPlotLocation_NorthWest;
983 | Scroll = ImVec2(0,0);
984 | }
985 |
986 | void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); }
987 | };
988 |
989 | // Holds Items and Legend data
990 | struct ImPlotItemGroup
991 | {
992 | ImGuiID ID;
993 | ImPlotLegend Legend;
994 | ImPool ItemPool;
995 | int ColormapIdx;
996 |
997 | ImPlotItemGroup() { ID = 0; ColormapIdx = 0; }
998 |
999 | int GetItemCount() const { return ItemPool.GetBufSize(); }
1000 | ImGuiID GetItemID(const char* label_id) { return ImGui::GetID(label_id); /* GetIDWithSeed */ }
1001 | ImPlotItem* GetItem(ImGuiID id) { return ItemPool.GetByKey(id); }
1002 | ImPlotItem* GetItem(const char* label_id) { return GetItem(GetItemID(label_id)); }
1003 | ImPlotItem* GetOrAddItem(ImGuiID id) { return ItemPool.GetOrAddByKey(id); }
1004 | ImPlotItem* GetItemByIndex(int i) { return ItemPool.GetByIndex(i); }
1005 | int GetItemIndex(ImPlotItem* item) { return ItemPool.GetIndex(item); }
1006 | int GetLegendCount() const { return Legend.Indices.size(); }
1007 | ImPlotItem* GetLegendItem(int i) { return ItemPool.GetByIndex(Legend.Indices[i]); }
1008 | const char* GetLegendLabel(int i) { return Legend.Labels.Buf.Data + GetLegendItem(i)->NameOffset; }
1009 | void Reset() { ItemPool.Clear(); Legend.Reset(); ColormapIdx = 0; }
1010 | };
1011 |
1012 | // Holds Plot state information that must persist after EndPlot
1013 | struct ImPlotPlot
1014 | {
1015 | ImGuiID ID;
1016 | ImPlotFlags Flags;
1017 | ImPlotFlags PreviousFlags;
1018 | ImPlotLocation MouseTextLocation;
1019 | ImPlotMouseTextFlags MouseTextFlags;
1020 | ImPlotAxis Axes[ImAxis_COUNT];
1021 | ImGuiTextBuffer TextBuffer;
1022 | ImPlotItemGroup Items;
1023 | ImAxis CurrentX;
1024 | ImAxis CurrentY;
1025 | ImRect FrameRect;
1026 | ImRect CanvasRect;
1027 | ImRect PlotRect;
1028 | ImRect AxesRect;
1029 | ImRect SelectRect;
1030 | ImVec2 SelectStart;
1031 | int TitleOffset;
1032 | bool JustCreated;
1033 | bool Initialized;
1034 | bool SetupLocked;
1035 | bool FitThisFrame;
1036 | bool Hovered;
1037 | bool Held;
1038 | bool Selecting;
1039 | bool Selected;
1040 | bool ContextLocked;
1041 |
1042 | ImPlotPlot() {
1043 | Flags = PreviousFlags = ImPlotFlags_None;
1044 | for (int i = 0; i < IMPLOT_NUM_X_AXES; ++i)
1045 | XAxis(i).Vertical = false;
1046 | for (int i = 0; i < IMPLOT_NUM_Y_AXES; ++i)
1047 | YAxis(i).Vertical = true;
1048 | SelectStart = ImVec2(0,0);
1049 | CurrentX = ImAxis_X1;
1050 | CurrentY = ImAxis_Y1;
1051 | MouseTextLocation = ImPlotLocation_South | ImPlotLocation_East;
1052 | MouseTextFlags = ImPlotMouseTextFlags_None;
1053 | TitleOffset = -1;
1054 | JustCreated = true;
1055 | Initialized = SetupLocked = FitThisFrame = false;
1056 | Hovered = Held = Selected = Selecting = ContextLocked = false;
1057 | }
1058 |
1059 | inline bool IsInputLocked() const {
1060 | for (int i = 0; i < IMPLOT_NUM_X_AXES; ++i) {
1061 | if (!XAxis(i).IsInputLocked())
1062 | return false;
1063 | }
1064 | for (int i = 0; i < IMPLOT_NUM_Y_AXES; ++i) {
1065 | if (!YAxis(i).IsInputLocked())
1066 | return false;
1067 | }
1068 | return true;
1069 | }
1070 |
1071 | inline void ClearTextBuffer() { TextBuffer.Buf.shrink(0); }
1072 |
1073 | inline void SetTitle(const char* title) {
1074 | if (title && ImGui::FindRenderedTextEnd(title, nullptr) != title) {
1075 | TitleOffset = TextBuffer.size();
1076 | TextBuffer.append(title, title + strlen(title) + 1);
1077 | }
1078 | else {
1079 | TitleOffset = -1;
1080 | }
1081 | }
1082 | inline bool HasTitle() const { return TitleOffset != -1 && !ImHasFlag(Flags, ImPlotFlags_NoTitle); }
1083 | inline const char* GetTitle() const { return TextBuffer.Buf.Data + TitleOffset; }
1084 |
1085 | inline ImPlotAxis& XAxis(int i) { return Axes[ImAxis_X1 + i]; }
1086 | inline const ImPlotAxis& XAxis(int i) const { return Axes[ImAxis_X1 + i]; }
1087 | inline ImPlotAxis& YAxis(int i) { return Axes[ImAxis_Y1 + i]; }
1088 | inline const ImPlotAxis& YAxis(int i) const { return Axes[ImAxis_Y1 + i]; }
1089 |
1090 | inline int EnabledAxesX() {
1091 | int cnt = 0;
1092 | for (int i = 0; i < IMPLOT_NUM_X_AXES; ++i)
1093 | cnt += XAxis(i).Enabled;
1094 | return cnt;
1095 | }
1096 |
1097 | inline int EnabledAxesY() {
1098 | int cnt = 0;
1099 | for (int i = 0; i < IMPLOT_NUM_Y_AXES; ++i)
1100 | cnt += YAxis(i).Enabled;
1101 | return cnt;
1102 | }
1103 |
1104 | inline void SetAxisLabel(ImPlotAxis& axis, const char* label) {
1105 | if (label && ImGui::FindRenderedTextEnd(label, nullptr) != label) {
1106 | axis.LabelOffset = TextBuffer.size();
1107 | TextBuffer.append(label, label + strlen(label) + 1);
1108 | }
1109 | else {
1110 | axis.LabelOffset = -1;
1111 | }
1112 | }
1113 |
1114 | inline const char* GetAxisLabel(const ImPlotAxis& axis) const { return TextBuffer.Buf.Data + axis.LabelOffset; }
1115 | };
1116 |
1117 | // Holds subplot data that must persist after EndSubplot
1118 | struct ImPlotSubplot {
1119 | ImGuiID ID;
1120 | ImPlotSubplotFlags Flags;
1121 | ImPlotSubplotFlags PreviousFlags;
1122 | ImPlotItemGroup Items;
1123 | int Rows;
1124 | int Cols;
1125 | int CurrentIdx;
1126 | ImRect FrameRect;
1127 | ImRect GridRect;
1128 | ImVec2 CellSize;
1129 | ImVector RowAlignmentData;
1130 | ImVector ColAlignmentData;
1131 | ImVector RowRatios;
1132 | ImVector ColRatios;
1133 | ImVector RowLinkData;
1134 | ImVector ColLinkData;
1135 | float TempSizes[2];
1136 | bool FrameHovered;
1137 | bool HasTitle;
1138 |
1139 | ImPlotSubplot() {
1140 | ID = 0;
1141 | Flags = PreviousFlags = ImPlotSubplotFlags_None;
1142 | Rows = Cols = CurrentIdx = 0;
1143 | Items.Legend.Location = ImPlotLocation_North;
1144 | Items.Legend.Flags = ImPlotLegendFlags_Horizontal|ImPlotLegendFlags_Outside;
1145 | Items.Legend.CanGoInside = false;
1146 | TempSizes[0] = TempSizes[1] = 0;
1147 | FrameHovered = false;
1148 | HasTitle = false;
1149 | }
1150 | };
1151 |
1152 | // Temporary data storage for upcoming plot
1153 | struct ImPlotNextPlotData
1154 | {
1155 | ImPlotCond RangeCond[ImAxis_COUNT];
1156 | ImPlotRange Range[ImAxis_COUNT];
1157 | bool HasRange[ImAxis_COUNT];
1158 | bool Fit[ImAxis_COUNT];
1159 | double* LinkedMin[ImAxis_COUNT];
1160 | double* LinkedMax[ImAxis_COUNT];
1161 |
1162 | ImPlotNextPlotData() { Reset(); }
1163 |
1164 | void Reset() {
1165 | for (int i = 0; i < ImAxis_COUNT; ++i) {
1166 | HasRange[i] = false;
1167 | Fit[i] = false;
1168 | LinkedMin[i] = LinkedMax[i] = nullptr;
1169 | }
1170 | }
1171 |
1172 | };
1173 |
1174 | // Temporary data storage for upcoming item
1175 | struct ImPlotNextItemData {
1176 | ImVec4 Colors[5]; // ImPlotCol_Line, ImPlotCol_Fill, ImPlotCol_MarkerOutline, ImPlotCol_MarkerFill, ImPlotCol_ErrorBar
1177 | float LineWeight;
1178 | ImPlotMarker Marker;
1179 | float MarkerSize;
1180 | float MarkerWeight;
1181 | float FillAlpha;
1182 | float ErrorBarSize;
1183 | float ErrorBarWeight;
1184 | float DigitalBitHeight;
1185 | float DigitalBitGap;
1186 | bool RenderLine;
1187 | bool RenderFill;
1188 | bool RenderMarkerLine;
1189 | bool RenderMarkerFill;
1190 | bool HasHidden;
1191 | bool Hidden;
1192 | ImPlotCond HiddenCond;
1193 | ImPlotNextItemData() { Reset(); }
1194 | void Reset() {
1195 | for (int i = 0; i < 5; ++i)
1196 | Colors[i] = IMPLOT_AUTO_COL;
1197 | LineWeight = MarkerSize = MarkerWeight = FillAlpha = ErrorBarSize = ErrorBarWeight = DigitalBitHeight = DigitalBitGap = IMPLOT_AUTO;
1198 | Marker = IMPLOT_AUTO;
1199 | HasHidden = Hidden = false;
1200 | }
1201 | };
1202 |
1203 | // Holds state information that must persist between calls to BeginPlot()/EndPlot()
1204 | struct ImPlotContext {
1205 | // Plot States
1206 | ImPool Plots;
1207 | ImPool Subplots;
1208 | ImPlotPlot* CurrentPlot;
1209 | ImPlotSubplot* CurrentSubplot;
1210 | ImPlotItemGroup* CurrentItems;
1211 | ImPlotItem* CurrentItem;
1212 | ImPlotItem* PreviousItem;
1213 |
1214 | // Tick Marks and Labels
1215 | ImPlotTicker CTicker;
1216 |
1217 | // Annotation and Tabs
1218 | ImPlotAnnotationCollection Annotations;
1219 | ImPlotTagCollection Tags;
1220 |
1221 | // Style and Colormaps
1222 | ImPlotStyle Style;
1223 | ImVector ColorModifiers;
1224 | ImVector StyleModifiers;
1225 | ImPlotColormapData ColormapData;
1226 | ImVector ColormapModifiers;
1227 |
1228 | // Time
1229 | tm Tm;
1230 |
1231 | // Temp data for general use
1232 | ImVector TempDouble1, TempDouble2;
1233 | ImVector TempInt1;
1234 |
1235 | // Misc
1236 | int DigitalPlotItemCnt;
1237 | int DigitalPlotOffset;
1238 | ImPlotNextPlotData NextPlotData;
1239 | ImPlotNextItemData NextItemData;
1240 | ImPlotInputMap InputMap;
1241 | bool OpenContextThisFrame;
1242 | ImGuiTextBuffer MousePosStringBuilder;
1243 | ImPlotItemGroup* SortItems;
1244 |
1245 | // Align plots
1246 | ImPool AlignmentData;
1247 | ImPlotAlignmentData* CurrentAlignmentH;
1248 | ImPlotAlignmentData* CurrentAlignmentV;
1249 | };
1250 |
1251 | //-----------------------------------------------------------------------------
1252 | // [SECTION] Internal API
1253 | // No guarantee of forward compatibility here!
1254 | //-----------------------------------------------------------------------------
1255 |
1256 | namespace ImPlot {
1257 |
1258 | //-----------------------------------------------------------------------------
1259 | // [SECTION] Context Utils
1260 | //-----------------------------------------------------------------------------
1261 |
1262 | // Initializes an ImPlotContext
1263 | IMPLOT_API void Initialize(ImPlotContext* ctx);
1264 | // Resets an ImPlot context for the next call to BeginPlot
1265 | IMPLOT_API void ResetCtxForNextPlot(ImPlotContext* ctx);
1266 | // Resets an ImPlot context for the next call to BeginAlignedPlots
1267 | IMPLOT_API void ResetCtxForNextAlignedPlots(ImPlotContext* ctx);
1268 | // Resets an ImPlot context for the next call to BeginSubplot
1269 | IMPLOT_API void ResetCtxForNextSubplot(ImPlotContext* ctx);
1270 |
1271 | //-----------------------------------------------------------------------------
1272 | // [SECTION] Plot Utils
1273 | //-----------------------------------------------------------------------------
1274 |
1275 | // Gets a plot from the current ImPlotContext
1276 | IMPLOT_API ImPlotPlot* GetPlot(const char* title);
1277 | // Gets the current plot from the current ImPlotContext
1278 | IMPLOT_API ImPlotPlot* GetCurrentPlot();
1279 | // Busts the cache for every plot in the current context
1280 | IMPLOT_API void BustPlotCache();
1281 |
1282 | // Shows a plot's context menu.
1283 | IMPLOT_API void ShowPlotContextMenu(ImPlotPlot& plot);
1284 |
1285 | //-----------------------------------------------------------------------------
1286 | // [SECTION] Setup Utils
1287 | //-----------------------------------------------------------------------------
1288 |
1289 | // Lock Setup and call SetupFinish if necessary.
1290 | static inline void SetupLock() {
1291 | ImPlotContext& gp = *GImPlot;
1292 | if (!gp.CurrentPlot->SetupLocked)
1293 | SetupFinish();
1294 | gp.CurrentPlot->SetupLocked = true;
1295 | }
1296 |
1297 | //-----------------------------------------------------------------------------
1298 | // [SECTION] Subplot Utils
1299 | //-----------------------------------------------------------------------------
1300 |
1301 | // Advances to next subplot
1302 | IMPLOT_API void SubplotNextCell();
1303 |
1304 | // Shows a subplot's context menu.
1305 | IMPLOT_API void ShowSubplotsContextMenu(ImPlotSubplot& subplot);
1306 |
1307 | //-----------------------------------------------------------------------------
1308 | // [SECTION] Item Utils
1309 | //-----------------------------------------------------------------------------
1310 |
1311 | // Begins a new item. Returns false if the item should not be plotted. Pushes PlotClipRect.
1312 | IMPLOT_API bool BeginItem(const char* label_id, ImPlotItemFlags flags=0, ImPlotCol recolor_from=IMPLOT_AUTO);
1313 |
1314 | // Same as above but with fitting functionality.
1315 | template
1316 | bool BeginItemEx(const char* label_id, const _Fitter& fitter, ImPlotItemFlags flags=0, ImPlotCol recolor_from=IMPLOT_AUTO) {
1317 | if (BeginItem(label_id, flags, recolor_from)) {
1318 | ImPlotPlot& plot = *GetCurrentPlot();
1319 | if (plot.FitThisFrame && !ImHasFlag(flags, ImPlotItemFlags_NoFit))
1320 | fitter.Fit(plot.Axes[plot.CurrentX], plot.Axes[plot.CurrentY]);
1321 | return true;
1322 | }
1323 | return false;
1324 | }
1325 |
1326 | // Ends an item (call only if BeginItem returns true). Pops PlotClipRect.
1327 | IMPLOT_API void EndItem();
1328 |
1329 | // Register or get an existing item from the current plot.
1330 | IMPLOT_API ImPlotItem* RegisterOrGetItem(const char* label_id, ImPlotItemFlags flags, bool* just_created = nullptr);
1331 | // Get a plot item from the current plot.
1332 | IMPLOT_API ImPlotItem* GetItem(const char* label_id);
1333 | // Gets the current item.
1334 | IMPLOT_API ImPlotItem* GetCurrentItem();
1335 | // Busts the cache for every item for every plot in the current context.
1336 | IMPLOT_API void BustItemCache();
1337 |
1338 | //-----------------------------------------------------------------------------
1339 | // [SECTION] Axis Utils
1340 | //-----------------------------------------------------------------------------
1341 |
1342 | // Returns true if any enabled axis is locked from user input.
1343 | static inline bool AnyAxesInputLocked(ImPlotAxis* axes, int count) {
1344 | for (int i = 0; i < count; ++i) {
1345 | if (axes[i].Enabled && axes[i].IsInputLocked())
1346 | return true;
1347 | }
1348 | return false;
1349 | }
1350 |
1351 | // Returns true if all enabled axes are locked from user input.
1352 | static inline bool AllAxesInputLocked(ImPlotAxis* axes, int count) {
1353 | for (int i = 0; i < count; ++i) {
1354 | if (axes[i].Enabled && !axes[i].IsInputLocked())
1355 | return false;
1356 | }
1357 | return true;
1358 | }
1359 |
1360 | static inline bool AnyAxesHeld(ImPlotAxis* axes, int count) {
1361 | for (int i = 0; i < count; ++i) {
1362 | if (axes[i].Enabled && axes[i].Held)
1363 | return true;
1364 | }
1365 | return false;
1366 | }
1367 |
1368 | static inline bool AnyAxesHovered(ImPlotAxis* axes, int count) {
1369 | for (int i = 0; i < count; ++i) {
1370 | if (axes[i].Enabled && axes[i].Hovered)
1371 | return true;
1372 | }
1373 | return false;
1374 | }
1375 |
1376 | // Returns true if the user has requested data to be fit.
1377 | static inline bool FitThisFrame() {
1378 | return GImPlot->CurrentPlot->FitThisFrame;
1379 | }
1380 |
1381 | // Extends the current plot's axes so that it encompasses a vertical line at x
1382 | static inline void FitPointX(double x) {
1383 | ImPlotPlot& plot = *GetCurrentPlot();
1384 | ImPlotAxis& x_axis = plot.Axes[plot.CurrentX];
1385 | x_axis.ExtendFit(x);
1386 | }
1387 |
1388 | // Extends the current plot's axes so that it encompasses a horizontal line at y
1389 | static inline void FitPointY(double y) {
1390 | ImPlotPlot& plot = *GetCurrentPlot();
1391 | ImPlotAxis& y_axis = plot.Axes[plot.CurrentY];
1392 | y_axis.ExtendFit(y);
1393 | }
1394 |
1395 | // Extends the current plot's axes so that it encompasses point p
1396 | static inline void FitPoint(const ImPlotPoint& p) {
1397 | ImPlotPlot& plot = *GetCurrentPlot();
1398 | ImPlotAxis& x_axis = plot.Axes[plot.CurrentX];
1399 | ImPlotAxis& y_axis = plot.Axes[plot.CurrentY];
1400 | x_axis.ExtendFitWith(y_axis, p.x, p.y);
1401 | y_axis.ExtendFitWith(x_axis, p.y, p.x);
1402 | }
1403 |
1404 | // Returns true if two ranges overlap
1405 | static inline bool RangesOverlap(const ImPlotRange& r1, const ImPlotRange& r2)
1406 | { return r1.Min <= r2.Max && r2.Min <= r1.Max; }
1407 |
1408 | // Shows an axis's context menu.
1409 | IMPLOT_API void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bool time_allowed = false);
1410 |
1411 | //-----------------------------------------------------------------------------
1412 | // [SECTION] Legend Utils
1413 | //-----------------------------------------------------------------------------
1414 |
1415 | // Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
1416 | IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0));
1417 | // Calculates the bounding box size of a legend _before_ clipping.
1418 | IMPLOT_API ImVec2 CalcLegendSize(ImPlotItemGroup& items, const ImVec2& pad, const ImVec2& spacing, bool vertical);
1419 | // Clips calculated legend size
1420 | IMPLOT_API bool ClampLegendRect(ImRect& legend_rect, const ImRect& outer_rect, const ImVec2& pad);
1421 | // Renders legend entries into a bounding box
1422 | IMPLOT_API bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, bool vertical, ImDrawList& DrawList);
1423 | // Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window! This is not thoroughly tested nor scrollable!).
1424 | IMPLOT_API void ShowAltLegend(const char* title_id, bool vertical = true, const ImVec2 size = ImVec2(0,0), bool interactable = true);
1425 | // Shows a legend's context menu.
1426 | IMPLOT_API bool ShowLegendContextMenu(ImPlotLegend& legend, bool visible);
1427 |
1428 | //-----------------------------------------------------------------------------
1429 | // [SECTION] Label Utils
1430 | //-----------------------------------------------------------------------------
1431 |
1432 | // Create a a string label for a an axis value
1433 | IMPLOT_API void LabelAxisValue(const ImPlotAxis& axis, double value, char* buff, int size, bool round = false);
1434 |
1435 | //-----------------------------------------------------------------------------
1436 | // [SECTION] Styling Utils
1437 | //-----------------------------------------------------------------------------
1438 |
1439 | // Get styling data for next item (call between Begin/EndItem)
1440 | static inline const ImPlotNextItemData& GetItemData() { return GImPlot->NextItemData; }
1441 |
1442 | // Returns true if a color is set to be automatically determined
1443 | static inline bool IsColorAuto(const ImVec4& col) { return col.w == -1; }
1444 | // Returns true if a style color is set to be automatically determined
1445 | static inline bool IsColorAuto(ImPlotCol idx) { return IsColorAuto(GImPlot->Style.Colors[idx]); }
1446 | // Returns the automatically deduced style color
1447 | IMPLOT_API ImVec4 GetAutoColor(ImPlotCol idx);
1448 |
1449 | // Returns the style color whether it is automatic or custom set
1450 | static inline ImVec4 GetStyleColorVec4(ImPlotCol idx) { return IsColorAuto(idx) ? GetAutoColor(idx) : GImPlot->Style.Colors[idx]; }
1451 | static inline ImU32 GetStyleColorU32(ImPlotCol idx) { return ImGui::ColorConvertFloat4ToU32(GetStyleColorVec4(idx)); }
1452 |
1453 | // Draws vertical text. The position is the bottom left of the text rect.
1454 | IMPLOT_API void AddTextVertical(ImDrawList *DrawList, ImVec2 pos, ImU32 col, const char* text_begin, const char* text_end = nullptr);
1455 | // Draws multiline horizontal text centered.
1456 | IMPLOT_API void AddTextCentered(ImDrawList* DrawList, ImVec2 top_center, ImU32 col, const char* text_begin, const char* text_end = nullptr);
1457 | // Calculates the size of vertical text
1458 | static inline ImVec2 CalcTextSizeVertical(const char *text) {
1459 | ImVec2 sz = ImGui::CalcTextSize(text);
1460 | return ImVec2(sz.y, sz.x);
1461 | }
1462 | // Returns white or black text given background color
1463 | static inline ImU32 CalcTextColor(const ImVec4& bg) { return (bg.x * 0.299f + bg.y * 0.587f + bg.z * 0.114f) > 0.5f ? IM_COL32_BLACK : IM_COL32_WHITE; }
1464 | static inline ImU32 CalcTextColor(ImU32 bg) { return CalcTextColor(ImGui::ColorConvertU32ToFloat4(bg)); }
1465 | // Lightens or darkens a color for hover
1466 | static inline ImU32 CalcHoverColor(ImU32 col) { return ImMixU32(col, CalcTextColor(col), 32); }
1467 |
1468 | // Clamps a label position so that it fits a rect defined by Min/Max
1469 | static inline ImVec2 ClampLabelPos(ImVec2 pos, const ImVec2& size, const ImVec2& Min, const ImVec2& Max) {
1470 | if (pos.x < Min.x) pos.x = Min.x;
1471 | if (pos.y < Min.y) pos.y = Min.y;
1472 | if ((pos.x + size.x) > Max.x) pos.x = Max.x - size.x;
1473 | if ((pos.y + size.y) > Max.y) pos.y = Max.y - size.y;
1474 | return pos;
1475 | }
1476 |
1477 | // Returns a color from the Color map given an index >= 0 (modulo will be performed).
1478 | IMPLOT_API ImU32 GetColormapColorU32(int idx, ImPlotColormap cmap);
1479 | // Returns the next unused colormap color and advances the colormap. Can be used to skip colors if desired.
1480 | IMPLOT_API ImU32 NextColormapColorU32();
1481 | // Linearly interpolates a color from the current colormap given t between 0 and 1.
1482 | IMPLOT_API ImU32 SampleColormapU32(float t, ImPlotColormap cmap);
1483 |
1484 | // Render a colormap bar
1485 | IMPLOT_API void RenderColorBar(const ImU32* colors, int size, ImDrawList& DrawList, const ImRect& bounds, bool vert, bool reversed, bool continuous);
1486 |
1487 | //-----------------------------------------------------------------------------
1488 | // [SECTION] Math and Misc Utils
1489 | //-----------------------------------------------------------------------------
1490 |
1491 | // Rounds x to powers of 2,5 and 10 for generating axis labels (from Graphics Gems 1 Chapter 11.2)
1492 | IMPLOT_API double NiceNum(double x, bool round);
1493 | // Computes order of magnitude of double.
1494 | static inline int OrderOfMagnitude(double val) { return val == 0 ? 0 : (int)(floor(log10(fabs(val)))); }
1495 | // Returns the precision required for a order of magnitude.
1496 | static inline int OrderToPrecision(int order) { return order > 0 ? 0 : 1 - order; }
1497 | // Returns a floating point precision to use given a value
1498 | static inline int Precision(double val) { return OrderToPrecision(OrderOfMagnitude(val)); }
1499 | // Round a value to a given precision
1500 | static inline double RoundTo(double val, int prec) { double p = pow(10,(double)prec); return floor(val*p+0.5)/p; }
1501 |
1502 | // Returns the intersection point of two lines A and B (assumes they are not parallel!)
1503 | static inline ImVec2 Intersection(const ImVec2& a1, const ImVec2& a2, const ImVec2& b1, const ImVec2& b2) {
1504 | float v1 = (a1.x * a2.y - a1.y * a2.x); float v2 = (b1.x * b2.y - b1.y * b2.x);
1505 | float v3 = ((a1.x - a2.x) * (b1.y - b2.y) - (a1.y - a2.y) * (b1.x - b2.x));
1506 | return ImVec2((v1 * (b1.x - b2.x) - v2 * (a1.x - a2.x)) / v3, (v1 * (b1.y - b2.y) - v2 * (a1.y - a2.y)) / v3);
1507 | }
1508 |
1509 | // Fills a buffer with n samples linear interpolated from vmin to vmax
1510 | template
1511 | void FillRange(ImVector& buffer, int n, T vmin, T vmax) {
1512 | buffer.resize(n);
1513 | T step = (vmax - vmin) / (n - 1);
1514 | for (int i = 0; i < n; ++i) {
1515 | buffer[i] = vmin + i * step;
1516 | }
1517 | }
1518 |
1519 | // Calculate histogram bin counts and widths
1520 | template
1521 | static inline void CalculateBins(const T* values, int count, ImPlotBin meth, const ImPlotRange& range, int& bins_out, double& width_out) {
1522 | switch (meth) {
1523 | case ImPlotBin_Sqrt:
1524 | bins_out = (int)ceil(sqrt(count));
1525 | break;
1526 | case ImPlotBin_Sturges:
1527 | bins_out = (int)ceil(1.0 + log2(count));
1528 | break;
1529 | case ImPlotBin_Rice:
1530 | bins_out = (int)ceil(2 * cbrt(count));
1531 | break;
1532 | case ImPlotBin_Scott:
1533 | width_out = 3.49 * ImStdDev(values, count) / cbrt(count);
1534 | bins_out = (int)round(range.Size() / width_out);
1535 | break;
1536 | }
1537 | width_out = range.Size() / bins_out;
1538 | }
1539 |
1540 | //-----------------------------------------------------------------------------
1541 | // Time Utils
1542 | //-----------------------------------------------------------------------------
1543 |
1544 | // Returns true if year is leap year (366 days long)
1545 | static inline bool IsLeapYear(int year) {
1546 | return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
1547 | }
1548 | // Returns the number of days in a month, accounting for Feb. leap years. #month is zero indexed.
1549 | static inline int GetDaysInMonth(int year, int month) {
1550 | static const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
1551 | return days[month] + (int)(month == 1 && IsLeapYear(year));
1552 | }
1553 |
1554 | // Make a UNIX timestamp from a tm struct expressed in UTC time (i.e. GMT timezone).
1555 | IMPLOT_API ImPlotTime MkGmtTime(struct tm *ptm);
1556 | // Make a tm struct expressed in UTC time (i.e. GMT timezone) from a UNIX timestamp.
1557 | IMPLOT_API tm* GetGmtTime(const ImPlotTime& t, tm* ptm);
1558 |
1559 | // Make a UNIX timestamp from a tm struct expressed in local time.
1560 | IMPLOT_API ImPlotTime MkLocTime(struct tm *ptm);
1561 | // Make a tm struct expressed in local time from a UNIX timestamp.
1562 | IMPLOT_API tm* GetLocTime(const ImPlotTime& t, tm* ptm);
1563 |
1564 | // NB: The following functions only work if there is a current ImPlotContext because the
1565 | // internal tm struct is owned by the context! They are aware of ImPlotStyle.UseLocalTime.
1566 |
1567 | // Make a timestamp from time components.
1568 | // year[1970-3000], month[0-11], day[1-31], hour[0-23], min[0-59], sec[0-59], us[0,999999]
1569 | IMPLOT_API ImPlotTime MakeTime(int year, int month = 0, int day = 1, int hour = 0, int min = 0, int sec = 0, int us = 0);
1570 | // Get year component from timestamp [1970-3000]
1571 | IMPLOT_API int GetYear(const ImPlotTime& t);
1572 |
1573 | // Adds or subtracts time from a timestamp. #count > 0 to add, < 0 to subtract.
1574 | IMPLOT_API ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count);
1575 | // Rounds a timestamp down to nearest unit.
1576 | IMPLOT_API ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit);
1577 | // Rounds a timestamp up to the nearest unit.
1578 | IMPLOT_API ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit);
1579 | // Rounds a timestamp up or down to the nearest unit.
1580 | IMPLOT_API ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit);
1581 | // Combines the date of one timestamp with the time-of-day of another timestamp.
1582 | IMPLOT_API ImPlotTime CombineDateTime(const ImPlotTime& date_part, const ImPlotTime& time_part);
1583 |
1584 | // Formats the time part of timestamp t into a buffer according to #fmt
1585 | IMPLOT_API int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt, bool use_24_hr_clk);
1586 | // Formats the date part of timestamp t into a buffer according to #fmt
1587 | IMPLOT_API int FormatDate(const ImPlotTime& t, char* buffer, int size, ImPlotDateFmt fmt, bool use_iso_8601);
1588 | // Formats the time and/or date parts of a timestamp t into a buffer according to #fmt
1589 | IMPLOT_API int FormatDateTime(const ImPlotTime& t, char* buffer, int size, ImPlotDateTimeSpec fmt);
1590 |
1591 | // Shows a date picker widget block (year/month/day).
1592 | // #level = 0 for day, 1 for month, 2 for year. Modified by user interaction.
1593 | // #t will be set when a day is clicked and the function will return true.
1594 | // #t1 and #t2 are optional dates to highlight.
1595 | IMPLOT_API bool ShowDatePicker(const char* id, int* level, ImPlotTime* t, const ImPlotTime* t1 = nullptr, const ImPlotTime* t2 = nullptr);
1596 | // Shows a time picker widget block (hour/min/sec).
1597 | // #t will be set when a new hour, minute, or sec is selected or am/pm is toggled, and the function will return true.
1598 | IMPLOT_API bool ShowTimePicker(const char* id, ImPlotTime* t);
1599 |
1600 | //-----------------------------------------------------------------------------
1601 | // [SECTION] Transforms
1602 | //-----------------------------------------------------------------------------
1603 |
1604 | static inline double TransformForward_Log10(double v, void*) {
1605 | v = v <= 0.0 ? DBL_MIN : v;
1606 | return ImLog10(v);
1607 | }
1608 |
1609 | static inline double TransformInverse_Log10(double v, void*) {
1610 | return ImPow(10, v);
1611 | }
1612 |
1613 | static inline double TransformForward_SymLog(double v, void*) {
1614 | return 2.0 * ImAsinh(v / 2.0);
1615 | }
1616 |
1617 | static inline double TransformInverse_SymLog(double v, void*) {
1618 | return 2.0 * ImSinh(v / 2.0);
1619 | }
1620 |
1621 | static inline double TransformForward_Logit(double v, void*) {
1622 | v = ImClamp(v, DBL_MIN, 1.0 - DBL_EPSILON);
1623 | return ImLog10(v / (1 - v));
1624 | }
1625 |
1626 | static inline double TransformInverse_Logit(double v, void*) {
1627 | return 1.0 / (1.0 + ImPow(10,-v));
1628 | }
1629 |
1630 | //-----------------------------------------------------------------------------
1631 | // [SECTION] Formatters
1632 | //-----------------------------------------------------------------------------
1633 |
1634 | static inline int Formatter_Default(double value, char* buff, int size, void* data) {
1635 | char* fmt = (char*)data;
1636 | return ImFormatString(buff, size, fmt, value);
1637 | }
1638 |
1639 | static inline int Formatter_Logit(double value, char* buff, int size, void*) {
1640 | if (value == 0.5)
1641 | return ImFormatString(buff,size,"1/2");
1642 | else if (value < 0.5)
1643 | return ImFormatString(buff,size,"%g", value);
1644 | else
1645 | return ImFormatString(buff,size,"1 - %g", 1 - value);
1646 | }
1647 |
1648 | struct Formatter_Time_Data {
1649 | ImPlotTime Time;
1650 | ImPlotDateTimeSpec Spec;
1651 | ImPlotFormatter UserFormatter;
1652 | void* UserFormatterData;
1653 | };
1654 |
1655 | static inline int Formatter_Time(double, char* buff, int size, void* data) {
1656 | Formatter_Time_Data* ftd = (Formatter_Time_Data*)data;
1657 | return FormatDateTime(ftd->Time, buff, size, ftd->Spec);
1658 | }
1659 |
1660 | //------------------------------------------------------------------------------
1661 | // [SECTION] Locator
1662 | //------------------------------------------------------------------------------
1663 |
1664 | void Locator_Default(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
1665 | void Locator_Time(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
1666 | void Locator_Log10(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
1667 | void Locator_SymLog(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
1668 |
1669 | } // namespace ImPlot
1670 |
--------------------------------------------------------------------------------