chart object create in a loop: last element never drawn?

 

Hi,

I have a small function that creates rectangles in a loop for a given amount of custom objects. It works like expected except that the _last_ rectangle is never drawn (same for some OBJ_TEXT's in the same loop for the rectangles: the last one  is never drawn)?

#include <ChartObjects\ChartObjectsShapes.mqh>

[...]

static void createObjRects(CTest* &objs[]) {
    CChartObjectRectangle Rect;

    [...]

    for(int i = 0; i < ArraySize(objs); i++) {

        datetime rightBorder = fkt(); // fkt fetches datetime value
        datetime leftBorder = fkt(30); // fkt fetches 'earlier' datetime value

        Rect.Create(CHART_ID, "ObjId-" + IntegerToString(i), SUB_WIN, rightBorder, objs[i].getAPrice(), leftBorder, objs[i].getBPrice());
        Rect.Color(clrRed);
        Rect.Fill(true);

        LOG(INFO, "Rect-" + i); // debug: outputs correct amount of objs, 0-10 (total 11 objs)
        LOG(INFO, "Obj-Vals: " + objs[i].getAPrice() + " - " + objs[i].getBPrice());  // debug: outputs correct values all 11 objs

    }
    ChartRedraw();
            
}

So, the given objs array has 11 elements, the two LOG() calls output correct strings: Rect-0, Rect-1, ..., Rect-10, same goes for the values. On the chart there are 10 rectangles drawn, the 11th is missing. If I add one obj, 11 rectangles are drawn, the 12th is missing and so on. The rectangle is definitely not hidden or something like that, I checked with objectlist in chart window.

Does somebody see a mistake?

Best regards,
Alex

 
Alex:

Hi,

I have a small function that creates rectangles in a loop for a given amount of custom objects. It works like expected except that the _last_ rectangle is never drawn (same for some OBJ_TEXT's in the same loop for the rectangles: the last one  is never drawn)?

So, the given objs array has 11 elements, the two LOG() calls output correct strings: Rect-0, Rect-1, ..., Rect-10, same goes for the values. On the chart there are 10 rectangles drawn, the 11th is missing. If I add one obj, 11 rectangles are drawn, the 12th is missing and so on. The rectangle is definitely not hidden or something like that, I checked with objectlist in chart window.

Does somebody see a mistake?

Best regards,
Alex


Hmm, just noticed, that if I create the objects w/o the library function (ObjectCreate([...]) instead of Rect.Create([...])) it is working. Bug?

 
Alex:

Hmm, just noticed, that if I create the objects w/o the library function (ObjectCreate([...]) instead of Rect.Create([...])) it is working. Bug?

Add this line at the end of your function.

Rect.Detach();
 
Alain Verleyen:

Add this line at the end of your function.


Thank you for your answer, I'll give it a try this evening. But my understanding of "detach" is "remove this object it from chart"

EDIT: yes ok that solves the problem, thank you!

 
Alex:

Thank you for your answer, I'll give it a try this evening. But my understanding of "detach" is "remove this object it from chart"

EDIT: yes ok that solves the problem, thank you!


Detach removes chart drawing reference from the object itself and if you're creating a new chart drawings by reusing the same drawing-class you might run into issues. I have found that it's better to create a new object for each drawing and add it to CList or CArrayObj, that way the chart drawings persist until the list is destroyed (easy to remove all drawings when program is finished) and you can easily iterate objects to make changes, etc.

//+------------------------------------------------------------------+
//|                                                BlinkingLines.mq4 |
#property strict
#include <Arrays\List.mqh>
#include <ChartObjects\ChartObjectsLines.mqh>
//+------------------------------------------------------------------+
void OnStart()
{
   CList list;
   while(!IsStopped())
   {
      for(int i=0;i<10;i++)
      {
         string name = "line "+string(i+1);
         CChartObjectVLine *line = new CChartObjectVLine();
         line.Create(0,name,0,Time[i]);
         list.Add(line);        
         ChartRedraw();
         Sleep(100);
      }
      Sleep(200);
      list.Clear();
   }
}
Reason: