Un autre module pour dessiner des graphiques

Il y a quinze ans, il m'a fallu pour afficher un graphique dans mon programme de diplôme. Il y aurait un programme dans Builder ou Delphi, tout irait bien, mais je n'ai écrit que pour Windows dans MFC, et là ce n'est pas très bien avec les classes de graphes. Et puis j'ai écrit mon propre module de traçage. Trois cinq ans se sont écoulés, mais le module est resté, a été repensé et je l'utilise parfois dans mes métiers sous QNX, Linux et Windows. Peut-être que cela vous sera utile d'une manière ou d'une autre.



Le module de dessin graphique présenté vous permet d'afficher un nombre arbitraire de graphiques colorés avec une légende. Le nombre de points dans les graphiques peut être des dizaines de millions ou plus (si seulement il y a assez de mémoire) sans diminution significative de la vitesse de redessin, puisque chaque fois que l'échelle est modifiée, un ensemble de points est construit, affiché sur le écran, en tenant compte de l’échelle. Ainsi, le nombre de points n'affecte que le temps de recalcul de ces points affichés lors du changement d'échelle.



Les fonctions de pixellisation ont été déplacées vers les classes de plug-ins. Au total, trois options sont actuellement possibles: le dessin avec les fonctions Windows-GUI standard de MFC (classe CVideo_Windows), le dessin avec les fonctions Qt standard (classe CVideo_Qt) et la rastérisation logicielle (classe CVideo_Software - avec révision ce module peut être utilisé sur les microcontrôleurs). Le transcodage des caractères au format requis pour les classes de pixellisation est effectué par la classe CTranslator.



Les classes séparées incluent les types de ligne (si le type est pris en charge par la classe de pixellisation), les couleurs, les points et les rectangles.



En maintenant le bouton gauche de la souris enfoncé, vous pouvez vous déplacer dans le champ du graphique. Avec le bouton droit, vous pouvez définir la zone sélectionnée, en cliquant sur laquelle avec le bouton droit de la souris vous reviendrez à l'échelle initiale spécifiée, et après avoir cliqué avec le bouton gauche, l'opération d'agrandissement sera effectuée.



Les graphiques dessinés ressemblent à ceci:







La création d'une classe de graphes, par exemple, pour Windows dans MFC, se fait comme suit:



 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);

      
      





Ici, la classe cWnd_Graphics fournit une liaison de la classe graphique CGraphics avec Windows, transmettant les événements qui se produisent sous Windows à la classe CGraphics et fournissant l'affichage du graphique dans l'événement de redessinage ON_WM_PAINT. Pour les autres systèmes d'exploitation, ce bundle devra être réécrit, en tenant compte du système d'exploitation utilisé. Dans cet exemple, via cWnd_Graphics.GetIGraphicsPtr (), vous pouvez accéder directement à la classe de graphique CGraphics et configurer les paramètres d'affichage du graphique, ainsi que demander à la classe de graphique de créer un nouveau graphique et d'y renvoyer le pointeur AddNewGraphic (un pointeur vers le La classe CGrData sera obtenue). Vous ne pouvez pas supprimer ce pointeur vous-même - le graphique ne peut être supprimé que via la fonction DeleteGraphic. À l'avenir, le travail avec le calendrier est effectué via le pointeur résultant.



Au total, les fonctions de gestion des graphiques suivantes sont disponibles:



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);//   

      
      





En principe, vous pouvez personnaliser l'affichage de manière assez flexible.



Le mode de contrôle utilisateur spécifié dans les deux dernières fonctions est utilisé lors de la sortie de données avec des mises à jour (par exemple, l'instrument ajoute des points à une certaine fréquence). Dans ce cas, lorsque vous essayez de déplacer / agrandir le graphique, le mode de contrôle utilisateur est activé et lorsque vous revenez à l'échelle d'origine, ce mode est désactivé. Cela vous permet d'arrêter de changer l'échelle lors de l'ajout de données (si le mode est activé, vous n'avez tout simplement pas besoin d'appeler le recalcul de l'échelle, comme dans l'exemple ci-dessus).



Un exemple de programme utilisant ce module (il existe des sources du module).

Il y a 4 fichiers du projet - main.cpp, cdialog_main.h, cdialog_main.cpp et stdafx.h. Ces quatre fichiers contiennent un exemple de connexion du module de traçage. Tous les autres fichiers source font partie du module de traçage.



Eh bien, c'est en fait tout ce que l'on peut dire sur ce métier primitif.

PS On m'a dit ici que j'avais un nom malheureux pour les fonctions (Graph - graph, et Graphic - graphics). Désolé, j'ai appris l'allemand et j'ai pensé qu'en anglais ce serait comme ça. :)



All Articles