MPAndroidChart使用详解--BarChart和PieChart使用实例
1. app的build.gradle中添加依赖:
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.1'
2. 项目的build.gradle中添加:
allprojects {
repositories {
……
maven { url 'https://jitpack.io' }
}
}
3. 布局文件:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".modules.analysis.collect.AnalysisCollectActivity">
<LinearLayout
android:orientation="vertical"
android:paddingTop="@dimen/px30"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.BarChart
android:id="@+id/bc_collect"
android:layout_marginHorizontal="@dimen/px20"
android:layout_width="match_parent"
android:layout_height="260dp"/>
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/pc_collect"
android:layout_marginTop="@dimen/px30"
android:layout_marginHorizontal="@dimen/px20"
android:layout_width="match_parent"
android:layout_height="240dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_collect"
android:layout_marginHorizontal="@dimen/px30"
android:layout_marginBottom="@dimen/px20"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
4. AnalysisCollectActivity.java
public class AnalysisCollectActivity extends BaseActivity {
private static final String TAG = "AnalysisCollectActivity";
private Context mContext;
@BindView(R.id.bc_collect)
BarChart bc_collect;
@BindView(R.id.pc_collect)
PieChart pc_collect;
@BindView(R.id.rv_collect)
RecyclerView rv_collect;
private List<CollectData> collectDataList = new ArrayList<>();
private List<CollectDataBL> collectDataBLList = new ArrayList<>();
private List<CollectDetailBean> collectDetailBeans = new ArrayList<>();
@Override
public int getLayoutResID() {
return R.layout.activity_analysis_collect;
}
public void initContentView(@Nullable Bundle savedInstanceState) {
mContext = AnalysisCollectActivity.this;
//柱状图点击监听
bc_collect.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
@Override
public void onValueSelected(Entry e, Highlight h) {
if (e.getData() != null) {
CollectData collectData = (CollectData) e.getData();
getCollectDetail(collectData.getId());
}
}
@Override
public void onNothingSelected() {
}
});
}
@Override
public void initData(@Nullable Bundle savedInstanceState) {
getCollectData();
}
private void getCollectData() {
HashMap<String, Object> baseParam = WebFrontUtil.getBaseParam();
OkHttpUtil.post(TAG, WebApi.ACTIVITY_ANALYSIS_COLLECT, baseParam, new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
Log.d(TAG,"getCollectData e="+e);
}
@Override
public void onResponse(String response, int id) {
Log.d(TAG,"getCollectData response="+response);
try {
JSONObject object = new JSONObject(response);
if ((int)object.get("code") == 200) {
JSONObject object1 = object.getJSONObject("data");
if (object1 == null) return;
JSONArray array = object1.getJSONArray("data");
Gson gson = new Gson();
for (int i= 0;i<array.length();i++) {
CollectData resultBean = gson.fromJson(array.get(i).toString(), CollectData.class);
collectDataList.add(resultBean);
}
//柱状图设置
ChartUtils.initBarChart(bc_collect,collectDataList.size(),true,false);
setBarChartData(bc_collect);
//与上一行代码同样的效果
//convertData(collectDataList);
List<PieEntry> entries = new ArrayList<>();
JSONArray array1 = object1.getJSONArray("dataBL");
for (int i= 0;i<array1.length();i++) {
CollectDataBL resultBean = gson.fromJson(array1.get(i).toString(), CollectDataBL.class);
PieEntry pieEntry = new PieEntry(resultBean.getOfficeCount(),resultBean.getType());
entries.add(pieEntry);
collectDataBLList.add(resultBean);
}
ChartUtils.initPieChart(pc_collect,false);
ChartUtils.setPieData(entries, pc_collect);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
//柱状数据填充
private void setBarChartData(BarChart mBarChart) {
List<BarEntry> barEntries = new ArrayList<>();
List<BarEntry> barEntries1 = new ArrayList<>();
for (int i= 0; i< collectDataList.size(); i++) {
CollectData bean = collectDataList.get(i);
BarEntry barEntry = new BarEntry(i,bean.getValue());
barEntry.setData(bean);
barEntries.add(barEntry);
}
for (int i= 0; i< collectDataList.size(); i++) {
CollectData bean = collectDataList.get(i);
BarEntry barEntry = new BarEntry(i,bean.getValueInspect());
barEntry.setData(bean);
barEntries1.add(barEntry);
}
//X轴自定义值
XAxis xAxis = mBarChart.getXAxis();
//X轴自定义值
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
//当设置了xAxis.setAxisMinimum(0f);时,value的值可能为负值,会报空指针异常
if (value < 0) {
return "";
}
String labelValue = collectDataList.get((int) value % collectDataList.size()).getName();
if (labelValue.length() > 4) {
labelValue = labelValue.substring(0,4)+"…";
}
return labelValue;
}
});
List<IBarDataSet> barDataSets = new ArrayList<>();
//BarDataSet第二个参数为图例的label
BarDataSet barDataSet = new BarDataSet(barEntries,"单位总数");
barDataSet.setColor(getResources().getColor(R.color.color_shop_title));
barDataSet.setFormSize(15.f);
// barDataSet.setFormLineWidth(1f);
barDataSet.setDrawValues(false);
BarDataSet barDataSet1 = new BarDataSet(barEntries1,"已检查单位数");
barDataSet1.setColor(getResources().getColor(R.color.color_expire));
barDataSet1.setFormSize(15.f);
// barDataSet1.setFormLineWidth(1f);
barDataSet1.setDrawValues(false);
barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
barDataSet1.setAxisDependency(YAxis.AxisDependency.LEFT);
barDataSets.add(barDataSet);
barDataSets.add(barDataSet1);
BarData data = new BarData(barDataSet,barDataSet1);
mBarChart.setData(data);
// 设置 柱子宽度
// float barWidth = 0.4f;
// float groupSpace = 0.2f;
// float barSpace = 0.00f;
float groupSpace = 0.3f; //柱状图组之间的间距
float barSpace = (float) ((1 - 0.12) / 2 / 10); // x4 DataSet
float barWidth = (float) ((1 - 0.3) / 2 / 10 * 9); // x4 DataSet
data.setBarWidth(barWidth);
//num为多条柱状图的条数
Log.e(TAG,"value = "+((barWidth + barSpace) * num + groupSpace));
mBarChart.groupBars(0f, groupSpace, barSpace);
mBarChart.invalidate();
}
}
5. BarChart和PieChart的工具类:
ChartUtils.java
public class ChartUtils {
/*
* 柱状图初始化
* size 为数据的条数
* isLegend 为是否显示图例
* isSingle 为是否为单柱状图
* */
public static void initBarChart(BarChart mBarChart, int size, boolean isLegend, boolean isSingle) {
mBarChart.setExtraOffsets(0, 20, 20, 20);
//初始化
mBarChart.setBackgroundColor(Color.WHITE);
//不显示图表网格
mBarChart.setDrawGridBackground(false);
//背景阴影
mBarChart.setDrawBarShadow(false);
mBarChart.setHighlightFullBarEnabled(false);
//显示边框
mBarChart.setDrawBorders(true);
// 二指控制X轴Y轴同时放大
mBarChart.setPinchZoom(false);
mBarChart.setDoubleTapToZoomEnabled(false);
//设置X轴显示文字旋转角度-60意为逆时针旋转60度
// mBarChart.getXAxis().setLabelRotationAngle(-30);
// 设置最大可见Value值的数量 针对于ValueFormartter有效果
mBarChart.setMaxVisibleValueCount(size+10);
mBarChart.setFitBars(false);
// mBarChart.setKeepPositionOnRotation(false);
mBarChart.fitScreen();
/* X轴的设置 */
XAxis xAxis = mBarChart.getXAxis();
//设置X轴显示位置
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
//X轴横坐标显示的数量
xAxis.setLabelCount(size);
//不显示X轴网格线
xAxis.setDrawGridLines(false);
//不显示X轴线条
xAxis.setDrawAxisLine(false);
// xAxis.setYOffset(150);
// xAxis.setXOffset(10);
// xAxis.setGranularity(1f);//设置最小间隔,防止当放大时,出现重复标签。
// mBarChart.fitScreen();
Log.e("ChartUtils",""+xAxis.getAxisMinimum());
//解决柱状图显示不全的问题,设置完xAxis.setAxisMinimum(0f);之后,柱状图就显示全了,但是X轴标签显示不对,全都贴边显示
if (!isSingle) {
xAxis.setAxisMaximum(size);
xAxis.setAxisMinimum(0f);
xAxis.setCenterAxisLabels(true);
}
/* Y轴设置 */
YAxis leftAxis = mBarChart.getAxisLeft();
YAxis rightAxis = mBarChart.getAxisRight();
//不显示X轴 Y轴线条
leftAxis.setDrawAxisLine(true);
rightAxis.setDrawAxisLine(false);
// leftAxis.setXOffset(0);
leftAxis.setYOffset(0);
//不显示左侧Y轴
rightAxis.setEnabled(false);
//右侧Y轴网格线设置为虚线
leftAxis.enableGridDashedLine(10f, 10f, 0f);
//设置Y左边轴显示的值 label 数量
leftAxis.setLabelCount(7, true);
leftAxis.setAxisMinValue(0);
//设置值显示的位置,我们这里设置为显示在Y轴外面
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
//设置Y轴 与值的空间空隙 这里设置30f意为30%空隙,默认是10%
leftAxis.setSpaceTop(0f);
// leftAxis.setAxisMinimum(0f);//设置Y轴最小值
/***折线图例 标签 设置***/
Legend legend = mBarChart.getLegend();
//图例的形状,SQUARE为方块,LINE为线型
legend.setForm(Legend.LegendForm.SQUARE);
legend.setTextSize(11f);
//显示位置
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
//图例的垂直位置 正值向下移,负值向上移
legend.setYOffset(0);
//是否绘制在图表里面
legend.setDrawInside(false);
legend.setEnabled(isLegend);
//不显示表边框
mBarChart.setDrawBorders(false);
// 不显示右下角描述内容
Description description = new Description();
description.setEnabled(false);
mBarChart.setDescription(description);
}
/*
* 饼图初始化
* isHole 是圆环还是实心
* */
public static void initPieChart(PieChart pc_collect, boolean isHole) {
pc_collect.setUsePercentValues(true);
pc_collect.getDescription().setEnabled(false);
//设置整个饼图的偏移
pc_collect.setExtraOffsets(0,10,5,5);
pc_collect.setDragDecelerationEnabled(true);
pc_collect.setDragDecelerationFrictionCoef(0.95f);
//设置中间文字
// pc_collect.setCenterText(generateCenterSpannableText());
//中间圆心显示与否以及颜色,默认true
pc_collect.setDrawHoleEnabled(isHole);
pc_collect.setHoleColor(Color.WHITE);
//半透明圆环的颜色和透明度
pc_collect.setTransparentCircleColor(Color.WHITE);
pc_collect.setTransparentCircleAlpha(110);
//设置中间圆心,如果setTransparentCircleRadius的值比setHoleRadius小,只显示一套圆环
// pc_collect.setHoleRadius(58f);
//内圆环的半径
pc_collect.setTransparentCircleRadius(41f);
//是否显示中间文字,默认是true
pc_collect.setDrawCenterText(false);
//旋转角度
pc_collect.setRotationAngle(0);
//触摸旋转
pc_collect.setRotationEnabled(false);
//点击放大
pc_collect.setHighlightPerTapEnabled(true);
//数据
pc_collect.setNoDataText("暂无数据");
pc_collect.animateY(1400, Easing.EasingOption.EaseInOutQuad);
//图表的标注,默认在最下方横排显示,此设置在右上角竖排显示
Legend l = pc_collect.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
l.setOrientation(Legend.LegendOrientation.VERTICAL);
l.setDrawInside(false);
l.setXEntrySpace(7f);
l.setYEntrySpace(0f);
l.setYOffset(0f);
//输入标签样式
pc_collect.setEntryLabelColor(Color.WHITE);
pc_collect.setEntryLabelTextSize(12f);
}
/*
* 饼图数据
*
*/
public static void setPieData(List<PieEntry> entries, PieChart pieChart) {
PieDataSet dataSet = new PieDataSet(entries,"");
//设置圆环之间的距离
dataSet.setSliceSpace(3f);
dataSet.setSelectionShift(5f);
//数据和颜色
List<Integer> colors = new ArrayList<>();
//5个for循环都可以用,每组颜色都不同
// for (int c : ColorTemplate.VORDIPLOM_COLORS) {
// colors.add(c);
// }
// for (int c : ColorTemplate.JOYFUL_COLORS) {
// colors.add(c);
// }
//
for (int c : ColorTemplate.COLORFUL_COLORS) {
colors.add(c);
}
// for (int c : ColorTemplate.LIBERTY_COLORS) {
// colors.add(c);
// }
//
for (int c : ColorTemplate.PASTEL_COLORS) {
colors.add(c);
}
//
// //每个圆环的颜色一样,都是蓝色
// colors.add(ColorTemplate.getHoloBlue());
dataSet.setColors(colors);
PieData data = new PieData(dataSet);
data.setValueFormatter(new PercentFormatter());
data.setValueTextSize(11f);
data.setValueTextColor(Color.WHITE);
pieChart.setData(data);
pieChart.highlightValue(null);
pieChart.invalidate();
}
}
数据示例:
{"code":200,"message":"成功","data":{"dataBL":[{"officeCount":2,"type":"旅游饭店"},{"officeCount":2,"type":"学校食堂"},{"officeCount":1,"type":"自助餐"},{"officeCount":3,"type":"中餐厅"}],"data":[{"id":"71aeb0c9fc1b439a8edcf6814c1e2fb0","valueInspect":0,"name":"内蒙古自治区","value":80},{"id":"c561f4c64f1f41d2896fea76d06d377f","valueInspect":3,"name":"吉林省","value":1223},{"id":"9c05558f83c24cc79201b6f5e1035d3b","valueInspect":7,"name":"山东省","value":1995},{"id":"642ef984602a4f03b2403f4a6c769353","valueInspect":1,"name":"河北省","value":3}]}}
实际效果:
6. BarChart赋值的工具类:
private void showBarChart(List<String> xValues, LinkedHashMap<String,List<Integer>> chartDatas,List<Integer> colors) {
List<IBarDataSet> barDataSets = new ArrayList<>();
int currentPosition = 0;
for (LinkedHashMap.Entry<String,List<Integer>> entry:chartDatas.entrySet()) {
String name = entry.getKey();
List<Integer> yValuesList = entry.getValue();
List<BarEntry> entries = new ArrayList<>();
for (int i=0;i<yValuesList.size();i++) {
entries.add(new BarEntry(i,yValuesList.get(i)));
}
BarDataSet barDataSet = new BarDataSet(entries,name);
barDataSet.setColor(colors.get(currentPosition));
barDataSets.add(barDataSet);
currentPosition++;
}
//X轴自定义值
XAxis xAxis = bc_collect.getXAxis();
//X轴自定义值
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
if (value < 0) {
return "";
}
//String labelValue = collectDataList.get((int) value % collectDataList.size()).getName();
String labelValue = xValues.get((int) value % xValues.size());
if (labelValue.length() > 4) {
labelValue = labelValue.substring(0,4)+"…";
}
return labelValue;
}
});
BarData barData = new BarData(barDataSets);
float groupSpace = 0.3f; //柱状图组之间的间距
int num = chartDatas.size();
float barSpace = 0f;
float barWidth = (1f-0.3f)/num;
barData.setBarWidth(barWidth);
barData.groupBars(0f, groupSpace, barSpace);
bc_collect.setData(barData);
}
7. 调用:先把获取到的数据值转换成showBarChart的三个参数:
private void convertData(List<CollectData> collectDataList) {
LinkedHashMap<String, List<Integer>> chartDataMap = new LinkedHashMap<>();
//两组柱状图的值
List<Integer> yValues1 = new ArrayList<>();
List<Integer> yValues2 = new ArrayList<>();
//柱状图的X轴的值
List<String> xValues = new ArrayList<>();
for (int i=0;i<collectDataList.size();i++) {
CollectData bean = collectDataList.get(i);
xValues.add(bean.getName());
yValues1.add(bean.getValue());
yValues2.add(bean.getValueInspect());
}
chartDataMap.put("单位总数",yValues1);
chartDataMap.put("已检查单位数",yValues2);
List<Integer> colors = Arrays.asList(
getResources().getColor(R.color.realplayer_blue),
getResources().getColor(R.color.color_expire)
);
showBarChart(xValues, chartDataMap, colors);
}
与4中的setBarChartData(bc_collect);一样的效果。