Ein weiteres Modul zum Zeichnen von Grafiken

Vor fünfzehn Jahren brauchte ich, um eine Grafik in meinem Diplomprogramm anzuzeigen. Es würde ein Programm in Builder oder Delphi geben, alles wäre in Ordnung, aber ich habe nur für Windows in MFC geschrieben, und dort ist es irgendwie nicht sehr gut mit Grafikklassen. Und dann habe ich mein eigenes Plotmodul geschrieben. Drei bis fünf Jahre sind vergangen, aber das Modul blieb erhalten, wurde neu gestaltet und ich verwende es manchmal in meinem Handwerk unter QNX, Linux und Windows. Vielleicht wird es Ihnen irgendwie nützlich sein.



Mit dem vorgestellten Modul zum Zeichnen von Diagrammen können Sie eine beliebige Anzahl farbiger Diagramme mit einer Legende anzeigen. Die Anzahl der Punkte in den Diagrammen kann mehrere zehn Millionen oder mehr betragen (wenn nur genügend Speicher vorhanden ist), ohne dass die Geschwindigkeit des Neuzeichnens erheblich verringert wird, da bei jeder Änderung der Skala eine Reihe von Punkten erstellt und auf dem angezeigt wird Bildschirm unter Berücksichtigung der Skala. Daher beeinflusst die Anzahl der Punkte nur die Neuberechnungszeit dieser angezeigten Punkte, wenn die Skala geändert wird.



Rasterisierungsfunktionen wurden in Plug-In-Klassen verschoben. Insgesamt sind derzeit drei Optionen möglich: Zeichnen mit Standard-Windows-GUI-Funktionen von MFC (CVideo_Windows-Klasse), Zeichnen mit Standard-Qt-Funktionen (CVideo_Qt-Klasse) und Software-Rasterisierung (CVideo_Software-Klasse - mit Überarbeitung kann dieses Modul auf Mikrocontrollern verwendet werden). Die Transcodierung von Zeichen in das für Rasterisierungsklassen erforderliche Format wird von der CTranslator-Klasse durchgeführt.



Separate Klassen umfassen Linientypen (wenn der Typ von der Rasterisierungsklasse unterstützt wird), Farben, Punkte und Rechtecke.



Wenn Sie die linke Maustaste gedrückt halten, können Sie sich im Diagrammfeld bewegen. Mit der rechten Taste können Sie den ausgewählten Bereich einstellen, indem Sie darauf klicken, mit der rechten Maustaste zur angegebenen Anfangsskala zurückkehren. Nach dem Klicken mit der linken Taste wird der Vergrößerungsvorgang ausgeführt.



Gezeichnete Diagramme sehen folgendermaßen aus:







Das Erstellen einer Diagrammklasse, z. B. für Windows in MFC, erfolgt wie folgt:



 CWnd_Graphics cWnd_Graphics;// 
 CGrData *cGrData_SinPtr;//    
 CGrData *cGrData_CosPtr;//    

// 
CRect cRect_Client;
((CStatic*)GetDlgItem(IDC_STATIC_MAIN_MAP))->GetClientRect(&cRect_Client);
cWnd_Graphics.Create(WS_VISIBLE,cRect_Client,(CStatic*)GetDlgItem(IDC_STATIC_MAIN_MAP));
 	
 // 
 cWnd_Graphics.GetIGraphicsPtr()->SetBackGroundColor(CGrColor(192,192,192));
 cWnd_Graphics.GetIGraphicsPtr()->SetLegendBackGroundColor(CGrColor(230,230,230));
 cWnd_Graphics.GetIGraphicsPtr()->SetAxisColor(CGrColor(0,0,0),CGrColor(0,0,0));
 cWnd_Graphics.GetIGraphicsPtr()->SetTextValueColor(CGrColor(0,0,0),CGrColor(0,0,0),CGrColor(0,0,0));
 cWnd_Graphics.GetIGraphicsPtr()->SetSelectRectangleColor(CGrColor(0,0,255)); 
 cWnd_Graphics.GetIGraphicsPtr()->SetName(" ");
 // 
 cGrData_SinPtr=cWnd_Graphics.GetIGraphicsPtr()->AddNewGraphic();
 cGrData_SinPtr->SetEnable(true);
 cGrData_SinPtr->SetGrColor(CGrColor(255,0,0));
 cGrData_SinPtr->SetGrLineStyle(CGrLineStyle(IVideo::LINE_TYPE_SOLID,1,false,false));
 cGrData_SinPtr->SetName(" ");
 
 for(size_t n=0;n<1024;n++)
 {
  double x=n;
  double y=sin(x*0.01);
  cGrData_SinPtr->AddPoint(x,y);
 }

 cGrData_CosPtr=cWnd_Graphics.GetIGraphicsPtr()->AddNewGraphic();
 cGrData_CosPtr->SetEnable(true);
 cGrData_CosPtr->SetGrColor(CGrColor(0,0,255));
 cGrData_CosPtr->SetGrLineStyle(CGrLineStyle(IVideo::LINE_TYPE_SOLID,3,false,false));
 cGrData_CosPtr->SetName(" ");

 for(size_t n=0;n<1024;n++)
 {
  double x=n;
  double y=cos(x*0.01);
  cGrData_CosPtr->AddPoint(x,y);
 }

 // ,    
 CGrRect cGrRect;
 cWnd_Graphics.GetIGraphicsPtr()->FindViewRectangle(cGrRect);
 cWnd_Graphics.GetIGraphicsPtr()->SetRectangle(cGrRect);
 cWnd_Graphics.GetIGraphicsPtr()->OnMagnify();
 cWnd_Graphics.GetIGraphicsPtr()->GetRectangle(cGrRect);
 cWnd_Graphics.GetIGraphicsPtr()->SetOriginalScale(cGrRect);

      
      





Hier bietet die cWnd_Graphics-Klasse eine Bindung der CGraphics-Grafikklasse an Windows, leitet Ereignisse, die unter Windows auftreten, an die CGraphics-Klasse weiter und stellt die Anzeige des Diagramms im ON_WM_PAINT-Neuzeichnungsereignis bereit. Bei anderen Betriebssystemen muss dieses Bundle unter Berücksichtigung des verwendeten Betriebssystems neu geschrieben werden. In diesem Beispiel können Sie über cWnd_Graphics.GetIGraphicsPtr () direkt auf die CGraphics-Diagrammklasse zugreifen und die Diagrammanzeigeparameter konfigurieren sowie die Diagrammklasse auffordern, ein neues Diagramm zu erstellen und den AddNewGraphic-Zeiger darauf zurückzugeben (ein Zeiger auf das CGrData-Klasse wird erhalten). Sie können diesen Zeiger nicht selbst löschen - das Diagramm kann nur über die Funktion DeleteGraphic gelöscht werden. In Zukunft wird die Arbeit mit dem Zeitplan über den resultierenden Zeiger ausgeführt.



Insgesamt stehen folgende Diagrammverwaltungsfunktionen zur Verfügung:



CGrData* AddNewGraphic(void);//       
  void DeleteAllGraphics(void);//    
  void DeleteGraphic(CGrData *cGrDataPtr);//   
  void FindRectangle(CGrRect &cGrRect) const;//     
  void FindRectangleOfEndPoints(CGrRect &cGrRect,size_t points) const;//        points 
  void FindRectangleOfEndTime(CGrRect &cGrRect,long double time) const;//        time 
  void FindViewRectangle(CGrRect &cGrRect) const;//         
  void FindViewRectangleOfEndPoints(CGrRect &cGrRect,size_t points) const;//            points 
  void FindViewRectangleOfEndTime(CGrRect &cGrRect,long double time) const;//            time 
  void SetTimeDivider(double value);//  
  double GetTimeDivider(void) const;//  
  // 
  void CancelSelect(void);// 
  void Redraw(void);// 
  void RedrawAll(void);// 
  void OnOriginalScale(void);//    
  //  
  void SetBackGroundColor(const CGrColor &cGrColor);//  
  void SetLegendBackGroundColor(const CGrColor &cGrColor);//   
  void SetAxisColor(const CGrColor &cGrColor_AxisX,const CGrColor &cGrColor_AxisY);//  
  void SetGridColor(const CGrColor &cGrColor_GridX,const CGrColor &cGrColor_GridY);//  
  void SetSelectRectangleColor(const CGrColor &cGrColor);//   
  void SetTextValueColor(const CGrColor &cGrColor_TextX,const CGrColor &cGrColor_TextY,const CGrColor &cGrColor_TextLegend);//  
  //   
  void SetAxisLineStyle(const CGrLineStyle &cGrLineStyle_AxisX,const CGrLineStyle &cGrLineStyle_AxisY);//  
  void SetGridLineStyle(const CGrLineStyle &cGrLineStyle_GridX,const CGrLineStyle &cGrLineStyle_GridY);//  
  //   
  void SetRectangle(const CGrRect &cGrRect);//   
  void SetGridStep(long double step_x,long double step_y);//  
  void GetRectangle(CGrRect &cGrRect) const;//   
  void GetGridSize(long double &step_x,long double &step_y) const;//   
  //  
  void SetEnableMagnify(bool enable);// 
  void SetEnableValue(bool x_value,bool y_value);//  
  void SetOriginalScale(const CGrRect &cGrRect);//  
  void SetMoveMode(bool inversion);//   
  bool GetSelectedRectangle(CGrRect &cGrRect) const;//  
  void GetClientRectangle(CGrRect &cGrRect) const;//  
  void SetName(const std::string &name);//  
  bool GetUserMode(void) const;//   
  void SetUserMode(bool state);//   

      
      





Grundsätzlich können Sie das Display sehr flexibel anpassen.



Der in den letzten beiden Funktionen angegebene Benutzersteuerungsmodus wird verwendet, wenn Daten mit Aktualisierungen ausgegeben werden (z. B. fügt das Instrument Punkte mit einer bestimmten Frequenz hinzu). In diesem Fall ist der Benutzersteuerungsmodus aktiviert, wenn Sie versuchen, das Diagramm zu verschieben / zu vergrößern, und wenn Sie zur ursprünglichen Skala zurückkehren, ist dieser Modus deaktiviert. Auf diese Weise können Sie die Änderung der Skala während des Hinzufügens von Daten beenden (wenn der Modus aktiviert ist, müssen Sie die Neuberechnung der Skala einfach nicht wie im obigen Beispiel aufrufen).



Ein Beispiel für ein Programm, das dieses Modul verwendet (es gibt Quellen für das Modul).

Es gibt 4 Dateien aus dem Projekt - main.cpp, cdialog_main.h, cdialog_main.cpp und stdafx.h. Diese vier Dateien enthalten ein Beispiel für den Anschluss des Plotmoduls. Alle anderen Quelldateien sind Teile des Plotmoduls.



Nun, das ist eigentlich alles, was über dieses primitive Handwerk gesagt werden kann.

PS Ich wurde hier aufgefordert, einen unglücklichen Namen für die Funktionen zu haben (Grafik - Grafik und Grafik - Grafik). Entschuldigung, ich habe Deutsch gelernt und dachte, dass es auf Englisch so sein würde. :) :)



All Articles