qt曲线绘制

#ifndef CSENSORLINE_H
#define CSENSORLINE_H

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

enum LINE_TYPE
{
    LINE_TYPE_ONE,
    LINE_TYPE_TWO,
    LINE_TYPE_MAX,
};

enum WIDGET_LINE_TYPE
{
    WIDGET_LINE_TYPE_ONE,
    WIDGET_LINE_TYPE_ALL,
    WIDGET_LINE_TYPE_MAX,
};

class CSensorLine : public QWidget
{
    Q_OBJECT
public:
    explicit CSensorLine(QWidget *parent = nullptr);
    ~CSensorLine();
protected:
    void paintEvent( QPaintEvent * event );
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

public:
    void initPosition();
    void initXYListData();
    void setTotalPointCount(qint32 count);
    void setStartDrawOnLeft(bool flag);
    void setShowOutSideRect(bool flag);
    void setShowInSideRect(bool flag);
    void setShowInSideGrid(bool flag);
    void setShowXBottomScale(bool flag);
    void setShowYLeftScale(bool flag);
    void setShowXTopScale(bool flag);
    void setShowYRightScale(bool flag);
    void setBackColor(QLinearGradient linegradent);
    void setYLeftMinMax(qint32 min,qint32 max);
    void setYRightMinMax(qint32 min,qint32 max);
    void setShowXBottomScaleValue(bool flag);
    void setShowYLeftScaleValue(bool flag);
    void setShowXTopScaleValue(bool flag);
    void setShowYRightScaleValue(bool flag);
    void addFirstPointDataToList(QListf_firstlist);
    void addFirstPointDataToList(int f_firstvalue);
    void addSecondPointDataToList(QListf_firstlist);
    void addSecondPointDataToList(int f_firstvalue);
    void setFirstCurvePolygon(bool flag);
    void setSecondCurvePolygon(bool flag);
    void clearAllStatu();//初始化,用于重新更新数据进行绘制的时候,需要清理该清理的数据
    void setType(qint32 type);//设置类型
public:

    QPainterPath drawBack(QPainter &painter);//绘制背景色
    void drawOutSideRect(QPainter &painter);//绘制最外边的区域
    void drawInSideRect(QPainter &painter);//绘制曲线所在的区域
    QPainterPath drawInSideRectPath();//绘制曲线所在的区域
    void drawInSideGrid(QPainter &painter);//绘制曲线的网格
    QPainterPath drawGridPath();

    void drawXBottomScale(QPainter &painter);//画x轴下面刻度
    QPainterPath drawXBottomScalePath();

    void drawYLeftScale(QPainter &painter);//画y轴左边刻度
    QPainterPath drawYLeftScalePath();

    void drawXTopScale(QPainter &painter);//画x轴上面刻度
    QPainterPath drawXTopScalePath();

    void drawYRightScale(QPainter &painter);//画y轴右边刻度
    QPainterPath drawYRightScalePath();


    void drawXBottomScaleValue(QPainter &painter);//画x轴下侧刻度值
    void drawYLeftScaleValue(QPainter &painter);  //画y轴左侧刻度值
    void drawXTopScaleValue(QPainter &painter);//画x轴上侧刻度值
    void drawYRightScaleValue(QPainter &painter);  //画y轴右侧刻度值


    void drawFirstLine(QPainter &painter);//左侧开始画第一条线
    QPainterPath drawFirstLineLeftPath();
    QPainterPath drawFirstLineRightPath();

    void drawSecondLine(QPainter &painter);//左侧开始画第2条线
    QPainterPath drawSecondLineLeftPath();
    QPainterPath drawSecondLineRigthPath();

    void drawFirstCurvePolygon(QPainter &painter);  //绘制第一条曲线与x轴的区域进行填充
    void drawSecondCurvePolygon(QPainter &painter);  //绘制第2条曲线与x轴的区域进行填充
    QPolygonF getFirstCurvePolygon();//构建第1条曲线与x轴之间区域进行填充
    QPolygonF getSecondCurvePolygon();//构建第二条曲线与x轴之间区域进行填充

    void setXBottomLabels(const QStringList &labellist);
    void setYLeftLabels(const QStringList &labellist);
    void setYRighttLabels(const QStringList &labellist);

public:
    qint32                  m_yLeftMax,m_yLeftMin,m_yRightMax,m_yRightMin;
    QList           m_defaultcolors;
    qint32                  m_totalPointCount;//点的总个数
    QQueue           m_firstPointList;//第一条曲线的数据点
    QQueue           m_secondPointList;//第2条曲线的数据点
    QPointF                 m_originPoint;//原点所在位置
    QColor                  m_lineColor;//线的颜色
    qint32                  m_firstPointRealCount;//第一条线实际点的个数
    qint32                  m_secondPointRealCount;//第2条线实际点的个数
    qint32                  m_lineType;//用于区分是第一条线还是第二条线
    bool                    bInitPosition;//是否初始化坐标原点
    bool                    bInitXYList;//是否初始化x轴上的文本0-100
    qint32                  m_gridCount_X;//网格x个数
    qint32                  m_gridCount_Y;//网格y个数
    QStringList             m_xBottomLabelList,m_yLeftLabelList,m_yRightLabelList;//坐标轴的文本
    bool                    bStartDrawOnLeft;//画的方式,从左侧还是右侧 默认左侧
    bool                    bShowOutSideRect;//显示外部矩形框
    bool                    bShowInSideRect;//显示曲线所在的矩形框
    QLinearGradient         m_backlinegradent;//背景底色
    qint32                  axisMargin;//曲线的坐标轴边距
    bool                    bShowInSideGrid;//绘制曲线所在的区域的网格
    bool                    bShowXBottomScale;//x轴下面的刻度
    bool                    bShowYLeftScale;//y左侧的刻度
    bool                    bShowXTopScale;//x轴上面的刻度
    bool                    bShowYRightScale;//y右侧的刻度
    bool                    bShowXBottomScaleValue;//x轴下面的刻度值
    bool                    bShowYLeftScaleValue;//y左侧的刻度值
    bool                    bShowXTopScaleValue;//x轴上面的刻度值
    bool                    bShowYRightScaleValue;//y右侧的刻度值
    bool                    bShowFirstCurvePolygon;//第一条曲线与x轴的交集
    bool                    bShowSecondCurvePolygon;//第2条曲线与x轴的交集
    qint32                  m_type;//设置窗口类型,一个是显示10个点数据,一个是显示全部数据的

};

#endif // CSENSORLINE_H
 

//cpp

#include "csensorline.h"

CSensorLine::CSensorLine(QWidget *parent)
    : QWidget{parent}
{
    m_totalPointCount = 10;
    m_gridCount_X = 10;
    m_gridCount_Y = 10;
    m_yLeftMax = 100;
    m_yLeftMin = 0;
    m_yRightMax = 100;
    m_yRightMin = 0;
    m_defaultcolors.append(QColor("#1575bb"));
    m_defaultcolors.append(QColor("#00ff00"));
    m_defaultcolors.append(QColor("#018484"));
    m_defaultcolors.append(QColor("#2ef02e"));
    m_lineColor = QColor("green");
    m_firstPointRealCount = 0;
    m_secondPointRealCount = 0;
    m_lineType = LINE_TYPE_ONE;
    m_firstPointList.clear();
    m_secondPointList.clear();
    bInitPosition = false;
    bInitXYList = false;
    bStartDrawOnLeft = false;
    bShowOutSideRect = false;
    axisMargin = 30;
    bShowInSideRect = false;
    bShowInSideGrid = false;
    bShowXBottomScale = false;
    bShowYLeftScale = false;
    bShowXTopScale = false;
    bShowYRightScale = false;
    bShowXBottomScaleValue = false;
    bShowYLeftScaleValue = false;
    bShowXTopScaleValue = false;
    bShowYRightScaleValue = false;
    bShowFirstCurvePolygon = false;
    bShowSecondCurvePolygon = false;
    m_type = WIDGET_LINE_TYPE_ONE;
    initXYListData();
}

CSensorLine::~CSensorLine()
{

}

void CSensorLine::paintEvent(QPaintEvent * event )
{
    initPosition();

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setRenderHint(QPainter::TextAntialiasing, true);
    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    QFont font;
    font.setPixelSize(10);
    painter.setFont(font);

    drawOutSideRect(painter);
    drawInSideRect(painter);
    drawInSideGrid(painter);
    drawXBottomScale(painter);
    drawYLeftScale(painter);
    drawXTopScale(painter);
    drawYRightScale(painter);
    drawXBottomScaleValue(painter);
    drawYLeftScaleValue(painter);
    drawXTopScaleValue(painter);
    drawYRightScaleValue(painter);
    drawFirstLine(painter);
    drawSecondLine(painter);

#if 1
//分别绘制2条曲线
    drawFirstCurvePolygon(painter);
    drawSecondCurvePolygon(painter);
#else
    // 获取两条曲线的多边形区域,统一绘制2条区域以及交集区域用红色填充
    QPolygonF firstPolygon = getFirstCurvePolygon();
    QPolygonF secondPolygon = getSecondCurvePolygon();

    // 将多边形转换为路径
    QPainterPath firstPath;
    firstPath.addPolygon(firstPolygon);

    QPainterPath secondPath;
    secondPath.addPolygon(secondPolygon);

    // 计算交集路径
    QPainterPath intersectionPath = firstPath.intersected(secondPath);

    // 填充第一条曲线区域
    //painter.fillPath(firstPath, QBrush(Qt::blue));  // 第一条区域填充蓝色
    QColor firstFillColor = Qt::blue;
    firstFillColor.setAlpha(128); // 设置 alpha 值,0 完全透明,255 完全不透明
    painter.fillPath(firstPath, QBrush(firstFillColor));

    // 填充第二条曲线区域
    //painter.fillPath(secondPath, QBrush(Qt::green));  // 第二条区域填充绿色
    QColor secondFillColor = Qt::green;
    secondFillColor.setAlpha(128); // 设置 alpha 值,0 完全透明,255 完全不透明
    painter.fillPath(secondPath, QBrush(secondFillColor));

    // 填充交集区域
    if (!intersectionPath.isEmpty()) {
        //painter.setPen(Qt::NoPen);
        //painter.fillPath(intersectionPath, QBrush(Qt::lightGray));  // 交集区域填充红色
        QColor fillColor = Qt::lightGray;
        fillColor.setAlpha(128); // 设置 alpha 值,0 完全透明,255 完全不透明
        painter.fillPath(intersectionPath, QBrush(fillColor));
    }
#endif
}

//绘制最外边的矩形框
void CSensorLine::drawOutSideRect(QPainter &painter)
{
    if (bShowOutSideRect)
    {
        // 画外框,一个矩形
        painter.save();
        painter.setPen(QPen(Qt::red));
        //painter.setBrush(m_backlinegradent);
        painter.setPen(QPen(QColor("#0864c9"), 1, Qt::SolidLine, Qt::RoundCap));
        painter.drawPath(drawBack(painter));
        painter.restore();
    }
}

//绘制曲线所在的区域,内框矩形
void CSensorLine::drawInSideRect(QPainter &painter)
{
    if(bShowInSideRect)
    {
        painter.save();
        painter.setPen(QPen(QColor(Qt::lightGray)));//#0864c9,Qt::lightGray
        //painter.setPen(QPen(Qt::green));//#0864c9,Qt::lightGray
        //painter.setBrush(m_backlinegradent);//用渐变颜色填充
        //painter.setBrush(m_bgPixmap);//用背景图片来填充,不用的话就是默认的父窗口背景色
        painter.drawPath(drawInSideRectPath());
        painter.restore();
    }
}

//画曲线所在的矩形区域
QPainterPath CSensorLine::drawInSideRectPath()
{
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    QPainterPath XYPathRect;
    //XYPathRect.addRect(m_originPoint.x(),m_originPoint.y()-h,this->width() -m_originPoint.x() ,h);
    XYPathRect.addRect(m_originPoint.x(),m_originPoint.y() - h,w,h);
    return XYPathRect;
}

//绘制曲线的网格线
void CSensorLine::drawInSideGrid(QPainter &painter)
{
    if(bShowInSideGrid)
    {
        painter.save();
        QPen pen;
        pen.setColor(Qt::lightGray);
        pen.setStyle(Qt::DotLine);//画背景虚线
        painter.setPen(pen);
        painter.drawPath(drawGridPath());
        painter.restore();
    }
}

//画曲线所在区域的网格
QPainterPath CSensorLine::drawGridPath()
{
    QPointF oldp(m_originPoint);
    QPainterPath gridding_xypath;
    oldp = m_originPoint;
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    float index = 1.0 * w / m_gridCount_X;
    for (int i = 0; i < m_gridCount_X; ++i)
    {
        oldp.setX(oldp.x() + index);
        gridding_xypath.moveTo(oldp);
        gridding_xypath.lineTo(oldp.x(),oldp.y() - h);
    }

    oldp = m_originPoint;
    index = 1.0 * h / m_gridCount_Y;
    for (int i = 0; i < m_gridCount_Y; ++i)
    {
        oldp.setY(oldp.y() - index);
        gridding_xypath.moveTo(oldp);
        gridding_xypath.lineTo(oldp.x() + w,oldp.y());
    }

    return gridding_xypath;
}

//画x轴下面刻度
void CSensorLine::drawXBottomScale(QPainter &painter)
{
    if(!bShowXBottomScale)return;
    painter.save();
    painter.setPen(QPen(Qt::white));
    painter.drawPath(drawXBottomScalePath());
    painter.restore();
}

QPainterPath CSensorLine::drawXBottomScalePath()
{
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    QPainterPath XYPath;
    //画刻度X
    QPointF oldp(m_originPoint);
    float index = 1.0 * w / m_gridCount_X;
    int tickcount = 1;//每个在细分几个小刻度
    //for (int i = 0; i <= m_gridCount_X; ++i)//如果要使得最后一个值这个地方也画一个刻度就应该<=
    for (int i = 0; i < m_gridCount_X; ++i)
    {
        QPointF tmppoint(oldp);
        float index_tmp = index / tickcount;
        tmppoint.setX(tmppoint.x() + index * i);
        for (int j = 0 ; j < tickcount ;j++)
        {
            QPointF p(tmppoint);
            int d = 0;
            if (j == 0)
                d = 5;

            p.setX(p.x() + index_tmp * j);
            XYPath.moveTo(p);
            p.setY(p.y() + 5 + d);

            XYPath.lineTo(p);

            if(i == m_gridCount_X)
            {
                break;//执行一次就行。这样后面的分割刻度就不会画了。 只会在最后一个值这个地方画一个刻度
            }
        }
    }
    return XYPath;
}

//画y轴左边刻度
void CSensorLine::drawYLeftScale(QPainter &painter)
{
    if(!bShowYLeftScale)return;

    painter.save();
    painter.setPen(QPen(Qt::white));
    painter.drawPath(drawYLeftScalePath());
    painter.restore();
}

QPainterPath CSensorLine::drawYLeftScalePath()
{
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    QPainterPath XYPath;
    QPointF oldp(m_originPoint);
    float index = 1.0 * w / m_gridCount_X;
    int tickcount = 5;
    //画刻度Y-左侧
    index = 1.0 * h / m_gridCount_Y;
    tickcount = 1;
    for (int i = 0; i <= m_gridCount_Y; ++i)    //如果要使得100这个地方也画一个刻度就应该<=
    //for (int i = 0; i < m_gridCount_Y; ++i)
    {
        QPointF tmppoint(oldp);
        float index_tmp = index / tickcount;
        tmppoint.setY(tmppoint.y() - index * i);
        {
            for (int j = 0 ; j < tickcount ;j++)
            {
                QPointF p(tmppoint);
                int d = 0;
                if (j == 0)
                    d = 2;
                p.setY(p.y() - index_tmp * j);
                XYPath.moveTo(p);
                p.setX(p.x() - 5 - d);
                XYPath.lineTo(p);
                if(i == m_gridCount_Y)
                {
                    break;//执行一次就行。这样后面的分割刻度就不会画了。 只会在时间的最后一个值这个地方画一个刻度
                }
            }
        }
    }

    return XYPath;
}

//画x轴上面刻度
void CSensorLine::drawXTopScale(QPainter &painter)
{
    if(!bShowXTopScale)return;
    painter.save();
    painter.setPen(QPen(Qt::white));
    painter.drawPath(drawXTopScalePath());
    painter.restore();
}

QPainterPath CSensorLine::drawXTopScalePath()
{
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    QPainterPath XYPath;
    QPointF oldp(m_originPoint);
    float index = 1.0 * w / m_gridCount_X;
    int tickcount = 5;
    //for (int i = 0; i <= m_gridCount_X; ++i)//如果要使得最后一个值这个地方也画一个刻度就应该<=
    for (int i = 0; i < m_gridCount_X; ++i)
    {
        QPointF tmppoint(oldp);
        float index_tmp = index / tickcount;
        tmppoint.setX(tmppoint.x() + index * i);
        tmppoint.setY(tmppoint.y() - h);

        for (int j = 0 ; j < tickcount ;j++)
        {
            QPointF p(tmppoint);
            int d = 0;
            if (j == 0)
                d = 5;

            p.setX(p.x() + index_tmp * j);
            XYPath.moveTo(p);
            p.setY(p.y() - 5 - d);

            XYPath.lineTo(p);

            if(i == m_gridCount_X)
            {
                break;//执行一次就行。这样后面的分割刻度就不会画了。 只会在时间的最后一个值这个地方画一个刻度
            }
        }
    }
    return XYPath;
}

//画y轴右边刻度
void CSensorLine::drawYRightScale(QPainter &painter)
{
    if(!bShowYRightScale)return;

    painter.save();
    painter.setPen(QPen(Qt::white));
    painter.drawPath(drawYRightScalePath());
    painter.restore();
}

QPainterPath CSensorLine::drawYRightScalePath()
{
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    float index = 1.0 * h / m_gridCount_Y;
    int tickcount = 1;
    QPainterPath XYPath;
    QPointF oldp(m_originPoint);
    for (int i = 0; i <= m_gridCount_Y; ++i)    //如果要使得100这个地方也画一个刻度就应该<=
    //for (int i = 0; i < m_gridCount_Y; ++i)
    {
        QPointF tmppoint(oldp);

        float index_tmp = index / tickcount;
        tmppoint.setY(tmppoint.y() - index * i);
        tmppoint.setX(tmppoint.x() + w);
        {
            for (int j = 0 ; j < tickcount ;j++)
            {
                QPointF p(tmppoint);
                int d = 0;
                if (j == 0)
                    d = 2;
                p.setY(p.y() - index_tmp * j);
                XYPath.moveTo(p);
                p.setX(p.x() + 5 + d);
                XYPath.lineTo(p);
                if(i == m_gridCount_Y)
                {
                    break;//执行一次就行。这样后面的分割刻度就不会画了。 只会在时间的最后一个值这个地方画一个刻度
                }
            }
        }
    }

    return XYPath;
}

//画x轴下侧刻度值
void CSensorLine::drawXBottomScaleValue(QPainter &painter)
{
    if (m_xBottomLabelList.isEmpty() || !bShowXBottomScaleValue)
        return;
    painter.save();
    painter.setPen(QPen(Qt::lightGray));

    int w = width() - axisMargin * 2;

    QPointF oldp(m_originPoint);
    int p_height = 15;
    int index = w / (m_xBottomLabelList.count() - 1);
    for (int i = 0; i < m_xBottomLabelList.count(); ++i)
    {
        QString textstr = m_xBottomLabelList.at(i);

        QPointF p(oldp);
        p.setY(p.y() + 10);

        float x = p.x() + index * i - 0;
        float y = p.y();

        QRectF p_rect(x,y,textstr.length() * 10,p_height);
        painter.drawText(p_rect, Qt::AlignTop, textstr);
    }
    painter.restore();
}

//画y轴左侧刻度值
void CSensorLine::drawYLeftScaleValue(QPainter &painter)
{
    if (m_yLeftLabelList.isEmpty() || !bShowYLeftScaleValue)
        return;
    painter.save();
    painter.setPen(QPen(QColor("#1575bb")));

    int h = height() - axisMargin * 2;
    QPointF oldp(m_originPoint);
    int p_height = 15;
    int index = h / (m_yLeftLabelList.count() - 1);
    for (int i = 0; i < m_yLeftLabelList.count(); ++i)
    {
        QString textstr = m_yLeftLabelList.at(i);
        QPointF p(oldp);

        float x = p.x() - p_height * textstr.length() - 10;//-10
        float y = p.y() - index * i - 10;//-10

        QRectF p_rect(x,y,p_height * textstr.length(),20);

        painter.drawText(p_rect, Qt::AlignRight, textstr);
    }
    painter.restore();
}

//画x轴上侧刻度值
void CSensorLine::drawXTopScaleValue(QPainter &painter)
{
    if (m_xBottomLabelList.isEmpty() || !bShowXTopScaleValue)
        return;
    painter.save();
    painter.setPen(QPen(Qt::lightGray));

    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;

    QPointF oldp(m_originPoint);
    int p_height = 15;
    int index = w / (m_xBottomLabelList.count() - 1);
    for (int i = 0; i < m_xBottomLabelList.count(); ++i)
    {
        QString textstr = m_xBottomLabelList.at(i);

        QPointF p(oldp);
        p.setY(p.y() - 20 - h);

        float x = p.x() + index * i - 0;
        float y = p.y();

        QRectF p_rect(x,y,textstr.length() * 10,p_height);
        painter.drawText(p_rect, Qt::AlignTop, textstr);
    }
    painter.restore();
}

//画y轴右侧刻度值
void CSensorLine::drawYRightScaleValue(QPainter &painter)
{
    if (m_yRightLabelList.isEmpty() || !bShowYRightScaleValue)
        return;
    painter.save();
    painter.setPen(QPen(Qt::green));

    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    QPointF oldp(m_originPoint);
    int p_height = 15;
    int index = h / (m_yRightLabelList.count() - 1);
    for (int i = 0; i < m_yRightLabelList.count(); ++i)
    {
        QString textstr = m_yRightLabelList.at(i);
        QPointF p(oldp);

        float x = p.x() - p_height * textstr.length() + 20 + w;//-10
        float y = p.y() - index * i - 10;//-10

        QRectF p_rect(x,y,p_height * textstr.length(),20);

        painter.drawText(p_rect, Qt::AlignRight, textstr);
    }
    painter.restore();
}

//左侧开始画第一条线
void CSensorLine::drawFirstLine(QPainter &painter)
{
    QColor color;
    painter.save();
    painter.setBrush(Qt::green);
    if(m_lineType == 0){
        color = m_defaultcolors.at(0);
    }else if(m_lineType == 1)
    {
        color = m_defaultcolors.at(2);
    }
    if (bStartDrawOnLeft)  //左侧开始
    {
        painter.setPen(QPen(color));
        painter.drawPath(drawFirstLineLeftPath());
    }
    else
    {
        painter.setPen(QPen(color));
        painter.drawPath(drawFirstLineRightPath());
    }
    painter.restore();
}

QPainterPath CSensorLine::drawFirstLineLeftPath()
{
    QPainterPath linepath;
    linepath.setFillRule(Qt::WindingFill);
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    float xstep = 1.0 * w / m_totalPointCount;
    float ystep = 1.0 * h / (m_yLeftMax - m_yLeftMin);
    if (m_firstPointList.isEmpty()) return linepath;
    if (m_firstPointList.count() == 1)
    {
        int x1=m_originPoint.x();
        int y1=m_originPoint.y() - ystep * m_firstPointList.at(0);
        linepath.moveTo(m_originPoint.x(),m_originPoint.y() - ystep * m_firstPointList.at(0));
        linepath.lineTo(m_originPoint.x() + 0,m_originPoint.y() - ystep * m_firstPointList.at(0));

    }else{
        for (int i = 0 ; i < m_firstPointList.count() - 1; ++i)
        {
            linepath.moveTo(m_originPoint.x() + xstep * i,m_originPoint.y() - ystep * m_firstPointList.at(i));
            linepath.lineTo(m_originPoint.x() + xstep * i + xstep,m_originPoint.y() - ystep * m_firstPointList.at(i+1));

        }
    }

    return linepath;
}

QPainterPath CSensorLine::drawFirstLineRightPath()
{
    QPainterPath linepath;
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    float xstep = 1.0 * w / m_totalPointCount;
    float ystep = 1.0 * h / (m_yLeftMax - m_yLeftMin);
    if (m_firstPointList.isEmpty()) return linepath;
    if (m_firstPointList.count() == 1)
    {
        linepath.moveTo(m_originPoint.x() + w,m_originPoint.y() - ystep * m_firstPointList.at(0));
        linepath.lineTo(m_originPoint.x() + w - 0,m_originPoint.y() - ystep * m_firstPointList.at(0));
        return linepath;
    }

    for (int i = m_firstPointList.count() - 1 ; i > 0; --i)
    {
        linepath.moveTo(m_originPoint.x() + w - xstep * i,m_originPoint.y() - ystep * m_firstPointList.at(i));
        linepath.lineTo(m_originPoint.x() + w - xstep * i + xstep,m_originPoint.y() - ystep * m_firstPointList.at(i - 1));
    }
    return linepath;
}

//左侧开始画第2条线
void CSensorLine::drawSecondLine(QPainter &painter)
{
    QColor color;
    painter.save();
    if(m_lineType == 0){
        color = m_defaultcolors.at(1);
    }else if(m_lineType == 1)
    {
        color = m_defaultcolors.at(3);
    }
    if (bStartDrawOnLeft)  //左侧开始
    {
        painter.setPen(QPen(color));
        painter.drawPath(drawSecondLineLeftPath());
    }
    else
    {
        painter.setPen(QPen(color));
        painter.drawPath(drawSecondLineRigthPath());
    }
    painter.restore();
}

QPainterPath CSensorLine::drawSecondLineLeftPath()
{
    QPainterPath linepath;
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    float xstep = 1.0 * w / m_totalPointCount;
    float ystep = 1.0 * h / (m_yLeftMax - m_yLeftMin);
    if (m_secondPointList.isEmpty()) return linepath;
    if (m_secondPointList.count() == 1)
    {
        linepath.moveTo(m_originPoint.x(),m_originPoint.y() - ystep * m_secondPointList.at(0));
        linepath.lineTo(m_originPoint.x() + 5,m_originPoint.y() -ystep * m_secondPointList.at(0));
        return linepath;
    }
    for (int i = 0 ; i < m_secondPointList.count() - 1; ++i)
    {
        linepath.moveTo(m_originPoint.x() + xstep * i,m_originPoint.y() - ystep * m_secondPointList.at(i));
        linepath.lineTo(m_originPoint.x() + xstep * i + xstep,m_originPoint.y() - ystep * m_secondPointList.at(i + 1));
    }
    return linepath;
}

QPainterPath CSensorLine::drawSecondLineRigthPath()
{
    QPainterPath linepath;
    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    float xstep = 1.0 * w / m_totalPointCount;
    float ystep = 1.0 * h / (m_yLeftMax - m_yLeftMin);
    if (m_secondPointList.isEmpty()) return linepath;
    if (m_secondPointList.count() == 1)
    {
        linepath.moveTo(m_originPoint.x() + w,m_originPoint.y() - ystep * m_secondPointList.at(0));
        linepath.lineTo(m_originPoint.x() + w - 5,m_originPoint.y() -ystep * m_secondPointList.at(0));
        return linepath;
    }

    for (int i = m_secondPointList.count() - 1 ; i > 0; --i)
    {
        linepath.moveTo(m_originPoint.x() + w - xstep * i,m_originPoint.y() - ystep * m_secondPointList.at(i));
        linepath.lineTo(m_originPoint.x() + w - xstep * i + xstep,m_originPoint.y() -ystep * m_secondPointList.at(i - 1));
    }
    return linepath;
}

//绘制第一条曲线与x轴的区域进行填充
void CSensorLine::drawFirstCurvePolygon(QPainter &painter)
{
    if(!bShowFirstCurvePolygon)return;
    QPolygonF firstpolygon = getFirstCurvePolygon();
    if(!firstpolygon.isEmpty())
    {
        painter.setPen(Qt::NoPen);
        painter.setBrush(QColor(0, 0, 255, 128));
        painter.drawPolygon(firstpolygon);
    }
}

//绘制第2条曲线与x轴的区域进行填充
void CSensorLine::drawSecondCurvePolygon(QPainter &painter)
{
    if(!bShowSecondCurvePolygon)return;
    QPolygonF secondpolygon = getSecondCurvePolygon();
    if(!secondpolygon.isEmpty())
    {
        painter.setPen(Qt::NoPen);
        painter.setBrush(QColor(0, 255, 0, 128));
        painter.drawPolygon(secondpolygon);
    }
}

//构建第1条曲线与x轴之间区域进行填充
QPolygonF CSensorLine::getFirstCurvePolygon()
{
    QPolygonF poly;

    if (m_firstPointList.isEmpty())
        return poly;

    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    float xstep = 1.0 * w / m_totalPointCount;
    float ystep = 1.0 * h / (m_yLeftMax - m_yLeftMin);

    // 曲线上的点
    for (int i = 0; i < m_firstPointList.size(); ++i) {
        float val = m_firstPointList[i];
        qreal x = m_originPoint.x() + xstep * i;
        qreal y = m_originPoint.y() - ystep * val;
        poly << QPointF(x, y);
    }

    // 回到 X 轴上的点
    for (int i = m_firstPointList.size() - 1; i >= 0; --i) {
        qreal x = m_originPoint.x() + xstep * i;
        poly << QPointF(x, m_originPoint.y());
    }

    return poly;
}

QPolygonF CSensorLine::getSecondCurvePolygon()
{
    QPolygonF poly;

    if (m_secondPointList.isEmpty())
        return poly;

    int w = width() - axisMargin * 2;
    int h = height() - axisMargin * 2;
    float xstep = 1.0 * w / m_totalPointCount;
    float ystep = 1.0 * h / (m_yLeftMax - m_yLeftMin);

    // 曲线上的点
    for (int i = 0; i < m_secondPointList.size(); ++i) {
        float val = m_secondPointList[i];
        qreal x = m_originPoint.x() + xstep * i;
        qreal y = m_originPoint.y() - ystep * val;
        poly << QPointF(x, y);
    }

    // 回到 X 轴上的点
    for (int i = m_secondPointList.size() - 1; i >= 0; --i) {
        qreal x = m_originPoint.x() + xstep * i;
        poly << QPointF(x, m_originPoint.y());
    }

    return poly;
}


// 画背景颜色,也可以用图片
QPainterPath CSensorLine::drawBack(QPainter &painter)
{
    QPainterPath XYPathRect;
    XYPathRect.addRect(0, 0, width(), height());
    return XYPathRect;
}

void CSensorLine::initPosition()
{
    m_originPoint.setX(axisMargin);
    m_originPoint.setY(height() - axisMargin);
}

void CSensorLine::initXYListData()
{
    m_xBottomLabelList.clear();
    if (bStartDrawOnLeft)
    {
        for (int i = 0; i < 11; ++i)
        {
            QString str = QString::number(i + 1); // 10段,下标就是1-11
            m_xBottomLabelList << QString("%1").arg(str);
        }
    }

    m_yLeftLabelList.clear();
    float yLeftstep = 1.0 * (m_yLeftMax - m_yLeftMin) / 10;
    for (int i = 0; i < 11; ++i)
    {
        m_yLeftLabelList << QString("%1").arg(m_yLeftMin + yLeftstep * i);
    }

    m_yRightLabelList.clear();
    float yRightstep = 1.0 * (m_yRightMax - m_yRightMin) / 10;
    for (int i = 0; i < 11; ++i)
    {
        m_yRightLabelList << QString("%1").arg(m_yRightMin + yRightstep * i);
    }
}

void CSensorLine::mousePressEvent(QMouseEvent *event)
{

}

void CSensorLine::mouseMoveEvent(QMouseEvent *event)
{

}

void CSensorLine::mouseReleaseEvent(QMouseEvent *event)
{

}

void CSensorLine::setShowOutSideRect(bool flag)
{
    bShowOutSideRect = flag;
    update();
}

void CSensorLine::setShowInSideRect(bool flag)
{
    bShowInSideRect = flag;
    update();
}

void CSensorLine::setShowInSideGrid(bool flag)
{
    bShowInSideGrid = flag;
    update();
}

void CSensorLine::setShowXBottomScale(bool flag)
{
    bShowXBottomScale = flag;
    update();
}

void CSensorLine::setShowYLeftScale(bool flag)
{
    bShowYLeftScale = flag;
    update();
}

void CSensorLine::setShowXTopScale(bool flag)
{
    bShowXTopScale = flag;
    update();
}

void CSensorLine::setShowYRightScale(bool flag)
{
    bShowYRightScale = flag;
    update();
}

void CSensorLine::setShowXBottomScaleValue(bool flag)
{
    bShowXBottomScaleValue = flag;
    update();
}

void CSensorLine::setShowYLeftScaleValue(bool flag)
{
    bShowYLeftScaleValue = flag;
    update();
}

void CSensorLine::setShowXTopScaleValue(bool flag)
{
    bShowXTopScaleValue = flag;
    update();
}

void CSensorLine::setShowYRightScaleValue(bool flag)
{
    bShowYRightScaleValue = flag;
    update();
}

void CSensorLine::setStartDrawOnLeft(bool flag)
{
    bStartDrawOnLeft = flag;
    update();
}

void CSensorLine::setYLeftMinMax(qint32 min,qint32 max)
{
    m_yLeftMax = max;
    m_yLeftMin = min;
}

void CSensorLine::setYRightMinMax(qint32 min,qint32 max)
{
    m_yRightMax = max;
    m_yRightMin = min;
}

void CSensorLine::setBackColor(QLinearGradient linegradent)
{
    m_backlinegradent = linegradent;
    m_backlinegradent.setStart(QPointF(width() / 2, 0));
    m_backlinegradent.setFinalStop(QPointF(width() / 2, height()));
}

void CSensorLine::setTotalPointCount(qint32 count)
{
    m_totalPointCount = count;
    update();
}

void CSensorLine::addFirstPointDataToList(QList f_firstlist)
{
    for (int i = 0 ; i < f_firstlist.count(); ++i)
    {
        addFirstPointDataToList(f_firstlist.at(i));
    }
}

void CSensorLine::addFirstPointDataToList(int f_firstvalue)
{
    qint32 ptemp_count = m_totalPointCount / 10;

    if(m_firstPointRealCount < m_totalPointCount){
        m_firstPointList.enqueue(f_firstvalue);
        m_firstPointRealCount = m_firstPointRealCount + 1;
    }else{
        for(int i = 0; i < ptemp_count; i++)
        {
            m_firstPointList.dequeue();//长江后浪推前浪:前消后加,每次更新对应的数据,把前面的数据给删除掉
        }
        m_firstPointRealCount = m_totalPointCount - ptemp_count;
        m_firstPointList.enqueue(f_firstvalue);
        m_firstPointRealCount = m_firstPointRealCount + 1;
    }
    update();//如果是2条线一起画,那就在第二条数据添加的地方更新
}


void CSensorLine::addSecondPointDataToList(QListf_secondlist)
{
    for (int i = 0 ; i < f_secondlist.count(); ++i)
    {
        addSecondPointDataToList(f_secondlist.at(i));
    }
}

void CSensorLine::addSecondPointDataToList(int f_secondvalue)
{
    qint32 ptemp_count = m_totalPointCount / 10;

    if(m_secondPointRealCount < m_totalPointCount){
        m_secondPointList.enqueue(f_secondvalue);
        m_secondPointRealCount = m_secondPointRealCount + 1;
    }else{
        for(int i = 0; i < ptemp_count; i++)
        {
            m_secondPointList.dequeue();//长江后浪推前浪:前消后加,每次更新对应的数据,把前面的数据给删除掉
        }
        m_secondPointRealCount = m_totalPointCount - ptemp_count;
        m_secondPointList.enqueue(f_secondvalue);
        m_secondPointRealCount = m_secondPointRealCount + 1;
    }
    update();
}

void CSensorLine::setFirstCurvePolygon(bool flag)
{
    bShowFirstCurvePolygon = flag;
    update();
}

void CSensorLine::setSecondCurvePolygon(bool flag)
{
    bShowSecondCurvePolygon = flag;
    update();
}

//初始化,用于重新更新数据进行绘制的时候,需要清理该清理的数据
void CSensorLine::clearAllStatu()
{
    m_firstPointList.clear();
    m_secondPointList.clear();
    m_firstPointRealCount = 0;
    m_secondPointRealCount = 0;
    bInitPosition = false;
    bInitXYList = false;
    //xy坐标标签也要清理
    initXYListData();
}

void CSensorLine::setXBottomLabels(const QStringList &labellist)
{
    m_xBottomLabelList.clear();
    m_xBottomLabelList = labellist;
    update();
}

void CSensorLine::setYLeftLabels(const QStringList &labellist)
{
    m_yLeftLabelList.clear();
    m_yLeftLabelList = labellist;
    update();
}

void CSensorLine::setYRighttLabels(const QStringList &labellist)
{
    m_yRightLabelList.clear();
    m_yRightLabelList = labellist;
    update();
}

//设置类型
void CSensorLine::setType(qint32 type)
{
    m_type = type;
}
 

你可能感兴趣的:(qt)