MPAndroidChart - 在条形图中动态显示Y轴数值变化

10

在调用barChart上的animateY时,整个图表将被重新绘制,动画效果是从y轴0到y轴新值的柱形图。

barChart.invalidate();
barChart.animateY(1000);

能否将动画限制在数值更改范围内?从而允许用户看到图表从旧的y(例如100)增长到新的y(例如120)的过程?


我认为不行。MPChart 的当前版本不支持这个功能。 - abhi
可以实现,但需要自己编写代码。一个简单的方法是使用计时器从100到120绘制y值。因此,您可以绘制100、101、102...直到120。 - Marcin D
在最新版本的MPAndroidChart(即v3.1.0)中,有没有针对这个问题的解决方案? - Maximus
1个回答

7

我曾经也遇到过同样的问题,但是找不到解决方案。所以,我创建了一个类来处理这种任务。

import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.data.Entry;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import android.os.Handler;

public class AnimateDataSetChanged {
    private int duration;
    private long startTime;
    private int fps = 30;
    private Handler timerHandler;
    private Chart chart;
    private List<Entry> oldData;
    private List<Entry> newData;
    private Interpolator interpolator;

    public AnimateDataSetChanged(int duration, Chart chart, List<Entry> oldData, List<Entry> newData){
        this.duration = duration;
        this.chart = chart;
        this.oldData = new ArrayList<>(oldData);
        this.newData = new ArrayList<>(newData);
        interpolator = new LinearInterpolator();
    }

    public void setInterpolator(Interpolator interpolator){
        this.interpolator = interpolator;
    }

    public void run(int fps){
        this.fps = fps;
        run();
    }

    public void run(){
        startTime = Calendar.getInstance().getTimeInMillis();
        timerHandler = new Handler();
        Runner runner = new Runner();
        runner.run();
    }

    private class Runner implements Runnable{
        @Override
        public void run() {
            float increment = (Calendar.getInstance().getTimeInMillis() - startTime) / (float)duration;
            increment = interpolator.getInterpolation(increment < 0f ? 0f : increment > 1f ? 1f :increment);
            chart.getData().getDataSetByIndex(0).clear();
            for(int i = 0; i < newData.size(); i++){
                float oldY = oldData.size() > i ? oldData.get(i).getY() : newData.get(i).getY();
                float oldX = oldData.size() > i ? oldData.get(i).getX() : newData.get(i).getX();
                float newX = newData.get(i).getX();
                float newY = newData.get(i).getY();
                Entry e = new Entry(oldX + (newX - oldX) * increment, oldY + (newY - oldY) * increment);
                chart.getData().getDataSetByIndex(0).addEntry(e);
            }
            chart.getXAxis().resetAxisMaximum();
            chart.getXAxis().resetAxisMinimum();
            chart.notifyDataSetChanged();
            chart.refreshDrawableState();
            chart.invalidate();
            if(chart instanceof BarLineChartBase){
                ((BarLineChartBase)chart).setAutoScaleMinMaxEnabled(true);
            }
            if(increment < 1f){
                timerHandler.postDelayed(this, 1000/fps);
            }
        }
    }
}

您可以这样调用该类:
List<Entry> oldEntries = ...
List<Entry> newEntries = ...

AnimateDataSetChanged changer = new AnimateDataSetChanged(600, mChart, oldEntries, currentDataEntries);
changer.setInterpolator(new AccelerateInterpolator()); // optionally set the Interpolator
changer.run();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接