How to make objects drawn by XY change smoothly (MT4 vs MT5) - page 2

 
Vitaliy Kuznetsov:

Thank you for this kind of solution to the problem. Indeed, the rendering speed has increased. Looks like I'll have to learn the library.

I would also like to clarify the following nuance. It compiles with this formulation with a warning:

And it compiles with this one without a warning, but the speed is a bit slower.

What is more correct?)

Ah, yes, I forgot to put int. The library is geared towards double coordinates.
Speed cannot drop. (int) is practically free. Less than nanosecond.
You may set it so:

y = Round(Canvas.Y(price));

It won't affect speed either (+ ~1 ns), but it will position a little more accurately.

The Round function built into iCanvas returns int and is much faster than the regular round() function, but the double argument x must be within int (-2 147 483 648 <= x <= 2 147 483 647)

int Ceil (double x) { return (x-(int)x>0)?(int)x+1:(int)x; }
int Round(double x) { return (x>0)?(int)(x+0.5):(int)(x-0.5);}
int Floor(double x) { return (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x; }
int Fabs(int x) {if (x<0) return -x; else return x;}
 
Vitaliy Kuznetsov:
I'm not quite sure what type Canvas.Y(price);

what type it returns

Look inside iCanvas and the question goes away:

   double            X(double bar){return((double)W.Left_bar-bar)*W.dx_pix;}; //The X coordinate by the bar number. The bar number must be of type double, otherwise, the bar will be interpreted as time.
   double            X(datetime Time)                                         //The X coordinate by the time.
     { if(tester) return X((double)iBarShift(_Symbol,_Period,Time));
       else return X(wBarShift(Time,W.time,_Period));}
   double            Y(double Price) {if(W.dy_pix==0) W.dy_pix=1; return((W.Y_max-Price)/W.dy_pix); }; //The Y coordinate by the price.
   double            Price(int y)     {return (W.Y_max-y*(W.Y_max-W.Y_min)/W.Height);};                // Price by the Y coordinate
   double            Bar(double x) {return((double)W.Left_bar+1-x/(double)W.dx_pix);};                 // bar number by coordinate X                                                                      
   datetime          TimePos(double x)                                                                 // time by coordinate X 
     {
      double B=Bar(x);
      if (tester || W.BarsInWind == 0) iT[0]=iTime(_Symbol,_Period,(int)B);
      else {if(B<0 ) iT[0]=datetime(W.time[W.BarsInWind-1]-(long)B*PeriodSeconds());
      else if(B<W.Right_bar || B>W.Left_bar) iT[0]=iTime(_Symbol,_Period,(int)B);
      else iT[0]=W.time[W.BarsInWind-Floor(B)-1+(int)W.Right_bar];}
      return iT[0]+int((double)PeriodSeconds()*(1-B+(int)B));
     };
 
Like a fish in water :)
 
Vitaliy Kuznetsov:

But Kanvas is much nicer to work with, you can apply transparency, it's faster and the code takes less space )):

#property indicator_chart_window
#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164
#define  width 50                 
#define  height 10

#property indicator_buffers 0
#property indicator_plots   0

//+------------------------------------------------------------------+
int OnInit() {
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,
                 const int prev_calculated,
                 const int begin,
                 const double& price[]) {
   if (rates_total!=prev_calculated) DrawObj();
   return(rates_total);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   if(id == CHARTEVENT_CHART_CHANGE) DrawObj();
}
//+------------------------------------------------------------------+
void DrawObj() {

   double startPricePos = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   int step_Pips = 50;
   Canvas.Erase(0x00FFFFFF);
   int x1 = W.Width/2;
   Canvas.CurentFont("Arial",10);
   for(int i=-19; i<=20; i++) {
      double stp = step_Pips*i*_Point;
      int y1 = (int)Canvas.Y(startPricePos + stp);
      Canvas.FillRectangle(x1,y1,x1+width, y1+ height, 0xA0ECE9D8);
      Canvas.Rectangle(x1,y1,x1+width, y1+ height, 0xDD807870);
      _CommXY(x1+5, y1, string(startPricePos + stp));
   }
   Canvas.Update();
}
//+------------------------------------------------------------------+



 
Vitaliy Kuznetsov:

Thank you for this kind of solution to the problem. Indeed, the rendering speed has improved. Looks like I'll have to learn the library.

I would also like to clarify the following nuance. It compiles with this formulation with a warning:

And it compiles with this one without a warning, but the speed is a bit slower.

What is more correct?)

Take this code of yours out of the loop and call it once before the loop on each repaint event:

 x=(int)(ChartGetInteger(chart_ID,CHART_WIDTH_IN_PIXELS,sub_window)/2);
   ChartXYToTimePrice(chart_ID,x,y,sub_window,time_pos_X_centr,price_pos_Y_tmp);         
         
   ChartTimePriceToXY(chart_ID,sub_window,time_pos_X_centr,price,x,y);

Is it more complicated than learning some library?

 
Aleksei Stepanenko:
Like a fish in water :)

PNB2))

 
Dmitry Fedoseev:

Take this code out of the loop and call it once before each redraw event:

Is it really more complicated than learning some library?

That's what I was saying.
I'm just wondering - can you do it yourself, and not just repeat my advice?
two of them are easy to output...
Code, please.
If you don't, I'll write it myself tomorrow when I wake up. But then I will call Fedoseev an idiot. ))

 
Nikolai Semko:

That's what I said.
I'm just wondering - can you do it yourself, and not just repeat my advice?
two of them are easy to output...
Code, please.
If you don't, I'll write it myself tomorrow when I wake up. But then I will call Fedoseev an idiot. ))

Incredibly impressed by your ideas about me))

 
Dmitry Fedoseev:

I'm incredibly impressed by your perceptions of me))

Less words, more action

 

Thank you for the examples! Very clear and informative, and not least quick.

All the graphics from the example on the kanvas in the object lists look like a single object.

Is it possible to get different tooltips (tooltips) when hovering the mouse on individual graphics items?

Or may I create a separate canvas object for each rectangle? Won't it affect the speed?

If you have time, I'm waiting for an answer, and maybe a code example.