? ? 本系列篇主要介紹下Android非常火爆的三方圖表庫(kù)MpAndroidChart的使用。可能在大多數(shù)情況下,我們很少會(huì)在Android端去開發(fā)圖表,一般情況下圖表都會(huì)在PC端用H5去展示。但如果說(shuō)做一些金融財(cái)經(jīng)類、工廠類、統(tǒng)計(jì)類、大數(shù)據(jù)類等的app,肯定會(huì)涉及到到數(shù)據(jù)可視化分析,那么你絕對(duì)會(huì)用到MpAndroidChart。
目錄
一、前言
二、最強(qiáng)實(shí)踐攻略???????
三、MpAndroidChart支持的圖表類型
四、柱形圖
1、單組柱狀圖
2、多組柱狀圖
一、前言
? ? 2018年,那年的我還沒(méi)進(jìn)入互聯(lián)網(wǎng)。當(dāng)時(shí)開發(fā)一個(gè)大數(shù)據(jù)平臺(tái)項(xiàng)目,因此調(diào)研了Android端主流的圖表三方庫(kù)。其中,包括功能強(qiáng)大的MpAndroidChart、使用簡(jiǎn)單且體積較小的HelloCharts,以及在web前端非?;鸬腅charts。
? ? 回到2023年的今天,我們?cè)俅稳ithub瞄一眼。以當(dāng)前github的star數(shù)來(lái)看,Echarts仍然是最強(qiáng)大的圖表庫(kù),支持的圖表種類也是最豐富的。然而由于Echarts不是NA的,在Android端使用并不方便。當(dāng)然這不代表無(wú)法使用,我們可以讓前端同學(xué)做一個(gè)H5頁(yè)面,在WebView中去加載h5頁(yè)面間接使用它。
? ? 作為Android端的開發(fā)同學(xué),既然我們可以NA來(lái)實(shí)現(xiàn),那就不要考慮h5這種方式了。 其實(shí)絕大多數(shù)情況下,客戶端展示的圖表不會(huì)太花里胡哨,MpAndroidChart完全可以滿足我們的訴求。
二、最強(qiáng)實(shí)踐攻略???????
? ? 2018年我調(diào)研和使用MpAndroidChart3的時(shí)候,就發(fā)現(xiàn)了一些問(wèn)題。而這些問(wèn)題我通過(guò)查閱網(wǎng)上的資料,根本沒(méi)發(fā)解決,其中不乏一些錯(cuò)誤或片面的說(shuō)法。我稱該篇為MpAndroidChart最強(qiáng)實(shí)踐攻略。
當(dāng)前網(wǎng)上90%資料是MpAndroidChart2的,MpAndroidChart3跟MpAndroidChart2差別非常大,而本系列攻略基于最新的MpAndroidChart3。
當(dāng)前網(wǎng)上資料,都是復(fù)制粘貼,有很多的錯(cuò)誤,比較經(jīng)典的就是多組柱狀圖的分組問(wèn)題,而本系列會(huì)整理MpAndroidChart3常見問(wèn)題。?
三、MpAndroidChart支持的圖表類型
? ? MpAndroidChart除支持常見的柱狀圖(BarChart)、折線圖(LineChart)、餅形圖(PieChart)外,還支持例如散點(diǎn)圖(ScatterChart)、K線圖(CandleStickChart)、氣泡圖(BubbleChart)、雷達(dá)圖(RadarChart)等,并且支持例如柱狀圖和折線圖的組合圖。
? ? 以上是對(duì)MpAndroidChart3的系統(tǒng)介紹,通過(guò)官方的一些示例來(lái)看,MpAndroidChart3的功能還是非常強(qiáng)大的。接下來(lái)通過(guò)對(duì)MpAndroidChart3的一些實(shí)戰(zhàn)編碼,來(lái)完整的總結(jié)MpAndroidChart3。
四、柱形圖
? ? 什么是柱形圖?簡(jiǎn)單來(lái)講,就是那種一個(gè)柱一個(gè)柱組成的圖。真是聽君一席話,如聽一席話。。??聪掳俣劝倏频墓俜浇忉專?/p>
柱形圖,又稱長(zhǎng)條圖、柱狀統(tǒng)計(jì)圖、條圖、條狀圖、棒形圖,是一種以長(zhǎng)方形的長(zhǎng)度為變量的統(tǒng)計(jì)圖表。
1、單組柱狀圖
? ? 從百度圖片隨便搜了個(gè)柱形圖,長(zhǎng)這樣,應(yīng)該是統(tǒng)計(jì)七大洲平均海拔高度的柱形圖,那我們接下來(lái)基于MpAndroidChart的BarChart去實(shí)現(xiàn)一樣的效果。
? ? 首先,這是單柱的簡(jiǎn)單柱形圖,數(shù)據(jù)源比較簡(jiǎn)單,就是一組七大洲的海拔高度數(shù)據(jù),那我們直接按照api設(shè)置一下就好了。
/**
* 設(shè)置數(shù)據(jù)源
*/
private void setData() {
List<BarEntry> barEntries = new ArrayList<>();
barEntries.add(new BarEntry(0,1500));
barEntries.add(new BarEntry(1,500));
barEntries.add(new BarEntry(2,1500));
barEntries.add(new BarEntry(3,2000));
barEntries.add(new BarEntry(4,1000));
barEntries.add(new BarEntry(5,500));
barEntries.add(new BarEntry(6,1));
BarDataSet barDataSet = new BarDataSet(barEntries,"標(biāo)題一");
BarData ba = new BarData(barDataSet);
mBarChart.setData(ba);
}
? ? 效果長(zhǎng)這樣,非常原始的風(fēng)格,看上去亂糟糟的,非常糟糕:?
? ? ?如果我們不對(duì)柱形圖去做一些UI的設(shè)置,那么默認(rèn)的效果是比較粗獷且不美觀的。因此,接下來(lái)我們一步步去美化這個(gè)柱形圖。
1、為不同的柱設(shè)置不同的顏色
/**
* 設(shè)置數(shù)據(jù)源
*/
private void setData() {
List<BarEntry> barEntries = new ArrayList<>();
barEntries.add(new BarEntry(0,1500));
barEntries.add(new BarEntry(1,500));
barEntries.add(new BarEntry(2,1500));
barEntries.add(new BarEntry(3,2000));
barEntries.add(new BarEntry(4,1000));
barEntries.add(new BarEntry(5,500));
barEntries.add(new BarEntry(6,1));
BarDataSet barDataSet = new BarDataSet(barEntries,"標(biāo)題一");
// 設(shè)置顏色
List<Integer> colors = new ArrayList<>();
colors.add(Color.GRAY);
colors.add(Color.GREEN);
colors.add(Color.BLUE);
colors.add(Color.RED);
colors.add(Color.YELLOW);
colors.add(Color.CYAN);
colors.add(Color.BLACK);
barDataSet.setColors(colors);
BarData ba = new BarData(barDataSet);
mBarChart.setData(ba);
}
2、設(shè)置柱形圖的樣式
private void initUI(){
// 不顯示圖例
mBarChart.getLegend().setEnabled(false);
// 不顯示描述
mBarChart.getDescription().setEnabled(false);
// 左右空出barWidth/2,更美觀
mBarChart.setFitBars(true);
// 不繪制網(wǎng)格
mBarChart.setDrawGridBackground(false);
XAxis xAxis = mBarChart.getXAxis();
// 設(shè)置x軸顯示在下方
xAxis.setPosition(XAxisPosition.BOTTOM);
// 設(shè)置x軸不畫線
xAxis.setDrawGridLines(false);
// 設(shè)置自定義的ValueFormatter
String[] labels = {"北美洲","南美洲","歐洲","亞洲","大洋洲","非洲","南極洲"};
xAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
int index = (int) value;
return labels[index];
}
});
// 設(shè)置左y軸
YAxis yAxis = mBarChart.getAxisLeft();
// 設(shè)置y-label顯示在圖表外
yAxis.setPosition(YAxisLabelPosition.OUTSIDE_CHART);
// Y軸從0開始,不然會(huì)上移一點(diǎn)
yAxis.setAxisMinimum(0f);
// 設(shè)置y軸不畫線
yAxis.setDrawGridLines(false);
// 不顯示右y軸
YAxis rightAxis = mBarChart.getAxisRight();
rightAxis.setEnabled(false);
}
? ? ?優(yōu)化后,新的柱形圖長(zhǎng)這樣:
2、多組柱狀圖
? ? 上面的例子是非常簡(jiǎn)單的柱狀圖,接下來(lái),我們繪制如下一個(gè)柱狀圖:描述2022年Q1-Q4四家企業(yè)蘋果、微軟、亞馬遜、谷歌的收入情況的柱狀圖。分三步走:
1、初始化數(shù)據(jù)源
private void setChartData() {
List<BarEntry> barEntries1 = new ArrayList<>();
barEntries1.add(new BarEntry(0, 1500));
barEntries1.add(new BarEntry(1, 1400));
barEntries1.add(new BarEntry(2, 800));
barEntries1.add(new BarEntry(3, 2000));
BarDataSet barDataSet1 = new BarDataSet(barEntries1, "Q1");
List<BarEntry> barEntries2 = new ArrayList<>();
barEntries2.add(new BarEntry(0, 1000));
barEntries2.add(new BarEntry(1, 1200));
barEntries2.add(new BarEntry(2, 1500));
barEntries2.add(new BarEntry(3, 900));
BarDataSet barDataSet2 = new BarDataSet(barEntries2, "Q2");
List<BarEntry> barEntries3 = new ArrayList<>();
barEntries3.add(new BarEntry(0, 900));
barEntries3.add(new BarEntry(1, 1000));
barEntries3.add(new BarEntry(2, 1200));
barEntries3.add(new BarEntry(3, 1500));
BarDataSet barDataSet3 = new BarDataSet(barEntries3, "Q3");
List<BarEntry> barEntries4 = new ArrayList<>();
barEntries4.add(new BarEntry(0, 1400));
barEntries4.add(new BarEntry(1, 800));
barEntries4.add(new BarEntry(2, 1000));
barEntries4.add(new BarEntry(3, 500));
BarDataSet barDataSet4 = new BarDataSet(barEntries4, "Q4");
List<Integer> colors = new ArrayList<>();
colors.add(Color.GREEN);
colors.add(Color.BLUE);
colors.add(Color.RED);
colors.add(Color.YELLOW);
barDataSet1.setColor(colors.get(0));
barDataSet2.setColor(colors.get(1));
barDataSet3.setColor(colors.get(2));
barDataSet4.setColor(colors.get(3));
List<IBarDataSet> barDataSets = new ArrayList<>();
barDataSets.add(barDataSet1);
barDataSets.add(barDataSet2);
barDataSets.add(barDataSet3);
barDataSets.add(barDataSet4);
BarData ba = new BarData(barDataSets);
mBarChart.setData(ba);
}
2、初始化公共UI
private void updateCommonUI(){
// 不顯示圖例
mBarChart.getLegend().setEnabled(false);
// 不顯示描述
mBarChart.getDescription().setEnabled(false);
// 不繪制網(wǎng)格
mBarChart.setDrawGridBackground(false);
mBarChart.setScaleYEnabled(false);
mBarChart.setScaleXEnabled(false);
mBarChart.setScaleEnabled(false);
// 設(shè)置左y軸
YAxis yAxis = mBarChart.getAxisLeft();
// 設(shè)置y-label顯示在圖表外
yAxis.setPosition(YAxisLabelPosition.OUTSIDE_CHART);
// Y軸從0開始,不然會(huì)上移一點(diǎn)
yAxis.setAxisMinimum(0f);
// 設(shè)置y軸不畫線
yAxis.setDrawGridLines(false);
// 不顯示右y軸
YAxis rightAxis = mBarChart.getAxisRight();
rightAxis.setEnabled(false);
}
3、初始化圖表UI
private void updateChartUI() {
String[] labels = {"Q1", "Q2", "Q3", "Q4"};
XAxis xAxis = mBarChart.getXAxis();
// 設(shè)置自定義的ValueFormatter
xAxis.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value) {
int index = (int) value;
// 注意不要數(shù)組越界
if (index >= 0 && index < labels.length) {
return labels[index];
}
return "";
}
});
// 設(shè)置x軸顯示在下方
xAxis.setPosition(XAxisPosition.BOTTOM);
// 設(shè)置x軸不畫線
xAxis.setDrawGridLines(false);
// 設(shè)置x軸標(biāo)簽從0開始
xAxis.setAxisMinimum(0);
// 設(shè)置x軸顯示的最大標(biāo)簽數(shù)量
xAxis.setAxisMaximum(labels.length);
// x軸標(biāo)簽居中
xAxis.setCenterAxisLabels(true);
// 接下來(lái)這段代碼尤其重要,網(wǎng)上幾乎99%的資料說(shuō)的都是錯(cuò)的,這里詳解一下
// 1、要想標(biāo)簽跟group中間對(duì)齊,必須保證:(barWidth + barSpace) * group + groupSpace = granularity
// 2、granularity < 1,則右邊會(huì)有空余;
// 3、granularity = 1,則剛好在一個(gè)屏幕顯示開;
// 4、granularity > 1,則一個(gè)屏幕顯示不開;
float barSpace = 0.025f;
float groupSpace = 0.1f;
float barWidth = 0.2f;
float granularity = (barWidth + barSpace) * labels.length + groupSpace;
xAxis.setGranularity(granularity);
mBarChart.setScaleX(granularity);
mBarChart.getBarData().setBarWidth(barWidth);
mBarChart.groupBars(0, groupSpace, barSpace);
}
? ? 我在代碼里有一大串非常重要的注釋,正如我前文所說(shuō),關(guān)于多組柱狀圖的分組問(wèn)題,網(wǎng)上的資料都是錯(cuò)的,我在這里再次拎出來(lái),大家務(wù)必理解核心的代碼:
// 接下來(lái)這段代碼尤其重要,網(wǎng)上幾乎99%的資料說(shuō)的都是錯(cuò)的,這里詳解一下 // 1、要想標(biāo)簽跟group中間對(duì)齊,必須保證:(barWidth + barSpace) * group + groupSpace = granularity // 2、granularity < 1,則右邊會(huì)有空余; // 3、granularity = 1,則剛好在一個(gè)屏幕顯示開; // 3、granularity > 1,則一個(gè)屏幕顯示不開; float barSpace = 0.025f; float groupSpace = 0.1f; float barWidth = 0.2f; float granularity = (barWidth + barSpace) * labels.length + groupSpace; xAxis.setGranularity(granularity); mBarChart.setScaleX(granularity); mBarChart.getBarData().setBarWidth(barWidth); mBarChart.groupBars(0, groupSpace, barSpace);
好,接下來(lái)我們運(yùn)行看下效果:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-619690.html
? ? 還有點(diǎn)不完美的地方,沒(méi)有畫圖例,后續(xù)我們一起看下如何添加圖例。持續(xù)更新中......20230418文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-619690.html
到了這里,關(guān)于Android最火的框架系列(十三)MpAndroidChart的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!