CGraphic'i test etme - sorular ve öneriler - sayfa 6

 
Roman Konopelko :
CGraphic sınıfında istediğiniz gibi renk tipini her yerde uint ile değiştirdim.

Ayrıca CCanvas sınıfına, belirli bir kalınlıkta ilkelleri çizmenize izin veren yeni yöntemler ekledim:
Yeniliğe uygun olarak CCanvas, CCurve özelliklerini genişletti:
Artık çizgilerle bir eğri çizerken çizgilerin kalınlığını ve uçlarının stilini ayarlayabilirsiniz.


Evet, bu harika.
 

Spline'larla çalışma (Bezier eğrileri ile enterpolasyon) revize edildi. Uygulaması, CGraphics sınıfından doğrudan CCanvas'a taşındı, bu da Graphics kitaplığının dışında spline'lar oluşturmanıza olanak tanıyor.‌

Ek olarak, kapalı bir spline çizmek için bir algoritma eklendi.

Sonuç olarak, CCanvas sınıfında iki yeni genel yöntem ortaya çıktı:

 void               PolylineSmooth( const int &x[], const int &y[], const uint clr, const int size,
                                     ENUM_LINE_STYLE style= STYLE_SOLID ,ENUM_LINE_END end_style=LINE_END_ROUND,
                                     double tension= 0.5 , double step= 10 );
void               PolygoneSmooth( int &x[], int &y[], const uint clr, const int size,
                                     ENUM_LINE_STYLE style= STYLE_SOLID ,ENUM_LINE_END end_style=LINE_END_ROUND,
                                     double tension= 0.5 , double step= 10 );

Bu yöntemler, belirli bir stilde ve belirli bir kalınlıkta spline çizmenize olanak tanır.

Bezier eğrilerinin bir daireyi ve bir elipsi doğru bir şekilde tanımlaması nedeniyle, bu ilkelleri belirli bir kalınlıkta çizmek için CCanvas sınıfını yeni yöntemlerle tamamlamaya açık bir ihtiyaç yoktur.

PolygoneSmooth yöntemine dayalı Bezier eğrileri ile bir elipsin‌ yaklaşımı örneği:

 #include <Canvas\Canvas.mqh>
//+------------------------------------------------------------------+
//| Get arrays with ellipse coordinates                              |
//+------------------------------------------------------------------+
void Ellipse( int &x[], int &y[])
  {
   int xc = 750 ;
   int yc = 300 ;
   int rx = 300 ;
   int ry = 150 ;
   ArrayResize (x, 16 );
   ArrayResize (y, 16 );
   int i= 0 ;
   for ( double fi= 0 ; fi< 2 * M_PI ; fi+= M_PI_4 / 2 ,i++)
     {
      x[i]=( int ) MathRound (xc+ cos (fi)*rx);
      y[i]=( int ) MathRound (yc+ sin (fi)*ry);
     }
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
  {
   CCanvas canvas;
   canvas.CreateBitmapLabel( 0 , 0 , "Canvas" , 0 , 0 , 1500 , 600 );
   canvas.Erase( ColorToARGB ( clrWhite ));
   int x[];
   int y[]; 
   Ellipse(x,y);
   canvas.PolygoneSmooth(x,y, ColorToARGB ( clrBlack ), 20 , STYLE_SOLID ,LINE_END_BUTT, 0.5 , 1 );
   canvas.Arc( 750 , 300 , 300 , 150 , 0 , M_PI * 2 , ColorToARGB ( clrRed ));   
   canvas.Update();
  }

Sonuç:

 

Grafik kitaplığının evrenselliğine doğru bir başka olası adım: CURVE_CUSTOM eğrileri çizmek için özel mod.

Bu mod, standart kitaplık araçlarının izin verdiğinden farklı bir eğri çizmek için ‌CGraphic sınıfının mirasçıları yapma ve ...Plot yöntemlerini aşırı yükleme ihtiyacını ortadan kaldırır.

Bu CURVE_CUSTOM modunu uygulamak için CCurve sınıfına yeni özellikler eklenecektir:‌

   //--- gets or sets the custom properties
   PlotFucntion      CustomPlotFunction( void )               const { return (m_custom_plot_func);   }
   void              *CustomPlotCBData( void )                 const { return (m_custom_plot_cbdata); }
   void               CustomPlotFunction(PlotFucntion func) { m_custom_plot_func=func;     }
   void               CustomPlotCBData( void *cbdata)        { m_custom_plot_cbdata=cbdata; }

PlotFucntion:‌ adlı yeni bir işlev işaretçisine dayanmaktadır.

 typedef void (*PlotFucntion)( double &x[], double &y[], int size, CGraphic *graphic,CCanvas *canvas, void *cbdata);

Bu yaklaşım, çizelgeler çizmek için yeni olanaklar açar.

Örneğin, CGraphics kitaplığında şamdanlar‌ oluşturalım:

1. Bir mumla ilgili tüm verilerin depolanacağı bir kap sınıfı oluşturalım:‌

 //+------------------------------------------------------------------+
//| Class CCandle                                                    |
//| Usage: class to represent the candle                             |
//+------------------------------------------------------------------+
class CCandle: public CObject
  {
private :
   double             m_open;
   double             m_close;
   double             m_high;
   double             m_low;
   uint               m_clr_inc;
   uint               m_clr_dec;
   int                m_width;

public :
                     CCandle( const double open, const double close, const double high, const double low,
                                                       const int width, const uint clr_inc= 0x000000 , const uint clr_dec= 0xF5F5F5 );
                    ~CCandle( void );
   double             OpenValue( void )             const { return (m_open);     }
   double             CloseValue( void )           const { return (m_close);    }
   double             HigthValue( void )           const { return (m_high);     }
   double             LowValue( void )             const { return (m_low);      }
   uint               CandleColorIncrement( void ) const { return (m_clr_inc);  }
   uint               CandleColorDecrement( void ) const { return (m_clr_dec);  }
   int                CandleWidth( void )           const { return (m_width);    }
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CCandle::CCandle( const double open, const double close, const double high, const double low,
                                 const int width, const uint clr_inc= 0x000000 , const uint clr_dec= 0xF5F5F5 ):
                                 m_open(open),m_close(close),m_high(high),m_low(low),
                                 m_clr_inc(clr_inc),m_clr_dec(clr_dec),m_width(width)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CCandle::~CCandle( void )
  {
  }

2. CCandle sınıfı, CObject'in mirasçısı olduğundan, çizmek istediğimiz tüm mumları sırayla CArrayObj sınıfının bir nesnesine yazabiliriz. Bu dizi, cbdata parametresi olarak özel oluşturma yöntemimize iletilecektir. Sonuç olarak, mum çizme yöntemi şöyle görünecektir:‌

 //+------------------------------------------------------------------+
//| Custom method for plot candles                                   |
//+------------------------------------------------------------------+
void PlotCandles( double &x[], double &y[], int size,CGraphic *graphic,CCanvas *canvas, void *cbdata)
  {
//--- check obj
   CArrayObj *candles=dynamic_cast<CArrayObj*>(cbdata);
   if (candles== NULL || candles.Total()!=size)
       return ;
//--- plot candles  
   for ( int i= 0 ; i<size; i++)
     {
      CCandle *candle=dynamic_cast<CCandle*>(candles.At(i));
       if (candle== NULL )
         return ;
       //--- primary calculate
       int xc=graphic.ScaleX(x[i]);
       int width_2=candle.CandleWidth()/ 2 ;
       int open=graphic.ScaleY(candle.OpenValue());
       int close=graphic.ScaleY(candle.CloseValue());
       int high=graphic.ScaleY(candle.HigthValue());
       int low=graphic.ScaleY(candle.LowValue());
       uint clr=(open<=close) ? candle.CandleColorIncrement() :  candle.CandleColorDecrement();
       //--- plot candle
      canvas.LineVertical(xc,high,low, 0x000000 );
       //--- plot candle real body
      canvas.FillRectangle(xc+width_2,open,xc-width_2,close,clr);
      canvas.Rectangle(xc+width_2,open,xc-width_2,close, 0x000000 );
     }
  }

‌‌‌3. Basitlik için, tüm mumlar rastgele oluşturulacaktır. Ve böylece sırayla 10 mum üretiyoruz ve onları CArrayObj sınıfının bir nesnesiyle dolduruyoruz. Bir CGraphics nesnesi oluşturup ona bir eğri ekledikten sonra, bunun PlotCandles işlevimize göre çizileceğini belirtir. Ayrıca mumlarımızın tam olarak görülebilmesi için y eksenindeki maksimum ve minimum değerleri değiştirmek gerekir.

 //+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
  {
   int count= 10 ;
   int width= 10 ;
   double x[];
   double y[];
   ArrayResize (x,count);
   ArrayResize (y,count);
   CArrayObj candles();
   double max= 0 ;
   double min= 0 ;
//--- create values 
   for ( int i= 0 ; i<count; i++)
     {
      x[i] = i;
      y[i] = i;
       //--- calculate values
       double open= MathRound ( 50.0 +( MathRand ()/ 32767.0 )* 50.0 );
       double close= MathRound ( 50.0 +( MathRand ()/ 32767.0 )* 50.0 );
       double high= MathRound ( MathMax (open,close)+( MathRand ()/ 32767.0 )* 10.0 );
       double low= MathRound ( MathMin (open,close) -( MathRand ()/ 32767.0 )* 10.0 );
       //--- find max and min
       if (i== 0 || max<high)
         max=high;
       if (i== 0 || min>low)
         min=low;
       //--- create candle
      CCandle *candle= new CCandle(open,close,high,low,width);
      candles.Add(candle);
     }
//--- create graphic
   CGraphic graphic;
   if (!graphic.Create( 0 , "CandleGraphic" , 0 , 30 , 30 , 780 , 380 ))
     {
      graphic.Attach( 0 , "CandleGraphic" );
     }
//--- create curve
   CCurve *curve=graphic.CurveAdd(x,y,CURVE_CUSTOM, "Candles" );
//--- sets the curve properties
   curve.CustomPlotFunction(PlotCandles);
   curve.CustomPlotCBData( GetPointer (candles));
//--- sets the graphic properties
   graphic.YAxis().Max(( int )max);
   graphic.YAxis().Min(( int )min);
//--- plot 
   graphic.CurvePlotAll();
   graphic.Update();
  }

Sonuç olarak, aşağıdaki grafiği elde ederiz:


Dosyalar:
Canvas.mqh  304 kb
Axis.mqh  12 kb
Curve.mqh  23 kb
Graphic.mqh  73 kb
Candle.mq5  6 kb
 

‌ @Roman Konopelko

CGraphic::SetDefaultParameters işlevinde küçük bir hata var

Renkler opaklık göz önünde bulundurularak başlatılmalıdır.

 void CGraphic::SetDefaultParameters( void )
  {
...
...
//--- sets the default values for grid
   m_grid.clr_line= ColorToARGB ( clrWhiteSmoke , 255 );
   m_grid.clr_axis_line= ColorToARGB ( clrSilver , 255 );
 
o_o :

‌ @Roman Konopelko

CGraphic::SetDefaultParameters işlevinde küçük bir hata var

Renkler opaklık göz önünde bulundurularak başlatılmalıdır.

İyi günler, bu anı zaten düzelttim, ancak ne yazık ki bu düzenlemeler henüz yapıya dahil edilmedi
 

İşte bilgisayarın donmasına neden olan bir örnek. Yaptığım şey: göstergeyi düzenleyicideki grafiğe ekledikten sonra, 87 ve 88. satırları yorumlamak/yorumsuz bırakmak için çeşitli kombinasyonlarla oynadım (birer birer, birlikteyken)

 //+------------------------------------------------------------------+
//|                                        tst.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link        "http://wmua.ru/slesar/"
#property version    "1.000"
#property description "Panel indicator: \"Evening Star\" pattern " 
#property description "search results for different periods" 
#property indicator_chart_window 
#property indicator_buffers 0
#property indicator_plots    0
#include <Graphics\Graphic.mqh>
//--- object for creating graphs
CGraphic my_graphic;
//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
bool            m_first_start= false ;
//+------------------------------------------------------------------+ 
//| Custom indicator initialization function                         | 
//+------------------------------------------------------------------+ 
int OnInit ()
  {
   if (! EventSetTimer ( 3 ))
       if (! EventSetTimer ( 3 ))
         if (! EventSetTimer ( 3 ))
           {
             Print ( "Error create timer! THREE attempts!" );
             return ( INIT_FAILED );
           }
//--- canvas creation
   my_graphic.Create( 0 , "Evening Star Statistics" , 0 , 10 , 10 , 800 , 550 );

   my_graphic.CurvePlotAll();
   my_graphic.Update();
//---
   m_first_start= false ;
//--- 
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {
   my_graphic.Destroy();
  }
//+------------------------------------------------------------------+ 
//| Custom indicator iteration function                              | 
//+------------------------------------------------------------------+ 
int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[])
  {
   if (!m_first_start)
     {
       //--- revert access to arrays - do it like in timeseries 
       ArraySetAsSeries (time, true );
       ArraySetAsSeries (open, true );
       ArraySetAsSeries (high, true );
       ArraySetAsSeries (low, true );
       ArraySetAsSeries (close, true );

       int size= ArraySize (time);
       double arrY[],arrX[];
       ArrayResize (arrX,size);
       ArrayResize (arrY,size);
       for ( int i= 0 ; i<size;++i)
        {
         arrX[i]=( double )time[i];
         arrY[i]=close[i];
        }
      CCurve *curve_b=my_graphic.CurveAdd(arrX,arrY,CURVE_LINES, "Close" );
      CAxis *xAxis=my_graphic.XAxis();           // получаем ось X
       //---попеременно комбинирую (комментировать, раскомментировать) строки 87
       //--- и 88 можно словить момент поглощения памяти и зависания компьютера
       //xAxis.AutoScale(false); 
       //xAxis.Type(AXIS_TYPE_DATETIME); 
      my_graphic.CurvePlotAll();
      my_graphic.Update();
      m_first_start= true ;
     }
//--- return value of prev_calculated for next call 
   return (rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer ()
  {

  }
//+------------------------------------------------------------------+

Başarıyı iki kez tekrarladı. Adımları yazmamış olmam çok kötü. Üçüncü kez kontrol etmeye korkuyorum.


Eklendi: 1607 x64 oluştur

Dosyalar:
tst.mq5  8 kb
 
Vladimir Karputov :

İşte bilgisayarın donmasına neden olan bir örnek. Yaptığım şey: göstergeyi düzenleyicideki grafiğe ekledikten sonra, 87 ve 88. satırları yorumlamak/yorumsuz bırakmak için çeşitli kombinasyonlarla oynadım (birer birer, birlikteyken)

Başarıyı iki kez tekrarladı. Adımları yazmamış olmam çok kötü. Üçüncü kez kontrol etmeye korkuyorum.


Eklendi: 1607 x64 oluştur


Bugün rekoru tekrarladım - bilgisayarın donması, RAM tüketiminde 2 GB'den 5.5 GB'a bir artış görmeyi başardı. Görünüşe göre grafiği kapatmayı başardım, ancak bilgisayar beş dakikadır kilitleniyor.

Bu sefer dizinin boyutuna bir sınır getirdim - en fazla 300 eleman. Görünüşe göre yardımcı olmadı.

 

hata ayıklama ne diyor?

 
o_o :

hata ayıklama ne diyor?


Zhebug ulaşmadı, şunu yaptım: bir göstergeyi astı ve bir veya iki satır yorumladı / yorumladı ve derledi. Sonuç olarak tabletten yazıyorum laptop söndü..
 
Vladimir Karputov :

Zhebug ulaşmadı, şunu yaptım: bir göstergeyi astı ve bir veya iki satır yorumladı / yorumladı ve derledi. Sonuç olarak tabletten yazıyorum laptop söndü..


Böylece, dizüstü bilgisayar donanımdan sıfırlama işleminden sonra canlandı, ancak yıkıcı deneye devam etme arzusu ortadan kalktı - birkaç Uzman Danışman dizüstü bilgisayarda dönüyor, bu nedenle bir saat boyunca donma arzusu yok.