Code: Select all
#include <hmg.ch>
Function Main
define window graph at 0, 0 width 1000 height 700 main
define label selecttype
row 10
col 10
width 150
value 'Select Graph Type'
end label
define combobox graphtype
row 10
col 160
width 100
items { 'Bar', 'Lines', 'Points', 'Pie' }
onchange drawgraph()
end combobox
define checkbox enable3d
row 10
col 280
width 100
caption 'Enable 3D'
onchange drawgraph()
end checkbox
define image grapharea
row 50
col 50
width 600
height 600
end image
end window
graph.graphtype.value := 1
graph.center
graph.activate
Return
function drawgraph
local cImage := 'graph.bmp'
local nImageWidth := 600
local nImageHeight := 600
local cTitle := 'Sample Graph'
local aYValues := {"Jan","Feb","Mar","Apr","May"}
local aData := { {14280,20420,12870,25347, 7640},;
{ 8350,10315,15870, 5347,12340},;
{12345, -8945,10560,15600,17610} }
local nBarDepth := 15
local nBarWidth := 15
local nHValues := 5
local l3D := graph.enable3D.value
local lGrid := .t.
local lXGrid := .t.
local lYGrid := .t.
local lXVal := .t.
local lYVal := .t.
local nGraphType := graph.graphtype.value
local lViewVal := .t.
local lLegends := .t.
local cPicture := '99,999.99'
local aSeries := {"Serie 1","Serie 2","Serie 3"}
local aColors := { {128,128,255}, {255,102, 10}, {55,201, 48} }
local lNoBorder := .f.
local nLegendWidth := 50
if graph.graphtype.value == 0
return nil
endif
if graph.graphtype.value == 4 // pie
drawpiegraphinBitMap( cImage, nImageWidth, nImageHeight, {1500,1800,200,500,800}, {"Product 1","Product 2","Product 3","Product 4","Product 5"}, {{255,0,0},{0,0,255},{255,255,0},{0,255,0},{255,128,64},{128,0,128}}, "Sales", 25, l3D, lxval, lLegends, lnoborder )
else
graphsave( cImage, nImageWidth, nImageHeight, aData, cTitle, aYValues, nBarDepth, nBarWidth, nil, nHValues, l3d, lGrid, lXGrid, lYGrid, ;
lXVal, lYVal, lLegends, aSeries, aColors, nGraphType, lViewVal, cPicture, nLegendWidth ,lNoBorder )
endif
graph.grapharea.picture := 'graph.bmp'
return nil
function graphsave( cImageFileName, nWidth, nHeight, aData, cTitle, aYVals, nBarD, nWideB, nSep, nXRanges, ;
l3D, lGrid, lxGrid, lyGrid, lxVal, lyVal, lLegends, aSeries, aColors, nType, lViewVal, cPicture , nLegendWindth , lNoborder )
LOCAL nI, nJ, nPos, nMax, nMin, nMaxBar, nDeep
LOCAL nRange, nResH, nResV, nWide, aPoint, cName
LOCAL nXMax, nXMin, nHigh, nRel, nZero, nRPos, nRNeg
local hBitMap, hDC, BTStruct
local nTop := 0
local nLeft := 0
local nBottom := nHeight
local nRight := nWidth
DEFAULT cTitle := ""
DEFAULT nSep := 0
DEFAULT cPicture := "999,999.99"
DEFAULT nLegendWindth := 50
private nPenWidth := 1
If ( HMG_LEN (aSeries) != HMG_LEN ( aData ) ) .or. ;
( HMG_LEN ( aSeries ) != HMG_LEN ( aColors ) )
MsgHMGError("DRAW GRAPH: 'Series' / 'SerieNames' / 'Colors' arrays size mismatch. Program terminated", "HMG Error" )
EndIf
hBitMap := BT_BitmapCreateNew ( nWidth, nHeight, { 255, 255, 255 } )
hDC := BT_CreateDC( hBitMap, BT_HDC_BITMAP, @BTStruct )
IF lGrid
lxGrid := lyGrid := .T.
ENDIF
IF nBottom <> NIL .AND. nRight <> NIL
nHeight := nBottom - nTop / 2
nWidth := nRight - nLeft / 2
nBottom -= IF( lyVal, 42, 32)
nRight -= IF( lLegends, 32 + nLegendWindth , 32 )
ENDIF
nTop += 1 + IF( Empty( cTitle ), 30, 44 ) // Top gap
nLeft += 1 + IF( lxVal, 80 + nBarD, 30 + nBarD ) // LEFT
DEFAULT nBottom := nHeight - 2 - IF( lyVal, 40, 30 ) // Bottom
DEFAULT nRight := nWidth - 2 - IF( lLegends, 30 + nLegendWindth , 30 ) // RIGHT
l3D := IF( nType == POINTS, .F., l3D )
nDeep := IF( l3D, nBarD, 1 )
nMaxBar := nBottom - nTop - nDeep - 5
nResH := nResV := 1
nWide := ( nRight - nLeft )* nResH / ( nMax( aData ) + 1 ) * nResH
// Graph area
//
IF ! lNoborder
DrawWindowBoxInBitMap( hDC, Max( 1, nTop - 44 ), Max( 1, nLeft - 80 - nBarD ), nHeight - 1, nWidth - 1 )
ENDIF
// Back area
//
IF l3D
drawrectinbitmap( hDC, nTop+1, nLeft, nBottom - nDeep, nRight, { 255, 255, 255 } )
ELSE
drawrectinbitmap( hDC, nTop-5, nLeft, nBottom, nRight, { 255, 255, 255 } )
ENDIF
IF l3D
// Bottom area
FOR nI := 1 TO nDeep+1
DrawLineinbitmap( hDC, nBottom-nI, nLeft-nDeep+nI, nBottom-nI, nRight-nDeep+nI, { 255, 255, 255 } )
NEXT nI
// Lateral
FOR nI := 1 TO nDeep
DrawLineinbitmap( hDC, nTop+nI, nLeft-nI, nBottom-nDeep+nI, nLeft-nI, {192, 192, 192} )
NEXT nI
// Graph borders
FOR nI := 1 TO nDeep+1
DrawLineinbitmap( hDC, nBottom-nI ,nLeft-nDeep+nI-1 ,nBottom-nI ,nLeft-nDeep+nI ,GRAY )
DrawLineinbitmap( hDC, nBottom-nI ,nRight-nDeep+nI-1,nBottom-nI ,nRight-nDeep+nI ,BLACK )
DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-1 ,nTop+nDeep-nI+1,nLeft-nDeep+nI ,BLACK )
DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-3 ,nTop+nDeep-nI+1,nLeft-nDeep+nI-2,BLACK )
NEXT nI
FOR nI=1 TO nDeep+2
DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-3,nTop+nDeep-nI+1,nLeft-nDeep+nI-2 ,BLACK )
DrawLineinbitmap( hDC, nBottom+ 2-nI+1,nRight-nDeep+nI ,nBottom+ 2-nI+1,nRight-nDeep+nI-2,BLACK )
NEXT nI
DrawLineinbitmap( hDC, nTop ,nLeft ,nTop ,nRight ,BLACK )
DrawLineinbitmap( hDC, nTop- 2 ,nLeft ,nTop- 2 ,nRight+ 2 ,BLACK )
DrawLineinbitmap( hDC, nTop ,nLeft ,nBottom-nDeep ,nLeft ,GRAY )
DrawLineinbitmap( hDC, nTop+nDeep ,nLeft-nDeep ,nBottom ,nLeft-nDeep ,BLACK )
DrawLineinbitmap( hDC, nTop+nDeep ,nLeft-nDeep-2,nBottom+ 2 ,nLeft-nDeep-2,BLACK )
DrawLineinbitmap( hDC, nTop ,nRight ,nBottom-nDeep ,nRight ,BLACK )
DrawLineinbitmap( hDC, nTop- 2 ,nRight+ 2 ,nBottom-nDeep+2,nRight+ 2 ,BLACK )
DrawLineinbitmap( hDC, nBottom-nDeep,nLeft ,nBottom-nDeep ,nRight ,GRAY )
DrawLineinbitmap( hDC, nBottom ,nLeft-nDeep ,nBottom ,nRight-nDeep ,BLACK )
DrawLineinbitmap( hDC, nBottom+ 2 ,nLeft-nDeep-2,nBottom+ 2 ,nRight-nDeep ,BLACK )
ENDIF
// Graph info
//
IF !Empty(cTitle)
DrawTextInBitmap( hDC, nTop - 30 * nResV, nLeft, cTitle, 'Arial', 12, RED, 2 )
ENDIF
// Legends
//
IF lLegends
nPos := nTop
FOR nI := 1 TO HMG_LEN( aSeries )
DrawBarinbitmap( hDC, nRight+(8*nResH), nPos+(9*nResV), 8*nResH, 7*nResV, l3D, 1, aColors[nI] )
DrawTextInBitmap( hDC, nPos, nRight+(20*nResH), aSeries[nI], 'Arial', 8, BLACK, 0 )
nPos += 18*nResV
NEXT nI
ENDIF
// Max, Min values
nMax := 0
FOR nJ := 1 TO HMG_LEN(aSeries)
FOR nI :=1 TO HMG_LEN(aData[nJ])
nMax := Max( aData[nJ][nI], nMax )
NEXT nI
NEXT nJ
nMin := 0
FOR nJ := 1 TO HMG_LEN(aSeries)
FOR nI :=1 TO HMG_LEN(aData[nJ])
nMin := Min( aData[nJ][nI], nMin )
NEXT nI
NEXT nJ
nXMax := IF( nMax > 0, DetMaxVal( nMax ), 0 )
nXMin := IF( nMin < 0, DetMaxVal( nMin ), 0 )
nHigh := nXMax + nXMin
nMax := Max( nXMax, nXMin )
nRel := ( nMaxBar / nHigh )
nMaxBar := nMax * nRel
nZero := nTop + (nMax*nRel) + nDeep + 5 // Zero pos
IF l3D
FOR nI := 1 TO nDeep+1
DrawLineinbitmap( hDC, nZero-nI+1, nLeft-nDeep+nI , nZero-nI+1, nRight-nDeep+nI, {192, 192, 192} )
NEXT nI
FOR nI := 1 TO nDeep+1
DrawLineinbitmap( hDC, nZero-nI+1, nLeft-nDeep+nI-1 , nZero-nI+1, nLeft -nDeep+nI, GRAY )
DrawLineinbitmap( hDC, nZero-nI+1, nRight-nDeep+nI-1, nZero-nI+1, nRight-nDeep+nI, BLACK )
NEXT nI
DrawLineinbitmap( hDC, nZero-nDeep, nLeft, nZero-nDeep, nRight, GRAY )
ENDIF
aPoint := Array( HMG_LEN( aSeries ), HMG_LEN( aData[1] ), 2 )
nRange := nMax / nXRanges
// xLabels
nRPos := nRNeg := nZero - nDeep
FOR nI := 0 TO nXRanges
IF lxVal
IF nRange*nI <= nXMax
DrawTextInBitmap( hDC, nRPos, nLeft-nDeep-70, Transform(nRange*nI, cPicture), 'Arial', 8, BLUE )
ENDIF
IF nRange*(-nI) >= nXMin*(-1)
DrawTextInBitmap( hDC, nRNeg, nLeft-nDeep-70, Transform(nRange*-nI, cPicture), 'Arial', 8, BLUE )
ENDIF
ENDIF
IF lxGrid
IF nRange*nI <= nXMax
IF l3D
FOR nJ := 0 TO nDeep + 1
DrawLineinbitmap( hDC, nRPos + nJ, nLeft - nJ - 1, nRPos + nJ, nLeft - nJ, BLACK )
NEXT nJ
ENDIF
DrawLineinbitmap( hDC, nRPos, nLeft, nRPos, nRight, BLACK )
ENDIF
IF nRange*-nI >= nXMin*-1
IF l3D
FOR nJ := 0 TO nDeep + 1
DrawLineinbitmap( hDC, nRNeg + nJ, nLeft - nJ - 1, nRNeg + nJ, nLeft - nJ, BLACK )
NEXT nJ
ENDIF
DrawLineinbitmap( hDC, nRNeg, nLeft, nRNeg, nRight, BLACK )
ENDIF
ENDIF
nRPos -= ( nMaxBar / nXRanges )
nRNeg += ( nMaxBar / nXRanges )
NEXT nI
IF lYGrid
nPos:=IF(l3D, nTop, nTop-5 )
nI := nLeft + nWide
FOR nJ := 1 TO nMax(aData)
DrawlineinBitmap( hDC, nBottom-nDeep, nI, nPos, nI, {100,100,100} )
DrawlineinBitmap( hDC, nBottom, nI-nDeep, nBottom-nDeep, nI, {100,100,100} )
nI += nWide
NEXT
ENDIF
DO WHILE .T. // Bar adjust
nPos = nLeft + ( nWide / 2 )
nPos += ( nWide + nSep ) * ( HMG_LEN(aSeries) + 1 ) * HMG_LEN(aData[1])
IF nPos > nRight
nWide--
ELSE
EXIT
ENDIF
ENDDO
nMin := nMax / nMaxBar
nPos := nLeft + ( ( nWide + nSep ) / 2 ) // first point graph
nRange := ( ( nWide + nSep ) * HMG_LEN(aSeries) ) / 2
IF lyVal .AND. HMG_LEN( aYVals ) > 0 // Show yLabels
nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
nI := nLeft + nWideB
FOR nJ := 1 TO nMax(aData)
cName := "yVal_Name_"+LTRIM(STR(nJ))
DrawTextInBitmap( hDC, nBottom + 8, nI - nDeep - IF(l3D, 0, 8), aYVals[nJ], 'Arial', 8, BLUE )
nI += nWideB
NEXT
ENDIF
// Bars
//
IF nType == BARS
if nMin <> 0
nPos := nLeft + ( ( nWide + nSep ) / 2 )
FOR nI=1 TO HMG_LEN(aData[1])
FOR nJ=1 TO HMG_LEN(aSeries)
DrawBarinbitmap( hDC, nPos, nZero, aData[nJ,nI] / nMin + nDeep, nWide, l3D, nDeep, aColors[nJ] )
nPos += nWide+nSep
NEXT nJ
nPos += nWide+nSep
NEXT nI
endif
ENDIF
// Lines
//
IF nType == LINES
if nMin <> 0
nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
nPos := nLeft + nWideB
FOR nI := 1 TO HMG_LEN(aData[1])
FOR nJ=1 TO HMG_LEN(aSeries)
IF !l3D
DrawPointinBitmap( hDC, nType, nPos, nZero, aData[nJ,nI] / nMin + nDeep, aColors[nJ] )
ENDIF
aPoint[nJ,nI,2] := nPos
aPoint[nJ,nI,1] := nZero - ( aData[nJ,nI] / nMin + nDeep )
NEXT nJ
nPos += nWideB
NEXT nI
FOR nI := 1 TO HMG_LEN(aData[1])-1
FOR nJ := 1 TO HMG_LEN(aSeries)
IF l3D
drawpolygoninbitmap(hDC,{{aPoint[nJ,nI,1],aPoint[nJ,nI,2]},{aPoint[nJ,nI+1,1],aPoint[nJ,nI+1,2]}, ;
{aPoint[nJ,nI+1,1]-nDeep,aPoint[nJ,nI+1,2]+nDeep},{aPoint[nJ,nI,1]-nDeep,aPoint[nJ,nI,2]+nDeep}, ;
{aPoint[nJ,nI,1],aPoint[nJ,nI,2]}},,,aColors[nJ])
ELSE
DrawLineinbitmap( hDC, aPoint[ nJ, nI, 1 ], aPoint[ nJ, nI, 2 ], aPoint[ nJ, nI+1, 1 ], aPoint[ nJ, nI + 1, 2 ], aColors[ nJ ] )
ENDIF
NEXT nJ
NEXT nI
endif
ENDIF
// Points
//
IF nType == POINTS
if nMin <> 0
nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
nPos := nLeft + nWideB
FOR nI := 1 TO HMG_LEN(aData[1])
FOR nJ=1 TO HMG_LEN(aSeries)
DrawPointinBitmap( hDC, nType, nPos, nZero, aData[nJ,nI] / nMin + nDeep, aColors[nJ] )
aPoint[nJ,nI,2] := nPos
aPoint[nJ,nI,1] := nZero - aData[nJ,nI] / nMin
NEXT nJ
nPos += nWideB
NEXT nI
ENDIF
endif
IF lViewVal
IF nType == BARS
nPos := nLeft + nWide + ( ( nWide+nSep ) * ( HMG_LEN(aSeries) / 2 ) )
ELSE
nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
nPos := nLeft + nWideB
ENDIF
FOR nI := 1 TO HMG_LEN( aData[ 1 ] )
FOR nJ := 1 TO HMG_LEN( aSeries )
DrawTextInBitmap( hDC, nZero - ( aData[nJ,nI] / nMin + nDeep + 18 ), IF(nType == BARS, nPos - IF(l3D, 44, 46), nPos + 10), Transform( aData[ nJ, nI ], cPicture ), 'Arial', 8 )
nPos+= IF( nType == BARS, nWide + nSep, 0 )
NEXT nJ
IF nType == BARS
nPos += nWide + nSep
ELSE
nPos += nWideB
ENDIF
NEXT nI
ENDIF
IF l3D
DrawLineinbitmap( hDC, nZero, nLeft-nDeep, nZero, nRight-nDeep, BLACK )
ELSE
IF nXMax<>0 .AND. nXMin<>0
DrawLineinbitmap( hDC, nZero-1, nLeft-2, nZero-1, nRight, RED )
ENDIF
endif
BT_BitmapSaveFile(hBitmap, cImageFileName )
BT_DeleteDC( BTstruct )
BT_BitmapRelease( hBitmap )
RETURN
function DrawWindowBoxInBitMap( hDC, row, col, rowr, colr )
BT_DrawRectangle ( hDC, Row, Col, Colr - col, rowr - row, { 0, 0, 0 }, nPenWidth )
return nil
function drawrectinbitmap( hDC, row, col, row1, col1, aColor )
BT_DrawFillRectangle (hDC, Row, Col, col1 - col, row1 - row, aColor, aColor, nPenWidth )
return nil
function DrawLineinbitmap( hDC, Row1, Col1, Row2, Col2, aColor )
BT_DrawLine ( hDC, Row1, Col1, Row2, Col2, aColor, nPenWidth )
return nil
function DrawTextInBitmap( hDC, Row, Col, cText, cFontName, nFontSize, aColor, nAlign )
default nAlign := 0
do case
case nAlign == 0
BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, )
case nAlign == 1
BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, , BT_TEXT_RIGHT )
case nAlign == 2
BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, , BT_TEXT_CENTER )
endcase
return nil
function DrawBarinbitmap( hDC, nY, nX, nHigh, nWidth, l3D, nDeep, aColor )
LOCAL nI, nColTop, nShadow, nH := nHigh
nColTop := ClrShadow( RGB(aColor[1],aColor[2],aColor[3]), 15 )
nShadow := ClrShadow( nColTop, 15 )
nColTop := {GetRed(nColTop),GetGreen(nColTop),GetBlue(nColTop)}
nShadow := {GetRed(nShadow),GetGreen(nShadow),GetBlue(nShadow)}
FOR nI=1 TO nWidth
DrawLineinbitmap( hDC, nX, nY+nI, nX+nDeep-nHigh, nY+nI, aColor ) // front
NEXT nI
IF l3D
// Lateral
drawpolygoninBitmap( hDC,{{nX-1,nY+nWidth+1},{nX+nDeep-nHigh,nY+nWidth+1},;
{nX-nHigh+1,nY+nWidth+nDeep},{nX-nDeep,nY+nWidth+nDeep},;
{nX-1,nY+nWidth+1}},nShadow,,nShadow )
// Superior
nHigh := Max( nHigh, nDeep )
drawpolygoninBitmap( hDC,{{nX-nHigh+nDeep,nY+1},{nX-nHigh+nDeep,nY+nWidth+1},;
{nX-nHigh+1,nY+nWidth+nDeep},{nX-nHigh+1,nY+nDeep},;
{nX-nHigh+nDeep,nY+1}},nColTop,,nColTop )
// Border
DrawBoxinBitmap( hDC, nY, nX, nH, nWidth, l3D, nDeep )
ENDIF
RETURN
STATIC FUNCTION ClrShadow( nColor, nFactor )
LOCAL aHSL, aRGB
aHSL := RGB2HSL( GetRed(nColor), GetGreen(nColor), GetBlue(nColor) )
aHSL[3] -= nFactor
aRGB := HSL2RGB( aHSL[1], aHSL[2], aHSL[3] )
RETURN RGB( aRGB[1], aRGB[2], aRGB[3] )
STATIC FUNCTION nMax(aData)
LOCAL nI, nMax := 0
FOR nI :=1 TO HMG_LEN( aData )
nMax := Max( HMG_LEN(aData[nI]), nMax )
NEXT nI
RETURN( nMax )
STATIC FUNCTION DetMaxVal(nNum)
LOCAL nE, nMax, nMan, nVal, nOffset
nE:=9
nVal:=0
nNum:=Abs(nNum)
DO WHILE .T.
nMax := 10**nE
IF Int(nNum/nMax)>0
nMan:=(nNum/nMax)-Int(nNum/nMax)
nOffset:=1
nOffset:=IF(nMan<=.75,.75,nOffset)
nOffset:=IF(nMan<=.50,.50,nOffset)
nOffset:=IF(nMan<=.25,.25,nOffset)
nOffset:=IF(nMan<=.00,.00,nOffset)
nVal := (Int(nNum/nMax)+nOffset)*nMax
EXIT
ENDIF
nE--
ENDDO
RETURN (nVal)
function DrawPointinBitmap( hDC, nType, nY, nX, nHigh, aColor )
IF nType == POINTS
DrawCircleinBitmap( hDC, nX - nHigh - 3, nY - 3, 8, aColor )
ELSEIF nType == LINES
DrawCircleinBitmap( hDC, nX - nHigh - 2, nY - 2, 6, aColor )
ENDIF
RETURN
function DrawCircleinBitmap( hDC, nCol, nRow, nWidth, aColor )
BT_DrawFillEllipse( hDC, nCol, nRow, nWidth, nWidth, aColor, aColor, nPenWidth)
RETURN
function drawpiegraphinBitMap( cImageFileName, nWidth, nHeight, series, aname, colors, ctitle, depth, l3d, lxval, lsleg, lnoborder )
local fromrow := 0
local fromcol := 0
local torow := nHeight
local tocol := nWidth
local topleftrow := fromrow
local topleftcol := fromcol
local toprightrow := fromrow
local toprightcol := tocol
local bottomrightrow := torow
local bottomrightcol := tocol
local bottomleftrow := torow
local bottomleftcol := fromcol
local middletoprow := fromrow
local middletopcol := fromcol + int(tocol - fromcol) / 2
local middleleftrow := fromrow + int(torow - fromrow) / 2
local middleleftcol := fromcol
local middlebottomrow := torow
local middlebottomcol := fromcol + int(tocol - fromcol) / 2
local middlerightrow := fromrow + int(torow - fromrow) / 2
local middlerightcol := tocol
local fromradialrow := 0
local fromradialcol := 0
local toradialrow := 0
local toradialcol := 0
local degrees := {}
local cumulative := {}
local j,i,sum := 0
local cname := ""
local shadowcolor := {}
local previos_cumulative
local hDC, hBitMap, BTStruct
private nPenWidth := 1
hBitMap := BT_BitmapCreateNew ( nWidth, nHeight, { 255, 255, 255 } )
hDC := BT_CreateDC( hBitMap, BT_HDC_BITMAP, @BTStruct )
if ! lnoborder
DrawLineinbitmap( hDC, torow ,fromcol ,torow ,tocol ,WHITE)
DrawLineinbitmap( hDC, torow-1,fromcol+1,torow-1,tocol-1,GRAY )
DrawLineinbitmap( hDC, torow-1,fromcol ,fromrow ,fromcol ,GRAY )
DrawLineinbitmap( hDC, torow-2,fromcol+1,fromrow+1,fromcol+1,GRAY )
DrawLineinbitmap( hDC, fromrow ,fromcol ,fromrow ,tocol-1,GRAY )
DrawLineinbitmap( hDC, fromrow+1,fromcol+1,fromrow+1,tocol-2,GRAY )
DrawLineinbitmap( hDC, fromrow ,tocol ,torow ,tocol ,WHITE)
DrawLineinbitmap( hDC, fromrow ,tocol-1,torow-1,tocol-1,GRAY )
endif
if HMG_LEN(ALLTRIM(ctitle)) > 0
DrawTextInBitmap( hDC, fromrow + 10, iif(HMG_LEN(ALLTRIM(ctitle)) * 12 > (tocol - fromcol),fromcol,int(((tocol - fromcol) - (HMG_LEN(ALLTRIM(ctitle)) * 12))/2) + fromcol), ALLTRIM(ctitle), 'Arial', 12, {0,0,255} )
fromrow := fromrow + 40
endif
if lsleg
if HMG_LEN(aname) * 20 > (torow - fromrow)
msginfo("No space for showing legends")
else
torow := torow - (HMG_LEN(aname) * 20)
endif
endif
drawrectinbitmap( hDC, fromrow + 10, fromcol + 10, torow - 10, tocol - 10, { 255, 255, 255 } )
if l3d
torow := torow - depth
endif
fromcol := fromcol + 25
tocol := tocol - 25
torow := torow - 25
fromrow := fromrow + 25
topleftrow := fromrow
topleftcol := fromcol
toprightrow := fromrow
toprightcol := tocol
bottomrightrow := torow
bottomrightcol := tocol
bottomleftrow := torow
bottomleftcol := fromcol
middletoprow := fromrow
middletopcol := fromcol + int(tocol - fromcol) / 2
middleleftrow := fromrow + int(torow - fromrow) / 2
middleleftcol := fromcol
middlebottomrow := torow
middlebottomcol := fromcol + int(tocol - fromcol) / 2
middlerightrow := fromrow + int(torow - fromrow) / 2
middlerightcol := tocol
torow := torow + 1
tocol := tocol + 1
for i := 1 to HMG_LEN(series)
sum := sum + series[i]
next i
for i := 1 to HMG_LEN(series)
aadd(degrees,round(series[i]/sum * 360,0))
next i
sum := 0
for i := 1 to HMG_LEN(degrees)
sum := sum + degrees[i]
next i
if sum <> 360
degrees[HMG_LEN(degrees)] := degrees[HMG_LEN(degrees)] + (360 - sum)
endif
sum := 0
for i := 1 to HMG_LEN(degrees)
sum := sum + degrees[i]
aadd(cumulative,sum)
next i
previos_cumulative := -1
fromradialrow := middlerightrow
fromradialcol := middlerightcol
for i := 1 to HMG_LEN(cumulative)
if cumulative[i] == previos_cumulative
loop
endif
previos_cumulative := cumulative[i]
shadowcolor := {iif(colors[i,1] > 50,colors[i,1] - 50,0),iif(colors[i,2] > 50,colors[i,2] - 50,0),iif(colors[i,3] > 50,colors[i,3] - 50,0)}
do case
case cumulative[i] <= 45
toradialcol := middlerightcol
toradialrow := middlerightrow - round(cumulative[i] / 45 * (middlerightrow - toprightrow),0)
drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
fromradialrow := toradialrow
fromradialcol := toradialcol
case cumulative[i] <= 90 .and. cumulative[i] > 45
toradialrow := toprightrow
toradialcol := toprightcol - round((cumulative[i] - 45) / 45 * (toprightcol - middletopcol),0)
drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
fromradialrow := toradialrow
fromradialcol := toradialcol
case cumulative[i] <= 135 .and. cumulative[i] > 90
toradialrow := topleftrow
toradialcol := middletopcol - round((cumulative[i] - 90) / 45 * (middletopcol - topleftcol),0)
drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
fromradialrow := toradialrow
fromradialcol := toradialcol
case cumulative[i] <= 180 .and. cumulative[i] > 135
toradialcol := topleftcol
toradialrow := topleftrow + round((cumulative[i] - 135) / 45 * (middleleftrow - topleftrow),0)
drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
fromradialrow := toradialrow
fromradialcol := toradialcol
case cumulative[i] <= 225 .and. cumulative[i] > 180
toradialcol := topleftcol
toradialrow := middleleftrow + round((cumulative[i] - 180) / 45 * (bottomleftrow - middleleftrow),0)
if l3d
for j := 1 to depth
drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
next j
endif
drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
fromradialrow := toradialrow
fromradialcol := toradialcol
case cumulative[i] <= 270 .and. cumulative[i] > 225
toradialrow := bottomleftrow
toradialcol := bottomleftcol + round((cumulative[i] - 225) / 45 * (middlebottomcol - bottomleftcol),0)
if l3d
for j := 1 to depth
drawarcinbitmap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
next j
endif
drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
fromradialrow := toradialrow
fromradialcol := toradialcol
case cumulative[i] <= 315 .and. cumulative[i] > 270
toradialrow := bottomleftrow
toradialcol := middlebottomcol + round((cumulative[i] - 270) / 45 * (bottomrightcol - middlebottomcol),0)
if l3d
for j := 1 to depth
drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
next j
endif
drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
fromradialrow := toradialrow
fromradialcol := toradialcol
case cumulative[i] <= 360 .and. cumulative[i] > 315
toradialcol := bottomrightcol
toradialrow := bottomrightrow - round((cumulative[i] - 315) / 45 * (bottomrightrow - middlerightrow),0)
if l3d
for j := 1 to depth
drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
next j
endif
drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
fromradialrow := toradialrow
fromradialcol := toradialcol
endcase
if l3d
drawlineinbitmap(hDC, middleleftrow, middleleftcol, middleleftrow+depth, middleleftcol, { 0, 0, 0 } )
drawlineinbitmap(hDC, middlerightrow, middlerightcol, middlerightrow+depth, middlerightcol, { 0, 0, 0 } )
drawarcinBitMap(hDC,fromrow + depth,fromcol,torow + depth,tocol,middleleftrow+depth,middleleftcol,middlerightrow+depth,middlerightcol )
endif
next i
if lsleg
fromrow := torow + 20 + iif(l3d,depth,0)
for i := 1 to HMG_LEN(aname)
drawrectinbitmap(hDC, fromrow, fromcol, fromrow + 15, fromcol + 15, colors[ i ] )
drawtextinbitmap( hDC, fromrow, fromcol + 20, aname[i]+iif(lxval," - "+ALLTRIM(STR(series[i],19,2))+" ("+ALLTRIM(STR(degrees[i] / 360 * 100,6,2))+" %)",""), 'Arial', 8, colors[i] )
fromrow := fromrow + 20
next i
endif
BT_BitmapSaveFile(hBitmap, cImageFileName )
BT_DeleteDC( BTstruct )
BT_BitmapRelease( hBitmap )
return nil
function drawarcinBitMap(hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth)
if valtype(penrgb) == "U"
penrgb = {0,0,0}
endif
if valtype(penwidth) == "U"
penwidth = 1
endif
arcdrawbitmap( hDC ,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth)
return nil
function drawpieinbitmap(hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth,fillrgb)
if valtype(penrgb) == "U"
penrgb = {0,0,0}
endif
if valtype(penwidth) == "U"
penwidth = 1
endif
if valtype(fillrgb) == "U"
fillrgb := {255,255,255}
fill := .f.
else
fill := .t.
endif
piedrawbitmap( hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth,fillrgb,fill)
return nil
function drawpolygoninbitmap( hDC, apoints, penrgb, penwidth, fillrgb )
local xarr := {}
local yarr := {}
local x := 0
if valtype(penrgb) == "U"
penrgb = {0,0,0}
endif
if valtype(penwidth) == "U"
penwidth = 1
endif
if valtype(fillrgb) == "U"
fillrgb := {255,255,255}
fill := .f.
else
fill := .t.
endif
for x := 1 to HMG_LEN(apoints)
aadd(xarr,apoints[x,2])
aadd(yarr,apoints[x,1])
next x
polygondrawbitmap( hDC, xarr, yarr, penrgb, penwidth, fillrgb, fill )
return nil
STATIC FUNCTION RGB2HSL( nR, nG, nB )
LOCAL nMax, nMin
LOCAL nH, nS, nL
IF nR < 0
nR := Abs( nR )
nG := GetGreen( nR )
nB := GetBlue( nR )
nR := GetRed( nR )
ENDIF
nR := nR / 255
nG := nG / 255
nB := nB / 255
nMax := Max( nR, Max( nG, nB ) )
nMin := Min( nR, Min( nG, nB ) )
nL := ( nMax + nMin ) / 2
IF nMax = nMin
nH := 0
nS := 0
ELSE
IF nL < 0.5
nS := ( nMax - nMin ) / ( nMax + nMin )
ELSE
nS := ( nMax - nMin ) / ( 2.0 - nMax - nMin )
ENDIF
DO CASE
CASE nR = nMax
nH := ( nG - nB ) / ( nMax - nMin )
CASE nG = nMax
nH := 2.0 + ( nB - nR ) / ( nMax - nMin )
CASE nB = nMax
nH := 4.0 + ( nR - nG ) / ( nMax - nMin )
ENDCASE
ENDIF
nH := Int( (nH * 239) / 6 )
IF nH < 0 ; nH += 240 ; ENDIF
nS := Int( nS * 239 )
nL := Int( nL * 239 )
RETURN { nH, nS, nL }
STATIC FUNCTION HSL2RGB( nH, nS, nL )
LOCAL nFor
LOCAL nR, nG, nB
LOCAL nTmp1, nTmp2, aTmp3 := { 0, 0, 0 }
nH /= 239
nS /= 239
nL /= 239
IF nS == 0
nR := nL
nG := nL
nB := nL
ELSE
IF nL < 0.5
nTmp2 := nL * ( 1 + nS )
ELSE
nTmp2 := nL + nS - ( nL * nS )
ENDIF
nTmp1 := 2 * nL - nTmp2
aTmp3[1] := nH + 1 / 3
aTmp3[2] := nH
aTmp3[3] := nH - 1 / 3
FOR nFor := 1 TO 3
IF aTmp3[nFor] < 0
aTmp3[nFor] += 1
ENDIF
IF aTmp3[nFor] > 1
aTmp3[nFor] -= 1
ENDIF
IF 6 * aTmp3[nFor] < 1
aTmp3[nFor] := nTmp1 + ( nTmp2 - nTmp1 ) * 6 * aTmp3[nFor]
ELSE
IF 2 * aTmp3[nFor] < 1
aTmp3[nFor] := nTmp2
ELSE
IF 3 * aTmp3[nFor] < 2
aTmp3[nFor] := nTmp1 + ( nTmp2 - nTmp1 ) * ( ( 2 / 3 ) - aTmp3[nFor] ) * 6
ELSE
aTmp3[nFor] := nTmp1
ENDIF
ENDIF
ENDIF
NEXT nFor
nR := aTmp3[1]
nG := aTmp3[2]
nB := aTmp3[3]
ENDIF
RETURN { Int( nR * 255 ), Int( nG * 255 ), Int( nB * 255 ) }
STATIC PROC DrawBoxinBitmap( hDC, nY, nX, nHigh, nWidth, l3D, nDeep )
// Set Border
DrawLineinbitmap( hDC, nX, nY , nX-nHigh+nDeep , nY , BLACK ) // LEFT
DrawLineinbitmap( hDC, nX, nY+nWidth , nX-nHigh+nDeep , nY+nWidth, BLACK ) // RIGHT
DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY, nX-nHigh+nDeep, nY+nWidth, BLACK ) // Top
DrawLineinbitmap( hDC, nX, nY, nX, nY+nWidth, BLACK ) // Bottom
IF l3D
// Set shadow
DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY+nWidth, nX-nHigh, nY+nDeep+nWidth, BLACK )
DrawLineinbitmap( hDC, nX, nY+nWidth, nX-nDeep, nY+nWidth+nDeep, BLACK )
IF nHigh > 0
DrawLineinbitmap( hDC, nX-nDeep, nY+nWidth+nDeep, nX-nHigh, nY+nWidth+nDeep, BLACK )
DrawLineinbitmap( hDC, nX-nHigh, nY+nDeep, nX-nHigh , nY+nWidth+nDeep, BLACK )
DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY, nX-nHigh, nY+nDeep, BLACK )
ELSE
DrawLineinbitmap( hDC, nX-nDeep, nY+nWidth+nDeep, nX-nHigh+1, nY+nWidth+nDeep, BLACK )
DrawLineinbitmap( hDC, nX, nY, nX-nDeep, nY+nDeep, BLACK )
ENDIF
ENDIF
RETURN
#pragma BEGINDUMP
#include "SET_COMPILE_HMG_UNICODE.ch"
#include "HMG_UNICODE.h"
#include <windows.h>
#include <commctrl.h>
#include "hbapi.h"
#include <wingdi.h>
#include <winuser.h>
HB_FUNC ( PIEDRAWBITMAP )
{
HDC hdc1;
HGDIOBJ hgdiobj1,hgdiobj2;
HPEN hpen;
HBRUSH hbrush;
hdc1 = (HDC) HMG_parnl (1);
hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(11), (COLORREF) RGB( (int) hb_parvni(10,1), (int) hb_parvni(10,2), (int) hb_parvni(10,3) ) );
hgdiobj1 = SelectObject((HDC) hdc1, hpen);
if (hb_parl(13))
{
hbrush = CreateSolidBrush((COLORREF) RGB((int) hb_parvni(12,1),(int) hb_parvni(12,2),(int) hb_parvni(12,3)));
hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
}
else
{
hbrush = GetSysColorBrush((int) COLOR_WINDOW);
hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
}
Pie((HDC) hdc1,(int) hb_parni(3),(int) hb_parni(2),(int) hb_parni(5),(int) hb_parni(4),(int) hb_parni(7),(int) hb_parni(6),(int) hb_parni(9),(int) hb_parni(8));
SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj2);
DeleteObject( hpen );
DeleteObject( hbrush );
}
HB_FUNC( POLYGONDRAWBITMAP )
{
HDC hdc1;
HGDIOBJ hgdiobj1,hgdiobj2;
HPEN hpen;
HBRUSH hbrush;
POINT apoints[1024];
int number=hb_parinfa(2,0);
int i;
hdc1 = (HDC) HMG_parnl (1);
hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(5), (COLORREF) RGB( (int) hb_parvni(4,1), (int) hb_parvni(4,2), (int) hb_parvni(4,3) ) );
hgdiobj1 = SelectObject((HDC) hdc1, hpen);
if (hb_parl(7))
{
hbrush = CreateSolidBrush((COLORREF) RGB((int) hb_parvni(6,1),(int) hb_parvni(6,2),(int) hb_parvni(6,3)));
hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
}
else
{
hbrush = GetSysColorBrush((int) COLOR_WINDOW);
hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
}
for(i = 0; i <= number-1; i++)
{
apoints[i].x=hb_parvni(2,i+1);
apoints[i].y=hb_parvni(3,i+1);
}
Polygon((HDC) hdc1,apoints,number);
SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj2);
DeleteObject( hpen );
DeleteObject( hbrush );
}
HB_FUNC ( ARCDRAWBITMAP )
{
HDC hdc1;
HGDIOBJ hgdiobj1;
HPEN hpen;
hdc1 = (HDC) HMG_parnl (1);
hpen = CreatePen( PS_SOLID, (int) hb_parni(11), (COLORREF) RGB( (int) hb_parvni(10,1), (int) hb_parvni(10,2), (int) hb_parvni(10,3) ) );
hgdiobj1 = SelectObject( hdc1, hpen );
Arc( hdc1,(int) hb_parni(3),(int) hb_parni(2),(int) hb_parni(5),(int) hb_parni(4),(int) hb_parni(7),(int) hb_parni(6),(int) hb_parni(9),(int) hb_parni(8));
SelectObject( hdc1, hgdiobj1);
DeleteObject( hpen );
}
HB_FUNC( POLYBEZIERDRAWBITMAP )
{
HDC hdc1;
HGDIOBJ hgdiobj1;
HPEN hpen;
POINT apoints[1024];
DWORD number=(DWORD) hb_parinfa(2,0);
DWORD i;
hdc1 = (HDC) HMG_parnl (1);
hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(5), (COLORREF) RGB( (int) hb_parvni(4,1), (int) hb_parvni(4,2), (int) hb_parvni(4,3) ) );
hgdiobj1 = SelectObject((HDC) hdc1, hpen);
for(i = 0; i <= number-1; i++)
{
apoints[i].x=hb_parvni(2,i+1);
apoints[i].y=hb_parvni(3,i+1);
}
PolyBezier((HDC) hdc1,apoints,number);
SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
DeleteObject( hpen );
}
#pragma ENDDUMP