Android Polar Graphing - android

I'm trying to do something like this, but I have a little bit of flexibility with how it looks. Essentially either a pie chart with only part of the pie filled (and the rest left blank), or some sort of dial chart.
It would also be relatively easy to use a polar graph to draw two arrows, one at 0 degrees and one at -92 degrees, but I can't find any libraries that will let you do this for Android. I do need it to make 0 degrees actually look like 0 polar degrees.
I've used an AChartEngine DialChart and managed to get something close, but I can't figure out how to get the labels to show up for each arrow. I've tried renderer.setDisplayValues(true); and series.setDisplayChartValues(true);
but it won't show the values for my two arrows, so I'm not sure if it's even possible with a DialChart. I realize that if I showed labels for the dial in the background, my users wouldn't need to have labels on the arrows, but I'm rotating the LinearLayout that the DialChart is added to in order to get 0 to look like 0 degrees in a polar graph. I am also struggling to hide labels for the dial in the background, despite using renderer.setShowLabels(false); and setting just about every other thing you can show to false. My hack is to set the label color to the background color, but if there is a better way to do it, please let me know.
Here is my code for the DialChart.
CategorySeries category = new CategorySeries("Angle");
category.add("Extension", 0);
category.add("Flexion", 90);
renderer = new DialRenderer();
renderer.setLabelsColor(getActivity().getResources().getColor(R.color.background));
renderer.setInScroll(true);
renderer.setDisplayValues(true);
renderer.setShowLegend(false);
renderer.setShowAxes(false);
renderer.setShowLabels(false);
renderer.setShowGrid(false);
renderer.setMargins(new int[] {20, 30, 15, 0});
renderer.setVisualTypes(new DialRenderer.Type[] {Type.ARROW, Type.ARROW});
renderer.setMinValue(-20);
renderer.setMaxValue(280);
renderer.setPanEnabled(false);
renderer.setZoomEnabled(false);
SimpleSeriesRenderer r = new SimpleSeriesRenderer();
series.setColor(getActivity().getResources().getColor(R.color.green));
series.setDisplayChartValues(true);
series.setChartValuesTextSize(30);
visualizationRenderer.addSeriesRenderer(r);
r = new SimpleSeriesRenderer();
series.setColor(getActivity().getResources().getColor(R.color.green));
series.setDisplayChartValues(true);
series.setChartValuesTextSize(30);
renderer.addSeriesRenderer(r);
visualization = ChartFactory.getDialChartView(getActivity(), category, renderer);
LinearLayout layout = (LinearLayout) this.getView().findViewById(R.id.sessions_visualization);
layout.addView(visualization);
layout.setRotation(220.0f);
I'm open to either modifying this code to get something that works, or other libraries that will help me accomplish what I'm trying to do. Thanks!

I'm answering my own question for anyone who wants to do something like this later.
You can create custom views in Android and draw whatever you want to display. There is good documentation here.
Here's a relevant code snippet. It's not perfect but it does the job.
public class AngleVisualization extends View {
private Paint textPaint;
private Paint arcPaint;
private Paint linePaint;
RectF oval;
private float extension;
private float flexion;
private int textColor;
private int arcColor;
private float extensionLabelX;
private float extensionLabelY;
private float flexionLabelX;
private float flexionLabelY;
private Rect extensionBounds = new Rect();
public AngleVisualization(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.AngleVisualization,
0, 0);
try {
extension = a.getFloat(R.styleable.AngleVisualization_extensionValue, 0);
flexion = a.getFloat(R.styleable.AngleVisualization_flexionValue, 0);
textColor = a.getColor(R.styleable.AngleVisualization_textColor, Color.BLACK);
arcColor = a.getColor(R.styleable.AngleVisualization_arcColor, context.getResources().getColor(R.color.green));
extensionLabelX = a.getDimension(R.styleable.AngleVisualization_extensionLabelX, 190);
extensionLabelY = a.getDimension(R.styleable.AngleVisualization_extensionLabelY, 150);
flexionLabelX = a.getDimension(R.styleable.AngleVisualization_flexionLabelX, 50);
extensionLabelY = a.getDimension(R.styleable.AngleVisualization_flexionLabelY, 190);
} finally {
a.recycle();
}
oval = new RectF();
init();
}
private void init() {
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(textColor);
textPaint.setTextSize(30);
arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
arcPaint.setColor(arcColor);
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setColor(arcColor);
linePaint.setStrokeWidth(3);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
String extensionString = decimalFormat.format(extension) + "˚";
textPaint.getTextBounds(extensionString, 0, extensionString.length(), extensionBounds);
canvas.drawArc(oval, extension, flexion - extension, true, arcPaint);
canvas.drawLine(0.0f, extensionBounds.height(), oval.right / 2, extensionBounds.height(), linePaint);
canvas.drawText(extensionString, extensionLabelX, extensionLabelY, textPaint);
canvas.drawText(decimalFormat.format(flexion) + "˚", flexionLabelX, flexionLabelY, textPaint);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// Account for padding
float xpad = (float)(getPaddingLeft() + getPaddingRight());
float ypad = (float)(getPaddingTop() + getPaddingBottom());
float ww = (float)w - xpad;
float hh = (float)h - ypad;
String extensionString = decimalFormat.format(extension) + "˚";
textPaint.getTextBounds(extensionString, 0, extensionString.length(), extensionBounds);
float diameter = Math.min(ww, (hh - extensionBounds.height()) * 2.0f) - extensionBounds.height();
oval = new RectF(
0,
diameter / -2.0f,
diameter,
diameter / 2.0f);
oval.offsetTo(getPaddingLeft(), getPaddingTop() - diameter / 2.0f + extensionBounds.height());
flexionLabelY = diameter / 2.0f + extensionBounds.height();
flexionLabelX = 0;
extensionLabelY = extensionBounds.height();
extensionLabelX = ww / 2;
}
}

Related

System.InvalidCastException: Specified cast is not valid Xamarin

here is my code for custom label renderer for label of doughnut pie chart, i get this exception and i dont know what to do, please help
exception is from line CategoricalDataPointdataPoint=(CategoricalDataPoint)relatedLabelNode;
and when i change it to CategoricalDataPoint dataPoint =
relatedLabelNode.JavaCast(); i get System.InvalidCastException: Unable to convert instance of type 'Com.Telerik.Widget.Chart.Engine.DataPoints.PieDataPoint' to type 'com/telerik/widget/chart/engine/dataPoints/CategoricalDataPoint'.
Here is my code
class CustomLabelRenderer : BaseLabelRenderer
{
private String labelFormat = "{0}";
private TextPaint paint = new TextPaint();
private Paint strokePaint = new Paint();
private Paint fillPaint = new Paint();
private float labelMargin = 10.0f;
private float labelPadding = 20.0f;
public CustomLabelRenderer(DoughnutSeries owner)
: base(owner)
{
this.strokePaint.SetStyle(Paint.Style.Stroke);
this.strokePaint.Color = Color.White;
this.strokePaint.StrokeWidth = 2;
this.fillPaint.Color = Color.ParseColor("#F5413F");
this.paint.TextSize = 35.0f;
this.paint.Color = Color.White;
}
public override void RenderLabel(Canvas canvas,
Com.Telerik.Widget.Chart.Engine.ElementTree.ChartNode relatedLabelNode)
{
CategoricalDataPoint dataPoint = (CategoricalDataPoint)relatedLabelNode;
RadRect dataPointSlot = dataPoint.LayoutSlot;
Double val = dataPoint.Value;
String labelText = String.Format(this.labelFormat, (int)val);
StaticLayout textInfo = this.CreateTextInfo(labelText, dataPoint);
this.RenderLabel(canvas, dataPointSlot, labelText, textInfo);
}
private StaticLayout CreateTextInfo(String labelText,
CategoricalDataPoint dataPoint)
{
return new StaticLayout(labelText,
0,
labelText.Length,
this.paint,
(int)Math.Round((float)dataPoint.LayoutSlot.Width),
Layout.Alignment.AlignCenter,
1.0f,
1.0f,
false);
}
private void RenderLabel(Canvas canvas, RadRect dataPointSlot,
String labelText, StaticLayout textBounds)
{
RectF labelBounds = new RectF();
float height = textBounds.Height + this.labelPadding * 2;
float top = (float)dataPointSlot.GetY() - this.labelMargin - height;
labelBounds.Set(
(float)dataPointSlot.GetX(),
top,
(float)dataPointSlot.Right,
top + height);
canvas.DrawRect(
labelBounds.Left,
labelBounds.Top,
labelBounds.Right,
labelBounds.Bottom,
this.fillPaint);
canvas.DrawRect(
labelBounds.Left,
labelBounds.Top,
labelBounds.Right,
labelBounds.Bottom,
this.strokePaint);
canvas.DrawText(
labelText,
(float)dataPointSlot.GetX() + (float)(dataPointSlot.Width / 2.0) -
textBounds.GetLineWidth(0) / 2.0f,
labelBounds.CenterY() + textBounds.GetLineBottom(0) -
textBounds.GetLineBaseline(0),
paint);
}
}
}
`
Categorical series data are only supported for cartesian (X/Y) chart type. Pie charts only support PieSeries, so for what you've described that chart node can only be a PieDataPoint. It can never be a CategoricalDataPoint.
Supported series types for Pie charts: http://docs.telerik.com/devtools/xamarin/controls/chart/types/chart-types-pie-chart#supported-series
And here is what cartesion charts support: http://docs.telerik.com/devtools/xamarin/controls/chart/types/chart-types-cartesian-chart#supported-series
http://docs.telerik.com/devtools/xamarin/controls/chart/chart-overview

Display multiple lines of text in Oxyplot TextAnnotation

I'm working on an Android app utilizing xamarin and the oxyplot library. I ran into a problem where I cannot add multiple lines of text in TextAnnotation.
I tried the following options:
var sb = new StringBuilder();
sb.Append("Line1");
sb.AppendLine(); // which is equal to Append(Environment.NewLine);
sb.Append("\n");
sb.Append("\r\n");
sb.Append(System.Environment.NewLine);
sb.Append("Line2");
and added it like so to the TextAnnotation text object:
var textAnnotation1 = new TextAnnotation();
textAnnotation1.Text = sb.ToString();
textAnnotation1.Background = OxyColors.White;
textAnnotation1.TextColor = OxyColors.Black;
textAnnotation1.FontSize = 18;
textAnnotation1.TextPosition = new DataPoint(4,_vericalLineYaxis);
plotModel.Annotations.Add(textAnnotation1);
but all to avail.
My goal is to have the text appear like so:
Line 1
Line 2
Currently it's appearing as:
Line 1 Line2
Any help would be much appreciated.
Multi-line Annotations is not currently supported on the Android platform.
OxyPlot is invoking Android.Canvas.DrawText and that function does not support text wrapping, it is a fairly low-level primitive drawing routine.
Google's Doc: public void drawText (String text, float x, float y, Paint paint)
If you feel like mod'ing the source, this could be done by using a static layout vs. the current canvas.DrawText.
Something like this would get you started (but is untested):
public void DrawText (string text, float x, float y, Paint paint)
{
TextPaint textPaint = new TextPaint();
StaticLayout textLayout = new StaticLayout(text, textPaint, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, False);
canvas.Save();
canvas.Translate(x, y);
textLayout.Draw(canvas);
canvas.Restore();
}
FYI: Oxyplot's SVG renderer manually handles multi-line text by string splitting on "\r\n" and rendering a separate element for each line so the same thing could be done for the Android instead of using a StaticLayout (slower performance wise, but easy to mod/test):
var lines = Regex.Split(text, "\r\n");
if (valign == VerticalAlignment.Bottom)
{
for (var i = lines.Length - 1; i >= 0; i--)
{
var line = lines[i];
var size = this.MeasureText(line, fontFamily, fontSize, fontWeight);
this.w.WriteText(p, line, c, fontFamily, fontSize, fontWeight, rotate, halign, valign);
p += new ScreenVector(Math.Sin(rotate / 180.0 * Math.PI) * size.Height, Math.Cos(rotate / 180.0 * Math.PI) * size.Height);
}
}

How to design a custom progress bar with rounded edges and slanting progress?

This is what I wish to achieve:
Clicky
The container color, the progress color, the progress background color and the rounded edge radius as well as the thickness should all be editable and modifiable.
How could this be achieved with a light weight custom UI element?
After days of research, I was able to achieve what was expected with clear crisp UI and with all the above requirements and flexibility. The exact above UI can be achieved and follow parameters can be achieved as well:
1. Progress Color
2. Progress background color
3. Container color (Color of container to be set by you, you can set color of rounded edges to match the container color)
4. Height and width of the progress bar to suit your needs.
Here's the code and steps to implement it:
I. Put this code in the attrs.xml file under the values folder
<declare-styleable name="SlantingProgressBar">
<attr name="slantingProgress" format="integer"/>
<attr name="borderRadius" format="integer"/>
<attr name="borderColor" format="integer"/>
<attr name="slantingProgressColor" format="string"/>
<attr name="progressBackgroundColor" format="string"/>
<attr name="slantingProgressFullColor" format="string"/>
</declare-styleable>
II. Create a java class like this:
public class SlantingProgressbar extends View {
private float height = 0;
private float width = 0;
private int borderRadius = 20;
private float progress = 0;
private int rawProgress = 0;
private static final String OPACITY_30_PERCENT = "#66";
private int roundedBorderColor;
private String backgroundColor = "";
private String progressColor = "";
private String progressFullColor = "#fc3d39";
public SlantingProgressbar(Context context) {
super(context);
}
public SlantingProgressbar(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray array = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.SlantingProgressBar,
0, 0);
try {
setProgress(array.getInt(R.styleable.SlantingProgressBar_slantingProgress, 0));
setBackgroundColor(array.getString(R.styleable.SlantingProgressBar_progressBackgroundColor)); //Default color set in the method
setBorderRadius(array.getInt(R.styleable.SlantingProgressBar_borderRadius, 20));
setRoundedBorderColor(array.getInt(R.styleable.SlantingProgressBar_borderColor, 0));
setProgressColor(array.getString(R.styleable.SlantingProgressBar_slantingProgressColor));
} finally {
array.recycle();
}
}
public void setBorderRadius(int borderRadius) {
this.borderRadius = borderRadius;
}
public int getProgress() {
return rawProgress;
}
public void setProgress(int progress) {
if(progress >=0)
{
this.rawProgress = progress;
this.invalidate();
}
else
Log.e("ChlorophyllProgressBar", "Invalid 'progress' value detected, value should be between 0 and 100");
}
public void setRoundedBorderColor(int roundedBorderColor) {
if ( roundedBorderColor == 0) {
this.roundedBorderColor = getResources().getColor(R.color.white);
Log.e("CUSTOM_TAG", "Color set to White: " + this.roundedBorderColor);
return;
}
this.roundedBorderColor = roundedBorderColor;
Log.e("CUSTOM_TAG", "Color set to custom: " + this.roundedBorderColor);
}
private int getRoundedBorderColor()
{
return roundedBorderColor;
}
public void setSlantingProgressFullColor(String color)
{
if (TextUtils.isEmpty(progressFullColor)) {
this.progressFullColor = "#fc3d39";
return;
}
}
public void setBackgroundColor(String backgroundColor) {
if (TextUtils.isEmpty(backgroundColor)) {
this.backgroundColor = "#bfe8d4";
return;
}
this.backgroundColor = backgroundColor;
}
public void setProgressColor(String progressColor) {
if (TextUtils.isEmpty(progressColor)) {
this.progressColor = "#2bb673"; //Green
return;
}
this.progressColor = progressColor;
}
public float getViewHeight() {
return height;
}
public void setViewHeight(float height) {
this.height = height;
}
public float getViewWidth() {
return width;
}
public void setViewWidth(float width) {
this.width = width;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
height = getHeight();
width = getWidth();
progress = getProcessedProgress();
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor(backgroundColor));
canvas.drawPaint(paint);
paint.setColor(getProcessedProgressColor());
paint.setAntiAlias(true);
Log.d("CUSTOM_TAG", "Height: " + height);
canvas.drawRect(0, 0, progress, height, paint);
Path triangle = new Path();
triangle.setFillType(Path.FillType.EVEN_ODD);
triangle.moveTo(progress, 0);
triangle.lineTo(progress + height, 0);
triangle.lineTo(progress, height);
triangle.close();
canvas.drawPath(triangle, paint);
drawBorders(canvas, getRoundedBorderColor());
}
private void drawBorders(Canvas canvas, int color) {
float height = getHeight();
float trueWidth = getWidth();
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
//paint.setColor(getResources().getColor(R.color.white));
paint.setAntiAlias(true);
Path border = new Path();
border.moveTo(0, 0);
border.lineTo(0, height / 2);
border.quadTo(height / borderRadius, height / borderRadius, height / 2, 0);
border.lineTo(0, 0);
canvas.drawPath(border, paint);
border.reset();
border.moveTo(0, height);
border.lineTo(height / 2, height);
border.quadTo(height / borderRadius, (height - height / borderRadius), 0, height / 2);
border.lineTo(0, height);
canvas.drawPath(border, paint);
border.reset();
border.moveTo(trueWidth, 0);
border.lineTo(trueWidth - (height / 2), 0);
border.quadTo((trueWidth - height / borderRadius), height / borderRadius, trueWidth, height / 2);
border.lineTo(trueWidth, 0);
canvas.drawPath(border, paint);
border.reset();
border.moveTo(trueWidth, height);
border.lineTo(trueWidth - (height / 2), height);
border.quadTo((trueWidth - height / borderRadius), (height - height / borderRadius), trueWidth, height / 2);
border.lineTo(trueWidth, height);
canvas.drawPath(border, paint);
//Adding 1 pixel color
Paint paint1 = new Paint();
paint1.setStyle(Paint.Style.FILL);
int fadedColor = (color & 0x00FFFFFF) | 0x66000000;
Log.d("CUSTOM_TAG", "Faded Color Code: " + fadedColor);
paint1.setColor(fadedColor);
canvas.drawRect(0, 0, 1, height, paint1);
canvas.drawRect(trueWidth-1, 0, trueWidth, height, paint1);
}
private float getProcessedProgress()
{
return (rawProgress == 99) ? ((getWidth() * 98) / 100) : ((getWidth() * rawProgress) / 100);
}
private int getProcessedProgressColor()
{
if(rawProgress > 100)
{
return Color.parseColor(progressFullColor);
}
else
{
return Color.parseColor(progressColor);
}
}
}
III. To use the layout in your xml file:
<com.whatever.package.SlantingProgressbar
android:id="#+id/progressbar_detail"
android:layout_width="match_parent"
android:layout_height="#dimen/dimension1"
android:layout_alignParentLeft="true"
slanting_progress:borderColor="#color/darkgray"
android:layout_below="#id/alphacon_detail"
android:layout_marginBottom="#dimen/budget_list_item_paddingBottom"
android:progress="50" />
I'm sharing this code after a little while, so I might have missed out a thing or two, I'm pretty sure you can get that worked out, please feel free to correct me.
Explanation:
We're using the 'draw' methods in java to implement this feature. The advantage is that, drawing a UI element gives us a sharp and clear UI no matter how big or small you make it.
There might be some hardcoded values, so be sure to edit those before implementing.
Good luck and don't forget to up-vote if this post helps you. Thanks! :)
I'll post an answer here to show some improvements on your code.
You should avoid creating new objects during draw.
draw is called several times again and again to redraw your custom element and all those calls to new Paint() are creating new objects, that needs new memory allocation, and it drives the garbage collector crazy and makes your View much more resource intensive and probably will cause lag on scrolling elements such as RecyclerView.
Alternatively you should have them declared as private Paint border and then private Paint triangle, etc, etc. And then you should initialise the values of All the paints in a separate method and only if the parameters changed. An example code:
private boolean initPaint = false;
private void initPaintsIfNecessary(){
if(!initPaint) return;
initPaint = false;
triangle = new Paint();
triangle.set.... etc
border = new Paint();
border.set.... etc
}
then on all the methods setRoundedBorderColor, setProgressColor, etc. You call initPaint = true; and on the beginning of draw you call initPaintsIfNecessary();. This will avoid all the extra garbage collector work and will allow the UI of your app to run much smoother.
That also includes all the Paint inside drawBorders method.
use format="color" instead ofstring`.
Calling Color.parse(String) is a very slow call and it is very error prone. Alternatively you should the correct color element, like following:
<attr name="slantingProgressColor" format="color"/>
that not just is the correct way, but gives you a color preview on the editor, can be indexed on app style parameters and avoid this inefficient call to parse
then of course you should adjust or method appriately. For example:
setProgressColor(array.getColor(R.styleable.SlantingProgressBar_slantingProgressColor));
getColor will return an integer that can be directly used in paint.setColor(int);
I hope those tips can help you (and others in the community) to create better more efficient View elements. Happy coding!
I know this this old question to answer but this answer may helpful..
You can use drawArc method to achieve this..
RectF oval = new RectF();
oval.set(left, top ,right, bottom);
canvas.drawArc(oval, 270, 360, false, paint);

Translucent gradient status bar on Android Lollipop presented in Material Design

I would like to make something like this
for Android 5.0 and above?
How can I implement this? I can not found any solution on StackOverFlow or on android developer site.
I suggested that I can make status bar transparent and draw gradient drawable under status bar. But there are few problems.
First problem is that usual gradient from shape drawable doesn't support Material Design spec http://www.google.com/design/spec/style/imagery.html
Second problem is that I can not fit map fragment to windows via android:fitsSystemWindows="true".
Formula that gives approximately same plot as shown on the site of Material Design is:
y = 3/(4*(x+0.5)) - 0.5
I've tried several ways to draw hyperboloid gradient via Canvas and found the fastest solution.
public class HyperbolaGradientDrawable extends Drawable {
private static final int ALPHA_DEFAULT = (int) (0.6f * 255);
private int mAlpha = ALPHA_DEFAULT;
private int mColor;
private Rect mBmpRect = new Rect();
private int[] mColors = new int[0];
private Bitmap mBmp;
#Override
public void draw(Canvas canvas) {
Rect bounds = getBounds();
if (mColors.length != bounds.height()) {
int alpha;
float y, alphaRelative;
mColors = new int[bounds.height()];
for (int i = 0; i < bounds.height(); i++) {
y = ((float) i) / bounds.height();
// this function gives approximately 0.5 of the bearing alpha at 3/10ths closed to the darker end
alphaRelative = 3 / (4 * (y + 0.5f)) - 0.5f;
alpha = (int) (alphaRelative * mAlpha);
mColors[i] = alpha << 24 | mColor;
}
mBmp = Bitmap.createBitmap(mColors, 1, bounds.height(), Bitmap.Config.ARGB_8888);
mBmpRect.set(0, 0, 1, bounds.height());
}
canvas.drawBitmap(mBmp, mBmpRect, bounds, null);
}
public void setColor(int color) {
// remove alpha chanel
mColor = color & 0x00FFFFFF;
}
#Override
public void setAlpha(int alpha) {
mAlpha = alpha;
}
#Override
public void setColorFilter(ColorFilter colorFilter) {
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
I know that Google recommend to do not create new objects in draw method, but it works faster than drawing line by line through Canvas.
You can look at comparison of several ways in demo project

How shift graph in Android's Canvas

I draw a graph with canvas in android, but I want to shift it to left or right side. I don't want to scroll it, I just want to shift it in one page by which you can see the graph is shifting lively.
I would be appreciated if any body help me.
I am looking for a an answer to this question as well. I have a solution but it is to slow and uses a lot of CPU time. I am drawing two graphs with a width of 200 pixels and have the values stored in an array. I just shift the values in the array and moves them into a path.
I would be nice to have a solution where the canvas gets shifted by 1 pixel to the left and the 200th column gets drawn with the new value. With both paths are empty it takes about 2ms (Droid Incredible) to draw the paths. When the 2 paths are filled up it can take more than 40ms. This would give still 25fps but I would like to run other threads at the same time and don't want to waste CPU time.
Here is the source.
public class OSCI extends View
{
Integer[] codebuffer = new Integer[200];
Integer[] codebuffer1 = new Integer[200];
private static final String TAG = "MyActivity";
long start;
int code=0;
// private static final String TAG = "MyActivity";
public OSCI(Context context)
{
super(context);
Arrays.fill(codebuffer, 1);
Arrays.fill(codebuffer1, 1);
}
public OSCI(Context context, AttributeSet attrs)
{
super(context, attrs);;
Arrays.fill(codebuffer, 1);
Arrays.fill(codebuffer1, 1);
}
#Override
protected void onDraw(Canvas canvas)
{
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.YELLOW);
Path path = new Path();
path.moveTo(0, 70);
Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint1.setStyle(Paint.Style.STROKE);
paint1.setStrokeWidth(2);
paint1.setColor(Color.GREEN);
Path path1 = new Path();
path1.moveTo(0, 70);
int max = Collections.max(Arrays.asList(codebuffer));
if(max==0)max=1;
for (int a = 0; a < codebuffer.length; a++)
{
if (codebuffer[a] < 0)code=0;
code = 70 * codebuffer[a] / max;
path.lineTo(a * 2 + 2, 70 - code);
path1.lineTo(a * 2+ 2, 70 - (codebuffer1[a]));
}
start=(SystemClock.elapsedRealtime());
canvas.drawPath(path1, paint);
canvas.drawPath(path, paint1);
Log.v(TAG, " "+(SystemClock.elapsedRealtime()-start));
}
public void newValue(int value, int valuew)
{
System.arraycopy(codebuffer, 1, codebuffer, 0, 199);
codebuffer[199] = value;
System.arraycopy(codebuffer1, 1, codebuffer1, 0, 199);
codebuffer1[199] = valuew;
invalidate();
}
}

Categories

Resources