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

 

@Roman Konopelko

İkinci sorun, yoksa bana söyler misin?

Kapat fiyatları ile bir çizgi oluşturmaya çalışıyorum. Sırasıyla X'te bir dizi zaman aktarırım. Ama sorun şu ki, fahişe yaratırken boşluklar ekliyor. Yani zamanı tek tip hale getirir ve verinin olmadığı yerleri ekler.

Yani anladığım kadarıyla ayrı bir fahişe türü yapmanız gerekiyor - CURVE_TIMESERIES, otomatik olarak herhangi bir adım bulmamalı ve X noktaları arasına boşluk eklememeli.

Bu, X'i geçmeden kıvrımlı yaratımı nasıl yaptığınıza benzer - ve sonra tüm değerler eşit gider, her şey tamamen X dizisinin boyutuna bağlanır (m_xmax = m_size-1; m_xmin = 0.0; ).

 
o_O :

@Roman Konopelko

İkinci sorun, yoksa bana söyler misin?

Kapat fiyatları ile bir satır oluşturmaya çalışıyorum. X'e göre, buna göre bir zaman dizisi aktarırım. Ama sorun şu ki, fahişe yaratırken boşluklar ekliyor. Yani zamanı tek tip hale getirir ve verinin olmadığı yerleri ekler.

Yani anladığım kadarıyla ayrı bir fahişe türü yapmanız gerekiyor - CURVE_TIMESERIES, otomatik olarak herhangi bir adım bulmamalı ve X noktaları arasına boşluk eklememeli.

Bu, X'i geçmeden kıvrımlı yaratımı nasıl yaptığınıza benzer - ve sonra tüm değerler eşit gider, her şey tamamen X dizisinin boyutuna bağlanır (m_xmax = m_size-1; m_xmin = 0.0; ).

Her iki eksendeki adım, yerleşik algoritma tarafından otomatik olarak hesaplanır. Anladığım kadarıyla max, min ve step yapmak istiyorsunuz. Bunu yapmak için manuel eksen ölçekleme moduna geçebilirsiniz:

   CAxis *xAxis = graphic.XAxis();   // получаем ось X
   xAxis.AutoScale( false );           // отключаем автомасштабирование
   xAxis.Min( 0 );                     // указываем минимальное значение по X
   xAxis.Max( 10 );                   // указываем максимальное значение по X
   xAxis.DefaultStep( 1 );             // указываем шаг по X

MaxLabels ekseni boyunca izin verilen maksimum değer sayısını da hesaba katmanız gerekir, (Max-Min)/DefaultStep değerinden büyük olmalıdır, aksi takdirde adım değişecektir.

 
Roman Konopelko :

Her iki eksendeki adım, yerleşik algoritma tarafından otomatik olarak hesaplanır. Anladığım kadarıyla max, min ve step yapmak istiyorsunuz. Bunu yapmak için manuel eksen ölçekleme moduna geçebilirsiniz.

MaxLabels ekseni boyunca izin verilen maksimum değer sayısını da hesaba katmanız gerekir, (Max-Min)/DefaultStep değerinden büyük olmalıdır, aksi takdirde adım değişecektir.


evet, bir şey oldu.

Ama sana açıkladığım gibi, ölçeğin tekdüze.

Kim ne derse desin, X ile ölçeklendirirsiniz ve koordinatı piksel cinsinden doğru bir şekilde hesaplarsınız.

Bu nedenle, zaman serisi oluştururken bu yapılamaz.

ne olduğunu görün






#include <Graphics/Graphic.mqh>

//+------------------------------------------------------------------+
void OnStart ()
{
         MqlRates rates[];
         CopyRates ( Symbol (), Period (), 0 , 100 , rates);
         ArraySetAsSeries (rates, true );
         int size= ArraySize (rates);
         double arrY[], arrX[];
         ArrayResize (arrX, size); ArrayResize (arrY, size);
         for ( int i= 0 ; i<size; ++i) { arrX[i]=( double )rates[i].time; arrY[i]=rates[i].close; }
        
        CGraphic graphic;
        graphic.Create( 0 , "Rates" , 0 , 30 , 30 , 1600 , 300 );
        CCurve* curve= NULL ;
        
         //curve=graphic.CurveAdd(arrY, CURVE_LINES, "Close");
        
        curve=graphic.CurveAdd(arrX, arrY, CURVE_LINES, "Close" );
        CAxis *xAxis = graphic.XAxis();   // получаем ось X
        xAxis.AutoScale( false );           // отключаем автомасштабирование
        xAxis.Min(arrX[size- 1 ]);                     // указываем минимальное значение по X
        xAxis.Max(arrX[ 0 ]);                 // указываем максимальное значение по X
        xAxis.DefaultStep( 10 *(arrX[ 0 ]-arrX[size- 1 ])/size);             // указываем шаг по X
        xAxis.MaxLabels((arrX[ 0 ]-arrX[size- 1 ])/xAxis.DefaultStep()+ 1 );                           // число значений по оси MaxLabels должно быть больше чем (Max-Min)/DefaultStep
        
        curve.Visible( true );
        graphic.Redraw();
        graphic.Update();
}
 

ve X'te buna zaman ayırmazsanız böyle olur.

inşaat grafik olarak doğru



#include <Graphics/Graphic.mqh>

//+------------------------------------------------------------------+
void OnStart ()
{
         MqlRates rates[];
         CopyRates ( Symbol (), Period (), 0 , 100 , rates);
         ArraySetAsSeries (rates, true );
         int size= ArraySize (rates);
         double arrY[];
        ArrayResize (arrY, size); ArraySetAsSeries (arrY, size);
         for ( int i= 0 ; i<size; ++i) arrY[i]=rates[i].close;
        
        CGraphic graphic;
        graphic.Create( 0 , "Rates" , 0 , 30 , 30 , 1600 , 300 );
        CCurve* curve= NULL ;
        
        curve=graphic.CurveAdd(arrY, CURVE_LINES, "Close" );
        curve.Visible( true );
        graphic.Redraw();
        graphic.Update();
}
 
o_O :


evet, bir şey oldu.

Ama sana açıkladığım gibi, ölçeğin tekdüze.

Kim ne derse desin, X ile ölçeklendirirsiniz ve koordinatı piksel cinsinden doğru bir şekilde hesaplarsınız.

Dolayısıyla, zaman serisi oluştururken bu yapılamaz.

ne olduğunu görün

Büyük olasılıkla, eksen değerleri için çıktı biçimini değiştirme olasılığı uygulanacaktır, ancak şu ana kadar hangi formda kesin olarak söyleyemem.

Örneğinizde düz bir çizgi oluşturan "Cumartesi ve Pazar" hakkında. Doğrulama için örneğinizi sonlandırdım ve dosyaya bir dizi girişi ekledim:

#include <Graphics/Graphic.mqh>
//+------------------------------------------------------------------+
void OnStart ()
  {
   MqlRates rates[];
   CopyRates ( Symbol (), Period (), 0 , 100 ,rates);
   ArraySetAsSeries (rates, true );
   int size= ArraySize (rates);
   double arrY[],arrX[];
   datetime arrTime[];
   ArrayResize (arrX,size);
   ArrayResize (arrY,size);
   ArrayResize (arrTime,size);
   int handle= FileOpen ( "result.txt" , FILE_WRITE | FILE_TXT );
   for ( int i= 0 ; i<size;++i)
     {
      arrTime[i]=rates[i].time;
      arrX[i]=( double )rates[i].time;
      arrY[i]=rates[i].close;
       string str= TimeToString (arrTime[i])+ "\t" + DoubleToString (arrY[i], 3 )+ "\n" ;
       FileWriteString (handle,str);

     }
   FileClose (handle);
   CGraphic graphic;
   graphic.Create( 0 , "Rates" , 0 , 30 , 30 , 1080 , 380 );
   CCurve *curve=graphic.CurveAdd(arrX,arrY,CURVE_LINES, "Close" );
   double min = arrX[ ArrayMinimum (arrX)];
   double max = arrX[ ArrayMaximum (arrX)];
   double step=(max-min)/ 10 ;
   CAxis *xAxis = graphic.XAxis();           // получаем ось X
   xAxis.AutoScale( false );                   // отключаем автомасштабирование
   xAxis.Min(min);                           // указываем минимальное значение по X
   xAxis.Max(max);                           // указываем максимальное значение по X
   xAxis.DefaultStep(step);                   // указываем шаг по X
   curve.Visible( true );
   graphic.Redraw();
   graphic.Update();
  }

Ve OpenOffice'te bir grafik oluşturdu:

Bu grafikte ayrıca düz bir bölüm vardır ve bu nedenle verinin kendisine gömülüdür (X ve Y dizileri). Bu çizelgeyi nolu yorumda açıklanana getirmek için, girdi verilerinizi manuel olarak düzenlemeniz (yani, tatilleri atmanız) gerekecektir.

 
Roman Konopelko :

Büyük olasılıkla, eksen değerleri için çıktı biçimini değiştirme olasılığı uygulanacaktır, ancak şu ana kadar hangi formda kesin olarak söyleyemem.

İyi haber, teşekkürler.

Dediğim gibi resmi yapıyı bekleyemezsiniz, test için sınıfları buraya koyun.
 
o_O :

İyi haber, teşekkürler.

Dediğim gibi resmi yapıyı bekleyemezsiniz, test için sınıfları buraya koyun.
Şimdiye kadar, eksenlerin formatını üç formatta ayarlama yeteneğini uygulamayı planladım:
enum ENUM_AXIS_TYPE
  {
   AXIS_TYPE_DOUBLE,
   AXIS_TYPE_DATETIME,
   AXIS_TYPE_CUSTOM,
  };
  1. AXIS_TYPE_DOUBLE - şimdi kullanılanlar varsayılan olarak ayarlanacak
  2. AXIS_TYPE_DATETIME - tam olarak istediğiniz şey TimeToString'e dayalı olacaktır
  3. AXIS_TYPE_CUSTOM - DoubleToStringFunction işlevine yönelik bir işaretçiye dayalı olarak keyfi çıktılar yapmanızı sağlar
    typedef string (*DoubleToStringFunction)( double );

Ekte, her ihtimale karşı, kütüphanenin tüm dosyalarını gönderdim.

Servis masasına mesajınızla ilgili olarak, evet, aslında X dizisinde Cumartesi ve Pazar günleri yoktur. Bu yüzden verileri düzenlemeniz gerektiğini doğru bir şekilde söylemedim.

Ama yine de sadece AXIS_TYPE_CUSTOM kullanarak sorununuzu çözebilirsiniz.

#include <Graphics/Graphic.mqh>
double arrX[];
double arrY[];
//---
string TimeFirmat( double x)
  {
   return ( TimeToString (( datetime )arrX[ ArraySize (arrX)-( int )x- 1 ]));
  }
//+------------------------------------------------------------------+
void OnStart ()
  {
   MqlRates rates[];
   CopyRates ( Symbol (), Period (), 0 , 100 ,rates);
   ArraySetAsSeries (rates, true );
   int size= ArraySize (rates);
   ArrayResize (arrX,size);
   ArrayResize (arrY,size);
   for ( int i= 0 ; i<size;++i)
     {
      arrX[i]=( double )rates[i].time;
      arrY[i]=rates[i].close;
     }
   CGraphic graphic;
   graphic.Create( 0 , "Rates" , 0 , 30 , 30 , 780 , 380 );
   CCurve *curve=graphic.CurveAdd(arrY,CURVE_LINES, "Close" );
   CAxis *xAxis=graphic.XAxis();           // получаем ось X
   xAxis.AutoScale( false );
   xAxis.Type(AXIS_TYPE_CUSTOM);
   xAxis.ValuesFunctionFormat(TimeFirmat);
   xAxis.DefaultStep( 20.0 );
   curve.Visible( true );
   graphic.Redraw();
   graphic.Update();
  }
//+------------------------------------------------------------------+

Sonuç:


Dosyalar:
Graphic.mqh  86 kb
Curve.mqh  21 kb
Axis.mqh  12 kb
 
Roman Konopelko :

Ama yine de sadece AXIS_TYPE_CUSTOM kullanarak sorununuzu çözebilirsiniz.

süper, uyuyor!
 

Graphic.mqh dosyasına kısaca baktım.

Tüm işlevleri sanal olmayan bırakmaya mı karar verdiniz?

TAMAM,

en azından ***Plot fonksiyonlarını (HistogramPlot, LinesPlot, vb.) sanal yapabilirsiniz. ?

"Tasarım" yetenekleri görev için yeterli olmadığı için (doldurma sırasında gradyanlar veya oluşturma sırasında birkaç renk).

 
o_O :

Graphic.mqh dosyasına kısaca baktım.

Tüm işlevleri sanal olmayan bırakmaya mı karar verdiniz?

TAMAM,

en azından ***Plot fonksiyonlarını (HistogramPlot, LinesPlot, vb.) sanal yapabilirsiniz. ?

"Tasarım" yetenekleri görev için yeterli olmadığı için (doldurma sırasında gradyanlar veya oluşturma sırasında birkaç renk).

Bunları sanal yaparak bile , CGraphics sınıf üyelerine tam erişim olmadan normal aşırı yüklemeler yapamazsınız, bu nedenle hepsinin (çoğu) korumalı olarak bildirilmesi gerekir. Ayrıca, kesin olarak söylemeyeceğim, ancak büyük olasılıkla her iki yön de uygulanacaktır.