Blackberry Bar-Graph (Class 2)

import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.util.Arrays;

/**
 * A field that can display data in a bar graph format.
 */

public class BarGraphField extends GraphField {
 /**
  * 
  * Use no padding.
  */
 public static final int PADDING_NONE = 0;

 /**
  * 
  * Use low padding.
  */
 public static final int PADDING_LOW = 4;

 /**
  * 
  * Use medium padding.
  */
 public static final int PADDING_MEDIUM = 8;

 /**
  * 
  * Use high padding.
  */
 public static final int PADDING_HIGH = 12;

 private int _scale, _increment, _barWidth, _barPadding, _scalePadding;
 private boolean _showScale;

 /**
  * 
  * Constructs a bar graph using the default (PADDING_MEDIUM) padding without
  * scale labels.
  * 
  * @param values
  * The values (data) to be graphed.
  * @param colors
  * The colors used to draw each bar.
  * @param scale
  * The maximum possible value of the graph, the top scale value.
  * @param increment
  * The increment amount for each scale value.
  * @param barWidth
  * The width in pixels of each bar.
  * 
  * @throws IllegalArgumentException
  * If the scale, increment or barWidth are <= 0, the array
  * lengths of values and colors do not match or if any value is
  * greater than the scale.
  */
 public BarGraphField(int[] values, int[] colors, int scale, int increment,
   int barWidth) {
  this(values, colors, scale, increment, barWidth, PADDING_MEDIUM,
    PADDING_MEDIUM, false);
 }

 /**
  * 
  * Constructs a bar graph using the default (PADDING_MEDIUM) padding.
  * 
  * @param values
  * The values (data) to be graphed.
  * @param colors
  * The colors used to draw each bar.
  * @param scale
  * The maximum possible value of the graph, the top scale value.
  * @param increment
  * The increment amount for each scale value.
  * @param barWidth
  * The width in pixels of each bar.
  * @param showScale
  * True to display scale labels, false to not.
  * 
  * @throws IllegalArgumentException
  * If the scale, increment or barWidth are <= 0, the array
  * lengths of values and colors do not match or if any value is
  * greater than the scale.
  */
 public BarGraphField(int[] values, int[] colors, int scale, int increment,
   int barWidth, boolean showScale) {
  this(values, colors, scale, increment, barWidth, PADDING_MEDIUM,
    PADDING_MEDIUM, showScale);
 }

 /**
  * 
  * Constructs a bar graph.
  * 
  * @param values
  * The values (data) to be graphed.
  * @param colors
  * The colors used to draw each bar.
  * @param scale
  * The maximum possible value of the graph, the top scale value.
  * @param increment
  * The increment amount for each scale value.
  * @param barWidth
  * The width in pixels of each bar.
  * @param barPadding
  * The amount of space between each bar. Can be PADDING_NONE,
  * PADDING_LOW, PADDING_MEDIUM or PADDING_HIGH.
  * @param scalePadding
  * The amount of space between scale ticks. Ignored if scale
  * labels are shown. Can be PADDING_NONE, PADDING_LOW,
  * PADDING_MEDIUM or PADDING_HIGH.
  * @param showScale
  * True to display scale labels, false to not.
  * 
  * @throws IllegalArgumentException
  * If the scale, increment or barWidth are <= 0, the padding
  * 
  * not match or if any value is greater than the scale.
  */
 public BarGraphField(int[] values, int[] colors, int scale, int increment,
   int barWidth, int barPadding, int scalePadding, boolean showScale) {

  // Ensure the scale is greater than 0.
  if (scale <= 0)
   throw new IllegalArgumentException("Scale must be greater than 0.");

  // Ensure the increment is greater than 0.
  if (increment <= 0)
   throw new IllegalArgumentException(
     "Increment must be greater than 0.");

  // Ensure the barWidth is greater than 0.
  if (barWidth <= 0)
   throw new IllegalArgumentException(
     "Bar width must be greater than 0.");

  // Ensure barPadding is a valid value.
  switch (barPadding) {
  case PADDING_NONE:
  case PADDING_LOW:
  case PADDING_MEDIUM:
  case PADDING_HIGH:
   break;
  default:
   throw new IllegalArgumentException("Invalid bar padding specified");
  }

  // Ensure scalePadding is a valid value.
  switch (scalePadding) {
  case PADDING_NONE:
  case PADDING_LOW:
  case PADDING_MEDIUM:
  case PADDING_HIGH:
   break;
  default:
   throw new IllegalArgumentException(
     "Invalid scale padding specified");
  }

  // Ensure the number of bar values match the number of colors.
  if (values.length != colors.length)
   throw new IllegalArgumentException(
     "Non matching array lengths for values and colors.");

  // Ensure not values are greater than the scale value.
  for (int count = values.length - 1; count >= 0; --count) {
   if (values[count] > scale)
    throw new IllegalArgumentException("Value greater than scale.");
  }

  _values = values;
  _colors = colors;
  _scale = scale;
  _increment = increment;
  _barWidth = barWidth;
  barPadding = barPadding;
  _scalePadding = scalePadding;
  _showScale = showScale;
  _width = calcWidth();
  _height = calcHeight();
 }

 /**
  * 
  * Calculate the width of the bar graph. The width is calculated by adding
  * the width of the scale, a 4 pixel spacer between the end of the scale
  * text and the start of the graph, a 2 pixel y axis, 2 pixels between the x
  * axis and first bar and the total width of all bars and spaces between
  * them. If _showScale is false the width of the scale and 2 pixel space is
  * not included.
  * 
  * @return The width of the graph.
  */

 private int calcWidth() {
  int theWidth;

  if (_showScale)
   theWidth = Font.getDefault().getAdvance(Integer.toString(_scale))
     + 8 + (_values.length * _barWidth)
     + ((_values.length - 1) * _barPadding);
  else
   theWidth = 10 + (_values.length * _barWidth)
     + ((_values.length - 1) * _barPadding);

  return theWidth;
 }

 /**
  * 
  * Calculate the height of the bar graph. If _showScale is true the height
  * is calculated by adding the 2 pixel line along the bottom the graph to
  * the font height multiplied by the number of scale increments shown. If
  * _showScale is false the padding value is used for the scale increment
  * height.
  * 
  * @return The height of the graph.
  */
 private int calcHeight() {
  if (_showScale)
   return 2 + (Font.getDefault().getHeight() * (_scale / _increment));
  else if (_scalePadding == PADDING_NONE)
   return 2 + (PADDING_LOW * (_scale / _increment));
  else
   return 2 + (_scalePadding * (_scale / _increment));
 }

 /**
  * 
  * Draws the graph.
  * 
  */
 protected void paint(Graphics graphics) {
  int count, tempX, tempY, leftOver, graphHeight = 0;

  int tickHeight; // The height of the scale ticks.
  int tickIndent; // The distance to indent the scale ticks.

  if (_showScale) {
   tickHeight = Font.getDefault().getHeight();
   // Subtract 4 from the width of the scale (2 pixels for the scale
   // width and 2 pixels for spacing).
   tickIndent = Font.getDefault().getAdvance(Integer.toString(_scale)) - 4;
  } else {
   if (_scalePadding == PADDING_NONE)
    tickHeight = PADDING_LOW;
   else
    tickHeight = _scalePadding;

   tickIndent = 0;
  }

  // Wipe out any existing graph image data.
  graphics.clear();

  graphics.setColor(0);

  // In case the increment doesn't divide into the scale evenly.
  leftOver = _scale % _increment;
  tempY = 0;

  // Draw the scale.
  for (count = _scale; count > leftOver; count -= _increment) {
   graphics.fillRect(tickIndent, tempY, 6, 2);

   if (_showScale)
    graphics.drawText(Integer.toString(count), 0, tempY);

   tempY += tickHeight;
  }

  tempX = tickIndent + 6;

  // Draw the x axis.
  graphics.fillRect(tempX, tempY, _width - tempX, 2);

  // Draw the y axis.
  graphics.fillRect(tempX, 0, 2, _height);

  tempX = _width - _barWidth;

  // Draw the bars.
  for (count = _values.length - 1; count >= 0; --count) {
   graphics.setColor(_colors[count]);

   // Calculate the top bar as a percentage of the available graphing
   // space
   // relating to the value. Graphing space is _height - 2 (2 pixel y
   // axis).
   tempY = _height - (int) (((_height - 2) * _values[count]) / _scale);
   graphHeight = _height - tempY - 2;

   graphics.fillRect(tempX, tempY, _barWidth, graphHeight);

   // Calculate the next graph starting point.
   tempX -= (_barWidth + _barPadding);
  }
 }

 /**
  * 
  * Retrieves the bar padding.
  * 
  * @return the bar padding.
  */
 public int getBarPadding() {
  return _barPadding;
 }

 /**
  * 
  * Retrieves the bar width.
  * 
  * @return the bar width.
  */
 public int getBarWidth() {
  return _barWidth;
 }

 /**
  * 
  * Retrieves the increment.
  * 
  * @return the increment.
  */
 public int getIncrement() {
  return _increment;
 }

 /**
  * 
  * Retrieves the scale.
  * 
  * @return the scale.
  */
 public int getScale() {
  return _scale;
 }

 /**
  * 
  * Retrieves the scale padding.
  * 
  * @return the scale padding.
  */
 public int getScalePadding() {
  return _scalePadding;
 }

 /**
  * 
  * Retrieves the scale label visibility flag.
  * 
  * @return true if the scale labels are visible, false if they are not.
  */
 public boolean isScaleVisible() {
  return _showScale;
 }

 /**
  * 
  * Sets the bar padding
  * 
  * @param barPadding
  *            Can be PADDING_NONE, PADDING_LOW, PADDING_MEDIUM or
  *            PADDING_HIGH.
  * 
  * @throws IllegalArgumentException
  *             if an invalid padding value is specified.
  */
 public void setBarPadding(int barPadding) {
  // Don't do anything unless the bar padding has changed.
  if (_barPadding != barPadding) {

   // Ensure barPadding is a valid value.
   switch (barPadding) {
   case PADDING_NONE:
   case PADDING_LOW:
   case PADDING_MEDIUM:
   case PADDING_HIGH:
    break;
   default:
    throw new IllegalArgumentException(
      "Invalid bar padding specified");
   }

   _barPadding = barPadding;
   _width = calcWidth();
  }
 }

 /**
  * 
  * Set the bar width
  * 
  * @param barWidth
  *            the bar width.
  * 
  * @throws IllegalArgumentException
  *             if the width <= 0.
  */
 public void setBarWidth(int barWidth) {
  // Dont do anything unless the bar width has changed.
  if (_barWidth != barWidth) {
   // Ensure the barWidth is greater than 0.
   if (barWidth <= 0)
    throw new IllegalArgumentException(
      "Bar width must be greater than 0.");

   _barWidth = barWidth;
   _width = calcWidth();
  }
 }

 /**
  * 
  * Set the graph values (data) and colors.
  * 
  * @param values
  * data used to create the graph.
  * @param colors
  * an array of colors used to draw each bar in the form of form
  * of 0x00RRGGBB.
  * 
  * @throws IllegalArgumentException
  * if the array lengths of values and colors do not match or if
  * a value is larger than the current scale value.
  */
 public void setGraphData(int[] values, int[] colors) {
  // Don't do anything unless the data has changed.
  if (!Arrays.equals(_values, values) || !Arrays.equals(_colors, colors)) {
   // Ensure the number of values match the number of colors.
   if (values.length != colors.length)
    throw new IllegalArgumentException(
      "Non matching array lengths for bars and colors.");

   // Ensure not values are greater than the scale value.
   for (int count = values.length - 1; count >= 0; --count) {
    if (values[count] > _scale)
     throw new IllegalArgumentException(
       "Value greater than scale.");
   }

   _values = values;
   _colors = colors;

   _width = calcWidth();
   _height = calcHeight();
  }
 }

 /**
  * 
  * Sets the scale increment. The increment value will determine the number
  * of ticks on the scale. It is recommended to use an increment value that
  * divides evenly into the scale.
  * 
  * @param increment
  * the scale increment.
  * 
  * @throws IllegalArgumentException
  * if the increment &lt;= 0.
  */
 public void setIncrement(int increment) {
  // Don't do anything unless the increment has changed.
  if (_increment != increment) {
   // Ensure the increment is greater than 0.
   if (increment <= 0)
    throw new IllegalArgumentException(
      "Increment must be greater than 0.");

   // Only the height changes with an increment change.
   _increment = increment;
   _height = calcHeight();
  }
 }

 /**
  * 
  * Sets the scale value. The scale represents the maximum value possible of
  * data in the graph, all values must be <= this value.
  * 
  * @param scale
  * the scale value.
  * 
  * @throws IllegalArgumentException
  * if the scale is &lt;= 0 or if a value is greater than the
  * scale.
  */
 public void setScale(int scale) {
  // /Don't do anything unless the scale has changed.
  if (_scale != scale) {
   // Ensure the scale is greater than 0.
   if (scale <= 0)
    throw new IllegalArgumentException(
      "Scale must be greater than 0.");

   // Ensure no values are greater than the scale value.
   for (int count = _values.length - 1; count >= 0; --count) {
    if (_values[count] > scale)
     throw new IllegalArgumentException(
       "Value greater than scale.");
   }

   _scale = scale;
   _width = calcWidth();
   _height = calcHeight();
  }
 }

 // Set the scale padding.
 /**
  * 
  * Set the scale padding. This represents the spacing between the ticks of
  * the scale. This parameter is only used if the scale labels are not
  * visible. If scale labels are visible the spacing is derived by the font
  * height.
  * 
  * @param scalePadding
  *            Can be PADDING_NONE, PADDING_LOW, PADDING_MEDIUM or
  *            PADDING_HIGH.
  * 
  * @throws IllegalArgumentException
  *             if an invalid padding value is specified.
  */
 public void setScalePadding(int scalePadding) {
  // Don't do anything unless the scale padding has changed.
  if (_scalePadding != scalePadding) {
   // Ensure scalePadding is a valid value.
   switch (scalePadding) {
   case PADDING_NONE:
   case PADDING_LOW:
   case PADDING_MEDIUM:
   case PADDING_HIGH:
    break;
   default:
    throw new IllegalArgumentException(
      "Invalid scale padding specified");
   }

   _scalePadding = scalePadding;
   _height = calcHeight();
  }
 }

 // Set the scale visibility flag.
 /**
  * 
  * Sets the scale label visibility flag.
  * 
  * @param showScale
  *            True to display scale labels, false to disable it.
  */
 public void setScaleVisible(boolean showScale) {
  // Don't do anything unless the flag has changed.
  if (_showScale != showScale) {
   _showScale = showScale;
   _width = calcWidth();
   _height = calcHeight();
  }
 }
}

Comments

Popular posts from this blog

Input filter (space not allowed) for EditText

Android Versions details

English - Formal and Informal words