// JavaScript
var index = 0;
var T = new Array(4);
var index = 0;
var nw = "";
var mean = 0;
// this is only for Microsoft Exloprer on Win!
var NL="\r\n";

var Delimiters=new Array();
Delimiters[0]=' ';
Delimiters[1]='\n';
Delimiters[2]='';
Delimiters[3]='\t';
Delimiters[4]='\r';
Delimiters[5]='';

function sort()
{
var x=new Array();
x=ParseString(document.theform.data.value );
if (x.length>0) x=bsort(x);
document.theform.data.value="Datos ordenados:"+NL
for (var j=0;j<x.length;j++)
{
document.theform.data.value=document.theform.data.value+x[j]+' '
}
document.theform.data.value=document.theform.data.value+NL+"___________"+NL
return x
}

function calculate()
{
var x=new Array();
x=sort()

var mid1=0
if (x.length>0) mid1=Math.floor((x.length-1)/2)
var mid2=0
if (x.length>0) mid2=Math.ceil((x.length-1)/2)

var m=0
var s=0

for (var j=0;j<x.length;j++)
{
        m+=x[j]
        s=s+x[j]*x[j]
}
if (x.length<2){s=''}else{s=(s-m*m/x.length)/(x.length-1)}
document.theform.data.value=document.theform.data.value+NL+"Parametros estadisticos:"
document.theform.data.value=document.theform.data.value+NL+"Tamano muestra n="+x.length
document.theform.data.value=document.theform.data.value+NL+"  mediana="+((x[mid1]+x[mid2])/2)
document.theform.data.value=document.theform.data.value+NL+"  media="+m/(x.length)
document.theform.data.value=document.theform.data.value+NL+"  varianza=" +s
document.theform.data.value=document.theform.data.value+NL+"  desviacion tipica="
+Math.sqrt(s)

}

function histogram()
{
var x=new Array();
x=sort()



var N=x.length
if (N<1) {alert("Por favor, introduce los datos");N=1; }

var n=NumberOfBins(x[0],x[N-1],N);
if (n<1){n=1}
var cutoff=x[0]-.5*(x[N-1]-x[0])/n



document.theform.data.value=document.theform.data.value+NL+"HISTOGRAM"
document.theform.data.value=document.theform.data.value+NL+cutoff+""
var debug=0;
        var xx ='';
for (j=0;j<x.length;j++)
{
xx=xx+x[j]+' ';
        if (debug>30 )
        {
        document.theform.data.value=document.theform.data.value+NL+" --- stopped: too many stems ---"+NL
        break;
        }
        if (x[j]<cutoff && x.length>0)
        {
        document.theform.data.value=document.theform.data.value+'x'
        }
        else
        {

        cutoff+=(x[N-1]-x[0]+.0000001)/n
        if (x.length>0)
                {
                document.theform.data.value=document.theform.data.value+NL+"    |"
                debug++
                j--
                }
        }
}
document.theform.data.value=document.theform.data.value+NL+(x[N-1]+.5*(x[N-1]-x[0])/n)

}

function boxplot(){
// need to get points and lines


var  nw=window.open("","hist",'toolbar=1,location=0,directories=0,status=0,menubar=0,scrollbars=1,resizable=1,width=500,height=360');
if (navigator.appName!="Microsoft Internet Explorer")nw.focus()
nw.document.write("<HTML><HEAD><TITLE>Box Plot</TITLE></head><BODY BGCOLOR='#FFFFFF'><center>");

nw.document.write ("<APPLET CODE='Grapher.class'")
nw.document.write ("    CODEBASE=http://math.uc.edu/WWW-test/JAVA/ WIDTH=200 HEIGHT=200>")
nw.document.write ("<PARAM name=xaxis value=0>")
nw.document.write ("<PARAM name=yaxis value=0.5>")
nw.document.write ("<PARAM name=formulas value=\" 0 \">")
nw.document.write ("<PARAM name=xlow value=0.5>")
nw.document.write ("<PARAM name=xhigh value=30.5>")
nw.document.write ("<PARAM name=ylow value=-5>")
nw.document.write ("<PARAM name=yhigh value=10>")
nw.document.write ("<PARAM name=points value=\"3 0 3 6 +;28 0 28 6 +;8 0 8 6 +;16 0 16 6 +;23 0 23 6 +\">")
nw.document.write ("<PARAM name=lines value=\"3 5 28 5;8 6 23 6;8 4 23 4;8 4 8 6;23 4 23 6;16 4 16 6\">")
nw.document.write ("<font color=FF0000><h2>No java</h2>Please use java-enabled browser!</font></APPLET>")
nw.document.write ("<br clear=all><form><input type=button value=Salir onClick=window.close()></form>")
nw.document.write ("<br clear=all><P>The box plot is drawn by an applet by Steve Pelikan as part of ")
nw.document.write ("<A HREF='http://math.uc.edu/onex/demo.html'>OnEx</a> project<br clear=all>");
nw.document.write ("</center></body> </html>")
nw.document.close();

}

function stemLeaf()
{
var x=new Array();
x=sort()

var N=x.length
var stem="";
var leaf="";
if (N<1) {alert("Please type your data");N=1}

//first guess for number of classes
var n=Math.floor(Math.sqrt(2*N));
if (n<1){n=1}
if (n>50){n=50}

// decimal multiplier upfront
var stemScale=1

//increment
var delta=1;
var n1=Math.floor(N/4)
var n2=Math.ceil(3*N/4)
var tmp=Math.max(Math.abs(x[n1]),Math.abs(x[n2]))

// adjust main stem size using ``middle of the sample"
while(Math.abs(tmp/stemScale)>1) {stemScale=stemScale*10;}
while (Math.abs(tmp/stemScale)<10){stemScale=stemScale/10;}
// temporary value to adjust n, delta
 tmp=Math.max((x[N-1]-x[0])/n,.00000000001);

// adjust increment delta

while (delta<tmp){ delta=delta*2; if (delta<tmp) delta=delta*5 }
while(delta>tmp) {delta=delta/5; if (delta>tmp) delta=delta/2}

// may need to increase stemScale
while ((x[N-1]-x[0])>(delta+stemScale)*n){stemScale*=10}


//var cutoff=stemScale*Math.floor(10*x[0]/stemScale)/10
var cutoff=stemScale*trunc(10*x[0]/stemScale)/10
document.theform.data.value=document.theform.data.value+NL+"Stem and Leaf Plot"+NL

var debug=0
for (j=0;j<N;j++)
{
        if (debug>30 )
        {
        document.theform.data.value=document.theform.data.value+NL+" --- stopped: too many stems ---"+NL
        break;
        }

        if (trunc(x[j]/stemScale)<trunc(cutoff/stemScale) && x[j]<cutoff)
        {

        stem=trunc(x[j]/stemScale)
        leaf=Math.round(Math.abs(10*(x[j]/stemScale-stem)))
        if (j<N) {document.theform.data.value=document.theform.data.value+leaf;} // +" j="+j+" x="+x[j]

        }
        else
        {
                //while(x[j]>=cutoff)
                {
                //if (eval(prompt("x[j]="+x[j]+" cutoff="+cutoff+"\nEnter 0 to stop",1))==0)break

                stem=trunc(cutoff/stemScale)+"|"

                // special handling of stem 0 is needed
                if (cutoff<0 && trunc(cutoff/stemScale)==0 && x[j]<0) {
                stem="-"+stem
                }
                cutoff+=Math.min(delta,stemScale)
                // correct rounding errors
                cutoff=stemScale*trunc(10*cutoff/stemScale)/10
                while (stem.length<8) {stem=' '+stem;}
                document.theform.data.value=document.theform.data.value+NL+stem
                debug++
                }
        j--;
        }
}
document.theform.data.value=document.theform.data.value+NL+"Multiply stems by "+stemScale
}


function NumberOfBins(min,max,N)
{
// think about triangular density
 var tNumInt=1+Math.floor(Math.sqrt(2*N));

if (min>=max) tNumInt=1
// check automatic choice with user
tNumInt=eval(prompt("¿Cuántos intervalos?",tNumInt));
return tNumInt-1;
}

function ParseString(string)
{
var x=new Array();

var tmp=string.indexOf("_")
if (tmp>0) string=string.substring(0,tmp)

var  i=string.indexOf(":")+1
var  ii=0;
  temp="";
  while(i<string.length)
    {
      c=string.charAt(i);
      while((c == Delimiters[0] ||  c == Delimiters[1] || c ==
Delimiters[2] || c == Delimiters[3] || c == Delimiters[4] ||  c ==
Delimiters[5]) && i<string.length)
        {
          i++;
          c=string.charAt(i);
        }
      temp="";
      while(c != Delimiters[0] &&  c != Delimiters[1] && c !=       Delimiters[2] && c != Delimiters[3] && c != Delimiters[4]&& c != Delimiters[5] && i<string.length)
        {
          if (c!= ',' && c!=' ' && c!='\n' && c!='\r' && c!='\t')
                {
                temp=temp+c;
                }
          i++;
          c=string.charAt(i);
        }
         if (temp != "")
        {
              x[ii]=temp;
        }
        // should do it only for correct temp that have
         if (temp != "") {ii++;}
 }

for(i=0;i<x.length;i++) x[i]=parseFloat(x[i]);

x.length=ii;
return x;
}

function trunc(x) {
  var s = (x<0)?-1:1;
  return s*Math.floor(Math.abs(x));
}

function bsort(x)
{
  var N = x.length -1;
  var done = false;
  while (done == false)
    {
      done = true;
      for (i=0; i<N; i++)
        {
          if (x[i] > x[i+1])
            {
              var t = x[i];
              x[i] = x[i+1];
              x[i+1] = t;
              done = false;
            }
        }
      N--;
    }

  return x;
}


function intlabels(y1,y2,tnumint){
  var diff =y2-y1;
  if (diff<0) {diff=-diff; }
if (diff==0){diff=.000000001}
  var x= intervals(diff,tnumint);
if (x<diff && x<1){x=1}
var bot = trunc(y1/x)*x;
// correction
//bot-x makes for better rounding of negatives WB
  var yy = bot-x;
  L = new Array();
  var i = 0;
  var xx = 0;
  while (yy-x < y2) {
    L[i] = yy;
    yy += x;
    i++;
    xx++;
    if (xx > 100) {break};
  }
// assign bigger value WB
  L[i] = yy;
  L[i+1] = yy+x;
        return L;
}
function intervals(diff, NumCats) {
  var t4 = trunc(Math.log(diff) * 0.4342945);

  t4 = Math.pow(10,t4);
if (t4==0){t4=10/(diff+1);}

  T[3]= t4;
  T[2] = t4/2;
  T[1] = t4/5;
  T[0] = t4/10;

  var A = new Array(4);

  for (i = 0;i < 4; i++) {
                A[i] = trunc(diff/T[i]) +1;
  }
  var D = Math.abs(10 - A[0]);
  index = 1;
  for (i = 1; i < 4; i++) {
    if (A[i] <= 25) {
      if (A[i] > 2) {
        XX = Math.abs(NumCats - A[i]);
        if (XX < D) {
          D = XX;
          index = i+1;
        }
      }
    }
  }

  return T[index-1];
}

function stemandleaf(x)
{

  nw.document.write("<b>Gr&aacute;fico de Tallos y Hojas</b>");
  var didzero = false;
  var N = x.length;
if (N==0){
 alert("Please type your data");
}
  var tNumInt=1;
  if (N<20)
    {
      tNumInt = 5;
    }
  else
    {
      if (N < 100)
        {
          tNumInt = 10;
        }
      else
        {
          if (N < 150)
            {
              tNumInt = 15;
            }
          else
            {
              tNumInt = 20;
            }
        }
    }

    if (N<1) {tNumInt=2;}
    // make sure N-1 is defined
  if (!N || N<1){N=1}
  var theMax = x[N-1];
  var theMin = x[0];
var BIGFIX="";
if (theMax<0){
        BIGFIX="-"
 for (var i = 0; i < N ; i++)
      {
        x[i] *= -1;
      }
 x=bsort(x);
theMax = x[N-1];
theMin = x[0];
}

//alldone = false;
  var ratio=1;
  if (theMax - theMin < 10 && theMax>theMin) {
    ratio = 1000/(theMax - theMin);
    ratio = Math.max(ratio,1000);
if (ratio<=0){ratio=1}
    ratio = trunc(Math.log(ratio) * 0.4342945);
    ratio = Math.pow(10,ratio);
    for (var i = 0; i < N ; i++)
      {
        x[i] *= ratio;
      }
  }

  var zcount = 0;
  theMin = x[0];
  var abMin = Math.abs(theMin);
  theMax = x[N-1];
  var Y = intervals(theMax-theMin,tNumInt);

  var indexA = index +0;
var ncats = 1;
var newz = 0;
  if (indexA== 2)
    {
      Y *= 5;
      ncats =5 ;
      newz = 1;
    }

      if(indexA==3)
        {
          Y *= 2;
           ncats = 2;
        }

  var cutoffs = intlabels(x[0], x[N-1], tNumInt);
  theMax = ratio * Math.round(theMax);

  var nc = cutoffs.length;
  if (nc<2) {nc=2}
  var xx8=0;
  while (cutoffs[nc-2] > Math.abs(theMax) && nc>2)
    {
      nc--;
    }
  theMax = cutoffs[nc-2];

  if (Y > Math.abs(theMax))
    {
      nc++;
      while(Y > Math.abs(theMax))
        {
          xx8++;
          if(xx8>100){break;}
          if (nc > cutoffs.length && nc>2)
            {
              var temp = cutoffs[nc-2] - cutoffs[nc - 3];
              temp += cutoffs[nc-2];
              cutoffs[nc-1] = temp;
            }
          theMax = cutoffs[nc-1];
          nc++;
        }
    }
if (Y==0){Y=1}
  var base = trunc(theMax/Y);
if (base==0){base=1}
  var leftover = Math.round(theMax - base * Y);
  while (Math.abs(leftover) > 10)
    {
      leftover = Math.abs(Math.round(leftover/10));
    }

  var theMax2 = Math.max(theMax,abMin);
  var t4 = trunc(theMax2/base);
if (t4<0){t4=1/Math.abs(theMax)+1}
  t4 = trunc(Math.log(t4) * .4342945);
  t4 = Math.pow(10,t4);
if (t4==0){t4=1/Math.abs(theMax)+1}
  var t3 = t4/10;

  if (indexA == 2)
    {
      if (leftover >= 8)
        {
          var newz = 1;
        }
    else
      {
        if (leftover >= 6)
          {
            var newz = 0;
          }
        else
          {
            if (leftover >= 4)
              {
                var newz = 4;
              }
            else
              {
                if (leftover >= 2)
                  {
                    var newz = 3;
                  }
                else
                  {
                    var newz = 2;
                  }
              }
          }
      }
    }
  else
    {
    if (indexA == 3)
      {
        if (leftover >=5)
          {
            var newz = 1;
          }
        else
          {
            var newz = 0;
          }
      }
    }
  var start = false;
  var LN = 1;
  var LN2 = 0;
  var nn = N;
  var cur = cutoffs[nc-2];
  var count = nc-2;
  var base2=base;
  var newline = true;
  var stems = new Array();
  var leaves = new Array();
  stems[0] = base2;
  leaves[0] = "";

  for (var i = nn-1; i >= 0 ; i--)
    {
    var it = x[i];
    var dd = Math.round(it/t3) * t3;
    var b = trunc(dd/t4);
    var L = dd-t4*b;
    leftover = Math.abs(Math.round(L/t3));
    while (leftover >= 10)
      {
        leftover = Math.round(leftover/10);
      }
    if (it >=0)
      {
        var tt = t3;
      }
    else
      {
      var tt = -t3;
      }
    var xz = b * t4 + leftover * tt;
    if (it<0)
      {
        if (xz > 0 )
          {
            xz = xz * -1;
          }
        xz -= .00001;
      }
    if (xz<cur)
      {
        newline = true;
      while (xz<cur)
        {
          LN ++;
          if (start)
            {
              LN2++;
              leaves[LN2] = "";
            }
          var temp =1;
        if (ncats>0){temp= trunc(LN/ncats);}
          temp = LN - temp*ncats;
        if(temp == newz)
          {
          if (base2 == 0)
            {
            if (didzero)
              {
                base2 -= 1;
              }
            else
              {
                didzero = 1;
              }
          }
          else
            {
              base2 -= 1;
            }
          }

        count -= 1;
        if (count < 0)
          {
            cur = xz -1000;
          }
        else
          {
            cur = cutoffs[count];
          }
        if (base2 == 0)
          {
            zcount ++;
            if ( ((indexA == 2) && (zcount >=6)) || ((indexA == 3) && (zcount >=3)) || ((indexA == 1) && (zcount >1)) || ((indexA == 4) && (zcount >1))) {
              stems[LN2] = "-" + base2;
            }
            else
              {
                stems[LN2] = base2;
              }
          }
        else
          {
            stems[LN2] = base2;
          }

        }


      }
    start = true;
    leftover += "";
    if (it>=0)
      {

      leaves[LN2] = leftover + "" + leaves[LN2];

      }
    else
      {
        leaves[LN2] = leaves[LN2] + "" + leftover;
      }
    }

  for (var i = 0; i < N ; i++) {
    x[i] /= ratio;
  }

  nw.document.write ("<br> <pre>");
  nw.document.write (" Tallos Hojas" + "<br>")
    for (i=0;i<leaves.length; i++){
      var test = " " +BIGFIX+ stems[i];
      while (test.length < 8) {
        test = " " + test}
      test += "|";
      nw.document.write(test +  leaves[i] + "<br>");

    }

  nw.document.write ("</pre>");
  nw.document.write("<FONT SIZE='-1'><p>  Tallos de tama&ntilde;o " + t4/ratio + "<br>")
    nw.document.write(" Hojas de tama&ntilde;o " + t3/ratio +"<br>"+" (Si el Tallo es positivo o por  -" + t3/ratio + "  si el Tallo es negativo).<p></font><p><p>");

}


//var x=new Array();
function main()
{
  nw = window.open("","Output", "toolbar=no,location=no,directories=no,status=no,menubar=yes,scrollbars=yes,resizable=yes,width=350,height=350");
  if (navigator.appName!="Microsoft Internet Explorer") nw.focus()
nw.document.clear()

nw.document.write("<HTML><HEAD><TITLE>Diagrama de tallos y hojas</TITLE></head><BODY BGCOLOR='#FFFFFF' >");
  //Parse the data from the field data
  //ParseString(document.theform.data.value );//Now x has the data
  //x=bsort(x);//Macs and Bill G's product don't do array.sort()
var x=new Array();
x=sort();

  stemandleaf(x);
  nw.document.write("<form> <center><input name=nic type=button value=Salir onClick=\"window.close()\"></center></form></body></html>");
  nw.document.close();
}

function compare (a,b) {
  return a-b;
}
