kuzulis
13th November 2016, 15:05
Hi all.
I have faced with the problem of very slow movements of "rubber band" lines when more than 3-curves are attached.
I have implemented the code from the "qwt-6.1.3\playground\curvetracker\" example:
struct compareX
{
inline bool operator()(const double x, const QPointF &pos) const
{
return (x < pos.x());
}
};
CurveTracker::CurveTracker(QWidget *canvas)
: QwtPlotPicker(canvas)
{
}
QRect CurveTracker::trackerRect(const QFont &font) const
{
QRect r = QwtPlotPicker::trackerRect(font);
// Always show the info on left-top of window.
r.moveTo(0, 0);
return r;
}
QwtText CurveTracker::trackerTextF(const QPointF &pos) const
{
// Inverse iterations over all attached curves.
QString info;
const auto curves = plot()->itemList(QwtPlotItem::Rtti_PlotCurve);
for (auto curveIt = curves.crbegin(); curveIt != curves.crend(); ++curveIt) {
// Show info only for visible curves.
if (!(*curveIt)->isVisible())
continue;
const QString curveInfo = curveInfoAt(static_cast<const QwtPlotCurve *>(*curveIt), pos);
if (!curveInfo.isEmpty()) {
if (!info.isEmpty())
info += tr("<br>");
info += curveInfo;
}
}
return info;
}
QString CurveTracker::curveInfoAt(const QwtPlotCurve *qwtcurve, const QPointF &pos) const
{
const QLineF line = curveLineAt(qwtcurve, pos.x());
if (line.isNull())
return QString();
const double y = line.pointAt((pos.x() - line.p1().x()) / line.dx()).y();
QString info(tr("<font color=""%1"">%2</font>"));
return info.arg(qwtcurve->pen().color().name()).arg(y);
}
QLineF CurveTracker::curveLineAt(const QwtPlotCurve *qwtcurve, double x) const
{
QLineF line;
const auto samplesCount = qwtcurve->dataSize();
if (samplesCount >= 2) {
const QRectF boundingRect = qwtcurve->boundingRect();
if ((boundingRect.width() > 0)
&& (x >= boundingRect.left())
&& (x <= boundingRect.right())) {
auto lessfunc = [](const double x, const QPointF &pos) { return (x < pos.x()); };
int sampleIndex = qwtUpperSampleIndex<QPointF>(*qwtcurve->data(), x, lessfunc);
if (sampleIndex == -1) {
const auto lastSample = qwtcurve->sample(samplesCount - 1);
if (x == lastSample.x())
sampleIndex = samplesCount - 1;
}
if (sampleIndex > 0) {
line.setP1(qwtcurve->sample(sampleIndex - 1));
line.setP2(qwtcurve->sample(sampleIndex));
}
}
}
return line;
}
And I see that if I use 3 and more curves, then the rubber band's crosshair isn't in time behind movements of the
mouse cursor, it lags behind on speed. And with the 15-curves or more, the delay of a sight is stronger.
I see this delay even with "pure" QwtPlotPicker...
So, is any tricks to solve it?
PS: Qwt6.3-multiaxes, Qt 5.7, MSVC2015x86.
BR,
Denis
Added after 13 minutes:
I found, that even this code brings to lags:
QwtText CurveTracker::trackerTextF(const QPointF &pos) const
{
QString info;
for (int i = 0; i < 15; ++i) {
info += tr("<br>");
info += QString::number(qrand() % 1000);
}
return info;
}
Added after 11 minutes:
UPD: Seems, that source of issue in HTML tags:
QString info(tr("<font color=""%1"">%2</font>"));
So... seems, we need to avoid to use the trackerTextF() method.
Seems, we need to draw the tracker's rect with all contents manually, directly in QwtPicker::drawTracker.. :(
Or, I am mistaken ?
I have faced with the problem of very slow movements of "rubber band" lines when more than 3-curves are attached.
I have implemented the code from the "qwt-6.1.3\playground\curvetracker\" example:
struct compareX
{
inline bool operator()(const double x, const QPointF &pos) const
{
return (x < pos.x());
}
};
CurveTracker::CurveTracker(QWidget *canvas)
: QwtPlotPicker(canvas)
{
}
QRect CurveTracker::trackerRect(const QFont &font) const
{
QRect r = QwtPlotPicker::trackerRect(font);
// Always show the info on left-top of window.
r.moveTo(0, 0);
return r;
}
QwtText CurveTracker::trackerTextF(const QPointF &pos) const
{
// Inverse iterations over all attached curves.
QString info;
const auto curves = plot()->itemList(QwtPlotItem::Rtti_PlotCurve);
for (auto curveIt = curves.crbegin(); curveIt != curves.crend(); ++curveIt) {
// Show info only for visible curves.
if (!(*curveIt)->isVisible())
continue;
const QString curveInfo = curveInfoAt(static_cast<const QwtPlotCurve *>(*curveIt), pos);
if (!curveInfo.isEmpty()) {
if (!info.isEmpty())
info += tr("<br>");
info += curveInfo;
}
}
return info;
}
QString CurveTracker::curveInfoAt(const QwtPlotCurve *qwtcurve, const QPointF &pos) const
{
const QLineF line = curveLineAt(qwtcurve, pos.x());
if (line.isNull())
return QString();
const double y = line.pointAt((pos.x() - line.p1().x()) / line.dx()).y();
QString info(tr("<font color=""%1"">%2</font>"));
return info.arg(qwtcurve->pen().color().name()).arg(y);
}
QLineF CurveTracker::curveLineAt(const QwtPlotCurve *qwtcurve, double x) const
{
QLineF line;
const auto samplesCount = qwtcurve->dataSize();
if (samplesCount >= 2) {
const QRectF boundingRect = qwtcurve->boundingRect();
if ((boundingRect.width() > 0)
&& (x >= boundingRect.left())
&& (x <= boundingRect.right())) {
auto lessfunc = [](const double x, const QPointF &pos) { return (x < pos.x()); };
int sampleIndex = qwtUpperSampleIndex<QPointF>(*qwtcurve->data(), x, lessfunc);
if (sampleIndex == -1) {
const auto lastSample = qwtcurve->sample(samplesCount - 1);
if (x == lastSample.x())
sampleIndex = samplesCount - 1;
}
if (sampleIndex > 0) {
line.setP1(qwtcurve->sample(sampleIndex - 1));
line.setP2(qwtcurve->sample(sampleIndex));
}
}
}
return line;
}
And I see that if I use 3 and more curves, then the rubber band's crosshair isn't in time behind movements of the
mouse cursor, it lags behind on speed. And with the 15-curves or more, the delay of a sight is stronger.
I see this delay even with "pure" QwtPlotPicker...
So, is any tricks to solve it?
PS: Qwt6.3-multiaxes, Qt 5.7, MSVC2015x86.
BR,
Denis
Added after 13 minutes:
I found, that even this code brings to lags:
QwtText CurveTracker::trackerTextF(const QPointF &pos) const
{
QString info;
for (int i = 0; i < 15; ++i) {
info += tr("<br>");
info += QString::number(qrand() % 1000);
}
return info;
}
Added after 11 minutes:
UPD: Seems, that source of issue in HTML tags:
QString info(tr("<font color=""%1"">%2</font>"));
So... seems, we need to avoid to use the trackerTextF() method.
Seems, we need to draw the tracker's rect with all contents manually, directly in QwtPicker::drawTracker.. :(
Or, I am mistaken ?