MPAndroidChart moveViewToX не всегда работает - PullRequest
0 голосов
/ 27 мая 2020

Я реализую решение разбиения по страницам и загружаю данные, когда я достигаю левой части графика (используя setOnChartGestureListener), данные отображаются в обратном порядке (с отрицательными значениями x). После загрузки нового набора данных область просмотра должна перейти к первой загруженной записи, но метод moveViewToX иногда дает ошибочное поведение c и не перемещает область просмотра.

Я пробовал разные хаки, например отложенный moveViewToX, вызов moveViewToX из других мест, даже добавление кнопки в действие, вызывающее moveViewToX, не работает.

Я искал stackoverflow и обнаружил аналогичную проблему, связанную с moveViewToX, но не решил проблему ( HorizontalBarChart moveViewToX не работает ).

Я использую это версия MPAndroidChart

com.github.PhilJay:MPAndroidChart:v3.1.0

Я сократил код до минимума, чтобы воспроизвести поведение.

activity_device_graph. xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:paddingTop="@dimen/keyline_5">

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/chart"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="15dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>

ChartTestActivity. java

import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.MotionEvent;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import com.github.mikephil.charting.utils.EntryXComparator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

import androidx.appcompat.app.AppCompatActivity;
import es.arpa.sensor.iot.R;

public class ChartTestActivity extends AppCompatActivity {

    private final static String TAG = ChartTestActivity.class.getSimpleName();

    private final static int ENTRIES_PER_PAGE = 100;

    private LineChart mChart;
    private int mPageCount = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_device_graph);
        mChart = (LineChart) findViewById(R.id.chart);

        initChart();

        getData(mPageCount);
    }

    private void initChart() {

        mChart.setBackgroundColor(Color.WHITE);
        mChart.getDescription().setEnabled(false);
        mChart.setDrawGridBackground(false);

        mChart.setScaleYEnabled(false);
        mChart.setExtraBottomOffset(20);

        // X-Axis Style
        XAxis xAxis = mChart.getXAxis();
        xAxis.enableGridDashedLine(10f, 10f, 0f);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

        // Y-Axis Style
        YAxis yAxis = mChart.getAxisLeft();
        yAxis.enableGridDashedLine(10f, 10f, 0f);
        yAxis.setAxisMinimum(0);
        yAxis.setAxisMaximum(20);
        mChart.getAxisRight().setEnabled(false);

        // Create a dataset
        ArrayList<Entry> values = new ArrayList<>();
        LineDataSet set = new LineDataSet(values, "TEST");
        set.setLineWidth(3f);
        set.setColor(getColor(R.color.purple_200));
        set.setDrawCircles(false);

        // Hide data point values
        set.setDrawValues(false);

        // Selection indicator
        set.setHighLightColor(Color.RED);
        set.setHighlightLineWidth(1f);

        // Customize legend entry
        set.setForm(Legend.LegendForm.LINE);
        set.setFormLineWidth(3f);
        set.setFormSize(30.f);

        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        dataSets.add(set);

        LineData data = new LineData(dataSets);
        mChart.setData(data);

        mChart.setOnChartGestureListener(new OnChartGestureListener() {
            @Override
            public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
            }

            @Override
            public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
                if (mChart.getLowestVisibleX() == mChart.getXAxis().getAxisMinimum())
                    getData(mPageCount++);
            }

            @Override
            public void onChartLongPressed(MotionEvent me) {

            }

            @Override
            public void onChartDoubleTapped(MotionEvent me) {

            }

            @Override
            public void onChartSingleTapped(MotionEvent me) {

            }

            @Override
            public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {

            }

            @Override
            public void onChartScale(MotionEvent me, float scaleX, float scaleY) {

            }

            @Override
            public void onChartTranslate(MotionEvent me, float dX, float dY) {

            }
        });
    }

    private void getData(int page) {
        LoadDataAsyncTask task = new LoadDataAsyncTask(new LoadDataListener<List<Entry>>() {
            @Override
            public void taskFinished(List<Entry> result) {
                ListIterator it = result.listIterator();
                LineDataSet set = (LineDataSet) mChart.getData().getDataSetByIndex(0);
                Entry jumpTo = null;
                while (it.hasNext()) {
                    Entry entry = (Entry) it.next();
                    set.addEntry(entry);
                    if (jumpTo == null)
                        jumpTo = entry;
                }

                Collections.sort(set.getValues(), new EntryXComparator());

                set.notifyDataSetChanged();
                mChart.getData().notifyDataChanged();
                mChart.notifyDataSetChanged();
                mChart.invalidate();

                mChart.setVisibleXRangeMaximum(50);
                mChart.setVisibleXRangeMinimum(10);

                // This statement should jump at the beginning of the added entries
                mChart.moveViewToX(jumpTo.getX());
            }

        });
        task.execute(page);
    }

    public interface LoadDataListener<T> {
        void taskFinished(T result);
    }

    public class LoadDataAsyncTask extends AsyncTask<Integer, Void, List<Entry>> {

        private LoadDataListener mListener;

        public LoadDataAsyncTask(LoadDataListener loadDataListener) {
            mListener = loadDataListener;
        }

        @Override
        protected List<Entry> doInBackground(Integer... params) {
            List<Entry> values = new ArrayList<>();
            int page = params[0];
            for (int i = 0; i < ENTRIES_PER_PAGE; i++) {
                int xValue = -(i + (page * ENTRIES_PER_PAGE));
                int yValue = page;
                values.add(new Entry(xValue, yValue));
            }
            return values;
        }

        @Override
        protected void onPostExecute(List<Entry> result) {
            super.onPostExecute(result);
            if (mListener != null)
                mListener.taskFinished(result);
        }

    }
}

Любая помощь приветствуется, спасибо

...