MPAndroidChart app Android Chart 圖表庫

MPAndroidChart 強大易用圖表庫

Vivian Wu 2020/02/20 10:18:16
396

 

一、 前言:

最近專案需要繪製「匯率走勢圖」(如下),同仁推薦使用MPAndroidChart,網路評價也是一個強大的圖表庫,支持Android && iOS跨平台使用,且在Android Studio中使用很方便,適用Android 2.2 (API 8)及以上,可以實現如折線圖、長條圖、圓餅圖、散點圖、K線圖、氣泡圖、雷達圖等,當然要趕快來體驗一下!

 

二、 使用方式:

本次是使用MPAndroidChart 3.0.3版本,要留意不同版本會有不同的使用語法,最新版本請參考這裡

build.gradle添加如下代碼

repositories {
       maven { url "https://jitpack.io" }
}

dependencies {
    implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
}

 

三、 匯率走勢圖(折線圖)功能實作:

(一) Layout

.xml文件定義如下

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

其中com.github.mikephil.charting.charts.LineChart依使用需求不同可替換成BarChart長條圖ScatterChart散點圖/雜湊圖CandleStickChart蠟燭圖(應用在金融分析時常稱為K線圖)PieChart圓餅圖BubbleChart氣泡圖、RadarChart雷達圖或CombinedChart組合圖(如:長條圖+折線圖)等

最後在Activity 中設定

lineChart = findViewById(R.id.lineChart);

 

(二)將主要實作功能統整成四個區塊,照步驟即可實現所需圖表,此外也針對常用功能併同研究並分類及說明如后,方便大家依不同情況可快速套用。

1、initDataSet(values, values1, values_end, values1_end); //設定數據源
2、initX();//設定X軸樣式
3、initY();//設定Y軸樣式
4、initChartFormat();//設定圖表樣式

1、  設定數據源:

1賦值XY

onCreate()設定如下,Entry可以理解成一個點,賦值XY,二條線要分別設定

// greenLine
ArrayList<Entry> values = new ArrayList<>();
values.add(new Entry(1, 30.65f));
values.add(new Entry(1.3f, 30.69f));
……
values.add(new Entry(5.8f, 30.58f));
values.add(new Entry(6, 30.58f));

//yellowLine
ArrayList<Entry> values1 = new ArrayList<>();
values1.add(new Entry(1f, 30.63f));
values1.add(new Entry(1.5f, 30.65f));
values1.add(new Entry(1.8f, 30.66f));
……
values1.add(new Entry(5.7f, 30.53f));
values1.add(new Entry(6, 30.53f));

2折線最後的圓點:

由於線尾的圓點樣式與其他座標不同,因此需再使用二條list,作為之後設定不同樣式使用

// greenLine
ArrayList<Entry> values_end = new ArrayList<>();
values_end.add(new Entry(6, 30.58f));
//yellowLine
ArrayList<Entry> values1_end = new ArrayList<>();
values1_end.add(new Entry(6, 30.53f));

3多個點連成一條線(LineDataSet):

private void initDataSet(final ArrayList<Entry> values, ArrayList<Entry> values1, ArrayList<Entry> values_end, ArrayList<Entry> values1_end) {
        final LineDataSet set, set1, set_end, set1_end;
        // greenLine
        set = new LineDataSet(values, ""); 
        set.setMode(LineDataSet.Mode.LINEAR);//類型為折線  
        set.setColor(getResources().getColor(R.color.green));//線的顏色
        set.setLineWidth(1.5f);//線寬
        set.setDrawCircles(false); //不顯示相應座標點的小圓圈(預設顯示)
set.setDrawValues(false);//不顯示座標點對應Y軸的數字(預設顯示)
       
//greenLine最後的圓點
       set_end = new LineDataSet(values_end, "");
       set_end.setCircleColor(getResources().getColor(R.color.green));//圓點顏色
set_end.setColor(getResources().getColor(R.color.green));//線的顏色
set_end.setCircleRadius(4);//圓點大小
       set_end.setDrawCircleHole(false);//圓點為實心(預設空心)
       set_end.setDrawValues(false);//不顯示座標點對應Y軸的數字(預設顯示)

       /**
 * yellowLine及其最後的圓點設定可比照如上greenLine設定,不再列示
 */

//理解爲多條線的集合
        LineData data = new LineData(set, set1, set_end, set1_end);
        lineChart.setData(data);//一定要放在最後
        lineChart.invalidate();//繪製圖表
    }

目前為止顯示如下圖,下個步驟要來調整一下XY軸數據。

4其他好用功能分享:

set.setMode(LineDataSet.Mode.LINEAR);//折線
     /* 共有四種模式可作變化    
STEPPED立方曲線 (如下greenLine)
CUBIC_BEZIER圓滑曲線 (如下yellowLine)
HORIZONTAL_BEZIER水平曲線
*/

set.setDrawValues(true);//顯示座標點對應Y軸的數字(預設顯示)
set.setValueTextSize(8);//座標點數字大小
set.setValueFormatter(new DefaultValueFormatter(1));//座標點數字的小數位數1位

set.setDrawFilled(true);//使用範圍背景填充(預設不使用)

set.setHighlightEnabled(false);//禁用點擊交點後顯示高亮線 (預設顯示,如為false則以下設定均無效)
set.enableDashedHighlightLine(5, 5, 0);//高亮線以虛線顯示,可設定虛線長度、間距等
set.setHighlightLineWidth(2);//高亮線寬度
set.setHighLightColor(Color.RED);//高亮線顏色

2、  設定X軸樣式:

1getXAxis()及設定資料:

private void initX() {
        XAxis xAxis = lineChart.getXAxis();

        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//X軸標籤顯示位置(預設顯示在上方,分為上方內/外側、下方內/外側及上下同時顯示)
        xAxis.setTextColor(Color.GRAY);//X軸標籤顏色
        xAxis.setTextSize(12);//X軸標籤大小

        xAxis.setLabelCount(6);//X軸標籤個數
        xAxis.setSpaceMin(0.5f);//折線起點距離左側Y軸距離
        xAxis.setSpaceMax(0.5f);//折線終點距離右側Y軸距離

        xAxis.setDrawGridLines(false);//不顯示每個座標點對應X軸的線 (預設顯示)

        //設定所需特定標籤資料
        String[] xValue = new String[]{"", "1/3", "1/10", "1/17", "1/24", "1/31", "2/7"};
        List<String> xList = new ArrayList<>();
        for (int i = 0; i < xValue.length; i++) {
            xList.add(xValue[i]);
//            xList.add(String.valueOf(i +1).concat("月"));
        }
        /**
         * 格式化軸標籤二種方式:
         * 1、用圖表庫已寫好的類_如下X 軸使用
         * 2、自己實現接口_下一步驟中Y 軸使用
         * */
        xAxis.setValueFormatter(new IndexAxisValueFormatter(xList));
    }

如下圖已愈來愈接近所需要的格式,下個步驟再來調整Y軸。

2其他好用功能分享:

xAxis.setEnabled(false);//不顯示X軸 (預設顯示,如為false則以下設定均無效)
xAxis.setDrawAxisLine(false);//不顯示X軸的線 (預設顯示)
xAxis.setAxisLineColor(Color.GREEN);//X軸線顏色
xAxis.setAxisLineWidth(2f);//X軸線寬度

xAxis.setDrawLabels(false);//不顯示X軸的對應標籤 (預設顯示)
xAxis.setAxisMinimum(1);//X軸標籤最小值
xAxis.setAxisMaximum(10);//X軸標籤最大值
xAxis.setLabelRotationAngle(-25);//X軸數字旋轉角度

xAxis.enableGridDashedLine(5f, 5f, 0f); //格線以虛線顯示,可設定虛線長度、間距等,如setDrawGridLines(false)則此設定無效
xAxis.setGridLineWidth(2f);//格線寬度
xAxis.setGridColor(Color.RED);//格線顏色

3、  設定Y軸樣式:

1getAxisRight()getAxisLeft()及設定資料:

Y軸預設左右兩側會同時顯示,設定原理與X軸大同小異,依照我們的需求設定如下

private void initY() {
    YAxis rightAxis = lineChart.getAxisRight();//獲取右側的軸線
    rightAxis.setEnabled(false);//不顯示右側Y軸
    YAxis leftAxis = lineChart.getAxisLeft();//獲取左側的軸線

    leftAxis.setLabelCount(4);//Y軸標籤個數
    leftAxis.setTextColor(Color.GRAY);//Y軸標籤顏色
    leftAxis.setTextSize(12);//Y軸標籤大小
    
    leftAxis.setAxisMinimum(30.5f);//Y軸標籤最小值
    leftAxis.setAxisMaximum(30.9f);//Y軸標籤最大值

    /**
     * 格式化軸標籤二種方式:
     * 1、用圖表庫已寫好的類_如上一步驟中X 軸使用
     * 2、自己實現接口_如下Y 軸使用
     * */
    leftAxis.setValueFormatter(new MyYAxisValueFormatter());
}

class MyYAxisValueFormatter implements IAxisValueFormatter {

    private DecimalFormat mFormat;

    public MyYAxisValueFormatter() {
        mFormat = new DecimalFormat("###,###.0");//Y軸數值格式及小數點位數
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        // "value" represents the position of the label on the axis (x or y)
        return mFormat.format(value);
    }
}

設定好X、Y軸後,圖表畫面只剩下幾個資訊需要再調整。

2其他好用功能分享:

leftAxis.setGranularity(0.1f);//Y軸數值的間隔
leftAxis.setDrawTopYLabelEntry(false);//不顯示Y軸最上方數值 (預設顯示)
leftAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);//Y軸標籤顯示位置
leftAxis.setXOffset(10f);//單位dp,Y數值與Y軸間的空隙寬度

leftAxis.enableGridDashedLine(5f, 5f, 0f);//格線以虛線顯示,可設定虛線長度、間距等

4、  設定圖表樣式:

1)設定description label圖表資訊、Legend圖例、背景顏包及沒資料時的顯示畫面:

private void initChartFormat() {
        //右下方description label:設置圖表資訊
        Description description = lineChart.getDescription();
        description.setEnabled(false);//不顯示Description Label (預設顯示)

        //左下方Legend:圖例數據資料
        Legend legend = lineChart.getLegend();
        legend.setEnabled(false);//不顯示圖例 (預設顯示)

        lineChart.setBackgroundColor(Color.WHITE);//顯示整個圖表背景顏色 (預設灰底)

        //設定沒資料時顯示的內容
        lineChart.setNoDataText("暫時沒有數據");   
        lineChart.setNoDataTextColor(Color.BLUE);//文字顏色
 }

大功告成,上圖為原始圖,下圖為MPAndroidChart,是不是挺相像的呢!

2其他好用功能分享:

//description label:設置圖表資訊
description.setText("美元(USD)");//顯示文字名稱
description.setTextSize(14);//字體大小
description.setTextColor(getResources().getColor(R.color.colorAccent));//字體顏色
description.setPosition(680, 80);//顯示位置座標 (預設右下方)

//圖表邊框
lineChart.setDrawBorders(true);//顯示邊框 (預設不顯示)

//縮放
lineChart.setScaleEnabled(false);// 禁用縮放及點二下觸摸響應,點擊可顯示高亮線
lineChart.setTouchEnabled(false);// 禁用縮放及點二下觸摸響應,點擊也不顯示高亮線
lineChart.setPinchZoom(true); // true->X、Y軸同時按比例縮放、false:X、Y可單獨縮放

 

四、 轉成圖片問題:

MPAndroidChart功能繁多且有多種縮放設定供選擇,為求圖表資訊第一眼即可讓人一目瞭然,一般會直接設定為靜態畫面,不會有過多的變動選項,這個部份可以參考前述的「縮放」功能,直接將setScaleEnabled() setTouchEnabled() 設定為false也有類似圖片的功能。

但如實際需要存成一張圖片應該也不是沒有辦法,找了許久功能才發現如下方法,但實作時要記得待MPAndroidChart功能實現後,再用延遲時間的語法去顯示圖片,大家可以試試看!

lineChart.saveToPath("chart", "/Download/");//保存到指定路徑
lineChart.setSaveEnabled(true);
img.setImageDrawable(null);
img.setImageURI(Uri.parse("/storage/emulated/0/Download/chart.png"));//顯示圖片

有圖有真相

 

五、結論:

本文主要針對常用圖表-折線圖作較詳盡的功能說明,並實作同時顯示多條折線圖及DataSet中如何設定折線尾端的實心圓點,過程中需多加留意版本設定、存儲圖片權限開啟及各圖表設定功能間的衝突等;此外,MPAndroidChart也可以實現組合式圖表,如折線圖+長條圖,基本上需先在 layout設定com.github.mikephil.charting.charts.CombinedChart,最後附上常用圖表相關連結如下,可依需求再作參考,謝謝!

 

github sample參考:https://github.com/PhilJay/MPAndroidChart

BarChart長條圖 https://blog.csdn.net/ww897532167/article/details/74171294

ScatterChart散點圖/雜湊圖 https://inducesmile.com/android-programming/how-to-draw-scatterchart-using-mpandroidchart-in-android/

CandleStickChart K線圖 https://blog.csdn.net/qq_31743309/article/details/82425959

PieChart圓餅圖 https://blog.csdn.net/zcmain/article/details/53611245

BubbleChart氣泡圖 https://www.tutorialspoint.com/how-to-use-bubble-chart-graph-in-android

RadarChart雷達圖 https://www.itdaan.com/tw/5141ba20189c

CombinedChart組合圖(如:長條圖+折線圖) https://blog.csdn.net/ww897532167/article/details/74178449

 

 

Vivian Wu