Как сделать плавность изменения объектов, нарисованных по XY (MT4 vs MT5) - страница 2

 
Vitaliy Kuznetsov:

Спасибо за подобное решение проблемы. Действительно, скорость отрисовки возросла. Похоже придётся осваивать библиотеку.

Хотел бы ещё уточнить следующий нюанс. С такой формулировкой компилируется с предупреждением:

А с такой без предупреждения, но скорость чутка падает

Как правильнее?)

а, да я int забыл поставить. Библиотека заточена на double координаты.
Скорость не может упасть. (int) это практически бесплатно. Меньше наносекунды.
Можете так поставить:

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

на скорость тоже не повлияет (+ ~1 нс) , но будет чуть точнее позиционировать. 

Встроенная в iCanvas функция Round возвращает int и работает намного быстрее штатной round(), но double аргумент x должен быть в пределах 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:
Я не совсем понимаю какого типа Canvas.Y(price);

какой тип он возвращает

загляните внутрь iCanvas и вопрос отпадет:

   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));
     };
 
Как рыба в воде :)
 
Vitaliy Kuznetsov:

И все же с Канвасом гораздо приятней работать, можно применять прозрачность, быстрее и код места меньше занимает )):

#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:

Спасибо за подобное решение проблемы. Действительно, скорость отрисовки возросла. Похоже придётся осваивать библиотеку.

Хотел бы ещё уточнить следующий нюанс. С такой формулировкой компилируется с предупреждением:

А с такой без предупреждения, но скорость чутка падает

Как правильнее?)

Вот этот свой код вынесите из цикла, чтобы он на каждом событии перерисовки вызывался один раз перед циклом:

 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);

Неужели это сложнее, чем осваивать какую-то библиотеку?

 
Aleksei Stepanenko:
Как рыба в воде :)

ПНБ2))

 
Dmitry Fedoseev:

Вот этот свой код вынесите из цикла, чтобы он на каждом событии перерисовки вызывался один раз перед циклом:

Неужели это сложнее, чем осваивать какую-то библиотеку?

Ну я об этом говорил.
Мне просто интересно - сам то сможешь это сделать, а не только повторять за мной советы?
две то выводятся легко...
Код в студию, короче. 
Не сбросишь, тогда сам напишу завтра как проснусь. Но тогда буду называть Федосеева порожняком. ))

 
Nikolai Semko:

Ну я об этом говорил.
Мне просто интересно - сам то сможешь это сделать, а не только повторять за мной советы?
две то выводятся легко...
Код в студию, короче. 
Не сбросишь, тогда сам напишу завтра как проснусь. Но тогда буду называть Федосеева порожняком. ))

Неимоверно впечатлен вашими представлениями обо мне))

 
Dmitry Fedoseev:

Неимоверно впечатлен вашими представлениями обо мне))

Меньше слов - больше дела

 

Спасибо за примеры! Очень наглядно и познавательно, что не маловажно - быстроработающе.

Вся графика из примера по канвасу в списках объектов выглядит, как один объект.

Возможно ли получать тултипы (всплывающие подсказки) различные при наведении мыши на отдельные элементы графики?

Или для каждого отдельного прямоугольника городить свой объект канваса? Тогда не повлияет ли это на скорость?

Если будет время, то жду ответа, а может и пример кода.

Причина обращения: