QCustomPlot Discussion and Comments

QCPCurve calls QCPCurve::drawCurveLine() 3 times with different number of lines on selection changeReturn to overview

I have subclassed QCPCurve in order to overload drawCurveLine and change the colour of specific line segments. Here's the class:
qcpcolorcurve.h

#ifndef QCPCOLORCURVE_H
#define QCPCOLORCURVE_H

#include <QVector>
#include "qcustomplot.h"

class QCPColorCurve : public QCPCurve
{
public:
    QCPColorCurve(QCPAxis *keyAxis, QCPAxis *valueAxis);
    virtual ~QCPColorCurve();
    void setData(const QVector<double> & keys, const QVector<double> & values, const QVector<QColor> & colors);
protected:
    virtual void drawCurveLine(QCPPainter *painter, const QVector<QPointF> &lines) const;
    virtual void drawScatterPlot(QCPPainter *painter, const QVector<QPointF> &points, const QCPScatterStyle &style) const;
private:
    QVector<QColor> colors_;
};

#endif // QCPCOLORCURVE_H

qcpcolorcurve.cpp

#include "qcpcolorcurve.h"

QCPColorCurve::QCPColorCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : QCPCurve(keyAxis, valueAxis) {}

QCPColorCurve::~QCPColorCurve(){ }

void QCPColorCurve::setData(const QVector<double> & keys, const QVector<double> & values, const QVector<QColor> & colors){
    if (values.size() != colors.size()) return;
    colors_ = colors;
    QCPCurve::setData(keys, values);
}

void QCPColorCurve::drawCurveLine(QCPPainter *painter, const QVector<QPointF> &lines) const
{
    applyDefaultAntialiasingHint(painter);
    int nLines = lines.size();
    qDebug() << this->name();
    qDebug() << "num_lines: " << lines.size() << ", offset: " << this->selection().span().begin();
    for (int i = 0; i < nLines; ++i) {
        int offset_i = this->selection().span().begin()+i;
        if (offset_i < colors_.size()) {
            painter->setPen(colors_[offset_i]);

        }
        if (i < nLines-1) {
            drawPolyline(painter, QVector<QPointF>(lines.begin()+i, lines.begin()+i+2));
        }
    }
}

void QCPColorCurve::drawScatterPlot(QCPPainter * painter, const QVector<QPointF> & points, const QCPScatterStyle & style) const {
    qDebug() << "redrawing scatter points";
    applyScattersAntialiasingHint(painter);
    int nPoints = points.size();
    for (int i = 0; i < nPoints; ++i)
        if (!qIsNaN(points.at(i).x()) && !qIsNaN(points.at(i).y())){
            painter->setPen(colors_[i]);
            style.drawShape(painter, points.at(i));
        }
}

The plot that has these plottables also has QCP::iSelectPlottables enabled and I realized when I select a data point on the plot it redraws the lines but with the color starting on different line segments. After some debugging I found that if I select a single data point on 1 plottable, it calls my implementation of drawCurveLine function 3 times for that plottable with different number of lines needing redrawing.

The qDebug() statements print out something like this when I click 1 data point on the plot after there were no selections:
Begin idx: 1 , End idx: 2
selected data range: 86 , 87
"wsPlot0"
num_lines: 5 , offset: 0
redrawing scatter points
"wsPlot1"
num_lines: 2 , offset: 1
redrawing scatter points
"wsPlot1"
num_lines: 4 , offset: 1
redrawing scatter points
"wsPlot1"
num_lines: 1 , offset: 1
redrawing scatter points
"wsPlot2"
num_lines: 5 , offset: 0

Any ideas?

QCP segments plottables into contiguous batches/segments with identical style (color, etc). So when you select a data point in the middle, it will have a different style (selected), and thus you'll get a draw call for all the data points preceding the selected point, the selected point itself, and the data points succeeding the selected point.