Otro módulo para dibujar gráficos.

Hace quince años, me tomó mostrar un gráfico en mi programa de diploma. Habría un programa en Builder o Delphi, todo estaría bien, pero solo escribí para Windows en MFC, y de alguna manera no es muy bueno con clases de gráficos. Y luego escribí mi propio módulo de trazado. Han pasado tres cinco años, pero el módulo se mantuvo, fue rediseñado y a veces lo uso en mis manualidades en QNX, Linux y Windows. Quizás te sea útil de alguna manera.



El módulo de dibujo de gráficos presentado le permite mostrar un número arbitrario de gráficos de colores con una leyenda. El número de puntos en los gráficos puede ser decenas de millones o más (si solo hay suficiente memoria) sin una disminución significativa en la velocidad de redibujo, ya que cada vez que se cambia la escala, se construye un conjunto de puntos, que se muestra en la pantalla, teniendo en cuenta la escala. Por lo tanto, el número de puntos solo afecta el tiempo de recálculo de estos puntos mostrados al cambiar la escala.



Las funciones de rasterización se han trasladado a clases de complementos. En total, actualmente son posibles tres opciones: dibujar con funciones estándar de Windows-GUI de MFC (clase CVideo_Windows), dibujar con funciones estándar Qt (clase CVideo_Qt) y rasterización de software (clase CVideo_Software - con revisión, este módulo se puede usar en microcontroladores). La transcodificación de caracteres al formato requerido para las clases de rasterización la realiza la clase CTranslator.



Las clases separadas incluyen tipos de línea (si el tipo es compatible con la clase de rasterización), colores, puntos, rectángulos.



Si mantiene presionado el botón izquierdo del mouse, puede moverse por el campo del gráfico. Con el botón derecho, puede configurar el área seleccionada, haciendo clic en la cual con el botón derecho del mouse regresará a la escala inicial especificada, y luego de hacer clic con el botón izquierdo, se realizará la operación de ampliación.



Los gráficos dibujados se ven así: La







creación de una clase de gráfico, por ejemplo, para Windows en MFC, se realiza de la siguiente manera:



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

      
      





Aquí, la clase cWnd_Graphics proporciona un enlace de la clase de gráficos CGraphics con Windows, reenviando eventos que ocurren en Windows a la clase CGraphics y proporcionando la visualización del gráfico en el evento de redraw ON_WM_PAINT. Para otros sistemas operativos, este paquete deberá reescribirse, teniendo en cuenta el sistema operativo utilizado. En este ejemplo, a través de cWnd_Graphics.GetIGraphicsPtr (), puede acceder directamente a la clase de gráfico CGraphics y configurar los parámetros de visualización del gráfico, así como pedirle a la clase de gráfico que cree un nuevo gráfico y le devuelva el puntero AddNewGraphic (un puntero al Se obtendrá la clase CGrData). No puede eliminar este puntero usted mismo; el gráfico solo se puede eliminar a través de la función DeleteGraphic. En el futuro, el trabajo con la programación se realiza a través del puntero resultante.



En total, están disponibles las siguientes funciones de gestión de cartas:



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 principio, puede personalizar la pantalla de forma bastante flexible.



El modo de control de usuario especificado en las dos últimas funciones se utiliza cuando se envían datos con actualizaciones (por ejemplo, el instrumento agrega puntos en alguna frecuencia). En este caso, cuando intenta mover / ampliar el gráfico, el modo de control de usuario está habilitado y cuando regresa a la escala original, este modo está deshabilitado. Esto le permite dejar de cambiar la escala mientras agrega datos (si el modo está habilitado, entonces simplemente no necesita llamar al recálculo de la escala, como en el ejemplo anterior).



Un ejemplo de un programa que utiliza este módulo (hay fuentes del módulo).

Hay 4 archivos del proyecto: main.cpp, cdialog_main.h, cdialog_main.cpp y stdafx.h. Estos cuatro archivos contienen un ejemplo de cómo conectar el módulo de trazado. Todos los demás archivos fuente son parte del módulo de trazado.



Bueno, eso es todo lo que se puede decir sobre esta nave primitiva.

PD: Aquí me preguntaron que tenía un nombre desafortunado para las funciones (Gráfico - gráfico y Gráfico - gráficos). Lo siento, aprendí alemán y pensé que en inglés sería así. :)



All Articles