Search code examples
c++qtgraphcurveqcustomplot

How to choose from which side of QCPCurve fill with gradient?


I am using qcustomplot and draw a curve (QCPCurve). Code below fills only area above the curve. But i want to fill area on other side of curve. And how to make gradient fill area till the borders of graph?

what i need to do

_myPlot->clearPlottables();

QVector<double> x;
QVector<double> y;

for(int point = 0; point < shadowZone.length() ; point++){
    x.push_back(shadowZone.at(point).longitude);
    y.push_back(shadowZone.at(point).latitude);
}

QBrush shadowBrush (QColor(0,0,0), Qt::Dense7Pattern);

QCPCurve *newCurve = new QCPCurve(_myPlot->xAxis, _myPlot->yAxis);
newCurve->setBrush(shadowBrush);
newCurve->addData(x,y);

_myPlot->replot();

Solution

  • One possible solution is to use QCPGraph instead of using QCPCurve to use setChannelFillGraph(), the strategy is to create another QCPGraph that is the lowest line of the graph, you must use the rangeChanged signals of the axes to update the graph if necessary.

    QCPGraph *newCurve = new QCPGraph(_myPlot->xAxis , _myPlot->yAxis);
    newCurve->addData(x,y);
    
    QBrush shadowBrush(QColor(0,0,0), Qt::Dense7Pattern);
    
    newCurve->setBrush(shadowBrush);
    
    QCPGraph *minGraph = new QCPGraph(_myPlot->xAxis , _myPlot->yAxis);
    newCurve->setChannelFillGraph(minGraph);
    
    QObject::connect(_myPlot->xAxis, static_cast<void(QCPAxis::*)(const QCPRange &)>(&QCPAxis::rangeChanged), [_myPlot, minGraph](const QCPRange & newRange){
        minGraph->setData(QVector<double>{newRange.lower, newRange.upper},
                          QVector<double>{_myPlot->yAxis->range().lower,_myPlot->yAxis->range().lower});
    });
    
    QObject::connect(_myPlot->yAxis, static_cast<void(QCPAxis::*)(const QCPRange &)>(&QCPAxis::rangeChanged), [_myPlot, minGraph](const QCPRange & newRange){
        minGraph->setData(QVector<double>{_myPlot->xAxis->range().lower,_myPlot->xAxis->range().upper},
                          QVector<double>{newRange.lower, newRange.lower});
    });
    

    A complete example can be found in the following link

    enter image description here