Sign in to follow this  
Followers 0
Andreik

Pie chart

21 posts in this topic




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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Thanks UEZ!

This was in my mind from beginning, I'm just looking for a nice method to create 3D effect.


When the words fail... music speaks

Share this post


Link to post
Share on other sites

#4 ·  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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

First off, I find this pretty awesome.  I think there are a ton of uses for it so thank you very much for sharing.  Also, thank you for making me aware of AutoItObject.au3.  That is an amazing UDF that I did not know about.  I think it would be great if it eventually became part of the core modules.


Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt

Share this post


Link to post
Share on other sites

#6 ·  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

Share this post


Link to post
Share on other sites

#7 ·  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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

That fixed it, thanks UEZ!

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

The script of post #4 .

Share this post


Link to post
Share on other sites

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

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?

 

Share this post


Link to post
Share on other sites

I know the aspect, style, etc. will be fixed but I just want to draw the pie if possible.

Share this post


Link to post
Share on other sites

#17 ·  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

When the words fail... music speaks

Share this post


Link to post
Share on other sites

Andreik with this Object implementation is really fast and simple, I was just investigating with GDI that provides a better looking 3D graph.

Thanks a lot and regards.

Share this post


Link to post
Share on other sites

Andreik by the way, the Objects implementation allows bar graph as well?

Share this post


Link to post
Share on other sites

Andreik by the way, the Objects implementation allows bar graph as well?

 

Right not just pie charts are available but can be deisgned to draw bar graphs as well.


When the words fail... music speaks

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0