Prüfung von CGraphic - Fragen und Anregungen - Seite 3

 

@Roman Konopelko

Zweites Problem, oder vielleicht können Sie mir einen Tipp geben.

Ich versuche, eine Zeile mit Close-Preisen zu erstellen. Auf X übergebe ich dementsprechend ein Array der Zeit. Das Problem ist jedoch, dass bei der Erstellung einer Kurve die Intervalle von selbst hinzugefügt werden. Das heißt, sie macht die Zeit einheitlich und fügt eine Stelle hinzu, an der es keine Daten gibt.

Ich verstehe also, dass Sie einen separaten Kurventyp erstellen müssen - CURVE_TIMESERIES - es sollte nicht automatisch eine Stufe finden und keine Lücken zwischen X-Punkten hinzufügen.

Dies ist analog zu der Art und Weise, wie Sie die Kurvenerstellung ohne Übergabe von X gemacht haben - und dann gehen alle Werte gleichmäßig, alles ist rein an die Größe des Arrays X gebunden (m_xmax = m_size-1; m_xmin = 0.0; ).

 
o_O:

@Roman Konopelko

Zweites Problem, oder vielleicht können Sie mir einen Tipp geben.

Ich versuche, eine Zeile mit Schlusskursen zu erstellen. Auf X übergebe ich dementsprechend ein Array der Zeit. Das Problem ist jedoch, dass beim Erstellen einer Kurve Intervalle hinzugefügt werden. Das heißt, sie macht die Zeit einheitlich und fügt eine Stelle hinzu, an der es keine Daten gibt.

Also, ich verstehe, dass man einen separaten Kurventyp erstellen muss - CURVE_TIMESERIES - es sollte nicht automatisch eine Stufe finden und keine Lücken zwischen X-Punkten hinzufügen.

Dies ist analog zu der Art und Weise, wie Sie die Kurvenerstellung ohne Übergabe von X gemacht haben - und dann gehen alle Werte gleichmäßig, alles ist rein an die Größe des Arrays X gebunden (m_xmax = m_size-1; m_xmin = 0.0; ).

Der Schritt auf beiden Achsen wird automatisch durch den eingebauten Algorithmus berechnet. Soweit ich das verstanden habe, wollen Sie Max, Min und Step selbst einstellen. Dazu können Sie in den manuellen Modus für die Skalierung der Achsen wechseln:

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

Ein weiterer Punkt ist die maximal zulässige Anzahl von Werten auf der MaxLabels-Achse. Sie muss größer sein als (Max-Min)/DefaultStep, sonst wird der Schritt geändert.

 
Roman Konopelko:

Der Schritt auf beiden Achsen wird automatisch durch den eingebauten Algorithmus berechnet. Soweit ich das verstanden habe, wollen Sie den Maximalwert, den Minimalwert und den Schritt selbst festlegen. Dazu können Sie in den manuellen Modus für die Skalierung der Achsen wechseln

Sie müssen auch die maxLabels-Achse berücksichtigen, sie muss größer sein als (Max-Min)/DefaultStep, sonst wird der Schritt geändert.


Ja, das ist schon etwas.

Aber wie ich Ihnen bereits erklärt habe, ist Ihr Maßstab einheitlich.

Wie man es auch dreht und wendet - man macht eine X-Skala und richtet die Koordinate in Pixeln aus.

Nun, mit einer Zeitreihe ist das nicht möglich.

Sehen Sie, was Sie bekommen






#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();
}
 

und das ist es, was es tut, wenn Sie ihm nicht die Zeit in X übergeben

die Konstruktion ist grafisch korrekt



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


Ja, ich habe etwas.

Aber wie ich Ihnen bereits erklärt habe - Ihre Skala ist flach.

Egal wie man es dreht und wendet - man skaliert mit X und gibt die Koordinate in Pixeln an.

Nun - bei der Darstellung von Zeitreihen ist dies nicht möglich.

Sehen Sie, was Sie bekommen

Höchstwahrscheinlich wird die Möglichkeit, das Ausgabeformat für Achsen zu ändern, implementiert werden, aber ich kann nicht genau sagen, in welcher Form.

Bezüglich "Samstag und Sonntag" in Ihrem Beispiel, die eine gerade Linie bilden. Um Ihr Beispiel zu überprüfen, habe ich es geändert und das Schreiben von Arrays in eine Datei hinzugefügt:

#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();
  }

Und in OpenOffice aufgezeichnet:

Dieses Diagramm enthält ebenfalls eine gerade Linie, die in die Daten (Arrays X und Y) eingebettet ist. Um das Diagramm wie in Kommentar beschrieben zu erstellen, müssen Sie Ihre Eingabedaten manuell bearbeiten (z. B. Wochenenden entfernen).

 
Roman Konopelko:

Es ist wahrscheinlich, dass die Möglichkeit, das Ausgabeformat für die Achsen zu ändern, implementiert werden wird, aber ich kann nicht mit Sicherheit sagen, in welcher Form genau.

Gute Nachrichten, danke.

Wie ich schon sagte, müsst ihr nicht auf die offizielle Version warten, sondern könnt hier Klassen zum Testen einstellen.
 
o_O:

Gute Nachrichten, danke.

Wie ich schon sagte, können Sie nicht warten, für die Build-Büro und legte Klassen für die Prüfung hier.
Bisher hatte ich geplant, die Möglichkeit zu implementieren, das Achsenformat in drei Formaten einzustellen:
enum ENUM_AXIS_TYPE
  {
   AXIS_TYPE_DOUBLE,
   AXIS_TYPE_DATETIME,
   AXIS_TYPE_CUSTOM,
  };
  1. AXIS_TYPE_DOUBLE - wie jetzt verwendet, wird die Standardeinstellung sein
  2. AXIS_TYPE_DATETIME - genau das, worum Sie gebeten haben, basiert auf TimeToString
  3. AXIS_TYPE_CUSTOM - erlaubt eine beliebige Ausgabe basierend auf dem Zeiger auf DoubleToStringFunction
    typedef string(*DoubleToStringFunction)(double);

Im Anhang habe ich vorsichtshalber alle Dateien der Bibliothek abgelegt.

Was Ihre Nachricht an servicedesk betrifft, so gibt es in der Tat keine Samstags- und Sonntagstermine in X array. Ich habe also nicht richtig gesagt, dass Sie die Daten korrigieren müssen.

Aber wir können Ihr Problem trotzdem lösen, indem wir einfach AXIS_TYPE_CUSTOM verwenden.

#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();
  }
//+------------------------------------------------------------------+

Ergebnis:


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

Sie können Ihr Problem aber trotzdem lösen, indem Sie AXIS_TYPE_CUSTOM verwenden.

Super, das passt!
 

Ich habe einen kurzen Blick auf die Datei Graphic.mqh geworfen.

Haben Sie beschlossen, alle nicht virtuellen Funktionen zu verlassen?

GUT,

Können wir zumindest ***Plot-Funktionen (HistogramPlot, LinesPlot, etc.) virtuell sein?

Da ihre "Design"-Fähigkeiten für diese Aufgabe nicht ausreichen (Farbverläufe beim Füllen oder mehrere Farben beim Rendern).

 
o_O:

Ich habe einen kurzen Blick auf die Datei Graphic.mqh geworfen.

Haben Sie beschlossen, alle nicht virtuellen Funktionen zu verlassen?

GUT,

Können wir zumindest ***Plot-Funktionen (HistogramPlot, LinesPlot, etc.) virtuell sein?

Da ihre "Design"-Fähigkeiten für diese Aufgabe nicht ausreichen (Farbverläufe beim Füllen oder mehrere Farben beim Rendern).

Selbst wenn Sie sie virtuell machen, werden Sie nicht in der Lage sein, normale Überladung ohne vollen Zugriff auf CGraphics Klassenmitglieder zu tun, so dass sie alle (die meisten) müssen als geschützt deklariert werden. Ich kann es nicht mit Sicherheit sagen, aber höchstwahrscheinlich werden beide Aspekte umgesetzt werden.