Android统计图表MPAndroidChart:为多条统计折线动态更新数据,以高温低温曲线为例【7】

简介: Android统计图表MPAndroidChart:为多条统计折线动态更新数据,以高温低温曲线为例【7】本文在附录文章6的基础上,为Android统计图表MPAndroidChart的同一个LineChart中同时增加两条统计折线,动态的为这两条折线同时增加数据并更新结果。


Android统计图表MPAndroidChart:为多条统计折线动态更新数据,以高温低温曲线为例【7】

本文在附录文章6的基础上,为Android统计图表MPAndroidChart的同一个LineChart中同时增加两条统计折线,动态的为这两条折线同时增加数据并更新结果。典型的,以天气预报中的高温和低温线为例加以说明。
写布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="zhangphil.chart.MainActivity" >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="动态添加数据" />

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/chart"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>


Java代码:

package zhangphil.chart;

import java.text.DecimalFormat;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
import com.github.mikephil.charting.components.YAxis.AxisDependency;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.components.Legend.LegendForm;
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.formatter.ValueFormatter;
import com.github.mikephil.charting.utils.ColorTemplate;
import com.github.mikephil.charting.utils.ViewPortHandler;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

	// 高温线下标
	private final int HIGH = 0;

	// 低温线下标
	private final int LOW = 1;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		final LineChart mChart = (LineChart) findViewById(R.id.chart);
		initialChart(mChart);
		addLineDataSet(mChart);

		// 每点击一次按钮,增加一个点
		Button addButton = (Button) findViewById(R.id.button);
		addButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				addEntry(mChart);
			}
		});
	}

	// 初始化图表
	private void initialChart(LineChart mChart) {
		mChart.setDescription("Zhang Phil @ http://blog.csdn.net/zhangphil");
		mChart.setNoDataTextDescription("暂时尚无数据");

		mChart.setTouchEnabled(true);

		// 可拖曳
		mChart.setDragEnabled(true);

		// 可缩放
		mChart.setScaleEnabled(true);
		mChart.setDrawGridBackground(false);

		mChart.setPinchZoom(true);

		// 设置图表的背景颜色
		mChart.setBackgroundColor(0xfff5f5f5);

		// 图表的注解(只有当数据集存在时候才生效)
		Legend l = mChart.getLegend();

		// 可以修改图表注解部分的位置
		// l.setPosition(LegendPosition.LEFT_OF_CHART);

		// 线性,也可是圆
		l.setForm(LegendForm.LINE);

		// 颜色
		l.setTextColor(Color.CYAN);

		// x坐标轴
		XAxis xl = mChart.getXAxis();
		xl.setTextColor(0xff00897b);
		xl.setDrawGridLines(false);
		xl.setAvoidFirstLastClipping(true);

		// 几个x坐标轴之间才绘制?
		xl.setSpaceBetweenLabels(5);

		// 如果false,那么x坐标轴将不可见
		xl.setEnabled(true);

		// 将X坐标轴放置在底部,默认是在顶部。
		xl.setPosition(XAxisPosition.BOTTOM);

		// 图表左边的y坐标轴线
		YAxis leftAxis = mChart.getAxisLeft();
		leftAxis.setTextColor(0xff37474f);

		// 最大值
		leftAxis.setAxisMaxValue(50f);

		// 最小值
		leftAxis.setAxisMinValue(-10f);

		// 不一定要从0开始
		leftAxis.setStartAtZero(false);

		leftAxis.setDrawGridLines(true);

		YAxis rightAxis = mChart.getAxisRight();
		// 不显示图表的右边y坐标轴线
		rightAxis.setEnabled(false);
	}

	// 为LineChart增加LineDataSet
	private void addLineDataSet(LineChart mChart) {
		LineData data = new LineData();

		data.addDataSet(createHighLineDataSet());
		data.addDataSet(createLowLineDataSet());

		// 数据显示的颜色
		// data.setValueTextColor(Color.WHITE);

		// 先增加一个空的数据,随后往里面动态添加
		mChart.setData(data);
	}

	// 同时为高温线和低温线添加进去一个坐标点
	private void addEntry(LineChart mChart) {

		LineData data = mChart.getData();

		data.addXValue((data.getXValCount()) + "");

		// 增加高温
		LineDataSet highLineDataSet = data.getDataSetByIndex(HIGH);
		float fh = (float) ((Math.random()) * 10 + 30);
		Entry entryh = new Entry(fh, highLineDataSet.getEntryCount());
		data.addEntry(entryh, HIGH);

		// 增加低温
		LineDataSet lowLineDataSet = data.getDataSetByIndex(LOW);
		float fl = (float) ((Math.random()) * 10);
		Entry entryl = new Entry(fl, lowLineDataSet.getEntryCount());
		data.addEntry(entryl, LOW);

		mChart.notifyDataSetChanged();

		// 当前统计图表中最多在x轴坐标线上显示的总量
		mChart.setVisibleXRangeMaximum(4);

		mChart.moveViewToX(data.getXValCount() - 4);
	}

	// 初始化数据集,添加一条高温统计折线
	private LineDataSet createHighLineDataSet() {

		LineDataSet set = new LineDataSet(null, "高温");
		set.setAxisDependency(AxisDependency.LEFT);

		// 折线的颜色
		set.setColor(Color.RED);
		set.setCircleColor(Color.YELLOW);
		set.setLineWidth(5f);
		set.setCircleSize(10f);
		// set.setFillAlpha(128);
		set.setCircleColorHole(Color.BLUE);
		set.setHighLightColor(Color.GREEN);
		set.setValueTextColor(Color.RED);
		set.setValueTextSize(10f);
		set.setDrawValues(true);

		set.setValueFormatter(new ValueFormatter() {
			@Override
			public String getFormattedValue(float value, Entry entry, int dataSetIndex,
					ViewPortHandler viewPortHandler) {
				DecimalFormat decimalFormat = new DecimalFormat(".0℃");
				String s = "高温" + decimalFormat.format(value);
				return s;
			}
		});

		return set;
	}

	// 初始化数据集,添加一条低温统计折线
	private LineDataSet createLowLineDataSet() {

		LineDataSet set = new LineDataSet(null, "低温");
		set.setAxisDependency(AxisDependency.LEFT);

		// 折线的颜色
		set.setColor(ColorTemplate.getHoloBlue());
		set.setCircleColor(Color.BLUE);
		set.setLineWidth(1f);
		set.setCircleSize(10f);
		// set.setFillAlpha(128);
		// set.setFillColor(ColorTemplate.getHoloBlue());
		set.setHighLightColor(Color.DKGRAY);
		set.setValueTextColor(Color.BLACK);
		set.setCircleColorHole(Color.RED);
		set.setValueTextSize(15f);
		set.setDrawValues(true);

		set.setValueFormatter(new ValueFormatter() {
			@Override
			public String getFormattedValue(float value, Entry entry, int dataSetIndex,
					ViewPortHandler viewPortHandler) {
				DecimalFormat decimalFormat = new DecimalFormat(".0℃");
				String s = "低温" + decimalFormat.format(value);
				return s;
			}
		});

		return set;
	}
}



运行结果动图展示动态效果:



一张静态截图展示更清晰的效果:


相关文章:
【1】《Android统计图表MPAndroidChart》链接地址:http://blog.csdn.net/zhangphil/article/details/47656521  
【2】《基于Android MPAndroidChart实现腾讯QQ群数据统计报表核心功能》链接地址:http://blog.csdn.net/zhangphil/article/details/47685515  
【3】《Android实现天气预报温度/气温折线趋势图》链接地址:http://blog.csdn.net/zhangphil/article/details/47702245  
【4】《Android统计图表之柱状图(条形图)》链接地址:http://blog.csdn.net/zhangphil/article/details/47727913  
【5】《Android MPAndroidChart之PieChart和数据结构以及模型【5】》链接地址:http://blog.csdn.net/zhangphil/article/details/50172817 
【6】《Android统计图表MPAndroidChart:动态添加数据更新【6】》链接地址:http://blog.csdn.net/zhangphil/article/details/50185115

【7】MPAndroidChart在github上的项目主页:https://github.com/PhilJay/MPAndroidChart  

相关文章
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
1618 4
|
11月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
675 11
|
开发工具 Android开发 开发者
Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?
本文介绍了一种在Android平台上实现实时截图快照的方法,尤其适用于无需依赖系统接口的情况,如在RTMP推送、RTSP服务或GB28181设备接入等场景下进行截图。通过底层模块(libSmartPublisher.so)实现了截图功能,封装了`SnapShotImpl.java`类来管理截图流程。此外,提供了关键代码片段展示初始化SDK实例、执行截图、以及在Activity销毁时释放资源的过程。此方案还考虑到了快照数据的灵活处理需求,符合GB/T28181-2022的技术规范。对于寻求更灵活快照机制的开发者来说,这是一个值得参考的设计思路。
448 1
|
存储 XML Java
Android 文件数据储存之内部储存 + 外部储存
简介:本文详细介绍了Android内部存储与外部存储的使用方法及核心原理。内部存储位于手机内存中,默认私有,适合存储SharedPreferences、SQLite数据库等重要数据,应用卸载后数据会被清除。外部存储包括公共文件和私有文件,支持SD卡或内部不可移除存储,需申请权限访问。文章通过代码示例展示了如何保存、读取、追加、删除文件以及将图片保存到系统相册的操作,帮助开发者理解存储机制并实现相关功能。
2927 2
|
XML 存储 JSON
51. 【Android教程】JSON 数据解析
51. 【Android教程】JSON 数据解析
549 2
|
数据库 Android开发
Android 通过升级SettingsProvider数据强制覆盖用户的设置项
Android 通过升级SettingsProvider数据强制覆盖用户的设置项 【5月更文挑战第7天】
637 5
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
1001 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
缓存 API Android开发
Android经典实战之Kotlin Flow中的3个数据相关的操作符:debounce、buffer和conflate
本文介绍了Kotlin中`Flow`的`debounce`、`buffer`及`conflate`三个操作符。`debounce`过滤快速连续数据,仅保留指定时间内的最后一个;`buffer`引入缓存减轻背压;`conflate`仅保留最新数据。通过示例展示了如何在搜索输入和数据流处理中应用这些操作符以提高程序效率和用户体验。
448 6
|
编解码 网络协议 前端开发
如何实现Android平台GB28181设备接入模块按需打开摄像头并回传数据
后台采集摄像头,如果想再进一步扩展,可以把android平台gb28181的camera2 demo,都移植过来,实现功能更强大的国标设备侧,这里主要是展示,收到国标平台侧的回传请求后,才打开摄像头,才开始编码打包,最大限度的减少资源的占用
445 3
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。
283 3

热门文章

最新文章