vsgImGui  0.0.0
VulkanSceneGraph 3rd party data integration library
implot_internal.h
1 // MIT License
2 
3 // Copyright (c) 2022 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.14
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 #ifndef IMGUI_DEFINE_MATH_OPERATORS
35 #define IMGUI_DEFINE_MATH_OPERATORS
36 #endif
37 
38 #include <time.h>
39 #include "imgui_internal.h"
40 
41 #ifndef IMPLOT_VERSION
42 #error Must include implot.h before implot_internal.h
43 #endif
44 
45 
46 // Support for pre-1.84 versions. ImPool's GetSize() -> GetBufSize()
47 #if (IMGUI_VERSION_NUM < 18303)
48 #define GetBufSize GetSize
49 #endif
50 
51 //-----------------------------------------------------------------------------
52 // [SECTION] Constants
53 //-----------------------------------------------------------------------------
54 
55 // Constants can be changed unless stated otherwise. We may move some of these
56 // to ImPlotStyleVar_ over time.
57 
58 // Mimimum allowable timestamp value 01/01/1970 @ 12:00am (UTC) (DO NOT DECREASE THIS)
59 #define IMPLOT_MIN_TIME 0
60 // Maximum allowable timestamp value 01/01/3000 @ 12:00am (UTC) (DO NOT INCREASE THIS)
61 #define IMPLOT_MAX_TIME 32503680000
62 // Default label format for axis labels
63 #define IMPLOT_LABEL_FORMAT "%g"
64 // Max character size for tick labels
65 #define IMPLOT_LABEL_MAX_SIZE 32
66 
67 //-----------------------------------------------------------------------------
68 // [SECTION] Macros
69 //-----------------------------------------------------------------------------
70 
71 #define IMPLOT_NUM_X_AXES ImAxis_Y1
72 #define IMPLOT_NUM_Y_AXES (ImAxis_COUNT - IMPLOT_NUM_X_AXES)
73 
74 // Split ImU32 color into RGB components [0 255]
75 #define IM_COL32_SPLIT_RGB(col,r,g,b) \
76  ImU32 r = ((col >> IM_COL32_R_SHIFT) & 0xFF); \
77  ImU32 g = ((col >> IM_COL32_G_SHIFT) & 0xFF); \
78  ImU32 b = ((col >> IM_COL32_B_SHIFT) & 0xFF);
79 
80 //-----------------------------------------------------------------------------
81 // [SECTION] Forward Declarations
82 //-----------------------------------------------------------------------------
83 
84 struct ImPlotTick;
85 struct ImPlotAxis;
86 struct ImPlotAxisColor;
87 struct ImPlotItem;
88 struct ImPlotLegend;
89 struct ImPlotPlot;
90 struct ImPlotNextPlotData;
91 struct ImPlotTicker;
92 
93 //-----------------------------------------------------------------------------
94 // [SECTION] Context Pointer
95 //-----------------------------------------------------------------------------
96 
97 #ifndef GImPlot
98 extern IMPLOT_API ImPlotContext* GImPlot; // Current implicit context pointer
99 #endif
100 
101 //-----------------------------------------------------------------------------
102 // [SECTION] Generic Helpers
103 //-----------------------------------------------------------------------------
104 
105 // Computes the common (base-10) logarithm
106 static inline float ImLog10(float x) { return log10f(x); }
107 static inline double ImLog10(double x) { return log10(x); }
108 static inline float ImSinh(float x) { return sinhf(x); }
109 static inline double ImSinh(double x) { return sinh(x); }
110 static inline float ImAsinh(float x) { return asinhf(x); }
111 static inline double ImAsinh(double x) { return asinh(x); }
112 // Returns true if a flag is set
113 template <typename TSet, typename TFlag>
114 static inline bool ImHasFlag(TSet set, TFlag flag) { return (set & flag) == flag; }
115 // Flips a flag in a flagset
116 template <typename TSet, typename TFlag>
117 static inline void ImFlipFlag(TSet& set, TFlag flag) { ImHasFlag(set, flag) ? set &= ~flag : set |= flag; }
118 // Linearly remaps x from [x0 x1] to [y0 y1].
119 template <typename T>
120 static inline T ImRemap(T x, T x0, T x1, T y0, T y1) { return y0 + (x - x0) * (y1 - y0) / (x1 - x0); }
121 // Linear rempas x from [x0 x1] to [0 1]
122 template <typename T>
123 static inline T ImRemap01(T x, T x0, T x1) { return (x - x0) / (x1 - x0); }
124 // Returns always positive modulo (assumes r != 0)
125 static inline int ImPosMod(int l, int r) { return (l % r + r) % r; }
126 // Returns true if val is NAN
127 static inline bool ImNan(double val) { return isnan(val); }
128 // Returns true if val is NAN or INFINITY
129 static inline bool ImNanOrInf(double val) { return !(val >= -DBL_MAX && val <= DBL_MAX) || ImNan(val); }
130 // Turns NANs to 0s
131 static inline double ImConstrainNan(double val) { return ImNan(val) ? 0 : val; }
132 // Turns infinity to floating point maximums
133 static inline double ImConstrainInf(double val) { return val >= DBL_MAX ? DBL_MAX : val <= -DBL_MAX ? - DBL_MAX : val; }
134 // Turns numbers less than or equal to 0 to 0.001 (sort of arbitrary, is there a better way?)
135 static inline double ImConstrainLog(double val) { return val <= 0 ? 0.001f : val; }
136 // Turns numbers less than 0 to zero
137 static inline double ImConstrainTime(double val) { return val < IMPLOT_MIN_TIME ? IMPLOT_MIN_TIME : (val > IMPLOT_MAX_TIME ? IMPLOT_MAX_TIME : val); }
138 // True if two numbers are approximately equal using units in the last place.
139 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; }
140 // Finds min value in an unsorted array
141 template <typename T>
142 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; }
143 // Finds the max value in an unsorted array
144 template <typename T>
145 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; }
146 // Finds the min and max value in an unsorted array
147 template <typename T>
148 static inline void ImMinMaxArray(const T* values, int count, T* min_out, T* max_out) {
149  T Min = values[0]; T Max = values[0];
150  for (int i = 1; i < count; ++i) {
151  if (values[i] < Min) { Min = values[i]; }
152  if (values[i] > Max) { Max = values[i]; }
153  }
154  *min_out = Min; *max_out = Max;
155 }
156 // Finds the sim of an array
157 template <typename T>
158 static inline T ImSum(const T* values, int count) {
159  T sum = 0;
160  for (int i = 0; i < count; ++i)
161  sum += values[i];
162  return sum;
163 }
164 // Finds the mean of an array
165 template <typename T>
166 static inline double ImMean(const T* values, int count) {
167  double den = 1.0 / count;
168  double mu = 0;
169  for (int i = 0; i < count; ++i)
170  mu += (double)values[i] * den;
171  return mu;
172 }
173 // Finds the sample standard deviation of an array
174 template <typename T>
175 static inline double ImStdDev(const T* values, int count) {
176  double den = 1.0 / (count - 1.0);
177  double mu = ImMean(values, count);
178  double x = 0;
179  for (int i = 0; i < count; ++i)
180  x += ((double)values[i] - mu) * ((double)values[i] - mu) * den;
181  return sqrt(x);
182 }
183 // Mix color a and b by factor s in [0 256]
184 static inline ImU32 ImMixU32(ImU32 a, ImU32 b, ImU32 s) {
185 #ifdef IMPLOT_MIX64
186  const ImU32 af = 256-s;
187  const ImU32 bf = s;
188  const ImU64 al = (a & 0x00ff00ff) | (((ImU64)(a & 0xff00ff00)) << 24);
189  const ImU64 bl = (b & 0x00ff00ff) | (((ImU64)(b & 0xff00ff00)) << 24);
190  const ImU64 mix = (al * af + bl * bf);
191  return ((mix >> 32) & 0xff00ff00) | ((mix & 0xff00ff00) >> 8);
192 #else
193  const ImU32 af = 256-s;
194  const ImU32 bf = s;
195  const ImU32 al = (a & 0x00ff00ff);
196  const ImU32 ah = (a & 0xff00ff00) >> 8;
197  const ImU32 bl = (b & 0x00ff00ff);
198  const ImU32 bh = (b & 0xff00ff00) >> 8;
199  const ImU32 ml = (al * af + bl * bf);
200  const ImU32 mh = (ah * af + bh * bf);
201  return (mh & 0xff00ff00) | ((ml & 0xff00ff00) >> 8);
202 #endif
203 }
204 
205 // Lerp across an array of 32-bit collors given t in [0.0 1.0]
206 static inline ImU32 ImLerpU32(const ImU32* colors, int size, float t) {
207  int i1 = (int)((size - 1 ) * t);
208  int i2 = i1 + 1;
209  if (i2 == size || size == 1)
210  return colors[i1];
211  float den = 1.0f / (size - 1);
212  float t1 = i1 * den;
213  float t2 = i2 * den;
214  float tr = ImRemap01(t, t1, t2);
215  return ImMixU32(colors[i1], colors[i2], (ImU32)(tr*256));
216 }
217 
218 // Set alpha channel of 32-bit color from float in range [0.0 1.0]
219 static inline ImU32 ImAlphaU32(ImU32 col, float alpha) {
220  return col & ~((ImU32)((1.0f-alpha)*255)<<IM_COL32_A_SHIFT);
221 }
222 
223 // Returns true of two ranges overlap
224 template <typename T>
225 static inline bool ImOverlaps(T min_a, T max_a, T min_b, T max_b) {
226  return min_a <= max_b && min_b <= max_a;
227 }
228 
229 //-----------------------------------------------------------------------------
230 // [SECTION] ImPlot Enums
231 //-----------------------------------------------------------------------------
232 
233 typedef int ImPlotTimeUnit; // -> enum ImPlotTimeUnit_
234 typedef int ImPlotDateFmt; // -> enum ImPlotDateFmt_
235 typedef int ImPlotTimeFmt; // -> enum ImPlotTimeFmt_
236 
237 enum ImPlotTimeUnit_ {
238  ImPlotTimeUnit_Us, // microsecond
239  ImPlotTimeUnit_Ms, // millisecond
240  ImPlotTimeUnit_S, // second
241  ImPlotTimeUnit_Min, // minute
242  ImPlotTimeUnit_Hr, // hour
243  ImPlotTimeUnit_Day, // day
244  ImPlotTimeUnit_Mo, // month
245  ImPlotTimeUnit_Yr, // year
246  ImPlotTimeUnit_COUNT
247 };
248 
249 enum ImPlotDateFmt_ { // default [ ISO 8601 ]
250  ImPlotDateFmt_None = 0,
251  ImPlotDateFmt_DayMo, // 10/3 [ --10-03 ]
252  ImPlotDateFmt_DayMoYr, // 10/3/91 [ 1991-10-03 ]
253  ImPlotDateFmt_MoYr, // Oct 1991 [ 1991-10 ]
254  ImPlotDateFmt_Mo, // Oct [ --10 ]
255  ImPlotDateFmt_Yr // 1991 [ 1991 ]
256 };
257 
258 enum ImPlotTimeFmt_ { // default [ 24 Hour Clock ]
259  ImPlotTimeFmt_None = 0,
260  ImPlotTimeFmt_Us, // .428 552 [ .428 552 ]
261  ImPlotTimeFmt_SUs, // :29.428 552 [ :29.428 552 ]
262  ImPlotTimeFmt_SMs, // :29.428 [ :29.428 ]
263  ImPlotTimeFmt_S, // :29 [ :29 ]
264  ImPlotTimeFmt_MinSMs, // 21:29.428 [ 21:29.428 ]
265  ImPlotTimeFmt_HrMinSMs, // 7:21:29.428pm [ 19:21:29.428 ]
266  ImPlotTimeFmt_HrMinS, // 7:21:29pm [ 19:21:29 ]
267  ImPlotTimeFmt_HrMin, // 7:21pm [ 19:21 ]
268  ImPlotTimeFmt_Hr // 7pm [ 19:00 ]
269 };
270 
271 //-----------------------------------------------------------------------------
272 // [SECTION] Callbacks
273 //-----------------------------------------------------------------------------
274 
275 typedef void (*ImPlotLocator)(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
276 
277 //-----------------------------------------------------------------------------
278 // [SECTION] Structs
279 //-----------------------------------------------------------------------------
280 
281 // Combined date/time format spec
283  ImPlotDateTimeSpec() {}
284  ImPlotDateTimeSpec(ImPlotDateFmt date_fmt, ImPlotTimeFmt time_fmt, bool use_24_hr_clk = false, bool use_iso_8601 = false) {
285  Date = date_fmt;
286  Time = time_fmt;
287  UseISO8601 = use_iso_8601;
288  Use24HourClock = use_24_hr_clk;
289  }
290  ImPlotDateFmt Date;
291  ImPlotTimeFmt Time;
292  bool UseISO8601;
293  bool Use24HourClock;
294 };
295 
296 // Two part timestamp struct.
297 struct ImPlotTime {
298  time_t S; // second part
299  int Us; // microsecond part
300  ImPlotTime() { S = 0; Us = 0; }
301  ImPlotTime(time_t s, int us = 0) { S = s + us / 1000000; Us = us % 1000000; }
302  void RollOver() { S = S + Us / 1000000; Us = Us % 1000000; }
303  double ToDouble() const { return (double)S + (double)Us / 1000000.0; }
304  static ImPlotTime FromDouble(double t) { return ImPlotTime((time_t)t, (int)(t * 1000000 - floor(t) * 1000000)); }
305 };
306 
307 static inline ImPlotTime operator+(const ImPlotTime& lhs, const ImPlotTime& rhs)
308 { return ImPlotTime(lhs.S + rhs.S, lhs.Us + rhs.Us); }
309 static inline ImPlotTime operator-(const ImPlotTime& lhs, const ImPlotTime& rhs)
310 { return ImPlotTime(lhs.S - rhs.S, lhs.Us - rhs.Us); }
311 static inline bool operator==(const ImPlotTime& lhs, const ImPlotTime& rhs)
312 { return lhs.S == rhs.S && lhs.Us == rhs.Us; }
313 static inline bool operator<(const ImPlotTime& lhs, const ImPlotTime& rhs)
314 { return lhs.S == rhs.S ? lhs.Us < rhs.Us : lhs.S < rhs.S; }
315 static inline bool operator>(const ImPlotTime& lhs, const ImPlotTime& rhs)
316 { return rhs < lhs; }
317 static inline bool operator<=(const ImPlotTime& lhs, const ImPlotTime& rhs)
318 { return lhs < rhs || lhs == rhs; }
319 static inline bool operator>=(const ImPlotTime& lhs, const ImPlotTime& rhs)
320 { return lhs > rhs || lhs == rhs; }
321 
322 // Colormap data storage
324  ImVector<ImU32> Keys;
325  ImVector<int> KeyCounts;
326  ImVector<int> KeyOffsets;
327  ImVector<ImU32> Tables;
328  ImVector<int> TableSizes;
329  ImVector<int> TableOffsets;
330  ImGuiTextBuffer Text;
331  ImVector<int> TextOffsets;
332  ImVector<bool> Quals;
333  ImGuiStorage Map;
334  int Count;
335 
336  ImPlotColormapData() { Count = 0; }
337 
338  int Append(const char* name, const ImU32* keys, int count, bool qual) {
339  if (GetIndex(name) != -1)
340  return -1;
341  KeyOffsets.push_back(Keys.size());
342  KeyCounts.push_back(count);
343  Keys.reserve(Keys.size()+count);
344  for (int i = 0; i < count; ++i)
345  Keys.push_back(keys[i]);
346  TextOffsets.push_back(Text.size());
347  Text.append(name, name + strlen(name) + 1);
348  Quals.push_back(qual);
349  ImGuiID id = ImHashStr(name);
350  int idx = Count++;
351  Map.SetInt(id,idx);
352  _AppendTable(idx);
353  return idx;
354  }
355 
356  void _AppendTable(ImPlotColormap cmap) {
357  int key_count = GetKeyCount(cmap);
358  const ImU32* keys = GetKeys(cmap);
359  int off = Tables.size();
360  TableOffsets.push_back(off);
361  if (IsQual(cmap)) {
362  Tables.reserve(key_count);
363  for (int i = 0; i < key_count; ++i)
364  Tables.push_back(keys[i]);
365  TableSizes.push_back(key_count);
366  }
367  else {
368  int max_size = 255 * (key_count-1) + 1;
369  Tables.reserve(off + max_size);
370  // ImU32 last = keys[0];
371  // Tables.push_back(last);
372  // int n = 1;
373  for (int i = 0; i < key_count-1; ++i) {
374  for (int s = 0; s < 255; ++s) {
375  ImU32 a = keys[i];
376  ImU32 b = keys[i+1];
377  ImU32 c = ImMixU32(a,b,s);
378  // if (c != last) {
379  Tables.push_back(c);
380  // last = c;
381  // n++;
382  // }
383  }
384  }
385  ImU32 c = keys[key_count-1];
386  // if (c != last) {
387  Tables.push_back(c);
388  // n++;
389  // }
390  // TableSizes.push_back(n);
391  TableSizes.push_back(max_size);
392  }
393  }
394 
395  void RebuildTables() {
396  Tables.resize(0);
397  TableSizes.resize(0);
398  TableOffsets.resize(0);
399  for (int i = 0; i < Count; ++i)
400  _AppendTable(i);
401  }
402 
403  inline bool IsQual(ImPlotColormap cmap) const { return Quals[cmap]; }
404  inline const char* GetName(ImPlotColormap cmap) const { return cmap < Count ? Text.Buf.Data + TextOffsets[cmap] : NULL; }
405  inline ImPlotColormap GetIndex(const char* name) const { ImGuiID key = ImHashStr(name); return Map.GetInt(key,-1); }
406 
407  inline const ImU32* GetKeys(ImPlotColormap cmap) const { return &Keys[KeyOffsets[cmap]]; }
408  inline int GetKeyCount(ImPlotColormap cmap) const { return KeyCounts[cmap]; }
409  inline ImU32 GetKeyColor(ImPlotColormap cmap, int idx) const { return Keys[KeyOffsets[cmap]+idx]; }
410  inline void SetKeyColor(ImPlotColormap cmap, int idx, ImU32 value) { Keys[KeyOffsets[cmap]+idx] = value; RebuildTables(); }
411 
412  inline const ImU32* GetTable(ImPlotColormap cmap) const { return &Tables[TableOffsets[cmap]]; }
413  inline int GetTableSize(ImPlotColormap cmap) const { return TableSizes[cmap]; }
414  inline ImU32 GetTableColor(ImPlotColormap cmap, int idx) const { return Tables[TableOffsets[cmap]+idx]; }
415 
416  inline ImU32 LerpTable(ImPlotColormap cmap, float t) const {
417  int off = TableOffsets[cmap];
418  int siz = TableSizes[cmap];
419  int idx = Quals[cmap] ? ImClamp((int)(siz*t),0,siz-1) : (int)((siz - 1) * t + 0.5f);
420  return Tables[off + idx];
421  }
422 };
423 
424 // ImPlotPoint with positive/negative error values
426  double X, Y, Neg, Pos;
427  ImPlotPointError(double x, double y, double neg, double pos) {
428  X = x; Y = y; Neg = neg; Pos = pos;
429  }
430 };
431 
432 // Interior plot label/annotation
434  ImVec2 Pos;
435  ImVec2 Offset;
436  ImU32 ColorBg;
437  ImU32 ColorFg;
438  int TextOffset;
439  bool Clamp;
440  ImPlotAnnotation() {
441  ColorBg = ColorFg = 0;
442  TextOffset = 0;
443  Clamp = false;
444  }
445 };
446 
447 // Collection of plot labels
449 
450  ImVector<ImPlotAnnotation> Annotations;
451  ImGuiTextBuffer TextBuffer;
452  int Size;
453 
454  ImPlotAnnotationCollection() { Reset(); }
455 
456  void AppendV(const ImVec2& pos, const ImVec2& off, ImU32 bg, ImU32 fg, bool clamp, const char* fmt, va_list args) IM_FMTLIST(7) {
457  ImPlotAnnotation an;
458  an.Pos = pos; an.Offset = off;
459  an.ColorBg = bg; an.ColorFg = fg;
460  an.TextOffset = TextBuffer.size();
461  an.Clamp = clamp;
462  Annotations.push_back(an);
463  TextBuffer.appendfv(fmt, args);
464  const char nul[] = "";
465  TextBuffer.append(nul,nul+1);
466  Size++;
467  }
468 
469  void Append(const ImVec2& pos, const ImVec2& off, ImU32 bg, ImU32 fg, bool clamp, const char* fmt, ...) IM_FMTARGS(7) {
470  va_list args;
471  va_start(args, fmt);
472  AppendV(pos, off, bg, fg, clamp, fmt, args);
473  va_end(args);
474  }
475 
476  const char* GetText(int idx) {
477  return TextBuffer.Buf.Data + Annotations[idx].TextOffset;
478  }
479 
480  void Reset() {
481  Annotations.shrink(0);
482  TextBuffer.Buf.shrink(0);
483  Size = 0;
484  }
485 };
486 
487 struct ImPlotTag {
488  ImAxis Axis;
489  double Value;
490  ImU32 ColorBg;
491  ImU32 ColorFg;
492  int TextOffset;
493 };
494 
496 
497  ImVector<ImPlotTag> Tags;
498  ImGuiTextBuffer TextBuffer;
499  int Size;
500 
501  ImPlotTagCollection() { Reset(); }
502 
503  void AppendV(ImAxis axis, double value, ImU32 bg, ImU32 fg, const char* fmt, va_list args) IM_FMTLIST(6) {
504  ImPlotTag tag;
505  tag.Axis = axis;
506  tag.Value = value;
507  tag.ColorBg = bg;
508  tag.ColorFg = fg;
509  tag.TextOffset = TextBuffer.size();
510  Tags.push_back(tag);
511  TextBuffer.appendfv(fmt, args);
512  const char nul[] = "";
513  TextBuffer.append(nul,nul+1);
514  Size++;
515  }
516 
517  void Append(ImAxis axis, double value, ImU32 bg, ImU32 fg, const char* fmt, ...) IM_FMTARGS(6) {
518  va_list args;
519  va_start(args, fmt);
520  AppendV(axis, value, bg, fg, fmt, args);
521  va_end(args);
522  }
523 
524  const char* GetText(int idx) {
525  return TextBuffer.Buf.Data + Tags[idx].TextOffset;
526  }
527 
528  void Reset() {
529  Tags.shrink(0);
530  TextBuffer.Buf.shrink(0);
531  Size = 0;
532  }
533 };
534 
535 // Tick mark info
537 {
538  double PlotPos;
539  float PixelPos;
540  ImVec2 LabelSize;
541  int TextOffset;
542  bool Major;
543  bool ShowLabel;
544  int Level;
545  int Idx;
546 
547  ImPlotTick(double value, bool major, int level, bool show_label) {
548  PixelPos = 0;
549  PlotPos = value;
550  Major = major;
551  ShowLabel = show_label;
552  Level = level;
553  TextOffset = -1;
554  }
555 };
556 
557 // Collection of ticks
558 struct ImPlotTicker {
559  ImVector<ImPlotTick> Ticks;
560  ImGuiTextBuffer TextBuffer;
561  ImVec2 MaxSize;
562  ImVec2 LateSize;
563  int Levels;
564 
565  ImPlotTicker() {
566  Reset();
567  }
568 
569  ImPlotTick& AddTick(double value, bool major, int level, bool show_label, const char* label) {
570  ImPlotTick tick(value, major, level, show_label);
571  if (show_label && label != NULL) {
572  tick.TextOffset = TextBuffer.size();
573  TextBuffer.append(label, label + strlen(label) + 1);
574  tick.LabelSize = ImGui::CalcTextSize(TextBuffer.Buf.Data + tick.TextOffset);
575  }
576  return AddTick(tick);
577  }
578 
579  ImPlotTick& AddTick(double value, bool major, int level, bool show_label, ImPlotFormatter formatter, void* data) {
580  ImPlotTick tick(value, major, level, show_label);
581  if (show_label && formatter != NULL) {
582  char buff[IMPLOT_LABEL_MAX_SIZE];
583  tick.TextOffset = TextBuffer.size();
584  formatter(tick.PlotPos, buff, sizeof(buff), data);
585  TextBuffer.append(buff, buff + strlen(buff) + 1);
586  tick.LabelSize = ImGui::CalcTextSize(TextBuffer.Buf.Data + tick.TextOffset);
587  }
588  return AddTick(tick);
589  }
590 
591  inline ImPlotTick& AddTick(ImPlotTick tick) {
592  if (tick.ShowLabel) {
593  MaxSize.x = tick.LabelSize.x > MaxSize.x ? tick.LabelSize.x : MaxSize.x;
594  MaxSize.y = tick.LabelSize.y > MaxSize.y ? tick.LabelSize.y : MaxSize.y;
595  }
596  tick.Idx = Ticks.size();
597  Ticks.push_back(tick);
598  return Ticks.back();
599  }
600 
601  const char* GetText(int idx) const {
602  return TextBuffer.Buf.Data + Ticks[idx].TextOffset;
603  }
604 
605  const char* GetText(const ImPlotTick& tick) {
606  return GetText(tick.Idx);
607  }
608 
609  void OverrideSizeLate(const ImVec2& size) {
610  LateSize.x = size.x > LateSize.x ? size.x : LateSize.x;
611  LateSize.y = size.y > LateSize.y ? size.y : LateSize.y;
612  }
613 
614  void Reset() {
615  Ticks.shrink(0);
616  TextBuffer.Buf.shrink(0);
617  MaxSize = LateSize;
618  LateSize = ImVec2(0,0);
619  Levels = 1;
620  }
621 
622  int TickCount() const {
623  return Ticks.Size;
624  }
625 };
626 
627 // Axis state information that must persist after EndPlot
629 {
630  ImGuiID ID;
631  ImPlotAxisFlags Flags;
632  ImPlotAxisFlags PreviousFlags;
633  ImPlotRange Range;
634  ImPlotCond RangeCond;
635  ImPlotScale Scale;
636  ImPlotRange FitExtents;
637  ImPlotAxis* OrthoAxis;
638  ImPlotRange ConstraintRange;
639  ImPlotRange ConstraintZoom;
640 
641  ImPlotTicker Ticker;
642  ImPlotFormatter Formatter;
643  void* FormatterData;
644  char FormatSpec[16];
645  ImPlotLocator Locator;
646 
647  double* LinkedMin;
648  double* LinkedMax;
649 
650  int PickerLevel;
651  ImPlotTime PickerTimeMin, PickerTimeMax;
652 
653  ImPlotTransform TransformForward;
654  ImPlotTransform TransformInverse;
655  void* TransformData;
656  float PixelMin, PixelMax;
657  double ScaleMin, ScaleMax;
658  double ScaleToPixel;
659  float Datum1, Datum2;
660 
661  ImRect HoverRect;
662  int LabelOffset;
663  ImU32 ColorMaj, ColorMin, ColorTick, ColorTxt, ColorBg, ColorHov, ColorAct, ColorHiLi;
664 
665  bool Enabled;
666  bool Vertical;
667  bool FitThisFrame;
668  bool HasRange;
669  bool HasFormatSpec;
670  bool ShowDefaultTicks;
671  bool Hovered;
672  bool Held;
673 
674  ImPlotAxis() {
675  ID = 0;
676  Flags = PreviousFlags = ImPlotAxisFlags_None;
677  Range.Min = 0;
678  Range.Max = 1;
679  Scale = ImPlotScale_Linear;
680  TransformForward = TransformInverse = NULL;
681  TransformData = NULL;
682  FitExtents.Min = HUGE_VAL;
683  FitExtents.Max = -HUGE_VAL;
684  OrthoAxis = NULL;
685  ConstraintRange = ImPlotRange(-INFINITY,INFINITY);
686  ConstraintZoom = ImPlotRange(DBL_MIN,INFINITY);
687  LinkedMin = LinkedMax = NULL;
688  PickerLevel = 0;
689  Datum1 = Datum2 = 0;
690  PixelMin = PixelMax = 0;
691  LabelOffset = -1;
692  ColorMaj = ColorMin = ColorTick = ColorTxt = ColorBg = ColorHov = ColorAct = 0;
693  ColorHiLi = IM_COL32_BLACK_TRANS;
694  Formatter = NULL;
695  FormatterData = NULL;
696  Locator = NULL;
697  Enabled = Hovered = Held = FitThisFrame = HasRange = HasFormatSpec = false;
698  ShowDefaultTicks = true;
699  }
700 
701  inline void Reset() {
702  Enabled = false;
703  Scale = ImPlotScale_Linear;
704  TransformForward = TransformInverse = NULL;
705  TransformData = NULL;
706  LabelOffset = -1;
707  HasFormatSpec = false;
708  Formatter = NULL;
709  FormatterData = NULL;
710  Locator = NULL;
711  ShowDefaultTicks = true;
712  FitThisFrame = false;
713  FitExtents.Min = HUGE_VAL;
714  FitExtents.Max = -HUGE_VAL;
715  OrthoAxis = NULL;
716  ConstraintRange = ImPlotRange(-INFINITY,INFINITY);
717  ConstraintZoom = ImPlotRange(DBL_MIN,INFINITY);
718  Ticker.Reset();
719  }
720 
721  inline bool SetMin(double _min, bool force=false) {
722  if (!force && IsLockedMin())
723  return false;
724  _min = ImConstrainNan(ImConstrainInf(_min));
725  if (_min < ConstraintRange.Min)
726  _min = ConstraintRange.Min;
727  double z = Range.Max - _min;
728  if (z < ConstraintZoom.Min)
729  _min = Range.Max - ConstraintZoom.Min;
730  if (z > ConstraintZoom.Max)
731  _min = Range.Max - ConstraintZoom.Max;
732  if (_min >= Range.Max)
733  return false;
734  Range.Min = _min;
735  PickerTimeMin = ImPlotTime::FromDouble(Range.Min);
736  UpdateTransformCache();
737  return true;
738  };
739 
740  inline bool SetMax(double _max, bool force=false) {
741  if (!force && IsLockedMax())
742  return false;
743  _max = ImConstrainNan(ImConstrainInf(_max));
744  if (_max > ConstraintRange.Max)
745  _max = ConstraintRange.Max;
746  double z = _max - Range.Min;
747  if (z < ConstraintZoom.Min)
748  _max = Range.Min + ConstraintZoom.Min;
749  if (z > ConstraintZoom.Max)
750  _max = Range.Min + ConstraintZoom.Max;
751  if (_max <= Range.Min)
752  return false;
753  Range.Max = _max;
754  PickerTimeMax = ImPlotTime::FromDouble(Range.Max);
755  UpdateTransformCache();
756  return true;
757  };
758 
759  inline void SetRange(double v1, double v2) {
760  Range.Min = ImMin(v1,v2);
761  Range.Max = ImMax(v1,v2);
762  Constrain();
763  PickerTimeMin = ImPlotTime::FromDouble(Range.Min);
764  PickerTimeMax = ImPlotTime::FromDouble(Range.Max);
765  UpdateTransformCache();
766  }
767 
768  inline void SetRange(const ImPlotRange& range) {
769  SetRange(range.Min, range.Max);
770  }
771 
772  inline void SetAspect(double unit_per_pix) {
773  double new_size = unit_per_pix * PixelSize();
774  double delta = (new_size - Range.Size()) * 0.5;
775  if (IsLocked())
776  return;
777  else if (IsLockedMin() && !IsLockedMax())
778  SetRange(Range.Min, Range.Max + 2*delta);
779  else if (!IsLockedMin() && IsLockedMax())
780  SetRange(Range.Min - 2*delta, Range.Max);
781  else
782  SetRange(Range.Min - delta, Range.Max + delta);
783  }
784 
785  inline float PixelSize() const { return ImAbs(PixelMax - PixelMin); }
786 
787  inline double GetAspect() const { return Range.Size() / PixelSize(); }
788 
789  inline void Constrain() {
790  Range.Min = ImConstrainNan(ImConstrainInf(Range.Min));
791  Range.Max = ImConstrainNan(ImConstrainInf(Range.Max));
792  if (Range.Min < ConstraintRange.Min)
793  Range.Min = ConstraintRange.Min;
794  if (Range.Max > ConstraintRange.Max)
795  Range.Max = ConstraintRange.Max;
796  double z = Range.Size();
797  if (z < ConstraintZoom.Min) {
798  double delta = (ConstraintZoom.Min - z) * 0.5;
799  Range.Min -= delta;
800  Range.Max += delta;
801  }
802  if (z > ConstraintZoom.Max) {
803  double delta = (z - ConstraintZoom.Max) * 0.5;
804  Range.Min += delta;
805  Range.Max -= delta;
806  }
807  if (Range.Max <= Range.Min)
808  Range.Max = Range.Min + DBL_EPSILON;
809  }
810 
811  inline void UpdateTransformCache() {
812  ScaleToPixel = (PixelMax - PixelMin) / Range.Size();
813  if (TransformForward != NULL) {
814  ScaleMin = TransformForward(Range.Min, TransformData);
815  ScaleMax = TransformForward(Range.Max, TransformData);
816  }
817  else {
818  ScaleMin = Range.Min;
819  ScaleMax = Range.Max;
820  }
821  }
822 
823  inline float PlotToPixels(double plt) const {
824  if (TransformForward != NULL) {
825  double s = TransformForward(plt, TransformData);
826  double t = (s - ScaleMin) / (ScaleMax - ScaleMin);
827  plt = Range.Min + Range.Size() * t;
828  }
829  return (float)(PixelMin + ScaleToPixel * (plt - Range.Min));
830  }
831 
832 
833  inline double PixelsToPlot(float pix) const {
834  double plt = (pix - PixelMin) / ScaleToPixel + Range.Min;
835  if (TransformInverse != NULL) {
836  double t = (plt - Range.Min) / Range.Size();
837  double s = t * (ScaleMax - ScaleMin) + ScaleMin;
838  plt = TransformInverse(s, TransformData);
839  }
840  return plt;
841  }
842 
843  inline void ExtendFit(double v) {
844  if (!ImNanOrInf(v) && v >= ConstraintRange.Min && v <= ConstraintRange.Max) {
845  FitExtents.Min = v < FitExtents.Min ? v : FitExtents.Min;
846  FitExtents.Max = v > FitExtents.Max ? v : FitExtents.Max;
847  }
848  }
849 
850  inline void ExtendFitWith(ImPlotAxis& alt, double v, double v_alt) {
851  if (ImHasFlag(Flags, ImPlotAxisFlags_RangeFit) && !alt.Range.Contains(v_alt))
852  return;
853  if (!ImNanOrInf(v) && v >= ConstraintRange.Min && v <= ConstraintRange.Max) {
854  FitExtents.Min = v < FitExtents.Min ? v : FitExtents.Min;
855  FitExtents.Max = v > FitExtents.Max ? v : FitExtents.Max;
856  }
857  }
858 
859  inline void ApplyFit(float padding) {
860  const double ext_size = FitExtents.Size() * 0.5;
861  FitExtents.Min -= ext_size * padding;
862  FitExtents.Max += ext_size * padding;
863  if (!IsLockedMin() && !ImNanOrInf(FitExtents.Min))
864  Range.Min = FitExtents.Min;
865  if (!IsLockedMax() && !ImNanOrInf(FitExtents.Max))
866  Range.Max = FitExtents.Max;
867  if (ImAlmostEqual(Range.Min, Range.Max)) {
868  Range.Max += 0.5;
869  Range.Min -= 0.5;
870  }
871  Constrain();
872  UpdateTransformCache();
873  }
874 
875  inline bool HasLabel() const { return LabelOffset != -1 && !ImHasFlag(Flags, ImPlotAxisFlags_NoLabel); }
876  inline bool HasGridLines() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoGridLines); }
877  inline bool HasTickLabels() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoTickLabels); }
878  inline bool HasTickMarks() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoTickMarks); }
879  inline bool WillRender() const { return Enabled && (HasGridLines() || HasTickLabels() || HasTickMarks()); }
880  inline bool IsOpposite() const { return ImHasFlag(Flags, ImPlotAxisFlags_Opposite); }
881  inline bool IsInverted() const { return ImHasFlag(Flags, ImPlotAxisFlags_Invert); }
882  inline bool IsForeground() const { return ImHasFlag(Flags, ImPlotAxisFlags_Foreground); }
883  inline bool IsAutoFitting() const { return ImHasFlag(Flags, ImPlotAxisFlags_AutoFit); }
884  inline bool CanInitFit() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoInitialFit) && !HasRange && !LinkedMin && !LinkedMax; }
885  inline bool IsRangeLocked() const { return HasRange && RangeCond == ImPlotCond_Always; }
886  inline bool IsLockedMin() const { return !Enabled || IsRangeLocked() || ImHasFlag(Flags, ImPlotAxisFlags_LockMin); }
887  inline bool IsLockedMax() const { return !Enabled || IsRangeLocked() || ImHasFlag(Flags, ImPlotAxisFlags_LockMax); }
888  inline bool IsLocked() const { return IsLockedMin() && IsLockedMax(); }
889  inline bool IsInputLockedMin() const { return IsLockedMin() || IsAutoFitting(); }
890  inline bool IsInputLockedMax() const { return IsLockedMax() || IsAutoFitting(); }
891  inline bool IsInputLocked() const { return IsLocked() || IsAutoFitting(); }
892  inline bool HasMenus() const { return !ImHasFlag(Flags, ImPlotAxisFlags_NoMenus); }
893 
894  inline bool IsPanLocked(bool increasing) {
895  if (ImHasFlag(Flags, ImPlotAxisFlags_PanStretch)) {
896  return IsInputLocked();
897  }
898  else {
899  if (IsLockedMin() || IsLockedMax() || IsAutoFitting())
900  return false;
901  if (increasing)
902  return Range.Max == ConstraintRange.Max;
903  else
904  return Range.Min == ConstraintRange.Min;
905  }
906  }
907 
908  void PushLinks() {
909  if (LinkedMin) { *LinkedMin = Range.Min; }
910  if (LinkedMax) { *LinkedMax = Range.Max; }
911  }
912 
913  void PullLinks() {
914  if (LinkedMin) { SetMin(*LinkedMin,true); }
915  if (LinkedMax) { SetMax(*LinkedMax,true); }
916  }
917 };
918 
919 // Align plots group data
921  bool Vertical;
922  float PadA;
923  float PadB;
924  float PadAMax;
925  float PadBMax;
927  Vertical = true;
928  PadA = PadB = PadAMax = PadBMax = 0;
929  }
930  void Begin() { PadAMax = PadBMax = 0; }
931  void Update(float& pad_a, float& pad_b, float& delta_a, float& delta_b) {
932  float bak_a = pad_a; float bak_b = pad_b;
933  if (PadAMax < pad_a) { PadAMax = pad_a; }
934  if (PadBMax < pad_b) { PadBMax = pad_b; }
935  if (pad_a < PadA) { pad_a = PadA; delta_a = pad_a - bak_a; } else { delta_a = 0; }
936  if (pad_b < PadB) { pad_b = PadB; delta_b = pad_b - bak_b; } else { delta_b = 0; }
937  }
938  void End() { PadA = PadAMax; PadB = PadBMax; }
939  void Reset() { PadA = PadB = PadAMax = PadBMax = 0; }
940 };
941 
942 // State information for Plot items
944 {
945  ImGuiID ID;
946  ImU32 Color;
947  ImRect LegendHoverRect;
948  int NameOffset;
949  bool Show;
950  bool LegendHovered;
951  bool SeenThisFrame;
952 
953  ImPlotItem() {
954  ID = 0;
955  Color = IM_COL32_WHITE;
956  NameOffset = -1;
957  Show = true;
958  SeenThisFrame = false;
959  LegendHovered = false;
960  }
961 
962  ~ImPlotItem() { ID = 0; }
963 };
964 
965 // Holds Legend state
967 {
968  ImPlotLegendFlags Flags;
969  ImPlotLegendFlags PreviousFlags;
970  ImPlotLocation Location;
971  ImPlotLocation PreviousLocation;
972  ImVector<int> Indices;
973  ImGuiTextBuffer Labels;
974  ImRect Rect;
975  bool Hovered;
976  bool Held;
977  bool CanGoInside;
978 
979  ImPlotLegend() {
980  Flags = PreviousFlags = ImPlotLegendFlags_None;
981  CanGoInside = true;
982  Hovered = Held = false;
983  Location = PreviousLocation = ImPlotLocation_NorthWest;
984  }
985 
986  void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); }
987 };
988 
989 // Holds Items and Legend data
991 {
992  ImGuiID ID;
993  ImPlotLegend Legend;
994  ImPool<ImPlotItem> 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
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, NULL) != 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, NULL) != 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
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<ImPlotAlignmentData> RowAlignmentData;
1130  ImVector<ImPlotAlignmentData> ColAlignmentData;
1131  ImVector<float> RowRatios;
1132  ImVector<float> ColRatios;
1133  ImVector<ImPlotRange> RowLinkData;
1134  ImVector<ImPlotRange> 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  FrameHovered = false;
1144  Items.Legend.Location = ImPlotLocation_North;
1145  Items.Legend.Flags = ImPlotLegendFlags_Horizontal|ImPlotLegendFlags_Outside;
1146  Items.Legend.CanGoInside = false;
1147  TempSizes[0] = TempSizes[1] = 0;
1148  FrameHovered = false;
1149  HasTitle = false;
1150  }
1151 };
1152 
1153 // Temporary data storage for upcoming plot
1155 {
1156  ImPlotCond RangeCond[ImAxis_COUNT];
1157  ImPlotRange Range[ImAxis_COUNT];
1158  bool HasRange[ImAxis_COUNT];
1159  bool Fit[ImAxis_COUNT];
1160  double* LinkedMin[ImAxis_COUNT];
1161  double* LinkedMax[ImAxis_COUNT];
1162 
1163  ImPlotNextPlotData() { Reset(); }
1164 
1165  void Reset() {
1166  for (int i = 0; i < ImAxis_COUNT; ++i) {
1167  HasRange[i] = false;
1168  Fit[i] = false;
1169  LinkedMin[i] = LinkedMax[i] = NULL;
1170  }
1171  }
1172 
1173 };
1174 
1175 // Temporary data storage for upcoming item
1177  ImVec4 Colors[5]; // ImPlotCol_Line, ImPlotCol_Fill, ImPlotCol_MarkerOutline, ImPlotCol_MarkerFill, ImPlotCol_ErrorBar
1178  float LineWeight;
1179  ImPlotMarker Marker;
1180  float MarkerSize;
1181  float MarkerWeight;
1182  float FillAlpha;
1183  float ErrorBarSize;
1184  float ErrorBarWeight;
1185  float DigitalBitHeight;
1186  float DigitalBitGap;
1187  bool RenderLine;
1188  bool RenderFill;
1189  bool RenderMarkerLine;
1190  bool RenderMarkerFill;
1191  bool HasHidden;
1192  bool Hidden;
1193  ImPlotCond HiddenCond;
1194  ImPlotNextItemData() { Reset(); }
1195  void Reset() {
1196  for (int i = 0; i < 5; ++i)
1197  Colors[i] = IMPLOT_AUTO_COL;
1198  LineWeight = MarkerSize = MarkerWeight = FillAlpha = ErrorBarSize = ErrorBarWeight = DigitalBitHeight = DigitalBitGap = IMPLOT_AUTO;
1199  Marker = IMPLOT_AUTO;
1200  HasHidden = Hidden = false;
1201  }
1202 };
1203 
1204 // Holds state information that must persist between calls to BeginPlot()/EndPlot()
1206  // Plot States
1207  ImPool<ImPlotPlot> Plots;
1208  ImPool<ImPlotSubplot> Subplots;
1209  ImPlotPlot* CurrentPlot;
1210  ImPlotSubplot* CurrentSubplot;
1211  ImPlotItemGroup* CurrentItems;
1212  ImPlotItem* CurrentItem;
1213  ImPlotItem* PreviousItem;
1214 
1215  // Tick Marks and Labels
1216  ImPlotTicker CTicker;
1217 
1218  // Annotation and Tabs
1219  ImPlotAnnotationCollection Annotations;
1220  ImPlotTagCollection Tags;
1221 
1222  // Flags
1223  bool ChildWindowMade;
1224 
1225  // Style and Colormaps
1226  ImPlotStyle Style;
1227  ImVector<ImGuiColorMod> ColorModifiers;
1228  ImVector<ImGuiStyleMod> StyleModifiers;
1229  ImPlotColormapData ColormapData;
1230  ImVector<ImPlotColormap> ColormapModifiers;
1231 
1232  // Time
1233  tm Tm;
1234 
1235  // Temp data for general use
1236  ImVector<double> TempDouble1, TempDouble2;
1237  ImVector<int> TempInt1;
1238 
1239  // Misc
1240  int DigitalPlotItemCnt;
1241  int DigitalPlotOffset;
1242  ImPlotNextPlotData NextPlotData;
1243  ImPlotNextItemData NextItemData;
1244  ImPlotInputMap InputMap;
1245  bool OpenContextThisFrame;
1246  ImGuiTextBuffer MousePosStringBuilder;
1247  ImPlotItemGroup* SortItems;
1248 
1249  // Align plots
1250  ImPool<ImPlotAlignmentData> AlignmentData;
1251  ImPlotAlignmentData* CurrentAlignmentH;
1252  ImPlotAlignmentData* CurrentAlignmentV;
1253 };
1254 
1255 //-----------------------------------------------------------------------------
1256 // [SECTION] Internal API
1257 // No guarantee of forward compatibility here!
1258 //-----------------------------------------------------------------------------
1259 
1260 namespace ImPlot {
1261 
1262 //-----------------------------------------------------------------------------
1263 // [SECTION] Context Utils
1264 //-----------------------------------------------------------------------------
1265 
1266 // Initializes an ImPlotContext
1267 IMPLOT_API void Initialize(ImPlotContext* ctx);
1268 // Resets an ImPlot context for the next call to BeginPlot
1269 IMPLOT_API void ResetCtxForNextPlot(ImPlotContext* ctx);
1270 // Resets an ImPlot context for the next call to BeginAlignedPlots
1271 IMPLOT_API void ResetCtxForNextAlignedPlots(ImPlotContext* ctx);
1272 // Resets an ImPlot context for the next call to BeginSubplot
1273 IMPLOT_API void ResetCtxForNextSubplot(ImPlotContext* ctx);
1274 
1275 //-----------------------------------------------------------------------------
1276 // [SECTION] Plot Utils
1277 //-----------------------------------------------------------------------------
1278 
1279 // Gets a plot from the current ImPlotContext
1280 IMPLOT_API ImPlotPlot* GetPlot(const char* title);
1281 // Gets the current plot from the current ImPlotContext
1282 IMPLOT_API ImPlotPlot* GetCurrentPlot();
1283 // Busts the cache for every plot in the current context
1284 IMPLOT_API void BustPlotCache();
1285 
1286 // Shows a plot's context menu.
1287 IMPLOT_API void ShowPlotContextMenu(ImPlotPlot& plot);
1288 
1289 //-----------------------------------------------------------------------------
1290 // [SECTION] Setup Utils
1291 //-----------------------------------------------------------------------------
1292 
1293 // Lock Setup and call SetupFinish if necessary.
1294 static inline void SetupLock() {
1295  if (!GImPlot->CurrentPlot->SetupLocked)
1296  SetupFinish();
1297  GImPlot->CurrentPlot->SetupLocked = true;
1298 }
1299 
1300 //-----------------------------------------------------------------------------
1301 // [SECTION] Subplot Utils
1302 //-----------------------------------------------------------------------------
1303 
1304 // Advances to next subplot
1305 IMPLOT_API void SubplotNextCell();
1306 
1307 // Shows a subplot's context menu.
1308 IMPLOT_API void ShowSubplotsContextMenu(ImPlotSubplot& subplot);
1309 
1310 //-----------------------------------------------------------------------------
1311 // [SECTION] Item Utils
1312 //-----------------------------------------------------------------------------
1313 
1314 // Begins a new item. Returns false if the item should not be plotted. Pushes PlotClipRect.
1315 IMPLOT_API bool BeginItem(const char* label_id, ImPlotItemFlags flags=0, ImPlotCol recolor_from=IMPLOT_AUTO);
1316 
1317 // Same as above but with fitting functionality.
1318 template <typename _Fitter>
1319 bool BeginItemEx(const char* label_id, const _Fitter& fitter, ImPlotItemFlags flags=0, ImPlotCol recolor_from=IMPLOT_AUTO) {
1320  if (BeginItem(label_id, flags, recolor_from)) {
1321  ImPlotPlot& plot = *GetCurrentPlot();
1322  if (plot.FitThisFrame && !ImHasFlag(flags, ImPlotItemFlags_NoFit))
1323  fitter.Fit(plot.Axes[plot.CurrentX], plot.Axes[plot.CurrentY]);
1324  return true;
1325  }
1326  return false;
1327 }
1328 
1329 // Ends an item (call only if BeginItem returns true). Pops PlotClipRect.
1330 IMPLOT_API void EndItem();
1331 
1332 // Register or get an existing item from the current plot.
1333 IMPLOT_API ImPlotItem* RegisterOrGetItem(const char* label_id, ImPlotItemFlags flags, bool* just_created = NULL);
1334 // Get a plot item from the current plot.
1335 IMPLOT_API ImPlotItem* GetItem(const char* label_id);
1336 // Gets the current item.
1337 IMPLOT_API ImPlotItem* GetCurrentItem();
1338 // Busts the cache for every item for every plot in the current context.
1339 IMPLOT_API void BustItemCache();
1340 
1341 //-----------------------------------------------------------------------------
1342 // [SECTION] Axis Utils
1343 //-----------------------------------------------------------------------------
1344 
1345 // Returns true if any enabled axis is locked from user input.
1346 static inline bool AnyAxesInputLocked(ImPlotAxis* axes, int count) {
1347  for (int i = 0; i < count; ++i) {
1348  if (axes[i].Enabled && axes[i].IsInputLocked())
1349  return true;
1350  }
1351  return false;
1352 }
1353 
1354 // Returns true if all enabled axes are locked from user input.
1355 static inline bool AllAxesInputLocked(ImPlotAxis* axes, int count) {
1356  for (int i = 0; i < count; ++i) {
1357  if (axes[i].Enabled && !axes[i].IsInputLocked())
1358  return false;
1359  }
1360  return true;
1361 }
1362 
1363 static inline bool AnyAxesHeld(ImPlotAxis* axes, int count) {
1364  for (int i = 0; i < count; ++i) {
1365  if (axes[i].Enabled && axes[i].Held)
1366  return true;
1367  }
1368  return false;
1369 }
1370 
1371 static inline bool AnyAxesHovered(ImPlotAxis* axes, int count) {
1372  for (int i = 0; i < count; ++i) {
1373  if (axes[i].Enabled && axes[i].Hovered)
1374  return true;
1375  }
1376  return false;
1377 }
1378 
1379 // Returns true if the user has requested data to be fit.
1380 static inline bool FitThisFrame() {
1381  return GImPlot->CurrentPlot->FitThisFrame;
1382 }
1383 
1384 // Extends the current plot's axes so that it encompasses a vertical line at x
1385 static inline void FitPointX(double x) {
1386  ImPlotPlot& plot = *GetCurrentPlot();
1387  ImPlotAxis& x_axis = plot.Axes[plot.CurrentX];
1388  x_axis.ExtendFit(x);
1389 }
1390 
1391 // Extends the current plot's axes so that it encompasses a horizontal line at y
1392 static inline void FitPointY(double y) {
1393  ImPlotPlot& plot = *GetCurrentPlot();
1394  ImPlotAxis& y_axis = plot.Axes[plot.CurrentY];
1395  y_axis.ExtendFit(y);
1396 }
1397 
1398 // Extends the current plot's axes so that it encompasses point p
1399 static inline void FitPoint(const ImPlotPoint& p) {
1400  ImPlotPlot& plot = *GetCurrentPlot();
1401  ImPlotAxis& x_axis = plot.Axes[plot.CurrentX];
1402  ImPlotAxis& y_axis = plot.Axes[plot.CurrentY];
1403  x_axis.ExtendFitWith(y_axis, p.x, p.y);
1404  y_axis.ExtendFitWith(x_axis, p.y, p.x);
1405 }
1406 
1407 // Returns true if two ranges overlap
1408 static inline bool RangesOverlap(const ImPlotRange& r1, const ImPlotRange& r2)
1409 { return r1.Min <= r2.Max && r2.Min <= r1.Max; }
1410 
1411 // Shows an axis's context menu.
1412 IMPLOT_API void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bool time_allowed = false);
1413 
1414 //-----------------------------------------------------------------------------
1415 // [SECTION] Legend Utils
1416 //-----------------------------------------------------------------------------
1417 
1418 // Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
1419 IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0));
1420 // Calculates the bounding box size of a legend
1421 IMPLOT_API ImVec2 CalcLegendSize(ImPlotItemGroup& items, const ImVec2& pad, const ImVec2& spacing, bool vertical);
1422 // Renders legend entries into a bounding box
1423 IMPLOT_API bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, bool vertical, ImDrawList& DrawList);
1424 // 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!).
1425 IMPLOT_API void ShowAltLegend(const char* title_id, bool vertical = true, const ImVec2 size = ImVec2(0,0), bool interactable = true);
1426 // Shows an legends's context menu.
1427 IMPLOT_API bool ShowLegendContextMenu(ImPlotLegend& legend, bool visible);
1428 
1429 //-----------------------------------------------------------------------------
1430 // [SECTION] Label Utils
1431 //-----------------------------------------------------------------------------
1432 
1433 // Create a a string label for a an axis value
1434 IMPLOT_API void LabelAxisValue(const ImPlotAxis& axis, double value, char* buff, int size, bool round = false);
1435 
1436 //-----------------------------------------------------------------------------
1437 // [SECTION] Styling Utils
1438 //-----------------------------------------------------------------------------
1439 
1440 // Get styling data for next item (call between Begin/EndItem)
1441 static inline const ImPlotNextItemData& GetItemData() { return GImPlot->NextItemData; }
1442 
1443 // Returns true if a color is set to be automatically determined
1444 static inline bool IsColorAuto(const ImVec4& col) { return col.w == -1; }
1445 // Returns true if a style color is set to be automaticaly determined
1446 static inline bool IsColorAuto(ImPlotCol idx) { return IsColorAuto(GImPlot->Style.Colors[idx]); }
1447 // Returns the automatically deduced style color
1448 IMPLOT_API ImVec4 GetAutoColor(ImPlotCol idx);
1449 
1450 // Returns the style color whether it is automatic or custom set
1451 static inline ImVec4 GetStyleColorVec4(ImPlotCol idx) { return IsColorAuto(idx) ? GetAutoColor(idx) : GImPlot->Style.Colors[idx]; }
1452 static inline ImU32 GetStyleColorU32(ImPlotCol idx) { return ImGui::ColorConvertFloat4ToU32(GetStyleColorVec4(idx)); }
1453 
1454 // Draws vertical text. The position is the bottom left of the text rect.
1455 IMPLOT_API void AddTextVertical(ImDrawList *DrawList, ImVec2 pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
1456 // Draws multiline horizontal text centered.
1457 IMPLOT_API void AddTextCentered(ImDrawList* DrawList, ImVec2 top_center, ImU32 col, const char* text_begin, const char* text_end = NULL);
1458 // Calculates the size of vertical text
1459 static inline ImVec2 CalcTextSizeVertical(const char *text) {
1460  ImVec2 sz = ImGui::CalcTextSize(text);
1461  return ImVec2(sz.y, sz.x);
1462 }
1463 // Returns white or black text given background color
1464 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; }
1465 static inline ImU32 CalcTextColor(ImU32 bg) { return CalcTextColor(ImGui::ColorConvertU32ToFloat4(bg)); }
1466 // Lightens or darkens a color for hover
1467 static inline ImU32 CalcHoverColor(ImU32 col) { return ImMixU32(col, CalcTextColor(col), 32); }
1468 
1469 // Clamps a label position so that it fits a rect defined by Min/Max
1470 static inline ImVec2 ClampLabelPos(ImVec2 pos, const ImVec2& size, const ImVec2& Min, const ImVec2& Max) {
1471  if (pos.x < Min.x) pos.x = Min.x;
1472  if (pos.y < Min.y) pos.y = Min.y;
1473  if ((pos.x + size.x) > Max.x) pos.x = Max.x - size.x;
1474  if ((pos.y + size.y) > Max.y) pos.y = Max.y - size.y;
1475  return pos;
1476 }
1477 
1478 // Returns a color from the Color map given an index >= 0 (modulo will be performed).
1479 IMPLOT_API ImU32 GetColormapColorU32(int idx, ImPlotColormap cmap);
1480 // Returns the next unused colormap color and advances the colormap. Can be used to skip colors if desired.
1481 IMPLOT_API ImU32 NextColormapColorU32();
1482 // Linearly interpolates a color from the current colormap given t between 0 and 1.
1483 IMPLOT_API ImU32 SampleColormapU32(float t, ImPlotColormap cmap);
1484 
1485 // Render a colormap bar
1486 IMPLOT_API void RenderColorBar(const ImU32* colors, int size, ImDrawList& DrawList, const ImRect& bounds, bool vert, bool reversed, bool continuous);
1487 
1488 //-----------------------------------------------------------------------------
1489 // [SECTION] Math and Misc Utils
1490 //-----------------------------------------------------------------------------
1491 
1492 // Rounds x to powers of 2,5 and 10 for generating axis labels (from Graphics Gems 1 Chapter 11.2)
1493 IMPLOT_API double NiceNum(double x, bool round);
1494 // Computes order of magnitude of double.
1495 static inline int OrderOfMagnitude(double val) { return val == 0 ? 0 : (int)(floor(log10(fabs(val)))); }
1496 // Returns the precision required for a order of magnitude.
1497 static inline int OrderToPrecision(int order) { return order > 0 ? 0 : 1 - order; }
1498 // Returns a floating point precision to use given a value
1499 static inline int Precision(double val) { return OrderToPrecision(OrderOfMagnitude(val)); }
1500 // Round a value to a given precision
1501 static inline double RoundTo(double val, int prec) { double p = pow(10,(double)prec); return floor(val*p+0.5)/p; }
1502 
1503 // Returns the intersection point of two lines A and B (assumes they are not parallel!)
1504 static inline ImVec2 Intersection(const ImVec2& a1, const ImVec2& a2, const ImVec2& b1, const ImVec2& b2) {
1505  float v1 = (a1.x * a2.y - a1.y * a2.x); float v2 = (b1.x * b2.y - b1.y * b2.x);
1506  float v3 = ((a1.x - a2.x) * (b1.y - b2.y) - (a1.y - a2.y) * (b1.x - b2.x));
1507  return ImVec2((v1 * (b1.x - b2.x) - v2 * (a1.x - a2.x)) / v3, (v1 * (b1.y - b2.y) - v2 * (a1.y - a2.y)) / v3);
1508 }
1509 
1510 // Fills a buffer with n samples linear interpolated from vmin to vmax
1511 template <typename T>
1512 void FillRange(ImVector<T>& buffer, int n, T vmin, T vmax) {
1513  buffer.resize(n);
1514  T step = (vmax - vmin) / (n - 1);
1515  for (int i = 0; i < n; ++i) {
1516  buffer[i] = vmin + i * step;
1517  }
1518 }
1519 
1520 // Calculate histogram bin counts and widths
1521 template <typename T>
1522 static inline void CalculateBins(const T* values, int count, ImPlotBin meth, const ImPlotRange& range, int& bins_out, double& width_out) {
1523  switch (meth) {
1524  case ImPlotBin_Sqrt:
1525  bins_out = (int)ceil(sqrt(count));
1526  break;
1527  case ImPlotBin_Sturges:
1528  bins_out = (int)ceil(1.0 + log2(count));
1529  break;
1530  case ImPlotBin_Rice:
1531  bins_out = (int)ceil(2 * cbrt(count));
1532  break;
1533  case ImPlotBin_Scott:
1534  width_out = 3.49 * ImStdDev(values, count) / cbrt(count);
1535  bins_out = (int)round(range.Size() / width_out);
1536  break;
1537  }
1538  width_out = range.Size() / bins_out;
1539 }
1540 
1541 //-----------------------------------------------------------------------------
1542 // Time Utils
1543 //-----------------------------------------------------------------------------
1544 
1545 // Returns true if year is leap year (366 days long)
1546 static inline bool IsLeapYear(int year) {
1547  return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
1548 }
1549 // Returns the number of days in a month, accounting for Feb. leap years. #month is zero indexed.
1550 static inline int GetDaysInMonth(int year, int month) {
1551  static const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
1552  return days[month] + (int)(month == 1 && IsLeapYear(year));
1553 }
1554 
1555 // Make a UNIX timestamp from a tm struct expressed in UTC time (i.e. GMT timezone).
1556 IMPLOT_API ImPlotTime MkGmtTime(struct tm *ptm);
1557 // Make a tm struct expressed in UTC time (i.e. GMT timezone) from a UNIX timestamp.
1558 IMPLOT_API tm* GetGmtTime(const ImPlotTime& t, tm* ptm);
1559 
1560 // Make a UNIX timestamp from a tm struct expressed in local time.
1561 IMPLOT_API ImPlotTime MkLocTime(struct tm *ptm);
1562 // Make a tm struct expressed in local time from a UNIX timestamp.
1563 IMPLOT_API tm* GetLocTime(const ImPlotTime& t, tm* ptm);
1564 
1565 // NB: The following functions only work if there is a current ImPlotContext because the
1566 // internal tm struct is owned by the context! They are aware of ImPlotStyle.UseLocalTime.
1567 
1568 // Make a timestamp from time components.
1569 // year[1970-3000], month[0-11], day[1-31], hour[0-23], min[0-59], sec[0-59], us[0,999999]
1570 IMPLOT_API ImPlotTime MakeTime(int year, int month = 0, int day = 1, int hour = 0, int min = 0, int sec = 0, int us = 0);
1571 // Get year component from timestamp [1970-3000]
1572 IMPLOT_API int GetYear(const ImPlotTime& t);
1573 
1574 // Adds or subtracts time from a timestamp. #count > 0 to add, < 0 to subtract.
1575 IMPLOT_API ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count);
1576 // Rounds a timestamp down to nearest unit.
1577 IMPLOT_API ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit);
1578 // Rounds a timestamp up to the nearest unit.
1579 IMPLOT_API ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit);
1580 // Rounds a timestamp up or down to the nearest unit.
1581 IMPLOT_API ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit);
1582 // Combines the date of one timestamp with the time-of-day of another timestamp.
1583 IMPLOT_API ImPlotTime CombineDateTime(const ImPlotTime& date_part, const ImPlotTime& time_part);
1584 
1585 // Formats the time part of timestamp t into a buffer according to #fmt
1586 IMPLOT_API int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt, bool use_24_hr_clk);
1587 // Formats the date part of timestamp t into a buffer according to #fmt
1588 IMPLOT_API int FormatDate(const ImPlotTime& t, char* buffer, int size, ImPlotDateFmt fmt, bool use_iso_8601);
1589 // Formats the time and/or date parts of a timestamp t into a buffer according to #fmt
1590 IMPLOT_API int FormatDateTime(const ImPlotTime& t, char* buffer, int size, ImPlotDateTimeSpec fmt);
1591 
1592 // Shows a date picker widget block (year/month/day).
1593 // #level = 0 for day, 1 for month, 2 for year. Modified by user interaction.
1594 // #t will be set when a day is clicked and the function will return true.
1595 // #t1 and #t2 are optional dates to highlight.
1596 IMPLOT_API bool ShowDatePicker(const char* id, int* level, ImPlotTime* t, const ImPlotTime* t1 = NULL, const ImPlotTime* t2 = NULL);
1597 // Shows a time picker widget block (hour/min/sec).
1598 // #t will be set when a new hour, minute, or sec is selected or am/pm is toggled, and the function will return true.
1599 IMPLOT_API bool ShowTimePicker(const char* id, ImPlotTime* t);
1600 
1601 //-----------------------------------------------------------------------------
1602 // [SECTION] Transforms
1603 //-----------------------------------------------------------------------------
1604 
1605 static inline double TransformForward_Log10(double v, void*) {
1606  v = v <= 0.0 ? DBL_MIN : v;
1607  return ImLog10(v);
1608 }
1609 
1610 static inline double TransformInverse_Log10(double v, void*) {
1611  return ImPow(10, v);
1612 }
1613 
1614 static inline double TransformForward_SymLog(double v, void*) {
1615  return 2.0 * ImAsinh(v / 2.0);
1616 }
1617 
1618 static inline double TransformInverse_SymLog(double v, void*) {
1619  return 2.0 * ImSinh(v / 2.0);
1620 }
1621 
1622 static inline double TransformForward_Logit(double v, void*) {
1623  v = ImClamp(v, DBL_MIN, 1.0 - DBL_EPSILON);
1624  return ImLog10(v / (1 - v));
1625 }
1626 
1627 static inline double TransformInverse_Logit(double v, void*) {
1628  return 1.0 / (1.0 + ImPow(10,-v));
1629 }
1630 
1631 //-----------------------------------------------------------------------------
1632 // [SECTION] Formatters
1633 //-----------------------------------------------------------------------------
1634 
1635 static inline int Formatter_Default(double value, char* buff, int size, void* data) {
1636  char* fmt = (char*)data;
1637  return ImFormatString(buff, size, fmt, value);
1638 }
1639 
1640 static inline int Formatter_Logit(double value, char* buff, int size, void*) {
1641  if (value == 0.5)
1642  return ImFormatString(buff,size,"1/2");
1643  else if (value < 0.5)
1644  return ImFormatString(buff,size,"%g", value);
1645  else
1646  return ImFormatString(buff,size,"1 - %g", 1 - value);
1647 }
1648 
1650  ImPlotTime Time;
1651  ImPlotDateTimeSpec Spec;
1652  ImPlotFormatter UserFormatter;
1653  void* UserFormatterData;
1654 };
1655 
1656 static inline int Formatter_Time(double, char* buff, int size, void* data) {
1658  return FormatDateTime(ftd->Time, buff, size, ftd->Spec);
1659 }
1660 
1661 //------------------------------------------------------------------------------
1662 // [SECTION] Locator
1663 //------------------------------------------------------------------------------
1664 
1665 void Locator_Default(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
1666 void Locator_Time(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
1667 void Locator_Log10(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
1668 void Locator_SymLog(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
1669 
1670 } // namespace ImPlot
Definition: imgui.h:2499
Definition: imgui.h:2231
Definition: imgui.h:2204
Definition: implot_internal.h:920
Definition: implot_internal.h:448
Definition: implot_internal.h:433
Definition: implot_internal.h:629
Definition: implot_internal.h:323
Definition: implot_internal.h:1205
Definition: implot_internal.h:282
Definition: implot.h:562
Definition: implot_internal.h:991
Definition: implot_internal.h:944
Definition: implot_internal.h:967
Definition: implot_internal.h:1176
Definition: implot_internal.h:1155
Definition: implot_internal.h:1014
Definition: implot_internal.h:425
Definition: implot.h:467
Definition: implot.h:481
Definition: implot.h:505
Definition: implot_internal.h:1118
Definition: implot_internal.h:495
Definition: implot_internal.h:487
Definition: implot_internal.h:537
Definition: implot_internal.h:558
Definition: implot_internal.h:297
Definition: implot_internal.h:1649
Definition: imgui_internal.h:517
Definition: imgui.h:254
Definition: imgui.h:267