1. 程式人生 > >Android圖表控制元件MPAndroidChart——曲線圖LineChart(多條曲線)動態新增資料

Android圖表控制元件MPAndroidChart——曲線圖LineChart(多條曲線)動態新增資料

發現最新的MPAndroidChart和以前版本的使用有一些差距,就寫下了現在新版的使用方法

相關文章:

一.效果圖

一條曲線動態新增資料(X軸為當前時間)

多條曲線線動態新增資料(X軸為當前時間)


二.實現效果

1.X軸為當前時間,只需要Y軸資料即可

2.X軸的值為字串,而Entry的構造方法引數全為float    public Entry(float x, float y)  所以需要另外定義X軸的值

簡要程式碼

動態新增值Entry

Entry entry = new Entry(lineDataSet.getEntryCount(), number);
lineData.addEntry(entry, 
0); //通知資料已經改變 lineData.notifyDataChanged(); lineChart.notifyDataSetChanged(); //設定在曲線圖中顯示的最大數量 lineChart.setVisibleXRangeMaximum(10); //移到某個位置 lineChart.moveViewToX(lineData.getEntryCount() - 5);

X軸值的設定

我並沒有找到直接設定X軸為當前時間的方法,

而是新建一個字串集合,選擇在每次新增Entry的時候將當前時間新增進集合,然後設定X軸的值

private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss"
);//設定日期格式private List<String> timeList = new ArrayList<>(); //儲存x軸的時間
xAxis.setValueFormatter(new IAxisValueFormatter() {
    @Override
public String getFormattedValue(float value, AxisBase axis) {
        return timeList.get((int) value % timeList.size());
}
});

三.詳細程式碼(一個管理類)

public class DynamicLineChartManager {

    private 
LineChart lineChart; private YAxis leftAxis; private YAxis rightAxis; private XAxis xAxis; private LineData lineData; private LineDataSet lineDataSet; private List<ILineDataSet> lineDataSets = new ArrayList<>(); private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//設定日期格式private List<String> timeList = new ArrayList<>(); //儲存x軸的時間 //一條曲線 public DynamicLineChartManager(LineChart mLineChart, String name, int color) { this.lineChart = mLineChart; leftAxis = lineChart.getAxisLeft(); rightAxis = lineChart.getAxisRight(); xAxis = lineChart.getXAxis(); initLineChart(); initLineDataSet(name, color); } //多條曲線 public DynamicLineChartManager(LineChart mLineChart, List<String> names, List<Integer> colors) { this.lineChart = mLineChart; leftAxis = lineChart.getAxisLeft(); rightAxis = lineChart.getAxisRight(); xAxis = lineChart.getXAxis(); initLineChart(); initLineDataSet(names, colors); } /** * 初始化LineChar */ private void initLineChart() { lineChart.setDrawGridBackground(false); //顯示邊界 lineChart.setDrawBorders(true); //折線圖例 標籤 設定 Legend legend = lineChart.getLegend(); legend.setForm(Legend.LegendForm.LINE); legend.setTextSize(11f); //顯示位置 legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); //X軸設定顯示位置在底部 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setGranularity(1f); xAxis.setLabelCount(10); xAxis.setValueFormatter(new IAxisValueFormatter() { @Override public String getFormattedValue(float value, AxisBase axis) { return timeList.get((int) value % timeList.size()); } }); //保證Y軸從0開始,不然會上移一點 leftAxis.setAxisMinimum(0f); rightAxis.setAxisMinimum(0f); } /** * 初始化折線(一條線) * * @param name * @param color */ private void initLineDataSet(String name, int color) { lineDataSet = new LineDataSet(null, name); lineDataSet.setLineWidth(1.5f); lineDataSet.setCircleRadius(1.5f); lineDataSet.setColor(color); lineDataSet.setCircleColor(color); lineDataSet.setHighLightColor(color); //設定曲線填充 lineDataSet.setDrawFilled(true); lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT); lineDataSet.setValueTextSize(10f); lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER); //新增一個空的 LineData lineData = new LineData(); lineChart.setData(lineData); lineChart.invalidate(); } /** * 初始化折線(多條線) * * @param names * @param colors */ private void initLineDataSet(List<String> names, List<Integer> colors) { for (int i = 0; i < names.size(); i++) { lineDataSet = new LineDataSet(null, names.get(i)); lineDataSet.setColor(colors.get(i)); lineDataSet.setLineWidth(1.5f); lineDataSet.setCircleRadius(1.5f); lineDataSet.setColor(colors.get(i)); lineDataSet.setDrawFilled(true); lineDataSet.setCircleColor(colors.get(i)); lineDataSet.setHighLightColor(colors.get(i)); lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER); lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT); lineDataSet.setValueTextSize(10f); lineDataSets.add(lineDataSet); } //新增一個空的 LineData lineData = new LineData(); lineChart.setData(lineData); lineChart.invalidate(); } /** * 動態新增資料(一條折線圖) * * @param number */ public void addEntry(int number) { //最開始的時候才新增 lineDataSet(一個lineDataSet 代表一條線) if (lineDataSet.getEntryCount() == 0) { lineData.addDataSet(lineDataSet); } lineChart.setData(lineData); //避免集合資料過多,及時清空(做這樣的處理,並不知道有沒有用,但還是這樣做了) if (timeList.size() > 11) { timeList.clear(); } timeList.add(df.format(System.currentTimeMillis())); Entry entry = new Entry(lineDataSet.getEntryCount(), number); lineData.addEntry(entry, 0); //通知資料已經改變 lineData.notifyDataChanged(); lineChart.notifyDataSetChanged(); //設定在曲線圖中顯示的最大數量 lineChart.setVisibleXRangeMaximum(10); //移到某個位置 lineChart.moveViewToX(lineData.getEntryCount() - 5); } /** * 動態新增資料(多條折線圖) * * @param numbers */ public void addEntry(List<Integer> numbers) { if (lineDataSets.get(0).getEntryCount() == 0) { lineData = new LineData(lineDataSets); lineChart.setData(lineData); } if (timeList.size() > 11) { timeList.clear(); } timeList.add(df.format(System.currentTimeMillis())); for (int i = 0; i < numbers.size(); i++) { Entry entry = new Entry(lineDataSet.getEntryCount(), numbers.get(i)); lineData.addEntry(entry, i); lineData.notifyDataChanged(); lineChart.notifyDataSetChanged(); lineChart.setVisibleXRangeMaximum(6); lineChart.moveViewToX(lineData.getEntryCount() - 5); } } /** * 設定Y軸值 * * @param max * @param min * @param labelCount */ public void setYAxis(float max, float min, int labelCount) { if (max < min) { return; } leftAxis.setAxisMaximum(max); leftAxis.setAxisMinimum(min); leftAxis.setLabelCount(labelCount, false); rightAxis.setAxisMaximum(max); rightAxis.setAxisMinimum(min); rightAxis.setLabelCount(labelCount, false); lineChart.invalidate(); } /** * 設定高限制線 * * @param high * @param name */ public void setHightLimitLine(float high, String name, int color) { if (name == null) { name = "高限制線"; } LimitLine hightLimit = new LimitLine(high, name); hightLimit.setLineWidth(4f); hightLimit.setTextSize(10f); hightLimit.setLineColor(color); hightLimit.setTextColor(color); leftAxis.addLimitLine(hightLimit); lineChart.invalidate(); } /** * 設定低限制線 * * @param low * @param name */ public void setLowLimitLine(int low, String name) { if (name == null) { name = "低限制線"; } LimitLine hightLimit = new LimitLine(low, name); hightLimit.setLineWidth(4f); hightLimit.setTextSize(10f); leftAxis.addLimitLine(hightLimit); lineChart.invalidate(); } /** * 設定描述資訊 * * @param str */ public void setDescription(String str) { Description description = new Description(); description.setText(str); lineChart.setDescription(description); lineChart.invalidate(); } }

XML佈局

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
    <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
        <com.github.mikephil.charting.charts.LineChart
android:id="@+id/dynamic_chart1"
android:layout_width="match_parent"
android:layout_height="380dp"/>
        <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="addEntry"
android:text="隨機資料"
/>
        <com.github.mikephil.charting.charts.LineChart
android:id="@+id/dynamic_chart2"
android:layout_width="match_parent"
android:layout_height="380dp"/>
    </LinearLayout>
</ScrollView>

Activity中的程式碼

public class DynamicLineChartActivity extends AppCompatActivity {

    private DynamicLineChartManager dynamicLineChartManager1;
    private DynamicLineChartManager dynamicLineChartManager2;
    private List<Integer> list = new ArrayList<>(); //資料集合
private List<String> names = new ArrayList<>(); //折線名字集合
private List<Integer> colour = new ArrayList<>();//折線顏色集合
@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_linechart);
LineChart mChart1 = (LineChart) findViewById(R.id.dynamic_chart1);
LineChart mChart2 = (LineChart) findViewById(R.id.dynamic_chart2);
//折線名字
names.add("溫度");
names.add("壓強");
names.add("其他");
//折線顏色
colour.add(Color.CYAN);
colour.add(Color.GREEN);
colour.add(Color.BLUE);
dynamicLineChartManager1 = new DynamicLineChartManager(mChart1, names.get(0), colour.get(0));
dynamicLineChartManager2 = new DynamicLineChartManager(mChart2, names, colour);
dynamicLineChartManager1.setYAxis(100, 0, 10);
dynamicLineChartManager2.setYAxis(100, 0, 10);
//死迴圈新增資料
new Thread(new Runnable() {
            @Override
public void run() {
                while (true) {
                    try {
                        Thread.sleep(500);
} catch (InterruptedException e) {
                        e.printStackTrace();
}
                    runOnUiThread(new Runnable() {
                        @Override
public void run() {
                            list.add((int) (Math.random() * 50) + 10);
list.add((int) (Math.random() * 80) + 10);
list.add((int) (Math.random() * 100));
dynamicLineChartManager2.addEntry(list);
list.clear();
}
                    });
}
            }
        }).start();
}

    //按鈕點選新增資料
public void addEntry(View view) {
        dynamicLineChartManager1.addEntry((int) (Math.random() * 100));
}
}

四.使用中遇到的一些問題

1.X軸新增字串,或者設定顯示格式

xAxis.setValueFormatter(new IAxisValueFormatter() {
    @Override
public String getFormattedValue(float value, AxisBase axis) {
        return timeList.get((int) value % timeList.size());
}
});

2.動態新增資料資料時,曲線不自動往左邊移動,而是擠在一堆

//設定在曲線圖中顯示的最大數量
lineChart.setVisibleXRangeMaximum(10);
//移到某個位置
lineChart.moveViewToX(lineData.getEntryCount() - 5);