MPDandroidChart-改变数据点数后,折线图不再填充整个视图

fjnneemd  于 2023-04-28  发布在  Android
关注(0)|答案(1)|浏览(139)

我在我的应用程序中遇到了一个问题,添加大量数据点,清除它们,添加少量数据点会导致LineChart无法完全到达视图的末尾。
我用一个简单的LineChart重现了这个问题。

在线性图表中,我首先通过单击Add 365按钮添加了365个数据点,它成功地将所有点加载到宽度为300dpLineChart视图中。
接下来,我单击Add 25按钮将25个数据点加载到LineChart中,但是正如您所看到的,由于某种原因,该行不再到达视图的末尾。
我想这可能是因为图表一直在缩放,所以我添加了lineChart.fitScreen(),但它没有做任何事情。
所以我不再确定问题出在哪里。有人知道我做错了什么吗?

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.linechart)
    LineChart lineChart;

    private final List<Entry> entries = new ArrayList<>();
    private LineDataSet dataSet;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        dataSet = new LineDataSet(entries, null);
        Drawable drawable = ContextCompat.getDrawable(this, R.drawable.gradient_purple);
        dataSet.setFillDrawable(drawable);
        dataSet.setLineWidth(1.5f);
        dataSet.setDrawHorizontalHighlightIndicator(false);
        dataSet.setHighLightColor(Color.WHITE);
        dataSet.setHighlightLineWidth(1.5f);
        dataSet.setColor(ContextCompat.getColor(this, R.color.teal_700));
        dataSet.setDrawFilled(true);
        dataSet.setDrawCircles(false);
        dataSet.setDrawValues(false);

        lineChart.setMinOffset(0f);
        lineChart.getAxisLeft().setEnabled(false);
        lineChart.getAxisRight().setEnabled(false);
        lineChart.getXAxis().setEnabled(false);
        lineChart.setNoDataText(null);
        lineChart.setScaleEnabled(false);
        lineChart.getDescription().setEnabled(false);
        lineChart.getLegend().setEnabled(false);
    }

    @OnClick(R.id.btn_add_25)
    void onAdd25() {
        dataSet.clear();
        for (int i = 0; i < 25; i++) {
            Entry entry = new Entry(i, i);
            dataSet.addEntry(entry);
        }
        LineData lineData = new LineData(dataSet);
        lineChart.setData(lineData);

        //lineChart.fitScreen(); Adding fitScreen doesn't do anything
        lineChart.invalidate();

    }

    @OnClick(R.id.btn_add_365)
    void onAdd365() {
        dataSet.clear();
        for (int i = 0; i < 365; i++) {
            Entry entry = new Entry(i, i);
            dataSet.addEntry(entry);
        }
        LineData lineData = new LineData(dataSet);
        lineChart.setData(lineData);

        //lineChart.fitScreen(); Adding fitScreen doesn't do anything
        lineChart.invalidate();
    }
}

布局:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/purple_500"
        android:elevation="4dp"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="sans-serif-medium"
            android:text="Test App"
            android:textColor="@color/white"
            android:textSize="20sp" />
    </androidx.appcompat.widget.Toolbar>

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/linechart"
        android:layout_width="250dp"
        android:layout_height="200dp"
        android:clipToPadding="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar" />

    <Button
        android:id="@+id/btn_add_25"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="300dp"
        android:text="Add 25"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/btn_add_365"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="200dp"
        android:text="Add 365"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

使用版本:implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

oxcyiej7

oxcyiej71#

TL;DR-在清除dataSet.calcMinMax()并使用较小的数据集更新其数据后调用dataSet.calcMinMax()

无论出于何种原因,当您调用dataSet.clear();时,数据集不会清除其最小/最大X & Y值,因此当您拥有X max为364的数据集时,添加一个仅为24的新数据集仍然保持旧的最大值,简单的解决方法是在填充较小的数据集后手动调用calcMinMax()(或始终作为最佳实践),如下所示:

dataSet.clear();
for (int i = 0; i < 25; i++) {
    Entry entry = new Entry(i, i);
    dataSet.addEntry(entry);
}

// if you print out dataSet.getXMax() here, it shows 364 if
//  you plotted the 365 point data set already

dataSet.calcMinMax();

// dataSet.getXMax() here will now be correct

另一种方法,对于像这样的数据集保存状态更健壮,将为每个调用生成一个新的数据集。您可以定义一个helper函数来应用接受条目列表的格式,如下所示:

private LineDataSet createDataSet(List<Entry> entries) {
    LineDataSet dataSet = new LineDataSet(entries, null);
    Drawable drawable = ContextCompat.getDrawable(this, R.drawable.gradient_purple);
    dataSet.setFillDrawable(drawable);
    dataSet.setLineWidth(1.5f);
    dataSet.setDrawHorizontalHighlightIndicator(false);
    dataSet.setHighLightColor(Color.WHITE);
    dataSet.setHighlightLineWidth(1.5f);
    dataSet.setColor(ContextCompat.getColor(this, R.color.teal_700));
    dataSet.setDrawFilled(true);
    dataSet.setDrawCircles(false);
    dataSet.setDrawValues(false);
    return dataSet;
}

然后删除dataSetentries类成员,并在onCreate中调用它们,然后在onAdd25onAdd365上执行类似的操作

void onAdd365() {
    ArrayList<Entry> entries = new ArrayList<>();
    for (int i = 0; i < 365; i++) {
        Entry entry = new Entry(i, i);
        entries.add(entry);
    }
    LineDataSet dataSet = createDataSet(entries);
    LineData lineData = new LineData(dataSet);
    lineChart.setData(lineData);
    lineChart.invalidate();
}

相关问题