epezent / implot

Immediate Mode Plotting
MIT License
4.55k stars 503 forks source link

Change plotted color for each point in the dataset #485

Open mihaly-sisak opened 1 year ago

mihaly-sisak commented 1 year ago

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:

Is this the way of doing this? Will this get merged if I implement it?

mihaly-sisak commented 1 year ago

Oh, this is already discussed.

mihaly-sisak commented 1 year ago

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);
epezent commented 11 months ago

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.