UtiLite  0.3.1
A lite utilities library
qt/include/utilite/UPlot.h
00001 /*
00002 *  utilite is a cross-platform library with
00003 *  useful utilities for fast and small developing.
00004 *  Copyright (C) 2010  Mathieu Labbe
00005 *
00006 *  utilite is free library: you can redistribute it and/or modify
00007 *  it under the terms of the GNU Lesser General Public License as published by
00008 *  the Free Software Foundation, either version 3 of the License, or
00009 *  (at your option) any later version.
00010 *
00011 *  utilite is distributed in the hope that it will be useful,
00012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *  GNU Lesser General Public License for more details.
00015 *
00016 *  You should have received a copy of the GNU Lesser General Public License
00017 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 #ifndef UPLOT_H_
00021 #define UPLOT_H_
00022 
00023 #include "utilite/UtiLiteQtExp.h" // DLL export/import defines
00024 
00025 #include <QtGui/QFrame>
00026 #include <QtCore/QList>
00027 #include <QtCore/QMap>
00028 #include <QtGui/QPen>
00029 #include <QtGui/QBrush>
00030 #include <QtGui/QGraphicsEllipseItem>
00031 #include <QtCore/QMutex>
00032 #include <QtGui/QLabel>
00033 #include <QtGui/QPushButton>
00034 #include <QtCore/QTime>
00035 
00036 class QGraphicsView;
00037 class QGraphicsScene;
00038 class QGraphicsItem;
00039 class QFormLayout;
00040 
00045 class UTILITEQT_EXP UPlotItem : public QGraphicsEllipseItem
00046 {
00047 public:
00051         UPlotItem(qreal dataX, qreal dataY, qreal width=2);
00055         UPlotItem(const QPointF & data, qreal width=2);
00056         virtual ~UPlotItem();
00057 
00058 public:
00059         void setNextItem(UPlotItem * nextItem);
00060         void setPreviousItem(UPlotItem * previousItem);
00061         void setData(const QPointF & data);
00062 
00063         UPlotItem * nextItem() const {return _nextItem;}
00064         UPlotItem * previousItem() const {return _previousItem;};
00065         const QPointF & data() const {return _data;}
00066 
00067 protected:
00068         virtual void hoverEnterEvent(QGraphicsSceneHoverEvent * event);
00069         virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent * event);
00070         virtual void focusInEvent(QFocusEvent * event);
00071         virtual void focusOutEvent(QFocusEvent * event);
00072         virtual void keyReleaseEvent(QKeyEvent * keyEvent);
00073 
00074         virtual void showDescription(bool shown);
00075 private:
00076         void init(qreal dataX, qreal dataY);
00077 
00078 private:
00079         QPointF _data;
00080         UPlotItem * _previousItem;
00081         UPlotItem * _nextItem;
00082         QGraphicsTextItem * _text;
00083         QGraphicsRectItem * _textBackground;
00084 };
00085 
00086 class UPlot;
00087 
00091 class UTILITEQT_EXP UPlotCurve : public QObject
00092 {
00093         Q_OBJECT
00094 
00095 public:
00099         UPlotCurve(const QString & name, QObject * parent = 0);
00103         UPlotCurve(const QString & name, const QVector<UPlotItem *> data, QObject * parent = 0);
00107         UPlotCurve(const QString & name, const QVector<float> & x, const QVector<float> & y, QObject * parent = 0);
00108         virtual ~UPlotCurve();
00109 
00113         const QPen & pen() const {return _pen;}
00117         const QBrush & brush() const {return _brush;}
00118 
00122         void setPen(const QPen & pen);
00126         void setBrush(const QBrush & brush);
00127 
00128         void setItemsColor(const QColor & color);
00129         QColor itemsColor() const  {return _itemsColor;}
00130 
00134         QString name() const {return _name;}
00138         int itemsSize() const;
00139         QPointF getItemData(int index);
00140         bool isVisible() const {return _visible;}
00141         void setData(QVector<UPlotItem*> & data); // take the ownership
00142         void getData(QVector<float> & x, QVector<float> & y) const; // only call in Qt MainThread
00143         void draw(QPainter * painter, const QRect & limits);
00144 
00145 public slots:
00150         virtual void clear();
00155     void setVisible(bool visible);
00160     void setXIncrement(float increment);
00165     void setXStart(float val);
00170         void addValue(UPlotItem * data); // take the ownership
00176         void addValue(float y);
00181         void addValue(float x, float y);
00188         void addValue(const QString & y);
00194         void addValues(QVector<UPlotItem *> & data); // take the ownership
00199         void addValues(const QVector<float> & xs, const QVector<float> & ys);
00205         void addValues(const QVector<float> & ys);
00206         void addValues(const QVector<int> & ys); // for convenience
00212         void addValues(const std::vector<float> & ys); // for convenience
00213         void addValues(const std::vector<int> & ys); // for convenience
00214 
00215         void setData(const QVector<float> & x, const QVector<float> & y);
00216         void setData(const std::vector<float> & x, const std::vector<float> & y);
00217         void setData(const QVector<float> & y);
00218         void setData(const std::vector<float> & y);
00219 
00220 signals:
00225         void dataChanged(const UPlotCurve *);
00226 
00227 protected:
00228         friend class UPlot;
00229         void attach(UPlot * plot);
00230         void detach(UPlot * plot);
00231         void updateMinMax();
00232         const QVector<float> & getMinMax() const {return _minMax;}
00233         int removeItem(int index);
00234         void _addValue(UPlotItem * data);;
00235         virtual bool isMinMaxValid() const {return _minMax.size();}
00236         virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, int maxItemsKept);
00237         QList<QGraphicsItem *> _items;
00238         UPlot * _plot;
00239 
00240 private:
00241         void removeItem(UPlotItem * item);
00242 
00243 private:
00244         QString _name;
00245         QPen _pen;
00246         QBrush _brush;
00247         float _xIncrement;
00248         float _xStart;
00249         bool _visible;
00250         bool _valuesShown;
00251         QVector<float> _minMax; // minX, maxX, minY, maxY
00252         QGraphicsRectItem * _rootItem;
00253         QColor _itemsColor;
00254 };
00255 
00256 
00260 class UTILITEQT_EXP UPlotCurveThreshold : public UPlotCurve
00261 {
00262         Q_OBJECT
00263 
00264 public:
00268         UPlotCurveThreshold(const QString & name, float thesholdValue, Qt::Orientation orientation = Qt::Horizontal, QObject * parent = 0);
00269         virtual ~UPlotCurveThreshold();
00270 
00271 public slots:
00275         void setThreshold(float threshold);
00279         void setOrientation(Qt::Orientation orientation);
00280 
00281 protected:
00282         friend class UPlot;
00283         virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, int maxItemsKept);
00284         virtual bool isMinMaxValid() const {return false;}
00285 
00286 private:
00287         Qt::Orientation _orientation;
00288 };
00289 
00293 class UTILITEQT_EXP UPlotAxis : public QWidget
00294 {
00295 public:
00299         UPlotAxis(Qt::Orientation orientation = Qt::Horizontal, float min=0, float max=1, QWidget * parent = 0);
00300         virtual ~UPlotAxis();
00301 
00302 public:
00307         void setAxis(float & min, float & max);
00311         int border() const {return _border;}
00315         int step() const {return _step;}
00319         int count() const {return _count;}
00323         void setReversed(bool reversed); // Vertical :bottom->up, horizontal :right->left
00324 
00325 protected:
00326         virtual void paintEvent(QPaintEvent * event);
00327 
00328 private:
00329         Qt::Orientation _orientation;
00330         float _min;
00331         float _max;
00332         int _count;
00333         int _step;
00334         bool _reversed;
00335         int _gradMaxDigits;
00336         int _border;
00337 };
00338 
00339 
00343 class UTILITEQT_EXP UPlotLegendItem : public QPushButton
00344 {
00345         Q_OBJECT
00346 
00347 public:
00351         UPlotLegendItem(UPlotCurve * curve, QWidget * parent = 0);
00352         virtual ~UPlotLegendItem();
00353         const UPlotCurve * curve() const {return _curve;}
00354         QPixmap createSymbol(const QPen & pen, const QBrush & brush);
00355 
00356 signals:
00357         void legendItemRemoved(const UPlotCurve *);
00358         void moveUpRequest(UPlotLegendItem *);
00359         void moveDownRequest(UPlotLegendItem *);
00360 
00361 protected:
00362         virtual void contextMenuEvent(QContextMenuEvent * event);
00363 
00364 private:
00365         UPlotCurve * _curve;
00366         QMenu * _menu;
00367         QAction * _aChangeText;
00368         QAction * _aResetText;
00369         QAction * _aChangeColor;
00370         QAction * _aCopyToClipboard;
00371         QAction * _aRemoveCurve;
00372         QAction * _aMoveUp;
00373         QAction * _aMoveDown;
00374 };
00375 
00379 class UTILITEQT_EXP UPlotLegend : public QWidget
00380 {
00381         Q_OBJECT
00382 
00383 public:
00387         UPlotLegend(QWidget * parent = 0);
00388         virtual ~UPlotLegend();
00389 
00390         void setFlat(bool on);
00391         bool isFlat() const {return _flat;}
00392         void addItem(UPlotCurve * curve);
00393         bool remove(const UPlotCurve * curve);
00394 
00395 private slots:
00396         void removeLegendItem(const UPlotCurve * curve);
00397         void moveUp(UPlotLegendItem * item);
00398         void moveDown(UPlotLegendItem * item);
00399 
00400 signals:
00401         void legendItemRemoved(const UPlotCurve * curve);
00402         void legendItemToggled(const UPlotCurve * curve, bool toggled);
00403         void legendItemMoved(const UPlotCurve * curve, int);
00404 
00405 protected:
00406         virtual void contextMenuEvent(QContextMenuEvent * event);
00407 
00408 private slots:
00409         void redirectToggled(bool);
00410 
00411 private:
00412         bool _flat;
00413         QMenu * _menu;
00414         QAction * _aUseFlatButtons;
00415 };
00416 
00417 
00421 class UTILITEQT_EXP UOrientableLabel : public QLabel
00422 {
00423         Q_OBJECT
00424 
00425 public:
00429         UOrientableLabel(const QString & text, Qt::Orientation orientation = Qt::Horizontal, QWidget * parent = 0);
00430         virtual ~UOrientableLabel();
00434         Qt::Orientation orientation() const {return _orientation;}
00438         void setOrientation(Qt::Orientation orientation);
00439         QSize sizeHint() const;
00440         QSize minimumSizeHint() const;
00441 protected:
00442     virtual void paintEvent(QPaintEvent* event);
00443 private:
00444     Qt::Orientation _orientation;
00445 };
00446 
00477 class UTILITEQT_EXP UPlot : public QWidget
00478 {
00479         Q_OBJECT
00480 
00481 public:
00485         UPlot(QWidget * parent = 0);
00486         virtual ~UPlot();
00487 
00491         UPlotCurve * addCurve(const QString & curveName, const QColor & color = QColor());
00495         bool addCurve(UPlotCurve * curve, bool ownershipTransferred = true);
00499         QStringList curveNames();
00500         bool contains(const QString & curveName);
00501         void removeCurves();
00505         UPlotCurveThreshold * addThreshold(const QString & name, float value, Qt::Orientation orientation = Qt::Horizontal);
00506         QString title() const {return this->objectName();}
00507         QPen getRandomPenColored();
00508         void showLegend(bool shown);
00509         void showGrid(bool shown);
00510         void showRefreshRate(bool shown);
00511         void trackMouse(bool tracking);
00512         void keepAllData(bool kept);
00513         void showXAxis(bool shown) {_horizontalAxis->setVisible(shown);}
00514         void showYAxis(bool shown) {_verticalAxis->setVisible(shown);}
00515         void setVariableXAxis() {_fixedAxis[0] = false;}
00516         void setVariableYAxis() {_fixedAxis[1] = false;}
00517         void setFixedXAxis(float x1, float x2);
00518         void setFixedYAxis(float y1, float y2);
00519         void setMaxVisibleItems(int maxVisibleItems);
00520         void setTitle(const QString & text);
00521         void setXLabel(const QString & text);
00522         void setYLabel(const QString & text, Qt::Orientation orientation = Qt::Vertical);
00523         void setWorkingDirectory(const QString & workingDirectory);
00524         void setGraphicsView(bool on);
00525         void setBackgroundColor(const QColor & color);
00526         QRectF sceneRect() const;
00527 
00528 public slots:
00533         void removeCurve(const UPlotCurve * curve);
00534         void showCurve(const UPlotCurve * curve, bool shown);
00535         void updateAxis(); //reset axis and recompute it with all curves minMax
00540         void clearData();
00541 
00542 private slots:
00543         void captureScreen();
00544         void updateAxis(const UPlotCurve * curve);
00545         void moveCurve(const UPlotCurve *, int index);
00546 
00547 protected:
00548         virtual void contextMenuEvent(QContextMenuEvent * event);
00549         virtual void paintEvent(QPaintEvent * event);
00550         virtual void resizeEvent(QResizeEvent * event);
00551         virtual void mousePressEvent(QMouseEvent * event);
00552         virtual void mouseMoveEvent(QMouseEvent * event);
00553         virtual void mouseReleaseEvent(QMouseEvent * event);
00554         virtual void mouseDoubleClickEvent(QMouseEvent * event);
00555 
00556 private:
00557         friend class UPlotCurve;
00558         void addItem(QGraphicsItem * item);
00559 
00560 private:
00561         void replot(QPainter * painter);
00562         bool updateAxis(float x, float y);
00563         bool updateAxis(float x1, float x2, float y1, float y2);
00564         void setupUi();
00565         void createActions();
00566         void createMenus();
00567         void selectScreenCaptureFormat();
00568         bool mousePosToValue(const QPoint & pos, float & x, float & y);
00569 
00570 private:
00571         UPlotLegend * _legend;
00572         QGraphicsView * _view;
00573         QGraphicsItem * _sceneRoot;
00574         QWidget * _graphicsViewHolder;
00575         float _axisMaximums[4]; // {x1->x2, y1->y2}
00576         bool _axisMaximumsSet[4]; // {x1->x2, y1->y2}
00577         bool _fixedAxis[2];
00578         UPlotAxis * _verticalAxis;
00579         UPlotAxis * _horizontalAxis;
00580         int _penStyleCount;
00581         int _maxVisibleItems;
00582         QList<QGraphicsLineItem *> hGridLines;
00583         QList<QGraphicsLineItem *> vGridLines;
00584         QList<UPlotCurve*> _curves;
00585         QLabel * _title;
00586         QLabel * _xLabel;
00587         UOrientableLabel * _yLabel;
00588         QLabel * _refreshRate;
00589         QString _workingDirectory;
00590         QTime _refreshIntervalTime;
00591         int _lowestRefreshRate;
00592         QTime _refreshStartTime;
00593         QString _autoScreenCaptureFormat;
00594         QPoint _mousePressedPos;
00595         QPoint _mouseCurrentPos;
00596         QColor _bgColor;
00597 
00598         QMenu * _menu;
00599         QAction * _aShowLegend;
00600         QAction * _aShowGrid;
00601         QAction * _aKeepAllData;
00602         QAction * _aLimit0;
00603         QAction * _aLimit10;
00604         QAction * _aLimit50;
00605         QAction * _aLimit100;
00606         QAction * _aLimit500;
00607         QAction * _aLimit1000;
00608         QAction * _aLimitCustom;
00609         QAction * _aAddVerticalLine;
00610         QAction * _aAddHorizontalLine;
00611         QAction * _aChangeTitle;
00612         QAction * _aChangeXLabel;
00613         QAction * _aChangeYLabel;
00614         QAction * _aChangeBackgroundColor;
00615         QAction * _aYLabelVertical;
00616         QAction * _aShowRefreshRate;
00617         QAction * _aMouseTracking;
00618         QAction * _aSaveFigure;
00619         QAction * _aAutoScreenCapture;
00620         QAction * _aClearData;
00621         QAction * _aGraphicsView;
00622 };
00623 
00624 #endif /* UPLOT_H_ */
 All Classes Files Functions Variables Enumerations Friends Defines