MPAndroidChart如何实现折线图标签附着/紧贴折线效果

首先明确结论:MPAndroidChart 原生没有提供折线标签附着/紧邻折线显示的开箱功能。库自带的图例默认固定在图表四周,自带的数值绘制能力只支持给单个数据点展示对应值,做不到整条折线的系列名称跟随折线位置展示的效果。
可落地的变通实现方案
叠加自定义View定位(实现成本最低,最贴近参考效果)
不用修改图表本身的渲染逻辑,在图表布局上叠加一层和图表大小完全一致的透明布局容器专门放标签。等图表渲染完成、或者每次图表触发滑动、缩放、刷新动作后,遍历每条折线的目标点位(一般取折线最末端的可见数据点),把数据坐标转换成屏幕实际像素坐标,把写好折线名称的TextView布局到对应点位的旁侧(比如点位右侧留8dp间距,垂直方向居中对齐)即可。
核心坐标转换代码参考:for (ILineDataSet dataSet : lineChart.getLineData().getDataSets()) { // 取折线最后一个点作为标签锚点 Entry anchorEntry = dataSet.getEntryForIndex(dataSet.getEntryCount() - 1); MPPointD anchorPoint = lineChart.getTransformer(dataSet.getAxisDependency()) .getPixelForValues(anchorEntry.getX(), anchorEntry.getY()); // 把对应标签TextView布局到 (anchorPoint.x + 24, anchorPoint.y - textViewHeight/2) 位置即可 }这种方案调整标签样式最灵活,不管是改字体、加色块标记都很方便,也是大部分同类需求的首选实现方式。
自定义渲染器直接在画布绘制(适合需要导出图表位图的场景)
如果不想额外叠View,或者需要把带标签的图表直接导出成图片,可以继承原生的LineChartRenderer,新增标签绘制逻辑,在绘制完折线之后,用Canvas的drawText方法直接把折线名称画到对应锚点的旁侧,坐标计算逻辑和上面的方案完全一致。最后调用lineChart.setRenderer()把自定义渲染器设置给图表就行。这种方案标签和图表完全融为一体,不会有布局层级冲突的问题。利用ValueFormatter给特殊点位赋值(适合无交互的静态图表)
如果你的图表不需要缩放、滑动,完全是静态展示,可以给每条折线额外加一个透明、不显示圆点的Entry,放在你想展示标签的位置,自定义ValueFormatter的时候,只有这个特殊Entry返回折线的系列名称,其他普通数据点返回空字符串,也能凑出标签在折线上的效果。缺点是交互时标签位置适配很麻烦,不建议可交互的图表用这个方案。
注意:实现时记得给图表设置足够的右侧内边距,避免折线末端的标签被图表边界裁剪截断。
内容的提问来源于stack exchange,提问作者Kamil Radz

