Android 图表开源框架之MPAndroidChart PieChart扇形图(一)
Android 图表开源框架之MPAndroidChart PieChart扇形图,版本:3.0.1
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.1'
效果图1:
效果图2:
一.具体实现:
1.主函数代码:
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.components.Legend;
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.data.PieEntry;
import com.github.mikephil.charting.formatter.PercentFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
ArrayList<PieEntry> pieEntryList = new ArrayList();//数据列表
ArrayList<Integer> colors = new ArrayList();//颜色列表
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final PieChart mChart = (PieChart) findViewById(R.id.chart1);
// 设置周围字体颜色
mChart.setCenterTextColor(Color.BLACK);
HashMap dataMap=new HashMap();
dataMap.put("Ⅰ类水","8");
dataMap.put("Ⅱ类水","12");
dataMap.put("Ⅲ类水","31");
dataMap.put("Ⅳ类水","24");
dataMap.put("Ⅴ类水","10");
dataMap.put("劣Ⅴ类水","15");
PieChartUtil.getPitChart().setPieChart(mChart,dataMap,"水质",true);
//点击事件
mChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
@Override
public void onValueSelected(Entry e, Highlight h) {
PieEntry pieEntry=(PieEntry)e;
mChart.setCenterText(pieEntry.getLabel());
}
@Override
public void onNothingSelected() {
}
});
// mChart.getDescription().setEnabled(false); //设置pieChart图表的描述
// mChart.setBackgroundColor(Color.WHITE); //设置pieChart图表背景色
// mChart.setRotationEnabled(true);//可以手动旋转
// mChart.setDragDecelerationFrictionCoef(0.95f);//设置pieChart图表转动阻力摩擦系数[0,1]
// mChart.setHighlightPerTapEnabled(true); //设置piecahrt图表点击Item高亮是否可用
// mChart.animateY(1400, Easing.EasingOption.EaseInOutQuad);// 设置pieChart图表展示动画效果
// Legend l = mChart.getLegend();
// l.setEnabled(true); //是否启用图列(true:下面属性才有意义
// l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
// l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
// l.setOrientation(Legend.LegendOrientation.VERTICAL);
// l.setForm(Legend.LegendForm.DEFAULT); //设置图例的形状
// l.setFormSize(10); //设置图例的大小
// l.setFormToTextSpace(10f); //设置每个图例实体中标签和形状之间的间距
// l.setDrawInside(false);
// l.setWordWrapEnabled(true); //设置图列换行(注意使用影响性能,仅适用legend位于图表下面)
// l.setXEntrySpace(10f); //设置图例实体之间延X轴的间距(setOrientation = HORIZONTAL有效)
// l.setYEntrySpace(8f); //设置图例实体之间延Y轴的间距(setOrientation = VERTICAL 有效)
// l.setYOffset(0f); //设置比例块Y轴偏移量
// l.setTextSize(14f); //设置图例标签文本的大小
// l.setTextColor(Color.parseColor("#333333"));//设置图例标签文本的颜色
// for (int i = 0; i < pieEntryList.size(); i++) {//list为数据列表
// Random random = new Random();
// int r = random.nextInt(256);
// int g = random.nextInt(256);
// int b = random.nextInt(256);
// colors.add(Color.rgb(r,g,b));
// pieEntryList.add(new PieEntry(Float.parseFloat(townsChartEntity.getRecordSet0().getR().get(i).getC().get(2)) * 100 / all, townsChartEntity.getRecordSet0().getR().get(i).getC().get(1)));
// }
// //饼状图数据集 PieDataSet
// PieDataSet pieDataSet = new PieDataSet(pieEntryList, "图表名称");
// pieDataSet.setSliceSpace(3f); //设置饼状Item之间的间隙
// pieDataSet.setSelectionShift(30f); //设置饼状Item被选中时变化的距离
// pieDataSet.setColors(colors); //为DataSet中的数据匹配上颜色集(饼图Item颜色)
// //最终数据 PieData
// PieData pieData = new PieData(pieDataSet);
// pieData.setDrawValues(true); //设置是否显示数据实体(百分比,true:以下属性才有意义)
// pieData.setValueTextColor(Color.BLUE); //设置所有DataSet内数据实体(百分比)的文本颜色
// pieData.setValueTextSize(12f); //设置所有DataSet内数据实体(百分比)的文本字体大小
// pieData.setValueFormatter(new PercentFormatter());//设置所有DataSet内数据实体(百分比)的文本字体格式
//
// mChart.setData(pieData);
// mChart.highlightValues(null);
// mChart.invalidate(); //将图表重绘以显示设置的属性和数据
// PieData mPieData = getPieData(4, 100);
// showChart(mChart, mPieData);
//模拟数据
// HashMap dataMap = new HashMap();
// dataMap.put("A","300");
// dataMap.put("B","600");
// dataMap.put("C","500");
// dataMap.put("D","800");
//
// setPieChart(mChart,dataMap,"数据",true);
}
//设置各区块的颜色
public static final int[] PIE_COLORS = {
Color.rgb(181, 194, 202), Color.rgb(129, 216, 200), Color.rgb(241, 214, 145),
Color.rgb(108, 176, 223), Color.rgb(195, 221, 155), Color.rgb(251, 215, 191),
Color.rgb(237, 189, 189), Color.rgb(172, 217, 243)
};
//设置饼形图属性
public void setPieChart(PieChart pieChart, Map<String, Float> pieValues, String title, boolean showLegend) {
pieChart.setUsePercentValues(true);//设置使用百分比(后续有详细介绍)
pieChart.getDescription().setEnabled(false);//设置描述
pieChart.setExtraOffsets(25, 10, 25, 25); //设置边距
pieChart.setDragDecelerationFrictionCoef(0.95f);//设置摩擦系数(值越小摩擦系数越大)
pieChart.setCenterText(title);//设置环中的文字
pieChart.setRotationEnabled(true);//是否可以旋转
pieChart.setHighlightPerTapEnabled(true);//点击是否放大
pieChart.setCenterTextSize(22f);//设置环中文字的大小
pieChart.setDrawCenterText(true);//设置绘制环中文字
pieChart.setRotationAngle(120f);//设置旋转角度
pieChart.setTransparentCircleRadius(61f);//设置半透明圆环的半径,看着就有一种立体的感觉
//这个方法为true就是环形图,为false就是饼图
pieChart.setDrawHoleEnabled(false);
//设置环形中间空白颜色是白色
pieChart.setHoleColor(Color.WHITE);
//设置半透明圆环的颜色
pieChart.setTransparentCircleColor(Color.WHITE);
//设置半透明圆环的透明度
pieChart.setTransparentCircleAlpha(110);
//图例设置
Legend legend = pieChart.getLegend();
if (showLegend) {
legend.setEnabled(true);//是否显示图例
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);//图例相对于图表横向的位置
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);//图例相对于图表纵向的位置
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);//图例显示的方向
legend.setDrawInside(false);
legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);
} else {
legend.setEnabled(false);
}
//设置饼图数据
setPieChartData(pieChart, pieValues);
pieChart.animateX(1500, Easing.EasingOption.EaseInOutQuad);//数据显示动画
}
//设置饼图数据
private void setPieChartData(PieChart pieChart, Map<String, Float> pieValues) {
ArrayList xValues = new ArrayList(); //xVals用来表示每个饼块上的内容
for (int i = 0; i < 4; i++) {
xValues.add("Quarterly" + (i + 1)); //饼块上显示成Quarterly1, Quarterly2, Quarterly3, Quarterly4
}
ArrayList yValues = new ArrayList(); //yVals用来表示封装每个饼块的实际数据
// 饼图数据
/**
* 将一个饼形图分成四部分, 四部分的数值比例为14:14:34:38
* 所以 14代表的百分比就是14%
*/
float quarterly1 = 14;
float quarterly2 = 14;
float quarterly3 = 34;
float quarterly4 = 38;
yValues.add(new Entry(quarterly1, 0));
yValues.add(new Entry(quarterly2, 1));
yValues.add(new Entry(quarterly3, 2));
yValues.add(new Entry(quarterly4, 3));
// Set set = pieValues.entrySet();
// Iterator it = set.iterator();
// 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(yValues, "");
dataSet.setSliceSpace(3f);//设置饼块之间的间隔
dataSet.setSelectionShift(5f);//设置饼块选中时偏离饼图中心的距离
dataSet.setColors(PIE_COLORS);//设置饼块的颜色
//设置数据显示方式有见图
dataSet.setValueLinePart1OffsetPercentage(80f);//数据连接线距图形片内部边界的距离,为百分数
dataSet.setValueLinePart1Length(0.3f);
dataSet.setValueLinePart2Length(0.4f);
dataSet.setValueLineColor(Color.YELLOW);//设置连接线的颜色
dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
PieData pieData = new PieData(dataSet);
pieData.setValueFormatter(new PercentFormatter());
pieData.setValueTextSize(11f);
pieData.setValueTextColor(Color.DKGRAY);
pieChart.setData(pieData);
pieChart.highlightValues(null);
pieChart.invalidate();
}
private void initPieChart() {
// PieChart mChart = (PieChart) findViewById(R.id.spread_pie_chart);
// PieData mPieData = getPieData(4, 100);
// showChart(mChart, mPieData);
}
private void showChart(PieChart pieChart, PieData pieData) {
// pieChart.setHoleColorTransparent(true);
pieChart.setHoleRadius(60f); //半径
pieChart.setTransparentCircleRadius(64f); // 半透明圈
//pieChart.setHoleRadius(0); //实心圆
// pieChart.setDescription("测试饼状图");
// mChart.setDrawYValues(true);
pieChart.setDrawCenterText(true); //饼状图中间可以添加文字
pieChart.setDrawHoleEnabled(true);
pieChart.setRotationAngle(90); // 初始旋转角度
// draws the corresponding description value into the slice
// mChart.setDrawXValues(true);
// enable rotation of the chart by touch
pieChart.setRotationEnabled(true); // 可以手动旋转
// display percentage values
pieChart.setUsePercentValues(true); //显示成百分比
// mChart.setUnit(" €");
// mChart.setDrawUnitsInChart(true);
// add a selection listener
// mChart.setOnChartValueSelectedListener(this);
// mChart.setTouchEnabled(false);
// mChart.setOnAnimationListener(this);
pieChart.setCenterText("Quarterly Revenue"); //饼状图中间的文字
//设置数据
pieChart.setData(pieData);
// undo all highlights
// pieChart.highlightValues(null);
// pieChart.invalidate();
Legend mLegend = pieChart.getLegend(); //设置比例图
mLegend.setPosition(Legend.LegendPosition.RIGHT_OF_CHART); //最右边显示
// mLegend.setForm(LegendForm.LINE); //设置比例图的形状,默认是方形
mLegend.setXEntrySpace(7f);
mLegend.setYEntrySpace(5f);
// Legend l = mChart.getLegend();
// l.setEnabled(true); //是否启用图列(true:下面属性才有意义
// l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
// l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
// l.setOrientation(Legend.LegendOrientation.VERTICAL);
// l.setForm(Legend.LegendForm.DEFAULT); //设置图例的形状
// l.setFormSize(10); //设置图例的大小
// l.setFormToTextSpace(10f); //设置每个图例实体中标签和形状之间的间距
// l.setDrawInside(false);
// l.setWordWrapEnabled(true); //设置图列换行(注意使用影响性能,仅适用legend位于图表下面)
// l.setXEntrySpace(10f); //设置图例实体之间延X轴的间距(setOrientation = HORIZONTAL有效)
// l.setYEntrySpace(8f); //设置图例实体之间延Y轴的间距(setOrientation = VERTICAL 有效)
// l.setYOffset(0f); //设置比例块Y轴偏移量
// l.setTextSize(14f); //设置图例标签文本的大小
// l.setTextColor(Color.parseColor("#333333"));//设置图例标签文本的颜色
pieChart.animateXY(1000, 1000); //设置动画
// mChart.spin(2000, 0, 360);
}
/**
* @param count 分成几部分
* @param range
*/
private PieData getPieData(int count, float range) {
ArrayList xValues = new ArrayList(); //xVals用来表示每个饼块上的内容
for (int i = 0; i < count; i++) {
xValues.add("Quarterly" + (i + 1)); //饼块上显示成Quarterly1, Quarterly2, Quarterly3, Quarterly4
}
ArrayList yValues = new ArrayList(); //yVals用来表示封装每个饼块的实际数据
// 饼图数据
/**
* 将一个饼形图分成四部分, 四部分的数值比例为14:14:34:38
* 所以 14代表的百分比就是14%
*/
float quarterly1 = 14;
float quarterly2 = 14;
float quarterly3 = 34;
float quarterly4 = 38;
yValues.add(new Entry(quarterly1, 0));
yValues.add(new Entry(quarterly2, 1));
yValues.add(new Entry(quarterly3, 2));
yValues.add(new Entry(quarterly4, 3));
//y轴的集合
PieDataSet pieDataSet = new PieDataSet(yValues, "Quarterly Revenue 2014"/*显示在比例图上*/);
pieDataSet.setSliceSpace(0f); //设置个饼状图之间的距离
ArrayList colors = new ArrayList();
// 饼图颜色
colors.add(Color.rgb(205, 205, 205));
colors.add(Color.rgb(114, 188, 223));
colors.add(Color.rgb(255, 123, 124));
colors.add(Color.rgb(57, 135, 200));
pieDataSet.setColors(colors);
DisplayMetrics metrics = getResources().getDisplayMetrics();
float px = 5 * (metrics.densityDpi / 160f);
pieDataSet.setSelectionShift(px); // 选中态多出的长度
// PieData pieData = new PieData(xValues, pieDataSet);
PieData pieData = new PieData(pieDataSet);
pieData.setDrawValues(true);
return pieData;
}
}
2.布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ccc"
tools:context=".MainActivity">
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/chart1"
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
3.工具类PieChartUtil
import android.graphics.Color;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.components.Legend;
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.data.PieEntry;
import com.github.mikephil.charting.formatter.IValueFormatter;
import com.github.mikephil.charting.formatter.PercentFormatter;
import com.github.mikephil.charting.interfaces.datasets.IPieDataSet;
import com.github.mikephil.charting.utils.ViewPortHandler;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class PieChartUtil {
//设置各区域颜色
public final int[] PIE_COLORS={
Color.rgb(181, 194, 202), Color.rgb(129, 216, 200), Color.rgb(241, 214, 145),
Color.rgb(108, 176, 223), Color.rgb(195, 221, 155), Color.rgb(251, 215, 191),
Color.rgb(237, 189, 189), Color.rgb(172, 217, 243)
};
private static PieChartUtil pieChartUtil;
private List<PieEntry> entries;
public static PieChartUtil getPitChart(){
if( pieChartUtil==null){
pieChartUtil=new PieChartUtil();
}
return pieChartUtil;
}
public void setPieChart(PieChart pieChart, Map<String, Float> pieValues, String title, boolean showLegend) {
pieChart.setUsePercentValues(true);//设置使用百分比(后续有详细介绍)
pieChart.getDescription().setEnabled(false);//设置描述
pieChart.setRotationEnabled(true);//是否可以旋转
pieChart.setHighlightPerTapEnabled(true);//点击是否放大
pieChart.setDrawCenterText(true);//设置绘制环中文字
pieChart.setDrawEntryLabels(true);
//这个方法为true就是环形图,为false就是饼图
pieChart.setDrawHoleEnabled(true);//环形
pieChart.setExtraOffsets(0, 0, 0, 0); //设置边距
// 0表示摩擦最大,基本上一滑就停
// 1表示没有摩擦,会自动转化为0.9999,及其顺滑
pieChart.setDragDecelerationFrictionCoef(0.35f);//设置滑动时的摩擦系数(值越小摩擦系数越大)
pieChart.setCenterText(title);//设置环中的文字
pieChart.setCenterTextSize(15f);//设置环中文字的大小
pieChart.setCenterTextColor(PIE_COLORS[2]);//设置扇形中间文字颜色
pieChart.setRotationAngle(120f);//设置旋转角度
pieChart.setTransparentCircleRadius(61f);//设置半透明圆环的半径,看着就有一种立体的感觉
// pieChart.setHoleRadius(0); //实心圆
//设置环形中间空白颜色是白色
pieChart.setHoleColor(Color.TRANSPARENT);
//设置半透明圆环的颜色
pieChart.setTransparentCircleColor(Color.WHITE);
//设置半透明圆环的透明度
pieChart.setTransparentCircleAlpha(110);
//图例设置
Legend legend = pieChart.getLegend();
if (showLegend) {
legend.setEnabled(true);//是否显示图例
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);//图例相对于图表横向的位置
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);//图例相对于图表纵向的位置
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);//图例显示的方向
legend.setDrawInside(false);
legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);//方向
} else {
legend.setEnabled(false);
}
//设置饼图数据
setPieChartData(pieChart, pieValues);
pieChart.animateX(1500, Easing.EasingOption.EaseInOutQuad);//数据显示动画
}
//设置饼图数据
private void setPieChartData(PieChart pieChart, Map<String, Float> pieValues) {
//遍历HashMap
Set set = pieValues.entrySet();
Iterator it = set.iterator();//得到适配器
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, "");
dataSet.setSliceSpace(3f);//设置饼块之间的间隔
dataSet.setSelectionShift(6f);//设置饼块选中时偏离饼图中心的距离
dataSet.setColors(PIE_COLORS);//设置饼块的颜色
dataSet.setValueTextSize(5f);
//设置数据显示方式有见图
dataSet.setValueLinePart1OffsetPercentage(80f);//数据连接线距图形片内部边界的距离,为百分数
dataSet.setValueLinePart1Length(0.3f);
dataSet.setValueLinePart2Length(0.4f);
dataSet.setValueLineColor( PIE_COLORS[3]);//设置连接线的颜色
dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);//y轴数据显示在饼图内/外
dataSet.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);//x轴数据显示在饼图内/外
PieData pieData = new PieData(dataSet);
pieData.setValueFormatter(new PercentFormatter());
pieData.setValueTextSize(11f);
pieData.setValueTextColor(Color.DKGRAY);//设置百分比内容字体颜色
//2. pieData.setValueFormatter(new PercentFormatter()); 替换成自定义的
//设置替换原来的%为元
pieData.setValueFormatter(new TestDefaultValueFormatter());
pieChart.setData(pieData);
pieChart.highlightValues(null);
pieChart.invalidate();
}
//1.在PieChartUtil 中创建内部类
private class TestDefaultValueFormatter implements IValueFormatter {
private DecimalFormat mFormat;
public TestDefaultValueFormatter(){
mFormat = new DecimalFormat("###");//十进制格式
}
@Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
return mFormat.format(value)+"元";
}
}
}
在自定义中可以修改原来的%为元或着其它单位
4.参考案例: