1.先上效果图(左为问题,右图为处理后效果)
2.百度搜索了很多文章,参考这位大佬的文章解决大部分问题链接
网上很多对于0的情况都不做显示,但有些时候不允许这样做,就难搞了。如果极小数太多,还是会出现重叠情况。
3.优化
在大佬的基础上做了简单优化,对minData()函数进行优化:
问题简单来说,就是这个方法在计算最近点的时候,未考虑存在多个数量占比极小(极小项)的情况,因为当占比过小时,原本计算出的label的y坐标值差比较小,因此会导致第二个之后的多个极小项找最近点时,都会找到第一个极小项的坐标,那转换后自然会重叠。那么只用每次判断下,转换后的坐标是否存在重叠的,如果有,则继续找即可。优化后代码如下:
private float[] minData(float[][] leftRecordY, float pt1y, float offset) {
//计算出离的最近的
List<Float> bigD = new ArrayList<>();
//变换前的数据
List<Float> nearestList = new ArrayList<>();
//变换后的数据
List<Float> nearestListCopy = new ArrayList<>();
for (int k = 0; k < leftRecordY[0].length; k++) {
if (leftRecordY[0][k] != 0) {
bigD.add(Math.abs(leftRecordY[0][k] - pt1y));
nearestList.add(leftRecordY[0][k]);
nearestListCopy.add(leftRecordY[1][k]);
}
}
// 距离最近的点,数值
float[] rF = new float[2];
if (bigD.size() == 0) {
return rF;
}
//从小到大排序
bigD.sort((o1, o2) -> (int) ((o1 - o2) / Math.abs(o1 - o2)));
rF[0] = nearestList.get(0);
rF[1] = nearestListCopy.get(0);
for (int g = 0; g < bigD.size(); g++) {
//如果排序靠后的项,修改后的坐标与当前项修改后的坐标差,小于文字高度,则跳过
if (nearestListCopy.size() > g + 1 && Math.abs(pt1y + offset - nearestListCopy.get(g + 1)) < offset) {
continue;
}
rF[0] = nearestList.get(g);
rF[1] = nearestListCopy.get(g);
}
return rF;
}