/*
 *------------------------------------------------------------------
 * Copyright (c) 2003, 2004, 2005 by cisco Systems, Inc.
 * All rights reserved.
 *------------------------------------------------------------------
 */
  
 
function Graph(width, height, stacked) {
	this.stacked = stacked;
	//this.width = width || 400;
	this.width = width;
	this.height = height || 200;
	this.name = "";
	this.rows = new Array();
	this.setGraphImages = _set_graph_images;
	this.addRow = _addRowGraph;
	this.addSingleRow = _addSingleRowGraph;
	//this.addDoubleColumn = _addDoubleColumnGraph; // this adds multiple columns per unit in the row
	this.setThreshold = _setThreshold; //
	this.thresholdValues = new Array(); //
	this.thresholdColors = new Array(); //
	this.setXScale = _setXScaleGraph;
	this.setXScaleValues = _setXScaleValuesGraph;
	this.setXCustomScaleValues = _setCustomXScaleValuesGraph;
	this.setTime = _setStartTimeGraph;
	this.setDate = _setStartDateGraph;
	this.build = _buildGraph;
	this.setLegend = _setLegendGraph;
	this.writeLegend = _writeLegendGraph;
	this.setLegendOrientation = _setLegendOrientationGraph;
	this.offset = 0;
	this.bar_gif1 = "images/bar_lg2.gif";
	this.bar_gif2 = "images/bar_lg2.gif";
	this.setBarIcon = _setAlternatingBarIcon;
	this.setGraphTooltip = _setGraphTooltip;
	
	 
	return this;
	
		
}

	
function gImages() {
	this.graph_cache_images = new graphImages();
   this.graph_cache_images.img["CLEAR"].src = "images/clear.gif";
   this.graph_cache_images.img["BLACK"].src = "images/black.gif";
   this.graph_cache_images.img["BAR_GIF1"].src = "images/bar_lg.gif";
   this.graph_cache_images.img["BAR_GIF2"].src = "images/bar_lg2.gif";
  
	return this.graph_cache_images;
   
   }
	
function _set_graph_images()
{ //var graph_cache_images = new Array();
	this.graph_cache_images = gImages();
  
	
}
 



function graphImages() {
    this.img = new Array(); 
   this.img["CLEAR"] = new Image();
   this.img["BLACK"] = new Image();
   this.img["BAR_GIF1"] = new Image();
   this.img["BAR_GIF2"] = new Image();
//  return img;
   
}


/* This is a customization of the mouse-over on the graph bar icons.
   You can provide specific information for each x-axis index.  Such as 
   whether it is displaying receive or transmit date.  Just pass in the array */
function _setGraphTooltip(array_of_tooltips) {
	this.perXColumnTooltipArray = new Array();
 	this.perXColumnToolipArray = array_of_tooltips;
	for(var i = 0;i< array_of_tooltips.length; i++)
		this.perXColumnTooltipArray[i] = array_of_tooltips[i];
				
}
 
function _setLegendGraph() {
	this.legends = arguments;
	
}

//either draw the legend on the right or the bottom of the graph, "right", or "bottom"
function _setLegendOrientationGraph() {
	this.legend_orientation = arguments[0];
}
 

function _addRowGraph() {
	this.rows[this.rows.length] = new Array();
	var row = this.rows[this.rows.length-1];
	
	for(var i = 0; i < arguments.length; i++)
	row[row.length] = arguments[i];
	
	
}

function _addSingleRowGraph(array_of_rows) {
 	this.rows[this.rows.length] = new Array();
	var row = this.rows[this.rows.length-1]; 
  	for(var i = 0; i < array_of_rows.length; i++)
		 row[row.length] = array_of_rows[i];
		 
}
 

function _rescaleGraph(g) {
	g.posMax = 0, g.negMax = 0, g.c = 0;
	for(var i = 0; i < g.rows.length; i++) {
		for(var j = 0; j < g.rows[i].length; j++) {
			g.c++;
			if(g.rows[i][j] > g.posMax) g.posMax = g.rows[i][j];
			if(g.rows[i][j] < g.negMax) g.negMax = g.rows[i][j];
		}
	}
	if (g.plotMaxPercent) g.posMax = 100; // added this line
	g.vscale = g.height/(g.posMax-g.negMax);
	g.hscale = Math.floor(g.width/g.c-1/g.rows[0].length);
}

function _stackRescaleGraph(g) {
	var m, n, c = 0;
	g.posMax = 0, g.negMax = 0;
	for(var i = 0; i < g.rows[0].length; i++) {
		m = 0; n = 0;
		c++;
		for(var j = 0; j < g.rows.length; j++) {
			if(g.rows[j][i] > 0) m += g.rows[j][i];
			else n += g.rows[j][i];
		}
		if(m > g.posMax) g.posMax = m;
		if(n < g.negMax) g.negMax = n;
	}
	g.vscale = g.height/(g.posMax-g.negMax);
	g.hscale = Math.floor(g.width/c)-1;
}

function _relRescaleGraph(g) {
	var m, c = 0;
	g.vscale = g.height/100;
	for(var i = 0; i < g.rows[0].length; i++) {
		m = 0;
		c++;
		for(var j = 0; j < g.rows.length; j++) {
			if(g.rows[j][i] < 0) g.rows[j][i] = 0;
			m += g.rows[j][i];
		}
		var s = 100/m; var k = 0;
		for(var j = 1; j < g.rows.length; j++) {
			g.rows[j][i] *= s;
			g.rows[j][i] = Math.round(10*g.rows[j][i])/10;
			if(j != 0) k += g.rows[j][i]*g.vscale;
		}
		g.rows[0][i] = Math.round(10*(g.height-k)/g.vscale)/10;
	}
	g.hscale = Math.floor(g.width/c)-1;
	g.posMax = 100; g.negMax = 0;
}

//changing this slightly  so that you pass in the legend name and icon
//[1] legend icon, [2] legend name, also need to have something where you can specify orientation
function _writeLegendGraph() {
	var st = "";
	st += "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><TR><TD class='graphcontent' ALIGN=LEFT>Legend: ";
	for(var i = 0; i < this.legends.length; i++) {
		 
		if(!this.legends[i]) continue;
		//if(i >= this.rows.length) break;
		//st += "<IMG SRC=images/"+i+".gif BORDER=1 HSPACE=3>"+this.legends[i]+"<BR>\n";
		//putting the legend horizontal, rather than vertical, so replace <BR> with &nbsp;
		st += "<IMG HEIGHT=10 WIDTH=10 SRC=images/"+this.legends[i]+".gif BORDER=1 HSPACE=3>"+this.legends[++i]+"&nbsp;\n";
	}
	st += "</TD></TR></TABLE>";
	return st;
}

function _buildRegGraph(g, doc) {
	var str = "";
	g.setGraphImages();
	str += "<TABLE class='graphcontent' BORDER=0 CELLPADDING=0 CELLSPACING=0>\n";
	if(g.title) {
		str += "<TR>\n";
		if(g.scale) str += "<TD COLSPAN=3></TD>\n";
		if(g.yLabel) str += "<TD class='graphcontent'></TD>\n";
		str += "<TH VALIGN=TOP HEIGHT=30 COLSPAN="+(g.c)+">\n";
	 	str += g.title;
		str += "</TH></TR>\n";
	}
	if(g.yLabel) {
	 
		g.yLabel = g.yLabel.split(" ");
		g.yLabel = g.yLabel.join("<BR>\n");
		str += "<TR class='graphcontent'>\n";
		var r = 2; if(g.negMax && g.posMax) r++;
		str += "<TD ROWSPAN="+r+" ALIGN=LEFT WIDTH=15 NOWRAP>\n";
		str += "<B>" + g.yLabel+"</B></TD>\n";
	}
	if(g.posMax > 0) {
		if(!g.yLabel) str += "<TR>\n";
		if(g.scale) str += _writeScaleGraph(g, 0, g.posMax);
		str += "<TD VALIGN=BOTTOM";
		if(g.bgColor) str += " BGCOLOR=\""+g.bgColor+"\"";
		str += ">";
		for(var j = 0; j < g.rows[0].length; j++) {
		 
			for(var i = 0; i < g.rows.length; i++) {
				//this command checking for if g.vscale*g.rows[i][j] is greater than zero, is causing a problem for 
				//values that maybe 1 because they are multipled against a fractional value, (.75*1 = .75) and then
				//parsed into an integer so that the values appear less than zero.
				//if(parseInt(g.vscale*g.rows[i][j]) > 0) {
				if((g.vscale*g.rows[i][j]) > 0)
				{
					if(j % 2 == 0)
					{
				    	if (g.rows[i][j] > 80) {	
					   														// made changes
						str += "<IMG BORDER=0 SRC=\""+g.bar_gif1+"\"";		// to these lines
						}else if (g.rows[i][j] > 60) {								// and to customize the icon type
						str += "<IMG BORDER=0 SRC=\""+g.bar_gif1+"\"";	// also allowing for alternating bar icons
						} else {													// to highlight bars
						str += "<IMG BORDER=0  SRC=\""+g.bar_gif1+"\"";	// which goes beyond 60%, 80%
						}
					}
						else
					{ 
						 if (g.rows[i][j] > 80) {	
					   														// made changes
						str += "<IMG BORDER=0 SRC=\""+g.bar_gif2+"\"";		// to these lines
						}else if (g.rows[i][j] > 60) {								// and to customize the icon type
						str += "<IMG BORDER=0 SRC=\""+g.bar_gif2+"\"";	// also allowing for alternating bar icons
						} else {													// to highlight bars
						str += "<IMG BORDER=0  SRC=\""+g.bar_gif2+"\"";	// which goes beyond 60%, 80%
						}
					}
					
					//this is the mouse-over code
					str += "Title=\"";
					//if(g.legends && g.legends[i]) str += g.legends[i]+": ";
					//if(g.dates) str += g.dates[j] + " : ";
					if(g.perXColumnTooltipArray != null) str += g.perXColumnTooltipArray[j] + " "; //this is the column that gives
																								  //more tooltip info about the data 
																								 
					if(g.xDisplay != null) str += g.xDisplay + " "; 	// added this line
									// modified this line
					if (g.yDisplay != null) str += g.yDisplay + " "; 	// added this line
					str += (g.rows[i][j]+g.offset) + "%"; 				// modified this line
					str += "\" ";
					str += "WIDTH="+parseInt(g.hscale)+" ";
					//g.rows[i][j] contains the value to display in the bar graph
					 if(parseInt(g.vscale*g.rows[i][j]) < 1)
						var bar_height = 1;
							else
						var bar_height = parseInt(g.vscale*g.rows[i][j]);
						
					if (document.all)
						str += "HEIGHT="+bar_height+" ";
					else
						str += "HEIGHT="+bar_height+" ";
					str += ">";
				} else
					str += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "'  WIDTH="+parseInt(g.hscale)+" HEIGHT=5>";
				str += "</TD>\n<TD VALIGN=BOTTOM";
				if(g.bgColor) str += " BGCOLOR=\""+g.bgColor+"\"";
				str += ">";
			}
			str += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH=1 HEIGHT=5>";
		}
		str += "</TD>\n";
	}
	/*This positioning of the legend does not work for 48 port graphs because it is too large, but you can pick the 
	  orientation of the graph, so if the legend has been set to 'right' then it will be drawn here*/
	if((g.legends && g.posMax != 0) && (g.legend_orientation.indexOf("right") != -1) ) {
		str += "<TD WIDTH=5 NOWRAP ROWSPAN=3></TD>\n";
		str += "<TD ROWSPAN=3>";
		str += g.writeLegend();
		str += "</TD>\n";
	}
	 
	if(g.scale || g.xScale) {
		if(g.posMax) str += "</TR><TR>\n";
		else str += "<TR><TD COLSPAN=2></TD>\n";
		str += "<TD BGCOLOR='#000000' height='1' COLSPAN="+(g.c+1)+">";	// 
		str += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src + "' HEIGHT=1 WIDTH=";
		str += parseInt(g.rows[0].length*g.hscale)+"></TD></TR>\n";
	}
	if(g.xScale && !g.negMax)
		str += _writeXScaleGraph(g);
	if(g.negMax < 0) {
		if(g.posMax != 0 && !g.scale) str += "</TR>";
		str += "<TR>\n";
		if(g.scale) str += _writeNegScaleGraph(g, g.negMax, 0);
			str += "<TD VALIGN=TOP";
		if(g.bgColor) str += " BGCOLOR=\""+g.bgColor+"\"";
			str += ">";
		for(var j = 0; j < g.rows[0].length; j++) {
			for(var i = 0; i < g.rows.length; i++) {
				if(parseInt(g.vscale*g.rows[i][j]) < 0) {
					str += "<IMG VSPACE=0 HSPACE=0 BORDER=0 ALIGN=TOP SRC=images/"+i+".gif WIDTH="+
					parseInt(g.hscale)+" HEIGHT="+
					parseInt(-1*g.vscale*g.rows[i][j]);
					str += " Title=\"";
					if(g.legends && g.legends[i]) str += g.legends[i]+": ";
						str += (g.rows[i][j]+g.offset);
					if(g.dates) str += ", "+g.dates[j];
						str += "\" >";
				} else
					str += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' ALIGN=TOP BORDER=0 WIDTH="+parseInt(g.hscale)+
						" HEIGHT=5>";
				str += "</TD>\n<TD VALIGN=TOP";
				if(g.bgColor) str += " BGCOLOR=\""+g.bgColor+"\"";
					str += ">";
			}
			str += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' ALIGN=TOP WIDTH=1 BORDER=0 HEIGHT=5>";
		}
		str += "</TD>\n";
		if(g.legends && g.posMax == 0) {
			str += "<TD WIDTH=5 NOWRAP ROWSPAN=2></TD><TD>";
			str += g.writeLegend();
			str += "</TD>\n";
		}
	}
	str += "</TD></TR>\n";
	if(g.xLabel) {
		str += "<TR class='graphcontent'>\n";
		if(g.scale) str += "<TD class='graphcontent' COLSPAN=3></TD>\n";
		if(g.yLabel) str += "<TD class='graphcontent'></TD>\n";
		str += "<TH class='graphcontent' COLSPAN="+g.c+" HEIGHT=15 VALIGN=BOTTOM>";
		str += g.xLabel;
		str += "</TH></TR>\n";
	}
	//this section of code was further up in the table, moved down so that it works 
	//with 48-port density graphs.  the default will be bottom, so if the orientation has
	//not been set, then it will default to 
	str += "</TABLE>\n";
	str += "<TABLE align='left'>\n";
	if(	(g.legends && g.posMax != 0) && 
		( (g.legend_orientation.length == 0) || 
		  (g.legend_orientation.indexOf("bottom") != -1)
		)
	   ) {
		str += "<TR align='left'><TD WIDTH=5 NOWRAP ROWSPAN=3></TD>\n";
		str += "<TD ALIGN=LEFT ROWSPAN=3>";
		str += g.writeLegend();
		str += "</TD></TR>\n";
	}
	str += "</TABLE>\n";
	//doc.write(str); 
	return str;
}

function _setXScaleGraph(s, skip, inc) {
	this.xScale = true;
	this.s = s || 0;
	this.skip = skip || 1;
	this.inc = inc || 1;
}

function _setXScaleValuesGraph() {
	this.xScale = true;
	this.s = 0;
	this.skip = 1;//don't override the skip or increment values that may have been set by _setXScaleGraph
	this.inc = 1;
	this.dates = new Array();
	for(var i = 0; i < arguments.length; i++)
		this.dates[this.dates.length] = arguments[i];
}

function _setCustomXScaleValuesGraph(xscale_units_to_add, value_to_print) {
	this.xScale = true;
	this.s = 0;
	this.skip = 1;
	this.inc = 1;
	this.dates = new Array();
	for(var i = 0; i < xscale_units_to_add.length; i++)
		{
		if((i % value_to_print) == 0) 
		// if((i % 3) == 0) 
		 	this.dates[this.dates.length] = xscale_units_to_add[i];
				else 
			this.dates[this.dates.length] = ""; //this is for cases where there are too many values in the x-axis
												//so we print every 'value_to_print' interval	
		}
}



function _setStartTimeGraph(hour, min, skip, inc) {
	this.xScale = true;
	this.sTime = new Date(0, 0, 0, hour, min);
	this.skip = skip || 1;
	this.inc = inc || 1;
}

function _setAlternatingBarIcon(bar_icon_image) {
	 	if(bar_icon_image)
			{
			this.bar_gif1 = bar_icon_image;
			this.bar_gif2 = bar_icon_image;
			}
			else
			{
			this.bar_gif1 =  "images/bar_lg.gif";
		 	this.bar_gif2 = "images/bar_lg2.gif";//default behavior is solid c	
			}
}




function _setStartDateGraph(month, day, year, skip, inc) {
	this.xScale = true;
	this.sDate = new Date(year, month-1, day);
	this.skip = skip || 1;
	this.inc = inc || skip || 1;
	this.showDate = true;
}

function _setDatesArrayGraph(g) {
	 if(g.dates) return;
  	
	g.dates = new Array();
	for(var i = 0; i < g.rows[0].length; i++) {
		var dateStr = "";
		if(g.sDate) {
			if(g.showDay) {
				eval('switch(g.sDate.getDay()) {'+
					'case 0: dateStr += "Sun"; break;'+
					'case 1: dateStr += "Mon"; break;'+
					'case 2: dateStr += "Tue"; break;'+
					'case 3: dateStr += "Wed"; break;'+
					'case 4: dateStr += "Thu"; break;'+
					'case 5: dateStr += "Fri"; break;'+
					'case 6: dateStr += "Sat"; break;'+
				'}');
				dateStr += " ";
			}
			if(g.longDate && g.showDate) {
				dateStr += g.sDate.getDate()+"-";
				eval('switch(g.sDate.getMonth()) {'+
					'case 0: dateStr += "Jan"; break;'+
					'case 1: dateStr += "Feb"; break;'+
					'case 2: dateStr += "Mar"; break;'+
					'case 3: dateStr += "Apr"; break;'+
					'case 4: dateStr += "May"; break;'+
					'case 5: dateStr += "Jun"; break;'+
					'case 6: dateStr += "Jul"; break;'+
					'case 7: dateStr += "Aug"; break;'+
					'case 8: dateStr += "Sep"; break;'+
					'case 9: dateStr += "Oct"; break;'+
					'case 10: dateStr += "Nov"; break;'+
					'case 11: dateStr += "Dec"; break;'+
				'}');
			} else if(g.showDate) dateStr += (g.sDate.getMonth()+1)+"/"+g.sDate.getDate();
			if(g.showYear && g.showDate) {
				if(g.longDate) dateStr += "-";
				else dateStr += "/";
			}
			if(g.showYear) {
				if(g.longYear) dateStr += g.sDate.getFullYear();
				else dateStr += (g.sDate.getFullYear()%100);
			}
			g.sDate.setDate(g.sDate.getDate()+ g.inc);
		} else if(g.sTime) {
			var hrs = g.sTime.getHours();
			if(!g.armyTime) {
				var pm = false;
				if(hrs == 0) { hrs = 12; }
				else if(hrs >= 12) { if(hrs > 12) hrs -= 12; pm = true; }
			} else 
				if(hrs < 10) hrs = "0" + hrs;
			dateStr = hrs + ":";
			var min = g.sTime.getMinutes();
			if(min < 10) min = "0" + min;
			dateStr += min;
			if(!g.armyTime) { !pm ? dateStr += "am" : dateStr += "pm" ; }
			g.sTime.setMinutes(g.sTime.getMinutes()+ g.inc); 
		} else dateStr = g.s+i*g.inc;
		g.dates[i] = dateStr;
	}
}

function _writeXScaleGraph(g) {
	var st = "";
	if(!g.c) g.c = g.rows[0].length*2-1;
	st += "<TR>\n";
	if(g.scale) st += "<TD COLSPAN=3></TD>\n";	//
	if(g.yLabel) st += "<TD></TD>\n";
	st += "<TD  VALIGN=TOP COLSPAN="+(g.c+1)+">";
	st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src + "' HEIGHT=10 WIDTH=1>";
 
	st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' HEIGHT=1 WIDTH=1>";
 
	var n = g.rows[0].length;
	var mult = g.rows.length;
	if(g.stacked || g.relative) mult = 1;
	 mult = 1.0;   //the multiple function spreads out the mult further
	// comment the for statement to remove the | in x-axis
	//this for loop is for the spacing between the | marks
	for(var i = 0; i < n; i++) {
		st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' HEIGHT=1 WIDTH="+(g.hscale*mult)+">";
		if((i+1) % g.skip)
			{ 
			st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' HEIGHT=10 WIDTH=1>";}
		else
			{
		 st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src + "' HEIGHT=10 WIDTH=1>";
			}
			
	}
	
	st += "</TD></TR><TR>\n";
	if(g.scale) st += "<TD COLSPAN=4></TD>\n";	//
	if(g.yLabel) st += "<TD></TD>\n";
	var cspan = g.rows.length;
	if(g.stacked || g.relative) cspan = 2;
	 
	cspan *= g.skip;
	if(g.sDate || g.sTime) _setDatesArrayGraph(g);
	var t = 0;
  
	//this is where actually specifying the x-axis units	
	for(var i = 0; i < Math.floor(g.rows[0].length/g.skip); i++) {
		st += "<TD align=center VALIGN=TOP";
		st += "WIDTH='"+(g.hscale*mult) + "'";
		st += " COLSPAN="+cspan; t += cspan;
		st += "><FONT class='graphcontent'>";
		st += g.dates[i*g.skip] || ""; //want the values to print inside the lined bars 
		
		st += "</FONT></TD>\n";
	}
	var len = g.rows[0].length;
	if(!g.stacked) len *= g.rows.length;
	if(i < Math.ceil(g.rows[0].length/g.skip)) {
		st += "<TD align=center VALIGN=TOP";
		//st += " COLSPAN="+(len-t);
		st += "WIDTH='"+(g.hscale*mult) + "'";
	
		st += "><FONT  class='graphcontent'>";
		st += g.dates[i*g.skip];
		st += "</FONT></TD>\n";
	}
	st += "</TR>\n"; 
	return st;
}

function _writeNegScaleGraph(g, min, max) {
	var h = Math.ceil(g.height/(g.posMax-g.negMax)*g.scale);
	var p = -1*g.negMax/(g.posMax-g.negMax);
	var n = Math.floor(g.height*p/h);
	var st = "";
	if(h < 15) {
		if(!g.posMax)
			//alert("Warning! Scale is too small! Please make\nthe scale larger or make the graph taller.");
		st += "<TD></TD><TD></TD><TD></TD>\n"
		return st;
	}
	st += "<TD VALIGN=TOP ALIGN=RIGHT>";
	var H = h - 3;
	for(var i = 0; i < n; i++) {
		st += "<FONT FACE=Arial,Helvetica SIZE=-3>"+(g.scale*-1*(i+1)+g.offset)+"</FONT>";
		st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src + "' WIDTH=1 HEIGHT="+H+"><BR>\n";
	}
	st += "</TD>\n";
	st += "<TD VALIGN=TOP>";
	for(var i = 0; i < n; i++) {
		st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH=1 HEIGHT="+(h-1)+"><BR>\n";
		st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src+ "' WIDTH=6 HEIGHT=1><BR>\n";
	}
	st += "</TD>\n";
	st += "<TD VALIGN=TOP>";
	st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src + "' WIDTH=1 HEIGHT="+(g.height*p)+">";
	st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH=1 HEIGHT="+(g.height*p)+">";
	st += "</TD>\n"
	return st;
}

function _writeScaleGraph(g, min, max) {
	var h;
	var p = g.posMax/(g.posMax-g.negMax);
	h = Math.ceil(g.height/(g.posMax-g.negMax)*g.scale);
	var n = Math.floor(g.height*p/h);
	var st = "";
	if(h < 15) {
		//alert("Warning! Scale is too small! Please make\nthe scale larger or make the graph taller.");
		st += "<TD ROWSPAN=2></TD><TD ROWSPAN=2></TD><TD></TD>\n"
		return st;
	}
	st += "<TD VALIGN=BOTTOM ROWSPAN=2 ALIGN=RIGHT>";
	var H = h - 3;
	for(var i = 0; i <= n; i++) { // modified this line
		st += "<FONT class='graphcontent'>";
		st += g.scale*(n)-g.scale*i+g.offset; //
		if(g.relative) st += "%";
		st += "</FONT>";
		st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH=1 HEIGHT="+H+"><BR>\n";
	}
	st += "</TD>\n";
	st += "<TD VALIGN=BOTTOM ROWSPAN=2>";
	for(var i = 0; i < n; i++) {
		st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src+ "' WIDTH=6 HEIGHT=1><BR>\n"; 
		st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src+ "' WIDTH=1 HEIGHT="+(h-1)+"><BR>\n";
	}
	st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src+ "' WIDTH=6 HEIGHT=1><BR>\n";
	st += "</TD>\n";
	
	st += "<TD VALIGN=BOTTOM ROWSPAN=2>";
	var maxValue = g.posMax;
	var totalValue = 0;
	var converter = g.height / 100;
	var thresholdWidth = g.rows[0].length * (g.hscale + 1) + 10;
	for(var i = 0; i < g.thresholdValues.length; i++) {
		if ((((maxValue - g.thresholdValues[i]) * converter) - 1) > 0) 
			st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src +"' WIDTH=1 HEIGHT="+ (((maxValue - g.thresholdValues[i]) * converter) - 1) +"><BR>\n";
		totalValue += (maxValue - g.thresholdValues[i] - 1);
		maxValue = g.thresholdValues[i];
		st += "<div id='LayerThreshold" + g.name + i + "' style='position:absolute; width:" + thresholdWidth + "; height:1px; z-index:1'>";
		st += "<table width='100%' height='1'  cellpadding='0' cellspacing='0'>";
		st += "<tr>";
		st += "<td bgcolor='" + g.thresholdColors[i] + "' height='1'></td>";
		st += "</tr>";
		st += "</table>";
		st += "</div>";
		st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src + "' WIDTH=1 HEIGHT=1><BR>\n";
		totalValue += 1;
	}
	if (maxValue > 0) 
		if (document.all) 
			st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src+ "' WIDTH=1 HEIGHT="+ ((g.posMax - totalValue) * converter) +"><BR>\n";
		else 
			st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH=1 HEIGHT="+ ((g.posMax - totalValue) * converter + 1) +"><BR>\n";
	st += "</TD>\n";
	
	st += "<TD VALIGN=BOTTOM>";
	st += "<IMG SRC='" + g.graph_cache_images.img['BLACK'].src + "' WIDTH=1 HEIGHT="+(g.height*p)+">";
	st += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH=1 HEIGHT="+(g.height*p)+">";
	st += "</TD>\n"
	return st;
}

function _buildStackGraph(g) {
	//if(!g.c) g.c = g.rows[0].length*2-1;
	g.setGraphImages();
	if(!g.c) g.c = g.rows[0].length*2-2;
	var str = "";
	str += "<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>\n";
	if(g.title) {
		str += "<TR>\n";
		if(g.scale) str += "<TD class='graphcontent' COLSPAN=2></TD>\n";
		//if(g.scale) str += "<TD class='graphcontent' COLSPAN=3></TD>\n";
		
		if(g.yLabel) str += "<TD class='graphcontent'></TD>\n";
		str += "<TH VALIGN=TOP HEIGHT=30 COLSPAN="+(g.c)+">"; 
		str += g.title;
		str += "</FONT></TH></TR>\n";
	}
	if(g.yLabel) {
		g.yLabel = g.yLabel.split("");
		g.yLabel = g.yLabel.join("<BR>\n");
		str += "<TR>\n";
		var rspan = 2; if(g.negMax && g.posMax) rspan++;
		str += "<TH ROWSPAN="+rspan+" ALIGN=CENTER NOWRAP WIDTH=15>";
		str += "<FONT FACE='Arial,Helvetica' SIZE=-1>"+g.yLabel+"</FONT></TH>\n";
	}
	if(g.posMax > 0) {
		if(!g.yLabel) str += "<TR>\n";
		if(g.scale) str += _writeScaleGraph(g, 0, g.posMax);
		for(var j = 0; j < g.rows[0].length; j++) {
			str += "<TD class='graphcontent' VALIGN=BOTTOM";
			if(g.bgColor) str += " BGCOLOR=\""+g.bgColor+"\"";
			str += ">";
			var k = 0, y = 0, drawn = false;
			for(var i = 1; i < g.rows.length; i++)
				if(parseInt(g.vscale*g.rows[i][j]) > 0)
					k += parseInt(g.vscale*g.rows[i][j]);
			if(g.rows.length > 0 && g.relative && (g.height > k)) {
				str += "<IMG SRC=images/0.gif WIDTH="+parseInt(g.hscale)+" HEIGHT="+(g.height-k)+" ";
				str += "Title=\"";
				if(g.legends && g.legends[0]) str += g.legends[0]+": ";
				str += Math.round((g.height-k)/g.vscale*10)/10+"%";
				if(g.dates) str += ", "+g.dates[j];
				str += "\" ><BR>\n";
				y++;
				drawn = true;
			}
			for(var i = y; i < g.rows.length; i++) {
				if(parseInt(g.vscale*g.rows[i][j]) > 0) {
					str += "<IMG SRC=images/"+i+".gif WIDTH="+parseInt(g.hscale)+" HEIGHT="+
					parseInt(g.vscale*g.rows[i][j])+" ";
					str += "Title=\"";
					if(g.legends && g.legends[i]) str += g.legends[i]+": ";
					str += g.rows[i][j];
					if(g.relative) str += "%";
					if(g.dates) str += ", "+g.dates[j];
					str += "\" ><BR>\n";
					drawn = true;
				}
			}
			if(!drawn) str += "<IMG SRC='"+ g.graph_cache_images.img['CLEAR'].src + "' WIDTH="+parseInt(g.hscale)+" HEIGHT=1>";
			str += "</TD>\n";
			str += "<TD";
			if(g.bgColor) str += " BGCOLOR=\""+g.bgColor+"\"";
			str += "><IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH=1 HEIGHT=5></TD>\n";
		}
	}
	if(g.legends && g.posMax != 0) {
		str += "<TD WIDTH=5 NOWRAP ROWSPAN=3></TD>\n<TD ROWSPAN=3>";
		str += g.writeLegend();
		str += "</TD>\n";
	}
	if(g.scale || g.xScale) {
		str += "</TR><TR>\n<TD BGCOLOR=#000000 COLSPAN="+(g.rows[0].length*2);
		str += "><IMG SRC='" + g.graph_cache_images.img['BLACK'].src + "' HEIGHT=1 WIDTH=";
		str += parseInt(g.rows[0].length*g.hscale)+" ></TD></TR>\n";
	}
	if(g.xScale && !g.negMax) {
		str += _writeXScaleGraph(g);
	}
	if(g.negMax < 0) {
		if(g.posMax != 0) str += "</TR>\n";
		str += "<TR>\n";
		if(g.scale) str += _writeNegScaleGraph(g, g.negMax, 0);
		for(var j = 0; j < g.rows[0].length; j++) {
			str += "<TD VALIGN=TOP";
			if(g.bgColor) str += " BGCOLOR=\""+g.bgColor+"\"";
			str += ">";
			var drawn = false;
			for(var i = 0; i < g.rows.length; i++) {
				if(parseInt(g.vscale*g.rows[i][j]) < 0) {
					str += "<IMG VSPACE=0 HSPACE=0 BORDER=0 ALIGN=TOP SRC=images/"+i+".gif WIDTH="+
					parseInt(g.hscale)+" HEIGHT="+
					parseInt(-1*g.vscale*g.rows[i][j])+" ";
					str += "Title=\"";
					if(g.legends && g.legends[i]) str += g.legends[i]+": ";
					str += g.rows[i][j];
					if(g.relative) str += "%";
					if(g.dates) str += ", "+g.dates[j];
					str += "\" ><BR>\n"; 
					drawn = true;
				}
			}
			if(!drawn) str += "<IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH="+parseInt(g.hscale)+" HEIGHT=1>";
			str += "</TD>\n";
			str += "<TD";
			if(g.bgColor) str += " BGCOLOR=\""+g.bgColor+"\"";
			str += "><IMG SRC='" + g.graph_cache_images.img['CLEAR'].src + "' WIDTH=1 HEIGHT=5></TD>";
		}
		if(g.legends && g.posMax == 0) {
			str += "<TD WIDTH=5 NOWRAP ROWSPAN=2></TD>\n<TD>";
			str += g.writeLegend();
			str += "</TD>\n";
		}
	}
	str += "</TD></TR>\n";
	if(g.xLabel) {
		str += "<TR class='graphcontent' >\n";
		if(g.scale) str += "<TD class='graphcontent' COLSPAN=3></TD>\n";
		if(g.yLabel) str += "<TD class='graphconten'></TD>\n";
		str += "<TH class='graphcontent  COLSPAN="+g.c+" HEIGHT=15 VALIGN=BOTTOM>";
		str += "<font class='graphcontent'>" + g.xLabel + "</font>";
		str += "</TH></TR>\n";
	}
	str += "</TABLE>\n";
	return str;
	//doc.write(str); 
}

function _adjustOffsetGraph(g) {
	if(g.relative) return;
	for(var i = 0; i < g.rows.length; i++)
		for(var j = 0; j < g.rows[i].length; j++)
			g.rows[i][j] -= g.offset;
}

function _buildGraph(d) {
	str = ""; //
	//this.setGraphImages();
	doc = d || document;
	if(!this.rows) return;
	if(this.rows.length == 0) {
		str += "<TABLE><TR><TD><TT>[empty graph]</TT></TD></TR></TABLE>\n";
		//doc.write(str);
		return str; //
	}
	_adjustOffsetGraph(this);
	if(this.xScale){ _setDatesArrayGraph(this);  }
	if(this.relative) {
		_relRescaleGraph(this);
		str += _buildStackGraph(this, doc); //
		return str; //
	}
	if(this.stacked) {
		_stackRescaleGraph(this);
		str += _buildStackGraph(this, doc); //
		return str; //
	}
	_rescaleGraph(this);
	str += _buildRegGraph(this, doc); //
	return str;
}

function _setThreshold(thresholdValues, thresholdColors) {
	for(var i = 0; i < thresholdValues.length - 1; i++) {
		var maxValue = thresholdValues[i];
		var maxIndex = i;
		for(var j = i + 1; j < thresholdValues.length; j++) {
			if (thresholdValues[j] > maxValue) {
				maxValue = thresholdValues[j];
				maxIndex = j;
			}
		}
		var temp = thresholdValues[i];
		thresholdValues[i] = maxValue;
		thresholdValues[maxIndex] = temp;
		temp = thresholdColors[i];
		thresholdColors[i] = thresholdColors[maxIndex];
		thresholdColors[maxIndex] = temp;
	}
	this.thresholdValues = thresholdValues;
	this.thresholdColors = thresholdColors;
}


/*
 *-------------------------------------------------------------------
 * Second graph object used to generate plots for timer wheel outputs
 *-------------------------------------------------------------------
 */
function lineGraph(_id) {
	this.id = _id;
	this.spacing = 50;
	this.scale = 1;
	this.baseHeight = 30;
	this.lineColor = "#000000"; //black
	this.secLineColor = "#808080"; //gray
	this.pointColor = "none";
	this.lineWidth = 1;
	this.xlineWidth = 1;
	this.yMax = 300;
	this.yScale = 20;
	this.yAxisBorder = 1;
	this.skipX = 1;
	this.xNumbers = true;
	this.dropLines = true;
	this.connectLines = false;
	this.yText = "%";
	this.xText = "Time Slots";
	this.showMaxValue = false; // flag to indicate if peek value should be marked with horizontal line
	this.coordLength = 60; // max number of bars to be displayed in the graph
	this.restartXAfter = 0;
	
	this.coordinates = new Array();
	this.secCoordinates = new Array();
	this.draw = drawLineGraph;
	
	this.generateYAxisText = generateYAxisText;
	this.generateXAxisText = generateXAxisText;
	this.generateCellText = generateCellText;
}

function drawLineGraph() {
	var maxValue = 2;
	var maxValueStyle = "";
	if(this.showMaxValue) {
		var temp = this.coordinates.join(",");
		temp = temp.split(",");
		for(var i=0; i<temp.length; i++) {
			temp[i] = parseInt(temp[i])
		}
		temp = temp.sort(function compareNumbers(a, b) { return a - b });
		
		if(temp[temp.length-1] > 0) {
			maxValue = temp[temp.length-1];
			maxValueStyle = "border-top:1px solid black;";
		}
	}
	
	if(this.coordinates.length < this.coordLength) {
		var addLengthStr = "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
		var addLengthArr = addLengthStr.split(" ");
		this.coordinates = this.coordinates.concat(addLengthArr.slice(0, this.coordLength - this.coordinates.length));
		if(this.secCoordinates.length > 0) {
			var addLengthArr2 = addLengthStr.split(" ");
			this.secCoordinates = this.secCoordinates.concat(addLengthArr2.slice(0, this.coordLength - this.secCoordinates.length));
		}
	}
	
	var graphStr = "";
	var graphRows = (this.yMax/this.yScale) + 1;
	var xAxisScale = "";
	var xAxisNumbers = "";
	var xAxisCounter = 0;
	
	graphStr += "<table cellpadding='0' cellspacing='0' height='100%' width2='100%' border='0'>";
	graphStr += "<tr>";
	
	graphStr += "<td align='center' valign='middle' style='width:10px;FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE:10px;'>";
	graphStr += this.yText;
	graphStr += "</td>";
	
	//graph cell
	graphStr += "<td valign='bottom'>";
		//inner table which contains the graph
		graphStr += "<table id='" + this.id + "_Graph_Table' cellpadding='0' cellspacing='0' height='100%' border='0'>";
		graphStr += "<tr>";
		
		//yaxis
		graphStr += "<td style='padding:0px;' valign='bottom'>";
		graphStr +=	this.generateYAxisText();
		graphStr += "</td>";
		
		if(this.secCoordinates.length > 0) {
			this.xlineWidth = this.lineWidth * 2;
		}
		else {
			this.xlineWidth = this.lineWidth;
		}
		
		for(var i=0; i<this.coordinates.length; i++) {		
			if(i==0) {
				graphStr += "<td style='width:"+this.spacing+"px;border-left:1px solid black;border-bottom:1px solid black;' valign='bottom' rowspan2='" + graphRows + "'><div style='height:"+maxValue+"px;width:"+this.spacing+"px;"+maxValueStyle+"'><!----></div></td>";
			}
			else {
				// spacing column
				graphStr += "<td style='width:2px;border-bottom:1px solid black;' valign='bottom'><div style='width:"+this.spacing+"px;height:"+maxValue+"px;"+maxValueStyle+"'><!----></div></td>";
			}
			graphStr += "<td style='width:1px;border-bottom:1px solid black;' valign='bottom'>";
				graphStr += "<table height='100%' width='100%' cellspacing='0' cellpadding='0'>";
				graphStr += "<tr>";
				graphStr += "<td valign='bottom' title=' " + this.coordinates[i] + "% '>";
				graphStr += "<div style='width:" + this.lineWidth + "px;height:" + this.coordinates[i]/this.scale + "px;background:" + this.lineColor + ";'><!----></div>";
				//graphStr += this.generateCellText(this.lineWidth, this.coordinates[i]/this.scale, this.pointColor, ((this.dropLines) ? this.lineColor : ""), this.connectLines);
				graphStr += "</td>";
				if(this.secCoordinates.length > 0) {
					graphStr += "<td valign='bottom' title=' " + this.secCoordinates[i] + "% '>";
					graphStr += "<div style='width:" + this.lineWidth + "px;height:" + this.secCoordinates[i]/this.scale + "px;background:" + this.secLineColor + ";'><!----></div>";
					//graphStr += this.generateCellText(this.lineWidth, this.secCoordinates[i]/this.scale, this.pointColor, ((this.dropLines) ? this.secLineColor : ""), this.connectLines);
					graphStr += "</td>";
				}
				graphStr += "</tr>";
				graphStr += "</table>";
			graphStr += "</td>";
			
			
			//this block generates x axis scale lines
			{
				var lineColor = "none";
				if((i+1) % (this.skipX) == 0) {
					lineColor = "black";
				}
				// to compensate for spacing column
				if(i == 0) {
					xAxisScale += "<td style='width:" + this.spacing + "px;border-left:1px solid black;' valign='bottom'>";
					xAxisScale += "<div style='width:" + this.spacing + "px;height:10px;'><!-- --></div>";
					xAxisScale += "</td>";
				}
				else {
					xAxisScale += "<td style='width:" + this.spacing + "px;' valign='bottom'><!-- --></td>";
				}
					
				xAxisScale += "<td style='height:10px;width:" + this.xlineWidth + "px;padding:0px;' align='center'>";
				xAxisScale += "<div style='background:" + lineColor + ";width:1px;height:10px;'><!-- --></div>";
				xAxisScale += "</td>";
			}
			//this block generates x axis scale numbers
			{
				if(i % this.skipX == 0) {
					var scaleText = 0;
					if(xAxisCounter - 1 + this.skipX == this.restartXAfter) {
						xAxisCounter = 0;
					}
					//else
					scaleText = xAxisCounter + this.skipX;
					// to compensate for spacing column
					if(i == 0) {
						xAxisNumbers += "<td style='width:" + this.spacing + "px;border-left2:1px solid black;FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE: 10px;' valign='bottom'>";
						xAxisNumbers += "<div style='width:" + this.spacing + "px;height:10px;'><!-- --></div>";
						xAxisNumbers += "</td>";
					}
					
					xAxisNumbers += "<td style='height:10px;width:" + ((this.xlineWidth*this.skipX) + (this.spacing*this.skipX)) + "px;FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE: 10px;padding:0px;' colspan='" + (this.skipX*2) + "' align='right'>";
					xAxisNumbers += "<div style='width:100%' align='right'>";
						xAxisNumbers += "<table cellspacing='0' cellpadding='0' width='100%'>";
						xAxisNumbers += "<tr>";
						var scaleTextLength = (""+scaleText).length;
						var cellWidth1 = (this.xlineWidth * (this.skipX-1)) + (this.spacing * (this.skipX-1));
						// 5 is used because the width occupied a single digit is approximately 5px
						var cellWidth2 = scaleTextLength * 5;
						var cellWidth3 = (this.xlineWidth * this.skipX) + (this.spacing * this.skipX) - (cellWidth1 + cellWidth2);
						xAxisNumbers += "<td style='height:10px;width:" + cellWidth1 + "px;FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE: 10px;padding:0px;' align='right'>";
						xAxisNumbers += "<div style='width:100%;'><!----></div>";
						xAxisNumbers += "</td>";
						xAxisNumbers += "<td style='height:10px;width:" + cellWidth2 + "px;FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE: 10px;padding:0px;' align='right'>";
						xAxisNumbers += "<div style='width:100%;'>" + scaleText + "</div>";
						xAxisNumbers += "</td>";
						if(cellWidth3 > 0) {
							xAxisNumbers += "<td style='height:10px;width:" + cellWidth3 + "px;FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE: 10px;padding:0px;' align='right'>";
							xAxisNumbers += "<div style='width:100%;'><!----></div>";
							xAxisNumbers += "</td>";
						}
						xAxisNumbers += "</tr>";
						xAxisNumbers += "</table>";
					xAxisNumbers += "</div>";
					xAxisNumbers += "</td>";
				}
				xAxisCounter++;
			}
		}
		
		//additional cell for the last number in x axis
		graphStr += "<td style='width:2px;border-bottom:1px solid black;' valign='bottom'><div style='height:"+maxValue+"px;width:"+this.spacing+"px;"+maxValueStyle+"'><!----></div></td>";
		
		
		
		
		graphStr += "</tr>";
		
		<!--************end of graph****************-->
		
		/*if(this.secCoordinates.length > 0) {
			this.xlineWidth = this.lineWidth * 2;
		}
		else {
			this.xlineWidth = this.lineWidth;
		}*/
		
		<!--************start of x axis numbers****************-->
		graphStr += "<tr>";
		//cell to display zero common to both axes
		graphStr += "<td rowspan='2' valign='top' align='right' style='FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE:10px;'>0&nbsp;</td>";
		
		//x axis vertical lines
		graphStr += xAxisScale;
		
		//additional cell for the last number in x axis
		graphStr += "<td style='width:" + this.spacing + "px;' valign='bottom'><!-- --></td>";
		graphStr += "</tr>";
		
		graphStr += "<tr>";
		graphStr += xAxisNumbers;
		
		//additional cell for the last number in x axis
		graphStr += "<td style='width:" + this.spacing + "px;' valign='bottom'><!-- --></td>";
		graphStr += "</tr>";
	
		graphStr += "</table>"; //end of graph table
		
	graphStr += "</td>";
	graphStr += "</tr>";
	
	graphStr += "<tr>";
	graphStr += "<td align='center' valign='middle' style='FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE:10px;'></td>";
	graphStr += "<td align='center' valign='middle' style='FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE:10px;'>";
	graphStr += this.xText;
	graphStr += "</td>";
	graphStr += "</tr>";
	
	graphStr += "</table>";
	return graphStr;
}

function generateCellText(_width, _height, _color, _bgColor, _border) {
	var cellText = "";
	cellText += "<div style='width:" + _width + "px;height:" + _height + "px;";
	if(_border) {
		cellText += "border-top:1px solid " + _color + ";";
	}
	cellText += "background:" + _bgColor + ";'><!----></div>";
	
	return cellText;
}

function generateYAxisText() {
	var str = "";
	str += "<table cellpadding='0' cellspacing='0' height='100px' border='0' style='border:none'>";
		for(var i=0; i<5; i++) {
			str += "<tr>";
			str += "<td style='height:20px;FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE:10px;padding:0px;' align='right'>" + ((100) - (i*20)) + "&nbsp;</td>";
			str += "<td style='height:20px;padding:0px;' align='center'>";
			str += "<div style='height:1px;width:7px;background:black;'><!----></div>";
			str += "</td>";
			str += "</tr>";
		}
		str += "<tr>";
		str += "<td style='height:10px;FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif;FONT-SIZE:10px;padding:0px;' align='right'><!----></td>";
		str += "<td style='height:10px;padding:0px;border-bottom:1px solid black;' align='center'>";
		str += "<div style='height:1px;width:7px;'><!----></div>";
		str += "</tr>";
	str += "</table>";
	
	return str;
}


function generateXAxisText() {

}