/** * Web Site Hits and TLI Sales Count Graph Generator * @author Robert John Morton UK-YE572246C * @version 27 April 2000 */ import java.applet.*; // all the gubbins to make the applet work import java.awt.*; // for graphics operations (GUI) import java.net.*; // for downloading data from the remote server import java.io.*; // for stream handling for the above public class tlisales extends Applet implements Runnable { int L = 0, // length of the remote item being loaded l = 0, // number of bytes of the above successfully downloaded w, // weeks counter used on horizontal axis of graph lp = 1, // indicates current download phase LP = 1, // indicates previous download phase X = 30, // horizontal bias from left edge of applet to start of x-axis Y = 145, // vertical bias from top edge of applet to start of y-axis n = 25, // off-set from start mark of year to start of its name weeks[] = {52,52,52,52,52,52,52}; // weeks in year byte B[]; // gigantic byte array to hold the downloaded index data Color bg1 = new Color(210,210,210), // main background colour bg2 = new Color(210,195,195), // graph background colour bg3 = new Color(180,180,180); // graticule colour String // Year names and "hits scale". year[] = {"1998","1999","2000","2001","2002","2003","2004"}, hits[] = {"0","20","40","60","80","100","110"}, cb, // code base URL - where this applet's class file came from E; // for Exception during downloading + method where it occurred AppletContext ac; // ref to HTML document this applet is running in InputStream I; // input stream for downloading index or current HTML file URL url; // url of current HTML file Thread TH; // reference for a separate Internet Data Transfer thread public void init() { bg1 = getBackground(); setBackground(bg1); ac = getAppletContext(); // get applet's context reference cb = getCodeBase().toString(); // URL path from where this applet came /* Workaround re Hotjava re Microsoft intranet machine names where getCodeBase() wrongly returns the document base (cira Nov 1999). */ if(!cb.endsWith("/")) { int x = cb.lastIndexOf('/'); if(x != -1) cb = cb.substring(0,x + 1); } TH = new Thread(this); // create a thread for downloading data setBackground(bg1); // set the applet's background colour } public void paint(Graphics g) { g.setColor(bg1); g.fillRect(0,0,450,170); // clear graph panel g.setColor(bg2); g.fillRect(X,Y-120,364,120); // clear graph area w = 0; for(int i = 0; i < weeks.length; i++) { // for each year shown g.setColor(Color.black); g.drawString(year[i],X + 13 + w,Y + 20); // year number g.drawLine(X + w,Y + 5,X + w,Y + 10); // year boundary mark g.setColor(bg3); g.drawLine(X + w,Y,X + w,Y - 120); // annotation mark w += weeks[i]; // accumulated number of weeks } g.setColor(bg3); g.drawLine(X + w,Y,X + w,Y - 120); // annotation mark g.setColor(Color.black); g.drawLine(X + w, Y + 5,X + w,Y + 10); // final year boundary mark g.drawLine(X,Y + 5,X + w,Y + 5); // horizontal axis int z = 0; for(int i = 0; i < hits.length; i++) { // for each 10-hit graduation rightString(g,hits[i],X - 10,Y + 5 - z); // annotation g.drawLine(X - 10,Y - z,X - 5,Y - z); // annotation mark g.setColor(bg3); g.drawLine(X,Y - z,X + w,Y - z); // annotation mark z += 20; // accumulated number of hits g.setColor(Color.black); } g.drawLine(X - 5,Y, X - 5,Y - 120); // vertical axis g.drawString("Hits per week:",X - n,Y - 130); g.drawString("Year:",X - n,Y + 20); update(g); // paint/repaint the graph bars } public void update(Graphics g) { g.setColor(Color.blue); // set trace colour to blue int h = 0; // number of hits for a given week if(lp == 3) { // provided hit count data download completed w = X; // initial x-bias for week number int W = 0, // number of weeks for which there is valid data H = 0; // hits total accumulator for(int i = 0; i < L; i++) { // For each weekly hits figure ... /* Provided the hits count > zero [to avoid displaying zero values before start date], display it as a vertical bar on the chart: */ if((h = (int)B[i]) > 0) { g.drawLine(w,Y,w,Y - h); H += h; // add this week's hits to the total W++; // increment number of weeks for which there's valid data } w++; // increment the week number } g.setColor(Color.black); g.drawString("Total to Date " + H,105,15); g.drawString("Weekly Average " + (H / W),230,15); } } // Start/resume execution of Internet data transfer thread public void start() { TH.start(); } // MANAGE THE INTERNET DATA TRANSFERS ON A SEPARATE THREAD public void run() { while(TH != null) { // while this thread exists switch(lp) { // THE 2 DOWNLOADING PHASES: case 1: fileConnect(); // connect to index resource on server break; case 2: fileLoad(); // manage the downloading of its content } if(lp != LP) { // If the hits data loading process has just finished, LP = lp; // latch the current load state repaint(); // and display the histogram bars. } /* Put the thread to sleep for 250 milliseconds. Catch any exceptions which may occur during this time but take no action as they are not relevant to this program. */ try { TH.sleep(250); } catch (InterruptedException e) { } } } // Freeze execution of thread while away from host HTML page. public void stop(){ TH = null; } /* Called after stop() before applet is removed from memory: if the Internet data transfer thread object still existsand jettison its object into limbo. */ public void destroy() { if(TH != null) { TH = null; } } void fileConnect() { // CONNECT TO THE HITS DATA FILE ON THE SERVER try { // for loading from a jar file I = getClass().getResourceAsStream("tlisales.dat"); L = 512; // cannot find the current file length easily l = 0; // number of bytes so far successfully downloaded B = new byte[L]; // create the gigantic buffer for the data lp = 2; // advance to the index loading phase } /* If an exception occurs while connecting, set unrecoverable error status and note the type of exception and where it occurred. */ catch(Exception e) { lp = 0; E = "fileConnect() " + e; } } void fileLoad() { // DOWNLOAD THE HITS DATA int k; // current byte being read() try { /* While read() hasn't hit the current end of input stream and the entire file has not yet been downloaded, add its new byte to the array big byte array. */ while((k = I.read()) != -1) B[l++] = (byte)k; I.close(); // close the URL Connection's input stream lp = 3; // indicate file loading completed successfully } /* If an exception occurs while connecting, set unrecoverable error status and note the type of exception and where it occurred. */ catch(Exception e) { lp = 0; E = "fileLoad() " + e + L + " " + l; } } // DRAW A RIGHT-JUSTIFIED STRING void rightString(Graphics g, String s, int x, int y) { //dimensions of characters for current font FontMetrics fm = g.getFontMetrics(); g.drawString(s, x - fm.stringWidth(s), y); //display the string } }