XYで描画したオブジェクトをスムーズに変化させる方法(MT4とMT5の比較) - ページ 2

 
Vitaliy Kuznetsov:

このような形で問題を解決していただき、ありがとうございました。確かに、描画速度は向上しています。図書館の勉強をしなければならないようだ。

また、次のようなニュアンスも明確にしたいと思います。この処方でコンパイルすると、警告が出ます。

で、これだと警告も出ずにコンパイルされますが、速度は少し落ちますね。

どちらが正しいのでしょうか)

あ、そうだ、intを入れ忘れた。ライブラリはダブルコーディネイト向けです。
スピードが落ちない。(int)は実質的に無料です。ナノ秒以下。
そう設定することができます。

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

速度には影響しませんが(+ ~1ns)、もう少し正確に位置決めします。

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:

しかし、Kanvasは、透明度を適用することができ、より速く、コードがより少ないスペースで動作するように、はるかに素晴らしいです))。

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

このような形で問題を解決していただき、ありがとうございました。確かに、描画速度は向上しています。図書館の勉強をしなければならないようだ。

また、次のようなニュアンスも明確にしたいと思います。この処方でコンパイルすると、警告が出ます。

で、これだと警告も出ずにコンパイルされますが、速度は少し落ちますね。

どちらが正しいのでしょうか)

このコードをループから取り出し、各repaintイベントでループの前に一度だけ呼び出します。

 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:
水を得た魚のように :)

PNB2))

 
Dmitry Fedoseev:

このコードをループから取り出し、各再描画イベントの前に一度だけ呼び出します。

ライブラリを学ぶより、もっと複雑なことなのでしょうか?

そういうこと なんです。
ちょっと疑問なんですが、私のアドバイスを繰り返すだけでなく、自分でできるんでしょうか?
2つは簡単に出力できる...
コード、要するに
ダメなら、明日起きたら自分で書きます。でも、その時はフェドセーエフをバカ呼ばわりしますよ。))

 
Nikolai Semko:

そう言った んです。
ちょっと疑問なんですが、私のアドバイスを繰り返すだけでなく、自分でできるんでしょうか?
2個は簡単に出力できる...
コードお願いします。
もしダメなら、明日起きたら自分で書きます。でも、その時はフェドセーエフをバカ呼ばわりしますよ。))

私に対するあなたの考えには、信じられないほど感動しました))

 
Dmitry Fedoseev:

あなたの私に対する認識には、信じられないほど感心しました))

より少ない言葉で、より多くのアクションを

 

例を挙げていただき、ありがとうございました非常に分かりやすく、有益で、しかも迅速。

オブジェクトリストのカンヴァス上の例のグラフィックは、すべて1つのオブジェクトのように見えます。

個々のグラフィックアイテム にマウスを合わせたときに、異なるツールチップ(tooltip)を表示させることは可能でしょうか?

それとも、矩形ごとに独自のキャンバスオブジェクトを作成してもよいのでしょうか?速度に影響が出ないか?

お時間があれば、回答、そしてコード例もお待ちしています。

理由: