Bueno, despues de probar un trillon de veces, logre hacer mi propio graficador de lineas.
Espero que a alguien le sirva, no es de lo mejor pero si que funciona. Y lo publico para que alguien me ayude a mejorarlo.
No es nada mas que un par de funciones con variables publicas, se hace el grafico sobre un static que le puse nombre IDC_STATI, ya que si hay oto static no funca, plis agradeceria si alguien me ayuda en esa parte.
El grafico se muestra en la linea "y" una linea de tiempo y en la "x" un valor en la fecha determinada, los datos deben estar dentro de una estructura. Es recomendable tiempos de mas de 3 años.
Declarar las funciones y variables publicas a usar
- Código: Seleccionar todo
int x,y;
struct sancione
{
int x;
char y[20];
} Sanc[100];//lo hice de esta manera porque no tengo mas tiempo, estoy super apurado
void CargaStruct(CString caco);
void Cuadricula (COleDateTime desd, COleDateTime hast,int max_x);
//fecha desde es la fecha minima del grafico
//fecha desde es la fecha maxima del grafico
//Max_x es el valor maximo de la estructura
//el minimo es 0
COleDateTime desde;
COleDateTime hasta;
pegar en el cpp lo siguiente:
- Código: Seleccionar todo
void CMiClase::CargaStruct (CString legajo)
{
x=y=0;
// aca hago un selec dato, fecha
result=PQexec (cone,sql);
if (PQresultStatus(result)==PGRES_TUPLES_OK)
if (PQntuples(result)!=0)
{
for (int i=0;i<PQntuples(result);i++)
{
Sanc[i].x=atoi(PQgetvalue (result,i,0));// la cantidad de datos
strcpy (Sanc[i].y,PQgetvalue (result,i,1));//fecha que corresponde al dato
}
Sanc[i].x=NULL;
}
else
Sanc[0].x=NULL;
maximo=20;
// maximo es el valor mas alto para la columna X
// puede ser cargado conforme lo que se obtiene
// ej: con un selec MAX(dato) group by dato order by dato desc
Cuadricula (desde, hasta, maximo);
};
/*
sea cual fuere la forma lo importante es cargar algo como esto
Sanc[0].x=12;
Sanc[0].y="1997-05-01";
Sanc[1].x=2;
Sanc[1].y="2005-01-08";
Sanc[2].x=NULL;
*/
void CMiClase::Cuadricula (COleDateTime desd, COleDateTime hast, int max_x)
{
if (desd>hast)
return;
if (max_x==0)
return;
COleDateTime aux (desd);
CClientDC dlgDC(GetDlgItem(IDC_STATI));
CRect rect;
GetDlgItem(IDC_STATI)->GetClientRect(&rect);
/////////////////////////////////// CUADRICULAS
//////////////// Linea de Tiempo
CString anio;
COleDateTimeSpan dias;
dias=hast-desd;
int total=dias.GetDays();
int punto=0, maxx;
for (aux;aux<hast;aux+=1)
{
if (aux.GetDay()==1 && aux.GetMonth ()==1)//para hacer una linea por año... Oviamente el 1 de Enero...
{
/* dias.GetDays()*rect.Width()/total
es una regla de 3 simple para obtener los pixels
total tiene todos los dias de "desde" a "hasta"
si total=rect.Width() (osea el ancho del Static)
cuanto seria dias.GetDays().
*/
dias=aux-desd;
dlgDC.MoveTo(dias.GetDays()*rect.Width()/total,0 );//
dlgDC.LineTo(dias.GetDays()*rect.Width()/total,rect.Height());
if (((dias.GetDays()*rect.Width()/total)-17)>=punto+34 || punto==0)//para q los años no se encimen
{
dlgDC.TextOut((dias.GetDays()*rect.Width()/total)-17,rect.Height(),aux.Format("%Y"));
punto=(dias.GetDays()*rect.Width()/total)-17;
}
}
}
////////////////
int fila=rect.Height()/max_x;
punto=0;
maxx=max_x-1;
for (int I=fila;I<rect.Height();I+=fila)
{
if (I>punto+15 || punto==0)//mismo concepto... para que no se encimen los numeros
{
anio.Format("%d",maxx);//economia de variables...
dlgDC.MoveTo(0,I);//
dlgDC.LineTo(rect.Width(),I);
dlgDC.TextOut(-25,I-10,anio);
punto=I;
}
maxx--;// en linea vertical el 0 esta arriba. Asi se muestra invertido.
}
/////////////////////////////////// LINEAS DE VALORES
CPen pen;
pen.CreatePen(PS_SOLID, 3, RGB(0,0,255));
CPen *oldPen = dlgDC.SelectObject(&pen);
CString fecha;
for (int i=0;i<1000;i++)
{
if (Sanc[i].x==NULL)
break;
else
{
fecha.Format("%s",Sanc[i].y);
aux.SetDate(atoi(fecha.Left(4)),atoi(fecha.Mid(5,6)),atoi(fecha.Right(2)));
dias=aux-desd;
if (x!=0 && y!=0)
dlgDC.MoveTo( x,y );
else
{
x=dias.GetDays()*rect.Width()/total;
y=rect.Height()-((rect.Height()/max_x)*Sanc[i].x);
dlgDC.MoveTo(x,y);
}
x=dias.GetDays()*rect.Width()/total;
y=rect.Height()-((rect.Height()/max_x)*Sanc[i].x);
dlgDC.LineTo(x,y);
dlgDC.Ellipse( x-2, y-2,x+5, y+5 );
}
}
x=y=0;
}
con el Windows Message Handle agregar la funcion OnPaint
y dentro colocar la funcion Cuadricula (desde, hasta,maximo);
- Código: Seleccionar todo
void CMiClase::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
Cuadricula (desde, hasta,maximo);
// Do not call CDialog::OnPaint() for painting messages
}
tener en cuenta que se debe cargar "desde" y "hasta" antes de llamar la funcion CargaStruct(legajo)
sancion->desde=desde;
sancion->hasta=hasta;
sancion->CargaStruct(legajo);