home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 November / PCWorld_2000-11_cd.bin / Komunik / sambar444 / _SETUP.1 / BARCHART.JS < prev    next >
Text File  |  1998-08-07  |  17KB  |  555 lines

  1. <SCRIPT Language="JavaScript">
  2. <!--
  3. ////////////////////////////////////////////////////////////////////////
  4. //                     Bar Chart v4.0 - 7/4/98
  5. //               Copyright (C) 1998 Michael Brownlow
  6. //
  7. // This program is free software; you can redistribute it and/or modify
  8. // it under the terms of the GNU General Public License as published by
  9. // the Free Software Foundation; either version 2 of the License, or
  10. // (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License
  18. // along with this program; if not, write to the Free Software
  19. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. //
  21. // For questions and comments, please email the author at:
  22. // starten@atdot.org
  23. // http://ctelcom.net/mike/java/barchart/
  24. // http://ctelcom.net/mike/
  25. ////////////////////////////////////////////////////////////////////////
  26. // Chart constructor:
  27. /////////////////////
  28. // title    : Title for graph
  29. // hlabel    : Label for horizontal axis
  30. // vlabel    : Label for vertical axis
  31. // orientation    : "horizontal" or "vertical"
  32. // hsize        : length of horizontal axis (left and right)
  33. // vsize        : length of vertical axis (up and down)
  34. // barsize    : width/length of bar as a percentage of the axis length
  35. //                it is on divided by the number of bars
  36. // tickimg    : image to use for scale tick
  37. // baseimg    : image to make base of graph
  38. // ticks    : approximate # of ticks to show
  39.  
  40. function Chart (
  41.   title,
  42.   hlabel,
  43.   vlabel,
  44.   orientation,
  45.   hsize,
  46.   vsize,
  47.   barsize,
  48.   tickimg,
  49.   baseimg,
  50.   ticks
  51. ) {
  52. // User defined
  53.   this.title       = title;
  54.   this.hlabel      = hlabel;
  55.   this.vlabel      = vlabel;
  56.   this.orientation = orientation;
  57.   this.hsize       = hsize;
  58.   this.vsize       = vsize;
  59.   this.barsize     = barsize;
  60.   this.tickimg     = tickimg;
  61.   this.baseimg     = baseimg;
  62.   this.ticks       = ticks;
  63.  
  64. // System defined
  65.   this.scale       = new Array();
  66.   this.data        = new Array();
  67.   this.scalesize   = 0;
  68.   this.labelsize   = 0;
  69.   this.scaledelta  = 0;
  70. }
  71.  
  72. // Data constructor:
  73. ////////////////////
  74. // label    : the label to show for the bar
  75. // num      : the number to use (can be int or float)
  76. // img      : the image to use for the bar
  77. // url      : the url for the bar to link to ("-1" for no link)
  78.  
  79. function Data (label, num, img, url) {
  80.   this.label = label;
  81.   this.num   = num;
  82.   this.img   = img;
  83.   this.url   = url;
  84. }
  85.  
  86. ///////////////////////////////////////////////
  87. // Special definitions
  88. var border = 0;
  89.  
  90. ///////////////////////////////////////////////
  91. // __chart : chart to plot
  92. // popup   : 1 or 0
  93. // preinit : if you already have a window to draw to specify it
  94. //           here, otherwise use "__default"
  95. function doChart(__chart,popup,preinit) {
  96.   if(popup == 1) {
  97.     if(preinit != "__default") {
  98.       drawChart(__chart,preinit);
  99.     } else {
  100.       __popup = open("","__popup","width=400,height=300");
  101.       __popup.document.write("<BODY Bgcolor=#FFFFFF>\n");
  102.       drawChart(__chart,__popup);
  103.       __popup.document.close();
  104.     }
  105.   } else {
  106.     drawChart(__chart,window);
  107.   }
  108. }
  109. ///////////////////////////////////////////////
  110.  
  111. function initChart(__chart,__win) {
  112.   var max = __chart.data[0].num;
  113.   var min = __chart.data[0].num;
  114.   
  115.   for(var i=0; i<(__chart.data.length); i++) {
  116.     if(max <= __chart.data[i].num)
  117.       max = __chart.data[i].num;
  118.   
  119.     if(min >= __chart.data[i].num)
  120.       min = __chart.data[i].num;
  121.   }
  122.  
  123.   computeAutoScale(max,min,__chart);
  124.   
  125.   if(__chart.orientation == "vertical") {
  126.     __chart.labelsize = __chart.hsize / __chart.data.length
  127.   } else {
  128.     __chart.labelsize = __chart.vsize / __chart.data.length
  129.   }
  130.   __chart.barsize = (__chart.barsize / 100) * __chart.labelsize;
  131. }
  132.  
  133. function drawChart(__chart,__win) {
  134.   initChart(__chart,__win);
  135.  
  136.   __win.document.write(
  137.     "<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0><TR>"
  138.   );
  139.  
  140.   doTitle(__chart,__win);
  141.  
  142.   __win.document.write("</TR><TR>");
  143.  
  144.   doVlabel(__chart,__win);
  145.   doTopL(__chart,__win);
  146.   doTopR(__chart,__win);
  147.  
  148.   __win.document.write("</TR><TR><TD></TD>");
  149.  
  150.   doBotL(__chart,__win);
  151.   doBotR(__chart,__win);
  152.  
  153.   __win.document.write("</TR><TR>");
  154.   
  155.   doHlabel(__chart,__win);
  156.  
  157.   __win.document.write("</TR></TABLE>");
  158.  
  159.   doFooter(__chart,__win);
  160. }
  161.  
  162. // Finds decent scaling for an array of numbers
  163. function computeAutoScale(max,min,__chart) {
  164.  
  165.   if(max == min) {
  166.     max+=1;
  167.     min-=1;
  168.   }
  169.  
  170.   var ticks = __chart.ticks;
  171.  
  172.   range = nicenum(max - min, 0);
  173.   d = nicenum(range/(ticks - 1), 1);
  174.   graphmin = Math.floor(min/d)*d;
  175.   if(graphmin>0) graphmin = 0;
  176.   graphmax = Math.ceil(max/d)*d;
  177.   if(graphmax<0) graphmax = 0;
  178.   nfrac = Math.max( -Math.floor(Math.log(d)/Math.E), 0);
  179.   i = 0;
  180.   for (x=graphmin; x < (graphmax+0.5*d); x+=d) {
  181.     __chart.scale[i] = doRound(x,nfrac,"after");
  182.     i++;
  183.   }
  184.   __chart.scaledelta = d;
  185.  
  186.   // Make the chart stay an apprx size
  187.   if(__chart.orientation == "vertical")
  188.     __chart.scalesize = doRound(__chart.vsize / __chart.scale.length,
  189.                                 0, "after");
  190.   else
  191.     __chart.scalesize = doRound(__chart.hsize / __chart.scale.length,
  192.                                 0, "after");
  193.  
  194. }
  195.  
  196. // Finds a nice number
  197. function nicenum(x,round) {
  198.   var expt = Math.floor(Math.log(x)/Math.E);
  199.   var f = x/Math.pow(10,expt);
  200.  
  201.   var nf;
  202.   if(round == 1) {
  203.     if (f< 1.5) nf = 1.;
  204.     else if (f<3) nf = 2.;
  205.     else if (f<7) nf = 5.;
  206.     else nf = 10.;
  207.   } else {
  208.     if (f<= 1) nf = 1.;
  209.     else if (f<=2) nf = 2.;
  210.     else if (f<=5) nf = 5.;
  211.     else nf = 10.;
  212.   }
  213.  
  214.   return nf*Math.pow(10, expt);
  215. }
  216.  
  217. // Rounds 'num' to 'p' places 'after'/'before' the decimal point
  218. function doRound(num,p,point) {
  219.   p = Math.pow(10,p);
  220.   if(point == "after")
  221.     num = Math.round(parseFloat(num)*(p))/(p);
  222.   else
  223.     num = Math.round(parseFloat(num)/(p))*(p);
  224.   return num;
  225. }
  226.  
  227. function doTitle(__chart,__win) {
  228.   __win.document.write(
  229.     "<TD></TD><TD></TD><TD Align=center>" +
  230.     "<TABLE Width=" + __chart.hsize + " Border=" + border +
  231.     " Cellpadding=3 Cellspacing=0><TR>" +
  232.     "<TD Align=center><FONT Size=4><B>" + __chart.title + "</B></FONT></TD>" +
  233.     "</TR></TABLE></TD>"
  234.   );
  235. }
  236.  
  237. function doHlabel(__chart,__win) {
  238.   __win.document.write(
  239.     "<TD></TD><TD></TD><TD Align=center>" +
  240.     "<TABLE Width=" + __chart.hsize + " Border=" + border +
  241.     " Cellpadding=3 Cellspacing=0><TR>" +
  242.     "<TD Align=center><B>" + __chart.hlabel + "</B></TD>" +
  243.     "</TR></TABLE></TD>"
  244.   );
  245. }
  246.  
  247. function doVlabel(__chart,__win) {
  248.   __win.document.write(
  249.     "<TD Valign=middle>" +
  250.     "<TABLE Height=" + __chart.vsize + " Border=" + border +
  251.     " Cellpadding=3 Cellspacing=0><TR>" +
  252.     "<TD Valign=middle><B>" + __chart.vlabel + "</B></TD>" +
  253.     "</TR></TABLE></TD>"
  254.   );
  255. }
  256.  
  257. function doTopL(__chart,__win) {
  258.   __win.document.write("<TD>");
  259.  
  260.   if(__chart.orientation == "vertical") {
  261.  
  262.     __win.document.write(
  263.       "<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0>"
  264.     );
  265.  
  266.     for(var i=__chart.scale.length-1; i>=0; i--) {
  267.       var scaledeltas = doRound((__chart.scalesize-1)/2,0,'after');
  268.  
  269.       __win.document.write(
  270.         "<TR><TD Height=" + __chart.scalesize + " Align=right>" +
  271.         "<FONT Size=2>" + __chart.scale[i] + "</FONT></TD>" +
  272.         "<TD Height=" + __chart.scalesize + ">" +
  273.           "<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0>" +
  274.           "<TR><TD Height=" + scaledeltas + " Align=right><IMG Src=" +
  275.           __chart.baseimg + " Height=" + scaledeltas + " Width=1></TD></TR>" +
  276.           "<TR><TD Height=1><IMG Src=" + __chart.tickimg + " Height=1></TD>" +
  277.           "</TR><TR><TD Height=" + scaledeltas + " Align=right><IMG Src=" +
  278.           __chart.baseimg + " Height=" + (scaledeltas+1) + " Width=1></TD></TR>" +
  279.           "</TABLE>" +
  280.         "</TD></TR>"
  281.       );
  282.     }
  283.  
  284.     __win.document.write("</TABLE>");
  285.  
  286.   } else {
  287.  
  288.     __win.document.write(
  289.       "<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0>"
  290.     );
  291.  
  292.     for(var i=0; i<__chart.data.length; i++) {
  293.       if(i==0) {
  294.         __win.document.write(
  295.           "<TR><TD Align=right Height=" + __chart.labelsize + "><FONT Size=2>" +
  296.           __chart.data[i].label + "</FONT></TD>" +
  297.           "<TD Rowspan=" + (__chart.data.length) + "><IMG Src=" +
  298.           __chart.baseimg + " Width=1 Height=" + __chart.vsize + "></TD></TR>"
  299.         );
  300.       } else {
  301.         __win.document.write(
  302.           "<TR><TD Align=right Height=" + __chart.labelsize + "><FONT Size=2>" +
  303.           __chart.data[i].label + "</FONT></TD></TR>"
  304.         );
  305.       }
  306.     }
  307.  
  308.     __win.document.write("</TABLE>");
  309.  
  310.   }
  311.  
  312.   __win.document.write("</TD>");
  313. }
  314.  
  315. function doTopR(__chart,__win) {
  316. //      if(height>(__chart.scalesize*__chart.scale.length)) height=1;
  317.  
  318.   var lessthanzero = 0;
  319.   var morethanzero = 0;
  320.  
  321.   for(i=0; i<__chart.scale.length; i++) {
  322.     if(__chart.scale[i] < 0)
  323.       lessthanzero++;
  324.     else if(__chart.scale[i] > 0)
  325.       morethanzero++;
  326.   }
  327.  
  328.   lessthanzero = doRound(lessthanzero * __chart.scalesize,0,'after');
  329.   if(lessthanzero) lessthanzero += doRound(__chart.scalesize/2,0,'after');
  330.   lessthanzero += 1;
  331.  
  332.   morethanzero = doRound(morethanzero * __chart.scalesize,0,'after');
  333.   if(morethanzero) morethanzero += doRound(__chart.scalesize/2,0,'after');
  334.   morethanzero -= 1;
  335.  
  336.   if(__chart.orientation == "vertical") {
  337.     __win.document.write("<TD Height=" + __chart.vsize + ">");
  338.     __win.document.write(
  339.       "<TABLE Height=" + __chart.vsize +
  340.       " Border=" + border + " Cellpadding=0 Cellspacing=0>"
  341.     );
  342.     __win.document.write("<TR>");
  343.     for(var i=0; i<__chart.data.length; i++) {
  344.  
  345.       var height = 
  346.         doRound((Math.abs(__chart.data[i].num)*__chart.scalesize)/
  347.                 __chart.scaledelta,0,'after');
  348.  
  349.       if(height<1) height = 1;
  350.  
  351.       if(__chart.data[i].num<0) {
  352.         __win.document.write(
  353.           "<TD Height=" + __chart.vsize + " Valign=bottom Align=center Width=" +
  354.           __chart.labelsize + ">"
  355.         );
  356.         __win.document.write(
  357.       "<TABLE Height=" + lessthanzero + " Border=" + border +
  358.           " Cellpadding=0 Cellspacing=0><TR>"
  359.     );
  360.         if(__chart.data[i].url != "-1") {
  361.           __win.document.write(
  362.         "<TD Valign=top Height=" + lessthanzero + "><A Href=" +
  363.             __chart.data[i].url + "><IMG Border=0 " +
  364.         "Src=" + __chart.data[i].img + " Height=" + height + " Width=" + 
  365.         __chart.barsize + "></A></TD>"
  366.       );
  367.         } else {
  368.           __win.document.write(
  369.         "<TD Valign=top Height=" + lessthanzero + "><IMG Border=0 " +
  370.         "Src=" + __chart.data[i].img + " Height=" + height + " Width=" + 
  371.         __chart.barsize + "></TD>"
  372.       );
  373.         }
  374.         __win.document.write("</TR></TABLE>");
  375.         __win.document.write("</TD>");
  376.       } else {
  377.         __win.document.write(
  378.           "<TD Height=" + __chart.vsize + " Valign=top Align=center Width=" +
  379.           __chart.labelsize + ">"
  380.         );
  381.         __win.document.write(
  382.       "<TABLE Height=" + morethanzero + " Border=" + border +
  383.           " Cellpadding=0 Cellspacing=0><TR>"
  384.     );
  385.         if(__chart.data[i].url != "-1") {
  386.           __win.document.write(
  387.         "<TD Valign=bottom Height=" + morethanzero + "><A Href=" +
  388.             __chart.data[i].url + "><IMG Border=0 " +
  389.             "Src=" + __chart.data[i].img + " Height=" + height + " Width=" +
  390.             __chart.barsize + "></A></TD>"
  391.       );
  392.         } else {
  393.           __win.document.write(
  394.         "<TD Valign=bottom Height=" + morethanzero + "><IMG Border=0 " +
  395.             "Src=" + __chart.data[i].img + " Height=" + height + " Width=" +
  396.             __chart.barsize + "></TD>"
  397.       );
  398.         }
  399.         __win.document.write("</TR></TABLE>");
  400.         __win.document.write("</TD>");
  401.       }
  402.     }
  403.     __win.document.write("</TR>");
  404.     __win.document.write("</TABLE>");
  405.   } else {
  406.     __win.document.write("<TD Width=" + __chart.hsize + ">");
  407.     __win.document.write(
  408.       "<TABLE Width=" + __chart.hsize + 
  409.       " Border=" + border + " Cellpadding=0 Cellspacing=0>"
  410.     );
  411.     for(var i=0; i<__chart.data.length; i++) {
  412.  
  413.       var width = 
  414.         doRound((Math.abs(__chart.data[i].num)*__chart.scalesize)/
  415.                 __chart.scaledelta,0,'after');
  416.  
  417.       if(width<1.0) width = 1;
  418.  
  419.       if(__chart.data[i].num<0) {
  420.         __win.document.write(
  421.           "<TR><TD Width=" + __chart.hsize + " Valign=center Align=left" +
  422.           " Height=" + __chart.labelsize + ">"
  423.         );
  424.         __win.document.write(
  425.       "<TABLE Width=" + lessthanzero + " Border=" + border +
  426.           " Cellpadding=0 Cellspacing=0><TR>"
  427.     );
  428.         if(__chart.data[i].url != "-1") {
  429.           __win.document.write(
  430.         "<TD Align=right Width=" + lessthanzero + "><A Href=" +
  431.             __chart.data[i].url + "><IMG Border=0 " +
  432.         "Src=" + __chart.data[i].img + " Width=" + width + " Height=" + 
  433.         __chart.barsize + "></A></TD>"
  434.       );
  435.         } else {
  436.           __win.document.write(
  437.         "<TD Align=right Width=" + lessthanzero + "><IMG Border=0 " +
  438.         "Src=" + __chart.data[i].img + " Width=" + width + " Height=" + 
  439.         __chart.barsize + "></TD>"
  440.       );
  441.         }
  442.         __win.document.write("</TR></TABLE>");
  443.         __win.document.write("</TD></TR>");
  444.       } else {
  445.         __win.document.write(
  446.           "<TR><TD Width=" + __chart.hsize + " Valign=center Align=right" +
  447.           " Height=" + __chart.labelsize + ">"
  448.         );
  449.         __win.document.write(
  450.       "<TABLE Width=" + morethanzero + " Border=" + border +
  451.           " Cellpadding=0 Cellspacing=0><TR>"
  452.     );
  453.         if(__chart.data[i].url != "-1") {
  454.           __win.document.write(
  455.         "<TD Align=left Width=" + morethanzero + "><A Href=" +
  456.             __chart.data[i].url + "><IMG Border=0 " +
  457.         "Src=" + __chart.data[i].img + " Width=" + width + " Height=" + 
  458.         __chart.barsize + "></A></TD>"
  459.       );
  460.         } else {
  461.           __win.document.write(
  462.         "<TD Align=left Width=" + morethanzero + "><IMG Border=0 " +
  463.         "Src=" + __chart.data[i].img + " Width=" + width + " Height=" + 
  464.         __chart.barsize + "></TD>"
  465.       );
  466.         }
  467.         __win.document.write("</TR></TABLE>");
  468.         __win.document.write("</TD></TR>");
  469.       }
  470.     }
  471.     __win.document.write("</TABLE>");
  472.   }
  473.   __win.document.write("</TD>");
  474. }
  475.  
  476. function doBotL(__chart,__win) {
  477.   __win.document.write("<TD Valign=top Align=right>");
  478.   __win.document.write("<IMG Src=" + __chart.baseimg + " Height=1 Width=1>");
  479.   __win.document.write("</TD>");
  480. }
  481.  
  482. function doBotR(__chart,__win) {
  483.   __win.document.write("<TD Align=center>");
  484.  
  485.   if(__chart.orientation == "vertical") {
  486.  
  487.     __win.document.write(
  488.       "<TABLE Width=" + __chart.hsize + " Border=" + border +
  489.       " Cellpadding=0 Cellspacing=0>"
  490.     );
  491.  
  492.     __win.document.write("<TR>");
  493.     __win.document.write(
  494.       "<TD><IMG Src=" + __chart.baseimg +
  495.       " Height=1 Width=" + __chart.hsize + "></TD>"
  496.     );
  497.     __win.document.write("</TR>");
  498.  
  499.     __win.document.write(
  500.       "<TR><TD><TABLE Width=" + __chart.hsize + " Border=" + border +
  501.       "Cellpadding=0 Cellspacing=0><TR>"
  502.     );
  503.     for(var i=0; i<__chart.data.length; i++) {
  504.       __win.document.write(
  505.         "<TD Valign=top Align=center Width=" + __chart.labelsize + "><FONT " +
  506.     "Size=2>" + __chart.data[i].label + "</FONT></TD>"
  507.       );
  508.     }
  509.     __win.document.write("</TR></TABLE></TD></TR>");
  510.     __win.document.write("</TABLE>");
  511.  
  512.   } else {
  513.  
  514.     __win.document.write(
  515.       "<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0>"
  516.     );
  517.  
  518.     __win.document.write("<TR>");
  519.     for(var i=0; i<__chart.scale.length; i++) {
  520.       var scaledeltas = doRound((__chart.scalesize-1)/2,0,'after');
  521.  
  522.       __win.document.write(
  523.         "<TD Valign=top Align=center Width=" + __chart.scalesize + ">" +
  524.           "<TABLE Border=" + border + " Cellpadding=0 Cellspacing=0><TR>" +
  525.           "<TD Width=" + scaledeltas + " Valign=top><IMG Src=" + __chart.baseimg +
  526.           " Width=" + scaledeltas + " Height=1></TD>" +
  527.           "<TD Width=1><IMG Src=" + __chart.tickimg + " Width=1></TD>" +
  528.           "<TD Witdh=" + scaledeltas + " Valign=top><IMG Src=" + __chart.baseimg +
  529.           " Width=" + scaledeltas + " Height=1></TD></TR></TABLE>" +
  530.     "</TD>"
  531.       );
  532.     }
  533.     __win.document.write("</TR>");
  534.     __win.document.write("<TR>");
  535.     for(var i=0; i<__chart.scale.length; i++) {
  536.       __win.document.write(
  537.         "<TD Valign=top Align=center Width=" + __chart.scalesize + "><FONT " +
  538.         "Size=2>" + __chart.scale[i] + "</FONT></TD>"
  539.       );
  540.     }
  541.     __win.document.write("</TR>");
  542.     __win.document.write("</TABLE>");
  543.  
  544.   }
  545.  
  546.   __win.document.write("</TD>");
  547. }
  548.  
  549.  
  550. function doFooter(__chart,__win) {
  551. }
  552.  
  553. // -->
  554. </SCRIPT>
  555.