Sign in to follow this  
Followers 0

3D Bar Graph

36 posts in this topic

Posted (edited)

An example of 3D bar graph using just native AutoIt functions. Example shown uses random numbers.

Posted Image

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <Array.au3>

Global $arNames[12]
Global $arValues[12]
Example1()

Func Example1()
    Local $gui = GUICreate("Example 1: 3D Bar Graph", 550, 550)
    GUISetBkColor(0xffffff)
    $arNames=StringSplit("January|February|March|April|May|June|July|August|September|October|November|December","|",2)
    For $i=0 To 11
        $arValues[$i]=Random(0,200,1)
    Next
    _CreateBarChart("3D Bar Chart","Example 1",-1,-1,500,500)
    GUISetState()
    While 1
        Sleep(10)
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                GUIDelete($gui)
                Example2()
        EndSwitch
    WEnd
EndFunc

Func Example2()
    Local $gui = GUICreate("Example 2: 3D Bar Graph", 450, 350)
    GUISetBkColor(0xffffff)
    For $i=0 To 11
        $arNames[$i]=$i+1
    Next
    For $i=0 To 11
        $arValues[$i]=Random(0,200,1)
    Next
    _CreateBarChart("3D Bar Chart","Example 2",20,20,400,300)
    GUISetState()
    While 1
    Sleep(10)
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                GUIDelete($gui)
                Example3()
                ;Exit
        EndSwitch
    WEnd
EndFunc

Func Example3()
    Local $gui = GUICreate("Example 3: 3D Bar Graph", 850, 400)
    GUISetBkColor(0xffffff)
    For $i=0 To 11
        $arNames[$i]=$i+1
    Next
    For $i=0 To 11
        $arValues[$i]=Random(0,200,1)
    Next
    _CreateBarChart("3D Bar Chart","Example 3 - without legend",-1,-1,400,300)
    $arNames=StringSplit("January|February|March|April|May|June|July|August|September|October|November|December","|",2)
    _CreateBarChart("3D Bar Chart","Example 3 - with legend",430,-1,400,350)
    GUISetState()
    While 1
    Sleep(10)
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                GUIDelete($gui)
                ;Example3()
                Exit
        EndSwitch
    WEnd
EndFunc


; #FUNCTION# ====================================================================================================
; Name...........:  _CreateBarChart
; Description....:  Create 3D bar graph with native AutoIt functions
; Syntax.........:  _CreateBarChart($sTitle1="",$sTitle2="",$iX=20,$iY=20,$iW=400,$iH=400)
; Parameters.....:  $sTitle1 - Title of the graph, [Optional]
;                   $sTitle2 - Subtitle of the graph, [Optional]
;                   $iX - left margin, [Optional]
;                   $iY - top margin, [Optional]
;                   $iW - width of the graph, [Optional]
;                   $iH - height of the graph, [Optional]
;
; Return values..:  none
;
; Author.........:  Mihai Iancu (taietel at yahoo dot com)
; Remarks........:  $array = ["name",value]
;                    - one with numbers/names (try to uncoment/coment them)
;                    - one with values
; ===============================================================================================================
Func _CreateBarChart($sTitle1="",$sTitle2="",$iX=20,$iY=20,$iW=400,$iH=400)
    Local $max=_ArrayMax($arValues,1);compare numerically
    ;Local $values = UBound($arValues)
    Local $arColours[UBound($arNames)]
    Local $color
    For $i=0 To UBound($arValues)-1
        $color = (Random(100, 255, 1) * 0x10000) + (Random(100, 255, 1) * 0x100) + Random(100, 255, 1)
        $arColours[$i]=$color
    Next
    ;set default values for the frame
    If $iX=-1 Then $iX=20
    If $iY=-1 Then $iY=20
    If $iW=-1 Then $iW=400
    If $iH=-1 Then $iH=400
    ;create frame for the chart
    $grp = GUICtrlCreateGroup("", $iX, $iY, $iW, $iH)
    ;title
    GUICtrlCreateLabel($sTitle1,$iX+15, $iY+10,$iW-30,-1,$SS_CENTER)
    GUICtrlSetColor(-1,0x002244)
    GUICtrlSetFont(-1, 9, 800, 0, "Arial")
    GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT)
    GUICtrlCreateLabel($sTitle2,$iX+15, $iY+25,$iW-30,-1,$SS_CENTER)
    GUICtrlSetColor(-1,0x002244)
    GUICtrlSetFont(-1, 8, 800, 0, "Arial")
    GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT)
    Local $Canvas
    If IsString($arNames[1]) Then
        $Canvas = _CreateBarCanvas($iX+15, $iY+15, $iW-110, $iH-60)
        GUICtrlCreateGroup("Legend", $Canvas[0]+$Canvas[2]+10, $Canvas[1]-5, ($iW-$Canvas[2])/2-10, $Canvas[3]+$Canvas[4]+5)
        For $i=0 To UBound($arNames)-1
            GUICtrlCreateLabel($arNames[$i],$Canvas[0]+$Canvas[2]+20, $Canvas[1]+10+(($Canvas[3]+$Canvas[4]-15)/UBound($arNames))*$i,($iW-$Canvas[2])/2-30,13,$SS_CENTER)
            GUICtrlSetColor(-1,$arColours[$i]-0x444444)
            GUICtrlSetFont(-1, 8, 800, 0, "Arial")
            GUICtrlSetBkColor(-1,$arColours[$i])
        Next
        GUICtrlCreateGroup("", -99, -99, 1, 1)
    Else
        $Canvas = _CreateBarCanvas($iX+15, $iY+15, $iW-50, $iH-60)
        For $i=0 To UBound($arNames)-1
            GUICtrlCreateLabel($arNames[$i],$iX+52+(($Canvas[2]/UBound($arNames)))*$i+5, $iY+$iH-30)
            GUICtrlSetColor(-1,0x990000)
            GUICtrlSetFont(-1, 8, 800, 0, "Arial")
            GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT)
        Next
    EndIf
    ;draw the bars
    GUICtrlCreateGraphic($Canvas[0]-0.5*$Canvas[4], $Canvas[1]+0.5*$Canvas[4], $Canvas[2], $Canvas[3],0)
    For $i=0 To UBound($arValues)-1
        For $j=$Canvas[4]/2.5 To 0 Step -0.5
            GUICtrlSetGraphic(-1, $GUI_GR_COLOR, $arColours[$i]-0x333333, $arColours[$i])
            GUICtrlSetGraphic(-1, $GUI_GR_RECT, 5+($Canvas[2]/UBound($arValues))*$i+$j, -2+$Canvas[3]-$j, 0.5*($Canvas[2]/UBound($arValues)), -($Canvas[3]/_RoundUp($max))*$arValues[$i])
        Next
    Next
    GUICtrlSetGraphic(-1,$GUI_GR_REFRESH)
    For $i=0 To UBound($arValues)-1
        ;values from the top of the bars
        GUICtrlCreateLabel($arValues[$i],$Canvas[0]+($Canvas[2]/UBound($arValues))*$i, $iH-$Canvas[1]+$Canvas[4]-10-(($Canvas[3]/_RoundUp($max))*$arValues[$i]))
        GUICtrlSetColor(-1,0x002244)
        GUICtrlSetFont(-1, 7, 800, 0, "Arial")
        GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT)
    Next
    ;Y Axis
    For $i=0 To $Canvas[3] Step $Canvas[3]/5
        GUICtrlCreateLabel(($i/$Canvas[3])*_RoundUp($max),$Canvas[0]-65,$Canvas[1]+$Canvas[3]+$Canvas[4]-$i,30,-1,$SS_RIGHT)
        GUICtrlSetColor(-1,0x990000)
        GUICtrlSetFont(-1, 8, 800, 0, "Arial")
        GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT)
    Next
    GUICtrlCreateGroup("", -99, -99, 1, 1)
EndFunc
#Region INTERNAL USE ONLY
Func _RoundUp($m)
    Local $rv = Round(Ceiling($m/10)*10,-1)
    ;ConsoleWrite($rv&@CRLF)
    Return $rv
EndFunc

Func _CreateBarCanvas($iX=0, $iY=0, $iW=400, $iH=400, $iDepthCanvas=30, $BgColor=0xEEEEEE)
    Local $iXCanvas=$iX+$iDepthCanvas
    Local $iYCanvas=$iY+10+2*$iDepthCanvas
    Local $iWCanvas=$iW-2*$iDepthCanvas
    Local $iHCanvas=$iH-2*$iDepthCanvas
    Local $BgColor2 = $BgColor - 0x333333
    ;create bg for the bars
    For $i=0 To $iDepthCanvas; Step 0.5
        GUICtrlCreateGraphic($iXCanvas+$i, $iYCanvas-$i, $iWCanvas, $iHCanvas, 0)
        GUICtrlSetBkColor(-1, $BgColor)
        GUICtrlSetColor(-1, $BgColor2)
    Next
    GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 0, $iHCanvas)
    GUICtrlSetGraphic(-1, $GUI_GR_COLOR, $BgColor)
    GUICtrlSetGraphic(-1, $GUI_GR_LINE, -$iDepthCanvas-1, $iHCanvas+$iDepthCanvas+1)
    ;horizontal grid
    For $i=0 To $iHCanvas Step $iHCanvas/5
        GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 0, $i)
        GUICtrlSetGraphic(-1, $GUI_GR_COLOR, $BgColor2)
        GUICtrlSetGraphic(-1, $GUI_GR_LINE, $iWCanvas, $i)

        GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 0, $i)
        GUICtrlSetGraphic(-1, $GUI_GR_COLOR, $BgColor)
        GUICtrlSetGraphic(-1, $GUI_GR_LINE, -$iDepthCanvas, $i+$iDepthCanvas)
    Next
    Local $Canvas = StringSplit($iXCanvas+$iDepthCanvas &"|"& $iYCanvas-$iDepthCanvas&"|"&$iWCanvas&"|"&$iHCanvas&"|"&$iDepthCanvas,"|",2)
    ;ConsoleWrite($iXCanvas+$iDepthCanvas &"|"& $iYCanvas-$iDepthCanvas&"|"&$iWCanvas&"|"&$iHCanvas&@CRLF)
    Return $Canvas
EndFunc
#EndRegion INTERNAL USE ONLY

Maybe someone find it useful.

[EDIT] another nice example from boomingranny,

Edited by taietel

Share this post


Link to post
Share on other sites



Posted

Looks nice and without GDI+ ;)

What about background grid lines? And try to generate a function where you can enter e.g. number of values, values, colors, size, etc.

Br,

UEZ

Share this post


Link to post
Share on other sites

Posted

Thanks UEZ! I'm not very familiar with GDI and for some statistical crap I need for the moment, it's enough.

I've added grid lines, but the UDF needs a lot of work (already started it), for general purpose.

There are too many variables involved... especially in the "etc" part! 

M.I.

Share this post


Link to post
Share on other sites

Posted

I like it too.

Share this post


Link to post
Share on other sites

Posted

Thanks trancexx!

Share this post


Link to post
Share on other sites

Posted

I've made an UDF for that (kind of...). See first post.

Share this post


Link to post
Share on other sites

Posted

really nice one ;)

Share this post


Link to post
Share on other sites

Posted

Well done!  ;)

If you still could give the corners of the bar a different color, it would look even better (more 3D look)! 

Br,

UEZ

Share this post


Link to post
Share on other sites

Posted (edited)

Different like darker color, or totally other color? It can be done.   ;)

At lines 92 and 124 there is 

... $color - 0x333333 ...

Instead 0x333333 you can put another darker/lighter/random value.

M.I.

Edited by taietel

Share this post


Link to post
Share on other sites

Posted

Fixed some minor bugs. First post updated.

Share this post


Link to post
Share on other sites

Posted

PS: In case you missed it. The bars-height/value and background grid don't match up anymore. Bars to short compared to grid.

Other than that. Nice work. :graduated:

Share this post


Link to post
Share on other sites

Posted

MvGulik, you're right! :graduated:  Thanks! 

I have completely rewritten it (and updated first post).

M.I.

Share this post


Link to post
Share on other sites

Posted

Nice work mate :graduated:

I really like the look-and-feel (sometimes is difficult to even find the correct color shades for these columns) - 5 stars from me :(

I don't have an use at this point but who knows ...? :D

Share this post


Link to post
Share on other sites

Posted

Thanks mate! :(

The idea came to me when I saw some papers, one on top of the others. From where I stood, it looks like a cube. :graduated:  So height/width of the paper was the height/depth of the column and the number of sheets was the depth. The rest was math.

Now I try to refresh it when button is pushed, but it needs a lot of work.  :D

Share this post


Link to post
Share on other sites

Posted

Very nice. Already implementing it for one of my clients.

5 stars.

Share this post


Link to post
Share on other sites

Posted (edited)

willichan, you can then output like this (a printscreen of a pdf)

Posted Image

directly from your program, with the use of the ActiveX from my signature (see CreatePDF). Adapt the math from this post when calling that ActiveX.

Edited by taietel

Share this post


Link to post
Share on other sites

Posted

I will take a look at that.

Share this post


Link to post
Share on other sites

Posted

It looks like professionals Bargraph !

very good work ! Posted Image

Share this post


Link to post
Share on other sites

Posted

Looks really impressive!!!

Five stars from me.

Share this post


Link to post
Share on other sites

Posted

Thank you all!  :graduated:

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