It is currently Thu Dec 12, 2019 4:48 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Simple Stacked Bar Chart
PostPosted: Wed Jan 02, 2019 2:46 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jan 12, 2008 3:25 pm
Posts: 344
Location: Greece
Hello and Happy New Year to all!
I just created a simple but configurable stacked bar graph, το cover a specific need.
The code is not very elegant but covers my need.
If it is useful to someone it can use it freely.
Best regards.

Thanos

Updated, 03/01/2019
v 1.1 :: Small changes to draw the data series, if it is desirable

Code:
;##-<< Simple Stacked Bar Graph >>-#######################################################
;{
;#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;#       Author: Athanasios I. Douros
;#      Version: 1.0, 02/01/2019
;#      Changes: 1.1, 03/01/2019. Small changes to draw the data series, if it is desirable
;#      Purpose: Show stacked bars
;# Restrictions: Free to use, no restrictions.
;#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;}
;##-<< Simple Stacked Bar Graph >>-#######################################################

EnableExplicit


DeclareModule StackedBarChart
 
  EnableExplicit
  #STACKBAR_CHART_WIDTH    = 1200
  #STACKBAR_CHART_HEIGHT   = 700
  #DRAW_BAR_AT_POS         = 150
  #LEGEND_HEIGHT           = 15
  #BAR_HEIGHT              = 65
  #DISTANCE_BETWEEN_BARS   = 10
  #DISTANCE_BETWEEN_LABELS = 2
  #AXIS_WIDTH              = 100
 
 
  Structure Delay
    Header.s
    Value_1.d
    Value_2.d
    Value_3.d
    Value_4.d
    Value_5.d
    Value_6.d
    Value_7.d
    Value_8.d
    List DataSeries.d()
  EndStructure
 
  Declare StackedBarShow(sTitle.s, List Values.Delay(), List Labels.s(), DrawDataSeries = #True)
 
EndDeclareModule


Module StackedBarChart
 
  Procedure Max(Value1, Value2)
    If (Value1 >= Value2)
      ProcedureReturn Value1
    Else
      ProcedureReturn Value2
    EndIf
  EndProcedure
 
 
  Procedure StackedBarsCalcPercentages(List Values.Delay())
    Protected dSum.d
   
    ForEach Values()
      With Values()
        dSum = \Value_1 +
               \Value_2 +
               \Value_3 +
               \Value_4 +
               \Value_5 +
               \Value_6 +
               \Value_7 +
               \Value_8
       
        \Value_1 = (\Value_1 / dSum)
        \Value_2 = (\Value_2 / dSum)
        \Value_3 = (\Value_3 / dSum)
        \Value_4 = (\Value_4 / dSum)
        \Value_5 = (\Value_5 / dSum)
        \Value_6 = (\Value_6 / dSum)
        \Value_7 = (\Value_7 / dSum)
        \Value_8 = (\Value_8 / dSum)
       
        ;~ Fill the data for data series
        AddElement(\DataSeries()): \DataSeries() = \Value_1
        AddElement(\DataSeries()): \DataSeries() = \Value_2
        AddElement(\DataSeries()): \DataSeries() = \Value_3
        AddElement(\DataSeries()): \DataSeries() = \Value_4
        AddElement(\DataSeries()): \DataSeries() = \Value_5
        AddElement(\DataSeries()): \DataSeries() = \Value_6
        AddElement(\DataSeries()): \DataSeries() = \Value_7
        AddElement(\DataSeries()): \DataSeries() = \Value_8
      EndWith
    Next
   
  EndProcedure
 
 
  Procedure StackedBarsDraw(List Values.Delay(), List Labels.s(), WinHeight, Font1, Font2, Font3, DrawDataSeries)
    Protected CurrBar
    Protected BarLeft
    Protected BarTop
    Protected BarLen
    Protected BarValue.d
    Protected StackLen  = #STACKBAR_CHART_WIDTH - 175
    Protected LabelTop
    Protected LabelLeft
   
    Protected CurrVal
    Protected TotalLabels
    Protected sLabel.s
    ;~ Protected NewList BranchData.d()
    Protected Dim StackBarColor(7)
   
    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ;~ Colors
    ;{
    StackBarColor(00) = RGBA(102, 170, 000, 255)
    StackBarColor(01) = RGBA(016, 150, 024, 255)
    StackBarColor(02) = RGBA(034, 170, 153, 255)
    StackBarColor(03) = RGBA(221, 068, 119, 255)
    StackBarColor(04) = RGBA(255, 010, 010, 255)
    StackBarColor(05) = RGBA(153, 000, 153, 255)
    StackBarColor(06) = RGBA(127, 000, 000, 255)
    StackBarColor(07) = RGBA(048, 048, 048, 255)
    ;}
    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   
    ForEach Values()
      ;~ ClearList(BranchData())
      ;~ AddElement(BranchData()): BranchData() = Values()\Value_1
      ;~ AddElement(BranchData()): BranchData() = Values()\Value_2
      ;~ AddElement(BranchData()): BranchData() = Values()\Value_3
      ;~ AddElement(BranchData()): BranchData() = Values()\Value_4
      ;~ AddElement(BranchData()): BranchData() = Values()\Value_5
      ;~ AddElement(BranchData()): BranchData() = Values()\Value_6
      ;~ AddElement(BranchData()): BranchData() = Values()\Value_7
      ;~ AddElement(BranchData()): BranchData() = Values()\Value_8       
     
      ;~ Set the drawing font
      DrawingFont(FontID(Font1))
     
      ;~ Take the values
      sLabel  = Values()\Header
      BarLeft = #DRAW_BAR_AT_POS
      BarTop  = (CurrBar * #BAR_HEIGHT)
      CurrVal = 0
     
      ForEach Values()\DataSeries()
        BarLen   = (StackLen * Values()\DataSeries())
        BarValue = (BarLen/StackLen) * 100
        LabelTop = BarTop  + (#BAR_HEIGHT / 2.5)
        Box(BarLeft, BarTop + (CurrBar * #DISTANCE_BETWEEN_BARS) + 5, BarLen, #BAR_HEIGHT,  StackBarColor(CurrVal))
        DrawText(BarLeft+5, LabelTop + (CurrBar * #DISTANCE_BETWEEN_BARS) + 5, StrD(BarValue, 2) + "%", $FFFFFF)
        BarLeft + BarLen
       
        ;~ Increase counter
        CurrVal + 1
      Next
     
      ;~ Set the label
      DrawingFont(FontID(Font2))
      DrawText(10, LabelTop + (CurrBar * #DISTANCE_BETWEEN_BARS), sLabel, RGBA(75, 75, 75, 75))
     
      CurrBar + 1
    Next
   
    ;~ Draw the legends
    CurrBar     = 0
    TotalLabels = ListSize(Labels()) + #DISTANCE_BETWEEN_LABELS
    BarTop      = WinHeight - (TotalLabels * #LEGEND_HEIGHT)
    ;~ Set the drawing font
    DrawingFont(FontID(Font3))
    ForEach Labels()
      Box(150, BarTop, 25, #LEGEND_HEIGHT, StackBarColor(CurrBar))
      DrawText(180, BarTop, Labels(), RGBA(75, 75, 75, 75))
      CurrBar + 1
      BarTop  + #LEGEND_HEIGHT + #DISTANCE_BETWEEN_LABELS
    Next
   
   
    ;~ Draw the Data series
    If (DrawDataSeries = #True)
      TotalLabels = ListSize(Labels()) + #DISTANCE_BETWEEN_LABELS
      LabelLeft   = 375
      ;~ Set the drawing font
      DrawingFont(FontID(Font3))
     
      ForEach Values()
        With Values()
          BarTop      = WinHeight - (TotalLabels * #LEGEND_HEIGHT) - 20
          DrawText(LabelLeft, BarTop, \Header, RGBA(75, 75, 75, 75))     
          ;~ Start drawing the data
          BarTop      = WinHeight - (TotalLabels * #LEGEND_HEIGHT)
          ForEach \DataSeries()
            DrawText(LabelLeft, BarTop, StrD((\DataSeries() * 100), 2) + "%", RGBA(75, 75, 75, 75))     
            BarTop    + #LEGEND_HEIGHT + #DISTANCE_BETWEEN_LABELS
          Next
        EndWith
        LabelLeft + #AXIS_WIDTH
      Next   
    EndIf
   
  EndProcedure
 
 
  Procedure StackedBarShow(sTitle.s, List Values.Delay(), List Labels.s(), DrawDataSeries = #True)
    Protected Event
    Protected hImg1
    Protected hImg2
    Protected hWnd
    Protected hScroll
    Protected WinHeight
    Protected WinWidth
    Protected Font1 = LoadFont(#PB_Any, "Tahoma",  7, #PB_Font_Bold|#PB_Font_HighQuality)
    Protected Font2 = LoadFont(#PB_Any, "Tahoma", 11, #PB_Font_HighQuality)
    Protected Font3 = LoadFont(#PB_Any, "Tahoma",  7, #PB_Font_HighQuality)
   
    WinHeight = ListSize(Values()) * (#BAR_HEIGHT + 5)
    WinHeight + ListSize(Labels()) * (#LEGEND_HEIGHT + 5)
    WinHeight * 1.05
    WinHeight = Max(WinHeight, #STACKBAR_CHART_HEIGHT)
   
    If (DrawDataSeries = #True)
      WinWidth  = ListSize(Values()) * (#AXIS_WIDTH * 1.30)
      WinWidth  = Max(WinWidth, #STACKBAR_CHART_WIDTH)
    Else
      WinWidth  = #STACKBAR_CHART_WIDTH
    EndIf
   
    hWnd = OpenWindow(#PB_Any, 0, 0, #STACKBAR_CHART_WIDTH, #STACKBAR_CHART_HEIGHT, sTitle, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If (hWnd)
      hScroll = ScrollAreaGadget(#PB_Any, 0, 0, #STACKBAR_CHART_WIDTH, #STACKBAR_CHART_HEIGHT, WinWidth, WinHeight, 30, #PB_ScrollArea_Flat)
     
      hImg1 = CreateImage(#PB_Any, WinWidth, WinHeight)
      If (hImg1) And (StartDrawing(ImageOutput(hImg1)))
        ;~ If CreateImage(0, #CHART_WIDTH, #CHART_HEIGHT) And StartDrawing(ImageOutput(0))
       
        DrawingMode(#PB_2DDrawing_Transparent)
       
        ;~ Change from values to percentages
        StackedBarsCalcPercentages(Values())
       
        ;~ Set white background for the whole chart
        Box(0, 0, WinWidth, WinHeight, $FFFFFF)
       
        ;~ Display the stacked bars
        StackedBarsDraw(Values(), Labels(), WinHeight, Font1, Font2, Font3, DrawDataSeries)
       
        StopDrawing()
        hImg2 = ImageGadget(#PB_Any, 0, 0, WinWidth, WinHeight, ImageID(hImg1))
        CloseGadgetList()
       
      EndIf
     
      Repeat
        Event = WaitWindowEvent()
      Until Event = #PB_Event_CloseWindow
      CloseWindow(hWnd)
    EndIf
  EndProcedure
EndModule


CompilerIf #PB_Compiler_IsMainFile
  Define NewList Labels.s()
  AddElement(Labels()): Labels() = "Label 1"
  AddElement(Labels()): Labels() = "Label 2"
  AddElement(Labels()): Labels() = "Label 3"
  AddElement(Labels()): Labels() = "Label 4"
  AddElement(Labels()): Labels() = "Label 5"
  AddElement(Labels()): Labels() = "Label 6"
  AddElement(Labels()): Labels() = "Label 7"
  AddElement(Labels()): Labels() = "Label 8"
 
  ;~ You can add as many Values() as you want
  ;~ Each Values() creates a new bar in chart
  Define NewList Values.StackedBarChart::Delay()
  AddElement(Values())
  Values()\Header   = "Header 001"
  Values()\Value_1 = 4898600.0
  Values()\Value_2 = 2811870.0
  Values()\Value_3 = 2013820.0
  Values()\Value_4 = 1834540.0
  Values()\Value_5 = 2586490.0
  Values()\Value_6 = 1134970.0
  Values()\Value_7 = 1253450.0
  Values()\Value_8 = 3738510.0
 
  AddElement(Values())
  Values()\Header   = "Header 002"
  Values()\Value_1 = 5068430.0
  Values()\Value_2 = 597752.0
  Values()\Value_3 = 1867140.0
  Values()\Value_4 = 1338630.0
  Values()\Value_5 = 422371.0
  Values()\Value_6 = 351421.0
  Values()\Value_7 = 307252.0
  Values()\Value_8 = 10894000.0
 
  AddElement(Values())
  Values()\Header   = "Header 003"
  Values()\Value_1 = 1098130.0
  Values()\Value_2 = 884433.0
  Values()\Value_3 = 277653.0
  Values()\Value_4 = 499117.0
  Values()\Value_5 = 448056.0
  Values()\Value_6 = 2138260.0
  Values()\Value_7 = 769726.0
  Values()\Value_8 = 3826260.0
 
  AddElement(Values())
  Values()\Header   = "Header 004"
  Values()\Value_1 = 1135720.0
  Values()\Value_2 = 371530.0
  Values()\Value_3 = 154354.0
  Values()\Value_4 = 46228.0
  Values()\Value_5 = 12444.2
  Values()\Value_6 = 0.0
  Values()\Value_7 = 8074.23
  Values()\Value_8 = 57124.9
 
  AddElement(Values())
  Values()\Header   = "Header 005"
  Values()\Value_1 = 522394.0
  Values()\Value_2 = 198548.0
  Values()\Value_3 = 108467.0
  Values()\Value_4 = 163168.0
  Values()\Value_5 = 62078.0
  Values()\Value_6 = 44384.9
  Values()\Value_7 = 131412.0
  Values()\Value_8 = 236213.0
 
  AddElement(Values())
  Values()\Header   = "Header 006"
  Values()\Value_1 = 522394.0
  Values()\Value_2 = 198548.0
  Values()\Value_3 = 108467.0
  Values()\Value_4 = 663168.0
  Values()\Value_5 = 62078.0
  Values()\Value_6 = 44384.6
  Values()\Value_7 = 131412.0
  Values()\Value_8 = 236213.0
 
  AddElement(Values())
  Values()\Header   = "Header 007"
  Values()\Value_1 = 222394.0
  Values()\Value_2 = 198548.0
  Values()\Value_3 = 108467.0
  Values()\Value_4 = 163168.0
  Values()\Value_5 = 62078.0
  Values()\Value_6 = 44385.1
  Values()\Value_7 = 131412.0
  Values()\Value_8 = 236213.0
 
  ;~ Show the chart
  StackedBarChart::StackedBarShow("Stacked bar demo", Values.StackedBarChart::Delay(), Labels(), #True)
CompilerEndIf

_________________
» myPersonal Banker :: Because you do not need to have a master degree in economics in order to organize your finances!


Last edited by thanos on Thu Jan 03, 2019 3:29 pm, edited 2 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Simple Stacked Bar Chart
PostPosted: Wed Jan 02, 2019 4:48 pm 
Offline
Enthusiast
Enthusiast

Joined: Fri Feb 19, 2010 3:42 am
Posts: 540
This is really simple -> thanks to PureBasic!

This is a great example -> thanks to thanos!

Thanks a lot!!!


Top
 Profile  
Reply with quote  
 Post subject: Re: Simple Stacked Bar Chart
PostPosted: Wed Jan 02, 2019 6:22 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jan 12, 2008 3:25 pm
Posts: 344
Location: Greece
@HanPBF
Thank you very much for the kind words!
Regards

Thanos

_________________
» myPersonal Banker :: Because you do not need to have a master degree in economics in order to organize your finances!


Top
 Profile  
Reply with quote  
 Post subject: Re: Simple Stacked Bar Chart
PostPosted: Thu Jan 03, 2019 12:13 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4545
Location: Lyon - France
Nice and simple
Thanks for sharing 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Simple Stacked Bar Chart
PostPosted: Thu Jan 03, 2019 12:26 pm 
Offline
Moderator
Moderator
User avatar

Joined: Thu Dec 31, 2009 11:05 pm
Posts: 1108
Location: Berlin (Germany)
Nice :)

_________________
ImageImageImageImage Image


Top
 Profile  
Reply with quote  
 Post subject: Re: Simple Stacked Bar Chart
PostPosted: Thu Jan 03, 2019 6:22 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jan 12, 2008 3:25 pm
Posts: 344
Location: Greece
There is an updated version with small changes.
Code has been updated in the first post.
Regards

Thanos

_________________
» myPersonal Banker :: Because you do not need to have a master degree in economics in order to organize your finances!


Top
 Profile  
Reply with quote  
 Post subject: Re: Simple Stacked Bar Chart
PostPosted: Thu Jan 03, 2019 8:42 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 6:14 pm
Posts: 1704
Location: Germany (Saxony, Deutscheinsiedel)
Very nice, thank you! :D

_________________
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye