How to plot discontinuous curves in Qwt ?
Hi everyone,
I just have to plot a curve which can be discontinuous over some intervals, but I can't find the way to do this.
My samples are set with the setRawSamples(const double *xData, const double *yData, int size) function of QwtPlotCurve.
To let a gap in Qwt curves I thought about 3 solutions:
1) Paint the empty intervals with segments colored in white/transparent (declare another data array specifying the color of each sample - but I believe multiple colors in one curve are not implemented in Qwt yet)
2) As all my curves are positive, I can set for example a negative value to yData[i] to tell the draw function that the sample should'nt be drawed and a gap has to be left (so I probably have to overload a Qwt function, and recompile and reinstall all the framework...)
3) Set a value that is far out of the Y axis range, so I get a gap, but the invisible samples are joined to the visible ones and I get two vertical segments which are undesirable...
Which solution is best to explore ? Or is there an easier solution to achieve this ?
Thanks a lot
Romain
Re: How to plot discontinuous curves in Qwt ?
You could reimplement draw() method in curve to draw a bunch of poly lines instead of one.
You can create polylines from the curve data after setting samples on the curve.
As long as the samples don't change, you don't have to re-create polylines.
something like that:
Code:
// this code is just to ilustrate the idea, it isn't correct nor compilable
curve->setSamples( data_x, data_y );
curve->prepare();
void MyCurve::prepare()
{
this->lines; // <QList< QVector< QPointF> >
double some_threshold = 10.0; // how far the points have to be from each other to be considered non-continous
for( int i = 0; i < this->dataSize(); ++i )
{
int prev = i -1;
if( prev >= 0 && this->x( i ) - this->x( prev ) > some_treshold )
{
this->lines.append( l );
l.clear();
}
l <<
QPointF( this
->x
( i
), this
->y
( i
) );
}
}
{
for( int i = 0; i < points.size(); ++i )
{
screen <<
QPointF( xMap.
transform( line.
x1() ), yMap.
transform( line.
y1() ) );
}
return screen;
}
void MyCurve
::draw( QPainter* p,
const QwtScaleMap
& xMap,
const QwtScaleMap
& yMap,
const QRect
& r
) const {
p->save();
p->setPen( this->pen() );
p->setClipRect( r );
for( int i = 0; i < this->lines.size(); ++i )
{
p->drawPolyLine( this->worldToScreen( this->lines.at( i ), xMap, yMap ), this->lines.at( i ).size() );
}
p->drawLines( v );
p->restore();
}
Re: How to plot discontinuous curves in Qwt ?
Ok, so assuming you advised me to reimplement a function, I worked on my solution 2) to get it work, with some inspiration of your code.
For my use I couldn't use the threshold method, so I preferred the "negative values = gap" method.
Anyway it's finally easy to reimplement the drawCurve function of the QwtPlotCurve class, so I made this code and it works great:
Code:
{
protected:
};
curve = new MyQwtPlotCurve();
curve->attach(this); // "this" is the QwtPlot
int preceding_from = from;
bool is_gap = true;
// Scan all data to identify gaps
for (int i = from; i <= to; i++){
const QPointF sample
= d_series
->sample
(i
);
// In a gap
if(sample.y() >= 0 && is_gap){ // wait for the curve to be positive again
preceding_from = i;
is_gap = false;
}
// At the beginning of a gap (or the end of the serie) : draw the preceding interval
if((sample.y() < 0 && !is_gap) || (i == to && sample.y() >= 0)){
drawSteps(painter, xMap, yMap, canvasRect, preceding_from, i>from ? i-1 : i); // or drawLines, drawSticks, drawDots
is_gap = true;
}
}
}
Thanks a lot for your help !
Romain