QCustomPlot Discussion and Comments

AntialiasingReturn to overview

If you need to smooth out the graph, here is the solution. But the problem is that it lags



void QCPGraph::getLines(QVector<QPointF> *lines, const QCPDataRange &dataRange) const
[i]...[/i]
  switch (mLineStyle)
  {
    case lsNone: lines->clear(); break;
    case lsLine: *lines = dataToLines(lineData); break;
    case lsStepLeft: *lines = dataToStepLeftLines(lineData); break;
    case lsStepRight: *lines = dataToStepRightLines(lineData); break;
    case lsStepCenter: *lines = dataToStepCenterLines(lineData); break;
    case lsImpulse: *lines = dataToImpulseLines(lineData); break;
    [b]case lsSpline: *lines = dataToSplineLines(lineData); break;[/b]
  }
[i]...[/i]

QVector<QPointF> QCPGraph::dataToSplineLines(const QVector<QCPGraphData> &data) const
{
    QVector<QPointF> result;
    if (data.size() < 2) return result;

    QCPAxis *keyAxis = mKeyAxis.data();
    QCPAxis *valueAxis = mValueAxis.data();
    if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; }

    QPainterPath path;
    QVector<QPointF> pixelPoints;

    for (const auto &point : data)
    {
        pixelPoints.append(QPointF(keyAxis->coordToPixel(point.key), valueAxis->coordToPixel(point.value)));
    }

    const qreal t = 0.2;
    if (!pixelPoints.isEmpty())
    {
        path.moveTo(pixelPoints.first());
        for (int i = 1; i < pixelPoints.size() - 1; ++i)
        {
            QPointF p0 = pixelPoints[i - 1];
            QPointF p1 = pixelPoints[i];
            QPointF p2 = pixelPoints[i + 1];

            QPointF c1 = p1 - t * (p1 - p0);
            QPointF c2 = p1 + t * (p2 - p1);

            path.cubicTo(c1, p1, c2);
        }
        path.lineTo(pixelPoints.last());
    }

    qreal step = 4.0;
    for (qreal t = 0; t < path.length(); t += step)
    {
        result.append(path.pointAtPercent(t / path.length()));
    }

    return result;
}

Fixed the code, now everything works perfectly


Data:

void QCPGraph::setData(const QVector<double> &keys, const QVector<double> &values, bool antialiasing, bool alreadySorted)
{
  if(antialiasing)
  {
    QVector<double> newKeys;
    QVector<double> newValues;

    QVector<QPair<double, double>> speed = dataAntialiasing(keys, values);
    for (const QPair<double, double>& pair : qAsConst(speed))
    {
      newKeys.append(pair.first);
      newValues.append(pair.second);
    }
    mDataContainer->clear();
    addData(newKeys, newValues, alreadySorted);
  }
  else
  {
    mDataContainer->clear();
    addData(keys, values, alreadySorted);
  }
}

Antialiasing:

QVector<QPair<double, double> > QCPGraph::dataAntialiasing(const QVector<double> &keys, const QVector<double> &values) const
{
    QVector<QPair<double, double>> result;

    if (keys.size() > values.size() || keys.size() < 2) {
        return result;
    }

    QVector<QPointF> pixelPoints;
    for (int i = 0; i < keys.size(); ++i)
    {
        pixelPoints.append(QPointF(keys[i], values[i]));
    }

    QPainterPath path;
    path.moveTo(pixelPoints.first());
    const qreal t = 0.3;
    for (int i = 1; i < pixelPoints.size() - 1; ++i)
    {
        QPointF p0 = pixelPoints[i - 1];
        QPointF p1 = pixelPoints[i];
        QPointF p2 = pixelPoints[i + 1];

        QPointF c1 = p1 - t * (p1 - p0);
        QPointF c2 = p1 + t * (p2 - p1);

        path.cubicTo(c1, p1, c2);
    }

    path.lineTo(pixelPoints.last());

    qreal step = 0.005;
    for (qreal t = 0; t < path.length(); t += step)
    {
        QPointF point = path.pointAtPercent(t / path.length());
        result.append(QPair<double, double>(point.x(), point.y()));
    }

    return result;
}

Turn off AdaptiveSampling

ui->plot->graph(0)->setAdaptiveSampling(false);

Сhange the .h file yourself

step - smoothness adjustment

qreal step = 0.005;