Skip to content
Advertisement

Drawing a graph in Paint with Android graphics

I’m trying to plot a graph on a View using a canvas. So far so good it plots correctly as show in the next image:

Desired Output

once you tap on the screen the expected result should clear the screen and plot a new graph but instead draws on top of it resulting in this:

Actual Output

private List<Float> xPosList, yPosList;
    private List<Path> pathList;
    private Path path;
    private Paint paint;

    private final Paint clearPaint = new Paint();



    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);
        this.clearPaint.setColor(Color.BLACK);
        generateData();

    }

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                generateData();
                break;
            case MotionEvent.ACTION_UP:
                //invalidate();
                break;
        }

        //invalidate();                               //Refresh canvas
        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;
        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);
            nextY = canvas.getHeight() - (this.yPosList.get(i) * 10);                    //Add 50 offset


            canvas.drawLine(startX, startY, nextX, nextY, p);

            startX = nextX;
            startY = nextY;
        }
    }
}

How do I properly clear screen?

I have tried

canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

seen from other questions but it does not work.

Advertisement

Answer

Actually it does not have anything to do with your clear color – the screen gets cleared correctly. The problem is the xPosList and likewise the yPosList ArrayList.

As soon as the user taps the screen the generateData() function gets called which keeps adding elements to both ArrayList. But: you never clear those! So as soon as you tap the screen twice, the ArrayList’s contain random data from the first and the second tap.

You need to clear those right before the for-loop:

this.xPosList.clear();
this.yPosList.clear();
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
}
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement