MPAndroidChart绘制多边形时渲染异常及触摸崩溃问题求助
问题分析与解决方案
核心问题
你用LineDataSet的setDrawFilled(true)来实现多边形填充,但MPAndroidChart默认的填充逻辑是填充折线与X轴(或指定基线)之间的区域,并非闭合多边形的填充。当你的多边形点顺序出现“反向回折”(比如从X=102.5回到X=100)时,填充路径会出现自交或非法区域,导致渲染异常,甚至在触摸重绘时触发OpenGL崩溃。
另外,你设置的X轴granularity = 1f,但点的X值包含102.5这种非整数,虽然不是直接原因,但会干扰图表的坐标计算,加重渲染问题。
解决方案
1. 直接用Canvas手动绘制多边形(推荐)
放弃用LineDataSet模拟,直接在图表的自定义Renderer里手动绘制填充多边形,完全可控,不会出现路径异常:
// 给chartTopView设置自定义Renderer chartTopView.setRenderer(object : LineChartRenderer(chartTopView, chartTopView.animator, chartTopView.viewPortHandler) { override fun drawExtras(c: Canvas) { super.drawExtras(c) // 绘制填充区域 val fillPaint = Paint().apply { color = ColorTemplate.COLORFUL_COLORS[0] style = Paint.Style.FILL alpha = 128 // 可选,调整填充透明度 } val path = Path() // 转换第一个点为屏幕像素坐标 val firstPoint = polygonTopView.vertices.first() val firstPixel = chartTopView.getTransformer(YAxis.AxisDependency.LEFT) .getPixelForValues(firstPoint.first.toFloat(), firstPoint.second.toFloat()) path.moveTo(firstPixel.x, firstPixel.y) // 依次添加剩余点到路径 for (point in polygonTopView.vertices.drop(1)) { val pixel = chartTopView.getTransformer(YAxis.AxisDependency.LEFT) .getPixelForValues(point.first.toFloat(), point.second.toFloat()) path.lineTo(pixel.x, pixel.y) } path.close() // 闭合路径 c.drawPath(path, fillPaint) // 绘制多边形边框 val strokePaint = Paint().apply { color = ColorTemplate.COLORFUL_COLORS[0] style = Paint.Style.STROKE strokeWidth = 2f } c.drawPath(path, strokePaint) } })
2. 辅助优化调整
- 确保多边形点的顺序是严格顺时针或逆时针,避免路径自交(你的当前顺序是合规的,但若后续修改点需注意)。
- 去掉X轴的粒度限制,因为你的点包含非整数X值,强制粒度为1会导致坐标计算精度丢失:
// 注释或删除这两行 // chartTopView.xAxis.granularity = 1f // chartTopView.xAxis.isGranularityEnabled = true
3. 临时验证方案
如果暂时不想修改绘制逻辑,可以先关闭第二个图表的填充功能,确认问题根源:
dataSetTopView.setDrawFilled(false)
此时若多边形显示正常、触摸无崩溃,即可确认是填充逻辑导致的问题,再改用手动绘制方案即可。
内容的提问来源于stack exchange,提问作者col625
相关产品推荐
相关产品推荐

