// ====================================================================================================
// Description:
//	Library for creating graphs.	*** UNDER CONSTRUCTION ***
//
// Author:
//	Henk Reints
//	http://henk-reints.nl
//
// Version history:			Date:		Version comment:
//	V00.00 (initial development)	Aug 2000	Original version
//
//	the border=0 hspace=0 vspace=0 and the extra table within the actual bars
//	are only needed with Netscape, so make that dynamic!
// ====================================================================================================

function nameOf (f)			// returns name of function specified as argument
{					// (w/o object prefix, e.g. nameOf(Math.floor) = 'floor')
	var x = f.toString()
	x = (x.substr(0,x.indexOf('('))+' ').replace(/\s+/g,' ')	// NS adds a leading space, IE doesn't
	return x.substring(x.indexOf('function')+9,x.length-1)
}

// ====================================================================================================

function fmtNum (x, n)
{
	var t = '' + Math.round (eval ('1e' + n) * Math.abs (x) )
	while (t.length <= n) {t = '0' + t}
	return (x < 0 ? '-' : '') + (n == 0 ? t : t.substr(0,t.length - n) + '.' + t.substr(t.length - n) )
}

// ====================================================================================================

function simpleBarGraph
		(f		// any function (without parenthesis) that accepts 1 argument and returns a numeric value
		,x0		// the lowest x-value
		,x1		// the highest x-value
		,dx		// if (dx > 0) then dx = increment value of x, if (dx < 0) then -dx = no. of bars in graph
		,scale		// the scale factor, f(x)*scale will become pixels
		,ndigitsX	// no. of digits behind dec.point, -1 = automatic based on x-increments
		,ndigitsY	// no. of digits behind dec.point, -1 = automatic based on scale
		,orientation	// orientation of the X-axis, "V" = vertical, anything else = horizontal
		,barwidth	// the widht of the bars to be drawn in the graph
		,spacing	// the distance between bars in the graph
		,bgcolor	// color of the graph outside the f(x) values
		,fgcolor	// color of the bars for the f(x) values
		,options	// HTML options for the outermost <table> tag
		,font		// options for the <font> tag of title displayed above the graph; '<notitle>' = suppress title
		,txtbgcolor	// background color of title
		,txtattr1	// user defined HTML tags for extra text attributes for title
		,txtattr0	// the corresponding closing tags in correct order
		)
{
	var m, n, t, u, v, w, x, y, z = []

	var ns = (navigator.appName == 'Netscape' ? true : false)
	var tbl = '<table' + (ns ? ' border=0' : '') + ' cellpadding=0 cellspacing='
//	var tbl = '<table border cellpadding=0 cellspacing='					// for debugging

	var fn = nameOf (f)

	var graphtitle

	var y0 = 0	// becomes minimum f(x) value but not > 0
	var y1 = 0	// becomes maximum f(x) value but not < 0

	var bw = (barwidth < 1 ? 1 : barwidth)
	var sp = (spacing  < 0 ? 0 : spacing )

	var bgc = (bgcolor    == '' ? document.bgColor : bgcolor)
	var fgc = (fgcolor    == '' ? document.fgColor : fgcolor)
	var txc = (txtbgcolor == '' ? document.bgColor : txtbgcolor)

	var ft1 = (font == '' ? '' : '<font ' + font + '>')
	var ft0 = (font == '' ? '' : '</font>')

var axw = 2		// width (thickness) of axis
var axr = 3		// axis marker length in units of axis thickness
var axc = 'black'	// color of axis

	var oldwinstat = window.status
	window.status = 'Drawing graph of ' + fn

	u = dx							// x increment
	v = x1							// last x value
	if (u == 0) {u = -10}	// arbitrary default of 10 bars (could do something sophisticated based on window size etc.)
	if (u < 0)
	{							// -dx = no. of bars
		v = -u - 1					// no. of steps
		u = Math.abs (x1 - x0); if (v > 0) {u /= v}	// x increment
		v = x0 + (x0 > x1 ? -u : u) * v			// last x value
	}

	n = ndigitsY; if (n < 0) {n = 0; x = Math.abs (scale); while (x > 1) {n++; x /= 10} }	// n = no. of dec.digits in Y
	m = ndigitsX; if (m < 0) {m = 0; x = 1/u;              while (x > 1) {m++; x /= 10} }	// m = no. of dec.digits in X

	if (x0 > x1) u = -u

	for (x = x0; (u < 0 ? x >= v : x <= v); x += u)		// fill array with [x, f(x), y] triplets (y = rounded and scaled f(x))
	{
		y = f(x)
		if (isNaN (y) ) {y = 0}
		if (isFinite (y) )
		{	if (y < y0) {y0 = y}
			if (y > y1) {y1 = y}
		}
		z[z.length] = [x, y, Math.round (y * scale) ]
	}
	for (var i = 0; i < z.length; i++)
	{	if (!isFinite (z[i][1]) )
		{	z[i][1] = (z[i][1] < 0 ? y0 : y1)
			z[i][2] = Math.round (z[i][1] * scale)
		}
	}

	t = ' (' + fmtNum (x0, m) + ' .. ' + fmtNum (x1, m) + ')'

	if (scale < 0) {u  = y0; y0 = y1; y1 = u}

	window.status += t 
	graphtitle = fn + t + ' = ' + fmtNum (y0, n) + ' .. ' + fmtNum (y1, n)

	y0 = Math.round (y0 * scale)
	y1 = Math.round (y1 * scale)

	document.writeln ('<table ',options,'>')

	if (font.toLowerCase() != '<notitle>')
	{
		document.writeln (' <tr><td align=center bgcolor=',txc,'>',ft1,txtattr1,graphtitle,txtattr0,ft0,'</td></tr>')
	}
	document.writeln (' <tr><td align=center bgcolor=',bgc,'>')

	if (orientation == 'V')
	{
		document.writeln ('  ',tbl,sp,'>')
		for (var i = 0; i < z.length; i++)
		{
			y = z[i][2]
			u = (y < 0 ? y-y0 : -y0)
			v = (y < 0 ? 1-y  : 1+y)

		if(ns)	{w = ''}
		else	{w = ' title="' + fn + '(' + fmtNum (z[i][0], m) + ') = ' + fmtNum (z[i][1], n) + '"'}

			document.write	('   <tr><td align=left>',tbl,'0><tr>')
		if(u>0){document.write	('<td',  ' height=',bw,' width=',u,' bgcolor=',bgc,'></td>')}

			document.write	('<td',w,' height=',bw,' width=',v,' bgcolor=',fgc,'>')
		if(ns) {document.write	(tbl,'0 height=',bw,' width=',v,' bgcolor=',fgc,'><tr><td></td></tr></table>')}
			document.write	('</td>')

			document.writeln('</tr></table></td></tr>')
		}
		document.writeln ('  </table>')
	}
	else
	{
		document.writeln ('  ',tbl,sp,'><tr>')
		for (var i = 0; i < z.length; i++)
		{
			y = z[i][2]
			u = (y > 0 ? y1-y : y1 )
			v = (y < 0 ? 1-y  : 1+y)

		if(ns)	{w = ''}
		else	{w = ' title="' + fn + '(' + fmtNum (z[i][0], m) + ') = ' + fmtNum (z[i][1], n) + '"'}

			document.write	('   <td valign=top width=',bw,'>',tbl,'0>')
		if(u>0){document.write	('<tr><td',  ' height=',u,' width=',bw,' bgcolor=',bgc,'></td></tr>')}

			document.write	('<tr><td',w,' height=',v,' width=',bw,' bgcolor=',fgc,'>')
		if(ns) {document.write	(tbl,'0 height=',v,' width=',bw,' bgcolor=',fgc,'><tr><td></td></tr></table>')}
			document.write	('</td></tr>')

			document.writeln('</table></td>')
		}
		document.writeln ('  </tr></table>')

		w = z.length * (bw + sp) - sp
		u = w - 3 * axw
		v = Math.floor (u / 2)
		u = u - v
		x = Math.floor (v / 2); v -= x
		y = Math.floor (u / 2); u -= y

		document.writeln ('  ',tbl,'0 width=',w,'>')
		if (axw > sp) {document.writeln ('   <tr><td colspan=7 width=',w,' height=',axw-sp,' bgcolor=',bgc,'></td></tr>') }
		document.writeln ('   <tr>')
		document.writeln ('    <td width=',axw,' height=',axr*axw,' bgcolor=',axc,' rowspan=2></td>')
		document.writeln ('    <td width=',x  ,' height=',    axw,' bgcolor=',axc,'></td>')
		document.writeln ('    <td width=',v  ,' height=',    axw,' bgcolor=',axc,'></td>')
		document.writeln ('    <td width=',axw,' height=',axr*axw,' bgcolor=',axc,' rowspan=2></td>')
		document.writeln ('    <td width=',y  ,' height=',    axw,' bgcolor=',axc,'></td>')
		document.writeln ('    <td width=',u  ,' height=',    axw,' bgcolor=',axc,'></td>')
		document.writeln ('    <td width=',axw,' height=',axr*axw,' bgcolor=',axc,' rowspan=2></td>')
		document.writeln ('   </tr>')
		document.writeln ('   <tr>')
		document.writeln ('    <td width=',x  ,' height=',(axr-1)*axw,' bgcolor=',bgc,'></td>')
		document.writeln ('    <td width=',v  ,' height=',(axr-1)*axw,' bgcolor=',bgc,'></td>')
		document.writeln ('    <td width=',y  ,' height=',(axr-1)*axw,' bgcolor=',bgc,'></td>')
		document.writeln ('    <td width=',u  ,' height=',(axr-1)*axw,' bgcolor=',bgc,'></td>')
		document.writeln ('   </tr>')
		document.writeln ('   <tr>')
		u = z[0][0]
		v = z[z.length-1][0]
		w = u + 0.5 * (v - u)
		document.writeln ('    <td align=left   bgcolor=',bgc,' colspan=2>',fmtNum(u,m),'</td>')
		document.writeln ('    <td align=center bgcolor=',bgc,' colspan=3>',fmtNum(w,m),'</td>')
		document.writeln ('    <td align=right  bgcolor=',bgc,' colspan=2>',fmtNum(v,m),'</td>')
		document.writeln ('   </tr>')
		document.writeln ('  </table>')
	}

	document.writeln (' </td></tr>')
	document.writeln ('</table>')

	window.status = oldwinstat
}

// ====================================================================================================
// end of file; Copyright (c) 2000 Henk Reints

