写点什么

MPAndroidChart 绘制曲线图、柱状图总结

用户头像
Android架构
关注
发布于: 5 小时前


如上所示,实现的图表种类非常多,还没有列举完全,功能非常强大,正好最近在项目中有使用到 MPAndroidChart,在此做一个总结。

项目中使用效果截图如下:
基础设置相关 API
  • Chart 的基础设置


// 设置是否绘制背景 mChart.setDrawGridBackground(false);// 设置是否绘制边框 mChart.setDrawBorders(false);// 设置是否可以缩放图表 mChart.setScaleEnabled(true);// 设置是否可以用手指移动图表 mChart.setDragEnabled(true);


注意:这里说一下后面 2 个属性setScaleEnabledsetDragEnabled,设置图表是佛可以缩放和移动,当手机屏幕一屏显示不下时,我们希望能通过缩放或者滑动图表。但是经过试验,仅仅设置这两个属性是不行的,还需要配合 Matrix 来实现,代码如下:


Matrix matrix = new Matrix();// x 轴放大 4 倍,y 不变 matrix.postScale(4.0f, 1.0f);// 设置缩放 mChart.getViewPortHandler().refresh(matrix, mChart, false);


  • 2,图表描述相关设置


// 不显示描述数据 mChart.getDescription().setEnabled(true);mChart.getAxisRight().setEnabled(false);// 设置描述 mChart.getDescription().setText("text desc");// 设置描述显示的位置,默认是显示在图表的右下角的 mChart.getDescription().setPosition(200,100);



  • 3,是否显示右侧 y 轴


mChart.getAxisRight().setEnabled(false);


![image.png](https://user-gold-cdn.xitu.io/2018/3/20/16243e199cb45139?imageView2/0/w/1280/h/960/ignore-error/


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码



    • 4, 图例相关设置


    Legend legend = mChart.getLegend();//是否显示 legend.setEnabled(true);//图例样式:有圆点,正方形,短线 几种样式 legend.setForm(Legend.LegendForm.CIRCLE);// 图例显示的位置:如下 2 行代码设置图例显示在左下角 legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);// 图例的排列方式:水平排列和竖直排列 2 种 legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);// 图例距离 x 轴的距离 legend.setXEntrySpace(10f);//图例距离 y 轴的距离 legend.setYEntrySpace(10f);//图例的大小 legend.setFormSize(7f);// 图例描述文字大小 legend.setTextSize(10);


    • 5,x 轴先关设置


    XAxis xAxis = mChart.getXAxis();


    // 是否显示 x 轴线 xAxis.setDrawAxisLine(true);// 设置 x 轴线的颜色 xAxis.setAxisLineColor(Color.parseColor("#4cffffff"));// 是否绘制 x 方向网格线 xAxis.setDrawGridLines(false);//x 方向网格线的颜色 xAxis.setGridColor(Color.parseColor("#30FFFFFF"));


    // 设置 x 轴数据的位置 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);// 设置 x 轴文字的大小 xAxis.setTextSize(12);


    // 设置 x 轴数据偏移量 xAxis.setYOffset(5);final List<String> labels = mLabels;// 显示 x 轴标签 IAxisValueFormatter formatter = new IAxisValueFormatter() {


    @Overridepublic String getFormattedValue(float value, AxisBase axis) {int index = (int) value;if (index < 0 || index >= labels.size()) {return "";}return labels.get(index);// return labels.get(Math.min(Math.max((int) value, 0), labels.size() - 1));}


    };// 引用标签 xAxis.setValueFormatter(formatter);// 设置 x 轴文字颜色 xAxis.setTextColor(mChart.getResources().getColor(R.color.char_text_color));// 设置 x 轴每最小刻度 intervalxAxis.setGranularity(1f);


    6,y 轴先关设置


    YAxis yAxis = mChart.getAxisLeft();//设置 x 轴的最大值 yAxis.setAxisMaximum(yMax);// 设置 y 轴的最大值 yAxis.setAxisMinimum(yMin);// 不显示 y 轴 yAxis.setDrawAxisLine(false);// 设置 y 轴数据的位置 yAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);// 不从 y 轴发出横向直线 yAxis.setDrawGridLines(false);// 是否显示 y 轴坐标线 yAxis.setDrawZeroLine(true);// 设置 y 轴的文字颜色 yAxis.setTextColor(mChart.getResources().getColor(R.color.char_text_color));// 设置 y 轴文字的大小 yAxis.setTextSize(12);// 设置 y 轴数据偏移量//yAxis.setXOffset(30);// yAxis.setYOffset(-3);yAxis.setXOffset(15);// 设置 y 轴 label 数量 yAxis.setLabelCount(5, false);// 设置 y 轴的最小刻度 yAxis.setGranularity(5);//interval


    • 7,缩放和动画设置


    Matrix matrix = new Matrix();// 根据数据量来确定 x 轴缩放大倍 if (mLabels.size() <= 10) {matrix.postScale(1.0f, 1.0f);} else if (mLabels.size() <= 15) {matrix.postScale(1.5f, 1.0f);} else if (mLabels.size() <= 20) {matrix.postScale(2.0f, 1.0f);} else {matrix.postScale(3.0f, 1.0f);}


    // 在图表动画显示之前进行缩放 mChart.getViewPortHandler().refresh(matrix, mChart, false);// x 轴执行动画 mChart.animateX(500);


    • 8, 无数据时,显示文案


    /**


    • 显示无数据的提示

    • @param mChart*/public static void NotShowNoDataText(Chart mChart) {mChart.clear();mChart.notifyDataSetChanged();mChart.setNoDataText("你还没有记录数据");mChart.setNoDataTextColor(Color.WHITE);// 记得最后要刷新一下 mChart.invalidate();}

    • 9,设置 marker (1)首先需要继承 MarkerView 实现一个自定义 View


    public class ChartMarkerView extends MarkerView {


    private TextView textView;


    /**


    • Constructor. Sets up the MarkerView with a custom layout resource.

    • @param context

    • @param layoutResource the layout resource to use for the MarkerView*/public ChartMarkerView(Context context, int layoutResource) {super(context, layoutResource);textView = (TextView) findViewById(R.id.marker_view_text);}


    @Overridepublic void refreshContent(Entry e, Highlight highlight) {float value = e.getY();textView.setText(DecimalFormatUtils.getIntOrFloatRemainOne(value));}


    @Overridepublic MPPointF getOffsetForDrawingAtPoint(float posX, float posY) {return new MPPointF(-getWidth() / 2f, -getHeight() - 10);}}


    (2), 通过addMaker 添加到图上


    combinedChart.setMarker(new ChartMarkerView(context, R.layout.chart_markerview_layout));


    以上就是对 Chart 的一些基础设置,包括 x,y 轴改如何显示(颜色、大小)、图例、描述等等。


    下面就看看如何来绘制曲线图呢?

    数据设置

    当我们要绘制曲线图、折线图、和柱状图等等的时候,怎样将我们要绘制的一个个数据点显示在图上的呢?MPAndroidChart 是用 dataSet 来表示的,我们需要将数据点包装成 DataSet,然后设置到 Chart,刷新绘制就 ok 了。MPAndroidChart 库中有很多 DataSet,如下所示:



    以曲线图或者折线图为例,我们使用 LineDataSet:


    /**


    • 获取 LineDataSet

    • @param entries

    • @param label

    • @param textColor

    • @param lineColor

    • @return*/public static LineDataSet getLineData(List<Entry> entries, String label, @ColorInt int textColor, @ColorInt int lineColor, boolean isFill) {LineDataSet dataSet = new LineDataSet(entries, label);// 设置曲线的颜色 dataSet.setColor(lineColor);//数值文字颜色 dataSet.setValueTextColor(textColor);// 模式为贝塞尔曲线 dataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);// 是否绘制数据值 dataSet.setDrawValues(false);// 是否绘制圆点 dataSet.setDrawCircles(true);dataSet.setDrawCircleHole(false);// 这里有一个坑,当我们想隐藏掉高亮线的时候,MarkerView 跟着不见了// 因此只有将它设置成透明色 dataSet.setHighlightEnabled(true);// 隐藏点击时候的高亮线//设置高亮线为透明色 dataSet.setHighLightColor(Color.TRANSPARENT);


    if (isFill) {//是否设置填充曲线到 x 轴之间的区域 dataSet.setDrawFilled(true);// 填充颜色 dataSet.setFillColor(lineColor);}//设置圆点的颜色 dataSet.setCircleColor(lineColor);// 设置圆点半径 dataSet.setCircleRadius(3.5f);// 设置线的宽度 dataSet.setLineWidth(1f);return dataSet;}

    将数据绘制到图表上

    如果是一条曲线,直接用 LineChart 和 LineData 就好,如果有多条曲线,就需要用 CombinedChart 和 CombinedData (混合图、混合数据)。可以是 LineData 和 BarData 混合来绘制曲线和柱状的混合图。


    /**


    • 初始化数据

    • @param chart

    • @param lineDatas*/public static void initData(CombinedChart chart, LineData... lineDatas) {CombinedData combinedData = new CombinedData();for (LineData lineData : lineDatas) {combinedData.setData(lineData);}


    chart.setData(combinedData);chart.invalidate();}


    最后调用 invalidate 绘制。

    柱状图

    柱状图跟曲线图其实是一样的,图表基础配置一样,然后将数据点包装成 BarData,最后包装成 BarDataSet。


    /**


    • 初始化柱状图图表数据

    • @param chart

    • @param entries

    • @param title

    • @param barColor*/public static void initBarChart(BarChart chart, List<BarEntry> entries, String title, @ColorInt int barColor) {BarDataSet set1 = new BarDataSet(entries, title);set1.setValueTextColor(Color.WHITE);set1.setColor(barColor);ArrayList<IBarDataSet> dataSets = new ArrayList<>();dataSets.add(set1);


    BarData data = new BarData(dataSets);data.setValueTextSize(10f);// 设置 bar 的宽度,但是点很多少的时候好像没作用,会拉得很宽 data.setBarWidth(0.1f);// 设置 value 值 颜色 data.setValueTextColor(Color.WHITE);//设置 y 轴显示的标签 data.setValueFormatter(new IValueFormatter() {@Overridepublic String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {return ((int) (value * 100)) + "%";}});


    chart.setData(data);chart.invalidate();}

    工具类

    项目中有很多出使用曲线图和柱状图的地方,因此抽取了一个工具类,完整代码如下:


    public class MPChartUtils {/**


    • 不显示无数据的提示

    • @param mChart/public static void NotShowNoDataText(Chart mChart) {mChart.clear();mChart.notifyDataSetChanged();mChart.setNoDataText("你还没有记录数据");mChart.setNoDataTextColor(Color.WHITE);mChart.invalidate();}/*

    • 配置 Chart 基础设置

    • @param mChart 图表

    • @param mLabels x 轴标签

    • @param yMax y 轴最大值

    • @param yMin y 轴最小值

    • @param isShowLegend 是否显示图例*/public static void configChart(CombinedChart mChart, List<String> mLabels, float yMax, float yMin, boolean isShowLegend) {


    mChart.setDrawGridBackground(false);mChart.setDrawBorders(false);mChart.setScaleEnabled(false);mChart.setDragEnabled(true);mChart.setNoDataText("");// 不显示描述数据 mChart.getDescription().setEnabled(false);mChart.getAxisRight().setEnabled(false);


    Legend legend = mChart.getLegend();// 是否显示图例 if (isShowLegend) {legend.setEnabled(true);legend.setTextColor(Color.WHITE);legend.setForm(Legend.LegendForm.CIRCLE);legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);legend.setYEntrySpace(20f);//图例的大小 legend.setFormSize(7f);// 图例描述文字大小 legend.setTextSize(10);legend.setXEntrySpace(20f);


    } else {legend.setEnabled(false);}


    XAxis xAxis = mChart.getXAxis();


    // 是否显示 x 轴线 xAxis.setDrawAxisLine(true);// 设置 x 轴线的颜色 xAxis.setAxisLineColor(Color.parseColor("#4cffffff"));// 是否绘制 x 方向网格线 xAxis.setDrawGridLines(false);//x 方向网格线的颜色 xAxis.setGridColor(Color.parseColor("#30FFFFFF"));


    // 设置 x 轴数据的位置 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);// 设置 x 轴文字的大小 xAxis.setTextSize(12);


    // 设置 x 轴数据偏移量 xAxis.setYOffset(5);final List<String> labels = mLabels;// 显示 x 轴标签 IAxisValueFormatter formatter = new IAxisValueFormatter() {


    @Overridepublic String getFormattedValue(float value, AxisBase axis) {int index = (int) value;if (index < 0 || index >= labels.size()) {return "";}return labels.get(index);// return labels.get(Math.min(Math.max((int) value, 0), labels.size() - 1));}


    };// 引用标签 xAxis.setValueFormatter(formatter);// 设置 x 轴文字颜色 xAxis.setTextColor(mChart.getResources().getColor(R.color.char_text_color));// 设置 x 轴每最小刻度 intervalxAxis.setGranularity(1f);


    YAxis yAxis = mChart.getAxisLeft();//设置 x 轴的最大值 yAxis.setAxisMaximum(yMax);// 设置 y 轴的最大值 yAxis.setAxisMinimum(yMin);// 不显示 y 轴 yAxis.setDrawAxisLine(false);// 设置 y 轴数据的位置 yAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);// 不从 y 轴发出横向直线 yAxis.setDrawGridLines(false);// 是否显示 y 轴坐标线 yAxis.setDrawZeroLine(true);// 设置 y 轴的文字颜色 yAxis.setTextColor(mChart.getResources().getColor(R.color.char_text_color));// 设置 y 轴文字的大小 yAxis.setTextSize(12);// 设置 y 轴数据偏移量//yAxis.setXOffset(30);// yAxis.setYOffset(-3);yAxis.setXOffset(15);// yAxis.setGranularity(yGranularity);yAxis.setLabelCount(5, false);//yAxis.setGranularity(5);//interval


    Matrix matrix = new Matrix();// 根据数据量来确定 x 轴缩放大倍 if (mLabels.size() <= 10) {matrix.postScale(1.0f, 1.0f);} else if (mLabels.size() <= 15) {matrix.postScale(1.5f, 1.0f);} else if (mLabels.size() <= 20) {matrix.postScale(2.0f, 1.0f);} else {matrix.postScale(3.0f, 1.0f);}


    // 在图表动画显示之前进行缩放 mChart.getViewPortHandler().refresh(matrix, mChart, false);// x 轴执行动画 mChart.animateX(500);


    }


    /**


    • 初始化数据

    • @param chart

    • @param lineDatas*/public static void initData(CombinedChart chart, LineData... lineDatas) {CombinedData combinedData = new CombinedData();for (LineData lineData : lineDatas) {combinedData.setData(lineData);}

    用户头像

    Android架构

    关注

    还未添加个人签名 2021.10.31 加入

    还未添加个人简介

    评论

    发布
    暂无评论
    MPAndroidChart绘制曲线图、柱状图总结