From efca49fb72e831c3d48e00cdfa8e3b622251b78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=8B=D1=87=D0=BA=D0=BE=D0=B2=20=D0=90=D0=BD=D0=B4?= =?UTF-8?q?=D1=80=D0=B5=D0=B9?= Date: Thu, 18 Jan 2018 14:11:48 +0000 Subject: [PATCH] Graphic fast autofit for addPoint git-svn-id: svn://db.shs.com.ru/libs@347 a8b55f48-bf90-11e4-a774-851b48703e85 --- qad/graphic/graphic.cpp | 137 +++++++++++++++++++++++++------------ qad/graphic/graphic.h | 4 +- qad/graphic/graphic_conf.h | 3 +- 3 files changed, 96 insertions(+), 48 deletions(-) diff --git a/qad/graphic/graphic.cpp b/qad/graphic/graphic.cpp index b802564..9acfc9a 100644 --- a/qad/graphic/graphic.cpp +++ b/qad/graphic/graphic.cpp @@ -94,8 +94,8 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), line_x_min(this), line_x_max mdm = 10.; visible_time = -1.; pause_phase = 0.; - selrect.setRect(0., 0., 1., 1.); - def_rect = selrect; + def_rect.setRect(0., 0., 1., 1.); + selrect = def_rect; margins_.setRect(4, 4, 4, 4); curaction = gaMove; selbrush.setStyle(Qt::SolidPattern); @@ -457,6 +457,7 @@ void Graphic::clear() { graphics[i].polyline.clear(); graphics[i].polyline_pause.clear(); graphics[i].max_x = 0.; + graphics[i].cvrect = QRectF(); } on_buttonAutofit_clicked(); } @@ -487,6 +488,7 @@ void Graphic::setPaused(bool yes) { graphics[i].polyline_pause = graphics[i].polyline; graphics[i].polyline_pause.detach(); graphics[i].max_x_pause = graphics[i].max_x; + graphics[i].cvrect = QRectF(); } timer_pause = startTimer(40); } @@ -498,6 +500,7 @@ void Graphic::setHistorySize(double val) { for (int i = 0; i < graphics.size(); ++i) { QPolygonF & pol(graphics[i].polyline); if (pol.isEmpty() || history <= 0.) continue; + graphics[i].cvrect = QRectF(); x = pol.back().x() - history; for (int j = pol.size() - 2; j >= 0 ; --j) if (pol[j].x() < x) { @@ -585,26 +588,37 @@ void Graphic::setButtonsPosition(Graphic::Alignment a) { void Graphic::addPoint(const QPointF & p, int graphic, bool update_) { if (graphic >= graphics.size() || graphic < 0) return; - if (graphics.at(graphic).polyline.size() == 0) graphics[graphic].max_x = p.x(); - graphics[graphic].polyline << p; - if (graphics.at(graphic).max_x < p.x()) graphics[graphic].max_x = p.x(); + GraphicType & t(graphics[graphic]); + if (!t.cvrect.isNull()) { +// if (graphics[graphic].cvrect.contains(p)) +// graphics[graphic].cvrect = QRectF(); + if (t.cvrect.top() < p.y()) t.cvrect.setTop(p.y()); + if (t.cvrect.bottom() > p.y()) t.cvrect.setBottom(p.y()); + if (t.cvrect.right() < p.x()) t.cvrect.setRight(p.x()); + if (t.cvrect.left() > p.x()) t.cvrect.setLeft(p.x()); + } + if (t.polyline.size() == 0) t.max_x = p.x(); + t.polyline << p; + if (t.max_x < p.x()) t.max_x = p.x(); tick(graphic, true, update_); } void Graphic::setGraphicData(const QVector & g, int graphic, bool update_) { if (graphic >= graphics.size() || graphic < 0) return; - graphics[graphic].polyline.clear(); - graphics[graphic].polyline = g; - if (graphics.at(graphic).polyline.size() == 0) { - graphics[graphic].max_x = 0.; + GraphicType & t(graphics[graphic]); + t.cvrect = QRectF(); + t.polyline.clear(); + t.polyline = g; + if (t.polyline.size() == 0) { + t.max_x = 0.; tick(graphic, false, update_); return; } - graphics[graphic].max_x = graphics.at(graphic).polyline[0].x(); - for (int i = 1; i < graphics.at(graphic).polyline.size(); ++i) - if (graphics.at(graphic).max_x < graphics.at(graphic).polyline[i].x()) - graphics[graphic].max_x = graphics.at(graphic).polyline[i].x(); + t.max_x = t.polyline[0].x(); + for (int i = 1; i < t.polyline.size(); ++i) + if (t.max_x < t.polyline[i].x()) + t.max_x = t.polyline[i].x(); tick(graphic, false, update_); } @@ -694,7 +708,7 @@ void Graphic::setGraphicsCount(int arg, bool update) { } -void Graphic::setHistogramData(const QVector & g, int graphic) { +/*void Graphic::setHistogramData(const QVector & g, int graphic) { graphics[graphic].polyline.clear(); if (g.isEmpty()) { return; @@ -739,25 +753,29 @@ void Graphic::setHistogramData(const QVector & g, int graphic) { cpol << QPointF(range + min, 0.); } updateGraphics(); -} +}*/ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, double end_y) { - double cx, cy, maxX, minX, maxY, minY, vx = DBL_MIN; + double cx, cy, maxX, minX, maxY, minY, vx; bool isRangeX = (start_x != end_x), isRangeY = (start_y != end_y); - bool isEmpty = true, anyVisible = false, isTimeLimit = (visible_time > 0.) && !(isRangeX || isRangeY); - foreach (const GraphicType & t, graphics) { - const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline); - if (!pol.isEmpty()) { - isEmpty = false; - break; - } - } - if (isEmpty) { - grect = def_rect; - setRectToLines(); - return; - } +// bool isEmpty = true; + bool fast = true, can_fast = (start_x == 0 && end_x == 0 && start_y == 0 && end_y == 0); + bool anyVisible = false, isTimeLimit = (visible_time > 0.) && !(isRangeX || isRangeY); +// foreach (const GraphicType & t, graphics) { +// const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline); +// if (!pol.isEmpty()) { +// isEmpty = false; +// break; +// } +// } +// if (isEmpty) { +// grect = def_rect; +// setRectToLines(); +// return; +// } +// can_fast = false; + vx = DBL_MIN; minY = minX = DBL_MAX; maxY = maxX = -DBL_MAX; foreach (const GraphicType & t, graphics) { @@ -765,27 +783,50 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou if (vx < (pause_ ? t.max_x_pause : t.max_x)) vx = (pause_ ? t.max_x_pause : t.max_x); } vx -= visible_time; - foreach (const GraphicType & t, graphics) { +// qDebug() << "[Graphic]" << "can_fast" << can_fast; + for (int g = 0; g < graphics.size(); g++) { + GraphicType & t(graphics[g]); if (!t.visible) continue; const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline); - for (int i = 0; i < pol.size(); i++) { - cx = pol[i].x(); - cy = pol[i].y(); - if ((start_x > cx || end_x < cx) && isRangeX) continue; - if ((start_y > cy || end_y < cy) && isRangeY) continue; - if ((cx < vx) && isTimeLimit) continue; - if (maxY < cy) maxY = cy; - if (minY > cy) minY = cy; - if (maxX < cx) maxX = cx; - if (minX > cx) minX = cx; + if (pol.isEmpty()) continue; + bool f = true; + //qDebug() << "[Graphic]" << "cvrect:" << t.cvrect << t.cvrect.isNull(); + if (t.cvrect.isNull() || !can_fast) { + for (int i = 0; i < pol.size(); i++) { + cx = pol[i].x(); + cy = pol[i].y(); + if ((start_x > cx || end_x < cx) && isRangeX) continue; + if ((start_y > cy || end_y < cy) && isRangeY) continue; + if ((cx < vx) && isTimeLimit) continue; + if (f) { + t.cvrect.setRect(cx, cy, 0, 0); + f = false; + } else { + if (t.cvrect.top() < cy) t.cvrect.setTop(cy); + if (t.cvrect.bottom() > cy) t.cvrect.setBottom(cy); + if (t.cvrect.right() < cx) t.cvrect.setRight(cx); + if (t.cvrect.left() > cx) t.cvrect.setLeft(cx); + } + fast = false; + } + if (f) continue; + //qDebug() << "[Graphic]" << "2 cvrect:" << t.cvrect; } - if (!pol.isEmpty()) anyVisible = true; + anyVisible = true; + if (maxY < t.cvrect.top()) maxY = t.cvrect.top(); + if (minY > t.cvrect.bottom()) minY = t.cvrect.bottom(); + if (maxX < t.cvrect.right()) maxX = t.cvrect.right(); + if (minX > t.cvrect.left()) minX = t.cvrect.left(); + if (!can_fast) t.cvrect = QRectF(); } if (!anyVisible) { - grect.setRect(0., 0., 1., 1.); + //qDebug() << "[Graphic]" << "empty autofit"; + grect = def_rect; setRectToLines(); return; } +// if (fast) qDebug() << "[Graphic]" << "FAST autofit"; +// else qDebug() << "[Graphic]" << "autofit"; if (maxX > limit_.right()) maxX = limit_.right(); if (minX > limit_.right()) minX = limit_.right(); if (minX < limit_.left()) minX = limit_.left(); @@ -796,8 +837,8 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou if (maxY < limit_.top()) maxY = limit_.top(); if (minX > maxX) qSwap(minX, maxX); if (minY > maxY) qSwap(minY, maxY); - if (qAbs(minX - maxX) < 1E-60) {minX -= 1E-20; maxX += 1E-20;} - if (qAbs(minY - maxY) < 1E-60) {minY -= 1E-20; maxY += 1E-20;} + if (qAbs(minX - maxX) < 1E-60) {minX -= defaultRect().width()/2; maxX += defaultRect().width()/2;} + if (qAbs(minY - maxY) < 1E-60) {minY -= defaultRect().height()/2; maxY += defaultRect().height()/2;} if (only_expand_x) { if (minX > eminx) minX = eminx; if (maxX < emaxx) maxX = emaxx; @@ -1279,6 +1320,12 @@ void Graphic::tick(int index, bool slide, bool update_) { if (history > 0.) while (t.polyline.size() > 1) { if (fabs(t.polyline.back().x() - t.polyline.front().x()) <= history) break; + if (!t.cvrect.isNull()) { + if (!t.cvrect.contains(t.polyline.first())) { + /// TODO: [Graphic] add smart remove for fast autofit + t.cvrect = QRectF(); + } + } t.polyline.pop_front(); } } @@ -1530,7 +1577,7 @@ QByteArray Graphic::save() { void Graphic::load(QByteArray ba) { if (ba.isEmpty()) return; char ver = ba[0]; - qDebug() << "load" << (int)ver; + //qDebug() << "load" << (int)ver; switch(ver) { case '2': {// version '2': ba.remove(0, 1); diff --git a/qad/graphic/graphic.h b/qad/graphic/graphic.h index 17102f2..6a17313 100644 --- a/qad/graphic/graphic.h +++ b/qad/graphic/graphic.h @@ -195,8 +195,8 @@ public: GraphicType graphic(int arg) {if (arg < 0 || arg >= graphics.size()) return GraphicType(); return graphics[arg];} const QVector & allGraphics() const {return graphics;} void setAllGraphics(const QVector & g, bool update = true) {graphics = g; if (update) updateLegend();} - void setHistogramData(const QVector & g, int graphic); - void setHistogramData(const QVector & g) {setHistogramData(g, curGraphic);} +// void setHistogramData(const QVector & g, int graphic); +// void setHistogramData(const QVector & g) {setHistogramData(g, curGraphic);} double canvas2realX(double px) const; double canvas2realY(double py) const; diff --git a/qad/graphic/graphic_conf.h b/qad/graphic/graphic_conf.h index 6d926a6..dd5305c 100644 --- a/qad/graphic/graphic_conf.h +++ b/qad/graphic/graphic_conf.h @@ -45,6 +45,7 @@ struct GraphicType { QCheckBox * pb; QIcon icon; bool visible; + QRectF cvrect; }; @@ -71,7 +72,7 @@ public: protected: void changeEvent(QEvent * e); - + Ui::GraphicConf * ui; private slots: