Package jmt.framework.gui.graph

Source Code of jmt.framework.gui.graph.DistributionDensityGraph

/**   
  * Copyright (C) 2013, Laboratorio di Valutazione delle Prestazioni - Politecnico di Milano

  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.

  * 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.

  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
package jmt.framework.gui.graph;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;

import javax.swing.AbstractAction;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

import org.freehep.util.export.ExportDialog;

import jmt.engine.math.DistributionDensity;

// Hacked cut+paste from FastGraph class...very bad...

/**
* @author Samarth Shukla, Aneish Goel
*
*/
public class DistributionDensityGraph extends JPanel {
  private static final long serialVersionUID = 1L;

  private double[] values;

  private double maxx;
  private double minx;
  private double intwidth;
  private int type;

  private int x0, y0;
  private double xstep, ystep;
  private static final int MARGIN = 8;

  private static final Color COLOR_DRAW = Color.BLUE;
  private static final Color COLOR_AXIS = Color.BLACK;
  private static final Color COLOR_BG = Color.WHITE;

  protected PlotPopupMenu popup = new PlotPopupMenu();

  // Used to format numbers. Formatters are not thread safe, so they should never be static.
  private DecimalFormat decimalFormat2 = new DecimalFormat("#0.00");
  private DecimalFormat decimalFormat3 = new DecimalFormat("#0.0");
  private DecimalFormat decimalFormat4 = new DecimalFormat("#00 ");




  public DistributionDensityGraph(DistributionDensity d)
  {
    values = d.getDistArray();
    maxx = d.getMax();
    minx = d.getMin();
    intwidth = d.getIntWidth();
    type = d.getType();
  }

  public void paint(Graphics g) {
    super.paint(g);
    int height = this.getHeight();
    int width = this.getWidth();

    // Draw graph area
    g.setColor(COLOR_BG);
    g.fillRect(MARGIN / 2, MARGIN / 2, width - MARGIN, height - MARGIN);

    // Aborts drawing if no elements are present
    if (values.length < 1) {
      return;
    }

    // Aborts graph drawing if width is too small...
    if (width < 80) {
      return;
    }

    // Find the range for x

    double xRange = maxx-minx;

    String xLabel="";


    // Find maximum value for y
    double maxy = 0;
    for (int i = 0; i < values.length; i++) {
      double currenty = values[i];
      if (currenty > maxy && !Double.isInfinite(currenty)) {
        maxy = currenty;
      }
    }

    // Correct zero maxy value, to avoid division per zero in ystep
    if (maxy == 0) {
      maxy = 1;
    }

    //Get text bounds
    FontMetrics metric = g.getFontMetrics();
    Rectangle2D xtextBound = metric.getStringBounds("XXXX", g);
    Rectangle2D ytextBound = metric.getStringBounds((formatNumber(maxy)), g);
    Rectangle2D xLabelBound = metric.getStringBounds(xLabel, g);

    // Find initial position
    x0 = (int) Math.ceil(ytextBound.getWidth()) + 2 + MARGIN;
    y0 = height - (int) Math.ceil(xtextBound.getHeight()) - 12 - MARGIN;

    xstep = (width - x0 - MARGIN - xtextBound.getWidth() / 2) / xRange;
    ystep = (y0 - MARGIN) / maxy;

    // Draws axis and captions
    g.setColor(COLOR_AXIS);
    // Y axis
    g.drawLine(x0, y0, x0, getY(maxy));
    int halfHeight = (int) Math.floor(ytextBound.getHeight() / 2);
    int yNum = (int) Math.floor((y0 - getY(maxy)) / (ytextBound.getHeight() + 2));
    // Draws caption for y axis
    for (int i = 0; i <= yNum; i++) {
      g.drawLine(x0, getY(maxy / yNum * i), x0 - 2, getY(maxy / yNum * i));
      g.drawString(decimalFormat2.format(maxy / yNum * i), MARGIN, getY(maxy / yNum * i) + halfHeight);
    }
    g.setColor(COLOR_AXIS);

    // X axis
    g.drawLine(x0, y0, getX(maxx), y0);

    double maxAvailableXWidth = width - x0 - MARGIN - xtextBound.getWidth() / 2;
    int xNum = (int) Math.floor(maxAvailableXWidth / (xtextBound.getWidth() + 12));
    // Draws caption for x axis
    for (int i = 0; i <= xNum; i++) {
      String label = formatNumber(minx + xRange / xNum * i);
      int halfWidth = (int) Math.floor(metric.getStringBounds(label,g).getWidth() / 2);
      g.drawLine(getX(minx + xRange / xNum * i), y0,getX(minx + xRange / xNum * i) ,y0+2 );
      g.drawString(label,getX(minx + xRange / xNum * i) - halfWidth, height - MARGIN - 12);
    }
    // Draws measure unit on X axis
    g.drawString(xLabel, width - (int)xLabelBound.getWidth() - MARGIN/2 - 1, height - MARGIN/2 - 1);

    // Draw chart series

    switch(type) {
    case DistributionDensity.TYPE_DENSITY_BAR:
      for (int i = 0; i < values.length -1 ; i++) {
        double yValue = values[i];
        double nextYValue = values[i+1];
        double xValue = getXValue(i);
        double nextXValue = getXValue(i+1);
        //draw 
        g.setColor(COLOR_DRAW);
        g.drawLine(getX(xValue),getY(yValue),getX(nextXValue),getY(nextYValue));
      }
      break;

    case DistributionDensity.TYPE_DENSITY_LINE:
      for (int i = 0; i < values.length ; i++) {
        double yValue = values[i];
        double xValue = getXValue(i);
        // draw
        g.setColor(COLOR_DRAW);
        g.drawLine(getX(xValue),getY(yValue),getX(xValue + intwidth),getY(yValue));
        g.drawLine(getX(xValue),getY(yValue),getX(xValue),y0);
        g.drawLine(getX(xValue+ intwidth),getY(yValue),getX(xValue+ intwidth),y0);
      }
      break;
    case DistributionDensity.TYPE_DISTRIBUTION:
      for (int i = 0; i < values.length -1 ; i++) {
        double yValue = values[i];
        double nextYValue = values[i+1];
        double xValue = getXValue(i);
        double nextXValue = getXValue(i+1);
        //draw 
        g.setColor(COLOR_DRAW);
        g.drawLine(getX(xValue),getY(yValue),getX(nextXValue),getY(nextYValue));
      }
      break
    }

  }

  /**
   * Returns X coordinate for the screen of a point, given its value
   * @param value value of point X
   * @return X coordinate on the screen
   */
  private int getX(double value) {
    return (int) Math.round(x0 + (value-minx) * xstep);
  }

  /**
   * Returns Y coordinate for the screen of a point, given its value
   * @param value value of point Y
   * @return Y coordinate on the screen
   */
  private int getY(double value) {
    return (int) Math.round(y0 - value * ystep);
  }

  /**
   * Reads the X value for the chart
   * @param value the measure value variable
   * @param index the index
   * @return the X value
   */
  private double getXValue(int index) {
    switch(type) {
    case DistributionDensity.TYPE_DENSITY_BAR:
      return minx + intwidth*(index+0.5);
    case DistributionDensity.TYPE_DENSITY_LINE:
      return minx + intwidth*(index);
    case DistributionDensity.TYPE_DISTRIBUTION:
      return minx + intwidth*(index+0.5);
    default :
      return minx + intwidth*(index+0.5);
    }
  }


  /**
   * Formats a number to string to be shown as label of the graph
   * @param value number to be converted
   * @return value converted into string
   */
  private String formatNumber(double value) {
    if (value == 0) {
      return "0.00";
    }
    else if (value < 10) {
      return decimalFormat2.format(value);
    }
    else if (value < 100) {
      return decimalFormat3.format(value);
    }
    else  {
      return decimalFormat4.format(value);
    }
  }



  private void rightClick(MouseEvent ev) {
    popup.show(this, ev.getX(), ev.getY());
  }

  protected class PlotPopupMenu extends JPopupMenu {
    private static final long serialVersionUID = 1L;
    public JMenuItem saveAs;
    public PlotPopupMenu() {
      saveAs = new JMenuItem("Save as...");
      this.add(saveAs);
      addListeners();
    }
    public void addListeners() {
      saveAs.addActionListener(new AbstractAction() {
        private static final long serialVersionUID = 1L;
        public void actionPerformed(ActionEvent e) {
          ExportDialog export = new ExportDialog();
          export.showExportDialog(DistributionDensityGraph.this,"Export view as ...", DistributionDensityGraph.this,"Export");
        }});

    }

  }

  public void mouseClicked(MouseEvent ev) {
    if (ev.getButton() == MouseEvent.BUTTON3) {
      rightClick(ev);
    } else {

    }
  }


}
TOP

Related Classes of jmt.framework.gui.graph.DistributionDensityGraph

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.