天天看點

MPChart餅圖自定義圖例

參考:http://www.lai18.com/content/8360860.html

先來個需求圖:

MPChart餅圖自定義圖例

該圖是項目中需要的,餅圖好實作,但MPChart的圖例不能顯示百分比,需通過自定義實作,二次封裝。

Demo圖:

MPChart餅圖自定義圖例

以下為實作代碼:

MainActivity:

package com.example.pieview;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

import com.github.mikephil.charting.charts.PieChart;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		PieChart pieChart = (PieChart) findViewById(R.id.pieView);
		LinearLayout legendLayout = (LinearLayout) findViewById(R.id.legend_layout);

		// 模拟資料
		float[] data = new float[] { 1.8f, 3, 5.5f, 10, 6, 5, 6, 4, 2, 1.3f,
				0.9f };
		String[] labels = new String[] { "A", "B", "C", "D", "E", "F", "G",
				"H", "J", "K", "L" };

		PieChartUtils.initPieChart(this, legendLayout, pieChart, data, labels);

	}
}
           

布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <com.github.mikephil.charting.charts.PieChart
        android:id="@+id/pieView"
        android:layout_width="0dp"
        android:layout_height="150dp"
        android:layout_weight="1" />

    <!-- 使用ScrollView解決資料太多時的顯示問題。注意:height一定要固定 -->

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="150dp"
        android:layout_weight="1" >

        <LinearLayout
            android:id="@+id/legend_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
        </LinearLayout>
    </ScrollView>

</LinearLayout>
           

重點:

package com.example.epnc.utils;

import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.formatter.PercentFormatter;
import com.github.mikephil.charting.interfaces.datasets.IDataSet;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created by TCL on 2016/9/1.
 * 餅圖自定義圖例的二次封裝
 */
public class PieChartUtils {

    /**
     * @param context      上下文
     * @param legendLayout 外層的Legend布局
     * @param pieChart     要初始化的餅圖
     * @param data         餅圖上的資料
     * @param labels       餅圖上的資料描述
     */
    public static void initPieChart(Context context, LinearLayout legendLayout, PieChart pieChart, float[] data,
                                    String[] labels) {
        //設定描述
        pieChart.setDescription("");
        // 設定中心圓孔半徑占整個餅狀圖半徑的百分比(100f 是最大=整個圖表的半徑),預設的50%的百分比(即50f)。
        pieChart.setHoleRadius(55f);
        // 設定中間文字中大小
        pieChart.setCenterTextSize(12f);
        // 百分比顯示
        pieChart.setUsePercentValues(true);
        // 禁用觸摸
        pieChart.setTouchEnabled(false);
        //設定内置圖例不顯示
        pieChart.getLegend().setEnabled(false);
        // 設定隐藏餅圖上文字,隻顯示百分比
        pieChart.setDrawSliceText(false);


        //數值
        ArrayList<Entry> values = new ArrayList<Entry>();
        //數值描述
        ArrayList<String> valuesLabels = new ArrayList<>();
        //顔色
        int[] colors = new int[data.length];

        //随機顔色需要随機
        Random random = new Random();
        for (int i = 0; i < data.length; i++) {
            //添加數值
            values.add(new Entry(data[i], i));
            //添加數值描述
            valuesLabels.add(labels[i]);

            //随機顔色
            int red = 30 + random.nextInt(200);
            int green = 30 + random.nextInt(200);
            int blue = 30 + random.nextInt(200);

            //添加顔色
            colors[i] = Color.rgb(red, green, blue);
        }


        PieDataSet pieDataSet = new PieDataSet(values, "");
        pieDataSet.setSliceSpace(2f);
        pieDataSet.setValueTextColor(Color.WHITE);
        pieDataSet.setValueTextSize(12f);
        //将随機的顔色設定進來
        pieDataSet.setColors(colors);


        PieData pieData = new PieData(valuesLabels, pieDataSet);
        //設定百分比顯示
        pieData.setValueFormatter(new PercentFormatter());

        //自定義圖例 該方法一定要在setData之前執行
        setCustomizeLegend(legendLayout, context, colors, data, labels);

        //set data...
        pieChart.setData(pieData);

        //設定是否顯示區域百分比的值
        for (IDataSet<?> set : pieChart.getData().getDataSets()) {
            set.setDrawValues(false);
        }
    }

    private static void setCustomizeLegend(LinearLayout legendLayout, Context context, int[] colors, float[] data,
                                           String[] labels) {
        for (int i = 0; i < data.length; i++) {
            //單個圖例的layoutParams
            LinearLayout.LayoutParams singleLegendLayoutParams = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
            // 設定比重為1
            singleLegendLayoutParams.weight = 1;
            // 單個圖例的布局
            LinearLayout singleLegendLayout = new LinearLayout(context);
            // 水準排列
            singleLegendLayout.setOrientation(LinearLayout.HORIZONTAL);
            // 垂直居中
            singleLegendLayout.setGravity(Gravity.CENTER_VERTICAL);
            singleLegendLayout.setLayoutParams(singleLegendLayoutParams);


            //添加顔色方塊
            LinearLayout.LayoutParams colorLayoutParams = new LinearLayout.LayoutParams(
                    20, 20);
            colorLayoutParams.setMargins(0, 0, 20, 0);
            LinearLayout colorLayout = new LinearLayout(context);
            colorLayout.setLayoutParams(colorLayoutParams);
            colorLayout.setBackgroundColor(colors[i]);
            singleLegendLayout.addView(colorLayout);


            //Label部分和百分比數值部分
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.weight = 1;
            params.gravity = Gravity.CENTER;


            // 添加label
            TextView tvLabel = new TextView(context);
            tvLabel.setText(labels[i] + " ");
            tvLabel.setLayoutParams(params);
            singleLegendLayout.addView(tvLabel);


            // 添加data(百分比顯示)
            TextView tvPercentData = new TextView(context);
            float total = 0;
            for (int j = 0; j < data.length; j++) {
                total += data[j];
            }
            tvPercentData.setText((data[i] / total * 100 + "").substring(0, 4) + "%");
            tvPercentData.setLayoutParams(params);
            singleLegendLayout.addView(tvPercentData);

            // legendLayout為外層布局即整個圖例布局,是在xml檔案中定義
            legendLayout.addView(singleLegendLayout);
        }
    }

}
           

繼續閱讀