MPAndroidChart: ArrayIndexOutOfBoundsException в XAxisValueFormatter - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь использовать LineChart с пользовательским XAxisValueFormatter.У меня есть 3 массива с разными датами и разной длины, потому что мне нужно показать данные за разные периоды времени.Когда я пытаюсь переключить эти массивы (и перерисовать диаграмму) с малого на большое, это работает хорошо.Но если я пытаюсь переключить его с большого массива на маленький, это вызывает исключение.Я проверял свой код много раз и не нашел ошибку.Я не могу понять, где это ?!Так что мне нужна твоя помощь.

Вот мой код:

public class TradescreenViewpager2SecondFragment extends Fragment {

    private TextView period1H;
    private TextView period1D;
    private TextView period1M;
    private LineChart chart;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.vpager2_2nd_fragment, container, false);

        period1H = view.findViewById(R.id.period_1h);
        period1D = view.findViewById(R.id.period_1d);
        period1M = view.findViewById(R.id.period_1m);
        period1H.setOnClickListener(onClick);
        period1D.setOnClickListener(onClick);
        period1M.setOnClickListener(onClick);

        chart = view.findViewById(R.id.chart);
        createChart(chart, getHourChart());

        return view;
    }

    public void createChart(LineChart chart, Date[] dates) {
        List<Entry> entries = new ArrayList<>();
        for (int i = 1; i <= dates.length; i++) {
            int n = new Random().nextInt(i) * 2 + 6400;
            entries.add(new Entry(i, n));
        }

        LineDataSet dataSet = new LineDataSet(entries, "Simple chart");
        ...

        LineData lineData = new LineData(dataSet);
        chart.setData(lineData);

        IAxisValueFormatter xAxisFormatter = new MyXAxisValueFormatter(dates);

        XAxis xAxis = chart.getXAxis();
        xAxis.setValueFormatter(xAxisFormatter);
        ...
        chart.invalidate();
    }

    View.OnClickListener onClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            refreshBackground();
            switch (v.getId()) {
                case R.id.period_1h:
                    v.setBackground(getResources().getDrawable(R.drawable.rounded_dark_grey_10dp_background));
                    createChart(chart, getHourChart());
                    break;
                case R.id.period_1d:
                    v.setBackground(getResources().getDrawable(R.drawable.rounded_dark_grey_10dp_background));
                    createChart(chart, getDayChart());
                    break;
                case R.id.period_1m:
                    v.setBackground(getResources().getDrawable(R.drawable.rounded_dark_grey_10dp_background));
                    createChart(chart, getMonthChart());
                    break;
            }
        }
    };

    public void refreshBackground() {
        period1H.setBackground(getResources().getDrawable(android.R.color.transparent));
        period1D.setBackground(getResources().getDrawable(android.R.color.transparent));
        period1M.setBackground(getResources().getDrawable(android.R.color.transparent));
    }

    private static Date[] getMonthChart() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        Date prevDate = calendar.getTime();
        Date now = new Date();
        int countOfDays = (int)((now.getTime() - prevDate.getTime()) / (1000 * 60 * 60 * 24));
        Date[] days = new Date[countOfDays];
        int i = 0;
        while (i < countOfDays) {
            prevDate = new Date(prevDate.getTime() + 1000 * 60 * 60 * 24);
            days[i] = prevDate;
            i++;
        }

        return days;
    }

    private static Date[] getDayChart() {
        Date[] hours = new Date[24];
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        calendar.add(Calendar.HOUR_OF_DAY, 1);
        Date prevDay = calendar.getTime();
        for (int i = 0; i < hours.length; i++) {
            hours[i] = prevDay;
            calendar.add(Calendar.HOUR_OF_DAY, 1);
            prevDay = calendar.getTime();
        }

        return hours;
    }

    private static Date[] getHourChart() {
        Date[] minutes = new Date[60];
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, -1);
        calendar.add(Calendar.MINUTE, 1);
        Date prevHour = calendar.getTime();
        for (int i = 0; i < minutes.length; i++) {
            minutes[i] = prevHour;
            calendar.add(Calendar.MINUTE, 1);
            prevHour = calendar.getTime();
        }

        return minutes;
    }
}

А это форматер:

public class MyXAxisValueFormatter implements IAxisValueFormatter {

    private Date[] data;
    private DateFormat dateFormat;

    public MyXAxisValueFormatter(Date[] data) {
        this.data = data;
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        if (data.length == 24 || data.length == 60) {
            dateFormat = new SimpleDateFormat("HH:mm");
        } else
            dateFormat = new SimpleDateFormat("dd.MM");

        String res = dateFormat.format(data[(int)value - 1]);
        return res;
    }
}

В этом коде String res = dateFormat.format(data[(int)value - 1]); я получаю исключение:

java.lang.ArrayIndexOutOfBoundsException: length=24; index=29

Надеюсь, вы можете помочь мне ..

1 Ответ

0 голосов
/ 05 октября 2018

Проблема была решена.До этого я пытался установить свои данные перед вызовом конструктора MyXAxisValueFormatter.Теперь я поменял 3 строки кода:

IAxisValueFormatter xAxisFormatter = new MyXAxisValueFormatter(dates);
...
LineData lineData = new LineData(dataSet);
chart.setData(lineData);

Теперь все работает хорошо!

...