DBL_EPSILON = 2.220446049250313E-16;
DBL_MIN = Number.MIN_VALUE;
DBL_MAX = Number.MAX_VALUE;
eps_correction = 0;
rounding_eps = 1e-7;

h = 1.5;
h5 = 0.5 + 1.5*h;
shrink_sml = 0.75;

return_bounds = 1;

function plot(){
	var x = new Array();
	var y = new Array();
	a = document.f1.data1.value.split("\n");
	for(i=0;i<a.length;i++){
		x[i] = parseFloat(a[i].split(',')[0]);
		y[i] = parseFloat(a[i].split(',')[1]);
	}

	var x_breaks = pretty(x);
	var y_breaks = pretty(y);

	var x_max = x_breaks[x_breaks.length-1];
	var x_min = x_breaks[0];
	var y_max = y_breaks[y_breaks.length-1];
	var y_min = y_breaks[0];

	var svgwidth = parseFloat(document.f1.width.value);
	var svgheight = parseFloat(document.f1.height.value);

	var win1 = window.open("plot.html","newwin1","resizable=yes,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,width="+String(svgwidth)+",height="+String(svgheight+40));

	win1.resizeTo(svgwidth,svgheight+40);
	win1.moveTo(320,20);
	while(win1.document.readyState!='complete'){}

	var svgdoc = win1.svgdoc.getSVGDocument();
	var svgroot = svgdoc.documentElement;

	win1.document.svgdoc.setAttribute("width",svgwidth);
	win1.document.svgdoc.setAttribute("height",svgheight);

	svgroot.setAttribute("width",svgwidth);
	svgroot.setAttribute("height",svgheight);

	svgroot.getElementById("plotarea").setAttribute("transform","translate("+String(0.20*svgwidth)+","+String(0.20*svgheight)+")");

	var bg = svgroot.getElementById("bg");
	bg.setAttribute("width",svgwidth);
	bg.setAttribute("height",svgheight);
	bg.setAttribute("fill",document.f1.col_bg.value);

	var plane = svgroot.getElementById("plane");
	plane.setAttribute("width",0.65*svgwidth);
	plane.setAttribute("height",0.65*svgheight);
	plane.setAttribute("x",-0.025*svgwidth);
	plane.setAttribute("y",-0.025*svgheight);
	plane.setAttribute("fill",document.f1.col_plotarea.value);
	plane.setAttribute("stroke",document.f1.col_line.value);

	svgroot.getElementById("points").setAttribute("style","pointer-events:all; fill:none;stroke:"+document.f1.col_point.value+";");

	for(i=0;i<a.length;i++){
		if(!(isNaN(x[i])||isNaN(y[i]))){
		var circle = svgdoc.createElement("circle");
		var plotx = 0.6*svgwidth*(x[i]-x_min)/(x_max-x_min);
		var ploty = 0.6*svgheight*(y_max-y[i])/(y_max-y_min);
		circle.setAttribute("cx",plotx);
		circle.setAttribute("cy",ploty);
		circle.setAttribute("r",(svgwidth+svgheight)/250);
		circle.setAttribute("id","x="+x[i]+" | y="+y[i]);
		svgroot.getElementById("points").appendChild(circle);
		}
	}

	var texts = svgroot.getElementById("texts");
	texts.setAttribute("style","text-anchor:middle; font-size:"+String((svgwidth+svgheight)/60.0)+";fill:"+document.f1.col_text.value+";");

	var xlab = svgroot.getElementById("xlab");
	xlab.setAttribute("x",svgwidth/2.0);
	xlab.setAttribute("y",svgheight*0.975);
	xlab.firstChild.setNodeValue(document.f1.xlab.value);

	var ylab = svgroot.getElementById("ylab");
	ylab.setAttribute("x",svgwidth*0.05);
	ylab.setAttribute("y",svgheight/2.0);
	ylab.firstChild.setNodeValue(document.f1.ylab.value);
	ylab.setAttribute("transform","rotate(270,"+String(svgwidth*0.05)+","+String(svgheight/2.0)+")");

	var title = svgroot.getElementById("title");
	title.setAttribute("x",svgwidth/2.0);
	title.setAttribute("y",svgheight*0.1);
	title.firstChild.setNodeValue(document.f1.title.value);

	svgroot.getElementById("xcalib").setAttribute("style","stroke:"+document.f1.col_line.value+";");
	svgroot.getElementById("ycalib").setAttribute("style","stroke:"+document.f1.col_line.value+";");


	for(i=0;i<x_breaks.length;i++){
		var calib = svgdoc.createElement("line");
		var x1 = 0.6*svgwidth*(x_breaks[i]-x_min)/(x_max-x_min);
		var x2 = x1;
		var y1 = 0.6*svgheight;
		var y2 = 0.625*svgheight;
		calib.setAttribute("x1",x1);
		calib.setAttribute("x2",x2);
		calib.setAttribute("y1",y1);
		calib.setAttribute("y2",y2);
		svgroot.getElementById("xcalib").appendChild(calib);

		var caltext = svgdoc.createElement("text");
		caltext.setAttribute("x",x1+0.2*svgwidth);
		caltext.setAttribute("y",0.675*svgheight+0.2*svgheight);
		caltext.appendChild(svgdoc.createTextNode(x_breaks[i]));
		svgroot.getElementById("xcaltext").appendChild(caltext);
	}

	for(i=0;i<y_breaks.length;i++){
		var calib = svgdoc.createElement("line");
		var x1 = -0.025*svgwidth;
		var x2 = -0.0125*svgwidth;
		var y1 = 0.6*svgheight*(y_max-y_breaks[i])/(y_max-y_min);
		var y2 = y1;
		calib.setAttribute("x1",x1);
		calib.setAttribute("x2",x2);
		calib.setAttribute("y1",y1);
		calib.setAttribute("y2",y2);
		svgroot.getElementById("ycalib").appendChild(calib);

		var caltext = svgdoc.createElement("text");
		var caltspan = svgdoc.createElement("tspan");
		caltspan.setAttribute("style","baseline-shift:sub;");
		caltext.setAttribute("x",-0.04*svgwidth+0.2*svgwidth);
		caltext.setAttribute("y",y1+0.2*svgheight);

		caltspan.appendChild(svgdoc.createTextNode(y_breaks[i]));
		caltext.appendChild(caltspan);
		svgroot.getElementById("ycaltext").appendChild(caltext);

	}
}

function pretty(x){
	var ndiv = 5;
	var min_n = Math.round(ndiv/3-0.5);
	var lo = x[0]; var up = x[0];
	for(i=1;i<a.length;i++){
		if(x[i]<lo) lo = x[i];
		if(x[i]>up) up = x[i];
	}
	var dx = up - lo;
	var cell = 0;
	var i_small = true;
	if((dx==0) && (up ==0)){
		cell = 1;
		i_small = true;
	}
	else{
		cell = Math.max(Math.abs(lo),Math.abs(up));
		var U = 1 + (h5 >= 1.5*h+0.5) ? 1/(1+h) : 1.5/(1+h5);
		i_small = dx < cell * U * Math.max(1,ndiv) * DBL_EPSILON*3;
	}

	if(i_small){
		if(cell > 10)
			cell = 9 + cell/10;
		cell *= shrink_sml;
		if(min_n > 1) cell /= min_n;
	}
	else{
		cell = dx;
		if(ndiv > 1) cell /= ndiv;
	}

	if(cell<20*DBL_MIN) cell = 20*DBL_MIN;
	else if(cell*10 > DBL_MAX)
		cell = 0.1*DBL_MAX;

	var base = Math.pow(10.0,Math.floor(Math.log(cell)/Math.LN10));

	unit = base;
	if((U= 2*base)-cell <  h*(cell-unit)){ unit = U;
	if((U= 5*base)-cell < h5*(cell-unit)){ unit = U;
	if((U=10*base)-cell <  h*(cell-unit)) unit = U;}}

	var ns = Math.floor(lo/unit+rounding_eps);
	var nu = Math.ceil(up/unit-rounding_eps);

	if(eps_correction && (eps_correction > 1 || !i_small)){
		if(lo) lo *= (1-DBL_EPSILON); else lo = -DBL_MIN;
		if(up) up *= (1+DBL_EPSILON); else up = +DBL_MIN;
	}

	while(ns*unit > lo + rounding_eps*unit) ns--;
	while(nu*unit < up - rounding_eps*unit) nu++;

	var k = Math.floor(0.5 + nu - ns);
	if(k < min_n){
		k = min_n - k;
		if(ns >= 0.){
			nu += k/2;
			ns -= k/2 + k%2;
		} else{
			ns -= k/2;
			nu += k/2 + k%2;
		}
		ndiv = min_n;
	} else
		ndiv = k;

	if(return_bounds){
		if(ns * unit < lo) lo = ns * unit;
		if(nu * unit > up) up = nu * unit;
	} else{
		lo = ns;
		up = nu;
	}

	var breakpoints = new Array(ndiv+1);
	for(i=0;i<=ndiv;i++)
		breakpoints[i] = myRound(lo + i*unit,unit);

	return(breakpoints);
}

function myRound(x,base){
	var maxdec = Math.pow(10,Math.ceil(Math.abs(Math.log(base)/Math.LN10)));
	var bb = Math.round(x*maxdec)/maxdec;
	return bb;
}
