Mpandroidchart: Invalid index 0, size is 0 in lineChart

Created on 9 Nov 2016  Â·  27Comments  Â·  Source: PhilJay/MPAndroidChart

in the first, I add an empty chart data ,then

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
11-09 19:34:42.397 E/AndroidRuntime( 5201):     at             java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
11-09 19:34:42.397 E/AndroidRuntime( 5201):     at java.util.ArrayList.get(ArrayList.java:308)
11-09 19:34:42.397 E/AndroidRuntime( 5201):     at com.github.mikephil.charting.data.DataSet.getEntryForIndex(DataSet.java:286)
11-09 19:34:42.397 E/AndroidRuntime( 5201):     at com.github.mikephil.charting.utils.Transformer.generateTransformedValuesLine(Transformer.java:184)
11-09 19:34:42.397 E/AndroidRuntime( 5201):     at com.github.mikephil.charting.renderer.LineChartRenderer.drawValues(LineChartRenderer.java:545)
11-09 19:34:42.397 E/AndroidRuntime( 5201):     at com.github.mikephil.charting.charts.BarLineChartBase.onDraw(BarLineChartBase.java:251)

I think it is because of you dont check size when you draw values

Most helpful comment

I still encountered this issue, although using the latest version (3.0.3).

All 27 comments

in 3.0.0 version

I'm using v.3.0.2 "compile 'com.github.PhilJay:MPAndroidChart:v3.0.2'" but the bug is still present

It seems the problem is in version 3.0.2. After getting back to version 3.0.1, the problem got gone.

Yeah, I happens on Pixel XL device API 25(Android 7.1) when use 3.0.2. After use version 3.0.1 no problem.

I too have this problem with 3.0.2. Changing back to 3.0.1 does not fix anything, unfortunately.

I to have this problem with 3.0.2. Changing back to 3.0.1 does not fix anything, unfortunately.

i have same problem

Are there any workarounds for this problem?
I'm facing this bug even if I check that the list passed to the chart is not null and with at least one element.
I also upgraded from version 3.0.1 to version 3.0.2 but it seems that nothing has changed.

What I did was to ensure any data we passed to LineDataSet or DataSet is not empty...

@PhilJay @danielgindi this needs to be fixed

@PhilJay Any Help Regarding this would be much appreciated

Try this, it worked for me:

if (values.isEmpty()) {
       chart.clear();
} else {
      // set data
      chart.setData(data);
}

Someone managed to fix it in the version v3.0.2 ??

at com.github.mikephil.charting.renderer.LegendRenderer.renderLegend(LegendRenderer.java:377)
at com.github.mikephil.charting.charts.BarLineChartBase.onDraw(BarLineChartBase.java:266)
at android.view.View.draw(View.java:17541)
at android.view.View.updateDisplayListIfDirty(View.java:16534)

Hello I solved it after assigning all the values to the chart, you should call the method mChart.notifyDataSetChanged(); to tell you that data changes were generated.

Clearing the chart when the list of data is cleared fixed it for me.

temperatureEntries.clear();
mChart.clear();

I have "fixed" this by disable drawValues and after I set data to chart, I do

dataSet.forEach {
  if (it.entryCount > 0 ) {
      it.setDrawValues(true)
  }
}

couldnt able to solve this.
please help.

I had the same issue in the version 3.0.2. It was because DataSets that I passed to the LineData instance were empty. Checking before adding helped me:

List<Entry> entries = new ArrayList<>();
// Add entries...
LineDataSet line = new LineDataSet(entries, "Label");
LineData chartData = new LineData();
if (!entries.isEmpty()) {
    chartData.addDataSet(line);
}

@PhilJay First and foremost, thanks for this lib. Second, It's true that setting a lineDataSet with empty entries, it throw this exception, but please, make this clearer. It's hard to understand what does it happening facing an Stack Trace like this:

    --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.github.nakamotossh.fishtool, PID: 12118
    java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.github.mikephil.charting.data.DataSet.getEntryForIndex(DataSet.java:286)
        at com.github.mikephil.charting.utils.Transformer.generateTransformedValuesLine(Transformer.java:184)
        at com.github.mikephil.charting.renderer.LineChartRenderer.drawValues(LineChartRenderer.java:547)
        at com.github.mikephil.charting.charts.BarLineChartBase.onDraw(BarLineChartBase.java:264)
        at android.view.View.draw(View.java:19212)
        at android.view.View.updateDisplayListIfDirty(View.java:18162)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.draw(View.java:19215)
        at android.support.v4.view.ViewPager.draw(ViewPager.java:2420)
        at android.view.View.updateDisplayListIfDirty(View.java:18162)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.support.constraint.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1966)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.updateDisplayListIfDirty(View.java:18153)
        at android.view.View.draw(View.java:18940)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
        at android.view.View.draw(View.java:19215)
        at com.android.internal.policy.DecorView.draw(DecorView.java:788)
        at android.view.View.updateDisplayListIfDirty(View.java:18162)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:669)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:675)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:783)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:3016)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2821)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2374)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1407)
E/AndroidRuntime:     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6783)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6499)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Note that is java.util.ArrayList class throwing this exception, not from your lib. I really think it could be useful.

And again, thanks for this lib!

fixed now in d67ea481af1e8528c617dfd404d0c7827b0134b2

I to have this problem with 3.0.2. Changing back to 3.0.1 does not fix anything, unfortunately.

i have same problem

i try all,only ur is right

I still encountered this issue, although using the latest version (3.0.3).

@PhilJay - Since the issue (Invalid index in Line chart data) isn't fixed it prevents filtering out data sets in a Line chart.

okay, thanks for fixed this bug. good luck further

Pada tanggal Sel, 26 Mar 2019 pukul 09.25 Nick Apperley <
[email protected]> menulis:

Since the issue isn't fixed it prevents filtering out data sets in a chart.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/PhilJay/MPAndroidChart/issues/2450#issuecomment-476448966,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AXq6PRwb_DVA4vCmcNKCub9-L6zhPU2zks5vaYT9gaJpZM4KtcyD
.

This is still an Issue in 3.0.3. However, an acceptable workflow for charting, especially if you are going to allow dynamic data loading would be to toggle visibility of the empty data sets.

```Kotlin
private fun updateDataSetVisibility(chart: CombinedChart) {
chart.data.lineData.dataSets.forEach { dataSet ->
dataSet.isVisible = dataSet.entryCount != 0
}

    chart.data.scatterData.dataSets.forEach { dataSet ->
        dataSet.isVisible = dataSet.entryCount != 0
    }

}
```

try runOnUIThread, this solved my problem.

Hi,
I still have a similar problem.
Following:
I've got a chart with 4 charts (LineData). Two of them are static and never change, so they don't cause any problems.
The other two get changed every second within a separate thread and within a synchronized block.
Then I've got a further thread that triggers the main thread to refresh the chart diagram (also in synchronized block).
First thread:

synchronized (mChartLock) {
    indexOfDataSet = mLineDate.getIndexOfDataSet(mPowerLineDataSet);
    mLineDate.addEntry(entry, indexOfDataSet);  // Index 3
    mChart.setData(mLineDate);
    mChart.notifyDataSetChanged();
}

The thread is called every second in a loop.
Second thread:

synchronized (mChartLock) {
    indexOfDataSet = mLineDate.getIndexOfDataSet(mHeartRateLineDataSet);
    mLineDate.addEntry(entry, indexOfDataSet); // index 2
    mChart.setData(mLineDate);
    mChart.notifyDataSetChanged();
}

The code is called every second in a loop.
Thread to update the chart:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        try {
            synchronized (mChartLock) {
                mChart.invalidate();
                Log.i(this.getClass().toString(), "Chart updated successfully.");
            }
        } catch (Exception ex) {
            Log.e(this.getClass().toString(), "Setting chart date in Heart rate thread throw an exception.");
            Log.e(this.getClass().toString(), ex.toString());
        }
    }
});

The thread is called permanently in a loop.
I never saw the exception if I let the UI update thread call only every second. But the exception can still occur by coincidence.

The thread to update the chart throws irregularly an exception which is not cough by the try-catch block.

--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bennoss.myergometertrainer, PID: 3610
java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.get(ArrayList.java:411)
at com.github.mikephil.charting.renderer.LegendRenderer.renderLegend(LegendRenderer.java:377)
at com.github.mikephil.charting.charts.BarLineChartBase.onDraw(BarLineChartBase.java:28

Process: com.bennoss.myergometertrainer, PID: 3610
1)
at android.view.View.draw(View.java:17071)
at android.view.View.updateDisplayListIfDirty(View.java:16053)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728)
at android.view.View.updateDisplayListIfDirty(View.java:16016)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:656)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:662)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:770)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2796)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2604)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2211)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1246)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6301)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

The index and size of the exception vary.

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
java.lang.IndexOutOfBoundsException: Index: 2, Size: 0

Hi guys,
I think I finally found the root cause of the problem. The problem occurs if I call

synchronized (mChartLock) {
    indexOfDataSet = mLineDate.getIndexOfDataSet(mHeartRateLineDataSet);
    mLineDate.addEntry(entry, indexOfDataSet); // index 2
    mChart.setData(mLineDate);
    mChart.notifyDataSetChanged();
}

right after calling mChart.invalidate();.
I put everything into synchronized, what was correct. But it seems invalidate()may not be completely executed after the method has been called.
My temporary solution is therefore to extend the synchronized within the thread to update the chart (invalidate()) and to put a sleep within the synchronized block:

synchronized (mChartLock) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            try {
                mChart.invalidate();
                Log.i(this.getClass().toString(), "Chart updated successfully.");
            } catch (Exception ex) {
                Log.e(this.getClass().toString(), "Updating the chart throw an exception.");
                ex.printStackTrace();
            }
        }
    });
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

50ms are too short and the exception still occurred occasionally. 100ms worked in my testcase for quite a while, but the exception occurred finally.1000ms are OK for my purpose and I hope this will be ok.
This is only a workaround and should be fixed within MPAndroidChart.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thanhcly920 picture thanhcly920  Â·  3Comments

OnlyInAmerica picture OnlyInAmerica  Â·  3Comments

andreyfel picture andreyfel  Â·  3Comments

vishvendu picture vishvendu  Â·  3Comments

botondbutuza picture botondbutuza  Â·  3Comments