Jump to content

Recommended Posts

Posted

Very nice object oriented coding example Andreik  :thumbsup:

How about 3d pie charts? Something like this here?

sample-single-series-3d-pie-chart.png

 

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted (edited)

Here something you can look at (WideBoyDixon's version):

;http://www.autoitscript.com/forum/index.php?showtopic=97241
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GUISlider.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <Date.au3>

; Let's be strict here
Opt("MustDeclareVars", 1)

; Controls the size of the pie and also the depth
Global Const $PIE_DIAMETER = 400
Global Const $PIE_MARGIN = $PIE_DIAMETER * 0.025
Global Const $PIE_DEPTH = $PIE_DIAMETER * 0.2
Global Const $PIE_AREA = $PIE_DIAMETER + 2 * $PIE_MARGIN

; Random data for values and colours
Global Const $NUM_VALUES = 8
Global $aChartValue[$NUM_VALUES]
Global $aChartColour[$NUM_VALUES]
For $i = 0 To $NUM_VALUES - 1
    $aChartValue[$i] = Random(5, 25, 1)
    $aChartColour[$i] = (Random(0, 255, 1) * 0x10000) + (Random(0, 255, 1) * 0x100) + Random(0, 255, 1)
Next

; The value of PI
Global Const $PI = ATan(1) * 4

; Start GDI+
_GDIPlus_Startup()

; Create the brushes and pens
Global $ahBrush[$NUM_VALUES][2], $ahPen[$NUM_VALUES]
For $i = 0 To $NUM_VALUES - 1
    $ahBrush[$i][0] = _GDIPlus_BrushCreateSolid(BitOR(0xff000000, $aChartColour[$i]))
    $ahBrush[$i][1] = _GDIPlus_BrushCreateSolid(BitOR(0xff000000, _GetDarkerColour($aChartColour[$i])))
    $ahPen[$i] = _GDIPlus_PenCreate(BitOR(0xff000000, _GetDarkerColour(_GetDarkerColour($aChartColour[$i]))))
Next

; Create the GUI with sliders to control the aspect, rotation, style and hole size (for donuts)
Global $hWnd = GUICreate("Pie Chart", $PIE_AREA, $PIE_AREA + 100, Default, Default)
Global $hSlideAspect = _GUICtrlSlider_Create($hWnd, $PIE_MARGIN, $PIE_AREA + 10, $PIE_DIAMETER, 20)
_GUICtrlSlider_SetRange($hSlideAspect, 10, 100)
_GUICtrlSlider_SetPos($hSlideAspect, 50)
Global $hSlideRotation = _GUICtrlSlider_Create($hWnd, $PIE_MARGIN, $PIE_AREA + 40, $PIE_DIAMETER, 20)
_GUICtrlSlider_SetRange($hSlideRotation, 0, 360)
Global $cStyle = GUICtrlCreateCheckbox("Donut", $PIE_MARGIN, $PIE_AREA + 70, $PIE_DIAMETER / 2 - $PIE_MARGIN, 20)
Global $hStyle = GUICtrlGetHandle($cStyle)
Global $hHoleSize = _GUICtrlSlider_Create($hWnd, $PIE_MARGIN + $PIE_DIAMETER / 2, $PIE_AREA + 70, $PIE_DIAMETER / 2, 20)
_GUICtrlSlider_SetRange($hHoleSize, 2, $PIE_DIAMETER - 4 * $PIE_MARGIN)
_GUICtrlSlider_SetPos($hHoleSize, $PIE_DIAMETER / 2)
GUISetState()

; Set up GDI+
Global $hDC = _WinAPI_GetDC($hWnd)
Global $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($PIE_AREA, $PIE_AREA, $hGraphics)
Global $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBuffer, 2)

; Draw the initial pie chart
_DrawPie($aChartValue, _GUICtrlSlider_GetPos($hSlideAspect) / 100, _
        _GUICtrlSlider_GetPos($hSlideRotation), _
        (GUICtrlRead($cStyle) = $GUI_CHECKED), _
        _GUICtrlSlider_GetPos($hHoleSize))

; The sliders will send WM_NOTIFY messages
GUIRegisterMsg($WM_NOTIFY, "_OnNotify")

; Wait until the user quits
While GUIGetMsg() <> $GUI_EVENT_CLOSE
    Sleep(20)
WEnd

; Release the resources
For $i = 0 To UBound($aChartColour) - 1
    _GDIPlus_PenDispose($ahPen[$i])
    _GDIPlus_BrushDispose($ahBrush[$i][0])
    _GDIPlus_BrushDispose($ahBrush[$i][1])
Next
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hGraphics)
_WinAPI_ReleaseDC($hWnd, $hDC)

; Shut down GDI+
_GDIPlus_Shutdown()

; Done
Exit

; Get a darker version of a colour by extracting the RGB components
Func _GetDarkerColour($Colour)
    Local $Red, $Green, $Blue
    $Red = (BitAND($Colour, 0xff0000) / 0x10000) - 40
    $Green = (BitAND($Colour, 0x00ff00) / 0x100) - 40
    $Blue = (BitAND($Colour, 0x0000ff)) - 40
    If $Red < 0 Then $Red = 0
    If $Green < 0 Then $Green = 0
    If $Blue < 0 Then $Blue = 0
    Return ($Red * 0x10000) + ($Green * 0x100) + $Blue
EndFunc ;==>_GetDarkerColour

; Draw the pie chart
Func _DrawPie($Percentage, $Aspect, $rotation, $style = 0, $holesize = 100)
    If $style <> 0 Then $Aspect = 1
    Local $nCount, $nTotal = 0, $angleStart, $angleSweep, $X, $Y
    Local $pieLeft = $PIE_MARGIN, $pieTop = $PIE_AREA / 2 - ($PIE_DIAMETER / 2) * $Aspect
    Local $pieWidth = $PIE_DIAMETER, $pieHeight = $PIE_DIAMETER * $Aspect, $hPath

; Total up the values
    For $nCount = 0 To UBound($Percentage) - 1
        $nTotal += $Percentage[$nCount]
    Next

; Set the fractional values
    For $nCount = 0 To UBound($Percentage) - 1
        $Percentage[$nCount] /= $nTotal
    Next

; Make sure we don't over-rotate
    $rotation = Mod($rotation, 360)

; Clear the graphics buffer
    _GDIPlus_GraphicsClear($hBuffer, 0xffc0c0c0)

; Set the initial angles based on the fractional values
    Local $Angles[UBound($Percentage) + 1]
    For $nCount = 0 To UBound($Percentage)
        If $nCount = 0 Then
            $Angles[$nCount] = $rotation
        Else
            $Angles[$nCount] = $Angles[$nCount - 1] + ($Percentage[$nCount - 1] * 360)
        EndIf
    Next

    Switch $style
        Case 0
    ; Adjust the angles based on the aspect
            For $nCount = 0 To UBound($Percentage)
                $X = $PIE_DIAMETER * Cos($Angles[$nCount] * $PI / 180)
                $Y = $PIE_DIAMETER * Sin($Angles[$nCount] * $PI / 180)
                $Y -= ($PIE_DIAMETER - $pieHeight) * Sin($Angles[$nCount] * $PI / 180)
                If $X = 0 Then
                    $Angles[$nCount] = 90 + ($Y < 0) * 180
                Else
                    $Angles[$nCount] = ATan($Y / $X) * 180 / $PI
                EndIf
                If $X < 0 Then $Angles[$nCount] += 180
                If $X >= 0 And $Y < 0 Then $Angles[$nCount] += 360
                $X = $PIE_DIAMETER * Cos($Angles[$nCount] * $PI / 180)
                $Y = $pieHeight * Sin($Angles[$nCount] * $PI / 180)
            Next

    ; Decide which pieces to draw first and last
            Local $nStart = -1, $nEnd = -1
            For $nCount = 0 To UBound($Percentage) - 1
                $angleStart = Mod($Angles[$nCount], 360)
                $angleSweep = Mod($Angles[$nCount + 1] - $Angles[$nCount] + 360, 360)
                If $angleStart <= 270 And ($angleStart + $angleSweep) >= 270 Then
                    $nStart = $nCount
                EndIf
                If ($angleStart <= 90 And ($angleStart + $angleSweep) >= 90) _
                        Or ($angleStart <= 450 And ($angleStart + $angleSweep) >= 450) Then
                    $nEnd = $nCount
                EndIf
                If $nEnd >= 0 And $nStart >= 0 Then ExitLoop
            Next

    ; Draw the first piece
            _DrawPiePiece($hBuffer, $pieLeft, $pieTop, $pieWidth, $pieHeight, $PIE_DEPTH * (1 - $Aspect), $nStart, $Angles)

    ; Draw pieces "to the right"
            $nCount = Mod($nStart + 1, UBound($Percentage))
            While $nCount <> $nEnd
                _DrawPiePiece($hBuffer, $pieLeft, $pieTop, $pieWidth, $pieHeight, $PIE_DEPTH * (1 - $Aspect), $nCount, $Angles)
                $nCount = Mod($nCount + 1, UBound($Percentage))
            WEnd

    ; Draw pieces "to the left"
            $nCount = Mod($nStart + UBound($Percentage) - 1, UBound($Percentage))
            While $nCount <> $nEnd
                _DrawPiePiece($hBuffer, $pieLeft, $pieTop, $pieWidth, $pieHeight, $PIE_DEPTH * (1 - $Aspect), $nCount, $Angles)
                $nCount = Mod($nCount + UBound($Percentage) - 1, UBound($Percentage))
            WEnd

    ; Draw the last piece
            _DrawPiePiece($hBuffer, $pieLeft, $pieTop, $pieWidth, $pieHeight, $PIE_DEPTH * (1 - $Aspect), $nEnd, $Angles)
        Case 1
    ; Draw the donut pieces
            For $nCount = 0 To UBound($Percentage) - 1
                $angleStart = Mod($Angles[$nCount], 360)
                $angleSweep = Mod($Angles[$nCount + 1] - $Angles[$nCount] + 360, 360)

        ; Draw the outer arc in a darker colour
                $hPath = _GDIPlus_PathCreate()
                _GDIPlus_PathAddArc($hPath, $pieLeft, $pieTop, $pieWidth, $pieHeight, $angleStart, $angleSweep)
                _GDIPlus_PathAddArc($hPath, $pieLeft + $PIE_MARGIN, $pieTop + $PIE_MARGIN, $pieWidth - $PIE_MARGIN * 2, _
                        $pieHeight - $PIE_MARGIN * 2, $angleStart + $angleSweep, -$angleSweep)
                _GDIPlus_PathCloseFigure($hPath)
                _GDIPlus_GraphicsFillPath($hBuffer, $hPath, $ahBrush[$nCount][1])
                _GDIPlus_GraphicsDrawPath($hBuffer, $hPath, $ahPen[$nCount])
                _GDIPlus_PathDispose($hPath)

        ; Draw the inner piece in a lighter colour - leave room for the hole
                $hPath = _GDIPlus_PathCreate()
                _GDIPlus_PathAddArc($hPath, $pieLeft + $PIE_MARGIN, $pieTop + $PIE_MARGIN, $pieWidth - $PIE_MARGIN * 2, _
                        $pieHeight - $PIE_MARGIN * 2, $angleStart, $angleSweep)
                _GDIPlus_PathAddArc($hPath, $pieLeft + ($PIE_DIAMETER - $holesize) / 2, $pieTop + ($PIE_DIAMETER - $holesize) / 2, _
                        $holesize, $holesize, $angleStart + $angleSweep, -$angleSweep)
                _GDIPlus_PathCloseFigure($hPath)
                _GDIPlus_GraphicsFillPath($hBuffer, $hPath, $ahBrush[$nCount][0])
                _GDIPlus_GraphicsDrawPath($hBuffer, $hPath, $ahPen[$nCount])
                _GDIPlus_PathDispose($hPath)
            Next
    EndSwitch

; Now draw the bitmap on to the device context of the window
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0)
EndFunc ;==>_DrawPie

Func _OnNotify($hWnd, $iMsg, $wParam, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    Switch $hWndFrom
        Case $hSlideAspect, $hSlideRotation, $hStyle, $hHoleSize
    ; Update the pie chart
            _DrawPie($aChartValue, _GUICtrlSlider_GetPos($hSlideAspect) / 100, _
                    _GUICtrlSlider_GetPos($hSlideRotation), _
                    (GUICtrlRead($cStyle) = $GUI_CHECKED), _
                    _GUICtrlSlider_GetPos($hHoleSize))
    EndSwitch
EndFunc ;==>_OnNotify

Func _DrawPiePiece($hGraphics, $iX, $iY, $iWidth, $iHeight, $iDepth, $nCount, $Angles)
    Local $hPath, $cX = $iX + ($iWidth / 2), $cY = $iY + ($iHeight / 2), $fDrawn = False
    Local $iStart = Mod($Angles[$nCount], 360), $iSweep = Mod($Angles[$nCount + 1] - $Angles[$nCount] + 360, 360)

; Draw side
    ConsoleWrite(_Now() & @CRLF)
    $hPath = _GDIPlus_PathCreate()
    If $iStart < 180 And ($iStart + $iSweep > 180) Then
        _GDIPlus_PathAddArc($hPath, $iX, $iY, $iWidth, $iHeight, $iStart, 180 - $iStart)
        _GDIPlus_PathAddArc($hPath, $iX, $iY + $iDepth, $iWidth, $iHeight, 180, $iStart - 180)
        _GDIPlus_PathCloseFigure($hPath)
        _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $ahBrush[$nCount][1])
        _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $ahPen[$nCount])
        $fDrawn = True
    EndIf
    If $iStart + $iSweep > 360 Then
        _GDIPlus_PathAddArc($hPath, $iX, $iY, $iWidth, $iHeight, 0, $iStart + $iSweep - 360)
        _GDIPlus_PathAddArc($hPath, $iX, $iY + $iDepth, $iWidth, $iHeight, $iStart + $iSweep - 360, 360 - $iStart - $iSweep)
        _GDIPlus_PathCloseFigure($hPath)
        _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $ahBrush[$nCount][1])
        _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $ahPen[$nCount])
        $fDrawn = True
    EndIf
    If $iStart < 180 And (Not $fDrawn) Then
        _GDIPlus_PathAddArc($hPath, $iX, $iY, $iWidth, $iHeight, $iStart, $iSweep)
        _GDIPlus_PathAddArc($hPath, $iX, $iY + $iDepth, $iWidth, $iHeight, $iStart + $iSweep, -$iSweep)
        _GDIPlus_PathCloseFigure($hPath)
        _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $ahBrush[$nCount][1])
        _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $ahPen[$nCount])
    EndIf
    _GDIPlus_PathDispose($hPath)

; Draw top
    _GDIPlus_GraphicsFillPie($hGraphics, $iX, $iY, $iWidth, $iHeight, $iStart, $iSweep, $ahBrush[$nCount][0])
    _GDIPlus_GraphicsDrawPie($hGraphics, $iX, $iY, $iWidth, $iHeight, $iStart, $iSweep, $ahPen[$nCount])

EndFunc ;==>_DrawPiePiece

Modified the code to run on latest version.

 

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted (edited)

hmm, for some reason I get no pie!

There is no error, just a blank window with title Pie Chart.

I tried both, forcing 32 bits and 64 bits, it's all the same.

That's a shame, I love pies (sorry, I could not resist that one!).

My OS is windows 2008 R1.

Edited by rodent1
Posted (edited)

Probably the same issue as described here: '?do=embed' frameborder='0' data-embedContent>>

Can you check please? Is it working when you replace _GDIPlus_Startup() with _GDIPlus_Startup("gdiplus.dll")?

 

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

  • 3 months later...
Posted

Hi UEZ, is it possible to use your scrit as a function to show the graph in any part of a GUI?

Thanks in advance and regards.

 

jcpetu,

which script you mean exactly? And of course you can show the graph in any part of a GUI.

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

Can you further define what you mean with "any part of a GUI"?

You can set e.g. the GDI+ graphic context to a picture control which is somewhere on your GUI.

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

Those are controls which return any value for the pie. You have to check out where the values from those controls are read.

E.g. _GUICtrlSlider_GetPos($hSlideAspect) which is used to draw the pie with function _DrawPie().

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

But instead of using the controls I would like to just use the function _DrawPie() filled with values I choose from my GUI. Is it possible?

 

Posted (edited)

@jcpetu You can have a GUI of any size and you can set the chart in a picture control created at any coordinates you like (the chart will be draw in picture control). Here is an example (check out the comments):

#include <Charts.au3>

Local $aData[11][2] =  _
    [   [10,0], _
        [72040000,"China"], _
        [36784200,"Russia"], _
        [26280000,"India"], _
        [20373267,"United states"], _
        [19102300,"Ukraine"], _
        [11791072,"Poland"], _
        [11643769,"Germany"], _
        [8743976,"Belarus"], _
        [7200000,"Netherlands"], _
        [6271000,"France"]]

_AutoItObject_Startup()

$hMain = GUICreate('Pie chart',1000,700)        ; <<<----------------- Big window
$hPic = GUICtrlCreatePic('',271,236,500,300)    ; <<<----------------- Your coordinates
$Pie = PieChart()
With $Pie
    .Width = 500
    .Height = 300
    .Title = 'Potatoes production in 2007 (tonnes)'
    .TitleHeight = 30
    .TitleAlign = "Left"
    .TitleSize = 11
    .TitleStyle = "Bold"
    .LegendWidth = 200
    .LegendTextSize = 10
    .LegendStyle = "Italic"
    .Palette = '0xFF00BEEF|0xFFDC143C|0xFF228B22|0xFF003399|0xFFFF8000|0xFF80FFA0|0xFFFFD700|0xFF800080|0xFFDB7093|0xFF7F00FF'
    .OthersColor = 0xFFEEE8AA
    .Background = 0xFFFFFFFF
    .TextColor = 0xFF002060
    .Font = 'Tahoma'
    .StartAngle = 45
    .Padding = 5
    .MinSlice = 10000000
    .Bullet = "Square"
    .LegendDetails = 'Percent'
    .BorderSize = 0
    .BorderColor = 0xFF004000
    .Draw($hPic,$aData)
EndWith
GUISetState(@SW_SHOW,$hMain)

Do
    Sleep(10)
Until GUIGetMsg() = -3

_AutoItObject_Shutdown()
Edited by Andreik

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...