Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

OnRender() questions. Drawing an object half on/off screen, as well as efficiency.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    OnRender() questions. Drawing an object half on/off screen, as well as efficiency.

    Howdy.

    I have a question, and am just looking to see if there is some obvious way of doing this that I have not thought of?

    But, I would like to draw objects, that are only PARTIALLY on the screen. Attached is an image of a chart, where you can see it technically STARTS off screen.

    Obviously, I'd like to take advantage of the EFFICIENCY that comes with only rendering what is visible to the user, instead of storing a million drawn objects in memory at all times.

    To further explain, imagine an indicator that only renders something on each bar. Also attached is a screenshot of such an indicator, where it simply draws a dot on the bottom of the screen, that is the width of the bar. This is simple, as I just have a dataseries that stores a value, and I simply loop through the visible bars on the chart within OnRender(), and draw a dot based on various conditions.

    And example would be like this:
    Code:
                int rightMostBar = ChartBars.ToIndex;                    
                int leftMostBar = ChartBars.FromIndex;                    
    
                for (int i=leftMostBar; i <= rightMostBar; i++) //Start at necessary List position
                {    
                  if(dataSeries[i] == 1)
                      draw red dot;
                  else
                      draw blue dot;
                }​
    My way of doing this for a line/box or another complex shape that may span what is and is-not visible, was to store ALL the locations of the thing I want to draw in various dataSeries, and check if any of those data points are WITHIN the bars that would be visible, and then render the line. And figure out some way to only draw that item ONCE.

    But this seems somewhat complex, and I wonder if there is a simple way to do this that I am failing to think of? Any ideas on the best way to accomplish what I am trying to do? Just looking for basic ideas, code not necessary.

    If it were JUST A LINE, I could potentially still use a single dataSeries, and just connect the individual elements of each point on that line. But this isn't possible with a more complex shape like a box.

    Second question... is rendering something to ONLY the visible bars ALWAYS more EFFICIENT? I.e., imagine the typical VWAP indicator, or even a simple moving average... If you create the SAME indicator, but push everything to OnRender() to display only what is visible to the user, is it always going to be more efficient and easier to run?

    Asking as I have many charts on screen, and I am going to recreate some of these indicators that use VWAPs, but push everything to OnRender().

    To recap:
    1) Is there an obvious way to render something to screen that is only PARTIALLY visible?
    2) Is OnRender() always going to be more efficient than drawnObjects or Plots(E.g. moving averages)?

    Thanks,
    FP
    Attached Files
    Last edited by forrestang; 05-31-2024, 11:20 AM.

    #2
    Hello FP,

    "Is there an obvious way to render something to screen that is only PARTIALLY visible?"

    I'm certain of a simple way to achieve this.

    You could choose to render anything that has an end point within the chart area. So even if one end point is out of view the object is still rendered.

    "Second question... is rendering something to ONLY the visible bars ALWAYS more EFFICIENT?"

    Not calling logic or RenderTarget methods for bars outside of the visible range is more efficient. CPU time is not lost performing calculations for things that will not appear in the render target.

    "Is OnRender() always going to be more efficient than drawnObjects or Plots(E.g. moving averages)?"

    With Drawing tools objects, these are scripts that have to have instances generated and stored in memory. The work of instantiating these class objects is much more work than rendering from a single script. Drawing tool objects also render the shapes in OnRender(), but the overhead of the script class instances is what would be using the might higher resource use.



    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      ChelseaB,

      Originally posted by NinjaTrader_ChelseaB View Post
      You could choose to render anything that has an end point within the chart area. So even if one end point is out of view the object is still rendered.
      ^I may be thinking incorrectly, but I think the problem with that may be, if you scroll a chart to the left a few bars for example, now you'd have items where the endpoint that USED to be onscreen, is no longer onscreen, so that object would disappear from view, even though it should still be shown.

      But the way you describe, is a similar way I thought to do it before, but I didn't do it as I thought there might be a simpler way.

      So it's almost like you'd need to check the start OR endpoint. So I can imagine using FOUR data series(to draw a rectangle), that would each hold the SAME value at each bar that is in line with the existence of a box. Attached image to simulate 4 dataSeries, each holding the same values, on bars where a box exists. I guess then, you'd loop through visible bars on screen, and query to see IF a value is in the dataSeries, and if so, draw that box.

      I guess if this works, you may be technically drawing the box over and over right? I.e., in the image I've attached, this box is 6 bars wide. So that means, you'd draw the box 6 times in the same location?

      To solve that... would the best solution be to some condition to only draw it once, or would it be to draw it, then erase the last one(I've never erased anything in OnRender before)?



      Originally posted by NinjaTrader_ChelseaB View Post
      With Drawing tools objects, these are scripts that have to have instances generated and stored in memory. The work of instantiating these class objects is much more work than rendering from a single script. Drawing tool objects also render the shapes in OnRender(), but the overhead of the script class instances is what would be using the might higher resource use.
      ^I hate to admit it, but I am not the sharpest tool in the shed ... but I think you saying it will always be more efficient to push things you want to draw into OnRender()... to include shapes you draw manually in OnRender... as well as plots(E.g. manually drawing a moving average in OnRender() by connecting points) instead of using say AddPlot()?

      Have I interpreted that correctly?


      FP
      Attached Files

      Comment


        #4
        Actually in thinking about it.... you'd probably need SIX dataSeries, as you'd want to include that startBar AND endBar. So you can imagine my picture I posted above, but with two more series.

        Comment


          #5
          Hello FP,

          "So it's almost like you'd need to check the start OR endpoint."

          Yes, this is what I was meaning, if any points are within the chart area, then render the object.

          While you can custom render anywhere on the chart you would like, the chart bars is the primary series which is what Drawing tools objects are anchored to.

          I would recommend that you create a list of objects you want to draw in relation to the primary series only and then only draw the object once in OnRender().

          "as well as plots(E.g. manually drawing a moving average in OnRender() by connecting points) instead of using say AddPlot()?​"

          Plots added with AddPlot() are not a separate scripts and are rendered by NinjaTrader in OnRender(). For these you could just use a plot as rendering a geometry path likely wouldn't be any more efficient as there is no extra overhead with plots.
          Chelsea B.NinjaTrader Customer Service

          Comment


            #6
            I had to read this a few times for it to make sense.

            Now I understand what you were trying to tell me in the last post.

            Very helpful,
            thanks!

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by Geovanny Suaza, 02-11-2026, 06:32 PM
            0 responses
            581 views
            0 likes
            Last Post Geovanny Suaza  
            Started by Geovanny Suaza, 02-11-2026, 05:51 PM
            0 responses
            338 views
            1 like
            Last Post Geovanny Suaza  
            Started by Mindset, 02-09-2026, 11:44 AM
            0 responses
            103 views
            0 likes
            Last Post Mindset
            by Mindset
             
            Started by Geovanny Suaza, 02-02-2026, 12:30 PM
            0 responses
            554 views
            1 like
            Last Post Geovanny Suaza  
            Started by RFrosty, 01-28-2026, 06:49 PM
            0 responses
            552 views
            1 like
            Last Post RFrosty
            by RFrosty
             
            Working...
            X