MPAndroidChart绘制柱形图、饼状图

导入依赖

在Android项目的gradle文件中导入依赖,代码如下

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

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

柱形图BarChart

柱形图布局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fragment_device_statistic"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/new_broad_list_bg"
    android:clickable="true">

    <LinearLayout
        android:layout_width="@dimen/dp_0"
        android:layout_height="@dimen/dp_0"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/tv_bar_chart_tip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按设备状态统计设备"
            android:gravity="center"
            android:textColor="@color/c_ffffff"
            android:textSize="@dimen/dp_12"/>


        <com.github.mikephil.charting.charts.BarChart
            android:id="@+id/v_bar_chart"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

<androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.03">

            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/guideline1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_percent="0.03"/>

            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/guideline5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_percent="0.36" />

            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/guideline7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_percent="0.69" />

            <View
                android:id="@+id/cv_4g_online"
                android:layout_width="@dimen/dp_15"
                android:layout_height="@dimen/dp_15"
                android:background="@color/c_4GOnLine"
                app:layout_constraintLeft_toLeftOf="@id/guideline1"
                app:layout_constraintTop_toTopOf="parent" />

            <View
                android:id="@+id/cv_4g_offline"
                android:layout_width="@dimen/dp_15"
                android:layout_height="@dimen/dp_15"
                android:layout_marginTop="@dimen/dp_10"
                android:background="@color/c_4GOffLine"
                android:gravity="center"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="@id/guideline1"
                app:layout_constraintTop_toBottomOf="@id/cv_4g_online" />

            <View
                android:id="@+id/cv_ip_online"
                android:layout_width="@dimen/dp_15"
                android:layout_height="@dimen/dp_15"
                android:background="@color/c_IPOnLine"
                app:layout_constraintLeft_toRightOf="@id/guideline5"
                app:layout_constraintTop_toTopOf="parent" />

            <View
                android:id="@+id/cv_ip_offline"
                android:layout_width="@dimen/dp_15"
                android:layout_height="@dimen/dp_15"
                android:layout_marginTop="@dimen/dp_10"
                android:background="@color/c_IPOffLine"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toRightOf="@id/guideline5"
                app:layout_constraintTop_toBottomOf="@id/cv_ip_online" />

            <View
                android:id="@+id/cv_sub_online"
                android:layout_width="@dimen/dp_15"
                android:layout_height="@dimen/dp_15"
                android:background="@color/c_subOnLine"
                app:layout_constraintLeft_toRightOf="@id/guideline7"
                app:layout_constraintTop_toTopOf="parent" />

            <View
                android:id="@+id/cv_sub_offline"
                android:layout_width="@dimen/dp_15"
                android:layout_height="@dimen/dp_15"
                android:layout_marginTop="@dimen/dp_10"
                android:background="@color/c_subOffLine"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toRightOf="@id/guideline7"
                app:layout_constraintTop_toBottomOf="@id/cv_sub_online" />

            <TextView
                android:id="@+id/tv_4g_online"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_8"
                android:text="Text"
                android:textColor="@color/c_ffffff"
                android:textSize="@dimen/dp_12"
                app:layout_constraintBottom_toBottomOf="@id/cv_4g_online"
                app:layout_constraintLeft_toRightOf="@id/cv_4g_online"
                app:layout_constraintTop_toTopOf="@id/cv_4g_online" />

            <TextView
                android:id="@+id/tv_4g_offline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_8"
                android:text="Text"
                android:textColor="@color/c_ffffff"
                android:textSize="@dimen/dp_12"
                app:layout_constraintBottom_toBottomOf="@id/cv_4g_offline"
                app:layout_constraintLeft_toRightOf="@id/cv_4g_offline"
                app:layout_constraintTop_toTopOf="@id/cv_4g_offline" />

            <TextView
                android:id="@+id/tv_ip_online"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_8"
                android:text="Text"
                android:textColor="@color/c_ffffff"
                android:textSize="@dimen/dp_12"
                app:layout_constraintBottom_toBottomOf="@id/cv_ip_online"
                app:layout_constraintLeft_toRightOf="@id/cv_ip_online"
                app:layout_constraintTop_toTopOf="@id/cv_ip_online" />

            <TextView
                android:id="@+id/tv_ip_offline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_8"
                android:text="Text"
                android:textColor="@color/c_ffffff"
                android:textSize="@dimen/dp_12"
                app:layout_constraintBottom_toBottomOf="@id/cv_ip_offline"
                app:layout_constraintLeft_toRightOf="@id/cv_ip_offline"
                app:layout_constraintTop_toTopOf="@id/cv_ip_offline" />

            <TextView
                android:id="@+id/tv_sub_online"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_8"
                android:text="Text"
                android:textColor="@color/c_ffffff"
                android:textSize="@dimen/dp_12"
                app:layout_constraintBottom_toBottomOf="@id/cv_sub_online"
                app:layout_constraintLeft_toRightOf="@id/cv_sub_online"
                app:layout_constraintTop_toTopOf="@id/cv_sub_online" />

            <TextView
                android:id="@+id/tv_sub_offline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_8"
                android:text="Text"
                android:textColor="@color/c_ffffff"
                android:textSize="@dimen/dp_12"
                app:layout_constraintBottom_toBottomOf="@id/cv_sub_offline"
                app:layout_constraintLeft_toRightOf="@id/cv_sub_offline"
                app:layout_constraintTop_toTopOf="@id/cv_sub_offline" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

BarChart的使用

得到BarChart对象 并初始化
得到BarEntry对象,此处添加(X,Y)值
得到BarDataSet对象,添加BarEntry对象
得到BarData对象,添加BarDaraSet对象
显示柱状图 BarChart.setData(BarData)

初始化BarChart

因为自定义图例故此没有初始化BarChart自带的图例Legend。

 @BindView(R.id.v_bar_chart)
 @BindView(R.id.cv_4g_offline)
    View cv4GOffline;
    @BindView(R.id.cv_4g_online)
    View cv4GOnline;
    @BindView(R.id.cv_ip_offline)
    View cvIPOffline;
    @BindView(R.id.cv_ip_online)
    View cvIPOnline;
    @BindView(R.id.cv_sub_offline)
    View cvSubOffline;
    @BindView(R.id.cv_sub_online)
    View cvSubOnline;
    @BindView(R.id.tv_4g_online)
    TextView tv4GOnline;
    @BindView(R.id.tv_4g_offline)
    TextView tv4GOffline;
    @BindView(R.id.tv_ip_online)
    TextView tvIPOnline;
    @BindView(R.id.tv_ip_offline)
    TextView tvIPOffline;
    @BindView(R.id.tv_sub_online)
    TextView tvSubOnline;
    @BindView(R.id.tv_sub_offline)
    TextView tvSubOffline;
    
    private View[] viewArray; // 自定义坐标图例view
    private TextView[] labelViewArray; // 自定义坐标图例文本
    BarChart barChartView; // 柱形图view
    private YAxis bcRightYAxis; // 右侧Y轴
    private YAxis bcLeftYAxis; // 左侧Y轴
    private XAxis bcXAxis; // X轴

以下代码初始化BarChart

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        viewArray = new View[]{cv4GOnline, cv4GOffline, cvIPOnline, cvIPOffline, cvSubOnline, cvSubOffline};
        labelViewArray = new TextView[]{tv4GOnline, tv4GOffline, tvIPOnline, tvIPOffline, tvSubOnline, tvSubOffline};
        ...
    }
    
private void initBarChart() {
		/**
		* 设置BarChart
		**/
        barChartView.setDrawGridBackground(false); // 不显示图标网格
        barChartView.setDrawBarShadow(false); // 不显示背景阴影
        barChartView.setDrawValueAboveBar(true); // 如果设置为true,所有柱形图顶部标值都高于柱形图顶部,而不是低于其顶部。默认:true
        barChartView.getDescription().setEnabled(false); // 不显示右下角的文本描述
        barChartView.getLegend().setEnabled(true); // 不启用BarChart自带图标示例
        barChartView.setHighlightFullBarEnabled(true); // 设置是否高亮显示。
        
        barChartView.setExtraOffsets(0,0,0,5); // 设置图标显示的坐标位置,依次是左、上、右、下坐标。
        barChartView.setPinchZoom(false); // 如果设置为true,则启用缩放。如果禁用,则可以分别缩放x和y轴。
        barChartView.setScaleXEnabled(false); // 启用/禁用x轴缩放。
        barChartView.setDoubleTapToZoomEnabled(false); // 将其设置为false可禁止通过双击双击放大图表。
       
		/**
		* 设置BarChart的X轴
		**/
        bcXAxis = barChartView.getXAxis();
        bcXAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        bcXAxis.setDrawGridLines(false); // 设置不从X轴发出纵向直线
        bcXAxis.setGranularity(1f); // 设置最小间隔,防止当放大时,出现重复标签。
        bcXAxis.setLabelCount(7); // 设置x轴显示的标签个数
        bcXAxis.setAxisLineColor(Color.WHITE);
        bcXAxis.setTextColor(Color.WHITE);
        bcXAxis.setTextSize(12);
		
		/**
		* 设置BarChart的Y轴
		**/
        bcLeftYAxis = barChartView.getAxisLeft();
        bcLeftYAxis.setLabelCount(8, false);
        bcLeftYAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        bcLeftYAxis.setSpaceTop(15f); // 设置轴上最高位置在表中最高位置的顶部间距,占总轴的百分比。
        bcLeftYAxis.setAxisMinimum(0f);
        bcLeftYAxis.setAxisMaximum(100);
        bcLeftYAxis.setAxisLineColor(Color.WHITE);
        bcLeftYAxis.setTextColor(Color.WHITE);
        bcLeftYAxis.setTextSize(12);

        bcRightYAxis = barChartView.getAxisRight();
        bcRightYAxis.setAxisMinimum(0f);
        bcRightYAxis.setAxisMaximum(100);
        bcRightYAxis.setDrawGridLines(false);
        bcRightYAxis.setLabelCount(8, false);
        bcRightYAxis.setSpaceTop(15f);
        bcRightYAxis.setAxisLineColor(Color.WHITE);
        bcRightYAxis.setTextColor(Color.WHITE);
        bcRightYAxis.setTextSize(12);
    }

获取数据

使用接口,通过Retrofit向服务端获取需要展示的数据

private Handler handler = new Handler() {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            initData((DeviceStatisticsEntity) msg.obj);
        }
    };

@RequiresApi(api = Build.VERSION_CODES.N)
    private void initData(DeviceStatisticsEntity deviceStatisticsEntity) {
        HashMap<String, DeviceStatisticsEntity.PostBackType> returnData = deviceStatisticsEntity.getReturnData();
        initBarChartData(returnData);
        initPieChartData(returnData);
    }

private void requestData() {
        APIManager.getInstance().statisticsDeviceByStatusAndArea((isRequestSuccess, isSuccess, msg) -> {
            String json = "{" +
                    "\"镇村适配器资源\":" +
                    "{" +
                    "\"SUB_PLATFORM_POSTBACK\":[{\"key\":\"offline\",\"value\":3},{\"key\":\"online\",\"value\":8}]," +
                    "\"IPPOSTBACK\":[{\"key\":\"offline\",\"value\":3},{\"key\":\"online\",\"value\":9}]," +
                    "\"GPRSPOSTBACK\":[{\"key\":\"offline\",\"value\":5},{\"key\":\"online\",\"value\":8}]" +
                    "},\"" +
                    "终端资源\":" +
                    "{" +
                    "\"SUB_PLATFORM_POSTBACK\":[{\"key\":\"offline\",\"value\":1},{\"key\":\"online\",\"value\":8}]," +
                    "\"IPPOSTBACK\":[{\"key\":\"offline\",\"value\":2},{\"key\":\"online\",\"value\":8}]," +
                    "\"GPRSPOSTBACK\":[{\"key\":\"offline\",\"value\":5},{\"key\":\"online\",\"value\":5}]" +
                    "}" +
                    "}";
            if (isRequestSuccess && isSuccess) {
                DeviceStatisticsEntity entity = setDeviceStatisticsEntity("镇村适配器资源", "终端资源", json);
                handler.obtainMessage(1, entity).sendToTarget();
            } else {
                Log.d(TAG, "-=-=- requestData: 请求设备统计数据失败,msg:" + msg);
            }
        });
    }

将X、Y轴数据依次放入LinkedHashMap中,再将多个Y轴数据放入IBarDataSet

private void initBarChartData(HashMap<String, DeviceStatisticsEntity.PostBackType> returnData) {
        LinkedHashMap<String, List<Integer>> chartDataMap = new LinkedHashMap<>();
        List<String> xValues = new ArrayList<>(); // X轴数据
        // 以下6个线性列表都是Y轴数据
        List<Integer> gprsOnLineList = new ArrayList<>();
        List<Integer> gprsOffLineList = new ArrayList<>();
        List<Integer> ipOnLineList = new ArrayList<>();
        List<Integer> ipOffLineList = new ArrayList<>();
        List<Integer> subOnLineList = new ArrayList<>();
        List<Integer> subOffLineList = new ArrayList<>();
        // 构造每个柱形条的颜色
        List<Integer> colors = Arrays.asList(
                getResources().getColor(R.color.c_4GOnLine), getResources().getColor(R.color.c_4GOffLine),
                getResources().getColor(R.color.c_IPOnLine), getResources().getColor(R.color.c_IPOffLine),
                getResources().getColor(R.color.c_subOnLine), getResources().getColor(R.color.c_subOffLine));

        for (Map.Entry<String, DeviceStatisticsEntity.PostBackType> entries : returnData.entrySet()) {
            xValues.add(entries.getKey());
            setYValues(entries.getValue().getGPRSPOSTBACK(), gprsOnLineList, gprsOffLineList);
            setYValues(entries.getValue().getIPPOSTBACK(), ipOnLineList, ipOffLineList);
            setYValues(entries.getValue().getSUB_PLATFORM_POSTBACK(), subOnLineList, subOffLineList);
        }
        chartDataMap.put("4G在线", gprsOnLineList);
        chartDataMap.put("4G离线", gprsOffLineList);
        chartDataMap.put("IP在线", ipOnLineList);
        chartDataMap.put("IP离线", ipOffLineList);
        chartDataMap.put("下级在线", subOnLineList);
        chartDataMap.put("下级离线", subOffLineList);
        showBarChart(xValues, chartDataMap, colors);
    }

多柱形图的展示

每一个BarDataSet代表一类柱状图,将多个BarDataSet放到IBarChartSet中。

public void showBarChart(List<String> xValues, 
LinkedHashMap<String, List<Integer>> dataLists,
                             List<Integer> colors) {
        ArrayList<IBarDataSet> dataSets = new ArrayList<>();
        int currentPosition = 0;
        long maxValue = 0; // 设置Y轴坐标最大值
        for (LinkedHashMap.Entry<String, List<Integer>> entry : dataLists.entrySet()) {
        	// 设置自定义坐标图例
            String name = entry.getKey();
            labelViewArray[currentPosition].setText(name);
            viewArray[currentPosition].setBackgroundColor(colors.get(currentPosition));

            // 设置柱形图数据
            List<Integer> yValueList = entry.getValue();
            List<BarEntry> barEntries = new ArrayList<>();
            for (int i = 0; i < yValueList.size(); i++) {
                barEntries.add(new BarEntry(i, yValueList.get(i)));
                if (maxValue == 0 || maxValue < yValueList.get(i)) {
                    maxValue = (long) (yValueList.get(i) * 1.5);
                }
            }
            BarDataSet barDataSet = new BarDataSet(barEntries, name);
            
            // 设置每个柱形的颜色、大小、以及柱形顶部文字
            initBarDataSet(barDataSet, colors.get(currentPosition), 
            ((value, entry1, dataSetIndex, viewPortHandler) -> {
                if (value != 0) {
                    String data = new DecimalFormat("#").format(value); // 实现整数
                    return name + data + "台";
                } else {
                    return "";
                }
            }));
            dataSets.add(barDataSet);
            currentPosition++;
        }
        
        if (bcXAxis != null) {
            bcXAxis.setValueFormatter(((value, axis) -> {
                if (value > -1 && value < xValues.size()) {
                // 显示自定义X轴坐标,否则默认显示1,2,3...
                    return xValues.get((int) value % xValues.size());
                } else {
                    return "";
                }
            }));
            bcXAxis.setAxisMinimum(0f);
            bcXAxis.setAxisMaximum(xValues.size());
            bcXAxis.setCenterAxisLabels(true);
        }
        
        if (bcRightYAxis != null && bcLeftYAxis != null) {
            bcLeftYAxis.setValueFormatter((value, axis) -> (int) (value) + "");
            bcRightYAxis.setValueFormatter((value, axis) -> (int) (value) + "");
            bcRightYAxis.setAxisMaximum(maxValue);
            bcLeftYAxis.setAxisMaximum(maxValue);
        }
        
        BarData barData = new BarData(dataSets);
        int barAmount = dataLists.size(); //需要显示柱状图的类别数量
        float groupSpace = 0.1f; // 柱状图组之间的间距
        float barWidth = (1f - groupSpace) / barAmount; // 每条柱状图宽度占比
        float barSpace = 0f; // 柱状图间距占比
        barData.setBarWidth(barWidth);
        barData.groupBars(0f, groupSpace, barSpace);
        
        if (barChartView != null) {
            barData.setHighlightEnabled(true);
            barChartView.setData(barData);
            barChartView.animateY(500); 
            barChartView.invalidate();
        }
    }

private void initBarDataSet(BarDataSet barDataSet, int color, IValueFormatter f) {
        barDataSet.setValueFormatter(f);
        barDataSet.setColor(color);
        // barDataSet.setFormLineWidth(1f); 设置图形线宽(单位:dp),默认3dp
        // barDataSet.setFormSize(15.f); 设置 legend-forms 的大小,单位dp。
        barDataSet.setDrawValues(true); // 是否显示柱形图顶部文字
        barDataSet.setValueTextSize(10);
        barDataSet.setValueTextColor(Color.WHITE);
    }

饼状图

饼状图获取数据的过程同柱形图的一致

饼状图布局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fragment_device_statistic"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/new_broad_list_bg"
    android:clickable="true">

    <LinearLayout
        android:layout_width="@dimen/dp_0"
        android:layout_height="@dimen/dp_0"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        
<com.github.mikephil.charting.charts.PieChart
            android:id="@+id/pie_chart"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.03">

            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/guideline11"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_percent="0.2" />

            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/guideline55"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_percent="0.6" />

            <View
                android:id="@+id/cv_adapter"
                android:layout_width="@dimen/dp_15"
                android:layout_height="@dimen/dp_15"
                android:background="@color/c_adapter"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="@id/guideline11"
                app:layout_constraintTop_toTopOf="parent" />

            <View
                android:id="@+id/cv_terminal"
                android:layout_width="@dimen/dp_15"
                android:layout_height="@dimen/dp_15"
                android:layout_marginTop="@dimen/dp_10"
                android:background="@color/c_terminal"
                android:gravity="center"
                app:layout_constraintLeft_toLeftOf="@id/guideline55"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/tv_adapter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_8"
                android:text="镇村适配器资源"
                android:textColor="@color/c_ffffff"
                android:textSize="@dimen/dp_12"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toRightOf="@id/cv_adapter"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/tv_terminal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/dp_8"
                android:text="终端资源"
                android:textColor="@color/c_ffffff"
                android:textSize="@dimen/dp_12"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toRightOf="@id/cv_terminal"
                app:layout_constraintTop_toTopOf="parent" />

        </androidx.constraintlayout.widget.ConstraintLayout>
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

初始化PieChart

@BindView(R.id.pie_chart)
    PieChart pieChart;

private void initPieChart() {
        pieChart.setUsePercentValues(true); // 饼状图的文字显示为百分数形式
        pieChart.getDescription().setEnabled(false);
        pieChart.setExtraOffsets(0, 5, 0, 10);

        pieChart.setDragDecelerationFrictionCoef(0.5f); // 拖动降速速率

        // 设置中心圆
        pieChart.setDrawHoleEnabled(true);
        pieChart.setHoleColor(getResources().getColor(R.color.new_broad_list_bg));

        // 设置中心圆文字
        pieChart.setDrawCenterText(true);
        pieChart.setCenterText(generateCenterSpannableText());
        pieChart.setCenterTextOffset(16f,7f);

        // 设置中心圆透明外圈
        pieChart.setTransparentCircleColor(Color.WHITE);
        pieChart.setTransparentCircleAlpha(110);
        pieChart.setHoleRadius(58f);
        pieChart.setTransparentCircleRadius(61f);

        pieChart.setRotationAngle(0); // 设置饼状图的旋转角度。默认是270f 。
        pieChart.setRotationEnabled(true);
        pieChart.setHighlightPerTapEnabled(true); // false,以防止通过点击手势突出显示值。可通过拖动突出显示值,默认值:true

        pieChart.animateX(1400, Easing.EasingOption.EaseInOutQuad);
        pieChart.getLegend().setEnabled(false);

        pieChart.setEntryLabelColor(Color.WHITE);
        pieChart.setEntryLabelTextSize(12f);
    }
    
// 绘制中心文字
    private SpannableString generateCenterSpannableText() {
        SpannableString s = new SpannableString("按设备区域类型统计设备");
        s.setSpan(new RelativeSizeSpan(1f), 0, s.length(), 0);
        s.setSpan(new StyleSpan(Typeface.NORMAL), 0, s.length(), 0);
        s.setSpan(new ForegroundColorSpan(Color.WHITE), 0, s.length(), 0);
        return s;
    }

获取数据

@RequiresApi(api = Build.VERSION_CODES.N)
    private void initPieChartData(HashMap<String, DeviceStatisticsEntity.PostBackType> returnData) {
        int adapterDeviceNum = 0;
        int terminalDeviceNum = 0;
        for (Map.Entry<String, DeviceStatisticsEntity.PostBackType> entries : returnData.entrySet()) {
            if (entries.getKey().contains("镇村适配器资源")) {
                adapterDeviceNum = setPieChartData(entries);
            } else if (entries.getKey().contains("终端资源")) {
                terminalDeviceNum = setPieChartData(entries);
            }
        }
        int deviceSum = adapterDeviceNum + terminalDeviceNum;
        float adapterDevicePercent = (float) adapterDeviceNum / (float) deviceSum * 100;
        float terminalDevicePercent = (float) terminalDeviceNum / (float) deviceSum * 100;
        Map<String, Float> pieValues = new HashMap<>();
        pieValues.put("镇村适配器资源", adapterDevicePercent);
        pieValues.put("终端资源", terminalDevicePercent);
        showPieChart(pieValues, "设备区域类型");
    }

展示饼状图

private void showPieChart(Map<String, Float> pieValues, String label) {
        Set set = pieValues.entrySet();
        Iterator it = set.iterator();
        List<PieEntry> entries = new ArrayList<>();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            entries.add(new PieEntry(Float.valueOf(entry.getValue().toString()),
                    entry.getKey().toString() + "占比"));
        }

        PieDataSet dataSet = new PieDataSet(entries, label);
        dataSet.setDrawIcons(false);
        dataSet.setSliceSpace(2f); // 设置dp中piechart切片之间的剩余空间。
        dataSet.setIconsOffset(new MPPointF(0, 40));
        dataSet.setSelectionShift(4f); // 设置此数据集突出显示的piechart切片的距离
        dataSet.setColors(Arrays.asList(new Integer[]{
                getResources().getColor(R.color.c_adapter), getResources().getColor(R.color.c_terminal)
        }));
        dataSet.setValueTextColor(Color.WHITE);
        dataSet.setValueTextSize(12f);

		// 设置饼状图上文字图标到圆心的连线
        dataSet.setValueLinePart1OffsetPercentage(80.f);
        dataSet.setValueLinePart1Length(0.2f);
        dataSet.setValueLinePart2Length(0.4f);
        dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);


        PieData pieData = new PieData(dataSet);
        pieData.setDrawValues(true);
        pieData.setValueFormatter(new PercentFormatter());
        pieData.setValueTextSize(12f);
        pieData.setValueTextColor(Color.WHITE);
        
        pieChart.setData(pieData);
        pieChart.highlightValues(null);
        pieChart.invalidate();

    }

参考文章:
MPAndroidChart3使用详解4:BarChart(柱形图)
Android图表控件MPAndroidChart——BarChart实现多列柱状图以及堆积柱状图
MPAndroidChart 3.0以后绘制饼状图
MPAndroidChart3使用详解5:PieChart(饼状图)


版权声明:本文为lxy1740原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。