前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android——MPAndroidChart折线图/柱状图/饼形图的使用

Android——MPAndroidChart折线图/柱状图/饼形图的使用

作者头像
Winter_world
发布2020-09-25 10:10:35
3.2K0
发布2020-09-25 10:10:35
举报

【背景】:项目中需要使用到图表,于是找了目前非常热门的开源图表,折线图/柱状图/饼图等应有尽有,各种效果实现都很给力,附上github链接,有原DEMO,github是最好的老师,看DEMO例程源码,相比在网上泛泛的查资料要高效的多。https://github.com/PhilJay/MPAndroidChart

【使用方法】

这里会介绍如何初始化、如何自定义XY坐标轴、如何点击折线图中的数据显示数据标签、如何设置数据。这里仅给出折线图的使用方法,柱状图和饼形图的使用基本类似,在官方GEMO中即可找到,不再赘述了,文末会给出柱状图和饼形图的使用效果展示。

一、折现图的初始化

      入参为折线图的对象和自定义的XY坐标轴数据,初始化的相关属性注释中都已给出,这里主要单独说明下如何自定义XY坐标轴、如何点击折线图中的数据显示数据标签。

【定义X坐标轴】

ValueFormatter xAxisFormatter = new LineBarXAxisFormatter(myAxis); //自定义X坐标轴
xAxis.setValueFormatter(xAxisFormatter);

【定义Y坐标轴】

ValueFormatter yAxisFormatter = new LineBarYAxisFormatter("Min"); //自定义Y坐标轴
yAxis.setValueFormatter(yAxisFormatter);

其中LineBarYAxisFormatter 是单独定义的XY坐标轴格式,我们需要单独封装一个类,继承自ValueFormatter,对于X轴,该类的构造函数,创建对象时即输入坐标轴的数据,通过重写方法getFormattedValue方法获取X轴自定义的数据,LineBarXAxisFormatter类定义如下:

/**
 * 自定义折线点上的X坐标轴
 */
public class LineBarXAxisFormatter extends ValueFormatter {

    private final List<AxisBean> mLabels;

    /**
     * 构造方法,把数据源传进来
     * @param labels
     */
    public LineBarXAxisFormatter(List<AxisBean> labels) {
        mLabels = labels;
    }

    @Override
    public String getFormattedValue(float value) {
    
        int v = (int) value;
        if(mLabels.size()==1){
            return mLabels.get(0).getTime(); //避免当只有一个点时,入参value会出现 -1 0 1 BUG,异常;
        }else if (v < mLabels.size() && v >= 0) {
            return mLabels.get(v).getTime();
        }else{
            return null;
        }

    }
}

对于Y轴,该类的构造函数,创建对象时即输入坐标轴的单位,通过重写方法getFormattedValue方法获取Y轴自定义的数据+单位,如原始数据是10,返回的是10Min,即Y坐标轴显示的是10Min。

//自定义折线点上的Y坐标轴
public class LineBarYAxisFormatter extends ValueFormatter {
    private final DecimalFormat mFormat;
    private String suffix;
    public LineBarYAxisFormatter(String suffix) {
        mFormat = new DecimalFormat("0");
        this.suffix = suffix;
    }
    @Override
    public String getFormattedValue(float value) { 

        return mFormat.format(value) + suffix;
    }
}

【点击折线图中的数据显示数据标签】

LineBarMarkerView mv = new LineBarMarkerView(this, xAxisFormatter);
mv.setChartView(chart); // For bounds control
chart.setMarker(mv);        //设置 marker ,点击后显示的功能 ,布局可以自定义

这里需要自定义LineBarMarkerView类,继承自MarkerView,内部重写refreshContent方法,当点击折线图的值时,就会出现标签,显示想要的数值,具体形式可以自定义,标签显示框布局也可以自定义

//自定义折现点的 值 被点击时,出现的显示框
public class LineBarMarkerView extends MarkerView {
    private final TextView tvContent;
    private final ValueFormatter xAxisValueFormatter;
    private final DecimalFormat format;
    public LineBarMarkerView(Context context, ValueFormatter xAxisValueFormatter) {
        super(context, R.layout.custom_marker_view);
        this.xAxisValueFormatter = xAxisValueFormatter;
        tvContent = findViewById(R.id.tvContent);  //自定义标签框
        format = new DecimalFormat("0");
    }
    // runs every time the MarkerView is redrawn, can be used to update the
    // content (user-interface)
    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        //根据坐标轴数据内容,刷新marker标签显示内容
        String x = xAxisValueFormatter.getFormattedValue(e.getX());
        String y = Float.toString(e.getY());
        tvContent.setText(String.format("x= %s, y= %s", x, y));
        super.refreshContent(e, highlight);
    }
    @Override
    public MPPointF getOffset() {
        return new MPPointF(-(getWidth() / 2), -getHeight());
    }
}
【折线图初始化】
/**初始化折线图
     *
     * @param chart 图表对象
     * @param myAxis XY轴数据
     */
    private void InitLineChart(LineChart chart,ArrayList<AxisBean> myAxis) {

        //设置图表属性
        chart.setLogEnabled(false);//打印日志
        chart.getDescription().setEnabled(false);//取消描述文字
        chart.setNoDataText("没有数据");//没有数据时显示的文字
        chart.setNoDataTextColor(Color.WHITE);//没有数据时显示文字的颜色
        chart.setDrawGridBackground(false);//chart 绘图区后面的背景矩形将绘制
        chart.setDrawBorders(false);//是否禁止绘制图表边框的线
//        chart.setBorderColor(Color.WHITE); //设置 chart 边框线的颜色。
//        chart.setBorderWidth(3f); //设置 chart 边界线的宽度,单位 dp。
        chart.setTouchEnabled(true);     //能否点击
        chart.setDragEnabled(true);   //能否拖拽
        chart.setScaleEnabled(true);  //能否缩放
        chart.setPinchZoom(true);  force pinch zoom along both axis
        chart.animateX(100);//绘制动画 从左到右
        chart.setDoubleTapToZoomEnabled(true);//设置是否可以通过双击屏幕放大图表。默认是true
        chart.setHighlightPerDragEnabled(true);//能否拖拽高亮线(数据点与坐标的提示线),默认是true
        chart.setDragDecelerationEnabled(true);//拖拽滚动时,手放开是否会持续滚动,默认是true(false是拖到哪是哪,true拖拽之后还会有缓冲)

        //设置X坐标轴属性
        XAxis xAxis = chart.getXAxis();       //获取x轴线
        xAxis.enableGridDashedLine(10f, 10f, 0f);
        xAxis.setDrawAxisLine(true);//是否绘制轴线
        xAxis.setDrawGridLines(false);//设置x轴上每个点对应的线
        xAxis.setDrawLabels(true);//绘制标签  指x轴上的对应数值
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置x轴的显示位置
        xAxis.setGranularity(1); // 让x轴上自定义的值和折线上相对应

//        xAxis.setTextSize(12f);//设置文字大小
//        xAxis.setTextColor(Color.WHITE);
        //设置0-24h时间点
//        xAxis.setAxisMinimum(0);//设置x轴的最小值
//        xAxis.setAxisMaximum(24);//设置最大值
//        xAxis.setLabelCount(12);  //设置X轴的显示个数
        xAxis.setAvoidFirstLastClipping(true);//图表将避免第一个和最后一个标签条目被减掉在图表或屏幕的边缘
//        xAxis.setAxisLineColor(Color.WHITE);//设置x轴线颜色
//        xAxis.setAxisLineWidth(0.5f);//设置x轴线宽度
        ValueFormatter xAxisFormatter = new LineBarXAxisFormatter(myAxis); //自定义X坐标轴
        xAxis.setValueFormatter(xAxisFormatter);

        //设置Y坐标轴属性
        YAxis yAxis = chart.getAxisLeft();
        YAxis axisRight = chart.getAxisRight();
        yAxis.enableGridDashedLine(10f, 10f, 0f);  //设置Y轴网格线条的虚线,参1 实线长度,参2 虚线长度 ,参3 周期
//        yAxis.setGranularity(1); // 网格线条间距
        axisRight.setEnabled(false);   //设置是否使用 Y轴右边的
        yAxis.setEnabled(true);     //设置是否使用 Y轴左边的
//        yAxis.setGridColor(Color.parseColor("#7189a9"));  //网格线条的颜色
        yAxis.setDrawLabels(true);        //是否显示Y轴刻度
        yAxis.setAxisMinimum(0f); //设置Y轴数值 从零开始
//        yAxis.setStartAtZero(true);        //设置Y轴数值 从零开始
//        yAxis.setDrawGridLines(true);      //是否使用 Y轴网格线条
//        yAxis.setTextSize(12f);            //设置Y轴刻度字体
//        yAxis.setTextColor(Color.WHITE);   //设置字体颜色
//        yAxis.setAxisLineColor(Color.WHITE); //设置Y轴颜色
//        yAxis.setAxisLineWidth(0.5f);
//        yAxis.setDrawAxisLine(true);//是否绘制轴线
//        yAxis.setMinWidth(0f);
//        yAxis.setMaxWidth(200f);
//        yAxis.setDrawGridLines(false);//设置x轴上每个点对应的线
        ValueFormatter yAxisFormatter = new LineBarYAxisFormatter("Min"); //自定义Y坐标轴
        yAxis.setValueFormatter(yAxisFormatter);

        //设置点击折现上的value时出现标签
        LineBarMarkerView mv = new LineBarMarkerView(this, xAxisFormatter);
        mv.setChartView(chart); // For bounds control
        chart.setMarker(mv);        //设置 marker ,点击后显示的功能 ,布局可以自定义

//        Legend l = chart.getLegend();//图例
//        l.setEnabled(true);   //是否使用 图例
    }

二、折现图设置数据

输入参数为折线图对象和自定义的XY坐标轴,因折线图设置数据需要有固定的格式,MyAndroidChart使用的Entry键值对,xy值都为浮点型数据,所以需要将我们的自定义XY坐标轴数据转化为对应的键值对形式,Entry的x key按序号从0开始递增,y value值即是我们要显示的y轴自定义的数值,实际上在我们上一节定义的X轴类中,可以看到获取X轴数据就是通过0开始的序号对应获取我们自定义的值的。代码如下,其中有一个设置X轴数据显示方向的比较有用,可以避免数据多时重叠不美观,单独提一下:

//设置X轴坐标斜着显示,避免X轴点较多时重合             chart.getXAxis().setLabelRotationAngle(-45);

/**设置折线图数据
     *
     * @param chart 图表对象
     * @param myAxis XY坐标轴数据
     */
    private void setLineChartData(LineChart chart,ArrayList<AxisBean> myAxis) {

        if (myAxis.size() == 0) return;
        //填充LineDataSet 所需要的键值对格式
        ArrayList<Entry> mValues =new ArrayList<>();
        for (int i = 0; i < myAxis.size(); i++) {
            float val = myAxis.get(i).getValue();
            mValues.add(new Entry(i,val));
        }

        LineDataSet set1;
        //判断图表中原来是否有数据
        if (chart.getData() != null &&  chart.getData().getDataSetCount() > 0) {
            //获取数据1
            set1 = (LineDataSet) chart.getData().getDataSetByIndex(0);
            set1.setValues(mValues);
            //刷新数据
            chart.getData().notifyDataChanged();
            chart.notifyDataSetChanged();
        } else {
            //设置数据1  参数1:数据源 参数2:图例名称
            set1 = new LineDataSet(mValues, "Time-test");
            set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
            set1.setColor(Color.WHITE);
            set1.setCircleColor(Color.parseColor("#AAFFFFFF"));

            set1.setHighLightColor(Color.WHITE);//设置点击交点后显示交高亮线的颜色
            set1.setHighlightEnabled(true);//是否使用点击高亮线
            set1.setDrawCircles(true);
            set1.setValueTextColor(Color.WHITE);
            set1.setLineWidth(1f);//设置线宽
            set1.setCircleRadius(2f);//设置焦点圆心的大小
            set1.setHighlightLineWidth(0.5f);//设置点击交点后显示高亮线宽
            set1.enableDashedHighlightLine(10f, 5f, 0f);//点击后的高亮线的显示样式
            set1.setValueTextSize(12f);//设置显示值的文字大小
            set1.setDrawFilled(true);//设置使用 范围背景填充
            set1.setDrawValues(false);
            set1.setFillColor(Color.GREEN);

            ArrayList<ILineDataSet> dataSets = new ArrayList<>();
            dataSets.add(set1); // add the datasets
            //创建LineData对象 属于LineChart折线图的数据集合
            LineData data = new LineData(dataSets);
            // 添加到图表中
            chart.setData(data);
            //绘制图表
            chart.invalidate();
            //设置X轴坐标斜着显示,避免X轴点较多时重合
            chart.getXAxis().setLabelRotationAngle(-45);

        }
    }

三、效果展示

若文章对您有些许帮助,还请您点赞鼓励:),欢迎留言讨论,多谢! 

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-01-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档