17 de agosto de 2006

Gráficas de barra sin complicaciones

Artículo original: BAR GRAPHICS WITHOUT COMPLICATIONS
https://vfpimaging.blogspot.com/2006/03/bar-graphics-without-complications_7232.html
Autor: Cesar Ch.
Traducido por: Ana María Bisbé York


Siempre veo gente preguntando cómo crear gráficos sin controles ActiveX.

En mi opinión, la forma más sencilla de hacerlo es empleando etiquetas. Las etiquetas son muy versátiles, podemos cargar sus propiedades BackColor, Caption, Width, Height. Estas cuatro propiedades son todo lo que necesitamos para crear un sencillo gráfico, como este que vemos debajo en la figura.



El gráfico está dibujado en un contenedor. Podemos configurar el color de la etiqueta para el color de la barra, en su título podemos guardar los valores, sus alturas son proporcionales a sus valores, y el ancho depende de la división entre el ancho del contenedor y la cantidad de barras.

Las barras se auto ajustan a si mismas, en dependencia del dato que reciben, y las dimensiones del contenedor.

Todo está hecho en un método sencillo. En el formulario de ejemplo, he puesto este código en el método Refresh() del objeto Container. Es necesario un cursor para guardar los datos, en el que el primer campo, FIELD(1), recibe los valores y el segundo, FIELD(2) recibe las títulos. El nombre del cursor se guarda en la propiedad Tag del contenedor. ¡ Y esto es todo !

Se agregó código extra para permitir el redimensionamiento del formulario.

Coloque este código en en evento Load del formulario:
CREATE CURSOR sales (amount n(8,2), cName c(6))
INSERT INTO sales VALUES (250,"JAN")
INSERT INTO sales VALUES (128,"FEB")
INSERT INTO sales VALUES ( 90,"MAR")
INSERT INTO sales VALUES (330,"APR")
INSERT INTO sales VALUES (190,"MAY")
INSERT INTO sales VALUES (250,"JUN")
INSERT INTO sales VALUES ( 50,"JUL")
INSERT INTO sales VALUES ( 80,"AUG")
INSERT INTO sales VALUES ( 50,"SEP")
INSERT INTO sales VALUES ( 19,"OCT")
INSERT INTO sales VALUES (160,"NOV")
INSERT INTO sales VALUES (199,"DEC")
Y esto en el evento Refresh:
*!* Crea una matriz de 12 colores que serán utilizados
DIMENSION laColors(12)
laColors(1) = RGB(255,128,128) && Rojo
laColors(2) = RGB(0,255,0) && Verde Claro
laColors(3) = RGB(128,128,255) && Azul Oscuro
laColors(4) = RGB(255,0,255) && Rosa
laColors(5) = RGB(0,255,255) && Cyan
laColors(6) = RGB(255,255,0) && Amarillo
laColors(7) = RGB(160,160,210) && Azul Claro
laColors(8) = RGB(255,160,30) && Naranja
laColors(9) = RGB(200,140,140) && Marrón Oscuro
laColors(10) = RGB(96,196,96) && Verde Oscuro
laColors(11) = RGB(255,200,200) && Marrón Claro
laColors(12) = RGB(200,200,200) && Gris
lnBlack = RGB(28,28,28) && Negro
lnWhite = RGB(255,255,255) && Blanco
lcTable = This.Tag
SELECT "&lcTable"
*!* Calcula el ancho de cada barra
lnlargura = INT(This.Width / RECCOUNT())
lnAltura = This.Height
lcFldValor = This.Tag + "." + FIELD(1)
IF FCOUNT() > 1
  lcFldLegenda = This.Tag + "." + FIELD(2)
ELSE
  lcFldLegenda = ""
ENDIF
CALCULATE MAX(EVALUATE(lcFldValor)) TO lnMax
*!* Agrega etiquetas que serán las barras y los títulos
SCAN 
  n = RECNO()
  lcObj = "label" + TRANSFORM(n)
  lcLeg = "lname" + TRANSFORM(n)
  *!* Verifica que existe ya el objeto, para evitar errores
  IF TYPE("This."+lcObj) <> "O"
    This.AddObject(lcObj,"label")
    This.AddObject(lcLeg,"label")
  ENDIF
  WITH This.&lcObj.
    .BackStyle = 1 && opaco
    .Backcolor = laColors(IIF(n>12,n-12,n))
    .Width = lnLargura
    lnValor = EVALUATE(lcFldValor)
    lnBarra = ( lnValor / lnMax) * (This.Height - 1 - 17)
    .Height = lnBarra
    .left = ((n-1) * lnLargura) + 2
    .Top = lnAltura - This.&lcObj..Height - 17
    .Tag = TRANSFORM(lnValor)
    .Caption = TRANSFORM(lnValor)
    .FontSize = 8
    .FontBold = .T.
    .Alignment = 2
    .Visible = .T.
  ENDWITH
  WITH This.&lcLeg.
    .BackStyle = 1 && opaco
    .Backcolor = lnWhite
    .ForeColor = lnBlack
    .Width = lnLargura - 2
    IF NOT EMPTY(lcFldLegenda)
      .Caption = ALLTRIM(EVALUATE(lcFldLegenda))
    ENDIF 
    .left = ((n-1) * lnLargura) + 3
    .Top = This.Height - 17
    .Height = 17
    .FontSize = 8
    .Alignment = 2
    .Visible = .T.
  ENDWITH
ENDSCAN
This.Width = ((n) * lnLargura) + 3
Puede utilizar esta técnica para crear gráficas de barras horizontales, con un ligera adaptación del código.

En el fichero adjunto, bargraphics.zip encontrará bargraphics.scx/sct para este ejemplo, y otros tres archivos, callbar.prg que llama a barras.scx/sct que crea un formulario modal con bargraphics que puede ser redimensionado.

4 comentarios :

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.