Files
comun/utile/foxcharts/foxchartsbeta.vc2

10983 lines
352 KiB
Plaintext
Raw Permalink Blame History

*--------------------------------------------------------------------------------------------------------------------------------------------------------
* (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!!
*--------------------------------------------------------------------------------------------------------------------------------------------------------
*< FOXBIN2PRG: Version="1.21" SourceFile="foxchartsbeta.vcx" CPID="1251" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries)
*
*
DEFINE CLASS _legend AS label && Internal use. Not to be used directly !
*< CLASSDATA: Baseclass="label" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: caption_assign
*m: reset && Resets the legend GDI+ objects
*m: rotation_assign
*m: _drawstring
*m: _setup
*m: _updatemeasures
*m: _value_assign
*p: backcoloralpha
*p: forecoloralpha
*p: format && Specifies the input and output formatting of a control's Value property.
*p: isparent
*p: ogfx
*p: rotationcenter
*p: _forceformat
*p: _height
*p: _initialized
*p: _memberdata && XML Metadata for customizable properties
*p: _obrush
*p: _ofont
*p: _orectangle
*p: _ostringformat
*p: _transfcaption
*p: _value
*p: _vartype
*p: _width
*</DefinedPropArrayMethod>
HIDDEN AddProperty,Anchor,AutoSize,BackStyle,BorderStyle,Click,CloneObject,ColorScheme,ColorSource,Comment,DblClick,Destroy,DisabledBackColor,DisabledForeColor,DragDrop,DragIcon,DragMode,DragOver,Drag,Error,FontCondense,FontExtend,FontOutline,FontShadow,GotFocus,HelpContextID,Init,LostFocus,MiddleClick,MouseDown,MouseEnter,MouseIcon,MouseLeave,MouseMove,MousePointer,MouseUp,MouseWheel,Move,OLECompleteDrag,OLEDragDrop,OLEDragMode,OLEDragOver,OLEDragPicture,OLEDrag,OLEDropEffects,OLEDropHasData,OLEDropMode,OLEGiveFeedback,OLESetData,OLEStartDrag,ParentClass,Parent,ReadExpression,ReadMethod,Refresh,ResetToDefault,RightClick,RightToLeft,SaveAsClass,ShowWhatsThis,StatusBarText,Style,TabIndex,TabStop,Tag,UIEnable,WhatsThisHelpID,WordWrap,WriteExpression,WriteMethod,ZOrder
*<PropValue>
AutoSize = .T.
backcoloralpha = 0
Caption = "Legend"
DragIcon = ..\..\foxcharts\
forecoloralpha = 255
format =
Height = 17
isparent = .F.
Name = "_legend"
ogfx = .F.
OLEDragPicture = ..\..\foxcharts\
rotationcenter = 0
Width = 44
_forceformat =
_height = 0
_initialized = .F.
_memberdata = <VFPData>
<memberdata name="autosize" type="property" display="AutoSize"/>
<memberdata name="whatsthishelpid" type="property" display="WhatsThisHelpID"/>
<memberdata name="_setup" type="method" display="_Setup"/>
<memberdata name="forecoloralpha" type="property" display="ForeColorAlpha"/>
<memberdata name="backcoloralpha" type="property" display="BackColorAlpha"/>
<memberdata name="width" type="property" display="Width"/>
<memberdata name="oledragpicture" type="property" display="OLEDragPicture"/>
<memberdata name="oledragmode" type="property" display="OLEDragMode"/>
<memberdata name="oledropeffects" type="property" display="OLEDropEffects"/>
<memberdata name="oledrophasdata" type="property" display="OLEDropHasData"/>
<memberdata name="oledropmode" type="property" display="OLEDropMode"/>
<memberdata name="anchor" type="property" favorites="True" display="Anchor"/>
<memberdata name="baseclass" type="property" display="BaseClass"/>
<memberdata name="class" type="property" display="Class"/>
<memberdata name="classlibrary" type="property" display="ClassLibrary"/>
<memberdata name="colorscheme" type="property" display="ColorScheme"/>
<memberdata name="colorsource" type="property" display="ColorSource"/>
<memberdata name="disabledbackcolor" type="property" display="DisabledBackColor"/>
<memberdata name="disabledforecolor" type="property" display="DisabledForeColor"/>
<memberdata name="dragicon" type="property" display="DragIcon"/>
<memberdata name="dragmode" type="property" display="DragMode"/>
<memberdata name="alignment" type="property" display="Alignment"/>
<memberdata name="_width" type="property" display="_Width"/>
<memberdata name="_updatemeasures" type="method" display="_UpdateMeasures"/>
<memberdata name="name" type="property" display="Name"/>
<memberdata name="caption" type="property" favorites="True" display="Caption"/>
<memberdata name="caption_assign" type="method" display="Caption_Assign"/>
<memberdata name="backstyle" type="property" display="BackStyle"/>
<memberdata name="borderstyle" type="property" display="BorderStyle"/>
<memberdata name="height" type="property" display="Height"/>
<memberdata name="_memberdata" type="property" display="_MemberData"/>
<memberdata name="wordwrap" type="property" display="WordWrap"/>
<memberdata name="_height" type="property" display="_Height"/>
<memberdata name="_drawstring" type="method" display="_DrawString"/>
<memberdata name="_obrush" type="property" display="_oBrush"/>
<memberdata name="_ofont" type="property" display="_oFont"/>
<memberdata name="reset" type="method" display="Reset"/>
<memberdata name="format" type="property" display="Format"/>
<memberdata name="_transfcaption" type="property" display="_TransfCaption"/>
<memberdata name="_vartype" type="property" display="_Vartype"/>
<memberdata name="_value" type="property" display="_Value"/>
<memberdata name="_value_assign" type="method" display="_Value_Assign"/>
<memberdata name="_forceformat" type="property" display="_ForceFormat"/>
<memberdata name="visible" type="property" display="Visible"/>
<memberdata name="rotationcenter" type="property" display="RotationCenter"/>
</VFPData>
_obrush =
_ofont =
_orectangle =
_ostringformat =
_transfcaption =
_value =
_vartype =
_width = 0
*</PropValue>
HIDDEN PROCEDURE caption_assign
LPARAMETERS tuCaption
LOCAL lcType
m.lcType = VARTYPE(m.tuCaption)
IF m.lcType $ "DLTN" && Logical, Date, DateTime, Numeric
m.tuCaption = TRANSFORM(m.tuCaption)
ENDIF
This.Caption = m.tuCaption
This._UpdateMeasures(.F.) && Character passed
*!* C Character, Memo, Varchar, Varchar (Binary)
*!* D Date
*!* G General
*!* L Logical
*!* N Numeric, Float, Double, or Integer
*!* O Object
*!* Q Blob, Varbinary
*!* T DateTime
*!* U Unknown or variable does not exist
*!* X Null
*!* Y Currency
ENDPROC
HIDDEN PROCEDURE Init
THIS.IsParent = TYPE('this.Parent.Name')='C'
IF THIS.IsParent AND VARTYPE(THIS.PARENT.oGfx)='O'
THIS.oGfx = THIS.PARENT.oGfx
ENDIF
ENDPROC
PROCEDURE reset && Resets the legend GDI+ objects
This._Setup()
This._UpdateMeasures()
ENDPROC
PROCEDURE rotation_assign
LPARAMETERS tnRotation
THIS.Rotation = tnRotation + IIF( tnRotation < 0, 360, 0 )
ENDPROC
PROCEDURE _drawstring
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tlVertical, toGfx
LOCAL x1, y1, lnAlign, lnMode, xBack, llBar
llBar = IIF(THIS.IsParent AND THIS.PARENT.NAME = "ShapeLegend",.T., .F.)
lnMode = 0 && 0 = x,y Coordinates ; 1 = xfcRectangle coordinates
lnAlign = THIS.ALIGNMENT
* 0 = Left 1 = Right 2 = Center
LOCAL loGfx AS xfcGraphics
loGfx = IIF(VARTYPE(toGfx)='O', toGfx, THIS.oGfx)
IF VARTYPE(THIS.oGfx)#'O' AND THIS.IsParent
THIS.oGfx = THIS.PARENT.oGfx
loGfx = THIS.oGfx
ENDIF
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE VARTYPE(tnWidth) + VARTYPE(tnHeight) = "NN"
lnMode = 1
* Create a STRINGFORMAT object in order to draw the string centered in the image
LOCAL loStringFmt AS xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
IF tlVertical
loStringFmt.FormatFlags = .StringFormatFlags.DirectionVertical
loStringFmt.LineAlignment = .StringAlignment.CENTER
ENDIF
LOCAL loSize AS xfcSize
IF THIS.IsParent AND tlVertical
loSize = .SIZE.New(THIS.PARENT.WIDTH, THIS.PARENT.HEIGHT)
ELSE
loSize = .SIZE.New(tnWidth, tnHeight)
ENDIF
loSize = loGfx.MeasureString( THIS._TransfCaption, THIS._oFont, loSize, loStringFmt )
THIS._Height = CEILING(loSize.HEIGHT)
THIS._Width = CEILING(loSize.WIDTH)
LOCAL loRect AS xfcRectangle
loRect = .Rectangle.New(tnX, tnY, tnWidth, THIS._Height)
x1 = tnX
y1 = tnY
IF tlVertical
xBack = tnX + tnWidth / 2 - (THIS._Width / 2)
DO CASE
CASE lnAlign = 0 && Left
y1 = tnY
CASE lnAlign = 1 && Right
y1 = tnY + tnHeight - THIS._Height
CASE lnAlign = 2 && Center
y1 = tnY + (tnHeight - THIS._Height) / 2
ENDCASE
ELSE
DO CASE
CASE lnAlign = 0 && Left
xBack = tnX
CASE lnAlign = 1 && Right
xBack = tnX + tnWidth - THIS._Width
CASE lnAlign = 2 && Center
xBack = tnX + (tnWidth - THIS._Width) / 2
ENDCASE
ENDIF
CASE lnAlign = 0 && Left
STORE tnX TO x1, xBack
y1 = tnY
CASE lnAlign = 1 && Right
x1 = tnX - THIS._Width
xBack = x1
y1 = tnY
CASE lnAlign = 2 && Center
x1 = tnX - (THIS._Width / 2)
xBack = x1
y1 = tnY
ENDCASE
LOCAL lnRotation
lnRotation = THIS.ROTATION
IF lnRotation <> 0
WITH _SCREEN.SYSTEM.Drawing
LOCAL loPointF AS xfcPointF, loMatrix AS xfcMatrix
loMatrix = .Drawing2D.Matrix.New()
IF lnMode = 1
loPointF = .PointF.New(tnX, tnY) && this is the point of rotation
ELSE
DO CASE
CASE lnAlign = 0 && Left
loPointF = .PointF.New(x1 + 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 1 && Right
loPointF = .PointF.New(x1 + THIS._Width - 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 2 && Center
loPointF = .PointF.New(x1 + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
ENDCASE
ENDIF
loMatrix.RotateAt(lnRotation, loPointF)
loGfx.MultiplyTransform(loMatrix)
ENDWITH
ENDIF
lnRotationCenter = THIS.RotationCenter
* Center Rotation
IF lnRotationCenter <> 0
WITH _SCREEN.SYSTEM.Drawing
LOCAL loPointFC AS xfcPointF, loMatrixC AS xfcMatrix
loMatrixC = .Drawing2D.Matrix.New()
* loPointFC = .PointF.New(x1 + This._Width / 2, y1 + This._Height / 2) && this is the point of rotation
loPointFC = .PointF.New(xBack + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
loMatrixC.RotateAt(lnRotationCenter, loPointFC)
loGfx.MultiplyTransform(loMatrixC)
ENDWITH
ENDIF
IF THIS.BackColorAlpha > 0
* Draw the BackGround Rectangle
WITH _SCREEN.SYSTEM.Drawing
IF lnMode = 0 && default
loGfx.FillRectangle( ;
.SolidBrush.New(.COLOR.FromARGB(THIS.BackColorAlpha, THIS.BACKCOLOR)), ;
x1, y1, THIS._Width, THIS._Height)
ELSE
loGfx.FillRectangle( ;
.SolidBrush.New(.COLOR.FromARGB(THIS.BackColorAlpha, THIS.BACKCOLOR)), ;
xBack, y1, THIS._Width, THIS._Height)
ENDIF
ENDWITH
ENDIF
* Draw the Text
IF lnMode = 0
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, x1, y1)
ELSE
IF tlVertical
loRect = .Rectangle.New(xBack, y1, THIS._Width, THIS._Height)
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ELSE
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ENDIF
ENDIF
IF lnRotation <> 0 OR lnRotationCenter <> 0
loGfx.ResetTransform()
ENDIF
ENDWITH
ENDPROC
PROCEDURE _setup
* Update the FONT object
LOCAL liStyle, lcFont
liStyle = IIF( THIS.FONTBOLD,1,0) + IIF( THIS.FONTITALIC,2,0) + IIF( THIS.FONTUNDERLINE,4,0) + IIF( THIS.FONTSTRIKETHRU ,8,0)
* Prepare the font object
lcFont = IIF(THIS.IsParent AND EMPTY(THIS.FONTNAME), THIS.PARENT.FONTNAME, THIS.FONTNAME)
* If no font was selected, then take the _Screen one!
IF EMPTY(lcFont)
lcFont = EVL(_SCREEN.FONTNAME, "Arial")
ENDIF
WITH _SCREEN.SYSTEM.Drawing
LOCAL loFont AS xfcFont
loFont = .FONT.New(lcFont, THIS.FONTSIZE, liStyle)
THIS._oFont = loFont
* Update the BRUSH object
LOCAL loColor AS xfcColor, lnColor, loBrush AS xfcSolidBrush
lnColor = IIF(THIS.IsParent AND THIS.PARENT.BrushType = 3, 0, THIS.FORECOLOR)
loColor = .COLOR.FromArgb(THIS.ForeColorAlpha, lnColor)
loBrush = .SolidBrush.New(loColor)
THIS._oBrush = loBrush
ENDWITH
THIS._initialized = .T.
ENDPROC
PROCEDURE _updatemeasures
LPARAMETERS tlNumeric
IF VARTYPE(THIS.oGfx)#'O' AND THIS.IsParent
THIS.oGfx = THIS.PARENT.oGfx
ENDIF
IF VARTYPE(THIS.oGfx) <> "O"
RETURN
ENDIF
* Measure the Legend height
IF VARTYPE(THIS._oBrush) + VARTYPE(THIS._oFont) <> "OO" OR NOT THIS._initialized
THIS._Setup()
ENDIF
LOCAL lcCaption, lcFormat
* _ForceFormat is a forced formatting managed directly from FoxCharts
lcFormat = IIF(EMPTY(ALLTRIM(THIS._ForceFormat)), THIS.FORMAT, ALLTRIM(THIS._ForceFormat))
IF tlNumeric
IF VARTYPE(THIS._Value) = "C"
lcCaption = THIS._Value
ELSE
IF this.IsParent and EMPTY(lcFormat)
lcFormat = "999,999,999,999" + ;
IIF(THIS.PARENT._ValueDecimals > 0, ;
"." + REPLICATE("9", THIS.PARENT._ValueDecimals), "")
ENDIF
lcCaption = ALLTRIM(TRANSFORM(THIS._Value, lcFormat))
IF this.IsParent and THIS.PARENT._ValueDecimals>0
lcCaption=RTRIM(RTRIM(lcCaption,'0'),'.')
ENDIF
ENDIF
ELSE
lcCaption = STRTRAN(THIS.CAPTION,[CHR(13)+CHR(10)], CHR(13)+CHR(10),-1,-1,1)
lcCaption = ALLTRIM(textmerge(lcCaption))
ENDIF
LOCAL loSize AS xfcSize
loSize = THIS.oGfx.MeasureString(lcCaption, THIS._oFont) &&, This._oStringFormat)
THIS._Height = loSize.HEIGHT
THIS._Width = CEILING(loSize.WIDTH)
THIS._TransfCaption = lcCaption
ENDPROC
PROCEDURE _value_assign
lparameters tuNewValue
This._Value = tuNewValue
This._UpdateMeasures(.T.) && Value passed
ENDPROC
ENDDEFINE
DEFINE CLASS fields AS collection
*< CLASSDATA: Baseclass="collection" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: clear && Clears the contents of a ComboBox or ListBox control.
*m: desc_assign
*m: isempty
*m: new
*m: pack
*m: setcount
*m: type
*m: unpack
*p: desc
*p: packexpr
*a: ladesc[1,0] && Fields description
*</DefinedPropArrayMethod>
*<PropValue>
desc =
Height = 23
Name = "fields"
packexpr = .F.
Width = 23
*</PropValue>
PROCEDURE clear && Clears the contents of a ComboBox or ListBox control.
LPARAMETERS tnIndex
LOCAL lcProp
LOCAL lcName, lnCol, lnLine, loMe
WITH THIS
m.loMe = This
FOR m.lnline = EVL(m.tnIndex,1)TO IIF(EMPTY(m.tnIndex),THIS.COUNT,m.tnIndex)
FOR m.lnCol=1 TO ALEN(.laDesc,1)
m.lcName = 'loMe(m.lnLine).'+ .laDesc(m.lnCol,1)
STORE totype('',.laDesc(m.lnCol,2)) TO (m.lcName)
NEXT
NEXT
m.lcProp = '.Parent.'+.Name+'Pack'
STORE .pack() TO (m.lcProp)
ENDWITH
ENDPROC
PROCEDURE desc_assign
LPARAMETERS vNewVal
*To do: Modify this routine for the Assign method
LOCAL lnCount, lnLine, la(1)
WITH THIS
.DESC = UPPER(rtrim(m.vNewVal,CHR(13)+CHR(1)))
lnCount = MAX(1,ALINES(la,.DESC))
DIMENSION .laDesc (lnCount,3)
FOR lnLine=1 TO ALINES(la,.DESC)
.laDesc (lnLine,1) = GETWORDNUM(la(lnLine),1,',')
.laDesc (lnLine,2) = GETWORDNUM(la(lnLine),2,',')
.laDesc (lnLine,3) = GETWORDNUM(la(lnLine),3,',')
NEXT
.PackExpr = ''
FOR lnLine=1 TO ALEN(.laDesc,1)
.PackExpr = IIF(lnLine=1,'',.PackExpr+'^') + [<<loMe(lnLine).]+.laDesc(lnLine,1)+[>>]
NEXT
ENDWITH
ENDPROC
PROCEDURE isempty
LPARAMETERS tnIndex
LOCAL loMe, lnCol, lnLine, luVal
WITH THIS
m.loMe=this
FOR m.lnLine = EVL(m.tnIndex,1)TO IIF(EMPTY(m.tnIndex),THIS.COUNT,m.tnIndex)
FOR m.lnCol=1 TO ALEN(.laDesc,1)
m.luVal = totype(EVALUATE('loMe(m.lnLine).'+ .laDesc(m.lnCol,1)),.laDesc(m.lnCol,2))
IF NOT EMPTY(m.luVal)
RETURN .F.
ENDIF
NEXT
NEXT
ENDWITH
RETURN .T.
ENDPROC
PROCEDURE new
LOCAL lnLine, loData
m.loData = CREATEOBJECT("Empty")
WITH THIS
FOR m.lnLine=1 TO ALEN(.laDesc,1)
ADDPROPERTY(m.loData,.laDesc(m.lnLine,1),Totype(.laDesc(m.lnLine,3),.laDesc(m.lnLine,2)))
NEXT
ENDWITH
RETURN m.loData
ENDPROC
PROCEDURE pack
LPARAMETERS tnDeleteIndex
LOCAL lcExpr, lcPack, lnLine, loMe
IF THIS.IsEmpty ()
RETURN ''
ENDIF
tnDeleteIndex=EVL(tnDeleteIndex,0)
loMe=THIS
lcPack = ''
WITH THIS
lcExpr = .PackExpr
FOR lnLine=1 TO .COUNT
IF lnLine # tnDeleteIndex
lcPack = lcPack + TEXTMERGE(lcExpr) + IIF(lnLine=.COUNT,'',CHR(13)+CHR(10))
ENDIF
NEXT
ENDWITH
RETURN lcPack
ENDPROC
PROCEDURE setcount
LPARAMETERS tnCnt
LOCAL lnLine, lnSelect, loData
*--MW-->The stock method handled adding fields to the collection but not removing them.
IF THIS.COUNT <> m.tnCnt
LOCAL lnIncr, lnFieldNo
lnIncr = m.tnCnt - THIS.COUNT
DO WHILE THIS.COUNT # m.tnCnt
IF lnIncr > 0
*--Adding fields
m.loData = THIS.New()
THIS.ADD(m.loData)
ELSE
*--Removing fields
lnFieldNo = THIS.COUNT
THIS.REMOVE(lnFieldNo)
ENDIF
ENDDO
ENDIF
ENDPROC
PROCEDURE type
LPARAMETERS tcField
LOCAL lnLine
tcField= UPPER(tcField)
FOR lnLine=1 TO ALEN(THIS.laDesc,1)
IF tcField== UPPER(THIS.laDesc (lnLine,1))
RETURN THIS.laDesc (lnLine,2)
ENDIF
NEXT
RETURN 'N'
ENDPROC
PROCEDURE unpack
LPARAMETERS lcPack
LOCAL lcName, lnCol, lnLine, lnLines, loMe
loMe=THIS
WITH THIS
lnLines = IIF(EMPTY(lcPack),0,ALINES(laPack,lcPack))
.SetCount( lnLines )
FOR lnLine=1 TO lnLines
FOR lnCol=1 TO MIN(ALEN(.laDesc,1), ALINES(laCols,laPack(lnLine),'^'))
lcName = 'loMe(lnLine).'+ .laDesc(lnCol,1)
STORE totype(EVL(laCols(lnCol),.laDesc(lnCol,3)),.laDesc(lnCol,2)) TO (lcName)
NEXT
NEXT
lcName = [.Parent.]+.Name+'Pack'
STORE .Pack() TO (lcName)
ENDWITH
ENDPROC
ENDDEFINE
DEFINE CLASS figure AS custom
*< CLASSDATA: Baseclass="custom" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: checkmouseposition
*m: draw && Repaints a Form object.
*m: drawcontour
*m: setdimensions
*p: arrowheight
*p: bartype
*p: caption && Specifies the text displayed in an object's caption.
*p: chartindex
*p: color
*p: contour
*p: coordnum
*p: currentrow
*p: front
*p: frontview && <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
*p: legend
*p: matrix
*p: parentcoord
*p: path
*p: pointfc
*p: recno
*p: rotationcenter
*p: rowsum
*p: start
*p: sweep
*p: tilt
*p: type
*p: value && Specifies the current state of a control.
*</DefinedPropArrayMethod>
*<PropValue>
arrowheight = 0
bartype = 0
caption =
chartindex = 0
color = 0
contour = .F.
coordnum = 0
currentrow = 0
front =
frontview = .F.
legend =
matrix = .F.
Name = "figure"
parentcoord = 0
path =
pointfc = .F.
recno = 0
rotationcenter = .F.
rowsum = 0
start = 0
sweep = 0
tilt = .F.
type =
value = .F.
*</PropValue>
PROCEDURE checkmouseposition
LPARAMETERS tnX, tnY, tcType
IF NOT EMPTY(tcType) AND NOT UPPER(tcType) == UPPER(THIS.TYPE)
RETURN .F.
ENDIF
IF EMPTY(THIS.Contour)
RETURN BETWEEN(tnX, THIS.LEFT, THIS.LEFT + THIS.WIDTH) AND BETWEEN(tnY, THIS.TOP, THIS.TOP + THIS.HEIGHT)
ELSE
RETURN _Screen.FoxChartsHelper.InsidePath(EVL(THIS.Contour,THIS.PATH),tnX,tnY)
ENDIF
ENDPROC
PROCEDURE draw && Repaints a Form object.
LPARAMETERS toGfx, toPen, toBrush, tnCanvasLeft, tnCanvastTop, tnRotationCenter
LOCAL lnDiag, lnSinAngle
tnCanvasLeft = EVL(tnCanvasLeft,This.LEFT)
tnCanvastTop = EVL(tnCanvastTop,This.TOP)
WITH THIS
IF .Tilt OR NOT EMPTY(tnRotationCenter)
WITH _SCREEN.SYSTEM.Drawing
This.Matrix = .Drawing2D.Matrix.New()
This.PointFC = .PointF.New(tnCanvasLeft, tnCanvastTop) && <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ENDWITH
lnDiag = SQRT(.WIDTH^2 + .ArrowHeight^2)
lnSinAngle = .ArrowHeight / lnDiag
.RotationCenter= iif(EMPTY(tnRotationCenter),RTOD(ASIN(lnSinAngle)),tnRotationCenter)
.Matrix.RotateAt(.RotationCenter, .PointFC)
toGfx.MultiplyTransform(.Matrix)
ENDIF
_SCREEN.FoxChartsHelper.DrawPath( toGfx, m.toPen, m.toBrush, .PATH , 0, 0 )
ENDWITH
ENDPROC
PROCEDURE drawcontour
LPARAMETERS toGfx, toPen, toBrush, tnCanvasLeft, tnCanvastTop
LOCAL lnDiag, lnSinAngle
tnCanvasLeft = EVL(tnCanvasLeft,0)
tnCanvastTop = EVL(tnCanvastTop,0)
WITH THIS
IF .Tilt
WITH _SCREEN.SYSTEM.Drawing
THIS.Matrix = .Drawing2D.Matrix.New()
THIS.PointFC = .PointF.New(THIS.LEFT+tnCanvasLeft, THIS.TOP+tnCanvastTop) && <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ENDWITH
m.lnDiag = SQRT(.WIDTH^2 + .ArrowHeight^2)
m.lnSinAngle = .ArrowHeight / m.lnDiag
.RotationCenter=RTOD(ASIN(lnSinAngle))
.Matrix.RotateAt(.RotationCenter, .PointFC)
toGfx.MultiplyTransform(.Matrix)
ENDIF
_Screen.FoxChartsHelper.DrawPath( m.toGfx, m.toPen, m.toBrush, .PATH , m.tnCanvasLeft, m.tnCanvastTop )
ENDWITH
ENDPROC
PROCEDURE setdimensions
LPARAMETERS lnLeft,lnTop,lnWidth,lnHeight
WITH THIS
.LEFT=lnLeft
.TOP=lnTop
.WIDTH = lnWidth
.HEIGHT = lnHeight
ENDWITH
ENDPROC
ENDDEFINE
DEFINE CLASS foxcharts AS foxcharts OF "foxcharts.vcx"
*< CLASSDATA: Baseclass="container" Timestamp="" Scale="Pixels" Uniqueid="" />
*-- OBJECTDATA items order determines ZOrder / El orden de los items OBJECTDATA determina el ZOrder
*< OBJECTDATA: ObjPath="Shapes" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="DeltaLegend" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Tips" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="Comments" UniqueID="" Timestamp="" />
*<DefinedPropArrayMethod>
*m: chart2report
*m: drawcontour
*m: fillpathdim
*m: getcontourmeasures
*m: gettexture
*m: getvalue
*m: openword
*m: rotate
*m: toword
*m: towriter
*m: toxls
*m: _drawcomments
*m: _drawcone
*m: _drawconoid
*m: _drawfrustum
*m: _drawpyramid
*p: backimage
*p: bottomvalue
*p: column
*p: commentssetpack
*p: contourgraphics
*p: contourpen
*p: deltagradient
*p: deltaheight
*p: deltaposition
*p: deltatilt
*p: drawarrowsfromsidelegend
*p: gradienthorcount
*p: gradientvertcount
*p: news
*p: oldmouseindex
*p: readonlyprops
*p: row
*p: shapelegendtype
*p: shapelegendvertalignment
*p: showcolcaption
*p: showcontour
*p: showdecimals
*p: showdelta
*p: showdeltapercent
*p: showrowcaption
*p: showvalue
*p: sleep
*p: texturename
*p: texturetheme
*p: userightclick
*p: value && Specifies the current state of a control.
*a: acolors[1,0]
*a: acoord[1,0]
*a: apalettecolors[1,0]
*a: _acolors[1,0]
*a: _apoints[1,2]
*a: _ashapes[1,0]
*a: _asidelegends[1,2]
*p: _odimbrush
*p: _orightbrush
*</DefinedPropArrayMethod>
*<PropValue>
backimage = .F.
bottomvalue = 0
column = 0
commentssetpack = .F.
contourgraphics = .F.
contourpen = .F.
deltagradient = 0
deltaheight = 24
deltaposition = 1
deltatilt = .F.
drawarrowsfromsidelegend = .F.
gradienthorcount = 1
gradientvertcount = 1
Height = 264
Name = "foxcharts"
news = .F.
oldmouseindex = 0
readonlyprops = .F.
row = 0
shapelegendtype = 1
shapelegendvertalignment = 2
showcolcaption = .F.
showcontour = .T.
showdecimals = 0
showdelta = 1
showdeltapercent = .F.
showrowcaption = .F.
showvalue = .T.
sleep = .F.
texturename =
texturetheme = .F.
userightclick = .F.
value = 0
versiona = FoxCharts v1.44 Beta
Width = 340
_odimbrush = .F.
_orightbrush = .F.
Title.Name = "Title"
SubTitle.Name = "SubTitle"
XAxis.Name = "XAxis"
YAxis.Name = "YAxis"
ScaleLegend.Name = "ScaleLegend"
AxisLegend2.Name = "AxisLegend2"
ShapeLegend.Name = "ShapeLegend"
SideLegend.Name = "SideLegend"
ChartCanvas.Name = "ChartCanvas"
Fields.Name = "Fields"
ToolTip.Name = "ToolTip"
YAxis2.Name = "YAxis2"
*</PropValue>
ADD OBJECT 'Comments' AS _legend WITH ;
Alignment = 2, ;
BackColor = 247,255,255, ;
Caption = "Comments", ;
FontSize = 9, ;
Left = 113, ;
Name = "Comments", ;
Top = 236, ;
Visible = .F.
*< END OBJECT: ClassLib="foxchartsbeta.vcx" BaseClass="label" />
ADD OBJECT 'DeltaLegend' AS _legend WITH ;
Alignment = 2, ;
BackColor = 247,255,255, ;
Caption = "DeltaLegend", ;
FontSize = 9, ;
Left = 113, ;
Name = "DeltaLegend", ;
Top = 162, ;
Visible = .F.
*< END OBJECT: ClassLib="foxchartsbeta.vcx" BaseClass="label" />
ADD OBJECT 'Shapes' AS shapes WITH ;
Height = 12, ;
Left = 113, ;
Name = "Shapes", ;
Top = 212, ;
Width = 72
*< END OBJECT: ClassLib="foxchartsbeta.vcx" BaseClass="container" />
ADD OBJECT 'Tips' AS tips WITH ;
AutoSize = .T., ;
Caption = "Tips", ;
Height = 17, ;
Left = 108, ;
Name = "Tips", ;
Top = 183, ;
Width = 24
*< END OBJECT: ClassLib="foxchartsbeta.vcx" BaseClass="label" />
PROCEDURE afterchart
WITH THIS
IF NOT EMPTY(.ShowDelta) AND .ChartType = 7 OR (INLIST(.ChartType , 3, 8, 9, 11) AND .ChartsCount=1)
PRIVATE lnHalf, loBrush, loGfx, loPen
lnArrowHeight= .DeltaHeight
lnHalf = lnArrowHeight/2
loGfx=_SCREEN.SYSTEM.Drawing
loPen = loGfx.PEN.New(loGfx.COLOR.Black, 1) && <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
IF .DeltaGradient = 0
m.loBrush = loGfx.SolidBrush.New(loGfx.COLOR.FromARGB(128,228,228,228))
ENDIF
loOldObject=.F.
FOR EACH loObject IN .Shapes.OBJECTS
IF loObject.TYPE = 'Rect'
lnValue=0
IF VARTYPE(loOldObject) = 'O'
lnX0= INT(loOldObject.LEFT + loOldObject.WIDTH/2) && Left
lnY0= ROUND(loOldObject.TOP + loOldObject.HEIGHT - lnArrowHeight,0)
DO CASE
CASE .DeltaPosition = 1
lnY0= ROUND(loOldObject.TOP + loOldObject.HEIGHT - lnArrowHeight,0) && Bottom
CASE .DeltaPosition = 2
lnY0= ROUND(loOldObject.TOP + loOldObject.HEIGHT/2,0) && Middle
CASE .DeltaPosition = 3
lnY0= ROUND(loOldObject.TOP - lnHalf,0) && Top
OTHERWISE
lnY0= ROUND(loOldObject.TOP - lnHalf*4,0) && Over top
ENDCASE
lcCaption = ''
IF .ShowDelta > 0
IF loOldObject.VALUE # 0 AND .ShowDeltaPercent
lnValue=(loObject.VALUE - loOldObject.VALUE) / loOldObject.VALUE * 100
lcCaption = ALLTRIM(STR(lnValue,20,1))+'%'
ENDIF
lnValue=loObject.VALUE - loOldObject.VALUE
lcCaption = IIF(EMPTY(lcCaption),'',lcCaption+', ') + TRANSFORM(lnValue)
ENDIF
lnWidth = loObject.LEFT - lnX0
DO CASE
CASE .DeltaPosition=1
lnTop2 = lnY0
CASE .DeltaPosition=2
lnTop2 = INT(loObject.TOP+loObject.HEIGHT/2)
CASE .DeltaPosition=3
lnTop2 = INT(loObject.TOP - lnHalf)
OTHER
lnTop2 = INT(loObject.TOP - lnHalf*4)
ENDCASE
lnHeight = lnTop2-lnY0
WITH _SCREEN.SYSTEM.Drawing
* Gradient brush
IF THIS.DeltaGradient > 0
loColor1 = .COLOR.FromARGB(200, loOldObject.COLOR)
loColor2 = .COLOR.FromARGB(200, loObject.COLOR)
loBrush = .Drawing2D.LinearGradientBrush.New(;
.Rectangle.New(m.lnX0, m.lnY0, m.lnWidth, m.lnArrowHeight), ;
loColor1, loColor2, 0)
ENDIF
ENDWITH
lnEndWidth = 30
lnTextLeft = lnX0
lcPolyGon = _Screen.FoxChartsHelper.Arrows(THIS.ShowDelta, @lnTextLeft, lnY0, lnArrowHeight, lnWidth, lnEndWidth, lnValue )
lcObjectName = 'Shape' + ALLTRIM(STR(.Shapes.OBJECTS.COUNT+1))
THIS.Shapes.ADDOBJECT(lcObjectName,JUSTSTEM(this.Classlibrary)+[.Figure])
WITH EVALUATE('.Shapes.'+lcObjectName)
.CoordNum = this.Shapes.OBJECTS.COUNT
.SetDimensions( m.lnX0, m.lnY0, m.lnWidth, lnArrowHeight)
.ArrowHeight = m.lnHeight
.CAPTION = lcCaption
.PATH = lcPolyGon
.Tilt = THIS.DeltaTilt
.TYPE="Delta"
.DRAW(THIS.oGfx, m.loPen, m.loBrush, 0,0)
.Contour = _Screen.FoxChartsHelper.SimplifyPath(lcPolyGon)
IF THIS.DeltaTilt && AND NOT EMPTY(.RotationCenter)
.Contour = _Screen.FoxChartsHelper.RotatePath(m.lnX0, m.lnY0, .Contour, .RotationCenter)
ENDIF
ENDWITH
.DeltaLegend._Value = lcCaption
.DeltaLegend._DrawString(lnTextLeft, lnY0-CEILING(.DeltaLegend._HEIGHT/2)+1,lnWidth-8,.DeltaLegend._HEIGHT)
.oGfx.ResetTransform()
ENDIF
loOldObject = loObject
ENDIF
NEXT
ENDIF
._DrawComments ()
ENDWITH
ENDPROC
PROCEDURE chart2report
** Chart2Report
Local lcReportBehaviorOld
Local oFoxChart
lcReportBehaviorOld = Set("Reportbehavior")
Set REPORTBEHAVIOR 90
Private m.oFoxChart && needed by report
oFoxChart = This.ChartCanvas
Report Form FoxChartsView Preview Nowait
Set REPORTBEHAVIOR &lcReportBehaviorOld
ENDPROC
PROCEDURE chartscount_assign
LPARAMETERS tnCount
This.ChartsCount = m.tnCount
* Prepare the Enumerated properties
IF This.OldStyleProperties
LOCAL n, lcIndex
FOR m.n = 1 TO m.tnCount
m.lcIndex = This._Str(m.n)
IF m.n > 1 && The enum properties #1 already exists - no need to recreate
This.AddProperty("ChartType" + m.lcIndex, 0)
This.AddProperty("FieldValue" + m.lcIndex, "")
This.AddProperty("Legend" + m.lcIndex, "")
This.AddProperty("Color" + m.lcIndex, "")
This.AddProperty("Shape" + m.lcIndex, 0)
This.AddProperty("ShowValuesOnShape" + m.lcIndex, .T.)
This.AddProperty("AxisIndex" + m.lcIndex, 1)
ENDIF
This.AddProperty("Bartype" + m.lcIndex, 0)
ENDFOR
ENDIF
* Prepare the Fields collection
This._SetFieldsCount(m.tnCount)
ENDPROC
PROCEDURE currlegend_access
RETURN IIF(This.CurrIndex = 0, "", EVL(EVALUATE('this.Shapes.Shape'+ALLTRIM(Str(This.CurrIndex))+'.Legend'), cLegend))
ENDPROC
PROCEDURE currobjtype_access
LOCAL lnIndex, lcObjType
lnIndex = This.CurrIndex
lcObjType = IIF(lnIndex = 0, "", EVALUATE('this.Shapes.Shape'+ALLTRIM(Str(lnIndex))+'.Type'))
RETURN lcObjType
ENDPROC
PROCEDURE currvalue_access
LOCAL lnIndex, lnValue
lnIndex = This.CurrIndex
lnValue = IIF(EMPTY(lnIndex), 0, EVALUATE('this.Shapes.Shape'+ALLTRIM(Str(lnIndex))+'.Value'))
RETURN lnValue
ENDPROC
PROCEDURE drawchart
LPARAMETERS llForceShow
LOCAL llSleep
* Some setups before drawing for the case of transparent background
* When some Image Canvas settings are needed
IF THIS.BackColorAlpha < 255 && Transparency active
THIS.ChartCanvas.CLEAR(_SCREEN.SYSTEM.Drawing.COLOR.Transparent)
THIS.ChartCanvas.RenderMode = 4 && Memory PNG
THIS.BACKSTYLE = 0 && Transparent
ENDIF
IF NOT THIS._Started
THIS._InitChart()
ENDIF
m.llSleep=THIS.Sleep
THIS.Sleep = THIS.Sleep AND NOT m.llForceShow
THIS.ChartCanvas.DRAW()
THIS.Sleep = m.llSleep
ENDPROC
PROCEDURE drawcontour
LPARAMETERS lcLines, tnIndex
_Screen.FoxChartsHelper.DrawContour(This, lcLines, tnIndex)
ENDPROC
PROCEDURE fillpathdim
LPARAMETERS loBrush, loPath
WITH THIS
.oGfx.FillPath(loBrush, loPath)
IF VARTYPE(._oDimBrush)='O'
.oGfx.FillPath( ._oDimBrush, loPath )
ENDIF
ENDWITH
ENDPROC
PROCEDURE getchartproperties
LPARAMETERS tnType, tbWrapper, tlShowDescriptions, tcReadOnlyProps
**********************************************************************************************
* Method: GetChartProperties
* Author: Jim R. Nelson
* Returns the properties and values used to create the current chart
* 2009-12-11 CChalom: added parameter #4, for getting the full script
**********************************************************************************************
LOCAL lcCRLF, lcCollection, lcDescription, lcItem, lcMember, lcObjMem, lcObjects, lcProperty, lcResult, lcTabs, lcTempResult, ;
lnI, lnJ, lnRow, lnTabSpaces, lnType, ;
loMember, loPropertiesList
* tnType = 1 for all properties
* = 2 for non-default properties
* = 3 for properties since last call to .SaveChartProperties
* = 4 for returning a full script for recreating the chart
* tbWrapper = .T. to include code around it ... WITH / ENDWITH
IF NOT EMPTY(tcReadOnlyProps)
THIS.Readonlyprops = THIS.Readonlyprops + tcReadOnlyProps+','
ENDIF
m.lcCRLF = CHR(13) + CHR(10)
m.lnTabSpaces = 4
m.lcTabs = SPACE(lnTabSpaces)
DO CASE
CASE EMPTY (tnType)
lnType = 1
CASE tnType = 3 AND ISNULL(THIS._savedchartproperties)
* for tnType =2, you must have first invoked method SaveChartProperties ...
* the result is then all properties modified after the call to SaveChartProperties
lnType = 2
CASE tnType = 4
RETURN THIS._GetChartScript()
OTHERWISE
lnType = tnType
ENDCASE
lcResult = ""
lcObjects = ""
lcCollection = ""
m.loPropertiesList = THIS._GetChartProperties()
AMEMBERS(laMembers, loPropertiesList, 3)
*!* 2009-12-17
*!* CChalom: Changed order of appearance of the properties
FOR lnI = 1 TO ALEN (laMembers, 1)
m.lcMember = THIS._spellproperty (m.laMembers(lnI,1))
lcDescription = ''
lnRow = ASCAN (loPropertiesList._Descriptions, m.lcMember, -1, -1, 1, 9)
IF lnRow > 0
lcDescription = loPropertiesList._Descriptions(lnRow, 4)
ENDIF
DO CASE
CASE LOWER(m.lcMember) = '_descriptions'
CASE "O" # TYPE ("loPropertiesList." + m.lcMember) && simple properties
m.lcResult = m.lcResult + THIS._GetChartProp(m.loPropertiesList, m.lcMember, m.lnType, THIS._savedchartproperties, lcDescription, tlShowDescriptions)
CASE "C" = TYPE ("loPropertiesList." + m.lcMember, 1) && collection container
FOR lnJ = 1 TO EVALUATE ("loPropertiesList." + m.lcMember + ".Count")
m.lcItem = m.lcMember + ".Item(" + TRANSFORM(lnJ) + ")"
loMember = EVALUATE ("loPropertiesList." + m.lcItem)
AMEMBERS (laObjMembers, loMember)
m.lcTempResult = ''
FOR EACH m.lcObjMem IN laObjMembers
m.lcObjMem = THIS._spellproperty (m.lcObjMem)
lcDescription = ''
IF tlShowDescriptions AND PEMSTATUS(loMember, "_Descriptions", 5)
lnRow = ASCAN (loMember._Descriptions, m.lcObjMem, -1, -1, 1, 9)
IF lnRow > 0
lcDescription = loMember._Descriptions(lnRow, 4)
ENDIF
ENDIF
m.lcProperty = THIS._GetChartProp(;
m.loPropertiesList, m.lcItem + "." + m.lcObjMem, m.lnType, THIS._savedchartproperties, lcDescription, tlShowDescriptions)
m.lcTempResult = m.lcTempResult + m.lcProperty
NEXT
IF NOT EMPTY (m.lcTempResult)
m.lcCollection = m.lcCollection + ;
"WITH ." + m.lcMember + "(" + TRANSFORM(lnJ) + ")" + m.lcCRLF + ;
STRTRAN(m.lcTempResult, "." + m.lcItem, m.lcTabs)+ "ENDWITH" + m.lcCRLF
ENDIF
NEXT
OTHERWISE && Legend objects
loMember = EVALUATE ("loPropertiesList." + m.lcMember)
AMEMBERS (laObjMembers, loMember)
m.lcTempResult = ''
FOR EACH m.lcObjMem IN laObjMembers
m.lcObjMem = THIS._spellproperty (m.lcObjMem)
lcDescription = ''
IF tlShowDescriptions AND PEMSTATUS(loMember, "_Descriptions", 5)
lnRow = ASCAN (loMember._Descriptions, m.lcObjMem, -1, -1, 1, 9)
IF lnRow > 0
lcDescription = loMember._Descriptions(lnRow, 4)
ENDIF
ENDIF
m.lcTempResult = m.lcTempResult + THIS._GetChartProp (;
m.loPropertiesList, m.lcMember + "." + m.lcObjMem, lnType, THIS._savedchartproperties, lcDescription, tlShowDescriptions)
NEXT
IF NOT EMPTY (m.lcTempResult)
m.lcObjects = m.lcObjects + "WITH ." + m.lcMember + m.lcCRLF + ;
STRTRAN(m.lcTempResult, "." + m.lcMember, m.lcTabs) + ;
"ENDWITH" + m.lcCRLF
ENDIF
ENDCASE
NEXT
* Merge all types
lcResult = lcResult + lcObjects + lcCollection
*!* 2009-02-21
*!* CChalom: Fixed insertion of With/Endwith
IF m.tbWrapper
LOCAL lcCommand, laLines(1), N
m.lcCommand = ""
FOR N = 1 TO ALINES(laLines, m.lcResult)
m.lcCommand = m.lcCommand + SPACE(3) + laLines(N) + m.lcCRLF
NEXT
TEXT TO lcResult NOSHOW TEXTMERGE
LOCAL loChart as FoxCharts OF "FoxCharts.vcx"
m.loChart = CREATEOBJECT("FoxCharts")
WITH loChart
<<m.lcCommand>>
<<m.lcTabs>>loChart.DrawChart()
ENDWITH
ENDTEXT
ENDIF
RETURN m.lcResult
ENDPROC
PROCEDURE getcontourmeasures
LPARAMETERS lcContour, tnLeft, tnTop, tnWidth, tnHeight
LOCAL lnLine, lnLines, lnVal, laLines(1),la(1),lnCount
lnLines = ALINES(laLines,lcContour)
FOR lnLine=1 TO lnLines
lnCount = ALINES(la,laLines(lnLine),',')
lnVal=VAL(la(1))
IF lnLine=1
STORE lnVal TO tnLeft, tnWidth
ELSE
tnLeft = MIN(tnLeft,lnVal)
tnWidth = MAX(tnWidth,lnVal)
ENDIF
lnVal=VAL(la(2))
IF lnLine=1
STORE lnVal TO tnTop, tnHeight
ELSE
tnTop = MIN(tnTop,lnVal)
tnHeight = MAX(tnHeight,lnVal)
ENDIF
IF lnCount>5
tnWidth = MAX(tnWidth,VAL(la(1)) +VAL(la(3)))
tnHeight = MAX(tnHeight,VAL(la(2)) + VAL(la(4)))
ENDIF
NEXT
tnWidth = tnWidth-tnLeft
tnHeight = tnHeight-tnTop
ENDPROC
PROCEDURE gettexture
LPARAMETERS lcTextureTheme,lcPicture
LOCAL lcExt, lnDir, lnLine
IF VARTYPE(lcPicture)= 'N'
lcPicture=TRANSFORM(lcPicture)+'.jpg'
ENDIF
lcTextureTheme = EVL(lcTextureTheme,THIS.TextureTheme)
lcPicture = TRANSFORM(EVL(lcPicture,THIS.TextureName))
DO CASE
CASE FILE('Textures\'+ADDBS(lcTextureTheme)+lcPicture)
RETURN 'Textures\'+ADDBS(lcTextureTheme)+lcPicture
CASE DIRECTORY('Textures\'+ADDBS(lcTextureTheme))
FOR lnLine=1 TO ADIR(la,'Textures\'+ADDBS(lcTextureTheme)+'*.*')
lcExt=LOWER(JUSTEXT(la(lnLine,1)))
IF lcExt $ [png,jpg,jpeg,gif,bmp]
THIS.TextureName = la(lnLine,1)
RETU 'Textures\'+ADDBS(lcTextureTheme)+THIS.TextureName
EXIT
ENDIF
NEXT
OTHERWISE
FOR lnDir=1 TO ADIR(laDir,'Textures\*',"D")
IF LEFT(laDir(lnDir,1),1)='.'
LOOP
ENDIF
FOR lnLine=1 TO ADIR(la,'Textures\'+ADDBS(laDir(lnDir,1))+'\*.*')
lcExt=LOWER(JUSTEXT(la(lnLine,1)))
IF lcExt $ [png,jpg,jpeg,gif,bmp]
THIS.TextureName = la(lnLine,1)
lcTextureTheme = laDir(lnDir,1)
RETURN 'Textures\'+ADDBS(lcTextureTheme)+THIS.TextureName
ENDIF
NEXT
NEXT
ENDCASE
RETURN ''
ENDPROC
PROCEDURE getvalue
LPARAMETERS tcField
LOCAL lcNum
WITH THIS
GO .ROW
IF EMPTY(tcField)
lcNum = ALLTRIM(STR(.COLUMN))
.VALUE = NVL(EVALUATE("nValue" + lcNum),0)
.BottomValue = IIF(TYPE([Bottom]+lcNum)='N',NVL(EVALUATE("Bottom" + lcNum),0),0 )
ELSE
RETURN EVALUATE(tcField)
ENDIF
ENDWITH
ENDPROC
PROCEDURE Init
IF NOT 'ALIAS FOXCHARTSBETA' $ SET('Class')
SET CLASSLIB TO foxchartsBeta.vcx ADDI
ENDIF
IF TYPE('_Screen.FoxChartsHelper') = 'U'
_SCREEN.ADDOBJECT('FoxChartsHelper', 'FoxChartsBeta.FoxChartsHelper')
ENDIF
DODEFAULT()
ENDPROC
PROCEDURE MouseDown
LPARAMETERS nButton, nShift, nXCoord, nYCoord, toShape
LOCAL llGradientInvertColors, llSingle, ;
lnAngle, lnDeltaLeft, lnDeltaTop, lnGradientLevel, lnHeight, lnLeft, lnMyLeft, lnMyTop, lnOldBrushType, lnRatio, lnSeconds, lnTop, lnWidth, lnX, lnX1, lnX2, lnY, lnY1, lnY2, ;
loGfx, loObject , loPen
IF TYPE('thisform.Rect1.Visible')='L' AND THISFORM.Rect1.VISIBLE
THISFORM.Rect1.VISIBLE=.F.
ENDIF
IF TYPE('toShape.Type') # 'C'
RETURN
ENDIF
IF m.nButton=1 AND m.toShape.TYPE='Comments'
IF TYPE([thisform.Canvas2])='U'
THISFORM.ADDOBJECT ('Canvas2','FoxChartsBeta.Pattern')
WITH THISFORM.Canvas2
.oGfx.SmoothingMode = _SCREEN.SYSTEM.Drawing.Drawing2D.SmoothingMode.AntiAlias
.PEN = _SCREEN.SYSTEM.Drawing.PEN.New(_SCREEN.SYSTEM.Drawing.COLOR.Black , 2)
.PEN.DASHSTYLE = 3
ENDWITH
ENDIF
STORE 0 TO m.lnLeft, m.lnTop, m.lnWidth, m.lnHeight
=THIS.GetContourmeasures (m.toShape.Contour, @m.lnLeft, @m.lnTop, @m.lnWidth, @m.lnHeight)
WITH THISFORM.Canvas2
.ZORDER(0)
.BACKSTYLE=0
.LEFT = THIS.LEFT + m.lnLeft
.TOP= THIS.TOP + m.lnTop
.WIDTH= m.lnWidth+1
.HEIGHT = m.lnHeight+1
.RenderMode = 4
* .CreateOSB()
.CLEAR(_SCREEN.SYSTEM.Drawing.COLOR.Transparent)
_Screen.FoxChartsHelper.DrawPath(.oGfx, .PEN, , m.toShape.Contour, -m.lnLeft, -m.lnTop)
.MyRenderOSB()
THISFORM.MOUSEPOINTER = 5
THISFORM.SETALL('MousePointer', 5)
.VISIBLE = .T.
m.lnMyLeft = .LEFT
m.lnMyTop = .TOP
m.lnLeft = m.lnMyLeft
m.lnTop = m.lnMyTop
DO WHILE MDOWN()
m.lnLeft = m.lnMyLeft + MCOL(THISFORM.NAME,THISFORM.SCALEMODE) - m.nXCoord
m.lnLeft = MAX(THIS.LEFT,MIN(THIS.LEFT+THIS.WIDTH -m.lnWidth-1,m.lnLeft))
m.lnTop = m.lnMyTop + MROW(THISFORM.NAME,THISFORM.SCALEMODE) - m.nYCoord
m.lnTop = MAX(THIS.TOP, MIN(THIS.TOP +THIS.HEIGHT-m.lnHeight-1, m.lnTop))
IF m.lnLeft = .LEFT AND m.lnTop = .TOP
LOOP
ENDIF
.LEFT = m.lnLeft
.TOP = m.lnTop
ENDDO
THISFORM.MOUSEPOINTER = 0
THISFORM.SETALL('MousePointer', 0)
.VISIBLE=.F.
ENDWITH
IF m.lnLeft = m.lnMyLeft AND m.lnTop = m.lnMyTop
RETURN
ENDIF
WITH THIS.CommentsSet(m.toShape.ChartIndex)
.LEFT = (m.toShape.LEFT + m.lnLeft-m.lnMyLeft) / THIS.WIDTH
.TOP = (m.toShape.TOP + m.lnTop-m.lnMyTop) / THIS.HEIGHT
ENDWITH
THIS.CommentsSetPack = THIS.CommentsSet.PACK()
THIS.Drawchart ()
RETURN
ENDIF
IF m.nButton=1 AND m.toShape.TYPE='Legend'
m.lnSeconds = SECONDS()+1
m.lnX2=-1
m.lnX1=m.nXCoord
m.lnY1=m.nYCoord
WITH _SCREEN.SYSTEM.Drawing
m.loGfx = .Graphics.FromHWnd(THISFORM.HWND) && Create a Graphics object
m.loGfx.SmoothingMode=4
m.loPen = .PEN.New(.COLOR.Blue,IIF(INLIST(THIS.ChartType,1,2,7,12),6,3)) && <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m.lnOldBrushType= THIS.BrushType
m.lnGradientLevel = THIS.GradientLevel
m.llGradientInvertColors = THIS.GradientInvertColors
THIS.GradientInvertColors =.T.
THIS.GradientLevel= 9
IF m.lnOldBrushType=1
THIS.BrushType=2
ENDIF
IF m.lnOldBrushType=2
THIS.BrushType=1
ENDIF
THIS._PrepareBrushes(0, 0, THIS.WIDTH, THIS.HEIGHT, .T., m.toShape.ChartIndex, .T.)
IF m.lnOldBrushType # THIS.BrushType
THIS.BrushType=m.lnOldBrushType
ENDIF
THIS.GradientLevel=m.lnGradientLevel
THIS.GradientInvertColors = m.llGradientInvertColors
m.loPen.Brush= THIS._oMainBrush
m.loPen.StartCap=18
m.loPen.EndCap=20
m.loPen.DASHSTYLE=1
m.llSingle = THIS.Singledata OR THIS.ChartsCount=1
FOR EACH m.loObject IN THIS.Shapes.OBJECTS
DO CASE
CASE THIS.ChartType<3 && Pie and donut
IF m.loObject.TYPE $ 'RectPie' AND m.loObject.Currentrow=m.toShape.VALUE
m.lnWidth = m.loObject.WIDTH / 2
m.lnHeight = m.loObject.HEIGHT / 2
m.lnX = m.loObject.LEFT + m.lnWidth
m.lnY = m.loObject.TOP + m.lnHeight
m.lnAngle = m.loObject.START + m.loObject.Sweep / 2
m.lnAngle = _Screen.FoxchartsHelper.UnAxonometric(m.lnAngle, m.lnWidth, m.lnHeight)
m.lnRatio = IIF(THIS.ChartType=1,0.5,THIS.DonutRatio)
m.lnRatio = m.lnRatio + (1 - m.lnRatio) / 2
m.lnX2 = m.lnX + COS(DTOR(m.lnAngle)) * m.lnWidth * m.lnRatio
m.lnY2 = m.lnY + SIN(DTOR(m.lnAngle)) * m.lnHeight * m.lnRatio
m.lnX2=m.lnX2 + OBJTOCLIENT(THIS,2)
m.lnY2=m.lnY2 + OBJTOCLIENT(THIS,1)
m.loGfx.Drawline(m.loPen, m.lnX1, m.lnY1, m.lnX2, m.lnY2)
EXIT
ENDIF
CASE m.llSingle
IF m.loObject.TYPE = 'Rect' AND m.loObject.Currentrow=m.toShape.VALUE
m.lnX2 = m.loObject.LEFT + m.loObject.WIDTH/2 + OBJTOCLIENT(THIS,2)
m.lnY2 = m.loObject.TOP + m.loObject.HEIGHT/2 + OBJTOCLIENT(THIS,1)
m.loGfx.Drawline(m.loPen, m.lnX1, m.lnY1, m.lnX2, m.lnY2)
EXIT
ENDIF
OTHERWISE
IF m.loObject.TYPE = 'Rect' AND m.loObject.ChartIndex = m.toShape.ChartIndex
IF m.loObject.LEFT=0 AND m.loObject.TOP=0
LOOP
ENDIF
m.lnX2=m.loObject.LEFT + m.loObject.WIDTH/2 + OBJTOCLIENT(THIS,2)
m.lnY2=m.loObject.TOP + m.loObject.HEIGHT/2 + OBJTOCLIENT(THIS,1)
m.loGfx.Drawline(m.loPen, m.lnX1, m.lnY1, m.lnX2, m.lnY2)
ENDIF
ENDCASE
NEXT
ENDWITH
DO WHILE MDOWN()
ENDDO
ENDIF
DO WHILE MDOWN()
ENDDO
THISFORM.CLS()
ENDPROC
PROCEDURE MouseUp
LPARAMETERS nButton, nShift, nXCoord, nYCoord, toShape
ENDPROC
PROCEDURE openword
* Code from Alex Yudin
* 23.11.2013: Koen added code to avoid "Application is Busy"
* Parameters from ToWord
Lparameters tcDoc, tlInvisible, tcPassWord
Local loWord, lnWindow, lcPath, lcPassWord
Local loErr As Object
#Define wdFormatDocument 0
#Define wdFormatDocument97 0
*!* lcPassWord = IIF(VARTYPE(m.tcPassWord) == 'C', m.tcPassWord, SPACE(0))
Declare Integer SetForegroundWindow In Win32API Long HWnd
Declare Long FindWindow In Win32API String lpClassName,String lpWindowName
Try
loWord=Getobject(,"WORD.APPLICATION")
Catch To m.loErr When m.loErr.ErrorNo=1426
loWord=Createobject("WORD.APPLICATION")
Finally
Endtry
** To avoid "Application is Busy" error messages using OLE Automation. see also - KB240809
Application.OLERequestPendingTimeout = 0
If Type('loWord.ActiveDocument')='O'
m.loWord.ActiveDocument.Close
Endif
lnWindow = FindWindow(.Null., m.loWord.Name)
If !Empty(m.tcDoc)
tcDoc=Lower(Forceext(Alltrim(m.tcDoc),'DOC'))
If File(m.tcDoc)
*tcDoc=Fullpath(m.tcDoc)
m.loWord.Documents.OpenFullpath(m.tcDoc)
Else
m.loWord.Documents.Add ("Normal", .F., 0)
*lcPath=Justpath(m.tcDoc)
If Not Directory(Justpath(m.tcDoc))
Md (Justpath(m.tcDoc))
Endif
Try
m.loWord.ActiveDocument.SaveAs(m.tcDoc,0,.F.,m.lcPassword)
Catch To m.loErr
Finally
Endtry
Endif
Endif
loWord.Visible=! m.tlInvisible
If m.lnWindow # 0
SetForegroundWindow(m.lnWindow)
Endif
Return m.loWord
ENDPROC
PROCEDURE rotate
LPARAMETERS lnX0,lnY0, lnX, lnY, lnNewAngle
LOCAL lnAlfa, lnC, lnX1, lnY1
lnX1=lnX-lnX0
lnY1=lnY-lnY0
lnNewAngle = DTOR(lnNewAngle)
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (lnX1,lnY1) <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> (x, y)
lnX = lnX1*COS(lnNewAngle)-lnY1*SIN(lnNewAngle) +lnX0
lnY = lnX1*SIN(lnNewAngle)+lnY1*COS(lnNewAngle) +lnY0
ENDPROC
PROCEDURE savechartproperties
****************************************************************
* Jim Nelson 10/20/2008
* modified 06/30/2009
* Save current settings of Chart Properties so that later comparisons
* can determine which properties have changed
LPARAMETERS tlSkipIfAlreadySaved
IF tlSkipIfAlreadySaved AND "O" = VARTYPE(THIS._SavedChartProperties)
RETURN
ENDIF
IF TYPE('this.CommentsSet.Name')='C'
THIS.CommentsSetPack = THIS.CommentsSet.PACK()
ENDIF
THIS._SavedChartProperties = THIS._GetChartProperties()
*!* ****************************************************************
*!* * Jim Nelson 10/20/2008
*!* *
*!* * Save current settings of Chart Properties so that later comparisons
*!* * can determine which properties have changed
*!* This._SavedChartProperties = This._GetChartProperties()
ENDPROC
PROCEDURE shapemouseenter
LPARAMETERS nButton, nShift, nXCoord, nYCoord, loShape
LOCAL lcLegend, lnChart, lo
lnChart=loShape.ChartIndex
lcLegend = EVL(loShape.Legend,'')
FOR EACH lo IN this.Shapes.Objects
IF lo.Type = 'Legend' AND ALLT(EVL(lo.Legend,''))==lcLegend
IF TYPE('THISFORM.Rect1')='U'
THISFORM.ADDOBJECT('Rect1','Shape')
THISFORM.Rect1.BACKSTYLE=0
BINDEVENT(THISFORM.rect1,'MouseDown',THIS.ChartCanvas ,'MouseDown')
ENDIF
WITH THISFORM.rect1
.LEFT = lo.Left - 1 + OBJTOCLIENT(THIS,2)
.WIDTH = lo.Width + 4
.TOP = lo.Top + OBJTOCLIENT(THIS,1)-1
.HEIGHT = lo.Height + 1
.VISIBLE=.T.
.BORDERCOLOR = RGB(255,0,0)
ENDWITH
RETURN
TRY
LOCAL lcBell
lcBell = SET("Bell")
SET BELL TO (ADDBS(GETENV('windir')))+"MEDIA\Start.WAV"
?? CHR(7)
SET BELL TO (lcBell)
CATCH
ENDTRY
ENDIF
NEXT
ENDPROC
PROCEDURE shapemouseleave
LPARAMETERS nButton, nShift, nXCoord, nYCoord, tnValue, tcLegend, tnCoordIndex
IF TYPE('thisform.Rect1.Visible')='L'
THISFORM.Rect1.VISIBLE=.F.
ENDIF
ENDPROC
PROCEDURE toword
* Code from Alex Yudin
* History : Koen Piller added codes for Clipboard checking in order to
* avoid errors when the clipboard is already in use
* Koen changed default saving directory and added "FindFirstFile"
* to avoid tcDir contains short a shortfilename
Local lcDir, lcFile, lcString, lcTableNum, lcVal, lcWordName, lhClipBMP, lhWndWord, lnChart
Local lnColumns, lnEnd, lnLine, lnRows, lnStart, lnStartRows, loTable, loWord, luValue, lcBuffer
** Function FindFirstFile derived from sample code posted by
** AirCon (IS/IT--Manageme) on TekTips.com on May 12, 2003
Declare Long FindFirstFile In Kernel32 As fnFindFirst ;
String cFileName, String @WIN32_DATA
Declare FindClose In Kernel32 As fnFindClose Long hFile
lcDir = GETENV("temp")
lcFile = 'Charts.DOC'
lcBuffer = Replicate(Chr(0), 318)
hFile = fnFindFirst(ADDBS(lcDir)+m.lcFile, @m.lcBuffer)
If (m.hFile > 0)
lcFile = Substr(m.lcBuffer, 45)
lcFile = Left(m.lcFile, At(Chr(0), m.lcFile)-1)
fnFindClose(m.hFile)
Endif
Clear Dlls fnFindFirst, fnFindClose
lcWordName = m.lcDir + m.lcFile
#Define cf_bitmap 2
#Define cf_dib 8
#Define obj_bitmap 7
Declare Integer CloseClipboard In user32
Declare Integer OpenClipboard In user32 Integer HWnd
Declare Integer GetClipboardData In user32 Integer uFormat
Declare Integer IsClipboardFormatAvailable In user32 Integer wFormat
Declare Integer GetObjectType In gdi32 Integer h
***
Local Array laHeaders(This.ChartsCount+1,2)
laHeaders(1,1) = This.FieldLegend
For lnChart=1 To This.ChartsCount
laHeaders(m.lnChart+1,1) = This.Fields(m.lnChart).Fieldvalue
laHeaders(m.lnChart+1,2) = Evl(This.Fields(m.lnChart).Legend,'-')
Next
If This.ChartsCount = 1
laHeaders(1,2) = Evl(This.Fields(1).Legend,'-')
laHeaders(2,2) = '-'
Else
laHeaders(1,2) = '-'
Endif
loWord = This.OpenWord(m.lcWordName,)
lnRows = 1
lnColumns = Alen(m.laHeaders,1)
This.oBMP.toClipboard()
*= OpenClipboard (0)
*= CloseClipboard ()
With m.loWord
lhWndWord = FindWindow("OPUSApp", '') &&"OPUSApp" is the internal name of the MSWord-Class
.Selection.WholeStory
lhClipBMP = GetClipboardData (cf_bitmap)
If m.lhClipBMP = 0 Or GetObjectType(m.lhClipBMP) # obj_bitmap
lcFile = Addbs(Getenv('temp')) + Sys(2015) + ".PNG"
This.SaveToFile(m.lcFile)
.Selection.InlineShapes.AddPicture(m.lcFile,.F.,.T.)
Erase (m.lcFile)
Else
.Selection.paste()
Endif
.ActiveDocument.Tables.Add(.Selection.Range(), m.lnRows+1, m.lnColumns, .T., .F.)
lcTableNum = Evl(m.lcTableNum,1)
Select (This.SourceAlias)
loTable = .ActiveDocument.Tables(m.lcTableNum)
loTable.Select
lnStartRows = 1 &&loTable.ROWS.COUNT for multiple use
lcString = ''
For lnLine = 1 To m.lnColumns
lcString = m.lcString+Alltrim(m.laHeaders(m.lnLine,2)) + iif(m.lnLine = m.lnColumns,Chr(13),Chr(9))
Next
Select (This.SourceAlias)
lnRows = 0
Scan
lnRows = m.lnRows + 1
For lnLine = 1 To m.lnColumns
lcVal = m.laHeaders(m.lnLine,1)
luValue = iif(Type(m.lcVal)=='U','-',Nvl(Evaluate(m.laHeaders(m.lnLine,1)),'-'))
lcString = m.lcString + Transform(m.luValue) + iif(m.lnLine = m.lnColumns,Chr(13),Chr(9))
Next
Endscan
If m.lnRows>1
.Selection.movedown (5, 1)
.Selection.insertrows(m.lnRows-1)
Endif
_Cliptext = m.lcString
lnStart = m.loTable.Cell(m.lnStartRows,1).Range.Start
lnEnd = m.loTable.Cell(m.lnStartRows + m.lnRows,m.lnColumns).Range.End
.ActiveDocument.Range(m.lnStart,m.lnEnd).Paste()
.ActiveDocument.Saved = .T.
.Visible=.T.
* SetWindowPos moves the window to the top, using the window handle
Declare SetWindowPos In WIN32API Long HWnd, Long hwndafter, ;
LONG x, Long Y, Long cx, Long cy, Long Flags
= SetWindowPos(m.lhWndWord, -1, 0,0,0,0, 3) && Moves Word to the topmost
= SetWindowPos(m.lhWndWord, -2, 0,0,0,0, 3) && Not topmost
* .Selection.TypeParagraph
Endwith
ENDPROC
PROCEDURE towriter
* Code from Alex Yudin
LOCAL lcVal, lnChart, lnColumns, lnLine, lnRowCount, lnRows, ;
loChart, loCoreReflection, loDesktop, loDispatcher, loDocument, loFrame, loRange, loTable, ;
luValue
LOCAL loWriter, laArgs(4), loProperty
TRY
m.loWriter = CREATEOBJECT("com.sun.star.ServiceManager")
CATCH
MESSAGEBOX('Open Office not installed')
ENDTRY
IF VARTYPE(m.loWriter) # "O"
RETURN .F.
ENDIF
m.loDesktop = m.loWriter.createInstance("com.sun.star.frame.Desktop")
m.loDispatcher = m.loWriter.createInstance("com.sun.star.frame.DispatchHelper")
m.loCoreReflection = m.loWriter.createInstance("com.sun.star.reflection.CoreReflection")
WITH m.loCoreReflection.forName("com.sun.star.beans.PropertyValue")
FOR m.lnLine=1 TO ALEN(laArgs,1)
m.loProperty =CREATEOBJECT( "Empty" )
.CREATEOBJECT(@m.loProperty)
laArgs(m.lnLine)=m.loProperty
NEXT
ENDWITH
RELEASE m.loProperty
COMARRAY(m.loDesktop,10)
* New document
laArgs[1].NAME = "ReadOnly"
laArgs[1].VALUE = .F.
m.loDocument = m.loDesktop.LoadComponentFromUrl( "private:factory/swriter", "_blank", 0, @laArgs )
m.loFrame = m.loDocument.getCurrentController().getFrame()
laArgs(1).NAME = "Text"
laArgs(1).VALUE = " "
m.loDispatcher.executeDispatch(m.loFrame, ".uno:InsertText", "", 0, @laArgs)
*** Insert table
SELECT (This.SourceAlias)
m.lnRows = RECCOUNT()
m.lnColumns = This.ChartsCount+1
m.lnRowCount = m.lnRows+1
LOCAL laArray(lnColumns, lnRowCount), laHeaders(lnColumns)
STORE '-' TO m.laArray
laHeaders(1) = This.FieldLegend
FOR m.lnChart=1 TO This.ChartsCount
laHeaders(m.lnChart+1) = This.FIELDS(m.lnChart).Fieldvalue
m.laArray(m.lnChart+1,1) = EVL(This.FIELDS(m.lnChart).Legend,'-')
NEXT
IF This.ChartsCount = 1
m.laArray(2,1) = EVL(This.FIELDS(1).Legend,'-')
ENDIF
m.lnRows = 0
SCAN
m.lnRows = m.lnRows + 1
FOR m.lnLine=1 TO m.lnColumns
m.lcVal = laHeaders( m.lnLine)
m.luValue = IIF(TYPE(m.lcVal)='U','-',NVL(EVALUATE(m.lcVal),'-'))
m.laArray(m.lnLine,m.lnRows+1)= TRANSFORM(m.luValue)
NEXT
ENDSCAN
laArgs(1).NAME = "TableName"
laArgs(1).VALUE = "ChartTable"
laArgs(2).NAME = "Columns"
laArgs(2).VALUE = m.lnColumns
laArgs(3).NAME = "Rows"
laArgs(3).VALUE = m.lnRows+1
laArgs(4).NAME = "Flags"
laArgs(4).VALUE = 9
m.loDispatcher.executeDispatch(m.loFrame, ".uno:InsertTable", "", 0, @laArgs)
m.loDispatcher.executeDispatch(m.loFrame, ".uno:GoToStartOfDoc", "", 0, @laArgs)
m.loTable = m.loDocument.TextTables.getByIndex(0)
m.loRange = m.loTable.getCellRangeByPosition(0,0, m.lnColumns-1, m.lnRows)
m.loRange.SetDataArray(@m.laArray)
m.loDispatcher.executeDispatch(m.loFrame, ".uno:Escape", "", 0, @laArgs)
m.loDispatcher.executeDispatch(m.loFrame, ".uno:GoToStartOfDoc", "", 0, @laArgs)
m.loDispatcher.executeDispatch(m.loFrame, ".uno:GoToStartOfDoc", "", 0, @laArgs)
THISFORM.ParentForm.Foxcharts1.oBmp.ToClipboard()
laArgs[1].NAME = ""
laArgs[1].VALUE = ""
m.loDispatcher.executeDispatch(m.loFrame, ".uno:Paste", "", 0, @laArgs)
m.loDispatcher.executeDispatch(m.loFrame, ".uno:Escape", "", 0, @laArgs)
m.loDispatcher.executeDispatch(m.loFrame, ".uno:GoToStartOfDoc", "", 0, @laArgs)
m.loFrame.getContainerWindow.setVisible(.T.)
ENDPROC
PROCEDURE toxls
LOCAL lcClip, lcLegend, lcOldCliptext, lcWorkBook, llOK, ;
lnChart, lnCount, lnHeight, lnLine, loBook, loSheet, loXls
* Trying to attach launched Excel
m.llOK=.T.
TRY
m.loXls=GETOBJECT(,"EXCEL.APPLICATION")
CATCH TO loErr
m.llOK=.F.
ENDTRY
IF ! m.llOK
m.llOK=.T.
TRY
m.loXls=CREATEOBJECT("EXCEL.APPLICATION")
CATCH TO loErr
m.llOK=.F.
ENDTRY
ENDIF
m.lcWorkBook=GETENV("TEMP")+'\Foxcharts.xls'
WITH m.loXls
.DisplayAlerts=.F.
m.loBook=.Workbooks.ADD
m.llOK=.T.
TRY
m.loBook.SAVEAS(m.lcWorkBook)
CATCH
m.llOK=.F.
ENDTRY
IF NOT m.llOK
.QUIT
m.loXls=0
RETURN
ENDIF
m.lcOldCliptext=_CLIPTEXT
* Chart image to Clipboard
THIS.oBmp.ToClipboard()
* Insert image into Active sheet
.activesheet.Paste
m.lnHeight=.activesheet.PICTURES(1).HEIGHT
m.loSheet=.activesheet
FOR m.lnLine=1 TO 1000
IF m.loSheet.cells(m.lnLine,1).TOP>m.lnHeight
EXIT
ENDIF
NEXT
m.lnCount = THIS.ChartsCount
m.loSheet.cells(m.lnLine,1).SELECT
m.lcClip = '-'
FOR m.lnChart=1 TO m.lnCount
TEXT TO m.lcClip addi
<<EVL(This.FIELDS(m.lnChart).Legend,'-')>>
ENDTEXT
NEXT
m.lcClip=m.lcClip+CHR(13)
SELECT (THIS.sourcealias)
m.lcLegend=THIS.FieldLegend
SCAN
m.lcClip = m.lcClip +ALLT(&lcLegend.)+CHR(9)
FOR m.lnChart=1 TO m.lnCount
m.lcClip = m.lcClip +TEXTMERGE([<<EVALUATE(This.FIELDS(m.lnChart).Fieldvalue))>>])+IIF(m.lnChart= THIS.ChartsCount,CHR(13),CHR(9))
NEXT
ENDSCAN
_CLIPTEXT=m.lcClip
m.llOK = .T.
.activesheet.Paste
_CLIPTEXT=m.lcOldCliptext
WITH m.loSheet.RANGE(m.loSheet.cells(m.lnLine,1),m.loSheet.cells(m.lnLine,m.lnCount+1))
.HorizontalAlignment =-4108
.VerticalAlignment=-4108
.WrapText = .T.
ENDWITH
m.loSheet.COLUMNS("A:A").EntireColumn.AUTOFIT
m.loSheet.cells(1,1).SELECT
.VISIBLE=.T.
* SetWindowPos moves the window to the top, using the window handle
DECLARE SetWindowPos IN WIN32API LONG HWND, LONG hwndafter, ;
LONG x, LONG Y, LONG cx, LONG cy, LONG FLAGS
= SetWindowPos(.HWND, -1, 0,0,0,0, 3) && Moves Excel to the topmost
= SetWindowPos(.HWND, -2, 0,0,0,0, 3) && Not topmost
ENDWITH
ENDPROC
PROCEDURE _beforedraw
This._Drawing = .T.
* Store the current selected table / cursor
LOCAL lnSelect
m.lnSelect = SELECT()
* Initial Settings
LOCAL loChart as FoxCharts OF FoxCharts.Vcx
m.loChart = This
m.loChart.oGfx = This.ChartCanvas.oGfx
m.loChart.oBmp = This.ChartCanvas.oBmp
* Update quality settings
This._UpdateQuality()
* Check if the FoxCharts object was created
* This is for the case when the user does not create the chart cursor before the form is initialized.
IF EMPTY(This.SourceAlias)
m.loChart._PrepareBackGround()
RETURN
ENDIF
* Check for the minimum dimensions
IF This.ChartCanvas.Width < 30 OR ;
This.ChartCanvas.Height < 30
RETURN
ENDIF
m.loChart._CheckParams()
m.loChart._UpdateChartInfo()
THIS.Shapes.CLEAR
IF NOT m.loChart._SkipPrepareData OR NOT USED(This._DataCursor)
* Check if empty cursor
IF NOT m.loChart._PrepareData()
m.loChart._PrepareBackGround()
m.loChart._PrepareTitle()
RETURN
ENDIF
* Make sure to clear some properties to avoid issues if changing the chart type
* having the Chart active
This._ScaleLegAxis1ForceFormat = ""
This._ScaleLegAxis2ForceFormat = ""
This.ScaleLegend._ForceFormat = ""
m.loChart._PrepareVariables()
m.loChart._PrepareColors()
ELSE
SELECT (This._DataCursor)
GO TOP
ENDIF
* m.loChart._PrepareColors()
m.loChart._PrepareBackGround()
m.loChart._PrepareTitle()
m.loChart._PrepareSideLegend()
m.loChart._PrepareLegend()
m.loChart._DrawAxis()
m.loChart._PrepareTooltip
IF m.loChart.ShowValuesOnShapes
m.loChart.ShapeLegend._Setup()
ENDIF
LOCAL lnChartType
m.lnChartType = m.loChart.ChartType
IF INLIST(m.lnChartType, 6, 9, 14, 11, 10) AND This._HasNegatives
MESSAGEBOX("The selected Chart type does not support negative values" + CHR(13) + "The chart will not be drawn", 48, "Invalid Data")
ELSE
DO CASE
*!* Chart Type Values:
*!* 1 = Pie ; 2 = Donut ;
*!* 3 = Unspecified ;
*!* 4 = Point ; 5 = Line ; 6 = Area ;
*!* 7 = Simple Bar ; 8 = Multiple Bars ; 9 = Stacked Bars ; 11 = 3D Bars
*!* 10 = Stacked Area
*!* 12 = Horizontal Bars ; 13 = Horizontal multiple bars ; 14 = Horizontal Stacked Bars
CASE This._GeneralType = "Pie" && Pie or Donut Chart
m.loChart._DrawPieChart()
CASE This._GeneralType = "Bar" && Bar Chart
m.loChart._DrawBarChart()
CASE INLIST(m.lnChartType, 4, 5, 6, 18) && Line or Area Chart
m.loChart._DrawLineChart()
CASE INLIST(m.lnChartType, 10, 16) && Stacked Area Chart
m.loChart._DrawStackedAreaChart()
ENDCASE
ENDIF
m.loChart._DrawSideLegends()
m.loChart.AfterChart()
m.loChart._FirstActivate = .F.
m.loChart._SkipPrepareData = .F.
m.loChart._yAxisWidth = 0
m.loChart._yAxisWidth2 = 0
* Restore the original selected alias
SELECT (m.lnSelect)
This._GetRelativePositions()
ENDPROC
PROCEDURE _checkmouseposition
LPARAMETERS nButton, nShift, nXCoord, nYCoord, lnValue, lnCoordIndex, toObject
* Passed by reference: lnValue
LOCAL lcObjectName, llFound, lnChartIndex, lnCoords, lnLeft, lnLine, lnNum, lnRecno, lnRecord, lnSelect, lnTop, lnX, lnY, ;
loFirstSlice , loFoundShape, loShape
m.toObject = .F.
WITH THIS
IF TYPE('.Shapes.Shape1.name') <> "C" OR nYCoord < 0 OR nXCoord <0
.MOUSEMOVE(nButton, nShift, nXCoord, nYCoord, toObject)
.OldMouseIndex = 0
RETURN
ENDIF
m.lnLeft = ._xRelative &&+ .Left
m.lnTop = ._yRelative &&+ .Top
lnX=nXCoord - m.lnLeft
lnY=nYCoord - m.lnTop
lnCoords = .Shapes.CONTROLCOUNT
FOR EACH loShape IN .Shapes.OBJECTS
IF loShape.TYPE $ "Title,Subtitle,YaxisCaption,Yaxis2Caption,XaxisCaption,Legend,ScaleLegend,Comments" AND loShape.CheckMousePosition(lnX, lnY)
m.toObject = loShape
lnValue = loShape.VALUE
lnCoordIndex = loShape.CoordNum
IF NOT loShape.TYPE = "Legend"
=IIF(.ShowContour AND .OldMouseIndex # loShape.CoordNum,.DrawContour(loShape.Contour,loShape.CoordNum),.F.)
.OldMouseIndex = loShape.CoordNum
RETURN
ENDIF
ENDIF
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "Delta"
IF .ShowDelta > 0 AND loShape.CheckMousePosition(lnX,lnY,"Delta")
m.toObject = loShape
=IIF(.ShowContour AND .OldMouseIndex # loShape.CoordNum, .DrawContour(loShape), .F.)
.OldMouseIndex = loShape.CoordNum
RETURN
ENDIF
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "ShapeLegend"
IF .ShowValuesOnShapes AND loShape.CheckMousePosition(lnX,lnY,"ShapeLegend")
m.toObject = loShape
=IIF(.ShowContour AND .OldMouseIndex # loShape.CoordNum,.DrawContour(loShape.Contour,loShape.CoordNum),.F.)
.OldMouseIndex = loShape.CoordNum
RETURN
ENDIF
NEXT
DO CASE
CASE ._GeneralType $ "Bar,Point"
lnRecord = ._nrecords+1
FOR lnNum=.Shapes.CONTROLCOUNT TO 1 STEP -1 && Reverse in order to catch the first drawing
lcObjectName='Shape'+ALLTRIM(STR(lnNum))
loShape=EVALUATE('.Shapes.' + lcObjectName)
IF loShape.TYPE = 'Delta'
LOOP
ENDIF
IF NOT loShape.TYPE $ 'Title,Subtitle'
lnRecord = lnRecord -1
ENDIF
IF loShape.CheckMousePosition(lnX,lnY,'Rect')
IF .ShowContour AND .OldMouseIndex # loShape.CoordNum
=.DrawContour(EVL(loShape.Front,loShape.Contour),loShape.CoordNum),.F.)
ENDIF
.OldMouseIndex = loShape.CoordNum
ELSE
LOOP
ENDIF
toObject = loShape
m.lnValue = loShape.VALUE
m.lnCoordIndex = loShape.CoordNum
IF m.loShape.TYPE $ "Legend"
._nMouseOnShape = 0
.OldMouseIndex = loShape.CoordNum
RETURN
ENDIF
IF ._nMouseOnShape = 0
._nMouseOnShape = lnRecord
.ShapeMouseEnter(nButton, nShift, nXCoord, nYCoord, loShape)
ELSE
IF ._nMouseOnShape # loShape.CoordNum
._nMouseOnShape = loShape.CoordNum
.ShapeMouseEnter(nButton, nShift, nXCoord, nYCoord, loShape)
ELSE && Mouse over the shape
.ShapeMouseMove(nButton, nShift, nXCoord, nYCoord, m.lnValue, ,m.lnCoordIndex)
ENDIF
ENDIF
.OldMouseIndex = loShape.CoordNum
RETURN
NEXT
IF ._nMouseOnShape # 0
._nMouseOnShape = 0
.ShapeMouseLeave(nButton, nShift, nXCoord, nYCoord, loShape)
ENDIF
CASE ._GeneralType = "Pie"
* Adapted code from Luis Maria Guayan - VFP MVP from Argentina
LOCAL lnX1, lnX2, lnX3, lnY1, lnY2, lnY3, lnStart, lnSweep, lnValue, lnAngle
llFound = .F.
FOR EACH loFirstSlice IN .Shapes.OBJECTS
IF loFirstSlice.TYPE='Pie'
.OldMouseIndex = loFirstSlice.CoordNum
llFound = .T.
EXIT
ENDIF
NEXT
IF NOT llFound
RETURN
ENDIF
* Center of Ellipse
m.lnX1 = loFirstSlice.WIDTH / 2
m.lnY1 = loFirstSlice.HEIGHT / 2
* Coordinates inside the Shape
IF ._Pie1stDetached
m.lnX2 = lnX - m.lnX1 - ._PieX0
m.lnY2 = - (lnY - m.lnY1 - ._PieY0)
ELSE
m.lnX2 = lnX - m.lnX1 - loFirstSlice.LEFT
m.lnY2 = - (lnY - m.lnY1 - loFirstSlice.TOP)
ENDIF
* <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> [0<>..360<EFBFBD>]
m.lnAngle = RTOD(ATAN(m.lnY2/m.lnX2))
DO CASE
CASE m.lnX2 < 0
m.lnAngle = 180 + m.lnAngle
CASE m.lnY2 < 0
m.lnAngle = 360 + m.lnAngle
ENDCASE
m.lnAngle = 360 - m.lnAngle
LOCAL lnFoundShape
m.lnFoundShape = 0
* Now we need to find the shape
FOR lnLine = loFirstSlice.CoordNum TO lnCoords
loFoundShape = EVALUATE('.Shapes.Shape' + ALLTRIM(STR(lnLine)))
m.lnStart = EVL(loFoundShape.START, 0)
IF loFoundShape.TYPE # 'Pie' OR VARTYPE(m.lnStart) <> "N"
LOOP
ENDIF
m.lnSweep = EVL(loFoundShape.Sweep, 0)
IF BETWEEN(m.lnAngle, m.lnStart, m.lnStart + m.lnSweep) OR ;
BETWEEN(m.lnAngle + 360, m.lnStart, m.lnStart + m.lnSweep)
m.lnFoundShape = lnLine
EXIT
ENDIF
NEXT
IF m.lnFoundShape = 0
.OldMouseIndex = 0
RETURN
ENDIF
* Now we can know exactly the positions in the screen
* for the case of detached slices
* So, we restart, using the correct information
* Center of Shape
m.lnX1 = loFoundShape.WIDTH / 2
m.lnY1 = loFoundShape.HEIGHT / 2
* Coordinates inside the Shape
m.lnX2 = lnX - m.lnX1 - loFoundShape.LEFT
m.lnY2 = -(lnY - m.lnY1 - loFoundShape.TOP)
* Percentage in the ellipse
m.lnX3 = m.lnX2 / m.lnX1
m.lnY3 = m.lnY2 / m.lnY1
*** NEW ANGLE
* Angle in degrees [0<>..360<EFBFBD>]
m.lnAngle = RTOD(ATAN(m.lnY2/m.lnX2))
DO CASE
CASE m.lnX2 < 0
m.lnAngle = 180 + m.lnAngle
CASE m.lnY2 < 0
m.lnAngle = 360 + m.lnAngle
ENDCASE
m.lnAngle = 360 - m.lnAngle
IF BETWEEN(m.lnAngle, m.lnStart, m.lnStart + m.lnSweep) OR ;
BETWEEN(m.lnAngle + 360, m.lnStart, m.lnStart + m.lnSweep)
ELSE
IF ._nMouseOnShape <> 0
._nMouseOnShape = 0
.ShapeMouseLeave(nButton, nShift, nXCoord, nYCoord, loShape)
ENDIF
.OldMouseIndex = 0
RETURN
ENDIF
*** NEW ANGLE
LOCAL lnRatio
m.lnRatio = m.lnY3^2 + m.lnX3^2
IF m.lnRatio > 1 OR ;
.ChartType = 2 AND m.lnRatio < .DonutRatio / 2 && Doughnut
IF ._nMouseOnShape <> 0
._nMouseOnShape = 0
.ShapeMouseLeave(nButton, nShift, nXCoord, nYCoord, loShape)
ENDIF
.OldMouseIndex = 0
RETURN
ENDIF
m.lnValue = loFoundShape.VALUE
m.lnCoordIndex = loFoundShape.CoordNum
m.toObject = loFoundShape
IF ._nMouseOnShape = 0
._nMouseOnShape = m.lnFoundShape
.ShapeMouseEnter(nButton, nShift, nXCoord, nYCoord, loFoundShape)
ELSE
IF ._nMouseOnShape <> m.lnFoundShape
._nMouseOnShape = m.lnFoundShape
.ShapeMouseEnter(nButton, nShift, nXCoord, nYCoord, loFoundShape)
ELSE
.ShapeMouseMove(nButton, nShift, nXCoord, nYCoord, loFoundShape)
ENDIF
ENDIF
RETURN
ENDCASE
IF .ShowAxis
FOR EACH loShape IN .Shapes.OBJECTS
IF loShape.TYPE $ "BottomSide,LeftSide,RightSide,AxisLegend2" AND loShape.CheckMousePosition(lnX,lnY)
m.toObject = loShape
=IIF(.ShowContour AND .OldMouseIndex # loShape.CoordNum,.DrawContour(loShape.Contour,loShape.CoordNum),.F.)
.OldMouseIndex = loShape.CoordNum
RETURN
ENDIF
NEXT
ENDIF
IF .OldMouseIndex # 0
THISFORM.CLS()
.Tips.VISIBLE=.F.
ENDIF
.OldMouseIndex= 0
ENDWITH
ENDPROC
PROCEDURE _checkparams
ASSERT BETWEEN(This.AlphaChannel, 0, 255) MESSAGE "AlphaChannel must be between 0-255"
ASSERT BETWEEN(This.AxisAlpha, 0, 255) MESSAGE "AxisAlpha must be between 0-255"
ASSERT BETWEEN(This.BackGradientMode, 0, 3) MESSAGE "BackGradientMode not available (0-3)"
ASSERT BETWEEN(This.BarType, 0, 6) MESSAGE "BarType not available (0-6)"
ASSERT BETWEEN(This.BrushType, 1, 5) MESSAGE "BrushType not available (1-5)"
ASSERT BETWEEN(This.ChartType, 1, 18) MESSAGE "ChartType not available (1-18)"
ASSERT BETWEEN(This.ColorType, 0, 27) MESSAGE "ColorType not available (0-27)"
ASSERT BETWEEN(This.DonutRatio, 0, 1) MESSAGE "DonutRatio must be between 0 and 1"
ASSERT BETWEEN(This.GradientLevel, -10, +10) MESSAGE "GradientLevel not available (-10, +10)"
ASSERT BETWEEN(This.ScaleBackAlpha, 0, 255) MESSAGE "ScaleBackAlpha must be between 0-255"
ASSERT BETWEEN(This.ScaleBackBarsType, 0, 3) MESSAGE "ScaleBackBarsType not available (0-3)"
ASSERT BETWEEN(This.ScaleBackLinesType, 0, 3) MESSAGE "ScaleBackLinesType not available (0-3)"
ASSERT BETWEEN(This.ScaleBackLinesDash, 0, 4) MESSAGE "ScaleBackLinesDash must be between 0-4"
ASSERT This.ScaleDivider > 0 MESSAGE "ScaleDivider must be greater than Zero"
ASSERT This.BarsPerScale > 0 MESSAGE "BarsPerScale must be greater than Zero"
ASSERT This.LegendPosition <=12 MESSAGE "LegendPosition must be between 0-12"
ASSERT USED(This.SourceAlias) MESSAGE "The specified source alias - '" + ;
This.SourceAlias + "' could not be found!"
IF This.ColorType = 3 && Gradient
ASSERT (VARTYPE(This.Fields(1).Color) = "N" OR VARTYPE(This.Color1) = "N") ;
MESSAGE "You have to define the property .Fields(1).Color to determine the main starting gradient color"
ENDIF
* GdiPlusX version check
LOCAL lnVersion
m.lnVersion = 1.10
IF pemstatus(_Screen.System, "Version", 5)
m.lnVersion = _Screen.System.Version
ENDIF
IF m.lnVersion < 1.20
ASSERT (This.ChartType <> 4) ;
MESSAGE "Points ChartType #4 is not supported for GdiPlusX System.App versions prior to version 1.20" + CHR(13) + ;
"Please make sure to be using at least version 1.20 to be able to use this type of chart"
ENDIF
ENDPROC
PROCEDURE _detachclickedslice
LPARAMETERS tnIndex
LOCAL lcCursor, ;
llOrigDetach, ;
lnDetachPixels, lnRecno, lnStep, ;
loObject, N
IF EMPTY(tnIndex) OR (VARTYPE(tnIndex) <> "N")
RETURN
ENDIF
WITH THIS
loObject = EVALUATE('.Shapes.Shape'+ALLTRIM(STR(tnIndex)))
._ChartIndex = loObject.ChartIndex
m.lnRecno = loObject.Currentrow
m.lcCursor = ._DataCursor
SELECT (lcCursor)
GO m.lnRecno
m.llOrigDetach = lDetach
m.lcCursor = (._DataCursor)
REPLACE lDetach WITH NOT lDetach FOR RECNO() = m.lnRecno IN &lcCursor
IF m.llOrigDetach
._SkipPrepareData = .T.
.DrawChart()
ELSE
._PieAnimatedRec = m.lnRecno
m.lnDetachPixels = .PieDetachPixels
m.lnStep = m.lnDetachPixels / MAX(1,.PieDetachAnimationSteps)
FOR m.n = m.lnStep TO m.lnDetachPixels STEP m.lnStep
._PieAnimationPix = m.n
._SkipPrepareData = .T.
.DrawChart()
ENDFOR
ENDIF
._PieAnimatedRec = 0
._PieAnimationPix = 0
._SkipPrepareData = .F.
ENDWITH
ENDPROC
PROCEDURE _drawaxis
LOCAL ln3D, lnMargin, lnYAxisHeight, x0, x1, y0, y1, lnX, lnY
m.lnMargin = THIS.MARGIN
IF THIS._DeepChart && Point, Line or Area
m.ln3D = THIS._3D * THIS.ChartsCount
ELSE
m.ln3D = THIS._3D
ENDIF
* Prepare the scale in the Y Axis, populating the ._ScaleW property
THIS._GetyLegendSize()
IF This.ChartType = 18 AND This.ShowScale && DoubleAxis
This._GetyLegendSize(2)
ENDIF
STORE 0 TO lnYAxisHeight, lnYaxisRight
IF THIS.ShowAxis
* Draw the main Y Axis caption
LOCAL lcYText
IF NOT EMPTY(THIS.YAxis.CAPTION)
THIS.YAxis.RESET()
lnYAxisHeight = CEILING(THIS.YAxis._Height)
lnYaxisRight = lnYAxisHeight + THIS.YAxis.Left
ENDIF
ENDIF
* Leaving some extra space for the X Axis legends
LOCAL lnMinLeft, lnLeftCaptionWidth
IF NOT EMPTY(THIS.FieldAxis2)
* Measure the legend width
THIS.AxisLegend2._Setup()
GO TOP && First Legend
THIS.AxisLegend2.CAPTION = cAxis2 && Field text
lnLeftCaptionWidth = THIS.AxisLegend2._Width
lnMinLeft = lnLeftCaptionWidth &&/ 2
ELSE
STORE 0 TO lnMinLeft, lnLeftCaptionWidth
ENDIF
LOCAL lnEstimatedX, lnXBetween
lnEstimatedX = THIS.WIDTH - ;
(THIS._Rightoffset + THIS._Scalew + lnYAxisHeight + ln3D)
lnXBetween = lnEstimatedX / THIS._nRecords
IF lnXBetween > (lnLeftCaptionWidth / 2)
lnMinLeft = (lnLeftCaptionWidth / 2) && - lnXBetween
ENDIF
lnMinLeft = lnMinLeft + THIS.YAxis.Left + IIF(EMPTY(THIS.YAxis.CAPTION),0, THIS.YAxis.Width)
IF (NOT THIS.ShowAxis) OR NOT THIS._AllowAxis
IF THIS._Orientation = 1 && Vertical
THIS._yAxisWidth = 10 + lnMinLeft
ELSE && Horizontal
THIS._yAxisWidth = MAX(lnMinLeft, 0 + THIS._Scalew)
ENDIF
THIS._XAxisHeight = THIS._XAxisHeight - THIS.XAxis._Height
RETURN
ENDIF
LOCAL lnTickWidth, loGfx
m.lnTickWidth = 4
m.loGfx = THIS.oGfx
WITH _SCREEN.SYSTEM.Drawing
* Determining Colors, Brushes and Pens
LOCAL lnAxisColor, lnAxisBorderColor
IF THIS.BrushType = 3 && Monochrome
m.lnAxisColor = RGB(255,255,255) && White
m.lnAxisBorderColor = 0 && Black
ELSE
m.lnAxisColor = THIS.AxisColor
m.lnAxisBorderColor = THIS.ChangeColor(m.lnAxisColor, -30)
ENDIF
LOCAL loAxisMainColor AS xfcColor, loAxisBorderColor AS xfcColor, loPen AS xfcPen, loBrush AS xfcSolidBrush
loAxisMainColor = .COLOR.FromARGB(THIS.AxisAlpha, m.lnAxisColor)
loAxisBorderColor = .COLOR.FromARGB(THIS.AxisAlpha, m.lnAxisBorderColor)
m.loPen = .PEN.New(loAxisBorderColor, 1)
m.loBrush = .SolidBrush.New(loAxisMainColor)
ENDWITH
****************
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> Y
THIS._DrawYAxis(ln3D, lnMinLeft, lnYAxisHeight, loBrush, loPen, 1)
IF THIS.ChartType = 18 && DoubleAxis
THIS._DrawYAxis(m.ln3D, m.lnMinLeft, m.lnYAxisHeight, m.loBrush, m.loPen, 2)
* IF THIS.ShowScale
* This._DrawScale(m.loPen, 2)
* ENDIF
ENDIF
WITH _SCREEN.SYSTEM.Drawing
m.lnHeight = THIS.ChartCanvas.HEIGHT - THIS._XAxisHeight - THIS._TopOffSet - m.ln3D
THIS._ChartY0 = THIS.ChartCanvas.HEIGHT - THIS._XAxisHeight - m.ln3D
THIS._ChartY1 = THIS._ChartY0 - m.lnHeight
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> X
m.lnMargin = THIS._yAxisWidth + THIS._LeftOffset
LOCAL x0, x1, y0
x0 = m.lnMargin
x1 = THIS.ChartCanvas.WIDTH - THIS._Rightoffset
y0 = ROUND(THIS.ChartCanvas.HEIGHT - THIS._XAxisHeight + 1,0)
IF THIS.ShowAxis
IF m.ln3D = 0
m.loGfx.DrawLine(m.loPen, x0, y0, x1, y0)
ELSE
LOCAL laPoints(4)
laPoints(1) = .POINT.New(x0, y0)
laPoints(2) = .POINT.New(x0 + m.ln3D, y0 - m.ln3D)
laPoints(3) = .POINT.New(x1, y0 - m.ln3D)
laPoints(4) = .POINT.New(x1 - m.ln3D, y0)
TEXT to lcPoints
<<ROUND(x0,0)>>,<<ROUND(y0,0)>>
<<ROUND(x0 + m.ln3D,0)>>,<<ROUND(y0 - m.ln3D,0)>>
<<ROUND(x1,0)>>,<<ROUND(y0 - m.ln3D,0)>>
<<ROUND(x1-m.ln3D,0)>>,<<ROUND(y0,0)>>
<<ROUND(x0,0)>>,<<ROUND(y0,0)>>
ENDTEXT
THIS._updatecoordinates (,'BottomSide', x0, y0, m.ln3D, m.ln3D, '', 0, lcPoints, 0)
m.loGfx.FillPolygon(m.loBrush, @laPoints)
LOCAL laPointsB(6)
laPointsB(1) = laPoints(1)
laPointsB(2) = laPoints(4)
laPointsB(3) = laPoints(3)
laPointsB(4) = .POINT.New(laPoints(3).x, y0 - m.ln3D + 3)
laPointsB(5) = .POINT.New(laPoints(4).x, y0 + 3)
laPointsB(6) = .POINT.New(laPoints(1).x, y0 + 3)
m.loGfx.FillPolygon(m.loBrush, @laPointsB)
m.loGfx.DrawLine(m.loPen, x0, y0, x0 + m.ln3D, y0 - m.ln3D)
ENDIF
ENDIF
* Draw the main X Axis caption
IF NOT EMPTY(THIS.XAxis.CAPTION)
THIS.XAxis.RESET()
LOCAL lnW, lnH
m.lnX = m.lnMargin
m.lnY = y0 + THIS._LegendPixHeight + 4
m.lnW = x1 - x0
m.lnH = THIS.XAxis._Height
THIS.XAxis._DrawString(m.lnX, m.lnY, m.lnW, m.lnH)
DO CASE
CASE THIS.XAxis.ALIGNMENT = 0
lnLeft = INT(lnX)
CASE THIS.XAxis.ALIGNMENT = 1
lnLeft = INT(lnX + m.lnW - THIS.XAxis._Width)
OTHER
lnLeft= INT(lnX + ( m.lnW-THIS.XAxis._Width )/2)
ENDCASE
lnTop = INT(lnY)
lnRight = INT(lnLeft + THIS.XAxis._Width)
lnBottom = INT(lnTop + THIS.XAxis._Height)
TEXT TO lcPoints
<<ROUND(lnLeft,0)>>,<<ROUND(lnTop,0)>>
<<ROUND(lnRight,0)>>,<<ROUND(lnTop,0)>>
<<ROUND(lnRight,0)>>,<<ROUND(lnbottom,0)>>
<<ROUND(lnLeft,0)>>,<<ROUND(lnbottom,0)>>
<<ROUND(lnLeft,0)>>,<<ROUND(lnTop,0)>>
ENDTEXT
THIS._updatecoordinates(,"XaxisCaption", lnLeft, lnTop, THIS.XAxis._Width, THIS.XAxis._Height, 0, THIS.XAxis.CAPTION, lcPoints)
ENDIF
IF THIS.ShowScale
THIS._DrawScale(m.loPen)
ENDIF
IF THIS.ChartType = 18 && DoubleAxis
IF THIS.ShowScale
THIS._DrawScale(m.loPen, 2)
ENDIF
ENDIF
ENDWITH
ENDPROC
PROCEDURE _drawbar
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnValue, tnMaxBarHeight, tn3D, tnMaxRowBarHeight, tnBarType
* Yudin Alex 27 May 2013
LOCAL lcFront, lcPoints, llFrustum, lnBarType, ln3D, loShape, loTopBrush
m.tnHeight = ABS(m.tnHeight)
m.ln3D = MAX(IIF(VARTYPE(tn3D)='N',tn3D,THIS._3d), 1)
m.lnBarType = EVL(m.tnBarType,THIS.BarType)
DO CASE
CASE m.lnBarType = 1 && Cylinder
THIS._DrawCylinder(m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnValue)
RETURN
CASE m.lnBarType = 2 && Triangle
THIS._DrawTriangleBar(m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnValue)
RETURN
CASE INLIST(m.lnBarType , 3, 5) && Cone or Conoid
m.llFrustum = NOT EMPTY(m.tnMaxBarHeight) AND IIF(THIS._Orientation = 1,m.tnHeight,m.tnWidth)+1 < INT(m.tnMaxBarHeight)
IF m.llFrustum
RETURN THIS._DrawConoid(m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnValue, @m.tn3D, m.tnMaxBarHeight )
ELSE
RETURN THIS._DrawCone(m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnValue, @m.tn3D )
ENDIF
CASE INLIST(m.lnBarType , 4, 6) && Pyramid or Frustum
m.llFrustum = NOT EMPTY(m.tnMaxBarHeight) AND IIF(THIS._Orientation = 1,m.tnHeight,m.tnWidth)+1 < INT(m.tnMaxBarHeight)
IF m.llFrustum
RETURN THIS._DrawFrustum(m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnValue, @m.tn3D, m.tnMaxBarHeight)
ELSE
RETURN THIS._DrawPyramid(m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnValue, @m.tn3D)
ENDIF
ENDCASE
THIS._PrepareBrushes(m.tnX, m.tnY, m.tnWidth, m.tnHeight, .F., IIF(THIS.SingleData, RECNO(),THIS._ChartIndex))
LOCAL loPen AS xfcPen, loGfx AS xfcGraphics, loMainBrush AS xfcBrush, lo3dBrush AS xfcBrush
m.loPen = THIS._oBorderPen
m.loGfx = THIS.oGfx
m.lo3dBrush = THIS._o3DBrush
m.loMainBrush = THIS._oMainBrush
WITH _SCREEN.SYSTEM.Drawing
* Draw the 3D Bar using the 3DBrush
IF m.ln3D > 0 && 3D
IF NOT THIS.SHADOW
* Prepare Array of points to draw the 3D part of the Bar
LOCAL laPoints(4)
m.tnY = m.tnY
m.laPoints(1) = .PointF.New(m.tnX + m.tnWidth, m.tnY)
m.laPoints(2) = .PointF.New(m.tnX + m.tnWidth + m.ln3D, m.tnY - m.ln3D)
m.laPoints(3) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D)
m.laPoints(4) = .PointF.New(m.tnX, m.tnY)
LOCAL loPath AS xfcGraphicsPath
m.loPath = .Drawing2D.GraphicsPath.New()
m.loPath.FillMode = .Drawing2D.FillMode.ALTERNATE
m.loPath.StartFigure()
m.loPath.ADDLINE(m.tnX + m.tnWidth, m.tnY, m.tnX + m.tnWidth + m.ln3D, m.tnY - m.ln3D)
m.loPath.ADDLINE(m.tnX + m.tnWidth + m.ln3D, m.tnY - m.ln3D, m.tnX + m.ln3D, m.tnY - m.ln3D)
m.loPath.ADDLINE(m.tnX + m.ln3D, m.tnY - m.ln3D, m.tnX, m.tnY)
m.loPath.ADDLINE(m.tnX, m.tnY, m.tnX + m.tnWidth, m.tnY)
m.loTopBrush = _SCREEN.FoxChartsHelper.PathGradient( , m.loPath, THIS._nColor,-1, m.tnX+m.tnWidth/2+m.ln3D/2, m.tnY+m.ln3D/2)
m.loGfx.FillPolygon(m.loTopBrush, @laPoints)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillPolygon(THIS._oDimBrush, @laPoints)
ENDIF
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Change only Points 3 and 4
m.laPoints(3) = .PointF.New(m.tnX + m.tnWidth + m.ln3D, m.tnY + m.tnHeight - m.ln3D)
m.laPoints(4) = .PointF.New(m.tnX + m.tnWidth, m.tnY + m.tnHeight)
m.loGfx.FillPolygon(THIS._oRightbrush , @laPoints)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillPolygon(THIS._oDimBrush , @laPoints)
ENDIF
m.loGfx.DrawPolygon(m.loPen, @laPoints)
ELSE
LOCAL loShadowBrush AS xfcSolidBrush
m.loShadowBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel,128,128,128))
m.loGfx.FillRectangle(m.loShadowBrush , m.tnX + m.ln3D, m.tnY + m.ln3D, m.tnWidth, m.tnHeight - m.ln3D - m.ln3D)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillRectangle(THIS._oDimBrush , m.tnX + m.ln3D, m.tnY + m.ln3D, m.tnWidth, m.tnHeight - m.ln3D - m.ln3D)
ENDIF
LOCAL laPoints(4)
m.laPoints(1) = .PointF.New(m.tnX , m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.tnWidth , m.tnY + m.tnHeight)
m.laPoints(3) = .PointF.New(m.tnX + m.tnWidth + m.ln3D, m.tnY + m.tnHeight - m.ln3D)
m.laPoints(4) = .PointF.New(m.tnX + m.ln3D, m.tnY + m.tnHeight - m.ln3D)
m.loGfx.FillPolygon(m.loShadowBrush , @laPoints)
ENDIF
ENDIF
m.loGfx.FillRectangle(m.loMainBrush, m.tnX, m.tnY, m.tnWidth, m.tnHeight)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillRectangle(THIS._oDimBrush, m.tnX, m.tnY, m.tnWidth, m.tnHeight)
ENDIF
m.loGfx.DrawRectangle(m.loPen, m.tnX, m.tnY, m.tnWidth, m.tnHeight)
TEXT TO m.lcPoints
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>,<<ROUND(m.tnX + m.tnWidth,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>,<<ROUND(m.tnX + m.tnWidth + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D + m.tnHeight,0)>>,<<ROUND(m.tnX + m.tnWidth + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D,0)>>
<<ROUND(m.tnX + m.tnWidth + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D,0)>>,<<ROUND(m.tnX + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D,0)>>
<<ROUND(m.tnX + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D,0)>>,<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY,0)>>,<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
TEXT TO m.lcFront
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth,0)>>,<<ROUND(m.tnY,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY,0)>>
ENDTEXT
m.loShape = THIS._UpdateCoordinates(,"Rect", m.tnX + m.ln3D / 2, m.tnY, m.tnWidth, m.tnHeight, m.tnValue,,m.lcPoints,,m.lcFront)
IF THIS._GeneralType = "Bar"
THIS._DrawLegendinBar(m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnValue,,m.loShape)
ENDIF
ENDWITH
ENDPROC
PROCEDURE _drawbarchart
* Yudin Alex 2 June 2013
LOCAL lnBarType, lnBottomValue
LOCAL lcAlias, lcLastPoint, ;
lnBottomHeight, lnBottomWidth, lnColumn, lnCount, lnHorDelta, lnLine, lnLines, lnMaxBarHeight, lnMaxBarWidth, lnMaxRowHeight, lnMaxRowWidth, lnNativeValue, ;
lnNewHorDelta, lnNewVertDelta, lnOldCone3D, lnStack, lnSumBarHeight, lnSumBarWidth, lnTotalMaxBarHeight, lnTotalMaxBarWidth, lnX1, lnY1, lnYDelta
LOCAL lnWidth, lnHeight, x1, y1, N, lnValue, lnLeftMargin, ln3D, lnTopMargin
LOCAL lnPointHeight AS NUMBER, lnYBase AS NUMBER
WITH THIS
SELECT(._DataCursor)
m.ln3D = ._3D
m.lnWidth = .ChartCanvas.WIDTH - ._LeftOffset - ._RightOffset - m.ln3D - ._yAxisWidth
m.lnHeight = .ChartCanvas.HEIGHT - ._XAxisHeight - ._TopOffSet - m.ln3D
IF (m.lnWidth <= 0) OR (m.lnHeight <= 0)
RETURN
ENDIF
m.lnLeftMargin = ._yAxisWidth + ._LeftOffset
m.lnTopMargin = ._TopOffSet + m.ln3D
LOCAL lnBarWidth, lnBarHeight, lnBetween, lnMaxValue, lnAdjust, lnChartsCount
m.lnBetween = .BarsSpaceBetween
m.lnMaxValue = ._ScaleRange
m.lnChartsCount = .ChartsCount
* Prepare Points
IF ._Orientation = 1 && Vertical
IF ._DeepChart
m.lnWidth = m.lnWidth - (m.ln3D * (m.lnChartsCount - 1))
ENDIF
m.lnBetween = MIN(m.lnBetween, ;
(m.lnWidth - ._nRecords) / ._nRecords)
m.lnBarWidth = (m.lnWidth - (._nRecords - 1) * m.lnBetween) / ._nRecords
SCAN
m.n = RECNO()
m.x1 = m.lnLeftMargin + ((m.lnBarWidth + m.lnBetween) * (m.n - 1))
._aPoints(m.n,1) = m.x1 + (m.lnBarWidth / 2)
ENDSCAN
ELSE && Horizontal
m.lnBetween = MIN(m.lnBetween, ;
(m.lnHeight - ._nRecords) / ._nRecords)
m.lnBarHeight = (m.lnHeight - (._nRecords - 1) * m.lnBetween) / ._nRecords
SCAN
m.n = RECNO()
m.y1 = m.lnTopMargin + ((m.lnBarHeight + m.lnBetween) * (m.n - 1))
._aPoints(m.n,2) = m.y1 + (m.lnBarHeight / 2)
ENDSCAN
._DrawYAxisLegend()
ENDIF
._DrawVerticalLineBack()
m.lnMaxBarHeight=0
DO CASE
CASE .ChartType = 7 && Simple Bar
SELECT (._DataCursor)
LOCAL laStack(RECCOUNT(),7)
m.lnScaleAdjustment = ._ScaleAdjust / m.lnMaxValue * m.lnHeight
m.lnZeroY = ._TopOffSet + m.ln3D + (._MaxScale / m.lnMaxValue * m.lnHeight)
IF ._MinScale > 0
m.lnZeroY = m.lnZeroY - (._MinScale / m.lnMaxValue * m.lnHeight)
ENDIF
._ChartIndex = .ChartRow
m.lcLastPoint=''
SCAN
m.lnLine = RECNO()
m.lnValue = ._GetValue(.ChartRow, .T.)
IF ISNULL(m.lnValue) OR m.lnValue < ._MinScale
LOOP
ENDIF
IF m.lnValue < 0
m.lnBarHeight = (m.lnValue / m.lnMaxValue * m.lnHeight)
m.lnY1 = m.lnZeroY
ELSE
m.lnBarHeight = (m.lnValue / m.lnMaxValue * m.lnHeight) + ;
IIF(._ScaleAdjust < 0, m.lnScaleAdjustment, 0)
m.lnY1 = m.lnZeroY - m.lnBarHeight
ENDIF
m.lnX1 = m.lnLeftMargin + ((m.lnBarWidth + m.lnBetween) * (RECNO() - 1))
m.lnMaxBarHeight=MAX(m.lnMaxBarHeight,m.lnBarHeight)
laStack(m.lnLine,1)=m.lnX1
laStack(m.lnLine,2)=m.lnY1
laStack(m.lnLine,3)=m.lnBarWidth
laStack(m.lnLine,4)=m.lnBarHeight
laStack(m.lnLine,5)=m.lnValue
laStack(m.lnLine,6)= RECNO()
laStack(m.lnLine,7) = IIF(.Fields(._ChartIndex).Bartype<0, .Bartype, .Fields(._ChartIndex).Bartype)
ENDSCAN
FOR m.lnLine=1 TO RECCOUNT()
GO laStack(m.lnLine,6)
._DrawBar(laStack(m.lnLine,1),laStack(m.lnLine,2),laStack(m.lnLine,3),laStack(m.lnLine,4),laStack(m.lnLine,5), IIF(INLIST(.BarType,3,4),0,m.lnMaxBarHeight),,,laStack(m.lnLine,7))
NEXT
CASE .ChartType = 8 && Multi Bars
LOCAL lnChart, lnOneBarWidth, lnZeroY, lnScaleAdjustment, lnTotRow, laValues(m.lnChartsCount), laBottom(m.lnChartsCount)
m.lnOneBarWidth = m.lnBarWidth / m.lnChartsCount
m.lnZeroY = ._TopOffSet + m.ln3D + (._MaxScale / m.lnMaxValue * m.lnHeight)
IF ._MinScale > 0
m.lnZeroY = m.lnZeroY - (._MinScale / m.lnMaxValue * m.lnHeight)
ENDIF
m.lnScaleAdjustment = ._ScaleAdjust / m.lnMaxValue * m.lnHeight
m.lcAlias=ALIAS()
LOCAL laLastPoint(MAX(1,m.lnChartsCount))
m.laLastPoint=''
STORE 0 TO m.lnValue,m.lnBottomValue, m.lnCount
m.lnLines =RECCOUNT()
SCAN
m.lnLine = RECNO()
m.lnTotRow = 0
* Get the total for the current row
FOR m.lnColumn = 1 TO m.lnChartsCount
m.lnValue = ._GetValue(m.lnColumn, .T.)
laValues(m.lnColumn) = m.lnValue
m.lnTotRow = m.lnTotRow + NVL(m.lnValue, 0)
NEXT
FOR m.lnColumn = 1 TO m.lnChartsCount
m.lnValue = laValues(m.lnColumn)
IF ISNULL(m.lnValue) OR m.lnValue < ._MinScale
LOOP
ENDIF
._ChartIndex = m.lnColumn
m.lnX1 = m.lnLeftMargin + ;
((m.lnBarWidth + m.lnBetween) * (m.lnLine - 1)) + ;
((m.lnColumn-1 ) * m.lnOneBarWidth)
IF m.lnValue < 0
m.lnBarHeight = (m.lnValue / m.lnMaxValue * m.lnHeight)
m.lnY1 = m.lnZeroY
ELSE
m.lnBarHeight = (m.lnValue / m.lnMaxValue * m.lnHeight) + IIF(._ScaleAdjust < 0, m.lnScaleAdjustment, 0)
m.BottomHeight=(m.lnBottomValue / m.lnMaxValue * m.lnHeight)
m.lnY1 = m.lnZeroY - m.lnBarHeight - m.BottomHeight
ENDIF
.ChartSum = m.lnTotRow
m.lnMaxBarHeight=MAX(m.lnMaxBarHeight,m.lnBarHeight)
m.lnCount = m.lnCount+1
LOCAL laStack(lnCount,8)
laStack(m.lnCount,1) = m.lnX1
laStack(m.lnCount,2) = m.lnY1
laStack(m.lnCount,3) = m.lnOneBarWidth
laStack(m.lnCount,4) = m.lnBarHeight
laStack(m.lnCount,5) = m.lnValue
laStack(m.lnCount,6) = m.lnLine
laStack(m.lnCount,7) = m.lnColumn
laStack(m.lnCount,8) = IIF(.Fields(m.lnColumn).Bartype<0, .Bartype, .Fields(m.lnColumn).Bartype)
NEXT
ENDSCAN
m.lcLastPoint=''
FOR m.lnLine=1 TO m.lnCount
GO laStack(m.lnLine,6)
._ChartIndex = laStack(m.lnLine,7)
lnBartype = laStack(m.lnLine,8)
._DrawBar(laStack(m.lnLine,1),laStack(m.lnLine,2),laStack(m.lnLine,3),laStack(m.lnLine,4),laStack(m.lnLine,5), IIF(INLIST(.BarType,3,4),0,m.lnMaxBarHeight),,,lnBartype)
NEXT
._ChartIndex = 1
CASE .ChartType = 9 && Stacked Bars
m.lnZeroY = ._TopOffSet + m.ln3D + (._MaxScale / m.lnMaxValue * m.lnHeight)
m.lnYBase = IIF(._HasNegatives, m.lnZeroY, ._TopOffSet + m.ln3D + m.lnHeight)
m.lnTotalMaxBarHeight = 0
LOCAL laMaxConeHeight(MAX(1,RECCOUNT()))
m.laMaxConeHeight = 0
STORE 0 TO m.lnValue,m.lnBottomValue
FOR .ROW = 1 TO RECCOUNT()
STORE m.lnYBase TO m.lnY1, m.yMinus1
STORE 0 TO m.lnStack, m.lnSumBarHeight
FOR .COLUMN = 1 TO .ChartsCount
._ChartIndex = .COLUMN
m.lnBarType = IIF(.Fields(.Column).Bartype<0, .Bartype, .Fields(.Column).Bartype)
.GetValue()
m.lnNativeValue = .VALUE
m.lnValue = ABS(NVL(m.lnNativeValue,0))
m.lnBarHeight = m.lnValue / m.lnMaxValue * m.lnHeight
IF m.lnBarType # 7
m.laMaxConeHeight(.ROW) = m.laMaxConeHeight(.ROW) + m.lnBarHeight
m.lnSumBarHeight = m.lnSumBarHeight + m.lnBarHeight
ENDIF
IF m.lnNativeValue >=0
LOOP
ENDIF
m.lnX1 = m.lnLeftMargin + ;
((m.lnBarWidth + m.lnBetween) * (.ROW - 1))
m.lnMaxBarHeight=MAX(m.lnMaxBarHeight,m.lnBarHeight)
m.lnStack = m.lnStack +1
LOCAL laStack(m.lnStack,8)
laStack(m.lnStack,1) = m.lnX1
laStack(m.lnStack,2) = m.yMinus1
laStack(m.lnStack,3) = m.lnBarWidth
laStack(m.lnStack,4) = m.lnBarHeight
laStack(m.lnStack,5) = m.lnNativeValue
laStack(m.lnStack,6) = ._ChartIndex
laStack(m.lnStack,7) = m.lnSumBarHeight
laStack(m.lnStack,8) = m.lnBarType
m.yMinus1 = m.yMinus1 + m.lnBarHeight
NEXT
m.lnTotalMaxBarHeight = MAX(m.lnTotalMaxBarHeight, m.lnSumBarHeight)
FOR m.lnLine=m.lnStack TO 1 STEP -1
._ChartIndex = laStack(m.lnLine,6)
._DrawBar(laStack(m.lnLine,1),laStack(m.lnLine,2),laStack(m.lnLine,3),laStack(m.lnLine,4),laStack(m.lnLine,5),m.lnMaxBarHeight,,,laStack(m.lnLine,8))
NEXT
NEXT
LOCAL laLastPoint(MAX(1,m.lnChartsCount))
m.laLastPoint=''
FOR .ROW = 1 TO RECCOUNT()
m.lnY1 = m.lnYBase
m.lnBottomHeight=0
m.lnHorDelta = 0
m.ln3dDelta = 0
m.lnCone3d = ._3D
m.lnMaxRowHeight = m.laMaxConeHeight(.ROW)
FOR .COLUMN = 1 TO .ChartsCount
._ChartIndex = .COLUMN
.GetValue()
m.lnNativeValue = .VALUE
IF m.lnNativeValue <=0
LOOP
ENDIF
m.lnBarType = IIF(.Fields(.Column).Bartype<0, .Bartype, .Fields(.Column).Bartype)
m.lnValue = ABS(NVL(m.lnNativeValue,0))
m.lnBarHeight = m.lnValue / m.lnMaxValue * m.lnHeight
m.lnX1 = m.lnLeftMargin + ((m.lnBarWidth + m.lnBetween) * (.ROW - 1))
m.lnOldCone3D = m.lnCone3d
DO CASE
CASE INLIST(m.lnBarType,3,4)
m.lnY1 = m.lnY1 - m.lnBarHeight
m.lnNewHorDelta = ._DrawBar(m.lnX1 + m.lnHorDelta + m.ln3dDelta, m.lnY1 - m.ln3dDelta, ;
m.lnBarWidth-m.lnHorDelta-m.lnHorDelta, m.lnBarHeight, ;
m.lnValue, m.lnMaxRowHeight-m.lnBottomHeight, @m.lnCone3d,,m.lnBartype)
OTHER
m.lnY1 = m.lnY1 - m.lnBarHeight
m.lnNewHorDelta = ._DrawBar(m.lnX1 + m.lnHorDelta + m.ln3dDelta, m.lnY1 - m.ln3dDelta, ;
m.lnBarWidth-m.lnHorDelta-m.lnHorDelta, m.lnBarHeight, ;
m.lnValue, m.lnTotalMaxBarHeight-m.lnBottomHeight, @m.lnCone3d, m.laMaxConeHeight(.ROW)-m.lnBottomHeight, m.lnBartype)
ENDCASE
m.lnHorDelta = m.lnHorDelta + IIF(VARTYPE(m.lnNewHorDelta) ='N',m.lnNewHorDelta,0)
m.lnBottomHeight = m.lnBottomHeight + IIF(m.lnBarType = 7, 0, m.lnBarHeight)
m.ln3dDelta = m.ln3dDelta + (m.lnOldCone3D - m.lnCone3d) / 2
NEXT
NEXT
._ChartIndex = 1
CASE .ChartType = 11 && 3D Bars
* Calculate the maximum width of the chart
m.lnHeight = m.lnHeight - (m.ln3D * (m.lnChartsCount - 1))
m.lnStack = 0
FOR ._ChartIndex = 1 TO m.lnChartsCount
m.lnAdjust = m.ln3D * (m.lnChartsCount - ._ChartIndex )
SCAN
m.lnValue = ._GetValue(._ChartIndex, .T.)
m.lnX1 = m.lnLeftMargin + m.lnAdjust + ((m.lnBarWidth + m.lnBetween) * (RECNO() - 1))
IF ._ChartIndex = m.lnChartsCount
* Prepare Points
._aPoints(RECNO(),1) = m.lnX1 + (m.lnBarWidth / 2)
ENDIF
IF ISNULL(m.lnValue)
LOOP
ENDIF
m.lnPointHeight = (m.lnValue-._MinScale) / m.lnMaxValue * m.lnHeight
m.lnY1 = ._TopOffSet + (m.lnHeight - m.lnPointHeight) - m.lnAdjust + (m.ln3D * (m.lnChartsCount))
m.lnYBase = .ChartCanvas.HEIGHT - ._XAxisHeight - m.lnAdjust
m.lnBarHeight = m.lnYBase - m.lnY1
m.lnMaxBarHeight = MAX(m.lnMaxBarHeight , m.lnBarHeight)
m.lnStack = m.lnStack + 1
LOCAL laStack(lnStack,8)
laStack(m.lnStack,1) = m.lnX1
laStack(m.lnStack,2) = m.lnY1
laStack(m.lnStack,3) = m.lnBarWidth
laStack(m.lnStack,4) = m.lnBarHeight
laStack(m.lnStack,5) = m.lnValue
laStack(m.lnStack,6) = RECNO()
laStack(m.lnStack,7) = ._ChartIndex
laStack(m.lnStack,8) = IIF(.Fields(._ChartIndex).Bartype<0, .Bartype, .Fields(._ChartIndex).Bartype)
ENDSCAN
NEXT
LOCAL laLastPoint(RECCOUNT())
STORE '' TO m.laLastPoint
FOR m.lnLine=1 TO m.lnStack
GO laStack(m.lnLine,6)
._ChartIndex = laStack(m.lnLine,7)
._ChartIndex = laStack(m.lnLine,7)
._DrawBar(laStack(m.lnLine,1),laStack(m.lnLine,2),laStack(m.lnLine,3),laStack(m.lnLine,4),laStack(m.lnLine,5), IIF(INLIST(.BarType,3,4),0,m.lnMaxBarHeight),,,laStack(m.lnLine,8))
NEXT
CASE .ChartType = 12 && HORIZONTAL Simple Bar
IF m.lnBetween >= m.lnHeight / (._nRecords - 1)
m.lnBarHeight = 1
m.lnBetween = (m.lnHeight - ._nRecords) / (._nRecords - 1)
ENDIF
LOCAL lnZeroX, lnScaleAdjustment, laLastPoint(RECCOUNT())
m.lnZeroX = m.lnLeftMargin + IIF(._ScaleAdjust < 0 , 0, (._ScaleAdjust / m.lnMaxValue * m.lnWidth))
m.lnScaleAdjustment = ._ScaleAdjust / m.lnMaxValue * m.lnWidth
._ChartIndex = .ChartRow
SET ORDER TO REVERT
m.lnStack=0
m.lnMaxBarWidth = 0
SCAN
m.lnValue = ._GetValue(.ChartRow, .T.)
IF ISNULL(m.lnValue) OR m.lnValue < ._MinScale
LOOP
ENDIF
IF m.lnValue < 0
m.lnBarWidth = ABS(m.lnValue / m.lnMaxValue * m.lnWidth)
m.lnX1 = m.lnZeroX - m.lnBarWidth
ELSE
m.lnBarWidth = (m.lnValue / m.lnMaxValue * m.lnWidth) + ;
IIF(._ScaleAdjust < 0, m.lnScaleAdjustment, 0)
m.lnX1 = m.lnZeroX
ENDIF
m.lnY1 = ._TopOffSet + ((m.lnBarHeight + m.lnBetween) * (RECNO() - 1)) + m.ln3D
m.lnStack = m.lnStack +1
LOCAL laStack(m.lnStack,7)
laStack(m.lnStack,1) =m.lnX1
laStack(m.lnStack,2) =m.lnY1
laStack(m.lnStack,3) =m.lnBarWidth
laStack(m.lnStack,4) =m.lnBarHeight
laStack(m.lnStack,5) = m.lnValue
laStack(m.lnStack,6) = RECNO()
m.lnMaxBarWidth = MAX(m.lnMaxBarWidth, m.lnBarWidth)
laStack(m.lnStack,7) = IIF(.Fields(.ChartRow).Bartype<0, .Bartype, .Fields(.ChartRow).Bartype)
ENDSCAN
FOR m.lnLine=1 TO m.lnStack
GO laStack(m.lnLine,6)
lnBartype = laStack(m.lnLine,7)
._DrawBar(laStack(m.lnLine,1),laStack(m.lnLine,2),laStack(m.lnLine,3),laStack(m.lnLine,4),laStack(m.lnLine,5), IIF(INLIST(lnBarType,3,4),0,m.lnMaxBarWidth),,,lnBarType)
NEXT
SET ORDER TO
CASE .ChartType = 13 && HORIZONTAL Multi Bars
IF m.lnBetween >= m.lnHeight / (._nRecords - 1)
m.lnBarHeight = 1
m.lnBetween = (m.lnHeight - ._nRecords) / (._nRecords - 1)
ENDIF
m.lnMaxBarWidth = 0
m.lnBarHeight = (m.lnHeight - (._nRecords - 1) * m.lnBetween) / ._nRecords
LOCAL i, lnOneBarHeight
m.lnOneBarHeight = m.lnBarHeight / m.lnChartsCount
LOCAL lnZeroX, lnScaleAdjustment, lnTotRow, laValues(m.lnChartsCount)
m.lnZeroX = m.lnLeftMargin + IIF(._ScaleAdjust < 0 , 0, (._ScaleAdjust / m.lnMaxValue * m.lnWidth))
m.lnScaleAdjustment = ._ScaleAdjust / m.lnMaxValue * m.lnWidth
LOCAL laLastPoint( RECCOUNT())
m.lnStack = 0
SET ORDER TO REVERT
SCAN
m.lnTotRow = 0
* Get the total for the current row
FOR ._ChartIndex = .ChartsCount TO 1 STEP -1
m.lnValue = ._GetValue(._ChartIndex, .T.)
laValues(._ChartIndex) = m.lnValue
m.lnTotRow = m.lnTotRow + NVL(m.lnValue, 0)
NEXT
FOR ._ChartIndex = .ChartsCount TO 1 STEP -1
m.lnValue = laValues(._ChartIndex)
IF ISNULL(m.lnValue) OR m.lnValue < ._MinScale
LOOP
ENDIF
IF m.lnValue < 0
m.lnBarWidth = ABS(m.lnValue / m.lnMaxValue * m.lnWidth)
m.lnX1 = m.lnZeroX - m.lnBarWidth
ELSE
m.lnBarWidth = (m.lnValue / m.lnMaxValue * m.lnWidth) + ;
IIF(._ScaleAdjust < 0, m.lnScaleAdjustment, 0)
m.lnX1 = m.lnZeroX
ENDIF
m.lnY1 = ._TopOffSet + m.ln3D + ((m.lnBarHeight + m.lnBetween) * (RECNO() - 1)) + ;
((._ChartIndex-1 ) * m.lnOneBarHeight)
.ChartSum = m.lnTotRow
m.lnStack = m.lnStack +1
LOCAL laStack(m.lnStack,8)
laStack(m.lnStack,1) = m.lnX1
laStack(m.lnStack,2) = m.lnY1 + m.lnOneBarHeight/2
laStack(m.lnStack,3) = m.lnBarWidth
laStack(m.lnStack,4) = m.lnOneBarHeight
laStack(m.lnStack,5) = m.lnValue
laStack(m.lnStack,6) = RECNO()
laStack(m.lnStack,7) = ._ChartIndex
laStack(m.lnStack,8) = IIF(.Fields(._ChartIndex).Bartype<0, .Bartype, .Fields(._ChartIndex).Bartype)
m.lnMaxBarWidth = MAX(m.lnMaxBarWidth, m.lnBarWidth)
NEXT
ENDSCAN
FOR m.lnLine=1 TO m.lnStack
GO laStack(m.lnLine,6)
._ChartIndex = laStack(m.lnLine,7)
._DrawBar(laStack(m.lnLine,1),laStack(m.lnLine,2),laStack(m.lnLine,3),laStack(m.lnLine,4),laStack(m.lnLine,5), IIF(INLIST(.BarType,3,4),0,m.lnMaxBarWidth),,,laStack(m.lnLine,8))
NEXT
SET ORDER TO
._ChartIndex = 1
CASE .ChartType = 14 && HORIZONTAL Stacked Bars
IF m.lnBetween >= m.lnHeight / (._nRecords - 1)
m.lnBarHeight = 1
m.lnBetween = (m.lnHeight - ._nRecordss) / (._nRecords - 1)
ENDIF
SET ORDER TO REVERT
m.lnTotalMaxBarWidth = 0
LOCAL laMaxConeWidth(MAX(1,RECCOUNT()))
m.laMaxConeWidth = 0
SCAN
m.lnX1 = m.lnLeftMargin
m.lnStack=0
m.lnSumBarWidth = 0
FOR ._ChartIndex = 1 TO m.lnChartsCount
m.lnValue = ._GetValue(._ChartIndex, .T.)
IF ISNULL(m.lnValue) OR EMPTY(m.lnValue)
LOOP
ENDIF
m.lnBarWidth = ROUND( m.lnValue / m.lnMaxValue * m.lnWidth, 0)
m.laMaxConeWidth(RECNO()) = m.laMaxConeWidth(RECNO()) + m.lnBarWidth
m.lnSumBarWidth = m.lnSumBarWidth + m.lnBarWidth
NEXT
m.lnTotalMaxBarWidth = MAX(m.lnTotalMaxBarWidth, m.lnSumBarWidth)
ENDSCAN
LOCAL lnVertDelta, lnCone3d, ln3dDelta, laLastPoint(RECCOUNT())
SCAN
m.lnYDelta = 0
m.lnX1 = m.lnLeftMargin
STORE 0 TO m.lnVertDelta, m.ln3dDelta, m.lnBottomWidth
m.lnCone3d = ._3D
m.lnMaxRowWidth = m.laMaxConeWidth(RECNO())
m.lnY1 = ._TopOffSet + ((m.lnBarHeight + m.lnBetween) * (RECNO() - 1)) + m.ln3D
FOR ._ChartIndex = .ChartsCount TO 1 STEP -1
m.lnValue = ._GetValue(._ChartIndex, .T.)
IF ISNULL(m.lnValue) OR EMPTY(m.lnValue)
LOOP
ENDIF
m.lnValue = ABS(NVL(m.lnValue,0))
m.lnBarWidth = ROUND(m.lnValue / m.lnMaxValue * m.lnWidth,0)
lnBarType = IIF(.Fields(._ChartIndex).Bartype<0, .Bartype, .Fields(._ChartIndex).Bartype)
m.lnOldCone3D = m.lnCone3d
IF INLIST(.BarType,3,4)
m.lnNewVertDelta = ._DrawBar(m.lnX1 + m.ln3dDelta, m.lnY1 + m.lnVertDelta- m.ln3dDelta, ;
m.lnBarWidth, m.lnBarHeight-m.lnVertDelta*2, ;
m.lnValue, m.lnMaxRowWidth-m.lnBottomWidth, @m.lnCone3d,,m.lnBarType)
m.lnX1 = m.lnX1 + m.lnBarWidth
ELSE
m.lnNewVertDelta = ._DrawBar(m.lnX1 + m.ln3dDelta, m.lnY1 + m.lnVertDelta- m.ln3dDelta , ;
m.lnBarWidth, m.lnBarHeight-m.lnVertDelta*2, ;
m.lnValue, m.lnTotalMaxBarWidth-m.lnBottomWidth, @m.lnCone3d, m.laMaxConeWidth(RECNO()),m.lnBarType)
m.lnX1 = m.lnX1 + m.lnBarWidth
ENDIF
m.lnVertDelta = m.lnVertDelta + IIF(VARTYPE(m.lnNewVertDelta) ='N',m.lnNewVertDelta,0)
m.lnBottomWidth=m.lnBottomWidth+m.lnBarWidth
m.ln3dDelta = m.ln3dDelta + (m.lnOldCone3D - m.lnCone3d) / 2
NEXT
ENDSCAN
SET ORDER TO
._ChartIndex = 1
CASE .ChartType = 15 && HORIZONTAL Full-Stacked Bars
IF m.lnBetween >= m.lnHeight / (._nRecords - 1)
m.lnBarHeight = 1
m.lnBetween = (m.lnHeight - ._nRecords) / (._nRecords - 1)
ENDIF
SET ORDER TO REVERT
LOCAL lnTotRow, laValues(m.lnChartsCount)
STORE 0 TO m.lnTotalMaxBarWidth, m.lnStack
SCAN
m.lnBottomWidth=0
m.lnVertDelta = 0
m.ln3dDelta = 0
m.lnCone3d = ._3D
m.lnTotRow = 0
* Get the total for the current row
FOR ._ChartIndex = .ChartsCount TO 1 STEP -1
m.lnValue = ._GetValue(._ChartIndex, .T.)
laValues(._ChartIndex) = m.lnValue
m.lnTotRow = m.lnTotRow + m.lnValue
NEXT
m.lnSumBarWidth = 0
m.lnX1 = m.lnLeftMargin
m.lnY1 = ._TopOffSet + ((m.lnBarHeight + m.lnBetween) * (RECNO() - 1)) + m.ln3D
FOR ._ChartIndex = .ChartsCount TO 1 STEP -1
m.lnValue = laValues(._ChartIndex)
IF EMPTY(m.lnValue)
LOOP
ENDIF
m.lnBarWidth = m.lnValue / m.lnTotRow * m.lnWidth
m.lnSumBarWidth = m.lnSumBarWidth + m.lnBarWidth
.ChartSum = m.lnTotRow
m.lnStack = m.lnStack +1
LOCAL laStack(m.lnStack,8)
laStack(m.lnStack,1) = m.lnX1
laStack(m.lnStack,2) = m.lnY1
laStack(m.lnStack,3) = m.lnBarWidth
laStack(m.lnStack,4) = m.lnBarHeight
laStack(m.lnStack,5) = m.lnValue
laStack(m.lnStack,6) = ._ChartIndex
laStack(m.lnStack,7) = m.lnSumBarWidth
m.lnOldCone3D = m.lnCone3d
m.lnBarType = IIF(.Fields(._ChartIndex).Bartype<0, .Bartype, .Fields(._ChartIndex).Bartype)
laStack(m.lnStack,8) = m.lnBarType
IF INLIST(.BarType,3,5)
m.lnNewVertDelta = ._DrawBar(m.lnX1 + m.ln3dDelta, m.lnY1 + m.lnVertDelta - m.ln3dDelta, ;
m.lnBarWidth, m.lnBarHeight-m.lnVertDelta*2, ;
m.lnValue, m.lnWidth-m.lnBottomWidth, @m.lnCone3d,,m.lnBarType)
ELSE
m.lnNewVertDelta = ._DrawBar(m.lnX1 + m.ln3dDelta, m.lnY1 + m.lnVertDelta- m.ln3dDelta, ;
m.lnBarWidth, m.lnBarHeight-m.lnVertDelta-m.lnVertDelta, ;
m.lnValue, m.lnWidth-m.lnBottomWidth, @m.lnCone3d, m.lnWidth-m.lnBottomWidth,m.lnBarType)
ENDIF
m.lnX1 = m.lnX1 + m.lnBarWidth
m.lnBottomWidth = m.lnBottomWidth + m.lnBarWidth
m.lnVertDelta = m.lnVertDelta + IIF(VARTYPE(m.lnNewVertDelta) ='N',m.lnNewVertDelta,0)
m.ln3dDelta = m.ln3dDelta + (m.lnOldCone3D - m.lnCone3d) / 2
NEXT
ENDSCAN
SET ORDER TO
._ChartIndex = 1
CASE .ChartType = 3 && Full-Stacked Bars
LOCAL lnTotRow, laValues(m.lnChartsCount)
m.lnYBase = ._TopOffSet + m.ln3D + m.lnHeight
FOR .ROW = 1 TO RECCOUNT()
m.lnY1 = m.lnYBase
m.lnTotRow = 0
* Get the total for the current row
FOR .COLUMN = 1 TO .ChartsCount
._ChartIndex = .COLUMN
.GetValue()
._ChartIndex = .COLUMN
laValues(.COLUMN) = .VALUE
m.lnTotRow = m.lnTotRow + .VALUE
NEXT
m.lnStack=0
m.lnSumBarHeight = 0
FOR .COLUMN = 1 TO .ChartsCount
._ChartIndex = .COLUMN
m.lnValue = laValues(.COLUMN)
IF m.lnValue = 0
LOOP
ENDIF
m.lnBarHeight = m.lnValue / m.lnTotRow * m.lnHeight
m.lnBarType = IIF(.Fields(._ChartIndex).Bartype<0, .Bartype, .Fields(._ChartIndex).Bartype)
m.lnX1 = m.lnLeftMargin + ;
((m.lnBarWidth + m.lnBetween) * (.ROW - 1))
m.lnY1 = m.lnY1 - m.lnBarHeight
.ChartSum = m.lnTotRow
m.lnStack = m.lnStack +1
LOCAL laStack(m.lnStack,6)
laStack(m.lnStack,1) = m.lnX1
laStack(m.lnStack,2) = m.lnY1
laStack(m.lnStack,3) = m.lnBarWidth
laStack(m.lnStack,3) = m.lnBarHeight
laStack(m.lnStack,4) = m.lnValue
laStack(m.lnStack,5) = .COLUMN
laStack(m.lnStack,6) = m.lnBarType
NEXT
m.lnBottomHeight=0
m.lnHorDelta = 0
m.ln3dDelta = 0
m.lnCone3d = ._3D
FOR m.lnLine=1 TO m.lnStack
._ChartIndex = laStack(m.lnLine,5)
.COLUMN = laStack(m.lnLine,5)
m.lnX1 = laStack(m.lnLine,1)
m.lnY1 = laStack(m.lnLine,2)
m.lnBarHeight = laStack(m.lnLine,3)
m.lnOldCone3D = m.lnCone3d
m.lnNewHorDelta = ._DrawBar(m.lnX1 + m.lnHorDelta + m.ln3dDelta, m.lnY1 - m.ln3dDelta, ;
m.lnBarWidth-m.lnHorDelta-m.lnHorDelta, m.lnBarHeight, ;
laStack(m.lnLine,4), m.lnHeight-m.lnBottomHeight, @m.lnCone3d , m.lnHeight - m.lnBottomHeight, laStack(m.lnLine,6))
m.lnHorDelta = m.lnHorDelta + IIF(VARTYPE(m.lnNewHorDelta) ='N',m.lnNewHorDelta,0)
m.lnBottomHeight=m.lnBottomHeight+m.lnBarHeight
m.ln3dDelta = m.ln3dDelta + (m.lnOldCone3D - m.lnCone3d) / 2
NEXT
NEXT
._ChartIndex = 1
CASE .ChartType = 17 && PAIRED HORIZONTAL BARS
LOCAL lnZeroX, lnScaleAdjustment, lnAlign
m.lnZeroX = m.lnLeftMargin + (m.lnWidth / 2)
SET ORDER TO REVERT
* Draw the left side of the chart
m.lnAlign = .ShapeLegend.ALIGNMENT
DO CASE
CASE m.lnAlign = 0 && Left
.ShapeLegend.ALIGNMENT = 1 && Right
CASE m.lnAlign = 1 && Right
.ShapeLegend.ALIGNMENT = 0 && Left
OTHERWISE
ENDCASE
._ChartIndex = 1
LOCAL laMax( RECCOUNT()), llCalcMax, lnRecno
m.lnBarType = IIF(.Fields(._ChartIndex).Bartype<0, .Bartype, .Fields(._ChartIndex).Bartype)
m.llCalcMax = INLIST(lnBarType,5,6) AND m.lnChartsCount > 1
SCAN
m.lnRecno = RECNO()
IF m.llCalcMax
m.lnValue = ._GetValue(2, .T.)
laMax(m.lnRecno) = ABS(m.lnValue / m.lnMaxValue * m.lnWidth)
ENDIF
m.lnValue = ._GetValue(1, .T.)
IF ISNULL(m.lnValue) OR (m.lnValue <= 0)
LOOP
ENDIF
m.lnBarWidth = ABS(m.lnValue / m.lnMaxValue * m.lnWidth)
laMax(m.lnRecno) = ROUND(IIF(m.llCalcMax, MAX(laMax(m.lnRecno),m.lnBarWidth), 0),0)
m.lnX1 = m.lnZeroX - m.lnBarWidth
m.lnY1 = ._TopOffSet + ((m.lnBarHeight + m.lnBetween) * (m.lnRecno - 1)) + m.ln3D
._DrawBar(m.lnX1, m.lnY1, m.lnBarWidth, m.lnBarHeight, m.lnValue, laMax(m.lnRecno),,,m.lnBarType)
ENDSCAN
.ShapeLegend.ALIGNMENT = m.lnAlign && Restore to the original setting
IF m.lnChartsCount > 1
* Draw the right side of the chart
._ChartIndex = 2
SCAN
m.lnRecno = RECNO()
m.lnValue = ._GetValue(2, .T.)
IF ISNULL(m.lnValue) OR (m.lnValue < ._MinScale)
LOOP
ENDIF
m.lnBarWidth = (m.lnValue / m.lnMaxValue * m.lnWidth)
m.lnX1 = m.lnZeroX
m.lnY1 = ._TopOffSet + ((m.lnBarHeight + m.lnBetween) * (m.lnRecno - 1)) + m.ln3D
._DrawBar(m.lnX1, m.lnY1, m.lnBarWidth, m.lnBarHeight, m.lnValue, IIF(m.llCalcMax,laMax(m.lnRecno),.F.),,m.lnBarType)
ENDSCAN
ENDIF
SET ORDER TO
OTHERWISE
ENDCASE
* Draw Legends on X Axis for Vertical charts
IF ._Orientation = 1 && Vertical
IF .BarType > 0
._DrawXAxisLegend(m.ln3D/2)
ELSE
._DrawXAxisLegend()
ENDIF
ENDIF
ENDWITH
ENDPROC
PROCEDURE _drawcomments
LOCAL lcCaption, lcObjectName, lcPolyGon, ;
lnAlignment, lnAlphaChannel, lnBackColor, lnFontSize, lnForeColor, lnGradientLevel, lnLeft, lnLine, lnRotation, lnTextHeight, lnTextWidth, lnTop, ;
loBrush, loColor1, loColor2, loShape,lnCenterX, m.lnCenterY
FOR lnLine=1 TO THIS.CommentsSet.COUNT
* lcObjectName='Shape'+ALLTRIM(STR(THIS.Shapes.OBJECTS.COUNT+1))
* THIS.Shapes.ADDOBJECT(lcObjectName,[Charts.Figure])
* loShape = EVALUATE('this.Shapes.' + lcObjectName)
loLegend = THIS.Comments
WITH THIS.CommentsSet(lnLine)
lnLeft = IIF(BETWEEN(.LEFT,0,1), THIS.ChartCanvas.WIDTH,1) * .LEFT
lnTop = IIF(BETWEEN(.TOP,0,1),THIS.ChartCanvas.HEIGHT,1) * .TOP
lnLeft = IIF(BETWEEN(.LEFT,0,1), THIS.WIDTH,1) * .LEFT
lnTop = IIF(BETWEEN(.TOP,0,1),THIS.HEIGHT,1) * .TOP
loLegend.FONTSIZE = EVL(.FONTSIZE,11)
loLegend.ALIGNMENT = IIF(BETWEEN(.ALIGNMENT,0,2),.ALIGNMENT,2)
loLegend.FORECOLOR = .FORECOLOR
loLegend.BACKCOLOR = .BACKCOLOR
loLegend.FONTNAME = .FONTNAME
loLegend.FONTSIZE = .FONTSIZE
loLegend.FONTBOLD = .FONTBOLD
loLegend.FONTITALIC = .FONTITALIC
loLegend.ForeColorAlpha = .ForeColorAlpha
loLegend.BackColorAlpha = IIF(.TYPE>0,255,.BackColorAlpha)
lnGradientLevel = .GradientLevel
lnRotation = .ROTATION
loLegend.ROTATION=0
loLegend._Setup ()
lcCaption = .CAPTION
IF 'CHR(13)' $ lcCaption
lcCaption = STRTRAN(lcCaption,[CHR(13)], CHR(13)+CHR(10))
ENDIF
loLegend._Value = lcCaption
lnTextHeight = CEILING(loLegend._Height)
lnTextWidth = CEILING(loLegend._Width)
m.lnTextLeft = m.lnLeft
m.lnTextTop = m.lnTop
lnHeight = lnTextHeight
lnWidth = lnTextWidth
lnCenterX = m.lnLeft
lnCenterY = m.lnTop
lcPolyGon = Labels(.TYPE, @lnTextLeft, @lnTextTop, @lnWidth, @lnHeight, @lnCenterX, @lnCenterY, .PointerSide, .PointerSubSide, .PointerWidth )
loBrush = _SCREEN.SYSTEM.Drawing.SolidBrush.New(_SCREEN.SYSTEM.Drawing.COLOR.FromARGB(.BackColorAlpha,.BACKCOLOR))
ENDWITH
loShape = THIS._UpdateCoordinates(,"Comments", m.lnLeft, m.lnTop, m.lnWidth, m.lnHeight)
WITH loShape
lnMargin = 4
.SetDimensions( m.lnLeft, m.lnTop, m.lnTextWidth, m.lnTextHeight)
IF THIS.CommentsSet(lnLine).TYPE>0
.PATH = lcPolyGon
ENDIF
.Contour = _Screen.FoxchartsHelper.SimplifyPath(lcPolyGon)
IF NOT EMPTY(lnRotation)
.Contour = _Screen.FoxchartsHelper.RotatePath(m.lnCenterX, m.lnCenterY, .Contour, lnRotation)
ENDIF
.Front = []
.Legend = lcCaption
.COLOR = lnForeColor
.ChartIndex = lnLine
.DRAW(THIS.oGfx, THIS._oblackpen, loBrush, m.lnCenterX, m.lnCenterY, lnRotation)
THIS.Comments._DrawString(lnTextLeft, m.lnTextTop,lnTextWidth,lnTextHeight)
THIS.oGfx.ResetTransform()
ENDWITH
NEXT
ENDPROC
PROCEDURE _drawcone
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnValue, tn3D
* Yudin Alex
LOCAL lcFile, llConoid, ln, lnA, lnA2, lnAngle, lnB, lnB2, lnCount, lnDelta, lnDet, ;
lnLine, lnMX, lnMY, lnRight, lnTop3D, lnTopHeight, lnTopWidth, lnX, lnY, lnY0, loTopBrush
LOCAL lnBottomY, lnRectY, ln3D, lcPoints, lnAlpha, lnOrigAlpha, lnTopX, lnX0,lnHorDelta, ;
loBottomBrush AS xfcBrush, loPen AS xfcPen, loGfx AS xfcGraphics, ;
loPath AS xfcGraphicsPath
m.loPen = THIS._oBorderPen
m.loGfx = THIS.oGfx
m.lcPoints=''
m.lnY = tnY
lnHorDelta=0
This._PrepareBrushes(m.tnX, m.tnY, m.tnWidth, m.tnHeight, .F., IIF(This.SingleData, RECNO(),This._ChartIndex))
lnOrigAlpha = THIS.AlphaChannel
lnAlpha = MIN(255, (THIS.AlphaChannel * 1.25))
THIS.AlphaChannel = lnAlpha
m.ln3D = MAX(IIF(VARTYPE(tn3D)='N',tn3D,THIS._3d), 1)
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE THIS.BrushType = 1 && SolidColors
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, - 20)))
loBottomBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
CASE THIS.BrushType = 2 && Gradient
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, + 50)))
loBottomBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, + 80)))
CASE THIS.BrushType = 4 && TextureBrush
lcFile = THIS.getTexture()
IF EMPTY(lcFile)
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, - 20)))
loBottomBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
ELSE
loTopBrush = THIS._o3dBrush
loBottomBrush = loTopBrush
ENDIF
OTHERWISE
THIS._PrepareBrushes(tnX, tnY, tnWidth, tnHeight, .F., IIF(THIS.SingleData OR THIS.ChartsCount = 1, RECNO(),THIS._ChartIndex))
loTopBrush = THIS._oMainBrush
loBottomBrush = loTopBrush
ENDCASE
THIS.AlphaChannel = lnOrigAlpha
IF THIS._Orientation = 1 && Vertical
*****************************
* *
* C o n e - Vertical *
* *
*****************************
m.lnRectY = tnY - m.ln3D / 2
m.lnBottomY = tnY + tnHeight - m.ln3D
m.lnX0 = tnX + m.ln3D / 2
* Draw ellipse
m.loGfx.FillEllipse(loBottomBrush, m.lnX0, m.lnBottomY, tnWidth, m.ln3D)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, m.lnX0, m.lnBottomY, tnWidth, m.ln3D)
ENDIF
* Draw the front shape using a GraphicsPath object
* Prepare the Main Path
lnTopX = m.lnX0 + tnWidth/2
loPath = .Drawing2D.GraphicsPath.New()
loPath.StartFigure()
* Bottom arc
lnB2 = m.ln3D*m.ln3D/4
lnA2 = tnWidth * tnWidth/4
lnMY = lnB2 / tnHeight
lnDet = (1-lnMY*lnMY/lnB2) * lnA2
IF lnDet>0
lnMX = SQRT(lnDet)
lnAngle = RTOD(ATAN(lnMY/lnMX))
ELSE
lnAngle=90
lnMX = tnWidth/2
lnMY = 0
ENDIF
loPath.ADDLINE(lnTopX, m.lnRectY, lnTopX, m.lnRectY)
loPath.AddArc(m.lnX0, m.lnBottomY, tnWidth, m.ln3D, -lnAngle, 180+lnAngle+lnAngle)
loPath.ADDLINE(lnTopX, m.lnRectY, lnTopX, m.lnRectY)
loPath.Reverse()
loPath.ADDLINE(lnTopX, m.lnRectY, lnTopX, m.lnRectY)
* Draw the path
THIS.FillPathDim(THIS._oMainBrush, loPath)
m.loGfx.DrawPath(m.loPen, loPath)
IF lnMY = 0
m.loGfx.Drawline(m.loPen,m.lnX0 + tnWidth/2, m.lnRectY, m.lnX0+tnWidth/2-lnMX , m.lnBottomY - m.lnMY + m.ln3D / 2)
ENDIF
TEXT TO lcPoints && I<>d<EFBFBD><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>d<EFBFBD> <20><><EFBFBD> d<><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<<Round(lnTopX,0)>>,<<Round(m.lnRectY,0)>>,<<Round(m.lnX0+tnWidth/2-lnMx,0)>>,<<Round(tnY + tnHeight - ln3d/2 - lnMY ,0)>>,0
<<Round(lnX0,0)>>,<<Round(m.lnBottomY,0)>>,<<Round(tnWidth,0)>>,<<Round(m.ln3D,0)>>,<<-lnAngle>>,<<180+lnAngle+lnAngle>>
<<Round(lnTopX,0)>>,<<Round(m.lnRectY,0)>>,<<Round(m.lnX0+tnWidth/2+m.lnMx,0)>>,<<Round(tnY + tnHeight - ln3d/2 - lnMY,0)>>,0
ENDTEXT
ELSE &&_Orientation = 2
llLeftRight = THIS.Charttype # 17 AND THIS._ChartIndex>1
m.lnTopX = m.tnX + m.tnWidth &&- m.ln3D/2 * IIF(llLeftRight,0,1)
IF THIS.Charttype = 17 AND THIS._ChartIndex=1
m.lnStore=m.lnTopX
m.lnTopX = m.tnX
m.tnX=m.lnStore
ENDIF
m.lnX0 = tnX
m.lnY = tnY - m.ln3D / 2
* Draw the front shape using a GraphicsPath object
* Prepare the Main Path
loPath = .Drawing2D.GraphicsPath.New()
* Ellipse
m.loGfx.FillEllipse(THIS._oMainBrush, tnX, lnY, m.ln3D, tnHeight)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, tnX, lnY, m.ln3D, tnHeight)
ENDIF
loPath.StartFigure()
* Bottom Arc
lnB2 = m.ln3D*m.ln3D/4
lnA2 = tnHeight * tnHeight/4
lnMY = lnB2 / tnWidth
lnDet = (1-lnMY*lnMY/lnB2) * lnA2
IF lnDet>0
lnMX = SQRT(lnDet)
lnAngle = RTOD(ATAN(lnMY/lnMX))
ELSE
lnAngle=90
lnMX = tnHeight/2
lnMY = 0
ENDIF
loPath.AddArc(tnX, lnY, m.ln3D, tnHeight, 90-lnAngle, 180 + lnAngle + lnAngle)
loPath.Reverse()
THIS.FillPathDim(THIS._oMainBrush, loPath)
m.loGfx.DrawPath(m.loPen, loPath)
IF lnMY = 0
m.loGfx.Drawline(m.loPen, m.lnTopX + m.ln3D / 2, lnY + tnHeight/2, tnX + m.ln3D / 2 + lnMY, lnY + tnHeight/2-lnMX )
ENDIF
* Lines
loPath.ADDLINE(tnX + m.ln3D / 2 + lnMY, ROUND(lnY + tnHeight/2+lnMX,0), m.lnTopX + m.ln3D / 2, lnY + tnHeight/2)
loPath.ADDLINE(m.lnTopX + m.ln3D / 2, lnY + tnHeight/2, tnX + m.ln3D / 2 + lnMY, ROUND(lnY + tnHeight/2-lnMX,0))
* Draw the path
THIS.FillPathDim(THIS._oMainBrush, loPath)
m.loGfx.DrawPath(m.loPen, loPath)
IF lnMY = 0
m.loGfx.Drawline(m.loPen, m.lnTopX + m.ln3D / 2, lnY + tnHeight/2, tnX + m.ln3D / 2 + lnMY, lnY + tnHeight/2-lnMX )
ENDIF
TEXT TO lcPoints && define the contour points for the recognition of the cone
<<round(tnX + m.ln3D / 2 + lnMY,0)>>, <<round(lnY + tnHeight/2+lnMX,0)>>, <<round(m.lnTopX + m.ln3D / 2,0)>>, <<round(lnY + tnHeight/2,0)>>
<<round(m.tnX,0)>>,<<round(lnY,0)>>,<<round(m.ln3D,0)>>,<<round(tnHeight,0)>>,<<90-lnAngle>>,<<180 +lnAngle+lnAngle>>
<<round(tnX + m.ln3D / 2 + lnMY,0)>>,<<round(lnY + tnHeight/2-lnMX,0)>>,<<round(m.lnTopX + m.ln3D / 2,0)>>,<<round(lnY + tnHeight/2,0)>>
ENDTEXT
IF THIS.Charttype = 17 AND THIS._ChartIndex=1
m.lnX0=m.lnTopX
ENDIF
ENDIF
loShape = THIS._UpdateCoordinates(,"Rect", m.lnX0 + THIS._3d / 2, m.lnY, m.tnWidth, m.tnHeight, m.tnValue,,lcPoints)
THIS._DrawLegendinBar(m.lnX0, lnY, tnWidth, tnHeight, tnValue)
ENDWITH
RETURN lnHorDelta
ENDPROC
PROCEDURE _drawconoid
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnValue, tn3D, tnMaxBarHeight
* Yudin Alex 16 Apr 2013
LOCAL lcFile, lcTopEllipse,lcTopEllipse1, llConoid, ln, lnA, lnA2, lnAngle, lnB, lnB2, lnCount, lnDelta, lnDet, ;
lnLine, lnMX, lnMY, lnRight, lnTop3D, lnTopHeight, lnTopWidth, lnX, lnY, lnY0, loTopBrush, ;
lnBottomY, lnRectY, ln3D, lcPoints, lnAlpha, lnOrigAlpha, lnTopX, lnX0,lnHorDelta, ;
loBottomBrush AS xfcBrush, loPen AS xfcPen, loGfx AS xfcGraphics, ;
loPath AS xfcGraphicsPath
m.loGfx = THIS.oGfx
STORE '' TO m.lcPoints, lcFront
THIS._PrepareBrushes(m.tnX, m.tnY, m.tnWidth, m.tnHeight, .F., IIF(THIS.SingleData, RECNO(),THIS._ChartIndex))
m.loPen = THIS._oBorderPen
lnHorDelta=0
lnOrigAlpha = THIS.AlphaChannel
lnAlpha = MIN(255, (THIS.AlphaChannel * 1.25))
THIS.AlphaChannel = lnAlpha
m.ln3D = MAX(IIF(VARTYPE(tn3D)='N',tn3D,THIS._3d), 1)
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE THIS.BrushType = 1 && SolidColors
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, - 20)))
loBottomBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
CASE THIS.BrushType = 2 && Gradient
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, + 50)))
loBottomBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, + 80)))
CASE THIS.BrushType = 4 && TextureBrush
lcFile = THIS.getTexture()
IF EMPTY(lcFile)
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, - 20)))
loBottomBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
ELSE
loTopBrush = THIS._o3dBrush
loBottomBrush = loTopBrush
ENDIF
OTHERWISE
THIS._PrepareBrushes(tnX, tnY, tnWidth, tnHeight, .F., IIF(THIS.SingleData OR THIS.ChartsCount = 1, RECNO(),THIS._ChartIndex))
loTopBrush = THIS._oMainBrush
loBottomBrush = loTopBrush
ENDCASE
THIS.AlphaChannel = lnOrigAlpha
IF THIS._Orientation = 1 && Vertical
************************
* Vertical conoid *
************************
LOCAL lnRectY, lnX0, yBotCyl, loPath AS xfcGraphicsPath
lnY = ROUND(tnY,0)
lnB=0
lnTopWidth = (tnMaxBarHeight-tnHeight) / tnMaxBarHeight * tnWidth
lnTop3D = lnTopWidth * m.ln3D/tnWidth
m.lnRectY = tnY - m.ln3D / 2
yBotCyl = tnY + tnHeight - m.ln3D
tnX= ROUND(tnx,0)
lnX0 = ROUND(tnX + m.ln3D / 2,0)
* Bottom ellipse
m.loGfx.FillEllipse(loBottomBrush, lnX0, yBotCyl, tnWidth, m.ln3D)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, lnX0, yBotCyl, tnWidth, m.ln3D)
ENDIF
loPath = .Drawing2D.GraphicsPath.New()
loPath.StartFigure()
* Bottom arc
lnB2 = m.ln3D*m.ln3D/4
lnA2 = tnWidth * tnWidth/4
lnMY = lnB2 / tnMaxBarHeight
lnDet = (1-lnMY*lnMY/lnB2) * lnA2
IF lnDet>0
lnMX = SQRT(lnDet)
lnAngle = RTOD(ATAN(lnMY/lnMX))
ELSE
lnAngle=90
lnMX = tnWidth/2
lnMY = 0
ENDIF
lnCenterX = lnX0 + tnWidth/2
IF m.ln3D<3
loPath.ADDLINE(m.lnX0+tnWidth, tnY + tnHeight-ln3D/2,m.lnX0, tnY + tnHeight-ln3D/2)
ELSE
loPath.AddArc(m.lnX0, yBotCyl, tnWidth, m.ln3D, 360-lnAngle, 180+lnAngle+lnAngle)
loPath.Reverse()
ENDIF
loPath.AddArc(ROUND(lnX0 + tnWidth/2 - lnTopWidth/2,0), ROUND(m.lnRectY - m.lnTop3D/2,0), ROUND(lnTopWidth,0), ROUND(m.lnTop3D,0), MOD(360-lnAngle,360), MOD(180+lnAngle*2,360))
loPath.Reverse()
TEXT TO lcPoints
<<round(m.lnX0,0)>>,<<round(yBotCyl,0)>>,<<round(tnWidth,0)>>,<<round(m.ln3D,0)>>,<<360-lnAngle>>,<<180+lnAngle*2>>
ENDTEXT
loPath.AddArc(m.lnX0, yBotCyl, tnWidth, m.ln3D, 180+lnAngle,0.01) && A <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>_ <20><><EFBFBD><EFBFBD><EFBFBD>
THIS.FillPathDim(THIS._oMainBrush, loPath)
* Top ellipse
IF m.lnTop3D<3
loPath.ADDLINE(m.lnX0, tnY + tnHeight-ln3D/2,m.lnCenterX-lnTopWidth/2, tnY-ln3D/2)
loPath.ADDLINE(m.lnCenterX+lnTopWidth/2, tnY-ln3D/2,m.lnCenterX-lnTopWidth/2, tnY-ln3D/2)
loPath.ADDLINE(m.lnCenterX+lnTopWidth/2, tnY-ln3D/2,m.lnX0+tnWidth, tnY + tnHeight-ln3D/2)
THIS.FillPathDim(THIS._oMainBrush, loPath)
TEXT TO lcTopEllipse
<<round(m.lnCenterX-lnTopWidth/2,0)>>,<<round(tnY-ln3D/2,0)>>,<<round(m.lnCenterX+lnTopWidth/2,0)>>,<<round(tnY-ln3D/2,0)>>
ENDTEXT
lcTopEllipse1=lcTopEllipse
ENDIF
* Draw the path
m.loGfx.DrawPath(m.loPen, loPath)
IF NOT m.lnTop3D<3
m.loGfx.FillEllipse(loTopBrush, lnX0+tnWidth/2-lnTopWidth/2, m.lnRectY - m.lnTop3D/2, lnTopWidth, m.lnTop3D)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, lnX0+tnWidth/2-lnTopWidth/2, m.lnRectY - m.lnTop3D/2, lnTopWidth, m.lnTop3D)
ENDIF
m.loGfx.DrawEllipse(m.loPen , lnX0+tnWidth/2-lnTopWidth/2, m.lnRectY - m.lnTop3D/2, lnTopWidth, m.lnTop3D)
TEXT TO lcTopEllipse
<<round(lnX0 + tnWidth/2 - lnTopWidth/2,0)>>,<<round(m.lnRectY - m.lnTop3D/2,0)>>,<<round(lnTopWidth,0)>>,<<round(m.lnTop3D,0)>>,180,180,1
ENDTEXT
TEXT TO lcTopEllipse1
<<round(lnX0 + tnWidth/2 - lnTopWidth/2,0)>>,<<round(m.lnRectY - m.lnTop3D/2,0)>>,<<round(lnTopWidth,0)>>,<<round(m.lnTop3D,0)>>,180,-180,1
ENDTEXT
ENDIF
lnHorDelta = (tnWidth - lnTopWidth) / 2
TEXT TO lcFront
<<lcPoints>>
<<round(lnX0+tnWidth/2 - lnTopWidth/2,0)>>,<<round(m.lnRectY,0)>>,<<round(lnX0 + tnWidth/2-lnMX,0)>>,<<round(lnRectY + tnHeight - m.lnMY,0)>>,0
<<lcTopEllipse1>>
<<round(lnX0+tnWidth/2 + lnMx,0)>>,<<round(lnRectY + tnHeight - m.lnMY,0)>>,<<round(lnX0+tnWidth/2+lnTopWidth/2,0)>>,<<round(m.lnRectY,0)>>,0
ENDTEXT
TEXT TO lcPoints ADDITIVE
<<round(lnX0+tnWidth/2 - lnTopWidth/2,0)>>,<<round(m.lnRectY,0)>>,<<round(lnX0 + tnWidth/2-lnMX,0)>>,<<round(lnRectY + tnHeight - m.lnMY,0)>>,0
<<lcTopEllipse>>
<<round(lnX0+tnWidth/2 + lnMx,0)>>,<<round(lnRectY + tnHeight - m.lnMY,0)>>,<<round(lnX0+tnWidth/2+lnTopWidth/2,0)>>,<<round(m.lnRectY,0)>>,0
ENDTEXT
ELSE &&_Orientation = 2
*****************************************
* *
* C o n o i d *
* Horizontal *
* *
*****************************************
m.lnY = tnY - m.ln3D / 2
m.lnTopX = tnX + tnWidth && - m.ln3D / 2
m.lnX0 = tnX
IF THIS.Charttype = 17 AND THIS._ChartIndex=1
m.lnStore=m.lnTopX
m.lnTopX = m.tnX
m.tnX=m.lnStore
ENDIF
lnTopHeight = (tnMaxBarHeight-tnWidth) / tnMaxBarHeight * tnHeight
lnTop3D = lnTopHeight * m.ln3D/tnHeight
m.lnRectY = lnY &&- m.ln3D / 2
yBotCyl = lnY + tnHeight && - m.ln3D
lnX0 = tnX + m.ln3D / 2
loPath = .Drawing2D.GraphicsPath.New()
m.loGfx.DrawEllipse(m.loPen , tnX, lnY, m.ln3D, tnHeight)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, tnX, lnY, m.ln3D, tnHeight)
ENDIF
lnHorDelta = (tnHeight - lnTopHeight) /2
IF VARTYPE(tn3D)='N'
tn3D = m.lnTop3D
ENDIF
loPath.StartFigure()
*
* Left arc of the ellipse
*
lnB2 = m.ln3D * m.ln3D / 4
lnA2 = tnHeight * tnHeight / 4
lnMY = lnB2 / tnMaxBarHeight
lnDet = (1-lnMY*lnMY/lnB2) * lnA2
IF lnDet>=0
lnMX = SQRT(lnDet)
lnAngle = RTOD(ATAN(lnMY/lnMX))
ELSE
lnAngle=90
lnMX = tnHeight/2
lnMY = 0
ENDIF
loPath.StartFigure()
loPath.AddArc(tnX, lnY, m.ln3D, tnHeight, 90-lnAngle, 180 + lnAngle + lnAngle)
* loPath.Reverse()
* Left arc of the ellipse
IF m.ln3D<3
TEXT TO lcLeftEllipsePoint
<<round(m.lnX0,0)>>,<<round(tnY + tnHeight,0)>>,<<Round(m.lnX0,0)>>,<<Round(tnY ,0)>>
ENDTEXT
ELSE
TEXT TO lcLeftEllipsePoint
<<round(m.tnX,0)>>,<<round(lnY,0)>>,<<round(m.ln3D,0)>>,<<round(tnHeight,0)>>,<<90-lnAngle>>,<<180 +lnAngle+lnAngle>>
ENDTEXT
ENDIF
IF m.lnTop3D<3
lnX = m.lnTopX+ m.ln3D / 2 - lnTop3D/2
loPath.ADDLINE(lnX, lnY + tnHeight/2 - lnTopHeight/2, ;
lnX, lnY + tnHeight/2 + lnTopHeight/2)
STORE 0 TO lnMx2, lnMy2
TEXT TO lcPoints && Define the contour points for the recognition of the cone
<<round(m.lnX,0)>>,<<round(lnY + tnHeight/2 - lnTopHeight/2,0)>>,<<Round(m.lnX,0)>>,<<Round(lnY + tnHeight/2 + lnTopHeight/2,0)>>
<<round(tnX + m.ln3D/2 + m.lnMY ,0)>>,<<round(lnY+m.tnHeight/2 + lnmX,0 )>>,<<round(m.lnTopX + m.ln3D/2 - m.lnMy2,0)>>,<<round(lnY+m.tnHeight/2 + lnMx2,0)>>,0
<<lcLeftEllipsePoint>>
<<round(tnX + m.ln3D/2 + m.lnMY ,0)>>,<<round(lnY+m.tnHeight/2 - lnmX,0 )>>,<<round(lnX,0)>>,<<round(lnY + tnHeight/2 - lnTopHeight/2,0)>>
ENDTEXT
lcFront = lcPoints
ENDIF
* Draw the path
m.loGfx.DrawPath(m.loPen, loPath)
IF NOT m.lnTop3D<3 && Not small
lnB2 = m.lnTop3D * m.lnTop3D /4
lnA2 = lnTopHeight * lnTopHeight / 4
lnMy2 = lnB2 / (tnMaxBarHeight-tnWidth)
lnDet = (1-lnMy2*lnMy2/lnB2) * lnA2
IF lnDet>=0
lnMx2 = SQRT(lnDet)
ELSE
lnMx2 = tnHeight/2
lnMy2 = 0
ENDIF
loPath.AddArc(m.lnTopX+ m.ln3D / 2 - lnTop3D/2 , lnY + tnHeight/2 - lnTopHeight/2 , lnTop3D, lnTopHeight, 270+lnAngle,180 - lnAngle * 2)
loPath.AddArc(tnX, lnY, m.ln3D, tnHeight, 90 - lnAngle,0.001)
TEXT TO lcPoints && Define the contour points for the recognition of the cone
<<round(m.lnTopX+ m.ln3D / 2 - lnTop3D/2,0)>>,<<round(lnY + tnHeight/2 - lnTopHeight/2,0)>>,<<Round(lnTop3D,0)>>,<<Round(m.lnTopHeight,0)>>,<<270+lnAngle>>,<<180-lnAngle*2>>,1
<<round(tnX + m.ln3D/2 + m.lnMY ,0)>>,<<round(lnY+m.tnHeight/2 + lnmX,0 )>>,<<round(m.lnTopX + m.ln3D/2 - m.lnMy2,0)>>,<<round(lnY+m.tnHeight/2 + lnMx2,0)>>,0
<<lcLeftEllipsePoint>>
<<round(tnX + m.ln3D/2 + m.lnMY ,0)>>,<<round(lnY+m.tnHeight/2 - lnmX,0 )>>,<<round(m.lnTopX + m.ln3D/2 + m.lnMy2,0)>>,<<round(lnY+m.tnHeight/2 - lnMX2,0)>>
ENDTEXT
TEXT TO lcFront && points of the front surface
<<round(m.lnTopX+ m.ln3D / 2 - lnTop3D/2,0)>>,<<round(lnY + tnHeight/2 - lnTopHeight/2,0)>>,<<Round(lnTop3D,0)>>,<<Round(m.lnTopHeight,0)>>,<<270+lnAngle>>,<<-180+lnAngle*2>>,0
<<round(tnX + m.ln3D/2 + m.lnMY ,0)>>,<<round(lnY+m.tnHeight/2 + lnmX,0 )>>,<<round(m.lnTopX + m.ln3D/2 - m.lnMy2,0)>>,<<round(lnY+m.tnHeight/2 + lnMx2,0)>>,0
<<lcLeftEllipsePoint>>
<<round(tnX + m.ln3D/2 + m.lnMY ,0)>>,<<round(lnY+m.tnHeight/2 - lnmX,0 )>>,<<round(m.lnTopX + m.ln3D/2 + m.lnMy2,0)>>,<<round(lnY+m.tnHeight/2 - lnMX2,0)>>
ENDTEXT
ENDIF
THIS.FillPathDim(THIS._oMainBrush, loPath)
m.loGfx.DrawPath(m.loPen, loPath)
IF lnMY = 0
* m.loGfx.Drawline(m.loPen, m.lnTopX + m.ln3D / 2, lnY + tnHeight/2, tnX + m.ln3D / 2 + lnMY, lnY + tnHeight/2-lnMX )
ENDIF
* Right ellipse
* m.loGfx.FillEllipse(THIS._o3dBrush, m.lnTopX+ m.ln3D / 2 - lnTop3D/2 , lnY + tnHeight/2 - lnTopHeight/2 , lnTop3D, lnTopHeight)
m.loGfx.DrawEllipse(m.loPen , m.lnTopX+ m.ln3D / 2 - lnTop3D/2 , lnY + tnHeight/2 - lnTopHeight/2 , lnTop3D, lnTopHeight)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, m.lnTopX+ m.ln3D / 2 - lnTop3D/2 , lnY + tnHeight/2 - lnTopHeight/2 , lnTop3D, lnTopHeight)
ENDIF
IF THIS.Charttype = 17 AND THIS._ChartIndex=1
m.lnX0 = m.lnTopX
ENDIF
ENDIF
IF VARTYPE(tn3D)='N'
tn3D = m.lnTop3D
ENDIF
loShape = THIS._UpdateCoordinates(,"Rect", m.lnX0 + THIS._3d / 2, m.lnY, m.tnWidth, m.tnHeight, m.tnValue,,lcPoints,,lcFront)
THIS._DrawLegendinBar(m.lnX0, lnY, tnWidth, tnHeight, tnValue)
ENDWITH
RETURN lnHorDelta
ENDPROC
PROCEDURE _drawcylinder
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnValue, tn3D
LOCAL lcFile, ln, lnY, lcPoints, lnA, lnA2, lnB, lnB2, lnCount, lnDelta, lnLine, lnX ;
,lnAlpha, lnOrigAlpha, loTopBrush AS xfcBrush, loBotBrush AS xfcBrush ;
,loPen AS xfcPen, loGfx AS xfcGraphics
This._PrepareBrushes(m.tnX, m.tnY, m.tnWidth, m.tnHeight, .F., IIF(This.SingleData, RECNO(),This._ChartIndex))
m.loPen = THIS._oBorderPen
m.loGfx = THIS.oGfx
lnOrigAlpha = THIS.AlphaChannel
lnAlpha = MIN(255, (THIS.AlphaChannel * 1.25))
THIS.AlphaChannel = lnAlpha
m.ln3D = MAX(IIF(VARTYPE(tn3D)='N',tn3D,THIS._3d), 1)
lnY = tnY
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE THIS.BrushType = 1 && SolidColors
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, - 20)))
loBotBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
CASE THIS.BrushType = 2 && Gradient
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, + 50)))
loBotBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, + 80)))
CASE THIS.BrushType = 4 && TextureBrush
lcFile = THIS.getTexture()
IF EMPTY(lcFile)
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, - 20)))
loBotBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
ELSE
loTopBrush = THIS._o3dBrush
loBotBrush = loTopBrush
ENDIF
OTHERWISE
THIS._PrepareBrushes(tnX, tnY, tnWidth, tnHeight, .F., IIF(THIS.SingleData OR THIS.ChartsCount = 1, RECNO(),THIS._ChartIndex))
loTopBrush = THIS._oMainBrush
loBotBrush = loTopBrush
ENDCASE
THIS.AlphaChannel = lnOrigAlpha
IF THIS._Orientation = 1 && Vertical
LOCAL lnRectY, lnX0, yTopCyl, yBotCyl
lnRectY = tnY - (m.ln3D / 2)
yTopCyl = tnY - m.ln3D
yBotCyl = tnY + tnHeight - m.ln3D
lnX0 = tnX + m.ln3D / 2
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m.loGfx.FillEllipse(loBotBrush, lnX0, yBotCyl, tnWidth, m.ln3D)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, lnX0, yBotCyl, tnWidth, m.ln3D)
ENDIF
* Draw the front shape using a GraphicsPath object
* Prepare the Main Path
LOCAL loPath AS xfcGraphicsPath
loPath = .Drawing2D.GraphicsPath.New()
loPath.FillMode = .Drawing2D.FillMode.ALTERNATE
loPath.StartFigure()
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
loPath.AddArc(lnX0, yBotCyl, tnWidth, m.ln3D, 180, -180)
* loPath.Reverse()
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
loPath.ADDLINE(lnX0 + tnWidth, lnRectY + tnHeight, lnX0 + tnWidth, lnRectY)
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
loPath.AddArc(lnX0, yTopCyl, tnWidth, m.ln3D, 0, 180)
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
THIS.FillPathDim(THIS._oMainBrush, loPath)
m.loGfx.DrawPath(m.loPen, loPath)
loPath = .Drawing2D.GraphicsPath.New()
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
loPath.StartFigure()
loPath.AddEllipse(lnX0, yTopCyl, tnWidth, m.ln3D)
loTopBrush=_Screen.FoxChartsHelper.PathGradient( , m.loPath, THIS._nColor,-1, lnX0+tnWidth/2, yTopCyl+m.ln3D/2)
m.loGfx.FillEllipse(loTopBrush, lnX0, yTopCyl, tnWidth, m.ln3D)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, lnX0, yTopCyl, tnWidth, m.ln3D)
ENDIF
m.loGfx.DrawEllipse(m.loPen , lnX0, yTopCyl, tnWidth, m.ln3D)
*
* <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
TEXT TO lcPoints
<<ROUND(lnX0,0)>>,<<ROUND(yBotCyl,0)>>,<<ROUND(tnWidth,0)>>,<<ROUND(m.ln3D,0)>>,0, 180
<<ROUND(lnX0,0)>>,<<ROUND(lnRectY + tnHeight,0)>>,<<ROUND(lnX0,0)>>,<<ROUND(lnRectY,0)>>
<<ROUND(lnX0,0)>>,<<ROUND(yTopCyl,0)>>,<<ROUND(tnWidth,0)>>,<<ROUND(m.ln3D,0)>>,-180,180,1
<<ROUND(m.lnX0+tnWidth,0)>>,<<ROUND(lnRectY,0)>>,<<ROUND(m.lnX0+tnWidth,0)>>,<<ROUND(lnRectY + tnHeight,0)>>
ENDTEXT
ELSE &&_Orientation = 2 - Horizontal
***************************************
* *
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> *
* *
***************************************
LOCAL xRect
xRect = tnX - m.ln3D / 2
xTopCyl = tnX + tnWidth &&- m.ln3D / 2
xBotCyl = tnX - m.ln3D
lnY = tnY - m.ln3D / 2
* Draw the left-most ellipse
m.loGfx.FillEllipse(loBotBrush , tnX, lnY, m.ln3D, tnHeight)
m.loGfx.FillEllipse(THIS._oMainBrush, tnX, lnY, m.ln3D, tnHeight)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, tnX, lnY, m.ln3D, tnHeight)
m.loGfx.FillEllipse(THIS._oDimBrush, tnX, lnY, m.ln3D, tnHeight)
ENDIF
* Draw the front shape using a GraphicsPath object
* Prepare the Main Path
LOCAL loPath AS xfcGraphicsPath
loPath = .Drawing2D.GraphicsPath.New()
loPath.StartFigure()
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
loPath.AddArc(tnX, lnY, m.ln3D, tnHeight, 90, 180)
loPath.Reverse()
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
loPath.ADDLINE(tnX + m.ln3D / 2, lnY + tnHeight, xTopCyl + m.ln3D / 2, lnY + tnHeight)
* Top Arc
loPath.AddArc(xTopCyl, lnY, m.ln3D, tnHeight, 90, 180)
* Top Line
loPath.ADDLINE(xTopCyl + m.ln3D / 2, lnY, tnX + m.ln3D / 2, lnY)
* Draw the path
THIS.FillPathDim(THIS._oMainBrush, loPath)
m.loGfx.DrawPath(m.loPen, loPath)
* Draw the upper ellipse
m.loGfx.FillEllipse(loTopBrush, xTopCyl, lnY, m.ln3D, tnHeight)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillEllipse(THIS._oDimBrush, xTopCyl, lnY, m.ln3D, tnHeight)
ENDIF
m.loGfx.DrawEllipse(m.loPen, xTopCyl, lnY, m.ln3D, tnHeight)
*
* <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
TEXT TO lcPoints
<<Round(tnX + m.ln3D / 2,0)>>,<<Round(lnY + tnHeight,0)>>,<<Round(xTopCyl + m.ln3D / 2,0)>>,<<Round(lnY + tnHeight,0)>>
<<Round(tnX,0)>>,<<Round(lnY,0)>>,<<Round(m.ln3D,0)>>,<<Round(tnHeight,0)>>, 90, 180
<<Round(tnX + m.ln3D / 2,0)>>,<<Round(lnY,0)>>,<<Round(xTopCyl + m.ln3D / 2,0)>>,<<Round(lnY,0)>>
<<Round(xTopCyl,0)>>,<<Round(lnY,0)>>,<<Round(m.ln3D,0)>>,<<Round(tnHeight,0)>>, 270,180,1
ENDTEXT
ENDIF
loShape = THIS._UpdateCoordinates(,"Rect", m.tnX + THIS._3d / 2, m.lnY, m.tnWidth, m.tnHeight, m.tnValue,,lcPoints)
THIS._DrawLegendinBar(tnX, lnY, tnWidth, tnHeight, tnValue,,loShape)
ENDWITH
ENDPROC
PROCEDURE _drawdoughnutslice
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnStart, tnSweep, tnValue, toShape
IF tnWidth <=0 OR tnHeight <=0
RETURN
ENDIF
WITH THIS
._AdjustStartSweep(@tnStart, @tnSweep, tnWidth, tnHeight)
toShape = THIS._UpdateCoordinates(toShape,"Pie", tnX, tnY, tnWidth, tnHeight, tnValue, tnStart, tnSweep)
LOCAL lnXBrush, lnYBrush
IF THIS.PieEnhancedDrawing
lnXBrush = tnX
lnYBrush = tnY
ELSE
lnXBrush = 0
lnYBrush = 0
ENDIF
THIS._PrepareBrushes(lnXBrush, lnYBrush, m.tnWidth, m.tnHeight, .F., RECNO())
LOCAL loPen AS xfcPen, loGfx AS xfcGraphics, loMainBrush AS xfcBrush, lo3dBrush AS xfcBrush, ln3d, lnFinalAngle
m.loPen = THIS._oBorderPen
m.loGfx = THIS.oGfx
m.loMainBrush = THIS._oMainBrush
lo3dBrush = THIS._o3DBrush
m.ln3d = THIS._3D
lnFinalAngle = tnStart + tnSweep
IF lnFinalAngle > 360
lnFinalAngle = lnFinalAngle - 360
ENDIF
ENDWITH
IF THIS.PieEnhancedDrawing && New behavior for Doughnuts
&& Drawing all edges using the GraphicsPath class
WITH _SCREEN.SYSTEM.Drawing
* Create a GraphicsPath object.
LOCAL loMainPath AS xfcGraphicsPath
loMainPath = .Drawing2D.GraphicsPath.New()
LOCAL loRect AS xfcRectangle, loRect2 AS xfcRectangle, lnRatio
lnRatio = THIS.DonutRatio
loRect = .Rectangle.New(tnX, tnY, tnWidth, tnHeight)
loRect2 = .Rectangle.New(;
tnX + (tnWidth * (1 - lnRatio) / 2), ;
tnY + (tnHeight * (1 - lnRatio) / 2), ;
tnWidth * lnRatio, ;
tnHeight * lnRatio)
LOCAL lnXInt, lnYInt, lnHInt, lnWInt
lnXInt = loRect2.X
lnYInt = loRect2.Y
lnWInt = loRect2.WIDTH
lnHInt = loRect2.HEIGHT
LOCAL loPoint0 AS xfcPointF, loPoint1 AS xfcPointF, loPoint2 AS xfcPointF, loPoint3 AS xfcPointF, loPath AS xfcGraphicsPath
* Obtaining the needed points
loMainPath.AddArc(loRect, tnStart, 0.0001)
loPoint0 = loMainPath.GetLastPoint()
loMainPath.AddArc(loRect2, tnStart, 0.0001)
loPoint3 = loMainPath.GetLastPoint()
loMainPath.AddArc(loRect, tnStart, tnSweep)
loPoint1 = loMainPath.GetLastPoint()
loMainPath.AddArc(loRect2, tnStart, tnSweep)
loPoint2 = loMainPath.GetLastPoint()
loPoint4 = .POINT.New(loPoint3.X, loPoint3.Y + m.ln3d)
loPoint5 = .POINT.New(loPoint0.X, loPoint0.Y + m.ln3d)
loPoint6 = .POINT.New(loPoint1.X, loPoint1.Y + m.ln3d)
* Prepare the Main Path
loPath = .Drawing2D.GraphicsPath.New()
loPath.StartFigure()
loPath.AddArc(loRect2, tnStart, tnSweep)
loPath.Reverse()
loPath.ADDLINE(loPoint3.X, loPoint3.Y, loPoint0.X, loPoint0.Y)
loPath.AddArc(loRect, tnStart, tnSweep)
loPath.ADDLINE(loPoint1.X, loPoint1.Y, loPoint2.X, loPoint2.Y)
IF ln3d = 0 OR THIS.SHADOW
* Draw shadow
IF THIS.SHADOW
* Prepare the Shadow Path
LOCAL loPath2 AS xfcGraphicsPath
loPath2 = .Drawing2D.GraphicsPath.New()
loPath2.StartFigure()
loPath2.AddArc(loRect2.X, loRect2.Y + ln3d, loRect2.WIDTH, loRect2.HEIGHT, tnStart, tnSweep)
loPath2.Reverse()
loPath2.ADDLINE(loPoint3.X, loPoint3.Y + ln3d, loPoint0.X, loPoint0.Y + ln3d)
loPath2.AddArc(loRect.X, loRect.Y + ln3d, loRect.WIDTH, loRect.HEIGHT, tnStart, tnSweep)
loPath2.ADDLINE(loPoint1.X, loPoint1.Y + ln3d, loPoint2.X, loPoint2.Y + ln3d)
* Prepare the shadow brush
LOCAL loShadowBrush AS xfcSolidBrush
m.loShadowBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel,128,128,128))
* Draw the shadow
THIS.FillPathDim(loShadowBrush, loPath2)
ENDIF
* Draw the Main doughnut slice (path)
THIS.FillPathDim(m.loMainBrush, loPath)
m.loGfx.DrawPath(m.loPen, loPath)
RETURN
ENDIF
* Continue Drawing, for 3D chart
* Prepare the polygon points for the final part of the slice
DIMENSION laEndPoints(4)
laEndPoints(1) = loPoint1
laEndPoints(2) = loPoint2
laEndPoints(3) = .POINT.New(loPoint2.X, loPoint2.Y + m.ln3d)
laEndPoints(4) = loPoint6
* Prepare the polygon points for the beginning part of the slice
DIMENSION laStartPoints(4)
laStartPoints(1) = loPoint0
laStartPoints(2) = loPoint5
laStartPoints(3) = loPoint4
laStartPoints(4) = loPoint3
* If the slice ends in the left side, draw the Ending polygon before the top face of the slice
IF BETWEEN(lnFinalAngle, 90.001, 269.999)
m.loGfx.DrawPolygon(m.loPen, @laEndPoints)
m.loGfx.FillPolygon(lo3dBrush, @laEndPoints)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillPolygon(THIS._oDimBrush, @laEndPoints)
ENDIF
ENDIF
IF NOT (tnStart >= 90 AND tnStart <= 270)
m.loGfx.DrawPolygon(m.loPen, @laStartPoints)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillPolygon(THIS._oDimBrush, @laStartPoints)
ENDIF
ENDIF
* Draw the external and internal paths
LOCAL lnFinalAngle
lnFinalAngle = tnStart + tnSweep
IF lnFinalAngle > 360
lnFinalAngle = lnFinalAngle - 360
ENDIF
LOCAL lnAdjStart, lnAdjSweep
lnAdjStart = tnStart
lnAdjSweep = tnSweep
LOCAL loAdjPoint0 AS xfcPoint, loAdjPoint1 AS xfcPoint
loAdjPoint0 = loPoint0
loAdjPoint1 = loPoint1
LOCAL loAdjPoint2 AS xfcPoint, loAdjPoint3 AS xfcPoint
loAdjPoint2 = loPoint3
loAdjPoint3 = loPoint2
IF tnStart >= 270 AND ;
tnStart < 360 AND ;
BETWEEN(lnFinalAngle, 0, 270)
LOCAL loTempPoint AS xfcPoint
loTempPoint = .POINT.New(tnX + tnWidth, tnY + tnHeight / 2)
LOCAL loTempPoint2 AS xfcPoint
loTempPoint2 = .POINT.New(lnXInt + lnWInt, lnYInt + lnHInt / 2)
* External part
THIS._DrawSliceExternal(tnX, tnY, tnWidth, tnHeight, tnStart, 360 - tnStart, loPoint0, loTempPoint)
* Internal part
THIS._DrawSliceExternal(lnXInt, lnYInt, lnWInt, lnHInt, tnStart, 360 - tnStart, loPoint3, loTempPoint2)
lnAdjStart = 0
lnAdjSweep = tnSweep - (360 - tnStart)
loAdjPoint0 = loTempPoint
loAdjPoint1 = loPoint1
* Internal
loAdjPoint2 = loTempPoint2
loAdjPoint3 = loPoint2
ENDIF
LOCAL llDrawExtAtEnd
llDrawExtAtEnd = .F.
IF (tnStart < 180 AND lnFinalAngle > 180) OR ;
(tnStart >= 270 AND lnFinalAngle > 180 AND lnFinalAngle < 270.01)
IF tnStart >= 270
lnAdjStart = 0
lnAdjSweep = 180
ELSE
lnAdjStart = tnStart
lnAdjSweep = 180 - tnStart
ENDIF
loAdjPoint1 = .POINT.New(tnX, tnY + tnHeight / 2)
loAdjPoint3 = .POINT.New(lnXInt, lnYInt + lnHInt / 2)
* External part
llDrawExtAtEnd = .T.
LOCAL lnStartB, lnSweepB, loPoint0B, loPoint1B
lnStartB = lnAdjStart
lnSweepB = lnAdjSweep
loPoint0B = loAdjPoint0
loPoint1B = loAdjPoint1
* Internal part
THIS._DrawSliceExternal(lnXInt, lnYInt, lnWInt, lnHInt, lnAdjStart, lnAdjSweep, loAdjPoint2, loAdjPoint3)
loAdjPoint0 = loAdjPoint1
loAdjPoint2 = loAdjPoint3
lnAdjStart = 180
lnAdjSweep = lnFinalAngle - 180
ENDIF
IF BETWEEN(lnFinalAngle, 0,180)
* Internal part
THIS._DrawSliceExternal(lnXInt, lnYInt, lnWInt, lnHInt, lnAdjStart, lnAdjSweep, loAdjPoint2, loPoint2)
* External part
THIS._DrawSliceExternal(tnX, tnY, tnWidth, tnHeight, lnAdjStart, lnAdjSweep, loAdjPoint0, loPoint1)
ELSE
* External part
THIS._DrawSliceExternal(tnX, tnY, tnWidth, tnHeight, lnAdjStart, lnAdjSweep, loAdjPoint0, loPoint1)
* Internal part
THIS._DrawSliceExternal(lnXInt, lnYInt, lnWInt, lnHInt, lnAdjStart, lnAdjSweep, loAdjPoint2, loPoint2)
ENDIF
IF llDrawExtAtEnd
THIS._DrawSliceExternal(tnX, tnY, tnWidth, tnHeight, lnStartB, lnSweepB, loPoint0B, loPoint1B)
ENDIF
* Draw polygon at the beginning of the doughnut
IF tnStart > 90 AND tnStart < 270
m.loGfx.DrawPolygon(m.loPen, @laStartPoints)
m.loGfx.FillPolygon(lo3dBrush, @laStartPoints)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillPolygon(THIS._oDimBrush, @laStartPoints)
ENDIF
ENDIF
IF NOT BETWEEN(lnFinalAngle, 90, 270)
m.loGfx.DrawPolygon(m.loPen, @laEndPoints)
m.loGfx.FillPolygon(lo3dBrush, @laEndPoints)
IF VARTYPE(THIS._oDimBrush)='O'
m.loGfx.FillPolygon(THIS._oDimBrush, @laEndPoints)
ENDIF
ENDIF
* Draw the main path
THIS.FillPathDim(m.loMainBrush, loPath)
m.loGfx.DrawPath(m.loPen, loPath)
ENDWITH
ELSE && This.PieEnhancedDrawing .F. - This is the old Behavior
WITH _SCREEN.SYSTEM.Drawing
LOCAL loBmp AS xfcBitmap
loBmp = poTempBmp
LOCAL loTempGfx AS xfcGraphics
loTempGfx = .Graphics.FromImage(loBmp)
loTempGfx.CLEAR(.COLOR.Transparent)
loTempGfx.SmoothingMode = .Drawing2D.SmoothingMode.AntiAlias
* Create a GraphicsPath object.
LOCAL loTempPath AS xfcGraphicsPath
loTempPath = .Drawing2D.GraphicsPath.New()
LOCAL loRect AS xfcRectangle, loRect2 AS xfcRectangle, lnRatio
lnRatio = THIS.DonutRatio
loRect = .Rectangle.New(0, 0, tnWidth, tnHeight)
loRect2 = .Rectangle.New(;
(tnWidth * (1 - lnRatio) / 2), ;
(tnHeight * (1 - lnRatio) / 2), ;
tnWidth * lnRatio, ;
tnHeight * lnRatio)
LOCAL loPoint0 AS xfcPointF, loPoint1 AS xfcPointF, loPoint2 AS xfcPointF, loPoint3 AS xfcPointF
* Obtaining the needed points
loTempPath.AddArc(loRect, tnStart, 0.0001)
loPoint0 = loTempPath.GetLastPoint()
loTempPath.AddArc(loRect2, tnStart, 0.0001)
loPoint3 = loTempPath.GetLastPoint()
loTempPath.AddArc(loRect, tnStart, tnSweep)
loPoint1 = loTempPath.GetLastPoint()
loTempPath.AddArc(loRect2, tnStart, tnSweep)
loPoint2 = loTempPath.GetLastPoint()
loPoint4 = .POINT.New(loPoint3.X, loPoint3.Y + m.ln3d)
loPoint5 = .POINT.New(loPoint0.X, loPoint0.Y + m.ln3d)
loPoint6 = .POINT.New(loPoint1.X, loPoint1.Y + m.ln3d)
* Prepare the Main Path
LOCAL loPath AS xfcGraphicsPath
loPath = .Drawing2D.GraphicsPath.New()
loPath.StartFigure()
loPath.ADDLINE(loPoint0.X, loPoint0.Y, loPoint3.X, loPoint3.Y)
loPath.AddArc(loRect2, tnStart, tnSweep)
loPath.StartFigure()
loPath.AddArc(loRect, tnStart, tnSweep)
loPath.ADDLINE(loPoint1.X, loPoint1.Y, loPoint2.X, loPoint2.Y)
IF m.ln3d > 0
* Create a new Path for the 3D
LOCAL lo3DPath AS xfcPath, loMatrix AS xfcMatrix
lo3DPath = loPath.CLONE()
loMatrix = .Drawing2D.Matrix.New()
loMatrix.Translate(0,+1)
* Prepare the polygon points for the final part of the slice
DIMENSION laPointsB(4)
laPointsB(1) = loPoint1
laPointsB(2) = loPoint2
laPointsB(3) = .POINT.New(loPoint2.X, loPoint2.Y + m.ln3d)
laPointsB(4) = loPoint6
* If the slice ends in the left side, draw the polygon before the top face of the slice
IF BETWEEN(lnFinalAngle, 90, 270)
loTempGfx.DrawPolygon(m.loPen, @laPointsB)
ENDIF
LOCAL N
FOR N = 1 TO m.ln3d - 1
lo3DPath.TRANSFORM(loMatrix)
loTempGfx.FillPathDim(lo3dBrush, lo3DPath)
NEXT
* Draw the side Polygons
* Draw polygon at the beginning of the donut
IF tnStart > 90 AND tnStart < 270
DIMENSION laPoints(4)
laPoints(1) = loPoint0
laPoints(2) = loPoint5
laPoints(3) = loPoint4
laPoints(4) = loPoint3
loTempGfx.DrawPolygon(m.loPen, @laPoints)
ENDIF
* Draw polygon at the end of the donut
IF lnFinalAngle < 90 OR lnFinalAngle > 270
loTempGfx.DrawPolygon(m.loPen, @laPointsB)
ENDIF
ENDIF
* Draw the path
loTempGfx.FillPathDim(m.loMainBrush, loPath)
loTempGfx.DrawPath(THIS._oBorderPen, loPath)
loBmp.ApplyColorMatrix(poClrMatrix)
m.loGfx.DrawImage(loBmp, tnX, tnY)
ENDWITH
ENDIF
ENDPROC
PROCEDURE _drawfrustum
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnValue, tn3D, tnMaxBarHeight
* Yudin Alex 21 May 2013
LOCAL lcFront, lcPoints, ;
ln3D, lnAlpha, lnHorDelta, lnOrigAlpha, lnStore, lnTop3D, lnTopHeight, lnTopWidth, lnTopX, lnTopY, ;
loBotBrush, loGfx, loPen
m.lnHorDelta=0
m.tnHeight = ABS(m.tnHeight)
m.ln3D = MAX(IIF(VARTYPE(tn3D)='N',tn3D,THIS._3d), 1)
m.loGfx = THIS.oGfx
m.lnOrigAlpha = THIS.AlphaChannel
m.lnAlpha = MIN(255, (THIS.AlphaChannel * 1.25))
THIS.AlphaChannel = lnAlpha
m.lcFront=''
THIS._PrepareBrushes(tnX, tnY, tnWidth, tnHeight, .F., IIF(THIS.SingleData OR THIS.ChartsCount = 1, RECNO(),THIS._ChartIndex))
m.loPen = THIS._oBorderPen
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE THIS.BrushType = 1 && SolidColors
loBotBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
CASE THIS.BrushType = 2 && Gradient
loBotBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, + 80)))
OTHERWISE
* THIS._PrepareBrushes(tnX, tnY, tnWidth, tnHeight, .F., IIF(THIS.SingleData OR THIS.ChartsCount = 1, RECNO(),THIS._ChartIndex))
loBotBrush = THIS._oMainBrush
ENDCASE
THIS.AlphaChannel = lnOrigAlpha
lcPoints=''
LOCAL laPoints(4)
* Draw the 3D Bar using the 3DBrush
IF THIS._Orientation = 1 && Vertical
lnTopWidth = (tnMaxBarHeight-tnHeight) / tnMaxBarHeight * tnWidth
lnTop3D = lnTopWidth * m.ln3D/tnWidth
lnHorDelta = (tnWidth - lnTopWidth) /2
lnTopX = m.tnX + (m.tnWidth - lnTopWidth)/2 + (ln3D - lnTop3D)/2
lnTopY = m.tnY - (ln3D - lnTop3D)/2
* Prepare points to draw the 3D part of the Pyramid
* Bottom
m.laPoints(1) = .PointF.New(m.tnX + m.tnWidth, m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.tnWidth + m.ln3D, m.tnY - m.ln3D + m.tnHeight)
m.laPoints(3) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D + m.tnHeight)
m.laPoints(4) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.loGfx.FillPolygon(m.loBotBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Left wall
LOCAL laPoints(4)
m.laPoints(1) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D + m.tnHeight)
m.laPoints(3) = .PointF.New(m.lnTopX + m.lnTop3D, lnTopY - m.lnTop3D)
m.laPoints(4) = .PointF.New(m.lnTopX, lnTopY)
m.loGfx.FillPolygon(THIS._o3DBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Top
m.laPoints(1) = .PointF.New(m.lnTopX + lnTopWidth, lnTopY)
m.laPoints(2) = .PointF.New(m.lnTopX + lnTopWidth + m.lnTop3D, lnTopY - m.lnTop3D)
m.laPoints(3) = .PointF.New(m.lnTopX + m.lnTop3D, lnTopY - m.lnTop3D)
* m.laPoints(4) = .PointF.New(m.lnTopX, m.tnY)
m.loGfx.FillPolygon(m.loBotBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Front
m.laPoints(1) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.tnWidth, m.tnY + m.tnHeight)
m.laPoints(3) = .PointF.New(m.lnTopX + lnTopWidth, m.lnTopY)
m.loGfx.FillPolygon(THIS._oMainBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Right wall
m.laPoints(1) = .PointF.New(m.tnX + m.tnWidth, m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.tnWidth + m.ln3D, m.tnY - m.ln3D + m.tnHeight)
m.laPoints(3) = .PointF.New(m.lnTopX + lnTopWidth+ m.lnTop3D, lnTopY - m.lnTop3D)
m.laPoints(4) = .PointF.New(m.lnTopX + lnTopWidth,lnTopY)
m.loGfx.FillPolygon(THIS._oRightbrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
TEXT TO lcPoints
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D + m.tnHeight,0)>>
<<ROUND(m.lnTopX + m.lnTopWidth + m.lnTop3D,0)>>,<<ROUND(m.lnTopY - m.lnTop3D,0)>>
<<ROUND(m.lnTopX +m.lnTop3D,0)>>,<<ROUND(m.lnTopY - m.lnTop3D ,0)>>
<<ROUND(m.lnTopX ,0)>>,<<ROUND(m.lnTopY ,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
TEXT TO lcFront
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.lnTopX + m.lnTopWidth,0)>>,<<ROUND(m.lnTopY,0)>>
<<ROUND(m.lnTopX ,0)>>,<<ROUND(m.lnTopY ,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
IF VARTYPE(tn3D)='N'
tn3D= m.lnTop3D
ENDIF
ELSE
****************
* *
* Horizontal *
* *
****************
lnTopHeight = (tnMaxBarHeight-tnWidth) / tnMaxBarHeight * tnHeight
lnTop3D = lnTopHeight * m.ln3D/tnHeight
lnHorDelta = (tnHeight - lnTopHeight) /2
lnTopX = m.tnX + m.tnWidth + (ln3D - lnTop3D)/2
lnTopY = m.tnY + (m.tnHeight - lnTopHeight)/2 + (ln3D - lnTop3D)/2 -(ln3D - lnTop3D)
IF THIS.Charttype = 17 AND THIS._ChartIndex=1
m.lnStore=m.lnTopX
m.lnTopX = m.tnX
m.tnX=m.lnStore
ENDIF
* Left bottom
m.laPoints(1) = .PointF.New(m.tnX, m.tnY)
m.laPoints(2) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D)
m.laPoints(3) = .PointF.New(m.tnX+ m.ln3D, m.tnY + m.tnHeight - m.ln3D)
m.laPoints(4) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.loGfx.FillPolygon(m.loBotBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Right bottom
m.laPoints(1) = .PointF.New(m.lnTopX, m.lnTopY)
m.laPoints(2) = .PointF.New(m.lnTopX + m.lnTop3D, m.lnTopY - m.lnTop3D)
m.laPoints(3) = .PointF.New(m.lnTopX + m.lnTop3D, m.lnTopY + m.lnTopHeight - m.lnTop3D)
m.laPoints(4) = .PointF.New(m.lnTopX, m.lnTopY + m.lnTopHeight)
m.loGfx.FillPolygon(m.loBotBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Walls
* 1.Top
m.laPoints(1) = .PointF.New(m.tnX, m.tnY)
m.laPoints(2) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D)
m.laPoints(3) = .PointF.New(m.lnTopX + m.lnTop3D, m.lnTopY - m.lnTop3D)
m.laPoints(4) = .PointF.New(m.lnTopX, m.lnTopY)
m.loGfx.FillPolygon(THIS._o3DBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* 2. Front
m.laPoints(1) = .PointF.New(m.tnX, m.tnY)
m.laPoints(2) = .PointF.New(m.lnTopX, m.lnTopY)
m.laPoints(3) = .PointF.New(m.lnTopX, m.lnTopY + m.lnTopHeight)
m.laPoints(4) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.loGfx.FillPolygon(THIS._oMainBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
TEXT TO lcPoints
<<ROUND(m.tnX ,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY,0)>>
<<ROUND(m.tnX + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D,0)>>
<<ROUND(m.lnTopX + m.lnTop3D,0)>>,<<ROUND(m.lnTopY - m.lnTop3D,0)>>
<<ROUND(m.lnTopX + m.lnTop3D,0)>>,<<ROUND(m.lnTopY + m.lnTopHeight - m.lnTop3D,0)>>
<<ROUND(m.lnTopX,0)>>,<<ROUND(m.lnTopY + m.lnTopHeight,0)>>
<<ROUND(m.tnX ,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
TEXT TO lcFront
<<ROUND(m.tnX ,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY,0)>>
<<ROUND(m.lnTopX,0)>>,<<ROUND(m.lnTopY,0)>>
<<ROUND(m.lnTopX,0)>>,<<ROUND(m.lnTopY + m.lnTopHeight,0)>>
<<ROUND(m.tnX ,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
IF VARTYPE(tn3D)='N'
tn3D= m.lnTop3D
ENDIF
IF THIS.Charttype = 17 AND THIS._ChartIndex=1
m.tnX=m.lnTopX
ENDIF
ENDIF
loShape = THIS._UpdateCoordinates(,"Rect", m.tnX + m.ln3D / 2, m.tnY, m.tnWidth, m.tnHeight, m.tnValue,,lcPoints,,lcFront)
THIS._DrawLegendinBar(tnX, tnY, tnWidth, tnHeight, tnValue)
ENDWITH
RETURN lnHorDelta
ENDPROC
PROCEDURE _drawlegendinbar
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnValue, tnIndex, loShapeObject
* Zero values in Stacked charts will not have space for drawing legends
* so we'll ignore this case
LOCAL lcCaption, lcLegend, lcValue, lnDecimals, loObject
IF VARTYPE(tnHeight) # 'N'
tnHeight = 8
ENDIF
WITH THIS
IF ._Stacked AND tnValue = 0
RETURN
ENDIF
.CurrIndex = ._nIndex
LOCAL lnLeftMargin
lnLeftMargin = ._yAxisWidth + ._LeftOffset
*!* Other available properties
*!* .CurrValue
*!* .CurrLegend
*!* .CurrObjType
*!* .CurrRecno
*!* .CurrColumn
IF TYPE('.Fields(._ChartIndex)') # 'U' AND NOT .FIELDS(._ChartIndex).ShowValuesOnShape
RETURN
ENDIF
m.lcLegend = ''
LOCAL lcExpr, lnAlign, lnDirection
lcExpr = .ShapeLegendExpression
IF (VARTYPE(lcExpr) = "C") AND (NOT EMPTY(lcExpr))
.ShapeLegend._Value = EVALUATE(lcExpr)
ELSE
IF ._SumRow AND .ShowPercentages
* Show percentages as values
DO CASE
CASE EMPTY(.ShapeLegend.FORMAT) AND EMPTY(.ShapeLegendExpression)
.ShapeLegend._ForceFormat = ;
._GetFieldType(.SourceAlias, EVALUATE(".Fields(.ChartRow).FieldValue"), .T.) + "%"
CASE NOT "%" $ .ShapeLegend.FORMAT
.ShapeLegend._ForceFormat = .ShapeLegend.FORMAT + "%"
ENDCASE
LOCAL lnValue
lnValue = ROUND(m.tnValue / .ChartSum * 100,0)
.ShapeLegend._Value = lnValue
ELSE
.ShapeLegend._Value = tnValue
ENDIF
ENDIF
lnDecimals = SET("Decimals")
SET DECIMALS TO .ShowDecimals
lcValue = IIF(VARTYPE(.ShapeLegend._Value)='N', ;
TRANSFORM(.ShapeLegend._Value,[999 999 999 999]+IIF(.ShowDecimals>0,[.]+REPLICATE([9],.ShowDecimals),'')), ;
.ShapeLegend._Value)
.ShapeLegend._Value = IIF(EMPTY(m.lcLegend),'', m.lcLegend + CHR(13)+CHR(10)) + IIF(.ShowValue,ALLTRIM(lcValue),'')
IF VARTYPE(loShapeObject)='O'
loShapeObject.CAPTION=.ShapeLegend._Value
ENDIF
SET DECIMALS TO lnDecimals
IF NOT .ShowValuesOnShapes OR EMPTY(.ShapeLegend._Value)
RETURN
ENDIF
lnAlign = .ShapeLegend.ALIGNMENT
*!* IF ._InvertShapeLegendAlignment = .T.
*!* DO CASE
*!* CASE lnAlign = 0 && Left
*!* lnAlign = 1 && Right
*!* CASE lnAlign = 1 && Right
*!* lnAlign = 0 && Left
*!* OTHERWISE
*!* ENDCASE
*!* ENDIF
lnDirection = IIF(EMPTY(.ShapeLegend.ROTATION),.BarLegendDirection,0)
IF lnDirection = 0 && Horizontal
* Draw the Values inside the shapes
IF ._Orientation = 1 && Vertical
*!* IF (tnHeight < .ShapeLegend._Height) AND (NOT ._Stacked)
*!* LOCAL y0
*!* y0 = .ChartCanvas.HEIGHT - ._XAxisHeight + 1
*!* tnY = y0 - .ShapeLegend._Height
*!* ENDIF
DO CASE
CASE .ShapeLegendVertAlignment=2
tnY=tnY+tnHeight/2 - .ShapeLegend._Height/2
CASE .ShapeLegendVertAlignment=1
tnY=tnY+tnHeight - .ShapeLegend._Height
ENDCASE
DO CASE
CASE .ShapeLegend.ROTATION # 0 AND .BarLegendType = 1
tnY = tnY - .ShapeLegend._Height - 2
loShape = .ShapeLegend._DrawString(tnX + tnWidth / 2, tnY)
CASE lnAlign = 0 && Left
loShape = .ShapeLegend._DrawString(tnX, tnY)
CASE lnAlign = 1 && Right
loShape = .ShapeLegend._DrawString(tnX + tnWidth, tnY)
CASE lnAlign = 2 && Center
x1=tnX + tnWidth / 2
loShape = .ShapeLegend._DrawString(x1, tnY)
OTHERWISE
ENDCASE
ELSE && ._Orientation = 2 && Horizontal
DO CASE
CASE lnAlign = 2 && Center
IF .ShapeLegend._Width > tnWidth && force left
.ShapeLegend.ALIGNMENT = 0
loShape = .ShapeLegend._DrawString(tnX, tnY)
.ShapeLegend.ALIGNMENT = 2
ELSE
loShape = .ShapeLegend._DrawString(tnX + tnWidth / 2, tnY)
ENDIF
CASE lnAlign = 0 AND tnValue >= 0 && Left
loShape = .ShapeLegend._DrawString(tnX, tnY)
CASE lnAlign = 1 AND tnValue >= 0 && Right
IF .ShapeLegend._Width > tnWidth && force left
.ShapeLegend.ALIGNMENT = 0
loShape = .ShapeLegend._DrawString(tnX, tnY)
.ShapeLegend.ALIGNMENT = 1
ELSE
loShape = .ShapeLegend._DrawString(tnX + tnWidth, tnY)
ENDIF
CASE lnAlign = 1 AND tnValue < 0 && Force Left
.ShapeLegend.ALIGNMENT = 0
loShape = .ShapeLegend._DrawString(tnX, tnY)
.ShapeLegend.ALIGNMENT = 1
CASE lnAlign = 0 AND tnValue < 0 && Force Right
.ShapeLegend.ALIGNMENT = 1
loShape = .ShapeLegend._DrawString(tnX + tnWidth, tnY)
.ShapeLegend.ALIGNMENT = 0
OTHERWISE
ENDCASE
ENDIF
ELSE && BarLegendDirection = 1 && Vertical
IF lnDirection = 2 && Invert Direction
LOCAL lnRotCenter
lnRotCenter = .ShapeLegend.RotationCenter
.ShapeLegend.RotationCenter = lnRotCenter + 180
ENDIF
IF tnValue >= 0 OR lnAlign = 2
loShape = .ShapeLegend._DrawString(tnX, tnY, tnWidth, tnHeight, .T.)
ELSE
IF lnAlign = 0
.ShapeLegend.ALIGNMENT = 1
ELSE
.ShapeLegend.ALIGNMENT = 0
ENDIF
loShape = .ShapeLegend._DrawString(tnX, tnY, tnWidth, tnHeight, .T.)
.ShapeLegend.ALIGNMENT = lnAlign
ENDIF
IF lnDirection = 2 && Invert Direction
.ShapeLegend.RotationCenter = lnRotCenter
ENDIF
ENDIF
loShape.CAPTION=.ShapeLegend._Value
ENDWITH
ENDPROC
PROCEDURE _drawlinechart
LOCAL laPoints[1], ;
laPointsI[1], ;
lcType as String, ;
lnAdjust as Number, ;
lnBarHeight as Number, ;
lnBarWidth as Number
SELECT(This._DataCursor)
LOCAL lnLeftMargin, lnWidth, lnHeight, lnValue
LOCAL lnBetween, lnBetween2, n, i, j, lnMaxValue, lnPointHeight, x1, y1, ln3D, lnChartsCount
LOCAL llIsNull, lnYBase
LOCAL lnTipPixels, lnType2, lnAlignment, lnRecs
LOCAL lnMaxValue2
m.lnAlignment = This.ShapeLegend.Alignment
m.lnRecs = This._nRecords
m.lnTipPixels = This._TipPixels
m.lnLeftMargin = This._YAxisWidth + This._LeftOffset
m.ln3D = This._3D
m.lnChartsCount = This.ChartsCount
* Calculate the maximum width of the chart
m.lnWidth = This.ChartCanvas.Width - This._YAxisWidth - This._LeftOffset - (m.ln3D * m.lnChartsCount) - This._RightOffset - THIS._yAxisWidth2
m.lnHeight = This.ChartCanvas.Height - This._XAxisHeight - This._TopOffSet - (m.ln3D * m.lnChartsCount)
IF m.lnWidth < 10 OR m.lnHeight < 10 OR m.lnRecs < 1
RETURN
ENDIF
LOCAL loGfx as xfcGraphics
m.loGfx = This.oGfx
* Get the maximum value of the chart
m.lnMaxValue = This._ScaleRange
m.lnMaxValue2 = This._ScaleRange2
LOCAL loBrush as xfcBrush
IF This.BrushType = 1
m.loBrush = "This._o3dbrush"
ELSE
m.loBrush = "This._oMainBrush"
ENDIF
* Prepare array of points
* 1st column is the current point object
* 2nd column is the global index number for the coordinates array
LOCAL lnArrayLength
IF INLIST(This.ChartType, 5, 18) && Line
m.lnArrayLength = m.lnRecs
ELSE && Area
m.lnArrayLength = m.lnRecs + 3
ENDIF
DIMENSION m.laPoints(m.lnArrayLength)
DIMENSION m.laPointsI(m.lnArrayLength)
WITH _Screen.System.Drawing
FOR m.i = 1 TO m.lnChartsCount
This._ChartIndex = m.i
m.lnType2 = EVALUATE("This.Fields(i).ChartType")
m.lnAdjust = (m.ln3D * (m.lnChartsCount - m.i ))
m.lnYBase = This._TopOffSet + m.lnHeight - m.lnAdjust + (m.ln3D * m.lnChartsCount)
* If MultiChart mode, the chart needs to start half a position further
IF This.Multichart AND This.MultiChartMargin
m.lnBetween = m.lnWidth / (m.lnRecs)
ELSE
m.lnBetween = m.lnWidth / (m.lnRecs - IIF(m.lnRecs = 1, 0, 1))
ENDIF
m.lnBetween2 = m.lnBetween + m.lnAdjust
&& the X distance between the points to be used when drawing the legends in the X axis
SCAN
m.n = RECNO()
m.x1 = m.lnLeftMargin + (m.lnBetween * (m.n - 1)) + ;
m.lnAdjust + IIF(This.Multichart AND This.MultiChartMargin, ;
(m.lnBetween / 2), 0)
m.lnValue = This._GetValue(m.i, .T.)
m.llIsNull = ISNULL(m.lnValue)
IF m.llIsNull
m.lnValue = 0
ENDIF
IF This.Fields(m.i).AxisIndex = 2 AND This.ChartType = 18
m.lnValue = m.lnValue + This._ScaleAdjust2
m.lnPointHeight = m.lnValue / m.lnMaxValue2 * m.lnHeight
m.y1 = m.lnYBase - m.lnPointHeight
This._aPoints(m.n, 1) = m.x1 + m.ln3D
This._aPoints(m.n, 2) = m.y1
This._aPoints(m.n, 3) = m.lnValue - This._ScaleAdjust2 && Restore the original value
ELSE && This.Fields(i).AxisIndex = 1
IF m.llIsNull AND (m.n > 1) AND (This.LineIgnoreNULLs) && Special situation to Tamar Granor
This._aPoints(m.n, 1) = This._aPoints(m.n - 1, 1)
This._aPoints(m.n, 2) = This._aPoints(m.n - 1, 2)
This._aPoints(m.n, 3) = This._aPoints(m.n - 1, 3)
* Extra checking to avoid drawing a line if the starting values are NULLs
IF VARTYPE(m.laPoints(m.n - 1)) = "L"
m.laPoints(RECNO()) = .F.
ELSE
m.laPoints(RECNO()) = .Point.New(This._aPoints(m.n, 1) - m.ln3D, This._aPoints(m.n, 2))
ENDIF
LOOP
ENDIF
m.lnValue = m.lnValue + This._ScaleAdjust
m.lnPointHeight = m.lnValue / m.lnMaxValue * m.lnHeight
m.y1 = m.lnYBase - m.lnPointHeight
This._aPoints(m.n, 1) = m.x1 + m.ln3D
This._aPoints(m.n, 2) = m.y1
This._aPoints(m.n, 3) = m.lnValue - This._ScaleAdjust && Restore the original value
ENDIF
m.laPoints(RECNO()) = IIF(m.llIsNull, .F., .Point.New(m.x1, m.y1))
ENDSCAN
GO TOP
* Draw the vertical line only for the first line
IF m.i = 1
This._DrawVerticalLineBack()
ENDIF
DO CASE
*-- 2010-11-26
*-- Fix by Paulo Henrique de Almeida (Casion)
CASE m.lnType2 = 3 && Single Bar
m.lnBarWidth = (m.lnWidth - (m.lnRecs - 1) * This.BarsSpaceBetween) / m.lnRecs
FOR m.n = 1 TO m.lnRecs
IF VARTYPE(m.laPoints(m.n)) <> "O"
LOOP
ENDIF
* changed by paulo henrique
m.x1 = This._aPoints(m.n, 1) - m.lnBarWidth / 2 - m.ln3D
m.y1 = This.Height - ((0 - This._MinScale) / m.lnMaxValue * m.lnHeight) - This._XAxisHeight
m.lnValue = This._aPoints(m.n, 3)
m.lnBarHeight = m.y1 - This._aPoints(m.n, 2)
m.y1 = min(m.y1, This._aPoints(m.n, 2))
* end - changed by paulo henrique
This._CurrentRow = m.n
This._DrawBar(m.x1, m.y1, m.lnBarWidth, m.lnBarHeight, m.lnValue)
m.laPointsI(m.n) = This._nIndex
ENDFOR
*--
CASE This.ChartType = 4 OR m.lnType2 = 4 && Point / Secondary Point
FOR m.n = 1 TO m.lnRecs
IF VARTYPE(m.laPoints(m.n)) <> "O"
LOOP
ENDIF
This._DrawShape(m.laPoints(m.n).X, m.laPoints(m.n).Y, This._aPoints(m.n, 3))
m.laPointsI(m.n) = This._nIndex
This._CurrentRow = m.n
ENDFOR
OTHERWISE && ChartType <> 4 - Line or Area
IF This.ChartType = 6 && Area
This._PrepareBrushes(0, 0, This.ChartCanvas.Width, This.ChartCanvas.Height, .F., m.i)
ENDIF
LOCAL laPolygon(4)
LOCAL laPolygonB(4)
IF m.ln3D = 0
* Create pen.
LOCAL loLinePen as xfcPen
LOCAL lnColor
IF This.BrushType = 3 && Monochrome
m.lnColor = 0
m.loLinePen = .Pen.New(This._oClrBlack, 3)
m.loLinePen.DashStyle = m.i - 1 && _Screen.System.Drawing.Drawing2D.DashStyle.Dash
ELSE
m.lnColor = This.aColors(m.i)
m.loLinePen = .Pen.New(.Color.FromRGB(m.lnColor), 2)
ENDIF
FOR m.n = 1 TO m.lnRecs - 1
This._CurrentRow = m.n
m.lcType = VARTYPE(m.laPoints(m.n)) + VARTYPE(m.laPoints(m.n + 1))
DO CASE
CASE m.lcType = "LO" OR m.lcType = "LL"
LOOP
CASE m.lcType = "OL"
m.loGfx.Drawline(m.loLinePen, m.laPoints(m.n).X, m.laPoints(m.n).Y, m.laPoints(m.n).X + 1, m.laPoints(m.n).Y + 1)
This._UpdateCoordinates(,"Rect", m.laPoints(m.n).X - m.lnTipPixels / 2, m.laPoints(m.n).Y - m.lnTipPixels / 2, m.lnTipPixels, m.lnTipPixels, ;
This._aPoints(m.n, 3), m.n)
m.laPointsI(m.n) = This._nIndex
LOOP
OTHERWISE
m.loGfx.Drawline(m.loLinePen, m.laPoints(m.n), m.laPoints(m.n + 1))
ENDCASE
IF This.ChartType = 6 && Area
* Draw the area
m.laPolygonB(1) = m.laPoints(m.n)
m.laPolygonB(2) = m.laPoints(m.n + 1)
m.laPolygonB(3) = .Point.New(m.laPolygonB(2).X, m.lnYBase)
m.laPolygonB(4) = .Point.New(m.laPolygonB(1).X, m.lnYBase)
m.loGfx.FillPolygon(This._oMainBrush, @m.laPolygonB)
IF This.AreaDrawBorders
m.loGfx.DrawPolygon(This._oBorderPen, @m.laPolygonB)
ENDIF
ENDIF
This._UpdateCoordinates(,"Rect", m.laPoints(m.n).X - m.lnTipPixels / 2, m.laPoints(m.n).Y - m.lnTipPixels / 2, m.lnTipPixels, m.lnTipPixels, ;
This._aPoints(m.n, 3))
m.laPointsI(m.n) = This._nIndex
ENDFOR
IF VARTYPE(m.laPoints(m.n)) = "O"
This._CurrentRow = m.n
This._UpdateCoordinates(, ;
"Rect", m.laPoints(m.n).X - m.lnTipPixels / 2, m.laPoints(m.n).Y - m.lnTipPixels / 2, ;
m.lnTipPixels, m.lnTipPixels, This._aPoints(m.n, 3))
m.laPointsI(m.n) = This._nIndex
ENDIF
* Draw the shapes after (over) the lines
IF This.LineCaps = .T. AND INLIST(This.ChartType, 5, 18) && Line
FOR m.j = 1 TO m.lnRecs
IF VARTYPE(m.laPoints(m.j)) <> "O" OR ;
VARTYPE(m.laPoints(m.j).X) + VARTYPE(m.laPoints(m.j).Y) <> "NN"
LOOP
ENDIF
This._DrawShape(m.laPoints(m.j).X, m.laPoints(m.j).Y, This._aPoints(m.j, 3))
m.laPointsI(m.n) = This._nIndex
This._CurrentRow = m.j
ENDFOR
ENDIF
ELSE && m.ln3D <> 0
* Store a big area brush that will be used for the main area part of the shapes
LOCAL loAreaBrush, llDrawPointLine
m.loAreaBrush = This._oMainBrush
FOR m.n = 1 TO m.lnRecs - 1
This._CurrentRow = m.n
m.lcType = VARTYPE(m.laPoints(m.n)) + VARTYPE(m.laPoints(m.n + 1))
DO CASE
CASE m.lcType = "LO" OR m.lcType = "LL"
LOOP
CASE m.lcType = "OL"
m.llDrawPointLine = .T.
OTHERWISE
m.llDrawPointLine = .F.
ENDCASE
IF This.ChartType = 6 ; && Area
AND "L" $ m.lcType
IF m.lcType = "OL"
This._UpdateCoordinates(,"Rect", m.laPoints(m.n).X - m.lnTipPixels / 2, m.laPoints(m.n).Y - m.lnTipPixels / 2, m.lnTipPixels, m.lnTipPixels, ;
This._aPoints(m.n, 3))
m.laPointsI(m.n) = This._nIndex
ENDIF
LOOP
ENDIF
IF INLIST(This.ChartType, 5, 18) OR (This.ChartType = 6 AND This.Area3dTop)
m.laPolygon(1) = m.laPoints(m.n)
m.laPolygon(2) = .Point.New(m.laPoints(m.n).X + m.ln3D, m.laPoints(m.n).Y - m.ln3D)
IF m.llDrawPointLine
LOCAL lnColor, loLinePen as xfcPen
m.lnColor = This.aColors(m.i)
m.loLinePen = .Pen.New(.Color.FromRGB(m.lnColor), 2)
m.loGfx.Drawline(m.loLinePen, m.laPolygon(1), m.laPolygon(2))
This._UpdateCoordinates(,"Rect", m.laPoints(m.n).X - m.lnTipPixels / 2, m.laPoints(m.n).Y - m.lnTipPixels / 2, m.lnTipPixels, m.lnTipPixels, ;
This._aPoints(m.n, 3))
m.laPointsI(m.n) = This._nIndex
LOOP
ENDIF
m.laPolygon(3) = .Point.New(m.laPoints(m.n + 1).X + m.ln3D, m.laPoints(m.n + 1).Y - m.ln3D)
m.laPolygon(4) = m.laPoints(m.n + 1)
This._PrepareBrushes(m.laPoints(m.n).X, m.laPoints(m.n).Y - m.ln3D, ;
m.laPoints(m.n + 1).X + m.ln3D - m.laPoints(m.n).X, ;
MAX(2, ABS(m.laPoints(m.n).Y - m.laPoints(m.n + 1).Y)), .F., m.i)
m.loGfx.FillPolygon(This._oMainBrush, @m.laPolygon)
m.loGfx.DrawPolygon(This._oBorderPen, @m.laPolygon)
ENDIF
IF This.ChartType = 6 && Area
* Draw the area
m.laPolygonB(1) = m.laPoints(m.n)
m.laPolygonB(2) = m.laPoints(m.n + 1)
m.laPolygonB(3) = .Point.New(m.laPolygonB(2).X, m.lnYBase)
m.laPolygonB(4) = .Point.New(m.laPolygonB(1).X, m.lnYBase)
m.loGfx.FillPolygon(m.loAreaBrush, @m.laPolygonB)
IF This.AreaDrawBorders
m.loGfx.DrawPolygon(This._oBorderPen, @m.laPolygonB)
ENDIF
* Draw the right 3d edge of the Area
IF This.Area3dTop
m.laPolygonB(1) = .Point.New(m.laPolygonB(2).X + m.ln3D, m.laPolygonB(2).Y - m.ln3D)
m.laPolygonB(4) = .Point.New(m.laPolygonB(3).X + m.ln3D, m.laPolygonB(3).Y - m.ln3D)
m.loGfx.FillPolygon(This._o3dbrush, @m.laPolygonB)
m.loGfx.DrawPolygon(This._oBorderPen, @m.laPolygonB)
ENDIF
ENDIF && ChartType = 6 - Area
This._UpdateCoordinates(,"Rect", m.laPoints(m.n).X - m.lnTipPixels / 2, m.laPoints(m.n).Y - m.lnTipPixels / 2, m.lnTipPixels, m.lnTipPixels, ;
This._aPoints(m.n, 3))
m.laPointsI(m.n) = This._nIndex
ENDFOR
This._CurrentRow = m.n
IF VARTYPE(m.laPoints(m.n)) = "O"
This._UpdateCoordinates(,"Rect", m.laPoints(m.n).X - m.lnTipPixels / 2, m.laPoints(m.n).Y - m.lnTipPixels / 2, m.lnTipPixels, m.lnTipPixels, ;
This._aPoints(m.n, 3))
m.laPointsI(m.n) = This._nIndex
ENDIF
ENDIF && m.ln3D = 0
ENDCASE
* Reset Row counter
This._CurrentRow = 0
* Adjust _aPoints Array to show the information in the correct position
FOR m.n = 1 TO m.lnRecs
This._aPoints(m.n, 1) = This._aPoints(m.n, 1) - m.ln3D
ENDFOR
IF This.ShowValuesOnShapes AND This.Fields(m.i).ShowValuesOnShape
LOCAL lnIndex
* Draw Legends above the points
FOR m.n = 1 TO m.lnRecs
* Adjust _aPoints Array to show the information in the correct position
This._aPoints(m.n, 1) = This._aPoints(m.n, 1) - m.ln3D
IF VARTYPE(m.laPoints(m.n)) = "L"
LOOP
ENDIF
m.x1 = This._aPoints(m.n, 1)
m.y1 = This._aPoints(m.n, 2)
m.lnIndex = m.laPointsI(m.n)
This._DrawShapeLegend(m.x1, m.y1, m.lnIndex)
ENDFOR
ENDIF
ENDFOR
This._DrawXAxisLegend(.F., m.lnBetween2)
ENDWITH
This.ShapeLegend.Alignment = m.lnAlignment
RETURN
ENDPROC
PROCEDURE _drawpiechart
LPARAMETERS toShape
LOCAL lcCursor, ln3D, lnDetachAngle, lnDetachPixels, lnHeight, lnMaxHeight, lnMaxWidth, lnNativeValue, ;
lnStart, lnSweep, lnTempStart, lnTempSweep, lnTotal, lnValue, lnWidth, lnX, lnX1, lnY, lnY1, lnRow, loShape
lnRow = IIF(TYPE('toShape.CurrentRow')='N', toShape.CurrentRow, 0)
WITH THIS
SELECT ( ._DataCursor )
lnLines = RECCOUNT()
m.lnDetachPixels = .PieDetachPixels
m.lnMaxWidth = .ChartCanvas.WIDTH - ._LeftOffset - ._RightOffset - (lnDetachPixels * 2)
m.lnMaxHeight = .ChartCanvas.HEIGHT - (.MARGIN * 2) - .MarginBottom - ;
.MarginTop - ._TitleHeight - ._3d - ;
(lnDetachPixels * 2) - ;
._LegendHeight
m.lnMaxHeight = .ChartCanvas.HEIGHT-(.MARGIN * 2)-.MarginBottom-.MarginTop-._TitleHeight-._3d- ;
(lnDetachPixels*2)-._LegendHeight
m.lnWidth = MIN(lnMaxWidth, lnMaxHeight)
m.lnHeight = m.lnWidth
IF NOT .PieForceCircle
* Adjust the maximum width in order to ensure that the chart will retain
LOCAL lnFactor
m.lnFactor = 0.80
IF m.lnMaxWidth <= m.lnWidth / m.lnFactor
m.lnWidth = lnMaxWidth
ELSE
m.lnWidth = m.lnWidth / m.lnFactor
ENDIF
ENDIF
m.ln3D = ._3d
IF .PieCompensateAngles
m.lnWidth = m.lnMaxWidth
ENDIF
IF m.lnWidth <= 10 OR ;
lnHeight <= 10 OR ;
lnHeight <= ln3D
RETURN
ENDIF
* Calculate the chart basic positions
lnX = lnDetachPixels + .MARGIN + ._LeftOffset + ((lnMaxWidth - m.lnWidth) / 2)
lnY = .MARGIN + ._TopOffSet + ((lnMaxHeight - m.lnHeight) / 2) + lnDetachPixels
lnTotal = .ChartSum
IF NOT .PieEnhancedDrawing && Draws without taking care of slices edges
* Prepare the Gdi+ objects
WITH _SCREEN.SYSTEM.Drawing
PRIVATE poTempBmp AS xfcBitmap, poClrMatrix AS xfcColorMatrix
poTempBmp = .BITMAP.New(m.lnWidth + m.ln3D + 2, m.lnHeight + m.ln3D + 2)
poClrMatrix = .Imaging.ColorMatrix.New()
poClrMatrix.Matrix33 = .AlphaChannel / 255
ENDWITH
ENDIF
LOCAL laLegends(lnLines + 1, 3), lnRec, llHidden, llDrawLegend, lnPixelsOut
llDrawLegend = .ShowValuesonShapes
lnRec = 1
._ChartIndex = .ChartRow
._Pie1stDetached = .F.
IF .PieDirection = 1 && Anticlockwise
SET ORDER TO REVERT
ENDIF
* Draw the pie
* Draw the RIGHT side of the pie
lnStart = 270
.COLUMN = IIF(BETWEEN(._ChartIndex, 1, .ChartsCount), ._ChartIndex,1)
FOR .ROW = 1 TO RECCOUNT()
IF lnStart >=450
EXIT
ENDIF
.GetValue()
*SCAN FOR lnStart < 450
lnX1 = lnX
lnY1 = lnY
* Calculate Start point and Sweep
lnNativeValue = .VALUE
lnValue = ABS(lnNativeValue)
IF lnValue <= 0
LOOP
ENDIF
lnSweep = lnValue / lnTotal * 360
IF lnSweep > 359.99
lnSweep = 359.99
ENDIF
llHidden = lSliceHidden OR (NOT EMPTY(lnRow) AND lnRow#.ROW)
IF lDetach
IF lnRec = 1
._Pie1stDetached = .T.
._PieX0 = lnX1
._PieY0 = lnY1
ENDIF
IF VARTYPE(._PieAnimatedRec) ='N' AND .ROW = ._PieAnimatedRec
lnPixelsOut = ._PieAnimationPix
ELSE
lnPixelsOut = lnDetachPixels
ENDIF
lnTempStart = lnStart
lnTempSweep = lnSweep
._AdjustStartSweep(@lnTempStart, @lnTempSweep, m.lnWidth, m.lnHeight)
lnDetachAngle = 360 - (lnTempStart + (lnTempSweep / 2))
lnX1 = lnX + (COS(DTOR(lnDetachAngle)) * lnPixelsOut)
lnY1 = lnY - (SIN(DTOR(lnDetachAngle)) * lnPixelsOut)
ELSE
lnX1 = lnX
lnY1 = lnY
ENDIF
IF lnStart + lnSweep > 450
EXIT
ENDIF
loShape = IIF(lnRow>0,toShape, ._UpdateCoordinates(,"Pie",0,0,0,0,0,,,,,lnRec))
IF NOT llHidden
IF .ChartType = 1 && Pie
._DrawSlice(lnX1, lnY1, m.lnWidth, m.lnHeight, lnStart, lnSweep, lnNativeValue,loShape)
ELSE && 2 - Doughnut
._DrawDoughnutSlice(lnX1, lnY1, m.lnWidth, m.lnHeight, lnStart, lnSweep, lnNativeValue,loShape)
ENDIF
IF llDrawLegend
._PrepareLegendinSlice(@lnX1, @lnY1, m.lnWidth, m.lnHeight, lnStart, lnSweep, lnNativeValue)
laLegends(lnRec,1) = lnX1
laLegends(lnRec,2) = lnY1
laLegends(lnRec,3) = lnNativeValue
lnRec = lnRec + 1
ENDIF
ENDIF
lnStart = lnStart + lnSweep
NEXT
* Draw the LEFT side of the pie
.ROW = RECCOUNT()
lnStart = 270
DO WHILE lnStart >= 90
IF lnStart < 90
EXIT
ENDIF
.GetValue()
* Calculate Start point and Sweep
IF .VALUE = 0
IF .ROW = 1
EXIT
ENDIF
.ROW = .ROW -1
LOOP
ENDIF
lnX1 = lnX
lnY1 = lnY
lnNativeValue = .VALUE
lnValue = ABS(lnNativeValue)
lnSweep = lnValue / lnTotal * 360
IF lnSweep > 359.99
lnSweep = 359.99
ENDIF
lnStart = lnStart - lnSweep
llHidden = lSliceHidden OR (NOT EMPTY(lnRow) AND lnRow # .ROW)
IF lDetach
lnTempStart = lnStart
lnTempSweep = lnSweep
IF lnStart + lnSweep >= 269.9
._Pie1stDetached = .T.
._PieX0 = lnX1
._PieY0 = lnY1
ENDIF
IF VARTYPE(._PieAnimatedRec) ='N' AND .ROW = ._PieAnimatedRec
lnPixelsOut = ._PieAnimationPix
ELSE
lnPixelsOut = lnDetachPixels
ENDIF
._AdjustStartSweep(@lnTempStart, @lnTempSweep, m.lnWidth, m.lnHeight)
lnDetachAngle = 360 - (lnTempStart + (lnTempSweep / 2))
lnX1 = lnX + (COS(DTOR(lnDetachAngle)) * lnPixelsOut)
lnY1 = lnY - (SIN(DTOR(lnDetachAngle)) * lnPixelsOut)
ENDIF
loShape = IIF(lnRow>0,toShape, ._UpdateCoordinates(,"Pie",0,0,0,0,0,,,,,lnRec))
IF NOT llHidden
IF .ChartType = 1 && Pie
._DrawSlice(lnX1, lnY1, m.lnWidth, m.lnHeight, lnStart, lnSweep, lnNativeValue,loShape)
ELSE && 2 - Doughnut
._DrawDoughnutSlice(lnX1, lnY1, m.lnWidth, m.lnHeight, lnStart, lnSweep, lnNativeValue,loShape)
ENDIF
IF llDrawLegend
._PrepareLegendinSlice(@lnX1, @lnY1, m.lnWidth, m.lnHeight, lnStart, lnSweep, lnNativeValue)
laLegends(lnRec,1) = lnX1
laLegends(lnRec,2) = lnY1
laLegends(lnRec,3) = lnNativeValue
lnRec = lnRec + 1
ENDIF
ENDIF
IF .ROW=1
EXIT
ENDIF
.ROW = .ROW - 1
ENDDO
* Draw the legends at the end of the process in order to avoid
* a slice hiding a legend
IF TYPE('.FIELDS(._ChartIndex).ShowValuesOnShape') # 'L' OR .FIELDS(._ChartIndex).ShowValuesOnShape
IF llDrawLegend
LOCAL lnOrigAlign, N
lnOrigAlign = .ShapeLegend.ALIGNMENT
.ShapeLegend.ALIGNMENT = 2 && Force Center
lc=''
FOR N = 1 TO lnRec - 1
LOCAL lcExpr
lcExpr = .ShapeLegendExpression
IF VARTYPE(lcExpr) = "C" AND NOT EMPTY(lcExpr)
*!* Other available properties
*!* .CurrValue
*!* .CurrLegend
*!* .CurrObjType
*!* .CurrRecno
*!* .CurrColumn
.CurrIndex = N
lnValue = EVALUATE(lcExpr)
ELSE
IF .PieShowPercent
DO CASE
CASE EMPTY(.ShapeLegend.FORMAT) AND EMPTY(lcExpr)
.ShapeLegend._ForceFormat = ;
._GetFieldType(._DataCursor, 'nValue'+ALLTRIM(STR(.ChartRow)), .T.) + "%"
CASE NOT "%" $ .ShapeLegend.FORMAT
.ShapeLegend._ForceFormat = .ShapeLegend.FORMAT + "%"
ENDCASE
lnValue = (laLegends(N,3) / lnTotal) * 100
ELSE
lnValue = laLegends(N,3)
ENDIF
ENDIF
.ShapeLegend._Value = lnValue
TEXT TO lc addi
<<.CurrLegend>> (<<.CurrIndex>>) : <<INT(laLegends(N,1))>>, <<INT(laLegends(N,2))>>, <<INT(laLegends(N,3))>> <<N>>
endtext
lnX1 = laLegends(N,1)
IF VARTYPE(lnX1) <> "N"
EXIT
ENDIF
lnY1 = laLegends(N,2)
* Draw the Text
.ShapeLegend._DrawString( lnX1, lnY1,,,,,loShape)
NEXT
.ShapeLegend._ForceFormat = ""
.ShapeLegend.ALIGNMENT = lnOrigAlign
ENDIF
ENDIF
IF .PieDirection = 1 && Anticlockwise
SET ORDER TO
ENDIF
ENDWITH
ENDPROC
PROCEDURE _drawpyramid
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnValue, tn3D
* Yudin Alex 21 May 2013
LOCAL lcFront, lcPoints, ;
llLeftRight, ln3D, lnAlpha, lnOrigAlpha, lnStore, lnTopX, lnTopY, ;
loBotBrush, loGfx, loPen
m.tnHeight = ABS(m.tnHeight)
m.ln3D = MAX(IIF(VARTYPE(tn3D)='N',tn3D,THIS._3d), 1)
m.loGfx = THIS.oGfx
lnOrigAlpha = THIS.AlphaChannel
lnAlpha = MIN(255, (THIS.AlphaChannel * 1.25))
THIS.AlphaChannel = lnAlpha
THIS._PrepareBrushes(m.tnX, m.tnY, m.tnWidth, m.tnHeight, .F., IIF(THIS.SingleData, RECNO(),THIS._ChartIndex))
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE THIS.BrushType = 1 && SolidColors
loBotBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
CASE THIS.BrushType = 2 && Gradient
loBotBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, + 80)))
OTHERWISE
THIS._PrepareBrushes(tnX, tnY, tnWidth, tnHeight, .F., IIF(THIS.SingleData OR THIS.ChartsCount = 1, RECNO(),THIS._ChartIndex))
loBotBrush = THIS._oMainBrush
ENDCASE
m.loPen = THIS._oBorderPen
THIS.AlphaChannel = lnOrigAlpha
STORE '' TO lcPoints, lcFront
LOCAL laPoints(4)
* Draw the 3D Bar using the 3DBrush
IF THIS._Orientation = 1 && Vertical
* Points for 3D pyramid parts
* Bottom
m.laPoints(1) = .PointF.New(m.tnX + m.tnWidth, m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.tnWidth + m.ln3D, m.tnY - m.ln3D + m.tnHeight)
m.laPoints(3) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D + m.tnHeight)
m.laPoints(4) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.loGfx.FillPolygon(m.loBotBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Left wall
LOCAL laPoints(3)
m.laPoints(1) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D + m.tnHeight)
m.laPoints(3) = .PointF.New(m.tnX + m.tnWidth/2 + m.ln3D/2, m.tnY - m.ln3D/2)
m.loGfx.FillPolygon(THIS._o3DBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Front wall
m.laPoints(1) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.tnWidth, m.tnY + m.tnHeight)
m.loGfx.FillPolygon(THIS._oMainBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
m.laPoints(1) = .PointF.New(m.tnX + m.tnWidth, m.tnY + m.tnHeight)
m.laPoints(2) = .PointF.New(m.tnX + m.tnWidth + m.ln3D, m.tnY - m.ln3D + m.tnHeight)
m.loGfx.FillPolygon(THIS._oRightbrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
TEXT TO lcPoints
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth/2 + m.ln3D/2,0)>>,<<ROUND(m.tnY - m.ln3D/2,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
TEXT TO lcFront
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX + m.tnWidth/2 + m.ln3D/2,0)>>,<<ROUND(m.tnY - m.ln3D/2,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
ELSE
*Horizont
llLeftRight = THIS.Charttype # 17 AND THIS._ChartIndex>1
lnTopX = m.tnX + m.tnWidth + m.ln3D/2 * IIF(llLeftRight,1,0)
lnTopY = m.tnY + m.tnHeight/2 - m.ln3D/2
IF THIS.Charttype = 17 AND THIS._ChartIndex=1
m.lnStore=m.lnTopX
m.lnTopX = m.tnX
m.tnX=m.lnStore
ENDIF
* Bottom
m.laPoints(1) = .PointF.New(m.tnX, m.tnY)
m.laPoints(2) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D)
m.laPoints(3) = .PointF.New(m.tnX+ m.ln3D, m.tnY + m.tnHeight - m.ln3D)
m.laPoints(4) = .PointF.New(m.tnX, m.tnY + m.tnHeight)
m.loGfx.FillPolygon(m.loBotBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
* Walls
LOCAL laPoints(3)
m.laPoints(1) = .PointF.New(m.tnX, m.tnY)
m.laPoints(2) = .PointF.New(m.tnX + m.ln3D, m.tnY - m.ln3D)
m.laPoints(3) = .PointF.New(lnTopX, lnTopY)
m.loGfx.FillPolygon(THIS._o3DBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
m.laPoints(1) = .PointF.New(m.tnX, m.tnY)
m.laPoints(2) = .PointF.New(m.tnX , m.tnY + m.tnHeight)
m.laPoints(3) = .PointF.New(lnTopX, lnTopY)
m.loGfx.FillPolygon(THIS._oMainBrush, @laPoints)
m.loGfx.DrawPolygon(m.loPen, @laPoints)
TEXT TO lcPoints
<<ROUND(m.tnX ,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY,0)>>
<<ROUND(m.tnX + m.ln3D,0)>>,<<ROUND(m.tnY - m.ln3D,0)>>
<<ROUND(m.lnTopX,0)>>,<<ROUND(m.lnTopY,0)>>
<<ROUND(m.tnX ,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
TEXT TO lcFront
<<ROUND(m.tnX ,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
<<ROUND(m.tnX,0)>>,<<ROUND(m.tnY,0)>>
<<ROUND(m.lnTopX,0)>>,<<ROUND(m.lnTopY,0)>>
<<ROUND(m.tnX ,0)>>,<<ROUND(m.tnY + m.tnHeight,0)>>
ENDTEXT
IF THIS.Charttype = 17 AND THIS._ChartIndex=1
m.tnX=m.lnTopX
ENDIF
ENDIF
loShape = THIS._UpdateCoordinates(,"Rect", m.tnX + m.ln3D / 2, m.tnY, m.tnWidth, m.tnHeight, m.tnValue,,lcPoints,,lcFront)
THIS._DrawLegendinBar(tnX, tnY, tnWidth, tnHeight, tnValue)
ENDWITH
ENDPROC
PROCEDURE _drawscale
LPARAMETERS toPen, tnAxisIndex
LOCAL lnScaleNumber as Number, ;
lnScaleWidth as Number, ;
lnThisScale as Number, ;
lnValue as Number, ;
lnWidth as Number, x
m.tnAxisIndex = EVL(m.tnAxisIndex, 1)
* Draw the scale in the Y Axis
Local ln3D, lnHeight, lnMargin, lnScaleValue, llShowLineZero
IF This.ChartType = 17 && Paired
m.llShowLineZero = .F.
ELSE
m.llShowLineZero = This.ShowLineZero
ENDIF
IF This._DeepChart && Point, Line or Area
m.ln3D = This._3D * This.ChartsCount
ELSE
m.ln3D = This._3D
ENDIF
LOCAL lnMaxValue, lnScale, lnScaleAdjust, lnMinScale, lnMaxScale
m.lnMaxValue = IIF(m.tnAxisIndex = 1, This._ScaleRange, This._ScaleRange2)
m.lnScale = IIF(m.tnAxisIndex = 1, This._Scale, This._Scale2)
m.lnScaleAdjust = IIF(m.tnAxisIndex = 1, This._ScaleAdjust, This._ScaleAdjust2)
m.lnMinScale = IIF(m.tnAxisIndex = 1, This._MinScale, This._MinScale2)
m.lnMaxScale = IIF(m.tnAxisIndex = 1, This._MaxScale, This._MaxScale2)
LOCAL loGfx AS xfcGraphics
m.loGfx = This.oGfx
LOCAL loBackBrush AS xfcSolidBrush
LOCAL loBackPen AS xfcPen
LOCAL loBlackPen AS xfcPen
LOCAL llDrawBack, lnOneScale, lnxWidth
m.loBlackPen = This._oBlackPen
m.llDrawBack = .T.
This.ScaleLegend._Setup()
If This._Orientation = 1 && Vertical
Local lnRectColor, lnLineColor
If This.BrushType = 3 && Monochrome
m.lnRectColor = Rgb(255, 255, 255) && White
m.lnLineColor = 0 && Black
Else
m.lnRectColor = This.ScaleBackColor
m.lnLineColor = This.ScaleLineColor
Endif
With _Screen.System.Drawing
m.loBackBrush = .SolidBrush.New(.Color.FromARGB(This.ScaleBackAlpha, m.lnRectColor))
This._oBlackPen = .Pen.New(.Color.FromARGB(This.AxisAlpha, m.lnLineColor), This.ScaleBackLinesWidth - 1)
Endwith
Local lnDashValue
m.lnDashValue = This.ScaleBackLinesDash
If m.lnDashValue > 0
This._oBlackPen.DashStyle = m.lnDashValue && _Screen.System.Drawing.Drawing2D.DashStyle.Dash
Endif
m.lnHeight = This.Height - This._XAxisHeight - This._TopOffSet - m.ln3D
m.lnOneScale = m.lnScale / m.lnMaxValue * m.lnHeight
m.lnxWidth = This.Width - This._LeftOffset - This._RightOffset - This._yAxisWidth - m.ln3D
Local x0, x1, y0, y1, lnScaleHeight, N, Y
m.y0 = This.Height - This._XAxisHeight
m.x0 = IIF(m.tnAxisIndex = 1, ;
This._yAxisWidth + This._LeftOffset, ;
This.ChartCanvas.Width - This._RightOffset - m.ln3D + 2 + 2)
****************************************************************
* Jim Nelson 10/10/08
*
* Loop now calls method GetScaleValue (and its cousin GetScaleLegend) to get the
* scale values and associated legends. lnScaleNumber = 0 returns highest scale
* Save original Alignment settings
LOCAL lnOrigAlignment, lcOrigScaleFormat
m.lnOrigAlignment = This.ScaleLegend.Alignment
m.lcOrigScaleFormat = This.ScaleLegend._ForceFormat
* CCHALOM 2013-02-21
* Fix in getting a nice Scale legend format for both axes
* New properties inserted: _ScaleLegAxis1ForceFormat , _ScaleLegAxis2ForceFormat
This.ScaleLegend._ForceFormat = IIF(m.tnAxisIndex = 1, This._ScaleLegAxis1ForceFormat, This._ScaleLegAxis2ForceFormat)
For m.lnScaleNumber = 0 To 1000
m.lnValue = This.GetScaleValue (m.lnScaleNumber, m.tnAxisIndex)
If "N" # Vartype(m.lnValue)
Exit
Endif
* Yudin: Escape zero divide
m.lnScaleHeight = IIF(m.lnMaxValue=0,0,(m.lnValue - m.lnMinScale) / m.lnMaxValue * m.lnHeight)
m.Y = This.Height - m.lnScaleHeight - This._XAxisHeight
m.x1 = IIF(m.tnAxisIndex = 1, ;
This._yAxisWidth + This._LeftOffset - 7, ;
This.ChartCanvas.Width - This._RightOffset - m.ln3D + 6)
m.y1 = m.Y - (This._ScaleH/2)
m.lnScaleValue = m.lnValue - m.lnScaleAdjust
* 2nd Y Axis
IF m.tnAxisIndex = 1
This.ScaleLegend.Alignment = 1 && Force Right alignment
ELSE
This.ScaleLegend.Alignment = 0 && Force Left alignment
ENDIF
This.ScaleLegend._Value = This.GetScaleLegend(m.lnScaleNumber, (m.lnValue / This.ScaleDivider))
This.ScaleLegend._DrawString(m.x1, m.y1)
* Draw the horizontal scale (tick) line in the Y Axis
m.loGfx.DrawLine(m.toPen, m.x0, m.Y, m.x0 + m.ln3D, m.Y - m.ln3D)
m.loGfx.DrawLine(m.loBlackPen, m.x0 - 0, m.Y, m.x0 - This.TicLength, m.Y)
* Chack if finished drawing
IF "N" # VARTYPE(This.GetScaleValue (m.lnScaleNumber + 1))
EXIT
ENDIF
* Draw the scale background
Local x1Scale, y1Scale
m.x1Scale = m.x0 + m.ln3D
m.y1Scale = m.Y - m.ln3D
If m.llDrawBack AND m.tnAxisIndex = 1
****************************************************************
* Jim Nelson 10/11/08
*
* Calculate height to next scale
m.lnThisScale = (This.GetScaleValue (m.lnScaleNumber) - This.GetScaleValue (m.lnScaleNumber+1)) / m.lnMaxValue * m.lnHeight
IF INLIST(This.ScaleBackBarsType, 1, 3) && Horizontal, Both
****************************************************************
* Jim Nelson 10/11/08
*
* Calculate the height of this horizontal bar (allowing for case where not all bars are same height)
* loGfx.FillRectangle(loBackBrush, x1Scale, y1Scale, lnxWidth, lnOneScale)
m.loGfx.FillRectangle(m.loBackBrush, m.x1Scale, m.y1Scale, m.lnxWidth, m.lnThisScale)
ENDIF
IF INLIST(This.ScaleBackLinesType, 1, 3) && Horizontal, Both
****************************************************************
* Jim Nelson 10/10/08
*
* Do NOT draw the line if its the zero line (see below)
IF NOT ( ;
m.llShowLineZero ;
AND ABS(m.lnValue) < m.lnScale / 100 ;
AND m.lnMaxScale > 0 ;
AND m.lnMinScale < 0 ;
AND m.ln3D = 0 ;
)
m.loGfx.DrawLine(This._oBlackPen, m.x1Scale, m.y1Scale, m.x1Scale + m.lnxWidth, m.y1Scale)
m.loGfx.DrawLine(This._oBlackPen, m.x1Scale, m.y1Scale + m.lnThisScale, m.x1Scale + m.lnxWidth, m.y1Scale + m.lnThisScale)
ENDIF
ENDIF
ENDIF
m.llDrawBack = Not m.llDrawBack
IF m.llShowLineZero AND m.tnAxisIndex = 1
* Draw the ZERO line
IF ABS(m.lnValue) < m.lnScale / 100 And m.lnMaxScale > 0 And m.lnMinScale < 0
WITH _Screen.System.Drawing
LOCAL loZeroPen As xfcPen
m.loZeroPen = .Pen.New(.Color.FromARGB(This.AxisAlpha, This.ScaleLineZeroColor), 1)
If m.ln3D = 0
m.loGfx.DrawLine(m.loZeroPen, ;
m.x1Scale, m.y1Scale, m.x1Scale + m.lnxWidth, m.y1Scale)
Else
* Following line moved; does not apply to case m.ln3D = 0
m.y1Scale = m.y1Scale + 1
Local laPolygon(4)
m.laPolygon(1) = .Point.New(m.x1Scale, m.y1Scale)
m.laPolygon(2) = .Point.New(m.x1Scale + m.lnxWidth, m.y1Scale)
m.laPolygon(3) = .Point.New(m.x1Scale + m.lnxWidth - m.ln3D, m.y1Scale + m.ln3D)
m.laPolygon(4) = .Point.New(m.x1Scale - m.ln3D, m.y1Scale + m.ln3D)
Local loZeroBrush As xfcSolidBrush
m.loZeroBrush = .SolidBrush.New(.Color.FromARGB(64, This.ScaleLineZeroColor))
m.loGfx.FillPolygon(m.loZeroBrush, @m.laPolygon)
m.loGfx.DrawPolygon(m.loZeroPen, @m.laPolygon)
Endif
Endwith
Endif
Endif
Endfor
This._ChartY0 = This.Height - This._XAxisHeight - m.ln3D
This._ChartY1 = This._ChartY0 - m.lnHeight
* Restore original Alignment settings
This.ScaleLegend.Alignment = m.lnOrigAlignment
This.ScaleLegend._ForceFormat = m.lcOrigScaleFormat
Else && _Orientation = 2 HORIZONTAL
Local x0, x1, y0, y1
m.lnMargin = This._yAxisWidth + This._LeftOffset
m.y0 = This._TopOffSet
m.y1 = This.Height - This._XAxisHeight + 6
m.x0 = m.lnMargin
m.x1 = This.Width - This._RightOffset && This._LegendWidth
m.lnWidth = This.Width - This._LeftOffset - This._RightOffset - This._yAxisWidth - m.ln3D
Local llDrawBack, lnOneScale
m.llDrawBack = .T.
Local lnRectColor, lnLineColor
If This.BrushType = 3 && Monochrome
m.lnRectColor = Rgb(255, 255, 255) && White
m.lnLineColor = 0 && Black
Else
m.lnRectColor = This.ScaleBackColor
m.lnLineColor = This.ScaleLineColor
Endif
With _Screen.System.Drawing
m.loBackBrush = .SolidBrush.New(.Color.FromARGB(This.ScaleBackAlpha, m.lnRectColor))
This._oBlackPen = .Pen.New(.Color.FromARGB(This.AxisAlpha, m.lnLineColor), This.ScaleBackLinesWidth - 1)
Endwith
Local lnDashValue
m.lnDashValue = This.ScaleBackLinesDash
If m.lnDashValue > 0
This._oBlackPen.DashStyle = m.lnDashValue && _Screen.System.Drawing.Drawing2D.DashStyle.Dash
Endif
m.lnOneScale = m.lnScale / m.lnMaxValue * m.lnWidth
****************************************************************
* Jim Nelson 10/10/08
*
* Loop now calls method GetScaleValue (and its cousin GetScaleLegend) to get the
* scale values and associated legends. lnScaleNumber = 0 returns highest scale
For m.lnScaleNumber = 0 To 1000
m.lnValue = This.GetScaleValue (m.lnScaleNumber)
If "N" # Vartype( m.lnValue)
Exit
Endif
m.lnScaleWidth = (m.lnValue - m.lnMinScale) / m.lnMaxValue * m.lnWidth
m.x = m.x0 + m.lnScaleWidth
m.lnScaleValue = This.GetScaleLegend (m.lnScaleNumber, m.lnValue)
IF VARTYPE(m.lnScaleValue) = "C"
This.ScaleLegend._Value = m.lnScaleValue
ELSE
This.ScaleLegend._Value = IIF(This._AbsoluteScaleValues, ABS(m.lnScaleValue), m.lnScaleValue)
ENDIF
If This.ScaleLegend.Rotation = 0
This.ScaleLegend._DrawString(m.x, m.y1, .T.) && Force Center
Else
This.ScaleLegend._DrawString(m.x, m.y1)
Endif
* Draw the horizontal scale line in the Y Axis
m.loGfx.DrawLine(m.toPen, m.x, m.y1 - 5, m.x + m.ln3D, m.y1 - 5 - m.ln3D)
m.loGfx.DrawLine(m.loBlackPen, m.x, m.y1, m.x, m.y1 - This.TicLength)
* Draw the scale background
Local x1Scale, y1Scale
m.x1Scale = m.x + m.ln3D
m.y1Scale = m.y1 - m.ln3D - 3
If m.llDrawBack and "N" = Vartype (This.GetScaleValue (m.lnScaleNumber+1))
****************************************************************
* Jim Nelson 10/11/08
*
* Calculate width to next scale
m.lnThisScale = (This.GetScaleValue (m.lnScaleNumber) - This.GetScaleValue (m.lnScaleNumber+1)) / m.lnMaxValue * m.lnWidth
If Inlist(This.ScaleBackBarsType, 2, 3) && Vertical, Both
****************************************************************
* Jim Nelson 10/11/08
*
* Calculate the widtht of this horizontal bar (allowing for case where not all bars are same height)
m.loGfx.FillRectangle(m.loBackBrush, m.x1Scale - m.lnThisScale, m.y0, m.lnThisScale, m.y1Scale - m.y0)
Endif
If Inlist(This.ScaleBackLinesType, 2, 3) && Vertical, Both
****************************************************************
* Jim Nelson 10/10/08
*
* Do NOT draw the line if its the zero line (see below)
If Not ( ;
m.llShowLineZero ;
and Abs(m.lnValue) < m.lnScale / 100 ;
And m.lnMaxScale > 0 ;
And m.lnMinScale < 0 ;
and m.ln3D = 0 ;
)
m.loGfx.DrawLine(This._oBlackPen, m.x1Scale, m.y0, m.x1Scale, m.y1Scale)
m.loGfx.DrawLine(This._oBlackPen, m.x1Scale - m.lnThisScale, m.y0, m.x1Scale - m.lnThisScale, m.y1Scale)
Endif
Endif
Endif
m.llDrawBack = Not m.llDrawBack
If m.llShowLineZero
* Draw the ZERO line
If Abs(m.lnValue) < m.lnScale / 100 And m.lnMaxScale > 0 And m.lnMinScale < 0
With _Screen.System.Drawing
Local loZeroPen As xfcPen
m.loZeroPen = .Pen.New(.Color.FromARGB(This.AxisAlpha, This.ScaleLineZeroColor), 1)
If m.ln3D = 0
m.loGfx.DrawLine(m.loZeroPen, m.x1Scale, m.y0, m.x1Scale, m.y1Scale)
Else
* Following line moved; does not apply to case m.ln3D = 0
m.y1Scale = m.y1Scale + 1
Local laPolygon(4)
m.laPolygon(1) = .Point.New(m.x1Scale, m.y0)
m.laPolygon(2) = .Point.New(m.x1Scale, m.y1Scale)
m.laPolygon(3) = .Point.New(m.x1Scale - m.ln3D, m.y1Scale + m.ln3D)
m.laPolygon(4) = .Point.New(m.x1Scale - m.ln3D, m.y0 + m.ln3D)
Local loZeroBrush As xfcSolidBrush
m.loZeroBrush = .SolidBrush.New(.Color.FromARGB(64, This.ScaleLineZeroColor))
m.loGfx.FillPolygon(m.loZeroBrush, @m.laPolygon)
m.loGfx.DrawPolygon(m.loZeroPen, @m.laPolygon)
Endif
Endwith
Endif
Endif
Endfor
Endif
Return
ENDPROC
PROCEDURE _drawshape
LPARAMETERS tnX, tnY, tnValue, tcObjType, luShape, tnBartype
LOCAL lnX1, lnY1, loRect, luShape, lcType, lnIndex, lnTipPixels, lnColor, loGfx AS xfcGraphics, loObject AS OBJECT
lnTipPixels = THIS._TipPixels
lnIndex = THIS._ChartIndex
tnBartype = EVL(tnBartype,0)
IF EMPTY(tcObjType)
tcObjType = "Rect"
ENDIF
IF THIS.BrushType = 3 && Monochrome
lnColor = 0
ELSE
lnColor = EVL(THIS.aColors(lnIndex),0)
ENDIF
DO CASE
CASE VARTYPE(luShape)='O'
CASE NOT EMPTY(THIS.LineCapsShape)
luShape = THIS.LineCapsShape
OTHER
luShape = THIS.FIELDS(lnIndex).SHAPE
ENDCASE
lcType = VARTYPE(luShape)
m.loGfx = THIS.oGfx
DO CASE
CASE lcType = "N" OR lcType = "O" && Graphics path using predefined Shape
LOCAL loPath AS xfcGraphicsPath, lnWidth, lnHeight, loBrush AS xfcSolidBrush, loAdjPath AS xfcGraphicsPath, loMatrix AS xfcMatrix
IF VARTYPE(THIS._aShapes(lnIndex, 1)) = "O"
m.loPath = THIS._aShapes(lnIndex, 1)
ELSE
IF lcType = "O"
loPath = luShape.CLONE()
THIS._CenterPath(loPath, .T.)
ELSE
loPath = THIS._GetShapePath(luShape)
THIS._CenterPath(loPath, .T.)
ENDIF
ENDIF
loRect = loPath.GetBounds()
lnWidth = loRect.WIDTH
lnHeight = loRect.HEIGHT
loBrush = .SolidBrush.New(.COLOR.FromRGB(lnColor))
loAdjPath = loPath.CLONE()
loMatrix = _SCREEN.SYSTEM.Drawing.Drawing2D.Matrix.New()
loMatrix.Translate(tnX, tnY)
loAdjPath.TRANSFORM(loMatrix)
THIS.FillPathDim(loBrush, loAdjPath)
lnX1 = tnX - (m.lnWidth / 2)
lnY1 = tnY - (lnHeight / 2)
loObject = loPath
CASE lcType = "C" && Image File
LOCAL loBmp AS xfcBitmap, lnWidth, lnHeight
IF VARTYPE(THIS._aShapes(lnIndex, 1)) = "O"
loBmp = THIS._aShapes(lnIndex, 1)
lnWidth = THIS._aShapes(lnIndex, 2)
lnHeight = THIS._aShapes(lnIndex, 3)
ELSE
loBmp = _SCREEN.SYSTEM.Drawing.BITMAP.FromVarbinary(FILETOSTR(luShape))
lnWidth = loBmp.WIDTH
lnHeight = loBmp.HEIGHT
ENDIF
lnX1 = tnX - (m.lnWidth /2)
lnY1 = tnY - (lnHeight /2)
m.loGfx.DrawImage(loBmp, lnX1, lnY1)
loObject = loBmp
OTHERWISE
ENDCASE
* Fix by Anal Roy Chowdhurry
IF NOT (THIS.LineCaps AND INLIST(This.ChartType, 5, 18)) AND tnBartype#7
THIS._UpdateCoordinates(,tcObjType, lnX1, lnY1, m.lnWidth, lnHeight, tnValue)
ENDIF
* End of Revision new checking
THIS._aShapes(lnIndex, 1) = loObject
THIS._aShapes(lnIndex, 2) = lnWidth
THIS._aShapes(lnIndex, 3) = lnHeight
ENDPROC
PROCEDURE _drawsidelegends
**!* Property LegendPosition
*!* Numeric,
*!* Determines the position where the side legend wiil be drawn in the canvas.
*1* 0 - No Legend
*!* 1 - Vertical Top Left
*!* 2 - Vertical Bottom Left
*!* 3 - Vertical Top Right
*!* 4 - Vertical Bottom Right
*!* 5 - Horiz Top Left
*!* 6 - Horiz Top Center
*!* 7 - Horiz Top Right
*!* 8 - Horiz Bottom Left
*!* 9 - Horiz Bottom Center
*!* 10 - Horiz Bottom Right
*!* 11 - Vertical Center Left
*!* 12 - Vertical Center Right
LOCAL lcCaption, llHorizontal, lnWidth, lnHeight, lnX1, lnY1, ;
lnAvailableHeight, lnChart, lnCount, lnExternalMargin, lnLegendHeight, lnLength, lnMargin, lnNeededHeight, lnOrigAlignment, lnOrigIndex, lnPosition, lnStart, lnTopMargin, lnVertHeight
m.lnPosition = THIS.LegendPosition
IF NOT THIS.ShowSideLegend OR m.lnPosition = 0
RETURN
ENDIF
* Force left alignment for the side legend - this value will be restored at the end of this method
m.lnOrigAlignment = THIS.SideLegend.ALIGNMENT
THIS.SideLegend.ALIGNMENT = 0 && Left
THIS._InLegend = .T.
m.llHorizontal = INLIST(m.lnPosition, 5, 6, 7, 8, 9, 10) && Horizontal Top or Bottom
m.lnLegendHeight = THIS.SideLegend._Height
m.lnExternalMargin = THIS._LegendExternalMargin
m.lnCount = ALEN(THIS._aSideLegends, 1)
IF this.ChartType=17
m.lnCount = MIN(2,m.lnCount)
ENDIF
m.lnTopMargin = THIS.MarginTop + THIS.MARGIN + THIS._TitleHeight
WITH _SCREEN.SYSTEM.Drawing
* Check if we have enough space for legends
m.lnAvailableHeight = THIS.ChartCanvas.HEIGHT - m.lnTopMargin - THIS.MARGIN
m.lnNeededHeight = (m.lnCount * m.lnLegendHeight) + (THIS.MARGIN * m.lnCount - 1)
IF m.lnNeededHeight > m.lnAvailableHeight
* Recalculate the Margin
m.lnMargin = (m.lnAvailableHeight - (m.lnCount * m.lnLegendHeight)) / m.lnCount
ELSE
m.lnMargin = 3
ENDIF
STORE m.lnLegendHeight TO m.lnWidth, m.lnHeight
m.lnLegendHeight = m.lnLegendHeight + MIN(m.lnMargin, m.lnLegendHeight / 2)
m.lnVertHeight = m.lnCount * m.lnLegendHeight
DO CASE
CASE m.lnPosition = 1 && Vertical Top Left Side
m.lnX1 = THIS.MARGIN + THIS.MarginLeft + m.lnExternalMargin
m.lnY1 = m.lnTopMargin
CASE m.lnPosition = 2 && Vertical Bottom Left Side
m.lnX1 = THIS.MARGIN + THIS.MarginLeft + m.lnExternalMargin
m.lnY1 = THIS.ChartCanvas.HEIGHT - THIS.MarginBottom - THIS.MARGIN - m.lnVertHeight
CASE m.lnPosition = 11 && Vertical Center Left Side
m.lnX1 = THIS.MARGIN + THIS.MarginLeft + m.lnExternalMargin
m.lnY1 = (THIS.ChartCanvas.HEIGHT - THIS.MarginBottom - m.lnTopMargin - m.lnVertHeight) / 2 + m.lnTopMargin
CASE m.lnPosition = 3 && Vertical Top Right Side (Default)
m.lnX1 = THIS.ChartCanvas.WIDTH - THIS._RightOffset + m.lnExternalMargin + THIS._Axis2ScaleWidth
m.lnY1 = m.lnTopMargin
CASE m.lnPosition = 4 && Vertical Bottom Right Side (Default)
m.lnX1 = THIS.ChartCanvas.WIDTH - THIS._RightOffset + m.lnExternalMargin + THIS._Axis2ScaleWidth
m.lnY1 = THIS.ChartCanvas.HEIGHT - THIS.MarginBottom - THIS.MARGIN - m.lnVertHeight
CASE m.lnPosition = 12 && Vertical Center Right Side
m.lnX1 = THIS.ChartCanvas.WIDTH - THIS._RightOffset + m.lnExternalMargin + THIS._Axis2ScaleWidth
m.lnY1 = (THIS.ChartCanvas.HEIGHT - THIS.MarginBottom - m.lnTopMargin - m.lnVertHeight) / 2 + m.lnTopMargin
CASE m.llHorizontal && Horizontal Top or Bottom
* Calculate the whole legends width in order to obtain the starting point
STORE 0 TO m.lnLength, m.lnStart
* Obtain the needed width for the whole horizontal legend
FOR m.lnChart = 1 TO m.lnCount
THIS.SideLegend.CAPTION = THIS._aSideLegends(m.lnChart,1)
m.lnLength = m.lnLength + m.lnWidth + 10 + THIS.SideLegend._Width
NEXT
DO CASE
CASE INLIST(m.lnPosition, 5, 8) && Left aligned
&& do nothing
CASE INLIST(m.lnPosition, 6, 9) && Center
m.lnStart = THIS._LeftOffset + (THIS.ChartCanvas.WIDTH - THIS._LeftOffset - THIS._RightOffset - m.lnLength) / 2
CASE INLIST(m.lnPosition, 7, 10) && Right
m.lnStart = THIS.ChartCanvas.WIDTH - THIS._RightOffset - m.lnLength
ENDCASE
m.lnX1 = THIS._LeftOffset + m.lnStart
IF INLIST(m.lnPosition , 5, 6, 7) && Horizontal Top
m.lnY1 = m.lnTopMargin + m.lnExternalMargin
ELSE && Horizontal Bottom
m.lnY1 = THIS.ChartCanvas.HEIGHT - THIS._LegendHeight - THIS.MARGIN - THIS.MarginBottom + THIS._LegendExternalMargin
ENDIF
ENDCASE
LOCAL loLinePen AS xfcPen
* Save the current _CharIndex
m.lnOrigIndex = THIS._ChartIndex
FOR m.lnChart = 1 TO m.lnCount
IF m.lnY1 <= 0
EXIT
ENDIF
THIS._ChartIndex = m.lnChart
m.lcCaption = THIS._aSideLegends(m.lnChart,1)
IF EMPTY(m.lcCaption)
LOOP
ENDIF
THIS.SideLegend.CAPTION = m.lcCaption
THIS.SideLegend._DrawString(m.lnX1 + m.lnWidth + 3, m.lnY1)
THIS._UpdateCoordinates(,"Legend", m.lnX1, m.lnY1, m.lnWidth + THIS.SideLegend._Width + 5, m.lnLegendHeight, m.lnChart, m.lcCaption)
DO CASE
CASE INLIST(THIS.ChartType, 5, 18) ;
AND THIS._3D = 0 ;
AND THIS.BrushType = 3 ; && Line, Plain, Monochrome
AND NOT THIS.Multichart
m.loLinePen = .PEN.New(THIS._oClrBlack, 3)
m.loLinePen.DashStyle = m.lnChart - 1 && _Screen.System.Drawing.Drawing2D.DashStyle.Dash
THIS.oGfx.DrawLine(m.loLinePen, m.lnX1, m.lnY1 + m.lnHeight / 2, m.lnX1 + m.lnWidth, m.lnY1 + m.lnHeight / 2)
CASE (THIS.ChartType = 4 ; && Point
OR (INLIST(THIS.ChartType, 5, 18) AND THIS._3D = 0 AND THIS.LineCaps)) ; && Plain line
AND NOT THIS.Multichart
LOCAL loPath AS xfcGraphicsPath
m.loPath = THIS._aShapes(m.lnChart,1)
IF VARTYPE(m.loPath) <> "O"
RETURN
ENDIF
IF INLIST(LOWER(m.loPath.CLASS),"xfcbitmap", "xfcimage")
THIS.oGfx.DrawImage(m.loPath, m.lnX1, m.lnY1, m.lnWidth, m.lnHeight)
ELSE
THIS._DrawShape(m.lnX1 + m.lnWidth / 2, m.lnY1 + m.lnHeight / 2, 0, "Legend")
IF THIS._aShapes(m.lnChart,3) > m.lnLegendHeight
m.lnLegendHeight = THIS._aShapes(m.lnChart,3) + 1
* m.lnY1 = m.lnY1 + This._aShapes(m.lnChart,3) + 3
ENDIF
ENDIF
OTHERWISE
THIS._PrepareBrushes(m.lnX1, m.lnY1, m.lnWidth, m.lnHeight, .T., m.lnChart, .T.) && 7-th parameter. Avoid GradientShapeDirection>2. Yudin
THIS.oGfx.FillRectangle(THIS._oMainBrush, m.lnX1, m.lnY1, m.lnWidth, m.lnHeight)
THIS.oGfx.DrawRectangle(THIS._oBorderPen, m.lnX1, m.lnY1, m.lnWidth, m.lnHeight)
ENDCASE
IF m.llHorizontal && Horizontal side legends
m.lnX1 = m.lnX1 + m.lnWidth + 10 + THIS.SideLegend._Width
ELSE
m.lnY1 = m.lnY1 + m.lnLegendHeight
ENDIF
NEXT
* Restore the current _CharIndex
THIS._ChartIndex = m.lnOrigIndex
ENDWITH
WITH THIS.SideLegend
.TOP = m.lnTopMargin
.LEFT = m.lnX1
.WIDTH = THIS._LegendWidth
.HEIGHT = MAX(0, m.lnY1 - m.lnTopMargin)
* Restore the alignment value to the original
.ALIGNMENT = m.lnOrigAlignment
ENDWITH
THIS._InLegend = .F.
ENDPROC
PROCEDURE _drawslice
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnStart, tnSweep, tnNativeValue, toShape
LOCAL llAdjLeft, llAdjRight, ln3D, lnFinalAngle, lnXBrush, lnYBrush
IF m.tnWidth <=0 OR m.tnHeight <=0
RETURN
ENDIF
WITH THIS
LOCAL loPen AS xfcPen, loGfx AS xfcGraphics, loMainBrush AS xfcBrush, lo3dBrush AS xfcBrush
._AdjustStartSweep(@tnStart, @tnSweep, m.tnWidth, m.tnHeight)
toShape = ._UpdateCoordinates(toShape, "Pie", m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnNativeValue, m.tnStart, m.tnSweep)
lcShapeName = TRANSFORM(toShape.CoordNum)
IF .PieEnhancedDrawing
lnXBrush = m.tnX
lnYBrush = m.tnY
ELSE
lnXBrush = 0
lnYBrush = 0
ENDIF
._PrepareBrushes(lnXBrush, lnYBrush, m.tnWidth, m.tnHeight, .F., RECNO())
m.loPen = ._oBorderPen
m.loGfx = .oGfx
m.loMainBrush = ._oMainBrush
lo3dBrush = ._o3DBrush
lnFinalAngle = m.tnStart + m.tnSweep
IF lnFinalAngle > 360
lnFinalAngle = lnFinalAngle - 360
ENDIF
m.ln3D = ._3D
ENDWITH
WITH _SCREEN.SYSTEM.Drawing
IF THIS.PieEnhancedDrawing
* Draw the 3D Slice using the GraphicsPath class
IF ln3D > 0 AND NOT THIS.SHADOW
x = m.tnX
Y = m.tnY
w = m.tnWidth
h = m.tnHeight
* Draw the bottom slice
m.loGfx.FillPie(m.loMainBrush, x, Y + m.ln3D, w, h, m.tnStart, m.tnSweep)
m.loGfx.DrawPie(m.loPen, x, Y, w, h, m.tnStart, m.tnSweep)
* Get the start point
LOCAL loPath AS xfcGraphicsPath, loPoint1 AS xfcPoint, loPoint2 AS xfcPoint
loPath = _SCREEN.SYSTEM.Drawing.Drawing2D.GraPHICSPATH.New()
loPath.AddPie(x,Y,w,h, m.tnStart, 0.0001)
loPoint1 = loPath.GetLastpoint()
loPath.AddPie(x,Y,w,h, m.tnStart, m.tnSweep)
loPoint2 = loPath.GetLastpoint()
* Draw side Polygon 1
LOCAL laPointsA(4), laPointsB(4), lnCenterX, lnCenterY
lnCenterX = x + (w/2)
lnCenterY = Y + (h/2)
laPointsA(1) = .POINT.New(lnCenterX, lnCenterY)
laPointsA(2) = .POINT.New(lnCenterX, lnCenterY + m.ln3D)
laPointsA(3) = .POINT.New(loPoint1.x, loPoint1.Y + m.ln3D)
laPointsA(4) = loPoint1
* Draw side Polygon 2
laPointsB(1) = laPointsA(1)
laPointsB(2) = laPointsA(2)
laPointsB(3) = .POINT.New(loPoint2.x, loPoint2.Y + m.ln3D)
laPointsB(4) = loPoint2
IF m.tnStart <= 90 OR m.tnStart > 270
m.loGfx.DrawPolygon(m.loPen, @laPointsA)
m.loGfx.FillPolygon(lo3dBrush, @laPointsA)
ENDIF
IF lnFinalAngle < 270 AND lnFinalAngle > 90
m.loGfx.FillPolygon(lo3dBrush, @laPointsB)
m.loGfx.DrawPolygon(m.loPen, @laPointsB)
ENDIF
* Draw the external 3d Face
LOCAL loPath2 AS xfcGraphicsPath
loPath2 = _SCREEN.SYSTEM.Drawing.Drawing2D.GraPHICSPATH.New()
loPath2.FillMode = _SCREEN.SYSTEM.Drawing.Drawing2D.FillMode.winding
loPath2.StartFigure()
LOCAL lnAdjStart, lnAdjSweep
lnAdjStart = m.tnStart
lnAdjSweep = m.tnSweep
IF m.tnStart >= 270 AND ;
m.tnStart < 360 AND ;
BETWEEN(lnFinalAngle, 0, 270)
llAdjRight = .T.
* Create a new partial path for the 1st part
LOCAL loPath3 AS xfcGraphicsPath
loPath3 = _SCREEN.SYSTEM.Drawing.Drawing2D.GraPHICSPATH.New()
loPath3.StartFigure()
loPath3.AddArc(x,Y,w,h, m.tnStart, 360 - m.tnStart)
loPath3.Reverse()
loPath3.ADDLINE(loPoint1.x, loPoint1.Y, loPoint1.x, loPoint1.Y + m.ln3D)
loPath3.AddArc(x,Y + m.ln3D, w, h, m.tnStart, 360 - m.tnStart)
loPath3.ADDLINE(m.tnX + m.tnWidth, lnCenterY + m.ln3D, m.tnX + m.tnWidth, lnCenterY)
THIS.FillPathDim(lo3dBrush, loPath3)
m.loGfx.DrawPath(m.loPen, loPath3)
loPoint1 = .POINT.New(m.tnX + m.tnWidth, lnCenterY)
lnAdjStart = 0
lnAdjSweep = m.tnSweep - (360 - m.tnStart)
ENDIF
IF (m.tnStart < 180 AND lnFinalAngle > 180) OR ;
(m.tnStart >= 270 AND lnFinalAngle > 180 AND lnFinalAngle < 270.01)
* IF (m.tnStart < 180 AND lnFinalAngle > 180) OR ;
(m.tnStart >= 270 AND lnFinalAngle > 180 AND lnFinalAngle < 269.9999)
llAdjLeft = .T.
* Create a new partial path for the 1st part
LOCAL loPath4 AS xfcGraphicsPath
loPath4 = _SCREEN.SYSTEM.Drawing.Drawing2D.GraPHICSPATH.New()
loPath4.StartFigure()
IF m.tnStart >= 270
lnAdjStart = 0
lnAdjSweep = 180
ELSE
lnAdjStart = m.tnStart
lnAdjSweep = 180 - m.tnStart
ENDIF
loPath4.AddArc(x,Y,w,h, lnAdjStart, lnAdjSweep)
loPath4.Reverse()
loPath4.ADDLINE(loPoint1.x, loPoint1.Y, loPoint1.x, loPoint1.Y + m.ln3D)
loPath4.AddArc(x,Y + m.ln3D, w, h, lnAdjStart, lnAdjSweep)
loPath4.ADDLINE(m.tnX, lnCenterY + m.ln3D, m.tnX, lnCenterY)
THIS.FillPathDim(lo3dBrush, loPath4)
m.loGfx.DrawPath(m.loPen, loPath4)
loPoint1 = .POINT.New(m.tnX, lnCenterY)
lnAdjStart = 180
lnAdjSweep = lnFinalAngle - 180
ENDIF
loPath2.AddArc(x,Y,w,h, lnAdjStart, lnAdjSweep)
loPath2.Reverse()
loPath2.ADDLINE(loPoint1.x, loPoint1.Y, loPoint1.x, loPoint1.Y + m.ln3D)
loPath2.AddArc(x,Y + m.ln3D, w, h, lnAdjStart, lnAdjSweep)
loPath2.ADDLINE(loPoint2.x, loPoint2.Y + m.ln3D, loPoint2.x, loPoint2.Y)
THIS.FillPathDim(lo3dBrush, loPath2)
m.loGfx.DrawPath(m.loPen, loPath2)
IF m.tnStart > 90 AND m.tnStart < 270
m.loGfx.DrawPolygon(m.loPen, @laPointsA)
m.loGfx.FillPolygon(lo3dBrush, @laPointsA)
ENDIF
IF lnFinalAngle > 270 OR lnFinalAngle <= 90
m.loGfx.FillPolygon(lo3dBrush, @laPointsB)
m.loGfx.DrawPolygon(m.loPen, @laPointsB)
ENDIF
* Draw the top slice
m.loGfx.FillPie(m.loMainBrush, x, Y, w, h, m.tnStart, m.tnSweep)
m.loGfx.DrawPie(m.loPen, x, Y, w, h, m.tnStart, m.tnSweep)
ELSE
* Draw shadow
IF THIS.SHADOW
LOCAL loShadowBrush AS xfcSolidBrush
m.loShadowBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel,128,128,128))
m.loGfx.FillPie(loShadowBrush, m.tnX, m.tnY + ln3D, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
ENDIF
* Draw the main slice
m.loGfx.FillPie(m.loMainBrush, m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
m.loGfx.DrawPie(m.loPen, m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
ENDIF
ELSE
*** This is the old behavior for Pie slices
LOCAL loBmp AS xfcBitmap
loBmp = poTempBmp
LOCAL loTempGfx AS xfcGraphics
loTempGfx = .Graphics.FromImage(loBmp)
loTempGfx.CLEAR(.COLOR.Transparent)
loTempGfx.SmoothingMode = .Drawing2D.SmoothingMode.AntiAlias
* Draw the 3D Slice using the Hatch Brush
IF ln3D > 0
LOCAL lnY1, N
lnY1 = m.ln3D
* Draw the contour of the 3D Slice
loTempGfx.FillPie(m.loMainBrush, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
loTempGfx.DrawPie(m.loPen, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
FOR N = 1 TO m.ln3D
lnY1 = lnY1 - 1
* Draw the Normal Slice using the Solid Brush
loTempGfx.FillPie(lo3dBrush, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep) && draw the slice
IF m.tnStart > 90
loTempGfx.DrawArc(m.loPen, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart, 0.25)
ENDIF
loTempGfx.DrawArc(m.loPen, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart + m.tnSweep - .25, 0.35)
NEXT
loTempGfx.FillPie(m.loMainBrush, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep) && draw the slice
* Draw border line from center of pie
LOCAL lnX, lnY
lnX = (m.tnWidth / 2)
lnY = (m.tnHeight / 2) + lnY1
IF m.tnStart > 90
loTempGfx.DrawLine(m.loPen, lnX, lnY, lnX, lnY + m.ln3D)
ENDIF
loTempGfx.DrawPie(m.loPen, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
loTempGfx.FillPie(m.loMainBrush, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
loTempGfx.DrawPie(m.loPen, 0, lnY1, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
* Draw the Image
loBmp.ApplyColorMatrix(poClrMatrix)
m.loGfx.DrawImage(loBmp, m.tnX, m.tnY)
ELSE
m.loGfx.FillPie(m.loMainBrush, m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
m.loGfx.DrawPie(m.loPen, m.tnX, m.tnY, m.tnWidth, m.tnHeight, m.tnStart, m.tnSweep)
ENDIF
ENDIF
ENDWITH
ENDPROC
PROCEDURE _drawstackedareachart
* Generates Stacked and Full-Stacked area Charts (ChartTypes and 16)
WITH THIS
SELECT (._DataCursor )
LOCAL lnIndex, lnMargin, lnWidth, lnHeight, lnValue, lnRecs, lnBetween, lnRec, lnChartsCount,;
lnLine, lnMaxValue, lnPointHeight, ln3D, lnYBase, lnTipPixels, lnX1, lnY1, lnTipPixels, llMultiChart
llMultiChart = .F.
lnTipPixels = ._TipPixels
lnMargin = .MARGIN
m.ln3D = ._3D
lnRecs = RECCOUNT()
lnChartsCount = .ChartsCount
* Calculate the maximum width of the chart
lnHeight = .ChartCanvas.HEIGHT - ._XAxisHeight - ._TopOffSet - ._3D
m.lnWidth = .ChartCanvas.WIDTH - ._YAxisWidth - ._LeftOffset - ln3D - ._RightOffset
IF m.lnWidth < 10 OR m.lnHeight < 10 OR lnRecs < 2
RETURN
ENDIF
LOCAL loGfx AS xfcGraphics
m.loGfx = .oGfx
* Get the maximum value of the chart
lnMaxValue = ._ScaleRange
* Get the lower Y point
lnYBase = .ChartCanvas.HEIGHT - ._XAxisHeight
* If MultiChart mode, the chart needs to start half a position further
IF llMultiChart
lnBetween = m.lnWidth / (lnRecs)
ELSE
lnBetween = m.lnWidth / (lnRecs - 1)
ENDIF
* Prepare array of points
* All the main points will be defined here
LOCAL laPointsX(lnRecs), laPointsY(lnRecs, lnChartsCount), laPointsYAV(lnRecs, lnChartsCount) ;
, lnPrevPoint, lnTotRow, laValues(lnChartsCount) ;
, laPointsI(lnRecs, lnChartsCount) && Points Index
FOR .ROW = 1 TO RECCOUNT()
lnRec = .Row
lnPrevPoint = 0
lnX1 = ._YAxisWidth + (lnBetween * (lnRec - 1)) + IIF(llMultiChart, (lnBetween / 2), 0) + ._LeftOffset && lnMargin
laPointsX(lnRec) = lnX1
._aPoints(lnRec,1) = lnX1 + ln3D
m.lnTotRow = 0
* Get the total for the current row
FOR .COLUMN = 1 TO .ChartsCount
.GetValue()
laValues(.Column) =.Value
m.lnTotRow = m.lnTotRow + .Value
NEXT
FOR .COLUMN = 1 TO .ChartsCount
m.lnValue = laValues(THIS.COLUMN)
._ChartIndex = .Column
IF .ChartType = 16 && Full-stacked Area
lnPointHeight = IIF( EMPTY( m.lnTotRow ), 0, lnValue / m.lnTotRow * lnHeight)
ELSE
lnPointHeight = lnValue / lnMaxValue * lnHeight
ENDIF
lnY1 = lnYBase - (lnPointHeight + lnPrevPoint)
laPointsY(lnRec, .Column) = lnY1
laPointsYAV(lnRec, .Column)= lnYBase - (lnPointHeight / 2 + lnPrevPoint)
lnPrevPoint = lnPointHeight + lnPrevPoint
IF lnValue = 0
._UpdateCoordinates(,"Rect", 0, 0, 0, 0, lnValue, lnTotRow)
ELSE
._UpdateCoordinates(,"Rect", lnX1 - lnTipPixels/2, lnY1, lnTipPixels, lnPointHeight, lnValue, lnTotRow)
ENDIF
laPointsI(lnRec,.Column) = ._nIndex
NEXT
NEXT
* Draw the vertical line only for the first line
._DrawVerticalLineBack()
LOCAL laMainPolygon(lnRecs * 2), laLinePolygon(4), laSidePolygon(4), lnCompl, loBrush AS xfcBrush
m.loBrush = IIF( .BrushType = 1,"This._o3dbrush", "This._oMainBrush")
ENDWITH
WITH _SCREEN.SYSTEM.Drawing
FOR THIS.COLUMN = 1 TO THIS.ChartsCount
* Fill the main polygon
FOR lnRec = 1 TO lnRecs
lnCompl = (lnRecs * 2) - lnRec + 1
laMainPolygon(lnRec) = .POINT.New(laPointsX(lnRec), laPointsY(lnRec, THIS.Column))
IF THIS.Column = 1
laMainPolygon(lnCompl) = .POINT.New(laPointsX(lnRec), lnYBase)
ELSE
laMainPolygon(lnCompl) = .POINT.New(laPointsX(lnRec), laPointsY(lnRec, THIS.Column-1))
ENDIF
NEXT
THIS._PrepareBrushes(0,0,THIS.ChartCanvas.WIDTH, THIS.ChartCanvas.HEIGHT, .F., THIS.Column)
m.loGfx.FillPolygon(THIS._oMainBrush, @laMainPolygon)
m.loGfx.DrawPolygon(THIS._oBorderPen, @laMainPolygon)
IF m.ln3D > 0
* Draw the 3D line above the main polygon
FOR lnRec = 1 TO lnRecs - 1
laLinePolygon(1) = laMainPolygon(lnRec)
laLinePolygon(2) = .POINT.New(laMainPolygon(lnRec).X + m.ln3D, laMainPolygon(lnRec).Y - m.ln3D)
laLinePolygon(3) = .POINT.New(laMainPolygon(lnRec+1).X + m.ln3D, laMainPolygon(lnRec+1).Y - m.ln3D)
laLinePolygon(4) = laMainPolygon(lnRec+1)
THIS._PrepareBrushes(laMainPolygon(lnRec).X, laMainPolygon(lnRec).Y - m.ln3D, ;
laMainPolygon(lnRec+1).X + m.ln3D - laMainPolygon(lnRec).X, ;
MAX(2,ABS(laMainPolygon(lnRec).Y - laMainPolygon(lnRec+1).Y)), .F., THIS.Column)
m.loGfx.FillPolygon(EVALUATE(m.loBrush), @laLinePolygon)
m.loGfx.DrawPolygon(THIS._oBorderPen, @laLinePolygon)
NEXT
* Fill the right-most external side of the area
* Draw the last 3D polygon, to fill the Area
laSidePolygon(1) = laLinePolygon(3)
laSidePolygon(2) = laLinePolygon(4)
laSidePolygon(3) = laMainPolygon(lnRecs + 1)
laSidePolygon(4) = .POINT.New(laSidePolygon(3).X + m.ln3D, laSidePolygon(3).Y - m.ln3D)
THIS._PrepareBrushes(laSidePolygon(2).X, laSidePolygon(1).Y, ;
m.ln3D, 2, .F., THIS.Column)
m.loGfx.FillPolygon(EVALUATE(m.loBrush), @laSidePolygon)
m.loGfx.DrawPolygon(THIS._oBorderPen, @laSidePolygon)
ENDIF
NEXT
* Adjust _aPoints Array to show the information in the correct position
FOR lnRec = 1 TO lnRecs
THIS._aPoints(lnRec,1) = THIS._aPoints(lnRec,1) - ln3D
NEXT
IF THIS.ShowValuesOnShapes
FOR lnLine = 1 TO lnChartsCount
IF TYPE('THIS.FIELDS(lnLine).ShowValuesOnShape') = 'U' OR THIS.FIELDS(lnLine).ShowValuesOnShape
*** Draw Legends above the points
FOR lnRec = 1 TO lnRecs
lnX1 = laPointsX(lnRec)
lnY1 = laPointsYAV(lnRec, lnLine)
lnIndex = laPointsI(lnRec,lnLine)
THIS._DrawShapeLegend(lnX1, lnY1, lnIndex)
NEXT
ENDIF
NEXT
ENDIF
THIS._DrawXAxisLegend()
ENDWITH
ENDPROC
PROCEDURE _drawtrianglebar
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnValue, tn3D
LOCAL loGfx AS xfcGraphics, loTopBrush AS xfcBrush, loBotBrush AS xfcBrush ;
,lnColor, ln3D, loPen AS xfcPen, lnAlpha, lnOrigAlpha, loShape
m.loGfx = THIS.oGfx
lnOrigAlpha = THIS.AlphaChannel
lnAlpha = MIN(255, (THIS.AlphaChannel * 1.25))
THIS.AlphaChannel = lnAlpha
THIS._PrepareBrushes(m.tnX, m.tnY, m.tnWidth, m.tnHeight, .F., IIF(THIS.SingleData, RECNO(),THIS._ChartIndex))
WITH _SCREEN.SYSTEM.Drawing
m.lnColor = THIS.ChangeColor(THIS._nColor, + 60)
m.loPen = .PEN.New(.COLOR.FromRGB(lnColor))
m.ln3D = MAX(IIF(VARTYPE(tn3D)='N',tn3D,THIS._3d), 1)
DO CASE
CASE THIS.BrushType = 1 && SolidColors
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, - 20)))
loBotBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
loLeftBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(THIS._nColor, - 20)))
loRightBrush = THIS._oMainBrush
CASE THIS.BrushType = 2 && Gradient
loTopBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS._nColor))
loBotBrush = loTopBrush
loLeftBrush = loTopBrush
loRightBrush = THIS._oMainBrush
CASE THIS.BrushType = 4 && <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
loTopBrush = THIS._o3DBrush
loBotBrush = loTopBrush
loLeftBrush = loTopBrush
loRightBrush = THIS._oMainBrush
OTHERWISE
THIS._PrepareBrushes(tnX, tnY, tnWidth, tnHeight, .F., IIF(THIS.SingleData OR THIS.ChartsCount = 1, RECNO(),THIS._ChartIndex))
loTopBrush = THIS._oMainBrush
loBotBrush = loTopBrush
loLeftBrush = loTopBrush
loRightBrush = THIS._oMainBrush
ENDCASE
THIS.AlphaChannel = lnOrigAlpha
IF THIS._Orientation = 1 && Vertical
LOCAL lnCenterX, x0, x1
x0 = tnX + m.ln3D / 2
x1 = x0 + tnWidth
lnCenterX = x0 + (tnWidth / 2)
* Prepare the bottom triangle
LOCAL yBott
yBott = tnY + tnHeight
LOCAL laBotPoints(3), laLeftPoints(4)
laBotPoints(1) = .POINT.New(lnCenterX, yBott)
laBotPoints(2) = .POINT.New(x0, yBott - m.ln3D)
laBotPoints(3) = .POINT.New(x1, yBott - m.ln3D)
m.loGfx.FillPolygon(loBotBrush, @laBotPoints)
m.loGfx.DrawPolygon(m.loPen, @laBotPoints)
* Prepare the top triangle
LOCAL laTopPoints(3)
laTopPoints(1) = .POINT.New(lnCenterX, tnY)
laTopPoints(2) = .POINT.New(x0, tnY - m.ln3D)
laTopPoints(3) = .POINT.New(x1, tnY - m.ln3D)
LOCAL loPath AS xfcGraphicsPath
loPath = .Drawing2D.GraphicsPath.New()
loPath.FillMode = .Drawing2D.FillMode.ALTERNATE
loPath.StartFigure()
loPath.ADDLINE(lnCenterX, tnY, x0, tnY - m.ln3D)
loPath.ADDLINE(x0, tnY - m.ln3D, x1, tnY - m.ln3D)
loPath.ADDLINE(x1, tnY - m.ln3D, lnCenterX, tnY)
loTopBrush=_Screen.FoxChartsHelper.PathGradient( , m.loPath, THIS._nColor,-1, m.lnCenterX, tnY - m.ln3D/2,,,THIS.AlphaChannel)
m.loGfx.FillPolygon(loTopBrush, @laTopPoints)
m.loGfx.DrawPolygon(m.loPen, @laTopPoints)
* Prepare the LEFT face of the 3d triangle (polygon)
laLeftPoints(1) = laTopPoints(1)
laLeftPoints(2) = laTopPoints(2)
laLeftPoints(3) = laBotPoints(2)
laLeftPoints(4) = laBotPoints(1)
m.loGfx.DrawPolygon(m.loPen, @laLeftPoints)
m.loGfx.FillPolygon(loLeftBrush, @laLeftPoints)
* Prepare the RIGHT face of the 3d triangle (polygon)
LOCAL laRightPoints(4)
laRightPoints(1) = laTopPoints(1)
laRightPoints(2) = laTopPoints(3)
laRightPoints(3) = laBotPoints(3)
laRightPoints(4) = laBotPoints(1)
m.loGfx.DrawPolygon(m.loPen, @laRightPoints)
m.loGfx.FillPolygon(loRightBrush, @laRightPoints)
TEXT TO lcPoints
<<ROUND(X0,0)>>,<<ROUND(m.yBott - m.ln3D,0)>>
<<ROUND(lnCenterX,0)>>,<<ROUND(m.yBott,0)>>
<<ROUND(X1,0)>>,<<ROUND(m.yBott - m.ln3D,0)>>
<<ROUND(X1,0)>>,<<ROUND(tnY - m.ln3D,0)>>
<<ROUND(X0,0)>>,<<ROUND(tnY - m.ln3D,0)>>
<<ROUND(X0,0)>>,<<ROUND(m.yBott - m.ln3D,0)>>
ENDTEXT
loShape = THIS._UpdateCoordinates(,"Rect", m.tnX + m.ln3D / 2, m.tnY, m.tnWidth, m.tnHeight, m.tnValue,,lcPoints)
ELSE && Horizontal
LOCAL lnCenterY, y0, ln3D
m.ln3D = MAX(THIS._3d, 1)
x0 = tnX
x1 = x0 + tnWidth
lnCenterY = tnY + tnHeight / 2
TEXT TO lcPoints
<<ROUND(X0 + ln3d,0)>>,<<ROUND(tnY,0)>>
<<ROUND(X0,0)>>,<<ROUND(m.lnCenterY,0)>>
<<ROUND(X0 + ln3d,0)>>,<<ROUND(m.tnY + tnHeight,0)>>
<<ROUND(X1 + ln3d,0)>>,<<ROUND(tnY + tnHeight,0)>>
<<ROUND(X1 + ln3d,0)>>,<<ROUND(tnY,0)>>
<<ROUND(X0 + ln3d,0)>>,<<ROUND(tnY,0)>>
ENDTEXT
loShape = THIS._UpdateCoordinates(,"Rect", m.tnX + m.ln3D / 2, m.tnY, m.tnWidth, m.tnHeight, m.tnValue,,lcPoints)
* Prepare the right (top) triangle
LOCAL laRightPoints(3)
laRightPoints(1) = .POINT.New(x1, lnCenterY)
laRightPoints(2) = .POINT.New(x1 + ln3D, tnY)
laRightPoints(3) = .POINT.New(x1 + ln3D, tnY + tnHeight)
m.loGfx.DrawPolygon(m.loPen, @laRightPoints)
m.loGfx.FillPolygon(loTopBrush, @laRightPoints)
* Prepare the Left triangle
LOCAL laLeftPoints(3)
laLeftPoints(1) = .POINT.New(x0, lnCenterY)
laLeftPoints(2) = .POINT.New(x0 + ln3D, tnY)
laLeftPoints(3) = .POINT.New(x0 + ln3D, tnY + tnHeight)
m.loGfx.DrawPolygon(m.loPen, @laLeftPoints)
m.loGfx.FillPolygon(loBotBrush, @laLeftPoints)
* Prepare the Top face of the 3d triangle (polygon)
LOCAL laTopPoints(4)
laTopPoints(1) = laLeftPoints(1)
laTopPoints(2) = laLeftPoints(2)
laTopPoints(3) = laRightPoints(2)
laTopPoints(4) = laRightPoints(1)
m.loGfx.DrawPolygon(m.loPen, @laTopPoints)
m.loGfx.FillPolygon(loLeftBrush, @laTopPoints)
* Prepare the BOTTOM face of the 3d triangle (polygon)
LOCAL laBotPoints(4)
laBotPoints(1) = laLeftPoints(1)
laBotPoints(2) = laLeftPoints(3)
laBotPoints(3) = laRightPoints(3)
laBotPoints(4) = laRightPoints(1)
m.loGfx.DrawPolygon(m.loPen, @laBotPoints)
m.loGfx.FillPolygon(loRightBrush, @laBotPoints)
ENDIF
* Draw the Values inside the shapes
THIS._DrawLegendinBar(x0, tnY, tnWidth, tnHeight, tnValue)
ENDWITH
ENDPROC
PROCEDURE _drawyaxis
LPARAMETERS tn3D, tnMinLeft, tnYAxisHeight, toBrush, toPen, tnIndex
LOCAL lcPoints, ;
ln3d, lnBottom, lnHeight, lnLeft, lnMaxValue, lnMinLeft, lnRight, lnScaleHeight, lnTop, lnX, lnX0, lnX1, lnXWidth, lnY, lnY0, lnY1, lnYAxisHeight, lnYaxisWidth, lnYaxisWidth2, ;
loBrush, loGfx, loPen
m.loBrush = m.toBrush
m.loPen = m.toPen
m.loGfx = THIS.oGfx
m.lnMinLeft = m.tnMinLeft
m.ln3d = m.tn3D
m.lnYAxisHeight = m.tnYAxisHeight
* DRAWING THE Y Axis
m.lnY0 = ROUND(THIS.ChartCanvas.HEIGHT - THIS._XAxisHeight,0)
m.lnY1 = ROUND(THIS._TopOffSet,0)
IF m.lnY0 - m.lnY1 < m.ln3d
RETURN
ENDIF
IF THIS.ShowAxis = .T.
* Draw the main Y Axis caption
IF tnIndex = 1
IF EMPTY(THIS.YAxis.CAPTION)
THIS._yAxisWidth = 0
ELSE
m.lnYaxisWidth = m.lnY0 - m.lnY1
IF m.lnYaxisWidth < 5 OR m.lnYAxisHeight < 5
RETURN
ENDIF
THIS._yAxisWidth = MAX(m.lnMinLeft, THIS.YAxis._Height + 3 + THIS._ScaleW)
THIS.YAxis.ROTATION = 270
THIS.YAxis._DrawString(THIS._LeftOffset, m.lnY1 + m.lnYaxisWidth, m.lnYaxisWidth, m.lnYAxisHeight)
lnLeft= INT(THIS._LeftOffset)
DO CASE
CASE THIS.YAxis.ALIGNMENT = 0
lnTop = INT(lnY1 + m.lnYaxisWidth - THIS.YAxis._Width)
CASE THIS.YAxis.ALIGNMENT = 1
lnTop = INT(lnY1)
OTHER
lnTop = INT(lnY1 + (m.lnYaxisWidth - THIS.YAxis._Width)/2)
ENDCASE
lnRight = INT(lnLeft + THIS.YAxis._Height)
lnBottom = INT(lnTop + THIS.YAxis._Width)
TEXT TO lcPoints
<<Round(lnLeft,0)>>,<<Round(lnTop,0)>>
<<Round(lnRight,0)>>,<<Round(lnTop,0)>>
<<Round(lnRight,0)>>,<<Round(lnbottom,0)>>
<<Round(lnLeft,0)>>,<<Round(lnbottom,0)>>
<<Round(lnLeft,0)>>,<<Round(lnTop,0)>>
ENDTEXT
THIS._UpdateCoordinates(,"YaxisCaption", lnLeft, lnTop, m.lnYAxisHeight, THIS.YAxis._Width, 0, THIS.YAxis.CAPTION, lcPoints)
ENDIF
ENDIF && tnIndex = 1
IF tnIndex = 2
IF EMPTY(THIS.YAxis2.CAPTION)
THIS._yAxisWidth2 = 0
ELSE
m.lnYaxisWidth2 = m.lnY0 - m.lnY1
IF m.lnYaxisWidth2 < 5 OR m.lnYAxisHeight < 5
RETURN
ENDIF
THIS.YAxis2.RESET()
THIS._yAxisWidth2 = THIS.YAxis2._Height && + THIS._ScaleW
THIS.YAxis2.ROTATION = 270
* Draw the main Y Axis2 caption
LOCAL lcYText2
m.lcYText2 = THIS.YAxis2.CAPTION
m.lnYAxisHeight = CEILING(THIS.YAxis2._Height)
m.lnX0 = THIS.ChartCanvas.WIDTH - THIS._RightOffset - m.ln3d - m.lnYAxisHeight + THIS._ScaleW2 + 6
THIS.YAxis2._DrawString( m.lnX0, m.lnY1 + m.lnYaxisWidth2, m.lnYaxisWidth2, m.lnYAxisHeight)
lnLeft= INT(lnX0)
DO CASE
CASE THIS.YAxis2.ALIGNMENT = 0
lnTop = INT(lnY1 + m.lnYaxisWidth2 - THIS.YAxis2._Width)
CASE THIS.YAxis.ALIGNMENT = 1
lnTop = INT(lnY1)
OTHER
lnTop = INT(lnY1 + (m.lnYaxisWidth2 - THIS.YAxis2._Width)/2)
ENDCASE
lnRight = INT(lnLeft + THIS.YAxis2._Height)
lnBottom = INT(lnTop + THIS.YAxis2._Width)
TEXT TO lcPoints
<<Round(lnLeft,0)>>,<<Round(lnTop,0)>>
<<Round(lnRight,0)>>,<<Round(lnTop,0)>>
<<Round(lnRight,0)>>,<<Round(lnbottom,0)>>
<<Round(lnLeft,0)>>,<<Round(lnbottom,0)>>
<<Round(lnLeft,0)>>,<<Round(lnTop,0)>>
ENDTEXT
THIS._UpdateCoordinates(,"Yaxis2Caption", lnLeft, lnTop, m.lnYAxisHeight, THIS.YAxis._Width, 0, THIS.YAxis.CAPTION, lcPoints)
ENDIF
ENDIF && tnIndex = 2
m.lnMaxValue = THIS._ScaleRange
WITH _SCREEN.SYSTEM.Drawing
* Draw the Y Axis
IF m.tnIndex = 2
m.lnX0 = THIS.ChartCanvas.WIDTH - THIS._RightOffset - m.ln3d + 2 - THIS._yAxisWidth2
ELSE
m.lnX0 = THIS._yAxisWidth + THIS._LeftOffset
ENDIF
m.lnX1 = m.lnX0 + m.ln3d + THIS._ScaleW
IF m.ln3d = 0
m.loGfx.DrawLine(m.loPen, m.lnX0 - 1, m.lnY0, m.lnX0 - 1, m.lnY1)
ELSE
LOCAL laPoints(4)
m.laPoints(1) = .POINT.New(m.lnX0, m.lnY0)
m.laPoints(2) = .POINT.New(m.lnX0, THIS._TopOffSet + m.ln3d)
m.laPoints(3) = .POINT.New(m.lnX0 + m.ln3d, THIS._TopOffSet)
m.laPoints(4) = .POINT.New(m.lnX0 + m.ln3d, m.lnY0 - m.ln3d)
m.loGfx.FillPolygon(m.loBrush, @m.laPoints)
m.loGfx.DrawPolygon(m.loPen, @m.laPoints)
LOCAL laPointsB(6)
m.laPointsB(1) = .POINT.New(m.lnX0, m.lnY0 + 4)
m.laPointsB(2) = .POINT.New(m.lnX0 - 4, m.lnY0 + 4)
m.laPointsB(3) = .POINT.New(m.lnX0 - 4, THIS._TopOffSet + m.ln3d)
m.laPointsB(4) = .POINT.New(m.lnX0 - 4 + m.ln3d, THIS._TopOffSet)
m.laPointsB(5) = .POINT.New(m.lnX0 + m.ln3d, THIS._TopOffSet)
m.laPointsB(6) = .POINT.New(m.lnX0, THIS._TopOffSet + m.ln3d)
m.loGfx.FillPolygon(m.loBrush, @m.laPointsB)
m.loGfx.DrawPolygon(m.loPen, @m.laPointsB)
TEXT to lcPoints
<<Round(lnX0,0)>>,<<Round(lnY0,0)>>
<<Round(lnX0,0)>>,<<Round(This._TopOffSet + m.ln3D,0)>>
<<Round(lnX0 + m.ln3D,0)>>,<<Round(This._TopOffSet,0)>>
<<Round(lnX0 + m.ln3D,0)>>,<<Round(lnY0 - m.ln3D,0)>>
<<Round(lnX0,0)>>,<<Round(lnY0,0)>>
ENDTEXT
THIS._UpdateCoordinates (, IIF(m.tnIndex=2,'RightSide','LeftSide'), lnx0, lny0, This._TopOffSet + m.ln3D, m.ln3D, '', 0, lcPoints, 0)
ENDIF
IF NOT EMPTY(THIS.BackImage) AND FILE(THIS.BackImage)
m.lnHeight = THIS.HEIGHT - THIS._XAxisHeight - THIS._TopOffSet - m.ln3d
lnXWidth = THIS.WIDTH - THIS._LeftOffset - THIS._RightOffset - THIS._yAxisWidth - m.ln3d
lnScaleHeight = (THIS.GetScaleValue (0)- THIS._MinScale) / m.lnMaxValue * lnHeight
lnY = THIS.HEIGHT - lnScaleHeight - THIS._XAxisHeight - m.ln3d
lnX = THIS._yAxisWidth + THIS._LeftOffset + m.ln3d
THIS.oGfx.DrawImage(_SCREEN.SYSTEM.Drawing.BITMAP.FromVarbinary(FILETOSTR(FULLPATH(THIS.BackImage))), lnX, lnY, lnXWidth, m.lnHeight)
ENDIF
ENDWITH
ENDIF
ENDPROC
PROCEDURE _getchartprop
LPARAMETERS toPropertiesList, tcProperty, tnType, toSavedProps, lcDescription, tlShowDescriptions
LOCAL lcCRLF
lcCRLF = CHR(13)
LOCAL lbChanged, lcNewType, lcOldType, lnBlue, lnDope, lnGreen, lnPos, lnRed
DO CASE
CASE tnType = 1
lbChanged = .T.
CASE tnType = 2
IF "." $ tcProperty
lnPos = RAT (".", tcProperty)
lbChanged = PEMSTATUS ( EVALUATE ("This." + LEFT(tcProperty, lnPos - 1)), SUBSTR(tcProperty, lnPos + 1), 0)
ELSE
lbChanged = PEMSTATUS(THIS, tcProperty, 5) AND PEMSTATUS(THIS, tcProperty, 0)
* lbChanged = Pemstatus (This, tcProperty, 0)
ENDIF
CASE tnType = 3
lcNewType = TYPE("toPropertiesList." + tcProperty)
lcOldType = TYPE("toSavedProps." + tcProperty)
lbChanged = (lcNewType # lcOldType) OR NOT ;
EVALUATE("toPropertiesList." + tcProperty) == EVALUATE("toSavedProps." + tcProperty)
ENDCASE
IF NOT lbChanged
RETURN ''
ENDIF
m.lcName = TRIM(tcProperty)
m.lxValue = EVALUATE ("toPropertiesList." + tcProperty)
m.lcType = VARTYPE (lxValue)
DO CASE
CASE m.lcType = 'C'
m.lxValue = TRIM(lxValue)
DO CASE
CASE NOT ['] $ m.lxValue
m.lcValue = ['] + m.lxValue + [']
CASE NOT ["] $ lxValue
m.lcValue = ["] + m.lxValue + ["]
OTHERWISE
m.lcValue = '[' + m.lxValue + ']'
ENDCASE
IF CHR(13)+CHR(10) $ lcValue
lcapostrophe1 = LEFT(lcValue,1)
lcapostrophe2 = RIGHT(lcValue,1)
m.lcValue = STRTRAN(m.lcValue, CHR(13)+CHR(10),[<<CHR(13)+CHR(10)>>]+ lcapostrophe2+'+ ;'+CHR(13)+CHR(10)+lcapostrophe1)
ENDIF
CASE m.lcType = "O"
m.lcValue = " " + CHR(38) + CHR(38) + "Custom object - " + m.lxValue.NAME
RETURN "* ." + m.lcName + " = " + m.lcValue + lcCRLF
CASE m.lcType = "N"
LOCAL lcUpName
lcUpName = UPPER(lcName)
lnDope = AT('***', lcDescription)
IF INLIST(ALLTRIM(RIGHT('.' + lcUpName,10)), ;
'.FORECOLOR', '.BACKCOLOR') OR ;
('BACKCOLOR2' $ lcUpName) OR ;
(').COLOR' $ lcUpName) OR ;
(lnDope > 0 AND "COLOR" == UPPER(ALLTRIM(SUBSTR(lcDescription, lnDope + 3))))
lnRed = BITAND(lxValue, 255)
lnGreen = BITRSHIFT(BITAND(lxValue, 256 * 255), 8)
lnBlue = BITRSHIFT(BITAND(lxValue, 256 * 256 * 255), 16)
m.lcValue = 'RGB(' + TRANSFORM(lnRed) + ',' + TRANSFORM(lnGreen) + ',' + TRANSFORM(lnBlue) + ')'
ELSE
m.lcValue = TRANSFORM(m.lxValue)
ENDIF
OTHERWISE
m.lcValue = TRANSFORM(m.lxValue)
ENDCASE
RETURN IIF (EMPTY (lcDescription) OR NOT tlShowDescriptions, '', '* ' + lcDescription + lcCRLF) + "." + m.lcName + " = " + m.lcValue + lcCRLF
ENDPROC
PROCEDURE _getchartproperties
****************************************************************
* Jim Nelson 10/20/2008
*
* Returns an object with current settings of all FoxCharts properties
Local loProperties
Local laProperties(1), laSubProperties(1), lcProperty
Local lcProperties, lcName, lcType, loObject, lnI, lnJ, laFieldMembers(1), lcFieldMem, loData
Local luPropValue, lcPropType
Local loFields as "Collection"
m.loProperties = Createobject("Empty")
m.lcProperties = "Format, FontName, FontSize, FontBold, FontItalic, FontUnderline, FontCharSet, ForeColor, ForeColorAlpha, BackColor, BackColorAlpha, Alignment, Rotation, RotationCenter"
Alines (laSubProperties, m.lcProperties, 5, ',')
With This
Local laProperties(1), lcProperty
Amembers(m.laProperties, This, 3)
AddProperty (m.loProperties, "_Descriptions(1)", m.laProperties)
Acopy(m.laProperties, m.loProperties._Descriptions)
For m.lnI = 1 To Alen (m.laProperties,1)
m.lcName = Proper(m.laProperties(m.lnI,1))
m.lcType = Proper(m.laProperties(m.lnI,2))
IF EMPTY(.ReadOnlyProps)
TEXT to .ReadOnlyProps
,ACOLORS,ALTERED,APALETTECOLORS,CHARTSUM,CHARTTYPE1,COLOR1,COLUMN,CURRCOLUMN,CURRRECNO,CURRINDEX,CURRVALUE,CURRLEGEND,CURROBJTYPE,FIELDVALUE1,FIELDXAXIS,CONTOURGRAPHICS,CONTOURPEN,INVISIBLESHAPES,LCPALETTES,LEGEND1,MINVALUE,OBMP,OGFX,OLDMOUSEINDEX,PICTURETOSAVE,READONLYPROPS,ROW,ROWCOLPROPS,SINGLEDATA,SHAPE1,VALUE,VERSION,WIDTH,HEIGHT,SLEEP
ENDTEXT
ENDIF
Do Case
CASE lcType = 'Property' ; && ReadOnly properties
AND NOT ','+UPPER (m.lcName)+',' $ .ReadOnlyProps ;
AND "_" # LEFT(m.lcName, 1) AND "On_" # LEFT(m.lcName, 3) ;
AND (PEMSTATUS(THIS, m.lcName, 4) OR ;
INLIST( UPPER(lcName), 'BACKCOLOR', 'FORECOLOR', 'MARGIN', 'SHOWTIPS', 'WIDTH', 'HEIGHT'))
ADDPROPERTY (loProperties, lcName, EVALUATE ("This." + lcName))
Case m.lcName = 'Fields'
m.loFields = Createobject("Collection")
For m.lnJ = 1 To This.Fields.Count
m.loData = Createobject("Empty")
Amembers(laFieldMembers, This.Fields(m.lnJ))
For Each m.lcFieldMem In m.laFieldMembers
m.luPropValue = Evaluate("This.Fields(lnJ)." + m.lcFieldMem)
m.lcPropType = VARTYPE(m.luPropValue)
IF (m.lcFieldMem = "CHARTTYPE" AND m.lcPropType = "N" AND m.luPropValue = 0) OR ;
(m.lcFieldMem = "SHOWVALUESONSHAPE" AND m.lcPropType = "L" AND m.luPropValue = .T.) OR ;
(m.lcFieldMem = "SHAPE" AND m.lcPropType = "N" AND m.luPropValue = 0)
LOOP
ENDIF
AddProperty(m.loData, m.lcFieldMem, m.luPropValue)
Endfor
m.loFields.Add(m.loData)
Next m.lnJ
AddProperty (m.loProperties, m.lcName, m.loFields)
CASE lcType = 'Object' ;
AND INLIST (lcName, "Title", "Subtitle", "Xaxis", "Axislegend2", "Yaxis", "Shapelegend", "Scalelegend", "Sidelegend", "Deltalegend", "Yaxis2", "CommentsSet")
* create an object
AddProperty (m.loProperties, m.lcName, Createobject("Empty"))
m.loObject = Evaluate ("loProperties." + m.lcName)
* conditionally add caption
If Not Inlist (m.lcName, "Axislegend2", "Shapelegend", "Scalelegend", "Sidelegend")
AddProperty (m.loObject, "Caption", Evaluate ("This." + m.lcName + ".Caption"))
Endif
* and add other properties of that object
IF INLIST (lcName,"CommentsSet")
MESSAGEBOX(loObject.Name)
endi
For Each m.lcProperty In m.laSubProperties
AddProperty (m.loObject, m.lcProperty, Evaluate ("This." + m.lcName + "." + m.lcProperty))
Endfor
Endcase
Endfor
Endwith
Return m.loProperties
ENDPROC
PROCEDURE _newfield
LOCAL loData
m.loData = CREATEOBJECT("Empty")
ADDPROPERTY(m.loData,"ChartType",0)
ADDPROPERTY(m.loData,"FieldValue","")
ADDPROPERTY(m.loData,"Legend","")
ADDPROPERTY(m.loData,"Color",0)
ADDPROPERTY(m.loData,"Shape",0)
ADDPROPERTY(m.loData,"ShowValuesOnShape",.T.)
ADDPROPERTY(m.loData,"AxisIndex",1)
ADDPROPERTY(m.loData,"BarType",-1)
RETURN m.loData
ENDPROC
PROCEDURE _preparebrushes
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tlRect, tnCount, llFromLegend
LOCAL lnShape AS NUMBER
EXTERNAL ARRAY XFCGDIPROTATETEXTURETRANSFORM, xfcGdipSetPathGradientSurroundColorsWithCount
IF VARTYPE(m.tnCount) = "L"
m.tnCount = 1
ENDIF
IF PCOUNT() = 0
m.tnX = 0
m.tnY = 0
m.tnWidth = THIS.ChartCanvas.WIDTH
m.tnHeight = THIS.ChartCanvas.HEIGHT
ENDIF
m.tnWidth = MAX(1,m.tnWidth)
m.tnHeight = MAX(1,m.tnHeight)
LOCAL lnBrushType, lnMainColor, lnGradientPosition
m.lnBrushType = THIS.BrushType
m.lnMainColor = THIS.aColors(m.tnCount)
IF VARTYPE(m.lnMainColor) <> "N"
m.lnMainColor = THIS._GetRandomColor()
ENDIF
THIS._nColor = m.lnMainColor
lnGradientPosition=MAX(0.05,MIN(0.95,THIS.GradientPosition))
WITH _SCREEN.SYSTEM.Drawing
IF THIS.BrushType = 3 && Monochrome
THIS._oBorderPen = .PEN.New(THIS._oClrBlack)
ELSE
LOCAL lnColor
m.lnColor = THIS.ChangeColor(m.lnMainColor, +30)
THIS._oBorderPen = .PEN.New(.COLOR.FromRGB(m.lnColor))
* Check if we are drawing on the selected shape
IF NOT THIS._InLegend AND THIS.ChangeColoronMouse AND ;
THIS._GeneralType <> "Point"
LOCAL m.lnShape
m.lnShape = THIS._nMouseOnShape
IF m.lnShape > 0 AND THIS._nMouseOnShape = THIS._nIndex
m.lnMainColor = THIS.SelectedShapeColor
ENDIF
ENDIF
ENDIF
DO CASE
CASE m.lnBrushType = 1 && Solid Brush
THIS._oMainBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, m.lnMainColor))
THIS._o3DBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(m.lnMainColor, - 20)))
THIS._oRightbrush=THIS._o3DBrush
CASE m.lnBrushType = 2 && Gradient Path Brush
LOCAL loColor1 AS xfcColor
m.loColor1 = .COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(m.lnMainColor, - 10))
LOCAL loColor2 AS xfcColor
m.loColor2 = .COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(m.lnMainColor, THIS.GradientLevel * 10))
IF THIS.GradientInvertColors
LOCAL loTmpColor AS xfcColor
m.loTmpColor = m.loColor2
m.loColor2 = m.loColor1
m.loColor1 = m.loTmpColor
ENDIF
DO CASE
CASE THIS._GeneralType = "Pie" AND NOT m.tlRect && Pie or Donut Chart and still not at legend
LOCAL loPath AS xfcGraphicsPath
m.loPath = .Drawing2D.GraphicsPath.New()
m.loPath.AddEllipse(m.tnX, m.tnY, m.tnWidth, m.tnHeight)
LOCAL loPathGradBrush AS xfcPathGradientBrush
m.loPathGradBrush = .Drawing2D.PathGradientBrush.New(m.loPath)
m.loPathGradBrush.CenterColor = m.loColor2
IF THIS.PieGradCenterDistance > 0
LOCAL loCenterPt AS xfcPointF
m.loCenterPt = THIS._GetCenterPoint(m.tnX, m.tnY, m.tnWidth, m.tnHeight)
* Set the center using direct API call because the original funciorn has bugs
* When fixed, the line below should work instead:
* m.loPathGradBrush.CenterPoint = m.loCenterPt
=xfcGdipSetPathGradientCenterPoint(m.loPathGradBrush.Handle, m.loCenterPt.ToVarBinary())
ENDIF
* Not working on version 1.20 official
* loPathGradBrush.SurroundColors[1] = loColor1
* loPathGradBrush.SurroundColors = loColor1
* Workaround using direct API call to assign the surround colors
LOCAL lqColors
m.lqColors = BINTOC(m.loColor1.ARGB,"4rs")
=xfcGdipSetPathGradientSurroundColorsWithCount(m.loPathGradBrush.Handle, @m.lqColors, 1)
IF THIS.GradientType = 0 && SigmaBell
m.loPathGradBrush.SetSigmaBellShape(lnGradientPosition, 1.0)
ELSE && BlendTriangularShape
m.loPathGradBrush.SetBlendTriangularShape(lnGradientPosition, 1.0)
ENDIF
THIS._oMainBrush = m.loPathGradBrush
CASE THIS._GeneralType = "Bar" OR tlRect && Bar Chart
lnGradientShapeDirection = EVL(THIS.GradientShapeDirection, 0)
lnGradientHorcount = THIS.GradientHorcount && 2
lnGradientVertcount = THIS.GradientVertcount && 3
IF llFromLegend
lnGradientShapeDirection = MIN(1,MAX(0,lnGradientShapeDirection))
ELSE
m.lnGradientShapeDirection = MIN(3,MAX(0,m.lnGradientShapeDirection))
ENDIF
m.tnWidth = MAX(1, m.tnWidth/lnGradientVertcount)
m.tnHeight = MAX(1, m.tnHeight/lnGradientHorcount)
LOCAL loLinGradBrush AS xfcLinearGradientBrush
loLinGradBrush = .Drawing2D.LinearGradientBrush.New(;
.Rectangle.New(m.tnX, m.tnY, m.tnWidth, m.tnHeight), ;
loColor1, loColor2, lnGradientShapeDirection)
IF THIS.GradientType = 0 && SigmaBell
loLinGradBrush.SetSigmaBellShape(lnGradientPosition, 1)
ELSE && BlendTriangularShape
loLinGradBrush.SetBlendTriangularShape(lnGradientPosition, 1.0)
ENDIF
THIS._oMainBrush = loLinGradBrush
CASE THIS._GeneralType = "Point" && Line, Point or Area Chart
m.loColor2 = .COLOR.FromRGB(THIS.ChangeColor(m.lnMainColor, THIS.GradientLevel * 8))
LOCAL loLinGradBrush AS xfcLinearGradientBrush
m.loLinGradBrush = .Drawing2D.LinearGradientBrush.New(;
.Rectangle.New(m.tnX, m.tnY, m.tnWidth, m.tnHeight), ;
m.loColor1, m.loColor2, THIS.GradientShapeDirection)
IF THIS.GradientType = 0 && SigmaBell
m.loLinGradBrush.SetSigmaBellShape(lnGradientPosition, 1)
ELSE && BlendTriangularShape
m.loLinGradBrush.SetBlendTriangularShape(lnGradientPosition, 1.0)
ENDIF
THIS._oMainBrush = m.loLinGradBrush
ENDCASE
THIS._o3DBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(m.lnMainColor, - 15)))
THIS._oRightbrush=THIS._o3DBrush
CASE INLIST( m.lnBrushType, 3, 5) && HatchBrush: 3-monochrome, 5 - color
LOCAL lnHatchBrushValue
IF THIS.ChartsCount > 1 AND NOT THIS.SingleData && Pie, Bar or Donut
m.lnHatchBrushValue = 4 + m.tnCount * 2
ELSE
m.lnHatchBrushValue = IIF(m.lnBrushType=3,lnMainColor * 2, 6)
ENDIF
THIS._oMainBrush = .Drawing2D.HatchBrush.New( m.lnHatchBrushValue, ; && HatchStyle
THIS._oClrBlack, ; && ForeColor
IIF(m.lnBrushType=3,THIS._oClrWhite,.COLOR.FromARGB(THIS.AlphaChannel, m.lnMainColor)) ) && BackColor
THIS._o3DBrush = .Drawing2D.HatchBrush.New( m.lnHatchBrushValue , ; && HatchStyle
IIF(m.lnBrushType=3,.COLOR.Gray, .COLOR.FromRGB(m.lnMainColor )), ; && ForeColor
.COLOR.LightGray) && BackColor
THIS._oRightbrush=THIS._oMainBrush
CASE m.lnBrushType = 4 && TextureBrush
m.lcTextureTheme = THIS.Texturetheme
LOCAL lcFile
lcFile = THIS.GetTexture (m.lcTextureTheme,m.tnCount)
IF EMPTY(lcFile)
THIS._oMainBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, m.lnMainColor))
THIS._o3DBrush = .SolidBrush.New(.COLOR.FromARGB(THIS.AlphaChannel, THIS.ChangeColor(m.lnMainColor, - 20)))
THIS._oRightbrush = THIS._o3DBrush
ELSE
THIS._oDimBrush = .Drawing2D.LinearGradientBrush.New(;
.Rectangle.New(m.tnX, m.tnY, m.tnWidth+THIS._3d, m.tnHeight), ;
.COLOR.FromARGB(THIS.AlphaChannel/2,.COLOR.White), ;
.COLOR.FromARGB(THIS.AlphaChannel/2,.COLOR.Black), ;
0)
THIS._oDimBrush.SetSigmaBellShape(lnGradientPosition, 1)
loBmp = .BITMAP.FromVarbinary(FILETOSTR(lcFile))
THIS._oMainBrush = .TextureBrush.New(loBmp)
THIS._o3DBrush = .TextureBrush.New(loBmp)
THIS._o3DBrush.WrapMode = .Drawing2D.WrapMode.TileFlipX
XFCGDIPROTATETEXTURETRANSFORM(THIS._o3DBrush.Handle, -45, _SCREEN.SYSTEM.Drawing.Drawing2D.MatrixOrder.APPEND)
THIS._oRightbrush = .TextureBrush.New(loBmp)
=xfcGdipRotateTextureTransform(THIS._oRightbrush.Handle, 45, _SCREEN.SYSTEM.Drawing.Drawing2D.MatrixOrder.APPEND)
ENDIF
ENDCASE
ENDWITH
ENDPROC
PROCEDURE _preparecolors
*
* Grigory Meriam (Aviv Advanced Solutions Ltd.)
* Here I put code sent by Grigory Meriam.
* Gradient colors depend on values.
* You can see it for m.lnColorType = 3 and ChartType=7
*
SELECT(THIS._DataCursor)
LOCAL lnColorType, N , m.nIndex
m.lnColorType = THIS.ColorType
IF NOT THIS.SingleData
LOCAL lnColor, lcIndex
DIMENSION THIS.aColors(THIS.ChartsCount)
FOR m.N = 1 TO THIS.ChartsCount
m.lcIndex = THIS._Str(m.N)
DO CASE
CASE THIS.BrushType = 3 && Monochrome
m.lnColor = 0
CASE m.lnColorType = 0 && Basic Colors
m.lnColor = THIS._GetBasicColor(m.N)
CASE m.lnColorType = 1 && Custom
m.lnColor = THIS.FIELDS(m.N).COLOR
IF VARTYPE(m.lnColor) <> "N"
m.lnColor = THIS._GetRandomColor()
ENDIF
* CASE m.lnColorType = 2 AND This._UpdateRandomColors && Random
CASE m.lnColorType = 2 AND ;
(THIS._UpdateRandomColors OR VARTYPE(THIS.aColors(m.N)) = "L") && Random or not initialized
m.lnColor = THIS._GetRandomColor()
CASE m.lnColorType = 2 AND NOT THIS._UpdateRandomColors && Random
RETURN && Keep the current color
CASE m.lnColorType = 3 && Gradient
m.lnColor = THIS._GetGradientColor(m.N)
CASE m.lnColorType >= 4
m.lnColor = THIS._GetPaletteColor(lnColorType - 4, m.N)
ENDCASE
THIS.aColors(m.N) = m.lnColor
ENDFOR
ELSE
IF THIS.charttype = 7
IF m.lnColorType = 3 AND THIS.BrushType != 3 && Gradient
SELECT RECNO() AS nn ;
FROM (THIS._DataCursor) ;
ORDER BY Nvalue1 DESC ;
INTO CURSOR curPrepareColors
SELECT curPrepareColors
ENDIF
ENDIF
DIMENSION THIS.aColors(THIS._nRecords)
SCAN
IF USED('curPrepareColors')
m.nIndex = INT(curPrepareColors.nn)
ELSE
m.nIndex = RECNO()
ENDIF
m.N = RECNO()
DO CASE
CASE THIS.BrushType = 3 && Monochrome
m.lnColor = m.N
CASE m.lnColorType = 0 && Basic Colors
m.lnColor = THIS._GetBasicColor(m.N)
* CASE m.lnColorType = 2 AND This._UpdateRandomColors && Random
CASE m.lnColorType = 2 AND ;
(THIS._UpdateRandomColors OR VARTYPE(THIS.aColors(m.N)) = "L") && Random or not initialized
m.lnColor = THIS._GetRandomColor()
CASE m.lnColorType = 2 AND NOT THIS._UpdateRandomColors && Random
RETURN
CASE m.lnColorType = 3 && Gradient
m.lnColor = THIS._GetGradientColor(m.N)
CASE m.lnColorType = 1 AND NOT EMPTY(THIS.FieldColor) && Custom
m.lnColor = nColor && Retrieve color from Field
CASE m.lnColorType = 1 AND EMPTY(THIS.FieldColor) && Custom
IF THIS._UpdateRandomColors
m.lnColor = THIS._GetRandomColor()
ELSE && no need to update, keep using the same prev color
RETURN
ENDIF
CASE m.lnColorType >= 4
m.lnColor = THIS._GetPaletteColor(lnColorType - 4, m.N)
OTHERWISE && Custom color and not Line or Area chart
ENDCASE
THIS.aColors(m.nIndex) = m.lnColor
ENDSCAN
IF USED('curPrepareColors')
USE IN SELECT ('curPrepareColors')
SELECT(THIS._DataCursor)
ENDIF
ENDIF
THIS._UpdateRandomColors = .F.
ENDPROC
PROCEDURE _preparedata
WITH THIS
* Comments
IF TYPE('.CommentsSet')='U'
.ADDOBJECT('CommentsSet','FoxChartsBeta.fields')
TEXT TO lcFieldsDesc
Left,N
Top,N
Caption,C
FontName,C,ARIAL
FontSize,I,<<.Comments.FontSize>>
FontBold,L,<<.Comments.FontBold>>
FontUnderLine,L
FontItalic,L
ForeColor,I,<<.Comments.ForeColor>>
BackColor,I,<<.Comments.BackColor>>
ForeColorAlpha,I,255
BackColorAlpha,I,128
Rotation,I,0
GradientLevel,I,5
Alignment,I,0
Type,I,1
PointerSide,I,0
PointerSubSide,I,1
PointerWidth,N,10
ENDTEXT
.CommentsSet.DESC = lcFieldsDesc
ENDIF
lnLines = IIF(EMPTY(.CommentsSetPack),0,ALINES(la,.CommentsSetPack))
.CommentsSet.SetCount(lnLines)
.CommentsSet.UNPACK(.CommentsSetPack)
ENDWITH
DODEFAULT()
ENDPROC
PROCEDURE _preparetitle
WITH _SCREEN.SYSTEM.Drawing
LOCAL lcPoint, lnTitleHeight, lnSubtitleHeight, lnTitleColor, lnLeft
STORE 0 TO lnTitleHeight, lnSubtitleHeight
* Check if Title was assigned
IF NOT EMPTY(This.Title.Caption)
This.Title.Reset()
lnTop = This.Margin + This.MarginTop
This.Title._DrawString(0, This.Margin + This.MarginTop, This.ChartCanvas.Width, This.ChartCanvas.Height)
lnTitleHeight = This.Title._height
lnLeft = ICASE(This.Title.Alignment = 0,0,This.Title.Alignment =1,This.ChartCanvas.Width -This.Title._Width,(This.ChartCanvas.Width - This.Title._Width)/2)
TEXT TO lcPoint
<<Round(lnLeft,0)>>,<<Round(lnTop,0)>>
<<Round(lnLeft+This.Title._Width,0)>>,<<Round(lnTop,0)>>
<<Round(lnLeft+This.Title._Width,0)>>,<<Round(lnTop+lnTitleHeight,0)>>
<<Round(lnLeft,0)>>,<<Round(lnTop+lnTitleHeight,0)>>
ENDTEXT
This._UpdateCoordinates(,"Title", lnLeft, This.Title.Top, This.Title._Width, lnTitleHeight, 0, This.Title.Caption, lcPoint)
ENDIF
* Check if Subtitle was assigned
IF NOT EMPTY(This.Subtitle.Caption)
This.Subtitle.Reset()
lnTop = This.Margin + This.MarginTop + lnTitleHeight
This.Subtitle._DrawString(0, lnTop, This.ChartCanvas.Width, This.ChartCanvas.Height)
lnSubtitleHeight = This.Subtitle._Height
lnLeft = ICASE(This.SubTitle.Alignment = 0,0,This.SubTitle.Alignment =1,This.ChartCanvas.Width -This.SubTitle._Width,(This.ChartCanvas.Width - This.SubTitle._Width)/2)
TEXT TO lcPoint
<<Round(lnLeft,0)>>,<<Round(lnTop,0)>>
<<Round(lnLeft+This.Subtitle._Width,0)>>,<<Round(lnTop,0)>>
<<Round(lnLeft+This.Subtitle._Width,0)>>,<<Round(lnTop+lnSubtitleHeight,0)>>
<<Round(lnLeft,0)>>,<<Round(lnTop+lnSubtitleHeight,0)>>
ENDTEXT
This._UpdateCoordinates(,"Subtitle", lnLeft, lnTop, This.Subtitle._Width, lnSubtitleHeight, 0, This.Subtitle.Caption, lcPoint)
ENDIF
This._TitleHeight = lnTitleHeight + lnSubtitleHeight
ENDWITH
ENDPROC
PROCEDURE _updatecoordinates
LPARAMETERS loShape, tcObjType, tnX, tnY, tnWidth, tnHeight, tnValue, tnStart, tnSweep, lnColor, tcFront, tnIndex
LOCAL lcFourthDimensionLegend, lcLegend, lcObjectName, ;
lnFourthIndex, lnLine, lnRow, ;
loObject
WITH THIS
* During DrawReport(), there's no need to update the coordinates
SELECT (._DataCursor)
m.lcLegend=.F.
._nIndex = ._nIndex + 1
DO CASE
CASE tcObjType = "Legend"
lcLegend = IIF(VARTYPE(m.tnStart) = "C", m.tnStart, "")
CASE tcObjType $ 'Title,Subtitle,YaxisCaption,LeftSide,BottomSide'
OTHERWISE
IF .SingleData OR .ChartsCount = 1
m.lcLegend = cLegend
ELSE
IF BETWEEN(._ChartIndex,1,.ChartsCount)
m.lcLegend = .FIELDS(._ChartIndex).Legend
ELSE
m.lcLegend = ''
ENDIF
ENDIF
ENDCASE
IF VARTYPE(loShape) # 'O'
lnIndex = IIF(EMPTY(tnIndex),.Shapes.OBJECTS.COUNT+1,tnIndex)
lcObjectName='Shape'+ALLTRIM(STR(lnIndex))
IF TYPE('.Shapes.'+lcObjectName) = 'U'
.Shapes.ADDOBJECT(lcObjectName,[FoxChartsBeta.Figure])
ENDIF
loShape = EVALUATE('THIS.Shapes.' + lcObjectName)
ENDIF
ENDWITH
WITH loShape
.TYPE = m.tcObjType
.LEFT = ROUND(m.tnX,0)
.TOP = ROUND(m.tnY,0)
.WIDTH = ROUND(m.tnWidth,0)
.HEIGHT = ROUND(m.tnHeight,0)
.VALUE = EVL(m.tnValue,0)
.START = m.tnStart
.Sweep = m.tnSweep
.Contour = m.tnSweep
.Front = tcFront
.ChartIndex = THIS._ChartIndex && ChartRow
.Currentrow = EVL(THIS._Currentrow, IIF(tcObjType = "Legend", tnValue, RECNO((This._DataCursor)))) && on "Legend" mode, tnValue passes the index
.Legend = m.lcLegend
.COLOR = EVL(lnColor,THIS._nColor)
.CoordNum = VAL(SUBSTR(.NAME,6))
.RowSum = IIF(m.tcObjType = "Rect", EVL(tnStart,0), 0) && Sum of the current row
ENDWITH
RETURN loShape
ENDPROC
PROCEDURE AxisLegend2._drawstring
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tlVertical, lnBackColor
LOCAL x1, y1, lnAlign, lnMode, xBack
lnMode = 0 && 0 = x,y Coordinates ; 1 = xfcRectangle coordinates
lnAlign = THIS.ALIGNMENT
* 0 = Left 1 = Right 2 = Center
LOCAL loGfx AS xfcGraphics
loGfx = THIS.PARENT.oGfx
lnBackColor=EVL(lnBackColor,THIS.BACKCOLOR)
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE VARTYPE(tnWidth) + VARTYPE(tnHeight) = "NN"
lnMode = 1
* Create a STRINGFORMAT object in order to draw the string centered in the image
LOCAL loStringFmt AS xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
IF tlVertical
loStringFmt.FormatFlags = .StringFormatFlags.DirectionVertical
loStringFmt.LineAlignment = .StringAlignment.CENTER
ENDIF
LOCAL loSize AS xfcSize, loRect AS xfcRectangle
IF tlVertical
loSize = .SIZE.New(THIS.PARENT.WIDTH, THIS.PARENT.HEIGHT)
ELSE
loSize = .SIZE.New(tnWidth, tnHeight)
ENDIF
loSize = loGfx.MeasureString(;
THIS._TransfCaption, THIS._oFont, loSize, loStringFmt)
THIS._Height = CEILING(loSize.HEIGHT)
THIS._Width = CEILING(loSize.WIDTH)
loRect = .Rectangle.New(tnX, tnY, tnWidth, THIS._Height)
x1 = tnX
y1 = tnY
IF tlVertical
xBack = tnX + (tnWidth - THIS._Width) / 2
DO CASE
CASE lnAlign = 0 && Left
y1 = tnY
CASE lnAlign = 1 && Right
y1 = tnY + tnHeight - THIS._Height
CASE lnAlign = 2 && Center
y1 = tnY + (tnHeight - THIS._Height) / 2
ENDCASE
ELSE
DO CASE
CASE lnAlign = 0 && Left
xBack = tnX
CASE lnAlign = 1 && Right
xBack = tnX + tnWidth - THIS._Width
CASE lnAlign = 2 && Center
xBack = tnX + (tnWidth - THIS._Width) / 2
ENDCASE
ENDIF
CASE lnAlign = 0 && Left
STORE tnX TO x1, xBack
y1 = tnY
CASE lnAlign = 1 && Right
x1 = tnX - THIS._Width
xBack = x1
y1 = tnY
CASE lnAlign = 2 && Center
x1 = tnX - (THIS._Width / 2)
xBack = x1
y1 = tnY
ENDCASE
LOCAL lnRotation
lnRotation = THIS.ROTATION
IF lnRotation <> 0
WITH _SCREEN.SYSTEM.Drawing
LOCAL loPointF AS xfcPointF, loMatrix AS xfcMatrix
loMatrix = .Drawing2D.Matrix.New()
IF lnMode = 1
loPointF = .PointF.New(tnX, tnY) && this is the point of rotation
ELSE
DO CASE
CASE lnAlign = 0 && Left
loPointF = .PointF.New(x1 + 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 1 && Right
loPointF = .PointF.New(x1 + THIS._Width - 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 2 && Center
loPointF = .PointF.New(x1 + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
ENDCASE
ENDIF
loMatrix.RotateAt(lnRotation, loPointF)
loGfx.MultiplyTransform(loMatrix)
ENDWITH
ENDIF
WITH _SCREEN.SYSTEM.Drawing
lnRotationCenter = THIS.RotationCenter
* Center Rotation
IF lnRotationCenter <> 0
LOCAL loMatrixC AS xfcMatrix, loPointFC AS xfcPointF
loMatrixC = .Drawing2D.Matrix.New()
loPointFC = .PointF.New(xBack + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
loMatrixC.RotateAt(lnRotationCenter, loPointFC)
loGfx.MultiplyTransform(loMatrixC)
ENDIF
* IF THIS.BackColorAlpha > 0
* Draw the BackGround Rectangle
IF lnMode = 0 && default
lnX=x1
lnY=y1
lnWidth = THIS._Width-2
lnHeight=THIS._Height-4
ELSE
lnX=xBack+2
lnY=y1+2
lnWidth = THIS._Width-4
lnHeight=THIS._Height-4
ENDIF
loGfx.FillRectangle( .SolidBrush.New(.COLOR.FromARGB(THIS.BackColorAlpha,lnBackColor)), ;
lnX, lnY, lnWidth, lnHeight)
IF lnMode = 0
loGfx.DrawRectangle( .PEN.New(.COLOR.FromRGB(RGB(192,192,192)), 1),lnX, lnY, lnWidth, lnHeight)
ENDIF
* ENDIF
lnX1=lnX
lnY1=lnY
lnX2=lnX+lnWidth
lnY2=lnY
lnX3=lnX2
lnY3=lnY+lnHeight
lnX4=lnX
lnY4=lnY3
IF lnRotation # 0
lnX0 = loPointF.X
lnY0 = loPointF.Y
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX1, @lnY1, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX2, @lnY2, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX3, @lnY3, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX4, @lnY4, lnRotation)
ENDIF
IF lnRotationCenter # 0
lnX0 = loPointFC.X
lnY0 = loPointFC.Y
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX1, @lnY1, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX2, @lnY2, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX3, @lnY3, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX4, @lnY4, lnRotationCenter)
ENDIF
TEXT TO lcPoints
<<Round(lnX1,0)>>,<<Round(lnY1,0)>>
<<Round(lnX2,0)>>,<<Round(lnY2,0)>>
<<Round(lnX3,0)>>,<<Round(lnY3,0)>>
<<Round(lnX4,0)>>,<<Round(lnY4,0)>>
ENDTEXT
LOCAL laPoints(4)
laPoints(1) = .POINT.New(lnX1, lnY1)
laPoints(2) = .POINT.New(lnX2, lnY2)
laPoints(3) = .POINT.New(lnX3, lnY3)
laPoints(4) = .POINT.New(lnX4, lnY4)
ENDWITH
* Draw the Text
IF lnMode = 0
LOCAL loStringFmt AS xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
loRect = .Rectangle.New(x1, y1, CEILING(THIS._Width), THIS._Height + 2)
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ELSE
IF tlVertical
loRect = .Rectangle.New(xBack, y1, THIS._Width, THIS._Height)
ENDIF
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ENDIF
THIS.PARENT._updatecoordinates (,'AxisLegend2', lnx1, lnY1, lnWidth, lnHeight, THIS._TransfCaption, lnRotationCenter, lcPoints, 0)
IF lnRotation # 0 OR lnRotationCenter # 0
loGfx.ResetTransform()
ENDIF
ENDWITH
ENDPROC
PROCEDURE ChartCanvas.Click
LOCAL lnCoordIndex, lnX, lnY, lnValue, loObject
lnCoordIndex = 0
lnX = MCOL(0,3)
lnY = MROW(0,3)
WITH THIS.PARENT
._CheckMousePosition(0, 0, lnX, lnY, @lnValue, @lnCoordIndex, @loObject)
.CurrValue = lnValue
.CurrIndex = lnCoordIndex
.CurrObjType = IIF(TYPE('loObject.Type')='C',loObject.Type,'')
.CLICK()
ENDWITH
ENDPROC
PROCEDURE ChartCanvas.DblClick
LOCAL lnCoordIndex, lnX, lnY, lnValue, loObject
lnCoordIndex = 0
lnX = MCOL(0,3)
lnY = MROW(0,3)
WITH THIS.PARENT
._CheckMousePosition(0, 0, lnX, lnY, @lnValue, @lnCoordIndex, @loObject)
.CurrValue = lnValue
.CurrIndex = lnCoordIndex
.CurrObjType = IIF(TYPE('loObject.Type')='C',loObject.Type,'')
.DBLCLICK()
ENDWITH
ENDPROC
PROCEDURE ChartCanvas.draw
LPARAMETERS tnWidth, tnHeight, toGfx
IF THIS.PARENT.Sleep
RETURN
ENDIF
DODEFAULT(tnWidth, tnHeight, toGfx)
ENDPROC
PROCEDURE ChartCanvas.Init
WITH THIS
.WIDTH = .PARENT.WIDTH
.HEIGHT = .PARENT.HEIGHT
IF VARTYPE(.nButton) = 'U'
.ADDPROPERTY ('nButton',-1)
.ADDPROPERTY ('nShift',-1)
.ADDPROPERTY ('nXCoord',-1)
.ADDPROPERTY ('nYCoord',-1)
ENDIF
ENDWITH
DODEFAULT()
ENDPROC
PROCEDURE ChartCanvas.MouseDown
LPARAMETERS nButton, nShift, nXCoord, nYCoord
LOCAL loObject, lnCoordIndex
lnCoordIndex = 0
THIS.PARENT._CheckMousePosition(nButton, nShift, nXCoord, nYCoord, , @lnCoordIndex, @loObject)
* Update the index property, that will allow all the other "curr"properties to be up to date
THIS.PARENT.CurrIndex = lnCoordIndex
THIS.PARENT.MOUSEDOWN( nButton, nShift, nXCoord, nYCoord, loObject)
ENDPROC
PROCEDURE ChartCanvas.MouseMove
LPARAMETERS nButton, nShift, nXCoord, nYCoord
LOCAL lnCoordIndex, loObject
IF nXCoord=THIS.nXCoord AND nYCoord=THIS.nYCoord AND nButton=THIS.nButton AND nShift = THIS.nShift
RETURN
ENDIF
THIS.nXCoord = nXCoord
THIS.nYCoord = nYCoord
THIS.nButton = nButton
THIS.nShift = nShift
m.lnCoordIndex = 0
loObject = .F.
WITH THIS.PARENT
._CheckMousePosition(nButton, nShift, nXCoord, nYCoord, , @lnCoordIndex, @loObject)
* Update the index property, that will allow all the other "curr"properties to be up to date
THIS.PARENT.Currindex = lnCoordIndex
.MOUSEMOVE(nButton, nShift, nXCoord, nYCoord, loObject)
ENDWITH
ENDPROC
PROCEDURE ChartCanvas.MouseUp
LPARAMETERS nButton, nShift, nXCoord, nYCoord
LOCAL lcObjectType, lnCoordIndex, loShape
lnCoordIndex = 0
WITH THIS.PARENT
._CheckMousePosition(nButton, nShift, nXCoord, nYCoord, , @lnCoordIndex, @loShape)
* Update the index property, that will allow all the other "curr"properties to be up to date
.Currindex = lnCoordIndex
lcObjectType = IIF(TYPE('loShape.Type')='C', loShape.TYPE, '' )
.MOUSEUP(nButton, nShift, nXCoord, nYCoord, loShape)
IF TYPE('loShape') = 'O' AND ._GeneralType = "Pie" AND nButton=1
.Column = loShape.CurrentRow
.Row = loShape.ChartIndex
IF lcObjectType = "Pie" AND .PieDetachSliceonClick
._DetachClickedSlice(lnCoordIndex)
ENDIF
IF lcObjectType = "Legend" AND .PieDetachSliceonLegendClick
._DetachClickedSlice(lnCoordIndex)
ENDIF
ENDIF
ENDWITH
ENDPROC
PROCEDURE Comments.caption_assign
lparameters tcText
This.Caption = tcText
ENDPROC
PROCEDURE Comments._drawstring
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tlVertical, lnBackColor, tnAlignMent
LOCAL lnAlign, lnHeight, lnMode, lnRotationCenter, lnWidth, lnX, lnY, ;
loGfx as xfcGraphics, loSize as xfcSize, loStringFmt as xfcStringFormat
lnMode = 0 && 0 = x,y Coordinates ; 1 = xfcRectangle coordinates
lnAlign = IIF(VARTYPE(tnAlignMent)='N',tnAlignMent,This.Alignment)
* 0 = Left 1 = Right 2 = Center
loGfx = This.Parent.oGfx
lnBackColor=EVL(lnBackColor,this.BackColor)
WITH _Screen.System.Drawing
DO CASE
CASE VARTYPE(tnWidth) + VARTYPE(tnHeight) = "NN"
lnMode = 1
* Create a STRINGFORMAT object in order to draw the string centered in the image
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.Center
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.Near
ENDCASE
loStringFmt.Alignment = lnGdipAlign
IF tlVertical
loStringFmt.FormatFlags = .StringFormatFlags.DirectionVertical
loStringFmt.LineAlignment = .StringAlignment.Center
ENDIF
IF tlVertical
loSize = .Size.New(This.Parent.Width, This.Parent.Height)
ELSE
loSize = .Size.New(tnWidth, tnHeight)
ENDIF
loSize = loGfx.MeasureString( This._TransfCaption, This._oFont, loSize, loStringFmt)
This._Height = CEILING(loSize.Height)
This._Width = CEILING(loSize.Width)
LOCAL loRect as xfcRectangle
loRect = .Rectangle.New(tnX, tnY, tnWidth, This._Height)
x1 = tnX
y1 = tnY
IF tlVertical
xBack = tnX + (tnWidth - This._Width) / 2
DO CASE
CASE lnAlign = 0 && Left
y1 = tnY
CASE lnAlign = 1 && Right
y1 = tnY + tnHeight - This._Height
CASE lnAlign = 2 && Center
y1 = tnY + (tnHeight - This._Height) / 2
ENDCASE
ELSE
DO CASE
CASE lnAlign = 0 && Left
xBack = tnX
CASE lnAlign = 1 && Right
xBack = tnX + tnWidth - This._Width
CASE lnAlign = 2 && Center
xBack = tnX + (tnWidth - This._Width) / 2
ENDCASE
ENDIF
CASE lnAlign = 0 && Left
STORE tnX TO x1, xBack
y1 = tnY
CASE lnAlign = 1 && Right
x1 = tnX - This._Width
xBack = x1
y1 = tnY
CASE lnAlign = 2 && Center
x1 = tnX - (This._Width / 2)
xBack = x1
y1 = tnY
ENDCASE
LOCAL lnRotation
lnRotation = This.Rotation
IF lnRotation <> 0
WITH _SCREEN.System.Drawing
LOCAL loPointF as xfcPointF
LOCAL loMatrix as xfcMatrix
loMatrix = .Drawing2D.Matrix.New()
IF lnMode = 1
loPointF = .PointF.New(tnX, tnY) && this is the point of rotation
ELSE
DO CASE
CASE lnAlign = 0 && Left
loPointF = .PointF.New(x1 + 5, y1 + This._Height / 2) && this is the point of rotation
CASE lnAlign = 1 && Right
loPointF = .PointF.New(x1 + This._Width - 5, y1 + This._Height / 2) && this is the point of rotation
CASE lnAlign = 2 && Center
loPointF = .PointF.New(x1 + This._Width / 2, y1 + This._Height / 2) && this is the point of rotation
ENDCASE
ENDIF
loMatrix.RotateAt(lnRotation, loPointF)
loGfx.MultiplyTransform(loMatrix)
ENDWITH
ENDIF
lnRotationCenter = This.RotationCenter
* Center Rotation
IF lnRotationCenter # 0
WITH _SCREEN.System.Drawing
LOCAL loPointFC as xfcPointF, loMatrixC as xfcMatrix
loMatrixC = .Drawing2D.Matrix.New()
loPointFC = .PointF.New(xBack + This._Width / 2, y1 + This._Height / 2) && this is the point of rotation
loMatrixC.RotateAt(lnRotationCenter, loPointFC)
loGfx.MultiplyTransform(loMatrixC)
ENDWITH
ENDIF
* Draw the BackGround Rectangle
IF lnMode = 0 && default
lnX=x1
lnY=y1
lnWidth = THIS._Width-2
lnHeight=THIS._Height-4
ELSE
lnX=xBack+2
lnY=y1+2
lnWidth = THIS._Width-4
lnHeight=THIS._Height-4
ENDIF
if THIS.BackColorAlpha<255
loGfx.FillRectangle( .SolidBrush.New(.COLOR.FromARGB(THIS.BackColorAlpha,lnBackColor)), ;
lnX, lnY, lnWidth, lnHeight)
ENDIF
IF lnMode = 0
loGfx.DrawRectangle( .PEN.New(.COLOR.FromRGB(RGB(192,192,192)), 1),lnX, lnY, lnWidth, lnHeight)
ENDIF
* Draw the Text
IF lnMode = 0
LOCAL loStringFmt as xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.Center
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.Near
ENDCASE
loStringFmt.Alignment = lnGdipAlign
loGfx.DrawString(This._TransfCaption, This._oFont, This._oBrush, ;
.Rectangle.New(x1, y1, CEILING(This._Width), This._Height + 2), ;
loStringFmt)
ELSE
IF tlVertical
loRect = .Rectangle.New(xBack, y1, This._Width, This._Height)
loGfx.DrawString(This._TransfCaption, This._oFont, This._oBrush, loRect, loStringFmt)
ELSE
loGfx.DrawString(This._TransfCaption, This._oFont, This._oBrush, loRect, loStringFmt)
ENDIF
ENDIF
IF lnRotation <> 0 OR lnRotationCenter <> 0
loGfx.ResetTransform()
ENDIF
ENDWITH
ENDPROC
PROCEDURE DeltaLegend.caption_assign
lparameters tcText
This.Caption = tcText
ENDPROC
PROCEDURE DeltaLegend._drawstring
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tlVertical, lnBackColor, tnAlignMent
LOCAL lnAlign, lnHeight, lnMode, lnRotationCenter, lnWidth, lnX, lnY, ;
loGfx AS xfcGraphics, loSize AS xfcSize, loStringFmt AS xfcStringFormat
lnMode = 0 && 0 = x,y Coordinates ; 1 = xfcRectangle coordinates
lnAlign = IIF(VARTYPE(tnAlignMent)='N',tnAlignMent,THIS.ALIGNMENT)
* 0 = Left 1 = Right 2 = Center
loGfx = THIS.PARENT.oGfx
lnBackColor=EVL(lnBackColor,THIS.BACKCOLOR)
this._Setup
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE VARTYPE(tnWidth) + VARTYPE(tnHeight) = "NN"
lnMode = 1
* Create a STRINGFORMAT object in order to draw the string centered in the image
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
IF tlVertical
loStringFmt.FormatFlags = .StringFormatFlags.DirectionVertical
loStringFmt.LineAlignment = .StringAlignment.CENTER
ENDIF
IF tlVertical
loSize = .SIZE.New(THIS.PARENT.WIDTH, THIS.PARENT.HEIGHT)
ELSE
loSize = .SIZE.New(tnWidth, tnHeight)
ENDIF
loSize = loGfx.MeasureString( THIS._TransfCaption, THIS._oFont, loSize, loStringFmt)
THIS._Height = CEILING(loSize.HEIGHT)
THIS._Width = CEILING(loSize.WIDTH)
LOCAL loRect AS xfcRectangle
loRect = .Rectangle.New(tnX, tnY, tnWidth, THIS._Height)
x1 = tnX
y1 = tnY
IF tlVertical
xBack = tnX + (tnWidth - THIS._Width) / 2
DO CASE
CASE lnAlign = 0 && Left
y1 = tnY
CASE lnAlign = 1 && Right
y1 = tnY + tnHeight - THIS._Height
CASE lnAlign = 2 && Center
y1 = tnY + (tnHeight - THIS._Height) / 2
ENDCASE
ELSE
DO CASE
CASE lnAlign = 0 && Left
xBack = tnX
CASE lnAlign = 1 && Right
xBack = tnX + tnWidth - THIS._Width
CASE lnAlign = 2 && Center
xBack = tnX + (tnWidth - THIS._Width) / 2
ENDCASE
ENDIF
CASE lnAlign = 0 && Left
STORE tnX TO x1, xBack
y1 = tnY
CASE lnAlign = 1 && Right
x1 = tnX - THIS._Width
xBack = x1
y1 = tnY
CASE lnAlign = 2 && Center
x1 = tnX - (THIS._Width / 2)
xBack = x1
y1 = tnY
ENDCASE
LOCAL lnRotation
lnRotation = THIS.ROTATION
IF lnRotation <> 0
WITH _SCREEN.SYSTEM.Drawing
LOCAL loPointF AS xfcPointF
LOCAL loMatrix AS xfcMatrix
loMatrix = .Drawing2D.Matrix.New()
IF lnMode = 1
loPointF = .PointF.New(tnX, tnY) && this is the point of rotation
ELSE
DO CASE
CASE lnAlign = 0 && Left
loPointF = .PointF.New(x1 + 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 1 && Right
loPointF = .PointF.New(x1 + THIS._Width - 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 2 && Center
loPointF = .PointF.New(x1 + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
ENDCASE
ENDIF
loMatrix.RotateAt(lnRotation, loPointF)
loGfx.MultiplyTransform(loMatrix)
ENDWITH
ENDIF
lnRotationCenter = THIS.RotationCenter
* Center Rotation
IF lnRotationCenter # 0
WITH _SCREEN.SYSTEM.Drawing
LOCAL loPointFC AS xfcPointF, loMatrixC AS xfcMatrix
loMatrixC = .Drawing2D.Matrix.New()
loPointFC = .PointF.New(xBack + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
loMatrixC.RotateAt(lnRotationCenter, loPointFC)
loGfx.MultiplyTransform(loMatrixC)
ENDWITH
ENDIF
* Draw the BackGround Rectangle
IF lnMode = 0 && default
lnX=x1
lnY=y1
lnWidth = THIS._Width-2
lnHeight=THIS._Height-4
ELSE
lnX=xBack+2
lnY=y1+2
lnWidth = THIS._Width-4
lnHeight=THIS._Height-4
ENDIF
IF THIS.BackColorAlpha<255
loGfx.FillRectangle( .SolidBrush.New(.COLOR.FromARGB(THIS.BackColorAlpha,lnBackColor)), ;
lnX, lnY, lnWidth, lnHeight)
ENDIF
IF lnMode = 0
loGfx.DrawRectangle( .PEN.New(.COLOR.FromRGB(RGB(192,192,192)), 1),lnX, lnY, lnWidth, lnHeight)
ENDIF
* Draw the Text
IF lnMode = 0
LOCAL loStringFmt AS xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, ;
.Rectangle.New(x1, y1, CEILING(THIS._Width), THIS._Height + 2), ;
loStringFmt)
ELSE
IF tlVertical
loRect = .Rectangle.New(xBack, y1, THIS._Width, THIS._Height)
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ELSE
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ENDIF
ENDIF
IF lnRotation <> 0 OR lnRotationCenter <> 0
loGfx.ResetTransform()
ENDIF
ENDWITH
ENDPROC
PROCEDURE ScaleLegend._drawstring
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tlVertical, lnBackColor
LOCAL x1, y1, lnAlign, lnMode, xBack
lnMode = 0 && 0 = x,y Coordinates ; 1 = xfcRectangle coordinates
lnAlign = THIS.ALIGNMENT
* 0 = Left 1 = Right 2 = Center
LOCAL loGfx AS xfcGraphics
loGfx = THIS.PARENT.oGfx
lnBackColor=EVL(lnBackColor,THIS.BACKCOLOR)
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE VARTYPE(tnWidth) + VARTYPE(tnHeight) = "NN"
lnMode = 1
* Create a STRINGFORMAT object in order to draw the string centered in the image
LOCAL loStringFmt AS xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
IF tlVertical
loStringFmt.FormatFlags = .StringFormatFlags.DirectionVertical
loStringFmt.LineAlignment = .StringAlignment.CENTER
ENDIF
LOCAL loSize AS xfcSize, loRect AS xfcRectangle
IF tlVertical
loSize = .SIZE.New(THIS.PARENT.WIDTH, THIS.PARENT.HEIGHT)
ELSE
loSize = .SIZE.New(tnWidth, tnHeight)
ENDIF
loSize = loGfx.MeasureString(;
THIS._TransfCaption, THIS._oFont, loSize, loStringFmt)
THIS._Height = CEILING(loSize.HEIGHT)
THIS._Width = CEILING(loSize.WIDTH)
loRect = .Rectangle.New(tnX, tnY, tnWidth, THIS._Height)
x1 = tnX
y1 = tnY
IF tlVertical
xBack = tnX + (tnWidth - THIS._Width) / 2
DO CASE
CASE lnAlign = 0 && Left
y1 = tnY
CASE lnAlign = 1 && Right
y1 = tnY + tnHeight - THIS._Height
CASE lnAlign = 2 && Center
y1 = tnY + (tnHeight - THIS._Height) / 2
ENDCASE
ELSE
DO CASE
CASE lnAlign = 0 && Left
xBack = tnX
CASE lnAlign = 1 && Right
xBack = tnX + tnWidth - THIS._Width
CASE lnAlign = 2 && Center
xBack = tnX + (tnWidth - THIS._Width) / 2
ENDCASE
ENDIF
CASE lnAlign = 0 && Left
STORE tnX TO x1, xBack
y1 = tnY
CASE lnAlign = 1 && Right
x1 = tnX - THIS._Width
xBack = x1
y1 = tnY
CASE lnAlign = 2 && Center
x1 = tnX - (THIS._Width / 2)
xBack = x1
y1 = tnY
ENDCASE
LOCAL lnRotation
lnRotation = THIS.ROTATION
IF lnRotation <> 0
WITH _SCREEN.SYSTEM.Drawing
LOCAL loPointF AS xfcPointF, loMatrix AS xfcMatrix
loMatrix = .Drawing2D.Matrix.New()
IF lnMode = 1
loPointF = .PointF.New(tnX, tnY) && this is the point of rotation
ELSE
DO CASE
CASE lnAlign = 0 && Left
loPointF = .PointF.New(x1 + 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 1 && Right
loPointF = .PointF.New(x1 + THIS._Width - 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 2 && Center
loPointF = .PointF.New(x1 + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
ENDCASE
ENDIF
loMatrix.RotateAt(lnRotation, loPointF)
loGfx.MultiplyTransform(loMatrix)
ENDWITH
ENDIF
WITH _SCREEN.SYSTEM.Drawing
lnRotationCenter = THIS.RotationCenter
* Center Rotation
IF lnRotationCenter <> 0
LOCAL loMatrixC AS xfcMatrix, loPointFC AS xfcPointF
loMatrixC = .Drawing2D.Matrix.New()
loPointFC = .PointF.New(xBack + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
loMatrixC.RotateAt(lnRotationCenter, loPointFC)
loGfx.MultiplyTransform(loMatrixC)
ENDIF
* IF THIS.BackColorAlpha > 0
* Draw the BackGround Rectangle
IF lnMode = 0 && default
lnX=x1
lnY=y1
lnWidth = THIS._Width-2
lnHeight=THIS._Height-4
ELSE
lnX=xBack+2
lnY=y1+2
lnWidth = THIS._Width-4
lnHeight=THIS._Height-4
ENDIF
loGfx.FillRectangle( .SolidBrush.New(.COLOR.FromARGB(THIS.BackColorAlpha,lnBackColor)), ;
lnX, lnY, lnWidth, lnHeight)
IF lnMode = 0
loGfx.DrawRectangle( .PEN.New(.COLOR.FromRGB(RGB(192,192,192)), 1),lnX, lnY, lnWidth, lnHeight)
ENDIF
* ENDIF
lnX1=lnX
lnY1=lnY
lnX2=lnX+lnWidth
lnY2=lnY
lnX3=lnX2
lnY3=lnY+lnHeight
lnX4=lnX
lnY4=lnY3
IF lnRotation # 0
lnX0 = loPointF.X
lnY0 = loPointF.Y
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX1, @lnY1, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX2, @lnY2, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX3, @lnY3, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX4, @lnY4, lnRotation)
ENDIF
IF lnRotationCenter # 0
lnX0 = loPointFC.X
lnY0 = loPointFC.Y
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX1, @lnY1, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX2, @lnY2, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX3, @lnY3, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX4, @lnY4, lnRotationCenter)
ENDIF
TEXT TO lcPoints
<<Round(lnX1,0)>>,<<Round(lnY1,0)>>
<<Round(lnX2,0)>>,<<Round(lnY2,0)>>
<<Round(lnX3,0)>>,<<Round(lnY3,0)>>
<<Round(lnX4,0)>>,<<Round(lnY4,0)>>
ENDTEXT
LOCAL laPoints(4)
laPoints(1) = .POINT.New(lnX1, lnY1)
laPoints(2) = .POINT.New(lnX2, lnY2)
laPoints(3) = .POINT.New(lnX3, lnY3)
laPoints(4) = .POINT.New(lnX4, lnY4)
ENDWITH
* Draw the Text
IF lnMode = 0
LOCAL loStringFmt AS xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
loRect = .Rectangle.New(x1, y1, CEILING(THIS._Width), THIS._Height + 2)
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ELSE
IF tlVertical
loRect = .Rectangle.New(xBack, y1, THIS._Width, THIS._Height)
ENDIF
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ENDIF
THIS.PARENT._updatecoordinates (,'ScaleLegend', lnX1, lnY1, lnWidth, lnHeight, THIS._TransfCaption, lnRotationCenter, lcPoints, 0)
IF lnRotation # 0 OR lnRotationCenter # 0
loGfx.ResetTransform()
ENDIF
ENDWITH
ENDPROC
PROCEDURE ShapeLegend._drawstring
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tlVertical, lnBackColor, toParentShape
LOCAL lcPoints, ;
lnHeight, lnMargin, lnRotationCenter, lnWidth, lnX, lnX0, lnX1, lnX2, lnX3, lnX4, lnY, lnY0, lnY1, lnY2, lnY3, lnY4, ;
loGfx, loShape , loThisShape
LOCAL x1, y1, lnAlign, lnMode, xBack, lnNum
IF THIS.PARENT.Bartype = 1
tnX = tnX +THIS.PARENT._3D/2
ENDIF
*!* if this.Rotation#0 and tlVertical
*!* this.Rotation=MOD(this.Rotation+90,360)
*!* ENDIF
lnMode = 0 && 0 = x,y Coordinates ; 1 = xfcRectangle coordinates
lnAlign = THIS.ALIGNMENT
* 0 = Left 1 = Right 2 = Center
loGfx = THIS.PARENT.oGfx
lnBackColor=EVL(lnBackColor,THIS.BACKCOLOR)
WITH _SCREEN.SYSTEM.Drawing
DO CASE
CASE VARTYPE(tnWidth) + VARTYPE(tnHeight) = "NN"
lnMode = 1
* Create a STRINGFORMAT object in order to draw the string centered in the image
LOCAL loStringFmt AS xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
IF tlVertical
loStringFmt.FormatFlags = .StringFormatFlags.DirectionVertical
loStringFmt.LineAlignment = .StringAlignment.CENTER
ENDIF
LOCAL loSize AS xfcSize, loRect AS xfcRectangle
IF tlVertical
loSize = .SIZE.New(THIS.PARENT.WIDTH, THIS.PARENT.HEIGHT)
ELSE
loSize = .SIZE.New(tnWidth, tnHeight)
ENDIF
loSize = loGfx.MeasureString(;
THIS._TransfCaption, THIS._oFont, loSize, loStringFmt)
THIS._Height = CEILING(loSize.HEIGHT)
THIS._Width = CEILING(loSize.WIDTH)
loRect = .Rectangle.New(tnX, tnY, tnWidth, THIS._Height)
x1 = tnX
y1 = tnY
IF tlVertical
xBack = tnX + (tnWidth - THIS._Width) / 2
DO CASE
CASE lnAlign = 0 && Left
y1 = tnY
CASE lnAlign = 1 && Right
y1 = tnY + tnHeight - THIS._Height
CASE lnAlign = 2 && Center
y1 = tnY + (tnHeight - THIS._Height) / 2
ENDCASE
ELSE
DO CASE
CASE lnAlign = 0 && Left
xBack = tnX
CASE lnAlign = 1 && Right
xBack = tnX + tnWidth - THIS._Width
CASE lnAlign = 2 && Center
xBack = tnX + (tnWidth - THIS._Width) / 2
ENDCASE
ENDIF
CASE lnAlign = 0 && Left
STORE tnX TO x1, xBack
y1 = tnY
CASE lnAlign = 1 && Right
x1 = tnX - THIS._Width
xBack = x1
y1 = tnY
CASE lnAlign = 2 && Center
x1 = tnX - (THIS._Width / 2)
xBack = x1
y1 = tnY
ENDCASE
LOCAL lnRotation
lnRotation = THIS.ROTATION
IF lnRotation <> 0
LOCAL loPointF AS xfcPointF, loMatrix AS xfcMatrix
loMatrix = .Drawing2D.Matrix.New()
IF lnMode = 1
loPointF = .PointF.New(tnX, tnY) && this is the point of rotation
ELSE
DO CASE
CASE lnAlign = 0 && Left
loPointF = .PointF.New(x1 + 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 1 && Right
loPointF = .PointF.New(x1 + THIS._Width - 5, y1 + THIS._Height / 2) && this is the point of rotation
CASE lnAlign = 2 && Center
loPointF = .PointF.New(x1 + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
ENDCASE
ENDIF
loMatrix.RotateAt(lnRotation, loPointF)
loGfx.MultiplyTransform(loMatrix)
ENDIF
lnRotationCenter = THIS.RotationCenter
* Center Rotation
IF lnRotationCenter # 0
LOCAL loMatrixC AS xfcMatrix, loPointFC AS xfcPointF
loMatrixC = .Drawing2D.Matrix.New()
loPointFC = .PointF.New(xBack + THIS._Width / 2, y1 + THIS._Height / 2) && this is the point of rotation
loMatrixC.RotateAt(lnRotationCenter, loPointFC)
loGfx.MultiplyTransform(loMatrixC)
ENDIF
* IF THIS.BackColorAlpha > 0
* Draw the BackGround Shape
IF lnMode = 0 && default
lnX=x1
lnY=y1
lnWidth = THIS._Width-2
lnHeight=THIS._Height-4
ELSE
lnX=xBack+2
lnY=y1+2
lnWidth = THIS._Width-4
lnHeight=THIS._Height-4
ENDIF
IF THIS.PARENT.ShapeLegendType = 1
loGfx.FillRectangle( .SolidBrush.New(.COLOR.FromARGB(THIS.BackColorAlpha,lnBackColor)), ;
lnX, lnY, lnWidth, lnHeight)
=IIF( lnMode = 0,loGfx.DrawRectangle( .PEN.New(.COLOR.FromRGB(RGB(192,192,192)), 1),lnX, lnY, lnWidth, lnHeight),0)
ELSE
lnMargin=4
loGfx.FillEllipse( .SolidBrush.New(.COLOR.FromRGB(RGB(192,192,192)), 1), ;
lnX-lnMargin, lnY, lnWidth+lnMargin*2, lnHeight+lnMargin*2)
loGfx.FillEllipse( .SolidBrush.New(.COLOR.FromARGB(THIS.BackColorAlpha,lnBackColor)), ;
lnX-lnMargin, lnY-lnMargin, lnWidth+lnMargin*2, lnHeight+lnMargin*2)
=IIF( lnMode = 0, loGfx.DrawEllipse( .PEN.New(.COLOR.FromRGB(RGB(192,192,192)), 1),lnX-lnMargin, lnY-lnMargin, lnWidth+lnMargin*2, lnHeight+lnMargin*2),0)
lnY = lnY + lnMargin
ENDIF
lnX1=lnX
lnY1=lnY
lnX2=lnX+lnWidth
lnY2=lnY
lnX3=lnX2
lnY3=lnY+lnHeight
lnX4=lnX
lnY4=lnY3
IF lnRotation # 0
lnX0 = loPointF.X
lnY0 = loPointF.Y
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX1, @lnY1, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX2, @lnY2, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX3, @lnY3, lnRotation)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX4, @lnY4, lnRotation)
ENDIF
IF lnRotationCenter # 0
lnX0 = loPointFC.X
lnY0 = loPointFC.Y
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX1, @lnY1, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX2, @lnY2, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX3, @lnY3, lnRotationCenter)
THIS.PARENT.ROTATE(lnX0,lnY0,@lnX4, @lnY4, lnRotationCenter)
ENDIF
TEXT TO lcPoints
<<ROUND(lnX1,0)>>,<<ROUND(lnY1,0)>>
<<ROUND(lnX2,0)>>,<<ROUND(lnY2,0)>>
<<ROUND(lnX3,0)>>,<<ROUND(lnY3,0)>>
<<ROUND(lnX4,0)>>,<<ROUND(lnY4,0)>>
<<ROUND(lnX1,0)>>,<<ROUND(lnY1,0)>>
ENDTEXT
LOCAL laPoints(4)
laPoints(1) = .POINT.New(lnX1, lnY1)
laPoints(2) = .POINT.New(lnX2, lnY2)
laPoints(3) = .POINT.New(lnX3, lnY3)
laPoints(4) = .POINT.New(lnX4, lnY4)
* Draw the Text
IF lnMode = 0
LOCAL loStringFmt AS xfcStringFormat, lnGdipAlign
loStringFmt = .StringFormat.New()
DO CASE
CASE lnAlign = 2 && Center
lnGdipAlign = .StringAlignment.CENTER
CASE lnAlign = 1
lnGdipAlign = .StringAlignment.Far
OTHERWISE
lnGdipAlign = .StringAlignment.NEAR
ENDCASE
loStringFmt.ALIGNMENT = lnGdipAlign
loRect = .Rectangle.New(x1, y1, CEILING(THIS._Width), THIS._Height + 2)
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ELSE
IF tlVertical
loRect = .Rectangle.New(xBack, y1, THIS._Width, THIS._Height)
ENDIF
loGfx.DrawString(THIS._TransfCaption, THIS._oFont, THIS._oBrush, loRect, loStringFmt)
ENDIF
loThisShape=.F.
lnNum=0
IF VARTYPE(toParentShape)='O'
lnNum = toParentShape.CoordNum
FOR EACH loShape IN THIS.PARENT.Shapes.OBJECTS
IF loShape.ParentCoord = lnNum
loThisShape = loShape
ENDIF
NEXT
ENDIF
loThisShape = THIS.PARENT._updatecoordinates (loThisShape,'ShapeLegend', lnX1, lny1, lnWidth, lnHeight, THIS._TransfCaption, lnRotationCenter, lcPoints, 0)
loThisShape.ParentCoord = lnNum
IF lnRotation # 0 OR lnRotationCenter # 0
loGfx.ResetTransform()
ENDIF
RETURN loThisShape
ENDWITH
ENDPROC
ENDDEFINE
DEFINE CLASS foxchartshelper AS custom
*< CLASSDATA: Baseclass="custom" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: arcandpoint
*m: arrows
*m: drawcontour
*m: drawpath
*m: insidepath
*m: lineandpoint
*m: newarrowrow
*m: newrow
*m: objform
*m: pathgradient
*m: rotate
*m: rotatepath
*m: shell
*m: simplifypath
*m: sl
*m: unaxonometric
*m: unrgb
*</DefinedPropArrayMethod>
*<PropValue>
Name = "foxchartshelper"
*</PropValue>
PROCEDURE arcandpoint
LPARAMETERS tnX, tnY, tnWidth, tnHeight, tnAngle1, tnSwap, tlInverse, tnMouseX, tnMouseY
* Coordinates
LOCAL llBetween, llInverse, llYes, ;
ln, lnA, lnAngle, lnAngle1, lnAngle2, lnB, lnCenterX, lnCenterY, lnMouseX, lnMouseY, lnX, lnY1, lnY2
lnCenterX = tnX + tnWidth/2
lnCenterY = tnY+ tnHeight/2
lnMouseX = tnMouseX - lnCenterX
lnMouseY = lnCenterY - tnMouseY
lnA = tnWidth / 2
lnB = tnHeight / 2
lnY2 = ( 1 - lnMouseX^2/ lnA^2) * lnB^2
IF lnY2<0
RETURN .F.
ENDIF
llInverse = tlInverse
lnAngle1 = IIF(tnAngle1<0,360+tnAngle1,tnAngle1)
lnAngle2 = lnAngle1+tnSwap
IF lnAngle2<0
lnAngle2 =360+lnAngle2
llInverse = NOT llInverse
ENDIF
lnAngle2 = IIF(lnAngle2>360,lnAngle2-360,lnAngle2)
IF lnAngle1 > lnAngle2
ln=lnAngle1
lnAngle1 = lnAngle2
lnAngle2 = ln
llInverse = NOT llInverse
ENDIF
llYes = .F.
*
* First point
*
lnY1 = SQRT(lnY2)
m.lnAngle = IIF(lnMouseX=0, IIF(lnY1 < 0, 270, 90), RTOD(ATAN(m.lnY1/m.lnMouseX)) )
DO CASE
CASE lnMouseX < 0
m.lnAngle = 180 + m.lnAngle
CASE lnY1 < 0
m.lnAngle = 360 + m.lnAngle
ENDCASE
m.lnAngle = 360 - m.lnAngle
llBetween=BETWEEN(lnAngle, lnAngle1, lnAngle2) && AND MAX(lnY1/TAN(DTOR(lnAngle1)), lnY1/TAN(DTOR(lnAngle2)))>m.lnMouseX
IF llInverse
llBetween = NOT llBetween
ENDIF
IF llBetween
lnX = MAX(lnY1/TAN(DTOR(lnAngle1)), lnY1/TAN(DTOR(lnAngle2))) && + lnCenterX
IF ABS(lnX) < 1
llBetween=.F.
ENDIF
ENDIF
IF llBetween AND lnMouseY < lnY1
llYes = NOT llYes
ENDIF
*
* Second Point
*
lnY1 = -lnY1
m.lnAngle = IIF(lnMouseX=0, IIF(lnY1<0, 270, 90), RTOD(ATAN(m.lnY1/m.lnMouseX)) )
DO CASE
CASE lnMouseX < 0
m.lnAngle = 180 + m.lnAngle
CASE lnY1 < 0
m.lnAngle = 360 + m.lnAngle
ENDCASE
m.lnAngle = 360 - m.lnAngle
llBetween=BETWEEN(lnAngle, lnAngle1, lnAngle2) && AND MAX(lnY1/TAN(DTOR(lnAngle1)), lnY1/TAN(DTOR(lnAngle2)))>m.lnMouseX
IF llBetween
lnX = MAX(lnY1/TAN(DTOR(lnAngle1)), lnY1/TAN(DTOR(lnAngle2))) && + lnCenterX
IF ABS(lnX) < 1
llBetween=.F.
ENDIF
ENDIF
IF llInverse
llBetween = NOT llBetween
ENDIF
IF llBetween AND lnMouseY < lnY1
llYes = NOT llYes
ENDIF
RETURN llYes
ENDPROC
PROCEDURE arrows
LPARAMETERS lnType, lnX0, lnY0, lnArrowHeight, lnArrowWidth, lnEndWidth, lnValue
LOCAL lcPolygon, lnHalf
m.lnHalf = lnArrowHeight/2
lnRad=5
lcPolygon=''
DO CASE
CASE lnType = 1
This.NewArrowRow( @lcPolygon, lnX0, lnY0+lnHalf-lnRad, lnX0, lnY0-lnHalf+lnRad)
This.NewArrowRow( @lcPolygon,lnX0,lnY0-lnHalf,lnRad*2,lnRad*2,180,90)
This.NewArrowRow( @lcPolygon,lnX0+lnRad,lnY0-lnHalf,lnX0 + m.lnArrowWidth -lnEndWidth-lnRad,lnY0 - m.lnHalf)
This.NewArrowRow( @lcPolygon,lnX0 + m.lnArrowWidth - lnEndWidth-lnRad*2,lnY0 - m.lnHalf-lnRad*2,lnRad*2,lnRad*2,90,-90)
This.NewArrowRow( @lcPolygon,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 - m. lnArrowHeight+lnRad, lnX0 + m.lnArrowWidth - lnEndWidth ,lnY0- m. lnArrowHeight )
This.NewArrowRow( @lcPolygon,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 - m. lnArrowHeight, lnX0 + m.lnArrowWidth ,lnY0 )
This.NewArrowRow( @lcPolygon,lnX0 + m.lnArrowWidth,lnY0 ,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 + m. lnArrowHeight )
This.NewArrowRow( @lcPolygon,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 + m. lnArrowHeight,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 + m.lnHalf + lnRad)
This.NewArrowRow( @lcPolygon,lnX0 + m.lnArrowWidth - lnEndWidth-lnRad*2,lnY0 + m.lnHalf,lnRad*2,lnRad*2,0,-90)
This.NewArrowRow( @lcPolygon,lnX0 + m.lnArrowWidth - lnEndWidth-lnRad,lnY0 + m.lnHalf,lnX0+lnRad ,lnY0 + m.lnHalf)
This.NewArrowRow( @lcPolygon,lnX0,lnY0+lnHalf-lnRad*2,lnRad*2,lnRad*2,90,90)
CASE lnType = 2
This.NewArrowRow( @lcPolygon, lnX0, lnY0-lnHalf,lnX0 + m.lnArrowWidth - lnEndWidth-lnRad,lnY0 - m.lnHalf )
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth-lnRad*2,lnY0 - m.lnHalf-lnRad*2,lnRad*2,lnRad*2,90,-90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 - m.lnHalf-lnRad,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 - m.lnHalf-lnRad)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 - m. lnArrowHeight,lnX0 + m.lnArrowWidth,lnY0 )
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0 ,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 + m. lnArrowHeight)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 + m. lnArrowHeight,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0 + m.lnHalf + lnRad)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth-lnRad*2,lnY0 + m.lnHalf,lnRad*2,lnRad*2,0,-90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth-lnRad,lnY0 + m.lnHalf,lnX0 ,lnY0 + m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 ,lnY0 + m.lnHalf,lnX0+lnHalf ,lnY0)
This.NewArrowRow( @lcPolygon, lnX0+lnHalf ,lnY0,lnX0,lnY0-lnHalf)
lnX0 = lnX0 + lnHalf
CASE lnType = 3 && <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
***********************************************
This.NewArrowRow( @lcPolygon, lnX0,lnY0,lnX0+lnEndWidth,lnY0-lnArrowHeight)
This.NewArrowRow( @lcPolygon, lnX0+lnEndWidth,lnY0-lnArrowHeight,lnX0+lnEndWidth,lnY0 - lnHalf - lnRad)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnEndWidth,lnY0-lnHalf-lnRad*2,lnRad*2,lnRad*2,180,-90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnEndWidth+lnRad,lnY0-lnHalf,lnX0 + m.lnArrowWidth - lnEndWidth-lnRad,lnY0-lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth-lnRad*2,lnY0-lnHalf-lnRad*2,lnRad*2,lnRad*2,90,-90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth,lnY0-lnHalf-lnRad,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0-lnHalf*2)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth,lnY0-lnHalf*2,lnX0 + m.lnArrowWidth,lnY0)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0+lnHalf*2)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth,lnY0+lnHalf*2,lnX0 + m.lnArrowWidth - lnEndWidth,lnY0+lnHalf+lnRad)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth-lnRad*2,lnY0+lnHalf,lnRad*2,lnRad*2,0,-90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnEndWidth-lnRad,lnY0+lnHalf,lnX0 + lnEndWidth+lnRad,lnY0+lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnEndWidth,lnY0+lnHalf,lnRad*2,lnRad*2,270,-90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnEndWidth,lnY0+lnHalf+lnRad,lnX0 + m.lnEndWidth,lnY0+lnHalf*2)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnEndWidth,lnY0+lnHalf*2,lnX0,lnY0)
CASE lnType = 4
This.NewArrowRow( @lcPolygon, lnX0,lnY0+lnHalf-lnRad,lnX0,lnY0-lnHalf+lnRad)
This.NewArrowRow( @lcPolygon, lnX0,lnY0-lnHalf,lnRad*2,lnRad*2,180,90)
This.NewArrowRow( @lcPolygon, lnX0+lnRad,lnY0-lnHalf,lnX0 + m.lnArrowWidth - lnHalf,lnY0 - m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf,lnY0 - m.lnHalf,lnX0 + m.lnArrowWidth,lnY0 )
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0 ,lnX0 + m.lnArrowWidth - lnHalf,lnY0 + m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf,lnY0 + m.lnHalf,lnX0+lnRad,lnY0 + m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0,lnY0+lnHalf-lnRad*2,lnRad*2,lnRad*2,90,90)
CASE lnType = 5
This.NewArrowRow( @lcPolygon, lnX0+lnHalf,lnY0)
This.NewArrowRow( @lcPolygon, lnX0,lnY0-lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf,lnY0 - m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0 )
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf,lnY0 + m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0,lnY0 + m.lnHalf)
lnX0 = lnX0 + lnHalf
CASE lnType = 6
This.NewArrowRow( @lcPolygon, lnX0,lnY0+lnHalf-lnRad,lnX0,lnY0-lnHalf+lnRad)
This.NewArrowRow( @lcPolygon, lnX0,lnY0-lnHalf,lnRad*2,lnRad*2,180,90)
This.NewArrowRow( @lcPolygon, lnX0+lnRad,lnY0-lnHalf,lnX0+lnArrowWidth-lnHalf-lnRad,lnY0-lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf-lnRad*2,lnY0-lnHalf,lnRad*2,lnRad*2,270,90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf,lnY0-lnHalf+lnRad,lnX0 + m.lnArrowWidth - lnHalf,lnY0-lnHalf/3)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf,lnY0 - m.lnHalf/3 ,lnX0 + m.lnArrowWidth - lnHalf + 5,lnY0 - m.lnHalf/3 )
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf + 5,lnY0 - m.lnHalf/3 ,lnX0 + m.lnArrowWidth - lnHalf + 5,lnY0 - m.lnHalf/1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf + 5,lnY0 - m.lnHalf/1.5,lnX0 + m.lnArrowWidth,lnY0 )
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0 ,lnX0 + m.lnArrowWidth - lnHalf + 5,lnY0 + m.lnHalf/1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf + 5,lnY0 + m.lnHalf/1.5,lnX0 + m.lnArrowWidth - lnHalf + 5,lnY0 + m.lnHalf/3 )
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf + 5,lnY0 + m.lnHalf/3 ,lnX0 + m.lnArrowWidth - lnHalf+lnRad,lnY0 + m.lnHalf/3 )
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf,lnY0 + m.lnHalf/3 ,lnX0 + m.lnArrowWidth - lnHalf,lnY0 + lnHalf-lnRad)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf-lnRad*2,lnY0+lnHalf-lnRad*2,lnRad*2,lnRad*2,0,90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - lnHalf-lnRad,lnY0+lnHalf,lnX0 + lnRad,lnY0+lnHalf)
This.NewArrowRow( @lcPolygon, lnX0,lnY0+lnHalf - lnRad*2,lnRad*2,lnRad*2,90,90)
CASE lnType = 7
lnArrowWidth=lnArrowWidth-8
DO CASE
CASE lnValue<0
This.NewArrowRow( @lcPolygon, lnX0,lnY0+lnHalf-lnRad,lnX0,lnY0-lnHalf+lnRad)
This.NewArrowRow( @lcPolygon, lnX0,lnY0-lnHalf,lnRad*2,lnRad*2,180,90)
This.NewArrowRow( @lcPolygon, lnX0+lnRad,lnY0-lnHalf,lnX0 + m.lnArrowWidth -lnRad,lnY0 - m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth-lnRad*2 ,lnY0-lnHalf,lnRad*2,lnRad*2, 270,90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0 - m.lnHalf +lnRad, lnX0 + m.lnArrowWidth,lnY0 + m.lnHalf*1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0 + m.lnHalf*1.5,lnX0 + m.lnArrowWidth + 8,lnY0 + m.lnHalf*1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth + 8,lnY0 + m.lnHalf*1.5,lnX0 + m.lnArrowWidth - m.lnHalf,lnY0 + m.lnHalf*2.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - m.lnHalf,lnY0 + m.lnHalf*2.5,lnX0 + m.lnArrowWidth - m.lnHalf*2 - 8,lnY0 + m.lnHalf*1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - m.lnHalf*2 - 8,lnY0 + m.lnHalf*1.5,lnX0 + m.lnArrowWidth - m.lnHalf*2,lnY0 + m.lnHalf * 1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - m.lnHalf*2,lnY0 + m.lnHalf * 1.5,lnX0 + m.lnArrowWidth - m.lnHalf*2,lnY0 + m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - m.lnHalf*2,lnY0 + m.lnHalf,lnX0+lnRad,lnY0 + m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0,lnY0+lnHalf-lnRad*2,lnRad*2,lnRad*2,90,90)
CASE lnValue>0
This.NewArrowRow( @lcPolygon, lnX0,lnY0+lnHalf-lnRad*2,lnRad*2,lnRad*2, 180, -90)
This.NewArrowRow( @lcPolygon, lnX0+lnRad,lnY0 + m.lnHalf,lnX0 + m.lnArrowWidth-lnRad,lnY0 + m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth-lnRad*2,lnY0+lnHalf-lnRad*2,lnRad*2,lnRad*2, 90, -90)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0 + m.lnHalf - lnRad, lnX0 + m.lnArrowWidth,lnY0 - m.lnHalf*1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth,lnY0 - m.lnHalf*1.5,lnX0 + m.lnArrowWidth + 8,lnY0 - m.lnHalf*1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth + 8,lnY0 - m.lnHalf*1.5,lnX0 + m.lnArrowWidth - m.lnHalf,lnY0 - m.lnHalf*2.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - m.lnHalf,lnY0 - m.lnHalf*2.5,lnX0 + m.lnArrowWidth - m.lnHalf*2 - 8,lnY0 - m.lnHalf*1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - m.lnHalf*2 - 8,lnY0 - m.lnHalf*1.5,lnX0 + m.lnArrowWidth - m.lnHalf*2,lnY0 - m.lnHalf * 1.5)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - m.lnHalf*2,lnY0 - m.lnHalf * 1.5,lnX0 + m.lnArrowWidth - m.lnHalf*2,lnY0 - m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0 + m.lnArrowWidth - m.lnHalf*2,lnY0 - m.lnHalf,lnX0+lnRad,lnY0 - m.lnHalf)
This.NewArrowRow( @lcPolygon, lnX0,lnY0-lnHalf,lnRad*2,lnRad*2, 270, -90)
This.NewArrowRow( @lcPolygon, lnX0,lnY0+lnHalf-lnRad,lnX0,lnY0-lnHalf+lnRad)
OTHERWISE
RETURN this.Arrows(1, lnX0, lnY0, lnArrowHeight, lnArrowWidth, lnEndWidth, lnValue)
ENDCASE
ENDCASE
RETURN lcPolygon
*!* LPARAMETERS lcText,tcParam1,tcParam2,tcParam3,tcParam4,tcParam5,tcParam6,tcParam7
*!* lnCount = PCOUNT()
*!* if lnCount>3 and VARTYPE(tcParam3)#'N'
*!* tcParam3=tcParam1
*!* endif
*!* FOR lnLine=1 TO lnCOUNT-1
*!* lcStr = IIF(lnLine=1, '', lcStr+',') + Transform(ROUND(EVALUATE('tcParam'+allt(STR(lnLine))),0))
*!* NEXT
*!* TEXT TO lcText addi
*!* <<lcStr>>
*!* ENDTEXT
ENDPROC
PROCEDURE drawcontour
LPARAMETERS loChart, lcLines, tnIndex
LOCAL lnGradientPosition, loBrush, loObject
WITH loChart
IF TYPE('.ContourGraphics.Name') = 'C'
.ContourGraphics.dispose()
.ContourGraphics=.F.
ENDIF
loForm = this.ObjForm(loChart)
loForm.CLS()
lnGradientPosition=MAX(0.05,MIN(0.95,.GradientPosition))
.Tips.VISIBLE = .F.
.ContourGraphics = _SCREEN.SYSTEM.Drawing.Graphics.FromHWnd(loForm.HWND) && Create a Graphics object
.ContourGraphics.SmoothingMode = 4
.ContourPen = _SCREEN.SYSTEM.Drawing.PEN.New(_SCREEN.SYSTEM.Drawing.COLOR.White , 2)
.ContourPen.DASHSTYLE = 3
IF VARTYPE(lcLines)='O'
WITH _SCREEN.SYSTEM.Drawing
loBrush = .Drawing2D.LinearGradientBrush.New(;
.Rectangle.New(lcLines.LEFT, lcLines.TOP, lcLines.WIDTH , lcLines.HEIGHT), ;
.COLOR.FromARGB(64,IIF(loChart.GradientInvertColors,.COLOR.Black,.COLOR.White)), ;
.COLOR.FromARGB(64,IIF(loChart.GradientInvertColors,.COLOR.White,.COLOR.Black)), ;
IIF(loChart._Orientation = 1,0,1))
ENDWITH
loBrush.SetSigmaBellShape(lnGradientPosition, 1)
lcLines.DrawContour(.ContourGraphics, .ContourPen, loBrush, OBJ2CLIENT(loChart,2), OBJ2CLIENT(loChart,1) )
RETURN
ENDIF
loObject = EVALUATE([loChart.shapes.shape] + ALLTRIM(STR(tnIndex)))
IF loObject.TYPE = 'Rect' AND .SHOWTIPS AND NOT .ShowValuesonshapes
WITH loChart.Tips
.ZORDER(0)
.BACKSTYLE = 1
.BACKCOLOR = loChart.ShapeLegend.BACKCOLOR
.VALUE = .F. &&loObject.Caption
.CAPTION = loObject.CAPTION
* .EvalCaption()
.TOP = loObject.TOP
.LEFT = loObject.LEFT
.WIDTH=200
.AUTOSIZE = .T.
.VISIBLE=.T.
ENDWITH
ENDIF
WITH _SCREEN.SYSTEM.Drawing
loBrush = .Drawing2D.LinearGradientBrush.New(;
.Rectangle.New(loObject.LEFT, loObject.TOP, EVL(loObject.WIDTH,1) , EVL(loObject.HEIGHT,1)), ;
.COLOR.FromARGB(64,IIF(loChart.GradientInvertColors,.COLOR.Black,.COLOR.White)), ;
.COLOR.FromARGB(64,IIF(loChart.GradientInvertColors,.COLOR.White,.COLOR.Black)), ;
IIF(loChart._Orientation = 1,0,1))
ENDWITH
loBrush.SetSigmaBellShape(lnGradientPosition, 1)
this.DrawPath(.ContourGraphics, .ContourPen, loBrush, lcLines, OBJ2CLIENT(loChart,2), OBJ2CLIENT(loChart,1))
ENDWITH
ENDPROC
PROCEDURE drawpath
LPARAMETERS toGraphics, toPen, toPathBrush, tcLines, tnLeft, tnTop
LOCAL llAfterArc, llWrapMode, lnCount, lnCount2, lnLeft, lnLine, lnLines, lnParams, lnTop, lnX1, lnX2, lnY1, lnY2, ;
loColor, loPath, la(1)
PRIVATE gnColor1, gnColor2, gnCenterPointX, gnCenterPointY, gnFocusScales
gnFocusScales=.3
EXTERNAL array xfcGdipGetPathGradientSurroundColorCount, xfcGdipSetPathGradientSurroundColorsWithCount, xfcGdipGetPathGradientSurroundColorsWithCount
WITH _SCREEN.SYSTEM.Drawing
lnLeft = EVL(tnLeft,0)
lnTop = EVL(tnTop,0)
loPath = .Drawing2D.GraphicsPath.New()
loPath.FillMode = .Drawing2D.FillMode.ALTERNATE
loPath.StartFigure()
tcLines=EVL(tcLines,'')
lnLines = ALINES(la, tcLines)
lnY1 = VAL(la2(ALINES(la2,la(1),',')))+lnTop
lnX1 = VAL(la2(1)) + lnLeft
llAfterArc = .F.
FOR lnLine=1 TO lnLines
lnParams = ALINES(la2,la(lnLine),',')
IF lnParams<2
LOOP
ENDIF
IF lnParams = 4
loPath.ADDLINE( VAL(la2(1)) + lnLeft, VAL(la2(2))+lnTop, VAL(la2(3)) + lnLeft, VAL(la2(4)) + lnTop )
llAfterArc = .T.
LOOP
ENDIF
IF lnParams = 5
loPath.ADDLINE( VAL(la2(1)) + lnLeft, VAL(la2(2))+lnTop, VAL(la2(1)) + lnLeft, VAL(la2(2)) + lnTop )
llAfterArc = .T.
LOOP
ENDIF
IF lnParams > 5
loPath.AddArc(VAL(la2(1))+ lnLeft, VAL(la2(2))+lnTop, VAL(la2(3)), VAL(la2(4)), VAL(la2(5)), VAL(la2(6)) )
IF lnParams >6 AND NOT EMPTY( VAL(la2(7)) )
loPath.Reverse()
ENDIF
llAfterArc = .T.
LOOP
ENDIF
IF llAfterArc
llAfterArc = .F.
LOOP
ENDIF
lnY2 = VAL(la2(2))+lnTop
lnX2= VAL(la2(1)) + lnLeft
IF llAfterArc
llAfterArc = .F.
LOOP
ELSE
loPath.ADDLINE(lnX1,lnY1, lnX2,lnY2)
ENDIF
lnX1=lnX2
lnY1=lnY2
NEXT
IF VARTYPE(toPathBrush) = 'C'
gnColor1 = RGB(212,212,212)
gnColor2 = RGB(250,250,250)
gnCenterPointX = -1
gnCenterPointY = 0
llWrapMode=.T.
=EXECSCRIPT(toPathBrush)
toPathBrush = .Drawing2D.PathGradientBrush.New(loPath)
lnCount=0
=xfcGdipGetPathGradientSurroundColorCount(toPathBrush.Handle, @lnCount)
m.lqColors = REPLICATE(0h00000000,lnCount)
m.lnCount2 = 0
=xfcGdipGetPathGradientSurroundColorsWithCount(toPathBrush.Handle, @lqColors, @lnCount2)
loColor = .COLOR.FromRGB(gnColor1)
m.lqColors = REPLICATE(BINTOC(loColor.ARGB,"4rs"),m.lnCount)
=xfcGdipSetPathGradientSurroundColorsWithCount(toPathBrush.Handle, @lqColors, @lnCount)
toPathBrush.CenterColor = .COLOR.FromRGB(gnColor2)
toPathBrush.SetBlendTriangularShape(.5,1)
toPathBrush.FocusScales = gnFocusScales
IF gnCenterPointX>=0
toPathBrush.CenterPoint = .POINT.New(gnCenterPointX,gnCenterPointY)
ENDIF
toPathBrush.WrapMode = llWrapMode
ENDIF
IIF(VARTYPE(toPathBrush) ='O', toGraphics.FillPath(toPathBrush, loPath),.F.)
IIF(VARTYPE(toPen) ='O', toGraphics.DrawPath(toPen, loPath),.F.)
ENDWITH
ENDPROC
PROCEDURE insidepath
LPARAMETERS lcPoints, lnMouseX, lnMouseY
LOCAL llInverse, llMouseInsideShape, ;
lnParams, lnPoint, lnPoints, lnX1, lnX2, lnY1, lnY2, la(1), la1(1)
llMouseInsideShape = .F.
STORE .F. TO lnX2, lnY2
FOR lnPoint=1 TO ALINES(la,RTRIM(lcPoints,CHR(13)+CHR(10)))
lnParams=ALINES(la1,la(lnPoint),',')
DO CASE
CASE INLIST(lnParams,4,5) && Line
lnX1 = VAL(la1(1))
lnY1 = VAL(la1(2))
lnX2 = VAL(la1(3))
lnY2 = VAL(la1(4))
IF VARTYPE(lnX2)='N' AND This.LineAndPoint (lnX1, lnY1, lnX2, lnY2, lnMouseX, lnMouseY) && and not lnX1=lnX2
llMouseInsideShape = NOT llMouseInsideShape
ENDIF
lnX2 = lnX1
lnY2 = lnY1
CASE lnParams>5 && Arc
STORE .F. TO lnX2, lnY2
llInverse = IIF(lnParams=6,.F., la1(7)='1')
IF This.ArcAndPoint( VAL(la1(1)), VAL(la1(2)), VAL(la1(3)), VAL(la1(4)), VAL(la1(5)), VAL(la1(6)), llInverse, lnMouseX, lnMouseY )
llMouseInsideShape = NOT llMouseInsideShape
ENDIF
CASE lnParams>1 && Point
lnX1 = VAL(la1(1))
lnY1 = VAL(la1(2))
IF VARTYPE(lnX2)='N' AND This.LineAndPoint (lnX1, lnY1, lnX2, lnY2, lnMouseX, lnMouseY)
llMouseInsideShape = NOT llMouseInsideShape
ENDIF
lnX2 = lnX1
lnY2 = lnY1
ENDCASE
NEXT
RETURN llMouseInsideShape
ENDPROC
PROCEDURE lineandpoint
LPARAMETERS lnX1, lnY1, lnX2, lnY2, lnMouseX, lnMouseY
LOCAL lnA1, lnB1, lnY_of_Meeting
IF MIN(m.lnY1,m.lnY2)>m.lnMouseY OR NOT BETWEEN(m.lnMouseX, MIN(m.lnX1,m.lnX2), MAX(m.lnX1,m.lnX2)-0.1)
RETURN .F.
ENDIF
m.lnA1 = (m.lnY2-m.lnY1) / (m.lnX2-m.lnX1)
m.lnB1 = m.lnY1 - m.lnX1*m.lnA1
m.lnY_of_Meeting = m.lnA1*m.lnMouseX +m.lnB1
RETURN m.lnY_of_Meeting <= m.lnMouseY && and lnX2#lnMouseX
ENDPROC
PROCEDURE newarrowrow
LPARAMETERS lcText,tcParam1,tcParam2,tcParam3,tcParam4,tcParam5,tcParam6,tcParam7
lnCount = PCOUNT()
IF lnCount>3 AND VARTYPE(tcParam3)#'N'
tcParam3=tcParam1
ENDIF
FOR lnLine=1 TO lnCount-1
lcStr = IIF(lnLine=1, '', lcStr+',') + TRANSFORM(ROUND(EVALUATE('tcParam'+ALLT(STR(lnLine))),0))
NEXT
TEXT TO lcText addi
<<lcStr>>
ENDTEXT
ENDPROC
PROCEDURE newrow
LPARAMETERS lcText,tcParam1,tcParam2,tcParam3,tcParam4,tcParam5,tcParam6,tcParam7
LOCAL lcStr, lnCount, lnLine
lnCount = PCOUNT()
lcStr = ''
IF lnCount>3 AND VARTYPE(tcParam3)#'N'
tcParam3=tcParam1
ENDIF
FOR lnLine=1 TO lnCount-1
lcStr = IIF(EMPTY(lcStr), '', lcStr+',') + TRANSF(ROUND(EVALUATE('tcParam'+ALLT(STR(lnLine))),0))
NEXT
TEXT TO lcText addi
<<lcStr>>
ENDTEXT
ENDPROC
PROCEDURE objform
LPARAMETERS loObj
LOCAL lnLine
IF TYPE('loObj')#'O' OR UPPER(loObj.BASECLASS)='FORM'
RETURN loObj
ENDIF
FOR lnLine=1 TO 20
loObj=loObj.PARENT
IF UPPER(loObj.BASECLASS)='FORM'
EXIT
ENDIF
NEXT
RETURN loObj
ENDPROC
PROCEDURE pathgradient
LPARAMETERS toGraphics, toPath, lnColor1, lnColor2, lnCenterPointX, lnCenterPointY, lnXkoef, lnYkoef, lnAlphaChannel
EXTERNAL array xfcGdipGetPathGradientSurroundColorCount, xfcGdipSetPathGradientSurroundColorsWithCount
LOCAL llWrapMode, lnB, lnCount, lnCount2, lnFocusScales, lnG, lnGray, lnR, loColor, loPathBrush
IF lnColor2<0
STORE 0 TO lnR, lnG, lnB, lnGray
THIS.UnRGB(lnColor1, @lnR, @lnG, @lnB, @lnGray)
lnColor2= IIF( lnGray > 127, RGB(114,43,0),RGB(255,249,183))
ENDIF
lnAlphaChannel = IIF(VARTYPE( lnAlphaChannel)='N', lnAlphaChannel,255)
lnFocusScales= 0
llWrapMode = .F.
lnXkoef = IIF(VARTYPE(lnXkoef)='N',lnXkoef,1)
lnYkoef = IIF(VARTYPE(lnYkoef)='N',lnYkoef,0.7)
WITH _SCREEN.SYSTEM.Drawing
loPathBrush = .Drawing2D.PathGradientBrush.New(toPath)
lnCount=0
=xfcGdipGetPathGradientSurroundColorCount(loPathBrush.Handle, @lnCount)
m.lqColors = REPLICATE(0h00000000,lnCount)
m.lnCount2 = 0
=xfcGdipGetPathGradientSurroundColorsWithCount(loPathBrush.Handle, @lqColors, @lnCount2)
loColor = .COLOR.FromRGB(lnColor1)
m.lqColors = REPLICATE(BINTOC(loColor.ARGB,"4rs"),m.lnCount)
=xfcGdipSetPathGradientSurroundColorsWithCount(loPathBrush.Handle, @lqColors, @lnCount)
loPathBrush.CenterColor = .COLOR.FromARGB( lnAlphaChannel,lnColor2)
loPathBrush.SetBlendTriangularShape(lnXkoef, lnYkoef)
loPathBrush.FocusScales = lnFocusScales
IF lnCenterPointX>=0
loPathBrush.CenterPoint = .POINT.New(lnCenterPointX,lnCenterPointY)
ENDIF
loPathBrush.WrapMode = llWrapMode
ENDWITH
IF VARTYPE(toGraphics)='O'
toGraphics.FillPath(loPathBrush, toPath)
ENDIF
RETURN loPathBrush
ENDPROC
PROCEDURE rotate
LPARAMETERS lnX0,lnY0, lnX, lnY, lnNewAngle
LOCAL lnX1, lnY1
lnX1=lnX-lnX0
lnY1=lnY-lnY0
lnX = lnX1*COS(lnNewAngle)-lnY1*SIN(lnNewAngle) +lnX0
lnY = lnX1*SIN(lnNewAngle)+lnY1*COS(lnNewAngle) +lnY0
ENDPROC
PROCEDURE rotatepath
LPARAMETERS lnX0, lnY0, lcPath, lnAngle
LOCAL lcNewPath, lcNewStr, lnCount, lnLine, lnX1, lnX2, lnY1, lnY2, la(1), la1(1)
lnAngle = DTOR(lnAngle)
lcNewPath = ''
FOR lnLine=1 TO IIF(EMPTY(lcPath),0,ALINE(la1,lcPath))
lnCount = ALINE(la, la1(lnLine), ',')
lnX1=VAL(la(1))
lnY1=VAL(la(2))
THIS.ROTATE(lnX0, lnY0, @lnX1, @lnY1, lnAngle)
la(1)=Transform(ROUND(lnX1,0))
la(2)=Transform(ROUND(lnY1,0))
IF lnCount=4
lnX1=VAL(la(3))
lnY1=VAL(la(4))
THIS.ROTATE(lnX0, lnY0, @lnX1, @lnY1, lnAngle)
la(3)=Transform(ROUND(lnX1,0))
la(4)=Transform(ROUND(lnY1,0))
ENDIF
FOR lnCol=1 TO lnCount
lcNewStr = IIF(lnCol=1,'',lcNewStr + ',')+la(lnCol)
NEXT
TEXT to lcNewPath addi
<<lcNewStr>>
ENDTEXT
NEXT
RETURN lcNewPath
ENDPROC
PROCEDURE shell
LPARAMETERS lcFileName,tcWorkDir,tcOperation,lcparams, llInVisible
LOCAL lcWorkDir,lcOperation
IF EMPTY(lcFileName)
RETURN -1
ENDIF
lcFileName=ALLTRIM(lcFileName)
lcWorkDir=IIF(TYPE("tcWorkDir")="C",ALLTRIM(tcWorkDir),"")
lcOperation=IIF(TYPE("tcOperation")="C" AND ! EMPTY(tcOperation),ALLTRIM(tcOperation),"Open")
IF PCOUNT()<4
lcparams=''
ENDIF
DECLARE INTEGER ShellExecute ;
IN SHELL32.DLL ;
INTEGER nWinHandle,;
STRING cOperation, STRING cFileName, STRING cParameters,;
STRING cDirectory, INTEGER nShowWindow
RETURN ShellExecute(0,lcOperation,lcFileName,lcparams,lcWorkDir,IIF(EMPTY(llInVisible),1,0))
ENDPROC
PROCEDURE simplifypath
LPARAMETERS lcPath
LOCAL lnLine
IF EMPTY(lcPath)
RETURN ''
ENDIF
LOCAL lcLeft, lcNew, lcNext, lcTop, lnCount, lnLines
lcNew=''
lnLines = ALINE(la1,lcPath)
IF lnLines = 1
RETU lcPath
ENDIF
lnCount= ALINE(la,la1(lnLines), [,])
IF lnCount>4
lnCount= ALINE(la,la1(lnLines-1), [,])
ENDIF
lcLeft=la(1)
lcTop=la(2)
FOR lnLine=1 TO lnLines
lnCount = ALINE(la, la1(lnLine), [,])
IF lnCount>4
lcNext = la1(IIF(lnLine=lnLines,1,lnLine+1))
ALINE(la2, lcNext,',')
TEXT to lcNew addi
<<lcLeft>>,<<lcTop>>,<<la2(1)>>,<<la2(2)>>
ENDTEXT
LOOP
ENDIF
TEXT to lcNew addi
<<la1(lnLine)>>
ENDTEXT
lcLeft = la(lnCount-1)
lcTop= la(lnCount)
NEXT
RETU lcNew
ENDPROC
PROCEDURE sl
LPARAMETERS lc,lcName,llLeave, lcType
LOCAL lcReturn
lcName=EVL(lcName,SET("Default")+CURDIR()+'\_Help.txt')
STRTOFILE(IIF(VARTYPE(lc)='C',lc,TRANSFORM(lc)),lcName,0)
IF EMPTY(lcType) OR VARTYPE(lcType)#'C'
MODIFY COMMAND &lcName && RANGE 1,1
lcReturn = FILETOSTR(lcName)
IF EMPTY(llLeave)
TRY
ERASE &lcName
CATCH
ENDTRY
ENDIF
ELSE
this.SHELL(lcType,'',,FULLPATH(lcName) )
lcReturn = FILETOSTR(lcName)
ENDIF
RETURN lcReturn
ENDPROC
PROCEDURE unaxonometric
LPARAMETERS tnAngle, tnWidth, tnHeight
LOCAL lnNewAngle
IF m.tnAngle > 360
m.tnAngle = m.tnAngle - 360
ENDIF
IF m.tnAngle < 0
m.tnAngle = m.tnAngle + 360
ENDIF
m.tnAngle = ROUND(m.tnAngle, 4)
lnNewAngle=DTOR(m.tnAngle - IIF(m.tnAngle>90 AND m.tnAngle<= 270,180,0))
lnNewAngle=RTOD(ATAN(TAN(lnNewAngle)*tnWidth/tnHeight)) + ICASE( BETWEEN(m.tnAngle , 0, 90),0, BETWEEN(m.tnAngle ,90,270),180, .T., 360)
IF m.lnNewAngle < 0
m.lnNewAngle = m.lnNewAngle + 360
ENDIF
IF m.lnNewAngle - m.tnAngle > 170
m.lnNewAngle = m.lnNewAngle - 180
ENDIF
RETURN m.lnNewAngle
ENDPROC
PROCEDURE unrgb
LPARAMETERS lnColor, lnRed, lnBlue, lnGreen, lnGrayColor
lnRed=MOD(lnColor,256)
lnGreen=ROUND(MOD((lnColor-lnRed)/256,256),0)
lnBlue=ROUND(MOD((lnColor-lnRed-lnGreen*256)/256/256,256),0)
lnGrayColor = ROUND(0.229*lnRed + 0.587*lnGreen + 0.114*lnBlue,0)
Return TEXTMERGE([RGB(<<lnRed>>,<<lnGreen>>,<<lnBlue>>)])
ENDPROC
ENDDEFINE
DEFINE CLASS pattern AS imgcanvas OF "gdiplusx.vcx"
*< CLASSDATA: Baseclass="image" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: myrenderosb
*p: brush
*p: pen
*p: todraw
*</DefinedPropArrayMethod>
*<PropValue>
brush = .F.
Name = "pattern"
pen = .F.
todraw = .F.
*</PropValue>
PROCEDURE beforedraw
WITH THIS
.CLEAR(_SCREEN.SYSTEM.Drawing.COLOR.Transparent)
.RenderMode = 4 && Memory PNG
.BACKSTYLE = 0 && Transparent
IF NOT EMPTY(.ToDraw)
RETURN EXECSCRIPT(.ToDraw)
ENDIF
ENDWITH
ENDPROC
PROCEDURE draw
LPARAMETERS tnWidth, tnHeight, toGfx
WITH THIS
.CLEAR(_SCREEN.SYSTEM.Drawing.COLOR.white)
.RenderMode = 0 && Memory PNG
.BACKSTYLE = 0 && Transparent
IF NOT EMPTY(.ToDraw )
=EXECSCRIPT(.ToDraw)
ENDIF
ENDWITH
DODEFAULT( tnWidth, tnHeight, toGfx )
ENDPROC
PROCEDURE MouseMove
LPARAMETERS nButton, nShift, nXCoord, nYCoord
IF TYPE('this.Parent.ChartCanvas.Name')='C'
THIS.PARENT.ChartCanvas.MOUSEMOVE(nButton, nShift, nXCoord, nYCoord)
ENDIF
ENDPROC
PROCEDURE myrenderosb
**************************************************************
* FUNCTION MyRenderOSB
*
**************************************************************
LOCAL llLockScreen
IF This._InForm
m.llLockScreen = ThisForm.LockScreen
ThisForm.LockScreen = .T.
ENDIF
DO CASE
CASE This.RenderMode = 0 && Memory BITMAP
This.PictureVal = This.oBmp.GetPictureValfromHBitmap()
CASE This.RenderMode = 1 && File BITMAP
IF EMPTY(This._tempfile)
This._tempfile = ADDBS(SYS(2023))+SYS(2015)+".bmp"
ELSE
This.Picture = ""
CLEAR RESOURCES (This._tempfile)
DELETE FILE (This._tempfile)
This._tempfile = ADDBS(SYS(2023))+SYS(2015)+".bmp"
ENDIF
This.oBmp.Save(This._tempfile, _Screen.System.Drawing.Imaging.ImageFormat.Bmp)
This.Picture = (This._tempfile)
CASE This.RenderMode = 4 && Memory PNG
** PNG PictureVal is only supported in SP2 and later
IF VERSION(4) >= "09.00.0000.5411" && "09.00.0000.5815" && VFP 9.0 SP2
This.PictureVal = This.oBmp.GetPictureVal(_Screen.System.Drawing.Imaging.ImageFormat.Png)
ELSE
** Default to BMP if SP1 or earlier
This.PictureVal = This.oBmp.GetPictureValfromHBitmap()
ENDIF
CASE This.RenderMode = 5 && File PNG
IF EMPTY(This._tempfile)
This._tempfile = ADDBS(SYS(2023))+SYS(2015)+".png"
ELSE
This.Picture = ""
CLEAR RESOURCES (This._tempfile)
DELETE FILE (This._tempfile)
This._tempfile = ADDBS(SYS(2023))+SYS(2015)+".png"
ENDIF
This.oBmp.Save(This._tempfile, _Screen.System.Drawing.Imaging.ImageFormat.Png)
This.Picture = (This._tempfile)
CASE This.RenderMode = 8 && File EMF
This.oGfx = NULL
LOCAL llLocked
IF This._InForm
m.llLocked = ThisForm.LockScreen
ThisForm.LockScreen = .T.
ENDIF
This.Picture = (This._tempFile)
IF This._InForm AND NOT ThisForm.LockScreen = m.llLocked
ThisForm.LockScreen = m.llLocked
ENDIF
ENDCASE
IF This._InForm
ThisForm.LockScreen = m.llLockScreen
ENDIF
RETURN
ENDPROC
ENDDEFINE
DEFINE CLASS radialgauge AS imgcanvas OF "gdiplusx.vcx"
*< CLASSDATA: Baseclass="image" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: addshape
*m: editproperies
*m: interactivechange && Occurs when the user changes the value of a control using the keyboard or the mouse.
*m: readproperties
*m: saveproperties
*m: _checkmouseposition
*p: adjustbrush
*p: arrowcolor
*p: arrowdownwidth
*p: arrowendwidth
*p: arrowtopwidth
*p: bigsteps
*p: centerradius
*p: centerx
*p: centery
*p: color1
*p: color2
*p: contourgraphics
*p: contourpen
*p: cornerrad
*p: currindex
*p: downarcheight
*p: focusscales
*p: fontbold && Specifies if the text is bold.
*p: fontname && Specifies the name of the font used to display text.
*p: fontsize && Specifies the font size for text displayed with an object.
*p: fontunderline && Specifies if the text is underlined.
*p: forecolor && Specifies the foreground color used to display text and graphics in an object.
*p: gradientshapedirection
*p: id
*p: leftmargin
*p: legend
*p: maxvalue
*p: minvalue
*p: mode
*p: nbutton
*p: newprops
*p: nshift
*p: nxcoord
*p: nycoord
*p: pen
*p: props
*p: savedpicture
*p: savedpictureval
*p: scalecolor
*p: scalemargin
*p: scalewidth
*p: shapes && An array for accessing the objects in a container object.
*p: showcontour
*p: showscale
*p: smallsteps
*p: topmargin
*p: type
*p: value && Specifies the current state of a control.
*</DefinedPropArrayMethod>
*<PropValue>
adjustbrush =
arrowcolor = (RGB(128,128,255))
arrowdownwidth = 10
arrowendwidth = 4
arrowtopwidth = 6
bigsteps = 5
centerradius = 5
centerx = 0
centery = 0
color1 = (RGB(245,245,245))
color2 = (RGB(255,255,255))
contourgraphics = .F.
contourpen = .F.
cornerrad = 14
currindex = 0
downarcheight = 4
focusscales = 0
fontbold = .F.
fontname = Arial
fontsize = 8
fontunderline = .F.
forecolor = 0
gradientshapedirection = 0
Height = 100
id =
leftmargin = 4
legend = .F.
maxvalue = 100
minvalue = 0
mode =
Name = "radialgauge"
nbutton = 0
newprops = .F.
nshift = 0
nxcoord = 0
nycoord = 0
pen = .F.
props = .F.
savedpicture = .F.
savedpictureval =
scalecolor = (RGB(165,170,194))
scalemargin = 0.15
scalewidth = 0.05
shapes = .F.
showcontour = .T.
showscale = .T.
smallsteps = 5
topmargin = 5
type = 1
value = 0
Width = 110
*</PropValue>
PROCEDURE addshape
LPARAMETERS tcObjectName, tcType, tcPolyGon, tnX0, tnY0, tnWidth, tnHeight, tcCaption
IF TYPE('this.Shapes.'+tcObjectName) = 'U'
THIS.Shapes.ADDOBJECT(tcObjectName , "FoxChartsBeta.Figure")
ENDIF
WITH EVALUATE('This.Shapes.'+tcObjectName)
.TYPE=tcType
.SetDimensions( 0, 0, this.Width, this.Height)
.CAPTION = EVL(tcCaption,tcType)
.PATH = tcPolyGon
.Contour = tcPolyGon
.CoordNum = this.Shapes.ControlCount
ENDWITH
ENDPROC
PROCEDURE beforedraw
LPARAMETERS llRedraw
LOCAL lcContour, llImageReady, ;
lnAngle, lnAngle1, lnAngle2, lnAngleDegree, lnArrowAngle, lnBackColor, lnBackColorAlpha, lnBigRadius, lnBigRadius1, lnBigRadius2, lnBottomY, lnDelta, lnDelta1, lnDeltaX, lnDownAngle, lnDownBeta, lnDownLeft, lnDownRad, lnDownTop, lnEndLeft, lnEndTop, lnHeight, lnLine, lnMainRad, lnOuterMargin, lnSmallRadius, lnSmallRadius1, lnSmallRadius2, lnSmallValue, lnStep, lnStep1, lnTopBeta, lnUpLeft, lnUpTop, lnValue, lnValue1, lnWidth, lnX, lnX1, lnX2, lnX3, lnY, lnY1, lnY2, lnY3, ;
loArrowBrush, loBlackPen, loCenterBrush, loColor1, loColor2, loCommonBrush, loDarkPen, loGrayPen, loScaleBrush, loWhiteBrush, loWhitePen
WITH THIS
lnWidth = FLOOR((.WIDTH - .LeftMargin*2)/2)*2
lnHeight = .HEIGHT - .TopMargin * 2
lnMainRad = ROUND( (MIN(lnWidth/2, lnHeight-.DownArcHeight- .CornerRad)),0)
.CenterX= .LeftMargin + lnMainRad
.CenterY = ROUND(.HEIGHT - .DownArcHeight- .CornerRad - .TopMargin, 0)
lnSmallRadius = ROUND(lnMainRad * (1-.ScaleMargin - .ScaleWidth),0)
lnArrowAngle= (.VALUE-.MinValue) / (.MaxValue - .MinValue) * 180 + 180
lnOuterMargin = 4
WITH .Legend
.FONTSIZE = THIS.FONTSIZE
.FONTNAME = THIS.FONTNAME
.FONTBOLD= THIS.FONTBOLD
.FORECOLOR = THIS.FORECOLOR
.oGfx = THIS.oGfx
._Setup()
ENDWITH
* <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>
llImageReady = VARTYPE(THIS.SavedPicture ) = 'O' AND NOT llRedraw
WITH _SCREEN.SYSTEM.Drawing
loArrowBrush = .SolidBrush.New(.COLOR.FromARGB(180,IIF(VARTYPE(THIS.ArrowColor)='C', EVAL(THIS.ArrowColor),THIS.ArrowColor)))
loDarkPen = .PEN.New(.COLOR.FromRGB(RGB(212,212,212)),1)
loBlackPen = .PEN.New(.COLOR.FromRGB(0),1)
lnBigRadius = ROUND(lnMainRad * (1-THIS.ScaleMargin),0)
lnBigRadius1 = lnBigRadius + lnOuterMargin
lnSmallRadius1= lnSmallRadius - lnOuterMargin
IF NOT llImageReady
loGrayPen = .PEN.New(.COLOR.FromRGB(RGB(222,222,222)),4)
lnBackColor = THIS.ScaleColor
lnBackColorAlpha = 255
loScalePen = .PEN.New(.COLOR.FromRGB(RGB(212,212,212)),1)
loScaleBrush = .SolidBrush.New(.COLOR.FromARGB(lnBackColorAlpha,lnBackColor))
loWhiteBrush = .SolidBrush.New(.COLOR.FromRGB(RGB(128,255,255)))
loWhitePen = .PEN.New(.COLOR.FromRGB(RGB(255,255,255)))
loColor1 = .COLOR.FromRGB( RGB(245,245,245))
loColor2 = .COLOR.FromRGB( RGB(192,192,192))
*!* loCommonBrush = .Drawing2D.LinearGradientBrush.New(;
*!* .Rectangle.New(THIS.LeftMargin, THIS.TopMargin, lnWidth, lnHeight), ;
*!* loColor1, loColor2, THIS.GradientShapeDirection)
*!* loCommonBrush.SetSigmaBellShape(1, 1)
loCenterBrush = .Drawing2D.LinearGradientBrush.New(;
.Rectangle.New(THIS.CenterX-THIS.CenterRadius, THIS.CenterY-THIS.CenterRadius, THIS.CenterRadius*2, THIS.CenterRadius*2), ;
loColor1, loColor2, 0)
loCenterBrush.SetSigmaBellShape(1, 1)
ENDIF
ENDWITH
lnDownRad = .DownArcHeight + .CornerRad
lnDownAngle = RTOD(ASIN(.CornerRad / lnDownRad))
IF llImageReady
THIS.oGfx.DrawImage(THIS.SavedPicture, 0, 0, THIS.WIDTH, THIS.HEIGHT)
ELSE
TEXT TO this.AdjustBrush
gnColor1 = <<.Color1>>
gnColor2 = <<.Color2>>
gnCenterPointX = <<.LeftMargin + lnMainRad>>
gnCenterPointY = <<ROUND(.HEIGHT - .DownArcHeight- .CornerRad - .TopMargin, 0)>>
gnFocusScales=<<.FocusScales>>
ENDTEXT
*
* <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
lcContour=''
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnDownRad,.CenterY - lnDownRad, lnDownRad*2, lnDownRad*2, lnDownAngle, 180 - lnDownAngle*2) && 1
lnDeltaX = lnDownRad * COS(DTOR(lnDownAngle))
lnX = .CenterX - lnDeltaX
lnBottomY = .CenterY + .CornerRad
_Screen.FoxChartsHelper.NewRow( @lcContour, lnX, lnBottomY, .CenterX - lnMainRad + .CornerRad, lnBottomY) && 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
lnX = .CenterX - lnMainRad
lnBottomY = .CenterY - .CornerRad
_Screen.FoxChartsHelper.NewRow( @lcContour, lnX, lnBottomY , .CornerRad*2, .CornerRad*2, 90, 90) && 3
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
lnY = .CenterY -lnMainRad
lnX = .CenterX - lnMainRad
_Screen.FoxChartsHelper.NewRow( @lcContour, lnX, lnY, lnMainRad*2, lnMainRad*2, 180, 180) && 4 - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
lnX = .CenterX + lnMainRad - .CornerRad*2
_Screen.FoxChartsHelper.NewRow( @lcContour, lnX, lnBottomY, .CornerRad*2, .CornerRad*2, 0, 90) && 5
lnX = .CenterX + lnMainRad - .CornerRad
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX + lnMainRad - .CornerRad, .CenterY + .CornerRad , .CenterX + lnDeltaX , .CenterY + .CornerRad)
_Screen.FoxChartsHelper.DrawPath(.oGfx, loGrayPen, loCommonBrush , lcContour, 2, 2)
_Screen.FoxChartsHelper.DrawPath(.oGfx, .PEN, .AdjustBrush , lcContour, 0, 0)
*
* <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
*
IF .ShowScale
lcContour=''
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnBigRadius, .CenterY - lnBigRadius, lnBigRadius*2, lnBigRadius*2, 180, 180) && 3 - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX + lnBigRadius, .CenterY, .CenterX + lnSmallRadius, .CenterY)
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnSmallRadius, .CenterY - lnSmallRadius, lnSmallRadius*2, lnSmallRadius*2, 0, -180) && 3 - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnSmallRadius, .CenterY, .CenterX - lnBigRadius, .CenterY)
_Screen.FoxChartsHelper.DrawPath(.oGfx, .PEN, loScaleBrush , lcContour, 0, 0)
ENDIF
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
lnStep = (THIS.MaxValue-THIS.MinValue)/THIS.BigSteps
lnDelta = 180/(THIS.MaxValue-THIS.MinValue)
lnStep1 = lnStep / THIS.SmallSteps
lnDelta1 = lnDelta / THIS.SmallSteps
lnBigRadius2 = lnBigRadius - 1
lnSmallRadius2= lnSmallRadius + 1
lnSmallValue = 1.1
FOR lnValue = THIS.MinValue TO THIS.MaxValue STEP lnStep
lcContour=''
lnAngleDegree = (lnValue - THIS.MinValue)*lnDelta + 180
lnAngle = DTOR(lnAngleDegree)
lnAngle1 = DTOR((lnValue - lnSmallValue - THIS.MinValue)*lnDelta + 180)
lnAngle2 = DTOR((lnValue + lnSmallValue - THIS.MinValue)*lnDelta + 180)
lnX1 = lnBigRadius1 * COS(lnAngle1) + .CenterX
lnY1 = lnBigRadius1 *SIN(lnAngle1) + .CenterY
lnX2 = lnBigRadius1 * COS(lnAngle2) + .CenterX
lnY2 = lnBigRadius1 *SIN(lnAngle2) + .CenterY
lnX3 = lnSmallRadius1 * COS(lnAngle) + .CenterX
lnY3 = lnSmallRadius1 *SIN(lnAngle) + .CenterY
_Screen.FoxChartsHelper.NewRow(@lcContour,lnX1, lnY1, lnX2, lnY2)
_Screen.FoxChartsHelper.NewRow(@lcContour,lnX2, lnY2, lnX3, lnY3)
_Screen.FoxChartsHelper.NewRow(@lcContour,lnX3, lnY3, lnX1, lnY1)
_Screen.FoxChartsHelper.DrawPath(.oGfx, loDarkPen, loWhiteBrush , lcContour, 0, 0)
.Legend.CAPTION = TRANSFORM(lnValue)
.Legend._UpdateMeasures()
IF BETWEEN(lnAngleDegree-180,45,135)
lnX = lnX3-.Legend._Width/2
lnY = lnY3
.Legend.ALIGNMENT=2
ELSE
lnX = lnX3 - IIF(lnAngleDegree-180>134,.Legend._Width-4,0)
lnY = lnY3-.Legend._Height/2
.Legend.ALIGNMENT=1
ENDIF
.Legend._DrawString(lnX, lnY, .Legend._Width,.Legend._Height,.F.,.oGfx)
IF lnValue = THIS.MaxValue
EXIT
ENDIF
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FOR lnLine = 1 TO THIS.SmallSteps-1
lcContour=''
lnValue1 = lnValue + lnStep1 * lnLine
lnAngle = DTOR((lnValue1 - THIS.MinValue)*lnDelta + 180)
lnX1 = ROUND(lnBigRadius2 * COS(lnAngle) + .CenterX,0)
lnY1 = ROUND(lnBigRadius2 * SIN(lnAngle) + .CenterY,0)
lnX2 = ROUND(lnSmallRadius2 * COS(lnAngle) + .CenterX,0)
lnY2 = ROUND(lnSmallRadius2 * SIN(lnAngle) + .CenterY,0)
_Screen.FoxChartsHelper.NewRow(@lcContour,lnX1, lnY1, lnX2, lnY2)
_Screen.FoxChartsHelper.DrawPath(.oGfx, loScalePen, , lcContour, 0, 0)
NEXT
NEXT
* <20><><EFBFBD><EFBFBD><EFBFBD>
lcContour=''
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - .CenterRadius, .CenterY - .CenterRadius, .CenterRadius*2, .CenterRadius*2, 0, 360) && <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_Screen.FoxChartsHelper.DrawPath(.oGfx, loDarkPen, loCenterBrush , lcContour, 0, 0)
.renderosb ()
.SavedPicture = _SCREEN.SYSTEM.Drawing.BITMAP.FromVarbinary(THIS.PICTUREVAL)
IF NOT EMPTY(.ID)
.SavedPictureVal = .PictureVal
ENDIF
ENDIF
*
* <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
*
IF TYPE('.Scale') = 'U'
lcContour=''
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnBigRadius1, .CenterY - lnBigRadius1, lnBigRadius1*2, lnBigRadius1*2, 180, 180) && 3 - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX + lnBigRadius1, .CenterY, .CenterX + lnBigRadius1, .CenterY+4)
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX + lnBigRadius1, .CenterY+4, .CenterX + lnSmallRadius1, .CenterY+4)
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX + lnSmallRadius1,.CenterY+4, .CenterX + lnSmallRadius1, .CenterY)
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnSmallRadius1, .CenterY - lnSmallRadius1, lnSmallRadius1*2, lnSmallRadius1*2, 0, -180) && 3 - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnSmallRadius1, .CenterY, .CenterX - lnBigRadius1, .CenterY)
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnSmallRadius1, .CenterY, .CenterX - lnSmallRadius1, .CenterY+4)
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnSmallRadius1, .CenterY+4, .CenterX - lnBigRadius1, .CenterY+4)
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - lnBigRadius1, .CenterY+4, .CenterX - lnBigRadius1, .CenterY)
.AddShape('Scale', 'Scale', lcContour, ;
.CenterX - lnBigRadius, .CenterY - lnBigRadius, lnBigRadius*2, lnBigRadius)
ENDIF
*
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
lcContour=''
lnArrowEndwidth = MIN(.ArrowEndwidth, lnBigRadius/4)
lnSmallRadius2 = lnSmallRadius - lnArrowEndwidth
.ArrowTopWidth = MIN(.ArrowTopWidth, .CenterRadius)
.ArrowDownWidth = MIN(.ArrowDownWidth, .CenterRadius*2)
lnTopBeta = ROUND(90 - RTOD(ACOS(.ArrowTopWidth/2/lnSmallRadius2)),0)
lnDownBeta = ROUND(90 - RTOD(ACOS(.ArrowDownWidth/2/.CenterRadius)),0)
_Screen.FoxChartsHelper.NewRow( @lcContour, .CenterX - .CenterRadius, .CenterY - .CenterRadius, ;
.CenterRadius*2, .CenterRadius*2, lnArrowAngle-lnDownBeta, lnDownBeta*2) && <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
lnDownLeft = ROUND(.CenterRadius * COS(DTOR(lnArrowAngle+lnDownBeta)) + .CenterX,0)
lnDownTop = ROUND(.CenterRadius * SIN(DTOR(lnArrowAngle+lnDownBeta)) + .CenterY,0)
lnUpLeft = ROUND(lnSmallRadius2 * COS(DTOR(lnArrowAngle+lnTopBeta)) + .CenterX,0)
lnUpTop = ROUND(lnSmallRadius2 * SIN(DTOR(lnArrowAngle+lnTopBeta)) + .CenterY,0)
_Screen.FoxChartsHelper.NewRow(@lcContour,lnDownLeft , lnDownTop, lnUpLeft, lnUpTop)
lnEndLeft = ROUND(lnSmallRadius * COS(DTOR(lnArrowAngle)) + .CenterX,0)
lnEndTop = ROUND(lnSmallRadius * SIN(DTOR(lnArrowAngle)) + .CenterY,0)
_Screen.FoxChartsHelper.NewRow(@lcContour,lnUpLeft , lnUpTop, lnEndLeft, lnEndTop)
lnDownLeft = ROUND(.CenterRadius * COS(DTOR(lnArrowAngle-lnDownBeta)) + .CenterX,0)
lnDownTop = ROUND(.CenterRadius * SIN(DTOR(lnArrowAngle-lnDownBeta)) + .CenterY,0)
lnUpLeft = ROUND(lnSmallRadius2 * COS(DTOR(lnArrowAngle-lnTopBeta)) + .CenterX,0)
lnUpTop = ROUND(lnSmallRadius2 * SIN(DTOR(lnArrowAngle-lnTopBeta)) + .CenterY,0)
_Screen.FoxChartsHelper.NewRow(@lcContour,lnEndLeft, lnEndTop,lnUpLeft , lnUpTop)
_Screen.FoxChartsHelper.NewRow(@lcContour, lnUpLeft, lnUpTop,lnDownLeft , lnDownTop)
_Screen.FoxChartsHelper.DrawPath(.oGfx, loDarkPen, loArrowBrush , lcContour, 0, 0)
ENDWITH
ENDPROC
PROCEDURE createosb
LPARAMETERS tnWidth, tnHeight
This.DeleteOSB()
LOCAL loRect
IF EMPTY(m.tnWidth)
m.tnWidth = This.Width
m.tnHeight = This.Height
ENDIF
This._BMPWidth = m.tnWidth
This._BMPHeight = m.tnHeight
m.tnWidth = MAX(m.tnWidth,1)
m.tnHeight = MAX(m.tnHeight,1)
WITH _Screen.System.Drawing
This.oBmp = .Bitmap.New(m.tnWidth, m.tnHeight)
This.oGfx = .Graphics.FromImage(This.oBmp)
This.oGfx.SmoothingMode = This.SmoothingMode
This.oGfx.TextRenderingHint = This.TextRenderingHint
This.oGfx.InterpolationMode = This.InterpolationMode
ENDWITH
ENDPROC
PROCEDURE Destroy
this.SaveProperties()
DODEFAULT()
ENDPROC
PROCEDURE draw
LPARAMETERS tnWidth, tnHeight, toGfx, llHide
n000=SECONDS()
LOCAL llRedraw
THISFORM.LOCKSCREEN = .T.
m.llRedraw = .F.
IF EMPTY(m.tnWidth)
THIS._WidthOverride = -1
THIS._HeightOverride = -1
m.tnWidth =THIS.WIDTH
m.tnHeight = THIS.HEIGHT
ELSE
IF VARTYPE(tnWidth)='L'
m.llRedraw = .T.
m.tnWidth = THIS.WIDTH
m.tnHeight = EVL(m.tnHeight, THIS.HEIGHT)
ENDIF
THIS._WidthOverride = m.tnWidth
THIS._HeightOverride = m.tnHeight
ENDIF
THIS._cSize = BINTOC(EVL(m.tnWidth,THIS.WIDTH),"4rs") + BINTOC(EVL(m.tnHeight,THIS.HEIGHT),"4rs")
IF THIS._BMPWidth <> m.tnWidth OR THIS._BMPHeight <> m.tnHeight OR THIS.RenderMode = 7
THIS.CreateOSB(m.tnWidth, m.tnHeight)
ENDIF
nn1=SECONDS()-n000
n000=SECONDS()
THIS.BeforeDraw(llRedraw)
nn2=SECONDS()-n000
n000=SECONDS()
THIS.RenderOSB()
nn3=SECONDS()-n000
n000=SECONDS()
THIS.AfterDraw()
nn4=SECONDS()-n000
n000=SECONDS()
THISFORM.LOCKSCREEN = .F.
TEXT TO lc
<<nn1>>, <<nn2>>, <<nn3>>, <<nn4>>
endtext
*sl(lc)
ENDPROC
PROCEDURE editproperies
LOCAL lcMode
lcMode = THIS.Mode
lcMode = _Screen.FoxChartsHelper.sl(THIS.Mode)
IF NOT THIS.Mode == lcMode
THIS.NewProps = .T.
THIS.ReadProperties (lcMode)
this.Draw(.t.)
ENDIF
ENDPROC
PROCEDURE Init
SET CLASSLIB TO foxchartsBeta.vcx ADDI
IF TYPE('_Screen.FoxChartsHelper') = 'U'
_Screen.ADDOBJECT('FoxChartsHelper', 'FoxChartsBeta.FoxChartsHelper')
ENDIF
WITH THIS
TEXT TO .Props
Arrowcolor
Arrowdownwidth
ArrowEndWidth
ArrowTopWidth
Bigsteps
Centerradius
Color1
Color2
Cornerrad
DownArcHeight
FocusScales
Fontbold
Fontname
Fontsize
Fontunderline
Forecolor
Gradientshapedirection
Height
Interpolationmode
Left
Leftmargin
Maxvalue
Minvalue
Scalecolor
Scalemargin
Scalewidth
Showcontour
Showscale
Smallsteps
Topmargin
Type
Width
ENDTEXT
.RenderMode = 4 && Memory PNG
.oGfx.SmoothingMode = _SCREEN.SYSTEM.Drawing.Drawing2D.SmoothingMode.AntiAlias
.PEN = _SCREEN.SYSTEM.Drawing.PEN.New(_SCREEN.SYSTEM.Drawing.COLOR.FromRGB(RGB(150,150,155)) , 3)
.Legend = CREATEOBJECT("_Legend")
.Legend.oGfx = .oGfx
.Shapes = CREATEOBJECT('Container')
.ReadProperties()
.DRAW
ENDWITH
ENDPROC
PROCEDURE interactivechange && Occurs when the user changes the value of a control using the keyboard or the mouse.
ENDPROC
PROCEDURE MouseMove
LPARAMETERS nButton, nShift, nXCoord, nYCoord
LOCAL lnCoordIndex, loObject
WITH THIS
IF nXCoord=THIS.nXCoord AND nYCoord=.nYCoord AND nButton=.nButton AND nShift = .nShift
RETURN
ENDIF
.nButton = nButton
.nShift = nShift
.nXCoord = nXCoord
.nYCoord = nYCoord
m.lnCoordIndex = 0
lnX = nXCoord - obj2Client(THIS, 2)
lnY = nYCoord - obj2Client(THIS, 1)
loObject = .F.
loShape = .Shapes.SCALE
IF .ShowContour AND loShape.CheckMousePosition(lnX, lnY)
IF VARTYPE(.ContourGraphics) # 'O'
.ContourGraphics = _SCREEN.SYSTEM.Drawing.Graphics.FromHWnd(THISFORM.HWND) && Create a Graphics object
.ContourGraphics.SmoothingMode = 4
.ContourPen = _SCREEN.SYSTEM.Drawing.PEN.New(_SCREEN.SYSTEM.Drawing.COLOR.FromARGB(212, RGB(255,255,255)) , 2)
.ContourPen.DASHSTYLE = 0
ENDIF
IF loShape.CoordNum # .Currindex
THISFORM.CLS()
loShape.DrawContour(.ContourGraphics, .ContourPen,, obj2Client(THIS, 2), obj2Client(THIS, 1))
ENDIF
lnCoordIndex = loShape.CoordNum
ENDIF
IF .Currindex # lnCoordIndex AND lnCoordIndex=0
THISFORM.CLS()
ENDIF
.Currindex = lnCoordIndex
ENDWITH
ENDPROC
PROCEDURE MouseUp
LPARAMETERS nButton, nShift, tnMouseX, tnMouseY
IF nButton=2 AND nShift=3
THIS.EditProperies()
RETURN
ENDIF
LOCAL lnA, lnAngle, lnB, lnMouseX, lnMouseY, lnOldValue, lnStart, loShape
tnMouseX = tnMouseX -Obj2Client(THIS,2)
tnMouseY = tnMouseY - Obj2Client(THIS,1)
WITH THIS
FOR EACH loShape IN THIS.Shapes.OBJECTS
IF loShape.TYPE = 'Scale' AND loShape.CheckMousePosition(tnMouseX, tnMouseY)
lnMouseX = tnMouseX - .CenterX
lnMouseY = tnMouseY - .CenterY
lnA = 1
lnB = 1
lnAngle = MOD(RTOD(ATAN( lnMouseY / lnMouseX * lnA/lnB ))- 90, 360)
IF lnMouseX < 0
m.lnAngle = 180 + m.lnAngle
ENDIF
lnAngle=MOD(360+lnAngle,360)
lnStart = 90
lnOldValue = .VALUE
IF NOT BETWEEN(lnAngle, lnStart, 360-lnStart)
.VALUE = IIF(lnAngle<lnStart,0,.Maxvalue )
ELSE
.VALUE = ROUND( (lnAngle-lnStart) /(360-lnStart*2) * .Maxvalue - .MinValue, 0)
ENDIF
.VALUE = MIN(.Maxvalue , MAX(.MinValue , .VALUE ))
IF lnOldValue = .VALUE
RETURN
ENDIF
.DRAW
.CurrIndex = 0
.INTERACTIVECHANGE
ENDIF
NEXT
ENDWITH
ENDPROC
PROCEDURE readproperties
LPARAMETERS lcMode
WITH THIS
IF VARTYPE(lcMode) = 'C' AND NOT EMPTY(lcMode)
.Mode = lcMode
=EXECSCRIPT(.Mode)
RETURN
ENDIF
.SaveProperties (.T.)
IF EMPTY(.ID)
RETURN
ENDIF
lcFile = ADDBS( SET("Default")+CURDIR() ) + 'gauges.dbf'
IF NOT FILE(lcFile)
CREATE TABLE (lcFile) (ID C(10), Mode M, PICTUREVAL W)
APPEND BLANK
REPLACE ID WITH .ID
ELSE
IF USED('Gauges')
SELECT Gauges
ELSE
SELECT 0
USE (lcFile) ALIAS Gauges
ENDIF
LOCATE FOR ALLTRIM(ID) == .ID
IF NOT FOUND()
APPEND BLANK
REPLACE ID WITH .ID
ENDIF
ENDIF
IF NOT EMPTY( Gauges.Mode)
.Mode = Gauges.Mode
endif
.SavedPicture = _SCREEN.SYSTEM.Drawing.BITMAP.FromVarbinary(Gauges.PICTUREVAL)
IF NOT EMPTY(.Mode)
=EXECSCRIPT(.Mode)
ENDIF
ENDWITH
ENDPROC
PROCEDURE saveproperties
LPARAMETERS llStoreMode
LOCAL lcProps, lcSave, lnLine, la(1)
WITH THIS
IF NOT llStoreMode AND ( EMPTY(.ID) OR NOT .NewProps )
RETURN
ENDIF
lcSave =''
FOR lnLine=1 TO ALINES(la,.Props)
luVal = EVALUATE('.'+la(lnLine))
TEXT TO lcSave addi
.<<la(lnLine)>>=<<IIF( VARTYPE(luVal) = 'C', '['+ALLTRIM(luVal)+']', TRANSFORM(luVal))>>
ENDTEXT
NEXT
IF llStoreMode
.Mode = lcSave
RETURN
ENDIF
SELECT Gauges
IF NOT ID == .ID
LOCATE FOR ALLTRIM(ID) == .ID
ENDIF
REPLACE Mode WITH lcSave, PICTUREVAL WITH .SavedPictureVal
ENDWITH
ENDPROC
PROCEDURE _checkmouseposition
ENDPROC
ENDDEFINE
DEFINE CLASS shapes AS container
*< CLASSDATA: Baseclass="container" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: clear && Clears the contents of a ComboBox or ListBox control.
*</DefinedPropArrayMethod>
*<PropValue>
Height = 43
Name = "shapes"
Visible = .F.
Width = 113
*</PropValue>
PROCEDURE clear && Clears the contents of a ComboBox or ListBox control.
LOCAL lnLine
FOR lnLine=THIS.OBJECTS.COUNT TO 1 STEP -1
THIS.REMOVEOBJECT (THIS.OBJECTS(lnLine).NAME)
NEXT
ENDPROC
ENDDEFINE
DEFINE CLASS tips AS label
*< CLASSDATA: Baseclass="label" Timestamp="" Scale="Pixels" Uniqueid="" />
*<DefinedPropArrayMethod>
*m: evalcaption
*p: caption1
*p: caption2
*p: stringformat
*p: value && Specifies the current state of a control.
*</DefinedPropArrayMethod>
*<PropValue>
AutoSize = .T.
BackColor = 255,255,228
Caption = ""
caption1 = .F.
caption2 = .F.
Height = 17
Name = "tips"
stringformat = 999 999 999 999.99
value = .F.
Width = 0
WordWrap = .T.
*</PropValue>
PROCEDURE evalcaption
WITH THIS
DO CASE
CASE VARTYPE(.VALUE) = 'N'
.CAPTION = IIF(EMPTY(.StringFormat), TRANSFORM(.VALUE), CHRTRAN(ALLTRIM(TRANSFORM( .VALUE, .StringFormat)),[ ],[_]))
CASE VARTYPE(.VALUE) $ 'CM'
.CAPTION = .VALUE
OTHERWISE
.CAPTION=''
ENDCASE
IF NOT EMPTY(.Caption1)
.CAPTION = IIF(EMPTY(.CAPTION),'' , .CAPTION + CHR(13)+CHR(10)) + TRANSFORM(.Caption1)
ENDI
IF NOT EMPTY(.Caption2)
.CAPTION = IIF(EMPTY(.CAPTION),'' , .CAPTION + CHR(13)+CHR(10)) + TRANSFORM(.Caption2)
ENDIF
.WordWrap = CHR(13) $ .Caption
.Width = 2000
.AutoSize=.T.
* .CAPTION = CHRTRAN(.CAPTION,'_',' ')
ENDWITH
ENDPROC
ENDDEFINE