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.
2021-03-20 22:45:31 -04:00
// ImPlot v0.10 WIP
2020-08-16 16:38:51 -04:00
# include "implot.h"
# include "implot_internal.h"
# ifdef _MSC_VER
# define sprintf sprintf_s
# endif
# define SQRT_1_2 0.70710678118f
# define SQRT_3_2 0.86602540378f
2021-03-20 22:45:31 -04:00
# define IMPLOT_NORMALIZE2F_OVER_ZERO(VX, VY) \
2020-08-16 16:38:51 -04:00
{ \
float d2 = VX * VX + VY * VY ; \
if ( d2 > 0.0f ) { \
float inv_len = 1.0f / ImSqrt ( d2 ) ; \
VX * = inv_len ; \
VY * = inv_len ; \
} \
}
2021-03-16 07:37:45 -04:00
// Support for pre-1.82 version. Users on 1.82+ can use 0 (default) flags to mean "all corners" but in order to support older versions we are more explicit.
# if (IMGUI_VERSION_NUM < 18102) && !defined(ImDrawFlags_RoundCornersAll)
# define ImDrawFlags_RoundCornersAll ImDrawCornerFlags_All
# endif
2020-08-16 16:38:51 -04:00
namespace ImPlot {
2020-08-30 12:03:25 -04:00
//-----------------------------------------------------------------------------
// Item Utils
//-----------------------------------------------------------------------------
2020-09-15 10:48:46 -04:00
ImPlotItem * RegisterOrGetItem ( const char * label_id , bool * just_created ) {
2020-08-30 12:03:25 -04:00
ImPlotContext & gp = * GImPlot ;
ImGuiID id = ImGui : : GetID ( label_id ) ;
2020-09-15 10:48:46 -04:00
if ( just_created ! = NULL )
* just_created = gp . CurrentPlot - > Items . GetByKey ( id ) = = NULL ;
2020-08-30 12:03:25 -04:00
ImPlotItem * item = gp . CurrentPlot - > Items . GetOrAddByKey ( id ) ;
if ( item - > SeenThisFrame )
return item ;
item - > SeenThisFrame = true ;
int idx = gp . CurrentPlot - > Items . GetIndex ( item ) ;
item - > ID = id ;
if ( ImGui : : FindRenderedTextEnd ( label_id , NULL ) ! = label_id ) {
2020-10-21 11:08:41 -04:00
gp . CurrentPlot - > LegendData . Indices . push_back ( idx ) ;
item - > NameOffset = gp . CurrentPlot - > LegendData . Labels . size ( ) ;
gp . CurrentPlot - > LegendData . Labels . append ( label_id , label_id + strlen ( label_id ) + 1 ) ;
2020-08-30 12:03:25 -04:00
}
else {
item - > Show = true ;
}
if ( item - > Show )
gp . VisibleItemCount + + ;
return item ;
}
ImPlotItem * GetItem ( const char * label_id ) {
ImPlotContext & gp = * GImPlot ;
ImGuiID id = ImGui : : GetID ( label_id ) ;
return gp . CurrentPlot - > Items . GetByKey ( id ) ;
}
ImPlotItem * GetCurrentItem ( ) {
ImPlotContext & gp = * GImPlot ;
return gp . CurrentItem ;
}
2020-09-07 17:08:59 -04:00
void SetNextLineStyle ( const ImVec4 & col , float weight ) {
ImPlotContext & gp = * GImPlot ;
2020-09-15 10:48:46 -04:00
gp . NextItemData . Colors [ ImPlotCol_Line ] = col ;
gp . NextItemData . LineWeight = weight ;
2020-09-07 17:08:59 -04:00
}
void SetNextFillStyle ( const ImVec4 & col , float alpha ) {
ImPlotContext & gp = * GImPlot ;
2020-09-15 10:48:46 -04:00
gp . NextItemData . Colors [ ImPlotCol_Fill ] = col ;
gp . NextItemData . FillAlpha = alpha ;
2020-09-07 17:08:59 -04:00
}
void SetNextMarkerStyle ( ImPlotMarker marker , float size , const ImVec4 & fill , float weight , const ImVec4 & outline ) {
ImPlotContext & gp = * GImPlot ;
2020-09-15 10:48:46 -04:00
gp . NextItemData . Marker = marker ;
gp . NextItemData . Colors [ ImPlotCol_MarkerFill ] = fill ;
gp . NextItemData . MarkerSize = size ;
gp . NextItemData . Colors [ ImPlotCol_MarkerOutline ] = outline ;
gp . NextItemData . MarkerWeight = weight ;
2020-09-07 17:08:59 -04:00
}
void SetNextErrorBarStyle ( const ImVec4 & col , float size , float weight ) {
ImPlotContext & gp = * GImPlot ;
2020-09-15 10:48:46 -04:00
gp . NextItemData . Colors [ ImPlotCol_ErrorBar ] = col ;
gp . NextItemData . ErrorBarSize = size ;
gp . NextItemData . ErrorBarWeight = weight ;
}
2020-09-19 21:54:19 -04:00
ImVec4 GetLastItemColor ( ) {
ImPlotContext & gp = * GImPlot ;
if ( gp . PreviousItem )
2021-03-17 08:38:45 -04:00
return ImGui : : ColorConvertU32ToFloat4 ( gp . PreviousItem - > Color ) ;
2020-09-19 21:54:19 -04:00
return ImVec4 ( ) ;
}
2020-09-15 10:48:46 -04:00
void HideNextItem ( bool hidden , ImGuiCond cond ) {
ImPlotContext & gp = * GImPlot ;
gp . NextItemData . HasHidden = true ;
gp . NextItemData . Hidden = hidden ;
gp . NextItemData . HiddenCond = cond ;
2020-09-07 17:08:59 -04:00
}
2020-08-30 12:03:25 -04:00
void BustItemCache ( ) {
ImPlotContext & gp = * GImPlot ;
for ( int p = 0 ; p < gp . Plots . GetSize ( ) ; + + p ) {
2020-09-21 08:09:14 -04:00
ImPlotPlot & plot = * gp . Plots . GetByIndex ( p ) ;
2020-08-30 12:03:25 -04:00
plot . ColormapIdx = 0 ;
plot . Items . Clear ( ) ;
2020-10-21 11:08:41 -04:00
plot . LegendData . Reset ( ) ;
2020-08-30 12:03:25 -04:00
}
}
2021-03-17 08:38:45 -04:00
void BustColorCache ( const char * plot_title_id ) {
ImPlotContext & gp = * GImPlot ;
if ( plot_title_id = = NULL ) {
BustItemCache ( ) ;
}
else {
ImPlotPlot * plot = gp . Plots . GetByKey ( ImGui : : GetCurrentWindow ( ) - > GetID ( plot_title_id ) ) ;
if ( plot = = NULL )
return ;
plot - > ColormapIdx = 0 ;
plot - > Items . Clear ( ) ;
plot - > LegendData . Reset ( ) ;
}
}
2020-09-07 17:08:59 -04:00
//-----------------------------------------------------------------------------
// Begin/EndItem
//-----------------------------------------------------------------------------
2020-08-30 12:03:25 -04:00
// Begins a new item. Returns false if the item should not be plotted.
2020-09-02 10:26:51 -04:00
bool BeginItem ( const char * label_id , ImPlotCol recolor_from ) {
2020-08-30 12:03:25 -04:00
ImPlotContext & gp = * GImPlot ;
2020-08-30 18:12:36 -04:00
IM_ASSERT_USER_ERROR ( gp . CurrentPlot ! = NULL , " PlotX() needs to be called between BeginPlot() and EndPlot()! " ) ;
2020-09-15 10:48:46 -04:00
bool just_created ;
ImPlotItem * item = RegisterOrGetItem ( label_id , & just_created ) ;
2020-09-19 21:54:19 -04:00
// set current item
gp . CurrentItem = item ;
ImPlotNextItemData & s = gp . NextItemData ;
2021-03-17 08:38:45 -04:00
// set/override item color
2020-09-19 21:54:19 -04:00
if ( recolor_from ! = - 1 ) {
if ( ! IsColorAuto ( s . Colors [ recolor_from ] ) )
2021-03-17 08:38:45 -04:00
item - > Color = ImGui : : ColorConvertFloat4ToU32 ( s . Colors [ recolor_from ] ) ;
2020-09-19 21:54:19 -04:00
else if ( ! IsColorAuto ( gp . Style . Colors [ recolor_from ] ) )
2021-03-17 08:38:45 -04:00
item - > Color = ImGui : : ColorConvertFloat4ToU32 ( gp . Style . Colors [ recolor_from ] ) ;
else if ( just_created )
item - > Color = NextColormapColorU32 ( ) ;
}
else if ( just_created ) {
item - > Color = NextColormapColorU32 ( ) ;
2020-09-19 21:54:19 -04:00
}
2020-09-15 10:48:46 -04:00
// hide/show item
if ( gp . NextItemData . HasHidden ) {
if ( just_created | | gp . NextItemData . HiddenCond = = ImGuiCond_Always )
item - > Show = ! gp . NextItemData . Hidden ;
}
2020-08-30 12:03:25 -04:00
if ( ! item - > Show ) {
// reset next item data
2020-11-15 22:47:06 -05:00
gp . NextItemData . Reset ( ) ;
2020-09-19 21:54:19 -04:00
gp . PreviousItem = item ;
gp . CurrentItem = NULL ;
2020-08-30 12:03:25 -04:00
return false ;
}
else {
2021-03-17 08:38:45 -04:00
ImVec4 item_color = ImGui : : ColorConvertU32ToFloat4 ( item - > Color ) ;
2020-08-30 18:12:36 -04:00
// stage next item colors
2021-03-17 08:38:45 -04:00
s . Colors [ ImPlotCol_Line ] = IsColorAuto ( s . Colors [ ImPlotCol_Line ] ) ? ( IsColorAuto ( ImPlotCol_Line ) ? item_color : gp . Style . Colors [ ImPlotCol_Line ] ) : s . Colors [ ImPlotCol_Line ] ;
s . Colors [ ImPlotCol_Fill ] = IsColorAuto ( s . Colors [ ImPlotCol_Fill ] ) ? ( IsColorAuto ( ImPlotCol_Fill ) ? item_color : gp . Style . Colors [ ImPlotCol_Fill ] ) : s . Colors [ ImPlotCol_Fill ] ;
2020-08-30 22:03:11 -04:00
s . Colors [ ImPlotCol_MarkerOutline ] = IsColorAuto ( s . Colors [ ImPlotCol_MarkerOutline ] ) ? ( IsColorAuto ( ImPlotCol_MarkerOutline ) ? s . Colors [ ImPlotCol_Line ] : gp . Style . Colors [ ImPlotCol_MarkerOutline ] ) : s . Colors [ ImPlotCol_MarkerOutline ] ;
s . Colors [ ImPlotCol_MarkerFill ] = IsColorAuto ( s . Colors [ ImPlotCol_MarkerFill ] ) ? ( IsColorAuto ( ImPlotCol_MarkerFill ) ? s . Colors [ ImPlotCol_Line ] : gp . Style . Colors [ ImPlotCol_MarkerFill ] ) : s . Colors [ ImPlotCol_MarkerFill ] ;
s . Colors [ ImPlotCol_ErrorBar ] = IsColorAuto ( s . Colors [ ImPlotCol_ErrorBar ] ) ? ( GetStyleColorVec4 ( ImPlotCol_ErrorBar ) ) : s . Colors [ ImPlotCol_ErrorBar ] ;
2020-08-30 18:12:36 -04:00
// stage next item style vars
s . LineWeight = s . LineWeight < 0 ? gp . Style . LineWeight : s . LineWeight ;
s . Marker = s . Marker < 0 ? gp . Style . Marker : s . Marker ;
s . MarkerSize = s . MarkerSize < 0 ? gp . Style . MarkerSize : s . MarkerSize ;
2020-09-01 00:23:48 -04:00
s . MarkerWeight = s . MarkerWeight < 0 ? gp . Style . MarkerWeight : s . MarkerWeight ;
s . FillAlpha = s . FillAlpha < 0 ? gp . Style . FillAlpha : s . FillAlpha ;
s . ErrorBarSize = s . ErrorBarSize < 0 ? gp . Style . ErrorBarSize : s . ErrorBarSize ;
2020-08-30 18:12:36 -04:00
s . ErrorBarWeight = s . ErrorBarWeight < 0 ? gp . Style . ErrorBarWeight : s . ErrorBarWeight ;
s . DigitalBitHeight = s . DigitalBitHeight < 0 ? gp . Style . DigitalBitHeight : s . DigitalBitHeight ;
2020-09-01 00:23:48 -04:00
s . DigitalBitGap = s . DigitalBitGap < 0 ? gp . Style . DigitalBitGap : s . DigitalBitGap ;
2020-08-30 18:12:36 -04:00
// apply alpha modifier(s)
s . Colors [ ImPlotCol_Fill ] . w * = s . FillAlpha ;
2020-09-01 00:23:48 -04:00
// s.Colors[ImPlotCol_MarkerFill].w *= s.FillAlpha; // TODO: this should be separate, if it at all
2020-08-30 18:12:36 -04:00
// apply highlight mods
2020-09-06 01:42:03 -04:00
if ( item - > LegendHovered & & ! ImHasFlag ( gp . CurrentPlot - > Flags , ImPlotFlags_NoHighlight ) ) {
2020-08-30 22:03:11 -04:00
s . LineWeight * = 2 ;
s . MarkerWeight * = 2 ;
2020-09-01 00:23:48 -04:00
// TODO: highlight fills?
2020-08-30 18:12:36 -04:00
}
// set render flags
s . RenderLine = s . Colors [ ImPlotCol_Line ] . w > 0 & & s . LineWeight > 0 ;
s . RenderFill = s . Colors [ ImPlotCol_Fill ] . w > 0 ;
s . RenderMarkerLine = s . Colors [ ImPlotCol_MarkerOutline ] . w > 0 & & s . MarkerWeight > 0 ;
s . RenderMarkerFill = s . Colors [ ImPlotCol_MarkerFill ] . w > 0 ;
// push rendering clip rect
PushPlotClipRect ( ) ;
2020-08-30 12:03:25 -04:00
return true ;
}
}
// Ends an item (call only if BeginItem returns true)
2020-09-02 10:26:51 -04:00
void EndItem ( ) {
2020-08-30 12:03:25 -04:00
ImPlotContext & gp = * GImPlot ;
2020-08-30 18:12:36 -04:00
// pop rendering clip rect
PopPlotClipRect ( ) ;
2020-08-30 12:03:25 -04:00
// reset next item data
2020-11-15 22:47:06 -05:00
gp . NextItemData . Reset ( ) ;
2020-08-30 12:03:25 -04:00
// set current item
2020-09-19 21:54:19 -04:00
gp . PreviousItem = gp . CurrentItem ;
gp . CurrentItem = NULL ;
2020-08-30 12:03:25 -04:00
}
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
// GETTERS
//-----------------------------------------------------------------------------
2020-08-17 19:31:30 -04:00
// Getters can be thought of as iterators that convert user data (e.g. raw arrays)
// to ImPlotPoints
// Interprets an array of Y points as ImPlotPoints where the X value is the index
2020-08-16 16:38:51 -04:00
template < typename T >
struct GetterYs {
2020-09-10 00:29:29 -04:00
GetterYs ( const T * ys , int count , double xscale , double x0 , int offset , int stride ) :
2020-09-15 10:48:46 -04:00
Ys ( ys ) ,
Count ( count ) ,
XScale ( xscale ) ,
X0 ( x0 ) ,
Offset ( count ? ImPosMod ( offset , count ) : 0 ) ,
Stride ( stride )
2020-09-10 00:29:29 -04:00
{ }
2020-09-15 09:56:58 -04:00
inline ImPlotPoint operator ( ) ( int idx ) const {
return ImPlotPoint ( X0 + XScale * idx , ( double ) OffsetAndStride ( Ys , idx , Count , Offset , Stride ) ) ;
}
2020-09-10 00:29:29 -04:00
const T * const Ys ;
const int Count ;
const double XScale ;
const double X0 ;
const int Offset ;
const int Stride ;
2020-08-16 16:38:51 -04:00
} ;
2020-08-17 19:31:30 -04:00
// Interprets separate arrays for X and Y points as ImPlotPoints
2020-08-16 16:38:51 -04:00
template < typename T >
struct GetterXsYs {
2020-09-15 09:56:58 -04:00
GetterXsYs ( const T * xs , const T * ys , int count , int offset , int stride ) :
2020-09-15 10:48:46 -04:00
Xs ( xs ) ,
Ys ( ys ) ,
Count ( count ) ,
Offset ( count ? ImPosMod ( offset , count ) : 0 ) ,
2020-09-15 09:56:58 -04:00
Stride ( stride )
{ }
2020-09-07 17:08:59 -04:00
inline ImPlotPoint operator ( ) ( int idx ) const {
2020-08-31 12:38:37 -04:00
return ImPlotPoint ( ( double ) OffsetAndStride ( Xs , idx , Count , Offset , Stride ) , ( double ) OffsetAndStride ( Ys , idx , Count , Offset , Stride ) ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-15 09:56:58 -04:00
const T * const Xs ;
const T * const Ys ;
const int Count ;
const int Offset ;
const int Stride ;
2020-08-16 16:38:51 -04:00
} ;
2020-08-21 00:01:21 -04:00
// Always returns a constant Y reference value where the X value is the index
struct GetterYRef {
2020-09-15 10:48:46 -04:00
GetterYRef ( double y_ref , int count , double xscale , double x0 ) :
YRef ( y_ref ) ,
Count ( count ) ,
XScale ( xscale ) ,
X0 ( x0 )
2020-09-15 09:56:58 -04:00
{ }
2020-09-07 17:08:59 -04:00
inline ImPlotPoint operator ( ) ( int idx ) const {
2020-09-10 16:59:08 -04:00
return ImPlotPoint ( X0 + XScale * idx , YRef ) ;
2020-08-21 00:01:21 -04:00
}
2020-09-10 16:59:08 -04:00
const double YRef ;
const int Count ;
const double XScale ;
const double X0 ;
2020-08-21 00:01:21 -04:00
} ;
// Interprets an array of X points as ImPlotPoints where the Y value is a constant reference value
2020-09-15 09:56:58 -04:00
template < typename T >
2020-08-16 16:38:51 -04:00
struct GetterXsYRef {
2020-09-15 09:56:58 -04:00
GetterXsYRef ( const T * xs , double y_ref , int count , int offset , int stride ) :
2020-09-15 10:48:46 -04:00
Xs ( xs ) ,
YRef ( y_ref ) ,
Count ( count ) ,
Offset ( count ? ImPosMod ( offset , count ) : 0 ) ,
Stride ( stride )
2020-09-15 09:56:58 -04:00
{ }
2020-09-07 17:08:59 -04:00
inline ImPlotPoint operator ( ) ( int idx ) const {
2020-09-15 09:56:58 -04:00
return ImPlotPoint ( ( double ) OffsetAndStride ( Xs , idx , Count , Offset , Stride ) , YRef ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-15 09:56:58 -04:00
const T * const Xs ;
const double YRef ;
const int Count ;
const int Offset ;
const int Stride ;
2020-08-16 16:38:51 -04:00
} ;
2021-01-15 02:52:37 -05:00
// Interprets an array of Y points as ImPlotPoints where the X value is a constant reference value
template < typename T >
struct GetterXRefYs {
GetterXRefYs ( double x_ref , const T * ys , int count , int offset , int stride ) :
XRef ( x_ref ) ,
Ys ( ys ) ,
Count ( count ) ,
Offset ( count ? ImPosMod ( offset , count ) : 0 ) ,
Stride ( stride )
{ }
inline ImPlotPoint operator ( ) ( int idx ) const {
return ImPlotPoint ( XRef , ( double ) OffsetAndStride ( Ys , idx , Count , Offset , Stride ) ) ;
}
const double XRef ;
const T * const Ys ;
const int Count ;
const int Offset ;
const int Stride ;
} ;
2020-08-17 19:31:30 -04:00
/// Interprets a user's function pointer as ImPlotPoints
2020-09-15 09:56:58 -04:00
struct GetterFuncPtr {
GetterFuncPtr ( ImPlotPoint ( * getter ) ( void * data , int idx ) , void * data , int count , int offset ) :
Getter ( getter ) ,
Data ( data ) ,
Count ( count ) ,
Offset ( count ? ImPosMod ( offset , count ) : 0 )
{ }
2020-09-07 17:08:59 -04:00
inline ImPlotPoint operator ( ) ( int idx ) const {
2020-08-22 01:35:41 -04:00
idx = ImPosMod ( Offset + idx , Count ) ;
2020-09-15 09:56:58 -04:00
return Getter ( Data , idx ) ;
2020-08-22 01:35:41 -04:00
}
2020-09-15 09:56:58 -04:00
ImPlotPoint ( * const Getter ) ( void * data , int idx ) ;
void * const Data ;
const int Count ;
const int Offset ;
2020-08-16 16:38:51 -04:00
} ;
template < typename T >
struct GetterBarV {
2020-09-07 01:16:47 -04:00
const T * Ys ; double XShift ; int Count ; int Offset ; int Stride ;
GetterBarV ( const T * ys , double xshift , int count , int offset , int stride ) { Ys = ys ; XShift = xshift ; Count = count ; Offset = offset ; Stride = stride ; }
2020-09-07 17:08:59 -04:00
inline ImPlotPoint operator ( ) ( int idx ) const { return ImPlotPoint ( ( double ) idx + ( double ) XShift , ( double ) OffsetAndStride ( Ys , idx , Count , Offset , Stride ) ) ; }
2020-08-16 16:38:51 -04:00
} ;
template < typename T >
struct GetterBarH {
2020-09-07 01:16:47 -04:00
const T * Xs ; double YShift ; int Count ; int Offset ; int Stride ;
GetterBarH ( const T * xs , double yshift , int count , int offset , int stride ) { Xs = xs ; YShift = yshift ; Count = count ; Offset = offset ; Stride = stride ; }
2020-09-07 17:08:59 -04:00
inline ImPlotPoint operator ( ) ( int idx ) const { return ImPlotPoint ( ( double ) OffsetAndStride ( Xs , idx , Count , Offset , Stride ) , ( double ) idx + ( double ) YShift ) ; }
2020-08-16 16:38:51 -04:00
} ;
template < typename T >
struct GetterError {
2020-09-15 09:56:58 -04:00
GetterError ( const T * xs , const T * ys , const T * neg , const T * pos , int count , int offset , int stride ) :
Xs ( xs ) ,
Ys ( ys ) ,
Neg ( neg ) ,
Pos ( pos ) ,
Count ( count ) ,
Offset ( count ? ImPosMod ( offset , count ) : 0 ) ,
Stride ( stride )
{ }
inline ImPlotPointError operator ( ) ( int idx ) const {
2020-08-31 12:38:37 -04:00
return ImPlotPointError ( ( double ) OffsetAndStride ( Xs , idx , Count , Offset , Stride ) ,
( double ) OffsetAndStride ( Ys , idx , Count , Offset , Stride ) ,
( double ) OffsetAndStride ( Neg , idx , Count , Offset , Stride ) ,
( double ) OffsetAndStride ( Pos , idx , Count , Offset , Stride ) ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-15 10:48:46 -04:00
const T * const Xs ;
const T * const Ys ;
const T * const Neg ;
const T * const Pos ;
const int Count ;
const int Offset ;
2020-09-15 09:56:58 -04:00
const int Stride ;
2020-08-16 16:38:51 -04:00
} ;
//-----------------------------------------------------------------------------
// TRANSFORMERS
//-----------------------------------------------------------------------------
2020-08-17 19:31:30 -04:00
// Transforms convert points in plot space (i.e. ImPlotPoint) to pixel space (i.e. ImVec2)
// Transforms points for linear x and linear y space
2020-08-16 16:38:51 -04:00
struct TransformerLinLin {
2020-08-30 12:03:25 -04:00
TransformerLinLin ( ) : YAxis ( GetCurrentYAxis ( ) ) { }
2020-09-07 17:08:59 -04:00
// inline ImVec2 operator()(const ImPlotPoint& plt) const { return (*this)(plt.x, plt.y); }
inline ImVec2 operator ( ) ( const ImPlotPoint & plt ) const {
2020-08-16 16:38:51 -04:00
ImPlotContext & gp = * GImPlot ;
2020-09-07 17:08:59 -04:00
return ImVec2 ( ( float ) ( gp . PixelRange [ YAxis ] . Min . x + gp . Mx * ( plt . x - gp . CurrentPlot - > XAxis . Range . Min ) ) ,
( float ) ( gp . PixelRange [ YAxis ] . Min . y + gp . My [ YAxis ] * ( plt . y - gp . CurrentPlot - > YAxis [ YAxis ] . Range . Min ) ) ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-07 17:08:59 -04:00
const int YAxis ;
2020-08-16 16:38:51 -04:00
} ;
2020-08-17 19:31:30 -04:00
// Transforms points for log x and linear y space
2020-08-16 16:38:51 -04:00
struct TransformerLogLin {
2020-08-30 12:03:25 -04:00
TransformerLogLin ( ) : YAxis ( GetCurrentYAxis ( ) ) { }
2020-09-07 21:59:43 -04:00
inline ImVec2 operator ( ) ( const ImPlotPoint & plt ) const {
2020-08-16 16:38:51 -04:00
ImPlotContext & gp = * GImPlot ;
2020-09-07 17:08:59 -04:00
double t = ImLog10 ( plt . x / gp . CurrentPlot - > XAxis . Range . Min ) / gp . LogDenX ;
double x = ImLerp ( gp . CurrentPlot - > XAxis . Range . Min , gp . CurrentPlot - > XAxis . Range . Max , ( float ) t ) ;
2020-08-16 16:38:51 -04:00
return ImVec2 ( ( float ) ( gp . PixelRange [ YAxis ] . Min . x + gp . Mx * ( x - gp . CurrentPlot - > XAxis . Range . Min ) ) ,
2020-09-07 17:08:59 -04:00
( float ) ( gp . PixelRange [ YAxis ] . Min . y + gp . My [ YAxis ] * ( plt . y - gp . CurrentPlot - > YAxis [ YAxis ] . Range . Min ) ) ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-07 17:08:59 -04:00
const int YAxis ;
2020-08-16 16:38:51 -04:00
} ;
2020-08-17 19:31:30 -04:00
// Transforms points for linear x and log y space
2020-08-16 16:38:51 -04:00
struct TransformerLinLog {
2020-08-30 12:03:25 -04:00
TransformerLinLog ( ) : YAxis ( GetCurrentYAxis ( ) ) { }
2020-09-07 17:08:59 -04:00
inline ImVec2 operator ( ) ( const ImPlotPoint & plt ) const {
2020-08-16 16:38:51 -04:00
ImPlotContext & gp = * GImPlot ;
2020-09-07 17:08:59 -04:00
double t = ImLog10 ( plt . y / gp . CurrentPlot - > YAxis [ YAxis ] . Range . Min ) / gp . LogDenY [ YAxis ] ;
double y = ImLerp ( gp . CurrentPlot - > YAxis [ YAxis ] . Range . Min , gp . CurrentPlot - > YAxis [ YAxis ] . Range . Max , ( float ) t ) ;
return ImVec2 ( ( float ) ( gp . PixelRange [ YAxis ] . Min . x + gp . Mx * ( plt . x - gp . CurrentPlot - > XAxis . Range . Min ) ) ,
2020-08-16 16:38:51 -04:00
( float ) ( gp . PixelRange [ YAxis ] . Min . y + gp . My [ YAxis ] * ( y - gp . CurrentPlot - > YAxis [ YAxis ] . Range . Min ) ) ) ;
}
2020-09-07 17:08:59 -04:00
const int YAxis ;
2020-08-16 16:38:51 -04:00
} ;
2020-08-17 19:31:30 -04:00
// Transforms points for log x and log y space
2020-08-16 16:38:51 -04:00
struct TransformerLogLog {
2020-08-30 12:03:25 -04:00
TransformerLogLog ( ) : YAxis ( GetCurrentYAxis ( ) ) { }
2020-09-07 17:08:59 -04:00
inline ImVec2 operator ( ) ( const ImPlotPoint & plt ) const {
2020-08-16 16:38:51 -04:00
ImPlotContext & gp = * GImPlot ;
2020-09-07 17:08:59 -04:00
double t = ImLog10 ( plt . x / gp . CurrentPlot - > XAxis . Range . Min ) / gp . LogDenX ;
double x = ImLerp ( gp . CurrentPlot - > XAxis . Range . Min , gp . CurrentPlot - > XAxis . Range . Max , ( float ) t ) ;
t = ImLog10 ( plt . y / gp . CurrentPlot - > YAxis [ YAxis ] . Range . Min ) / gp . LogDenY [ YAxis ] ;
double y = ImLerp ( gp . CurrentPlot - > YAxis [ YAxis ] . Range . Min , gp . CurrentPlot - > YAxis [ YAxis ] . Range . Max , ( float ) t ) ;
2020-08-16 16:38:51 -04:00
return ImVec2 ( ( float ) ( gp . PixelRange [ YAxis ] . Min . x + gp . Mx * ( x - gp . CurrentPlot - > XAxis . Range . Min ) ) ,
( float ) ( gp . PixelRange [ YAxis ] . Min . y + gp . My [ YAxis ] * ( y - gp . CurrentPlot - > YAxis [ YAxis ] . Range . Min ) ) ) ;
}
2020-09-07 17:08:59 -04:00
const int YAxis ;
2020-08-16 16:38:51 -04:00
} ;
//-----------------------------------------------------------------------------
2020-08-17 19:31:30 -04:00
// PRIMITIVE RENDERERS
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-09-02 10:17:18 -04:00
inline void AddLine ( const ImVec2 & P1 , const ImVec2 & P2 , float weight , ImU32 col , ImDrawList & DrawList , ImVec2 uv ) {
float dx = P2 . x - P1 . x ;
float dy = P2 . y - P1 . y ;
2020-11-10 08:42:51 -05:00
IMPLOT_NORMALIZE2F_OVER_ZERO ( dx , dy ) ;
2020-09-02 10:17:18 -04:00
dx * = ( weight * 0.5f ) ;
dy * = ( weight * 0.5f ) ;
DrawList . _VtxWritePtr [ 0 ] . pos . x = P1 . x + dy ;
DrawList . _VtxWritePtr [ 0 ] . pos . y = P1 . y - dx ;
DrawList . _VtxWritePtr [ 0 ] . uv = uv ;
DrawList . _VtxWritePtr [ 0 ] . col = col ;
DrawList . _VtxWritePtr [ 1 ] . pos . x = P2 . x + dy ;
DrawList . _VtxWritePtr [ 1 ] . pos . y = P2 . y - dx ;
DrawList . _VtxWritePtr [ 1 ] . uv = uv ;
DrawList . _VtxWritePtr [ 1 ] . col = col ;
DrawList . _VtxWritePtr [ 2 ] . pos . x = P2 . x - dy ;
DrawList . _VtxWritePtr [ 2 ] . pos . y = P2 . y + dx ;
DrawList . _VtxWritePtr [ 2 ] . uv = uv ;
DrawList . _VtxWritePtr [ 2 ] . col = col ;
DrawList . _VtxWritePtr [ 3 ] . pos . x = P1 . x - dy ;
DrawList . _VtxWritePtr [ 3 ] . pos . y = P1 . y + dx ;
DrawList . _VtxWritePtr [ 3 ] . uv = uv ;
DrawList . _VtxWritePtr [ 3 ] . col = col ;
DrawList . _VtxWritePtr + = 4 ;
DrawList . _IdxWritePtr [ 0 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx ) ;
DrawList . _IdxWritePtr [ 1 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 1 ) ;
DrawList . _IdxWritePtr [ 2 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 2 ) ;
DrawList . _IdxWritePtr [ 3 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx ) ;
DrawList . _IdxWritePtr [ 4 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 2 ) ;
DrawList . _IdxWritePtr [ 5 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 3 ) ;
DrawList . _IdxWritePtr + = 6 ;
DrawList . _VtxCurrentIdx + = 4 ;
}
2020-10-19 11:00:03 -04:00
inline void AddRectFilled ( const ImVec2 & Pmin , const ImVec2 & Pmax , ImU32 col , ImDrawList & DrawList , ImVec2 uv ) {
DrawList . _VtxWritePtr [ 0 ] . pos = Pmin ;
DrawList . _VtxWritePtr [ 0 ] . uv = uv ;
DrawList . _VtxWritePtr [ 0 ] . col = col ;
DrawList . _VtxWritePtr [ 1 ] . pos = Pmax ;
DrawList . _VtxWritePtr [ 1 ] . uv = uv ;
DrawList . _VtxWritePtr [ 1 ] . col = col ;
DrawList . _VtxWritePtr [ 2 ] . pos . x = Pmin . x ;
DrawList . _VtxWritePtr [ 2 ] . pos . y = Pmax . y ;
DrawList . _VtxWritePtr [ 2 ] . uv = uv ;
DrawList . _VtxWritePtr [ 2 ] . col = col ;
DrawList . _VtxWritePtr [ 3 ] . pos . x = Pmax . x ;
DrawList . _VtxWritePtr [ 3 ] . pos . y = Pmin . y ;
DrawList . _VtxWritePtr [ 3 ] . uv = uv ;
DrawList . _VtxWritePtr [ 3 ] . col = col ;
DrawList . _VtxWritePtr + = 4 ;
DrawList . _IdxWritePtr [ 0 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx ) ;
DrawList . _IdxWritePtr [ 1 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 1 ) ;
DrawList . _IdxWritePtr [ 2 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 2 ) ;
DrawList . _IdxWritePtr [ 3 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx ) ;
DrawList . _IdxWritePtr [ 4 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 1 ) ;
DrawList . _IdxWritePtr [ 5 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 3 ) ;
DrawList . _IdxWritePtr + = 6 ;
DrawList . _VtxCurrentIdx + = 4 ;
}
2020-08-17 17:26:45 -04:00
template < typename TGetter , typename TTransformer >
2020-09-02 10:17:18 -04:00
struct LineStripRenderer {
2020-09-07 17:08:59 -04:00
inline LineStripRenderer ( const TGetter & getter , const TTransformer & transformer , ImU32 col , float weight ) :
2020-08-17 17:26:45 -04:00
Getter ( getter ) ,
2020-09-07 17:08:59 -04:00
Transformer ( transformer ) ,
Prims ( Getter . Count - 1 ) ,
Col ( col ) ,
Weight ( weight )
2020-09-07 21:59:43 -04:00
{
2020-08-17 17:26:45 -04:00
P1 = Transformer ( Getter ( 0 ) ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-07 17:08:59 -04:00
inline bool operator ( ) ( ImDrawList & DrawList , const ImRect & cull_rect , const ImVec2 & uv , int prim ) const {
2020-08-17 17:26:45 -04:00
ImVec2 P2 = Transformer ( Getter ( prim + 1 ) ) ;
2020-09-02 10:17:18 -04:00
if ( ! cull_rect . Overlaps ( ImRect ( ImMin ( P1 , P2 ) , ImMax ( P1 , P2 ) ) ) ) {
2020-08-17 17:26:45 -04:00
P1 = P2 ;
2020-08-16 16:38:51 -04:00
return false ;
}
2020-09-02 10:17:18 -04:00
AddLine ( P1 , P2 , Weight , Col , DrawList , uv ) ;
2020-08-17 17:26:45 -04:00
P1 = P2 ;
2020-08-16 16:38:51 -04:00
return true ;
}
2020-09-07 17:08:59 -04:00
const TGetter & Getter ;
const TTransformer & Transformer ;
const int Prims ;
const ImU32 Col ;
const float Weight ;
mutable ImVec2 P1 ;
2020-08-16 16:38:51 -04:00
static const int IdxConsumed = 6 ;
static const int VtxConsumed = 4 ;
} ;
2020-10-19 11:00:03 -04:00
template < typename TGetter , typename TTransformer >
struct StairsRenderer {
inline StairsRenderer ( const TGetter & getter , const TTransformer & transformer , ImU32 col , float weight ) :
Getter ( getter ) ,
Transformer ( transformer ) ,
Prims ( Getter . Count - 1 ) ,
Col ( col ) ,
HalfWeight ( weight * 0.5f )
{
P1 = Transformer ( Getter ( 0 ) ) ;
}
inline bool operator ( ) ( ImDrawList & DrawList , const ImRect & cull_rect , const ImVec2 & uv , int prim ) const {
ImVec2 P2 = Transformer ( Getter ( prim + 1 ) ) ;
if ( ! cull_rect . Overlaps ( ImRect ( ImMin ( P1 , P2 ) , ImMax ( P1 , P2 ) ) ) ) {
P1 = P2 ;
return false ;
}
AddRectFilled ( ImVec2 ( P1 . x , P1 . y + HalfWeight ) , ImVec2 ( P2 . x , P1 . y - HalfWeight ) , Col , DrawList , uv ) ;
AddRectFilled ( ImVec2 ( P2 . x - HalfWeight , P2 . y ) , ImVec2 ( P2 . x + HalfWeight , P1 . y ) , Col , DrawList , uv ) ;
// AddLine(P1, P12, Weight, Col, DrawList, uv);
// AddLine(P12, P2, Weight, Col, DrawList, uv);
P1 = P2 ;
return true ;
}
const TGetter & Getter ;
const TTransformer & Transformer ;
const int Prims ;
const ImU32 Col ;
const float HalfWeight ;
mutable ImVec2 P1 ;
static const int IdxConsumed = 12 ;
static const int VtxConsumed = 8 ;
} ;
2020-09-02 10:17:18 -04:00
template < typename TGetter1 , typename TGetter2 , typename TTransformer >
struct LineSegmentsRenderer {
2020-09-07 17:08:59 -04:00
inline LineSegmentsRenderer ( const TGetter1 & getter1 , const TGetter2 & getter2 , const TTransformer & transformer , ImU32 col , float weight ) :
2020-09-02 10:17:18 -04:00
Getter1 ( getter1 ) ,
Getter2 ( getter2 ) ,
2020-09-07 17:08:59 -04:00
Transformer ( transformer ) ,
Prims ( ImMin ( Getter1 . Count , Getter2 . Count ) ) ,
Col ( col ) ,
Weight ( weight )
{ }
inline bool operator ( ) ( ImDrawList & DrawList , const ImRect & cull_rect , const ImVec2 & uv , int prim ) const {
2020-09-02 10:17:18 -04:00
ImVec2 P1 = Transformer ( Getter1 ( prim ) ) ;
ImVec2 P2 = Transformer ( Getter2 ( prim ) ) ;
if ( ! cull_rect . Overlaps ( ImRect ( ImMin ( P1 , P2 ) , ImMax ( P1 , P2 ) ) ) )
return false ;
AddLine ( P1 , P2 , Weight , Col , DrawList , uv ) ;
return true ;
}
2020-09-07 17:08:59 -04:00
const TGetter1 & Getter1 ;
const TGetter2 & Getter2 ;
const TTransformer & Transformer ;
const int Prims ;
const ImU32 Col ;
const float Weight ;
2020-09-02 10:17:18 -04:00
static const int IdxConsumed = 6 ;
static const int VtxConsumed = 4 ;
} ;
2020-08-17 17:26:45 -04:00
template < typename TGetter1 , typename TGetter2 , typename TTransformer >
2020-08-16 16:38:51 -04:00
struct ShadedRenderer {
2020-09-07 17:08:59 -04:00
ShadedRenderer ( const TGetter1 & getter1 , const TGetter2 & getter2 , const TTransformer & transformer , ImU32 col ) :
2020-08-17 17:26:45 -04:00
Getter1 ( getter1 ) ,
Getter2 ( getter2 ) ,
Transformer ( transformer ) ,
2020-09-07 17:08:59 -04:00
Prims ( ImMin ( Getter1 . Count , Getter2 . Count ) - 1 ) ,
2020-08-16 16:38:51 -04:00
Col ( col )
{
2020-08-17 17:26:45 -04:00
P11 = Transformer ( Getter1 ( 0 ) ) ;
P12 = Transformer ( Getter2 ( 0 ) ) ;
2020-08-16 16:38:51 -04:00
}
2021-03-20 23:22:18 -04:00
inline bool operator ( ) ( ImDrawList & DrawList , const ImRect & cull_rect , const ImVec2 & uv , int prim ) const {
2020-08-17 17:26:45 -04:00
ImVec2 P21 = Transformer ( Getter1 ( prim + 1 ) ) ;
ImVec2 P22 = Transformer ( Getter2 ( prim + 1 ) ) ;
2021-03-20 23:22:18 -04:00
ImRect rect ( ImMin ( ImMin ( ImMin ( P11 , P12 ) , P21 ) , P22 ) , ImMax ( ImMax ( ImMax ( P11 , P12 ) , P21 ) , P22 ) ) ;
if ( ! cull_rect . Overlaps ( rect ) ) {
P11 = P21 ;
P12 = P22 ;
return false ;
}
2020-08-17 17:26:45 -04:00
const int intersect = ( P11 . y > P12 . y & & P22 . y > P21 . y ) | | ( P12 . y > P11 . y & & P21 . y > P22 . y ) ;
ImVec2 intersection = Intersection ( P11 , P21 , P12 , P22 ) ;
DrawList . _VtxWritePtr [ 0 ] . pos = P11 ;
2020-08-16 16:38:51 -04:00
DrawList . _VtxWritePtr [ 0 ] . uv = uv ;
DrawList . _VtxWritePtr [ 0 ] . col = Col ;
2020-08-17 17:26:45 -04:00
DrawList . _VtxWritePtr [ 1 ] . pos = P21 ;
2020-08-16 16:38:51 -04:00
DrawList . _VtxWritePtr [ 1 ] . uv = uv ;
DrawList . _VtxWritePtr [ 1 ] . col = Col ;
DrawList . _VtxWritePtr [ 2 ] . pos = intersection ;
DrawList . _VtxWritePtr [ 2 ] . uv = uv ;
DrawList . _VtxWritePtr [ 2 ] . col = Col ;
2020-08-17 17:26:45 -04:00
DrawList . _VtxWritePtr [ 3 ] . pos = P12 ;
2020-08-16 16:38:51 -04:00
DrawList . _VtxWritePtr [ 3 ] . uv = uv ;
DrawList . _VtxWritePtr [ 3 ] . col = Col ;
2020-08-17 17:26:45 -04:00
DrawList . _VtxWritePtr [ 4 ] . pos = P22 ;
2020-08-16 16:38:51 -04:00
DrawList . _VtxWritePtr [ 4 ] . uv = uv ;
DrawList . _VtxWritePtr [ 4 ] . col = Col ;
DrawList . _VtxWritePtr + = 5 ;
DrawList . _IdxWritePtr [ 0 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx ) ;
DrawList . _IdxWritePtr [ 1 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 1 + intersect ) ;
DrawList . _IdxWritePtr [ 2 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 3 ) ;
DrawList . _IdxWritePtr [ 3 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 1 ) ;
DrawList . _IdxWritePtr [ 4 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 3 - intersect ) ;
DrawList . _IdxWritePtr [ 5 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 4 ) ;
DrawList . _IdxWritePtr + = 6 ;
DrawList . _VtxCurrentIdx + = 5 ;
2020-08-17 17:26:45 -04:00
P11 = P21 ;
P12 = P22 ;
2020-08-16 16:38:51 -04:00
return true ;
}
2020-09-07 17:08:59 -04:00
const TGetter1 & Getter1 ;
const TGetter2 & Getter2 ;
const TTransformer & Transformer ;
const int Prims ;
const ImU32 Col ;
mutable ImVec2 P11 ;
mutable ImVec2 P12 ;
2020-08-16 16:38:51 -04:00
static const int IdxConsumed = 6 ;
static const int VtxConsumed = 5 ;
} ;
2020-08-17 19:31:30 -04:00
// Stupid way of calculating maximum index size of ImDrawIdx without integer overflow issues
template < typename T >
struct MaxIdx { static const unsigned int Value ; } ;
template < > const unsigned int MaxIdx < unsigned short > : : Value = 65535 ;
template < > const unsigned int MaxIdx < unsigned int > : : Value = 4294967295 ;
/// Renders primitive shapes in bulk as efficiently as possible.
template < typename Renderer >
2020-09-07 17:08:59 -04:00
inline void RenderPrimitives ( const Renderer & renderer , ImDrawList & DrawList , const ImRect & cull_rect ) {
2020-08-17 19:31:30 -04:00
unsigned int prims = renderer . Prims ;
unsigned int prims_culled = 0 ;
unsigned int idx = 0 ;
const ImVec2 uv = DrawList . _Data - > TexUvWhitePixel ;
while ( prims ) {
// find how many can be reserved up to end of current draw command's limit
unsigned int cnt = ImMin ( prims , ( MaxIdx < ImDrawIdx > : : Value - DrawList . _VtxCurrentIdx ) / Renderer : : VtxConsumed ) ;
// make sure at least this many elements can be rendered to avoid situations where at the end of buffer this slow path is not taken all the time
if ( cnt > = ImMin ( 64u , prims ) ) {
if ( prims_culled > = cnt )
prims_culled - = cnt ; // reuse previous reservation
else {
DrawList . PrimReserve ( ( cnt - prims_culled ) * Renderer : : IdxConsumed , ( cnt - prims_culled ) * Renderer : : VtxConsumed ) ; // add more elements to previous reservation
prims_culled = 0 ;
}
}
else
{
if ( prims_culled > 0 ) {
DrawList . PrimUnreserve ( prims_culled * Renderer : : IdxConsumed , prims_culled * Renderer : : VtxConsumed ) ;
prims_culled = 0 ;
}
cnt = ImMin ( prims , ( MaxIdx < ImDrawIdx > : : Value - 0 /*DrawList._VtxCurrentIdx*/ ) / Renderer : : VtxConsumed ) ;
DrawList . PrimReserve ( cnt * Renderer : : IdxConsumed , cnt * Renderer : : VtxConsumed ) ; // reserve new draw command
}
prims - = cnt ;
for ( unsigned int ie = idx + cnt ; idx ! = ie ; + + idx ) {
2020-09-02 10:17:18 -04:00
if ( ! renderer ( DrawList , cull_rect , uv , idx ) )
2020-08-17 19:31:30 -04:00
prims_culled + + ;
}
}
if ( prims_culled > 0 )
DrawList . PrimUnreserve ( prims_culled * Renderer : : IdxConsumed , prims_culled * Renderer : : VtxConsumed ) ;
}
template < typename Getter , typename Transformer >
2020-09-07 17:08:59 -04:00
inline void RenderLineStrip ( const Getter & getter , const Transformer & transformer , ImDrawList & DrawList , float line_weight , ImU32 col ) {
2020-08-17 19:31:30 -04:00
ImPlotContext & gp = * GImPlot ;
2020-08-25 23:47:03 -04:00
if ( ImHasFlag ( gp . CurrentPlot - > Flags , ImPlotFlags_AntiAliased ) | | gp . Style . AntiAliasedLines ) {
2020-08-17 19:31:30 -04:00
ImVec2 p1 = transformer ( getter ( 0 ) ) ;
2020-09-02 10:17:18 -04:00
for ( int i = 1 ; i < getter . Count ; + + i ) {
2020-08-17 19:31:30 -04:00
ImVec2 p2 = transformer ( getter ( i ) ) ;
2020-11-15 22:47:06 -05:00
if ( gp . CurrentPlot - > PlotRect . Overlaps ( ImRect ( ImMin ( p1 , p2 ) , ImMax ( p1 , p2 ) ) ) )
2020-08-17 19:31:30 -04:00
DrawList . AddLine ( p1 , p2 , col , line_weight ) ;
p1 = p2 ;
}
}
else {
2020-11-15 22:47:06 -05:00
RenderPrimitives ( LineStripRenderer < Getter , Transformer > ( getter , transformer , col , line_weight ) , DrawList , gp . CurrentPlot - > PlotRect ) ;
2020-09-02 10:17:18 -04:00
}
}
template < typename Getter1 , typename Getter2 , typename Transformer >
2020-09-07 17:08:59 -04:00
inline void RenderLineSegments ( const Getter1 & getter1 , const Getter2 & getter2 , const Transformer & transformer , ImDrawList & DrawList , float line_weight , ImU32 col ) {
2020-09-02 10:17:18 -04:00
ImPlotContext & gp = * GImPlot ;
if ( ImHasFlag ( gp . CurrentPlot - > Flags , ImPlotFlags_AntiAliased ) | | gp . Style . AntiAliasedLines ) {
int I = ImMin ( getter1 . Count , getter2 . Count ) ;
for ( int i = 0 ; i < I ; + + i ) {
ImVec2 p1 = transformer ( getter1 ( i ) ) ;
ImVec2 p2 = transformer ( getter2 ( i ) ) ;
2020-11-15 22:47:06 -05:00
if ( gp . CurrentPlot - > PlotRect . Overlaps ( ImRect ( ImMin ( p1 , p2 ) , ImMax ( p1 , p2 ) ) ) )
2020-09-02 10:17:18 -04:00
DrawList . AddLine ( p1 , p2 , col , line_weight ) ;
}
}
else {
2020-11-15 22:47:06 -05:00
RenderPrimitives ( LineSegmentsRenderer < Getter1 , Getter2 , Transformer > ( getter1 , getter2 , transformer , col , line_weight ) , DrawList , gp . CurrentPlot - > PlotRect ) ;
2020-08-17 19:31:30 -04:00
}
}
2020-10-19 11:00:03 -04:00
template < typename Getter , typename Transformer >
inline void RenderStairs ( const Getter & getter , const Transformer & transformer , ImDrawList & DrawList , float line_weight , ImU32 col ) {
ImPlotContext & gp = * GImPlot ;
if ( ImHasFlag ( gp . CurrentPlot - > Flags , ImPlotFlags_AntiAliased ) | | gp . Style . AntiAliasedLines ) {
ImVec2 p1 = transformer ( getter ( 0 ) ) ;
for ( int i = 1 ; i < getter . Count ; + + i ) {
ImVec2 p2 = transformer ( getter ( i ) ) ;
2020-11-15 22:47:06 -05:00
if ( gp . CurrentPlot - > PlotRect . Overlaps ( ImRect ( ImMin ( p1 , p2 ) , ImMax ( p1 , p2 ) ) ) ) {
2020-10-19 11:00:03 -04:00
ImVec2 p12 ( p2 . x , p1 . y ) ;
DrawList . AddLine ( p1 , p12 , col , line_weight ) ;
DrawList . AddLine ( p12 , p2 , col , line_weight ) ;
}
p1 = p2 ;
}
}
else {
2020-11-15 22:47:06 -05:00
RenderPrimitives ( StairsRenderer < Getter , Transformer > ( getter , transformer , col , line_weight ) , DrawList , gp . CurrentPlot - > PlotRect ) ;
2020-10-19 11:00:03 -04:00
}
}
2020-08-17 19:31:30 -04:00
//-----------------------------------------------------------------------------
// MARKER RENDERERS
//-----------------------------------------------------------------------------
inline void TransformMarker ( ImVec2 * points , int n , const ImVec2 & c , float s ) {
for ( int i = 0 ; i < n ; + + i ) {
points [ i ] . x = c . x + points [ i ] . x * s ;
points [ i ] . y = c . y + points [ i ] . y * s ;
}
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerGeneral ( ImDrawList & DrawList , ImVec2 * points , int n , const ImVec2 & c , float s , bool outline , ImU32 col_outline , bool fill , ImU32 col_fill , float weight ) {
2020-08-17 19:31:30 -04:00
TransformMarker ( points , n , c , s ) ;
if ( fill )
DrawList . AddConvexPolyFilled ( points , n , col_fill ) ;
if ( outline & & ! ( fill & & col_outline = = col_fill ) ) {
for ( int i = 0 ; i < n ; + + i )
DrawList . AddLine ( points [ i ] , points [ ( i + 1 ) % n ] , col_outline , weight ) ;
}
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerCircle ( ImDrawList & DrawList , const ImVec2 & c , float s , bool outline , ImU32 col_outline , bool fill , ImU32 col_fill , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 10 ] = { ImVec2 ( 1.0f , 0.0f ) ,
ImVec2 ( 0.809017f , 0.58778524f ) ,
ImVec2 ( 0.30901697f , 0.95105654f ) ,
ImVec2 ( - 0.30901703f , 0.9510565f ) ,
ImVec2 ( - 0.80901706f , 0.5877852f ) ,
ImVec2 ( - 1.0f , 0.0f ) ,
ImVec2 ( - 0.80901694f , - 0.58778536f ) ,
ImVec2 ( - 0.3090171f , - 0.9510565f ) ,
ImVec2 ( 0.30901712f , - 0.9510565f ) ,
ImVec2 ( 0.80901694f , - 0.5877853f ) } ;
2020-08-28 18:11:36 -04:00
RenderMarkerGeneral ( DrawList , marker , 10 , c , s , outline , col_outline , fill , col_fill , weight ) ;
2020-08-17 19:31:30 -04:00
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerDiamond ( ImDrawList & DrawList , const ImVec2 & c , float s , bool outline , ImU32 col_outline , bool fill , ImU32 col_fill , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 4 ] = { ImVec2 ( 1 , 0 ) , ImVec2 ( 0 , - 1 ) , ImVec2 ( - 1 , 0 ) , ImVec2 ( 0 , 1 ) } ;
2020-08-28 18:11:36 -04:00
RenderMarkerGeneral ( DrawList , marker , 4 , c , s , outline , col_outline , fill , col_fill , weight ) ;
2020-08-17 19:31:30 -04:00
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerSquare ( ImDrawList & DrawList , const ImVec2 & c , float s , bool outline , ImU32 col_outline , bool fill , ImU32 col_fill , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 4 ] = { ImVec2 ( SQRT_1_2 , SQRT_1_2 ) , ImVec2 ( SQRT_1_2 , - SQRT_1_2 ) , ImVec2 ( - SQRT_1_2 , - SQRT_1_2 ) , ImVec2 ( - SQRT_1_2 , SQRT_1_2 ) } ;
2020-08-28 18:11:36 -04:00
RenderMarkerGeneral ( DrawList , marker , 4 , c , s , outline , col_outline , fill , col_fill , weight ) ;
2020-08-17 19:31:30 -04:00
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerUp ( ImDrawList & DrawList , const ImVec2 & c , float s , bool outline , ImU32 col_outline , bool fill , ImU32 col_fill , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 3 ] = { ImVec2 ( SQRT_3_2 , 0.5f ) , ImVec2 ( 0 , - 1 ) , ImVec2 ( - SQRT_3_2 , 0.5f ) } ;
2020-08-28 18:11:36 -04:00
RenderMarkerGeneral ( DrawList , marker , 3 , c , s , outline , col_outline , fill , col_fill , weight ) ;
2020-08-17 19:31:30 -04:00
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerDown ( ImDrawList & DrawList , const ImVec2 & c , float s , bool outline , ImU32 col_outline , bool fill , ImU32 col_fill , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 3 ] = { ImVec2 ( SQRT_3_2 , - 0.5f ) , ImVec2 ( 0 , 1 ) , ImVec2 ( - SQRT_3_2 , - 0.5f ) } ;
2020-08-28 18:11:36 -04:00
RenderMarkerGeneral ( DrawList , marker , 3 , c , s , outline , col_outline , fill , col_fill , weight ) ;
2020-08-17 19:31:30 -04:00
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerLeft ( ImDrawList & DrawList , const ImVec2 & c , float s , bool outline , ImU32 col_outline , bool fill , ImU32 col_fill , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 3 ] = { ImVec2 ( - 1 , 0 ) , ImVec2 ( 0.5 , SQRT_3_2 ) , ImVec2 ( 0.5 , - SQRT_3_2 ) } ;
2020-08-28 18:11:36 -04:00
RenderMarkerGeneral ( DrawList , marker , 3 , c , s , outline , col_outline , fill , col_fill , weight ) ;
2020-08-17 19:31:30 -04:00
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerRight ( ImDrawList & DrawList , const ImVec2 & c , float s , bool outline , ImU32 col_outline , bool fill , ImU32 col_fill , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 3 ] = { ImVec2 ( 1 , 0 ) , ImVec2 ( - 0.5 , SQRT_3_2 ) , ImVec2 ( - 0.5 , - SQRT_3_2 ) } ;
2020-08-28 18:11:36 -04:00
RenderMarkerGeneral ( DrawList , marker , 3 , c , s , outline , col_outline , fill , col_fill , weight ) ;
2020-08-17 19:31:30 -04:00
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerAsterisk ( ImDrawList & DrawList , const ImVec2 & c , float s , bool /*outline*/ , ImU32 col_outline , bool /*fill*/ , ImU32 /*col_fill*/ , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 6 ] = { ImVec2 ( SQRT_3_2 , 0.5f ) , ImVec2 ( 0 , - 1 ) , ImVec2 ( - SQRT_3_2 , 0.5f ) , ImVec2 ( SQRT_3_2 , - 0.5f ) , ImVec2 ( 0 , 1 ) , ImVec2 ( - SQRT_3_2 , - 0.5f ) } ;
TransformMarker ( marker , 6 , c , s ) ;
DrawList . AddLine ( marker [ 0 ] , marker [ 5 ] , col_outline , weight ) ;
DrawList . AddLine ( marker [ 1 ] , marker [ 4 ] , col_outline , weight ) ;
DrawList . AddLine ( marker [ 2 ] , marker [ 3 ] , col_outline , weight ) ;
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerPlus ( ImDrawList & DrawList , const ImVec2 & c , float s , bool /*outline*/ , ImU32 col_outline , bool /*fill*/ , ImU32 /*col_fill*/ , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 4 ] = { ImVec2 ( 1 , 0 ) , ImVec2 ( 0 , - 1 ) , ImVec2 ( - 1 , 0 ) , ImVec2 ( 0 , 1 ) } ;
TransformMarker ( marker , 4 , c , s ) ;
DrawList . AddLine ( marker [ 0 ] , marker [ 2 ] , col_outline , weight ) ;
DrawList . AddLine ( marker [ 1 ] , marker [ 3 ] , col_outline , weight ) ;
}
2020-08-28 18:11:36 -04:00
inline void RenderMarkerCross ( ImDrawList & DrawList , const ImVec2 & c , float s , bool /*outline*/ , ImU32 col_outline , bool /*fill*/ , ImU32 /*col_fill*/ , float weight ) {
2020-08-17 19:31:30 -04:00
ImVec2 marker [ 4 ] = { ImVec2 ( SQRT_1_2 , SQRT_1_2 ) , ImVec2 ( SQRT_1_2 , - SQRT_1_2 ) , ImVec2 ( - SQRT_1_2 , - SQRT_1_2 ) , ImVec2 ( - SQRT_1_2 , SQRT_1_2 ) } ;
TransformMarker ( marker , 4 , c , s ) ;
DrawList . AddLine ( marker [ 0 ] , marker [ 2 ] , col_outline , weight ) ;
DrawList . AddLine ( marker [ 1 ] , marker [ 3 ] , col_outline , weight ) ;
}
template < typename Transformer , typename Getter >
2020-08-30 18:12:36 -04:00
inline void RenderMarkers ( Getter getter , Transformer transformer , ImDrawList & DrawList , ImPlotMarker marker , float size , bool rend_mk_line , ImU32 col_mk_line , float weight , bool rend_mk_fill , ImU32 col_mk_fill ) {
2020-09-02 10:17:18 -04:00
static void ( * marker_table [ ImPlotMarker_COUNT ] ) ( ImDrawList & , const ImVec2 & , float s , bool , ImU32 , bool , ImU32 , float ) = {
2020-09-01 00:23:48 -04:00
RenderMarkerCircle ,
RenderMarkerSquare ,
RenderMarkerDiamond ,
RenderMarkerUp ,
RenderMarkerDown ,
RenderMarkerLeft ,
RenderMarkerRight ,
RenderMarkerCross ,
RenderMarkerPlus ,
2020-08-28 18:11:36 -04:00
RenderMarkerAsterisk
} ;
2020-08-17 19:31:30 -04:00
ImPlotContext & gp = * GImPlot ;
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImVec2 c = transformer ( getter ( i ) ) ;
2020-11-15 22:47:06 -05:00
if ( gp . CurrentPlot - > PlotRect . Contains ( c ) )
2020-09-01 00:23:48 -04:00
marker_table [ marker ] ( DrawList , c , size , rend_mk_line , col_mk_line , rend_mk_fill , col_mk_fill , weight ) ;
2020-08-17 19:31:30 -04:00
}
}
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-09-07 17:08:59 -04:00
// PLOT LINE
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
template < typename Getter >
2020-09-07 17:08:59 -04:00
inline void PlotLineEx ( const char * label_id , const Getter & getter ) {
2020-08-30 18:12:36 -04:00
if ( BeginItem ( label_id , ImPlotCol_Line ) ) {
2020-08-30 22:03:11 -04:00
if ( FitThisFrame ( ) ) {
2020-08-30 18:12:36 -04:00
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPoint p = getter ( i ) ;
FitPoint ( p ) ;
}
2020-08-16 16:38:51 -04:00
}
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-08-30 18:12:36 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
if ( getter . Count > 1 & & s . RenderLine ) {
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Line ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderLineStrip ( getter , TransformerLinLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLin : RenderLineStrip ( getter , TransformerLogLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LinLog : RenderLineStrip ( getter , TransformerLinLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
2020-09-01 00:23:48 -04:00
case ImPlotScale_LogLog : RenderLineStrip ( getter , TransformerLogLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
2020-08-30 18:12:36 -04:00
}
2020-08-30 12:03:25 -04:00
}
2020-08-30 18:12:36 -04:00
// render markers
if ( s . Marker ! = ImPlotMarker_None ) {
2021-03-28 15:59:25 -04:00
PopPlotClipRect ( ) ;
PushPlotClipRect ( s . MarkerSize ) ;
2020-08-30 18:12:36 -04:00
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_MarkerOutline ] ) ;
const ImU32 col_fill = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_MarkerFill ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderMarkers ( getter , TransformerLinLin ( ) , DrawList , s . Marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LogLin : RenderMarkers ( getter , TransformerLogLin ( ) , DrawList , s . Marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LinLog : RenderMarkers ( getter , TransformerLinLog ( ) , DrawList , s . Marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
2020-09-01 00:23:48 -04:00
case ImPlotScale_LogLog : RenderMarkers ( getter , TransformerLogLog ( ) , DrawList , s . Marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
2020-08-30 18:12:36 -04:00
}
2020-08-30 12:03:25 -04:00
}
2020-08-30 18:12:36 -04:00
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-10 00:29:29 -04:00
void PlotLine ( const char * label_id , const T * values , int count , double xscale , double x0 , int offset , int stride ) {
GetterYs < T > getter ( values , count , xscale , x0 , offset , stride ) ;
2020-09-01 00:23:48 -04:00
PlotLineEx ( label_id , getter ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-10 00:29:29 -04:00
template IMPLOT_API void PlotLine < ImS8 > ( const char * label_id , const ImS8 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImU8 > ( const char * label_id , const ImU8 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImS16 > ( const char * label_id , const ImS16 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImU16 > ( const char * label_id , const ImU16 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImS32 > ( const char * label_id , const ImS32 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImU32 > ( const char * label_id , const ImU32 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImS64 > ( const char * label_id , const ImS64 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImU64 > ( const char * label_id , const ImU64 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < float > ( const char * label_id , const float * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotLine < double > ( const char * label_id , const double * values , int count , double xscale , double x0 , int offset , int stride ) ;
2020-09-06 23:34:58 -04:00
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-06 23:34:58 -04:00
void PlotLine ( const char * label_id , const T * xs , const T * ys , int count , int offset , int stride ) {
GetterXsYs < T > getter ( xs , ys , count , offset , stride ) ;
2020-09-01 00:23:48 -04:00
return PlotLineEx ( label_id , getter ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotLine < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < float > ( const char * label_id , const float * xs , const float * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotLine < double > ( const char * label_id , const double * xs , const double * ys , int count , int offset , int stride ) ;
2020-09-06 23:34:58 -04:00
2020-08-17 17:26:45 -04:00
// custom
2020-09-06 23:34:58 -04:00
void PlotLineG ( const char * label_id , ImPlotPoint ( * getter_func ) ( void * data , int idx ) , void * data , int count , int offset ) {
2020-09-15 09:56:58 -04:00
GetterFuncPtr getter ( getter_func , data , count , offset ) ;
2020-09-01 00:23:48 -04:00
return PlotLineEx ( label_id , getter ) ;
2020-08-16 16:38:51 -04:00
}
//-----------------------------------------------------------------------------
// PLOT SCATTER
//-----------------------------------------------------------------------------
2020-09-01 00:23:48 -04:00
template < typename Getter >
2020-09-07 17:08:59 -04:00
inline void PlotScatterEx ( const char * label_id , const Getter & getter ) {
2020-09-01 00:23:48 -04:00
if ( BeginItem ( label_id , ImPlotCol_MarkerOutline ) ) {
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPoint p = getter ( i ) ;
FitPoint ( p ) ;
}
}
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-09-01 00:23:48 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
// render markers
ImPlotMarker marker = s . Marker = = ImPlotMarker_None ? ImPlotMarker_Circle : s . Marker ;
if ( marker ! = ImPlotMarker_None ) {
2021-03-28 15:59:25 -04:00
PopPlotClipRect ( ) ;
PushPlotClipRect ( s . MarkerSize ) ;
2020-09-01 00:23:48 -04:00
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_MarkerOutline ] ) ;
const ImU32 col_fill = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_MarkerFill ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderMarkers ( getter , TransformerLinLin ( ) , DrawList , marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LogLin : RenderMarkers ( getter , TransformerLogLin ( ) , DrawList , marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LinLog : RenderMarkers ( getter , TransformerLinLog ( ) , DrawList , marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LogLog : RenderMarkers ( getter , TransformerLogLog ( ) , DrawList , marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
}
}
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-10 00:29:29 -04:00
void PlotScatter ( const char * label_id , const T * values , int count , double xscale , double x0 , int offset , int stride ) {
GetterYs < T > getter ( values , count , xscale , x0 , offset , stride ) ;
2020-09-01 00:23:48 -04:00
PlotScatterEx ( label_id , getter ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-10 00:29:29 -04:00
template IMPLOT_API void PlotScatter < ImS8 > ( const char * label_id , const ImS8 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImU8 > ( const char * label_id , const ImU8 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImS16 > ( const char * label_id , const ImS16 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImU16 > ( const char * label_id , const ImU16 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImS32 > ( const char * label_id , const ImS32 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImU32 > ( const char * label_id , const ImU32 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImS64 > ( const char * label_id , const ImS64 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImU64 > ( const char * label_id , const ImU64 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < float > ( const char * label_id , const float * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < double > ( const char * label_id , const double * values , int count , double xscale , double x0 , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-07 01:16:47 -04:00
void PlotScatter ( const char * label_id , const T * xs , const T * ys , int count , int offset , int stride ) {
GetterXsYs < T > getter ( xs , ys , count , offset , stride ) ;
2020-09-01 00:23:48 -04:00
return PlotScatterEx ( label_id , getter ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotScatter < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < float > ( const char * label_id , const float * xs , const float * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotScatter < double > ( const char * label_id , const double * xs , const double * ys , int count , int offset , int stride ) ;
2020-09-07 01:16:47 -04:00
2020-08-17 17:26:45 -04:00
// custom
2020-09-07 01:16:47 -04:00
void PlotScatterG ( const char * label_id , ImPlotPoint ( * getter_func ) ( void * data , int idx ) , void * data , int count , int offset ) {
2020-09-15 09:56:58 -04:00
GetterFuncPtr getter ( getter_func , data , count , offset ) ;
2020-09-01 00:23:48 -04:00
return PlotScatterEx ( label_id , getter ) ;
2020-08-16 16:38:51 -04:00
}
2020-10-19 11:00:03 -04:00
//-----------------------------------------------------------------------------
// PLOT STAIRS
//-----------------------------------------------------------------------------
template < typename Getter >
inline void PlotStairsEx ( const char * label_id , const Getter & getter ) {
if ( BeginItem ( label_id , ImPlotCol_Line ) ) {
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPoint p = getter ( i ) ;
FitPoint ( p ) ;
}
}
const ImPlotNextItemData & s = GetItemData ( ) ;
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
if ( getter . Count > 1 & & s . RenderLine ) {
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Line ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderStairs ( getter , TransformerLinLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLin : RenderStairs ( getter , TransformerLogLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LinLog : RenderStairs ( getter , TransformerLinLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLog : RenderStairs ( getter , TransformerLogLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
}
}
// render markers
if ( s . Marker ! = ImPlotMarker_None ) {
2021-03-28 15:59:25 -04:00
PopPlotClipRect ( ) ;
PushPlotClipRect ( s . MarkerSize ) ;
2020-10-19 11:00:03 -04:00
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_MarkerOutline ] ) ;
const ImU32 col_fill = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_MarkerFill ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderMarkers ( getter , TransformerLinLin ( ) , DrawList , s . Marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LogLin : RenderMarkers ( getter , TransformerLogLin ( ) , DrawList , s . Marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LinLog : RenderMarkers ( getter , TransformerLinLog ( ) , DrawList , s . Marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LogLog : RenderMarkers ( getter , TransformerLogLog ( ) , DrawList , s . Marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
}
}
EndItem ( ) ;
}
}
template < typename T >
void PlotStairs ( const char * label_id , const T * values , int count , double xscale , double x0 , int offset , int stride ) {
GetterYs < T > getter ( values , count , xscale , x0 , offset , stride ) ;
PlotStairsEx ( label_id , getter ) ;
}
template IMPLOT_API void PlotStairs < ImS8 > ( const char * label_id , const ImS8 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImU8 > ( const char * label_id , const ImU8 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImS16 > ( const char * label_id , const ImS16 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImU16 > ( const char * label_id , const ImU16 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImS32 > ( const char * label_id , const ImS32 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImU32 > ( const char * label_id , const ImU32 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImS64 > ( const char * label_id , const ImS64 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImU64 > ( const char * label_id , const ImU64 * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < float > ( const char * label_id , const float * values , int count , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < double > ( const char * label_id , const double * values , int count , double xscale , double x0 , int offset , int stride ) ;
template < typename T >
void PlotStairs ( const char * label_id , const T * xs , const T * ys , int count , int offset , int stride ) {
GetterXsYs < T > getter ( xs , ys , count , offset , stride ) ;
return PlotStairsEx ( label_id , getter ) ;
}
template IMPLOT_API void PlotStairs < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < float > ( const char * label_id , const float * xs , const float * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotStairs < double > ( const char * label_id , const double * xs , const double * ys , int count , int offset , int stride ) ;
// custom
void PlotStairsG ( const char * label_id , ImPlotPoint ( * getter_func ) ( void * data , int idx ) , void * data , int count , int offset ) {
GetterFuncPtr getter ( getter_func , data , count , offset ) ;
return PlotStairsEx ( label_id , getter ) ;
}
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
// PLOT SHADED
//-----------------------------------------------------------------------------
template < typename Getter1 , typename Getter2 >
2021-01-11 14:22:52 -05:00
inline void PlotShadedEx ( const char * label_id , const Getter1 & getter1 , const Getter2 & getter2 , bool fit2 ) {
2020-08-30 18:12:36 -04:00
if ( BeginItem ( label_id , ImPlotCol_Fill ) ) {
2020-08-30 22:03:11 -04:00
if ( FitThisFrame ( ) ) {
2021-01-15 02:52:37 -05:00
for ( int i = 0 ; i < getter1 . Count ; + + i )
FitPoint ( getter1 ( i ) ) ;
2021-01-11 14:22:52 -05:00
if ( fit2 ) {
2021-01-15 02:52:37 -05:00
for ( int i = 0 ; i < getter2 . Count ; + + i )
FitPoint ( getter2 ( i ) ) ;
2020-08-30 18:12:36 -04:00
}
2020-08-16 16:38:51 -04:00
}
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-08-30 18:12:36 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
if ( s . RenderFill ) {
ImU32 col = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Fill ] ) ;
switch ( GetCurrentScale ( ) ) {
2020-11-15 22:47:06 -05:00
case ImPlotScale_LinLin : RenderPrimitives ( ShadedRenderer < Getter1 , Getter2 , TransformerLinLin > ( getter1 , getter2 , TransformerLinLin ( ) , col ) , DrawList , GImPlot - > CurrentPlot - > PlotRect ) ; break ;
case ImPlotScale_LogLin : RenderPrimitives ( ShadedRenderer < Getter1 , Getter2 , TransformerLogLin > ( getter1 , getter2 , TransformerLogLin ( ) , col ) , DrawList , GImPlot - > CurrentPlot - > PlotRect ) ; break ;
case ImPlotScale_LinLog : RenderPrimitives ( ShadedRenderer < Getter1 , Getter2 , TransformerLinLog > ( getter1 , getter2 , TransformerLinLog ( ) , col ) , DrawList , GImPlot - > CurrentPlot - > PlotRect ) ; break ;
case ImPlotScale_LogLog : RenderPrimitives ( ShadedRenderer < Getter1 , Getter2 , TransformerLogLog > ( getter1 , getter2 , TransformerLogLog ( ) , col ) , DrawList , GImPlot - > CurrentPlot - > PlotRect ) ; break ;
2020-08-30 18:12:36 -04:00
}
2020-08-16 16:38:51 -04:00
}
2020-08-30 18:12:36 -04:00
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-10 00:29:29 -04:00
void PlotShaded ( const char * label_id , const T * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) {
2021-01-11 14:22:52 -05:00
bool fit2 = true ;
if ( y_ref = = - HUGE_VAL ) {
2021-01-15 02:52:37 -05:00
fit2 = false ;
2021-01-11 14:22:52 -05:00
y_ref = GetPlotLimits ( ) . Y . Min ;
}
if ( y_ref = = HUGE_VAL ) {
fit2 = false ;
y_ref = GetPlotLimits ( ) . Y . Max ;
}
2020-09-10 00:29:29 -04:00
GetterYs < T > getter1 ( values , count , xscale , x0 , offset , stride ) ;
2020-09-10 16:59:08 -04:00
GetterYRef getter2 ( y_ref , count , xscale , x0 ) ;
2021-01-11 14:22:52 -05:00
PlotShadedEx ( label_id , getter1 , getter2 , fit2 ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-10 00:29:29 -04:00
template IMPLOT_API void PlotShaded < ImS8 > ( const char * label_id , const ImS8 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU8 > ( const char * label_id , const ImU8 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS16 > ( const char * label_id , const ImS16 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU16 > ( const char * label_id , const ImU16 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS32 > ( const char * label_id , const ImS32 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU32 > ( const char * label_id , const ImU32 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS64 > ( const char * label_id , const ImS64 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU64 > ( const char * label_id , const ImU64 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < float > ( const char * label_id , const float * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < double > ( const char * label_id , const double * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-07 01:16:47 -04:00
void PlotShaded ( const char * label_id , const T * xs , const T * ys , int count , double y_ref , int offset , int stride ) {
2021-01-11 14:22:52 -05:00
bool fit2 = true ;
if ( y_ref = = - HUGE_VAL ) {
2021-01-15 02:52:37 -05:00
fit2 = false ;
2021-01-11 14:22:52 -05:00
y_ref = GetPlotLimits ( ) . Y . Min ;
}
if ( y_ref = = HUGE_VAL ) {
fit2 = false ;
y_ref = GetPlotLimits ( ) . Y . Max ;
}
2020-09-07 01:16:47 -04:00
GetterXsYs < T > getter1 ( xs , ys , count , offset , stride ) ;
2020-09-15 09:56:58 -04:00
GetterXsYRef < T > getter2 ( xs , y_ref , count , offset , stride ) ;
2021-01-11 14:22:52 -05:00
PlotShadedEx ( label_id , getter1 , getter2 , fit2 ) ;
2020-08-21 00:01:21 -04:00
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotShaded < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < float > ( const char * label_id , const float * xs , const float * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < double > ( const char * label_id , const double * xs , const double * ys , int count , double y_ref , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-07 01:16:47 -04:00
void PlotShaded ( const char * label_id , const T * xs , const T * ys1 , const T * ys2 , int count , int offset , int stride ) {
GetterXsYs < T > getter1 ( xs , ys1 , count , offset , stride ) ;
GetterXsYs < T > getter2 ( xs , ys2 , count , offset , stride ) ;
2021-01-11 14:22:52 -05:00
PlotShadedEx ( label_id , getter1 , getter2 , true ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotShaded < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys1 , const ImS8 * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys1 , const ImU8 * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys1 , const ImS16 * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys1 , const ImU16 * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys1 , const ImS32 * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys1 , const ImU32 * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys1 , const ImS64 * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys1 , const ImU64 * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < float > ( const char * label_id , const float * xs , const float * ys1 , const float * ys2 , int count , int offset , int stride ) ;
template IMPLOT_API void PlotShaded < double > ( const char * label_id , const double * xs , const double * ys1 , const double * ys2 , int count , int offset , int stride ) ;
2020-09-07 01:16:47 -04:00
2020-08-21 23:13:11 -04:00
// custom
2020-09-07 01:16:47 -04:00
void PlotShadedG ( const char * label_id , ImPlotPoint ( * g1 ) ( void * data , int idx ) , void * data1 , ImPlotPoint ( * g2 ) ( void * data , int idx ) , void * data2 , int count , int offset ) {
2020-09-15 09:56:58 -04:00
GetterFuncPtr getter1 ( g1 , data1 , count , offset ) ;
GetterFuncPtr getter2 ( g2 , data2 , count , offset ) ;
2021-01-11 14:22:52 -05:00
PlotShadedEx ( label_id , getter1 , getter2 , true ) ;
2020-08-21 23:13:11 -04:00
}
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-09-07 01:16:47 -04:00
// PLOT BAR
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
2020-08-30 22:03:11 -04:00
// TODO: Migrate to RenderPrimitives
2020-09-07 17:08:59 -04:00
template < typename Getter >
void PlotBarsEx ( const char * label_id , const Getter & getter , double width ) {
2020-08-30 22:03:11 -04:00
if ( BeginItem ( label_id , ImPlotCol_Fill ) ) {
2020-09-07 17:08:59 -04:00
const double half_width = width / 2 ;
2020-08-30 22:03:11 -04:00
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPoint p = getter ( i ) ;
FitPoint ( ImPlotPoint ( p . x - half_width , p . y ) ) ;
FitPoint ( ImPlotPoint ( p . x + half_width , 0 ) ) ;
}
}
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-08-30 22:03:11 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Line ] ) ;
ImU32 col_fill = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Fill ] ) ;
bool rend_line = s . RenderLine ;
if ( s . RenderFill & & col_line = = col_fill )
rend_line = false ;
2020-08-16 16:38:51 -04:00
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPoint p = getter ( i ) ;
2020-08-30 22:03:11 -04:00
if ( p . y = = 0 )
continue ;
ImVec2 a = PlotToPixels ( p . x - half_width , p . y ) ;
ImVec2 b = PlotToPixels ( p . x + half_width , 0 ) ;
if ( s . RenderFill )
DrawList . AddRectFilled ( a , b , col_fill ) ;
if ( rend_line )
2021-03-16 07:37:45 -04:00
DrawList . AddRect ( a , b , col_line , 0 , ImDrawFlags_RoundCornersAll , s . LineWeight ) ;
2020-08-16 16:38:51 -04:00
}
2020-08-30 22:03:11 -04:00
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-07 01:16:47 -04:00
void PlotBars ( const char * label_id , const T * values , int count , double width , double shift , int offset , int stride ) {
GetterBarV < T > getter ( values , shift , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
PlotBarsEx ( label_id , getter , width ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotBars < ImS8 > ( const char * label_id , const ImS8 * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImU8 > ( const char * label_id , const ImU8 * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImS16 > ( const char * label_id , const ImS16 * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImU16 > ( const char * label_id , const ImU16 * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImS32 > ( const char * label_id , const ImS32 * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImU32 > ( const char * label_id , const ImU32 * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImS64 > ( const char * label_id , const ImS64 * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImU64 > ( const char * label_id , const ImU64 * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < float > ( const char * label_id , const float * values , int count , double width , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBars < double > ( const char * label_id , const double * values , int count , double width , double shift , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-07 01:16:47 -04:00
void PlotBars ( const char * label_id , const T * xs , const T * ys , int count , double width , int offset , int stride ) {
GetterXsYs < T > getter ( xs , ys , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
PlotBarsEx ( label_id , getter , width ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotBars < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < float > ( const char * label_id , const float * xs , const float * ys , int count , double width , int offset , int stride ) ;
template IMPLOT_API void PlotBars < double > ( const char * label_id , const double * xs , const double * ys , int count , double width , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-08-17 17:26:45 -04:00
// custom
2020-09-07 01:16:47 -04:00
void PlotBarsG ( const char * label_id , ImPlotPoint ( * getter_func ) ( void * data , int idx ) , void * data , int count , double width , int offset ) {
2020-09-15 09:56:58 -04:00
GetterFuncPtr getter ( getter_func , data , count , offset ) ;
2020-08-16 16:38:51 -04:00
PlotBarsEx ( label_id , getter , width ) ;
}
//-----------------------------------------------------------------------------
// PLOT BAR H
//-----------------------------------------------------------------------------
// TODO: Migrate to RenderPrimitives
template < typename Getter , typename THeight >
2020-09-07 17:08:59 -04:00
void PlotBarsHEx ( const char * label_id , const Getter & getter , THeight height ) {
2020-08-30 22:03:11 -04:00
if ( BeginItem ( label_id , ImPlotCol_Fill ) ) {
const THeight half_height = height / 2 ;
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPoint p = getter ( i ) ;
FitPoint ( ImPlotPoint ( 0 , p . y - half_height ) ) ;
FitPoint ( ImPlotPoint ( p . x , p . y + half_height ) ) ;
}
}
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-08-30 22:03:11 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Line ] ) ;
ImU32 col_fill = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Fill ] ) ;
bool rend_line = s . RenderLine ;
if ( s . RenderFill & & col_line = = col_fill )
rend_line = false ;
2020-08-16 16:38:51 -04:00
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPoint p = getter ( i ) ;
2020-08-30 22:03:11 -04:00
if ( p . x = = 0 )
continue ;
ImVec2 a = PlotToPixels ( 0 , p . y - half_height ) ;
ImVec2 b = PlotToPixels ( p . x , p . y + half_height ) ;
if ( s . RenderFill )
DrawList . AddRectFilled ( a , b , col_fill ) ;
if ( rend_line )
2021-03-16 07:37:45 -04:00
DrawList . AddRect ( a , b , col_line , 0 , ImDrawFlags_RoundCornersAll , s . LineWeight ) ;
2020-08-16 16:38:51 -04:00
}
2020-08-30 22:03:11 -04:00
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-07 01:16:47 -04:00
void PlotBarsH ( const char * label_id , const T * values , int count , double height , double shift , int offset , int stride ) {
GetterBarH < T > getter ( values , shift , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
PlotBarsHEx ( label_id , getter , height ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotBarsH < ImS8 > ( const char * label_id , const ImS8 * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImU8 > ( const char * label_id , const ImU8 * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImS16 > ( const char * label_id , const ImS16 * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImU16 > ( const char * label_id , const ImU16 * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImS32 > ( const char * label_id , const ImS32 * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImU32 > ( const char * label_id , const ImU32 * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImS64 > ( const char * label_id , const ImS64 * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImU64 > ( const char * label_id , const ImU64 * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < float > ( const char * label_id , const float * values , int count , double height , double shift , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < double > ( const char * label_id , const double * values , int count , double height , double shift , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-09-07 21:59:43 -04:00
template < typename T >
2020-09-07 01:16:47 -04:00
void PlotBarsH ( const char * label_id , const T * xs , const T * ys , int count , double height , int offset , int stride ) {
GetterXsYs < T > getter ( xs , ys , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
PlotBarsHEx ( label_id , getter , height ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotBarsH < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < float > ( const char * label_id , const float * xs , const float * ys , int count , double height , int offset , int stride ) ;
template IMPLOT_API void PlotBarsH < double > ( const char * label_id , const double * xs , const double * ys , int count , double height , int offset , int stride ) ;
2020-09-07 01:33:47 -04:00
2020-08-17 17:26:45 -04:00
// custom
2020-09-07 01:16:47 -04:00
void PlotBarsHG ( const char * label_id , ImPlotPoint ( * getter_func ) ( void * data , int idx ) , void * data , int count , double height , int offset ) {
2020-09-15 09:56:58 -04:00
GetterFuncPtr getter ( getter_func , data , count , offset ) ;
2020-08-16 16:38:51 -04:00
PlotBarsHEx ( label_id , getter , height ) ;
}
//-----------------------------------------------------------------------------
// PLOT ERROR BARS
//-----------------------------------------------------------------------------
template < typename Getter >
2020-09-07 17:08:59 -04:00
void PlotErrorBarsEx ( const char * label_id , const Getter & getter ) {
2020-08-30 22:03:11 -04:00
if ( BeginItem ( label_id ) ) {
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPointError e = getter ( i ) ;
FitPoint ( ImPlotPoint ( e . X , e . Y - e . Neg ) ) ;
FitPoint ( ImPlotPoint ( e . X , e . Y + e . Pos ) ) ;
}
}
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-08-30 22:03:11 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
const ImU32 col = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_ErrorBar ] ) ;
const bool rend_whisker = s . ErrorBarSize > 0 ;
const float half_whisker = s . ErrorBarSize * 0.5f ;
2020-08-16 16:38:51 -04:00
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPointError e = getter ( i ) ;
2020-08-30 22:03:11 -04:00
ImVec2 p1 = PlotToPixels ( e . X , e . Y - e . Neg ) ;
ImVec2 p2 = PlotToPixels ( e . X , e . Y + e . Pos ) ;
DrawList . AddLine ( p1 , p2 , col , s . ErrorBarWeight ) ;
if ( rend_whisker ) {
DrawList . AddLine ( p1 - ImVec2 ( half_whisker , 0 ) , p1 + ImVec2 ( half_whisker , 0 ) , col , s . ErrorBarWeight ) ;
DrawList . AddLine ( p2 - ImVec2 ( half_whisker , 0 ) , p2 + ImVec2 ( half_whisker , 0 ) , col , s . ErrorBarWeight ) ;
}
2020-08-16 16:38:51 -04:00
}
2020-08-30 22:03:11 -04:00
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 17:08:59 -04:00
template < typename T >
void PlotErrorBars ( const char * label_id , const T * xs , const T * ys , const T * err , int count , int offset , int stride ) {
GetterError < T > getter ( xs , ys , err , err , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
PlotErrorBarsEx ( label_id , getter ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotErrorBars < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , const ImS8 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , const ImU8 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , const ImS16 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , const ImU16 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , const ImS32 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , const ImU32 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , const ImS64 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , const ImU64 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < float > ( const char * label_id , const float * xs , const float * ys , const float * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < double > ( const char * label_id , const double * xs , const double * ys , const double * err , int count , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-09-07 17:08:59 -04:00
template < typename T >
void PlotErrorBars ( const char * label_id , const T * xs , const T * ys , const T * neg , const T * pos , int count , int offset , int stride ) {
GetterError < T > getter ( xs , ys , neg , pos , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
PlotErrorBarsEx ( label_id , getter ) ;
}
2021-03-17 08:38:45 -04:00
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotErrorBars < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , const ImS8 * neg , const ImS8 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , const ImU8 * neg , const ImU8 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , const ImS16 * neg , const ImS16 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , const ImU16 * neg , const ImU16 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , const ImS32 * neg , const ImS32 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , const ImU32 * neg , const ImU32 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , const ImS64 * neg , const ImS64 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , const ImU64 * neg , const ImU64 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < float > ( const char * label_id , const float * xs , const float * ys , const float * neg , const float * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBars < double > ( const char * label_id , const double * xs , const double * ys , const double * neg , const double * pos , int count , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
// PLOT ERROR BARS H
//-----------------------------------------------------------------------------
template < typename Getter >
2020-09-07 17:08:59 -04:00
void PlotErrorBarsHEx ( const char * label_id , const Getter & getter ) {
2020-08-30 22:03:11 -04:00
if ( BeginItem ( label_id ) ) {
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPointError e = getter ( i ) ;
FitPoint ( ImPlotPoint ( e . X - e . Neg , e . Y ) ) ;
FitPoint ( ImPlotPoint ( e . X + e . Pos , e . Y ) ) ;
}
}
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-08-30 22:03:11 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
const ImU32 col = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_ErrorBar ] ) ;
const bool rend_whisker = s . ErrorBarSize > 0 ;
const float half_whisker = s . ErrorBarSize * 0.5f ;
2020-08-16 16:38:51 -04:00
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPointError e = getter ( i ) ;
2020-08-30 22:03:11 -04:00
ImVec2 p1 = PlotToPixels ( e . X - e . Neg , e . Y ) ;
ImVec2 p2 = PlotToPixels ( e . X + e . Pos , e . Y ) ;
DrawList . AddLine ( p1 , p2 , col , s . ErrorBarWeight ) ;
if ( rend_whisker ) {
DrawList . AddLine ( p1 - ImVec2 ( 0 , half_whisker ) , p1 + ImVec2 ( 0 , half_whisker ) , col , s . ErrorBarWeight ) ;
DrawList . AddLine ( p2 - ImVec2 ( 0 , half_whisker ) , p2 + ImVec2 ( 0 , half_whisker ) , col , s . ErrorBarWeight ) ;
}
2020-08-16 16:38:51 -04:00
}
2020-08-30 22:03:11 -04:00
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 17:08:59 -04:00
template < typename T >
void PlotErrorBarsH ( const char * label_id , const T * xs , const T * ys , const T * err , int count , int offset , int stride ) {
GetterError < T > getter ( xs , ys , err , err , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
PlotErrorBarsHEx ( label_id , getter ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotErrorBarsH < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , const ImS8 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , const ImU8 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , const ImS16 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , const ImU16 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , const ImS32 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , const ImU32 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , const ImS64 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , const ImU64 * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < float > ( const char * label_id , const float * xs , const float * ys , const float * err , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < double > ( const char * label_id , const double * xs , const double * ys , const double * err , int count , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-09-07 17:08:59 -04:00
template < typename T >
void PlotErrorBarsH ( const char * label_id , const T * xs , const T * ys , const T * neg , const T * pos , int count , int offset , int stride ) {
GetterError < T > getter ( xs , ys , neg , pos , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
PlotErrorBarsHEx ( label_id , getter ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotErrorBarsH < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , const ImS8 * neg , const ImS8 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , const ImU8 * neg , const ImU8 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , const ImS16 * neg , const ImS16 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , const ImU16 * neg , const ImU16 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , const ImS32 * neg , const ImS32 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , const ImU32 * neg , const ImU32 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , const ImS64 * neg , const ImS64 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , const ImU64 * neg , const ImU64 * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < float > ( const char * label_id , const float * xs , const float * ys , const float * neg , const float * pos , int count , int offset , int stride ) ;
template IMPLOT_API void PlotErrorBarsH < double > ( const char * label_id , const double * xs , const double * ys , const double * neg , const double * pos , int count , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
2020-09-02 10:17:18 -04:00
//-----------------------------------------------------------------------------
// PLOT STEMS
//-----------------------------------------------------------------------------
template < typename GetterM , typename GetterB >
2020-09-07 17:08:59 -04:00
inline void PlotStemsEx ( const char * label_id , const GetterM & get_mark , const GetterB & get_base ) {
2020-09-02 10:17:18 -04:00
if ( BeginItem ( label_id , ImPlotCol_Line ) ) {
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < get_base . Count ; + + i ) {
FitPoint ( get_mark ( i ) ) ;
FitPoint ( get_base ( i ) ) ;
}
}
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-09-02 10:17:18 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
// render stems
if ( s . RenderLine ) {
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Line ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderLineSegments ( get_mark , get_base , TransformerLinLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLin : RenderLineSegments ( get_mark , get_base , TransformerLogLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LinLog : RenderLineSegments ( get_mark , get_base , TransformerLinLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLog : RenderLineSegments ( get_mark , get_base , TransformerLogLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
}
}
// render markers
ImPlotMarker marker = s . Marker = = ImPlotMarker_None ? ImPlotMarker_Circle : s . Marker ;
if ( marker ! = ImPlotMarker_None ) {
2021-03-28 15:59:25 -04:00
PopPlotClipRect ( ) ;
PushPlotClipRect ( s . MarkerSize ) ;
2020-09-02 10:17:18 -04:00
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_MarkerOutline ] ) ;
const ImU32 col_fill = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_MarkerFill ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderMarkers ( get_mark , TransformerLinLin ( ) , DrawList , marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LogLin : RenderMarkers ( get_mark , TransformerLogLin ( ) , DrawList , marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LinLog : RenderMarkers ( get_mark , TransformerLinLog ( ) , DrawList , marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
case ImPlotScale_LogLog : RenderMarkers ( get_mark , TransformerLogLog ( ) , DrawList , marker , s . MarkerSize , s . RenderMarkerLine , col_line , s . MarkerWeight , s . RenderMarkerFill , col_fill ) ; break ;
}
}
EndItem ( ) ;
}
}
2020-09-07 17:08:59 -04:00
template < typename T >
2020-09-10 00:29:29 -04:00
void PlotStems ( const char * label_id , const T * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) {
GetterYs < T > get_mark ( values , count , xscale , x0 , offset , stride ) ;
2020-09-10 16:59:08 -04:00
GetterYRef get_base ( y_ref , count , xscale , x0 ) ;
2020-09-02 10:17:18 -04:00
PlotStemsEx ( label_id , get_mark , get_base ) ;
}
2020-09-10 00:29:29 -04:00
template IMPLOT_API void PlotStems < ImS8 > ( const char * label_id , const ImS8 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImU8 > ( const char * label_id , const ImU8 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImS16 > ( const char * label_id , const ImS16 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImU16 > ( const char * label_id , const ImU16 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImS32 > ( const char * label_id , const ImS32 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImU32 > ( const char * label_id , const ImU32 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImS64 > ( const char * label_id , const ImS64 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImU64 > ( const char * label_id , const ImU64 * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < float > ( const char * label_id , const float * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
template IMPLOT_API void PlotStems < double > ( const char * label_id , const double * values , int count , double y_ref , double xscale , double x0 , int offset , int stride ) ;
2020-09-02 10:17:18 -04:00
2020-09-07 17:08:59 -04:00
template < typename T >
void PlotStems ( const char * label_id , const T * xs , const T * ys , int count , double y_ref , int offset , int stride ) {
GetterXsYs < T > get_mark ( xs , ys , count , offset , stride ) ;
2020-09-15 09:56:58 -04:00
GetterXsYRef < T > get_base ( xs , y_ref , count , offset , stride ) ;
2020-09-02 10:17:18 -04:00
PlotStemsEx ( label_id , get_mark , get_base ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotStems < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < float > ( const char * label_id , const float * xs , const float * ys , int count , double y_ref , int offset , int stride ) ;
template IMPLOT_API void PlotStems < double > ( const char * label_id , const double * xs , const double * ys , int count , double y_ref , int offset , int stride ) ;
2020-09-07 17:08:59 -04:00
2021-01-15 02:52:37 -05:00
//-----------------------------------------------------------------------------
// INFINITE LINES
//-----------------------------------------------------------------------------
template < typename T >
void PlotVLines ( const char * label_id , const T * xs , int count , int offset , int stride ) {
if ( BeginItem ( label_id , ImPlotCol_Line ) ) {
const ImPlotLimits lims = GetPlotLimits ( ) ;
GetterXsYRef < T > get_min ( xs , lims . Y . Min , count , offset , stride ) ;
GetterXsYRef < T > get_max ( xs , lims . Y . Max , count , offset , stride ) ;
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < get_min . Count ; + + i )
FitPointX ( get_min ( i ) . x ) ;
}
const ImPlotNextItemData & s = GetItemData ( ) ;
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
// render stems
if ( s . RenderLine ) {
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Line ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderLineSegments ( get_min , get_max , TransformerLinLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLin : RenderLineSegments ( get_min , get_max , TransformerLogLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LinLog : RenderLineSegments ( get_min , get_max , TransformerLinLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLog : RenderLineSegments ( get_min , get_max , TransformerLogLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
}
}
EndItem ( ) ;
}
}
template IMPLOT_API void PlotVLines < ImS8 > ( const char * label_id , const ImS8 * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < ImU8 > ( const char * label_id , const ImU8 * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < ImS16 > ( const char * label_id , const ImS16 * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < ImU16 > ( const char * label_id , const ImU16 * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < ImS32 > ( const char * label_id , const ImS32 * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < ImU32 > ( const char * label_id , const ImU32 * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < ImS64 > ( const char * label_id , const ImS64 * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < ImU64 > ( const char * label_id , const ImU64 * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < float > ( const char * label_id , const float * xs , int count , int offset , int stride ) ;
template IMPLOT_API void PlotVLines < double > ( const char * label_id , const double * xs , int count , int offset , int stride ) ;
template < typename T >
void PlotHLines ( const char * label_id , const T * ys , int count , int offset , int stride ) {
if ( BeginItem ( label_id , ImPlotCol_Line ) ) {
const ImPlotLimits lims = GetPlotLimits ( ) ;
GetterXRefYs < T > get_min ( lims . X . Min , ys , count , offset , stride ) ;
GetterXRefYs < T > get_max ( lims . X . Max , ys , count , offset , stride ) ;
if ( FitThisFrame ( ) ) {
for ( int i = 0 ; i < get_min . Count ; + + i )
FitPointY ( get_min ( i ) . y ) ;
}
const ImPlotNextItemData & s = GetItemData ( ) ;
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
// render stems
if ( s . RenderLine ) {
const ImU32 col_line = ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Line ] ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderLineSegments ( get_min , get_max , TransformerLinLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLin : RenderLineSegments ( get_min , get_max , TransformerLogLin ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LinLog : RenderLineSegments ( get_min , get_max , TransformerLinLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
case ImPlotScale_LogLog : RenderLineSegments ( get_min , get_max , TransformerLogLog ( ) , DrawList , s . LineWeight , col_line ) ; break ;
}
}
EndItem ( ) ;
}
}
template IMPLOT_API void PlotHLines < ImS8 > ( const char * label_id , const ImS8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < ImU8 > ( const char * label_id , const ImU8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < ImS16 > ( const char * label_id , const ImS16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < ImU16 > ( const char * label_id , const ImU16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < ImS32 > ( const char * label_id , const ImS32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < ImU32 > ( const char * label_id , const ImU32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < ImS64 > ( const char * label_id , const ImS64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < ImU64 > ( const char * label_id , const ImU64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < float > ( const char * label_id , const float * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotHLines < double > ( const char * label_id , const double * ys , int count , int offset , int stride ) ;
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
// PLOT PIE CHART
//-----------------------------------------------------------------------------
inline void RenderPieSlice ( ImDrawList & DrawList , const ImPlotPoint & center , double radius , double a0 , double a1 , ImU32 col ) {
static const float resolution = 50 / ( 2 * IM_PI ) ;
static ImVec2 buffer [ 50 ] ;
buffer [ 0 ] = PlotToPixels ( center ) ;
int n = ImMax ( 3 , ( int ) ( ( a1 - a0 ) * resolution ) ) ;
double da = ( a1 - a0 ) / ( n - 1 ) ;
for ( int i = 0 ; i < n ; + + i ) {
double a = a0 + i * da ;
buffer [ i + 1 ] = PlotToPixels ( center . x + radius * cos ( a ) , center . y + radius * sin ( a ) ) ;
}
DrawList . AddConvexPolyFilled ( buffer , n + 1 , col ) ;
}
template < typename T >
2020-09-07 17:08:59 -04:00
void PlotPieChart ( const char * const label_ids [ ] , const T * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) {
2020-08-16 19:46:59 -04:00
IM_ASSERT_USER_ERROR ( GImPlot - > CurrentPlot ! = NULL , " PlotPieChart() needs to be called between BeginPlot() and EndPlot()! " ) ;
2020-08-30 18:12:36 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
2020-09-07 17:08:59 -04:00
double sum = 0 ;
2020-08-16 16:38:51 -04:00
for ( int i = 0 ; i < count ; + + i )
2020-09-07 17:08:59 -04:00
sum + = ( double ) values [ i ] ;
normalize = normalize | | sum > 1.0 ;
2020-08-16 16:38:51 -04:00
ImPlotPoint center ( x , y ) ;
PushPlotClipRect ( ) ;
2020-09-07 17:08:59 -04:00
double a0 = angle0 * 2 * IM_PI / 360.0 ;
double a1 = angle0 * 2 * IM_PI / 360.0 ;
2020-08-16 16:38:51 -04:00
for ( int i = 0 ; i < count ; + + i ) {
2020-09-07 17:08:59 -04:00
double percent = normalize ? ( double ) values [ i ] / sum : ( double ) values [ i ] ;
2020-08-16 16:38:51 -04:00
a1 = a0 + 2 * IM_PI * percent ;
2020-09-01 00:23:48 -04:00
if ( BeginItem ( label_ids [ i ] ) ) {
2021-03-17 08:38:45 -04:00
ImU32 col = GetCurrentItem ( ) - > Color ;
2020-08-16 16:38:51 -04:00
if ( percent < 0.5 ) {
RenderPieSlice ( DrawList , center , radius , a0 , a1 , col ) ;
}
else {
2020-09-07 17:08:59 -04:00
RenderPieSlice ( DrawList , center , radius , a0 , a0 + ( a1 - a0 ) * 0.5 , col ) ;
RenderPieSlice ( DrawList , center , radius , a0 + ( a1 - a0 ) * 0.5 , a1 , col ) ;
2020-08-16 16:38:51 -04:00
}
2020-09-01 00:23:48 -04:00
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
a0 = a1 ;
}
if ( fmt ! = NULL ) {
2020-09-07 17:08:59 -04:00
a0 = angle0 * 2 * IM_PI / 360.0 ;
a1 = angle0 * 2 * IM_PI / 360.0 ;
2020-08-16 16:38:51 -04:00
char buffer [ 32 ] ;
for ( int i = 0 ; i < count ; + + i ) {
ImPlotItem * item = GetItem ( label_ids [ i ] ) ;
2020-09-07 17:08:59 -04:00
double percent = normalize ? ( double ) values [ i ] / sum : ( double ) values [ i ] ;
2020-08-16 16:38:51 -04:00
a1 = a0 + 2 * IM_PI * percent ;
if ( item - > Show ) {
2020-09-07 17:08:59 -04:00
sprintf ( buffer , fmt , ( double ) values [ i ] ) ;
2020-08-16 16:38:51 -04:00
ImVec2 size = ImGui : : CalcTextSize ( buffer ) ;
2020-09-07 17:08:59 -04:00
double angle = a0 + ( a1 - a0 ) * 0.5 ;
ImVec2 pos = PlotToPixels ( center . x + 0.5 * radius * cos ( angle ) , center . y + 0.5 * radius * sin ( angle ) ) ;
2021-03-17 08:38:45 -04:00
ImU32 col = CalcTextColor ( ImGui : : ColorConvertU32ToFloat4 ( item - > Color ) ) ;
2020-08-16 16:38:51 -04:00
DrawList . AddText ( pos - size * 0.5f , col , buffer ) ;
}
a0 = a1 ;
}
}
PopPlotClipRect ( ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotPieChart < ImS8 > ( const char * const label_ids [ ] , const ImS8 * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < ImU8 > ( const char * const label_ids [ ] , const ImU8 * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < ImS16 > ( const char * const label_ids [ ] , const ImS16 * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < ImU16 > ( const char * const label_ids [ ] , const ImU16 * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < ImS32 > ( const char * const label_ids [ ] , const ImS32 * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < ImU32 > ( const char * const label_ids [ ] , const ImU32 * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < ImS64 > ( const char * const label_ids [ ] , const ImS64 * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < ImU64 > ( const char * const label_ids [ ] , const ImU64 * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < float > ( const char * const label_ids [ ] , const float * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
template IMPLOT_API void PlotPieChart < double > ( const char * const label_ids [ ] , const double * values , int count , double x , double y , double radius , bool normalize , const char * fmt , double angle0 ) ;
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
// PLOT HEATMAP
//-----------------------------------------------------------------------------
2021-03-17 08:38:45 -04:00
struct RectInfo {
ImPlotPoint Min , Max ;
ImU32 Color ;
} ;
template < typename TGetter , typename TTransformer >
struct RectRenderer {
inline RectRenderer ( const TGetter & getter , const TTransformer & transformer ) :
Getter ( getter ) ,
Transformer ( transformer ) ,
Prims ( Getter . Count )
{ }
inline bool operator ( ) ( ImDrawList & DrawList , const ImRect & cull_rect , const ImVec2 & uv , int prim ) const {
RectInfo rect = Getter ( prim ) ;
ImVec2 P1 = Transformer ( rect . Min ) ;
ImVec2 P2 = Transformer ( rect . Max ) ;
if ( ( rect . Color & IM_COL32_A_MASK ) = = 0 | | ! cull_rect . Overlaps ( ImRect ( ImMin ( P1 , P2 ) , ImMax ( P1 , P2 ) ) ) )
return false ;
DrawList . _VtxWritePtr [ 0 ] . pos = P1 ;
DrawList . _VtxWritePtr [ 0 ] . uv = uv ;
DrawList . _VtxWritePtr [ 0 ] . col = rect . Color ;
DrawList . _VtxWritePtr [ 1 ] . pos . x = P1 . x ;
DrawList . _VtxWritePtr [ 1 ] . pos . y = P2 . y ;
DrawList . _VtxWritePtr [ 1 ] . uv = uv ;
DrawList . _VtxWritePtr [ 1 ] . col = rect . Color ;
DrawList . _VtxWritePtr [ 2 ] . pos = P2 ;
DrawList . _VtxWritePtr [ 2 ] . uv = uv ;
DrawList . _VtxWritePtr [ 2 ] . col = rect . Color ;
DrawList . _VtxWritePtr [ 3 ] . pos . x = P2 . x ;
DrawList . _VtxWritePtr [ 3 ] . pos . y = P1 . y ;
DrawList . _VtxWritePtr [ 3 ] . uv = uv ;
DrawList . _VtxWritePtr [ 3 ] . col = rect . Color ;
DrawList . _VtxWritePtr + = 4 ;
DrawList . _IdxWritePtr [ 0 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx ) ;
DrawList . _IdxWritePtr [ 1 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 1 ) ;
DrawList . _IdxWritePtr [ 2 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 3 ) ;
DrawList . _IdxWritePtr [ 3 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 1 ) ;
DrawList . _IdxWritePtr [ 4 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 2 ) ;
DrawList . _IdxWritePtr [ 5 ] = ( ImDrawIdx ) ( DrawList . _VtxCurrentIdx + 3 ) ;
DrawList . _IdxWritePtr + = 6 ;
DrawList . _VtxCurrentIdx + = 4 ;
return true ;
}
const TGetter & Getter ;
const TTransformer & Transformer ;
const int Prims ;
static const int IdxConsumed = 6 ;
static const int VtxConsumed = 4 ;
} ;
template < typename T >
struct GetterHeatmap {
GetterHeatmap ( const T * values , int rows , int cols , double scale_min , double scale_max , double width , double height , double xref , double yref , double ydir ) :
Values ( values ) ,
Count ( rows * cols ) ,
Rows ( rows ) ,
Cols ( cols ) ,
ScaleMin ( scale_min ) ,
ScaleMax ( scale_max ) ,
Width ( width ) ,
Height ( height ) ,
XRef ( xref ) ,
YRef ( yref ) ,
YDir ( ydir ) ,
HalfSize ( Width * 0.5 , Height * 0.5 )
{ }
inline RectInfo operator ( ) ( int idx ) const {
double val = ( double ) Values [ idx ] ;
const int r = idx / Cols ;
const int c = idx % Cols ;
const ImPlotPoint p ( XRef + HalfSize . x + c * Width , YRef + YDir * ( HalfSize . y + r * Height ) ) ;
RectInfo rect ;
rect . Min . x = p . x - HalfSize . x ;
rect . Min . y = p . y - HalfSize . y ;
rect . Max . x = p . x + HalfSize . x ;
rect . Max . y = p . y + HalfSize . y ;
const float t = ImClamp ( ( float ) ImRemap01 ( val , ScaleMin , ScaleMax ) , 0.0f , 1.0f ) ;
rect . Color = GImPlot - > ColormapData . LerpTable ( GImPlot - > Style . Colormap , t ) ;
return rect ;
}
const T * const Values ;
const int Count , Rows , Cols ;
const double ScaleMin , ScaleMax , Width , Height , XRef , YRef , YDir ;
const ImPlotPoint HalfSize ;
} ;
2020-08-16 16:38:51 -04:00
template < typename T , typename Transformer >
2021-03-17 08:38:45 -04:00
void RenderHeatmap ( Transformer transformer , ImDrawList & DrawList , const T * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max , bool reverse_y ) {
2020-08-16 16:38:51 -04:00
ImPlotContext & gp = * GImPlot ;
2021-03-20 00:43:03 -04:00
if ( scale_min = = 0 & & scale_max = = 0 ) {
T temp_min , temp_max ;
ImMinMaxArray ( values , rows * cols , & temp_min , & temp_max ) ;
scale_min = ( double ) temp_min ;
scale_max = ( double ) temp_max ;
}
2021-03-17 08:38:45 -04:00
if ( scale_min = = scale_max ) {
ImVec2 a = transformer ( bounds_min ) ;
ImVec2 b = transformer ( bounds_max ) ;
ImU32 col = GetColormapColorU32 ( 0 , gp . Style . Colormap ) ;
DrawList . AddRectFilled ( a , b , col ) ;
return ;
}
const double yref = reverse_y ? bounds_max . y : bounds_min . y ;
const double ydir = reverse_y ? - 1 : 1 ;
GetterHeatmap < T > getter ( values , rows , cols , scale_min , scale_max , ( bounds_max . x - bounds_min . x ) / cols , ( bounds_max . y - bounds_min . y ) / rows , bounds_min . x , yref , ydir ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderPrimitives ( RectRenderer < GetterHeatmap < T > , TransformerLinLin > ( getter , TransformerLinLin ( ) ) , DrawList , gp . CurrentPlot - > PlotRect ) ; break ;
case ImPlotScale_LogLin : RenderPrimitives ( RectRenderer < GetterHeatmap < T > , TransformerLogLin > ( getter , TransformerLogLin ( ) ) , DrawList , gp . CurrentPlot - > PlotRect ) ; break ; ;
case ImPlotScale_LinLog : RenderPrimitives ( RectRenderer < GetterHeatmap < T > , TransformerLinLog > ( getter , TransformerLinLog ( ) ) , DrawList , gp . CurrentPlot - > PlotRect ) ; break ; ;
case ImPlotScale_LogLog : RenderPrimitives ( RectRenderer < GetterHeatmap < T > , TransformerLogLog > ( getter , TransformerLogLog ( ) ) , DrawList , gp . CurrentPlot - > PlotRect ) ; break ; ;
2020-08-16 16:38:51 -04:00
}
if ( fmt ! = NULL ) {
2021-03-17 08:38:45 -04:00
const double w = ( bounds_max . x - bounds_min . x ) / cols ;
const double h = ( bounds_max . y - bounds_min . y ) / rows ;
const ImPlotPoint half_size ( w * 0.5 , h * 0.5 ) ;
int i = 0 ;
2020-08-16 16:38:51 -04:00
for ( int r = 0 ; r < rows ; + + r ) {
for ( int c = 0 ; c < cols ; + + c ) {
ImPlotPoint p ;
p . x = bounds_min . x + 0.5 * w + c * w ;
2021-03-17 08:38:45 -04:00
p . y = yref + ydir * ( 0.5 * h + r * h ) ;
2020-08-16 16:38:51 -04:00
ImVec2 px = transformer ( p ) ;
char buff [ 32 ] ;
sprintf ( buff , fmt , values [ i ] ) ;
ImVec2 size = ImGui : : CalcTextSize ( buff ) ;
2021-03-17 08:38:45 -04:00
double t = ImClamp ( ImRemap01 ( ( double ) values [ i ] , scale_min , scale_max ) , 0.0 , 1.0 ) ;
ImVec4 color = SampleColormap ( ( float ) t ) ;
2020-08-16 16:38:51 -04:00
ImU32 col = CalcTextColor ( color ) ;
DrawList . AddText ( px - size * 0.5f , col , buff ) ;
i + + ;
}
}
}
}
template < typename T >
2020-09-07 17:08:59 -04:00
void PlotHeatmap ( const char * label_id , const T * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) {
2020-08-30 22:03:11 -04:00
if ( BeginItem ( label_id ) ) {
if ( FitThisFrame ( ) ) {
FitPoint ( bounds_min ) ;
FitPoint ( bounds_max ) ;
}
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
switch ( GetCurrentScale ( ) ) {
2021-03-17 08:38:45 -04:00
case ImPlotScale_LinLin : RenderHeatmap ( TransformerLinLin ( ) , DrawList , values , rows , cols , scale_min , scale_max , fmt , bounds_min , bounds_max , true ) ; break ;
case ImPlotScale_LogLin : RenderHeatmap ( TransformerLogLin ( ) , DrawList , values , rows , cols , scale_min , scale_max , fmt , bounds_min , bounds_max , true ) ; break ;
case ImPlotScale_LinLog : RenderHeatmap ( TransformerLinLog ( ) , DrawList , values , rows , cols , scale_min , scale_max , fmt , bounds_min , bounds_max , true ) ; break ;
case ImPlotScale_LogLog : RenderHeatmap ( TransformerLogLog ( ) , DrawList , values , rows , cols , scale_min , scale_max , fmt , bounds_min , bounds_max , true ) ; break ;
2020-08-30 22:03:11 -04:00
}
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotHeatmap < ImS8 > ( const char * label_id , const ImS8 * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < ImU8 > ( const char * label_id , const ImU8 * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < ImS16 > ( const char * label_id , const ImS16 * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < ImU16 > ( const char * label_id , const ImU16 * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < ImS32 > ( const char * label_id , const ImS32 * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < ImU32 > ( const char * label_id , const ImU32 * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < ImS64 > ( const char * label_id , const ImS64 * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < ImU64 > ( const char * label_id , const ImU64 * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < float > ( const char * label_id , const float * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
template IMPLOT_API void PlotHeatmap < double > ( const char * label_id , const double * values , int rows , int cols , double scale_min , double scale_max , const char * fmt , const ImPlotPoint & bounds_min , const ImPlotPoint & bounds_max ) ;
2020-08-16 16:38:51 -04:00
2021-03-17 08:38:45 -04:00
//-----------------------------------------------------------------------------
// PLOT HISTOGRAM
//-----------------------------------------------------------------------------
template < typename T >
double PlotHistogram ( const char * label_id , const T * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) {
if ( count < = 0 | | bins = = 0 )
return 0 ;
if ( range . Min = = 0 & & range . Max = = 0 ) {
T Min , Max ;
ImMinMaxArray ( values , count , & Min , & Max ) ;
range . Min = ( double ) Min ;
range . Max = ( double ) Max ;
}
double width ;
if ( bins < 0 )
CalculateBins ( values , count , bins , range , bins , width ) ;
else
width = range . Size ( ) / bins ;
ImVector < double > & bin_centers = GImPlot - > Temp1 ;
ImVector < double > & bin_counts = GImPlot - > Temp2 ;
bin_centers . resize ( bins ) ;
bin_counts . resize ( bins ) ;
int below = 0 ;
for ( int b = 0 ; b < bins ; + + b ) {
bin_centers [ b ] = range . Min + b * width + width * 0.5 ;
bin_counts [ b ] = 0 ;
}
int counted = 0 ;
double max_count = 0 ;
for ( int i = 0 ; i < count ; + + i ) {
double val = ( double ) values [ i ] ;
if ( range . Contains ( val ) ) {
const int b = ImClamp ( ( int ) ( ( val - range . Min ) / width ) , 0 , bins - 1 ) ;
bin_counts [ b ] + = 1.0 ;
if ( bin_counts [ b ] > max_count )
max_count = bin_counts [ b ] ;
counted + + ;
}
else if ( val < range . Min ) {
below + + ;
}
}
if ( cumulative & & density ) {
if ( outliers )
bin_counts [ 0 ] + = below ;
for ( int b = 1 ; b < bins ; + + b )
bin_counts [ b ] + = bin_counts [ b - 1 ] ;
double scale = 1.0 / ( outliers ? count : counted ) ;
for ( int b = 0 ; b < bins ; + + b )
bin_counts [ b ] * = scale ;
max_count = bin_counts [ bins - 1 ] ;
}
else if ( cumulative ) {
if ( outliers )
bin_counts [ 0 ] + = below ;
for ( int b = 1 ; b < bins ; + + b )
bin_counts [ b ] + = bin_counts [ b - 1 ] ;
max_count = bin_counts [ bins - 1 ] ;
}
else if ( density ) {
double scale = 1.0 / ( ( outliers ? count : counted ) * width ) ;
for ( int b = 0 ; b < bins ; + + b )
bin_counts [ b ] * = scale ;
max_count * = scale ;
}
PlotBars ( label_id , & bin_centers . Data [ 0 ] , & bin_counts . Data [ 0 ] , bins , bar_scale * width ) ;
return max_count ;
}
template IMPLOT_API double PlotHistogram < ImS8 > ( const char * label_id , const ImS8 * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < ImU8 > ( const char * label_id , const ImU8 * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < ImS16 > ( const char * label_id , const ImS16 * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < ImU16 > ( const char * label_id , const ImU16 * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < ImS32 > ( const char * label_id , const ImS32 * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < ImU32 > ( const char * label_id , const ImU32 * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < ImS64 > ( const char * label_id , const ImS64 * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < ImU64 > ( const char * label_id , const ImU64 * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < float > ( const char * label_id , const float * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
template IMPLOT_API double PlotHistogram < double > ( const char * label_id , const double * values , int count , int bins , bool cumulative , bool density , ImPlotRange range , bool outliers , double bar_scale ) ;
//-----------------------------------------------------------------------------
// PLOT HISTOGRAM 2D
//-----------------------------------------------------------------------------
template < typename T >
double PlotHistogram2D ( const char * label_id , const T * xs , const T * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) {
if ( count < = 0 | | x_bins = = 0 | | y_bins = = 0 )
return 0 ;
if ( range . X . Min = = 0 & & range . X . Max = = 0 ) {
T Min , Max ;
ImMinMaxArray ( xs , count , & Min , & Max ) ;
range . X . Min = ( double ) Min ;
range . X . Max = ( double ) Max ;
}
if ( range . Y . Min = = 0 & & range . Y . Max = = 0 ) {
T Min , Max ;
ImMinMaxArray ( ys , count , & Min , & Max ) ;
range . Y . Min = ( double ) Min ;
range . Y . Max = ( double ) Max ;
}
double width , height ;
if ( x_bins < 0 )
CalculateBins ( xs , count , x_bins , range . X , x_bins , width ) ;
else
width = range . X . Size ( ) / x_bins ;
if ( y_bins < 0 )
CalculateBins ( ys , count , y_bins , range . Y , y_bins , height ) ;
else
height = range . Y . Size ( ) / y_bins ;
const int bins = x_bins * y_bins ;
ImVector < double > & bin_counts = GImPlot - > Temp1 ;
bin_counts . resize ( bins ) ;
for ( int b = 0 ; b < bins ; + + b )
bin_counts [ b ] = 0 ;
int counted = 0 ;
double max_count = 0 ;
for ( int i = 0 ; i < count ; + + i ) {
if ( range . Contains ( ( double ) xs [ i ] , ( double ) ys [ i ] ) ) {
const int xb = ImClamp ( ( int ) ( ( double ) ( xs [ i ] - range . X . Min ) / width ) , 0 , x_bins - 1 ) ;
const int yb = ImClamp ( ( int ) ( ( double ) ( ys [ i ] - range . Y . Min ) / height ) , 0 , y_bins - 1 ) ;
const int b = yb * x_bins + xb ;
bin_counts [ b ] + = 1.0 ;
if ( bin_counts [ b ] > max_count )
max_count = bin_counts [ b ] ;
counted + + ;
}
}
if ( density ) {
double scale = 1.0 / ( ( outliers ? count : counted ) * width * height ) ;
for ( int b = 0 ; b < bins ; + + b )
bin_counts [ b ] * = scale ;
max_count * = scale ;
}
if ( BeginItem ( label_id ) ) {
if ( FitThisFrame ( ) ) {
FitPoint ( range . Min ( ) ) ;
FitPoint ( range . Max ( ) ) ;
}
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
switch ( GetCurrentScale ( ) ) {
case ImPlotScale_LinLin : RenderHeatmap ( TransformerLinLin ( ) , DrawList , & bin_counts . Data [ 0 ] , y_bins , x_bins , 0 , max_count , NULL , range . Min ( ) , range . Max ( ) , false ) ; break ;
case ImPlotScale_LogLin : RenderHeatmap ( TransformerLogLin ( ) , DrawList , & bin_counts . Data [ 0 ] , y_bins , x_bins , 0 , max_count , NULL , range . Min ( ) , range . Max ( ) , false ) ; break ;
case ImPlotScale_LinLog : RenderHeatmap ( TransformerLinLog ( ) , DrawList , & bin_counts . Data [ 0 ] , y_bins , x_bins , 0 , max_count , NULL , range . Min ( ) , range . Max ( ) , false ) ; break ;
case ImPlotScale_LogLog : RenderHeatmap ( TransformerLogLog ( ) , DrawList , & bin_counts . Data [ 0 ] , y_bins , x_bins , 0 , max_count , NULL , range . Min ( ) , range . Max ( ) , false ) ; break ;
}
EndItem ( ) ;
}
return max_count ;
}
template IMPLOT_API double PlotHistogram2D < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < float > ( const char * label_id , const float * xs , const float * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
template IMPLOT_API double PlotHistogram2D < double > ( const char * label_id , const double * xs , const double * ys , int count , int x_bins , int y_bins , bool density , ImPlotLimits range , bool outliers ) ;
2020-08-16 16:38:51 -04:00
//-----------------------------------------------------------------------------
// PLOT DIGITAL
//-----------------------------------------------------------------------------
2020-09-07 17:08:59 -04:00
// TODO: Make this behave like all the other plot types (.e. not fixed in y axis)
2020-08-16 16:38:51 -04:00
2020-08-30 22:03:11 -04:00
template < typename Getter >
inline void PlotDigitalEx ( const char * label_id , Getter getter ) {
if ( BeginItem ( label_id , ImPlotCol_Fill ) ) {
ImPlotContext & gp = * GImPlot ;
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
2020-09-15 10:48:46 -04:00
const ImPlotNextItemData & s = GetItemData ( ) ;
2020-08-30 22:03:11 -04:00
if ( getter . Count > 1 & & s . RenderFill ) {
const int y_axis = GetCurrentYAxis ( ) ;
int pixYMax = 0 ;
ImPlotPoint itemData1 = getter ( 0 ) ;
for ( int i = 0 ; i < getter . Count ; + + i ) {
ImPlotPoint itemData2 = getter ( i ) ;
2020-09-04 20:33:10 -04:00
if ( ImNanOrInf ( itemData1 . y ) ) {
2020-08-30 22:03:11 -04:00
itemData1 = itemData2 ;
continue ;
}
2020-09-04 20:33:10 -04:00
if ( ImNanOrInf ( itemData2 . y ) ) itemData2 . y = ImConstrainNan ( ImConstrainInf ( itemData2 . y ) ) ;
2020-08-30 22:03:11 -04:00
int pixY_0 = ( int ) ( s . LineWeight ) ;
itemData1 . y = ImMax ( 0.0 , itemData1 . y ) ;
float pixY_1_float = s . DigitalBitHeight * ( float ) itemData1 . y ;
int pixY_1 = ( int ) ( pixY_1_float ) ; //allow only positive values
int pixY_chPosOffset = ( int ) ( ImMax ( s . DigitalBitHeight , pixY_1_float ) + s . DigitalBitGap ) ;
pixYMax = ImMax ( pixYMax , pixY_chPosOffset ) ;
ImVec2 pMin = PlotToPixels ( itemData1 ) ;
ImVec2 pMax = PlotToPixels ( itemData2 ) ;
int pixY_Offset = 20 ; //20 pixel from bottom due to mouse cursor label
pMin . y = ( gp . PixelRange [ y_axis ] . Min . y ) + ( ( - gp . DigitalPlotOffset ) - pixY_Offset ) ;
pMax . y = ( gp . PixelRange [ y_axis ] . Min . y ) + ( ( - gp . DigitalPlotOffset ) - pixY_0 - pixY_1 - pixY_Offset ) ;
//plot only one rectangle for same digital state
while ( ( ( i + 2 ) < getter . Count ) & & ( itemData1 . y = = itemData2 . y ) ) {
const int in = ( i + 1 ) ;
itemData2 = getter ( in ) ;
2020-09-04 20:33:10 -04:00
if ( ImNanOrInf ( itemData2 . y ) ) break ;
2020-08-30 22:03:11 -04:00
pMax . x = PlotToPixels ( itemData2 ) . x ;
i + + ;
}
//do not extend plot outside plot range
if ( pMin . x < gp . PixelRange [ y_axis ] . Min . x ) pMin . x = gp . PixelRange [ y_axis ] . Min . x ;
if ( pMax . x < gp . PixelRange [ y_axis ] . Min . x ) pMax . x = gp . PixelRange [ y_axis ] . Min . x ;
if ( pMin . x > gp . PixelRange [ y_axis ] . Max . x ) pMin . x = gp . PixelRange [ y_axis ] . Max . x ;
if ( pMax . x > gp . PixelRange [ y_axis ] . Max . x ) pMax . x = gp . PixelRange [ y_axis ] . Max . x ;
//plot a rectangle that extends up to x2 with y1 height
2020-11-15 22:47:06 -05:00
if ( ( pMax . x > pMin . x ) & & ( gp . CurrentPlot - > PlotRect . Contains ( pMin ) | | gp . CurrentPlot - > PlotRect . Contains ( pMax ) ) ) {
2020-08-30 22:03:11 -04:00
// ImVec4 colAlpha = item->Color;
// colAlpha.w = item->Highlight ? 1.0f : 0.9f;
DrawList . AddRectFilled ( pMin , pMax , ImGui : : GetColorU32 ( s . Colors [ ImPlotCol_Fill ] ) ) ;
}
2020-08-16 16:38:51 -04:00
itemData1 = itemData2 ;
}
2020-08-30 22:03:11 -04:00
gp . DigitalPlotItemCnt + + ;
gp . DigitalPlotOffset + = pixYMax ;
2020-08-16 16:38:51 -04:00
}
2020-08-30 22:03:11 -04:00
EndItem ( ) ;
2020-08-16 16:38:51 -04:00
}
}
2020-09-07 17:08:59 -04:00
template < typename T >
void PlotDigital ( const char * label_id , const T * xs , const T * ys , int count , int offset , int stride ) {
GetterXsYs < T > getter ( xs , ys , count , offset , stride ) ;
2020-08-16 16:38:51 -04:00
return PlotDigitalEx ( label_id , getter ) ;
}
2020-09-07 21:59:43 -04:00
template IMPLOT_API void PlotDigital < ImS8 > ( const char * label_id , const ImS8 * xs , const ImS8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < ImU8 > ( const char * label_id , const ImU8 * xs , const ImU8 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < ImS16 > ( const char * label_id , const ImS16 * xs , const ImS16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < ImU16 > ( const char * label_id , const ImU16 * xs , const ImU16 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < ImS32 > ( const char * label_id , const ImS32 * xs , const ImS32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < ImU32 > ( const char * label_id , const ImU32 * xs , const ImU32 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < ImS64 > ( const char * label_id , const ImS64 * xs , const ImS64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < ImU64 > ( const char * label_id , const ImU64 * xs , const ImU64 * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < float > ( const char * label_id , const float * xs , const float * ys , int count , int offset , int stride ) ;
template IMPLOT_API void PlotDigital < double > ( const char * label_id , const double * xs , const double * ys , int count , int offset , int stride ) ;
2020-09-07 17:08:59 -04:00
2020-08-16 16:38:51 -04:00
// custom
2020-09-07 17:08:59 -04:00
void PlotDigitalG ( const char * label_id , ImPlotPoint ( * getter_func ) ( void * data , int idx ) , void * data , int count , int offset ) {
2020-09-15 09:56:58 -04:00
GetterFuncPtr getter ( getter_func , data , count , offset ) ;
2020-08-16 16:38:51 -04:00
return PlotDigitalEx ( label_id , getter ) ;
}
2020-09-17 12:58:58 -04:00
//-----------------------------------------------------------------------------
// PLOT IMAGE
//-----------------------------------------------------------------------------
void PlotImage ( const char * label_id , ImTextureID user_texture_id , const ImPlotPoint & bmin , const ImPlotPoint & bmax , const ImVec2 & uv0 , const ImVec2 & uv1 , const ImVec4 & tint_col ) {
if ( BeginItem ( label_id ) ) {
if ( FitThisFrame ( ) ) {
FitPoint ( bmin ) ;
FitPoint ( bmax ) ;
}
2021-03-17 08:38:45 -04:00
ImU32 tint_col32 = ImGui : : ColorConvertFloat4ToU32 ( tint_col ) ;
GetCurrentItem ( ) - > Color = tint_col32 ;
2020-09-17 12:58:58 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
ImVec2 p1 = PlotToPixels ( bmin . x , bmax . y ) ;
ImVec2 p2 = PlotToPixels ( bmax . x , bmin . y ) ;
PushPlotClipRect ( ) ;
2021-03-17 08:38:45 -04:00
DrawList . AddImage ( user_texture_id , p1 , p2 , uv0 , uv1 , tint_col32 ) ;
2020-09-17 21:34:37 -04:00
PopPlotClipRect ( ) ;
2020-09-17 12:58:58 -04:00
EndItem ( ) ;
}
}
2020-08-17 17:26:45 -04:00
//-----------------------------------------------------------------------------
// PLOT TEXT
//-----------------------------------------------------------------------------
2020-08-16 16:38:51 -04:00
// double
void PlotText ( const char * text , double x , double y , bool vertical , const ImVec2 & pixel_offset ) {
2020-08-16 19:46:59 -04:00
IM_ASSERT_USER_ERROR ( GImPlot - > CurrentPlot ! = NULL , " PlotText() needs to be called between BeginPlot() and EndPlot()! " ) ;
2020-08-30 18:12:36 -04:00
ImDrawList & DrawList = * GetPlotDrawList ( ) ;
2020-08-16 16:38:51 -04:00
PushPlotClipRect ( ) ;
2020-09-01 00:23:48 -04:00
ImU32 colTxt = GetStyleColorU32 ( ImPlotCol_InlayText ) ;
2020-08-17 19:31:30 -04:00
if ( vertical ) {
ImVec2 ctr = CalcTextSizeVertical ( text ) * 0.5f ;
ImVec2 pos = PlotToPixels ( ImPlotPoint ( x , y ) ) + ImVec2 ( - ctr . x , ctr . y ) + pixel_offset ;
2020-08-24 09:51:03 -04:00
AddTextVertical ( & DrawList , pos , colTxt , text ) ;
2020-08-17 19:31:30 -04:00
}
else {
ImVec2 pos = PlotToPixels ( ImPlotPoint ( x , y ) ) - ImGui : : CalcTextSize ( text ) * 0.5f + pixel_offset ;
2020-08-16 16:38:51 -04:00
DrawList . AddText ( pos , colTxt , text ) ;
2020-08-17 19:31:30 -04:00
}
2020-08-16 16:38:51 -04:00
PopPlotClipRect ( ) ;
}
2020-10-19 00:26:34 -04:00
//-----------------------------------------------------------------------------
// PLOT DUMMY
//-----------------------------------------------------------------------------
void PlotDummy ( const char * label_id ) {
if ( BeginItem ( label_id , ImPlotCol_Line ) )
EndItem ( ) ;
}
2020-08-16 16:38:51 -04:00
} // namespace ImPlot