2020-08-16 16:38:51 -04:00
// MIT License
// Copyright (c) 2020 Evan Pezent
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
2020-11-10 09:27:28 -05:00
// ImPlot v0.9 WIP
2020-08-16 16:38:51 -04:00
2020-08-22 23:55:37 -04:00
// You may use this file to debug, understand or extend ImPlot features but we
2020-08-16 19:46:59 -04:00
// don't provide any guarantee of forward compatibility!
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-08-19 01:04:05 -04:00
// [SECTION] Header Mess
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
# pragma once
# ifndef IMGUI_DEFINE_MATH_OPERATORS
# define IMGUI_DEFINE_MATH_OPERATORS
# endif
2020-09-03 00:30:32 -04:00
# include <time.h>
2020-08-16 16:38:51 -04:00
# include "imgui_internal.h"
# ifndef IMPLOT_VERSION
# error Must include implot.h before implot_internal.h
# endif
//-----------------------------------------------------------------------------
2020-08-19 01:04:05 -04:00
// [SECTION] Forward Declarations
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
struct ImPlotTick ;
struct ImPlotAxis ;
struct ImPlotAxisState ;
struct ImPlotAxisColor ;
struct ImPlotItem ;
2020-10-21 11:08:41 -04:00
struct ImPlotLegendData ;
2020-09-21 08:09:14 -04:00
struct ImPlotPlot ;
2020-08-16 16:38:51 -04:00
struct ImPlotNextPlotData ;
//-----------------------------------------------------------------------------
2020-08-19 01:04:05 -04:00
// [SECTION] Context Pointer
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-09-07 21:59:43 -04:00
extern IMPLOT_API ImPlotContext * GImPlot ; // Current implicit context pointer
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-08-19 01:04:05 -04:00
// [SECTION] Macros and Constants
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-08-21 00:01:21 -04:00
// Constants can be changed unless stated otherwise. We may move some of these
// to ImPlotStyleVar_ over time.
2020-08-19 01:04:05 -04:00
2020-08-16 16:38:51 -04:00
// The maximum number of supported y-axes (DO NOT CHANGE THIS)
2020-10-19 00:26:34 -04:00
# define IMPLOT_Y_AXES 3
2020-08-19 01:04:05 -04:00
// The number of times to subdivided grid divisions (best if a multiple of 1, 2, and 5)
2020-10-19 00:26:34 -04:00
# define IMPLOT_SUB_DIV 10
2020-08-19 01:04:05 -04:00
// Zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click)
2020-10-19 00:26:34 -04:00
# define IMPLOT_ZOOM_RATE 0.1f
2020-09-19 21:54:19 -04:00
// Mimimum allowable timestamp value 01/01/1970 @ 12:00am (UTC) (DO NOT DECREASE THIS)
2020-10-19 00:26:34 -04:00
# define IMPLOT_MIN_TIME 0
2020-09-19 21:54:19 -04:00
// Maximum allowable timestamp value 01/01/3000 @ 12:00am (UTC) (DO NOT INCREASE THIS)
2020-10-19 00:26:34 -04:00
# define IMPLOT_MAX_TIME 32503680000
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-08-19 01:04:05 -04:00
// [SECTION] Generic Helpers
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
// Computes the common (base-10) logarithm
static inline float ImLog10 ( float x ) { return log10f ( x ) ; }
static inline double ImLog10 ( double x ) { return log10 ( x ) ; }
// Returns true if a flag is set
template < typename TSet , typename TFlag >
inline bool ImHasFlag ( TSet set , TFlag flag ) { return ( set & flag ) = = flag ; }
// Flips a flag in a flagset
template < typename TSet , typename TFlag >
inline void ImFlipFlag ( TSet & set , TFlag flag ) { ImHasFlag ( set , flag ) ? set & = ~ flag : set | = flag ; }
// Linearly remaps x from [x0 x1] to [y0 y1].
template < typename T >
inline T ImRemap ( T x , T x0 , T x1 , T y0 , T y1 ) { return y0 + ( x - x0 ) * ( y1 - y0 ) / ( x1 - x0 ) ; }
2020-08-16 19:46:59 -04:00
// Returns always positive modulo (assumes r != 0)
2020-08-16 16:38:51 -04:00
inline int ImPosMod ( int l , int r ) { return ( l % r + r ) % r ; }
2020-09-04 20:33:10 -04:00
// Returns true if val is NAN or INFINITY
inline bool ImNanOrInf ( double val ) { return val = = HUGE_VAL | | val = = - HUGE_VAL | | isnan ( val ) ; }
// Turns NANs to 0s
inline double ImConstrainNan ( double val ) { return isnan ( val ) ? 0 : val ; }
// Turns infinity to floating point maximums
inline double ImConstrainInf ( double val ) { return val = = HUGE_VAL ? DBL_MAX : val = = - HUGE_VAL ? - DBL_MAX : val ; }
// Turns numbers less than or equal to 0 to 0.001 (sort of arbitrary, is there a better way?)
inline double ImConstrainLog ( double val ) { return val < = 0 ? 0.001f : val ; }
// Turns numbers less than 0 to zero
inline double ImConstrainTime ( double val ) { return val < IMPLOT_MIN_TIME ? IMPLOT_MIN_TIME : ( val > IMPLOT_MAX_TIME ? IMPLOT_MAX_TIME : val ) ; }
2020-11-15 22:47:06 -05:00
// True if two numbers are approximately equal using units in the last place.
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 ; }
2020-08-16 16:38:51 -04:00
// Offset calculator helper
template < int Count >
struct ImOffsetCalculator {
2020-08-21 23:13:11 -04:00
ImOffsetCalculator ( const int * sizes ) {
2020-08-16 16:38:51 -04:00
Offsets [ 0 ] = 0 ;
for ( int i = 1 ; i < Count ; + + i )
Offsets [ i ] = Offsets [ i - 1 ] + sizes [ i - 1 ] ;
}
int Offsets [ Count ] ;
} ;
2020-11-15 22:47:06 -05:00
// Character buffer writer helper (FIXME: Can't we replace this with ImGuiTextBuffer?)
2020-08-16 16:38:51 -04:00
struct ImBufferWriter
{
2020-08-16 19:46:59 -04:00
char * Buffer ;
2020-09-06 01:06:51 -04:00
int Size ;
int Pos ;
2020-08-16 19:46:59 -04:00
2020-09-06 01:06:51 -04:00
ImBufferWriter ( char * buffer , int size ) {
2020-08-16 19:46:59 -04:00
Buffer = buffer ;
Size = size ;
Pos = 0 ;
}
2020-08-16 16:38:51 -04:00
2020-09-19 21:54:19 -04:00
void Write ( const char * fmt , . . . ) {
2020-12-06 12:09:53 -05:00
va_list args ;
va_start ( args , fmt ) ;
WriteV ( fmt , args ) ;
va_end ( args ) ;
}
void WriteV ( const char * fmt , va_list args ) {
const int written = : : vsnprintf ( & Buffer [ Pos ] , Size - Pos - 1 , fmt , args ) ;
2020-08-16 16:38:51 -04:00
if ( written > 0 )
2020-09-06 01:06:51 -04:00
Pos + = ImMin ( written , Size - Pos - 1 ) ;
2020-08-16 16:38:51 -04:00
}
} ;
2020-09-02 10:17:18 -04:00
// Fixed size point array
template < int N >
struct ImPlotPointArray {
inline ImPlotPoint & operator [ ] ( int i ) { return Data [ i ] ; }
inline const ImPlotPoint & operator [ ] ( int i ) const { return Data [ i ] ; }
2020-09-07 22:30:57 -04:00
inline int Size ( ) { return N ; }
2020-09-02 10:17:18 -04:00
ImPlotPoint Data [ N ] ;
2020-08-17 17:26:45 -04:00
} ;
2020-08-30 12:03:25 -04:00
//-----------------------------------------------------------------------------
// [SECTION] ImPlot Enums
//-----------------------------------------------------------------------------
2020-10-19 00:26:34 -04:00
typedef int ImPlotScale ; // -> enum ImPlotScale_
typedef int ImPlotTimeUnit ; // -> enum ImPlotTimeUnit_
typedef int ImPlotDateFmt ; // -> enum ImPlotDateFmt_
typedef int ImPlotTimeFmt ; // -> enum ImPlotTimeFmt_
2020-09-21 08:09:14 -04:00
2020-08-30 12:03:25 -04:00
// XY axes scaling combinations
enum ImPlotScale_ {
ImPlotScale_LinLin , // linear x, linear y
ImPlotScale_LogLin , // log x, linear y
ImPlotScale_LinLog , // linear x, log y
ImPlotScale_LogLog // log x, log y
} ;
2020-09-06 22:08:25 -04:00
enum ImPlotTimeUnit_ {
ImPlotTimeUnit_Us , // microsecond
ImPlotTimeUnit_Ms , // millisecond
ImPlotTimeUnit_S , // second
ImPlotTimeUnit_Min , // minute
ImPlotTimeUnit_Hr , // hour
ImPlotTimeUnit_Day , // day
ImPlotTimeUnit_Mo , // month
ImPlotTimeUnit_Yr , // year
2020-09-05 00:30:45 -04:00
ImPlotTimeUnit_COUNT
} ;
2020-10-14 23:07:27 -04:00
enum ImPlotDateFmt_ { // default [ ISO 8601 ]
ImPlotDateFmt_None = 0 ,
ImPlotDateFmt_DayMo , // 10/3 [ --10-03 ]
ImPlotDateFmt_DayMoYr , // 10/3/91 [ 1991-10-03 ]
ImPlotDateFmt_MoYr , // Oct 1991 [ 1991-10 ]
2020-10-19 00:26:34 -04:00
ImPlotDateFmt_Mo , // Oct [ --10 ]
2020-10-14 23:07:27 -04:00
ImPlotDateFmt_Yr // 1991 [ 1991 ]
} ;
enum ImPlotTimeFmt_ { // default [ 24 Hour Clock ]
ImPlotTimeFmt_None = 0 ,
ImPlotTimeFmt_Us , // .428 552 [ .428 552 ]
ImPlotTimeFmt_SUs , // :29.428 552 [ :29.428 552 ]
ImPlotTimeFmt_SMs , // :29.428 [ :29.428 ]
ImPlotTimeFmt_S , // :29 [ :29 ]
ImPlotTimeFmt_HrMinSMs , // 7:21:29.428pm [ 19:21:29.428 ]
ImPlotTimeFmt_HrMinS , // 7:21:29pm [ 19:21:29 ]
ImPlotTimeFmt_HrMin , // 7:21pm [ 19:21 ]
ImPlotTimeFmt_Hr // 7pm [ 19:00 ]
2020-09-05 00:30:45 -04:00
} ;
2021-01-18 22:49:23 -05:00
// Input mapping structure, default values listed in the comments.
struct ImPlotInputMap {
ImGuiMouseButton PanButton ; // LMB enables panning when held
ImGuiKeyModFlags PanMod ; // none optional modifier that must be held for panning
ImGuiMouseButton FitButton ; // LMB fits visible data when double clicked
ImGuiMouseButton ContextMenuButton ; // RMB opens plot context menu (if enabled) when clicked
ImGuiMouseButton BoxSelectButton ; // RMB begins box selection when pressed and confirms selection when released
ImGuiKeyModFlags BoxSelectMod ; // none optional modifier that must be held for box selection
ImGuiMouseButton BoxSelectCancelButton ; // LMB cancels active box selection when pressed
ImGuiMouseButton QueryButton ; // MMB begins query selection when pressed and end query selection when released
ImGuiKeyModFlags QueryMod ; // none optional modifier that must be held for query selection
ImGuiKeyModFlags QueryToggleMod ; // Ctrl when held, active box selections turn into queries
ImGuiKeyModFlags HorizontalMod ; // Alt expands active box selection/query horizontally to plot edge when held
ImGuiKeyModFlags VerticalMod ; // Shift expands active box selection/query vertically to plot edge when held
IMPLOT_API ImPlotInputMap ( ) ;
} ;
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
// [SECTION] ImPlot Structs
//-----------------------------------------------------------------------------
2020-11-15 22:47:06 -05:00
// Combined date/time format spec
2020-10-14 23:07:27 -04:00
struct ImPlotDateTimeFmt {
ImPlotDateTimeFmt ( ImPlotDateFmt date_fmt , ImPlotTimeFmt time_fmt , bool use_24_hr_clk = false , bool use_iso_8601 = false ) {
Date = date_fmt ;
Time = time_fmt ;
UseISO8601 = use_iso_8601 ;
Use24HourClock = use_24_hr_clk ;
}
ImPlotDateFmt Date ;
ImPlotTimeFmt Time ;
bool UseISO8601 ;
bool Use24HourClock ;
} ;
// Two part timestamp struct.
2020-09-09 00:47:02 -04:00
struct ImPlotTime {
time_t S ; // second part
int Us ; // microsecond part
ImPlotTime ( ) { S = 0 ; Us = 0 ; }
ImPlotTime ( time_t s , int us = 0 ) { S = s + us / 1000000 ; Us = us % 1000000 ; }
void RollOver ( ) { S = S + Us / 1000000 ; Us = Us % 1000000 ; }
double ToDouble ( ) const { return ( double ) S + ( double ) Us / 1000000.0 ; }
static ImPlotTime FromDouble ( double t ) { return ImPlotTime ( ( time_t ) t , ( int ) ( t * 1000000 - floor ( t ) * 1000000 ) ) ; }
} ;
static inline ImPlotTime operator + ( const ImPlotTime & lhs , const ImPlotTime & rhs )
{ return ImPlotTime ( lhs . S + rhs . S , lhs . Us + rhs . Us ) ; }
static inline ImPlotTime operator - ( const ImPlotTime & lhs , const ImPlotTime & rhs )
{ return ImPlotTime ( lhs . S - rhs . S , lhs . Us - rhs . Us ) ; }
static inline bool operator = = ( const ImPlotTime & lhs , const ImPlotTime & rhs )
{ return lhs . S = = rhs . S & & lhs . Us = = rhs . Us ; }
static inline bool operator < ( const ImPlotTime & lhs , const ImPlotTime & rhs )
{ return lhs . S = = rhs . S ? lhs . Us < rhs . Us : lhs . S < rhs . S ; }
static inline bool operator > ( const ImPlotTime & lhs , const ImPlotTime & rhs )
{ return rhs < lhs ; }
static inline bool operator < = ( const ImPlotTime & lhs , const ImPlotTime & rhs )
{ return lhs < rhs | | lhs = = rhs ; }
static inline bool operator > = ( const ImPlotTime & lhs , const ImPlotTime & rhs )
{ return lhs > rhs | | lhs = = rhs ; }
2020-08-22 23:55:37 -04:00
// Storage for colormap modifiers
2020-08-21 23:13:11 -04:00
struct ImPlotColormapMod {
ImPlotColormapMod ( const ImVec4 * colormap , int colormap_size ) {
2020-08-22 23:55:37 -04:00
Colormap = colormap ;
2020-08-21 23:13:11 -04:00
ColormapSize = colormap_size ;
}
const ImVec4 * Colormap ;
int ColormapSize ;
} ;
2020-08-17 17:26:45 -04:00
// ImPlotPoint with positive/negative error values
2020-08-22 23:55:37 -04:00
struct ImPlotPointError
2020-08-17 17:26:45 -04:00
{
double X , Y , Neg , Pos ;
ImPlotPointError ( double x , double y , double neg , double pos ) {
X = x ; Y = y ; Neg = neg ; Pos = pos ;
}
} ;
2020-09-19 21:54:19 -04:00
// Interior plot label/annotation
struct ImPlotAnnotation {
ImVec2 Pos ;
ImVec2 Offset ;
ImU32 ColorBg ;
ImU32 ColorFg ;
int TextOffset ;
bool Clamp ;
} ;
// Collection of plot labels
struct ImPlotAnnotationCollection {
ImVector < ImPlotAnnotation > Annotations ;
ImGuiTextBuffer TextBuffer ;
int Size ;
ImPlotAnnotationCollection ( ) { Reset ( ) ; }
void AppendV ( const ImVec2 & pos , const ImVec2 & off , ImU32 bg , ImU32 fg , bool clamp , const char * fmt , va_list args ) IM_FMTLIST ( 7 ) {
ImPlotAnnotation an ;
an . Pos = pos ; an . Offset = off ;
an . ColorBg = bg ; an . ColorFg = fg ;
an . TextOffset = TextBuffer . size ( ) ;
an . Clamp = clamp ;
Annotations . push_back ( an ) ;
TextBuffer . appendfv ( fmt , args ) ;
const char nul [ ] = " " ;
TextBuffer . append ( nul , nul + 1 ) ;
Size + + ;
}
void Append ( const ImVec2 & pos , const ImVec2 & off , ImU32 bg , ImU32 fg , bool clamp , const char * fmt , . . . ) IM_FMTARGS ( 7 ) {
va_list args ;
va_start ( args , fmt ) ;
AppendV ( pos , off , bg , fg , clamp , fmt , args ) ;
va_end ( args ) ;
}
const char * GetText ( int idx ) {
return TextBuffer . Buf . Data + Annotations [ idx ] . TextOffset ;
}
void Reset ( ) {
Annotations . shrink ( 0 ) ;
TextBuffer . Buf . shrink ( 0 ) ;
Size = 0 ;
}
} ;
2020-08-16 16:38:51 -04:00
// Tick mark info
struct ImPlotTick
{
double PlotPos ;
float PixelPos ;
2020-08-19 01:04:05 -04:00
ImVec2 LabelSize ;
2020-09-19 21:54:19 -04:00
int TextOffset ;
2020-08-16 16:38:51 -04:00
bool Major ;
2020-08-19 01:04:05 -04:00
bool ShowLabel ;
2020-09-04 00:27:56 -04:00
int Level ;
2020-08-16 16:38:51 -04:00
2020-08-19 01:04:05 -04:00
ImPlotTick ( double value , bool major , bool show_label ) {
2020-08-25 22:59:43 -04:00
PlotPos = value ;
Major = major ;
ShowLabel = show_label ;
2020-09-19 21:54:19 -04:00
TextOffset = - 1 ;
2020-09-04 00:27:56 -04:00
Level = 0 ;
2020-08-16 16:38:51 -04:00
}
} ;
2020-08-25 22:59:43 -04:00
// Collection of ticks
struct ImPlotTickCollection {
ImVector < ImPlotTick > Ticks ;
2020-09-19 21:54:19 -04:00
ImGuiTextBuffer TextBuffer ;
2020-08-25 22:59:43 -04:00
float TotalWidth ;
float TotalHeight ;
float MaxWidth ;
float MaxHeight ;
int Size ;
2020-09-19 21:54:19 -04:00
ImPlotTickCollection ( ) { Reset ( ) ; }
void Append ( const ImPlotTick & tick ) {
2020-08-25 22:59:43 -04:00
if ( tick . ShowLabel ) {
TotalWidth + = tick . ShowLabel ? tick . LabelSize . x : 0 ;
TotalHeight + = tick . ShowLabel ? tick . LabelSize . y : 0 ;
MaxWidth = tick . LabelSize . x > MaxWidth ? tick . LabelSize . x : MaxWidth ;
MaxHeight = tick . LabelSize . y > MaxHeight ? tick . LabelSize . y : MaxHeight ;
}
Ticks . push_back ( tick ) ;
Size + + ;
}
2020-09-01 00:23:48 -04:00
2020-09-19 21:54:19 -04:00
void Append ( double value , bool major , bool show_label , void ( * labeler ) ( ImPlotTick & tick , ImGuiTextBuffer & buf ) ) {
2020-08-25 22:59:43 -04:00
ImPlotTick tick ( value , major , show_label ) ;
if ( labeler )
2020-09-19 21:54:19 -04:00
labeler ( tick , TextBuffer ) ;
Append ( tick ) ;
2020-08-25 22:59:43 -04:00
}
2020-09-19 21:54:19 -04:00
const char * GetText ( int idx ) {
return TextBuffer . Buf . Data + Ticks [ idx ] . TextOffset ;
2020-08-25 22:59:43 -04:00
}
2020-09-01 00:23:48 -04:00
void Reset ( ) {
Ticks . shrink ( 0 ) ;
2020-09-19 21:54:19 -04:00
TextBuffer . Buf . shrink ( 0 ) ;
2020-08-25 22:59:43 -04:00
TotalWidth = TotalHeight = MaxWidth = MaxHeight = 0 ;
Size = 0 ;
}
} ;
2020-08-16 16:38:51 -04:00
// Axis state information that must persist after EndPlot
struct ImPlotAxis
{
2020-11-15 22:47:06 -05:00
ImPlotAxisFlags Flags ;
ImPlotAxisFlags PreviousFlags ;
ImPlotRange Range ;
float Pixels ;
ImPlotOrientation Orientation ;
bool Dragging ;
bool ExtHovered ;
bool AllHovered ;
bool Present ;
bool HasRange ;
double * LinkedMin ;
double * LinkedMax ;
ImPlotTime PickerTimeMin , PickerTimeMax ;
int PickerLevel ;
ImU32 ColorMaj , ColorMin , ColorTxt ;
ImGuiCond RangeCond ;
ImRect HoverRect ;
2020-08-16 19:46:59 -04:00
2020-08-16 16:38:51 -04:00
ImPlotAxis ( ) {
2020-11-15 22:47:06 -05:00
Flags = PreviousFlags = ImPlotAxisFlags_None ;
Range . Min = 0 ;
Range . Max = 1 ;
Dragging = false ;
ExtHovered = false ;
AllHovered = false ;
LinkedMin = LinkedMax = NULL ;
2020-09-09 00:47:02 -04:00
PickerLevel = 0 ;
2020-11-15 22:47:06 -05:00
ColorMaj = ColorMin = ColorTxt = 0 ;
2020-08-16 16:38:51 -04:00
}
2020-09-04 20:33:10 -04:00
2020-09-06 22:08:25 -04:00
bool SetMin ( double _min ) {
2020-09-04 20:33:10 -04:00
_min = ImConstrainNan ( ImConstrainInf ( _min ) ) ;
if ( ImHasFlag ( Flags , ImPlotAxisFlags_LogScale ) )
_min = ImConstrainLog ( _min ) ;
2020-09-06 22:08:25 -04:00
if ( ImHasFlag ( Flags , ImPlotAxisFlags_Time ) )
_min = ImConstrainTime ( _min ) ;
if ( _min > = Range . Max )
2020-09-04 20:33:10 -04:00
return false ;
Range . Min = _min ;
2020-09-09 00:47:02 -04:00
PickerTimeMin = ImPlotTime : : FromDouble ( Range . Min ) ;
2020-09-06 22:08:25 -04:00
return true ;
2020-09-04 20:33:10 -04:00
} ;
2020-09-06 22:08:25 -04:00
bool SetMax ( double _max ) {
2020-09-04 20:33:10 -04:00
_max = ImConstrainNan ( ImConstrainInf ( _max ) ) ;
if ( ImHasFlag ( Flags , ImPlotAxisFlags_LogScale ) )
_max = ImConstrainLog ( _max ) ;
2020-09-06 22:08:25 -04:00
if ( ImHasFlag ( Flags , ImPlotAxisFlags_Time ) )
_max = ImConstrainTime ( _max ) ;
if ( _max < = Range . Min )
2020-09-04 20:33:10 -04:00
return false ;
Range . Max = _max ;
2020-09-09 00:47:02 -04:00
PickerTimeMax = ImPlotTime : : FromDouble ( Range . Max ) ;
2020-09-06 22:08:25 -04:00
return true ;
2020-09-04 20:33:10 -04:00
} ;
2020-09-05 13:25:44 -04:00
void SetRange ( double _min , double _max ) {
Range . Min = _min ;
Range . Max = _max ;
Constrain ( ) ;
2020-09-09 00:47:02 -04:00
PickerTimeMin = ImPlotTime : : FromDouble ( Range . Min ) ;
PickerTimeMax = ImPlotTime : : FromDouble ( Range . Max ) ;
2020-09-05 13:25:44 -04:00
}
void SetRange ( const ImPlotRange & range ) {
SetRange ( range . Min , range . Max ) ;
}
2020-11-15 22:47:06 -05:00
void SetAspect ( double unit_per_pix ) {
double new_size = unit_per_pix * Pixels ;
double delta = ( new_size - Range . Size ( ) ) * 0.5f ;
if ( IsLocked ( ) )
return ;
else if ( IsLockedMin ( ) & & ! IsLockedMax ( ) )
SetRange ( Range . Min , Range . Max + 2 * delta ) ;
else if ( ! IsLockedMin ( ) & & IsLockedMax ( ) )
SetRange ( Range . Min - 2 * delta , Range . Max ) ;
else
SetRange ( Range . Min - delta , Range . Max + delta ) ;
}
double GetAspect ( ) const { return Range . Size ( ) / Pixels ; }
2020-09-04 20:33:10 -04:00
void Constrain ( ) {
Range . Min = ImConstrainNan ( ImConstrainInf ( Range . Min ) ) ;
Range . Max = ImConstrainNan ( ImConstrainInf ( Range . Max ) ) ;
if ( ImHasFlag ( Flags , ImPlotAxisFlags_LogScale ) ) {
Range . Min = ImConstrainLog ( Range . Min ) ;
Range . Max = ImConstrainLog ( Range . Max ) ;
}
if ( ImHasFlag ( Flags , ImPlotAxisFlags_Time ) ) {
Range . Min = ImConstrainTime ( Range . Min ) ;
Range . Max = ImConstrainTime ( Range . Max ) ;
}
if ( Range . Max < = Range . Min )
Range . Max = Range . Min + DBL_EPSILON ;
}
2020-08-16 16:38:51 -04:00
2020-11-15 22:47:06 -05:00
inline bool IsLabeled ( ) const { return ! ImHasFlag ( Flags , ImPlotAxisFlags_NoTickLabels ) ; }
inline bool IsInverted ( ) const { return ImHasFlag ( Flags , ImPlotAxisFlags_Invert ) ; }
inline bool IsAlwaysLocked ( ) const { return HasRange & & RangeCond = = ImGuiCond_Always ; }
inline bool IsLockedMin ( ) const { return ImHasFlag ( Flags , ImPlotAxisFlags_LockMin ) | | IsAlwaysLocked ( ) ; }
inline bool IsLockedMax ( ) const { return ImHasFlag ( Flags , ImPlotAxisFlags_LockMax ) | | IsAlwaysLocked ( ) ; }
inline bool IsLocked ( ) const { return ! Present | | ( ( IsLockedMin ( ) & & IsLockedMax ( ) ) | | IsAlwaysLocked ( ) ) ; }
inline bool IsTime ( ) const { return ImHasFlag ( Flags , ImPlotAxisFlags_Time ) ; }
inline bool IsLog ( ) const { return ImHasFlag ( Flags , ImPlotAxisFlags_LogScale ) ; }
2020-08-16 16:38:51 -04:00
} ;
// State information for Plot items
struct ImPlotItem
{
2020-08-28 18:11:36 -04:00
ImGuiID ID ;
ImVec4 Color ;
int NameOffset ;
bool Show ;
2020-09-01 00:58:15 -04:00
bool LegendHovered ;
2020-08-28 18:11:36 -04:00
bool SeenThisFrame ;
2020-08-16 16:38:51 -04:00
ImPlotItem ( ) {
2020-08-16 19:46:59 -04:00
ID = 0 ;
Color = ImPlot : : NextColormapColor ( ) ;
2020-08-28 18:11:36 -04:00
NameOffset = - 1 ;
2020-08-16 16:38:51 -04:00
Show = true ;
SeenThisFrame = false ;
2020-09-01 00:58:15 -04:00
LegendHovered = false ;
2020-08-16 16:38:51 -04:00
}
~ ImPlotItem ( ) { ID = 0 ; }
} ;
2020-10-19 00:26:34 -04:00
// Holds Legend state labels and item references
2020-10-21 11:08:41 -04:00
struct ImPlotLegendData
2020-10-19 00:26:34 -04:00
{
ImVector < int > Indices ;
ImGuiTextBuffer Labels ;
void Reset ( ) { Indices . shrink ( 0 ) ; Labels . Buf . shrink ( 0 ) ; }
} ;
2020-08-16 16:38:51 -04:00
// Holds Plot state information that must persist after EndPlot
2020-09-21 08:09:14 -04:00
struct ImPlotPlot
2020-08-16 16:38:51 -04:00
{
2020-10-21 11:08:41 -04:00
ImGuiID ID ;
2020-08-16 19:46:59 -04:00
ImPlotFlags Flags ;
ImPlotFlags PreviousFlags ;
ImPlotAxis XAxis ;
2020-08-19 01:04:05 -04:00
ImPlotAxis YAxis [ IMPLOT_Y_AXES ] ;
2020-10-21 11:08:41 -04:00
ImPlotLegendData LegendData ;
2020-08-16 16:38:51 -04:00
ImPool < ImPlotItem > Items ;
ImVec2 SelectStart ;
2020-08-16 19:46:59 -04:00
ImVec2 QueryStart ;
ImRect QueryRect ;
2020-08-16 16:38:51 -04:00
bool Selecting ;
2021-01-18 22:49:23 -05:00
bool ContextLocked ;
2020-08-16 16:38:51 -04:00
bool Querying ;
bool Queried ;
bool DraggingQuery ;
2020-10-19 00:26:34 -04:00
bool LegendHovered ;
bool LegendOutside ;
2020-11-15 22:47:06 -05:00
bool LegendFlipSideNextFrame ;
bool FrameHovered ;
bool PlotHovered ;
2020-08-16 19:46:59 -04:00
int ColormapIdx ;
2020-08-16 16:38:51 -04:00
int CurrentYAxis ;
2020-10-19 00:26:34 -04:00
ImPlotLocation MousePosLocation ;
ImPlotLocation LegendLocation ;
ImPlotOrientation LegendOrientation ;
2020-11-15 22:47:06 -05:00
ImRect FrameRect ;
ImRect CanvasRect ;
ImRect PlotRect ;
ImRect AxesRect ;
2020-08-16 16:38:51 -04:00
2020-10-21 11:08:41 -04:00
ImPlotPlot ( ) {
2020-11-15 22:47:06 -05:00
Flags = PreviousFlags = ImPlotFlags_None ;
XAxis . Orientation = ImPlotOrientation_Horizontal ;
2020-09-21 08:09:14 -04:00
for ( int i = 0 ; i < IMPLOT_Y_AXES ; + + i )
2020-11-15 22:47:06 -05:00
YAxis [ i ] . Orientation = ImPlotOrientation_Vertical ;
2020-10-19 00:26:34 -04:00
SelectStart = QueryStart = ImVec2 ( 0 , 0 ) ;
2021-01-18 22:49:23 -05:00
Selecting = ContextLocked = Querying = Queried = DraggingQuery = LegendHovered = LegendOutside = LegendFlipSideNextFrame = false ;
2020-10-19 00:26:34 -04:00
ColormapIdx = CurrentYAxis = 0 ;
LegendLocation = ImPlotLocation_North | ImPlotLocation_West ;
LegendOrientation = ImPlotOrientation_Vertical ;
MousePosLocation = ImPlotLocation_South | ImPlotLocation_East ;
2020-08-16 16:38:51 -04:00
}
2020-10-19 00:26:34 -04:00
2020-10-21 11:08:41 -04:00
int GetLegendCount ( ) const { return LegendData . Indices . size ( ) ; }
ImPlotItem * GetLegendItem ( int i ) ;
const char * GetLegendLabel ( int i ) ;
2020-11-15 22:47:06 -05:00
inline bool IsLocked ( ) const { return XAxis . IsLocked ( ) & & YAxis [ 0 ] . IsLocked ( ) & & YAxis [ 1 ] . IsLocked ( ) & & YAxis [ 2 ] . IsLocked ( ) ; }
2020-08-16 16:38:51 -04:00
} ;
// Temporary data storage for upcoming plot
struct ImPlotNextPlotData
{
ImGuiCond XRangeCond ;
2020-08-19 01:04:05 -04:00
ImGuiCond YRangeCond [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
ImPlotRange X ;
2020-08-19 01:04:05 -04:00
ImPlotRange Y [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
bool HasXRange ;
2020-08-19 01:04:05 -04:00
bool HasYRange [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
bool ShowDefaultTicksX ;
2020-08-19 01:04:05 -04:00
bool ShowDefaultTicksY [ IMPLOT_Y_AXES ] ;
2020-08-20 00:50:12 -04:00
bool FitX ;
bool FitY [ IMPLOT_Y_AXES ] ;
2020-09-03 10:19:34 -04:00
double * LinkedXmin ;
double * LinkedXmax ;
double * LinkedYmin [ IMPLOT_Y_AXES ] ;
double * LinkedYmax [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
2020-11-15 22:47:06 -05:00
ImPlotNextPlotData ( ) { Reset ( ) ; }
void Reset ( ) {
2020-08-16 16:38:51 -04:00
HasXRange = false ;
ShowDefaultTicksX = true ;
2020-08-20 00:50:12 -04:00
FitX = false ;
2020-09-03 10:19:34 -04:00
LinkedXmin = LinkedXmax = NULL ;
2020-08-19 01:04:05 -04:00
for ( int i = 0 ; i < IMPLOT_Y_AXES ; + + i ) {
2020-08-16 16:38:51 -04:00
HasYRange [ i ] = false ;
ShowDefaultTicksY [ i ] = true ;
2020-08-20 00:50:12 -04:00
FitY [ i ] = false ;
2020-09-03 10:19:34 -04:00
LinkedYmin [ i ] = LinkedYmax [ i ] = NULL ;
2020-08-16 16:38:51 -04:00
}
}
2020-11-15 22:47:06 -05:00
2020-08-16 16:38:51 -04:00
} ;
2020-08-30 12:03:25 -04:00
// Temporary data storage for upcoming item
2020-09-15 10:48:46 -04:00
struct ImPlotNextItemData {
2020-08-30 18:12:36 -04:00
ImVec4 Colors [ 5 ] ; // ImPlotCol_Line, ImPlotCol_Fill, ImPlotCol_MarkerOutline, ImPlotCol_MarkerFill, ImPlotCol_ErrorBar
2020-09-01 00:23:48 -04:00
float LineWeight ;
ImPlotMarker Marker ;
float MarkerSize ;
float MarkerWeight ;
float FillAlpha ;
float ErrorBarSize ;
float ErrorBarWeight ;
float DigitalBitHeight ;
float DigitalBitGap ;
2020-08-30 18:12:36 -04:00
bool RenderLine ;
bool RenderFill ;
bool RenderMarkerLine ;
bool RenderMarkerFill ;
2020-09-15 10:48:46 -04:00
bool HasHidden ;
bool Hidden ;
ImGuiCond HiddenCond ;
2020-11-15 22:47:06 -05:00
ImPlotNextItemData ( ) { Reset ( ) ; }
void Reset ( ) {
2020-08-30 12:03:25 -04:00
for ( int i = 0 ; i < 5 ; + + i )
2020-08-30 18:12:36 -04:00
Colors [ i ] = IMPLOT_AUTO_COL ;
2020-09-15 10:48:46 -04:00
LineWeight = MarkerSize = MarkerWeight = FillAlpha = ErrorBarSize = ErrorBarWeight = DigitalBitHeight = DigitalBitGap = IMPLOT_AUTO ;
Marker = IMPLOT_AUTO ;
HasHidden = Hidden = false ;
2020-09-01 00:23:48 -04:00
}
2020-08-30 12:03:25 -04:00
} ;
2020-08-16 16:38:51 -04:00
// Holds state information that must persist between calls to BeginPlot()/EndPlot()
struct ImPlotContext {
// Plot States
2020-09-21 08:09:14 -04:00
ImPool < ImPlotPlot > Plots ;
ImPlotPlot * CurrentPlot ;
2020-10-19 00:26:34 -04:00
ImPlotItem * CurrentItem ;
ImPlotItem * PreviousItem ;
2020-08-16 16:38:51 -04:00
// Tick Marks and Labels
2020-08-25 22:59:43 -04:00
ImPlotTickCollection XTicks ;
ImPlotTickCollection YTicks [ IMPLOT_Y_AXES ] ;
2020-08-19 12:34:52 -04:00
float YAxisReference [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
2020-09-19 21:54:19 -04:00
// Annotation and User Labels
ImPlotAnnotationCollection Annotations ;
2020-08-16 16:38:51 -04:00
// Transformations and Data Extents
2020-08-30 12:03:25 -04:00
ImPlotScale Scales [ IMPLOT_Y_AXES ] ;
2020-08-19 01:04:05 -04:00
ImRect PixelRange [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
double Mx ;
2020-08-19 01:04:05 -04:00
double My [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
double LogDenX ;
2020-08-19 01:04:05 -04:00
double LogDenY [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
ImPlotRange ExtentsX ;
2020-08-19 01:04:05 -04:00
ImPlotRange ExtentsY [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
// Data Fitting Flags
bool FitThisFrame ;
bool FitX ;
2020-08-19 01:04:05 -04:00
bool FitY [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
// Axis Rendering Flags
bool RenderX ;
2020-08-19 01:04:05 -04:00
bool RenderY [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
// Axis Locking Flags
bool ChildWindowMade ;
// Style and Colormaps
2020-08-21 23:13:11 -04:00
ImPlotStyle Style ;
ImVector < ImGuiColorMod > ColorModifiers ;
ImVector < ImGuiStyleMod > StyleModifiers ;
const ImVec4 * Colormap ;
int ColormapSize ;
ImVector < ImPlotColormapMod > ColormapModifiers ;
2020-08-16 16:38:51 -04:00
2020-09-03 00:30:32 -04:00
// Time
tm Tm ;
2020-08-16 16:38:51 -04:00
// Misc
int VisibleItemCount ;
int DigitalPlotItemCnt ;
int DigitalPlotOffset ;
ImPlotNextPlotData NextPlotData ;
2020-09-15 10:48:46 -04:00
ImPlotNextItemData NextItemData ;
2020-08-16 16:38:51 -04:00
ImPlotInputMap InputMap ;
2020-08-22 23:55:37 -04:00
ImPlotPoint MousePos [ IMPLOT_Y_AXES ] ;
2020-08-16 16:38:51 -04:00
} ;
//-----------------------------------------------------------------------------
// [SECTION] Internal API
// No guarantee of forward compatibility here!
//-----------------------------------------------------------------------------
namespace ImPlot {
2020-09-01 22:01:00 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Context Utils
//-----------------------------------------------------------------------------
2020-08-16 16:38:51 -04:00
// Initializes an ImPlotContext
2020-09-07 21:59:43 -04:00
IMPLOT_API void Initialize ( ImPlotContext * ctx ) ;
2020-08-16 16:38:51 -04:00
// Resets an ImPlot context for the next call to BeginPlot
2020-09-07 21:59:43 -04:00
IMPLOT_API void Reset ( ImPlotContext * ctx ) ;
2020-08-16 19:46:59 -04:00
2021-01-18 22:49:23 -05:00
//-----------------------------------------------------------------------------
// [SECTION] Input Utils
//-----------------------------------------------------------------------------
// Allows changing how keyboard/mouse interaction works.
IMPLOT_API ImPlotInputMap & GetInputMap ( ) ;
2020-09-01 22:01:00 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Plot Utils
//-----------------------------------------------------------------------------
2020-08-16 16:38:51 -04:00
// Gets a plot from the current ImPlotContext
2020-09-21 08:09:14 -04:00
IMPLOT_API ImPlotPlot * GetPlot ( const char * title ) ;
2020-08-16 16:38:51 -04:00
// Gets the current plot from the current ImPlotContext
2020-09-21 08:09:14 -04:00
IMPLOT_API ImPlotPlot * GetCurrentPlot ( ) ;
2020-08-24 00:45:42 -04:00
// Busts the cache for every plot in the current context
2020-09-07 21:59:43 -04:00
IMPLOT_API void BustPlotCache ( ) ;
2020-08-16 19:46:59 -04:00
2020-09-09 10:00:50 -04:00
// Shows a plot's context menu.
2020-09-21 08:09:14 -04:00
IMPLOT_API void ShowPlotContextMenu ( ImPlotPlot & plot ) ;
2020-09-09 10:00:50 -04:00
2020-09-01 22:01:00 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Item Utils
//-----------------------------------------------------------------------------
2020-08-30 12:03:25 -04:00
2020-08-30 22:03:11 -04:00
// Begins a new item. Returns false if the item should not be plotted. Pushes PlotClipRect.
2020-09-07 21:59:43 -04:00
IMPLOT_API bool BeginItem ( const char * label_id , ImPlotCol recolor_from = - 1 ) ;
2020-08-30 22:03:11 -04:00
// Ends an item (call only if BeginItem returns true). Pops PlotClipRect.
2020-09-07 21:59:43 -04:00
IMPLOT_API void EndItem ( ) ;
2020-08-16 19:46:59 -04:00
2020-10-19 00:26:34 -04:00
// Register or get an existing item from the current plot.
2020-09-15 10:48:46 -04:00
IMPLOT_API ImPlotItem * RegisterOrGetItem ( const char * label_id , bool * just_created = NULL ) ;
2020-10-19 00:26:34 -04:00
// Get a plot item from the current plot.
2020-09-07 21:59:43 -04:00
IMPLOT_API ImPlotItem * GetItem ( const char * label_id ) ;
2020-10-19 00:26:34 -04:00
// Gets the current item.
2020-09-07 21:59:43 -04:00
IMPLOT_API ImPlotItem * GetCurrentItem ( ) ;
2020-08-24 00:45:42 -04:00
// Busts the cache for every item for every plot in the current context.
2020-09-07 21:59:43 -04:00
IMPLOT_API void BustItemCache ( ) ;
2020-08-16 19:46:59 -04:00
2020-09-01 22:01:00 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Axis Utils
//-----------------------------------------------------------------------------
2020-08-30 12:03:25 -04:00
2020-09-01 22:01:00 -04:00
// Gets the current y-axis for the current plot
inline int GetCurrentYAxis ( ) { return GImPlot - > CurrentPlot - > CurrentYAxis ; }
// Updates axis ticks, lins, and label colors
2020-12-06 12:09:53 -05:00
IMPLOT_API void UpdateAxisColors ( int axis_flag , ImPlotAxis * axis ) ;
2020-09-01 22:01:00 -04:00
// Updates plot-to-pixel space transformation variables for the current plot.
2020-09-07 21:59:43 -04:00
IMPLOT_API void UpdateTransformCache ( ) ;
2020-09-01 22:01:00 -04:00
// Gets the XY scale for the current plot and y-axis
inline ImPlotScale GetCurrentScale ( ) { return GImPlot - > Scales [ GetCurrentYAxis ( ) ] ; }
// Returns true if the user has requested data to be fit.
inline bool FitThisFrame ( ) { return GImPlot - > FitThisFrame ; }
2021-01-15 02:52:37 -05:00
// Extends the current plot's axes so that it encompasses point p
2020-09-07 21:59:43 -04:00
IMPLOT_API void FitPoint ( const ImPlotPoint & p ) ;
2021-01-15 02:52:37 -05:00
// Extends the current plot's axes so that it encompasses a vertical line at x
IMPLOT_API void FitPointX ( double x ) ;
// Extends the current plot's axes so that it encompasses a horizontal line at y
IMPLOT_API void FitPointY ( double y ) ;
2020-09-01 22:01:00 -04:00
2020-09-05 00:30:45 -04:00
// Returns true if two ranges overlap
2020-09-06 22:08:25 -04:00
inline bool RangesOverlap ( const ImPlotRange & r1 , const ImPlotRange & r2 )
2020-09-05 13:25:44 -04:00
{ return r1 . Min < = r2 . Max & & r2 . Min < = r1 . Max ; }
2020-09-05 00:30:45 -04:00
2020-09-06 17:09:00 -04:00
// Updates pointers for linked axes from axis internal range.
2020-09-07 21:59:43 -04:00
IMPLOT_API void PushLinkedAxis ( ImPlotAxis & axis ) ;
2020-09-06 17:09:00 -04:00
// Updates axis internal range from points for linked axes.
2020-09-07 21:59:43 -04:00
IMPLOT_API void PullLinkedAxis ( ImPlotAxis & axis ) ;
2020-09-03 10:19:34 -04:00
2020-09-09 10:00:50 -04:00
// Shows an axis's context menu.
2020-12-06 12:09:53 -05:00
IMPLOT_API void ShowAxisContextMenu ( ImPlotAxis & axis , ImPlotAxis * equal_axis , bool time_allowed = false ) ;
2020-09-09 10:00:50 -04:00
2020-09-01 22:01:00 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Legend Utils
//-----------------------------------------------------------------------------
2020-08-30 12:03:25 -04:00
2020-10-19 00:26:34 -04:00
// Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
IMPLOT_API ImVec2 GetLocationPos ( const ImRect & outer_rect , const ImVec2 & inner_size , ImPlotLocation location , const ImVec2 & pad = ImVec2 ( 0 , 0 ) ) ;
// Calculates the bounding box size of a legend
2020-10-21 11:08:41 -04:00
IMPLOT_API ImVec2 CalcLegendSize ( ImPlotPlot & plot , const ImVec2 & pad , const ImVec2 & spacing , ImPlotOrientation orientation ) ;
2020-10-19 00:26:34 -04:00
// Renders legend entries into a bounding box
2020-10-21 11:08:41 -04:00
IMPLOT_API void ShowLegendEntries ( ImPlotPlot & plot , const ImRect & legend_bb , bool interactable , const ImVec2 & pad , const ImVec2 & spacing , ImPlotOrientation orientation , ImDrawList & DrawList ) ;
2020-10-19 00:26:34 -04:00
// 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!).
IMPLOT_API void ShowAltLegend ( const char * title_id , ImPlotOrientation orientation = ImPlotOrientation_Vertical , const ImVec2 size = ImVec2 ( 0 , 0 ) , bool interactable = true ) ;
2020-08-16 19:46:59 -04:00
2020-09-01 22:01:00 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Tick Utils
//-----------------------------------------------------------------------------
2020-09-03 00:30:32 -04:00
// Label a tick with default formatting.
2020-09-07 21:59:43 -04:00
IMPLOT_API void LabelTickDefault ( ImPlotTick & tick , ImGuiTextBuffer & buffer ) ;
2020-09-03 00:30:32 -04:00
// Label a tick with scientific formating.
2020-09-07 21:59:43 -04:00
IMPLOT_API void LabelTickScientific ( ImPlotTick & tick , ImGuiTextBuffer & buffer ) ;
2020-09-03 00:30:32 -04:00
// Label a tick with time formatting.
2020-10-14 23:07:27 -04:00
IMPLOT_API void LabelTickTime ( ImPlotTick & tick , ImGuiTextBuffer & buffer , const ImPlotTime & t , ImPlotDateTimeFmt fmt ) ;
2020-09-01 22:01:00 -04:00
2020-08-22 23:55:37 -04:00
// Populates a list of ImPlotTicks with normal spaced and formatted ticks
2020-09-07 21:59:43 -04:00
IMPLOT_API void AddTicksDefault ( const ImPlotRange & range , int nMajor , int nMinor , ImPlotTickCollection & ticks ) ;
2020-08-22 23:55:37 -04:00
// Populates a list of ImPlotTicks with logarithmic space and formatted ticks
2020-09-07 21:59:43 -04:00
IMPLOT_API void AddTicksLogarithmic ( const ImPlotRange & range , int nMajor , ImPlotTickCollection & ticks ) ;
2020-09-03 00:30:32 -04:00
// Populates a list of ImPlotTicks with time formatted ticks.
2020-12-03 08:20:55 -05:00
IMPLOT_API void AddTicksTime ( const ImPlotRange & range , float plot_width , ImPlotTickCollection & ticks ) ;
2020-08-16 16:38:51 -04:00
// Populates a list of ImPlotTicks with custom spaced and labeled ticks
2020-09-07 21:59:43 -04:00
IMPLOT_API void AddTicksCustom ( const double * values , const char * const labels [ ] , int n , ImPlotTickCollection & ticks ) ;
2020-08-19 01:04:05 -04:00
2020-09-21 08:09:14 -04:00
// Create a a string label for a an axis value
IMPLOT_API int LabelAxisValue ( const ImPlotAxis & axis , const ImPlotTickCollection & ticks , double value , char * buff , int size ) ;
2020-09-01 22:01:00 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Styling Utils
//-----------------------------------------------------------------------------
// Get styling data for next item (call between Begin/EndItem)
2020-09-15 10:48:46 -04:00
inline const ImPlotNextItemData & GetItemData ( ) { return GImPlot - > NextItemData ; }
2020-09-01 22:01:00 -04:00
// Returns true if a color is set to be automatically determined
inline bool IsColorAuto ( const ImVec4 & col ) { return col . w = = - 1 ; }
// Returns true if a style color is set to be automaticaly determined
inline bool IsColorAuto ( ImPlotCol idx ) { return IsColorAuto ( GImPlot - > Style . Colors [ idx ] ) ; }
// Returns the automatically deduced style color
2020-09-07 21:59:43 -04:00
IMPLOT_API ImVec4 GetAutoColor ( ImPlotCol idx ) ;
2020-09-01 22:01:00 -04:00
// Returns the style color whether it is automatic or custom set
inline ImVec4 GetStyleColorVec4 ( ImPlotCol idx ) { return IsColorAuto ( idx ) ? GetAutoColor ( idx ) : GImPlot - > Style . Colors [ idx ] ; }
inline ImU32 GetStyleColorU32 ( ImPlotCol idx ) { return ImGui : : ColorConvertFloat4ToU32 ( GetStyleColorVec4 ( idx ) ) ; }
// Get built-in colormap data and size
2020-09-07 21:59:43 -04:00
IMPLOT_API const ImVec4 * GetColormap ( ImPlotColormap colormap , int * size_out ) ;
2020-09-01 22:01:00 -04:00
// Linearly interpolates a color from the current colormap given t between 0 and 1.
2020-09-07 21:59:43 -04:00
IMPLOT_API ImVec4 LerpColormap ( const ImVec4 * colormap , int size , float t ) ;
2020-09-01 22:01:00 -04:00
// Resamples a colormap. #size_out must be greater than 1.
2020-09-07 21:59:43 -04:00
IMPLOT_API void ResampleColormap ( const ImVec4 * colormap_in , int size_in , ImVec4 * colormap_out , int size_out ) ;
2020-08-25 22:59:43 -04:00
2020-08-16 16:38:51 -04:00
// Draws vertical text. The position is the bottom left of the text rect.
2020-09-07 21:59:43 -04:00
IMPLOT_API void AddTextVertical ( ImDrawList * DrawList , ImVec2 pos , ImU32 col , const char * text_begin , const char * text_end = NULL ) ;
2020-08-16 16:38:51 -04:00
// Calculates the size of vertical text
2020-09-01 22:01:00 -04:00
inline ImVec2 CalcTextSizeVertical ( const char * text ) { ImVec2 sz = ImGui : : CalcTextSize ( text ) ; return ImVec2 ( sz . y , sz . x ) ; }
// Returns white or black text given background color
2020-09-22 18:23:50 -04:00
inline ImU32 CalcTextColor ( const ImVec4 & bg ) { return ( bg . x * 0.299 + bg . y * 0.587 + bg . z * 0.114 ) > 0.5 ? IM_COL32_BLACK : IM_COL32_WHITE ; }
2020-09-01 22:01:00 -04:00
2020-09-19 13:33:33 -04:00
// Clamps a label position so that it fits a rect defined by Min/Max
inline ImVec2 ClampLabelPos ( ImVec2 pos , const ImVec2 & size , const ImVec2 & Min , const ImVec2 & Max ) {
if ( pos . x < Min . x ) pos . x = Min . x ;
if ( pos . y < Min . y ) pos . y = Min . y ;
if ( ( pos . x + size . x ) > Max . x ) pos . x = Max . x - size . x ;
if ( ( pos . y + size . y ) > Max . y ) pos . y = Max . y - size . y ;
return pos ;
}
2020-09-01 22:01:00 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Math and Misc Utils
//-----------------------------------------------------------------------------
2020-08-16 19:46:59 -04:00
2020-09-01 22:01:00 -04:00
// Rounds x to powers of 2,5 and 10 for generating axis labels (from Graphics Gems 1 Chapter 11.2)
2020-09-07 21:59:43 -04:00
IMPLOT_API double NiceNum ( double x , bool round ) ;
2020-08-16 16:38:51 -04:00
// Computes order of magnitude of double.
inline int OrderOfMagnitude ( double val ) { return val = = 0 ? 0 : ( int ) ( floor ( log10 ( fabs ( val ) ) ) ) ; }
// Returns the precision required for a order of magnitude.
inline int OrderToPrecision ( int order ) { return order > 0 ? 0 : 1 - order ; }
// Returns a floating point precision to use given a value
inline int Precision ( double val ) { return OrderToPrecision ( OrderOfMagnitude ( val ) ) ; }
2020-08-16 19:46:59 -04:00
2020-08-16 16:38:51 -04:00
// Returns the intersection point of two lines A and B (assumes they are not parallel!)
inline ImVec2 Intersection ( const ImVec2 & a1 , const ImVec2 & a2 , const ImVec2 & b1 , const ImVec2 & b2 ) {
2020-09-01 22:01:00 -04:00
float v1 = ( a1 . x * a2 . y - a1 . y * a2 . x ) ; float v2 = ( b1 . x * b2 . y - b1 . y * b2 . x ) ;
2020-08-16 16:38:51 -04:00
float v3 = ( ( a1 . x - a2 . x ) * ( b1 . y - b2 . y ) - ( a1 . y - a2 . y ) * ( b1 . x - b2 . x ) ) ;
return ImVec2 ( ( v1 * ( b1 . x - b2 . x ) - v2 * ( a1 . x - a2 . x ) ) / v3 , ( v1 * ( b1 . y - b2 . y ) - v2 * ( a1 . y - a2 . y ) ) / v3 ) ;
}
2020-08-16 19:46:59 -04:00
2020-08-16 16:38:51 -04:00
// Fills a buffer with n samples linear interpolated from vmin to vmax
template < typename T >
void FillRange ( ImVector < T > & buffer , int n , T vmin , T vmax ) {
buffer . resize ( n ) ;
T step = ( vmax - vmin ) / ( n - 1 ) ;
for ( int i = 0 ; i < n ; + + i ) {
buffer [ i ] = vmin + i * step ;
}
}
2020-08-16 19:46:59 -04:00
2020-08-16 16:38:51 -04:00
// Offsets and strides a data buffer
template < typename T >
inline T OffsetAndStride ( const T * data , int idx , int count , int offset , int stride ) {
idx = ImPosMod ( offset + idx , count ) ;
return * ( const T * ) ( const void * ) ( ( const unsigned char * ) data + ( size_t ) idx * stride ) ;
}
2020-09-03 00:30:32 -04:00
//-----------------------------------------------------------------------------
2020-09-05 00:30:45 -04:00
// Time Utils
2020-09-03 00:30:32 -04:00
//-----------------------------------------------------------------------------
// Returns true if year is leap year (366 days long)
inline bool IsLeapYear ( int year ) {
2020-09-09 00:47:02 -04:00
return year % 4 = = 0 & & ( year % 100 ! = 0 | | year % 400 = = 0 ) ;
2020-09-03 00:30:32 -04:00
}
2020-09-06 01:06:51 -04:00
// Returns the number of days in a month, accounting for Feb. leap years. #month is zero indexed.
2020-09-03 00:30:32 -04:00
inline int GetDaysInMonth ( int year , int month ) {
2020-09-05 00:30:45 -04:00
static const int days [ 12 ] = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ;
2020-09-08 01:56:00 -04:00
return days [ month ] + ( int ) ( month = = 1 & & IsLeapYear ( year ) ) ;
2020-09-03 00:30:32 -04:00
}
2020-09-09 00:47:02 -04:00
// Make a UNIX timestamp from a tm struct expressed in UTC time (i.e. GMT timezone).
2020-09-07 21:59:43 -04:00
IMPLOT_API ImPlotTime MkGmtTime ( struct tm * ptm ) ;
2020-09-09 00:47:02 -04:00
// Make a tm struct expressed in UTC time (i.e. GMT timezone) from a UNIX timestamp.
2020-09-07 21:59:43 -04:00
IMPLOT_API tm * GetGmtTime ( const ImPlotTime & t , tm * ptm ) ;
2020-09-06 15:48:16 -04:00
2020-09-09 00:47:02 -04:00
// Make a UNIX timestamp from a tm struct expressed in local time.
2020-09-07 21:59:43 -04:00
IMPLOT_API ImPlotTime MkLocTime ( struct tm * ptm ) ;
2020-09-09 00:47:02 -04:00
// Make a tm struct expressed in local time from a UNIX timestamp.
2020-09-07 21:59:43 -04:00
IMPLOT_API tm * GetLocTime ( const ImPlotTime & t , tm * ptm ) ;
2020-09-06 15:48:16 -04:00
2020-09-09 00:47:02 -04:00
// NB: The following functions only work if there is a current ImPlotContext because the
// internal tm struct is owned by the context! They are aware of ImPlotStyle.UseLocalTime.
// Make a timestamp from time components.
// year[1970-3000], month[0-11], day[1-31], hour[0-23], min[0-59], sec[0-59], us[0,999999]
IMPLOT_API ImPlotTime MakeTime ( int year , int month = 0 , int day = 1 , int hour = 0 , int min = 0 , int sec = 0 , int us = 0 ) ;
// Get year component from timestamp [1970-3000]
IMPLOT_API int GetYear ( const ImPlotTime & t ) ;
2020-09-06 15:48:16 -04:00
2020-09-09 10:00:50 -04:00
// Adds or subtracts time from a timestamp. #count > 0 to add, < 0 to subtract.
2020-09-07 21:59:43 -04:00
IMPLOT_API ImPlotTime AddTime ( const ImPlotTime & t , ImPlotTimeUnit unit , int count ) ;
2020-09-09 10:00:50 -04:00
// Rounds a timestamp down to nearest unit.
2020-09-07 21:59:43 -04:00
IMPLOT_API ImPlotTime FloorTime ( const ImPlotTime & t , ImPlotTimeUnit unit ) ;
2020-09-05 00:30:45 -04:00
// Rounds a timestamp up to the nearest unit.
2020-09-07 21:59:43 -04:00
IMPLOT_API ImPlotTime CeilTime ( const ImPlotTime & t , ImPlotTimeUnit unit ) ;
2020-09-05 00:30:45 -04:00
// Rounds a timestamp up or down to the nearest unit.
2020-09-07 21:59:43 -04:00
IMPLOT_API ImPlotTime RoundTime ( const ImPlotTime & t , ImPlotTimeUnit unit ) ;
2020-09-09 10:00:50 -04:00
// Combines the date of one timestamp with the time-of-day of another timestamp.
2020-09-09 20:17:19 -04:00
IMPLOT_API ImPlotTime CombineDateTime ( const ImPlotTime & date_part , const ImPlotTime & time_part ) ;
2020-09-05 00:30:45 -04:00
2020-10-14 23:07:27 -04:00
// Formats the time part of timestamp t into a buffer according to #fmt
IMPLOT_API int FormatTime ( const ImPlotTime & t , char * buffer , int size , ImPlotTimeFmt fmt , bool use_24_hr_clk ) ;
// Formats the date part of timestamp t into a buffer according to #fmt
IMPLOT_API int FormatDate ( const ImPlotTime & t , char * buffer , int size , ImPlotDateFmt fmt , bool use_iso_8601 ) ;
// Formats the time and/or date parts of a timestamp t into a buffer according to #fmt
IMPLOT_API int FormatDateTime ( const ImPlotTime & t , char * buffer , int size , ImPlotDateTimeFmt fmt ) ;
2020-09-09 00:47:02 -04:00
// Shows a date picker widget block (year/month/day).
// #level = 0 for day, 1 for month, 2 for year. Modified by user interaction.
// #t will be set when a day is clicked and the function will return true.
// #t1 and #t2 are optional dates to highlight.
IMPLOT_API bool ShowDatePicker ( const char * id , int * level , ImPlotTime * t , const ImPlotTime * t1 = NULL , const ImPlotTime * t2 = NULL ) ;
2020-10-14 23:07:27 -04:00
// Shows a time picker widget block (hour/min/sec).
2020-09-09 20:17:19 -04:00
// #t will be set when a new hour, minute, or sec is selected or am/pm is toggled, and the function will return true.
2020-10-14 23:07:27 -04:00
IMPLOT_API bool ShowTimePicker ( const char * id , ImPlotTime * t ) ;
2020-09-08 01:56:00 -04:00
2020-08-17 19:31:30 -04:00
//-----------------------------------------------------------------------------
// [SECTION] Internal / Experimental Plotters
// No guarantee of forward compatibility here!
//-----------------------------------------------------------------------------
// Plots axis-aligned, filled rectangles. Every two consecutive points defines opposite corners of a single rectangle.
2020-09-07 21:59:43 -04:00
IMPLOT_API void PlotRects ( const char * label_id , const float * xs , const float * ys , int count , int offset = 0 , int stride = sizeof ( float ) ) ;
IMPLOT_API void PlotRects ( const char * label_id , const double * xs , const double * ys , int count , int offset = 0 , int stride = sizeof ( double ) ) ;
IMPLOT_API void PlotRects ( const char * label_id , ImPlotPoint ( * getter ) ( void * data , int idx ) , void * data , int count , int offset = 0 ) ;
2020-08-17 19:31:30 -04:00
2020-09-17 18:35:14 -04:00
} // namespace ImPlot