I'm trying to draw a line graph using 
The aplication class
public class Plotter extends View {
private List<Float> xPosList, yPosList;
private List<Path> pathList;
private Path path;
private Paint paint;
private ConstraintLayout cl;
private TextView stockPriceView;
public Plotter(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.xPosList = new ArrayList<>();
this.yPosList = new ArrayList<>();
this.pathList = new ArrayList<>();
this.paint = new Paint();
this.paint.setStrokeWidth(20);
this.paint.setColor(Color.GREEN);
generateData();
}
/***
* Generates random float data points from 5 to 100 and creates a path to plot
*/
private void generateData() {
int min = 5;
int max = 100;
double random = 0;
float xPos = 0;
float yPos = 0;
for (int i = 1; i <= 20; i ) {
random = min Math.random() * (max - min);
xPos = 50 * i; //50 pixels
yPos = (float)random;
this.xPosList.add(xPos);
this.yPosList.add(yPos);
path = new Path(); //Create path
path.moveTo(xPos, yPos); //Add values to path
this.pathList.add(path); //Add path to pathList
}
}
/***
* Clears the points list
*/
private void clearData() {
this.xPosList.clear();
this.yPosList.clear();
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
clearData();
generateData();
break;
case MotionEvent.ACTION_UP:
invalidate(); //Refresh canvas
break;
}
return true; //Activate event
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
p.setColor(Color.GREEN);
p.setStrokeWidth(10);
p.setStyle(Paint.Style.FILL);
/***
* Better use 50 by 50 pixels
*/
float startX = 0; //Start graph at bottom left
float startY = canvas.getHeight(); //Start at the bottom (max height)
float nextX = 0;
float nextY = 0;
for (int i = 0; i < this.xPosList.size(); i ){
nextX = this.xPosList.get(i);
//TODO: Find a better function
nextY = (canvas.getHeight() - this.yPosList.get(i));
canvas.drawLine(startX, startY, nextX, nextY, p); //Draw segment
startX = nextX; //Save previous X point
startY = nextY; //Save previous Y point
}
//TODO: Find a better way to manage this
cl = (ConstraintLayout) ((ViewGroup)this.getParent()); //get parent Layout
this.stockPriceView = cl.findViewById(R.id.stockPriceText); //access the sibling
if (this.stockPriceView != null) {
this.stockPriceView.setText((nextY) ""); //Write number
}
}
}
Although my current output is not far from desired, it is not correct.
CodePudding user response:
It looks like your max y value will be 100px and that is not very much and pales in comparison to the 1000px max x value. You need to convert the y values to dps or some other scaling value to fill up more of your view.
In detail, within generateData() x will be set to a range of 50..1,000 in increments of 50 while y values will be randomly assigned values between 5 and 100. In the drawing code, you use these values for 
Here is another way using the canvas translate() method:
float viewWidth = getWidth();
float viewHeight = getHeight();
canvas.save();
// Flip the canvas vertically.
canvas.scale(1f, -1f, canvas.getWidth() / 2f, canvas.getHeight() / 2f);
for (int i = 0; i < this.xPosList.size(); i ) {
nextX = this.xPosList.get(i);
nextY = this.yPosList.get(i);
canvas.drawLine(viewWidth * startX / 1000, viewHeight * startY / 100,
viewWidth * nextX / 1000, viewHeight * nextY / 100, p); //Draw segment
startX = nextX; //Save previous X point
startY = nextY; //Save previous Y point
}
canvas.restore();

