Android图表MPandroidChart之曲线图绘制教程

前言:

本文介绍MpAndroidChart对曲线图绘制的用法,包括引用库的配置及语法使用,帮你从零做一款曲线图或者折线图。

一.MPandroidChart的简介和配置:

1.简介

MPandroidChart是一款稳定实用的绘图库,可以绘制折线图、曲线图、柱状图、饼图、雷达图等,功能十分强大。对比了HelloChartWilliamChart图标库以后,觉得后两款的动画效果不错,但是功能和稳定性没有MPandroidChart好,所以最终还是选择用这款图表库。附上上述图表库的GitHub 地址,大家根据自己喜好,可以自由选择使用。

2.图表效果动画展示:

(动态图片加载较慢,多刷新几次,耐心等待……)
Android图表MPandroidChart之曲线图绘制教程_第1张图片

3.各类Android图表库下载地址:

图表库 GitHub地址
MPandroidChart 点击进入
HelloChart 点击进入
WilliamChart 点击进入

4.本文所用到的jar包下载:

本文所用MPandroidChart的jar包,版本号:v2.16: 点击下载

注:Android studio用户可直接去GitHub添加依赖即可,截止2017年8月,最新版为3.0.2。

二.MPandroidChart的使用:

1.添加项目依赖

在项目中,将jar包拷贝到项目的lib文件夹下,右键单击,选择Build Path..,在选择Add to Build Path

2.在布局中引用:

LineChart可以当做折线图或曲线图使用,如果用饼图,改为com.github.mikephil.charting.charts.PieChart即可。

 <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/lineChart"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.8" />

3.在Activity 代码中声明绑定控件:

private LineChart lineChart;// 声明图表控件

lineChart = (LineChart) findViewById(R.id.lineChart);//绑定控件

4.MPandroidChart关键类名解释:

  • LineChart 表示整个图表类
  • XAxis 表示X轴类
  • YAxis 表示Y轴类
  • LineDataSet 表示一条曲线数据集(曲线类)
  • LineData 表示LineChart的数据源类
  • Legend 曲线图例类
  • MarkerView 点击坐标点弹出提示框(CustomMarkerView为自定义的提示框)
  • Entry 表示Y轴的数据值对象,如new Entry(123f, i),其中123f是该坐标点的Y轴value值,i是一个指针,代表给第i个点赋值123f

5.绘制一条曲线的实现步骤:

①.获取坐标数据源,X轴数据源List xDataList , Y轴数据源List yDataList

②.配置ArrayList lineDataSets,设置一条曲线数据源。

③.设置LineData ,将LineDataSet添加到LineData

④.设置图表数据lineChart.setData(LineData)

⑤.其他设置:
- 设置图例Legend (如需要可设置,亦可省略)。
- 设置坐标点弹出框CustomMarkerView (如需要可设置,亦可省略)。

6.封装曲线图初始化配置工具类:

①.封装工具类原因:
为了代码的复用,不在每个用到图表的类中,都引用一堆图表的设置属性代码,故此将图表的属性,封装在ChartUtil图表工具类中,随处调用即可。大家可将下面的类整个复制到自己的项目中,即可使用。

②坐标点击弹出框: 在该工具类中,有个内部类CustomMarkerView,此类继承MarkerView类,实现的是一个自定义的点击坐标点弹出提示框(看上图动画展示),用来显示当前坐标点的y轴数据。

③曲线的坐标数据隐藏: 曲线的坐标数据,在工具类中设置为隐藏了,因为在手机屏幕上显示多个点的时候,数字会重叠,用户体验比较差,通过点击弹出提示框的方式,可以有好的展示数据,增强交互体验。

④重要的方法使用介绍:

设置曲线图或折线图显示:true为曲线图,false为折线图

lineDataSet.setDrawCubic(true);

而在MPandroidChart最新版V3.0中,要使用这种方式设置曲线图:

lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);

设置为面图(显示曲线和X轴围成的区域阴影面):true 为显示,false 只显示一条曲线,曲线和X轴围成的阴影不显示。(上图动画中为显示阴影效果)。

lineDataSet.setDrawFilled(true);

图例设置:
每条线都有一个图例,说明这是条什么曲线,图例的颜色和样式(方块、圆形、线段),都可以设置:

Legend mLegend = lineChart.getLegend();
mLegend.setEnabled(true);
// 图例样式 (CIRCLE圆形;LINE线性;SQUARE是方块)
mLegend.setForm(LegendForm.SQUARE);

显示坐标点的值:true 为显示,false 为不显示。

当数值长度,图表会自动四舍五入,保留一位小数。

lineDataSet.setDrawValues(false);

绘制动画设置:

// 执行的动画,x轴(动画持续时间2500毫秒)
lineChart.animateX(2500)

注: 其他设置,在下面工具类代码里都给出示例,每行都给出了注释,大家可以自行设置。

⑤该工具类用到颜色bg_blue,需要在项目 res/value/color.xml中增加颜色,颜色值可以设置为你需要的颜色.

<color name="bg_blue">#58ACED

⑥点击弹出框的使用:

弹出框的布局需要自定义,将下面代码保存在chart_marker_view.xml中,放入代码路径res/layout下,并为弹出框background属性配上一个底图,名为img_message,或者设置一个深色的颜色均可。


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:background="@drawable/img_message">

    <TextView
        android:id="@+id/txt_tips"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginBottom="5dp"
        android:text="123.4567899"
        android:textSize="10dp"
        android:textColor="@android:color/white"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:ellipsize="marquee"
        android:singleLine="true"
        />

RelativeLayout>

⑦.在工具类代码中,通过下面方式使用“提示弹出框”。

//声明点击提示框
CustomMarkerView mv = new CustomMarkerView(context, R.layout.chart_marker_view,unitName);
//设置曲线的点击提示框
lineChart.setMarkerView(mv);

⑧.完整的曲线图工具类代码,可复制项目中直接使用:

package com.today.util;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.widget.TextView;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.Legend.LegendForm;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.highlight.Highlight;
import com.today.main.R;

public class ChartUtil {
    /**
     * 显示图表
     * @param context
     *            上下文
     * @param lineChart
     *            图表对象
     * @param xDataList
     *            X轴数据
     * @param yDataList
     *            Y轴数据
     * @param title
     *            图表标题(如:XXX趋势图)
     * @param curveLable
     *            曲线图例名称(如:--用电量/时间)
     * @param unitName
     *            坐标点击弹出提示框中数字单位(如:KWH)
     */
    public static void showChart(Context context, LineChart lineChart, List xDataList,
        List yDataList, String title, String curveLable,String unitName) {
        // 设置数据
        lineChart.setData(setLineData(context, xDataList, yDataList, curveLable));
        CustomMarkerView mv = new CustomMarkerView(context, R.layout.chart_marker_view,unitName);
        // set the marker to the chart
        lineChart.setMarkerView(mv);
        // 是否在折线图上添加边框
        lineChart.setDrawBorders(true);
        // 曲线描述 -标题
        lineChart.setDescription(title);
        // 标题字体大小
        lineChart.setDescriptionTextSize(16f);
        // 标题字体颜色
        lineChart.setDescriptionColor(context.getApplicationContext().getResources()
            .getColor(R.color.txt_black));
        // 如果没有数据的时候,会显示这个,类似文本框的placeholder
        lineChart.setNoDataTextDescription("暂无数据");
        // 是否显示表格颜色
        lineChart.setDrawGridBackground(false);
        // 禁止绘制图表边框的线
        lineChart.setDrawBorders(false);
        // 表格的的颜色,在这里是是给颜色设置一个透明度
        // lineChart.setGridBackgroundColor(Color.WHITE & 0x70FFFFFF);
        // 设置是否启动触摸响应
        lineChart.setTouchEnabled(true);
        // 是否可以拖拽
        lineChart.setDragEnabled(true);
        // 是否可以缩放
        lineChart.setScaleEnabled(true);
        // 如果禁用,可以在x和y轴上分别进行缩放
        lineChart.setPinchZoom(false);
        // lineChart.setMarkerView(mv);
        // 设置背景色
        // lineChart.setBackgroundColor(getResources().getColor(R.color.bg_white));
        // 图例对象
        Legend mLegend = lineChart.getLegend();
        // mLegend.setPosition(LegendPosition.BELOW_CHART_CENTER);
        // 图例样式 (CIRCLE圆形;LINE线性;SQUARE是方块)
        mLegend.setForm(LegendForm.SQUARE);
        // 图例大小
        mLegend.setFormSize(8f);
        // 图例上的字体颜色
        mLegend.setTextColor(context.getApplicationContext().getResources().getColor(R.color.bg_blue));
        mLegend.setTextSize(12f);
        // 图例字体
        // mLegend.setTypeface(mTf);
        // 图例的显示和隐藏
        mLegend.setEnabled(true);
        // 隐藏右侧Y轴(只在左侧的Y轴显示刻度)
        lineChart.getAxisRight().setEnabled(false);

        XAxis xAxis = lineChart.getXAxis();
        // 显示X轴上的刻度值
        xAxis.setDrawLabels(true);
        // 设置X轴的数据显示在报表的下方
        xAxis.setPosition(XAxisPosition.BOTTOM);
        // 轴线
        // xAxis.setDrawAxisLine(false);
        // 设置不从X轴发出纵向直线
        xAxis.setDrawGridLines(false);
        // 执行的动画,x轴(动画持续时间)
        lineChart.animateX(2500);
        // lineChart.notifyDataSetChanged();
    }

    /**
     * 曲线赋值与设置
     * 
     * @param context
     *            上下文
     * @param xDataList
     *            x轴数据
     * @param yDataList
     *            y轴数据
     * @return LineData
     */
    private static LineData setLineData(Context context, List xDataList, List yDataList,
        String curveLable) {
        // LineDataSet表示一条曲线数据对象
        ArrayList lineDataSets = new ArrayList();
        // y轴的数据集合
        LineDataSet lineDataSet = new LineDataSet(yDataList, curveLable);
        // mLineDataSet.setFillAlpha(110);
        // mLineDataSet.setFillColor(Color.RED);
        // 用y轴的集合来设置参数
        // 不显示坐标点的数据
        lineDataSet.setDrawValues(false);
        // 显示坐标点的小圆点
        lineDataSet.setDrawCircles(true);
        // 定位线
        lineDataSet.setHighlightEnabled(true);
        // 线宽
        lineDataSet.setLineWidth(2.0f);
        // 显示的圆形大小
        lineDataSet.setCircleSize(4f);
        // 显示颜色
        lineDataSet.setColor(context.getApplicationContext().getResources().getColor(R.color.bg_blue));
        // 圆形的颜色
        lineDataSet.setCircleColor(context.getApplicationContext().getResources().getColor(R.color.bg_blue));
        // 高亮的线的颜色
        lineDataSet.setHighLightColor(context.getApplicationContext().getResources()
            .getColor(R.color.text_yellow));
        // 设置坐标点的颜色
        lineDataSet.setFillColor(context.getApplicationContext().getResources().getColor(R.color.bg_blue));
        // 设置坐标点为空心环状
        lineDataSet.setDrawCircleHole(false);
        // lineDataSet.setValueTextSize(9f);
        lineDataSet.setFillAlpha(65);
        // 设置显示曲线和X轴围成的区域阴影
        lineDataSet.setDrawFilled(true);
        // 坐标轴在左侧
        lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        // 设置每条曲线图例标签名
        // lineDataSet.setLabel("标签");
        lineDataSet.setValueTextSize(14f);
        // 曲线弧度(区间0.05f-1f,默认0.2f)
        lineDataSet.setCubicIntensity(0.2f);
        // 设置为曲线显示,false为折线
        lineDataSet.setDrawCubic(true);
        lineDataSets.add(lineDataSet);
        // y轴的数据
        LineData lineData = new LineData(xDataList, lineDataSets);
        return lineData;
    }

}

/**
 * 自定义图表的MarkerView(点击坐标点,弹出提示框)
 */
class CustomMarkerView extends MarkerView {

    private TextView tvContent;
    private String unitName;
    /**
     * 
     * @param context
     *            上下文
     * @param layoutResource
     *            资源文件
     * @param unitName
     *            Y轴数值计量单位名称
     */
    public CustomMarkerView(Context context, int layoutResource,final String unitName) {
        super(context, layoutResource);
        // 显示布局中的文本框
        tvContent = (TextView) findViewById(R.id.txt_tips);
        this.unitName = unitName;
    }

    // 每次markerview回调重绘,可以用来更新内容
    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        // 设置Y周数据源对象Entry的value值为显示的文本内容
        tvContent.setText("" + e.getVal()+unitName);
    }

    @Override
    public int getXOffset(float xpos) {
        // 水平居中
        return -(getWidth() / 2);
    }

    @Override
    public int getYOffset(float ypos) {
        // 提示框在坐标点上方显示
        return -getHeight();
    }
}

在color.xml中,引入以下颜色值:


<resources>
    <color name="txt_black_light">#333333color>
    <color name="bg_white">#FFFFFFcolor>
    <color name="bg_blue">#58ACEDcolor>
    <color name="text_yellow">#FFC800color>
resources>

7.引用工具类,绘制一条曲线:

在需要引用图表的类中,只需给X和Y轴数据源赋值,然后调用ChartUtil.showChart()方法,就可完成一条曲线的绘制了,非常方便快捷。示例如下:

List xDataList = new ArrayList<>();// x轴数据源
List yDataList = new ArrayList<>();// y轴数据数据源
//给上面的X、Y轴数据源做假数据测试
for (int i = 0; i < 24; i++) {
    // x轴显示的数据
    xDataList.add(i + ":00");
    //y轴生成float类型的随机数
    float value = (float) (Math.random() * range) + 3;
    yDataList.add(new Entry(value, i));
    }

//显示图表,参数( 上下文,图表对象, X轴数据,Y轴数据,图表标题,曲线图例名称,坐标点击弹出提示框中数字单位)   
ChartUtil.showChart(this, lineChart, xDataList, yDataList, "供热趋势图", "供热量/时间","kw/h");

三.总结:

通过本文,可以快速的完成绘制一条曲线图,步骤总结:

  1. 引入MPandroidChart.jar包。
  2. 引入LineChart布局,绑定控件。
  3. 配置X轴、Y轴的数据源xDataListyDataList
  4. 引入ChartUtil类,调用showChart()方法。

你可能感兴趣的:(Android)