Android图表利器-MPAndroidChart

最近需要在Android上将数据展示为图表,偶然间在GitHub上找到一个很不错的Android图表框架,支持柱状图,饼图,曲线图,点的误差图等等等,关键一点,好看!。
闲话少说,先上图(CSDN出问题了。。。图片传不上):
这里写图片描述这里写图片描述
本篇博客,我们介绍其中两种:柱状图和饼状图,其他的示例可以查看该大神的GitHub:https://github.com/PhilJay/MPAndroidChart
或者下载我整理的项目:http://download.csdn.net/detail/zengxyuyu/9848370
(app是对MPAndroidChart的整理,mychart是自己修改的(柱状图和饼图),realmTest是一个realm的demo,其它两个是放大镜的demo)

首先我们看看饼图:
饼图支持在中间填写文本,并可根据需求更改大小、颜色,点击饼图中的某一块会放大该块。

public class PieChartActivity extends Activity implements OnChartValueSelectedListener {
    @BindView(R.id.chart1)
    PieChart chart1;

    private String[] labels = {"香蕉", "葡萄", "菠萝", "桃子", "樱桃"};
    private float[] values = {25f, 33f, 10f, 17f, 15f};


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_piechart);
        ButterKnife.bind(this);

        initChartSetting();
    }

    private void initChartSetting() {
        chart1.setUsePercentValues(true);
        chart1.getDescription().setEnabled(false);
        chart1.setExtraOffsets(5, 10, 5, 5);

        //设置减速摩擦系数
        chart1.setDragDecelerationFrictionCoef(0.95f);

        chart1.setCenterTextTypeface(Typeface.DEFAULT);
        chart1.setCenterText(generateCenterText());

        chart1.setDrawHoleEnabled(true);
        chart1.setHoleColor(Color.WHITE);

        chart1.setTransparentCircleColor(Color.WHITE);
        chart1.setTransparentCircleAlpha(110);

        chart1.setHoleRadius(58f);
        chart1.setTransparentCircleRadius(61f);

        chart1.setDrawCenterText(true);

        chart1.setRotationAngle(0);
        // enable rotation of the chart by touch
        chart1.setRotationEnabled(true);
        //应该是允许点击某一块时放大
        chart1.setHighlightPerTapEnabled(true);

        // chart1.setDrawUnitsInChart(true);

        chart1.setOnChartValueSelectedListener(this);


        chart1.animateY(1400, Easing.EasingOption.EaseInOutQuad);
        // chart1.spin(2000, 0, 360);

        setData(labels,values);

        Legend l = chart1.getLegend();
        l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        l.setOrientation(Legend.LegendOrientation.VERTICAL);
        l.setDrawInside(false);
        l.setXEntrySpace(7f);
        l.setYEntrySpace(0f);
        l.setYOffset(0f);

        // entry label styling
        chart1.setEntryLabelColor(Color.WHITE);
        chart1.setEntryLabelTypeface(Typeface.DEFAULT);
        chart1.setEntryLabelTextSize(12f);
    }

    private SpannableString generateCenterText() {

        SpannableString s = new SpannableString("饼状图\n测试用例");
        s.setSpan(new RelativeSizeSpan(1.7f), 0, 4, 0);
        s.setSpan(new StyleSpan(Typeface.NORMAL), 4, s.length(), 0);
        s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), 4, s.length(), 0);
        return s;
    }

    private void setData(String[] labels, float[] values) {
        ArrayList<PieEntry> entries = new ArrayList<PieEntry>();

        if (labels.length != values.length)
            return;
        for (int i = 0; i < labels.length; i++) {
            entries.add(new PieEntry(values[i], labels[i], getResources().getDrawable(R.drawable.star)));
        }

        PieDataSet dataSet = new PieDataSet(entries, "个人爱好");

        dataSet.setDrawIcons(false);
        dataSet.setSliceSpace(3f);
        dataSet.setIconsOffset(new MPPointF(0, 40));
        dataSet.setSelectionShift(5f);

        // 添加颜色
        ArrayList<Integer> colors = new ArrayList<Integer>();
        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);
        //dataSet.setSelectionShift(0f);

        PieData data = new PieData(dataSet);
        data.setValueFormatter(new PercentFormatter());
        data.setValueTextSize(15f);
        //设置值的颜色
        data.setValueTextColor(Color.WHITE);
        data.setValueTypeface(Typeface.DEFAULT);
        chart1.setData(data);
        // undo all highlights
        chart1.highlightValues(null);
        //开始绘制
        chart1.invalidate();
    }

    @Override
    public void onValueSelected(Entry e, Highlight h) {

        if (e == null)
            return;
        Log.e("选中:", "Value: " + e.getY() + ", index: " + h.getX()
                + ", DataSet index: " + h.getDataSetIndex());
    }

    @Override
    public void onNothingSelected() {
        Log.e("PieChartActivity", "没有选中任何一个");
    }
}

然后,我们再看看柱状图,柱状图比较复杂,需要重写格式化类,对X轴和Y轴的数据进行格式化操作,当然,你也可以直接返回,比如我这里写的对X轴数据的格式化类:

public class XAxisValueFormatter implements IAxisValueFormatter {

    private String[] xValues;

    public XAxisValueFormatter(String[] xValues) {
        this.xValues = xValues;
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        return xValues[(int) value];
    }

}

如果你的y轴数据是代表数据(比如,个数,大小等),那么,你可以直接复制这段代码:

public class YAxisValueFormatter implements IAxisValueFormatter
{

    private DecimalFormat mFormat;

    public YAxisValueFormatter() {
        mFormat = new DecimalFormat("###,###,###,##0.0");
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        return mFormat.format(value);
    }
}

然后,我们说一下点击柱子会出现的东西,提示(有点像QQ消息):

public class XYMarkerView extends MarkerView {

    private TextView tvContent;
    private IAxisValueFormatter xAxisValueFormatter;

    private DecimalFormat format;

    public XYMarkerView(Context context, IAxisValueFormatter xAxisValueFormatter) {
        super(context, R.layout.custom_marker_view);

        this.xAxisValueFormatter = xAxisValueFormatter;
        tvContent = (TextView) findViewById(R.id.tvContent);
        format = new DecimalFormat("###.0");
    }

    @Override
    public void refreshContent(Entry e, Highlight highlight) {

        tvContent.setText("x: " + xAxisValueFormatter.getFormattedValue(e.getX(), null) + ", y: " + format.format(e.getY()));

        super.refreshContent(e, highlight);
    }

    @Override
    public MPPointF getOffset() {
        return new MPPointF(-(getWidth() / 2), -getHeight());
    }
}

最后,重头戏,柱状图的代码:

public class BartChartActivity extends Activity implements OnChartValueSelectedListener {
    @BindView(R.id.chart1)
    BarChart chart1;

    private String[] xValues = {"香蕉", "葡萄", "菠萝", "桃子", "樱桃"};
    private float[] yValues = {25f, 33f, 10f, 17f, 15f};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_barchart);
        ButterKnife.bind(this);
        initSetting();
    }

    private void initSetting() {
        chart1.setOnChartValueSelectedListener(this);

        chart1.setDrawBarShadow(false);
        chart1.setDrawValueAboveBar(true);

        chart1.getDescription().setEnabled(false);

        //设置当超过多少个x值时不在柱状图的柱子上绘制y值,这里设置为60
        chart1.setMaxVisibleValueCount(60);

        // 只能在x或y轴上单独的缩放
        chart1.setPinchZoom(false);

        chart1.setDrawGridBackground(false);
        // chart1.setDrawYLabels(false);

        IAxisValueFormatter xAxisFormatter = new XAxisValueFormatter(xValues);

        XAxis xAxis = chart1.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTypeface(Typeface.DEFAULT);
        xAxis.setDrawGridLines(false);
        xAxis.setGranularity(1f);
        xAxis.setTextSize(15);
        xAxis.setLabelCount(xValues.length);
        xAxis.setValueFormatter(xAxisFormatter);

        IAxisValueFormatter custom = new YAxisValueFormatter();

        YAxis leftAxis = chart1.getAxisLeft();
        leftAxis.setTypeface(Typeface.DEFAULT);
        leftAxis.setLabelCount(yValues.length, false);
        leftAxis.setValueFormatter(custom);
        leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        leftAxis.setTextSize(13);
        leftAxis.setSpaceTop(15f);
        leftAxis.setAxisMinimum(0f);

        YAxis rightAxis = chart1.getAxisRight();
        rightAxis.setDrawGridLines(false);
        rightAxis.setTypeface(Typeface.DEFAULT);
        rightAxis.setLabelCount(yValues.length, false);
        rightAxis.setValueFormatter(custom);
        rightAxis.setSpaceTop(15f);
        rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)

        Legend l = chart1.getLegend();
        l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        l.setDrawInside(false);
        l.setForm(Legend.LegendForm.SQUARE);
        l.setFormSize(9f);
        l.setTextSize(11f);
        l.setXEntrySpace(4f);

        XYMarkerView mv = new XYMarkerView(this, xAxisFormatter);
        mv.setChartView(chart1); // For bounds control
        chart1.setMarker(mv); // Set the marker to the chart

        setData(yValues);
    }

    private void setData(float[] yValues) {
        ArrayList<BarEntry> y_list = new ArrayList<>();

        for (int i = 0; i < yValues.length; i++) {
            y_list.add(new BarEntry(i, yValues[i]));
        }

        BarDataSet set1;

        if (chart1.getData() != null && chart1.getData().getDataSetCount() > 0) {
            set1 = (BarDataSet) chart1.getData().getDataSetByIndex(0);
            set1.setValues(y_list);
            chart1.getData().notifyDataChanged();
            chart1.notifyDataSetChanged();
        } else {
            set1 = new BarDataSet(y_list, "各种水果爱好人数");

            set1.setDrawIcons(false);

            set1.setColors(ColorTemplate.MATERIAL_COLORS);

            ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
            dataSets.add(set1);

            BarData data = new BarData(dataSets);
            data.setValueTextSize(10f);
            data.setValueTypeface(Typeface.DEFAULT);
            data.setBarWidth(0.9f);

            chart1.setData(data);
        }
    }


    @Override
    public void onValueSelected(Entry e, Highlight h) {

    }

    @Override
    public void onNothingSelected() {

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值