MPAndroidChart统计图开发总结

前段时间公司要求要给项目里面用统计图来统计数据的直观信息。之后在GitHub上找到了  MPAndroidChart这个库,
今天不对其原理进行解剖。指记录其用法以及常用的属性设置。围绕柱状图、折线图、和饼状图来给大家解析。。。

一、引言

MPAndroidChart 是 Android 一个强大且容易使用的图表库

  • 支持线状图、柱状图、散点图、烛状图、气泡图、饼状图和蜘蛛网状图
  • 支持缩放、拖动(平移)、选择和动画
  • 适用于 Android 2.2 ( API 8 ) 和以上
  • 8种不同的图表类型
  • 两轴缩放(支持触摸手势,两轴单独或同时的放缩) 
  • 拖 / 平移 / 抛(触摸手势)
  • Combined-Charts 组合图表(线状、柱状、散点图等)
  • 双轴(比如说有两个独立的Y轴数据)
  • 高亮显示值(我们可以自定义Popup-views来高亮显示我们选中的值)
  • 自定义轴(x轴和y轴)
  • 动画(建立x和y轴动画,如开始绘制是的显示动画)
  • 自定义(paints、字体、legends、颜色、背景、手势、虚线 …)

二、柱形图、折线图公用属性

不同的统计图表的很多属性都是公用的如:柱状图、折线图
  • setDrawBarShadow(false);//–绘制当前展示的内容顶部阴影
  • setDrawValueAboveBar(true);//–绘制的图形都在bar顶部
  • getDescription().setEnabled(false); // 不显示数据描述
  • setPinchZoom(true);//–捏合手势,双指缩放..
  • setScaleEnabled(true);//设置是否可以缩放–
  • setDrawGridBackground(false);//–绘制中心内容区域背景色.
  • getAxisRight().setDrawLabels(false);//禁止显示Y右侧有数据–
  • getAxisRight().setDrawAxisLine(false);//禁止显示Y右侧线条–
  • setDragEnabled(true);//设置是否拖动–
  • setScaleYEnabled(false); //取消Y轴缩放–
  • setScaleXEnabled(true);//打开x轴缩放–
  • zoomToCenter(2.5f,0f);//让初始显示比例为其总数的一半

1、设置x轴的属性

  • setDrawGridLines(false);//–是否绘制竖直分割线.
  • setGranularity(1f); // only intervals of 1 day底部label的分割间隙
  • setLabelCount(y.length, false); //–对应的当前绘制在底部的label数
  • setValueFormatter(new DayAxisValueFormatter(barChart, y)); //设置底部label的文字内容
  • setLabelRotationAngle(-25);//设置底部label的旋转角度.
  • setAxisMinimum(0); // restrict the x-axis range限制x轴范围

2、设置Y轴的属性

  • setLabelCount(5, false); //–绘制Y方向(应该)被显示的数量,第二个参数表示label是否是精准变化,还是近似变化
  • setValueFormatter(myAxisValueFormatter);//设置显示的值
  • setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);//Y方向文字的位置,在线外侧.(默认在外侧)
  • setSpaceTop(15f);//分割线的间距百分比.
  • setAxisMinimum(0f); // this replaces setStartAtZero(true)Y方向的起始值.

3、设置图列属性

  • .setPosition(Legend.LegendPosition.ABOVE_CHART_LEFT);//设置注解的位置在左上方,还有别的值设置不同的位置
  • setForm(Legend.LegendForm.CIRCLE);//这是左边显示小图标的形状,还有别的值设置不同的形状
  • setEnabled(false);//设置图列隐藏

4、设置每组柱子的个数,或者折线的个数

 BarDataSet set1, set2, set3;//每创建一个,就会每组多个柱子,一般会在设置数据里面定义,
 (我创建了3个,代表每组有三个柱子)。下面是两种图形对比:

MPAndroidChart统计图开发总结_第1张图片
MPAndroidChart统计图开发总结_第2张图片

代码如下:

 /**
     * 柱型统计图数据数据
     */
    private void setData(ArrayList all, ArrayList finish, ArrayList unFinish) {
        float groupSpace = 0.08f;
        float barSpace = 0f; // x4 DataSet
        float barWidth = 0.3f; // x4 DataSet
        ArrayList dataSets = new ArrayList();

        BarDataSet set1, set2, set3;
        set1 = new BarDataSet(all, isAmountChat ? "总金额" : "事故数量");
        set1.setColors(ColorTemplate.MATERIAL_COLORS);   //设置柱型颜色
        dataSets.add(set1);

        if (finish != null&&unFinish!=null) {
            set2 = new BarDataSet(finish, isAmountChat ? "已结案金额" : "事故数量");
            set3 = new BarDataSet(unFinish, isAmountChat ? "未结案金额 单位(万元)" : "事故数量");

            set2.setColor(Color.rgb(124, 36, 98)); //设置柱型颜色set2.setColors(Color.GREEN);
            set3.setColors(Color.rgb(215, 96, 12));   //设置柱型颜色
            dataSets.add(set2);
            dataSets.add(set3);
        }
        if (!isAmountChat){
            barChart.getLegend().setEnabled(false);
        }
        barChart.getLegend().setPosition(Legend.LegendPosition.ABOVE_CHART_LEFT);//设置注解的位置在左上方
        barChart.getLegend().setForm(Legend.LegendForm.CIRCLE);//这是左边显示小图标的形状
        barChart.animateXY(1000, 2000);//设置动画
        BarData data = new BarData(dataSets);
        data.setValueTextSize(10f);
        data.setValueTypeface(mTfLight);
        data.setBarWidth(0.3f);//--设置bar的宽度 ,取值(0-1).
        if (finish == null&&unFinish == null) {
            data.setValueFormatter(new IValueFormatter() {
                @Override
                public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                    return "" + (int) value;
                }
            });
        }else{
            data.setValueFormatter(new IValueFormatter() {
                @Override
                public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                    return "" + value;
                }
            });
        }
        barChart.setData(data);
if (finish != null||unFinish != null){
    barChart.getBarData().setBarWidth(barWidth);// specify the width each bar should have指定每个条应有的宽度。
    barChart.getXAxis().setAxisMinimum(0); // restrict the x-axis range限制x轴范围
    barChart.getXAxis().setAxisMaximum(0 + barChart.getBarData().getGroupWidth(groupSpace, barSpace) * all.size()); //bardata。getgroupwith(…)是一个辅助计算宽度根据提供的参数,每一组都需要
    barChart.groupBars(0, groupSpace, barSpace);
    barChart.invalidate();
}

    }

二、饼状图属性

  • setUsePercentValues(false);//设置饼图是否使用百分比
  • .getDescription().setEnabled(false);// 不显示数据描述
  • .setExtraOffsets(5, 10, 5, 5);
  • setDragDecelerationFrictionCoef(0.95f);
  • setCenterText(generateCenterSpannableText(centerText));//设置圆盘中间文字的字体
  • setExtraOffsets(20.f, 0.f, 20.f, 0.f);
  • setDrawHoleEnabled(true);//是否显示饼图中间空白区域,默认显示
  • setHoleColor(Color.WHITE);//设置中间圆盘的颜色
  • setTransparentCircleColor(Color.TRANSPARENT);//–内圆边框色
  • setTransparentCircleAlpha(110);//–内圆边框透明度
  • setHoleRadius(58f);//设置中间圆盘的半径,值为所占饼图的百分比
  • .setTransparentCircleRadius(61f);//设置中间透明圈的半径,值为所占饼图的百分比
  • setDrawCenterText(true);//是否显示圆盘中间文字,默认显示
  • setRotationAngle(0);//–绘制的开始位置
  • setRotationEnabled(true);//–允许旋转
  • setHighlightPerTapEnabled(true);//—允许点击其中某个扇形区域.
  • animateY(1400, Easing.EasingOption.EaseInOutQuad);//设置y轴动画

1、设置图列属性

  • setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);//设置显示方向
  • setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
  • setOrientation(Legend.LegendOrientation.HORIZONTAL);
  • setDrawInside(false);
  • setXEntrySpace(7f);
  • setYEntrySpace(0f);
  • setYOffset(0f);

2、设置数据的显示方式和属性如:扇形区域内,或扇形区域外

  • PieDataSet dataSet = new PieDataSet(entries, “”);//控件右上角的说明文字
  • dataSet.setSliceSpace(3f);//设置个饼状图之间的距离
  • dataSet.setSelectionShift(10f);// 部分区域被选中时多出的长度
  • dataSet.setColors(colors);//颜色
  • dataSet.setValueLinePart1OffsetPercentage(100.f);//折线中第一段起始位置相对于区块的偏移量, 数值越大, 折线距离区块越远
  • dataSet.setValueLinePart1Length(0.4f);//折线中第一段长度占比
  • dataSet.setValueLinePart2Length(0.2f);//折线中第二段长度最大占比
  • dataSet.setValueLineColor(Color.rgb(255, 110, 110));//折线颜色
  • dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);//数据位置INSIDE_SLICE,OUTSIDE_SLICE 可以显示折线上的数据
  • dataSet.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);//隐藏扇形区域内的显示数据

3、效果如下图所示

MPAndroidChart统计图开发总结_第3张图片

  如果想要将数据显示到扇形区域内,不要设置以下属性:
  • setYValuePosition();

4、示例代码

 /**
     * 圆形统计图数据函数
     */
       private void setPieData(PieChart mPiechar,ArrayList entries, ArrayList colors, final String anotherType) {
        PieDataSet dataSet = new PieDataSet(entries, "");//控件右上角的说明文字
        dataSet.setSliceSpace(3f);//设置个饼状图之间的距离
        dataSet.setSelectionShift(10f);// 部分区域被选中时多出的长度
        dataSet.setColors(colors);
        dataSet.setValueLinePart1OffsetPercentage(100.f);//折线中第一段起始位置相对于区块的偏移量, 数值越大, 折线距离区块越远
        dataSet.setValueLinePart1Length(0.4f);//折线中第一段长度占比
        dataSet.setValueLinePart2Length(0.2f);//折线中第二段长度最大占比
        dataSet.setValueLineColor(Color.rgb(255, 110, 110));//折线颜色
        dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);//数据位置INSIDE_SLICE,OUTSIDE_SLICE 可以显示折线上的数据
        dataSet.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);

        PieData data = new PieData(dataSet);
        data.setValueTextSize(11f);//区域文字的大小
        data.setValueTextColor(Color.BLACK);//设置区域文字的颜色
        data.setValueTypeface(tf);//设置区域文字的字体
        data.setValueFormatter(new IValueFormatter() {
            @Override
            public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                PieEntry pieEntry=(PieEntry)entry;
                return anotherType.equals("人员伤亡") ? pieEntry.getLabel() + (int) value +" 人" :  pieEntry.getLabel() + (int) value + "件";

            }
        });
        mPiechar.setData(data);
        mPiechar.highlightValues(null);
        mPiechar.invalidate();
    }

二、屏幕适配问题

如果你的统计图是在一个较小的空间里面,那么如果不对高度进行限制,
将会有一部分会被遮挡,这时候要手动设置最大值,否則系统会默认自己根据数据设置图的比例.   

如果没有,则忽略

代码如下:

private void setMaxValue() {
        YAxis leftAxis = incomeChart.getAxisLeft();
        double maxRatio = 0.0;
        double maxInterest = 0.0;
        if (mTrends != null) {
            for (int i = 0; i < mTrends.size(); i++) {
                MonthAppreciateProduct.Trend trend = mTrends.get(i);
                double ratioDay = trend.getRatioDay();
                double interestDay = trend.getInterestDay();
                if (ratioDay > maxRatio) maxRatio = ratioDay;
                if (interestDay > maxInterest) maxInterest = interestDay;
            }
        }

        if (mType.equals("ratio")) {
            if (maxRatio > 0) {
                leftAxis.setAxisMaxValue((float) (maxRatio * 1.3));            
            } else {
                leftAxis.setAxisMaxValue(10f);
            }

        } else {
            if (maxInterest > 0) {
                leftAxis.setAxisMaxValue((float) (maxInterest * 1.3));//Y轴最大值
            } else {
                leftAxis.setAxisMaxValue(5f);
            }
        }
    }
这篇就这样了、大家有新发现了,欢迎留言讨论……   顺便给大家个官方的源码案列,和使用库

http://download.csdn.net/detail/changalbert/9911066

你可能感兴趣的:(Android)