Last active
July 13, 2017 05:54
-
-
Save crearo/9e3d75de2734834009663ba539adaf20 to your computer and use it in GitHub Desktop.
A simple line graph view that renders at 60fps. Fast, elegant.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rish.crearo.imagestabv2; | |
/** | |
* Original author unknown. | |
* | |
* Modified by rish on 10/7/17. | |
* [email protected] | |
*/ | |
import android.content.Context; | |
import android.graphics.Canvas; | |
import android.graphics.Paint; | |
import android.os.Handler; | |
import android.util.AttributeSet; | |
import android.util.TypedValue; | |
import android.view.View; | |
public class LineGraphView extends View { | |
private static final String TAG = LineGraphView.class.getSimpleName(); | |
private static final int UPDATE_DELAY = 16; // 60 FPS | |
private static final int TEXT_SIZE = 10; | |
private final Handler mHandler = new Handler(); | |
private final Paint mPaint = new Paint(); | |
private float[] mData; | |
private int mFramePos = 0; | |
private int mWidth = 0; | |
private float mMaxAbsValue = 0; | |
private float mCurrValue = 0; | |
private int mBackgroundColor = 0xFF202020; | |
private int mAxisColor = 0xFF708090; | |
private int mDataColor = 0xFFFF8090; | |
private boolean mIsAttached = false; | |
private int mStringHeight; | |
private int mStringWidth; | |
private final Runnable mUpdateRunnable = new Runnable() { | |
@Override | |
public void run() { | |
// shift mData | |
mFramePos++; | |
if (mFramePos == mWidth - 1) { | |
mFramePos = 0; | |
// shift mData | |
System.arraycopy(mData, (mWidth - 1) * 4, mData, 0, mData.length / 2); | |
// fill X | |
fillX(); | |
} else { | |
mData[(mFramePos + mWidth - 1) * 4 + 1] = mData[(mFramePos - 1 + mWidth - 1) * 4 + 3]; | |
mData[(mFramePos + mWidth - 1) * 4 + 3] = mCurrValue; | |
} | |
invalidate(); | |
if (mIsAttached) mHandler.postDelayed(mUpdateRunnable, UPDATE_DELAY); | |
} | |
}; | |
public LineGraphView(Context context) { | |
super(context); | |
mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE, | |
getResources().getDisplayMetrics())); | |
} | |
public LineGraphView(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
mPaint.setTextSize(TypedValue.applyDimension( | |
TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE, getResources().getDisplayMetrics())); | |
} | |
@Override | |
protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
super.onSizeChanged(w, h, oldw, oldh); | |
mWidth = w; | |
mFramePos = 0; | |
mData = new float[(mWidth * 2 - 1) * 4]; | |
clearData(); | |
} | |
@Override | |
protected void onAttachedToWindow() { | |
super.onAttachedToWindow(); | |
mIsAttached = true; | |
mHandler.postDelayed(mUpdateRunnable, UPDATE_DELAY); | |
} | |
@Override | |
protected void onDetachedFromWindow() { | |
mIsAttached = false; | |
mHandler.removeCallbacks(mUpdateRunnable); | |
super.onDetachedFromWindow(); | |
} | |
private void clearData() { | |
for (int x = 0; x < mData.length / 4; ++x) { | |
mData[x * 4] = x; | |
mData[x * 4 + 1] = 0; | |
mData[x * 4 + 2] = x + 1; | |
mData[x * 4 + 3] = 0; | |
} | |
} | |
public void setValue(float value) { | |
mCurrValue = value; | |
setAbsValue(value); | |
} | |
private void setAbsValue(float value) { | |
if (Math.abs(value) > Math.abs(mMaxAbsValue)) mMaxAbsValue = value; | |
} | |
public void clear() { | |
if (mData == null) return; | |
clearData(); | |
mMaxAbsValue = mCurrValue = 0; | |
} | |
@Override | |
protected void onDraw(Canvas canvas) { | |
int width = getWidth(); | |
int height = getHeight(); | |
if (width != this.mWidth) return; | |
canvas.drawColor(mBackgroundColor); | |
canvas.save(); | |
canvas.translate(0, height / 2 - 1); | |
canvas.scale(1, 10); | |
{ | |
// axis | |
mPaint.setColor(mAxisColor); | |
canvas.drawLine(0, 0, width - 1, 0, mPaint); | |
// mData | |
if (mData != null) { | |
mPaint.setColor(mDataColor); | |
canvas.translate(-mFramePos, 0); | |
canvas.drawLines(mData, mFramePos * 4, (width - 1) * 4, mPaint); | |
} | |
} | |
canvas.restore(); | |
// text | |
mPaint.setColor(mAxisColor); | |
if (mStringHeight == 0) | |
mStringHeight = Math.round(Math.abs(mPaint.ascent()) + mPaint.descent() + 0.5f); | |
if (mStringWidth == 0) mStringWidth = Math.round(mPaint.measureText("00.00") + 0.5f); | |
String str = String.format("%.1f", mMaxAbsValue); | |
canvas.drawText(str, width - 2 - mStringWidth, 1 + mStringHeight, mPaint); | |
str = String.format("%.1f", mCurrValue); | |
canvas.drawText(str, width - 2 - mStringWidth, height - mPaint.descent(), mPaint); | |
} | |
private void fillX() { | |
for (int x = 0; x < mData.length / 4; ++x) { | |
mData[x * 4] = x; | |
mData[x * 4 + 2] = x + 1; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment