
function XYLine() {

	this.x = new Array();
	this.y = new Array();
	

	this.VMLstroke = "weight='1pt'; color='blue'; dashstyle='solid';";
	this.drawline=true;	// set to true or false



	this.label = "line";	// displayed when mouse is over line


	this.VMLpointshapetype="diamond";	// [ diamond, square, triangle, circle, x, none ]
	this.drawpoints=true;	 	// set to true or false



	this.pointsize=5;	 	// shape display size in "pt"
	this.pointfillcolor="blue";	// point fill color
	this.pointstrokecolor="black";	// point line color
}




function XYGraph() {


	this.rrates = new Array();

	this.xmax=null;
	this.xmin=null;
	this.ymax=null; 
	this.ymin=null;



	this.title=null;
	this.xaxis=null;
	this.yaxis=null;



	this.xscale=null;
	this.yscale=null;


	this.xint=0;
	this.yint=0;



	this.gheight=300;	// Plotting height in "pt"
	this.gwidth=370;	// Plotting width in "pt"
	this.pad_top=10;	// Internal padding margins in "pt"
	this.pad_bottom=10;
	this.pad_left=10;
	this.pad_right=20;

	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.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; color: '#39386B';";  // 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.Plot = function (XYLine) {


	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;}
	if (this.xint < this.xmin) {this.xint=this.xmin;} 
	if (this.yint < this.ymin) {this.yint=this.ymin;}
	if (this.xint > this.xmax) {this.xint=this.xmax;}
	if (this.yint > this.ymax) {this.yint=this.ymax;}


	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;

  for (n=0; n<lines.length; n++) {
	j=0; tempx = new Array(); tempy = new Array();
	linelen = (lines[n].y.length > lines[n].x.length ? lines[n].x.length : lines[n].y.length);
	for (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];
			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]; 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]; 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)].x=lines[n].x.slice(i);
			lines[(lines.length-1)].y=lines[n].y.slice(i); 
			lines[n].x=tempx; lines[n].y=tempy;
			clipped=true;

			break; 
			}
		}
		else if (i > 1000) {
			lines[n].drawpoints = 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)].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;
  }
	xmax = (this.xmax ? Number(this.xmax) : xmax); 
	xmin = (this.xmin ? Number(this.xmin) : xmin);
	ymax = (this.ymax ? Number(this.ymax) : ymax); 
	ymin = (this.ymin ? Number(this.ymin) : ymin);

	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;}



	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;


	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
	


	if (xint < xmin) {xmin=xint;}
	if (xint > xmax) {xmax=xint;}


     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);
     }


	if (!clipped) {
		ymin = (ymin%yscale ? ymin-ymin%yscale-yscale : ymin);
		ymax = (ymax%yscale ? ymax-ymax%yscale+yscale : ymax);
	}


	if (xticloc!="none") {
	xticlabels = new Array(); xticcharnum=1;
	numxticleft = Math.floor((xint-xmin)/xscale); 
	numxtic = numxticleft+Math.floor((xmax-xint)/xscale)+1;
	for (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);
			xticlabels[i]=this.rrates[xticlabel-1];			



			
			break;
		}
		xticcharnum=Math.max(xticcharnum,String(xticlabels[i]).length);
	}}
	xticcharnumlast=String(xticlabels[i-1]).length;


	if (yticloc!="none") {
	yticlabels = new Array(); yticcharnum=0;
	numyticbot = Math.floor((yint-ymin)/yscale);
	
	numytic = numyticbot+Math.floor((ymax-yint)/yscale)+1;

	for (i=0; i<numytic; i++) {
		yticlabel=(i-numyticbot)*yscale+yint;
		negstr=""; expstr=0;
		if (yticlabel < 0) {yticlabel*=-1; negstr="-";}
		switch (true) { 
		default:
			//Ian Removed
			//yticlabel=(Math.round(yticlabel*Math.pow(10,3)))/Math.pow(10,3);
			yticlabel=(Math.round(yticlabel*Math.pow(10,4)))/Math.pow(10,4);
			yticlabels[i]=negstr+String(yticlabel).slice(0,6);
			break;
		} 
		yticcharnum=Math.max(yticcharnum,String(yticlabels[i]).length);
	}}



	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);

	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>';


	gstr+='<v:line from="'+gxmin+','+Math.round(gyint)+'" to="'+gxmax+','+Math.round(gyint)+'" ><v:stroke '+this.VMLmajoraxisstroke+' /></v:line>';
	

	gstr+='<v:line from="'+Math.round(gxint)+','+gymin+'" to="'+Math.round(gxint)+','+gymax+'" ><v:stroke '+this.VMLmajoraxisstroke+' /></v:line>';


	yticmin=gyint+numyticbot*gytic;
	for (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>';}
	}


	xticmin=gxint-numxticleft*gxtic;
	for (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>';}
	}


	gstr+='<v:shape style="'+gstyle+'"><v:path v="';
	for (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>';


	gstr+='<v:shape style="'+gstyle+'"><v:path v="';
	for (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>';


	if (this.title) {
	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*title_pt*0.25)+'pt;">'+this.title+'</span>';
	}
	if (this.xaxis) {
	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*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>';
	}



  for (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>';
  }}


  for (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);
		//gstr+='" title="'+lines[n].x[i]+','+lines[n].y[i]+'" fillcolor="'+lines[n].pointfillcolor+'"';
		gstr+='" title="'+this.rrates[i]+','+lines[n].y[i]+'" fillcolor="'+lines[n].pointfillcolor+'"';
		gstr+=' strokecolor="'+lines[n].pointstrokecolor+'" />';
	}
  }}



	if (xticloc!="none") {
	for (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>';
	}}


	if (yticloc!="none") {
	for (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>';
	}}



	gstr+='</v:group>';
	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




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







