Koltin实现动态心率曲线
Posted 期待的是什么
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Koltin实现动态心率曲线相关的知识,希望对你有一定的参考价值。
用MPAndroid 实现动态的心率曲线
废话不多说,先上图
上面是实现效果,由于是第一次上传图片,不会发动图,目前就两张图片,
- 首先是集成mpchart android,具体集成方式请直接百度就好
- 先实现y轴的代码,相关参数设计如下:
leftAxis?.let {
//是否绘制轴线
it.setDrawAxisLine(true)
//设置轴线的颜色
it.axisLineColor = context!!.resources.getColor(R.color.color_f3f3f3)
//是否绘制网格线
it.setDrawGridLines(true) //横的线(与Y轴有关)
//y轴的线为虚线
//leftAxis.enableGridDashedLine(10f, 5f, 0f);
it.gridLineWidth = gridLineWidth
//设置网格线的颜色
it.gridColor = context!!.resources.getColor(R.color.color_f3f3f3)
it.textSize = axisYTextSize
it.textColor = axisTextColor
//leftAxis.setSpaceMin(20);
//leftAxis.setSpaceMax(20);
//字体距离曲线的位置
it.xOffset = 6f
it.yOffset = 0f
//设置最大值和最小值
it.axisMinimum = Y_MIN
it.axisMaximum = Y_MAX
//y轴坐标点个数
it.labelCount = yAxisLabelCount
it.valueFormatter = StepYaxisValueFormat()
}
///右边的y轴///
rightAxis?.let {
it.isEnabled = false
// it.setDrawAxisLine(false)
// it.spaceMax = 0f
}
这里主要是把左边和右边的轴线,显示为不显示,如果需要显示请把 isEnable设置为true,即可
3.接下来是x轴的相关参数的设置:
xAxis?.let {
//是否绘制网格线
it.setDrawGridLines(true) //竖的线(与X轴有关)
//网格线的宽度
it.gridLineWidth = gridLineWidth
//网格颜色
it.gridColor = context!!.resources.getColor(R.color.color_f3f3f3)
//字体距离曲线的位置
it.yOffset = 0f
it.xOffset = 0f
it.position = XAxis.XAxisPosition.BOTTOM // 设置X轴的位置
it.setDrawAxisLine(true) //是否显示X轴
//轴线的颜色
it.axisLineColor = context!!.resources.getColor(R.color.color_f3f3f3)
it.textSize = axisXTextSize
it.textColor = axisTextColor
//xAxis.setSpaceMin(5);//小于最小值5开始画
it.spaceMax = 0f //大于最大值10
it.axisMinimum = 0f //x轴显示的最小值
//只有不是实时曲线的时候才设置这个值
// it.axisMaximum = xAxisVisibleValueRange //x轴显示的最大值
//xAxis.mAxisRange=2f;
it.setLabelCount(xAxisLabelCount, false)
it.valueFormatter = StepXAxisValueFormat()
}
相同的道理,这里是将x轴的相关方法设置为不显示,具体的参数意思,在代码中已经有了注释,到这里我们完成了,相关设置
4.接下来是实现linechart的曲线属性相关设置;
/**
*
*
* @return void
* @time 2021-9-16 17:06:04
*/
private fun buildOxDataSet(entries: List<Entry>, label: String): LineDataSet {
val oxDataSet = LineDataSet(entries, label)
oxDataSet.lineWidth = lineWidth
oxDataSet.mode = LineDataSet.Mode.CUBIC_BEZIER //设置为贝塞尔曲线
oxDataSet.setDrawValues(false) //不显示数值
oxDataSet.setDrawCircles(false) //不显示圆点
// 设置高亮十字光标线的虚化:设置第二个参数为虚线间隔
oxDataSet.enableDashedHighlightLine(10f, 0f, 0f)
// 设置十字光标线的颜色
oxDataSet.isHighlightEnabled = true //显示高亮
oxDataSet.highLightColor = highLightColor
oxDataSet.setDrawHorizontalHighlightIndicator(false) //水平的高亮线不绘制
//设置原点的颜色
oxDataSet.circleRadius = 2.0f
//oxDataSet.setDrawCircles(true);
oxDataSet.circleHoleRadius = 2.0f
oxDataSet.setCircleColor(context!!.resources.getColor(R.color.color_ff4900))
oxDataSet.color = lineColor
//是否填充
oxDataSet.setDrawFilled(true)
oxDataSet.fillDrawable = context!!.resources.getDrawable(R.drawable.gradient_ecg_line)
return oxDataSet
}
这里就不做过多介绍了,属性参数的意思都有注释,如果需要改线条的颜色或者粗细,只用修改对应的属性值就好了
5.最后就是动态添加数据环节,代码如下:
/**
* 动态增加折线数据
*
* @param entries 折线的数据
* @return void
* @time 2019-10-16 15:07:53
*/
fun addEntry(entries: ArrayList<Entry>) {
if (null == ecgDataSet) {
// realTimeList.clear()
// realTimeList.addAll(entries)
ecgDataSet = buildOXDataSet(entries)
(lineDataSets as ArrayList).add(ecgDataSet!!)
} else {
val lineDataSet = lineData!!.getDataSetByLabel(
LABEL_ECG,
true
) as LineDataSet
// realTimeList.addAll(entries)
// lineDataSet.entries = realTimeList
//changeLineStatues(lineDataSet);
for (entry in entries) {
lineDataSet.addEntry(entry)
}
}
val entry = entries[entries.size - 1]
//设置上面的limitline动态增加
val lineDataSet = lineData!!.getDataSetByLabel(LABEL_LIMIT_LINE_UP, true)
if (lineDataSet.entryCount >= 2 && entry.x > xAxisVisibleValueRange) {
lineDataSet.removeEntry(lineDataSet.entryCount - 1)
lineDataSet.addEntry(Entry(entry.x, LIMIT_VALUE_MAX))
}
lineData!!.notifyDataChanged()
lineChart!!.notifyDataSetChanged()
//控制x轴值的显示范围
lineChart!!.setVisibleXRangeMaximum(xAxisVisibleValueRange)
if (entry.x > xAxisVisibleValueRange) {
lineChart!!.moveViewToX(entry.x) //移动到最后一个
} else {
lineChart!!.moveViewToX(0f)
}
}
这里主要是通过getDataSetByLabel()函数去获取linechart中已经有的曲线的linedataset,同时把获取的数据添加到对应的linedataset里面,同时将视图拉向最后一个点的x轴最大值,要实现动态的,必须设置x轴的最大视图范围,通过函数名:setVisibleXRangeMaximum()去设置。以上就是动态实现心率的相关代码
6.最后贴出全部的代码:
/**
* @ClassName EcgChartHelper
* @Description TODO
* @Author Darcy
* @Date 2021/9/17 16:44
* @Version 1.0
*/
class EcgChartHelper(chart: LineChart, context: Context) {
private var xAxis: XAxis? = null
private var leftAxis: YAxis? = null
private var rightAxis: YAxis? = null
private var context: Context? = context
private var lineChart: LineChart? = chart
//高亮线的颜色
private val highLightColor = -0x3e3717
//网格线宽度
private val gridLineWidth = 1.0f
//Y坐标轴刻度文字大小
private val axisYTextSize = 10f
//X坐标轴刻度文字大小
private val axisXTextSize = 8f
//坐标轴刻度文字颜色
private val axisTextColor = -0x5c5c5d
private val Y_MAX = 120f //正常范围边界最大值
private val Y_MIN = 70f //正常范围边界最小值
private val yAxisLabelCount = 20 //y轴刻度数
// x轴显示的值范围大小,
private val xAxisVisibleValueRange = 300.0f
private val LABEL_LIMIT_LINE_UP = "limit_line_up"
//有效值(灰色区域)
private val LIMIT_VALUE_MIN = 90f //有效范围的最小值
private val LIMIT_VALUE_MAX = 100f //有效范围的最大值
//灰色区域最大值
private val maxRangeVaule = 300.0f
//灰色区域颜色值
private val limitAreaColor = -0xdf243a
private val LABEL_ECG = "label_ecg"
//X轴的刻度数,
private val xAxisLabelCount = 60
//线宽
private val lineWidth = 1.0f
//private val lineColor: Int = -0x7f006800
private val lineColor: Int = -0x5bd00
//设置灰色区域(有效的范围值)
private fun bulidLimitArea() {
//灰色区域绘制
val dataSet: LineDataSet = buildUpLimitDataSet()
(lineDataSets as ArrayList).add(dataSet)
//添加一个 LineData
lineData = LineData(lineDataSets)
lineChart!!.data = lineData
lineChart!!.invalidate()
}
/**
* 设置限制线.基线(预警线的线条)
*
* @return void
* @time 2020-7-30 18:09:16
*/
private fun buildUpLimitDataSet(): LineDataSet {
val limitLineWidth = 0.1f
val entries: ArrayList<Entry> = ArrayList()
entries.add(Entry(0f, LIMIT_VALUE_MAX))
entries.add(Entry(maxRangeVaule, LIMIT_VALUE_MAX))
val dataSet = LineDataSet(entries, LABEL_LIMIT_LINE_UP)
dataSet.lineWidth = limitLineWidth
dataSet.mode = LineDataSet.Mode.LINEAR //
dataSet.setDrawValues(false) //不显示数值
dataSet.setDrawCircles(false) //不显示圆点
dataSet.isHighlightEnabled = false
dataSet.setDrawFilled(true)
dataSet.fillFormatter = LimitLineFillFormatter(LIMIT_VALUE_MIN)
dataSet.fillColor = limitAreaColor
dataSet.color = -0x111112
dataSet.fillAlpha = 0x1a
return dataSet
}
/**
* Y坐标轴设置
*
* @return void
* @time 2021-9-16 16:25:46
*/
private fun initYAxis() {
leftAxis?.let {
//是否绘制轴线
it.setDrawAxisLine(true)
//设置轴线的颜色
it.axisLineColor = context!!.resources.getColor(R.color.color_f3f3f3)
//是否绘制网格线
it.setDrawGridLines(true) //横的线(与Y轴有关)
//y轴的线为虚线
//leftAxis.enableGridDashedLine(10f, 5f, 0f);
it.gridLineWidth = gridLineWidth
//设置网格线的颜色
it.gridColor = context!!.resources.getColor(R.color.color_f3f3f3)
it.textSize = axisYTextSize
it.textColor = axisTextColor
//leftAxis.setSpaceMin(20);
//leftAxis.setSpaceMax(20);
//字体距离曲线的位置
it.xOffset = 6f
it.yOffset = 0f
//设置最大值和最小值
it.axisMinimum = Y_MIN
it.axisMaximum = Y_MAX
//y轴坐标点个数
it.labelCount = yAxisLabelCount
it.valueFormatter = StepYaxisValueFormat()
}
///右边的y轴///
rightAxis?.let {
it.isEnabled = false
// it.setDrawAxisLine(false)
// it.spaceMax = 0f
}
}
/**
* X坐标轴设置
*
* @return void
* @time 2020-7-30 18:09:24
*/
private fun initXAxis() {
xAxis?.let {
//是否绘制网格线
it.setDrawGridLines(true) //竖的线(与X轴有关)
//网格线的宽度
it.gridLineWidth = gridLineWidth
//网格颜色
it.gridColor = context!!.resources.getColor(R.color.color_f3f3f3)
//字体距离曲线的位置
it.yOffset = 0f
it.xOffset = 0f
it.position = XAxis.XAxisPosition.BOTTOM // 设置X轴的位置
it.setDrawAxisLine(true) //是否显示X轴
//轴线的颜色
it.axisLineColor = context!!.resources.getColor(R.color.color_f3f3f3)
it.textSize = axisXTextSize
it.textColor = axisTextColor
//xAxis.setSpaceMin(5);//小于最小值5开始画
it.spaceMax = 0f //大于最大值10
it.axisMinimum = 0f //x轴显示的最小值
//只有不是实时曲线的时候才设置这个值
// it.axisMaximum = xAxisVisibleValueRange //x轴显示的最大值
//xAxis.mAxisRange=2f;
it.setLabelCount(xAxisLabelCount, false)
it.valueFormatter = StepXAxisValueFormat()
}
}
/**
* 图表LineChart设置
*
* @return void
* @time 2020-7-30 18:09:20
*/
private fun initLineChart() {
lineChart?.let {
/*图表设置***/
it.setTouchEnabled(true) // 设置是否可以触摸
//是否启用chart绘图区后面的背景矩形将绘制
it.setDrawGridBackground(false)
// //设置网格背景应与绘制的颜色
it.setGridBackgroundColor(-0x1)
//设置markView
// TempMarkView myMarkerView = new TempMarkView(context);
// myMarkerView.setChartView(lineChart);
// lineChart.setMarker(myMarkerView);
//启用/禁用绘制图表边框(chart周围的线)。
it.setDrawBorders(false)
//是否可以拖动
it.isDragEnabled = true
//启用/禁用缩放图表上的两个轴
it.setScaleEnabled(false)
//设置在曲线图中显示的最大数量
// vMutlilineChart.setVisibleXRangeMaximum(40);//可视范围的值的范围
it.setNoDataText("")
val description = Description()
description.isEnabled = false
description.text = "" //我是描述信息
it.description = description
//是否显示高亮线,十字线条
it.isHighlightPerTapEnabled = false
it.isHighlightPerDragEnabled = false
val legend: Legend = it.legend
//legend.setWordWrapEnabled(false);//设置标签是否换行(当多条标签时 需要换行显示、如上右图)true:可换行。false:不换行
legend.isEnabled = false //隐藏图例
}
}
/**
* 计步的折线图
*
* @return void
* @time 2021-9-16 17:06:17
*/
private fun buildOXDataSet(entries: List<Entry>): LineDataSet? {
return buildOxDataSet(entries, LABEL_ECG)
}
/**
* 计步的折线图
*
* @return void
* @time 2021-9-16 17:06:04
*/
private fun buildOxDataSet(entries: List<Entry>, label: String): LineDataSet {
//温度曲线设置
val oxDataSet = LineDataSet(entries, label)
oxDataSet.lineWidth = lineWidth
oxDataSet.mode = LineDataSet.Mode.CUBIC_BEZIER //设置为贝塞尔曲线
oxDataSet.setDrawValues(false) //不显示数值
oxDataSet.setDrawCircles(false) //不显示圆点
// 设置高亮十字光标线的虚化:设置第二个参数为虚线间隔
oxDataSet.enableDashedHighlightLine(10f, 0f, 0f)
// 设置十字光标线的颜色
oxDataSet.isHighlightEnabled = true //显示高亮
oxDataSet.highLightColor = highLightColor
oxDataSet.setDrawHorizontalHighlightIndicator(false) //水平的高亮线不绘制
//设置原点的颜色
oxDataSet.circleRadius = 2.0f
//oxDataSet.setDrawCircles(true);
oxDataSet.circleHoleRadius = 2.0f
oxDataSet.setCircleColor(context!!.resources.getColor(R.color.color_ff4900))
oxDataSet.color = lineColor
//是否填充
oxDataSet.setDrawFilled(true)
oxDataSet.fillDrawable = context!!.resources.getDrawable(R.drawable.gradient_ecg_line)
return oxDataSet
}
private var ecgDataSet: LineDataSet? = null
private val lineDataSets: List<LineDataSet> = ArrayList()
private var lineData: LineData? = null
/**
* 添加数据
*
* @param entries 折线的数据
* @return void
* @time 2021-9-16 17:08:48
*/
fun addEntries(entries: ArrayList<Entry>) {
//先清除存在的点
lineChart!!.clearValues()
ecgDataSet = buildOXDataSet(entries)
(lineDataSets as ArrayList).add(ecgDataSet!!)
//控制网格不变
if (entries.isNotEmpty() && entries[entries.size - 1].x > xAxisVisibleValueRange) {
xAxis!!.spaceMax = 0f
} else {
val max =
if (entries.size == 0) xAxisVisibleValueRange else xAxisVisibleValueRange - entries[entries.size - 1].x
xAxis!!.spaceMax = max
}
lineData?.notifyDataChanged()
lineChart!!.notifyDataSetChanged()
lineChart!!.setVisibleXRangeMinimum(xAxisVisibleValueRange)
//lineChart!!.moveViewToX(entries.size.toFloat())
}
/**
* 动态增加折线数据
*
* @param xValue x轴对应的值
* @param yValue y轴对应的值
* @return void
* @time 2020-8-24 15:55:08
*/
fun addEntry(xValue: Float, yValue: Float) {
addEntry(Entry(xValue, yValue))
}
/**
* 动态增加折线数据
*
* @param entry 折线的数据
* @return void
* @time 2020-8-24 15:55:11
*/
fun addEntry(entry: Entry) {
val entries = java.util.ArrayList<Entry>()
entries.add(entry)
addEntry(entries)
}
var realTimeList: ArrayList<Entry> = ArrayList()
/**
* 动态增加折线数据
*
* @param entries 折线的数据
* @return void
* @time 2019-10-16 15:07:53
*/
fun addEntry(entries: ArrayList<Entry>) {
if (null == ecgDataSet) {
// realTimeList.clear()
// realTimeList.addAll(entries)
ecgDataSet = buildOXDataSet(entries)
(lineDataSets as ArrayList).add(ecgDataSet!!以上是关于Koltin实现动态心率曲线的主要内容,如果未能解决你的问题,请参考以下文章