0
votes

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.

1
Why you can't simply compare the Entry objects? - Don Chakkappan
What do you mean? I can click on an empty space and getting this event raised. - Makalele

1 Answers

1
votes

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.