Path绘图之平滑曲线

论坛 期权论坛 脚本     
匿名技术用户   2020-12-22 11:36   15   0

效果图

这里写图片描述

文章开头先放上效果图。
效果图中上面的阴影图是之前的文章
Path曲线下的阴影绘制

效果图中这个平滑曲线的效果是我比较早之前项目中的一个需求,MPchart在这种需求下不仅不合适,反而还比较复杂,所以完全自定义了一个View。

实现思路

结构还是很清晰的。可以分成三个部分

  • 曲线

    Path画平滑曲线使用cubicTo方法,使用两个控制点,根据贝赛尔曲线原理可以画出

        mPath.reset();
        mPath.moveTo(point.x, point.y);
        float preX = point.x;
        float preY = point.y;
        for (int i = 1; i < size; i++) {
            point = mPointList.get(i);
            float controlX = (preX + point.x) / 2;
            mPath.cubicTo(controlX, preY, controlX, point.y, point.x, point.y);
            preX = point.x;
            preY = point.y;
        }
  • 数字
    数字有 X轴上的时间显示、Y轴的最大值和最小值 以及最后一个点的圆圈和文字显示
    public void drawXAxis(Canvas canvas) {
        float baseY = getHeight();
        Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
        float top = baseY - metrics.bottom;
        canvas.drawText(mPathValue.startTime, mXaxisPaddingLeft, top, mTextPaint);
        canvas.drawText(mPathValue.endTime, mLastPoint.x - mTextPaint.measureText(mPathValue.endTime) / 2, top, mTextPaint);
    }

    public void drawYAxis(Canvas canvas) {
        float baseY = getHeight() / 2 - mPathHeight / 2;
        Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
        float top = baseY - metrics.bottom;
        final int padding = 5;
        canvas.drawText(String.valueOf(mMaxY), mYaxisPaddingLeft, top - padding, mTextPaint);
        canvas.drawText(String.valueOf(mMinY), mYaxisPaddingLeft, top + mPathHeight - metrics.top + padding, mTextPaint);
    }

    private void drawEnd(Canvas canvas) {
        drawEndString(canvas);
        drawEndPointCycle(canvas);
        drawQualityCycle(canvas);
    }
  • 数值和坐标像素的转化
    这里需要注意的是整个Path曲线图在View中是居中显示,而不是从顶部开始显示
    因为需要满足需求,如果所有的点在一条直线上的话,需要居中。主要计算方法如下:
            //计算水质点高低点和像素点高低点的比例
            float disQuality = maxY - minY;
            final int startY = getHeight() / 2 - mPathHeight / 2;
            float disPixel = mPathHeight;
            float x;
            float y;
            float scale;
            if (disQuality == 0) {
                for (int i = 0; i < size; i++) {
                    x = mPathPaddingLeft + (pecX * i);
                    y = (startY + disPixel * 0.5f);//线段居中
                    points.add(new Point(x, y));
                }
            } else {
                for (int i = 0; i < size; i++) {
                    x = mPathPaddingLeft + (pecX * i);
                    scale = (maxY - list.get(i)) / disQuality;
                    y = (startY + disPixel * scale);
                    points.add(new Point(x, y));
                }
            }

代码地址

具体代码见Demo:https://github.com/xindasunday/ShareDemo

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP