I need to draw a line curve, which has "gaps" (or "holes").
Yes, I can create several plot curves, which won't be connected each other, but is there a more elegant solution?
Have I to override QwtPlotCurve?
I need to draw a line curve, which has "gaps" (or "holes").
Yes, I can create several plot curves, which won't be connected each other, but is there a more elegant solution?
Have I to override QwtPlotCurve?
I never used qwt, but i did this with opengl in the following way:
- wrote a function to find the zeros of the function (note that the gaps of f(x) are the zeros of 1/f(x))
- create a class with a array of x and y points to store the graph values, and a min and max value (the limits of the segment)
-create a array of that class (each element of the array will be a segment)
- put the array in a for and draw the graph
So I guess there is no elegant way, just use the segments, and if you find another away let us know![]()
kiriM (16th June 2009)
kiriM (16th June 2009)
Thanks, guys!
I'll override drawLines().
But it's desirable to implement this feature in future versions of QwtPlot)
I'm surprised that nobody in this forum didn't run into this problem. I think it looks ugly when plot in missed points has a dip to X axis (when missed Y value is zero, for example).
OK, I've created a QwtPlotCurve descendant, QwtPlotGappedCurve, with
virtual void draw(QPainter *p, const QwtScaleMap &xMap,
const QwtScaleMap &yMap, int from, int to) const
overridden and additional data member, gapValue.
Everybody interested in can see attachment.
Uwe, maybe it will be useful to include this class into Qwt package?![]()
Fractal (10th February 2012), jesse_mark (5th February 2013)
Thanks, KiriM.
I had to implement some tweaks to get this to work in qwt-6.0.0 because the draw() function is different in 6.0.0.
I overrode QwtPlotCurve::drawSeries(), included the QRectF of the canvas in it's constructor, and used the d_deries->samples(i).y() data-values in the comparison to "gapValue_"
Qt Code:
//////////////////////////////////////////////////////////////////////////////// { if ( !painter || dataSize() <= 0 ) return; if (to < 0) to = dataSize() - 1; int i = from; while (i < to) { // If data begins with missed values, // we need to find first non-missed point. double y = d_series->sample(i).y(); while ((i < to) && (y == gapValue_)) { ++i; y = d_series->sample(i).y(); } // First non-missed point will be the start of curve section. int start = i; y = d_series->sample(i).y(); // Find the last non-missed point, it will be the end of curve section. while ((i < to) && (y != gapValue_)) { ++i; y = d_series->sample(i).y(); } // Correct the end of the section if it is at missed point int end = (y == gapValue_) ? i - 1 : i; // Draw the curve section if (start <= end) } } ////////////////////////////////////////////////////////////////////////////////To copy to clipboard, switch view to plain text mode
Thank you Fractal and KiriM. This subclass works great with Qwt6.0.2.
Hello!
I'm trying to make this subclass work in my Qt 5.1.0 + Qwt 6.1.0 project, but without success. I added the change suggested by Fractal above, but the compiler gives me the error that "d_series" is private.
Any guess how to correct this?
Thanks,
Momergil
Hello!
Since no one managed to help me, I created a new class able to do this in a different way:
Qt Code:
//.h #define QWTPLOTCURVESPECIAL_DEFAULT -1 { public: void setPenList(QList<QPen>& pen); void setPosList(QList<char>& pos); virtual void drawLines(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const; private: QList<QPen> v_pen; QList<char> v_pos; }; //cpp QwtPlotCurveSpecial::QwtPlotCurveSpecial(const QString& title) { setTitle(title); } void QwtPlotCurveSpecial::setPenList(QList<QPen>& pen) { v_pen = pen; } void QwtPlotCurveSpecial::setPosList(QList<char>& pos) { v_pos = pos; } void QwtPlotCurveSpecial::drawLines(QPainter *p, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const { for (int counter = 1; counter < v_pos.size(); counter++) { if (v_pos.at(counter) == -1) continue; p->setPen(v_pen[v_pos[counter]]); } }To copy to clipboard, switch view to plain text mode
As you can see, in order to use this class, one have to crate a QList<QPen> with all the pen he want to use in the draw (useful for another situation, which is when somebody wants to draw a line with multiple colors) and a QList<char> containing which of the QPen he want to be used for each point. If hits QList<char> contains a -1 value, this is interpreted as not wanting to draw that point, so nothing is draw in that point.
Notice that its required that the QList<char> list has the same value as the samples set in setSamples(...), otherwise one would have a failure there.
Momergil
another_qt (26th July 2016)
Hi,
I'm using QWT 6.1.x.
just had the same problem and used KiriM's solution patched with Fractal's code and had the same errors as Momergil ("d_series" is private). I found out that by just replacing 'd_series->sample' with 'sample' it works.
If anyone needs a working solution with QWT >= 6.1.x, please use the attached files for the QwtPlotGappedCurve.
Cheers and thanks to kiriM and Fractal
Edit:
Since the value 0.0 is a valid value in my case I needed another value that marks a gap. The double value NAN is not possible because NAN != NAN. Since I'm not a fan of curious magic numbers I simply use 1.0/0.0 (inf) as the gap value![]()
Momergil (14th May 2014)
Bookmarks