/*=========================================================================*/
// BarChart Object
// - draws vertical and horizontal bar charts in Javascript
//
// (c) Marco Zierl January 2002
// Contact: mzierl@web.de
//
// Freeware - use in commercial and private applications/websites allowed
// 		if this copyright notice is not removed
// 
// Documentation provided in March 2002 issue of Internet Professionell
// Order: www.vnunet.de
/*=========================================================================*/

function Entry(label, value){
	this.label=label;
	this.value=value;
}


// object definition
function BarChart(){

	// variables
	this.bar_width=20; // bar width in pixel
	this.bar_space=5; // pixelspace between the different bars
	this.default_color="black"; // default color, if no color cycling
	this.color_cycle=true; // change bar colors
	this.color_list=new Array("black", "magenta", "yellow", "green", "red", "cyan", "blue", "darkred");
	this.current_color=0; 

	this.show_values=true; // show data values after bars
	this.draw_axis=true; // show axis
	this.fontpixel = 11; // font size

	this.axis_unit=-1; 

	this.bar_data=new Array(); // holds all bar data
 
	// methods
	this.addEntry=addEntry;
	this.compute_size=compute_size;
	this.get_max_label=get_max_label;
	this.draw_chart_hor=draw_chart_hor;
	this.get_color=get_color;
	this.get_limit=get_limit;
	this.draw_chart_vert=draw_chart_vert;
	this.get_max=get_max;
	this.draw_sections_hor=draw_sections_hor;
	this.draw_sections_ver=draw_sections_ver;
	this.compute_section=compute_section;
	
	// Method definitions
	
	// add entry to BarChart Object
	function addEntry(label, value){
		var len = this.bar_data.length;
		this.bar_data[len]=new Entry(label, value);
	}
	
	// calculate data value in relation to max_value and given size
	function compute_size(value, size, max_value){
		var result= (size/max_value) * value;
		return Math.round(result);
	}

	/*-------------------------------------------------------------------------*/
	// return label with highest number of characters
	// - for calculation of td width
	/*-------------------------------------------------------------------------*/

	function get_max_label(){
		var max_value=this.bar_data[0].label.length;
		for(i=1; i< this.bar_data.length; i++){
			if(max_value < this.bar_data[i].label.length){
				max_value=this.bar_data[i].label.length;
			}
		}
		return max_value;
	}

	/*-------------------------------------------------------------------------*/
	// draw horizontal bar charts
	// Arg: x-size in pixel
	/*-------------------------------------------------------------------------*/

	function draw_chart_hor(x_size){
		this.current_color=0;
		var max_value = this.get_max();
		var max_label = this.get_max_label();
	
		document.write("<table cellpadding=0 cellspacing=0 border=0><tr><td>");
		document.write("<table cellpadding=0 cellspacing=0 border=0 width=" + 
			(this.fontpixel-1)*max_label + ">"); 
		document.write("<tr><td></td></tr></table>");
		document.write("</td><td>");
		document.write("<table cellpadding=0 cellspacing=0 border=0>");
		document.write("<tr><td>");

		if(this.draw_axis==true){
			this.draw_sections_hor(x_size);
		}

		document.write("</td></tr></table>");
		document.write("</td></tr></table>");

		for(i=0; i<this.bar_data.length; i++){
			document.write("<table cellpadding=0 cellspacing=0 border=0><tr colspan=3><td height=" + this.bar_space + "></td></tr><tr><td>");
	
			document.write("<table cellpadding=0 cellspacing=0 border=0 width=" + 
				(this.fontpixel-1)*max_label + ">"); 
			document.write("<tr><td style='font-size:" + this.fontpixel + 
				";'>" + this.bar_data[i].label + "</td></tr></table>");
			document.write("</td><td>");
	
			document.write("<table cellpadding=0 cellspacing=0 border=0 width=" + 
				compute_size(this.bar_data[i].value, x_size, max_value) + ">");
			document.write("<tr><td style='font-size:1px;' height=" + 
				this.bar_width + " bgcolor='" + this.get_color() + "' width=" + 
				this.compute_size(this.bar_data[i].value, x_size, max_value) + ">&nbsp;</td><tr>");
			document.write("</table>");
			document.write("</td><td>");
			document.write("<table cellpadding=0 cellspacing=0 border=0>"); 
			document.write("<tr><td style='font-size:" + this.fontpixel + ";'>&nbsp;" +
				this.bar_data[i].value + "</td></tr></table>");
			document.write("</td></tr></table>");
		}
	
		//document.write("</tr></table>");
	
	}

	/*-------------------------------------------------------------------------*/
	// draw vertical bar charts
	// Arg: y-size in pixel
	/*-------------------------------------------------------------------------*/

	function draw_chart_vert(size){
		this.current_color=0;
		var max_value=this.get_max();
		document.write("<table cellpadding=0 cellspacing=0 border=0><tr><td valign=bottom>");
	
		if(this.draw_axis==true){
			this.draw_sections_ver(size);
		}
		document.write("</td><td width=5></td>");
		var rest_value

		// draw bar
		for(i=0; i<this.bar_data.length; i++){
			var rest_value= max_value - this.bar_data[i].value;
	
			var disp_value = compute_size(this.bar_data[i].value, size, max_value);
			var disp_rest_value = compute_size(rest_value, size, max_value);
			document.write("<td valign=bottom align=middle><table cellpadding=0 cellspacing=0 border=0><tr>" + 
				"<td valign=bottom width=" + this.bar_width + "height=" + 
				disp_rest_value + "></td></tr> <tr><td style='font-size:1px;' width=" + this.bar_width +
				" height=" + disp_value + " bgcolor='" + this.get_color() +
				"'>&nbsp;</td></tr></table></td><td width=" + this.bar_space + "></td>");
		}
	
		document.write("<tr><td><td>");
	
		if(this.show_values==true){
		// print value and label 
		for(i=0; i<this.bar_data.length; i++){
			document.write("<td align=center style='font-size:" + this.fontpixel + ";'>" +
				this.bar_data[i].value + "</td><td width=" + this.bar_space + "></td>");
		}
		document.write("<tr><td><td>");
		}
		for(i=0; i<this.bar_data.length; i++){
			document.write("<td align=center style='font-size:" + this.fontpixel + ";'>" +
				this.bar_data[i].label + "</td><td width=" + this.bar_space + "></td>");
		}
	
		document.write("</tr><table>");
	}

	/*-------------------------------------------------------------------------*/
	// get current current of the bar chart -- color cycling
	// 
	/*-------------------------------------------------------------------------*/

	function get_color(){
		if(this.color_cycle != true){
			return (this.default_color);
		} else {
			var result = this.color_list[this.current_color];
			if( (this.current_color+1) == this.color_list.length){
				this.current_color=0;
			} else {
				this.current_color++;
			}
			return (result);
		}
	}

	/*-------------------------------------------------------------------------*/
	// get limit
	// 
	/*-------------------------------------------------------------------------*/

	function get_limit(){
		var max_value=this.get_max();
		
		if(max_value <= 20){
			divi=5;
		} else {
			var tmp = new String(max_value);
			divi = Math.pow(10, tmp.length-1);
		}
		var result=0;
		for(i=0; i<max_value; i=i+divi){
			result += divi;
		}
		return result;
	}

	/*-------------------------------------------------------------------------*/
	// compute lowest unit for x/y axis sections
	// 
	/*-------------------------------------------------------------------------*/

	function compute_section(max_value){
		if(this.axis_unit > 0){
			return (this.axis_unit);
		}
		var result=1;
		var tmp= new String(Math.ceil(max_value));
		if(tmp.length==1){
			return result;
		} 
		if(max_value < 17){
			return (5);
		}
		
		result=Math.pow(10, (tmp.length-1));
		var test = tmp.substring(0,2);
		if(test <= 14){
			return(result/10);
		} else {
			return result;
		}
	}

	/*-------------------------------------------------------------------------*/
	// draw horizontal section axis
	// 
	/*-------------------------------------------------------------------------*/

	function draw_sections_hor(size){
		var max_value=this.get_max();
		var divi=this.compute_section(max_value);

		var divi_abs = this.compute_size(divi, size, max_value);
		document.write("<table cellpadding=0 cellspacing=0 border=0><tr>");
		for(i=0; i<=max_value; i=i+divi){
			document.write("<td valign=top width=" + (divi_abs-1) + 
				" height=5><img src='px.gif' width=" + (divi_abs-1) + 
				" height=1></td><td width=1><img src='px.gif' width=1 height=10></td>");
		}
		document.write("</tr><tr>");

		for(i=0; i<max_value; i=i+divi){
			document.write("<td style='font-size:" + this.fontpixel + ";' width=" + 
				(divi_abs-1) + ">" + i + "</td><td widht=1></td>");
		}
	
		document.write("</tr></table>");
	}		

	/*-------------------------------------------------------------------------*/
	// draw vertical section axis
	// 
	/*-------------------------------------------------------------------------*/

	function draw_sections_ver(size){
		var max_value=this.get_max();

		divi=this.compute_section(max_value);
		document.write("<table cellpadding=0 cellspacing=0 border=0 align=bottom>");
	
		var number_of_sections=Math.ceil(max_value / divi);
		var divi_abs = this.compute_size(divi, size, max_value);
	
		for(i=number_of_sections; i>=0; i--){
			document.write("<tr><td valign=bottom width=20 height=");
			if(i==number_of_sections){
				document.write("1 style='font-size:" + this.fontpixel + ";'>" + (i*divi) + 
					"</td><td valign=bottom><img src='px.gif' width=10 height=1></td>" +
					"<td valign=bottom><img src='px.gif' width=1 height=1></tr>");
			} else { 
				document.write(divi_abs + " style='font-size:" + this.fontpixel + ";'>" + (i*divi) +
					"</td><td valign=bottom><img src='px.gif' width=10 height=1></td>" +
					"<td valign=bottom><img src='px.gif' width=1 height=" + divi_abs + "></tr>");
			} 
		}
		document.write("</table>");
	}		

	/*-------------------------------------------------------------------------*/
	// return highest dataset value
	// 
	/*-------------------------------------------------------------------------*/

	function get_max(){
		var max_value=this.bar_data[0].value;
		for(i=1; i<this.bar_data.length; i++){
			if(max_value < this.bar_data[i].value){
				max_value=this.bar_data[i].value;
			}
		}
		return max_value;
	}

} // end Object BarChart
