MPAndroidChart 強大易用圖表庫
一、 前言:
最近專案需要繪製「匯率走勢圖」(如下),同仁推薦使用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)賦值X與Y:
在onCreate()設定如下,Entry可以理解成一個點,賦值X與Y,二條線要分別設定
// 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();//繪製圖表
}
目前為止顯示如下圖,下個步驟要來調整一下X、Y軸數據。
(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軸樣式:
(1)getXAxis()及設定資料:
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軸樣式:
(1)getAxisRight()、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