失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)

Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)

时间:2024-07-18 07:51:53

相关推荐

Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)

目录

前言

本文涉及文章

其他相关文章

1.数据准备

1.1 数据来源

2.曲线展示

2.1 MPAndroidChart获取

2.2 数据对象获取

2.3 数据展示

3.曲线完善

3.1 图表背景、边框、网格线修改

3.2 X Y轴值的自定义

3.3 线条的渐变背景、值、点的修改

3.4 MarkerView的实现

3.5 X轴的位置调整、以及X Y 轴的刻度显示

4. 多条曲线

4.1 LineChart创建多条曲线

4.2 MarkerView显示所以曲线的X Y 轴值

5. 重置某条曲线

6. 最终效果图

前言

发现最新的MPAndroidChart和以前版本的使用有一些差距,就写下了现在新版的使用方法

注:-06-01更新,当前MPAndroidChart版本:3.0.3

本文涉及文章

Android图表控件MPAndroidChart的简单介绍(MPAndroidChart3.0)

Android图表控件MPAndroidChart——LineChart实现 X、Y轴以及原点线的直尺刻度样式

其他相关文章

Android图表控件MPAndroidChart——曲线图LineChart的使用(多条曲线)

Android图表控件MPAndroidChart——曲线图LineChart(多条曲线)动态添加数据

Android图表控件MPAndroidChart——柱状图BarChart的使用(多条柱状图)

Android图表控件MPAndroidChart——曲线图+柱状图 CombinedChart的使用

本文将要实现的图表效果,个人财富收益图。

1.数据准备

1.1 数据来源

数据是抓包佣金宝的数据,将获取的数据存入.json文件。

json格式如下

Json 文件地址:

/897532167/ChartManager/blob/master/app/src/main/assets/line_chart.json

2.曲线展示

2.1 MPAndroidChart获取

Github 地址:/PhilJay/MPAndroidChart

依赖:

Project 的build.gradle文件中添加

allprojects {

repositories {

maven { url 'https://jitpack.io' }

}

}

然后在 module中的build,gradle 中添加

implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'

然而大多情况下,我们会根据自己的需求自定义MPAndroidChart库,则需要下载源码并将MPChartLib引入自己的项目中。

2.2 数据对象获取

在Android Studio app项目src同级目录下新建中新建assets文件夹,然后将步骤1.1得到的.json文件放入改文件夹中。

然后在获取.json文件中的json字符串并解析为对应的数据对象,可参考以下文章

相关文章:Android访问assets本地Json文件

在此就不详叙述了,只是列出图表展示所需要的类

/**

* 我的收益

*/

public class IncomeBean {

/**

* tradeDate : 0502

* value : 0.03676598

*/

private String tradeDate;

private double value;

}

/**

* 沪深创指数

*/

public class CompositeIndexBean {

/**

* rate : -0.00034196

* tradeDate : 0502

*/

private String rate;

private String tradeDate;

}

2.3 数据展示

2.3.1LineChart 图表初始化设置

LineChart曲线图表一会使用到如下属性

private LineChart lineChart;

private XAxis xAxis; //X轴

private YAxis leftYAxis;//左侧Y轴

private YAxis rightYaxis;//右侧Y轴

private Legend legend; //图例

private LimitLine limitLine; //限制线

// private MyMarkerView markerView; //标记视图 即点击xy轴交点时弹出展示信息的View 需自定义

然后进行相应的设置

/**

* 初始化图表

*/

private void initChart(LineChart lineChart) {

/***图表设置***/

//是否展示网格线

lineChart.setDrawGridBackground(false);

//是否显示边界

lineChart.setDrawBorders(true);

//是否可以拖动

lineChart.setDragEnabled(false);

//是否有触摸事件

lineChart.setTouchEnabled(true);

//设置XY轴动画效果

lineChart.animateY(2500);

lineChart.animateX(1500);

/***XY轴的设置***/

xAxis = lineChart.getXAxis();

leftYAxis = lineChart.getAxisLeft();

rightYaxis = lineChart.getAxisRight();

//X轴设置显示位置在底部

xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

xAxis.setAxisMinimum(0f);

xAxis.setGranularity(1f);

//保证Y轴从0开始,不然会上移一点

leftYAxis.setAxisMinimum(0f);

rightYaxis.setAxisMinimum(0f);

/***折线图例 标签 设置***/

legend = lineChart.getLegend();

//设置显示类型,LINE CIRCLE SQUARE EMPTY 等等 多种方式,查看LegendForm 即可

legend.setForm(Legend.LegendForm.LINE);

legend.setTextSize(12f);

//显示位置 左下方

legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);

legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);

legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);

//是否绘制在图表里面

legend.setDrawInside(false);

}

2.3.2 LineDataSet 曲线初始化设置

/**

* 曲线初始化设置 一个LineDataSet 代表一条曲线

*

* @param lineDataSet 线条

* @param color 线条颜色

* @param mode

*/

private void initLineDataSet(LineDataSet lineDataSet, int color, LineDataSet.Mode mode) {

lineDataSet.setColor(color);

lineDataSet.setCircleColor(color);

lineDataSet.setLineWidth(1f);

lineDataSet.setCircleRadius(3f);

//设置曲线值的圆点是实心还是空心

lineDataSet.setDrawCircleHole(false);

lineDataSet.setValueTextSize(10f);

//设置折线图填充

lineDataSet.setDrawFilled(true);

lineDataSet.setFormLineWidth(1f);

lineDataSet.setFormSize(15.f);

if (mode == null) {

//设置曲线展示为圆滑曲线(如果不设置则默认折线)

lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);

} else {

lineDataSet.setMode(mode);

}

}

2.3.3曲线展示

/**

* 展示曲线

*

* @param dataList 数据集合

* @param name 曲线名称

* @param color 曲线颜色

*/

public void showLineChart(List<IncomeBean> dataList, String name, int color) {

List<Entry> entries = new ArrayList<>();

for (int i = 0; i < dataList.size(); i++) {

IncomeBean data = dataList.get(i);

/**

* 在此可查看 Entry构造方法,可发现 可传入数值 Entry(float x, float y)

* 也可传入Drawable, Entry(float x, float y, Drawable icon) 可在XY轴交点 设置Drawable图像展示

*/

Entry entry = new Entry(i, (float) data.getValue());

entries.add(entry);

}

// 每一个LineDataSet代表一条线

LineDataSet lineDataSet = new LineDataSet(entries, name);

initLineDataSet(lineDataSet, color, LineDataSet.Mode.LINEAR);

LineData lineData = new LineData(lineDataSet);

lineChart.setData(lineData);

}

然后在Activity中调用

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_line_chart);

lineChart = findViewById(R.id.lineChart);

initChart(lineChart);

LineChartBean lineChartBean = LocalJsonAnalyzeUtil.JsonToObject(this,

"chart.json", LineChartBean.class);

List<IncomeBean> list = lineChartBean.getGRID0().getResult().getClientAccumulativeRate();

showLineChart(list, "我的收益", Color.CYAN);

}

注意:不了解数据怎么来的可查看相关文章:Android访问assets本地Json文件或者本文相关代码

此时的图形效果

线性图是有了,但离需要达到的效果差了很多很多,所有需要一点点的完善。

3.曲线完善

首先总结哪里需要进行修改完善,然后一一进行修改,需要的修改的地方如下。

图表背景、边框、网格的修改

X Y轴值的自定义

线条的渐变背景、值、点 的修改

MarkerView的实现

X轴的位置、X Y 轴的刻度展示(需要修改源码、放最后来处理)

3.1 图表背景、边框、网格线修改

修改背景,去掉边框

lineChart.setBackgroundColor(Color.WHITE);

//是否显示边界

lineChart.setDrawBorders(false);

网格线修改

在2.3.1步的我们已经设置了禁止显示网格线

//是否展示网格线

lineChart.setDrawGridBackground(false);

但还是显示了网格线,而且不是我们想要的虚线 。其实那是 X Y轴自己的网格线,禁掉即可

xAxis.setDrawGridLines(false);

rightYaxis.setDrawGridLines(false);

leftYAxis.setDrawGridLines(true);

设置X Y轴网格线为虚线(实体线长度、间隔距离、偏移量:通常使用 0)

leftYAxis.enableGridDashedLine(10f, 10f, 0f);

目标效果图没有右侧Y轴,所以去掉右侧Y轴

rightYaxis.setEnabled(false);

现在的效果图

3.2 X Y轴值的自定义

目标图的效果是 X轴显示日期,Y轴显示百分比而且均分10份

数据获取到的时间为 0502 我们需要显示 05-02 所以需要进行日期转换

一个日期转换工具

public class DateUtil {

public static String formatDate(String str) {

SimpleDateFormat sf1 = new SimpleDateFormat("yyyyMMdd");

SimpleDateFormat sf2 = new SimpleDateFormat("MM-dd");

String formatStr = "";

try {

formatStr = sf2.format(sf1.parse(str));

} catch (ParseException e) {

e.printStackTrace();

}

return formatStr;

}

}

X轴值的定义

在showLineChart 方法中我们会传入X轴的值,所以自定义X轴的值可以 写在该方法内

xAxis.setValueFormatter(new IAxisValueFormatter() {

@Override

public String getFormattedValue(float value, AxisBase axis) {

String tradeDate = dataList.get((int) value % dataList.size()).getTradeDate();

return DateUtil.formatDate(tradeDate);

}

});

注:目标图的数据是5月2日到5月28日,而本文所使用的数据是5月2日至5月25日。且数据日期是不包含周末的

X轴的间隔的实现,数据一共有18条,目标图是按照3天一间隔(因为无周末数据的关系,日期上看可能不是那样)

设置X轴分割数量

xAxis.setLabelCount(6,false);

true代表强制均分,可能会导致数据显示不均匀

Y轴值的自定义

与X轴值得自定义类似,并按照目标图的分割要求一样 将Y轴分为 8份

leftYAxis.setValueFormatter(new IAxisValueFormatter() {

@Override

public String getFormattedValue(float value, AxisBase axis) {

return ((int) (value * 100)) + "%";

}

});

leftYAxis.setLabelCount(8);

然后此时的效果

3.3 线条的渐变背景、值、点的修改

线条渐变线

新建一个方法

/**

* 设置线条填充背景颜色

*

* @param drawable

*/

public void setChartFillDrawable(Drawable drawable) {

if (lineChart.getData() != null && lineChart.getData().getDataSetCount() > 0) {

LineDataSet lineDataSet = (LineDataSet) lineChart.getData().getDataSetByIndex(0);

//避免在 initLineDataSet()方法中 设置了 lineDataSet.setDrawFilled(false); 而无法实现效果

lineDataSet.setDrawFilled(true);

lineDataSet.setFillDrawable(drawable);

lineChart.invalidate();

}

}

然后drawable 文件中 创建渐变样式fade_blue.xml

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="/apk/res/android">

<gradient

android:angle="90"

android:endColor="#FF6FA9E1"

android:startColor="#00ff0000" />

</shape>

再调用该方法

showLineChart(list, "我的收益", getResources().getColor(R.color.blue));

Drawable drawable = getResources().getDrawable(R.drawable.fade_blue);

setChartFillDrawable(drawable);

线条点和值的更改

不显示点,在 initLineDataSet方法中添加

lineDataSet.setDrawCircles(false);

线条值的更改

目标图的效果是不显示 值,但有时候还是会要求显示值,而且还要求更高 线条X值的显示内容

所以在此介绍一下更改 曲线显示自定义X值的内容

lineDataSet.setValueFormatter(new IValueFormatter() {

@Override

public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {

DecimalFormat df = new DecimalFormat(".00");

return df.format(value * 100) + "%";

}

});

会发现只要是自定义 值的显示内容 都是Chart对应的部分.setValueFormatter()。

现在的效果(修改了宽高)

不显示值

lineDataSet.setDrawValues(false);

3.4 MarkerView的实现

要求是点击曲线的点,然后弹出一个View 显示当前的日期,以及我的收益

即 MarkView 显示X Y 轴的值

1.搭建MarkView的布局文件layout_markview

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="/apk/res/android"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@drawable/shape_square"

android:orientation="vertical">

<TextView

android:id="@+id/tv_date"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textColor="@android:color/white" />

<TextView

android:id="@+id/tv_value"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="5dp"

android:textColor="@android:color/white" />

</LinearLayout>

其中背景 shape_square.xml 是圆角透明灰背景

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="/apk/res/android">

<corners android:radius="5dp" />

<stroke

android:width="1px"

android:color="@color/transparent_gray" />

<solid android:color="@color/transparent_gray" />

<padding

android:bottom="5dp"

android:left="5dp"

android:right="5dp"

android:top="5dp" />

</shape>

2.自定义MarkerView

public class LineChartMarkView extends MarkerView {

private TextView tvDate;

private TextView tvValue;

private IAxisValueFormatter xAxisValueFormatter;

DecimalFormat df = new DecimalFormat(".00");

public LineChartMarkView(Context context, IAxisValueFormatter xAxisValueFormatter) {

super(context, R.layout.layout_markview);

this.xAxisValueFormatter = xAxisValueFormatter;

tvDate = findViewById(R.id.tv_date);

tvValue = findViewById(R.id.tv_value);

}

@SuppressLint("SetTextI18n")

@Override

public void refreshContent(Entry e, Highlight highlight) {

//展示自定义X轴值 后的X轴内容

tvDate.setText(xAxisValueFormatter.getFormattedValue(e.getX(), null));

tvValue.setText("我的收益:" + df.format(e.getY() * 100) + "%");

super.refreshContent(e, highlight);

}

@Override

public MPPointF getOffset() {

return new MPPointF(-(getWidth() / 2), -getHeight());

}

}

注:这种方式是显示自定义X轴值后的 x轴内容,只是靠e.getX()得到的float类型,无法满足我们的要求

3.设置MarkView

/**

* 设置 可以显示X Y 轴自定义值的 MarkerView

*/

public void setMarkerView() {

LineChartMarkView mv = new LineChartMarkView(this, xAxis.getValueFormatter());

mv.setChartView(lineChart);

lineChart.setMarker(mv);

lineChart.invalidate();

}

调用该方法即可

此时的效果

3.5 X轴的位置调整、以及X Y 轴的刻度显示

X Y 轴的刻度显示,以及位置调整可查看我的另一篇文章

相关文章:Android图表控件MPAndroidChart——LineChart实现 X、Y轴以及原点线的直尺刻度样式

发现图表的右下角还有一个描述标签 Descripition Lable 需要在LineChart初始化时设置一下

Description description = new Description();

// description.setText("需要展示的内容");

description.setEnabled(false);

lineChart.setDescription(description);

此时的效果

4. 多条曲线

当前只是实现了展示一条曲线,而目标图需要实现两条(多条曲线)

4.1 LineChart创建多条曲线

前面说过 一个LineDataSet就是一条曲线,需要两条曲线的时候 在创建一个LineDataSet 添加进去即可

/**

* 添加曲线

*/

private void addLine(List<CompositeIndexBean> dataList, String name, int color) {

List<Entry> entries = new ArrayList<>();

for (int i = 0; i < dataList.size(); i++) {

CompositeIndexBean data = dataList.get(i);

Entry entry = new Entry(i, (float) data.getRate());

entries.add(entry);

}

// 每一个LineDataSet代表一条线

LineDataSet lineDataSet = new LineDataSet(entries, name);

initLineDataSet(lineDataSet, color, LineDataSet.Mode.LINEAR);

lineChart.getLineData().addDataSet(lineDataSet);

lineChart.invalidate();

}

然后调用改方法即可,也可以在 showLineChart方法中 创建两条曲线。

showLineChart(list, "我的收益", getResources().getColor(R.color.blue));

List<CompositeIndexBean> indexBeanList = lineChartBean.getGRID0().getResult().getCompositeIndexShanghai();

addLine(indexBeanList, "上证指数", getResources().getColor(R.color.orange));

此时的效果

4.2 MarkerView显示所以曲线的X Y 轴值

现在两条曲线了,前面MarkerView只是显示的我的收益的数据。现在需要显示所有曲线的的值

也就是在MarkerView 的 refreshContent中需要获取到我们展示的数据。

两种方式可以实现:

一:通过MarkerView构造方法 传入我们所展示的数据的集合

二:通过MarkerView 获取到当前的LineChart,然后通过LineChart获取LineData,图表展示的数据 都在LineData中可以得到

采用方式二比较方便,代码如下:

public class LineChartMarkView extends MarkerView {

private TextView tvDate;

private TextView tvValue0;

private TextView tvValue1;

private IAxisValueFormatter xAxisValueFormatter;

DecimalFormat df = new DecimalFormat("0.00");

public LineChartMarkView(Context context, IAxisValueFormatter xAxisValueFormatter) {

super(context, R.layout.layout_markview);

this.xAxisValueFormatter = xAxisValueFormatter;

tvDate = (TextView) findViewById(R.id.tv_date);

tvValue0 = (TextView) findViewById(R.id.tv_value0);

tvValue1 = (TextView) findViewById(R.id.tv_value1);

}

@SuppressLint("SetTextI18n")

@Override

public void refreshContent(Entry e, Highlight highlight) {

Chart chart = getChartView();

if (chart instanceof LineChart) {

LineData lineData = ((LineChart) chart).getLineData();

//获取到图表中的所有曲线

List<ILineDataSet> dataSetList = lineData.getDataSets();

for (int i = 0; i < dataSetList.size(); i++) {

LineDataSet dataSet = (LineDataSet) dataSetList.get(i);

//获取到曲线的所有在Y轴的数据集合,根据当前X轴的位置 来获取对应的Y轴值

float y = dataSet.getValues().get((int) e.getX()).getY();

if (i == 0) {

tvValue0.setText(dataSet.getLabel() + ":" + df.format(y * 100) + "%");

}

if (i == 1) {

tvValue1.setText(dataSet.getLabel() + ":" + df.format(y * 100) + "%");

}

}

tvDate.setText(xAxisValueFormatter.getFormattedValue(e.getX(), null));

}

super.refreshContent(e, highlight);

}

@Override

public MPPointF getOffset() {

return new MPPointF(-(getWidth() / 2), -getHeight());

}

}

此时的图表

5. 重置某条曲线

经过前面的几步图表是基本完成了,就差底部的切换按钮以及曲线重置了。

布局代码在此就不展示了,详细代码请看文本 本文相关代码。在此列出重置曲线方法的代码

public void resetLine(int position, List<CompositeIndexBean> dataList, String name, int color) {

LineData lineData = lineChart.getData();

List<ILineDataSet> list = lineData.getDataSets();

if (list.size() <= position) {

return;

}

List<Entry> entries = new ArrayList<>();

for (int i = 0; i < dataList.size(); i++) {

CompositeIndexBean data = dataList.get(i);

Entry entry = new Entry(i, (float) data.getRate());

entries.add(entry);

}

LineDataSet lineDataSet = new LineDataSet(entries, name);

initLineDataSet(lineDataSet, color, LineDataSet.Mode.LINEAR);

lineData.getDataSets().set(position, lineDataSet);

lineChart.invalidate();

}

调用该方法,将第二条曲线设置为深证指数

shenzheng = lineChartBean.getGRID0().getResult().getCompositeIndexShenzhen();

resetLine(1, shenzheng, "深证指数", getResources().getColor(R.color.orange));

设置不显示曲线名称(图例)Legend

legend.setEnabled(false);

6. 最终效果图

本文代码:/897532167/ChartManager

绘制刻度线:Android图表控件MPAndroidChart——LineChart实现 X、Y轴以及原点线的直尺刻度样式

---------------------

原文:/ww897532167/article/details/74129478

如果觉得《Android图表控件MPAndroidChart——曲线图LineChart的使用(财富收益图)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。