Skip to content

Instantly share code, notes, and snippets.

@yccheok
Created October 21, 2022 10:09
Show Gist options
  • Save yccheok/437fad5e31504e52365d5ab5c4507bc3 to your computer and use it in GitHub Desktop.
Save yccheok/437fad5e31504e52365d5ab5c4507bc3 to your computer and use it in GitHub Desktop.
Demo for real-time time series graph
package com.demo.demo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
public class CustomView extends View {
private final Paint paint = new Paint();
private final Timer timer = new Timer();
private long start = 0;
public CustomView(Context context) {
super(context);
init();
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
paint.setColor(Color.BLACK);
paint.setTextSize(36);
paint.setTextAlign(Paint.Align.CENTER);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
invalidate();
}
}, 0, 10);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final long currentTimeMillis = System.currentTimeMillis();
if (start == 0) {
start = currentTimeMillis;
}
draw(canvas, currentTimeMillis - start);
}
private void draw(Canvas canvas, long duration) {
final long durationInSecond = duration / 1000L;
final long durationWithoutMillisecond = durationInSecond * 1000L;
final int localOffsetFromCenter = millisecondToPixel(
durationWithoutMillisecond - duration
);
assert(localOffsetFromCenter <= 0);
final int width = canvas.getWidth();
final int height = canvas.getHeight();
final int centerX = width / 2;
final int centerY = height / 2;
final int textLocationY = centerY;
final int pixelForOneSecond = millisecondToPixel(1000);
final int textLocationX = centerX + localOffsetFromCenter;
int lowerTextLocationX = textLocationX - pixelForOneSecond;
int upperTextLocationX = textLocationX + pixelForOneSecond;
long lowerDurationWithoutMillisecond = durationWithoutMillisecond - 1000;
long upperDurationWithoutMillisecond = durationWithoutMillisecond + 1000;
canvas.drawLine(centerX, 0, centerX, height, paint);
// Lower
while (lowerTextLocationX >= -pixelForOneSecond && lowerDurationWithoutMillisecond >= 0) {
final String s = getDurationAsString(lowerDurationWithoutMillisecond);
canvas.drawText(s, (float)lowerTextLocationX, (float)textLocationY, paint);
lowerTextLocationX = lowerTextLocationX - pixelForOneSecond;
lowerDurationWithoutMillisecond = lowerDurationWithoutMillisecond - 1000;
}
// Center
final String string = getDurationAsString(durationWithoutMillisecond);
canvas.drawText(string, (float)textLocationX, (float)textLocationY, paint);
// Upper
while (upperTextLocationX <= (pixelForOneSecond+width) && upperDurationWithoutMillisecond >= 0) {
final String s = getDurationAsString(upperDurationWithoutMillisecond);
canvas.drawText(s, (float)upperTextLocationX, (float)textLocationY, paint);
upperTextLocationX = upperTextLocationX + pixelForOneSecond;
upperDurationWithoutMillisecond = upperDurationWithoutMillisecond + 1000;
}
}
public static int millisecondToPixel(long millisecond) {
return (int)(0.125 * (double)millisecond);
}
public static String getDurationAsString(long duration) {
duration = duration / 1000L;
return String.format(Locale.ENGLISH, "%01d:%02d", (duration / 60), (duration % 60));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment