Mega Code Archive

 
Categories / Android / UI
 

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);   } }