androidandroid-studioandroid-graphviewandroid-touch-event

How can i draw a shape on a graphView using onTouchEvent or any other way?


I am making an app where I have a graphView where the cartesian X-axis varies from -150 to 150 and Y-axis values vary from 0-150 as shown below.Now I want to draw any shapes over this graphView using the touch of my finger.I want that I should draw any shape over this graph.The coordinates of the drawn shape should be in accordance with X and Y axis values not that of the pixel screen coordinates(which we get using MotionEvent()).

My app screen

I have tried to achieve this using onTouchEvent() but there the MotionEvent() returns me the pixel coordinates of the screen which all are positive. The second approach I used is filling all the possible datapoint of the graphView using for loops as show in code below.I have used setOnDataPointTapListener where I get the DataPoints touched when I tab over the graphView.But the problem here is when i move my finger over the screen for drawing the setOnDataPointTapListener() is not triggered. Is there any way to do this?I will be very grateful for your help.Thanks

public class MainActivity extends AppCompatActivity {

    GraphView graph;
    ArrayList<Point> dataPoints;
    private static final String TAG = "MainActivity";
    LineGraphSeries<DataPoint> series;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dataPoints = new ArrayList<>();
        graph = findViewById(R.id.graphView);
        Viewport viewport = graph.getViewport();
        graph.getViewport().setXAxisBoundsManual(true);
        graph.getViewport().setYAxisBoundsManual(true);
        graph.getViewport().setScrollable(true);
        graph.getViewport().setScalable(true);
        viewport.setMaxX(150);
        viewport.setMinX(-150);
        viewport.setMaxY(150);
        viewport.setMinY(0);

        series = new LineGraphSeries<>();
        for (int x = -150; x <= 150; x++) {
            for (int y = 0; y <= 150; y++) {
                DataPoint dataPoint = new DataPoint(x, y);
                //100000 is the max datapoints
                series.appendData(dataPoint, false, 100000);
            }
        }
        graph.addSeries(series);

        series.setOnDataPointTapListener(new OnDataPointTapListener() {
            @Override
            public void onTap(Series series, DataPointInterface dataPoint) {
                Toast.makeText(MainActivity.this, "Datapoints are " + dataPoint.getX();
                        + " " + dataPoint.getY(), Toast.LENGTH_LONG).show();

                DataPoint dataPoint1 = (DataPoint) dataPoint;
                int x = (int) dataPoint1.getX();
                int y = (int) dataPoint1.getY();

                dataPoints.add(new Point(x, y));
                Log.d(TAG, "onTap: " + dataPoints.size());
            }
        }
    });
}

Solution

  • Did you try using Cartesian Plotter.

    https://github.com/ederdoski/SimpleCartesianPlotter?utm_source=android-arsenal.com&utm_medium=referral&utm_campaign=7223

    You can also add thread in your onTouch() method. Below code worked for me:

    @Override
    public boolean onTouchEvent(final MotionEvent event) {
    
       Thread CoordinatesThread = new Thread(new Runnable() {
           @Override
            public void run() {
    
                float x = event.getX();
                float y = event.getX();
    
                Log.e("coordinates", x + ":" + y);
    
                try {// take a gap for 5000 milisec before displaying new coordinates
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                     e.printStackTrace();
                }
             }
        });
        CoordinatesThread.start();
    
        return true;
    }