implot
implot copied to clipboard
Change plotted color for each point in the dataset
Hi!
I would like to implement a feature to change the plotted color for each point in the dataset, something like this.
I plan on doing it this way:
- Defining a
ColorGetter
struct with function:ImU32 operator()(ImPlotCol col, int idx)
, this will be the base case, constant colors fromImPlotNextItemData
- Defining a
ColorGetterFuncPtr
struct where an user defined function is passed in and called,GetterFuncPtr
style -
Renderer*
structs will take a templatedColorGetter
as an argument instead ofImU32 col
- User facing functions will use
ColorGetter
, but a new version of them will useColorGetterFuncPtr
Is this the way of doing this? Will this get merged if I implement it?
Oh, this is already discussed.
I created a small patch file to niavok's version.
When applied void PlotLine(const char* label_id, const T* values, int count, double xscale=1, double xstart=0, ImPlotLineFlags flags=0, int offset=0, int stride=sizeof(T))
function call applies the provided offset
to the color array too. This way I can use a ring buffer.
< draw_list._VtxWritePtr[1].col = col2;
---
> draw_list._VtxWritePtr[1].col = col1; //col2;
149c149
< draw_list._VtxWritePtr[2].col = col2;
---
> draw_list._VtxWritePtr[2].col = col1; //col2;
1616c1616
< GetterColor<IndexerIdx<ImU32>> GenerateColorGetter(const ImPlotNextItemData& s, ImPlotCol col, const ImU32& static_col, int count)
---
> GetterColor<IndexerIdx<ImU32>> GenerateColorGetter(const ImPlotNextItemData& s, ImPlotCol col, const ImU32& static_col, int count, int offset = 0)
1632c1632
< GetterColor<IndexerIdx<ImU32>> get_col(IndexerIdx<ImU32>(col_ptr, count, 0, col_stride), count);
---
> GetterColor<IndexerIdx<ImU32>> get_col(IndexerIdx<ImU32>(col_ptr, count, offset, col_stride), count);
1637c1637
< void RenderMarkers(const _Getter& getter, ImPlotMarker marker, float size, bool rend_fill, ImU32 col_fill, bool rend_line, ImU32 col_line, float weight) {
---
> void RenderMarkers(const _Getter& getter, ImPlotMarker marker, float size, bool rend_fill, ImU32 col_fill, bool rend_line, ImU32 col_line, float weight, int offset = 0) {
1641c1641
< GetterColor<IndexerIdx<ImU32>> get_col_fill = GenerateColorGetter(s, ImPlotCol_MarkerFill, col_fill, getter.Count);
---
> GetterColor<IndexerIdx<ImU32>> get_col_fill = GenerateColorGetter(s, ImPlotCol_MarkerFill, col_fill, getter.Count, offset);
1653c1653
< GetterColor<IndexerIdx<ImU32>> get_col_line = GenerateColorGetter(s, ImPlotCol_MarkerOutline, col_line, getter.Count);
---
> GetterColor<IndexerIdx<ImU32>> get_col_line = GenerateColorGetter(s, ImPlotCol_MarkerOutline, col_line, getter.Count, offset);
1674c1674
< void PlotLineEx(const char* label_id, const _Getter& getter, ImPlotLineFlags flags) {
---
> void PlotLineEx(const char* label_id, const _Getter& getter, ImPlotLineFlags flags, int offset = 0) {
1680c1680
< GetterColor<IndexerIdx<ImU32>> get_col = GenerateColorGetter(s, ImPlotCol_Fill, col_fill, getter.Count);
---
> GetterColor<IndexerIdx<ImU32>> get_col = GenerateColorGetter(s, ImPlotCol_Fill, col_fill, getter.Count, offset);
1686c1686
< GetterColor<IndexerIdx<ImU32>> get_col_line = GenerateColorGetter(s, ImPlotCol_Line, col_line, getter.Count);
---
> GetterColor<IndexerIdx<ImU32>> get_col_line = GenerateColorGetter(s, ImPlotCol_Line, col_line, getter.Count, offset);
1712c1712
< RenderMarkers<_Getter>(getter, s.Marker, s.MarkerSize, s.RenderMarkerFill, col_fill, s.RenderMarkerLine, col_line, s.MarkerWeight);
---
> RenderMarkers<_Getter>(getter, s.Marker, s.MarkerSize, s.RenderMarkerFill, col_fill, s.RenderMarkerLine, col_line, s.MarkerWeight, offset);
1721c1721
< PlotLineEx(label_id, getter, flags);
---
> PlotLineEx(label_id, getter, flags, offset);
Thanks for the suggestions. Per element coloring as been an outstanding feature request. I avoided it for a long time, thinking we might eventually adopt a new item styling scheme (see https://github.com/epezent/implot/discussions/330), but I am leaning now toward merging @niavok's implementation. Please stay posted.