repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}
布局引用
<com.github.mikephil.charting.charts.CombinedChart
android:id="@+id/combinedChart"
android:layout_width="350dp"
android:layout_height="270dp"
android:layout_margin="20dp"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
private lateinit var lineDataSet: LineDataSet//折线数据集
/** 初始化 CombinedChart **/
private fun setupChart() {
val chart = binding.combinedChart
// 折线数据集 参数设置
lineDataSet = LineDataSet(mutableListOf(Entry(0f, 0f)), "实时曲线").apply {
color = ColorTemplate.rgb("1E88E5")
lineWidth = 2f
setDrawCircles(false)
setDrawValues(false)
setDrawFilled(true) // 曲线下方填充
mode = LineDataSet.Mode.CUBIC_BEZIER // 平滑曲线 LINEAR
axisDependency = YAxis.AxisDependency.LEFT
}
lineDataSet.setDrawFilled(true)
lineDataSet.fillColor = Color.parseColor("#82F689") // 填充颜色
lineDataSet.fillAlpha = 80 // 透明度 0~255
// 曲面折线
redDataSet = LineDataSet(mutableListOf(), "GC 谱图").apply {
setDrawHorizontalHighlightIndicator(false)
setDrawVerticalHighlightIndicator(false)
lineWidth = 0f // 安全
color = Color.TRANSPARENT // 即使透明也不影响
mode = LineDataSet.Mode.LINEAR // 不要贝塞尔
setCircleColor(Color.RED) // 圆点颜色为红色
setDrawCircleHole(false) // 圆点不留白
setDrawCircles(true) // 不画圆点
setDrawFilled(false) // 曲线下方填充
fillColor = Color.TRANSPARENT
}
val lineData = LineData(redDataSet,lineDataSet)
// 柱状数据集(初始化为空)
barDataSet = BarDataSet(mutableListOf(), "目标气体峰").apply {
color = Color.RED
}
val barData = BarData(barDataSet).apply { barWidth = 0.8f }
// CombinedData
val combinedData = CombinedData().apply {
setData(lineData)
setData(barData)
}
chart.data = combinedData
// 限制最大缩放比例
chart.viewPortHandler.setMaximumScaleX(Float.MAX_VALUE) // X轴无限放大
chart.viewPortHandler.setMinimumScaleX(0f) // 无限缩小(到很小)
chart.viewPortHandler.setMaximumScaleY(Float.MAX_VALUE) // Y轴无限放大
chart.viewPortHandler.setMinimumScaleY(0f) // 无限缩小
// X轴设置
chart.xAxis.apply {
position = XAxis.XAxisPosition.BOTTOM
granularity = 1f
axisMinimum = 0f
}
// Y轴设置
// chart.axisLeft.apply {
// axisMinimum = 0f
// valueFormatter = object : ValueFormatter() {
// override fun getFormattedValue(value: Float): String = "${value.toInt()} mV"
// }
// setAxisMinValue(0f)//强制y轴最小值
// }
chart.axisLeft.apply {
axisMinimum = 0f // 下限固定 0(PID 不会为负)
spaceTop = 80f // 上方预留 20%,防止贴顶
spaceBottom = 5f // 下方预留一点更美观
setDrawGridLines(true)
setDrawZeroLine(false)
// Y 轴单位
valueFormatter = object : ValueFormatter() {
override fun getFormattedValue(value: Float): String = "${value.toInt()} mV"
}
}
chart.axisRight.isEnabled = false
// 缩放 + 拖动 + 图表一次最多能看到多少 X 点(宽度限制)
chart.setScaleEnabled(true)
chart.setPinchZoom(true)
chart.setVisibleXRangeMaximum(maxVisiblePoints)
chart.description.isEnabled = false
//替换默认的renderer为自定义的SampleHighlightRenderer,画高亮区间
val highlightPaint = Paint().apply {
style = Paint.Style.FILL
color = Color.parseColor("#5533B5E5") // 半透明蓝色
}
val renderer = SampleHighlightRenderer(binding.combinedChart, binding.combinedChart.viewPortHandler, highlightPaint)
binding.combinedChart.renderer = renderer
//设置高亮的mark
// val marker = MyMarkerView(this)
// marker.chartView = binding.combinedChart
// binding.combinedChart.marker = marker
//
// chart.isHighlightPerTapEnabled = true
// chart.isHighlightPerDragEnabled = true
chart.invalidate()
}
private fun addGCPoint(value: Float) {
val chart = binding.combinedChart
val entry = Entry(xIndex, value)
xIndex += 1f
lineDataSet.addEntry(entry)
if(xIndex == 10f || xIndex == 20f){
redDataSet.addEntry(entry)
}
chart.data.lineData.notifyDataChanged()
chart.data.notifyDataChanged()
chart.notifyDataSetChanged()
// 固定显示最近 maxVisiblePoints 个点
if (lineDataSet.entryCount > maxVisiblePoints) {
chart.setVisibleXRangeMaximum(maxVisiblePoints)
chart.moveViewToX(lineDataSet.entryCount - maxVisiblePoints)
} else {
chart.moveViewToX(0f)
}
chart.invalidate()
}
安卓图表MpAndroidChart使用
安卓理事人2025-12-12 18:28
相关推荐
消失的旧时光-194321 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?Jinkxs1 天前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南&有梦想的咸鱼&1 天前
Kotlin委托机制的底层实现深度解析(74)LDORntKQH1 天前
基于深度强化学习的混合动力汽车能量管理策略 1.利用DQN算法控制电池和发动机发电机组的功率分配 2冬奇Lab1 天前
Android 15 ServiceManager与Binder服务注册深度解析2501_916008891 天前
深入解析iOS机审4.3原理与混淆实战方法独行soc1 天前
2026年渗透测试面试题总结-20(题目+回答)常利兵1 天前
2026年,Android开发已死?不,它正迎来黄金时代!Risehuxyc1 天前
备份三个PHP程序Doro再努力1 天前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译