Search code examples
androidmpandroidchart

MPAndroidChart onValueSelected icon only


I'm using MPAndroidChart (https://github.com/PhilJay/MPAndroidChart) library to draw a simple line chart, where I have a line connected by points (values) represented as icons.

I'm using OnChartValueSelectedListener:

//initialization
mChart.setOnChartValueSelectedListener(this);

//later in class
public void onValueSelected(Entry e, Highlight h){
    Log.i(TAG, "Something selected.");
}

@Override
public void onNothingSelected() {
    Log.i(TAG, "Nothing selected.");
}

But in my case, almost always I'm getting onValueSelected instead of onNothingSelected, wherever I click.

So, I'm clicking on an empty space and still I'm getting onValueSelected. The 'e' param (Entry) is the closest one to the point I clicked.

I'm looking for a solution to detect if I really clicked on the icon on the chart or somehow change onValueSelected behavior to only be raised when I'm doing so.


Solution

  • Take a look at this example... should solve your problem

    public class MpAndroidLineChartActivity extends AppCompatActivity {
    
        LineChart mChart;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_mp_android_line_chart);
    
            mChart = (LineChart) findViewById(R.id.bar_chart);
            mChart.getDescription().setEnabled(false);
            mChart.setPinchZoom(false);
            mChart.setDrawGridBackground(false);
    
            XAxis xAxis = mChart.getXAxis();
            xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
            xAxis.setDrawGridLines(false);
    
            YAxis leftAxis = mChart.getAxisLeft();
            leftAxis.setDrawGridLines(false);
            leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
    
            mChart.getAxisRight().setEnabled(false);
            mChart.getLegend().setEnabled(false);
    
            float[] val = {10, 20, 30, 40, 50};
    
            ArrayList<Entry> entryList = new ArrayList<>();
            for (int i = 0; i < val.length; i++) {
                entryList.add(new BarEntry(i, val[i]));
            }
    
            LineDataSet set1 = new LineDataSet(entryList, "entryList");
            set1.setColor(Color.BLUE);
    
            set1.setDrawValues(false);
            set1.setColor(Color.BLACK);
            set1.setCircleColor(Color.BLACK);
            set1.setCircleRadius(6f);
            set1.setDrawCircleHole(false);
    
            ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
            dataSets.add(set1);
            LineData data = new LineData(dataSets);
            mChart.setData(data);
            mChart.setScaleEnabled(false);
            mChart.invalidate();
            mChart.setMaxHighlightDistance(6f);
    
            mChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
                @Override
                public void onValueSelected(Entry e, Highlight h) {
                    Log.d("onValueSelected", "onValueSelected");
                }
    
                @Override
                public void onNothingSelected() {
                    Log.d("onNothingSelected", "onNothingSelected");
                }
            });
    
        }
    }
    

    Make sure to add these lines to your code...

    //Sets the radius of the drawn circles.
      set1.setCircleRadius(6f);
    

    and

    //Sets the maximum distance in screen dp a touch can be away from an entry to cause it to get highlighted.
    mChart.setMaxHighlightDistance(6f);
    

    The methods are pretty much self explanatory.Even if you are using custom icons in place of circles, you can play around with the "MaxHighlightDistance" number and solve your problem.

    In this case, with both the "circleRadius" and "MaxHighlightDistance" as 6f, the "onValueSelected" will be invoked only when the user clicks exactly on the drawn circle. You could adjust the "MaxHighlightDistance" to 10f or 12f to give the user some room for error while clicking.