1. 程式人生 > >Android之MPAndroidChart的動態折線圖

Android之MPAndroidChart的動態折線圖

寫的太多,但是比較詳細

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import com.example.mpandroidcharttest.Global.MyApplication;
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.utils.ColorTemplate;

import java.util.Random;

public class LinearChart extends AppCompatActivity implements View.OnClickListener {
    private LineChart mChart;
    private Button mBtnClick;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_liner);

        initView();
        initData();

    }

    private void initData() {
        //設定可以觸控
        mChart.setTouchEnabled(true);
        //設定可拖拽
        mChart.setDragEnabled(true);
        //設定可縮放
        mChart.setScaleEnabled(true);
        //設定圖表網格背景
        mChart.setDrawGridBackground(false);
        //設定多點觸控
        mChart.setPinchZoom(true);
        //設定圖表的背景顏色
        mChart.setBackgroundColor(Color.YELLOW);
        //設定折線圖的資料
        LineData data = new LineData();
        //資料顯示的顏色
        data.setValueTextColor(Color.BLACK);
        //先新增一個空的資料,隨後往裡面動態新增
        mChart.setData(data);
        // 圖表的註解(只有當資料集存在時候才生效)
        Legend legend = mChart.getLegend();
        // 可以修改圖表註解部分的位置
        // l.setPosition(LegendPosition.LEFT_OF_CHART);
        //線性也可以是圓
        legend.setForm(Legend.LegendForm.LINE);
        //設定標籤文字的顏色
        legend.setTextColor(Color.BLUE);
        //獲取X座標軸
        XAxis xAxis = mChart.getXAxis();
        xAxis.setTextColor(Color.BLACK);
        //網格線
        xAxis.setDrawGridLines(false);
        //避免第一次最後剪裁
        xAxis.setAvoidFirstLastClipping(true);
        //幾個X座標之間才繪製
        xAxis.setSpaceBetweenLabels(5);
        //如果為false則X座標不可見
        xAxis.setEnabled(true);
        //將X座標軸放在底部,預設就是底部
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

        //圖表左邊Y軸的座標軸
        YAxis yAxis = mChart.getAxisLeft();
        //最大值
        yAxis.setAxisMaxValue(100f);
        //最小值
        yAxis.setAxisMinValue(0);
        //不一定從零開始
        yAxis.setStartAtZero(false);
        //設定圖表線
        yAxis.setDrawGridLines(true);

        //獲取圖表右邊的座標線
        YAxis right = mChart.getAxisRight();
        //不顯示圖表右邊的座標線
        right.setDrawGridLines(false);
    }

    private void initView() {
        mChart = (LineChart) findViewById(R.id.chart);
        mBtnClick = (Button) findViewById(R.id.btn_click);
        mBtnClick.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_click:
                MyApplication.getHandler(new Runnable() {
                    @Override
                    public void run() {
                        addEntry(new Random().nextInt(100));
                        MyApplication.getHandler(this, 2000);
                    }
                }, 0);
                break;
        }
    }

    /**
     * 每次點選一次增加一個點
     * @param v 隨機數
     */
    private void addEntry(int v) {
        LineData data = mChart.getData();
        //每個LineDataSet就代表一條線,每一個圖表可以有很多條線,這些折線就像是陣列一樣,下標從零開始
        LineDataSet dataSet = data.getDataSetByIndex(0);
        //如果該折線圖還沒有資料集,就建立一個出來,反之則跳過此處
        if (dataSet == null) {
            dataSet = createDataSet();
            data.addDataSet(dataSet);
        }
        //先新增一個X座標的值
        //因為是從零開始,data.getXValuesCount每次返回的都是X軸座標上的總數量,所以不必多次一舉加一
        data.addXValue(String.valueOf(data.getXValCount()));

        //dataSet.getEntryCount是獲取所有統計圖表上的資料點總量
        //從0開始的陣列下標,不必多此一舉加1
        Entry entry = new Entry((float) v,dataSet.getEntryCount());
        //往LineData裡面新增點,addEntry第二個引數就代表折線的下標索引
        // 因為本例只有一個統計折線,那麼就是第一個,其下標為0.
        // 如果同一張統計圖表中存在若干條統計折線,那麼必須分清是針對哪一條(依據下標索引)統計折線新增。
        data.addEntry(entry,0);
        //像ListView那樣通知資料更新
        mChart.notifyDataSetChanged();
        //當前統計圖表中X軸最多顯示X軸座標的總量
        mChart.setVisibleXRangeMaximum(10);

        // y座標軸線最大值
//        mChart.setVisibleYRangeMaximum(30, YAxis.AxisDependency.LEFT);

        //將座標移動到最新
        //此程式碼重新整理圖表的繪圖
//        mChart.moveViewToX(data.getXValCount()-5);

         mChart.moveViewTo(data.getXValCount()-7, 55f,
         YAxis.AxisDependency.LEFT);
    }

    /**
     * 建立資料集
     * 初始化資料集,新增一條統計折線,可以簡單的理解是初始化y座標軸線上點的表徵
     * @return LineDataSet
     */
    private LineDataSet createDataSet() {
        LineDataSet dataSet = new LineDataSet(null,"動態的新增資料");
        //設定軸的依賴
        dataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        //設定折線的顏色,整體的藍色
        dataSet.setColor(ColorTemplate.getHoloBlue());
        //包裹點的眼圈顏色
        dataSet.setCircleColor(Color.GREEN);
        //設定線的寬度
        dataSet.setLineWidth(5f);
        //設定填補透明
        dataSet.setFillAlpha(128);
        //設定填補的顏色
        dataSet.setFillColor(ColorTemplate.getHoloBlue());
        //設定高光的顏色
        dataSet.setHighLightColor(Color.BLACK);
        //設定文字值的顏色
        dataSet.setValueTextColor(Color.BLUE);
        //設定值的文字大小
        dataSet.setValueTextSize(15f);
        //設定顯示的值
        dataSet.setDrawValues(true);
        return dataSet;
    }
}

---------------------------------------------------------------------------------

還有一種程式碼量少點的實現方式,和上面的折線圖是從相反的方向變化。

import android.content.Context;
import android.graphics.Color;

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 java.util.Random;

/**
 * 這是個動態折線圖的工具類
 */

public class LineEngine {
    private String title;
    private int max;
    private LineChart mChart;

    public LineEngine(String title) {
        this.title = title;
    }

    public LineChart getView(Context context,int max) {
        this.max = max;
        mChart = new LineChart(context);
        mChart.setDescription("");
        mChart.setScaleEnabled(false);

        LineData lineData = new LineData();
        lineData.setValueTextColor(0xFF000000);
        mChart.setData(lineData);

        Legend legend = mChart.getLegend();
        legend.setForm(Legend.LegendForm.CIRCLE);
        legend.setFormSize(25f);
        legend.setTextColor(Color.BLACK);

        XAxis xAxis = mChart.getXAxis();
        xAxis.setDrawGridLines(false);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextSize(25f);

        YAxis yAxis = mChart.getAxisLeft();
        yAxis.setAxisMaxValue(max);
        yAxis.setAxisMinValue(0);
        yAxis.setTextSize(25f);

        YAxis axisRight = mChart.getAxisRight();
        axisRight.setDrawGridLines(false);
        axisRight.setXOffset(15f);
        return mChart;

    }

    public void update(int values) {
        if (values <= 0) {
            values = new Random().nextInt(max);
        }

        LineData data = mChart.getData();
        LineDataSet set = data.getDataSetByIndex(0);
        if (set == null) {
            set = createDataSet();
            data.addDataSet(set);
        }

        data.addXValue(MyUtils.getCurrentTime());

        Entry entry = new Entry(values, set.getEntryCount());
        data.addEntry(entry,0);

        mChart.notifyDataSetChanged();//通知更新速度
        mChart.setVisibleXRangeMaximum(2);//可見X範圍最大
        mChart.moveViewToX(mChart.getXValCount()-2);//對X移動檢視
    }

    private LineDataSet createDataSet() {
        LineDataSet dataSet = new LineDataSet(null,title);
        dataSet.setCircleSize(5f);
        dataSet.setLineWidth(4f);
        dataSet.setCircleColor(Color.GREEN);
        dataSet.setDrawCubic(true);
        dataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        dataSet.setColor(Color.GREEN);
        return dataSet;
    }

}

呼叫方式如下:

import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.github.mikephil.charting.charts.LineChart;

import itsoha.com.tffic.Utils.LineEngine;
import itsoha.com.tffic.Utils.LineEngineFive;
import itsoha.com.tffic.Utils.LineEngineFour;
import itsoha.com.tffic.Utils.LineEngineThree;
import itsoha.com.tffic.Utils.LineEngineTo;

/**
 * Created by Administrator on 2018/3/26.
 */

public class LineFragment extends Fragment {
    private Handler handler = new Handler();
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            engine.update(0);
            handler.postDelayed(runnable, 1500);
        }
    };
    private LineEngine engine;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        engine = new LineEngine("Test");
        LineChart chart = engine.getView(getActivity(), 100);
        handler.post(runnable);
        return chart;
    }
}