git-svn-id: svn://db.shs.com.ru/libs@37 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2015-10-13 11:26:10 +00:00
parent 9d505ef323
commit cf997d59ba
2 changed files with 75 additions and 46 deletions

View File

@@ -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();
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);
if (axis_type_x == Graphic::Numeric) {
int dx = -font_sz.height() / 4.;
painter->setFont(nf);
if (axis_type_x == Graphic::Numeric) {
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();

View File

@@ -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;}
@@ -214,6 +216,22 @@ public:
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);
void setLabelX(const QString & str) {label_x = str; hasLblX = (str.length() > 0); if (aupdate) update();}
@@ -299,31 +317,20 @@ 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);
virtual void resizeEvent(QResizeEvent * ) {if (leg_update) updateLegend();}
@@ -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;