PhilJay / MPAndroidChart

A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.
Other
37.63k stars 9.02k forks source link

Unable to add new values to another barchart, it crashes for java.lang.IndexOutOfBoundsException: Invalid index 8, size is 7 #3253

Open mkamals1989 opened 7 years ago

mkamals1989 commented 7 years ago

Hi,

I am using barchart for my project in which i have multiple fragment and based on the fragment the values in the barchart will change. I am using view pager and on swiping the viewpager changing the fragment and the data to drawn in the graph. I first fragment has 7 data and the next fragment has 12 data. So first fragment shows 7 bar data this is fine but when i swipe to another fragment then it crashes. I don't understand why it crashes because when i set same data on both fragment then it works fine. Below is the crash report. Pls guide me on what the issue is while setting new data.

java.lang.IndexOutOfBoundsException: Invalid index 8, size is 7 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) at java.util.ArrayList.get(ArrayList.java:308) at com.trularquotes.fragment.ReportBaseFragment$1.getFormattedValue(ReportBaseFragment.java:192) at com.github.mikephil.charting.components.AxisBase.getFormattedLabel(AxisBase.java:472) at com.github.mikephil.charting.components.AxisBase.getLongestLabel(AxisBase.java:458) at com.github.mikephil.charting.renderer.XAxisRenderer.computeSize(XAxisRenderer.java:79) at com.github.mikephil.charting.renderer.XAxisRenderer.computeAxisValues(XAxisRenderer.java:74) at com.github.mikephil.charting.renderer.XAxisRenderer.computeAxis(XAxisRenderer.java:67) at com.github.mikephil.charting.charts.BarLineChartBase.notifyDataSetChanged(BarLineChartBase.java:331) at com.github.mikephil.charting.charts.Chart.setData(Chart.java:304) at com.trularquotes.fragment.ReportBaseFragment.setUpSourceChartData(ReportBaseFragment.java:286) at com.trularquotes.fragment.ReportBaseFragment$19.onPageSelected(ReportBaseFragment.java:1291) at android.support.v4.view.ViewPager.dispatchOnPageSelected(ViewPager.java:1967) at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:685) at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:669) at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2284) at android.view.View.dispatchTouchEvent(View.java:9308) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2637) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2324) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2643) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2338) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2643) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2338) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2643) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2338) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2643) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2338) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2643) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2338) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2643) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2338)

And the below is my code of fragment :

setUpBranchChartData() contains the first fragment data and setUpSourceChartData() contains the second fragment data. I am calling this method from viewpager's onPagechanged listener.

public void setUpBranchChartData() {

    Typeface tf;
    try {
        tf = Typeface.createFromAsset(mContext.getAssets(), mContext.getResources().getString(R.string.custom_font_bold));
    } catch (Exception e) {
        tf = null;
    }

    barChart.setNoDataText("You need to provide data for the chart.");
    barChart.setNoDataTextColor(mContext.getResources().getColor(R.color.white));
    if (tf != null)
        barChart.setNoDataTextTypeface(tf);
    final ArrayList<String> xAxisLabelARR = new ArrayList<>();
    ArrayList<Float> valueARR = new ArrayList<Float>();
    ArrayList<Integer> colorARR = new ArrayList<Integer>();
    valueARR.clear();
    xAxisLabelARR.clear();
    colorARR.clear();

    xAxisLabelARR.add("JAN");
    xAxisLabelARR.add("FEB");
    xAxisLabelARR.add("MAR");
    xAxisLabelARR.add("APR");
    xAxisLabelARR.add("MAY");
    xAxisLabelARR.add("JUN");
    xAxisLabelARR.add("JUL");

    valueARR.add(1700f);
    valueARR.add(3600f);
    valueARR.add(4400f);
    valueARR.add(4900f);
    valueARR.add(4700f);
    valueARR.add(3600f);
    valueARR.add(4300f);

    colorARR.add(mContext.getResources().getColor(R.color.report_branch_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_branch_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_branch_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_branch_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_branch_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.white));
    colorARR.add(mContext.getResources().getColor(R.color.report_branch_bar_color));

    ArrayList<BarEntry> barEntries;
    barEntries = new ArrayList<>();

    for (int i = 0; i < xAxisLabelARR.size(); i++) {
        barEntries.add(new BarEntry(i, valueARR.get(i)));
    }

    BarDataSet barDataSet = new BarDataSet(barEntries, "Dates");
    barDataSet.setColors(colorARR);
    barDataSet.setDrawValues(false);

    BarData barData = new BarData(barDataSet);
    barData.notifyDataChanged();
    barChart.setData(barData);
    barChart.notifyDataSetChanged();

    barChart.animateY(1000, Easing.EasingOption.Linear);
    barChart.getXAxis().setGranularity(1);
    barChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
    barChart.setDrawBorders(false);
    barChart.getXAxis().setDrawAxisLine(true);
    barChart.getXAxis().setAxisLineColor(mContext.getResources().getColor(R.color.white));
    barChart.getXAxis().setDrawGridLines(false);
    barChart.getAxisLeft().setDrawGridLines(true);
    barChart.getAxisRight().setDrawGridLines(false);
    barChart.getAxisLeft().setDrawAxisLine(false);
    barChart.getAxisRight().setDrawAxisLine(false);

    barChart.getAxisLeft().setDrawAxisLine(false);
    barChart.getLegend().setEnabled(false);
    barChart.getDescription().setEnabled(false);
    barChart.getAxisRight().setDrawLabels(false);
    barChart.getAxisLeft().setGridColor(mContext.getResources().getColor(R.color.report_branch_line_color));
    barChart.getAxisLeft().setTextColor(mContext.getResources().getColor(R.color.white));
    barChart.getAxisLeft().setTextSize(12);
    barChart.getXAxis().setTextColor(mContext.getResources().getColor(R.color.white));
    barChart.getXAxis().setTextSize(12);

    barChart.setTouchEnabled(false);

    if (tf != null) {
        barChart.getAxisLeft().setTypeface(tf);
        barChart.getXAxis().setTypeface(tf);
    }
    Log.w("Size Branches", String.valueOf(xAxisLabelARR.size()));
    barChart.getXAxis().setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return xAxisLabelARR.get((int) value);
        }
    });

    barChart.getAxisLeft().setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            String val = "";
            if (value < 1000f)
                val = "" + value;
            else {
                value = (value / 1000);
                int res = (int) value;
                val = res + "K";
            }
            return val;
        }
    });
}

public void setUpSourceChartData() {

    Typeface tf;
    try {
        tf = Typeface.createFromAsset(mContext.getAssets(), mContext.getResources().getString(R.string.custom_font_bold));
    } catch (Exception e) {
        tf = null;
    }

    barChart.setNoDataText("You need to provide data for the chart.");
    barChart.setNoDataTextColor(mContext.getResources().getColor(R.color.white));
    if (tf != null)
        barChart.setNoDataTextTypeface(tf);
    final ArrayList<String> xAxisLabelARR = new ArrayList<>();
    ArrayList<Float> valueARR = new ArrayList<Float>();
    ArrayList<Integer> colorARR = new ArrayList<Integer>();
    valueARR.clear();
    xAxisLabelARR.clear();
    colorARR.clear();

    xAxisLabelARR.add("MON");
    xAxisLabelARR.add("TUE");
    xAxisLabelARR.add("WED");
    xAxisLabelARR.add("THU");
    xAxisLabelARR.add("FRI");
    xAxisLabelARR.add("SAT");
    xAxisLabelARR.add("SUN");
    xAxisLabelARR.add("AUG");
    xAxisLabelARR.add("SEP");
    xAxisLabelARR.add("OCT");
    xAxisLabelARR.add("NOV");
    xAxisLabelARR.add("DEC");

    valueARR.add(1200f);
    valueARR.add(3600f);
    valueARR.add(4400f);
    valueARR.add(4900f);
    valueARR.add(4700f);
    valueARR.add(3600f);
    valueARR.add(4300f);
    valueARR.add(1300f);
    valueARR.add(3000f);
    valueARR.add(1200f);
    valueARR.add(3800f);
    valueARR.add(4900f);

    colorARR.add(mContext.getResources().getColor(R.color.white));
    colorARR.add(mContext.getResources().getColor(R.color.report_source_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_source_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_source_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_source_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_source_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.report_source_bar_color));
    colorARR.add(mContext.getResources().getColor(R.color.white_light));
    colorARR.add(mContext.getResources().getColor(R.color.white_light));
    colorARR.add(mContext.getResources().getColor(R.color.white_light));
    colorARR.add(mContext.getResources().getColor(R.color.white_light));
    colorARR.add(mContext.getResources().getColor(R.color.white_light));

    ArrayList<BarEntry> barEntries;
    barEntries = new ArrayList<>();

    for (int i = 0; i < xAxisLabelARR.size(); i++) {
        barEntries.add(new BarEntry(i, valueARR.get(i)));
    }

    BarDataSet barDataSet = new BarDataSet(barEntries, "Dates");
    barDataSet.setColors(colorARR);
    barDataSet.setDrawValues(false);

    BarData barData = new BarData(barDataSet);
    barData.notifyDataChanged();
    barChart.setData(barData);
    barChart.notifyDataSetChanged();

    barChart.animateY(1000, Easing.EasingOption.Linear);
    barChart.getXAxis().setGranularity(1);
    barChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
    barChart.setDrawBorders(false);
    barChart.getXAxis().setDrawAxisLine(true);
    barChart.getXAxis().setAxisLineColor(mContext.getResources().getColor(R.color.white));
    barChart.getXAxis().setDrawGridLines(false);
    barChart.getAxisLeft().setDrawGridLines(true);
    barChart.getAxisRight().setDrawGridLines(false);
    barChart.getAxisLeft().setDrawAxisLine(false);
    barChart.getAxisRight().setDrawAxisLine(false);

    barChart.getAxisLeft().setDrawAxisLine(false);
    barChart.getLegend().setEnabled(false);
    barChart.getDescription().setEnabled(false);
    barChart.getAxisRight().setDrawLabels(false);
    barChart.getAxisLeft().setGridColor(mContext.getResources().getColor(R.color.report_source_line_color));
    barChart.getAxisLeft().setTextColor(mContext.getResources().getColor(R.color.white));
    barChart.getAxisLeft().setTextSize(12);
    barChart.getXAxis().setTextColor(mContext.getResources().getColor(R.color.white));
    barChart.getXAxis().setTextSize(12);

    barChart.setTouchEnabled(false);

    if (tf != null) {
        barChart.getAxisLeft().setTypeface(tf);
        barChart.getXAxis().setTypeface(tf);
    }
    Log.w("Size Sources", String.valueOf(xAxisLabelARR.size()));
    barChart.getXAxis().setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            return xAxisLabelARR.get((int) value);
        }
    });

    barChart.getAxisLeft().setValueFormatter(new IAxisValueFormatter() {
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            String val = "";
            if (value < 1000f)
                val = "" + value;
            else {
                value = (value / 1000);
                int res = (int) value;
                val = res + "K";
            }
            return val;
        }
    });
}
tahakhozooie commented 5 years ago

If you're using IAxisValueFormatter, just add this code inside that:

   IAxisValueFormatter formatter = new IAxisValueFormatter() {
                @Override
                public String getFormattedValue(float value, AxisBase axis) {
                    if (((int) value) < YOURLISTDATA.size()) {
                        return YOURLISTDATA.get((int) value);
                    } else {
                        return "0";
                    }

                }
            };
jemshit commented 2 years ago

But why this error happens o.O It happens when you have 7 items, then you update data to 5 items -> boom IndexOutOfBoundsException