git-svn-id: svn://db.shs.com.ru/libs@37 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
@@ -112,6 +112,7 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), line_x_min(this), line_x_max
|
||||
visible_time = -1.;
|
||||
pause_phase = 0.;
|
||||
selrect.setRect(0., 0., 1., 1.);
|
||||
def_rect = selrect;
|
||||
margins_.setRect(4, 4, 4, 4);
|
||||
curaction = gaMove;
|
||||
selbrush.setStyle(Qt::SolidPattern);
|
||||
@@ -629,6 +630,12 @@ void Graphic::setVisualRect(const QRectF & rect) {
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setDefaultRect(const QRectF & rect) {
|
||||
def_rect = rect;
|
||||
if (isFit) autofit();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::saveImage() {
|
||||
QString str = QFileDialog::getSaveFileName(this, tr("Save Image"), ppath, "PNG(*.png);;JPEG(*.jpg *.jpeg);;BMP(*.bmp);;TIFF(*.tiff *.tif);;PPM(*.ppm)");
|
||||
if (str == "") return;
|
||||
@@ -744,7 +751,7 @@ void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, dou
|
||||
}
|
||||
}
|
||||
if (isEmpty) {
|
||||
grect.setRect(0., 0., 1., 1.);
|
||||
grect = def_rect;
|
||||
setRectToLines();
|
||||
return;
|
||||
}
|
||||
@@ -886,8 +893,12 @@ void Graphic::drawGrid() {
|
||||
cy = chei - font_sz.height() / 4;
|
||||
if (hasLblX) cy -= font_sz.height();
|
||||
range = selrect.right() - selrect.left();
|
||||
if (grad_x == Graphic::Auto) step = splitRange(range, wid / gridx / font_sz.width() * 1.4);
|
||||
else step = gridx;//range / wid * gridx;
|
||||
QString df;
|
||||
if (axis_type_x == Graphic::Numeric) {
|
||||
if (grad_x == Graphic::Auto) step = splitRange(range, wid / gridx / font_sz.width() * 1.4);
|
||||
else step = gridx;//range / wid * gridx;
|
||||
} else
|
||||
step = splitRangeDate(range, wid / gridx / font_sz.width() * 1.4, &df);
|
||||
start = roundTo(canvas2realX(wid), step) + step;
|
||||
px = start + step;
|
||||
if (step > 0.) {
|
||||
@@ -901,11 +912,11 @@ void Graphic::drawGrid() {
|
||||
painter->setPen(grid_pen);
|
||||
painter->drawLine(cx, hei + 5, cx, 0);
|
||||
painter->setPen(text_color);
|
||||
int dx = -font_sz.height() / 4.;
|
||||
painter->setFont(nf);
|
||||
if (axis_type_x == Graphic::Numeric) {
|
||||
int dx = -font_sz.height() / 4.;
|
||||
str = gridMark(px * grid_numbers_x);
|
||||
rect = fm.boundingRect(str.first);
|
||||
painter->setFont(nf);
|
||||
painter->drawText(cx + dx, cy, str.first);
|
||||
dx += rect.width() + font_sz.height() / 6.;
|
||||
if (!str.second.isEmpty()) {
|
||||
@@ -914,7 +925,8 @@ void Graphic::drawGrid() {
|
||||
painter->drawText(cx + dx, cy - font_sz.height() / 2.5, str.second);
|
||||
}
|
||||
} else {
|
||||
|
||||
str.first = QDateTime::fromMSecsSinceEpoch(px * grid_numbers_x).toString(df);
|
||||
painter->drawText(cx + dx, cy, str.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -996,11 +1008,18 @@ void Graphic::drawGraphics() {
|
||||
}
|
||||
|
||||
|
||||
QString Graphic::pointCoords(QPointF point) {
|
||||
if (axis_type_x == Numeric)
|
||||
return "(" + QString::number(point.x(), 'f', 3) + " ; " + QString::number(point.y(), 'f', 3) + ")";
|
||||
return "(" + QDateTime::fromMSecsSinceEpoch(point.x()).toString() + " ; " + QString::number(point.y(), 'f', 3) + ")";
|
||||
}
|
||||
|
||||
|
||||
void Graphic::drawGuides() {
|
||||
if (!guides || !isHover) return;
|
||||
int wid = canvas->width(), hei = canvas->height();
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
painter->setPen(grid_pen.color());
|
||||
painter->setPen(QPen(grid_pen.color(), qMax<int>(qRound(thick / 1.4), 1)));
|
||||
painter->resetTransform();
|
||||
painter->setClipping(true);
|
||||
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
|
||||
@@ -1009,9 +1028,9 @@ void Graphic::drawGuides() {
|
||||
QString str = pointCoords(canvas2real(curpos));
|
||||
QFontMetrics fm(font());
|
||||
QRect r = fm.boundingRect(str);
|
||||
QPoint p = curpos + QPoint(2, -2);
|
||||
if (r.width() + curpos.x() > wid - 5) p.setX(curpos.x() - r.width() - 3);
|
||||
if (curpos.y() - r.height() < 2) p.setY(curpos.y() + r.height() - 2);
|
||||
QPoint p = curpos + QPoint(font_sz.height() / 4., -font_sz.height() / 4.);
|
||||
if (r.width() + curpos.x() > wid - font_sz.height() / 2.) p.setX(curpos.x() - r.width() - font_sz.height() / 4.);
|
||||
if (curpos.y() - r.height() < font_sz.height() / 8.) p.setY(curpos.y() + r.height() - font_sz.height() / 8.);
|
||||
painter->setPen(text_color);
|
||||
painter->drawText(p, str);
|
||||
}
|
||||
@@ -1020,7 +1039,7 @@ void Graphic::drawGuides() {
|
||||
void Graphic::drawPause() {
|
||||
painter->setClipping(false);
|
||||
painter->resetMatrix();
|
||||
painter->translate(canvas->width() - icon_pause_b.width() - 4, 4);
|
||||
painter->translate(canvas->width() - icon_pause_b.width() - 6, 6);
|
||||
double o = (0.5 - pause_phase) * 2;
|
||||
painter->setOpacity(o*o);
|
||||
painter->drawImage(0, 0, icon_pause_b);
|
||||
@@ -1031,32 +1050,34 @@ void Graphic::drawPause() {
|
||||
|
||||
double Graphic::splitRange(double range, int count) {
|
||||
double digits, step, tln;
|
||||
//bool neg = range < 0;
|
||||
//if (neg) range = -range;
|
||||
range = qAbs<double>(range);
|
||||
tln = qFloor(qLn(range) / LN10);
|
||||
/*double mul = 1.;
|
||||
if (tln >= 4) {
|
||||
mul = qPow(10, tln);
|
||||
tln = 2;
|
||||
range /= mul;
|
||||
}*/
|
||||
for (int i = 0; i <= 5; ++i) {
|
||||
digits = qPow(10., tln - i);
|
||||
step = qRound(range / count / digits);
|
||||
if (step > 0.) {
|
||||
digits = qPow(10., tln - i - 1);
|
||||
step = qRound(range / count / digits);
|
||||
//qDebug() << "break at" << i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//qDebug() << step << digits;
|
||||
double step5 = qRound(step / 5.) * 5., step10 = qRound(step / 10.) * 10.;
|
||||
double err5 = qAbs<double>(step - step5), err10 = qAbs<double>(step - step10);
|
||||
step = (err5 < err10 ? step5 : step10) * digits;
|
||||
//qDebug() << step;
|
||||
return step;// * mul;
|
||||
return step;
|
||||
}
|
||||
|
||||
|
||||
double Graphic::splitRangeDate(double range, int count, QString * format) {
|
||||
double ret = splitRange(range, count);
|
||||
if (ret < 1000. * 1) *format = "ss.zzz";
|
||||
else if (ret < 1000. * 60) *format = "h:m:ss";
|
||||
else if (ret < 1000. * 60 * 60) *format = "h:mm";
|
||||
else if (ret < 1000. * 60 * 60 * 24) *format = "dd(ddd) hh";
|
||||
else if (ret < 1000. * 60 * 60 * 24 * 30) *format = "MMM dd";
|
||||
else if (ret < 1000. * 60 * 60 * 24 * 30 * 12) *format = "yyyy MMM";
|
||||
else *format = "yyyy";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1066,28 +1087,28 @@ double Graphic::roundTo(double value, double round_to) {
|
||||
}
|
||||
|
||||
|
||||
double Graphic::canvas2realX(double px) {
|
||||
double Graphic::canvas2realX(double px) const {
|
||||
int gbx = gridborder.x() + margins_.left(), cwid = lastw, wid = cwid - gbx - margins_.width();
|
||||
double cx = px - gbx, sclx = selrect.width() / (double)wid;
|
||||
return cx * sclx + selrect.x();
|
||||
}
|
||||
|
||||
|
||||
double Graphic::canvas2realY(double py) {
|
||||
double Graphic::canvas2realY(double py) const {
|
||||
int gby = gridborder.y() + margins_.top(), chei = lasth - legy, hei = chei - gby - margins_.height();
|
||||
double cy = chei - py - gby, scly = selrect.height() / (double)hei;
|
||||
return cy * scly + selrect.y();
|
||||
}
|
||||
|
||||
|
||||
double Graphic::real2canvasX(double px) {
|
||||
double Graphic::real2canvasX(double px) const {
|
||||
int gbx = gridborder.x() + margins_.left(), cwid = lastw, wid = cwid - gbx - margins_.width();
|
||||
double sclx = selrect.width() / (double)wid;
|
||||
return (px - selrect.x()) / sclx + gbx;
|
||||
}
|
||||
|
||||
|
||||
double Graphic::real2canvasY(double py) {
|
||||
double Graphic::real2canvasY(double py) const {
|
||||
int gby = gridborder.y() + margins_.top(), chei = lasth - legy, hei = chei - gby - margins_.height();
|
||||
double scly = selrect.height() / (double)hei;
|
||||
return chei - gby - (py - selrect.y()) / scly;
|
||||
@@ -1200,7 +1221,7 @@ void Graphic::on_buttonAutofit_clicked() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isEmpty) grect.setRect(0., 0., 1., 1.);
|
||||
if (isEmpty) grect = def_rect;
|
||||
selrect = grect;
|
||||
findGraphicsRect();
|
||||
update();
|
||||
|
||||
@@ -106,6 +106,7 @@ class Graphic: public QFrame
|
||||
Q_PROPERTY(QRectF limit READ limit WRITE setLimit)
|
||||
Q_PROPERTY(QRect margins READ margins WRITE setMargins)
|
||||
Q_PROPERTY(QRectF visualRect READ visualRect WRITE setVisualRect)
|
||||
Q_PROPERTY(QRectF defaultRect READ defaultRect WRITE setDefaultRect)
|
||||
Q_PROPERTY(int minimumRepaintInterval READ minimumRepaintInterval WRITE setMinimumRepaintInterval)
|
||||
|
||||
Q_PROPERTY(double gridNumbersMultiplierX READ gridNumbersMultiplierX WRITE setGridNumbersMultiplierX)
|
||||
@@ -191,6 +192,7 @@ public:
|
||||
double maxVisibleTime() const {return visible_time;}
|
||||
double autoXIncrement() const {return inc_x;}
|
||||
QRectF visualRect() const {return selrect;}
|
||||
QRectF defaultRect() const {return def_rect;}
|
||||
QRectF limit() const {return limit_;}
|
||||
QRect margins() const {return margins_;}
|
||||
int minimumRepaintInterval() const {return min_repaint_int;}
|
||||
@@ -207,12 +209,28 @@ public:
|
||||
QVector<QPointF> graphicData(const int index = 0) const {return graphics[index].polyline;}
|
||||
GraphicsData graphicsData() const;
|
||||
QWidget * viewport() const {return canvas;}
|
||||
QByteArray save();
|
||||
void load(QByteArray ba);
|
||||
void lock() {mutex_.lock();}
|
||||
void unlock() {mutex_.unlock();}
|
||||
QByteArray save();
|
||||
void load(QByteArray ba);
|
||||
void lock() {mutex_.lock();}
|
||||
void unlock() {mutex_.unlock();}
|
||||
|
||||
void reset() {mutex.lock(); clear(); mutex.unlock();}
|
||||
|
||||
GraphicType graphic(int arg) {if (arg < 0 || arg >= graphics.size()) return GraphicType(); return graphics[arg];}
|
||||
const QVector<GraphicType> & allGraphics() const {return graphics;}
|
||||
void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {graphics = g; if (update) updateLegend();}
|
||||
void setHistogramData(const QVector<float> & g, int graphic);
|
||||
void setHistogramData(const QVector<float> & g) {setHistogramData(g, curGraphic);}
|
||||
|
||||
double canvas2realX(double px) const;
|
||||
double canvas2realY(double py) const;
|
||||
double real2canvasX(double px) const;
|
||||
double real2canvasY(double py) const;
|
||||
QPointF canvas2real(QPointF canvas_point) const {return QPointF(canvas2realX(canvas_point.x()), canvas2realY(canvas_point.y()));}
|
||||
QPointF real2canvas(QPointF real_point) const {return QPointF(real2canvasX(real_point.x()), real2canvasY(real_point.y()));}
|
||||
double getScaleX() const {return real2canvasX(1.) - real2canvasX(0.);}
|
||||
double getScaleY() const {return real2canvasY(1.) - real2canvasY(0.);}
|
||||
QPointF getScale() const {return QPointF(getScaleX(), getScaleY());}
|
||||
|
||||
public slots:
|
||||
void setCaption(const QString & str);
|
||||
@@ -299,30 +317,19 @@ public slots:
|
||||
void addGraphic(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true);
|
||||
void addGraphic(const GraphicType & gd, bool update = true) {graphics << gd; if (update) updateLegend();}
|
||||
void setVisualRect(const QRectF & rect);
|
||||
void setDefaultRect(const QRectF & rect);
|
||||
void autofit() {on_buttonAutofit_clicked();}
|
||||
void saveImage();
|
||||
void clear();
|
||||
void update(bool force = false);
|
||||
void updateGraphics() {findGraphicsRect(); update();}
|
||||
GraphicType graphic(int arg) {if (arg < 0 || arg >= graphics.size()) return GraphicType(); return graphics[arg];}
|
||||
const QVector<GraphicType> & allGraphics() const {return graphics;}
|
||||
void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {graphics = g; if (update) updateLegend();}
|
||||
void setCurrentGraphic(int arg) {if (arg < 0 || arg >= graphics.size()) return; curGraphic = arg;}
|
||||
void setGraphicsCount(int arg, bool update = true);
|
||||
void setHistogramData(const QVector<float> & g, int graphic);
|
||||
void setHistogramData(const QVector<float> & g) {setHistogramData(g, curGraphic);}
|
||||
|
||||
void zoom(float factor);
|
||||
void zoomIn() {zoom(1. / 1.2);}
|
||||
void zoomOut() {zoom(1.2);}
|
||||
void fullscreen();
|
||||
|
||||
double canvas2realX(double px);
|
||||
double canvas2realY(double py);
|
||||
double real2canvasX(double px);
|
||||
double real2canvasY(double py);
|
||||
QPointF canvas2real(QPointF canvas_point) {return QPointF(canvas2realX(canvas_point.x()), canvas2realY(canvas_point.y()));}
|
||||
QPointF real2canvas(QPointF real_point) {return QPointF(real2canvasX(real_point.x()), real2canvasY(real_point.y()));}
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent * e);
|
||||
@@ -348,9 +355,10 @@ protected:
|
||||
void setRectToLines();
|
||||
void checkLines();
|
||||
double splitRange(double range, int count = 1);
|
||||
double splitRangeDate(double range, int count = 1, QString * format = 0);
|
||||
double roundTo(double value, double round_to);
|
||||
QPointF absPoint(QPointF point) {return QPointF(qAbs(point.x()), qAbs(point.y()));}
|
||||
QString pointCoords(QPointF point) {return "(" + QString::number(point.x(), 'f', 3) + " ; " + QString::number(point.y(), 'f', 3) + ")";}
|
||||
QString pointCoords(QPointF point);
|
||||
QPair<QString, QString> gridMark(double v) const;
|
||||
|
||||
Ui::Graphic * ui;
|
||||
@@ -364,7 +372,7 @@ protected:
|
||||
QVector<GraphicType> graphics;
|
||||
int curGraphic;
|
||||
GraphicAction curaction, prevaction;
|
||||
QRectF grect, rrect, selrect, limit_;
|
||||
QRectF grect, rrect, selrect, limit_, def_rect;
|
||||
QRect margins_;
|
||||
QSize font_sz;
|
||||
QPoint startpos, curpos, prevpos, gridborder;
|
||||
|
||||
Reference in New Issue
Block a user