Package gld.sim.stats

Source Code of gld.sim.stats.TrackingView$MyMouseListener

/*-----------------------------------------------------------------------
* Copyright (C) 2001 Green Light District Team, Utrecht University
*
* This program (Green Light District) is free software.
* You may redistribute it and/or modify it under the terms
* of the GNU General Public License as published by
* the Free Software Foundation (version 2 or later).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* See the documentation of Green Light District for further information.
*------------------------------------------------------------------------*/

package gld.sim.stats;

import gld.sim.SimModel;
import gld.infra.Infrastructure;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.io.*;
import java.util.Observer;
import java.util.Observable;

/**
*
* A <code>TrackingView</code> shows a certain tracking graph.
*
* @author  Group GUI
* @version 1.0
*/

public abstract class TrackingView extends Canvas implements Observer
{
  /** The separator used when saving data. */
  public static String SEP = "\t";
  /** Determines how many samples are tracked. */
  protected final static int MAX_DATA = 1000;
  /** Determines how many different data flows can be tracked. */
  protected int MAX_TRACK = getMaxTrack();
  /** Colors used to draw the graph. */
  protected Color[] colors = getColors();
  /** Determines whether a graph is drawn or not. */
  protected boolean[] show;

  /** The back buffer */
  protected BufferedImage buffer;
  /** The history of tracking data */
  protected float[][] trackData;
  /** The cycle this view started tracking */
  protected int startCycle;
  /** The cycle the end of the x-axis currently represents */
  protected int endCycle;
 
  /** Used to determine where the user clicked the mouse. */
  protected float xStep;
  /** Index to the point in trackData to highlight. */
  protected int highlightIndex;
  /** Strings to draw in upper right corner. */
  protected String[] highlightText;
  /** String containing highlighted cycle text */
  protected String highlightCycle;
 
  /** Current index in trackData[][]. */
  protected int curIndex;
  /** Highest valued sampled. */
  protected float maximum;
  /** Sample rate: each trackRate cycles, a sample is taken. */
  protected int trackRate;
  /** Current count: sample if trackCount == trackRate. */
  protected int trackCount;
 
  /**
   * Creates a new <code>TrackingView</code>. A <code>TrackingView</code> is a component
   * displaying a tracking graph.
   *
   * @param _startCycle The cycle this view starts tracking.
   */
  public TrackingView(int _startCycle)
  {
    buffer = new BufferedImage(1,1,BufferedImage.TYPE_INT_BGR);

    trackData = new float[MAX_TRACK][MAX_DATA];
    highlightText = new String[MAX_TRACK];
    addMouseListener(new MyMouseListener());
   
    show = new boolean[MAX_TRACK];
    show[0] = true;
    for(int i=1; i<MAX_TRACK; i++)
      show[i] = false;
   
    init(_startCycle);
  }

  protected void init(int _startCycle)
  {
    startCycle = _startCycle;
    trackRate = 1;
    trackCount = 0;
    curIndex = 0;
    maximum = (float)5.0;
    endCycle = startCycle + MAX_DATA;
    highlightIndex = 0;
  }
 
  public void reset() { init(0); }




  /*============================================*/
  /* Basic GET and SET methods                  */
  /*============================================*/

  /** Returns the cycle this window started tracking */
  public int getStartCycle() { return startCycle; }
  /** Sets the cycle this window started tracking */
  public void setStartCycle(int cycle) { startCycle = cycle; }

  /** Determines the number of tracking graphs. */
  protected int getMaxTrack() { return 1; }
  /** Determines the colors of the tracking graphs. */
  protected Color[] getColors() { Color[] c = {Color.black}; return c; }
  /** Either shows or hides tracking graph <code>index</code>. */
  public void showGraph(int index, boolean b) { show[index] = b; }






  /*============================================*/
  /* Abstract methods                           */
  /*============================================*/

  /** Returns the next sample to be 'tracked'. */
  protected abstract float nextSample(int sourceIndex);

  /** Returns a short description of the specified source. */
  protected abstract String getSourceDesc(int sourceIndex);
 
  /** Returns the description for this tracking window. */
  protected abstract String getDescription();
 
  /** Returns the Y-axis label */
  protected abstract String getYLabel();






  /*============================================*/
  /* Painting                                   */
  /*============================================*/


  /**
   * This method is called by the <code>notifyObservers()</code> method
   * in the <code>Model</code> representing the infrastructure.
   *
   * @param o The observed <code>Model</code>.
   * @param arg Optional arguments.
   */
  public void update(Observable o, Object arg)
  {
    if(++trackCount != trackRate) return;
    trackCount = 0;
   
    for(int i=0; i<MAX_TRACK; i++) {
      trackData[i][curIndex] = nextSample(i);
      maximum = Math.max(maximum, trackData[i][curIndex]);
    }
    if(++curIndex == MAX_DATA)
      collapseData();
   
    redraw();
  }
 
  /** Redraws the buffer and paints it to the screen. */
  public void redraw()
  {
    if (!isVisible()) return;
   
    drawBuffer();
    repaint();
  }

  /** Draws the buffer. */
  public void drawBuffer()
  {
    int w = buffer.getWidth();
    int h = buffer.getHeight();
    Graphics g = buffer.getGraphics();
    g.setColor(Color.white);
    g.fillRect(0,0,w,h);

    xStep = (float)(w - 40) / MAX_DATA;
    float yStep = (float)(h - 35) / maximum;

    g.setColor(Color.black);

    // y-axis
    String max = maximum + "";
    int dot;
    if((dot = max.indexOf(".")) > -1)
      max = max.substring(0, dot+2);
    g.drawString(max, 2, 15);
    g.drawString("0", 16, h - 22);
    g.drawString(getYLabel(), 0, 28);
    g.drawLine(30, 5, 30, h - 20);
   
    // x-axis
    g.drawString(startCycle + "", 30, h - 7);
    g.drawString(endCycle + "", w - 40, h - 7);
    g.drawString("time (cycles)", w / 2 - 20, h - 5);
    g.drawLine(30, h - 19, w - 10, h - 19);

    // the data
    for(int num=0; num<MAX_TRACK; num++)
      if(show[num]) {
        g.setColor(colors[num]);   
        for(int i=0; i<curIndex; i++)
          g.fillArc((int)(i * xStep) + 30, h - 20 - (int)(trackData[num][i] * yStep), 2, 2, 0, 360);
      }

    // highlight a certain point and give its values in trackData
    if(highlightIndex != 0)
    {
      g.setColor(Color.cyan);
      g.drawLine((int)(highlightIndex * xStep) + 30, 0, (int)(highlightIndex * xStep) + 30, h);
      g.setColor(Color.black);
      g.drawString(highlightCycle, w - 80, 15);
      int y = 35;
      for(int num=0; num<MAX_TRACK; num++)
        if(show[num]) {
          g.setColor(colors[num]);
          g.drawString(highlightText[num], w - 80, y);
          y += 15;
        }
    }
  }
 
  /** Override default update() to avoid flickering. */
  public void update(Graphics g)
  {
    paint(g);
  }

  /**
   * Draws the data in the graphics buffer onto the screen.
   *
   * @param g the <code>Graphics</code> objects of this view.
   */
  public void paint(Graphics g)
  {
    // draw buffer
    while (!g.drawImage(buffer,0,0,this));
  }
















  /*============================================*/
  /* Miscellaneous                              */
  /*============================================*/

  /**
   * Sets the size for this <code>View</code>
   *
   * @param width the new width
   * @param height the new height
   */
  public void setSize(int width, int height)
  {
    buffer = new BufferedImage(width+1,height+1,BufferedImage.TYPE_INT_BGR);
    super.setSize(width,height);
    redraw();
  }

  public void setBounds(int x, int y, int width, int height)
  {
    width = width < 1 ? 1 : width;
    height = height < 1 ? 1 : height;
    buffer = new BufferedImage(width+1,height+1,BufferedImage.TYPE_INT_BGR);
    super.setBounds(x,y,width,height);
    redraw();
  }
 
  /**
  * Collapses trackData and changes other variables accordingly.
  */
  protected void collapseData()
  {
    for(int i=0; i<MAX_TRACK; i++)
      for(int j=0; j<MAX_DATA/2; j++)
        trackData[i][j] = trackData[i][j*2];
    curIndex = MAX_DATA / 2;
    trackRate *= 2;
    endCycle = startCycle + (endCycle - startCycle) * 2;
    highlightIndex = 0;
  }
 
  /**
   * Save data to a CSV file.
   */
  protected void saveData(String filename, SimModel model) throws IOException
  {
    PrintWriter out=new PrintWriter(new FileWriter(new File(filename)));
    out.println("# Data exported by Green Light District"); out.println("#");
    Infrastructure infra = model.getInfrastructure();
    out.println("# Infrastructure: \"" + infra.getTitle() + "\" by " + infra.getAuthor());
    out.println("# Simulation: \"" + model.getSimName() + "\"");
    out.println("# Tracking data: \"" + getDescription() + "\"");
    out.println("# Measured: " + getYLabel()); out.println("#");
    String fieldsDesc = "";
    for(int i=0; i<MAX_TRACK; i++)
      if(show[i])
        fieldsDesc += "<" + getSourceDesc(i) + ">" + (i==MAX_TRACK-1?"":SEP);
    out.println("# Format: <Cycle>" + SEP + fieldsDesc); out.println("#");
   
    String ln;
    for(int i=0; i<curIndex; i++) {
      ln = (startCycle + i * trackRate) + SEP;
      for(int j=0; j<MAX_TRACK; j++)
        if(show[j])
          ln += trackData[j][i] + (j==MAX_TRACK-1?"":SEP);
      out.println(ln);
    }
    out.close();
  }






  /*============================================*/
  /* Listeners                                  */
  /*============================================*/
 
  /**
  * Listens to mouse clicks on this TrackingView.
  * Sets the index of the graph datatable to be highlighted.
  */
  protected class MyMouseListener extends MouseAdapter
  {
    public void mouseClicked(MouseEvent e)
    {
      if((e.getModifiers() & InputEvent.BUTTON3_MASK) > 0) // right-click
      {
        highlightIndex = 0;
      }
      else
      {
        Point p = e.getPoint();
        highlightIndex = (int)((p.x - 30) / xStep);
        if(highlightIndex < 0 || highlightIndex > curIndex)
        {
          highlightIndex = 0;
          return;
        }
        highlightCycle = "cycle = " + (startCycle + highlightIndex * trackRate);
        String desc;
        for(int i=0; i<MAX_TRACK; i++) {
          highlightText[i] = getSourceDesc(i) + " = " + trackData[i][highlightIndex];
          int dot;
          if((dot = highlightText[i].indexOf(".")) > -1)
            highlightText[i] = highlightText[i].substring(0,dot+2);
        }
      }
      redraw();
    }
  }
}
TOP

Related Classes of gld.sim.stats.TrackingView$MyMouseListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.