<!--
/**
2009-06-11-14-35 start
To use this file jsgraph2.js, in your web
page add next code

<script type="text/javascript"
 src=http://freeman2.com/jsgraph2.js>
</script>

(and add VML declaration code below)

then in your web page you can call the
following functions

function XYLine()
function Arrow()
function Label()
function XYGraph()
XYGraph.prototype.Plot = function (XYLine)
XYGraph.prototype.DeleteLast = function ()
XYGraph.prototype.Findedge = function (x1,x2,y1,y2,xmax,xmin,ymax,ymin)
XYGraph.prototype.VMLpointshape = function (shapename)
XYGraph.prototype.Drawarrow = function (arrowdef)
XYGraph.prototype.Drawlabel = function (labeldef)
//above is written by J. Gebelein, Last Updated 2006.01.11
//below is Ab hier (17. 3. 2000) von Ken's Script &#252;bernommen:
function factorial(n)
function loggamma(x)
function gamma(x)
//below is written by LiuHH (freeman2.com)
function stepf(t0,bgn0) //step function
function open0lxr(xx) //open/close document
function closelxr(yy) //
function openTable(drawID,table01)
//openTable() work with function XYGraph() 
//openTable() allow use XYGraph() many times
2009-06-11-14-47 stop

//9506241341 change 'bold' to 'regular'
//9506241347 change 'bold' to 'regular'
//9506241355 change 'Arial' to 'Dotum' character thinner

2009-06-11-14-52 start
this file
http://freeman2.com/jsgraph2.js
is part of
http://freeman2.com/graph09e.htm

Now any file can include jsgraph2.js to add
graph function. But need to pay attention to
next two points.

First:  only MSIE 5.0 and later support VML code
        VML = Vector Markup Language
Second: graph page must include next three lines
        on top of page in <head> and </head>
[[
<style type="text/css">
	v\:* { behavior: url(#default#VML); }
</style>
]]

otherwise all graph elements dis-integrate!!

You can find example code at next URL
http://www.structura.info/XYGraph/Examples.htm
or Freeman's web page
http://freeman2.com/graph03e.htm
and
http://freeman2.com/graph09e.htm

graph03e.htm use older version of openTable()
graph09e.htm use newer version of openTable()
structure slight different and not compatible.

you can learn from
Examples.htm non-openTable() drawing code
graph03e.htm non-openTable() drawing code
graph09e.htm use-openTable() drawing code
in other words, ignore
graph03e.htm use-openTable() drawing code

non-openTable() drawing code is powerful.
It allow you draw many lines, allow you put
many arrow many labels. But you must write
program to draw curves.

use-openTable() drawing code allow at most
five lines, at most one arrow, at most one
label. You do not need to write program.
use-openTable() drawing code is a lazy-boy
design.

Thank you for visiting Freeman's web site.
Freeman 
2009-06-11-15-12 stop
/**/

/*================================================================================

 XYGraph.js : v2.3

 by J. Gebelein, Last Updated 2006.01.11

 Contact: info@Structura.info

 All rights reserved.
 Copyright 2006 Structura.info


 This script generates an XY Graph
 using Vector Markup Language (VML)
 and returns
 an html string for display via
 Javascript.  Labels for points on
 a line, individual
 labels and arrows may be drawn with
 fully customizable features. 
 Multiple lines 
 with unlimited points and customizable
 formats can be drawn on the same plot
 with 
 intelligent data axes that provide a
 best fit to the data for simple, dynamic 
 programming.  

 The VML used by this script is fully
 supported by Internet Explorer 5 or
 later, 
 and will run on any website or intranet,
 online or offline.  Data for the graph
 may be generated from static or dynamic
 Javascript and user form interfaces, or
 even from complex active server database
 programs.

 Use of this code is free for all
 non-commercial websites.  If you find
 this code
 to be useful, I will gladly accept
 PayPal donations to info@Structura.info.
 I 
 provide free email support and will try
 to accomodate your various needs into
 improving this program.

 For commercial use I ask for a one time
 licensing fee of $39.95 per domain, or 
 $99.95 for an unlimited license. Both
 will cover all future version upgrades
 and 
 allow for customization of the source
 code. An unlimited license will allow
 unrestricted use by a single organization
 including redistribution or resale as 
 supporting code for a software product.

 Please leave this header intact if you
 intend on sharing this code.

=========================================
=========================================

"XYGraph" object documentation

Initialize: 
	var MyGraph = new XYGraph();
	MyGraph.xmax = 10;
 // set properties as desired
		
Properties: 
	See constructor script with
 inline comments below.
	
Methods:
	MyGraph.Plot(XYLine [, XYLine_1, ...])
 // returns html code for display

Notes:

 Input x,y coordinate pairs using the
 "XYLine" object found in this script.

 The only required input is the x and
 y data, all formatting and other
 parameters either have default values
 defined in this script, or are
 automatically calculated as required
 to best display the data.

 Multiple XYLine objects may be passed
 to the Plot function for graphing.

 Extreme values +/-999E+99 and "NaN"
 are clipped from the data set.

 Unlike standard XY graphs, lines are
 drawn point to point in any direction
 without limitation.  This allows step
 functions, circles, shapes, etc.

 This script does not optimize data for
 better resolution, it is up to the
 programmer to input the data spacing as
 desired.

 Generating smooth output requires
 increasing the number of data points
 at the
 expense of computation time. 
 Generally, 1000 points or less is
 adequate.
 
 Formatting for text may be modified
 using CSS.

 Formatting for the axes and lines may
 be modified using VML styles, for more 
 information on VML see the W3C
 definition page:
 http://www.w3.org/TR/NOTE-VML

=========================================
=========================================

"XYLine" object documentation

Initialize: 
	var MyLine = new XYLine();
	MyLine.x = [1, 2, 3, 4];
 // set x and y data points
	MyLine.label = "plot 1";
 // set properties as desired
		
Properties: 
	See constructor script with
 inline comments below.

========================================
========================================*/


function XYLine() {

	// Arrays for holding x, y coordinate values and point labels

	this.x = new Array();
	this.y = new Array();
	this.labels = new Array();
	
	// Assign VML compliant properties for the line.
	// Note that non-primary colors must be in #hex or rbg(r,g,b) format.

// 9506162040 here
// color='red' or
// color='blue' determine curve color.
//	this.VMLstroke = "weight='1pt'; color='red'; dashstyle='solid';";
// 9506201957 only here change color ok
//	this.VMLstroke = "weight='3pt'; color='red'; dashstyle='solid';";
	this.VMLstroke = "weight='1pt'; color='blue'; dashstyle='solid';";


	this.drawline=true;	// set to true or false

	// Assign a label for the line

	this.label = "line";	// displayed when mouse is over line
	this.labelfont = "'Arial'";
	this.labelsize = "8"; // font size in "pt"
	this.labelcolor = "black";

	// Assign a VML shapetype for plotting data points, see definitions at bottom of script.
	// Using the 'none' shapetype plots invisible points and allows coordinates to be
	// shown when the mouse is over the point.  Set 'drawpoints' to false to turn off
	// the points completely and speed up graphing for extensive data sets.  The graph script
	// automatically turns off points if the data set has more than 1000 points.

	this.VMLpointshapetype="diamond";	// [ diamond, square, triangle, circle, x, none ]
	this.drawpoints=true;	 	// set to true or false
	this.drawlabels=false;		// set to true or false
	this.mouseoverlabels=false;	// true will show the "labels" on mouseover, false will show x,y coord

	// Assign VML properties for the points

	this.pointsize="5";	 	// shape display size in "pt"
	this.pointfillcolor="blue";	// point fill color
	this.pointstrokecolor="black";	// point line color
}


function Arrow() {

	// x and y coordinate values of arrow origin

	this.x = 0;
	this.y = 0;
	this.rotation = 45;
	this.length = 25;
	
	// Assign a label for the arrow

	this.label = "Test";

	// Assign VML properties for the arrow

	this.size="10";	 	// shape display size in "pt"
	this.color="red";	// arrow color
	this.labelcolor="red";	// label color
	this.labelsize="12";	// label size in "pt"
	this.lineweight="2";  // line weight in "pt"
	this.dashstyle="solid"; // line style

	// Arrow head shape definition

	this.arrowhead='<v:shapetype id="arrowhead" coordsize="500,500" path=" m 0 0 l 250 500 500 0 250 100 x e" />';

} // end function



function Label() {

	// x and y coordinate values of the label origin

	this.x = 0;
	this.y = 0;
	this.rotation = 45;
	this.length = 0;
	
	// Assign a label text

	this.label = "";

	// Assign VML properties for the label

	this.labelcolor="red";	// label color
	this.labelsize="12";	// label size in "pt"

//	this.VMLpointshapetype="circle";	// [ diamond, square, triangle, circle, x, none ]
//9506172103 change to next
//	this.VMLpointshapetype="none";	// [ diamond, square, triangle, circle, x, none ]
//result all label dot disappear
//9506172105 return to original setting
	this.VMLpointshapetype="circle";	// [ diamond, square, triangle, circle, x, none ]

	this.pointsize="6";	 	// shape display size in "pt"
	this.pointfillcolor="red";	// point fill color
	this.pointstrokecolor="black";	// point line color

} // end function



function XYGraph() {

  // Data Properties

	// The max and min values define the upper and lower axis values to display.
	// If not specified they will automatically fit to the data limits.

	this.xmax=null;
	this.xmin=null;
	this.ymax=null; 
	this.ymin=null;

	// Graph titles

	this.title=null;
	this.xaxis=null;
	this.yaxis=null;

	// Tic scale spacing, if not specified it will be fit to the data.

	this.xscale=null;
	this.yscale=null;

	// Value where the axes cross.  Default is at 0,0
	// Set to "Number.NEGATIVE_INFINITY" to align with the minimum axis value.
	// Set to "Number.POSITIVE_INFINITY" to align with the maximum axis value.

	this.xint=0;
	this.yint=0;

	// The last plot string generated is maintained in memory

	this.lastplot="";

	// Tracks the changes made from additional plots for use with DeleteLast()

	this.lastplotadded= new Array();
	this.numplots=0;

  // Style Properties

	this.gheight=200;	// Plotting height in "pt"
	this.gwidth=300;	// Plotting width in "pt"
	this.pad_top=10;	// Internal padding margins in "pt"
	this.pad_bottom=10;
	this.pad_left=10;
	this.pad_right=10;

	this.ticsize=5; 	// Tic size in "pt", set to "0" to turn off
	this.ticspaceavg=30;	// Average auto tic spacing in "pt"
	this.xticloc="auto";	// x-axis labels "top", "bottom", "auto" or "none"
	this.yticloc="auto";	// y-axis labels "right", "left", "auto" or "none"
	this.userxticlabels=null;	// allows the user to override x axis tic labels
	this.useryticlabels=null;	// allows the user to override y axis tic labels

	this.VMLminorxaxisstroke = "weight='0.5pt'; color='#D3D3D3'; dashstyle='dash';";
	this.VMLminoryaxisstroke = "weight='0.5pt'; color='#D3D3D3'; dashstyle='dash';";
	this.VMLmajoraxisstroke = "weight='1pt'; color='black';";
	this.VMLbackgroundfill = "color='white'";
	this.VMLframestroke = "color='white'";

	this.CSSticfont = "font: 8pt 'Arial';";

//	this.CSStitlefont = "font: 10pt 'Arial'; font-weight: bold;";  // font sizes must be set in "pt"
//9506181816 delete [ font-weight: bold;]
	this.CSStitlefont = "font: 10pt 'Arial';";  // font sizes must be set in "pt"

	this.CSSxaxisfont = "font: 8pt 'Arial'; font-weight: bold;";
	this.CSSyaxisfont = "font: 8pt 'Arial'; font-weight: bold;";
	this.VMLyaxisfontcolor = "black";  // must specify y-axis title font color since it is VML object

}

XYGraph.prototype.toString = function() {return this.lastplot;} // The object will evaluate to the last plot



XYGraph.prototype.Plot = function (XYLine) {

// Parse input to determine x,y data limits and clip extreme values
	lines = arguments; 
	xmax = Number.NEGATIVE_INFINITY; xmin = Number.POSITIVE_INFINITY;
	ymax = Number.NEGATIVE_INFINITY; ymin = Number.POSITIVE_INFINITY;
	clipxmax = (this.xmax ? Number(this.xmax) : 999E+99); 
	clipxmin = (this.xmin ? Number(this.xmin) : -999E+99);
	clipymax = (this.ymax ? Number(this.ymax) : 999E+99);
	clipymin = (this.ymin ? Number(this.ymin) : -999E+99);
	clipped=false;

// fix input
	this.yint = Number(this.yint); this.xint = Number(this.xint);
	this.ymin = Number(this.ymin); this.xmin = Number(this.xmin);
	this.ymax = Number(this.ymax); this.xmax = Number(this.xmax);

	if (this.xmax < this.xmin && this.xmax) {temp=this.xmax; this.xmax=this.xmin; this.xmin=temp;} 
	if (this.ymax < this.ymin && this.ymax) {temp=this.ymax; this.ymax=this.ymin; this.ymin=temp;}

	xmax=this.xmax; xmin=this.xmin; ymax=this.ymax; ymin=this.ymin;

  for (var n=0; n<lines.length; n++) {
	var j=0; tempx = new Array(); tempy = new Array(); templabels = new Array();
	linelen = (lines[n].y.length > lines[n].x.length ? lines[n].x.length : lines[n].y.length);
	for (var i=0; i<linelen; i++) {
		if ((lines[n].x[i] <= clipxmax)&&(lines[n].x[i] >= clipxmin)&&(lines[n].y[i] <= clipymax)&&(lines[n].y[i] >= clipymin)&&(i<=1000)) {
			if (xmax < lines[n].x[i]) {xmax = lines[n].x[i]};
			if (xmin > lines[n].x[i]) {xmin = lines[n].x[i]};
			if (ymax < lines[n].y[i]) {ymax = lines[n].y[i]};
			if (ymin > lines[n].y[i]) {ymin = lines[n].y[i]};
			tempx[j]=lines[n].x[i]; 
			tempy[j]=lines[n].y[i];
			if(lines[n].drawlabels || lines[n].mouseoverlabels) {templabels[j]= lines[n].labels[j];}
			j++;
		}
		else if (isNaN(lines[n].x[i]) || isNaN(lines[n].y[i])) {clipped=true;}
		else if (((lines[n].x[i+1] <= clipxmax)&&(lines[n].x[i+1] >= clipxmin)&&(lines[n].y[i+1] <= clipymax)&&(lines[n].y[i+1] >= clipymin)&&(i<=1000))) {
			lastxy = this.Findedge(lines[n].x[i+1],lines[n].x[i],lines[n].y[i+1],lines[n].y[i],clipxmax,clipxmin,clipymax,clipymin);
			if (Math.abs(lastxy[0]) < 999E+99 && Math.abs(lastxy[1]) < 999E+99) {
				tempx[j]=lastxy[0]; tempy[j]=lastxy[1]; 
				if(lines[n].drawlabels || lines[n].mouseoverlabels) {templabels[j]="";}
				j++;
			}
			clipped=true; 
		}
		else if (((lines[n].x[i-1] <= clipxmax)&&(lines[n].x[i-1] >= clipxmin)&&(lines[n].y[i-1] <= clipymax)&&(lines[n].y[i-1] >= clipymin))&&(i<=1000)) {
			lastxy = this.Findedge(lines[n].x[i-1],lines[n].x[i],lines[n].y[i-1],lines[n].y[i],clipxmax,clipxmin,clipymax,clipymin);
			if (Math.abs(lastxy[0]) < 999E+99 && Math.abs(lastxy[1]) < 999E+99) {
				tempx[j]=lastxy[0]; tempy[j]=lastxy[1]; 
				if(lines[n].drawlabels || lines[n].mouseoverlabels) {templabels[j]="";}
				j++;
			}
			if (i+1 != linelen) {
			lines.length += 1;
			lines[(lines.length-1)] = new Array();
			lines[(lines.length-1)].VMLstroke = lines[n].VMLstroke;
			lines[(lines.length-1)].drawline = lines[n].drawline;
			lines[(lines.length-1)].label = lines[n].label;
			lines[(lines.length-1)].VMLpointshapetype = lines[n].VMLpointshapetype;
			lines[(lines.length-1)].pointsize = lines[n].pointsize;
			lines[(lines.length-1)].pointfillcolor = lines[n].pointfillcolor;
			lines[(lines.length-1)].pointstrokecolor = lines[n].pointstrokecolor;
			lines[(lines.length-1)].drawpoints = lines[n].drawpoints;
			lines[(lines.length-1)].labelsize = lines[n].labelsize;
			lines[(lines.length-1)].labelfont = lines[n].labelfont;
			lines[(lines.length-1)].labelcolor = lines[n].labelcolor;
			lines[(lines.length-1)].drawlabels = lines[n].drawlabels;
			lines[(lines.length-1)].mouseoverlabels = lines[n].mouseoverlabels;
			lines[(lines.length-1)].x=lines[n].x.slice(i);
			lines[(lines.length-1)].y=lines[n].y.slice(i); 
			lines[n].x=tempx; lines[n].y=tempy; 
			if(lines[n].drawlabels || lines[n].mouseoverlabels) {
				lines[(lines.length-1)].labels=lines[n].labels.slice(i);
				lines[n].labels=templabels;
			}
			clipped=true;

			break; 
			}
		}
		else if (i > 1000) {
			lines[n].drawpoints = false;
			lines[n].drawlabels = false;
			lines.length += 1;
			lines[(lines.length-1)] = new Array();
			lines[(lines.length-1)].VMLstroke = lines[n].VMLstroke;
			lines[(lines.length-1)].drawline = lines[n].drawline;
			lines[(lines.length-1)].label = lines[n].label;
			lines[(lines.length-1)].drawpoints = false;
			lines[(lines.length-1)].drawlabels = false;
			lines[(lines.length-1)].x=lines[n].x.slice(i-1);
			lines[(lines.length-1)].y=lines[n].y.slice(i-1); 
			lines[n].x=tempx; lines[n].y=tempy;

			break; 
		}
		else {clipped=true;}
	}
	lines[n].x=tempx; lines[n].y=tempy; lines[n].labels=templabels;
  }

	if (this.xint == Number.NEGATIVE_INFINITY) {this.xint = xmin;}
	if (this.xint == Number.POSITIVE_INFINITY) {this.xint = xmax;}
	if (this.yint == Number.NEGATIVE_INFINITY) {this.yint = ymin;}
	if (this.yint == Number.POSITIVE_INFINITY) {this.yint = ymax;}



// Initialize data

if (this.lastplot == "") { // don't redraw graph background if called multiple times

	xscale=Number(this.xscale); yscale=Number(this.yscale);
	xint=Number(this.xint); yint=Number(this.yint);

	gheight=Number(this.gheight); gwidth=Number(this.gwidth);
	ticsize=Number(this.ticsize);

	xticloc=this.xticloc; yticloc=this.yticloc;

// Initialize parameters

	gxpt=100;
	pad_t=gxpt*this.pad_top; pad_b=gxpt*this.pad_bottom; // padding
	pad_l=gxpt*this.pad_left; pad_r=gxpt*this.pad_right; 
	gwt=Math.abs(Math.round(gwidth*gxpt)); // total graph width;
	ght=Math.abs(Math.round(gheight*gxpt)); // total graph height;

	gstyle='position:absolute; width='+gwt+'; height='+ght; // repetitive string constant
	GXstyle=this.CSSticfont+'position:absolute;';
	GYstyle=this.CSSticfont+'position:absolute;';
	GYLstyle=this.CSSticfont+'position:absolute; text-align:right; width:'; // finished later

// fix auto scale x axis
	if (xint < xmin) {xmin=xint;}
	if (xint > xmax) {xmax=xint;}

// x auto tic scale
     if (xscale <= 0) {
	xticmax=(gwidth-(pad_r+pad_l)/gxpt)/this.ticspaceavg;
	ticdivision=[0.1,0.2,0.25,0.5];
	divpow=0;
	i=0;
	  while ((xmax-xmin)/(ticdivision[i]*Math.pow(10,divpow)) > xticmax) { 
	    i++; 
	    if (!(i % ticdivision.length)) {divpow++; i=0;}
	    if (divpow>1) {xticmax=(gwidth-(pad_r+pad_l)/gxpt)/(Number(this.ticspaceavg)+5);}
	  }
	if (i==0 && divpow==0) {
	  i=ticdivision.length-1; divpow=-1; xticmax=(gwidth-(pad_r+pad_l)/gxpt)/(Number(this.ticspaceavg)+10);
	  while ((xmax-xmin)/(ticdivision[i]*Math.pow(10,divpow)) < xticmax) { 
	    i--; 
	    if (i==-1) {divpow--; i=ticdivision.length-1; xticmax=(gwidth-(pad_r+pad_l)/gxpt)/(Number(this.ticspaceavg)+30);}
	  }
	}
	xscale=ticdivision[i]*Math.pow(10,divpow);
     }


// fix auto scale y axis
	if (yint < ymin) {ymin = yint;}
	if (yint > ymax) {ymax = yint;}

// y auto tic scale
     if (yscale <= 0) {
	yticmax=(gheight-(pad_t+pad_b)/gxpt)/this.ticspaceavg;
	ticdivision=[0.1,0.2,0.25,0.5];
	divpow=0;
	i=0;
	  while ((ymax-ymin)/(ticdivision[i]*Math.pow(10,divpow)) > yticmax) { 
	    i++; 
	    if (!(i % ticdivision.length)) {divpow++; i=0;}
	    if (divpow>1) {yticmax=(gwidth-(pad_t+pad_b)/gxpt)/(Number(this.ticspaceavg)+5);}
	  }
	if (i==0 && divpow==0) {
	  i=ticdivision.length-1; divpow=-1; yticmax=(gheight-(pad_t+pad_b)/gxpt)/(this.ticspaceavg+10);
	  while ((ymax-ymin)/(ticdivision[i]*Math.pow(10,divpow)) < yticmax) { 
	    i--; 
	    if (i==-1) {divpow--; i=ticdivision.length-1; yticmax=(gheight-(pad_t+pad_b)/gxpt)/(this.ticspaceavg+30);}
	  }
	}
	yscale=ticdivision[i]*Math.pow(10,divpow);
     }

// fix auto scale y axis
	if (!clipped) {
		ymin = (ymin%yscale ? ymin-ymin%yscale-yscale : ymin);
		ymax = (ymax%yscale ? ymax-ymax%yscale+yscale : ymax);
	}


// Determine x tic labels

	xticlabels = new Array(); xticcharnum=1;
	numxticleft = Math.floor((xint-xmin)/xscale); 
	numxtic = numxticleft+Math.floor((xmax-xint)/xscale)+1;
	for (var i=0; i<numxtic; i++) {
		xticlabel=(i-numxticleft)*xscale+xint;  
		negstr=""; expstr=0;
		if (xticlabel < 0) {xticlabel*=-1; negstr="-";}
		switch (true) {	
		case (xticlabel > 99999) : 
			while (xticlabel>=1000) {xticlabel/=1000; expstr++;}
			xticlabel=String(xticlabel).slice(0,4);
			xticlabels[i]=negstr+xticlabel+"E+"+(expstr*3);
			break;
		case (xticlabel < 0.001 && xticlabel!=0) : 
			while (xticlabel<=0.001) {xticlabel*=1000; expstr++;}
			xticlabel=(Math.round(xticlabel*Math.pow(10,4)))/Math.pow(10,4);
			xticlabels[i]=negstr+xticlabel+"E-"+(expstr*3);
			break;
		default:
			xticlabel=(Math.round(xticlabel*Math.pow(10,3)))/Math.pow(10,3);
			xticlabels[i]=negstr+String(xticlabel).slice(0,6);
			break;
		} 
		xticcharnum=Math.max(xticcharnum,String(xticlabels[i]).length);
	}
	xticcharnumlast=String(xticlabels[i-1]).length;

	if (this.userxticlabels!=null) {
	len=Math.min(this.userxticlabels.length,xticlabels.length);
	for (var i=0; i<len; i++) {
		xticlabels[i]=this.userxticlabels[i];
	}}


// Determine y tic labels

	yticlabels = new Array(); yticcharnum=0;
	numyticbot = Math.floor((yint-ymin)/yscale);
	numytic = numyticbot+Math.floor((ymax-yint)/yscale)+1;
	for (var i=0; i<numytic; i++) {
		yticlabel=(i-numyticbot)*yscale+yint;
		negstr=""; expstr=0;
		if (yticlabel < 0) {yticlabel*=-1; negstr="-";}
		switch (true) { 
		case (yticlabel > 99999) : 
			while (yticlabel>=1000) {yticlabel/=1000; expstr++;}
			yticlabel=String(yticlabel).slice(0,4);
			yticlabels[i]=negstr+yticlabel+"E+"+(expstr*3);
			break;
		case (yticlabel < 0.001 && yticlabel!=0) : 
			while (yticlabel<=0.001) {yticlabel*=1000; expstr++;}
			yticlabel=(Math.round(yticlabel*Math.pow(10,4)))/Math.pow(10,4);
			yticlabels[i]=negstr+yticlabel+"E-"+(expstr*3);
			break;
		default:
			yticlabel=(Math.round(yticlabel*Math.pow(10,3)))/Math.pow(10,3);
			yticlabels[i]=negstr+String(yticlabel).slice(0,6);
			break;
		} 
		yticcharnum=Math.max(yticcharnum,String(yticlabels[i]).length);
	}

	if (this.useryticlabels!=null) {
	len=Math.min(this.useryticlabels.length,yticlabels.length);
	for (var i=0; i<len; i++) {
		yticlabels[i]=this.useryticlabels[i];
	}}

// Determine required extra padding and auto axis location
	tic_pt=Number((this.CSSticfont.slice(0,this.CSSticfont.indexOf("pt"))).slice(-2));
	GYLstyle+=tic_pt*(yticcharnum+1)*0.5+"pt;";
	if (yticloc!="none") {
	  if (!numxticleft) {
		if (yticloc=="auto") {yticloc="left";}
		if (yticloc!="right") {
			pad_l+=0.75*yticcharnum*tic_pt*gxpt;
			if (this.yaxis) {pad_l+=0.5*this.pad_left*gxpt;}
		}
	  }
	  if (numxticleft == numxtic-1) {
		if (yticloc=="auto") {yticloc="right";}
		if (yticloc!="left") {pad_r+=0.75*yticcharnum*tic_pt*gxpt;}
	  }
	}

	if (xticloc!="none") {
	  if (!numyticbot) {
		if (xticloc=="auto") {xticloc="bottom";}
		if (xticloc!="top") {pad_b+=0.75*tic_pt*gxpt;}
	  }
	  if (numyticbot == numytic-1) {
		if (xticloc=="auto") {xticloc="top";}
		if (xticloc!="bottom") {pad_t+=0.75*tic_pt*gxpt;}
	  }
	if (!((numxticleft == numxtic-1) && (yticloc=="right"))) {pad_r+=0.25*xticcharnumlast*tic_pt*gxpt;}
	}
	if (this.title) {
		title_pt=Number((this.CSStitlefont.slice(0,this.CSStitlefont.indexOf("pt"))).slice(-2));
		pad_t+=1.25*title_pt*gxpt;
		if (xticloc=="top") pad_t+=0.75*tic_pt*gxpt;}
	if (this.xaxis) {
		xaxis_pt=Number((this.CSSxaxisfont.slice(0,this.CSSxaxisfont.indexOf("pt"))).slice(-2));
		pad_b-=0.25*pad_b;
		pad_b+=xaxis_pt*gxpt;
		if (xticloc=="bottom") pad_b+=0.75*tic_pt*gxpt;}
	if (this.yaxis) {
		yaxis_pt=Number((this.CSSyaxisfont.slice(0,this.CSSyaxisfont.indexOf("pt"))).slice(-2));
		pad_l-=0.25*pad_l;
		pad_l+=yaxis_pt*gxpt;}


	gw=gwt-pad_l-pad_r;
	gh=ght-pad_t-pad_b;

	xscl=gw/(xmax-xmin);
	yscl=gh/(ymax-ymin);

	this.xmin=xmin; 
	this.xmax=xmax; 
	this.ymin=ymin; 
	this.ymax=ymax;

	gxmin=pad_l;
	gxmax=gw+pad_l;
	gxint=(xint-xmin)*xscl+pad_l;
	gymin=gh+pad_t;
	gymax=pad_t;
	gyint=(ymax-yint)*yscl+pad_t;
	gytic=yscale*yscl;
	gxtic=xscale*xscl;
	gticsize=Math.abs(Math.round(ticsize*gxpt));

	gstr='<v:group style="antialias:true; width='+gwidth+'pt; height='+gheight+'pt" coordsize="'+gwt+','+ght+'" coordorigin="0,0">';
	gstr+='<v:rect style="'+gstyle+'" ><v:stroke '+this.VMLframestroke+' /><v:fill '+this.VMLbackgroundfill+' /></v:rect>';

// draw x-axis
	if(xscl!=Number.POSITIVE_INFINITY) {
		gstr+='<v:line from="'+gxmin+','+Math.round(gyint)+'" to="'+gxmax+','+Math.round(gyint)+'" ><v:stroke '+this.VMLmajoraxisstroke+' /></v:line>';
		}
// draw y-axis
	if(yscl!=Number.POSITIVE_INFINITY) {
		gstr+='<v:line from="'+Math.round(gxint)+','+gymin+'" to="'+Math.round(gxint)+','+gymax+'" ><v:stroke '+this.VMLmajoraxisstroke+' /></v:line>';
		}
// draw minor x-axis
	yticmin=gyint+numyticbot*gytic;
	for (var i=0; i<numytic; i++) {
	  curint=Math.round(yticmin-gytic*i);
	  if (curint!=Math.round(gyint)) {gstr+='<v:line from="'+gxmin+','+curint+'" to="'+gxmax+','+curint+'" ><v:stroke '+this.VMLminorxaxisstroke+' /></v:line>';}
	}

// draw minor y-axis
	xticmin=gxint-numxticleft*gxtic;
	for (var i=0; i<numxtic; i++) {
	  curint=Math.round(gxtic*i+xticmin);
	  if (curint!=Math.round(gxint)) {gstr+='<v:line from="'+curint+','+gymin+'" to="'+curint+','+gymax+'" ><v:stroke '+this.VMLminoryaxisstroke+' /></v:line>';}
	}

// draw x-axis tics
	gstr+='<v:shape style="'+gstyle+'"><v:path v="';
	for (var i=0; i<numxtic; i++) { gstr+='m '+Math.round(xticmin+i*gxtic)+','+Math.round(gyint)+' r 0,'+((xticloc=="top" ? -1 : 1)*gticsize)+' x ';}
	gstr+='e" /><v:stroke '+this.VMLmajoraxisstroke+' /><v:fill on="false" /></v:shape>';

// draw y-axis tics
	gstr+='<v:shape style="'+gstyle+'"><v:path v="';
	for (var i=0; i<numytic; i++) { gstr+='m '+Math.round(gxint)+','+Math.round(yticmin-i*gytic)+' r '+((yticloc=="right" ? 1 : -1)*gticsize)+',0 x ';}
	gstr+='e" /><v:stroke '+this.VMLmajoraxisstroke+' /><v:fill on="false" /></v:shape>';

// draw titles
	if (this.title) {
	nonchar=0; 
	for (var i=0; i<this.title.length; i++) {if (this.title.charAt(i)==";") {nonchar++;}}
	gstr+='<span style="'+this.CSStitlefont+' position:absolute; text-align:center; top: '+0.5*this.pad_top;
	gstr+='pt; left: '+(0.5*gwt/gxpt-(this.title.length-5.5*nonchar)*title_pt*0.25)+'pt;">'+this.title+'</span>';
	}
	if (this.xaxis) {
	nonchar=0; 
	for (var i=0; i<this.xaxis.length; i++) {if (this.xaxis.charAt(i)==";") {nonchar++;}}
	gstr+='<span style="'+this.CSSxaxisfont+' position:absolute; text-align:center; top: '+((gymin+0.5*(pad_b-xaxis_pt*gxpt))/gxpt+(xticloc=="bottom" ? 0.75*tic_pt:0));
	gstr+='pt; left: '+(0.5*gwt/gxpt-(this.xaxis.length-5.5*nonchar)*xaxis_pt*0.25)+'pt;">'+this.xaxis+'</span>';
	}
	if (this.yaxis) { 
	gstr+='<v:shape style="'+gstyle;
	gstr+='" path="M '+((0.25*this.pad_left+0.5*yaxis_pt)*gxpt)+','+gymin+' L '+((0.25*this.pad_left+0.5*yaxis_pt)*gxpt)+','+gymax+'" fillcolor="'+this.VMLyaxisfontcolor+'">';
	gstr+='<v:stroke on="false" /><v:path textpathok="true" />';
	gstr+='<v:textpath on="true" style="'+this.CSSyaxisfont+'" string="'+this.yaxis+'" /></v:shape>';
	}

} // end of draw graph background


// hold on to previous plot
  if (this.lastplot != "") {
	gstr=this.lastplot.substring(0,this.lastplot.length-10);
	gstrtemp=gstr;
  }

// draw lines
  for (var n=0; n<lines.length; n++) {
  if (lines[n].drawline && lines[n].x.length>1) {
	gstr+='<v:polyline points="';
	for (i=0; i<lines[n].x.length; i++) {gstr+= Math.round(gxmin+(lines[n].x[i]-xmin)*xscl)+" "+Math.round(gymin-(lines[n].y[i]-ymin)*yscl)+" ";}
	gstr+='" title="'+lines[n].label+'" ><v:stroke '+lines[n].VMLstroke+' /><v:fill on="false" /></v:polyline>';
  }}


// draw points
  for (var n=0; n<lines.length; n++) {
  if (lines[n].drawpoints && lines[n].x.length>0) {
	gstr+=this.VMLpointshape(lines[n].VMLpointshapetype);
	for (i=0; i<lines[n].x.length; i++) {
		gstr+='<v:shape type="#'+(lines[n].VMLpointshapetype).toLowerCase()+'" style="width:'+lines[n].pointsize*gxpt+'; height:'+lines[n].pointsize*gxpt;
		gstr+='; top:'+Math.round(gymin-0.5*lines[n].pointsize*gxpt-(lines[n].y[i]-ymin)*yscl)+'; left:'+Math.round(gxmin-0.5*lines[n].pointsize*gxpt+(lines[n].x[i]-xmin)*xscl);
		ptitle = (lines[n].mouseoverlabels) ? lines[n].labels[i] : lines[n].x[i]+','+lines[n].y[i]; 
		gstr+='" title="'+ptitle+'" fillcolor="'+lines[n].pointfillcolor+'"';
		gstr+=' strokecolor="'+lines[n].pointstrokecolor+'" />';
	}
  }}

// draw labels
  for (var n=0; n<lines.length; n++) { 
  if (lines[n].drawlabels && lines[n].labels.length>0) { 
	for (i=0; i<lines[n].labels.length; i++) { 
		gstr+='<span style="font: '+lines[n].labelsize+'pt '+lines[n].labelfont+'; position:absolute;';
		gstr+=' top:'+Math.round((gymin-1.5*lines[n].labelsize*gxpt-(lines[n].y[i]-ymin)*yscl)/gxpt)+'pt; left:'+Math.round((gxmin+0.5*lines[n].labelsize*gxpt+(lines[n].x[i]-xmin)*xscl)/gxpt)+'pt; ';
		gstr+=' color:'+lines[n].labelcolor+'">'+lines[n].labels[i]+'</span>';
	}
  }}

if (this.lastplot == "") { // don't redraw graph background if called multiple times
// draw x-axis labels
	if (xticloc!="none") {
	for (var i=0; i<numxtic; i++) { 
		  if (xticloc=="top") {
			gstr+='<span style="'+GXstyle+' top: '+((gyint-gticsize*1.25)/gxpt-8)+'pt; left: '+((xticmin+i*gxtic-0.5*gticsize)/gxpt)+'pt;">';
		  }
		  else {
			gstr+='<span style="'+GXstyle+' top: '+((gyint+gticsize*1.25)/gxpt)+'pt; left: '+((xticmin+i*gxtic-0.5*gticsize)/gxpt)+'pt;">';
		  }
		gstr+=xticlabels[i]+'</span>';
	}}

// draw y-axis labels
	if (yticloc!="none") {
	for (var i=0; i<numytic; i++) { 
		  if (yticloc=="right") {
		  	gstr+='<span style="'+GYstyle+' top: '+((yticmin-i*gytic-gticsize)/gxpt)+'pt; left: '+((gxint+gticsize*1.5)/gxpt)+'pt;">';
		  }
		  else {
		  	gstr+='<span style="'+GYLstyle+' top: '+((yticmin-i*gytic-gticsize)/gxpt)+'pt; left: '+((gxint-gticsize)/gxpt-0.5*(yticcharnum+1)*tic_pt)+'pt;">';
		  }
		  gstr+=yticlabels[i]+'</span>';
	}}
} // end of draw graph background

// close and return output 
	gstr+='</v:group>';
  	if (this.numplots > 0) {this.lastplotadded[this.numplots]=gstr.length-gstrtemp.length;}
	else {this.lastplotadded[0]=gstr.length;}
	this.numplots++;
	this.lastplot=gstr;  // save this output in memory

	return gstr;

} // end function




// function to undo last added line, label or arrow from the plot

XYGraph.prototype.DeleteLast = function () {
	if (this.numplots > 1) {
		gstr=this.lastplot.substring(0,this.lastplot.length-this.lastplotadded[this.numplots-1]+1);
		gstr+='</v:group>';
		this.lastplot=gstr;
		this.numplots--;
	}
	return gstr;
} // end function



XYGraph.prototype.Findedge = function (x1,x2,y1,y2,xmax,xmin,ymax,ymin) {

	x=0; y=0;
    if (!isNaN(x2)) {
	if (!isFinite(x2)) {
		switch (x2) {
			case Number.POSITIVE_INFINITY: x2 = 999E+99; break;
			case Number.NEGATIVE_INFINITY: x2 = -999E+99; break;
		}
	}
	if (!isFinite(y2)) {
		switch (y2) {
			case Number.POSITIVE_INFINITY: y2 = 999E+99; break;
			case Number.NEGATIVE_INFINITY: y2 = -999E+99; break;
		}
	}

	angle = Math.atan2(y2-y1,x2-x1);
	angle += (angle > 0 ? 0 : 2*Math.PI);

	slope = (y2-y1)/(x2-x1);
	Mxx = Math.atan2(ymax-y1,xmax-x1); Mxx += (Mxx > 0 ? 0 : 2*Math.PI);
	Mnx = Math.atan2(ymax-y1,xmin-x1); Mnx += (Mnx > 0 ? 0 : 2*Math.PI);
	Mnn = Math.atan2(ymin-y1,xmin-x1); Mnn += (Mnn > 0 ? 0 : 2*Math.PI);
	Mxn = Math.atan2(ymin-y1,xmax-x1); Mxn += (Mxn > 0 ? 0 : 2*Math.PI);

	switch (true) {
		case (angle>=Mxx && angle<Mnx) : 
			y = ymax;
			x = (ymax-y1)/slope+x1;
			break;
		case (angle>=Mnx && angle<Mnn) :
			x = xmin;
			y = (xmin-x1)*slope+y1;
			break;
		case (angle>=Mnn && angle<Mxn) :
			y = ymin;
			x = (ymin-y1)/slope+x1;
			break;
		case (angle>=Mxn || angle<Mxx) :
			x = xmax;
			y = (xmax-x1)*slope+y1;
			break;
	}
     }

	return [x,y]; 
} // end function



// point shapetype definitions, these can be modified and expanded

XYGraph.prototype.VMLpointshape = function (shapename) {
	switch (shapename.toLowerCase()) {
	
	case "diamond" :
		return '<v:shapetype id="diamond" coordsize="500,500" path=" m 250 500 l 500 250 250 0 0 250 x e" />';
	case "square" :
		return '<v:shapetype id="square" coordsize="350,350" path=" m 0 0 l 0 350 350 350 350 0 x e" />';
	case "triangle" :
		return '<v:shapetype id="triangle" coordsize="400,400" path=" m 200 0 l 400 400 0 400 x e" />';
	case "circle" :
		return '<v:shapetype id="circle" coordsize="350,350" path=" m 0 175 l 23 262 88 327 175 350 262 327 327 262 350 175 327 88 262 23 175 0 88 23 23 88 x e" />';
	case "x" :
		return '<v:shapetype id="x" coordsize="350,350" path=" m 0 0 l 350 350 e m 0 350 l 350 0 e" />';
	case "none" :
		return '<v:shapetype id="none" coordsize="350,350" filled="false" stroked="false" path=" m 0 0 l 0 350 350 350 350 0 x e" />';
	}
} // end function



XYGraph.prototype.Drawarrow = function (arrowdef) {

	gstr=gstr.substring(0,gstr.length-10);
	gstrtemp=gstr;

	arrowdef.x = Number(arrowdef.x)
	arrowdef.y = Number(arrowdef.y)
	arrowdef.rotation = Number(arrowdef.rotation)
	arrowdef.length = Number(arrowdef.length)
	arrowdef.size = Number(arrowdef.size)

	xpoint=Math.round(gxmin+(arrowdef.x-xmin)*xscl+0.5*arrowdef.size*gxpt*Math.sin(arrowdef.rotation*Math.PI/180));
	ypoint=Math.round(gymin-(arrowdef.y-ymin)*yscl-0.5*arrowdef.size*gxpt*Math.cos(arrowdef.rotation*Math.PI/180));

	xpoint2=Math.round(xpoint+arrowdef.length*gxpt*Math.sin(arrowdef.rotation*Math.PI/180));
	ypoint2=Math.round(ypoint-arrowdef.length*gxpt*Math.cos(arrowdef.rotation*Math.PI/180));

	gstr+='<v:line from="'+xpoint+','+ypoint+'" to="'+xpoint2+','+ypoint2+'" ><v:stroke weight="'+arrowdef.lineweight+'pt"; color="'+arrowdef.color+'"; dashstyle="'+arrowdef.dashstyle+'"; /></v:line>';

	xpoint3=Math.round(xpoint2+1.25*arrowdef.labelsize*gxpt*Math.sin(arrowdef.rotation*Math.PI/180));
	ypoint3=Math.round(ypoint2-1.25*arrowdef.labelsize*gxpt);

	if(Math.cos(arrowdef.rotation*Math.PI/180)>0.707) 
		{position=' text-align:center; top:'+Math.round(ypoint3/gxpt)+'pt; left: '+Math.round(xpoint3/gxpt-0.25*arrowdef.label.length*arrowdef.labelsize)+'pt; ';}
	if(Math.cos(arrowdef.rotation*Math.PI/180)<0.707) 
		{position=' text-align:center; top:'+Math.round(ypoint2/gxpt)+'pt; left: '+Math.round(xpoint3/gxpt-0.25*arrowdef.label.length*arrowdef.labelsize)+'pt; ';}
	if(Math.sin(arrowdef.rotation*Math.PI/180)>0.707) 
		{position=' text-align:center; top:'+Math.round(ypoint2/gxpt-arrowdef.labelsize*(0.5+Math.cos(arrowdef.rotation*Math.PI/180)))+'pt; left: '+Math.round(xpoint3/gxpt-0.25*arrowdef.label.length*arrowdef.labelsize)+'pt; ';}
	if(Math.sin(arrowdef.rotation*Math.PI/180)<0.707) 
		{position=' text-align:center; top:'+Math.round(ypoint2/gxpt-arrowdef.labelsize*(0.5+Math.cos(arrowdef.rotation*Math.PI/180)))+'pt; left: '+Math.round(xpoint3/gxpt-0.25*arrowdef.label.length*arrowdef.labelsize)+'pt; ';}

//	gstr+='<span style="font: '+arrowdef.labelsize+'pt Arial; font-weight:bold; position:absolute;';
//9506241341 change 'bold' to 'regular'
	gstr+='<span style="font: '+arrowdef.labelsize+'pt Arial; font-weight:regular; position:absolute;';
	gstr+=position+'color:'+arrowdef.labelcolor+'">'+arrowdef.label+'</span>';

	xpoint=Math.round(gxmin-0.5*arrowdef.size*gxpt+(arrowdef.x-xmin)*xscl+0.5*arrowdef.size*gxpt*Math.sin(arrowdef.rotation*Math.PI/180));
	ypoint=Math.round(gymin-0.5*arrowdef.size*gxpt-(arrowdef.y-ymin)*yscl-0.5*arrowdef.size*gxpt*Math.cos(arrowdef.rotation*Math.PI/180));

	gstr+=arrowdef.arrowhead;
	gstr+='<v:shape type="#arrowhead" style="width:'+arrowdef.size*gxpt+'; height:'+arrowdef.size*gxpt;
	gstr+='; top:'+ypoint+'; left:'+xpoint;
	gstr+='" title="'+arrowdef.label+'" fillcolor="'+arrowdef.color+'"';
	gstr+='"; style= "rotation:'+arrowdef.rotation+'deg"';
	gstr+=' strokecolor="'+arrowdef.color+'" />';
	
	gstr+='</v:group>';
	this.lastplot=gstr;
	this.lastplotadded[this.numplots]=gstr.length-gstrtemp.length;
	this.numplots++;
	return gstr;

} // end function



XYGraph.prototype.Drawlabel = function (labeldef) {

	gstr=gstr.substring(0,gstr.length-10);
	gstrtemp=gstr;

	labeldef.x = Number(labeldef.x)
	labeldef.y = Number(labeldef.y)
	labeldef.rotation = Number(labeldef.rotation)
	labeldef.length = Number(labeldef.length)

	xpoint=Math.round(gxmin+(labeldef.x-xmin)*xscl+0.5*labeldef.labelsize*gxpt*Math.sin(labeldef.rotation*Math.PI/180));
	ypoint=Math.round(gymin-(labeldef.y-ymin)*yscl-0.5*labeldef.labelsize*gxpt*Math.cos(labeldef.rotation*Math.PI/180));

	xpoint2=Math.round(xpoint+labeldef.length*gxpt*Math.sin(labeldef.rotation*Math.PI/180));
	ypoint2=Math.round(ypoint-labeldef.length*gxpt*Math.cos(labeldef.rotation*Math.PI/180));

	xpoint3=Math.round(xpoint2+1.25*labeldef.labelsize*gxpt*Math.sin(labeldef.rotation*Math.PI/180));
	ypoint3=Math.round(ypoint2-1.25*labeldef.labelsize*gxpt);

	if(Math.cos(labeldef.rotation*Math.PI/180)>0.707) 
		{position=' text-align:center; top:'+Math.round(ypoint3/gxpt)+'pt; left: '+Math.round(xpoint3/gxpt-0.25*labeldef.label.length*labeldef.labelsize)+'pt; ';}
	if(Math.cos(labeldef.rotation*Math.PI/180)<0.707) 
		{position=' text-align:center; top:'+Math.round(ypoint2/gxpt)+'pt; left: '+Math.round(xpoint3/gxpt-0.25*labeldef.label.length*labeldef.labelsize)+'pt; ';}
	if(Math.sin(labeldef.rotation*Math.PI/180)>0.707) 
		{position=' text-align:center; top:'+Math.round(ypoint2/gxpt-labeldef.labelsize*(0.5+Math.cos(labeldef.rotation*Math.PI/180)))+'pt; left: '+Math.round(xpoint3/gxpt-0.25*labeldef.label.length*labeldef.labelsize)+'pt; ';}
	if(Math.sin(labeldef.rotation*Math.PI/180)<0.707) 
		{position=' text-align:center; top:'+Math.round(ypoint2/gxpt-labeldef.labelsize*(0.5+Math.cos(labeldef.rotation*Math.PI/180)))+'pt; left: '+Math.round(xpoint3/gxpt-0.25*labeldef.label.length*labeldef.labelsize)+'pt; ';}

//	gstr+='<span style="font: '+labeldef.labelsize+'pt Arial; font-weight:bold; position:absolute;';
//9506241347 change 'bold' to 'regular' OK right
//	gstr+='<span style="font: '+labeldef.labelsize+'pt Arial; font-weight:regular; position:absolute;';
//9506241352 change 'Arial' to 'Courier New' to 'Courier' useless
//9506241355 change 'Arial' to 'Dotum' character thinner
	gstr+='<span style="font: '+labeldef.labelsize+'pt Dotum; font-weight:regular; position:absolute;';
	gstr+=position+'color:'+labeldef.labelcolor+'">'+labeldef.label+'</span>';

	gstr+=this.VMLpointshape(labeldef.VMLpointshapetype);

	gstr+='<v:shape type="#'+(labeldef.VMLpointshapetype).toLowerCase()+'" style="width:'+labeldef.pointsize*gxpt+'; height:'+labeldef.pointsize*gxpt;
	gstr+='; top:'+Math.round(gymin-0.5*labeldef.pointsize*gxpt-(labeldef.y-ymin)*yscl,2)+'; left:'+Math.round(gxmin-0.5*labeldef.pointsize*gxpt+(labeldef.x-xmin)*xscl);
	gstr+='" fillcolor="'+labeldef.pointfillcolor+'"';
	gstr+=' strokecolor="'+labeldef.pointstrokecolor+'" />';

	gstr+='</v:group>';
	this.lastplot=gstr;
	this.lastplotadded[this.numplots]=gstr.length-gstrtemp.length;
	this.numplots++;
	return gstr;

} // end function


// 9507121343
function stepf(t0,bgn0)
{
  if(t0<bgn0) return 0.;
  return 1.;

} // end function // 9507121346
// 9507121356
// stepf(t,3) get t<3  value 0
// stepf(t,3) get t>=3 value 1
//
// (1-stepf(t,3)) get t<3  value 1
// (1-stepf(t,3)) get t>=3 value 0
//
// (stepf(t,2)-stepf(t,3))
//  get  2<=t<3  value 1
//  t<2 and t>=3 value 0
// 9507121400





/*
95,07,08,14,55,00
http://www.univie.ac.at/future.media/moe/JavaCalc/jcintro.html
c:\$fm\js\math9507\JavaCalc-jcintro.html

95,07,08,15,00
http://www.univie.ac.at/future.media/moe/JavaCalc/parser.js
c:\$fm\js\math9507\JavaCalc-jcintro-parser.js


Return to MathCollections

Ken Kikuchi
Comment me: kikuchi@mix.or.jp
Last updated: 2/29/2000

9507132210 include
function loggamma(x)
and
function gamma(x) 

/**/


// Ab hier (17. 3. 2000) von Ken's Script &#252;bernommen:

function factorial(n) {  /* factorial */
  with(Math) {
  if (n<0)  /* if negative */
  	return gamma(n+1);
  else if ((n == 0) || (n == 1))
    return 1;
  else if (abs(n)-floor(abs(n))==0 ) /* if positive integer */
    return n * factorial(n-1) ;
  else         /* if non-integer */
    return gamma(n+1);
} }


function loggamma(x)  { /* log gamma */
var u0; //9507142008

    with(Math) {
        var v=1;
        var w=0;
        var z=0;
        while ( x<8 ) { v*=x; x++ }
        w=1/(x*x);

u0= //9507142009
((((((((-3617/122400)*w + 7/1092)*w
         -691/360360)*w + 5/5940)*w
         -1/1680)*w + 1/1260)*w
         -1/360)*w + 1/12)/x 
+ 0.5 * log(2*PI)-log(v)-x+(x-0.5)*log(x) ;

//status='x=['+x+']; w=['+w+']; u0=['+u0+'] 9507142010';

/*
        return 
u0;

9507142028 I use above return,
 then return nothing !!

/**/
        return u0;

} }



function gamma(x) {  /* gamma */

//9507141940
var i0;
var y0='';
var g0,g1,g2; //9507142019

for(i0=0;i0<(x+'').length;i0++)
{
  if(i0==0&&(x+'').charAt(i0)=='(')continue;
  if((x+'').charAt(i0)==')')break; //9507141944
  y0+=(x+'').charAt(i0);
}


//status="x=["+x+"]; y0=["+y0+"]; isNaN(x)=["+isNaN(x)+"] 9507141945";
x=parseFloat(y0);

//9507141947


    with(Math) {
        if ( x <= 0 )
        {
            if (abs(x)-floor(abs(x))==0 )
                return "ComplexInfinity" ;
            else
            {
//status=PI/( sin(PI*x) * exp( loggamma(1-x) ) )
//     +' 9507142004';

g0=loggamma(1-x);
g1=PI/( sin(PI*x) * exp( g0 ) );

// alert("x=["+x+"]; g0=["+g0+"]\ng1=["+g1+"] 9507142021");


 return g1;


// PI/( sin(PI*x) * exp( loggamma(1-x) ) );

            }
        }
        else 
        {
//status= exp(loggamma(x))+' 9507142005' ;

g0=loggamma(x);
g1=exp( g0 ) ;

//alert("x=["+x+"]; g0=["+g0+"]\ng1=["+g1+"] 9507142022");

//          return exp(loggamma(x)) ;

            return g1 ;
        }
} }


// "dynamic assign". One input form
// command serve infinite many graph
// openTable(drawID,table01)
// Because 'drawID' can be any value.
// 9510231220

function openTable(drawID,table01) // 9510221840
{
// 9510221944 add 'table01'
// table01==0 close,  table01==1 open
var openClose="block";
if(table01==0) openClose="none"; //9510221946

var htmlStr= //9510221823
'<TABLE cellSpacing=1 cellPadding=0 width="100%" align=center border=0><TBODY><br><TR id="showlxr'+drawID+'" style="DISPLAY:'+openClose+'" bgColor=#ccfcfc><TD colSpan=7><TABLE width="100%" align=left border=0><TBODY><TR><TD align=right bgColor=#FFFF00 border=0 onclick=open0lxr('+drawID+')>'

+'C<br>L<br>O<br>S<br>E</TD><TD width="100%"><table>  <tr>  <td height="0%">'

+'<input onclick="javascript:DrawGraf2('+drawID+')" type="button" value=" Draw " /><INPUT name=Del0Graph type="button" value="Wipe" onclick=javascript:wipeCurve('+drawID+');><INPUT name=DelAllBox type="button" value="Del ALL" onclick=javascript:delAll('+drawID+')><INPUT name=DelTitle type="button" value="Del title" onclick=javascript:document.getElementById("title0'+drawID+'").value="";><input onclick="javascript:SelectEqn('+drawID+')" type="button" value="Reuse default" /><br>'

+'Title:  <input type="text" id="title0'+drawID+'" value="" size=55 /><br>function 1  x(t) <input type="text" id="func1x'+drawID+'" value="" size=55 /><br>function 1  y(t) <input type="text" id="func1y'+drawID+'" value="" size=55 /><br>function 2  x(t) <input type="text" id="func2x'+drawID+'" value="" size=55 /><br>function 2  y(t) <input type="text" id="func2y'+drawID+'" value="" size=55 /><br>function 3  x(t) <input type="text" id="func3x'+drawID+'" value="" size=55 /><br>function 3  y(t) <input type="text" id="func3y'+drawID
+'" value="" size=55 /><br>function 4  x(t) <input type="text" id="func4x'+drawID+'" value="" size=55 /><br>function 4  y(t) <input type="text" id="func4y'+drawID+'" value="" size=55 /><br>function 5  x(t) <input type="text" id="func5x'+drawID+'" value="" size=55 /><br>function 5  y(t) <input type="text" id="func5y'+drawID+'" value="" size=55 /><br>Each curve at moat 1000 pt. Del function <INPUT name=DelEqn1 type="button" value="1 " onclick=javascript:deleteData(61,'+drawID+');><INPUT name=DelEqn2 type="button" value="2 " onclick=javascript:deleteData(62,'+drawID+');><INPUT name=DelEqn3 type="button" value="3 " onclick=javascript:deleteData(63,'+drawID+');><INPUT name=DelEqn4 type="button" value="4 " onclick=javascript:deleteData(64,'+drawID+');><INPUT name=DelEqn5 type="button" value="5 " onclick=javascript:deleteData(65,'+drawID+');><INPUT name=DelEqnAll type="button" value="ALL" onclick=javascript:deleteData(6000,'+drawID
+');><br>independent variable t step size and begin end &nbsp; <INPUT name=Del0Graph type="button" value="del" onclick=javascript:deleteData(0,'+drawID+');> &nbsp;<input onclick="javascript:DrawGraf2('+drawID+')" type="button" value="Draw" /><br>curve1 step size <input type="text" id="t1Len'+drawID+'" value="" size="6" /> begin <input type="text" id="t1Min'+drawID+'" value="" size="6" /> end <input type="text" id="t1Max'+drawID+'" value="" size="6" /><br>curve2 step size <input type="text" id="t2Len'+drawID+'" value="" size="6" /> begin <input type="text" id="t2Min'+drawID+'" value="" size="6" /> end <input type="text" id="t2Max'+drawID+'" value="" size="6" /><br>curve3 step size <input type="text" id="t3Len'+drawID+'" value="" size="6" /> begin <input type="text" id="t3Min'+drawID+'" value="" size="6" /> end <input type="text" id="t3Max'+drawID+'" value="" size="6" /><br>curve4 step size <input type="text" id="t4Len'+drawID+'" value="" size="6" /> begin <input type="text" id="t4Min'+drawID
+'" value="" size="6" /> end <input type="text" id="t4Max'+drawID+'" value="" size="6" /><br>curve5 step size <input type="text" id="t5Len'+drawID+'" value="" size="6" /> begin <input type="text" id="t5Min'+drawID+'" value="" size="6" /> end <input type="text" id="t5Max'+drawID+'" value="" size="6" /><br>Below one column one curve &nbsp; <INPUT name=Del1Arrow type="button" value="del 5 col" onclick=javascript:deleteData(2,'+drawID+')><br>width &nbsp; &nbsp; &nbsp; &nbsp; <input type="text" id="width1'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="width2'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="width3'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="width4'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="width5'+drawID+'" value="" size="3" /><br>color &nbsp; &nbsp; &nbsp; &nbsp;  <input type="text" id="color1'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="color2'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="color3'+drawID
+'" value="" size="3" /> &nbsp; <input type="text" id="color4'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="color5'+drawID+'" value="" size="3" /><br>'
+'solid/dot  &nbsp; <input type="text" id="style1'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="style2'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="style3'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="style4'+drawID+'" value="" size="3" /> &nbsp; <input type="text" id="style5'+drawID+'" value="" size="3" /><br><form id="arrowform'+drawID+'" action=""><table>Below define one arrow (for many arrow write program)<tr><td>arrow x</td><td><input type="text" size="4" id="x" value="" /> &nbsp; </td><td>arrow y</td><td><input type="text" size="4" id="y" value="" /> &nbsp; </td><td>angle </td><td><input type="text" size="4" id="rotation" value="" /> &nbsp; </td></tr><tr><td>length </td>'
+'<td><input type="text" size="4" id="length" value="" /> &nbsp; </td><td>size</td><td><input type="text" size="4" id="size" value="" /> &nbsp; </td><td>color </td><td><input type="text" size="4" id="color" value="" /></td></tr><tr><td>text</td><td><input type="text" size="4" id="label" value="" /> &nbsp; </td><td>txtColor</td><td><input type="text" size="4" id="labelcolor" value="" /> &nbsp; </td><td>txtSize</td><td><input type="text" size="4" id="labelsize" value="" /></td></tr><tr><td>thickness</td><td><input type="text" size="4" id="lineweight" value="" /> &nbsp; </td><td>solid/dot</td><td><input type="text" size="4" id="dashstyle" value="" /></td><td><INPUT name=Del1Arrow type="button" value="delArrow" onclick=javascript:deleteData(1,'+drawID+')></td></tr></table></form>'
+'<form id="labelform'+drawID+'" action=""><table>Below define one label (for many label write program)<tr><td><!--div id="graphdiv3"></div--></td><td>  <table><tr><td>label x</td><td><input type="text" id="x" size="4" value="" /></td><td>label y</td><td><input type="text" id="y" size="4" value="" /></td></tr><tr><td>angle</td><td><input type="text" id="rotation" size="4" value="" /></td><td>length</td><td><input type="text" id="length" size="4" value="" /></td></tr><tr><td>color</td><td><input type="text" id="labelcolor" size="4" value="" /></td><td>size</td><td><input type="text" id="labelsize" size="4" value="" /></td></tr>'
+'<tr><td>text</td><td><input type="text" id="label" size="4" value="" /></td><td>ptSize</td><td><input type="text" id="pointsize" size="4" value="" /></td></tr><tr><td>fillColor</td><td><input type="text" id="pointfillcolor" size="4" value="" /></td><td>edgColor</td><td><input type="text" id="pointstrokecolor" size="4" value="" /></td></tr><tr><td>ptStyle</td><td><select id="VMLpointshapetype" ><option value="diamond">diamond</option><option value="square">square</option><option value="triangle">triangle</option><option value="circle">circle</option><option value="x">x</option><option value="none" selected="selected">none</option></select></td><td><INPUT name=Del1Arrow type="button" value="delLabel " onclick=javascript:deleteData(3,'+drawID+')></td><td>  <input onclick="javascript:DrawGraf2('+drawID+')" type="button" value="Draw" /></td></tr></table></td></table></form>'
+'<form id="Docform'+drawID+'" name="Docform1">Curve document&nbsp;<INPUT onclick=\'javascript:window.clipboardData.setData("Text",document.getElementById("CurveDoc0'+drawID+'").value)\' type=button value="Copy 0"> &nbsp; <INPUT onclick=\'document.getElementById("CurveDoc0'+drawID+'").value="";\' type=button value="Delete 0"><br><TEXTAREA id=CurveDoc0'+drawID+' name=CurveBox0 rows=8  cols=60 ></TEXTAREA></form>'
+'Drawing board size and X,Y axis range<br>board &nbsp; width<input type="text" id="boardW'+drawID+'" value="300" size="3" />&nbsp;height &nbsp; <input type="text" id="boardH'+drawID+'" value="300" size="3" />&nbsp;in points<br><font color=red>Adjust board size and X,Y range to get X:Y=1:1</font><br>min X <input type="text" id="minX'+drawID+'" value="-10" size="2" /> &nbsp; max X <input type="text" id="maxX'+drawID+'" value="+10" size="2" /> &nbsp; min Y <input type="text" id="minY'+drawID+'" value="-10" size="2" /> &nbsp; max Y <input type="text" id="maxY'+drawID
+'" value="+10" size="2" /><br><form name="aa'+drawID+'"><table><tr><td width=248>Box 1 <input type="radio" name="radio1" checked />0<input type="radio" name="radio1" />1<INPUT onclick=\'javascript:window.clipboardData.setData("Text",document.getElementById("box11'+drawID+'").value)\' type=button value="copy 1"> &nbsp; <INPUT onclick=\'document.getElementById("box11'+drawID+'").value="";\' type=button value="del 1"><TEXTAREA id=box11'+drawID+' name=aaBox11 rows=8  cols=28 >all points x,y coord. store in Box 1</TEXTAREA></td><td width=248>Box 2 <input type="radio" name="radio2" checked />0<input type="radio" name="radio2" />1<INPUT onclick=\'javascript:window.clipboardData.setData("Text",document.getElementById("box12'+drawID+'").value)\' type=button value="copy 2"> &nbsp; <INPUT onclick=\'document.getElementById("box12'+drawID+'").value="";\' type=button value="del 2"><TEXTAREA id=box12'+drawID+' name=aaBox12 rows=8  cols=28 >all points t,x,y coord. store in Box 2\nt is independent variable.</TEXTAREA>'

+'</td>'


+'</tr><tr>'

//9511120720
+'This form let you modify original problem. <br>'
+'You can do small scale change, you can also<br>'
+'change to a brand new equation. At the same<br>'
+'time, please define independent variable t<br>'
+'start point and end point and step size.<br>'
+'You need define drawing board x,y axis range<br>'
+'min X    max X    min Y    max Y<font color=red><br>'
+'Please click [Draw] within this form, change<br>'
+'made appears in new drawing.<br>'
+'If you click [Draw '+drawID+'] outside of this form,<br>'
+'change made discarded.</font><br>'
+'If you do not like the change, please click<br>'
+'[Reuse default]. 9511120730<br>'

+'If you want to keep curve plot as picture file<br>'
+'please <font color=red>press [control] key and press [prt scr]</font><br>'
+'Open paint.exe, paste full screen image to<br>'
+'drawing board. Save to picture file 9511122013<br>'

+'</tr><tr>Box 3 <input type="radio" name="radio3" checked />0 <input type="radio" name="radio3" />1 &nbsp;<input onclick="javascript:DrawGraf2('+drawID+')" type="button" value="Draw" />&nbsp;<INPUT name=FuncButton type="button" value="JS function def." onclick=javascript:open0lxr(102)> &nbsp;<INPUT onclick=\'javascript:window.clipboardData.setData("Text",document.getElementById("box13'+drawID
+'").value)\' type=button value="copy 3"> &nbsp; <INPUT onclick=\'document.getElementById("box13'+drawID+'").value="";\' type=button value="del 3"><br><TEXTAREA id=box13'+drawID+' name=aaBox13 rows=8  cols=60 >Other info. store in Box 3. Default Box 1,2,3 all close\nto increase computing speed. If you need one box open, click \n\"1" next to that box. "0" button is no output. "1" button has output\nIf box 1 open frequently please goto source code to find\n[name="radio1"], change\n<input type="radio" name="radio1"\n checked />0\n<input type="radio" name="radio1"\n />1\nto\n<input type="radio" name="radio1"\n />0\n<input type="radio" name="radio1"\n checked />1\nKey is to move [checked]\nBox 2 find "radio2"\nBox 3 find "radio3"\n9510221011</TEXTAREA>'

+'</tr>'


+'</table></FORM></td></tr><tr>'

+'<td></td></tr></table></TD></TR></TBODY></TABLE></TBODY></TABLE>'


//+'</table></FORM></td></tr><tr><td></td></tr></table></TD></TR></TBODY></TABLE></TBODY></TABLE>'


document.getElementById("putTable"+drawID).innerHTML=htmlStr;
}



// 9506130914 add  open0lxr(xx)
function open0lxr(xx)
{
 var i0;
 var totalWin=1;
 if(xx==100)
 {
  for(i0=101;i0<totalWin+101;i0++)
  closelxr(i0);
 }
 else
 {
  ss=eval("showlxr"+xx);

  if(ss.style.display=="block")
  {ss.style.display="none"
  }
  else
  {ss.style.display="block"
  }
// for(i0=101;i0<totalWin+101;i0++)
// if(i0!=xx) closelxr(i0);
 }
}
function closelxr(yy)
{ss=eval("showlxr"+yy);
  if(ss.style.display=="block")
  {ss.style.display="none"
  }

//9510230255 add next line to save system
// resources
 document.getElementById("putTable"+yy).innerHTML="";
//9510230331 need above line, because when
//click right side yellow stripe to close
//still need to save system resources
}





///////////////////////////////////////////////////////
//2009-06-18-15-57 include the following to jsgraph2.js

// 9506191230
function wipeCurve(d3)
{
document.getElementById("graphdiv"+d3).innerHTML="";
document.getElementById("eqnDoc"+d3).innerHTML=""
}



// DrawGraph() has statistic graph
//             plotting capability
// DrawGraf2() delete statistic graph 9510182128
//
function DrawGraf2(argd2)
{
  var i0,i1,i2,i3,i4,i5;
  var sz1=2; 
  var sz2=5; 
  var sz3=5; 
  var MyGraph = new XYGraph();

  var ev0; 
  var ev1;
  var ev2='[';
  var ev3='[';

  var ouStr1="";
  var ouStr2="";
  var ouStr3="";

// find out if output box 1 is open
  j4=0; 
  var box21=1;
  j5='if(document.aa'+argd2+'.radio1[0].checked==1)box21=0;';
  eval(j5); 

// find out if output box 2 is open
  var box22=1;
  j5='if(document.aa'+argd2+'.radio2[0].checked==1)box22=0;';
  eval(j5);

// find out if output box 3 is open
  var box23=1;
  j5='if(document.aa'+argd2+'.radio3[0].checked==1)box23=0;';
  eval(j5); 

// Default NOT use output box 1,2,3
// to increase process. User can click
// '1' button to open output box.

// Avoid last output mistake to this time
// output. Below clear all output boxes.
document.getElementById("box11"+argd2).value=
document.getElementById("box12"+argd2).value=
document.getElementById("box13"+argd2).value=
''; 

// define storage space for five curve
// data.
// (no point data stored at this step)
  ev0='var MyLines=';  
  ev3='[';
  for(i3=0;i3<sz3;i3++)
  {
    ev3+='""';
    if(i3<sz3-1)ev3+=',';
    else        ev3+=']';
  }
  ev0=ev0+ev3; 
  eval(ev0);
// window.clipboardData.setData("Text",ev0+"\n") 
// alert("The command to create array ev0 has\nbeen copied to clipboard 9510191735");
// ev0 look like  var MyLines=["","","","",""]

// eval(ev0);  is to define this array.

// Above to create array for curves.
// Below assign the property of this array.
// Curve and equation are different.
// Curve is a collection of hundreds point
// x,y coordinates.
// Equation is mathematics expression.
// When variable t in equation is determined
// this equation with known t give one point
// x,y coordinates, which is one element of
// curve array. After curve array get hundred
// x,y data, curve array can be used to plot.
// Equation can not plot directly.

// XYLine() is XYGraph() declaration for line
// Below assign curve array to be new XYLine()
  for(i3=0;i3<sz3;i3++)  
  {
    MyLines[i3] = new XYLine();
  }

// XYGraph default to use thick black curve.
// Next command say curve not use thick square.
  ev0='';
  ev1='MyLines[';
  ev2='].VMLpointshapetype="none";';
  for(i3=0;i3<sz3;i3++)
  {
    ev0=ev1+i3+ev2; //Avoid thick curve
    eval(ev0);      //9510201524 add
  }
// after run MyLines[*].VMLpointshapetype="none";
// curve is thin line, look better.
// [*] means [0] to [4]

  var MyArrow = new Arrow();
  var MyLabel1 = new Label(); 
  var UpLimit=1000; // every curve at most 1000 points
  var LoLimit=2;    // every curve at least 2 points

//determine drawing board size
  var jj= 
  document.getElementById("boardH"+argd2).value;
  jj=parseFloat(jj);
  if(!isNaN(jj)&&jj>0)
  MyGraph.gheight=jj; 
  else 
  MyGraph.gheight=300; 
  jj= 
  document.getElementById("boardW"+argd2).value;
  jj=parseFloat(jj);
  if(!isNaN(jj)&&jj>0)
  MyGraph.gwidth=jj; 
  else
  MyGraph.gwidth=300;
//Above determine drawing board size.
//input table has one line
// board   width 300   height 300 in pt. 
//this line let user determine board size

//define array for five equations
//no equation definition at this step.
  ev0='var eq5xy=';
  ev1='[';
  ev2='[';
  ev3='[';
  for(i3=0;i3<sz3;i3++)
  {
    ev3+='""';
    if(i3<sz3-1)ev3+=',';
    else        ev3+=']';
  }
  for(i2=0;i2<sz2;i2++)
  {
    ev2+=ev3;
    if(i2<sz2-1)ev2+=',';
    else        ev2+=']';
  }
  for(i1=0;i1<sz1;i1++)
  {
    ev1+=ev2;
    if(i1<sz1-1)ev1+=',';
    else        ev1+=']';
  }
  ev0=ev0+ev1; 
  eval(ev0);

if(box23)
ouStr3+=
 "Three index array eq5xy[i1][i2][i3] is defined by [eval(ev0);] ev0=\n"
+ev0+"\n"
+"0<=i1<sz1=2;  x(t),y(t) two expression form one equation.\n"
+"0<=i2<sz2=5;  constant a,b evaluation, variable t evaluation total five steps.\n"
+"0<=i3<sz3=5;  program allow five equation definition. 9510191434\n"
+"i2==0 is user input equation expression.\n";
+"     variable x confuse with exp(); variable t confuse with tan()\n";
+"i2==1 change x to tt and change t to tt\n";
+"i2==2 change a with assigned value (not use at this version)\n";
+"i2==3 change b with assigned value (not use at this version)\n";
+"i2==4 change variable tt to numerical value.\n";
+"eq5xy[*][4][*] can be used to find (x,y) coordinate value.\n";
+"\n";
// above create equation array.
// below read in equation expression.
// user's equation definition copied
// to eq5xy[i1][i2][i3]
// i1=0 f(x); i1=1 f(y);
// [i2]=[0] = user's equation definition
// i3=0 equation 1 ... i3=4 equation 5
  for(i3=0;i3<sz3;i3++)
  {
eq5xy[0][0][i3]=document.getElementById("func"+(i3+1)+"x"+argd2).value;
eq5xy[1][0][i3]=document.getElementById("func"+(i3+1)+"y"+argd2).value;
  } // 9510241220

// user defined equation: eq5xy[*][0][*]
// change x and t to tt : eq5xy[*][1][*]
// change x to tt not confuse with exp()
// change t to tt not confuse with tan()
// user do not input tt directly 9510202120
  for(i3=0;i3<sz3;i3++)
  {
eq5xy[0][1][i3]=toSyntax(eq5xy[0][0][i3]);
eq5xy[1][1][i3]=toSyntax(eq5xy[1][0][i3]);
  }

// define array for five curve
// upper/lower limits
  ev0='var tMinMax=';
  ev1='[';
  ev3='[';
  for(i3=0;i3<sz3;i3++) // sz3=5 five curve
  {
    ev3+='""';
    if(i3<sz3-1)ev3+=',';
    else        ev3+=']';
  }
  for(i1=0;i1<sz1;i1++) // sz1=2 two ends
  {
    ev1+=ev3;
    if(i1<sz1-1)ev1+=',';
    else        ev1+=']';
  }
  ev0=ev0+ev1; 
  eval(ev0);
// above define array
// below read in upper/lower limits
  for(i3=0;i3<sz3;i3++)
  {
    ev0='tMinMax[0]['; // 9510191929
    ev1=']=document.getElementById("t'+(i3+1)+'Min"+argd2).value;';
    ev0+=i3+ev1;
    eval(ev0);   //9510191931

    ev0='tMinMax[1]['; // 9510191929
    ev1=']=document.getElementById("t'+(i3+1)+'Max"+argd2).value;';
    ev0+=i3+ev1;
    eval(ev0);   //9510191932
  } // 9510191933

// string tMinMax[][] '1' + '2' get '12'
// number tMinMax[][] '1' + '2' get 3
// change string tMinMax[][]
//     to number tMinMax[][]
  for(i3=0;i3<sz3;i3++)
  {
tMinMax[0][i3]=parseFloat(tMinMax[0][i3]); // 9510192047
tMinMax[1][i3]=parseFloat(tMinMax[1][i3]);
  }  // 9510192048

//define drawing title NOT ok at 9510221650
//define drawing title here OK   9510221651
    MyGraph.title= 
document.getElementById("title0"+argd2).value;

  var flag0=0;
  for(i3=0;i3<sz3;i3++)
  {
    if(tMinMax[0][i3]>tMinMax[1][i3])
    {
      flag0=1;
    alert("Start point t"+(i3+1)+"="+tMinMax[0][i3]+">"+tMinMax[1][i3]+"=end point t"+(i3+1)+"\n"
+"Allow only t from small to large, allow only positive step size.\n"
+"If you need from large t to small t and negative step size, please modify code.\n"
+"9510191952"
);
    } //9510191952
  }
  if(flag0) return;

//define step size array
  ev0='var tStep=[';  
  for(i3=0;i3<sz3;i3++)
  {
    ev0+='""';
    if(i3<sz3-1)ev0+=',';
    else        ev0+=']';
  }
  eval(ev0); // 9510202129
// above define step size array
// below assign data to step size array
  for(i3=0;i3<sz3;i3++)
  {
tStep[i3]=document.getElementById("t"+(i3+1)+"Len"+argd2).value;
tStep[i3]=parseFloat(tStep[i3]);

    if(tStep[i3]<0)
    {
    alert("Line "+(i3+1)+" step size tStep="+tStep[i3]+"<0\n"
+"This program allow only positive step size.\n"
+"Please modify code for negative step.\n9510192000");
    return;
    }

ev1=0.001; //9510241458

    if(tStep[i3]<ev1)
    {
if(box23)
    ouStr3+='\nCurve '+(i3+1)+' step size was '
+tStep[i3]+' change to '+ev1+'\n'
+'If you need tiny step size, please open '
+'source code.\nFind [ev1=0.001;] modify its value.'
+' 9510241451\n\n';

ev0='document.getElementById("t'+(i3+1)
   +'Len"+argd2).value=tStep[i3]=ev1';
eval(ev0); //9510241443
    }

  } // 9510202134

// Define array for line total steps
// 9510192153
  ev0='var t0Total=';  
  ev3='[';
  for(i3=0;i3<sz3;i3++)
  {
    ev3+='""';
    if(i3<sz3-1)ev3+=',';
    else        ev3+=']';
  }
  ev0=ev0+ev3; 
  eval(ev0);
// Above define array for line total steps
// Below find line total steps
  for(i3=0;i3<sz3;i3++)  
  {
    t0Total[i3]=(tMinMax[1][i3]-tMinMax[0][i3])/tStep[i3];

    if(t0Total[i3]>UpLimit)t0Total[i3]=UpLimit; // 1000
    if(t0Total[i3]<LoLimit)t0Total[i3]=LoLimit; // 2
    if(isNaN(t0Total[i3])) t0Total[i3]=0; // not draw curve.
  }

// Below define x-axis and y-axis range
// XYGraph insist to include (0,0)
// Although user did not include (0,0)
// output still include (0,0) this may
// cause most blank output. 9510211754
  MyGraph.xmax=
  document.getElementById("maxX"+argd2).value;
  MyGraph.xmin=
  document.getElementById("minX"+argd2).value;
  MyGraph.ymax=
  document.getElementById("maxY"+argd2).value;
  MyGraph.ymin=
  document.getElementById("minY"+argd2).value;

// Below define five lines width, color
// solid/dash/dot properties.
// Calculate each point x,y co-ordinate.
  for(i3=0;i3<sz3;i3++)
  {
    k1='document.getElementById("width'
    +(i3+1)+argd2+'").value';
    k1=eval(k1);
    k2='document.getElementById("color'
    +(i3+1)+argd2+'").value';
    k2=eval(k2);
    k3='document.getElementById("style'
    +(i3+1)+argd2+'").value';
    k3=eval(k3);
    k4="\"weight='"+k1+"pt'; color='"
    +k2+"'; dashstyle='"+k3+"';\"";
    MyLines[i3].VMLstroke = eval(k4); 
if(box23)
    ouStr3+="\nCurve "+(i3+1)+" property is defined as below\nk4=["+k4+"]\n\n";//9510201509

// Above define five lines width, color
// solid/dash/dot properties.
// Below calculate each point x,y 
// co-ordinate. t is independent variable.
// Each step, t get a new value, put this
// new value to equation to find new point
// x,y co-ordinate.

    for(j4=0;j4<t0Total[i3];j4++)
    { 
// t get a new value (because j4 is new)
      t = tMinMax[0][i3]+j4*tStep[i3];

// Above t get a value, for example t=0.32
// below change equation tt to above 0.32
// for example sin(tt) change to sin(0.32)
// 9510222211 use 'with(Math){' and '}'
      eq5xy[0][4][i3]='with(Math){'+eq5xy[0][1][i3].replace(/tt/g, t)+'}'
      eq5xy[1][4][i3]='with(Math){'+eq5xy[1][1][i3].replace(/tt/g, t)+'}'

// equation sin(0.32) can be evaluated by
// eval(sin(0.32)) to get value.
// Trigonometric functions must use radian
// as input. 57.2957795 degree = 1 rad.
// After evaluation,
// sin(tt) become sin(0.32)=0.31456
// This is x coordinate (or y coordinate)
//
// Point x,y coord value store to curve array
      MyLines[i3].x[j4]=eval(eq5xy[0][4][i3]);
      MyLines[i3].y[j4]=eval(eq5xy[1][4][i3]);
// Above is used to plot curve.
// Below store same data for reading.
if(box21)
 ouStr1+=MyLines[i3].x[j4]+', '+MyLines[i3].y[j4]+'\n';//9510201217

if(box22)
 ouStr2+=t+', '+MyLines[i3].x[j4]+', '+MyLines[i3].y[j4]+'\n';//9510201217
    } // end of for(j4=0;j4<t0Total[i3];j4++)
      // Above find curve point x,y coord.

    if(box21)
    {
    ouStr1+='Above curve '+(i3+1)+'. Total points: '+t0Total[i3]+'\n';//9510221039
    if(i3<sz3-1)
    ouStr1+='Below curve '+(i3+2)+'. Total points: '+t0Total[i3+1]+'\n';
    }

    if(box22)
    {
    ouStr2+='Above curve '+(i3+1)+'. Total points: '+t0Total[i3]+'\n';//9510221041
    if(i3<sz3-1)
    ouStr2+='Below curve '+(i3+2)+'. Total points: '+t0Total[i3+1]+'\n';
    }

    if(box23)
    {
 ouStr3+='Curve '+(i3+1)+' last point equation is next\n';//9510221032
 ouStr3+='t='+t+'\nx='+eq5xy[0][4][i3]+'\ny='+eq5xy[1][4][i3]+'\n\n';//9510201217
    }

// Next line draw ONE line (assume total five lines)
    MyGraph.Plot(MyLines[i3]); // 9510201141 add drawing command
  }  // end of for(i3=0;i3<sz3;i3++) 

  ev0="arrowform"+argd2; // 9510221402
  for (var i in MyArrow) {
    if (i != "arrowhead") {
    var n = document.forms[ev0][i]; 
    MyArrow[i] = ( n.value !="" ? n.value : null);
    }
  }

// If arrow head location x,y coord. are
// not defined, then not draw arrowhead.
  if( //9506211935
    !(
    document.forms[ev0][0].value==[]
    ||
    document.forms[ev0][1].value==[]
      )
    ) //9506211936 
    MyGraph.Drawarrow(MyArrow);

// if draw graph number 601
// ev0 = "labelform601" in which
// 601 (argd2) determined at run time
// by user click.
ev0="labelform"+argd2; // 9510221403
// If draw graph number 602, argd2=602
// "labelform"+argd2 become labelform602
// argd2 value change at each run. This
// is "dynamic assign". One input form
// command serve infinite many graph
// openTable(drawID,table01)
// Because 'drawID' can be any value.
// 9510231220
// table01==0 is close input form.
// table01==1 is  open input form.

//9506211753 
  for (var i in MyLabel1) { 
  var n = document.forms[ev0][i]; 
  if (n.type != "select-one") { 
  MyLabel1[i] = ( n.value !="" ? n.value : null);
  }
  else {
    MyLabel1[i] = n[n.selectedIndex].value;}
  }

// If label x or y coordinate is 
// not defined, not print label.
  if( //9506211938
    !(
    document.forms[ev0][0].value==[]
    ||
    document.forms[ev0][1].value==[]
     )
    )
  MyGraph.Drawlabel(MyLabel1);

if(box21)
 ouStr1+=
'\nEach line max 1000 points. If draw\n'
+'5 lines, control start/end points and\n'
+'step size such that each line print\n'
+'only 100 to 200 points. If print 5000\n'
+'points in one graph, javascript is slow.\n'
+'9510221117\n'
;

if(box23)
 ouStr3+=
'\nEach line output only equation used by\n'
+'last point. If print for each point, too\n'
+'long output and unnecessary. 9510221050\n'
;

/** 
end of for(i3=0;i3<sz3;i3++)
that is end of five curves.

//define drawing title NOT ok here 9510221650
//define drawing title OK at       9510221651
    MyGraph.title= 
document.getElementById("title0"+argd2).value;
/**/

// Next command send graph data to web page
document.getElementById("graphdiv"+argd2).innerHTML=MyGraph;

// Next command send graph doc. to web page
document.getElementById("eqnDoc"+argd2).innerHTML=document.getElementById("CurveDoc0"+argd2).value;

// print x,y coordinate to output box1
if(box21)
document.getElementById("box11"+argd2).value=ouStr1;//9510221025
// This is not plot curve, this is to
// store each point x,y coordinate,
// user can read and copy value.

// print t,x,y coordinate to output box2
if(box22)
document.getElementById("box12"+argd2).value=ouStr2;//9510221026

// print program notes to output box3
if(box23)
document.getElementById("box13"+argd2).value=ouStr3;//9510201215

} // end of function DrawGraf2(argd2)







// 9510230247
function closeStr(klozID)
{
document.getElementById("putTable"+klozID).innerHTML="";
}
// 9510230248 To save system resources
// when user close input table, delete
// table dynamic string immediately.
// Equal nothing [...=""] that is delete.








//9506191246
//toSyntax(inStr1) change 
//from 't' to '(tt)'
//from 'a' to '(aa)'
//from 'b' to '(bb)'
//avoid confuse
//'t' is independent variable.
//'tan(t)' change to 'tan((tt))'
//'a' and 'b' are variable constant.
//'a*acos(t)' change to '(aa)*acos((tt))'
//'2+b' => '2+bb' when b=-1, 2+-1 ?! error
//'2+b' => '2+(bb)' when b=-1 no trouble
//9506191250
//
function toSyntax(inStr1)
{
  var oustr0=""; //9506191548
  var oustr1=""; //9506191539
  var oustr2=""; //9506191606
  var i0,i1,i2,i3,i4,i5;

//9506191404 't' 'a' 'b' to be replaced
  var tab3="tab";
  var tab3len=tab3.length;
  var inStr2=new Array(tab3len+1); //9506191412

  for(i3=0;i3<=tab3len;i3++)
    inStr2[i3]=""; //9506191614

/**
from
 Math.tan(t*a/b)
*Math.cot(a/b+t*t)/(t/a-1.2*b)
+Math.abs(t+a-b)
to
 Math.tan((tt)*(aa)/(bb))
*Math.cot((aa)/(bb)+(tt)*(tt))/((tt)/(aa)-1.2*(bb))
+Math.abs((tt)+(aa)-(bb))

i2 control 't', 'a', 'b'
inStr2[0] store original string
inStr2[1] store 'tt'ed string
inStr2[2] store 'aa'ed string
inStr2[3] store 'bb'ed string
/**/

  oustr1+=inStr1+'\n';
  inStr2[0]=inStr1;
  for(i2=0;i2<tab3len;i2++)
  {
   for(i1=0;i1<inStr2[i2].length;i1++)
   {
    if(inStr2[i2].charAt(i1)!=tab3.charAt(i2))
    inStr2[i2+1]+=inStr2[i2].charAt(i1); //9506191454
    else// when i2==0 test tab3.charAt(i2)=='t'
    {   // when i2==1 test tab3.charAt(i2)=='a'
        // when i2==2 test tab3.charAt(i2)=='b'
      if(inStr2[i2].charAt(i1-1)=='.' //Math.tan()  't'  left has '.'
       ||inStr2[i2].charAt(i1+1)=='(' //Math.sqrt() 't' right has '('
        ) // tan and sqrt both 't' are not independent variable 't'
       inStr2[i2+1]+=inStr2[i2].charAt(i1); //9506191507. copy 't'
/**
      else
      if( // independent variable 't' NOT neighbor to another alphabet
         (inStr2[i2].charAt(i1+1)>='a' //Math.atan()
        &&inStr2[i2].charAt(i1+1)<='z'
         )
         ||
         (inStr2[i2].charAt(i1-1)>='A' //Math.atan()
        &&inStr2[i2].charAt(i1-1)<='Z'  //9506191641
         )
        ) // 't' is just an example.  'a' and 'b' are same.
/*9506300225 change to next*/
      else
      if( // independent variable 't' NOT neighbor to another alphabet
         ((inStr2[i2].charAt(i1+1)>='a' //Math.atan()
        &&inStr2[i2].charAt(i1+1)<='z'
         )
         ||
         (inStr2[i2].charAt(i1+1)>='A' //Math.atan()
        &&inStr2[i2].charAt(i1+1)<='Z'  //9506191641
         ))
         ||
         ((inStr2[i2].charAt(i1-1)>='a' //Math.atan()
        &&inStr2[i2].charAt(i1-1)<='z'
         )
         ||
         (inStr2[i2].charAt(i1-1)>='A' //Math.atan()
        &&inStr2[i2].charAt(i1-1)<='Z'  //9506191641
         ))
        ) // 't' is just an example.  'a' and 'b' are same.
       inStr2[i2+1]+=inStr2[i2].charAt(i1); //9506191507 copy 't'
      else     // upto here 't' is independent variable 't'
               // 'a' & 'b' are variable constant. change
       inStr2[i2+1]+='('                    // add one '('
                    +inStr2[i2].charAt(i1)  // add one 't' or 'a' or 'b'
                    +inStr2[i2].charAt(i1)  // add one 't' or 'a' or 'b'
                    +')' //9506191512       // add one ')'
      // now 't' change to '(tt)'  ('a', 'b' same)
    } // end of if(inStr2[i2].charAt(i1)!=tab3.charAt(i2))
   }  // end of for(i1=0;i1<inStr1.length;i1++)

    oustr0 =inStr2[i2+1]; //9506191548 for return

  }   // end of for(i2=0;i2<tab3len;i2++)

//9506200807 if input no 't',
//user use 'x' instead of 't'
  if(oustr0.length==inStr2[i2-1].length)
  {       // then change 'x' to '(tt)'
    oustr0=x2t(oustr0); //9506200816
  }

  return oustr0;
}



//9506151257 x2z (here is x2t)
// To evaluate an equation
// if replace 'x' to '-2' directly
// then
// Math.exp(x*x)+Math.max(x,1/x)
// become
// Math.e-2p(-2*-2)+Math.ma-2(-2,1/-2)
// big trouble !!
//
// This function x2t() change from
// Math.exp(x*x)+Math.max(x,1/x)
// to
// Math.exp((tt)*(tt))+Math.Max((tt),1/(tt))
// so that evaluation has no trouble
// evaluation: eval(this.fOfx.replace(/tt/g, i));
// Since Javascript math functions no 'tt'.
//9506151302 x2z (here is x2t)
//9506200814 x2t
function x2t(in0)
{
  var u0;
  var out0="";
  for(u0=0;u0<in0.length;u0++)
  {
    if(in0.charAt(u0)!=='x')
      out0+=in0.charAt(u0);
    else
    {
      if(in0.charAt(u0-1)=='e'
       &&in0.charAt(u0+1)=='p'
        ) // copy Math.exp()
      out0+=in0.charAt(u0);
      else
      if(in0.charAt(u0-1)=='a'
       &&in0.charAt(u0-2)=='m'
        ) // copy Math.max()
      out0+=in0.charAt(u0);
      else// replace 'x' to '(tt)'
      out0+="(tt)"; //9506151309
    } // use 'tt' not use 'z' avoid conflict
  }   // with future math function 9506151348
  return out0;
} //9506151311
  //9506200815 done x2t


// 9506211006
function deleteData(workID,probID)
{
  var s1='document.getElementById("'; //9506211423
  var w1, w2, w3, w4; //9506211427

  w3=probID; //9510181942

  var s2='"+'+w3+').value=';

//This function deleteData(workID)
// use several method to delete data.
// workID==0 use direct delete, fast.
  if(workID==0)
  {
document.getElementById("t1Len"+w3).value=
document.getElementById("t1Min"+w3).value=
document.getElementById("t1Max"+w3).value=
document.getElementById("t2Len"+w3).value=
document.getElementById("t2Min"+w3).value=
document.getElementById("t2Max"+w3).value=
document.getElementById("t3Len"+w3).value=
document.getElementById("t3Min"+w3).value=
document.getElementById("t3Max"+w3).value=
document.getElementById("t4Len"+w3).value=
document.getElementById("t4Min"+w3).value=
document.getElementById("t4Max"+w3).value=
document.getElementById("t5Len"+w3).value=
document.getElementById("t5Min"+w3).value=
document.getElementById("t5Max"+w3).value=
"";
  }
//workID==1 use loop to assign "" to boxes
  else
  if(workID==1) // delete arrow data
  {

//9506211959
for(w1=0;w1<11;w1++)
document.forms["arrowform"+w3][w1].value="";

  }
//workID==2 create string array
//then use loop to assign "" to boxes.
  else
  if(workID==2)
  {
// delete five curve width, color
// solid/dash/dot properties.

//var lbarr= new Array(25);
//9510201953 change 25 to 15
var lbarr= new Array(15);
lbarr=
[
// "varya1",
// "varya2",
// "varya3",
// "varya4",
// "varya5", //this file graph09e.htm 
// "varyb1", //do not use variable 
// "varyb2", //constant 'a', 'b'
// "varyb3", //9510201952 delete 'a', 'b'
// "varyb4", //Change to allow five
// "varyb5", // arbitrary functions.
"width1",
"width2",
"width3",
"width4",
"width5",
"color1",
"color2",
"color3",
"color4",
"color5",
"style1",
"style2",
"style3",
"style4",
"style5"
];
    for(w1=0;w1<lbarr.length;w1++)
    {
      w4=s1+lbarr[w1]+s2+'""';
      eval(w4);
    } //9506211440
  }
  else
  if(workID==3)
  {
//9506211951
for(w1=0;w1<10;w1++)
document.forms["labelform"+w3][w1].value="";

document.forms["labelform"+w3][10].value="none"; //9510221500
  }
  else
  if(workID==61) // 9510221930
  { // delete equation one
document.getElementById("func1x"+probID).value=
document.getElementById("func1y"+probID).value="";
  }
  else
  if(workID==62)
  { // delete equation two
document.getElementById("func2x"+probID).value=
document.getElementById("func2y"+probID).value="";
  }
  else
  if(workID==63)
  { // delete equation three
document.getElementById("func3x"+probID).value=
document.getElementById("func3y"+probID).value="";
  }
  else
  if(workID==64)
  { // delete equation four
document.getElementById("func4x"+probID).value=
document.getElementById("func4y"+probID).value="";
  }
  else
  if(workID==65)
  { // delete equation five
document.getElementById("func5x"+probID).value=
document.getElementById("func5y"+probID).value="";
  }
  else
  if(workID==6000)
  { // delete equation 1,2,3,4,5
document.getElementById("func1x"+probID).value=
document.getElementById("func1y"+probID).value=
document.getElementById("func2x"+probID).value=
document.getElementById("func2y"+probID).value=
document.getElementById("func3x"+probID).value=
document.getElementById("func3y"+probID).value=
document.getElementById("func4x"+probID).value=
document.getElementById("func4y"+probID).value=
document.getElementById("func5x"+probID).value=
document.getElementById("func5y"+probID).value="";
  }
  else
  if(workID==4)
  {
// future use
  }
}




//9507142127
function delAll(probID)
{
  document.getElementById("title0"+probID).value="";
  deleteData(0,probID);
  deleteData(1,probID);
  deleteData(2,probID);
  deleteData(3,probID);
  deleteData(6000,probID);
  document.getElementById("CurveDoc0"+probID).value="";
}
//9507142130



//-->
