Qt developed using QCustomPlot

1. Getting Started

1. Download the source file http://www.qcustomplot.com/;

2. Place .cpp and .h in the project directory, and add cpp and h to the project;

3. In .pro: QT + = printsupport;

4. Add a Widget in the ui, right-click and raise to, enter: QCustomPlot, change the object name to customPlot;

5. Add code:

void MainWindow::initUi()

{

QVector x(101), y(101); // initialize with entries 0..100

for (int i=0; i<101; + + i)

{

x[i] = i/50.0 – 1; // x goes from -1 to 1

y[i] = x[i]*x[i]; // let’s plot a quadratic function

}

ui->customPlot->addGraph();//Add data curve (one image can have multiple data curves), graph(0); you can get a certain data curve (sorted by adding); default x1, y1 axis

ui->customPlot->addGraph(ui->customPlot->xAxis,ui->customPlot->yAxis2);//The added curve takes x1 and y2 as the reference axis

ui->customPlot->graph(0)->setData(x, y);// setData(); associates data with the data curve

ui->customPlot->xAxis->setLabel(“x”); // Add labels to the axis

ui->customPlot->yAxis->setLabel(“y”);

ui->customPlot->xAxis->setRange(-1, 1);//Set the range of the coordinate axis to see all data

ui->customPlot->yAxis->setRange(-1, 1);

ui->customPlot->replot();//Redraw the image

//ui->customPlot->rescaleAxes();//Automatically set the most appropriate display range

//ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);//Mobile and drag-and-drop

//ui->customPlot->graph(0)->addData(double,double);//Add points

}

Effect:

6: Add help documentation for QCustomPlot

There is a qch file in the downloaded source code package. Place it in: D:\QT5.8\Docs\Qt-5.8, and you can use the help document.

ps:

1. Set the x-axis to time

int showTime=60;//60 seconds
QDateTime dateTime = QDateTime::currentDateTime();
<strong>double now =</strong><strong> dateTime.toTime_t();</strong>
QSharedPointer<QCPAxisTickerDateTime> xTicker(new QCPAxisTickerDateTime);
xTicker->setTickCount(2);
xTicker->setDateTimeFormat("yyyy.MM.dd-hh:mm");//
ui->customPlot_4_1->xAxis->setTicker(xTicker);
xTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
ui->customPlot_4_1->xAxis->setRange(now-showTime,now + showTime);//How long to display the data, 60 seconds before and after

The minimum unit is seconds

2. Set the location

setPositionAlignment(Qt::AlignTop)

3. Coordinate axis scale style

Use QCPAxis::setTicker (QSharedPointer) to customize the tick

4. Set the scale height

setTickLength

5. Set the coordinate axis style

setUpperEnding

6. Set the padding between two lines

ui->customplot->graph(0)->setBrush(Qt::cyan);

ui->customplot->graph(0)->setChannelFillGraph(ui->customplot_2_1->graph(1));

7. Set the curve shape

QCPGraph::setScatterStyle(QCPScatterStyle & amp;style);

8. Naming of coordinate axis related parameters

9. Name the relevant distance of the axes area

9.1. Set the distance of the entire cp coordinate axis from the left side

ui.customPlot->yAxis->setPadding(40);//Distance from the left

10. Set the scale label rotation

ui.customPlot->xAxis->setTickLabelRotation(60);

11. Set the coordinate axis direction

ui.customPlot->xAxis->setRangeReversed(false);//x-axis reversed

12. Get the left and right values of the current x and y axis range

realLeft = ui.customPlot->xAxis->range().lower;
realRight = ui.customPlot->xAxis->range().upper;

13. Set how many scales the current display range has

ticker->setTickCount(n);

ui->customplot_2_3->xAxis->ticker()->setTickCount(5);

14. Set the long scale step size

QCPAxisTickerFixed ticker->setTickStep(0.1);

15. Timeline customization

QDateTime dateTime = QDateTime::currentDateTime();
double now = dateTime.toTime_t();
QSharedPointer<QCPAxisTickerDateTime> yTicker(new QCPAxisTickerDateTime);
yTicker->setTickCount(2);
yTicker->setDateTimeFormat("yyyy.MM.dd-hh:mm");//
ui->customPlot->xAxis->setTicker(yTicker);
yTicker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
ui->customPlot->xAxis->setRange(now-3600,now + 3600);//Display 3 hours of data

The default tickStep is 1s, so there is no setTickStep function to set it.

Generally, coordinate axis customization requires two parameters: the coordinate axis display range [range]; how many ticks this coordinate axis has [setTickCount]

16. QCPAbstractItem

17. Sketch 2 points after drawing one point

customPlot->graph(0)->setScatterSkip(2);

18. Set location

①、

itemText_2_2->position->setType(QCPItemPosition::ptPlotCoords);//Using the coordinate point as a reference

itemText_2_2->position->setCoords(100,200);//x=100,y=200

②、

itemText_2_2->position->setType(QCPItemPosition::ptAxisRectRatio);//Use 0~1 ratio to represent the entire plot

itemText_2_2->position->setCoords(1,1);//lower right corner

18. Legend settings are transparent

ui->customplot_5_1->legend->setBrush(QColor(255,255,255,0));

19. Clear the data that has been drawn for a certain line [the line is not recycled]

pPlot->graph(0)->data().data()->clear();

Note that there are two data

20. Set the background to be transparent

ui->customplot_deduce_radar->setBackground(Qt::transparent);
ui->customplot_deduce_radar->setStyleSheet("background: transparent;");

Reference: https://www.pianshen.com/article/60931360320/

2. Advanced

1. Single-level histogram [only one color]

①, Bar statement

QCPBars *cpBar;

②、Definition

cpBar = new QCPBars(ui.customPlot->xAxis, ui.customPlot->yAxis);

③、Set value

QVector ticks;//Customized value
ticks << 1 << 2 << 3 << 4;
QVector yCount;

yCount<<2<<3<<3<<1;

cpBar->setData(ticks, yCount);
ui.customPlot->replot();

④. Effect

2. Multi-level histogram

Let’s see the effect first【Official website】

①. Statement

QCPBars *max;
QCPBars *min;
QCPBars *sdDev;
QCPBars *varice;

②、Definition

max = new QCPBars(ui.customPlot->xAxis, ui.customPlot->yAxis);
min = new QCPBars(ui.customPlot->xAxis, ui.customPlot->yAxis);
sdDev = new QCPBars(ui.customPlot->xAxis, ui.customPlot->yAxis);
varice = new QCPBars(ui.customPlot->xAxis, ui.customPlot->yAxis);

③、Related settings

max->setStackingGap(0);//Set the distance between the upper and lower bars
min->setStackingGap(0);
sdDev->setStackingGap(0);
varice->setStackingGap(0);
max->setAntialiased(false); //Provide clearer, pixel-aligned bar borders
min->setAntialiased(false);
sdDev->setAntialiased(false);
varice->setAntialiased(false);

sdDev->moveAbove(varice);//Must be written with this, otherwise it will not overlap
min->moveAbove(sdDev);//Set the position
max->moveAbove(min);

④、Set value

QVector ticks;//Customized value
ticks << 1 << 2 << 3 << 4;
QVector yCount;

yCount<<2<<3<<3<<1;

max->setData(ticks, yCount);

min->setData(ticks, yCount);

varice->setData(ticks, yCount);

sdDev->setData(ticks, yCount);
ui.customPlot->replot();

3. Better-looking grid lines

①.Default

②、Customization

ui.customPlot->xAxis->grid()->setVisible(true);
ui.customPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine));

ui.customPlot->yAxis->grid()->setSubGridVisible(true);
ui.customPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine));
ui.customPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine));

4. Mouse events

In the header file:

void myMousePressEvent(QMouseEvent *event);
void myMouseReleaseEvent(QMouseEvent *event);

Binding:

connect(ui.customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(myMousePressEvent(QMouseEvent*)));
connect(ui.customPlot, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(myMouseReleaseEvent(QMouseEvent*)));

accomplish:

void RoadAllData::myMousePressEvent(QMouseEvent *event)
{
if (event->button() != Qt::LeftButton)return;//Return if the left mouse button is not pressed
int x_pos = event->pos().x();
int y_pos = event->pos().y();

//Convert the mouse coordinate point to QCustomPlot internal coordinate value (pixelToCoord function)
// The coordToPixel function is the opposite, it converts the internal coordinate value into an external coordinate point
double x_val = ui.customPlot->xAxis->pixelToCoord(x_pos);
double y_val = ui.customPlot->yAxis->pixelToCoord(y_pos);

}

void RoadAllData::myMouseReleaseEvent(QMouseEvent *event)
{
?if (event->button() != Qt::LeftButton)return;
}

5. Use of textitem

①. Statement

QCPItemText* itemText = NULL;

②、Definition

 QCPItemText* itemText = new QCPItemText(ui->customplot_1_1);
    itemText->setPositionAlignment(Qt::AlignHCenter | Qt::AlignBottom);//Which position is used as the standard
    itemText->position->setType(QCPItemPosition::ptAxisRectRatio);//Using the visible range of the screen as a reference
    itemText->position->setCoords(0.5, 0.95); //Position, starting from the upper left corner of the coordinate rectangle is (0,0), the lower right corner is (1,1), x is to the right, y is downward
    itemText->setFont(QFont(font().family(), 12)); //Font library, size
    itemText->setTextAlignment(Qt::AlignLeft);
#if CLOSE_IF
    itemText->setPen(QPen(Qt::black)); //Border
#endif
    itemText->setText("Gain decreased by 0.225dB\
Pointing deviation 0°\
Beam broadened by 4.9954%\
Side lobe increased by 7.353dB");//
    itemText->setBrush(QBrush(QColor("#C4DDC3")));//Background color
    itemText->setPadding(QMargins(3, 3, 3, 3));

For related settings, please refer to: https://blog.csdn.net/umke888/article/details/54572647

③、Set value

itemText->setText(“…”);

6. QSlider corresponds to the display range

① Use QSlider to press, release, and get values

 QObject::connect(ui.horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMovedSlot(int)));
    QObject::connect(ui.horizontalSlider, SIGNAL(sliderPressed()), this, SLOT(sliderPressSlot()));
    QObject::connect(ui.horizontalSlider, SIGNAL(sliderReleased()), this, SLOT(sliderReleaseSlot()));

②. Display the current position of Custommplot by setting the range.

ui.customPlot->xAxis->setRange(realMax, realMax );

7. Example, online user statistics

ui->customplot_online->setBackground(QColor(34,38,72));
ui->customplot_online->xAxis->setBasePen(QPen(QColor(34,38,72)));
ui->customplot_online->yAxis->setBasePen(QPen(Qt::white));
ui->customplot_online->xAxis2->setBasePen(QPen(QColor(34,38,72)));
ui->customplot_online->yAxis2->setBasePen(QPen(QColor(34,38,72)));
ui->customplot_online->xAxis->setTickLabelColor(Qt::white);
ui->customplot_online->yAxis->setTickLabelColor(Qt::white);
ui->customplot_online->xAxis->setRange(0,8);
ui->customplot_online->yAxis->setRange(0,10);
ui->customplot_online->xAxis->setSubTicks(false);<br>ui->customplot_online->xAxis->setTickLabels(false);<br>ui->customplot_online->legend->setBrush(QColor(255,255,255,50));//nameplate style; transparent<br>ui->customplot_online->legend->setVisible(true);<br>ui->customplot_online->legend->setTextColor(QColor(255,255,255));<br>ui->customplot_online->legend->setBorderPen(QColor(255,0,0));<br>ui->customplot_online->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignLeft|Qt::AlignTop);//Set the nameplate position<br>ui->customplot_online->addGraph()->setName("Operation Control User");<br>ui->customplot_online->addGraph()->setName("Monitoring User");<br>ui->customplot_online->addGraph()->setName("Operation and Maintenance User");<br>QPen pen; pen.setWidth(2);//Line width pen.setStyle(Qt::PenStyle::DashLine);//Dash line<br>pen.setColor(Qt::yellow); ui->customplot_online->graph(0)->setPen(pen);<br>pen.setColor(Qt::white); ui->customplot_online->graph(1)->setPen(pen);<br>pen.setColor(Qt::green); ui->customplot_online->graph(2)->setPen(pen);<br>ui->customplot_online->graph(0)->setLineStyle(QCPGraph::lsLine);<br>ui->customplot_online->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ScatterShape::ssDisc,5));<br>ui->customplot_online->graph(1)->setLineStyle(QCPGraph::lsLine);<br>ui->customplot_online->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ScatterShape::ssDisc,5));<br>ui->customplot_online->graph(2)->setLineStyle(QCPGraph::lsLine);<br>ui->customplot_online->graph(2)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ScatterShape::ssDisc,5));<br>QVector<double> x,y1,y2,y3; // initialize with entries 0..100<br>x << 0 << 1 << 2 << 3 << 4 << 5;<br>y1 << 3 << 4 << 6 << 7 << 9 << 8;<br>y2 << 1 << 2 << 3 << 5 << 6 << 9;<br>y3 << 3 << 5 << 6 << 4 << 3 << 5;<br>ui->customplot_online->graph(0)->setData(x,y1);<br>ui->customplot_online->graph(1)->setData(x,y2);<br>ui->customplot_online->graph(2)->setData(x,y3);<br>ui->customplot_online->replot();

8. The difference between tick and subtick

9. Example

QFont font;
font.setFamily("Microsoft YaHei");
font.setPixelSize(12);
ui->customplot->setBackground(QColor(1,23,68));
ui->customplot->xAxis->setBasePen(QPen(QColor(202,241,255)));
ui->customplot->yAxis->setBasePen(QPen(QColor(202,241,255)));
ui->customplot->xAxis->setTickLabelColor(QColor(202,241,255));
ui->customplot->yAxis->setTickLabelColor(QColor(202,241,255));
ui->customplot->xAxis->setRange(0,16);
ui->customplot->yAxis->setRange(0,219);
ui->customplot->yAxis->ticker()->setTickCount(10);
ui->customplot->xAxis->setSubTicks(false);
ui->customplot->yAxis->setSubTicks(false);
ui->customplot->xAxis->grid()->setVisible(false);
ui->customplot->yAxis->grid()->setPen(QPen(QColor(22,44,85), 0, Qt::SolidLine));
ui->customplot->xAxis->setTickPen(QPen(QColor(202,241,255)));
ui->customplot->xAxis->setTickLength(0);
ui->customplot->yAxis->setTickPen(QPen(QColor(202,241,255)));
ui->customplot->yAxis->setTickLength(0);
ui->customplot->xAxis->setTickLabelFont(font);
ui->customplot->yAxis->setTickLabelFont(font);
missionBarTotal = new CustomBars(ui->customplot->xAxis,ui->customplot->yAxis);
missionBarZS = new CustomBars(ui->customplot->xAxis,ui->customplot->yAxis);
missionBarZC = new CustomBars(ui->customplot->xAxis,ui->customplot->yAxis);
missionBarTotal->setFont(font);missionBarTotal->setSpacing(0);
missionBarZS->setFont(font);missionBarZS->setSpacing(0);
missionBarZC->setFont(font);missionBarZC->setSpacing(0);
missionBarTotal->setAntialiased(false);
missionBarZS->setAntialiased(false);
missionBarZC->setAntialiased(false);
missionBarTotal->setPen(QPen(QColor(36,201,217)));
missionBarTotal->setBrush(QColor(36,201,217));
missionBarZS->setPen(QPen(QColor(59,172,131)));
missionBarZS->setBrush(QColor(59,172,131));
missionBarZC->setPen(QPen(QColor(189,143,43)));
missionBarZC->setBrush(QColor(189,143,43));
QVector<double> ticks;
ticks << 3 << 8 << 13;
QVector<QString> labels; //Coordinate axis customization
labels << "Total number of tasks" << "Number of ZS tasks" << "Number of ZC tasks";
QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
textTicker->addTicks(ticks,labels);
ui->customplot->xAxis->setTicker(textTicker);

10. Each Bar used above is rewritten and set after inheriting QCpbar. The inherited class name is: CustomBars

①.Header file

#ifndef CUSTOMBARS_H
#define CUSTOMBARS_H


#pragma once

#include <QWidget>
#include "qcustomplot.h"
class CustomBars : public QCPBars
{
    Q_OBJECT

public:
    explicit CustomBars(QCPAxis *keyAxis, QCPAxis *valueAxis);

    Qt::Alignment textAligment() const { return mTextAlignment; }
    double spacing() const { return mSpacing; }
    QFont font() const { return mFont; }

    void setTextAlignment(Qt::Alignment alignment);
    void setSpacing(double spacing);
    void setFont(const QFont & amp;font);
    void setTextValue(const QString & value){
        mTextValue = value;
    }
protected:
    Qt::Alignment mTextAlignment; // Text alignment
    double mSpacing = 10; // The spacing between text and histogram, here based on pixel size
    QFont mFont; // Font used for text
    QString mTextValue;

    virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
};
#endif // CUSTOMBARS_H

②、cpp

#include "custombars.h"

CustomBars::CustomBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
    : QCPBars(keyAxis, valueAxis),
    mTextAlignment(Qt::AlignCenter),
    mSpacing(5),
    mFont(QFont(QLatin1String("sans serif"), 12))
{

}

void CustomBars::setTextAlignment(Qt::Alignment alignment)
{
    mTextAlignment = alignment;
}

void CustomBars::setSpacing(double spacing)
{
    mSpacing = spacing;
}

void CustomBars::setFont(const QFont & amp;font)
{
    mFont = font;
}
void CustomBars::draw(QCPPainter *painter)
{
    if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
    if (mDataContainer->isEmpty()) return;

    QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd;
    getVisibleDataBounds(visibleBegin, visibleEnd);

    // loop over and draw segments of unselected/selected data:
    QList<QCPDataRange> selectedSegments, unselectedSegments, allSegments;
    getDataSegments(selectedSegments, unselectedSegments);
    allSegments << unselectedSegments << selectedSegments;
    for (int i = 0; i < allSegments.size(); + + i)
    {
        bool isSelectedSegment = i >= unselectedSegments.size();
        QCPBarsDataContainer::const_iterator begin = visibleBegin;
        QCPBarsDataContainer::const_iterator end = visibleEnd;
        mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i));
        if (begin == end)
            continue;

        for (QCPBarsDataContainer::const_iterator it = begin; it != end; + + it)
        {
            // draw bar:
            if (isSelectedSegment & amp; & amp; mSelectionDecorator)
            {
                mSelectionDecorator->applyBrush(painter);
                mSelectionDecorator->applyPen(painter);
            }
            else
            {
                painter->setBrush(mBrush);
                painter->setPen(mPen);
            }
            applyDefaultAntialiasingHint(painter);
            QRectF barRect = getBarRect(it->key, it->value); //added by yourself
            painter->drawPolygon(barRect);
            //The above is the copied source code part
            painter->drawPolygon(barRect);

            // We only need to add the following content under the line painter->drawPolygon(barRect);

            // Calculate the position of the text
            painter->setFont(mFont); // Set font
            //QString text = QString::number(it->value); // Get the value of the current value axis, retaining two digits of precision
            QString text = mTextValue;

            QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip | mTextAlignment, text); // Calculate the size occupied by text

            if (mKeyAxis.data()->orientation() == Qt::Horizontal) { // When the key axis is the horizontal axis
                if (mKeyAxis.data()->axisType() == QCPAxis::atTop) // Upper axis, move the text below the histogram
                    textRect.moveTopLeft(barRect.bottomLeft() + QPointF(0, mSpacing));
                else // Lower axis, move the text to the top of the histogram
                    textRect.moveBottomLeft(barRect.topLeft() - QPointF(0, mSpacing));
                textRect.setWidth(barRect.width());
                painter->drawText(textRect, Qt::TextDontClip | mTextAlignment, text);
            }
            else { // When the key axis is the vertical axis
                if (mKeyAxis.data()->axisType() == QCPAxis::atLeft) // Left axis, move the text to the right of the histogram
                    textRect.moveTopLeft(barRect.topRight() + QPointF(mSpacing, 0));
                else // Right axis, move the text to the left of the histogram
                    textRect.moveTopRight(barRect.topLeft() - QPointF(mSpacing, 0));
                textRect.setHeight(barRect.height());
                painter->drawText(textRect, Qt::TextDontClip | mTextAlignment, text);
            }
        }
    }
}

Reference here: https://blog.csdn.net/qq_40501206/article/details/108065801?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-18-108065801.nonecase &utm_term =qcustomplot add text&spm=1000.2123.3001.4430

For reference:

1. Line style: https://blog.csdn.net/yxy244/article/details/100033549

2. To set the color of the line, etc., you can only construct the pen first and cannot return to QPen and then set it. It can be understood that there is no QPen object itself and needs to be set first, otherwise the return is meaningless.