Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PlotShadedClip, fills region only if the second line is higher than the first one. #161

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

WildRackoon
Copy link

@WildRackoon WildRackoon commented Dec 31, 2020

PlotShaded only supports a single color for the overlap region, It could use a segregation based on a quantity being higher than another.

Here is a Simple example, used to visually assert wether a stock market's limit orders are appropriate for transactions to be done:
ShadedClip

This is achieved by two PlotShadedClip calls, one from ys1 to ys2 and a second from ys2 to ys1;

//ClipShades
ImPlot::SetNextFillStyle(ImVec4(1.0f,0.0f,0.0f,0.25f));
ImPlot::PlotShadedClip  ("Market Bad" , &history_price_buy.Data[0].x , &history_price_buy.Data[0].y , &history_price_sell.Data[0].y, history_price_buy.Data.size() , history_price_buy.Offset , 2*sizeof(float));
ImPlot::SetNextFillStyle(ImVec4(0.0f,1.0f,0.0f,0.25f));
ImPlot::PlotShadedClip  ("Market Good", &history_price_sell.Data[0].x, &history_price_sell.Data[0].y, &history_price_buy.Data[0].y , history_price_sell.Data.size(), history_price_sell.Offset, 2*sizeof(float));

The Implementation is very basic, it comes down to 2 modified lines in comparison with PlotShaded, upper vertices coords are squeezed down if relative height conditions are not met.

DrawList._IdxWritePtr[0] = (ImDrawIdx)(DrawList._VtxCurrentIdx);
DrawList._IdxWritePtr[1] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1 + intersect);
DrawList._IdxWritePtr[2] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 0 + 3 * (P11.y >= P12.y) );
DrawList._IdxWritePtr[3] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
DrawList._IdxWritePtr[4] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 3 - intersect);
DrawList._IdxWritePtr[5] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1 + 3 * (P21.y >= P22.y) );
DrawList._IdxWritePtr += 6;
DrawList._VtxCurrentIdx += 5;

This PR only a baseline for a better implementation of this kind of feature, it also only does ShadeClipping between two series, not with a single serie and a ref, simply because I didn't know how to elegantly handle the choice between a shaded region above or under the reference line. (switching positional arguments doesn't seem very clean to me, but its work).

EDIT: I mean extending this to lines, scatter etc... and have dual/multi color thresholds would need significant changes.

Looking forward to your suggestions.

@epezent
Copy link
Owner

epezent commented Jan 6, 2021

@WildRackoon , thanks for the PR. This looks useful! I'll try to take a look soon (currently swamped with school).

@WildRackoon
Copy link
Author

Rebased this to latest code changes just in case anyone needs this
Added Demo example
But still no idea to reduce code duplication in an intuitive manner / handle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants