Create HTML bar charts with WhizBase

Published:
In this tutorial I will show you how to make a simple HTML bar chart with the usage of WhizBase, If you want more information about WhizBase please read my previous articles at http://www.experts-exchange.com/ARTH_5123186.html

A bar chart  is a chart with rectangular bars with lengths proportional to the values that they represent. The bars in this tutorial will be plotted horizontally. I will use WhizBase and HTML only. No need for any graphics or flash.

Creating the library
I will first begin with making a library of subroutines so I can call any subroutine to do me a job in any time in my code. Subroutines are something similar to custom functions in other programming languages. You can create any number of subroutines as you want, and they will not be processed until you call it in the code.

I will create five subroutines, one will be to initialize the width, the rest are to add a column,  to calculate the percentage, to calculate the width values and to draw the graph (bar chart).

First the initialization subroutine:
<!--wb_beginsub_init-->
                      $wbif[$wbgetv[w]>99|$wbsetv[width|$wbgetv[w]]|$wbsetv[width|100]]
                      <!--WB_EndSub-->

Open in new window


Before calling this subroutine I will set a variable 'w', if it is less than 99 or it is not sat I will set it to 100. Else I will take my variable value and set it in variable 'width'. This step is nessecery so we have always a default maximum width for the columns. Setting 'w' is not necessary.

Line 1 and line 3 are the start and the end of the subroutine. After beginsub 'init' is the name of the subroutine. Everything in between will not be rendered until you call the subroutine. Subroutines can call also subroutines in it self.

Now I will need a subroutine to add a new column. I want my graph to be dynamic so I can use it to unlimited number of comparetions.

<!--wb_beginsub_addColumn-->
                      $WBAADD[headers|$wbgetv[hN]|F]
                      $WBAADD[barVals|$wbgetv[bV]|F]
                       $wbsetv[sum|$wbcalc[$wbgetv[sum] + $wbgetv[bV]]]   
                       $WBAADD[colorBars|$wbgetv[cB]|F] 
                      <!--WB_EndSub-->

Open in new window


When adding a new column (bar) I need to specify 3 elements, the name of that bar, it's color and value. So I need to set 3 variables before calling this subroutines, 'hN' for name, 'bV' for value and 'cB' for color.

In the subroutine I am adding the bar name to an array named as 'headers ', the values to an array named as 'barVals' and the color to 'colorBars' array. I also need to sum all values because I will needed it later.

In WhizBase if you set a value to undefined variable or array it will define it automatically, so you do not need to worry about memory allocations and errors for undefined variables.

Every bar has a value which is a part of the sum of all values. To unify the values I need to get the percentage of these values to the total sum of all. 'calcPercents' will do the calculations I need.

<!--wb_beginsub_calcPercents-->
                      $wbsetv[numBars|$WBALEN[barVals]]
                      $wbsetv[i|0]
                      $wbwhile[$wbgetv[i]<$wbgetv[numBars]|
                      $WBAADD[barPerc|$wbformat$wbcalc[($wbgetv[barVals($wbgetv[i])]/$wbgetv[sum])*100]|#]|F]
                      $wbsetv[i|$wbcalc[$wbgetv[i]+1]]
                      ]
                      <!--WB_EndSub-->

Open in new window


Now if you do not like mathematics you have a problem. I will need number of the bars to calculate all the percentages in a loop. The calculated value is added to 'barPerc' array. The formula in logic terms are:

 interger of( (Bar value devided by total) multiply with 100)

Open in new window


I will not explain more how I got the percentage value it is pure mathematics.
'calcWidthVals' subroutine is used to calculate the width of every bar in HTML so I can draw the bars.

<!--wb_beginsub_calcWidthVals-->
                      $wbsetv[numBars|$WBALEN[barVals]]
                      $wbsetv[i|0]
                      $wbwhile[$wbgetv[i]<$wbgetv[numBars]|
                      $WBAADD[widthVals|$wbcalc[abs(($wbgetv[barPerc($wbgetv[i])]/$wbgetv[width])*100)]|F]
                      $wbsetv[i|$wbcalc[$wbgetv[i]+1]]
                      ]
                      <!--WB_EndSub-->

Open in new window


Again by looping through all bar percentages I will get the width by this formula:

Absolute of((bar percentage devided by maximum width) multiply with 100)

Open in new window


I am using absolute values here because in HTML I can not use negative values.
Finally I have just one subroutine to create, it is 'drawGraph', this one will draw the bars in HTML.

<!--wb_beginsub_drawGraph-->
                      	$wbsub[calcPercents]
                      	$wbsub[calcWidthVals]
                      	$wbsetv[numBars|$WBALEN[barVals]]
                      	<table cellpadding="0" cellspacing="0" border="0">
                      	$wbsetv[i|0]
                      	$wbwhile[$wbgetv[i]<$wbgetv[numBars]|
                      		<tr>
                      		<td class="$wbgetv[cellClassName]">
                      		$wbgetv[headers($wbgetv[i])]</td>
                      		<td align="right" width="$wbcalc[$wbgetv[width]/2]">
                      		<table cellpadding="0" cellspacing="0" width="$wbif[$wbgetv[barVals($wbgetv[i])]<0|$wbgetv[widthVals($wbgetv[i])]|0]%" border="0">
                      		<tr height="20"><td width="100%" bgcolor="$wbgetv[colorBars($wbgetv[i])]"></td></tr>
                      		</table>
                      		</td>
                      		<td align="left" width="$wbcalc[$wbgetv[width]/2]">
                      		<table cellpadding="0" cellspacing="0" width="$wbif[$wbgetv[barVals($wbgetv[i])]>0|$wbgetv[widthVals($wbgetv[i])]|0]%" border="0">
                      		<tr height="20"><td width="100%" bgcolor="$wbgetv[colorBars($wbgetv[i])]"></td></tr>
                      		</table>
                      		</td>
                      		</tr>
                      		$wbsetv[i|$wbcalc[$wbgetv[i]+1]]
                      	]</table>
                      <!--WB_EndSub-->

Open in new window


This subroutine does most of the job for us, in it I am calling the other subroutines. The only variable I can use if I want is 'cellClassName' which will hold the cell class name for CSS. You can skip this variable, it is just for formatting.

In this subroutine I am calculating the percentages by 'calcPercents', calculating bar widths by 'calcWidthVals' and counting how many bars do I have. Now I will create a table and loop the rows to create a row for every bar.

As bar graphs can have negative values I will use a two side bars view, the left ones are less than zero and the right ones are above zero. I am making a table with two cells, every cell will have an IF statement to check if the value is less than zero, this will show every row in its proper place.

In this table I am coloring the cell background and manipilating the cell width to show a presentation of the bar.

That will be all for the library. Just save this code as 'graph.ic'.

#* Initialization width *#
                      <!--wb_beginsub_init-->
                      $wbif[$wbgetv[w]>99|$wbsetv[width|$wbgetv[w]]|$wbsetv[width|100]]
                      <!--WB_EndSub-->
                      
                      #*
                        This subroutine adds a new values to the graphic 
                        "hN" This is the name of the column (string type) 
                        "bV" This is a number that specifies the value of the bar 
                        "cB" This is an string that specifies the color of the bar 
                      *#
                      <!--wb_beginsub_addColumn-->
                      	$WBAADD[headers|$wbgetv[hN]|F]
                      	$WBAADD[barVals|$wbgetv[bV]|F]
                          $wbsetv[sum|$wbcalc[$wbgetv[sum] + $wbgetv[bV]]]   
                          $WBAADD[colorBars|$wbgetv[cB]|F] 
                      <!--WB_EndSub-->
                      
                      #* This subroutine calculates the percents of the total *#
                      <!--wb_beginsub_calcPercents-->
                      	$wbsetv[numBars|$WBALEN[barVals]]
                      	$wbsetv[i|0]
                      	$wbwhile[$wbgetv[i]<$wbgetv[numBars]|
                      		$WBAADD[barPerc|$wbformat[$wbcalc[($wbgetv[barVals($wbgetv[i])]/$wbgetv[sum])*100]|#]|F]
                      		$wbsetv[i|$wbcalc[$wbgetv[i]+1]]
                      	]
                      <!--WB_EndSub-->
                      
                      #* This subroutine calculates the width values *#
                      <!--wb_beginsub_calcWidthVals-->
                      	$wbsetv[numBars|$WBALEN[barVals]]
                      	$wbsetv[i|0]
                      	$wbwhile[$wbgetv[i]<$wbgetv[numBars]|
                      		$WBAADD[widthVals|$wbcalc[abs(($wbgetv[barPerc($wbgetv[i])]/$wbgetv[width])*100)]|F]
                      		$wbsetv[i|$wbcalc[$wbgetv[i]+1]]
                      	]
                      <!--WB_EndSub-->
                      
                      #* 
                      	This subroutine draws the graph 
                      	"cellClassName" a css class name for easier formatting
                      *#
                      <!--wb_beginsub_drawGraph-->
                      	$wbsub[calcPercents]
                      	$wbsub[calcWidthVals]
                      	$wbsetv[numBars|$WBALEN[barVals]]
                      	<table cellpadding="0" cellspacing="0" border="0">
                      	$wbsetv[i|0]
                      	$wbwhile[$wbgetv[i]<$wbgetv[numBars]|
                      		<tr>
                      		<td class="$wbgetv[cellClassName]">
                      		$wbgetv[headers($wbgetv[i])]</td>
                      		<td align="right" width="$wbcalc[$wbgetv[width]/2]">
                      		<table cellpadding="0" cellspacing="0" width="$wbif[$wbgetv[barVals($wbgetv[i])]<0|$wbgetv[widthVals($wbgetv[i])]|0]%" border="0">
                      		<tr height="20"><td width="100%" bgcolor="$wbgetv[colorBars($wbgetv[i])]"></td></tr>
                      		</table>
                      		</td>
                      		<td align="left" width="$wbcalc[$wbgetv[width]/2]">
                      		<table cellpadding="0" cellspacing="0" width="$wbif[$wbgetv[barVals($wbgetv[i])]>0|$wbgetv[widthVals($wbgetv[i])]|0]%" border="0">
                      		<tr height="20"><td width="100%" bgcolor="$wbgetv[colorBars($wbgetv[i])]"></td></tr>
                      		</table>
                      		</td>
                      		</tr>
                      		$wbsetv[i|$wbcalc[$wbgetv[i]+1]]
                      	]</table>
                      <!--WB_EndSub-->

Open in new window


Creating the main file
I will create my main file, I am naming it as 'default.wbsp', in it I do not have a lot to do, in general these are steps I need:
1.      Include the bar chart library
2.      Initialize the maximum width of a bar
3.      Add all the bars ( name, color, value)
4.      Finally draw the graph


This is the code for all above:
[FormFields]
                      wb_command=r
                      WB_showlogo=F
                      <!--WB_BeginTemplate-->
                      $wbrinc[graph.ic]
                      $wbsetv[w|100]$wbsub[init]
                      $wbsetv[hN|Column 1]$wbsetv[bV|25,2]$wbsetv[cB|#CCCCCC]$wbsub[addColumn]
                      $wbsetv[hN|Column 2]$wbsetv[bV|-25,2]$wbsetv[cB|#AAAAAA]$wbsub[addColumn]
                      $wbsetv[hN|Column 3]$wbsetv[bV|100,32]$wbsetv[cB|#999999]$wbsub[addColumn]
                      $wbsetv[hN|Column 4]$wbsetv[bV|88,236]$wbsetv[cB|#777777]$wbsub[addColumn]
                      $wbsetv[hN|Column 5]$wbsetv[bV|11,236]$wbsetv[cB|#555555]$wbsub[addColumn]
                      
                      <html> 
                      <head> 
                      <title>Test graphs</title> 
                      <style> 
                      <!-- 
                      .cell_header { 
                          font-family: "Arial Narrow"; 
                          font-size: 12px; 
                          font-style: normal; 
                          line-height: normal; 
                          font-weight: bold; 
                          font-variant: normal; 
                          text-transform: uppercase; 
                          color: #E0E0E0; 
                          text-decoration: none; 
                          background-color: #4E4E4E; 
                      }
                      --> 
                      </style> 
                      </head>
                      <body>$wbsetv[cellClassName|icon_links_off]$wbsub[drawGraph]</body></html>

Open in new window


For more information please visit my member profile at http://www.experts-exchange.com/M_5123186.html
Or visit the WhizBase official site at www.whizbase.com

NurAzije is a PHP and WhizBase programmer, who at the time of article publication has been working in partnership with WhizBase company on several projects and very recently as an employee.
1
3,288 Views

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.