编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

实现LineChart的线不接触到数据点

wxchong 2024-07-07 00:20:05 开源技术 12 ℃ 0 评论



遇到的需求中规定折线不能接触到数据点,要有一个指定外圆的距离。

实现思虑其实比较简单,做一个三角形(如下图),根据两点之间的x和y的差值,算出角度,然后根据要求的距离算出折线端点到数据点的x轴和y轴上的差值。

MPAndroidChart的LineChart对于折线的实现是在LineChartRenderer类的drawLinear方法中,进入drawLinear的路径是同一个类的drawDataSet方法中,可以自己根据需要写一个自己的LineChartRenderer,重写涉及到的这几个方法。在drawLinear方法中有一个mLineBuffer变量,是用于存储折线起始、结束位置的。四个值为一根线,在mLineBuffer里的数据都转换为像素距离后,可以重新遍历一遍,去掉规定的距离。如果看不懂上面的思路,那就直接看代码吧。

private void drawSplitLinear(Canvas c, ILineDataSet dataSet) {
        ... ...
                if (j > 0) {
                    trans.pointValuesToPixel(mLineBuffer);
                    transformBuffer(mLineBuffer, dataSet.getCircleRadius()*2);
                    ... ...
                    }
                }
            }
        }

        mRenderPaint.setPathEffect(null);
    }

然后是transformBuffer的实现:

private void transformBuffer(float[] mLineBuffer, float circleRadius) {
        int i = 0;
        while (i < mLineBuffer.length) {
            float x1 = mLineBuffer[i++];
            float y1 = mLineBuffer[i++];
            float x2 = mLineBuffer[i++];
            float y2 = mLineBuffer[i++];
            if (x1 == x2 && y1 == y2) continue;
            float dx = x2 - x1;
            float dy = Math.abs(y2 - y1);
            double degree = Math.atan(dy / dx);
            float ddx = (float) (circleRadius * Math.cos(degree));
            float ddy = (float) (circleRadius * Math.sin(degree)) * ((y2 > y1) ? 1 : -1);
            mLineBuffer[i - 4] = x1 + ddx;
            mLineBuffer[i - 3] = y1 + ddy;
            mLineBuffer[i - 2] = x2 - ddx;
            mLineBuffer[i - 1] = y2 - ddy;
        }
    }

?以上就实现了折线不接触数据点,且可以规定距离?。?

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表