Por la necesidad de hacer una gráfica con las cantidades arriba de un millón y menos de 10 millones, hice esta humilde muestra, se que se puede mejorar mucho, pero por tiempo se las comparto así. Es solo de una serie.
El código tampoco esta del todo limpio, pero creo que funciona a pequeñas necesidades.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
By the need to make a chart with amounts above one million and less than 10 million, made this humble sample, you can improve a lot, but time as well share them. It's just a number.
The code is not completely clean, but I think it works for small needs.
Code: Select all
#include "hmg.ch"
#define nWIDTH GetDeskTopWidth()
#define nHEIGHT GetDeskTopHeight()-40
FUNCTION MAIN
Local cColor := RED
*-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-SOLO ESTO HAY QUE MODIFICAR-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.--.-.-.-.-.//
LOCAL nRow := 10
LOCAL nCol := 10
LOCAL nW := 800
LOCAL nH := 300
LOCAL cTitulo := "VENTAS POR MES DURANTE 2014"
LOCAL aNombresS := {"Serie 1"}
*LOCAL aValoresS := {-114054.57 , -2141184.09 , -146106.72 , -11210.16 , -148153.12 , -140945.27 , -15857.91 ,-180792.10 , -16074.99}
*LOCAL aValoresS := {-14054.57 , +2141184.09 , -146106.72 , +11210.16 , -148153.12 , +140945.27 , +15857.91 ,-180792.10 , +16074.99}
*LOCAL aValoresS := {+14054.57 , -2141184.09 , +146106.72 , -11210.16 , +148153.12 , -140945.27 , +15857.91 ,-180792.10 , +16074.99}
LOCAL aValoresS := {14054.57 , 2141184.09 , 146106.72 , 11210.16 , 148153.12 , 140945.27 , 15857.91 ,180792.10 , 16074.99}
*LOCAL aValoresS := {1152391.62 , 1145743.14 , 1222495.43 , 1451246.80 , 1282571.94 , 1251319.02 , 1245945.15 , 1282475.94 , 1293606.78 }
*LOCAL aValoresS := {1.57 , 2.09 , 3.72 , 4.16 , 5.12 , 6.27 , 7.91 , 8.10 , 9.99}
*LOCAL aValoresS := {250.57 , 320.09 , 200.72 , 800.16 , 1200.12 , 400.27 , 300.91 ,150.10 , 800.99}
LOCAL aX := {"ENE","FEB","MAR","ABR","MAY","JUN","JUL","AGO","SEP"}
LOCAL aColores := {cColor,cColor,cColor,cColor,cColor,cColor,cColor,cColor,cColor}
LOCAL nWColumn := 50
LOCAL lLineas := .T.
LOCAL lMarco := .T.
*-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.//
LOCAL cFormat := "99,999,999.99"
LOCAL nY := 0
LOCAL nVecesY := 0
LOCAL nVecesP := 0
LOCAL nVecesN := 0
LOCAL nRowF := nRow + nH
LOCAL nColF := nCol + nW
LOCAL nAnchoVal := 0
LOCAL lNegativo := .F.
LOCAL lPositivo := .F.
LOCAL nValorP := 0
LOCAL nValorN := 0
LOCAL nValorM := 0
LOCAL nAltoP := 0
LOCAL nRowX := 0
LOCAL nColY := 0
LOCAL nRowG := 0
LOCAL nColG := 0
LOCAL nWG := 0
LOCAL nHG := 0
LOCAL nValDiv := 0
LOCAL cLabel := ""
LOCAL cLabel2 := ""
LOCAL nColYFija := 0
LOCAL nValorY := 0
LOCAL nAncho := 0
LOCAL nValorYN := 0
SET FIXED on
SET DECIMALS TO 6
*LONGITUD DE LOS VALORES
FOR n:= 1 To Len(aValoresS)
IF Len(AllTrim(STR(aValoresS[n]))) > nAnchoVal
nAnchoVal := Len(AllTrim(STR(aValoresS[n])))
ENDIF
NEXT n
*MsgInfo(nAnchoVal)
*AVERIGUAR SI HAY NEGATIVOS Y POSITIVOS
FOR n:= 1 TO Len(aValoresS)
IF aValoresS[n] < 0
lNegativo := .T.
ELSE
lPositivo := .T.
ENDIF
Next n
*----------------------------------------------------------------------------------------------------------------------------------------------------
IF !lNegativo .and. lPositivo //Solo +
*Obtener el Valor Maximo
FOR n:= 1 TO Len(aValoresS)
IF(aValoresS[n] > nValorP , nValorP := aValoresS[n] , )
Next n
nValorM := nValorP
nY := ValnY(nValorM)
*Obtener Row de las X y Col de las Y
nRowX := nRowF //-30
nColY := nCol+(nAnchoVal*10)
nWG := nColF-200-nColY-30
nHG := nRowF-nRow -80
*MsgInfo(nWG)
*MsgInfo(nHG)
nValDiv:= nHG/nValorP
*nAltoP := nValDiv * aValoresS[1]
nAltoP := nHG
nVecesP := Int(nValorP/nY) //Numero de veces que pone los valores en el Eje Y
* MsgInfo(nVecesP)
ELSEIF lNegativo .and. !lPositivo //Solo - *********************************************************************
*Obtener el Valor Maximo Negativo
FOR n:= 1 TO Len(aValoresS)
IF(Abs(aValoresS[n]) > (nValorN) , nValorN := Abs(aValoresS[n]) , )
Next n
*CALCULAR VALOR MAXIMO TOTAL
nValorM := nValorN
*MsgInfo(nValorN)
*MsgInfo(nValorM)
nY := ValnY(nValorM)
*Obtener Row de las X y Col de las Y
nRowX := nRow+40
nColY := nCol+(nAnchoVal*10)
nWG := nColF-200 - nColY-30
nHG := nRowF-nRow -80
*MsgInfo(nWG)
* MsgInfo(nHG)
* MsgInfo(nValorN)
nValDiv:= nHG/nValorN
* MsgInfo(nValDiv)
nAltoN := nHG
nRowX := nRow+60
nVecesN := Int(nValorN/nY) //Numero de veces que pone los valores en el Eje Y
ELSEIF lNegativo .and. lPositivo //Hay +- ************************************************************
*Obtener Row de las X y Col de las Y
nColY := nCol+(nAnchoVal*10)
nWG := nColF-200 - nColY-30
nHG := nRowF-nRow -80
*MsgInfo(nAnchoVal)
*OBTENER LOS VALORES MAXIMOS Negativos y Positivos
FOR n:= 1 TO Len(aValoresS)
IF aValoresS[n] < 0
* MsgBox("Si hay Negativos")
lNegativo := .T.
IF(Abs(aValoresS[n]) > nValorN , nValorN := Abs(aValoresS[n]) , )
ELSE
IF(aValoresS[n] > nValorP , nValorP := aValoresS[n] , )
lPositivo := .T.
ENDIF
Next n
*CALCULAR VALOR MAXIMO TOTAL
nValorM := nValorP + nValorN
nY := ValnY(nValorM)
nVecesP := Int(nValorP/nY) //Numero de veces que pone los valores en el Eje Y
IF( nVecesP = 0 , nVecesP := 1,)
nVecesN := Int(nValorN/nY) //Numero de veces que pone los valores en el Eje Y
IF( nVecesN = 0 , nVecesN := 1,)
*MsgInfo("Veces valores en Y : " + str(nVecesY))
*nAltoP := nValDiv * aValoresS[1]
nAltoN := (nHG * nValorN) / nValorM
nAltoP := (nHG * nValorP) / nValorM
nValDiv:= nAltoP/nValorP
nRowX := nRowF -nAltoN
* MsgInfo(nVecesP)
* MsgInfo(nVecesN)
ENDIF
IF nValorM < 10
cFormat := "99.99"
ELSEIF nValorM < 100
cFormat := "999.99"
ELSEIF nValorM < 1000
cFormat := "9,999.99"
ELSEIF nValorM < 10000
cFormat := "99,999.99"
ELSEIF nValorM < 100000
cFormat := "9,999,999.99"
ELSEIF nValorM > 1000000
cFormat := "99,999,999.99"
ENDIF
nColY := nColY + 1
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DEFINE WINDOW Main AT 0 , 0 WIDTH nW+100 HEIGHT nH+150 TITLE "GRAPH" MAIN ON INIT NIL //(MsgBox(Main.HEIGHT) , MsgInfo(Main.WIDTH))
@ nRow+10,nCol LABEL Label_1 VALUE cTitulo WIDTH nRow + nW - 10 HEIGHT 30 FONT 'Arial' SIZE 15 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT CENTERALIGN
@ nRow+40,nColF-180 LABEL Serie VALUE "- "+aNombresS[1] WIDTH 200 HEIGHT 30 FONT 'Arial' SIZE 10 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT
IF lMarco
draw line in window Main at nRow,nCol to nRow,nColF pencolor aColores[1] penwidth 1
draw line in window Main at nRow,nCol to nRowF+50,nCol pencolor aColores[1] penwidth 1
draw line in window Main at nRow,nColF to nRowF+50,nColF pencolor aColores[1] penwidth 1
draw line in window Main at nRowF+50,nCol to nRowF+50,nColF pencolor aColores[1] penwidth 1
ENDIF
IF (!lNegativo .and. lPositivo) //+
draw line in window Main at nRowX,nColY-10 to nRowX,nColF-200 pencolor {0,0,0} penwidth 1 //EJE X
draw line in window Main at nRowF-20+50,nColY-1 to nRow+40,nColY-1 pencolor {0,0,0} penwidth 1 //EJE Y
nColYFija := nColY
@ nRowX,nColY-10 LABEL Label_2 VALUE "0" CENTERALIGN WIDTH 10 TRANSPARENT TOOLTIP "Label 5 CenterAlign Transparent" //el "0" entre los ejes
FOR n:= 1 TO Len(aValoresS) //Valores en las X y Barras
cLabel2:= "Label_" +StrZero(n,3,0)
nAltoP := nValDiv * aValoresS[n]
draw rectangle in window Main at nRowX-nAltoP,nColY to nRowX,nColY+nWColumn pencolor aColores[n] penwidth 0 fillcolor aColores[n]
@ nRowX,nColY LABEL &(cLabel2) VALUE aX[n] WIDTH nColY-nRow - 10 HEIGHT 30 FONT 'Arial' SIZE 9 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT //RIGHTALIGN
nColY := nColY + nWColumn + 5
NEXT n
FOR n:= 1 TO nVecesP+1 //Valores en Y y Si se ponen Lineas o no.
cLabel := "Label_" +StrZero(n,2,0)
nValorY := nY * n
nValorY := nValorY * nValDiv
* MsgInfo(nValorY)
@ nRowX-nValorY-8,nCol+10 LABEL &(cLabel) VALUE Transform(nY*n,cFormat) WIDTH nColY-nRow - 10 HEIGHT 30 FONT 'Arial' SIZE 9 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT //Valores en el eje Y
IF lLineas
draw line in window Main at nRowX-nValorY,nColYFija to nRowX-nValorY,nColF-200 pencolor {0,0,0} penwidth 1 //EJE X paralelas
ENDIF
Next n
IF lNegativo
*MsgBox("Si Hay Negativos")
nVecesY := Int(nValorN/nY) //Numero de veces que pone los valores en el Eje Y
IF (nVecesY = 0, nVecesY := 1, )
*MsgInfo(nVecesY)
FOR n:= 1 TO nVecesY
cLabel := "Label_" +StrZero(n,4,0)
nValorY := nY * n
nValorY := nValorY * nValDiv
* MsgInfo(nValorY)
@ nRowX+nValorY,nCol+10 LABEL &(cLabel) VALUE "-"+Transform(nY*n,cFormat) WIDTH nColY-nRow - 10 HEIGHT 30 FONT 'Arial' SIZE 9 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT //Valores en el eje Y
IF lLineas
draw line in window Main at nRowX+nValorY,nColYFija to nRowX+nValorY,nColF-200 pencolor {0,0,0} penwidth 1 //EJE X paralelas
ENDIF
Next n
ENDIF
ELSEIF (lNegativo .and. !lPositivo) //-
draw line in window Main at nRowX,nColY-10 to nRowX,nColF-200 pencolor {0,0,0} penwidth 1 //EJE X
draw line in window Main at nRowF-20+50,nColY-1 to nRow+40,nColY-1 pencolor {0,0,0} penwidth 1 //EJE Y
nColYFija := nColY
@ nRowX,nColY-10 LABEL Label_2 VALUE "0" CENTERALIGN WIDTH 10 TRANSPARENT TOOLTIP "Label 5 CenterAlign Transparent" //el "0" entre los ejes
FOR n:= 1 TO Len(aValoresS)
cLabel2:= "Label_" +StrZero(n,3,0)
nAltoP := nValDiv * Abs(aValoresS[n])
* MsgInfo(nValDiv)
* MsgInfo(nAltoP)
draw rectangle in window Main at nRowX,nColY to nRowX+nAltoP,nColY+nWColumn pencolor aColores[n] penwidth 0 fillcolor aColores[n]
@ nRowX-15,nColY LABEL &(cLabel2) VALUE aX[n] WIDTH nColY-nRow - 10 HEIGHT 30 FONT 'Arial' SIZE 9 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT //RIGHTALIGN
nColY := nColY + nWColumn + 5
NEXT n
IF lNegativo
*MsgBox("Si Hay Negativos")
nVecesY := Int(nValorN/nY) //Numero de veces que pone los valores en el Eje Y
IF (nVecesY = 0, nVecesY := 1, )
*MsgInfo(nVecesY)
FOR n:= 1 TO nVecesY
cLabel := "Label_" +StrZero(n,4,0)
nValorY := nY * n
nValorY := nValorY * nValDiv
* MsgInfo(nValorY)
@ nRowX+nValorY-8,nCol+10 LABEL &(cLabel) VALUE "-"+Transform(nY*n,cFormat) WIDTH nColY-nRow - 10 HEIGHT 30 FONT 'Arial' SIZE 9 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT //Valores en el eje Y
IF lLineas
draw line in window Main at nRowX+nValorY,nColYFija to nRowX+nValorY,nColF-200 pencolor {0,0,0} penwidth 1 //EJE X paralelas
ENDIF
Next n
ENDIF
ELSEIF lNegativo .and. lPositivo //+-
draw line in window Main at nRowX,nColY-10 to nRowX,nColF-200 pencolor {0,0,0} penwidth 1 //EJE X
draw line in window Main at nRowF-20+50,nColY-1 to nRow+40,nColY-1 pencolor {0,0,0} penwidth 1 //EJE Y
nColYFija := nColY
@ nRowX,nColY-10 LABEL Label_2 VALUE "0" CENTERALIGN WIDTH 10 TRANSPARENT TOOLTIP "Label 5 CenterAlign Transparent" //el "0" entre los ejes
FOR n:= 1 TO Len(aValoresS) //Valores en las X y Barras
cLabel2:= "Label_" +StrZero(n,3,0)
nAltoP := nValDiv * aValoresS[n]
draw rectangle in window Main at nRowX-nAltoP,nColY to nRowX,nColY+nWColumn pencolor aColores[n] penwidth 0 fillcolor aColores[n]
@ nRowX,nColY LABEL &(cLabel2) VALUE aX[n] WIDTH nColY-nRow - 10 HEIGHT 30 FONT 'Arial' SIZE 9 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT //RIGHTALIGN
nColY := nColY + nWColumn + 5
NEXT n
FOR n:= 1 TO nVecesP //Valores en Y y Si se ponen Lineas o no.
cLabel := "Label_" +StrZero(n,2,0)
nValorY := nY * n
nValorY := nValorY * nValDiv
* MsgInfo(nValorY)
@ nRowX-nValorY-8,nCol+10 LABEL &(cLabel) VALUE Transform(nY*n,cFormat) WIDTH nColY-nRow - 10 HEIGHT 30 FONT 'Arial' SIZE 9 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT //Valores en el eje Y
IF lLineas
draw line in window Main at nRowX-nValorY,nColYFija to nRowX-nValorY,nColF-200 pencolor {0,0,0} penwidth 1 //EJE X paralelas
ENDIF
Next n
FOR n:= 1 TO nVecesN
cLabel := "Label_" +StrZero(n,4,0)
nValorN := nY * n
nValorN := nValorN * nValDiv
* MsgInfo(nValorN)
@ nRowX+nValorN-8,nCol+10 LABEL &(cLabel) VALUE "-"+Transform(nY*n,cFormat) WIDTH nColY-nRow - 10 HEIGHT 30 FONT 'Arial' SIZE 9 BOLD TOOLTIP "Esto es una gráfica" BACKCOLOR nil FONTCOLOR BLUE TRANSPARENT //Valores en el eje Y
IF lLineas
draw line in window Main at nRowX+nValorN,nColYFija to nRowX+nValorN,nColF-200 pencolor {0,0,0} penwidth 1 //EJE X paralelas
ENDIF
Next n
ENDIF
END WINDOW
Main.ACTIVATE
RETURN NIL
FUNCTION ValnY(nValorM)
LOCAL nValRet
IF nValorM <= 10
nValRet := 1
ELSEIF nValorM <= 100
nValRet := 10
ELSEIF nValorM <= 1000
nValRet := 100
ELSEIF nValorM <= 5000
nValRet := 100
ELSEIF nValorM <= 10000
nValRet := 1000
ELSEIF nValorM <= 500000
nValRet := 10000
ELSEIF nValorM <= 1000000
nValRet := 200000
ELSEIF nValorM <= 1500000
nValRet := 300000
ELSEIF nValorM <= 3000000
nValRet := 200000
ELSEIF nValorM <= 5000000
nValRet := 1000000
ELSEIF nValorM >= 10000000
nValRet := 1000000
ENDIF
RETURN nValRet