1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-13 22:48:50 -05:00
* SubPlots: Y axis padding over multiple plots

* Align Plots Group

new signature ID, ImPool  to store padding data, demo

* Align plots orientation (vertically, horizontally)

vertical will align Y axis, horizontal will align X axis.
*signature changed

* ImPlotOrientation used as flag for 2D grids of aligned plots

https://github.com/epezent/implot/pull/144#issuecomment-725849368

* AlignPlots updates to merge with v.0.9

* Sync to v0.9 20210127

* subplots proto

* make link flags work

* stuff

* add multi-line centered titles

* subplots work

* flag ideas

* better subplot positioning

* resizable subplots

* subplot shared items

* subplot ratios

* some cleanup and refactor

* some cleanup and refactor

* refactors and demo reorganization

* context menus...almost done!

* context menus, bug fixes

* active id

* make implot use ButtonBehavior throughout

* bug fixes

* more bug fixes

* tweaks

* fix id issue

* finish work on subplots

Co-authored-by: ozlb <ozlb@users.noreply.github.com>
This commit is contained in:
Evan Pezent 2021-07-07 21:06:15 -07:00 committed by GitHub
parent 65aa2c8264
commit 8c1bbf4d8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 3057 additions and 2027 deletions

View File

@ -30,6 +30,7 @@ ImPlot is an immediate mode, GPU accelerated plotting library for [Dear ImGui](h
- and more likely to come - and more likely to come
- mix/match multiple plot items on a single plot - mix/match multiple plot items on a single plot
- configurable axes ranges and scaling (linear/log) - configurable axes ranges and scaling (linear/log)
- subplots
- time formatted x-axes (US formatted or ISO 8601) - time formatted x-axes (US formatted or ISO 8601)
- reversible and lockable axes - reversible and lockable axes
- up to three independent y-axes - up to three independent y-axes

1717
implot.cpp

File diff suppressed because it is too large Load Diff

119
implot.h
View File

@ -52,18 +52,19 @@
struct ImPlotContext; // ImPlot context (opaque struct, see implot_internal.h) struct ImPlotContext; // ImPlot context (opaque struct, see implot_internal.h)
// Enums/Flags // Enums/Flags
typedef int ImPlotFlags; // -> enum ImPlotFlags_ typedef int ImPlotFlags; // -> enum ImPlotFlags_
typedef int ImPlotAxisFlags; // -> enum ImPlotAxisFlags_ typedef int ImPlotAxisFlags; // -> enum ImPlotAxisFlags_
typedef int ImPlotCol; // -> enum ImPlotCol_ typedef int ImPlotSubplotFlags; // -> enum ImPlotSubplotFlags_
typedef int ImPlotStyleVar; // -> enum ImPlotStyleVar_ typedef int ImPlotCol; // -> enum ImPlotCol_
typedef int ImPlotMarker; // -> enum ImPlotMarker_ typedef int ImPlotStyleVar; // -> enum ImPlotStyleVar_
typedef int ImPlotColormap; // -> enum ImPlotColormap_ typedef int ImPlotMarker; // -> enum ImPlotMarker_
typedef int ImPlotLocation; // -> enum ImPlotLocation_ typedef int ImPlotColormap; // -> enum ImPlotColormap_
typedef int ImPlotOrientation; // -> enum ImPlotOrientation_ typedef int ImPlotLocation; // -> enum ImPlotLocation_
typedef int ImPlotYAxis; // -> enum ImPlotYAxis_; typedef int ImPlotOrientation; // -> enum ImPlotOrientation_
typedef int ImPlotBin; // -> enum ImPlotBin_ typedef int ImPlotYAxis; // -> enum ImPlotYAxis_;
typedef int ImPlotBin; // -> enum ImPlotBin_
// Options for plots. // Options for plots (see BeginPlot).
enum ImPlotFlags_ { enum ImPlotFlags_ {
ImPlotFlags_None = 0, // default ImPlotFlags_None = 0, // default
ImPlotFlags_NoTitle = 1 << 0, // the plot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MyPlot") ImPlotFlags_NoTitle = 1 << 0, // the plot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MyPlot")
@ -82,7 +83,7 @@ enum ImPlotFlags_ {
ImPlotFlags_CanvasOnly = ImPlotFlags_NoTitle | ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMousePos ImPlotFlags_CanvasOnly = ImPlotFlags_NoTitle | ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMousePos
}; };
// Options for plot axes (X and Y). // Options for plot axes (see BeginPlot).
enum ImPlotAxisFlags_ { enum ImPlotAxisFlags_ {
ImPlotAxisFlags_None = 0, // default ImPlotAxisFlags_None = 0, // default
ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels also hidden if the supplied string name is NULL) ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels also hidden if the supplied string name is NULL)
@ -102,6 +103,22 @@ enum ImPlotAxisFlags_ {
ImPlotAxisFlags_NoDecorations = ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels ImPlotAxisFlags_NoDecorations = ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_NoTickMarks | ImPlotAxisFlags_NoTickLabels
}; };
// Options for subplots (see BeginSubplot).
enum ImPlotSubplotFlags_ {
ImPlotSubplotFlags_None = 0, // default
ImPlotSubplotFlags_NoTitle = 1 << 0, // the subplot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MySubplot")
ImPlotSubplotFlags_NoLegend = 1 << 1, // the legend will not be displayed (only applicable if ImPlotSubplotFlags_ShareItems is enabled)
ImPlotSubplotFlags_NoMenus = 1 << 2, // the user will not be able to open context menus with right-click
ImPlotSubplotFlags_NoResize = 1 << 3, // resize splitters between subplot cells will be not be provided
ImPlotSubplotFlags_NoAlign = 1 << 4, // subplot edges will not be aligned vertically or horizontally
ImPlotSubplotFlags_ShareItems = 1 << 5, // items across all subplots will be shared and rendered into a single legend entry
ImPlotSubplotFlags_LinkRows = 1 << 6, // link the y-axis limits of all plots in each row (does not apply auxiliary y-axes)
ImPlotSubplotFlags_LinkCols = 1 << 7, // link the x-axis limits of all plots in each column
ImPlotSubplotFlags_LinkAllX = 1 << 8, // link the x-axis limits in every plot in the subplot
ImPlotSubplotFlags_LinkAllY = 1 << 9 , // link the y-axis limits in every plot in the subplot (does not apply to auxiliary y-axes)
ImPlotSubplotFlags_ColMajor = 1 << 10 // subplots are added in column major order instead of the default row major order
};
// Plot styling colors. // Plot styling colors.
enum ImPlotCol_ { enum ImPlotCol_ {
// item styling colors // item styling colors
@ -301,7 +318,7 @@ struct ImPlotStyle {
ImVec2 AnnotationPadding; // = 2,2 text padding around annotation labels ImVec2 AnnotationPadding; // = 2,2 text padding around annotation labels
ImVec2 FitPadding; // = 0,0 additional fit padding as a percentage of the fit extents (e.g. ImVec2(0.1f,0.1f) adds 10% to the fit extents of X and Y) ImVec2 FitPadding; // = 0,0 additional fit padding as a percentage of the fit extents (e.g. ImVec2(0.1f,0.1f) adds 10% to the fit extents of X and Y)
ImVec2 PlotDefaultSize; // = 400,300 default size used when ImVec2(0,0) is passed to BeginPlot ImVec2 PlotDefaultSize; // = 400,300 default size used when ImVec2(0,0) is passed to BeginPlot
ImVec2 PlotMinSize; // = 300,225 minimum size plot frame can be when shrunk ImVec2 PlotMinSize; // = 200,150 minimum size plot frame can be when shrunk
// style colors // style colors
ImVec4 Colors[ImPlotCol_COUNT]; // Array of styling colors. Indexable with ImPlotCol_ enums. ImVec4 Colors[ImPlotCol_COUNT]; // Array of styling colors. Indexable with ImPlotCol_ enums.
// colormap // colormap
@ -380,6 +397,67 @@ IMPLOT_API bool BeginPlot(const char* title_id,
// of an if statement conditioned on BeginPlot(). See example above. // of an if statement conditioned on BeginPlot(). See example above.
IMPLOT_API void EndPlot(); IMPLOT_API void EndPlot();
//-----------------------------------------------------------------------------
// Begin/EndSubplots
//-----------------------------------------------------------------------------
// Starts a subdivided plotting context. If the function returns true,
// EndSubplots() MUST be called! Call BeginPlot/EndPlot AT MOST [rows*cols]
// times in between the begining and end of the subplot context. Plots are
// added in row major order.
//
// Example:
//
// if (BeginSubplots("My Subplot",2,3,ImVec2(800,400)) {
// for (int i = 0; i < 6; ++i) {
// if (BeginPlot(...)) {
// ImPlot::PlotLine(...);
// ...
// EndPlot();
// }
// }
// EndSubplots();
// }
//
// Procudes:
//
// [0][1][2]
// [3][4][5]
//
// Important notes:
//
// - #title_id must be unique to the current ImGui ID scope. If you need to avoid ID
// collisions or don't want to display a title in the plot, use double hashes
// (e.g. "MyPlot##HiddenIdText" or "##NoTitle").
// - #rows and #cols must be greater than 0.
// - #size is the size of the entire grid of subplots, not the individual plots
// - #row_ratios and #col_ratios must have AT LEAST #rows and #cols elements,
// respectively. These are the sizes of the rows and columns expressed in ratios.
// If the user adjusts the dimensions, the arrays are updated with new ratios.
//
// Important notes regarding BeginPlot from inside of BeginSubplots:
//
// - The #title_id parameter of _BeginPlot_ (see above) does NOT have to be
// unique when called inside of a subplot context. Subplot IDs are hashed
// for your convenience so you don't have call PushID or generate unique title
// strings. Simply pass an empty string to BeginPlot unless you want to title
// each subplot.
// - The #size parameter of _BeginPlot_ (see above) is ignored when inside of a
// subplot context. The actual size of the subplot will be based on the
// #size value you pass to _BeginSubplots_ and #row/#col_ratios if provided.
IMPLOT_API bool BeginSubplots(const char* title_id,
int rows,
int cols,
const ImVec2& size,
ImPlotSubplotFlags flags = ImPlotSubplotFlags_None,
float* row_ratios = NULL,
float* col_ratios = NULL);
// Only call EndSubplots() if BeginSubplots() returns true! Typically called at the end
// of an if statement conditioned on BeginSublots(). See example above.
IMPLOT_API void EndSubplots();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Plot Items // Plot Items
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -573,6 +651,19 @@ IMPLOT_API ImPlotLimits GetPlotQuery(ImPlotYAxis y_axis = IMPLOT_AUTO);
// Set the current plot query bounds. Query must be enabled with ImPlotFlags_Query. // Set the current plot query bounds. Query must be enabled with ImPlotFlags_Query.
IMPLOT_API void SetPlotQuery(const ImPlotLimits& query, ImPlotYAxis y_axis = IMPLOT_AUTO); IMPLOT_API void SetPlotQuery(const ImPlotLimits& query, ImPlotYAxis y_axis = IMPLOT_AUTO);
//-----------------------------------------------------------------------------
// Algined Plots
//-----------------------------------------------------------------------------
// Consider using Begin/EndSubplots first. They are more feature rich and
// accomplish the same behaviour by default. The functions below offer lower
// level control of plot alignment.
// Align axis padding over multiple plots in a single row or column. If this function returns true, EndAlignedPlots() must be called. #group_id must be unique.
IMPLOT_API bool BeginAlignedPlots(const char* group_id, ImPlotOrientation orientation = ImPlotOrientation_Vertical);
// Only call EndAlignedPlots() if BeginAlignedPlots() returns true!
IMPLOT_API void EndAlignedPlots();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Plot Tools // Plot Tools
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -604,7 +695,7 @@ IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label
// The following functions MUST be called BETWEEN Begin/EndPlot! // The following functions MUST be called BETWEEN Begin/EndPlot!
// Set the location of the current plot's legend (default = North|West). // Set the location of the current plot's (or subplot's) legend.
IMPLOT_API void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation = ImPlotOrientation_Vertical, bool outside = false); IMPLOT_API void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation = ImPlotOrientation_Vertical, bool outside = false);
// Set the location of the current plot's mouse position text (default = South|East). // Set the location of the current plot's mouse position text (default = South|East).
IMPLOT_API void SetMousePosLocation(ImPlotLocation location); IMPLOT_API void SetMousePosLocation(ImPlotLocation location);

File diff suppressed because it is too large Load Diff

View File

@ -139,6 +139,14 @@ static inline void ImMinMaxArray(const T* values, int count, T* min_out, T* max_
} }
*min_out = Min; *max_out = Max; *min_out = Min; *max_out = Max;
} }
// Finds the sim of an array
template <typename T>
static inline T ImSum(const T* values, int count) {
T sum = 0;
for (int i = 0; i < count; ++i)
sum += values[i];
return sum;
}
// Finds the mean of an array // Finds the mean of an array
template <typename T> template <typename T>
static inline double ImMean(const T* values, int count) { static inline double ImMean(const T* values, int count) {
@ -698,6 +706,28 @@ struct ImPlotAxis
inline bool IsLog() const { return ImHasFlag(Flags, ImPlotAxisFlags_LogScale); } inline bool IsLog() const { return ImHasFlag(Flags, ImPlotAxisFlags_LogScale); }
}; };
// Align plots group data
struct ImPlotAlignmentData {
ImPlotOrientation Orientation;
float PadA;
float PadB;
float PadAMax;
float PadBMax;
ImPlotAlignmentData() {
Orientation = ImPlotOrientation_Vertical;
PadA = PadB = PadAMax = PadBMax = 0;
}
void Begin() { PadAMax = PadBMax = 0; }
void Update(float& pad_a, float& pad_b) {
if (PadAMax < pad_a) PadAMax = pad_a;
if (pad_a < PadA) pad_a = PadA;
if (PadBMax < pad_b) PadBMax = pad_b;
if (pad_b < PadB) pad_b = PadB;
}
void End() { PadA = PadAMax; PadB = PadBMax; }
void Reset() { PadA = PadB = PadAMax = PadBMax = 0; }
};
// State information for Plot items // State information for Plot items
struct ImPlotItem struct ImPlotItem
{ {
@ -719,50 +749,81 @@ struct ImPlotItem
~ImPlotItem() { ID = 0; } ~ImPlotItem() { ID = 0; }
}; };
// Holds Legend state labels and item references // Holds Legend state
struct ImPlotLegendData struct ImPlotLegendData
{ {
ImVector<int> Indices; ImVector<int> Indices;
ImGuiTextBuffer Labels; ImGuiTextBuffer Labels;
bool Hovered;
bool Outside;
bool CanGoInside;
bool FlipSideNextFrame;
ImPlotLocation Location;
ImPlotOrientation Orientation;
ImRect Rect;
ImPlotLegendData() {
CanGoInside = true;
Hovered = Outside = FlipSideNextFrame = false;
Location = ImPlotLocation_North | ImPlotLocation_West;
Orientation = ImPlotOrientation_Vertical;
}
void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); } void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); }
}; };
// Holds Items and Legend data
struct ImPlotItemGroup
{
ImGuiID ID;
ImPlotLegendData Legend;
ImPool<ImPlotItem> ItemPool;
int ColormapIdx;
ImPlotItemGroup() { ColormapIdx = 0; }
int GetItemCount() const { return ItemPool.GetBufSize(); }
ImGuiID GetItemID(const char* label_id) { return ImGui::GetID(label_id); /* GetIDWithSeed */ }
ImPlotItem* GetItem(ImGuiID id) { return ItemPool.GetByKey(id); }
ImPlotItem* GetItem(const char* label_id) { return GetItem(GetItemID(label_id)); }
ImPlotItem* GetOrAddItem(ImGuiID id) { return ItemPool.GetOrAddByKey(id); }
ImPlotItem* GetItemByIndex(int i) { return ItemPool.GetByIndex(i); }
int GetItemIndex(ImPlotItem* item) { return ItemPool.GetIndex(item); }
int GetLegendCount() const { return Legend.Indices.size(); }
ImPlotItem* GetLegendItem(int i) { return ItemPool.GetByIndex(Legend.Indices[i]); }
const char* GetLegendLabel(int i) { return Legend.Labels.Buf.Data + GetLegendItem(i)->NameOffset; }
void Reset() { ItemPool.Clear(); Legend.Reset(); ColormapIdx = 0; }
};
// Holds Plot state information that must persist after EndPlot // Holds Plot state information that must persist after EndPlot
struct ImPlotPlot struct ImPlotPlot
{ {
ImGuiID ID; ImGuiID ID;
ImPlotFlags Flags; ImPlotFlags Flags;
ImPlotFlags PreviousFlags; ImPlotFlags PreviousFlags;
ImPlotAxis XAxis; ImPlotAxis XAxis;
ImPlotAxis YAxis[IMPLOT_Y_AXES]; ImPlotAxis YAxis[IMPLOT_Y_AXES];
ImPlotLegendData LegendData; ImPlotItemGroup Items;
ImPool<ImPlotItem> Items; ImVec2 SelectStart;
ImVec2 SelectStart; ImRect SelectRect;
ImRect SelectRect; ImVec2 QueryStart;
ImVec2 QueryStart; ImRect QueryRect;
ImRect QueryRect; bool Initialized;
bool Initialized; bool Selecting;
bool Selecting; bool Selected;
bool Selected; bool ContextLocked;
bool ContextLocked; bool Querying;
bool Querying; bool Queried;
bool Queried; bool DraggingQuery;
bool DraggingQuery; bool FrameHovered;
bool LegendHovered; bool FrameHeld;
bool LegendOutside; bool PlotHovered;
bool LegendFlipSideNextFrame; int CurrentYAxis;
bool FrameHovered; ImPlotLocation MousePosLocation;
bool PlotHovered; ImRect FrameRect;
int ColormapIdx; ImRect CanvasRect;
int CurrentYAxis; ImRect PlotRect;
ImPlotLocation MousePosLocation; ImRect AxesRect;
ImPlotLocation LegendLocation;
ImPlotOrientation LegendOrientation;
ImRect FrameRect;
ImRect CanvasRect;
ImRect PlotRect;
ImRect AxesRect;
ImRect LegendRect;
ImPlotPlot() { ImPlotPlot() {
Flags = PreviousFlags = ImPlotFlags_None; Flags = PreviousFlags = ImPlotFlags_None;
@ -770,22 +831,46 @@ struct ImPlotPlot
for (int i = 0; i < IMPLOT_Y_AXES; ++i) for (int i = 0; i < IMPLOT_Y_AXES; ++i)
YAxis[i].Orientation = ImPlotOrientation_Vertical; YAxis[i].Orientation = ImPlotOrientation_Vertical;
SelectStart = QueryStart = ImVec2(0,0); SelectStart = QueryStart = ImVec2(0,0);
Initialized = Selecting = Selected = ContextLocked = Querying = Queried = DraggingQuery = LegendHovered = LegendOutside = LegendFlipSideNextFrame = false; Initialized = Selecting = Selected = ContextLocked = Querying = Queried = DraggingQuery = false;
ColormapIdx = CurrentYAxis = 0; CurrentYAxis = 0;
LegendLocation = ImPlotLocation_North | ImPlotLocation_West;
LegendOrientation = ImPlotOrientation_Vertical;
MousePosLocation = ImPlotLocation_South | ImPlotLocation_East; MousePosLocation = ImPlotLocation_South | ImPlotLocation_East;
} }
int GetLegendCount() const { return LegendData.Indices.size(); }
ImPlotItem* GetLegendItem(int i);
const char* GetLegendLabel(int i);
inline bool AnyYInputLocked() const { return YAxis[0].IsInputLocked() || (YAxis[1].Present ? YAxis[1].IsInputLocked() : false) || (YAxis[2].Present ? YAxis[2].IsInputLocked() : false); } inline bool AnyYInputLocked() const { return YAxis[0].IsInputLocked() || (YAxis[1].Present ? YAxis[1].IsInputLocked() : false) || (YAxis[2].Present ? YAxis[2].IsInputLocked() : false); }
inline bool AllYInputLocked() const { return YAxis[0].IsInputLocked() && (YAxis[1].Present ? YAxis[1].IsInputLocked() : true ) && (YAxis[2].Present ? YAxis[2].IsInputLocked() : true ); } inline bool AllYInputLocked() const { return YAxis[0].IsInputLocked() && (YAxis[1].Present ? YAxis[1].IsInputLocked() : true ) && (YAxis[2].Present ? YAxis[2].IsInputLocked() : true ); }
inline bool IsInputLocked() const { return XAxis.IsInputLocked() && YAxis[0].IsInputLocked() && YAxis[1].IsInputLocked() && YAxis[2].IsInputLocked(); } inline bool IsInputLocked() const { return XAxis.IsInputLocked() && YAxis[0].IsInputLocked() && YAxis[1].IsInputLocked() && YAxis[2].IsInputLocked(); }
}; };
// Holds subplot data that must persist afer EndSubplot
struct ImPlotSubplot {
ImGuiID ID;
ImPlotSubplotFlags Flags;
ImPlotSubplotFlags PreviousFlags;
ImPlotItemGroup Items;
int Rows;
int Cols;
int CurrentIdx;
ImRect FrameRect;
ImRect GridRect;
ImVec2 CellSize;
ImVector<ImPlotAlignmentData> RowAlignmentData;
ImVector<ImPlotAlignmentData> ColAlignmentData;
ImVector<float> RowRatios;
ImVector<float> ColRatios;
ImVector<ImPlotRange> RowLinkData;
ImVector<ImPlotRange> ColLinkData;
float TempSizes[2];
bool FrameHovered;
ImPlotSubplot() {
Rows = Cols = CurrentIdx = 0;
FrameHovered = false;
Items.Legend.Location = ImPlotLocation_North;
Items.Legend.Orientation = ImPlotOrientation_Horizontal;
Items.Legend.CanGoInside = false;
}
};
// Temporary data storage for upcoming plot // Temporary data storage for upcoming plot
struct ImPlotNextPlotData struct ImPlotNextPlotData
{ {
@ -859,10 +944,13 @@ struct ImPlotNextItemData {
// Holds state information that must persist between calls to BeginPlot()/EndPlot() // Holds state information that must persist between calls to BeginPlot()/EndPlot()
struct ImPlotContext { struct ImPlotContext {
// Plot States // Plot States
ImPool<ImPlotPlot> Plots; ImPool<ImPlotPlot> Plots;
ImPlotPlot* CurrentPlot; ImPool<ImPlotSubplot> Subplots;
ImPlotItem* CurrentItem; ImPlotPlot* CurrentPlot;
ImPlotItem* PreviousItem; ImPlotSubplot* CurrentSubplot;
ImPlotItemGroup* CurrentItems;
ImPlotItem* CurrentItem;
ImPlotItem* PreviousItem;
// Tick Marks and Labels // Tick Marks and Labels
ImPlotTickCollection CTicks; ImPlotTickCollection CTicks;
@ -892,6 +980,7 @@ struct ImPlotContext {
bool RenderX; bool RenderX;
bool RenderY[IMPLOT_Y_AXES]; bool RenderY[IMPLOT_Y_AXES];
// Axis Locking Flags // Axis Locking Flags
bool ChildWindowMade; bool ChildWindowMade;
@ -909,13 +998,17 @@ struct ImPlotContext {
ImVector<double> Temp1, Temp2; ImVector<double> Temp1, Temp2;
// Misc // Misc
int VisibleItemCount;
int DigitalPlotItemCnt; int DigitalPlotItemCnt;
int DigitalPlotOffset; int DigitalPlotOffset;
ImPlotNextPlotData NextPlotData; ImPlotNextPlotData NextPlotData;
ImPlotNextItemData NextItemData; ImPlotNextItemData NextItemData;
ImPlotInputMap InputMap; ImPlotInputMap InputMap;
ImPlotPoint MousePos[IMPLOT_Y_AXES]; ImPlotPoint MousePos[IMPLOT_Y_AXES];
// Align plots
ImPool<ImPlotAlignmentData> AlignmentData;
ImPlotAlignmentData* CurrentAlignmentH;
ImPlotAlignmentData* CurrentAlignmentV;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -932,7 +1025,11 @@ namespace ImPlot {
// Initializes an ImPlotContext // Initializes an ImPlotContext
IMPLOT_API void Initialize(ImPlotContext* ctx); IMPLOT_API void Initialize(ImPlotContext* ctx);
// Resets an ImPlot context for the next call to BeginPlot // Resets an ImPlot context for the next call to BeginPlot
IMPLOT_API void Reset(ImPlotContext* ctx); IMPLOT_API void ResetCtxForNextPlot(ImPlotContext* ctx);
// Restes an ImPlot context for the next call to BeginAlignedPlots
IMPLOT_API void ResetCtxForNextAlignedPlots(ImPlotContext* ctx);
// Resets an ImPlot context for the next call to BeginSubplot
IMPLOT_API void ResetCtxForNextSubplot(ImPlotContext* ctx);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Input Utils // [SECTION] Input Utils
@ -955,6 +1052,16 @@ IMPLOT_API void BustPlotCache();
// Shows a plot's context menu. // Shows a plot's context menu.
IMPLOT_API void ShowPlotContextMenu(ImPlotPlot& plot); IMPLOT_API void ShowPlotContextMenu(ImPlotPlot& plot);
//-----------------------------------------------------------------------------
// [SECTION] Subplot Utils
//-----------------------------------------------------------------------------
// Advances to next subplot
IMPLOT_API void SubplotNextCell();
// Shows a subplot's context menu.
IMPLOT_API void ShowSubplotsContextMenu(ImPlotSubplot& subplot);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Item Utils // [SECTION] Item Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1044,11 +1151,13 @@ static inline const char* GetFormatY(ImPlotYAxis y) { return GImPlot->NextPlotDa
// Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount. // Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0)); IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0));
// Calculates the bounding box size of a legend // Calculates the bounding box size of a legend
IMPLOT_API ImVec2 CalcLegendSize(ImPlotPlot& plot, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orientation); IMPLOT_API ImVec2 CalcLegendSize(ImPlotItemGroup& items, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orientation);
// Renders legend entries into a bounding box // Renders legend entries into a bounding box
IMPLOT_API void ShowLegendEntries(ImPlotPlot& plot, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orientation, ImDrawList& DrawList); IMPLOT_API bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, ImPlotOrientation orientation, ImDrawList& DrawList);
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window!). // Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window!).
IMPLOT_API void ShowAltLegend(const char* title_id, ImPlotOrientation orientation = ImPlotOrientation_Vertical, const ImVec2 size = ImVec2(0,0), bool interactable = true); IMPLOT_API void ShowAltLegend(const char* title_id, ImPlotOrientation orientation = ImPlotOrientation_Vertical, const ImVec2 size = ImVec2(0,0), bool interactable = true);
// Shows an legends's context menu.
IMPLOT_API bool ShowLegendContextMenu(ImPlotLegendData& legend, bool visible);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Tick Utils // [SECTION] Tick Utils
@ -1089,6 +1198,8 @@ static inline ImU32 GetStyleColorU32(ImPlotCol idx) { return ImGui::ColorConve
// Draws vertical text. The position is the bottom left of the text rect. // Draws vertical text. The position is the bottom left of the text rect.
IMPLOT_API void AddTextVertical(ImDrawList *DrawList, ImVec2 pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMPLOT_API void AddTextVertical(ImDrawList *DrawList, ImVec2 pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
// Draws multiline horizontal text centered.
IMPLOT_API void AddTextCentered(ImDrawList* DrawList, ImVec2 top_center, ImU32 col, const char* text_begin, const char* text_end = NULL);
// Calculates the size of vertical text // Calculates the size of vertical text
static inline ImVec2 CalcTextSizeVertical(const char *text) { static inline ImVec2 CalcTextSizeVertical(const char *text) {
ImVec2 sz = ImGui::CalcTextSize(text); ImVec2 sz = ImGui::CalcTextSize(text);

View File

@ -61,32 +61,30 @@ namespace ImPlot {
ImPlotItem* RegisterOrGetItem(const char* label_id, bool* just_created) { ImPlotItem* RegisterOrGetItem(const char* label_id, bool* just_created) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
ImGuiID id = ImGui::GetID(label_id); ImPlotItemGroup& Items = *gp.CurrentItems;
ImGuiID id = Items.GetItemID(label_id);
if (just_created != NULL) if (just_created != NULL)
*just_created = gp.CurrentPlot->Items.GetByKey(id) == NULL; *just_created = Items.GetItem(id) == NULL;
ImPlotItem* item = gp.CurrentPlot->Items.GetOrAddByKey(id); ImPlotItem* item = Items.GetOrAddItem(id);
if (item->SeenThisFrame) if (item->SeenThisFrame)
return item; return item;
item->SeenThisFrame = true; item->SeenThisFrame = true;
int idx = gp.CurrentPlot->Items.GetIndex(item); int idx = Items.GetItemIndex(item);
item->ID = id; item->ID = id;
if (ImGui::FindRenderedTextEnd(label_id, NULL) != label_id) { if (ImGui::FindRenderedTextEnd(label_id, NULL) != label_id) {
gp.CurrentPlot->LegendData.Indices.push_back(idx); Items.Legend.Indices.push_back(idx);
item->NameOffset = gp.CurrentPlot->LegendData.Labels.size(); item->NameOffset = Items.Legend.Labels.size();
gp.CurrentPlot->LegendData.Labels.append(label_id, label_id + strlen(label_id) + 1); Items.Legend.Labels.append(label_id, label_id + strlen(label_id) + 1);
} }
else { else {
item->Show = true; item->Show = true;
} }
if (item->Show)
gp.VisibleItemCount++;
return item; return item;
} }
ImPlotItem* GetItem(const char* label_id) { ImPlotItem* GetItem(const char* label_id) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
ImGuiID id = ImGui::GetID(label_id); return gp.CurrentItems->GetItem(label_id);
return gp.CurrentPlot->Items.GetByKey(id);
} }
ImPlotItem* GetCurrentItem() { ImPlotItem* GetCurrentItem() {
@ -140,9 +138,11 @@ void BustItemCache() {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
for (int p = 0; p < gp.Plots.GetBufSize(); ++p) { for (int p = 0; p < gp.Plots.GetBufSize(); ++p) {
ImPlotPlot& plot = *gp.Plots.GetByIndex(p); ImPlotPlot& plot = *gp.Plots.GetByIndex(p);
plot.ColormapIdx = 0; plot.Items.Reset();
plot.Items.Clear(); }
plot.LegendData.Reset(); for (int p = 0; p < gp.Subplots.GetBufSize(); ++p) {
ImPlotSubplot& subplot = *gp.Subplots.GetByIndex(p);
subplot.Items.Reset();
} }
} }
@ -152,12 +152,15 @@ void BustColorCache(const char* plot_title_id) {
BustItemCache(); BustItemCache();
} }
else { else {
ImPlotPlot* plot = gp.Plots.GetByKey(ImGui::GetCurrentWindow()->GetID(plot_title_id)); ImGuiID id = ImGui::GetCurrentWindow()->GetID(plot_title_id);
if (plot == NULL) ImPlotPlot* plot = gp.Plots.GetByKey(id);
return; if (plot != NULL)
plot->ColormapIdx = 0; plot->Items.Reset();
plot->Items.Clear(); else {
plot->LegendData.Reset(); ImPlotSubplot* subplot = gp.Subplots.GetByKey(id);
if (subplot != NULL)
subplot->Items.Reset();
}
} }
} }