Qt to write custom 25 custom QCustomPlot

I. Introduction

In the last write data visualization big screen digital signage system when mentioned to achieve the transformation QCustomPlot columnar section map, horizontal bar graph, horizontal section map, hover tips. The individual lists are described, there are a lot of people question why do not QChart, or echart other forms, in fact, these two methods I have tried, such as Qt5.7 after the new QChart module, this curve, the amount of data to support it small, and extremely suited to use, very awkward, especially the amount of data than 10W support, simply slag slag, but also has a lot of advantages, such as animation, I read his full source code, this process is very good animation even axes can have animation, and supports a variety of effects, but also built a lot of sets of theme skin, eliminating a lot of slag slag aesthetic programmers themselves to color, this is actually very convenient. For echart, must rely on browser controls, resource consumption is relatively high, behind the transformation of QCustomPlot decided to implement a variety of charts effect user needs.
Throughout the transformation process, all packaged into a user-friendly functions, parameters can be passed, while also supporting global style changes, support for style sheets to control the overall color change, consider a lot of details, such as pop-up hovering position information, etc., are displayed automatically calculates the best and most reasonable position. Taking into account QCustomPlot1.0 a lot of people use, but also specially made fully compatible QCustomPlot1.0 and 2.0.

Second, the realization of functions

  • 1: X and Y axes may be provided a range of values
  • 2: Text can set the background color + + Color Color Mesh
  • 3: Color curve may be provided three color set +
  • 4: can set whether to display the positioning cross lines, horizontal and vertical, respectively, may be provided
  • 5: width and color may be provided crosshairs
  • 6: display size can be set whether the data point and the data point
  • 7: can set whether to fill the background area is formed in FIG.
  • 8: mode can be set - scaling drag +
  • 9: the pitch axis may be provided a second coordinate system visible +
  • 10: provide an interface directly setDataLine curve, a plurality of support
  • 11: provide an interface directly setDataBar histogram, forming a plurality of stacked supports FIG.
  • 12: the interface provides an alternative text label key provided setLabs
  • 13: the interface provides clear + + redraw the object externally acquired QCustomPlot
  • 14: start + stop provides functions to simulate the sinusoidal
  • 15: position value may be set histogram + + Color Accuracy
  • 16: Support point the mouse to move the highlighted data to the data points, and display data message
  • 17: presentation information may be provided to automatically position the upper right corner treatment + + + right top + bottom left bottom right + left + + + bottom left corner
  • 18: checking whether the data set may be produced in different background colors, such as histograms each pillar different background colors can be generated based on the data
  • 19: you can set whether to display the number of rows legend legend position + + Legend
  • 20: Support multiple histogram curve + + + lateral cylindrical section map histogram + + lateral cylindrical section map columnar stacked FIG
  • 21: Built-in 15 sets of exquisite color, automatic color set to take color, eliminating the trouble of color
  • 22: support QCustomPlot 1.0 and QCustomPlot 2.0

Third, renderings

Fourth, the core code

void CustomPlot::setDataLine(int index, const QString &name, const QVector<double> &key, const QVector<double> &value)
{
    if (customPlot->graphCount() > index) {
        customPlot->graph(index)->setName(name);
        customPlot->graph(index)->setData(key, value);
        customPlot->xAxis->setRange(-offsetX, key.count() + offsetX, Qt::AlignLeft);

        //超过3条线条颜色设置颜色集合的颜色
        if (index >= 3) {
            setColor(index, colors.at(index));
        } else {
            setColor(0, colors.at(0));
            setColor(1, colors.at(1));
            setColor(2, colors.at(2));
        }
    }
}

void CustomPlot::setDataBarv(const QStringList &rowNames,
                             const QStringList &columnNames,
                             const QList<QVector<double> > &values,
                             const QColor &borderColor,
                             int valuePosition,
                             int valuePrecision,
                             const QColor &valueColor,
                             bool checkData)
{
    //只有1列的才能设置
    if (columnNames.count() != 1) {
        return;
    }

    //可以直接用堆积图,因为只有一列的柱状图不会形成堆积
    setDataBars(rowNames, columnNames, values, borderColor, valuePosition, valuePrecision, valueColor, checkData);
}

void CustomPlot::setDataBarvs(const QStringList &rowNames,
                              const QStringList &columnNames,
                              const QList<QVector<double> > &values,
                              const QColor &borderColor,
                              int valuePosition,
                              int valuePrecision,
                              const QColor &valueColor,
                              bool checkData)
{
    //过滤个数不一致数据,防止索引越界
    int rowCount = rowNames.count();
    int columnCount = columnNames.count();
    int valueCount = values.count();
    if (columnCount == 0 || valueCount == 0 || columnCount != valueCount) {
        return;
    }

    //设置网格线不显示,会更好看
    customPlot->xAxis->grid()->setVisible(false);
    //customPlot->yAxis->grid()->setVisible(false);

    //设置横坐标文字描述
    QVector<double> ticks;
    QVector<QString> labels;
    int count = rowCount * columnCount;
    for (int i = 0; i < rowCount; i++) {
        ticks << 1.5 + (i * columnCount);
        labels << rowNames.at(i);
    }

    setLabX(ticks, labels);
    customPlot->xAxis->setRange(0, count + 1);

    for (int i = 0; i < columnCount; i++) {
        //同样也要先过滤个数是否符合要求
        QVector<double> value = values.at(i);
        if (rowCount != value.count()) {
            continue;
        }

        //创建柱状图
        CustomBarv *bar = new CustomBarv(customPlot->xAxis, customPlot->yAxis);
        bar->setCheckData(checkData);

        //设置宽度比例
        bar->setWidth(0.9);

        //设置显示值的位置 0-不绘制 1-顶部上面 2-顶部居中 3-中间居中 4-底部居中
        bar->setValuePostion(valuePosition);
        bar->setValuePrecision(valuePrecision);
        bar->setValueColor(valueColor);

        //设置名称
        bar->setName(columnNames.at(i));

        //设置颜色,取颜色集合
        QColor color = QColor(51, 204, 255);
        if (i < colors.count()) {
            color = colors.at(i);
        }

        //边缘高亮,如果传入了边框颜色则取边框颜色
        bar->setPen(QPen(borderColor == Qt::transparent ? color.light(150) : borderColor));
        bar->setBrush(color);

        //这个算法很巧妙,想了很久
        QVector<double> ticks;
        double offset = i * 0.9;
        for (int j = 0; j < rowCount; j++) {
            ticks << 1.0 + (j * columnCount) + offset;
        }

        //设置数据
        bar->setData(ticks, value);
    }
}

void CustomPlot::setDataBarh(const QStringList &rowNames,
                             const QStringList &columnNames,
                             const QList<QVector<double> > &values,
                             const QColor &borderColor,
                             int valuePosition,
                             int valuePrecision,
                             const QColor &valueColor,
                             bool checkData)
{
    //只有1列的才能设置
    if (columnNames.count() != 1) {
        return;
    }

    //过滤个数不一致数据,防止索引越界
    int rowCount = rowNames.count();
    int columnCount = columnNames.count();
    int valueCount = values.count();
    if (columnCount == 0 || valueCount == 0 || columnCount != valueCount) {
        return;
    }

    //设置网格线不显示,会更好看
    customPlot->xAxis->grid()->setVisible(false);
    customPlot->yAxis->grid()->setVisible(false);
    customPlot->yAxis->setTickLength(0, 0);

    //设置横坐标文字描述
    QVector<double> ticks;
    QVector<QString> labels;
    int count = rowCount * columnCount;
    double padding = 1;
    for (int i = 0; i < rowCount; i++) {
        ticks << padding + (i * columnCount);
        labels << rowNames.at(i);
    }

    setLabY(ticks, labels);
    customPlot->yAxis->setRange(0, count + 1);

    //先计算出每个柱子占用的高度
    double barHeight = 0.7;
    for (int i = 0; i < columnCount; i++) {
        //同样也要先过滤个数是否符合要求
        QVector<double> value = values.at(i);
        if (rowCount != value.count()) {
            continue;
        }

        //先绘制系列1的数据,再绘制系列2,依次类推
        for (int j = 0; j < rowCount; j++) {
            //创建横向柱状图
            double y = (0.67 + (j * columnCount));
            CustomBarh *bar = new CustomBarh(customPlot);
            bar->setCheckData(checkData);
            bar->setRect(QPointF(0, y), QPointF(value.at(j), y + barHeight));
            bar->setValue(value.at(j));

            //设置显示值的位置 0-不绘制 1-顶部上面 2-顶部居中 3-中间居中 4-底部居中
            bar->setValuePostion(valuePosition);
            bar->setValuePrecision(valuePrecision);
            bar->setValueColor(valueColor);

            //设置颜色,取颜色集合
            QColor color = QColor(51, 204, 255);
            if (i < colors.count()) {
                color = colors.at(i);
            }

            //边缘高亮,如果传入了边框颜色则取边框颜色
            bar->setPen(QPen(borderColor == Qt::transparent ? color.light(150) : borderColor));
            bar->setBrush(color);
        }
    }
}

void CustomPlot::setDataBarhs(const QStringList &rowNames,
                              const QStringList &columnNames,
                              const QList<QVector<double> > &values,
                              const QColor &borderColor,
                              int valuePosition,
                              int valuePrecision,
                              const QColor &valueColor,
                              bool checkData)
{
    //过滤个数不一致数据,防止索引越界
    int rowCount = rowNames.count();
    int columnCount = columnNames.count();
    int valueCount = values.count();
    if (columnCount == 0 || valueCount == 0 || columnCount != valueCount) {
        return;
    }

    //设置网格线不显示,会更好看
    customPlot->xAxis->grid()->setVisible(false);
    customPlot->yAxis->grid()->setVisible(false);
    customPlot->yAxis->setTickLength(0, 0);
    customPlot->xAxis->setVisible(false);

    //设置横坐标文字描述
    QVector<double> ticks;
    QVector<QString> labels;
    int count = rowCount * columnCount;
    //这个算法想了很久,很牛逼
    double padding = 1.5 + (columnCount - 2) * 0.4;
    for (int i = 0; i < rowCount; i++) {
        ticks << padding + (i * columnCount);
        labels << rowNames.at(i);
    }

    setLabY(ticks, labels);
    customPlot->yAxis->setRange(0, count + 1);

    //先计算出每个柱子占用的高度
    double barHeight = 0.8;
    for (int i = 0; i < columnCount; i++) {
        //同样也要先过滤个数是否符合要求
        QVector<double> value = values.at(i);
        if (rowCount != value.count()) {
            continue;
        }

        //先绘制系列1的数据,再绘制系列2,依次类推
        for (int j = 0; j < rowCount; j++) {
            //创建横向柱状图
            double y = (0.7 + i * barHeight + (j * columnCount));
            CustomBarh *bar = new CustomBarh(customPlot);
            bar->setCheckData(checkData);
            bar->setRect(QPointF(0, y), QPointF(value.at(j), y + barHeight));
            bar->setValue(value.at(j));

            //设置显示值的位置 0-不绘制 1-顶部上面 2-顶部居中 3-中间居中 4-底部居中
            bar->setValuePostion(valuePosition);
            bar->setValuePrecision(valuePrecision);
            bar->setValueColor(valueColor);

            //设置颜色,取颜色集合
            QColor color = QColor(51, 204, 255);
            if (j < colors.count()) {
                color = colors.at(j);
            }

            //边缘高亮,如果传入了边框颜色则取边框颜色
            bar->setPen(QPen(borderColor == Qt::transparent ? color.light(150) : borderColor));
            bar->setBrush(color);
        }
    }
}

void CustomPlot::setDataBars(const QStringList &rowNames,
                             const QStringList &columnNames,
                             const QList<QVector<double> > &values,
                             const QColor &borderColor,
                             int valuePosition,
                             int valuePrecision,
                             const QColor &valueColor,
                             bool checkData)
{
    //过滤个数不一致数据,防止索引越界
    int rowCount = rowNames.count();
    int columnCount = columnNames.count();
    int valueCount = values.count();
    if (columnCount == 0 || valueCount == 0 || columnCount != valueCount) {
        return;
    }

    //设置网格线不显示,会更好看
    customPlot->xAxis->grid()->setVisible(false);
    //customPlot->yAxis->grid()->setVisible(false);

    //先清空原有柱状图
    bars.clear();

    //设置横坐标文字描述
    QVector<double> ticks;
    QVector<QString> labels;
    for (int i = 0; i < rowCount; i++) {
        ticks << i + 1;
        labels << rowNames.at(i);
    }

    setLabX(ticks, labels);
    customPlot->xAxis->setRange(0, rowCount + 1);

    for (int i = 0; i < columnCount; i++) {
        //同样也要先过滤个数是否符合要求
        QVector<double> value = values.at(i);
        if (rowCount != value.count()) {
            continue;
        }

        //创建柱状堆积图
        CustomBarv *bar = new CustomBarv(customPlot->xAxis, customPlot->yAxis);
        bar->setCheckData(checkData);

        //设置宽度比例
        bar->setWidth(0.6);

        //设置显示值的位置 0-不绘制 1-顶部上面 2-顶部居中 3-中间居中 4-底部居中
        bar->setValuePostion(valuePosition);
        bar->setValuePrecision(valuePrecision);
        bar->setValueColor(valueColor);

#ifndef old
        //设置堆积间隙
        if (borderColor != Qt::transparent) {
            bar->setStackingGap(1);
        }
#endif
        //设置名称
        bar->setName(columnNames.at(i));

        //设置颜色,取颜色集合
        QColor color = QColor(51, 204, 255);
        if (i < colors.count()) {
            color = colors.at(i);
        }

        //边缘高亮,如果传入了边框颜色则取边框颜色
        if (columnCount > 1 && borderColor == Qt::transparent) {
            bar->setPen(Qt::NoPen);
        } else {
            bar->setPen(QPen(borderColor == Qt::transparent ? color.light(150) : borderColor));
        }

        bar->setBrush(color);

        //设置堆积层叠顺序,后面那个移到前一个上面
        bars << bar;
        if (i > 0) {
            bar->moveAbove(bars.at(i - 1));
        }

        //设置数据
        bar->setData(ticks, value);
    }
}

Fifth, introduce controls

  1. More than 146 exquisite control, covers a variety of dashboards, progress bar, the progress of the ball, compass, graphs, scales, thermometers, navigation bar, navigation bar, flatui, highlight the button, slide the selector, the lunar calendar and so on. Qwt far more than the number of controls integration.
  2. Each class can be independently as a separate control, zero coupling each control file and a header file to achieve a code amount, independent of other files to facilitate individual control integrated into the project source code form, less. qwt interlocking control class, highly coupled, want to use one of the controls, must contain all the code.
  3. Write all pure Qt, QWidget + QPainter to draw, to support any Qt version Qt4.6 Qt5.12, support for mingw, msvc, gcc compiler, etc., support any operating system such as windows + linux + mac + embedded linux, which does not garbled can be directly integrated into Qt Creator, a built-in controls and use the same, most of the effects can be as long as several properties are set, very convenient.
  4. DEMO separate source containing the control corresponding to each control has a convenient reference. It also provides integrated use of all controls a DEMO.
  5. Source code for each control has detailed Chinese annotation, are prepared in accordance with unified design specifications, easy to learn to write custom controls.
  6. Each control default color and demo corresponding color is very beautiful.
  7. More than 130 visible control, six invisible control.
  8. Portion control provides a variety of styles style selection, multiple choice style indicator.
  9. All controls changes adaptive stretched form.
  10. Integrated design custom attribute that supports drag design, WYSIWYG support the import and export in xml format.
  11. Activex control that comes with demo, all controls can be run directly in the browser ie.
  12. Fontawesome integrated graphics font + Alibaba iconfont collection of hundreds of graphic fonts, font fun graphic brings.
  13. All controls and finally generate a dll dynamic library files, can be integrated directly into qtcreator designed for use in drag.
  14. Already qml version, the latter will consider a pyqt version, if the user is in great demand then.

Six, SDK download

  • SDK download link: https://pan.baidu.com/s/1tD9v1YPfE2fgYoK6lqUr1Q extraction code: lyhk
  • + Custom attributes Designer appreciation: https://pan.baidu.com/s/1l6L3rKSiLu_uYi7lnL3ibQ extraction code: tmvl
  • Download link is included in the various versions of the dynamic library files, header files of all the controls, the use of demo.
  • Open plug-in custom dynamic library dll use (permanent free), and the back door without any restrictions, ease of use.
  • 26 now available version dll, which includes qt5.12.3 msvc2017 32 + 64 mingw 32 + 64 in.
  • From time to time to increase control and improve controls, regularly updated SDK, to welcome all suggestions, thank you!
  • widget versions (QQ: 517216493) qml versions (QQ: 373955953) sambong camel (QQ: 278969898).
  • Qt's advanced column know almost Taoge road https://zhuanlan.zhihu.com/TaoQt
  • Welcome concern public micro-channel number] [efficient programmers, content C ++ / Python, learning, writing skills, popular technology, career development, a lot of dry goods, benefits a lot!

Guess you like

Origin www.cnblogs.com/feiyangqingyun/p/10991761.html