Graph View : View « UI « Android






Graph View

    
/*
  Amarino - A prototyping software toolkit for Android and Arduino
  Copyright (c) 2010 Bonifaz Kaufmann.  All right reserved.
  
  This application and its library is free software; you can redistribute
  it and/or modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 3 of the License, or (at your option) any later version.

  This library 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

import java.util.logging.Logger;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

class GraphView extends Visualizer {

  private static final String TAG = "GraphView";

  private Bitmap mBitmap;
  private Canvas mCanvas = new Canvas();

  private float mSpeed = 1f;
  private float mLastX;
  private float[] mLastValue = new float[10]; // 10 should be more than enough
  private int[] mColor = new int[4];

  public GraphView(Context context) {
    super(context);
    init();
  }

  public GraphView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }

  private void init() {
    mColor[0] = Color.argb(255, 100, 255, 100); // g
    mColor[1] = Color.argb(255, 255, 255, 100); // y
    mColor[2] = Color.argb(255, 255, 100, 100); // r
    mColor[3] = Color.argb(255, 100, 255, 255); // c

    mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
  }

  public void setData(float value) {
    addDataPoint(value, mColor[0], mLastValue[0], 0);
    invalidate();
  }

  public void setData(float[] values) {
    final int length = values.length;
    try {
      for (int i = 0; i < length; i++) {
        addDataPoint(values[i], mColor[i % 4], mLastValue[i], i);
      }
    } catch (ArrayIndexOutOfBoundsException e) {
      /* mLastValue might run into this in extreme situations */
      // but then we just do not want to support more than 10 values in
      // our little graph

    }
    invalidate();
  }

  private void addDataPoint(float value, final int color,
      final float lastValue, final int pos) {
    value += minValue;

    final Paint paint = mPaint;
    float newX = mLastX + mSpeed;
    final float v = mYOffset + value * mScaleY;

    paint.setColor(color);
    mCanvas.drawLine(mLastX, lastValue, newX, v, paint);
    mLastValue[pos] = v;
    if (pos == 0)
      mLastX += mSpeed;

  }

  public void setSpeed(float speed) {
    mSpeed = speed;
  }

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    // TODO when screen size changes sometimes w or h == 0 -> Exception

    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
    mCanvas.setBitmap(mBitmap);
    mCanvas.drawColor(0xFF111111);
    mLastX = mWidth;

    // set origin to zero
    for (int i = 0; i < mLastValue.length; i++)
      mLastValue[i] = minValue;
  }

  @Override
  protected void onDraw(Canvas canvas) {
    synchronized (this) {
      if (mBitmap != null) {
        final Paint paint = mPaint;
        final Canvas cavas = mCanvas;

        if (mLastX >= mWidth) {
          mLastX = 0;
          cavas.drawColor(0xFF111111);

          int x = 20;
          paint.setColor(0x33DDFFDD);
          while (x < mWidth) {
            cavas.drawLine(x, mYOffset, x, 0, paint);
            x += 20;
          }

          final float v = mYOffset + minValue * mScaleY;
          // draw the zero line
          paint.setColor(0xFF779977);
          cavas.drawLine(0, v, mWidth, v, paint);

        }
        paint.setColor(0xaa996666);
        cavas.drawText(min, 1, mYOffset - 1, paint);
        cavas.drawText(max, 1, textHeight - 1, paint);

        canvas.drawBitmap(mBitmap, 0, 0, null);
      }
    }
  }

}

abstract class Visualizer extends View {

  Paint mPaint = new Paint();
  float maxValue = 1024f;
  float minValue = 0f;
  float mScaleX;
  float mScaleY;
  float mYOffset;
  float mWidth;
  String min, max;
  float textWidth = 0;
  float textHeight = 0;

  public Visualizer(Context context) {
    super(context);
  }

  public Visualizer(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public abstract void setData(float value);

  public abstract void setData(float[] values);

  public void setBoundaries(float min, float max) {
    this.min = String.valueOf(min);
    this.max = String.valueOf(max);
    minValue = -min;
    maxValue = max - min;
    mScaleY = -(mYOffset * (1.0f / maxValue));
    mScaleX = (mWidth * (1.0f / maxValue));

    float[] sizes = new float[this.max.length()];
    textHeight = mPaint.getTextSize();
    mPaint.getTextWidths(this.max, sizes);
    for (float f : sizes)
      textWidth += f;
  }

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    mYOffset = h;
    mWidth = w;

    mScaleY = -(h * (1.0f / maxValue));
    mScaleX = (w * (1.0f / maxValue));

    super.onSizeChanged(w, h, oldw, oldh);
  }

  /* SIMPLE CAST FUNCTIONS  */

  public void setData(int value) {
    setData((float) value);
  }

  public void setData(double value) {
    setData((float) value);
  }

  public void setData(short value) {
    setData((float) value);
  }

  public void setData(long value) {
    setData((float) value);
  }

  public void setData(byte value) {
    setData((float) value);
  }

  public void setData(boolean value) {
    if (value)
      setData(1f);
    else
      setData(0f);
  }

  public void setData(int[] values) {
    final int length = values.length;
    float[] arr = new float[length];
    for (int i = 0; i < length; i++)
      arr[i] = values[i];
    setData(arr);
  }

  public void setData(double[] values) {
    final int length = values.length;
    float[] arr = new float[length];
    for (int i = 0; i < length; i++)
      arr[i] = (float) values[i];
    setData(arr);
  }

  public void setData(short[] values) {
    final int length = values.length;
    float[] arr = new float[length];
    for (int i = 0; i < length; i++)
      arr[i] = values[i];
    setData(arr);
  }

  public void setData(long[] values) {
    final int length = values.length;
    float[] arr = new float[length];
    for (int i = 0; i < length; i++)
      arr[i] = values[i];
    setData(arr);
  }

  public void setData(byte[] values) {
    final int length = values.length;
    float[] arr = new float[length];
    for (int i = 0; i < length; i++)
      arr[i] = values[i];
    setData(arr);
  }

  public void setData(boolean[] values) {
    final int length = values.length;
    float[] arr = new float[length];
    for (int i = 0; i < length; i++)
      arr[i] = values[i] ? 1 : 0;
    setData(arr);
  }

  public void setData(String[] values) {
    final int length = values.length;
    float[] arr = new float[length];
    for (int i = 0; i < length; i++)
      arr[i] = Float.valueOf(values[i]);
    setData(arr);
  }

}

   
    
    
    
  








Related examples in the same category

1.Brightness Slider
2.extends View to do drawing
3.Set View background
4.Extends View to draw
5.extends View to create customized User interface widget
6.Render View
7.Using Reflection to call method
8.Example of how to write a custom subclass of View.
9.Demonstrates making a view VISIBLE, INVISIBLE and GONE
10.Pint View
11.Compass View
12.Bars View
13.View inflate