├── .gitattributes ├── .gitignore ├── QCustomPlot ├── QCustomPlot.pro ├── arf_model.cpp ├── arf_model.h ├── main.cpp ├── qcustomplot.cpp ├── qcustomplot.h ├── widget.cpp ├── widget.h ├── widget.ui └── 说明 └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | # QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | 36 | # QtCtreator CMake 37 | CMakeLists.txt.user 38 | 39 | 40 | # ========================= 41 | # Operating System Files 42 | # ========================= 43 | 44 | # OSX 45 | # ========================= 46 | 47 | .DS_Store 48 | .AppleDouble 49 | .LSOverride 50 | 51 | # Thumbnails 52 | ._* 53 | 54 | # Files that might appear in the root of a volume 55 | .DocumentRevisions-V100 56 | .fseventsd 57 | .Spotlight-V100 58 | .TemporaryItems 59 | .Trashes 60 | .VolumeIcon.icns 61 | 62 | # Directories potentially created on remote AFP share 63 | .AppleDB 64 | .AppleDesktop 65 | Network Trash Folder 66 | Temporary Items 67 | .apdisk 68 | 69 | # Windows 70 | # ========================= 71 | 72 | # Windows image file caches 73 | Thumbs.db 74 | ehthumbs.db 75 | 76 | # Folder config file 77 | Desktop.ini 78 | 79 | # Recycle Bin used on file shares 80 | $RECYCLE.BIN/ 81 | 82 | # Windows Installer files 83 | *.cab 84 | *.msi 85 | *.msm 86 | *.msp 87 | 88 | # Windows shortcuts 89 | *.lnk 90 | -------------------------------------------------------------------------------- /QCustomPlot/QCustomPlot.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StandOutstar/Artificial-Potential-Field-Method-Simulation/8d088a1d7cf4922f76042219e3d2474d04a3c101/QCustomPlot/QCustomPlot.pro -------------------------------------------------------------------------------- /QCustomPlot/arf_model.cpp: -------------------------------------------------------------------------------- 1 | #include "arf_model.h" 2 | 3 | //吸引力计算 4 | void Compute_Attract(double current[2], double goal[2], double attract_gain, double Fa[2]) 5 | { 6 | double r;//距离暂存 7 | double deltax,deltay;//差值暂存 8 | double angle_a;//角度暂存 9 | 10 | //计算距离 11 | deltax = goal[0] - current[0]; 12 | deltay = goal[1] - current[1]; 13 | r = sqrt(deltax*deltax + deltay*deltay); 14 | 15 | //计算角度 16 | angle_a = sign(deltay) * acos(deltax/r); 17 | 18 | //计算分量 19 | Fa[0] = attract_gain * r * cos(angle_a); 20 | Fa[1] = attract_gain * r * sin(angle_a); 21 | } 22 | 23 | //斥力计算 24 | void Compute_Repulsion(double current[2], double obs[7][2], int Obs_Number, double repulse_gain, double Po, double Fr[2]) 25 | { 26 | double deltax,deltay;//差值暂存 27 | double r;//距离暂存 28 | double temp_x,temp_y;//当前坐标暂存 29 | double Fsum; 30 | double frtx,frty; 31 | double obs_distance[7]; 32 | double obs_angle[7]; 33 | 34 | temp_x = current[0]; 35 | temp_y = current[1]; 36 | 37 | //计算角度和距离 38 | for (int i = 0; i < Obs_Number; ++i) 39 | { 40 | /* code */ 41 | deltax = obs[i][0] - temp_x; 42 | deltay = obs[i][1] - temp_y; 43 | 44 | r = sqrt(deltax*deltax + deltay*deltay); 45 | 46 | obs_distance[i] = r; 47 | 48 | obs_angle[i] = sign(deltay)*acos(deltax/r); 49 | } 50 | 51 | //计算斥力 52 | for (int i = 0; i < Obs_Number; ++i) 53 | { 54 | /* code */ 55 | if (obs_distance[i] > Po) 56 | { 57 | /* code */ 58 | frtx = 0; 59 | frty = 0; 60 | } 61 | else 62 | { 63 | Fsum = -repulse_gain * (1/obs_distance[i] - 1/Po) * (1 / (obs_distance[i]*obs_distance[i])); 64 | frtx = Fsum * cos(obs_angle[i]); 65 | frty = Fsum * sin(obs_angle[i]); 66 | } 67 | 68 | Fr[0] += frtx; 69 | Fr[1] += frty; 70 | } 71 | } 72 | 73 | //计算路径,返回值是路径点数 74 | int Compute_Road(double start[2], double goal[2], double obs[7][2], double road[200][2]) 75 | { 76 | 77 | 78 | //引力增益系数 79 | double attract_gain = 7; 80 | 81 | //斥力增益系数 82 | double repulse_gain = 7; 83 | //障碍物影响距离 84 | double Po = 2; 85 | //障碍物个数 86 | double Obs_Number = 7; 87 | 88 | //步长 89 | double StepLength = 0.2; 90 | 91 | //循环迭代最大次数 92 | int max_circletime = 200; 93 | 94 | int s = 0;//存储最后路径点数 95 | double position_angle; 96 | double xnext,ynext; 97 | double current_point[2]; 98 | // double last_point[2]; 99 | double FsumX,FsumY; 100 | double Fa[2],Fr[2]; 101 | 102 | current_point[0] = start[0]; 103 | current_point[1] = start[1]; 104 | 105 | for(int i = 0; i < max_circletime; ++i) 106 | { 107 | 108 | 109 | //吸引力计算 110 | Compute_Attract(current_point, goal, attract_gain, Fa); 111 | //斥力计算 112 | Compute_Repulsion(current_point, obs, Obs_Number, repulse_gain, Po, Fr); 113 | 114 | //计算合力 115 | FsumX = Fa[0] + Fr[0]; 116 | FsumY = Fa[1] + Fr[1]; 117 | 118 | //计算合力角度 119 | if (FsumX > 0) 120 | { 121 | /* code */ 122 | position_angle = atan(FsumY/FsumX); 123 | } 124 | else 125 | { 126 | position_angle = PI + atan(FsumY/FsumX); 127 | } 128 | 129 | //计算下一路径点 130 | xnext = current_point[0] + StepLength*cos(position_angle); 131 | ynext = current_point[1] + StepLength*sin(position_angle); 132 | 133 | // //更新坐标 134 | // last_point[0] = current_point[0]; 135 | // last_point[1] = current_point[1]; 136 | 137 | current_point[0] = xnext; 138 | current_point[1] = ynext; 139 | 140 | //记录路径点 141 | road[i][0] = current_point[0]; 142 | road[i][1] = current_point[1]; 143 | 144 | s = i; 145 | 146 | //判断是否到达目标点 147 | if ((abs(goal[0] - current_point[0]) < 1) && (abs(goal[1] - current_point[1]) < 1)) 148 | { 149 | /* code */ 150 | break; 151 | } 152 | } 153 | 154 | 155 | return s; 156 | } 157 | int sign(double x) 158 | { 159 | if(x > 0) 160 | return 1; 161 | else if(x == 0) 162 | return 0; 163 | else if(x < 0) 164 | return -1; 165 | else 166 | return 1; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /QCustomPlot/arf_model.h: -------------------------------------------------------------------------------- 1 | #ifndef ARF_MODEL_H 2 | #define ARF_MODEL_H 3 | #include 4 | 5 | #define PI 3.1415 6 | 7 | 8 | //吸引力计算 9 | void Compute_Attract(double current[2], double goal[2], double Fa[2], double attract_gain); 10 | 11 | //斥力计算 12 | void Compute_Repulsion(double current[2], double obs[7][2], double Fr[2], int Obs_Number, double repulse_gain, double Po); 13 | 14 | //计算路径,返回值是路径点数 15 | int Compute_Road(double start[2], double goal[2], double obs[7][2], double road[200][2]); 16 | 17 | int sign(double x); 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /QCustomPlot/main.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include 3 | //#include "ARF_C++/arf.h" 4 | #include 5 | //#include 6 | //using namespace std; 7 | int main(int argc, char *argv[]) 8 | { 9 | QApplication a(argc, argv); 10 | Widget w; 11 | 12 | w.show(); 13 | 14 | return a.exec(); 15 | } 16 | // //起点位置 17 | // Point Start(0, 0); 18 | // //障碍物个数 19 | // int Obs_Number = 7; 20 | // //目标和障碍物位置 21 | // Point Goal(10, 10); 22 | // Point Obstacle[7]= { 23 | // Point(1, 1), 24 | // Point(3, 2.5), 25 | // Point(4, 4.5), 26 | // Point(3, 6), 27 | // Point(6, 2), 28 | // Point(5, 5.5), 29 | // Point(9, 9), 30 | // }; 31 | 32 | // APF_Model b(7, 7, 2, 0.2); 33 | // b.Compute_Road (Start,Goal,Obstacle,Obs_Number); 34 | -------------------------------------------------------------------------------- /QCustomPlot/qcustomplot.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | ** ** 3 | ** QCustomPlot, an easy to use, modern plotting widget for Qt ** 4 | ** Copyright (C) 2011-2015 Emanuel Eichhammer ** 5 | ** ** 6 | ** This program is free software: you can redistribute it and/or modify ** 7 | ** it under the terms of the GNU General Public License as published by ** 8 | ** the Free Software Foundation, either version 3 of the License, or ** 9 | ** (at your option) any later version. ** 10 | ** ** 11 | ** This program is distributed in the hope that it will be useful, ** 12 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 13 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 14 | ** GNU General Public License for more details. ** 15 | ** ** 16 | ** You should have received a copy of the GNU General Public License ** 17 | ** along with this program. If not, see http://www.gnu.org/licenses/. ** 18 | ** ** 19 | **************************************************************************** 20 | ** Author: Emanuel Eichhammer ** 21 | ** Website/Contact: http://www.qcustomplot.com/ ** 22 | ** Date: 22.12.15 ** 23 | ** Version: 1.3.2 ** 24 | ****************************************************************************/ 25 | 26 | #ifndef QCUSTOMPLOT_H 27 | #define QCUSTOMPLOT_H 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 49 | # include 50 | # include 51 | # include 52 | #else 53 | # include 54 | # include 55 | #endif 56 | 57 | class QCPPainter; 58 | class QCustomPlot; 59 | class QCPLayerable; 60 | class QCPLayoutElement; 61 | class QCPLayout; 62 | class QCPAxis; 63 | class QCPAxisRect; 64 | class QCPAxisPainterPrivate; 65 | class QCPAbstractPlottable; 66 | class QCPGraph; 67 | class QCPAbstractItem; 68 | class QCPItemPosition; 69 | class QCPLayer; 70 | class QCPPlotTitle; 71 | class QCPLegend; 72 | class QCPAbstractLegendItem; 73 | class QCPColorMap; 74 | class QCPColorScale; 75 | class QCPBars; 76 | 77 | 78 | /*! \file */ 79 | 80 | 81 | // decl definitions for shared library compilation/usage: 82 | #if defined(QCUSTOMPLOT_COMPILE_LIBRARY) 83 | # define QCP_LIB_DECL Q_DECL_EXPORT 84 | #elif defined(QCUSTOMPLOT_USE_LIBRARY) 85 | # define QCP_LIB_DECL Q_DECL_IMPORT 86 | #else 87 | # define QCP_LIB_DECL 88 | #endif 89 | 90 | /*! 91 | The QCP Namespace contains general enums and QFlags used throughout the QCustomPlot library 92 | */ 93 | namespace QCP 94 | { 95 | /*! 96 | Defines the sides of a rectangular entity to which margins can be applied. 97 | 98 | \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins 99 | */ 100 | enum MarginSide { msLeft = 0x01 ///< 0x01 left margin 101 | ,msRight = 0x02 ///< 0x02 right margin 102 | ,msTop = 0x04 ///< 0x04 top margin 103 | ,msBottom = 0x08 ///< 0x08 bottom margin 104 | ,msAll = 0xFF ///< 0xFF all margins 105 | ,msNone = 0x00 ///< 0x00 no margin 106 | }; 107 | Q_DECLARE_FLAGS(MarginSides, MarginSide) 108 | 109 | /*! 110 | Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is 111 | neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective 112 | element how it is drawn. Typically it provides a \a setAntialiased function for this. 113 | 114 | \c AntialiasedElements is a flag of or-combined elements of this enum type. 115 | 116 | \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements 117 | */ 118 | enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks 119 | ,aeGrid = 0x0002 ///< 0x0002 Grid lines 120 | ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines 121 | ,aeLegend = 0x0008 ///< 0x0008 Legend box 122 | ,aeLegendItems = 0x0010 ///< 0x0010 Legend items 123 | ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables (excluding error bars, see element \ref aeErrorBars) 124 | ,aeItems = 0x0040 ///< 0x0040 Main lines of items 125 | ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) 126 | ,aeErrorBars = 0x0100 ///< 0x0100 Error bars 127 | ,aeFills = 0x0200 ///< 0x0200 Borders of fills (e.g. under or between graphs) 128 | ,aeZeroLine = 0x0400 ///< 0x0400 Zero-lines, see \ref QCPGrid::setZeroLinePen 129 | ,aeAll = 0xFFFF ///< 0xFFFF All elements 130 | ,aeNone = 0x0000 ///< 0x0000 No elements 131 | }; 132 | Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) 133 | 134 | /*! 135 | Defines plotting hints that control various aspects of the quality and speed of plotting. 136 | 137 | \see QCustomPlot::setPlottingHints 138 | */ 139 | enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set 140 | ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality 141 | ///< especially of the line segment joins. (Only relevant for solid line pens.) 142 | ,phForceRepaint = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpHint. 143 | ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). 144 | ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. 145 | }; 146 | Q_DECLARE_FLAGS(PlottingHints, PlottingHint) 147 | 148 | /*! 149 | Defines the mouse interactions possible with QCustomPlot. 150 | 151 | \c Interactions is a flag of or-combined elements of this enum type. 152 | 153 | \see QCustomPlot::setInteractions 154 | */ 155 | enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) 156 | ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) 157 | ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking 158 | ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) 159 | ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) 160 | ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) 161 | ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) 162 | ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, the plot title,...) 163 | }; 164 | Q_DECLARE_FLAGS(Interactions, Interaction) 165 | 166 | /*! \internal 167 | 168 | Returns whether the specified \a value is considered an invalid data value for plottables (i.e. 169 | is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the 170 | compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. 171 | */ 172 | inline bool isInvalidData(double value) 173 | { 174 | return qIsNaN(value) || qIsInf(value); 175 | } 176 | 177 | /*! \internal 178 | \overload 179 | 180 | Checks two arguments instead of one. 181 | */ 182 | inline bool isInvalidData(double value1, double value2) 183 | { 184 | return isInvalidData(value1) || isInvalidData(value2); 185 | } 186 | 187 | /*! \internal 188 | 189 | Sets the specified \a side of \a margins to \a value 190 | 191 | \see getMarginValue 192 | */ 193 | inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) 194 | { 195 | switch (side) 196 | { 197 | case QCP::msLeft: margins.setLeft(value); break; 198 | case QCP::msRight: margins.setRight(value); break; 199 | case QCP::msTop: margins.setTop(value); break; 200 | case QCP::msBottom: margins.setBottom(value); break; 201 | case QCP::msAll: margins = QMargins(value, value, value, value); break; 202 | default: break; 203 | } 204 | } 205 | 206 | /*! \internal 207 | 208 | Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or 209 | \ref QCP::msAll, returns 0. 210 | 211 | \see setMarginValue 212 | */ 213 | inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) 214 | { 215 | switch (side) 216 | { 217 | case QCP::msLeft: return margins.left(); 218 | case QCP::msRight: return margins.right(); 219 | case QCP::msTop: return margins.top(); 220 | case QCP::msBottom: return margins.bottom(); 221 | default: break; 222 | } 223 | return 0; 224 | } 225 | 226 | } // end of namespace QCP 227 | 228 | Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) 229 | Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) 230 | Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) 231 | Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) 232 | 233 | 234 | class QCP_LIB_DECL QCPScatterStyle 235 | { 236 | Q_GADGET 237 | public: 238 | /*! 239 | Defines the shape used for scatter points. 240 | 241 | On plottables/items that draw scatters, the sizes of these visualizations (with exception of 242 | \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are 243 | drawn with the pen and brush specified with \ref setPen and \ref setBrush. 244 | */ 245 | Q_ENUMS(ScatterShape) 246 | enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) 247 | ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) 248 | ,ssCross ///< \enumimage{ssCross.png} a cross 249 | ,ssPlus ///< \enumimage{ssPlus.png} a plus 250 | ,ssCircle ///< \enumimage{ssCircle.png} a circle 251 | ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) 252 | ,ssSquare ///< \enumimage{ssSquare.png} a square 253 | ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond 254 | ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus 255 | ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline 256 | ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner 257 | ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside 258 | ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside 259 | ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside 260 | ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside 261 | ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines 262 | ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates 263 | ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) 264 | }; 265 | 266 | QCPScatterStyle(); 267 | QCPScatterStyle(ScatterShape shape, double size=6); 268 | QCPScatterStyle(ScatterShape shape, const QColor &color, double size); 269 | QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); 270 | QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); 271 | QCPScatterStyle(const QPixmap &pixmap); 272 | QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); 273 | 274 | // getters: 275 | double size() const { return mSize; } 276 | ScatterShape shape() const { return mShape; } 277 | QPen pen() const { return mPen; } 278 | QBrush brush() const { return mBrush; } 279 | QPixmap pixmap() const { return mPixmap; } 280 | QPainterPath customPath() const { return mCustomPath; } 281 | 282 | // setters: 283 | void setSize(double size); 284 | void setShape(ScatterShape shape); 285 | void setPen(const QPen &pen); 286 | void setBrush(const QBrush &brush); 287 | void setPixmap(const QPixmap &pixmap); 288 | void setCustomPath(const QPainterPath &customPath); 289 | 290 | // non-property methods: 291 | bool isNone() const { return mShape == ssNone; } 292 | bool isPenDefined() const { return mPenDefined; } 293 | void applyTo(QCPPainter *painter, const QPen &defaultPen) const; 294 | void drawShape(QCPPainter *painter, QPointF pos) const; 295 | void drawShape(QCPPainter *painter, double x, double y) const; 296 | 297 | protected: 298 | // property members: 299 | double mSize; 300 | ScatterShape mShape; 301 | QPen mPen; 302 | QBrush mBrush; 303 | QPixmap mPixmap; 304 | QPainterPath mCustomPath; 305 | 306 | // non-property members: 307 | bool mPenDefined; 308 | }; 309 | Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); 310 | 311 | 312 | class QCP_LIB_DECL QCPPainter : public QPainter 313 | { 314 | Q_GADGET 315 | public: 316 | /*! 317 | Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, 318 | depending on whether they are wanted on the respective output device. 319 | */ 320 | enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices 321 | ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. 322 | ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels 323 | ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) 324 | }; 325 | Q_FLAGS(PainterMode PainterModes) 326 | Q_DECLARE_FLAGS(PainterModes, PainterMode) 327 | 328 | QCPPainter(); 329 | QCPPainter(QPaintDevice *device); 330 | ~QCPPainter(); 331 | 332 | // getters: 333 | bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } 334 | PainterModes modes() const { return mModes; } 335 | 336 | // setters: 337 | void setAntialiasing(bool enabled); 338 | void setMode(PainterMode mode, bool enabled=true); 339 | void setModes(PainterModes modes); 340 | 341 | // methods hiding non-virtual base class functions (QPainter bug workarounds): 342 | bool begin(QPaintDevice *device); 343 | void setPen(const QPen &pen); 344 | void setPen(const QColor &color); 345 | void setPen(Qt::PenStyle penStyle); 346 | void drawLine(const QLineF &line); 347 | void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} 348 | void save(); 349 | void restore(); 350 | 351 | // non-virtual methods: 352 | void makeNonCosmetic(); 353 | 354 | protected: 355 | // property members: 356 | PainterModes mModes; 357 | bool mIsAntialiasing; 358 | 359 | // non-property members: 360 | QStack mAntialiasingStack; 361 | }; 362 | Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) 363 | 364 | 365 | class QCP_LIB_DECL QCPLayer : public QObject 366 | { 367 | Q_OBJECT 368 | /// \cond INCLUDE_QPROPERTIES 369 | Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) 370 | Q_PROPERTY(QString name READ name) 371 | Q_PROPERTY(int index READ index) 372 | Q_PROPERTY(QList children READ children) 373 | Q_PROPERTY(bool visible READ visible WRITE setVisible) 374 | /// \endcond 375 | public: 376 | QCPLayer(QCustomPlot* parentPlot, const QString &layerName); 377 | ~QCPLayer(); 378 | 379 | // getters: 380 | QCustomPlot *parentPlot() const { return mParentPlot; } 381 | QString name() const { return mName; } 382 | int index() const { return mIndex; } 383 | QList children() const { return mChildren; } 384 | bool visible() const { return mVisible; } 385 | 386 | // setters: 387 | void setVisible(bool visible); 388 | 389 | protected: 390 | // property members: 391 | QCustomPlot *mParentPlot; 392 | QString mName; 393 | int mIndex; 394 | QList mChildren; 395 | bool mVisible; 396 | 397 | // non-virtual methods: 398 | void addChild(QCPLayerable *layerable, bool prepend); 399 | void removeChild(QCPLayerable *layerable); 400 | 401 | private: 402 | Q_DISABLE_COPY(QCPLayer) 403 | 404 | friend class QCustomPlot; 405 | friend class QCPLayerable; 406 | }; 407 | 408 | class QCP_LIB_DECL QCPLayerable : public QObject 409 | { 410 | Q_OBJECT 411 | /// \cond INCLUDE_QPROPERTIES 412 | Q_PROPERTY(bool visible READ visible WRITE setVisible) 413 | Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) 414 | Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) 415 | Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) 416 | Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) 417 | /// \endcond 418 | public: 419 | QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); 420 | ~QCPLayerable(); 421 | 422 | // getters: 423 | bool visible() const { return mVisible; } 424 | QCustomPlot *parentPlot() const { return mParentPlot; } 425 | QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } 426 | QCPLayer *layer() const { return mLayer; } 427 | bool antialiased() const { return mAntialiased; } 428 | 429 | // setters: 430 | void setVisible(bool on); 431 | Q_SLOT bool setLayer(QCPLayer *layer); 432 | bool setLayer(const QString &layerName); 433 | void setAntialiased(bool enabled); 434 | 435 | // introduced virtual methods: 436 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 437 | 438 | // non-property methods: 439 | bool realVisibility() const; 440 | 441 | signals: 442 | void layerChanged(QCPLayer *newLayer); 443 | 444 | protected: 445 | // property members: 446 | bool mVisible; 447 | QCustomPlot *mParentPlot; 448 | QPointer mParentLayerable; 449 | QCPLayer *mLayer; 450 | bool mAntialiased; 451 | 452 | // introduced virtual methods: 453 | virtual void parentPlotInitialized(QCustomPlot *parentPlot); 454 | virtual QCP::Interaction selectionCategory() const; 455 | virtual QRect clipRect() const; 456 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; 457 | virtual void draw(QCPPainter *painter) = 0; 458 | // events: 459 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); 460 | virtual void deselectEvent(bool *selectionStateChanged); 461 | 462 | // non-property methods: 463 | void initializeParentPlot(QCustomPlot *parentPlot); 464 | void setParentLayerable(QCPLayerable* parentLayerable); 465 | bool moveToLayer(QCPLayer *layer, bool prepend); 466 | void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; 467 | 468 | private: 469 | Q_DISABLE_COPY(QCPLayerable) 470 | 471 | friend class QCustomPlot; 472 | friend class QCPAxisRect; 473 | }; 474 | 475 | 476 | class QCP_LIB_DECL QCPRange 477 | { 478 | public: 479 | double lower, upper; 480 | 481 | QCPRange(); 482 | QCPRange(double lower, double upper); 483 | 484 | bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } 485 | bool operator!=(const QCPRange& other) const { return !(*this == other); } 486 | 487 | QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } 488 | QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } 489 | QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } 490 | QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } 491 | friend inline const QCPRange operator+(const QCPRange&, double); 492 | friend inline const QCPRange operator+(double, const QCPRange&); 493 | friend inline const QCPRange operator-(const QCPRange& range, double value); 494 | friend inline const QCPRange operator*(const QCPRange& range, double value); 495 | friend inline const QCPRange operator*(double value, const QCPRange& range); 496 | friend inline const QCPRange operator/(const QCPRange& range, double value); 497 | 498 | double size() const; 499 | double center() const; 500 | void normalize(); 501 | void expand(const QCPRange &otherRange); 502 | QCPRange expanded(const QCPRange &otherRange) const; 503 | QCPRange sanitizedForLogScale() const; 504 | QCPRange sanitizedForLinScale() const; 505 | bool contains(double value) const; 506 | 507 | static bool validRange(double lower, double upper); 508 | static bool validRange(const QCPRange &range); 509 | static const double minRange; //1e-280; 510 | static const double maxRange; //1e280; 511 | 512 | }; 513 | Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); 514 | 515 | /* documentation of inline functions */ 516 | 517 | /*! \fn QCPRange &QCPRange::operator+=(const double& value) 518 | 519 | Adds \a value to both boundaries of the range. 520 | */ 521 | 522 | /*! \fn QCPRange &QCPRange::operator-=(const double& value) 523 | 524 | Subtracts \a value from both boundaries of the range. 525 | */ 526 | 527 | /*! \fn QCPRange &QCPRange::operator*=(const double& value) 528 | 529 | Multiplies both boundaries of the range by \a value. 530 | */ 531 | 532 | /*! \fn QCPRange &QCPRange::operator/=(const double& value) 533 | 534 | Divides both boundaries of the range by \a value. 535 | */ 536 | 537 | /* end documentation of inline functions */ 538 | 539 | /*! 540 | Adds \a value to both boundaries of the range. 541 | */ 542 | inline const QCPRange operator+(const QCPRange& range, double value) 543 | { 544 | QCPRange result(range); 545 | result += value; 546 | return result; 547 | } 548 | 549 | /*! 550 | Adds \a value to both boundaries of the range. 551 | */ 552 | inline const QCPRange operator+(double value, const QCPRange& range) 553 | { 554 | QCPRange result(range); 555 | result += value; 556 | return result; 557 | } 558 | 559 | /*! 560 | Subtracts \a value from both boundaries of the range. 561 | */ 562 | inline const QCPRange operator-(const QCPRange& range, double value) 563 | { 564 | QCPRange result(range); 565 | result -= value; 566 | return result; 567 | } 568 | 569 | /*! 570 | Multiplies both boundaries of the range by \a value. 571 | */ 572 | inline const QCPRange operator*(const QCPRange& range, double value) 573 | { 574 | QCPRange result(range); 575 | result *= value; 576 | return result; 577 | } 578 | 579 | /*! 580 | Multiplies both boundaries of the range by \a value. 581 | */ 582 | inline const QCPRange operator*(double value, const QCPRange& range) 583 | { 584 | QCPRange result(range); 585 | result *= value; 586 | return result; 587 | } 588 | 589 | /*! 590 | Divides both boundaries of the range by \a value. 591 | */ 592 | inline const QCPRange operator/(const QCPRange& range, double value) 593 | { 594 | QCPRange result(range); 595 | result /= value; 596 | return result; 597 | } 598 | 599 | 600 | class QCP_LIB_DECL QCPMarginGroup : public QObject 601 | { 602 | Q_OBJECT 603 | public: 604 | QCPMarginGroup(QCustomPlot *parentPlot); 605 | ~QCPMarginGroup(); 606 | 607 | // non-virtual methods: 608 | QList elements(QCP::MarginSide side) const { return mChildren.value(side); } 609 | bool isEmpty() const; 610 | void clear(); 611 | 612 | protected: 613 | // non-property members: 614 | QCustomPlot *mParentPlot; 615 | QHash > mChildren; 616 | 617 | // non-virtual methods: 618 | int commonMargin(QCP::MarginSide side) const; 619 | void addChild(QCP::MarginSide side, QCPLayoutElement *element); 620 | void removeChild(QCP::MarginSide side, QCPLayoutElement *element); 621 | 622 | private: 623 | Q_DISABLE_COPY(QCPMarginGroup) 624 | 625 | friend class QCPLayoutElement; 626 | }; 627 | 628 | 629 | class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable 630 | { 631 | Q_OBJECT 632 | /// \cond INCLUDE_QPROPERTIES 633 | Q_PROPERTY(QCPLayout* layout READ layout) 634 | Q_PROPERTY(QRect rect READ rect) 635 | Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) 636 | Q_PROPERTY(QMargins margins READ margins WRITE setMargins) 637 | Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) 638 | Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) 639 | Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) 640 | /// \endcond 641 | public: 642 | /*! 643 | Defines the phases of the update process, that happens just before a replot. At each phase, 644 | \ref update is called with the according UpdatePhase value. 645 | */ 646 | enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout 647 | ,upMargins ///< Phase in which the margins are calculated and set 648 | ,upLayout ///< Final phase in which the layout system places the rects of the elements 649 | }; 650 | Q_ENUMS(UpdatePhase) 651 | 652 | explicit QCPLayoutElement(QCustomPlot *parentPlot=0); 653 | virtual ~QCPLayoutElement(); 654 | 655 | // getters: 656 | QCPLayout *layout() const { return mParentLayout; } 657 | QRect rect() const { return mRect; } 658 | QRect outerRect() const { return mOuterRect; } 659 | QMargins margins() const { return mMargins; } 660 | QMargins minimumMargins() const { return mMinimumMargins; } 661 | QCP::MarginSides autoMargins() const { return mAutoMargins; } 662 | QSize minimumSize() const { return mMinimumSize; } 663 | QSize maximumSize() const { return mMaximumSize; } 664 | QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } 665 | QHash marginGroups() const { return mMarginGroups; } 666 | 667 | // setters: 668 | void setOuterRect(const QRect &rect); 669 | void setMargins(const QMargins &margins); 670 | void setMinimumMargins(const QMargins &margins); 671 | void setAutoMargins(QCP::MarginSides sides); 672 | void setMinimumSize(const QSize &size); 673 | void setMinimumSize(int width, int height); 674 | void setMaximumSize(const QSize &size); 675 | void setMaximumSize(int width, int height); 676 | void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); 677 | 678 | // introduced virtual methods: 679 | virtual void update(UpdatePhase phase); 680 | virtual QSize minimumSizeHint() const; 681 | virtual QSize maximumSizeHint() const; 682 | virtual QList elements(bool recursive) const; 683 | 684 | // reimplemented virtual methods: 685 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 686 | 687 | protected: 688 | // property members: 689 | QCPLayout *mParentLayout; 690 | QSize mMinimumSize, mMaximumSize; 691 | QRect mRect, mOuterRect; 692 | QMargins mMargins, mMinimumMargins; 693 | QCP::MarginSides mAutoMargins; 694 | QHash mMarginGroups; 695 | 696 | // introduced virtual methods: 697 | virtual int calculateAutoMargin(QCP::MarginSide side); 698 | // events: 699 | virtual void mousePressEvent(QMouseEvent *event) {Q_UNUSED(event)} 700 | virtual void mouseMoveEvent(QMouseEvent *event) {Q_UNUSED(event)} 701 | virtual void mouseReleaseEvent(QMouseEvent *event) {Q_UNUSED(event)} 702 | virtual void mouseDoubleClickEvent(QMouseEvent *event) {Q_UNUSED(event)} 703 | virtual void wheelEvent(QWheelEvent *event) {Q_UNUSED(event)} 704 | 705 | // reimplemented virtual methods: 706 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const { Q_UNUSED(painter) } 707 | virtual void draw(QCPPainter *painter) { Q_UNUSED(painter) } 708 | virtual void parentPlotInitialized(QCustomPlot *parentPlot); 709 | 710 | private: 711 | Q_DISABLE_COPY(QCPLayoutElement) 712 | 713 | friend class QCustomPlot; 714 | friend class QCPLayout; 715 | friend class QCPMarginGroup; 716 | }; 717 | 718 | 719 | class QCP_LIB_DECL QCPLayout : public QCPLayoutElement 720 | { 721 | Q_OBJECT 722 | public: 723 | explicit QCPLayout(); 724 | 725 | // reimplemented virtual methods: 726 | virtual void update(UpdatePhase phase); 727 | virtual QList elements(bool recursive) const; 728 | 729 | // introduced virtual methods: 730 | virtual int elementCount() const = 0; 731 | virtual QCPLayoutElement* elementAt(int index) const = 0; 732 | virtual QCPLayoutElement* takeAt(int index) = 0; 733 | virtual bool take(QCPLayoutElement* element) = 0; 734 | virtual void simplify(); 735 | 736 | // non-virtual methods: 737 | bool removeAt(int index); 738 | bool remove(QCPLayoutElement* element); 739 | void clear(); 740 | 741 | protected: 742 | // introduced virtual methods: 743 | virtual void updateLayout(); 744 | 745 | // non-virtual methods: 746 | void sizeConstraintsChanged() const; 747 | void adoptElement(QCPLayoutElement *el); 748 | void releaseElement(QCPLayoutElement *el); 749 | QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; 750 | 751 | private: 752 | Q_DISABLE_COPY(QCPLayout) 753 | friend class QCPLayoutElement; 754 | }; 755 | 756 | 757 | class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout 758 | { 759 | Q_OBJECT 760 | /// \cond INCLUDE_QPROPERTIES 761 | Q_PROPERTY(int rowCount READ rowCount) 762 | Q_PROPERTY(int columnCount READ columnCount) 763 | Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) 764 | Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) 765 | Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) 766 | Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) 767 | /// \endcond 768 | public: 769 | explicit QCPLayoutGrid(); 770 | virtual ~QCPLayoutGrid(); 771 | 772 | // getters: 773 | int rowCount() const; 774 | int columnCount() const; 775 | QList columnStretchFactors() const { return mColumnStretchFactors; } 776 | QList rowStretchFactors() const { return mRowStretchFactors; } 777 | int columnSpacing() const { return mColumnSpacing; } 778 | int rowSpacing() const { return mRowSpacing; } 779 | 780 | // setters: 781 | void setColumnStretchFactor(int column, double factor); 782 | void setColumnStretchFactors(const QList &factors); 783 | void setRowStretchFactor(int row, double factor); 784 | void setRowStretchFactors(const QList &factors); 785 | void setColumnSpacing(int pixels); 786 | void setRowSpacing(int pixels); 787 | 788 | // reimplemented virtual methods: 789 | virtual void updateLayout(); 790 | virtual int elementCount() const; 791 | virtual QCPLayoutElement* elementAt(int index) const; 792 | virtual QCPLayoutElement* takeAt(int index); 793 | virtual bool take(QCPLayoutElement* element); 794 | virtual QList elements(bool recursive) const; 795 | virtual void simplify(); 796 | virtual QSize minimumSizeHint() const; 797 | virtual QSize maximumSizeHint() const; 798 | 799 | // non-virtual methods: 800 | QCPLayoutElement *element(int row, int column) const; 801 | bool addElement(int row, int column, QCPLayoutElement *element); 802 | bool hasElement(int row, int column); 803 | void expandTo(int newRowCount, int newColumnCount); 804 | void insertRow(int newIndex); 805 | void insertColumn(int newIndex); 806 | 807 | protected: 808 | // property members: 809 | QList > mElements; 810 | QList mColumnStretchFactors; 811 | QList mRowStretchFactors; 812 | int mColumnSpacing, mRowSpacing; 813 | 814 | // non-virtual methods: 815 | void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; 816 | void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; 817 | 818 | private: 819 | Q_DISABLE_COPY(QCPLayoutGrid) 820 | }; 821 | 822 | 823 | class QCP_LIB_DECL QCPLayoutInset : public QCPLayout 824 | { 825 | Q_OBJECT 826 | public: 827 | /*! 828 | Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. 829 | */ 830 | enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect 831 | ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment 832 | }; 833 | 834 | explicit QCPLayoutInset(); 835 | virtual ~QCPLayoutInset(); 836 | 837 | // getters: 838 | InsetPlacement insetPlacement(int index) const; 839 | Qt::Alignment insetAlignment(int index) const; 840 | QRectF insetRect(int index) const; 841 | 842 | // setters: 843 | void setInsetPlacement(int index, InsetPlacement placement); 844 | void setInsetAlignment(int index, Qt::Alignment alignment); 845 | void setInsetRect(int index, const QRectF &rect); 846 | 847 | // reimplemented virtual methods: 848 | virtual void updateLayout(); 849 | virtual int elementCount() const; 850 | virtual QCPLayoutElement* elementAt(int index) const; 851 | virtual QCPLayoutElement* takeAt(int index); 852 | virtual bool take(QCPLayoutElement* element); 853 | virtual void simplify() {} 854 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 855 | 856 | // non-virtual methods: 857 | void addElement(QCPLayoutElement *element, Qt::Alignment alignment); 858 | void addElement(QCPLayoutElement *element, const QRectF &rect); 859 | 860 | protected: 861 | // property members: 862 | QList mElements; 863 | QList mInsetPlacement; 864 | QList mInsetAlignment; 865 | QList mInsetRect; 866 | 867 | private: 868 | Q_DISABLE_COPY(QCPLayoutInset) 869 | }; 870 | 871 | 872 | class QCP_LIB_DECL QCPLineEnding 873 | { 874 | Q_GADGET 875 | public: 876 | /*! 877 | Defines the type of ending decoration for line-like items, e.g. an arrow. 878 | 879 | \image html QCPLineEnding.png 880 | 881 | The width and length of these decorations can be controlled with the functions \ref setWidth 882 | and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only 883 | support a width, the length property is ignored. 884 | 885 | \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding 886 | */ 887 | Q_ENUMS(EndingStyle) 888 | enum EndingStyle { esNone ///< No ending decoration 889 | ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) 890 | ,esSpikeArrow ///< A filled arrow head with an indented back 891 | ,esLineArrow ///< A non-filled arrow head with open back 892 | ,esDisc ///< A filled circle 893 | ,esSquare ///< A filled square 894 | ,esDiamond ///< A filled diamond (45° rotated square) 895 | ,esBar ///< A bar perpendicular to the line 896 | ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) 897 | ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) 898 | }; 899 | 900 | QCPLineEnding(); 901 | QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); 902 | 903 | // getters: 904 | EndingStyle style() const { return mStyle; } 905 | double width() const { return mWidth; } 906 | double length() const { return mLength; } 907 | bool inverted() const { return mInverted; } 908 | 909 | // setters: 910 | void setStyle(EndingStyle style); 911 | void setWidth(double width); 912 | void setLength(double length); 913 | void setInverted(bool inverted); 914 | 915 | // non-property methods: 916 | double boundingDistance() const; 917 | double realLength() const; 918 | void draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const; 919 | void draw(QCPPainter *painter, const QVector2D &pos, double angle) const; 920 | 921 | protected: 922 | // property members: 923 | EndingStyle mStyle; 924 | double mWidth, mLength; 925 | bool mInverted; 926 | }; 927 | Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); 928 | 929 | 930 | class QCP_LIB_DECL QCPGrid :public QCPLayerable 931 | { 932 | Q_OBJECT 933 | /// \cond INCLUDE_QPROPERTIES 934 | Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) 935 | Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) 936 | Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) 937 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 938 | Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) 939 | Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) 940 | /// \endcond 941 | public: 942 | QCPGrid(QCPAxis *parentAxis); 943 | 944 | // getters: 945 | bool subGridVisible() const { return mSubGridVisible; } 946 | bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } 947 | bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } 948 | QPen pen() const { return mPen; } 949 | QPen subGridPen() const { return mSubGridPen; } 950 | QPen zeroLinePen() const { return mZeroLinePen; } 951 | 952 | // setters: 953 | void setSubGridVisible(bool visible); 954 | void setAntialiasedSubGrid(bool enabled); 955 | void setAntialiasedZeroLine(bool enabled); 956 | void setPen(const QPen &pen); 957 | void setSubGridPen(const QPen &pen); 958 | void setZeroLinePen(const QPen &pen); 959 | 960 | protected: 961 | // property members: 962 | bool mSubGridVisible; 963 | bool mAntialiasedSubGrid, mAntialiasedZeroLine; 964 | QPen mPen, mSubGridPen, mZeroLinePen; 965 | // non-property members: 966 | QCPAxis *mParentAxis; 967 | 968 | // reimplemented virtual methods: 969 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; 970 | virtual void draw(QCPPainter *painter); 971 | 972 | // non-virtual methods: 973 | void drawGridLines(QCPPainter *painter) const; 974 | void drawSubGridLines(QCPPainter *painter) const; 975 | 976 | friend class QCPAxis; 977 | }; 978 | 979 | 980 | class QCP_LIB_DECL QCPAxis : public QCPLayerable 981 | { 982 | Q_OBJECT 983 | /// \cond INCLUDE_QPROPERTIES 984 | Q_PROPERTY(AxisType axisType READ axisType) 985 | Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) 986 | Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) 987 | Q_PROPERTY(double scaleLogBase READ scaleLogBase WRITE setScaleLogBase) 988 | Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) 989 | Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) 990 | Q_PROPERTY(bool autoTicks READ autoTicks WRITE setAutoTicks) 991 | Q_PROPERTY(int autoTickCount READ autoTickCount WRITE setAutoTickCount) 992 | Q_PROPERTY(bool autoTickLabels READ autoTickLabels WRITE setAutoTickLabels) 993 | Q_PROPERTY(bool autoTickStep READ autoTickStep WRITE setAutoTickStep) 994 | Q_PROPERTY(bool autoSubTicks READ autoSubTicks WRITE setAutoSubTicks) 995 | Q_PROPERTY(bool ticks READ ticks WRITE setTicks) 996 | Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) 997 | Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) 998 | Q_PROPERTY(LabelType tickLabelType READ tickLabelType WRITE setTickLabelType) 999 | Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) 1000 | Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) 1001 | Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) 1002 | Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) 1003 | Q_PROPERTY(QString dateTimeFormat READ dateTimeFormat WRITE setDateTimeFormat) 1004 | Q_PROPERTY(Qt::TimeSpec dateTimeSpec READ dateTimeSpec WRITE setDateTimeSpec) 1005 | Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) 1006 | Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) 1007 | Q_PROPERTY(double tickStep READ tickStep WRITE setTickStep) 1008 | Q_PROPERTY(QVector tickVector READ tickVector WRITE setTickVector) 1009 | Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels WRITE setTickVectorLabels) 1010 | Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) 1011 | Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) 1012 | Q_PROPERTY(int subTickCount READ subTickCount WRITE setSubTickCount) 1013 | Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) 1014 | Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) 1015 | Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) 1016 | Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) 1017 | Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) 1018 | Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) 1019 | Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) 1020 | Q_PROPERTY(QString label READ label WRITE setLabel) 1021 | Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) 1022 | Q_PROPERTY(int padding READ padding WRITE setPadding) 1023 | Q_PROPERTY(int offset READ offset WRITE setOffset) 1024 | Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) 1025 | Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) 1026 | Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) 1027 | Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) 1028 | Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) 1029 | Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) 1030 | Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) 1031 | Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) 1032 | Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) 1033 | Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) 1034 | Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) 1035 | Q_PROPERTY(QCPGrid* grid READ grid) 1036 | /// \endcond 1037 | public: 1038 | /*! 1039 | Defines at which side of the axis rect the axis will appear. This also affects how the tick 1040 | marks are drawn, on which side the labels are placed etc. 1041 | */ 1042 | enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect 1043 | ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect 1044 | ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect 1045 | ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect 1046 | }; 1047 | Q_FLAGS(AxisType AxisTypes) 1048 | Q_DECLARE_FLAGS(AxisTypes, AxisType) 1049 | /*! 1050 | When automatic tick label generation is enabled (\ref setAutoTickLabels), defines how the 1051 | coordinate of the tick is interpreted, i.e. translated into a string. 1052 | 1053 | \see setTickLabelType 1054 | */ 1055 | enum LabelType { ltNumber ///< Tick coordinate is regarded as normal number and will be displayed as such. (see \ref setNumberFormat) 1056 | ,ltDateTime ///< Tick coordinate is regarded as a date/time (seconds since 1970-01-01T00:00:00 UTC) and will be displayed and formatted as such. (for details, see \ref setDateTimeFormat) 1057 | }; 1058 | Q_ENUMS(LabelType) 1059 | /*! 1060 | Defines on which side of the axis the tick labels (numbers) shall appear. 1061 | 1062 | \see setTickLabelSide 1063 | */ 1064 | enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect 1065 | ,lsOutside ///< Tick labels will be displayed outside the axis rect 1066 | }; 1067 | Q_ENUMS(LabelSide) 1068 | /*! 1069 | Defines the scale of an axis. 1070 | \see setScaleType 1071 | */ 1072 | enum ScaleType { stLinear ///< Linear scaling 1073 | ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed plots and (major) tick marks at every base power (see \ref setScaleLogBase). 1074 | }; 1075 | Q_ENUMS(ScaleType) 1076 | /*! 1077 | Defines the selectable parts of an axis. 1078 | \see setSelectableParts, setSelectedParts 1079 | */ 1080 | enum SelectablePart { spNone = 0 ///< None of the selectable parts 1081 | ,spAxis = 0x001 ///< The axis backbone and tick marks 1082 | ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) 1083 | ,spAxisLabel = 0x004 ///< The axis label 1084 | }; 1085 | Q_FLAGS(SelectablePart SelectableParts) 1086 | Q_DECLARE_FLAGS(SelectableParts, SelectablePart) 1087 | 1088 | explicit QCPAxis(QCPAxisRect *parent, AxisType type); 1089 | virtual ~QCPAxis(); 1090 | 1091 | // getters: 1092 | AxisType axisType() const { return mAxisType; } 1093 | QCPAxisRect *axisRect() const { return mAxisRect; } 1094 | ScaleType scaleType() const { return mScaleType; } 1095 | double scaleLogBase() const { return mScaleLogBase; } 1096 | const QCPRange range() const { return mRange; } 1097 | bool rangeReversed() const { return mRangeReversed; } 1098 | bool autoTicks() const { return mAutoTicks; } 1099 | int autoTickCount() const { return mAutoTickCount; } 1100 | bool autoTickLabels() const { return mAutoTickLabels; } 1101 | bool autoTickStep() const { return mAutoTickStep; } 1102 | bool autoSubTicks() const { return mAutoSubTicks; } 1103 | bool ticks() const { return mTicks; } 1104 | bool tickLabels() const { return mTickLabels; } 1105 | int tickLabelPadding() const; 1106 | LabelType tickLabelType() const { return mTickLabelType; } 1107 | QFont tickLabelFont() const { return mTickLabelFont; } 1108 | QColor tickLabelColor() const { return mTickLabelColor; } 1109 | double tickLabelRotation() const; 1110 | LabelSide tickLabelSide() const; 1111 | QString dateTimeFormat() const { return mDateTimeFormat; } 1112 | Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } 1113 | QString numberFormat() const; 1114 | int numberPrecision() const { return mNumberPrecision; } 1115 | double tickStep() const { return mTickStep; } 1116 | QVector tickVector() const { return mTickVector; } 1117 | QVector tickVectorLabels() const { return mTickVectorLabels; } 1118 | int tickLengthIn() const; 1119 | int tickLengthOut() const; 1120 | int subTickCount() const { return mSubTickCount; } 1121 | int subTickLengthIn() const; 1122 | int subTickLengthOut() const; 1123 | QPen basePen() const { return mBasePen; } 1124 | QPen tickPen() const { return mTickPen; } 1125 | QPen subTickPen() const { return mSubTickPen; } 1126 | QFont labelFont() const { return mLabelFont; } 1127 | QColor labelColor() const { return mLabelColor; } 1128 | QString label() const { return mLabel; } 1129 | int labelPadding() const; 1130 | int padding() const { return mPadding; } 1131 | int offset() const; 1132 | SelectableParts selectedParts() const { return mSelectedParts; } 1133 | SelectableParts selectableParts() const { return mSelectableParts; } 1134 | QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } 1135 | QFont selectedLabelFont() const { return mSelectedLabelFont; } 1136 | QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } 1137 | QColor selectedLabelColor() const { return mSelectedLabelColor; } 1138 | QPen selectedBasePen() const { return mSelectedBasePen; } 1139 | QPen selectedTickPen() const { return mSelectedTickPen; } 1140 | QPen selectedSubTickPen() const { return mSelectedSubTickPen; } 1141 | QCPLineEnding lowerEnding() const; 1142 | QCPLineEnding upperEnding() const; 1143 | QCPGrid *grid() const { return mGrid; } 1144 | 1145 | // setters: 1146 | Q_SLOT void setScaleType(QCPAxis::ScaleType type); 1147 | void setScaleLogBase(double base); 1148 | Q_SLOT void setRange(const QCPRange &range); 1149 | void setRange(double lower, double upper); 1150 | void setRange(double position, double size, Qt::AlignmentFlag alignment); 1151 | void setRangeLower(double lower); 1152 | void setRangeUpper(double upper); 1153 | void setRangeReversed(bool reversed); 1154 | void setAutoTicks(bool on); 1155 | void setAutoTickCount(int approximateCount); 1156 | void setAutoTickLabels(bool on); 1157 | void setAutoTickStep(bool on); 1158 | void setAutoSubTicks(bool on); 1159 | void setTicks(bool show); 1160 | void setTickLabels(bool show); 1161 | void setTickLabelPadding(int padding); 1162 | void setTickLabelType(LabelType type); 1163 | void setTickLabelFont(const QFont &font); 1164 | void setTickLabelColor(const QColor &color); 1165 | void setTickLabelRotation(double degrees); 1166 | void setTickLabelSide(LabelSide side); 1167 | void setDateTimeFormat(const QString &format); 1168 | void setDateTimeSpec(const Qt::TimeSpec &timeSpec); 1169 | void setNumberFormat(const QString &formatCode); 1170 | void setNumberPrecision(int precision); 1171 | void setTickStep(double step); 1172 | void setTickVector(const QVector &vec); 1173 | void setTickVectorLabels(const QVector &vec); 1174 | void setTickLength(int inside, int outside=0); 1175 | void setTickLengthIn(int inside); 1176 | void setTickLengthOut(int outside); 1177 | void setSubTickCount(int count); 1178 | void setSubTickLength(int inside, int outside=0); 1179 | void setSubTickLengthIn(int inside); 1180 | void setSubTickLengthOut(int outside); 1181 | void setBasePen(const QPen &pen); 1182 | void setTickPen(const QPen &pen); 1183 | void setSubTickPen(const QPen &pen); 1184 | void setLabelFont(const QFont &font); 1185 | void setLabelColor(const QColor &color); 1186 | void setLabel(const QString &str); 1187 | void setLabelPadding(int padding); 1188 | void setPadding(int padding); 1189 | void setOffset(int offset); 1190 | void setSelectedTickLabelFont(const QFont &font); 1191 | void setSelectedLabelFont(const QFont &font); 1192 | void setSelectedTickLabelColor(const QColor &color); 1193 | void setSelectedLabelColor(const QColor &color); 1194 | void setSelectedBasePen(const QPen &pen); 1195 | void setSelectedTickPen(const QPen &pen); 1196 | void setSelectedSubTickPen(const QPen &pen); 1197 | Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); 1198 | Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); 1199 | void setLowerEnding(const QCPLineEnding &ending); 1200 | void setUpperEnding(const QCPLineEnding &ending); 1201 | 1202 | // reimplemented virtual methods: 1203 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 1204 | 1205 | // non-property methods: 1206 | Qt::Orientation orientation() const { return mOrientation; } 1207 | void moveRange(double diff); 1208 | void scaleRange(double factor, double center); 1209 | void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); 1210 | void rescale(bool onlyVisiblePlottables=false); 1211 | double pixelToCoord(double value) const; 1212 | double coordToPixel(double value) const; 1213 | SelectablePart getPartAt(const QPointF &pos) const; 1214 | QList plottables() const; 1215 | QList graphs() const; 1216 | QList items() const; 1217 | 1218 | static AxisType marginSideToAxisType(QCP::MarginSide side); 1219 | static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } 1220 | static AxisType opposite(AxisType type); 1221 | 1222 | signals: 1223 | void ticksRequest(); 1224 | void rangeChanged(const QCPRange &newRange); 1225 | void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); 1226 | void scaleTypeChanged(QCPAxis::ScaleType scaleType); 1227 | void selectionChanged(const QCPAxis::SelectableParts &parts); 1228 | void selectableChanged(const QCPAxis::SelectableParts &parts); 1229 | 1230 | protected: 1231 | // property members: 1232 | // axis base: 1233 | AxisType mAxisType; 1234 | QCPAxisRect *mAxisRect; 1235 | //int mOffset; // in QCPAxisPainter 1236 | int mPadding; 1237 | Qt::Orientation mOrientation; 1238 | SelectableParts mSelectableParts, mSelectedParts; 1239 | QPen mBasePen, mSelectedBasePen; 1240 | //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter 1241 | // axis label: 1242 | //int mLabelPadding; // in QCPAxisPainter 1243 | QString mLabel; 1244 | QFont mLabelFont, mSelectedLabelFont; 1245 | QColor mLabelColor, mSelectedLabelColor; 1246 | // tick labels: 1247 | //int mTickLabelPadding; // in QCPAxisPainter 1248 | bool mTickLabels, mAutoTickLabels; 1249 | //double mTickLabelRotation; // in QCPAxisPainter 1250 | LabelType mTickLabelType; 1251 | QFont mTickLabelFont, mSelectedTickLabelFont; 1252 | QColor mTickLabelColor, mSelectedTickLabelColor; 1253 | QString mDateTimeFormat; 1254 | Qt::TimeSpec mDateTimeSpec; 1255 | int mNumberPrecision; 1256 | QLatin1Char mNumberFormatChar; 1257 | bool mNumberBeautifulPowers; 1258 | //bool mNumberMultiplyCross; // QCPAxisPainter 1259 | // ticks and subticks: 1260 | bool mTicks; 1261 | double mTickStep; 1262 | int mSubTickCount, mAutoTickCount; 1263 | bool mAutoTicks, mAutoTickStep, mAutoSubTicks; 1264 | //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter 1265 | QPen mTickPen, mSelectedTickPen; 1266 | QPen mSubTickPen, mSelectedSubTickPen; 1267 | // scale and range: 1268 | QCPRange mRange; 1269 | bool mRangeReversed; 1270 | ScaleType mScaleType; 1271 | double mScaleLogBase, mScaleLogBaseLogInv; 1272 | 1273 | // non-property members: 1274 | QCPGrid *mGrid; 1275 | QCPAxisPainterPrivate *mAxisPainter; 1276 | int mLowestVisibleTick, mHighestVisibleTick; 1277 | QVector mTickVector; 1278 | QVector mTickVectorLabels; 1279 | QVector mSubTickVector; 1280 | bool mCachedMarginValid; 1281 | int mCachedMargin; 1282 | 1283 | // introduced virtual methods: 1284 | virtual void setupTickVectors(); 1285 | virtual void generateAutoTicks(); 1286 | virtual int calculateAutoSubTickCount(double tickStep) const; 1287 | virtual int calculateMargin(); 1288 | 1289 | // reimplemented virtual methods: 1290 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; 1291 | virtual void draw(QCPPainter *painter); 1292 | virtual QCP::Interaction selectionCategory() const; 1293 | // events: 1294 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); 1295 | virtual void deselectEvent(bool *selectionStateChanged); 1296 | 1297 | // non-virtual methods: 1298 | void visibleTickBounds(int &lowIndex, int &highIndex) const; 1299 | double baseLog(double value) const; 1300 | double basePow(double value) const; 1301 | QPen getBasePen() const; 1302 | QPen getTickPen() const; 1303 | QPen getSubTickPen() const; 1304 | QFont getTickLabelFont() const; 1305 | QFont getLabelFont() const; 1306 | QColor getTickLabelColor() const; 1307 | QColor getLabelColor() const; 1308 | 1309 | private: 1310 | Q_DISABLE_COPY(QCPAxis) 1311 | 1312 | friend class QCustomPlot; 1313 | friend class QCPGrid; 1314 | friend class QCPAxisRect; 1315 | }; 1316 | Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) 1317 | Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) 1318 | Q_DECLARE_METATYPE(QCPAxis::SelectablePart) 1319 | 1320 | 1321 | class QCPAxisPainterPrivate 1322 | { 1323 | public: 1324 | explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); 1325 | virtual ~QCPAxisPainterPrivate(); 1326 | 1327 | virtual void draw(QCPPainter *painter); 1328 | virtual int size() const; 1329 | void clearCache(); 1330 | 1331 | QRect axisSelectionBox() const { return mAxisSelectionBox; } 1332 | QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } 1333 | QRect labelSelectionBox() const { return mLabelSelectionBox; } 1334 | 1335 | // public property members: 1336 | QCPAxis::AxisType type; 1337 | QPen basePen; 1338 | QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters 1339 | int labelPadding; // directly accessed by QCPAxis setters/getters 1340 | QFont labelFont; 1341 | QColor labelColor; 1342 | QString label; 1343 | int tickLabelPadding; // directly accessed by QCPAxis setters/getters 1344 | double tickLabelRotation; // directly accessed by QCPAxis setters/getters 1345 | QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters 1346 | bool substituteExponent; 1347 | bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters 1348 | int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters 1349 | QPen tickPen, subTickPen; 1350 | QFont tickLabelFont; 1351 | QColor tickLabelColor; 1352 | QRect axisRect, viewportRect; 1353 | double offset; // directly accessed by QCPAxis setters/getters 1354 | bool abbreviateDecimalPowers; 1355 | bool reversedEndings; 1356 | 1357 | QVector subTickPositions; 1358 | QVector tickPositions; 1359 | QVector tickLabels; 1360 | 1361 | protected: 1362 | struct CachedLabel 1363 | { 1364 | QPointF offset; 1365 | QPixmap pixmap; 1366 | }; 1367 | struct TickLabelData 1368 | { 1369 | QString basePart, expPart; 1370 | QRect baseBounds, expBounds, totalBounds, rotatedTotalBounds; 1371 | QFont baseFont, expFont; 1372 | }; 1373 | QCustomPlot *mParentPlot; 1374 | QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters 1375 | QCache mLabelCache; 1376 | QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; 1377 | 1378 | virtual QByteArray generateLabelParameterHash() const; 1379 | 1380 | virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); 1381 | virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; 1382 | virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; 1383 | virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; 1384 | virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; 1385 | }; 1386 | 1387 | 1388 | class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable 1389 | { 1390 | Q_OBJECT 1391 | /// \cond INCLUDE_QPROPERTIES 1392 | Q_PROPERTY(QString name READ name WRITE setName) 1393 | Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) 1394 | Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) 1395 | Q_PROPERTY(bool antialiasedErrorBars READ antialiasedErrorBars WRITE setAntialiasedErrorBars) 1396 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 1397 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 1398 | Q_PROPERTY(QBrush brush READ brush WRITE setBrush) 1399 | Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) 1400 | Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) 1401 | Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) 1402 | Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) 1403 | Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) 1404 | /// \endcond 1405 | public: 1406 | QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); 1407 | 1408 | // getters: 1409 | QString name() const { return mName; } 1410 | bool antialiasedFill() const { return mAntialiasedFill; } 1411 | bool antialiasedScatters() const { return mAntialiasedScatters; } 1412 | bool antialiasedErrorBars() const { return mAntialiasedErrorBars; } 1413 | QPen pen() const { return mPen; } 1414 | QPen selectedPen() const { return mSelectedPen; } 1415 | QBrush brush() const { return mBrush; } 1416 | QBrush selectedBrush() const { return mSelectedBrush; } 1417 | QCPAxis *keyAxis() const { return mKeyAxis.data(); } 1418 | QCPAxis *valueAxis() const { return mValueAxis.data(); } 1419 | bool selectable() const { return mSelectable; } 1420 | bool selected() const { return mSelected; } 1421 | 1422 | // setters: 1423 | void setName(const QString &name); 1424 | void setAntialiasedFill(bool enabled); 1425 | void setAntialiasedScatters(bool enabled); 1426 | void setAntialiasedErrorBars(bool enabled); 1427 | void setPen(const QPen &pen); 1428 | void setSelectedPen(const QPen &pen); 1429 | void setBrush(const QBrush &brush); 1430 | void setSelectedBrush(const QBrush &brush); 1431 | void setKeyAxis(QCPAxis *axis); 1432 | void setValueAxis(QCPAxis *axis); 1433 | Q_SLOT void setSelectable(bool selectable); 1434 | Q_SLOT void setSelected(bool selected); 1435 | 1436 | // introduced virtual methods: 1437 | virtual void clearData() = 0; 1438 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; 1439 | virtual bool addToLegend(); 1440 | virtual bool removeFromLegend() const; 1441 | 1442 | // non-property methods: 1443 | void rescaleAxes(bool onlyEnlarge=false) const; 1444 | void rescaleKeyAxis(bool onlyEnlarge=false) const; 1445 | void rescaleValueAxis(bool onlyEnlarge=false) const; 1446 | 1447 | signals: 1448 | void selectionChanged(bool selected); 1449 | void selectableChanged(bool selectable); 1450 | 1451 | protected: 1452 | /*! 1453 | Represents negative and positive sign domain for passing to \ref getKeyRange and \ref getValueRange. 1454 | */ 1455 | enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero 1456 | ,sdBoth ///< Both sign domains, including zero, i.e. all (rational) numbers 1457 | ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero 1458 | }; 1459 | 1460 | // property members: 1461 | QString mName; 1462 | bool mAntialiasedFill, mAntialiasedScatters, mAntialiasedErrorBars; 1463 | QPen mPen, mSelectedPen; 1464 | QBrush mBrush, mSelectedBrush; 1465 | QPointer mKeyAxis, mValueAxis; 1466 | bool mSelectable, mSelected; 1467 | 1468 | // reimplemented virtual methods: 1469 | virtual QRect clipRect() const; 1470 | virtual void draw(QCPPainter *painter) = 0; 1471 | virtual QCP::Interaction selectionCategory() const; 1472 | void applyDefaultAntialiasingHint(QCPPainter *painter) const; 1473 | // events: 1474 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); 1475 | virtual void deselectEvent(bool *selectionStateChanged); 1476 | 1477 | // introduced virtual methods: 1478 | virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; 1479 | virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const = 0; 1480 | virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const = 0; 1481 | 1482 | // non-virtual methods: 1483 | void coordsToPixels(double key, double value, double &x, double &y) const; 1484 | const QPointF coordsToPixels(double key, double value) const; 1485 | void pixelsToCoords(double x, double y, double &key, double &value) const; 1486 | void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; 1487 | QPen mainPen() const; 1488 | QBrush mainBrush() const; 1489 | void applyFillAntialiasingHint(QCPPainter *painter) const; 1490 | void applyScattersAntialiasingHint(QCPPainter *painter) const; 1491 | void applyErrorBarsAntialiasingHint(QCPPainter *painter) const; 1492 | double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const; 1493 | 1494 | private: 1495 | Q_DISABLE_COPY(QCPAbstractPlottable) 1496 | 1497 | friend class QCustomPlot; 1498 | friend class QCPAxis; 1499 | friend class QCPPlottableLegendItem; 1500 | }; 1501 | 1502 | 1503 | class QCP_LIB_DECL QCPItemAnchor 1504 | { 1505 | public: 1506 | QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId=-1); 1507 | virtual ~QCPItemAnchor(); 1508 | 1509 | // getters: 1510 | QString name() const { return mName; } 1511 | virtual QPointF pixelPoint() const; 1512 | 1513 | protected: 1514 | // property members: 1515 | QString mName; 1516 | 1517 | // non-property members: 1518 | QCustomPlot *mParentPlot; 1519 | QCPAbstractItem *mParentItem; 1520 | int mAnchorId; 1521 | QSet mChildrenX, mChildrenY; 1522 | 1523 | // introduced virtual methods: 1524 | virtual QCPItemPosition *toQCPItemPosition() { return 0; } 1525 | 1526 | // non-virtual methods: 1527 | void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent 1528 | void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted 1529 | void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent 1530 | void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted 1531 | 1532 | private: 1533 | Q_DISABLE_COPY(QCPItemAnchor) 1534 | 1535 | friend class QCPItemPosition; 1536 | }; 1537 | 1538 | 1539 | 1540 | class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor 1541 | { 1542 | public: 1543 | /*! 1544 | Defines the ways an item position can be specified. Thus it defines what the numbers passed to 1545 | \ref setCoords actually mean. 1546 | 1547 | \see setType 1548 | */ 1549 | enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. 1550 | ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top 1551 | ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and 1552 | ///< vertically at the top of the viewport/widget, etc. 1553 | ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top 1554 | ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and 1555 | ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. 1556 | ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). 1557 | }; 1558 | 1559 | QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name); 1560 | virtual ~QCPItemPosition(); 1561 | 1562 | // getters: 1563 | PositionType type() const { return typeX(); } 1564 | PositionType typeX() const { return mPositionTypeX; } 1565 | PositionType typeY() const { return mPositionTypeY; } 1566 | QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } 1567 | QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } 1568 | QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } 1569 | double key() const { return mKey; } 1570 | double value() const { return mValue; } 1571 | QPointF coords() const { return QPointF(mKey, mValue); } 1572 | QCPAxis *keyAxis() const { return mKeyAxis.data(); } 1573 | QCPAxis *valueAxis() const { return mValueAxis.data(); } 1574 | QCPAxisRect *axisRect() const; 1575 | virtual QPointF pixelPoint() const; 1576 | 1577 | // setters: 1578 | void setType(PositionType type); 1579 | void setTypeX(PositionType type); 1580 | void setTypeY(PositionType type); 1581 | bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); 1582 | bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); 1583 | bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); 1584 | void setCoords(double key, double value); 1585 | void setCoords(const QPointF &coords); 1586 | void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); 1587 | void setAxisRect(QCPAxisRect *axisRect); 1588 | void setPixelPoint(const QPointF &pixelPoint); 1589 | 1590 | protected: 1591 | // property members: 1592 | PositionType mPositionTypeX, mPositionTypeY; 1593 | QPointer mKeyAxis, mValueAxis; 1594 | QPointer mAxisRect; 1595 | double mKey, mValue; 1596 | QCPItemAnchor *mParentAnchorX, *mParentAnchorY; 1597 | 1598 | // reimplemented virtual methods: 1599 | virtual QCPItemPosition *toQCPItemPosition() { return this; } 1600 | 1601 | private: 1602 | Q_DISABLE_COPY(QCPItemPosition) 1603 | 1604 | }; 1605 | 1606 | 1607 | class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable 1608 | { 1609 | Q_OBJECT 1610 | /// \cond INCLUDE_QPROPERTIES 1611 | Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) 1612 | Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) 1613 | Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) 1614 | Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) 1615 | /// \endcond 1616 | public: 1617 | QCPAbstractItem(QCustomPlot *parentPlot); 1618 | virtual ~QCPAbstractItem(); 1619 | 1620 | // getters: 1621 | bool clipToAxisRect() const { return mClipToAxisRect; } 1622 | QCPAxisRect *clipAxisRect() const; 1623 | bool selectable() const { return mSelectable; } 1624 | bool selected() const { return mSelected; } 1625 | 1626 | // setters: 1627 | void setClipToAxisRect(bool clip); 1628 | void setClipAxisRect(QCPAxisRect *rect); 1629 | Q_SLOT void setSelectable(bool selectable); 1630 | Q_SLOT void setSelected(bool selected); 1631 | 1632 | // reimplemented virtual methods: 1633 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; 1634 | 1635 | // non-virtual methods: 1636 | QList positions() const { return mPositions; } 1637 | QList anchors() const { return mAnchors; } 1638 | QCPItemPosition *position(const QString &name) const; 1639 | QCPItemAnchor *anchor(const QString &name) const; 1640 | bool hasAnchor(const QString &name) const; 1641 | 1642 | signals: 1643 | void selectionChanged(bool selected); 1644 | void selectableChanged(bool selectable); 1645 | 1646 | protected: 1647 | // property members: 1648 | bool mClipToAxisRect; 1649 | QPointer mClipAxisRect; 1650 | QList mPositions; 1651 | QList mAnchors; 1652 | bool mSelectable, mSelected; 1653 | 1654 | // reimplemented virtual methods: 1655 | virtual QCP::Interaction selectionCategory() const; 1656 | virtual QRect clipRect() const; 1657 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; 1658 | virtual void draw(QCPPainter *painter) = 0; 1659 | // events: 1660 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); 1661 | virtual void deselectEvent(bool *selectionStateChanged); 1662 | 1663 | // introduced virtual methods: 1664 | virtual QPointF anchorPixelPoint(int anchorId) const; 1665 | 1666 | // non-virtual methods: 1667 | double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const; 1668 | double rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const; 1669 | QCPItemPosition *createPosition(const QString &name); 1670 | QCPItemAnchor *createAnchor(const QString &name, int anchorId); 1671 | 1672 | private: 1673 | Q_DISABLE_COPY(QCPAbstractItem) 1674 | 1675 | friend class QCustomPlot; 1676 | friend class QCPItemAnchor; 1677 | }; 1678 | 1679 | 1680 | class QCP_LIB_DECL QCustomPlot : public QWidget 1681 | { 1682 | Q_OBJECT 1683 | /// \cond INCLUDE_QPROPERTIES 1684 | Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) 1685 | Q_PROPERTY(QPixmap background READ background WRITE setBackground) 1686 | Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) 1687 | Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) 1688 | Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) 1689 | Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) 1690 | Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) 1691 | Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) 1692 | Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) 1693 | /// \endcond 1694 | public: 1695 | /*! 1696 | Defines how a layer should be inserted relative to an other layer. 1697 | 1698 | \see addLayer, moveLayer 1699 | */ 1700 | enum LayerInsertMode { limBelow ///< Layer is inserted below other layer 1701 | ,limAbove ///< Layer is inserted above other layer 1702 | }; 1703 | Q_ENUMS(LayerInsertMode) 1704 | 1705 | /*! 1706 | Defines with what timing the QCustomPlot surface is refreshed after a replot. 1707 | 1708 | \see replot 1709 | */ 1710 | enum RefreshPriority { rpImmediate ///< The QCustomPlot surface is immediately refreshed, by calling QWidget::repaint() after the replot 1711 | ,rpQueued ///< Queues the refresh such that it is performed at a slightly delayed point in time after the replot, by calling QWidget::update() after the replot 1712 | ,rpHint ///< Whether to use immediate repaint or queued update depends on whether the plotting hint \ref QCP::phForceRepaint is set, see \ref setPlottingHints. 1713 | }; 1714 | 1715 | explicit QCustomPlot(QWidget *parent = 0); 1716 | virtual ~QCustomPlot(); 1717 | 1718 | // getters: 1719 | QRect viewport() const { return mViewport; } 1720 | QPixmap background() const { return mBackgroundPixmap; } 1721 | bool backgroundScaled() const { return mBackgroundScaled; } 1722 | Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } 1723 | QCPLayoutGrid *plotLayout() const { return mPlotLayout; } 1724 | QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } 1725 | QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } 1726 | bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } 1727 | const QCP::Interactions interactions() const { return mInteractions; } 1728 | int selectionTolerance() const { return mSelectionTolerance; } 1729 | bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } 1730 | QCP::PlottingHints plottingHints() const { return mPlottingHints; } 1731 | Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } 1732 | 1733 | // setters: 1734 | void setViewport(const QRect &rect); 1735 | void setBackground(const QPixmap &pm); 1736 | void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); 1737 | void setBackground(const QBrush &brush); 1738 | void setBackgroundScaled(bool scaled); 1739 | void setBackgroundScaledMode(Qt::AspectRatioMode mode); 1740 | void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); 1741 | void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); 1742 | void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); 1743 | void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); 1744 | void setAutoAddPlottableToLegend(bool on); 1745 | void setInteractions(const QCP::Interactions &interactions); 1746 | void setInteraction(const QCP::Interaction &interaction, bool enabled=true); 1747 | void setSelectionTolerance(int pixels); 1748 | void setNoAntialiasingOnDrag(bool enabled); 1749 | void setPlottingHints(const QCP::PlottingHints &hints); 1750 | void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); 1751 | void setMultiSelectModifier(Qt::KeyboardModifier modifier); 1752 | 1753 | // non-property methods: 1754 | // plottable interface: 1755 | QCPAbstractPlottable *plottable(int index); 1756 | QCPAbstractPlottable *plottable(); 1757 | bool addPlottable(QCPAbstractPlottable *plottable); 1758 | bool removePlottable(QCPAbstractPlottable *plottable); 1759 | bool removePlottable(int index); 1760 | int clearPlottables(); 1761 | int plottableCount() const; 1762 | QList selectedPlottables() const; 1763 | QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; 1764 | bool hasPlottable(QCPAbstractPlottable *plottable) const; 1765 | 1766 | // specialized interface for QCPGraph: 1767 | QCPGraph *graph(int index) const; 1768 | QCPGraph *graph() const; 1769 | QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); 1770 | bool removeGraph(QCPGraph *graph); 1771 | bool removeGraph(int index); 1772 | int clearGraphs(); 1773 | int graphCount() const; 1774 | QList selectedGraphs() const; 1775 | 1776 | // item interface: 1777 | QCPAbstractItem *item(int index) const; 1778 | QCPAbstractItem *item() const; 1779 | bool addItem(QCPAbstractItem* item); 1780 | bool removeItem(QCPAbstractItem *item); 1781 | bool removeItem(int index); 1782 | int clearItems(); 1783 | int itemCount() const; 1784 | QList selectedItems() const; 1785 | QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; 1786 | bool hasItem(QCPAbstractItem *item) const; 1787 | 1788 | // layer interface: 1789 | QCPLayer *layer(const QString &name) const; 1790 | QCPLayer *layer(int index) const; 1791 | QCPLayer *currentLayer() const; 1792 | bool setCurrentLayer(const QString &name); 1793 | bool setCurrentLayer(QCPLayer *layer); 1794 | int layerCount() const; 1795 | bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); 1796 | bool removeLayer(QCPLayer *layer); 1797 | bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); 1798 | 1799 | // axis rect/layout interface: 1800 | int axisRectCount() const; 1801 | QCPAxisRect* axisRect(int index=0) const; 1802 | QList axisRects() const; 1803 | QCPLayoutElement* layoutElementAt(const QPointF &pos) const; 1804 | Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); 1805 | 1806 | QList selectedAxes() const; 1807 | QList selectedLegends() const; 1808 | Q_SLOT void deselectAll(); 1809 | 1810 | bool savePdf(const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); 1811 | bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1); 1812 | bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1); 1813 | bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0); 1814 | bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1); 1815 | QPixmap toPixmap(int width=0, int height=0, double scale=1.0); 1816 | void toPainter(QCPPainter *painter, int width=0, int height=0); 1817 | Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpHint); 1818 | 1819 | QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; 1820 | QCPLegend *legend; 1821 | 1822 | signals: 1823 | void mouseDoubleClick(QMouseEvent *event); 1824 | void mousePress(QMouseEvent *event); 1825 | void mouseMove(QMouseEvent *event); 1826 | void mouseRelease(QMouseEvent *event); 1827 | void mouseWheel(QWheelEvent *event); 1828 | 1829 | void plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event); 1830 | void plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event); 1831 | void itemClick(QCPAbstractItem *item, QMouseEvent *event); 1832 | void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); 1833 | void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); 1834 | void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); 1835 | void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); 1836 | void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); 1837 | void titleClick(QMouseEvent *event, QCPPlotTitle *title); 1838 | void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title); 1839 | 1840 | void selectionChangedByUser(); 1841 | void beforeReplot(); 1842 | void afterReplot(); 1843 | 1844 | protected: 1845 | // property members: 1846 | QRect mViewport; 1847 | QCPLayoutGrid *mPlotLayout; 1848 | bool mAutoAddPlottableToLegend; 1849 | QList mPlottables; 1850 | QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph 1851 | QList mItems; 1852 | QList mLayers; 1853 | QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; 1854 | QCP::Interactions mInteractions; 1855 | int mSelectionTolerance; 1856 | bool mNoAntialiasingOnDrag; 1857 | QBrush mBackgroundBrush; 1858 | QPixmap mBackgroundPixmap; 1859 | QPixmap mScaledBackgroundPixmap; 1860 | bool mBackgroundScaled; 1861 | Qt::AspectRatioMode mBackgroundScaledMode; 1862 | QCPLayer *mCurrentLayer; 1863 | QCP::PlottingHints mPlottingHints; 1864 | Qt::KeyboardModifier mMultiSelectModifier; 1865 | 1866 | // non-property members: 1867 | QPixmap mPaintBuffer; 1868 | QPoint mMousePressPos; 1869 | QPointer mMouseEventElement; 1870 | bool mReplotting; 1871 | 1872 | // reimplemented virtual methods: 1873 | virtual QSize minimumSizeHint() const; 1874 | virtual QSize sizeHint() const; 1875 | virtual void paintEvent(QPaintEvent *event); 1876 | virtual void resizeEvent(QResizeEvent *event); 1877 | virtual void mouseDoubleClickEvent(QMouseEvent *event); 1878 | virtual void mousePressEvent(QMouseEvent *event); 1879 | virtual void mouseMoveEvent(QMouseEvent *event); 1880 | virtual void mouseReleaseEvent(QMouseEvent *event); 1881 | virtual void wheelEvent(QWheelEvent *event); 1882 | 1883 | // introduced virtual methods: 1884 | virtual void draw(QCPPainter *painter); 1885 | virtual void axisRemoved(QCPAxis *axis); 1886 | virtual void legendRemoved(QCPLegend *legend); 1887 | 1888 | // non-virtual methods: 1889 | void updateLayerIndices() const; 1890 | QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; 1891 | void drawBackground(QCPPainter *painter); 1892 | 1893 | friend class QCPLegend; 1894 | friend class QCPAxis; 1895 | friend class QCPLayer; 1896 | friend class QCPAxisRect; 1897 | }; 1898 | 1899 | 1900 | class QCP_LIB_DECL QCPColorGradient 1901 | { 1902 | Q_GADGET 1903 | public: 1904 | /*! 1905 | Defines the color spaces in which color interpolation between gradient stops can be performed. 1906 | 1907 | \see setColorInterpolation 1908 | */ 1909 | enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated 1910 | ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) 1911 | }; 1912 | Q_ENUMS(ColorInterpolation) 1913 | 1914 | /*! 1915 | Defines the available presets that can be loaded with \ref loadPreset. See the documentation 1916 | there for an image of the presets. 1917 | */ 1918 | enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) 1919 | ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) 1920 | ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) 1921 | ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) 1922 | ,gpCandy ///< Blue over pink to white 1923 | ,gpGeography ///< Colors suitable to represent different elevations on geographical maps 1924 | ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) 1925 | ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white 1926 | ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values 1927 | ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) 1928 | ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) 1929 | ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) 1930 | }; 1931 | Q_ENUMS(GradientPreset) 1932 | 1933 | QCPColorGradient(GradientPreset preset=gpCold); 1934 | bool operator==(const QCPColorGradient &other) const; 1935 | bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } 1936 | 1937 | // getters: 1938 | int levelCount() const { return mLevelCount; } 1939 | QMap colorStops() const { return mColorStops; } 1940 | ColorInterpolation colorInterpolation() const { return mColorInterpolation; } 1941 | bool periodic() const { return mPeriodic; } 1942 | 1943 | // setters: 1944 | void setLevelCount(int n); 1945 | void setColorStops(const QMap &colorStops); 1946 | void setColorStopAt(double position, const QColor &color); 1947 | void setColorInterpolation(ColorInterpolation interpolation); 1948 | void setPeriodic(bool enabled); 1949 | 1950 | // non-property methods: 1951 | void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); 1952 | QRgb color(double position, const QCPRange &range, bool logarithmic=false); 1953 | void loadPreset(GradientPreset preset); 1954 | void clearColorStops(); 1955 | QCPColorGradient inverted() const; 1956 | 1957 | protected: 1958 | void updateColorBuffer(); 1959 | 1960 | // property members: 1961 | int mLevelCount; 1962 | QMap mColorStops; 1963 | ColorInterpolation mColorInterpolation; 1964 | bool mPeriodic; 1965 | 1966 | // non-property members: 1967 | QVector mColorBuffer; 1968 | bool mColorBufferInvalidated; 1969 | }; 1970 | 1971 | 1972 | class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement 1973 | { 1974 | Q_OBJECT 1975 | /// \cond INCLUDE_QPROPERTIES 1976 | Q_PROPERTY(QPixmap background READ background WRITE setBackground) 1977 | Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) 1978 | Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) 1979 | Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) 1980 | Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) 1981 | /// \endcond 1982 | public: 1983 | explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); 1984 | virtual ~QCPAxisRect(); 1985 | 1986 | // getters: 1987 | QPixmap background() const { return mBackgroundPixmap; } 1988 | bool backgroundScaled() const { return mBackgroundScaled; } 1989 | Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } 1990 | Qt::Orientations rangeDrag() const { return mRangeDrag; } 1991 | Qt::Orientations rangeZoom() const { return mRangeZoom; } 1992 | QCPAxis *rangeDragAxis(Qt::Orientation orientation); 1993 | QCPAxis *rangeZoomAxis(Qt::Orientation orientation); 1994 | double rangeZoomFactor(Qt::Orientation orientation); 1995 | 1996 | // setters: 1997 | void setBackground(const QPixmap &pm); 1998 | void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); 1999 | void setBackground(const QBrush &brush); 2000 | void setBackgroundScaled(bool scaled); 2001 | void setBackgroundScaledMode(Qt::AspectRatioMode mode); 2002 | void setRangeDrag(Qt::Orientations orientations); 2003 | void setRangeZoom(Qt::Orientations orientations); 2004 | void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); 2005 | void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); 2006 | void setRangeZoomFactor(double horizontalFactor, double verticalFactor); 2007 | void setRangeZoomFactor(double factor); 2008 | 2009 | // non-property methods: 2010 | int axisCount(QCPAxis::AxisType type) const; 2011 | QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; 2012 | QList axes(QCPAxis::AxisTypes types) const; 2013 | QList axes() const; 2014 | QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); 2015 | QList addAxes(QCPAxis::AxisTypes types); 2016 | bool removeAxis(QCPAxis *axis); 2017 | QCPLayoutInset *insetLayout() const { return mInsetLayout; } 2018 | 2019 | void setupFullAxesBox(bool connectRanges=false); 2020 | QList plottables() const; 2021 | QList graphs() const; 2022 | QList items() const; 2023 | 2024 | // read-only interface imitating a QRect: 2025 | int left() const { return mRect.left(); } 2026 | int right() const { return mRect.right(); } 2027 | int top() const { return mRect.top(); } 2028 | int bottom() const { return mRect.bottom(); } 2029 | int width() const { return mRect.width(); } 2030 | int height() const { return mRect.height(); } 2031 | QSize size() const { return mRect.size(); } 2032 | QPoint topLeft() const { return mRect.topLeft(); } 2033 | QPoint topRight() const { return mRect.topRight(); } 2034 | QPoint bottomLeft() const { return mRect.bottomLeft(); } 2035 | QPoint bottomRight() const { return mRect.bottomRight(); } 2036 | QPoint center() const { return mRect.center(); } 2037 | 2038 | // reimplemented virtual methods: 2039 | virtual void update(UpdatePhase phase); 2040 | virtual QList elements(bool recursive) const; 2041 | 2042 | protected: 2043 | // property members: 2044 | QBrush mBackgroundBrush; 2045 | QPixmap mBackgroundPixmap; 2046 | QPixmap mScaledBackgroundPixmap; 2047 | bool mBackgroundScaled; 2048 | Qt::AspectRatioMode mBackgroundScaledMode; 2049 | QCPLayoutInset *mInsetLayout; 2050 | Qt::Orientations mRangeDrag, mRangeZoom; 2051 | QPointer mRangeDragHorzAxis, mRangeDragVertAxis, mRangeZoomHorzAxis, mRangeZoomVertAxis; 2052 | double mRangeZoomFactorHorz, mRangeZoomFactorVert; 2053 | // non-property members: 2054 | QCPRange mDragStartHorzRange, mDragStartVertRange; 2055 | QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; 2056 | QPoint mDragStart; 2057 | bool mDragging; 2058 | QHash > mAxes; 2059 | 2060 | // reimplemented virtual methods: 2061 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; 2062 | virtual void draw(QCPPainter *painter); 2063 | virtual int calculateAutoMargin(QCP::MarginSide side); 2064 | // events: 2065 | virtual void mousePressEvent(QMouseEvent *event); 2066 | virtual void mouseMoveEvent(QMouseEvent *event); 2067 | virtual void mouseReleaseEvent(QMouseEvent *event); 2068 | virtual void wheelEvent(QWheelEvent *event); 2069 | 2070 | // non-property methods: 2071 | void drawBackground(QCPPainter *painter); 2072 | void updateAxesOffset(QCPAxis::AxisType type); 2073 | 2074 | private: 2075 | Q_DISABLE_COPY(QCPAxisRect) 2076 | 2077 | friend class QCustomPlot; 2078 | }; 2079 | 2080 | 2081 | class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement 2082 | { 2083 | Q_OBJECT 2084 | /// \cond INCLUDE_QPROPERTIES 2085 | Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) 2086 | Q_PROPERTY(QFont font READ font WRITE setFont) 2087 | Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) 2088 | Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) 2089 | Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) 2090 | Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) 2091 | Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) 2092 | /// \endcond 2093 | public: 2094 | explicit QCPAbstractLegendItem(QCPLegend *parent); 2095 | 2096 | // getters: 2097 | QCPLegend *parentLegend() const { return mParentLegend; } 2098 | QFont font() const { return mFont; } 2099 | QColor textColor() const { return mTextColor; } 2100 | QFont selectedFont() const { return mSelectedFont; } 2101 | QColor selectedTextColor() const { return mSelectedTextColor; } 2102 | bool selectable() const { return mSelectable; } 2103 | bool selected() const { return mSelected; } 2104 | 2105 | // setters: 2106 | void setFont(const QFont &font); 2107 | void setTextColor(const QColor &color); 2108 | void setSelectedFont(const QFont &font); 2109 | void setSelectedTextColor(const QColor &color); 2110 | Q_SLOT void setSelectable(bool selectable); 2111 | Q_SLOT void setSelected(bool selected); 2112 | 2113 | // reimplemented virtual methods: 2114 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 2115 | 2116 | signals: 2117 | void selectionChanged(bool selected); 2118 | void selectableChanged(bool selectable); 2119 | 2120 | protected: 2121 | // property members: 2122 | QCPLegend *mParentLegend; 2123 | QFont mFont; 2124 | QColor mTextColor; 2125 | QFont mSelectedFont; 2126 | QColor mSelectedTextColor; 2127 | bool mSelectable, mSelected; 2128 | 2129 | // reimplemented virtual methods: 2130 | virtual QCP::Interaction selectionCategory() const; 2131 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; 2132 | virtual QRect clipRect() const; 2133 | virtual void draw(QCPPainter *painter) = 0; 2134 | // events: 2135 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); 2136 | virtual void deselectEvent(bool *selectionStateChanged); 2137 | 2138 | private: 2139 | Q_DISABLE_COPY(QCPAbstractLegendItem) 2140 | 2141 | friend class QCPLegend; 2142 | }; 2143 | 2144 | 2145 | class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem 2146 | { 2147 | Q_OBJECT 2148 | public: 2149 | QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); 2150 | 2151 | // getters: 2152 | QCPAbstractPlottable *plottable() { return mPlottable; } 2153 | 2154 | protected: 2155 | // property members: 2156 | QCPAbstractPlottable *mPlottable; 2157 | 2158 | // reimplemented virtual methods: 2159 | virtual void draw(QCPPainter *painter); 2160 | virtual QSize minimumSizeHint() const; 2161 | 2162 | // non-virtual methods: 2163 | QPen getIconBorderPen() const; 2164 | QColor getTextColor() const; 2165 | QFont getFont() const; 2166 | }; 2167 | 2168 | 2169 | class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid 2170 | { 2171 | Q_OBJECT 2172 | /// \cond INCLUDE_QPROPERTIES 2173 | Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) 2174 | Q_PROPERTY(QBrush brush READ brush WRITE setBrush) 2175 | Q_PROPERTY(QFont font READ font WRITE setFont) 2176 | Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) 2177 | Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) 2178 | Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) 2179 | Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) 2180 | Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) 2181 | Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) 2182 | Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) 2183 | Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) 2184 | Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) 2185 | Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) 2186 | Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) 2187 | /// \endcond 2188 | public: 2189 | /*! 2190 | Defines the selectable parts of a legend 2191 | 2192 | \see setSelectedParts, setSelectableParts 2193 | */ 2194 | enum SelectablePart { spNone = 0x000 ///< 0x000 None 2195 | ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) 2196 | ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) 2197 | }; 2198 | Q_FLAGS(SelectablePart SelectableParts) 2199 | Q_DECLARE_FLAGS(SelectableParts, SelectablePart) 2200 | 2201 | explicit QCPLegend(); 2202 | virtual ~QCPLegend(); 2203 | 2204 | // getters: 2205 | QPen borderPen() const { return mBorderPen; } 2206 | QBrush brush() const { return mBrush; } 2207 | QFont font() const { return mFont; } 2208 | QColor textColor() const { return mTextColor; } 2209 | QSize iconSize() const { return mIconSize; } 2210 | int iconTextPadding() const { return mIconTextPadding; } 2211 | QPen iconBorderPen() const { return mIconBorderPen; } 2212 | SelectableParts selectableParts() const { return mSelectableParts; } 2213 | SelectableParts selectedParts() const; 2214 | QPen selectedBorderPen() const { return mSelectedBorderPen; } 2215 | QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } 2216 | QBrush selectedBrush() const { return mSelectedBrush; } 2217 | QFont selectedFont() const { return mSelectedFont; } 2218 | QColor selectedTextColor() const { return mSelectedTextColor; } 2219 | 2220 | // setters: 2221 | void setBorderPen(const QPen &pen); 2222 | void setBrush(const QBrush &brush); 2223 | void setFont(const QFont &font); 2224 | void setTextColor(const QColor &color); 2225 | void setIconSize(const QSize &size); 2226 | void setIconSize(int width, int height); 2227 | void setIconTextPadding(int padding); 2228 | void setIconBorderPen(const QPen &pen); 2229 | Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); 2230 | Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); 2231 | void setSelectedBorderPen(const QPen &pen); 2232 | void setSelectedIconBorderPen(const QPen &pen); 2233 | void setSelectedBrush(const QBrush &brush); 2234 | void setSelectedFont(const QFont &font); 2235 | void setSelectedTextColor(const QColor &color); 2236 | 2237 | // reimplemented virtual methods: 2238 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 2239 | 2240 | // non-virtual methods: 2241 | QCPAbstractLegendItem *item(int index) const; 2242 | QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; 2243 | int itemCount() const; 2244 | bool hasItem(QCPAbstractLegendItem *item) const; 2245 | bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; 2246 | bool addItem(QCPAbstractLegendItem *item); 2247 | bool removeItem(int index); 2248 | bool removeItem(QCPAbstractLegendItem *item); 2249 | void clearItems(); 2250 | QList selectedItems() const; 2251 | 2252 | signals: 2253 | void selectionChanged(QCPLegend::SelectableParts parts); 2254 | void selectableChanged(QCPLegend::SelectableParts parts); 2255 | 2256 | protected: 2257 | // property members: 2258 | QPen mBorderPen, mIconBorderPen; 2259 | QBrush mBrush; 2260 | QFont mFont; 2261 | QColor mTextColor; 2262 | QSize mIconSize; 2263 | int mIconTextPadding; 2264 | SelectableParts mSelectedParts, mSelectableParts; 2265 | QPen mSelectedBorderPen, mSelectedIconBorderPen; 2266 | QBrush mSelectedBrush; 2267 | QFont mSelectedFont; 2268 | QColor mSelectedTextColor; 2269 | 2270 | // reimplemented virtual methods: 2271 | virtual void parentPlotInitialized(QCustomPlot *parentPlot); 2272 | virtual QCP::Interaction selectionCategory() const; 2273 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; 2274 | virtual void draw(QCPPainter *painter); 2275 | // events: 2276 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); 2277 | virtual void deselectEvent(bool *selectionStateChanged); 2278 | 2279 | // non-virtual methods: 2280 | QPen getBorderPen() const; 2281 | QBrush getBrush() const; 2282 | 2283 | private: 2284 | Q_DISABLE_COPY(QCPLegend) 2285 | 2286 | friend class QCustomPlot; 2287 | friend class QCPAbstractLegendItem; 2288 | }; 2289 | Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) 2290 | Q_DECLARE_METATYPE(QCPLegend::SelectablePart) 2291 | 2292 | 2293 | class QCP_LIB_DECL QCPPlotTitle : public QCPLayoutElement 2294 | { 2295 | Q_OBJECT 2296 | /// \cond INCLUDE_QPROPERTIES 2297 | Q_PROPERTY(QString text READ text WRITE setText) 2298 | Q_PROPERTY(QFont font READ font WRITE setFont) 2299 | Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) 2300 | Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) 2301 | Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) 2302 | Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) 2303 | Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) 2304 | /// \endcond 2305 | public: 2306 | explicit QCPPlotTitle(QCustomPlot *parentPlot); 2307 | explicit QCPPlotTitle(QCustomPlot *parentPlot, const QString &text); 2308 | 2309 | // getters: 2310 | QString text() const { return mText; } 2311 | QFont font() const { return mFont; } 2312 | QColor textColor() const { return mTextColor; } 2313 | QFont selectedFont() const { return mSelectedFont; } 2314 | QColor selectedTextColor() const { return mSelectedTextColor; } 2315 | bool selectable() const { return mSelectable; } 2316 | bool selected() const { return mSelected; } 2317 | 2318 | // setters: 2319 | void setText(const QString &text); 2320 | void setFont(const QFont &font); 2321 | void setTextColor(const QColor &color); 2322 | void setSelectedFont(const QFont &font); 2323 | void setSelectedTextColor(const QColor &color); 2324 | Q_SLOT void setSelectable(bool selectable); 2325 | Q_SLOT void setSelected(bool selected); 2326 | 2327 | // reimplemented virtual methods: 2328 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 2329 | 2330 | signals: 2331 | void selectionChanged(bool selected); 2332 | void selectableChanged(bool selectable); 2333 | 2334 | protected: 2335 | // property members: 2336 | QString mText; 2337 | QFont mFont; 2338 | QColor mTextColor; 2339 | QFont mSelectedFont; 2340 | QColor mSelectedTextColor; 2341 | QRect mTextBoundingRect; 2342 | bool mSelectable, mSelected; 2343 | 2344 | // reimplemented virtual methods: 2345 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; 2346 | virtual void draw(QCPPainter *painter); 2347 | virtual QSize minimumSizeHint() const; 2348 | virtual QSize maximumSizeHint() const; 2349 | // events: 2350 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); 2351 | virtual void deselectEvent(bool *selectionStateChanged); 2352 | 2353 | // non-virtual methods: 2354 | QFont mainFont() const; 2355 | QColor mainTextColor() const; 2356 | 2357 | private: 2358 | Q_DISABLE_COPY(QCPPlotTitle) 2359 | }; 2360 | 2361 | 2362 | class QCPColorScaleAxisRectPrivate : public QCPAxisRect 2363 | { 2364 | Q_OBJECT 2365 | public: 2366 | explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); 2367 | protected: 2368 | QCPColorScale *mParentColorScale; 2369 | QImage mGradientImage; 2370 | bool mGradientImageInvalidated; 2371 | // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale 2372 | using QCPAxisRect::calculateAutoMargin; 2373 | using QCPAxisRect::mousePressEvent; 2374 | using QCPAxisRect::mouseMoveEvent; 2375 | using QCPAxisRect::mouseReleaseEvent; 2376 | using QCPAxisRect::wheelEvent; 2377 | using QCPAxisRect::update; 2378 | virtual void draw(QCPPainter *painter); 2379 | void updateGradientImage(); 2380 | Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); 2381 | Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); 2382 | friend class QCPColorScale; 2383 | }; 2384 | 2385 | 2386 | class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement 2387 | { 2388 | Q_OBJECT 2389 | /// \cond INCLUDE_QPROPERTIES 2390 | Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) 2391 | Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) 2392 | Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) 2393 | Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) 2394 | Q_PROPERTY(QString label READ label WRITE setLabel) 2395 | Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) 2396 | Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) 2397 | Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) 2398 | /// \endcond 2399 | public: 2400 | explicit QCPColorScale(QCustomPlot *parentPlot); 2401 | virtual ~QCPColorScale(); 2402 | 2403 | // getters: 2404 | QCPAxis *axis() const { return mColorAxis.data(); } 2405 | QCPAxis::AxisType type() const { return mType; } 2406 | QCPRange dataRange() const { return mDataRange; } 2407 | QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } 2408 | QCPColorGradient gradient() const { return mGradient; } 2409 | QString label() const; 2410 | int barWidth () const { return mBarWidth; } 2411 | bool rangeDrag() const; 2412 | bool rangeZoom() const; 2413 | 2414 | // setters: 2415 | void setType(QCPAxis::AxisType type); 2416 | Q_SLOT void setDataRange(const QCPRange &dataRange); 2417 | Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); 2418 | Q_SLOT void setGradient(const QCPColorGradient &gradient); 2419 | void setLabel(const QString &str); 2420 | void setBarWidth(int width); 2421 | void setRangeDrag(bool enabled); 2422 | void setRangeZoom(bool enabled); 2423 | 2424 | // non-property methods: 2425 | QList colorMaps() const; 2426 | void rescaleDataRange(bool onlyVisibleMaps); 2427 | 2428 | // reimplemented virtual methods: 2429 | virtual void update(UpdatePhase phase); 2430 | 2431 | signals: 2432 | void dataRangeChanged(QCPRange newRange); 2433 | void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); 2434 | void gradientChanged(QCPColorGradient newGradient); 2435 | 2436 | protected: 2437 | // property members: 2438 | QCPAxis::AxisType mType; 2439 | QCPRange mDataRange; 2440 | QCPAxis::ScaleType mDataScaleType; 2441 | QCPColorGradient mGradient; 2442 | int mBarWidth; 2443 | 2444 | // non-property members: 2445 | QPointer mAxisRect; 2446 | QPointer mColorAxis; 2447 | 2448 | // reimplemented virtual methods: 2449 | virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; 2450 | // events: 2451 | virtual void mousePressEvent(QMouseEvent *event); 2452 | virtual void mouseMoveEvent(QMouseEvent *event); 2453 | virtual void mouseReleaseEvent(QMouseEvent *event); 2454 | virtual void wheelEvent(QWheelEvent *event); 2455 | 2456 | private: 2457 | Q_DISABLE_COPY(QCPColorScale) 2458 | 2459 | friend class QCPColorScaleAxisRectPrivate; 2460 | }; 2461 | 2462 | 2463 | /*! \file */ 2464 | 2465 | 2466 | 2467 | class QCP_LIB_DECL QCPData 2468 | { 2469 | public: 2470 | QCPData(); 2471 | QCPData(double key, double value); 2472 | double key, value; 2473 | double keyErrorPlus, keyErrorMinus; 2474 | double valueErrorPlus, valueErrorMinus; 2475 | }; 2476 | Q_DECLARE_TYPEINFO(QCPData, Q_MOVABLE_TYPE); 2477 | 2478 | /*! \typedef QCPDataMap 2479 | Container for storing \ref QCPData items in a sorted fashion. The key of the map 2480 | is the key member of the QCPData instance. 2481 | 2482 | This is the container in which QCPGraph holds its data. 2483 | \see QCPData, QCPGraph::setData 2484 | */ 2485 | typedef QMap QCPDataMap; 2486 | typedef QMapIterator QCPDataMapIterator; 2487 | typedef QMutableMapIterator QCPDataMutableMapIterator; 2488 | 2489 | 2490 | class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable 2491 | { 2492 | Q_OBJECT 2493 | /// \cond INCLUDE_QPROPERTIES 2494 | Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) 2495 | Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) 2496 | Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) 2497 | Q_PROPERTY(QPen errorPen READ errorPen WRITE setErrorPen) 2498 | Q_PROPERTY(double errorBarSize READ errorBarSize WRITE setErrorBarSize) 2499 | Q_PROPERTY(bool errorBarSkipSymbol READ errorBarSkipSymbol WRITE setErrorBarSkipSymbol) 2500 | Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) 2501 | Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) 2502 | /// \endcond 2503 | public: 2504 | /*! 2505 | Defines how the graph's line is represented visually in the plot. The line is drawn with the 2506 | current pen of the graph (\ref setPen). 2507 | \see setLineStyle 2508 | */ 2509 | enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented 2510 | ///< with symbols according to the scatter style, see \ref setScatterStyle) 2511 | ,lsLine ///< data points are connected by a straight line 2512 | ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point 2513 | ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point 2514 | ,lsStepCenter ///< line is drawn as steps where the step is in between two data points 2515 | ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line 2516 | }; 2517 | Q_ENUMS(LineStyle) 2518 | /*! 2519 | Defines what kind of error bars are drawn for each data point 2520 | */ 2521 | enum ErrorType { etNone ///< No error bars are shown 2522 | ,etKey ///< Error bars for the key dimension of the data point are shown 2523 | ,etValue ///< Error bars for the value dimension of the data point are shown 2524 | ,etBoth ///< Error bars for both key and value dimensions of the data point are shown 2525 | }; 2526 | Q_ENUMS(ErrorType) 2527 | 2528 | explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); 2529 | virtual ~QCPGraph(); 2530 | 2531 | // getters: 2532 | QCPDataMap *data() const { return mData; } 2533 | LineStyle lineStyle() const { return mLineStyle; } 2534 | QCPScatterStyle scatterStyle() const { return mScatterStyle; } 2535 | ErrorType errorType() const { return mErrorType; } 2536 | QPen errorPen() const { return mErrorPen; } 2537 | double errorBarSize() const { return mErrorBarSize; } 2538 | bool errorBarSkipSymbol() const { return mErrorBarSkipSymbol; } 2539 | QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } 2540 | bool adaptiveSampling() const { return mAdaptiveSampling; } 2541 | 2542 | // setters: 2543 | void setData(QCPDataMap *data, bool copy=false); 2544 | void setData(const QVector &key, const QVector &value); 2545 | void setDataKeyError(const QVector &key, const QVector &value, const QVector &keyError); 2546 | void setDataKeyError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus); 2547 | void setDataValueError(const QVector &key, const QVector &value, const QVector &valueError); 2548 | void setDataValueError(const QVector &key, const QVector &value, const QVector &valueErrorMinus, const QVector &valueErrorPlus); 2549 | void setDataBothError(const QVector &key, const QVector &value, const QVector &keyError, const QVector &valueError); 2550 | void setDataBothError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus, const QVector &valueErrorMinus, const QVector &valueErrorPlus); 2551 | void setLineStyle(LineStyle ls); 2552 | void setScatterStyle(const QCPScatterStyle &style); 2553 | void setErrorType(ErrorType errorType); 2554 | void setErrorPen(const QPen &pen); 2555 | void setErrorBarSize(double size); 2556 | void setErrorBarSkipSymbol(bool enabled); 2557 | void setChannelFillGraph(QCPGraph *targetGraph); 2558 | void setAdaptiveSampling(bool enabled); 2559 | 2560 | // non-property methods: 2561 | void addData(const QCPDataMap &dataMap); 2562 | void addData(const QCPData &data); 2563 | void addData(double key, double value); 2564 | void addData(const QVector &keys, const QVector &values); 2565 | void removeDataBefore(double key); 2566 | void removeDataAfter(double key); 2567 | void removeData(double fromKey, double toKey); 2568 | void removeData(double key); 2569 | 2570 | // reimplemented virtual methods: 2571 | virtual void clearData(); 2572 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 2573 | using QCPAbstractPlottable::rescaleAxes; 2574 | using QCPAbstractPlottable::rescaleKeyAxis; 2575 | using QCPAbstractPlottable::rescaleValueAxis; 2576 | void rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface 2577 | void rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface 2578 | void rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface 2579 | 2580 | protected: 2581 | // property members: 2582 | QCPDataMap *mData; 2583 | QPen mErrorPen; 2584 | LineStyle mLineStyle; 2585 | QCPScatterStyle mScatterStyle; 2586 | ErrorType mErrorType; 2587 | double mErrorBarSize; 2588 | bool mErrorBarSkipSymbol; 2589 | QPointer mChannelFillGraph; 2590 | bool mAdaptiveSampling; 2591 | 2592 | // reimplemented virtual methods: 2593 | virtual void draw(QCPPainter *painter); 2594 | virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; 2595 | virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 2596 | virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 2597 | virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface 2598 | virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface 2599 | 2600 | // introduced virtual methods: 2601 | virtual void drawFill(QCPPainter *painter, QVector *lineData) const; 2602 | virtual void drawScatterPlot(QCPPainter *painter, QVector *scatterData) const; 2603 | virtual void drawLinePlot(QCPPainter *painter, QVector *lineData) const; 2604 | virtual void drawImpulsePlot(QCPPainter *painter, QVector *lineData) const; 2605 | 2606 | // non-virtual methods: 2607 | void getPreparedData(QVector *lineData, QVector *scatterData) const; 2608 | void getPlotData(QVector *lineData, QVector *scatterData) const; 2609 | void getScatterPlotData(QVector *scatterData) const; 2610 | void getLinePlotData(QVector *linePixelData, QVector *scatterData) const; 2611 | void getStepLeftPlotData(QVector *linePixelData, QVector *scatterData) const; 2612 | void getStepRightPlotData(QVector *linePixelData, QVector *scatterData) const; 2613 | void getStepCenterPlotData(QVector *linePixelData, QVector *scatterData) const; 2614 | void getImpulsePlotData(QVector *linePixelData, QVector *scatterData) const; 2615 | void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const; 2616 | void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const; 2617 | int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const; 2618 | void addFillBasePoints(QVector *lineData) const; 2619 | void removeFillBasePoints(QVector *lineData) const; 2620 | QPointF lowerFillBasePoint(double lowerKey) const; 2621 | QPointF upperFillBasePoint(double upperKey) const; 2622 | const QPolygonF getChannelFillPolygon(const QVector *lineData) const; 2623 | int findIndexBelowX(const QVector *data, double x) const; 2624 | int findIndexAboveX(const QVector *data, double x) const; 2625 | int findIndexBelowY(const QVector *data, double y) const; 2626 | int findIndexAboveY(const QVector *data, double y) const; 2627 | double pointDistance(const QPointF &pixelPoint) const; 2628 | 2629 | friend class QCustomPlot; 2630 | friend class QCPLegend; 2631 | }; 2632 | 2633 | 2634 | /*! \file */ 2635 | 2636 | 2637 | 2638 | class QCP_LIB_DECL QCPCurveData 2639 | { 2640 | public: 2641 | QCPCurveData(); 2642 | QCPCurveData(double t, double key, double value); 2643 | double t, key, value; 2644 | }; 2645 | Q_DECLARE_TYPEINFO(QCPCurveData, Q_MOVABLE_TYPE); 2646 | 2647 | /*! \typedef QCPCurveDataMap 2648 | Container for storing \ref QCPCurveData items in a sorted fashion. The key of the map 2649 | is the t member of the QCPCurveData instance. 2650 | 2651 | This is the container in which QCPCurve holds its data. 2652 | \see QCPCurveData, QCPCurve::setData 2653 | */ 2654 | 2655 | typedef QMap QCPCurveDataMap; 2656 | typedef QMapIterator QCPCurveDataMapIterator; 2657 | typedef QMutableMapIterator QCPCurveDataMutableMapIterator; 2658 | 2659 | 2660 | class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable 2661 | { 2662 | Q_OBJECT 2663 | /// \cond INCLUDE_QPROPERTIES 2664 | Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) 2665 | Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) 2666 | /// \endcond 2667 | public: 2668 | /*! 2669 | Defines how the curve's line is represented visually in the plot. The line is drawn with the 2670 | current pen of the curve (\ref setPen). 2671 | \see setLineStyle 2672 | */ 2673 | enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) 2674 | ,lsLine ///< Data points are connected with a straight line 2675 | }; 2676 | explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); 2677 | virtual ~QCPCurve(); 2678 | 2679 | // getters: 2680 | QCPCurveDataMap *data() const { return mData; } 2681 | QCPScatterStyle scatterStyle() const { return mScatterStyle; } 2682 | LineStyle lineStyle() const { return mLineStyle; } 2683 | 2684 | // setters: 2685 | void setData(QCPCurveDataMap *data, bool copy=false); 2686 | void setData(const QVector &t, const QVector &key, const QVector &value); 2687 | void setData(const QVector &key, const QVector &value); 2688 | void setScatterStyle(const QCPScatterStyle &style); 2689 | void setLineStyle(LineStyle style); 2690 | 2691 | // non-property methods: 2692 | void addData(const QCPCurveDataMap &dataMap); 2693 | void addData(const QCPCurveData &data); 2694 | void addData(double t, double key, double value); 2695 | void addData(double key, double value); 2696 | void addData(const QVector &ts, const QVector &keys, const QVector &values); 2697 | void removeDataBefore(double t); 2698 | void removeDataAfter(double t); 2699 | void removeData(double fromt, double tot); 2700 | void removeData(double t); 2701 | 2702 | // reimplemented virtual methods: 2703 | virtual void clearData(); 2704 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 2705 | 2706 | protected: 2707 | // property members: 2708 | QCPCurveDataMap *mData; 2709 | QCPScatterStyle mScatterStyle; 2710 | LineStyle mLineStyle; 2711 | 2712 | // reimplemented virtual methods: 2713 | virtual void draw(QCPPainter *painter); 2714 | virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; 2715 | virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 2716 | virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 2717 | 2718 | // introduced virtual methods: 2719 | virtual void drawScatterPlot(QCPPainter *painter, const QVector *pointData) const; 2720 | 2721 | // non-virtual methods: 2722 | void getCurveData(QVector *lineData) const; 2723 | int getRegion(double x, double y, double rectLeft, double rectTop, double rectRight, double rectBottom) const; 2724 | QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const; 2725 | QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const; 2726 | bool mayTraverse(int prevRegion, int currentRegion) const; 2727 | bool getTraverse(double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom, QPointF &crossA, QPointF &crossB) const; 2728 | void getTraverseCornerPoints(int prevRegion, int currentRegion, double rectLeft, double rectTop, double rectRight, double rectBottom, QVector &beforeTraverse, QVector &afterTraverse) const; 2729 | double pointDistance(const QPointF &pixelPoint) const; 2730 | 2731 | friend class QCustomPlot; 2732 | friend class QCPLegend; 2733 | }; 2734 | 2735 | 2736 | /*! \file */ 2737 | 2738 | 2739 | 2740 | class QCP_LIB_DECL QCPBarsGroup : public QObject 2741 | { 2742 | Q_OBJECT 2743 | /// \cond INCLUDE_QPROPERTIES 2744 | Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) 2745 | Q_PROPERTY(double spacing READ spacing WRITE setSpacing) 2746 | /// \endcond 2747 | public: 2748 | /*! 2749 | Defines the ways the spacing between bars in the group can be specified. Thus it defines what 2750 | the number passed to \ref setSpacing actually means. 2751 | 2752 | \see setSpacingType, setSpacing 2753 | */ 2754 | enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels 2755 | ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size 2756 | ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range 2757 | }; 2758 | QCPBarsGroup(QCustomPlot *parentPlot); 2759 | ~QCPBarsGroup(); 2760 | 2761 | // getters: 2762 | SpacingType spacingType() const { return mSpacingType; } 2763 | double spacing() const { return mSpacing; } 2764 | 2765 | // setters: 2766 | void setSpacingType(SpacingType spacingType); 2767 | void setSpacing(double spacing); 2768 | 2769 | // non-virtual methods: 2770 | QList bars() const { return mBars; } 2771 | QCPBars* bars(int index) const; 2772 | int size() const { return mBars.size(); } 2773 | bool isEmpty() const { return mBars.isEmpty(); } 2774 | void clear(); 2775 | bool contains(QCPBars *bars) const { return mBars.contains(bars); } 2776 | void append(QCPBars *bars); 2777 | void insert(int i, QCPBars *bars); 2778 | void remove(QCPBars *bars); 2779 | 2780 | protected: 2781 | // non-property members: 2782 | QCustomPlot *mParentPlot; 2783 | SpacingType mSpacingType; 2784 | double mSpacing; 2785 | QList mBars; 2786 | 2787 | // non-virtual methods: 2788 | void registerBars(QCPBars *bars); 2789 | void unregisterBars(QCPBars *bars); 2790 | 2791 | // virtual methods: 2792 | double keyPixelOffset(const QCPBars *bars, double keyCoord); 2793 | double getPixelSpacing(const QCPBars *bars, double keyCoord); 2794 | 2795 | private: 2796 | Q_DISABLE_COPY(QCPBarsGroup) 2797 | 2798 | friend class QCPBars; 2799 | }; 2800 | 2801 | 2802 | class QCP_LIB_DECL QCPBarData 2803 | { 2804 | public: 2805 | QCPBarData(); 2806 | QCPBarData(double key, double value); 2807 | double key, value; 2808 | }; 2809 | Q_DECLARE_TYPEINFO(QCPBarData, Q_MOVABLE_TYPE); 2810 | 2811 | /*! \typedef QCPBarDataMap 2812 | Container for storing \ref QCPBarData items in a sorted fashion. The key of the map 2813 | is the key member of the QCPBarData instance. 2814 | 2815 | This is the container in which QCPBars holds its data. 2816 | \see QCPBarData, QCPBars::setData 2817 | */ 2818 | typedef QMap QCPBarDataMap; 2819 | typedef QMapIterator QCPBarDataMapIterator; 2820 | typedef QMutableMapIterator QCPBarDataMutableMapIterator; 2821 | 2822 | 2823 | class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable 2824 | { 2825 | Q_OBJECT 2826 | /// \cond INCLUDE_QPROPERTIES 2827 | Q_PROPERTY(double width READ width WRITE setWidth) 2828 | Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) 2829 | Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) 2830 | Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) 2831 | Q_PROPERTY(QCPBars* barBelow READ barBelow) 2832 | Q_PROPERTY(QCPBars* barAbove READ barAbove) 2833 | /// \endcond 2834 | public: 2835 | /*! 2836 | Defines the ways the width of the bar can be specified. Thus it defines what the number passed 2837 | to \ref setWidth actually means. 2838 | 2839 | \see setWidthType, setWidth 2840 | */ 2841 | enum WidthType { wtAbsolute ///< Bar width is in absolute pixels 2842 | ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size 2843 | ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range 2844 | }; 2845 | Q_ENUMS(WidthType) 2846 | 2847 | explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); 2848 | virtual ~QCPBars(); 2849 | 2850 | // getters: 2851 | double width() const { return mWidth; } 2852 | WidthType widthType() const { return mWidthType; } 2853 | QCPBarsGroup *barsGroup() const { return mBarsGroup; } 2854 | double baseValue() const { return mBaseValue; } 2855 | QCPBars *barBelow() const { return mBarBelow.data(); } 2856 | QCPBars *barAbove() const { return mBarAbove.data(); } 2857 | QCPBarDataMap *data() const { return mData; } 2858 | 2859 | // setters: 2860 | void setWidth(double width); 2861 | void setWidthType(WidthType widthType); 2862 | void setBarsGroup(QCPBarsGroup *barsGroup); 2863 | void setBaseValue(double baseValue); 2864 | void setData(QCPBarDataMap *data, bool copy=false); 2865 | void setData(const QVector &key, const QVector &value); 2866 | 2867 | // non-property methods: 2868 | void moveBelow(QCPBars *bars); 2869 | void moveAbove(QCPBars *bars); 2870 | void addData(const QCPBarDataMap &dataMap); 2871 | void addData(const QCPBarData &data); 2872 | void addData(double key, double value); 2873 | void addData(const QVector &keys, const QVector &values); 2874 | void removeDataBefore(double key); 2875 | void removeDataAfter(double key); 2876 | void removeData(double fromKey, double toKey); 2877 | void removeData(double key); 2878 | 2879 | // reimplemented virtual methods: 2880 | virtual void clearData(); 2881 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 2882 | 2883 | protected: 2884 | // property members: 2885 | QCPBarDataMap *mData; 2886 | double mWidth; 2887 | WidthType mWidthType; 2888 | QCPBarsGroup *mBarsGroup; 2889 | double mBaseValue; 2890 | QPointer mBarBelow, mBarAbove; 2891 | 2892 | // reimplemented virtual methods: 2893 | virtual void draw(QCPPainter *painter); 2894 | virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; 2895 | virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 2896 | virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 2897 | 2898 | // non-virtual methods: 2899 | void getVisibleDataBounds(QCPBarDataMap::const_iterator &lower, QCPBarDataMap::const_iterator &upperEnd) const; 2900 | QPolygonF getBarPolygon(double key, double value) const; 2901 | void getPixelWidth(double key, double &lower, double &upper) const; 2902 | double getStackedBaseValue(double key, bool positive) const; 2903 | static void connectBars(QCPBars* lower, QCPBars* upper); 2904 | 2905 | friend class QCustomPlot; 2906 | friend class QCPLegend; 2907 | friend class QCPBarsGroup; 2908 | }; 2909 | 2910 | 2911 | /*! \file */ 2912 | 2913 | 2914 | 2915 | class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable 2916 | { 2917 | Q_OBJECT 2918 | /// \cond INCLUDE_QPROPERTIES 2919 | Q_PROPERTY(double key READ key WRITE setKey) 2920 | Q_PROPERTY(double minimum READ minimum WRITE setMinimum) 2921 | Q_PROPERTY(double lowerQuartile READ lowerQuartile WRITE setLowerQuartile) 2922 | Q_PROPERTY(double median READ median WRITE setMedian) 2923 | Q_PROPERTY(double upperQuartile READ upperQuartile WRITE setUpperQuartile) 2924 | Q_PROPERTY(double maximum READ maximum WRITE setMaximum) 2925 | Q_PROPERTY(QVector outliers READ outliers WRITE setOutliers) 2926 | Q_PROPERTY(double width READ width WRITE setWidth) 2927 | Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) 2928 | Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) 2929 | Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) 2930 | Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) 2931 | Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) 2932 | /// \endcond 2933 | public: 2934 | explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); 2935 | 2936 | // getters: 2937 | double key() const { return mKey; } 2938 | double minimum() const { return mMinimum; } 2939 | double lowerQuartile() const { return mLowerQuartile; } 2940 | double median() const { return mMedian; } 2941 | double upperQuartile() const { return mUpperQuartile; } 2942 | double maximum() const { return mMaximum; } 2943 | QVector outliers() const { return mOutliers; } 2944 | double width() const { return mWidth; } 2945 | double whiskerWidth() const { return mWhiskerWidth; } 2946 | QPen whiskerPen() const { return mWhiskerPen; } 2947 | QPen whiskerBarPen() const { return mWhiskerBarPen; } 2948 | QPen medianPen() const { return mMedianPen; } 2949 | QCPScatterStyle outlierStyle() const { return mOutlierStyle; } 2950 | 2951 | // setters: 2952 | void setKey(double key); 2953 | void setMinimum(double value); 2954 | void setLowerQuartile(double value); 2955 | void setMedian(double value); 2956 | void setUpperQuartile(double value); 2957 | void setMaximum(double value); 2958 | void setOutliers(const QVector &values); 2959 | void setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum); 2960 | void setWidth(double width); 2961 | void setWhiskerWidth(double width); 2962 | void setWhiskerPen(const QPen &pen); 2963 | void setWhiskerBarPen(const QPen &pen); 2964 | void setMedianPen(const QPen &pen); 2965 | void setOutlierStyle(const QCPScatterStyle &style); 2966 | 2967 | // non-property methods: 2968 | virtual void clearData(); 2969 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 2970 | 2971 | protected: 2972 | // property members: 2973 | QVector mOutliers; 2974 | double mKey, mMinimum, mLowerQuartile, mMedian, mUpperQuartile, mMaximum; 2975 | double mWidth; 2976 | double mWhiskerWidth; 2977 | QPen mWhiskerPen, mWhiskerBarPen, mMedianPen; 2978 | QCPScatterStyle mOutlierStyle; 2979 | 2980 | // reimplemented virtual methods: 2981 | virtual void draw(QCPPainter *painter); 2982 | virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; 2983 | virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 2984 | virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 2985 | 2986 | // introduced virtual methods: 2987 | virtual void drawQuartileBox(QCPPainter *painter, QRectF *quartileBox=0) const; 2988 | virtual void drawMedian(QCPPainter *painter) const; 2989 | virtual void drawWhiskers(QCPPainter *painter) const; 2990 | virtual void drawOutliers(QCPPainter *painter) const; 2991 | 2992 | friend class QCustomPlot; 2993 | friend class QCPLegend; 2994 | }; 2995 | 2996 | 2997 | class QCP_LIB_DECL QCPColorMapData 2998 | { 2999 | public: 3000 | QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); 3001 | ~QCPColorMapData(); 3002 | QCPColorMapData(const QCPColorMapData &other); 3003 | QCPColorMapData &operator=(const QCPColorMapData &other); 3004 | 3005 | // getters: 3006 | int keySize() const { return mKeySize; } 3007 | int valueSize() const { return mValueSize; } 3008 | QCPRange keyRange() const { return mKeyRange; } 3009 | QCPRange valueRange() const { return mValueRange; } 3010 | QCPRange dataBounds() const { return mDataBounds; } 3011 | double data(double key, double value); 3012 | double cell(int keyIndex, int valueIndex); 3013 | 3014 | // setters: 3015 | void setSize(int keySize, int valueSize); 3016 | void setKeySize(int keySize); 3017 | void setValueSize(int valueSize); 3018 | void setRange(const QCPRange &keyRange, const QCPRange &valueRange); 3019 | void setKeyRange(const QCPRange &keyRange); 3020 | void setValueRange(const QCPRange &valueRange); 3021 | void setData(double key, double value, double z); 3022 | void setCell(int keyIndex, int valueIndex, double z); 3023 | 3024 | // non-property methods: 3025 | void recalculateDataBounds(); 3026 | void clear(); 3027 | void fill(double z); 3028 | bool isEmpty() const { return mIsEmpty; } 3029 | void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; 3030 | void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; 3031 | 3032 | protected: 3033 | // property members: 3034 | int mKeySize, mValueSize; 3035 | QCPRange mKeyRange, mValueRange; 3036 | bool mIsEmpty; 3037 | // non-property members: 3038 | double *mData; 3039 | QCPRange mDataBounds; 3040 | bool mDataModified; 3041 | 3042 | friend class QCPColorMap; 3043 | }; 3044 | 3045 | 3046 | class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable 3047 | { 3048 | Q_OBJECT 3049 | /// \cond INCLUDE_QPROPERTIES 3050 | Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) 3051 | Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) 3052 | Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) 3053 | Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) 3054 | Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) 3055 | Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) 3056 | /// \endcond 3057 | public: 3058 | explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); 3059 | virtual ~QCPColorMap(); 3060 | 3061 | // getters: 3062 | QCPColorMapData *data() const { return mMapData; } 3063 | QCPRange dataRange() const { return mDataRange; } 3064 | QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } 3065 | bool interpolate() const { return mInterpolate; } 3066 | bool tightBoundary() const { return mTightBoundary; } 3067 | QCPColorGradient gradient() const { return mGradient; } 3068 | QCPColorScale *colorScale() const { return mColorScale.data(); } 3069 | 3070 | // setters: 3071 | void setData(QCPColorMapData *data, bool copy=false); 3072 | Q_SLOT void setDataRange(const QCPRange &dataRange); 3073 | Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); 3074 | Q_SLOT void setGradient(const QCPColorGradient &gradient); 3075 | void setInterpolate(bool enabled); 3076 | void setTightBoundary(bool enabled); 3077 | void setColorScale(QCPColorScale *colorScale); 3078 | 3079 | // non-property methods: 3080 | void rescaleDataRange(bool recalculateDataBounds=false); 3081 | Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); 3082 | 3083 | // reimplemented virtual methods: 3084 | virtual void clearData(); 3085 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3086 | 3087 | signals: 3088 | void dataRangeChanged(QCPRange newRange); 3089 | void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); 3090 | void gradientChanged(QCPColorGradient newGradient); 3091 | 3092 | protected: 3093 | // property members: 3094 | QCPRange mDataRange; 3095 | QCPAxis::ScaleType mDataScaleType; 3096 | QCPColorMapData *mMapData; 3097 | QCPColorGradient mGradient; 3098 | bool mInterpolate; 3099 | bool mTightBoundary; 3100 | QPointer mColorScale; 3101 | // non-property members: 3102 | QImage mMapImage, mUndersampledMapImage; 3103 | QPixmap mLegendIcon; 3104 | bool mMapImageInvalidated; 3105 | 3106 | // introduced virtual methods: 3107 | virtual void updateMapImage(); 3108 | 3109 | // reimplemented virtual methods: 3110 | virtual void draw(QCPPainter *painter); 3111 | virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; 3112 | virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 3113 | virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 3114 | 3115 | friend class QCustomPlot; 3116 | friend class QCPLegend; 3117 | }; 3118 | 3119 | 3120 | /*! \file */ 3121 | 3122 | 3123 | 3124 | class QCP_LIB_DECL QCPFinancialData 3125 | { 3126 | public: 3127 | QCPFinancialData(); 3128 | QCPFinancialData(double key, double open, double high, double low, double close); 3129 | double key, open, high, low, close; 3130 | }; 3131 | Q_DECLARE_TYPEINFO(QCPFinancialData, Q_MOVABLE_TYPE); 3132 | 3133 | /*! \typedef QCPFinancialDataMap 3134 | Container for storing \ref QCPFinancialData items in a sorted fashion. The key of the map 3135 | is the key member of the QCPFinancialData instance. 3136 | 3137 | This is the container in which QCPFinancial holds its data. 3138 | \see QCPFinancial, QCPFinancial::setData 3139 | */ 3140 | typedef QMap QCPFinancialDataMap; 3141 | typedef QMapIterator QCPFinancialDataMapIterator; 3142 | typedef QMutableMapIterator QCPFinancialDataMutableMapIterator; 3143 | 3144 | 3145 | class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable 3146 | { 3147 | Q_OBJECT 3148 | /// \cond INCLUDE_QPROPERTIES 3149 | Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) 3150 | Q_PROPERTY(double width READ width WRITE setWidth) 3151 | Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) 3152 | Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) 3153 | Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) 3154 | Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) 3155 | Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) 3156 | /// \endcond 3157 | public: 3158 | /*! 3159 | Defines the possible representations of OHLC data in the plot. 3160 | 3161 | \see setChartStyle 3162 | */ 3163 | enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation 3164 | ,csCandlestick ///< Candlestick representation 3165 | }; 3166 | Q_ENUMS(ChartStyle) 3167 | 3168 | explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); 3169 | virtual ~QCPFinancial(); 3170 | 3171 | // getters: 3172 | QCPFinancialDataMap *data() const { return mData; } 3173 | ChartStyle chartStyle() const { return mChartStyle; } 3174 | double width() const { return mWidth; } 3175 | bool twoColored() const { return mTwoColored; } 3176 | QBrush brushPositive() const { return mBrushPositive; } 3177 | QBrush brushNegative() const { return mBrushNegative; } 3178 | QPen penPositive() const { return mPenPositive; } 3179 | QPen penNegative() const { return mPenNegative; } 3180 | 3181 | 3182 | // setters: 3183 | void setData(QCPFinancialDataMap *data, bool copy=false); 3184 | void setData(const QVector &key, const QVector &open, const QVector &high, const QVector &low, const QVector &close); 3185 | void setChartStyle(ChartStyle style); 3186 | void setWidth(double width); 3187 | void setTwoColored(bool twoColored); 3188 | void setBrushPositive(const QBrush &brush); 3189 | void setBrushNegative(const QBrush &brush); 3190 | void setPenPositive(const QPen &pen); 3191 | void setPenNegative(const QPen &pen); 3192 | 3193 | // non-property methods: 3194 | void addData(const QCPFinancialDataMap &dataMap); 3195 | void addData(const QCPFinancialData &data); 3196 | void addData(double key, double open, double high, double low, double close); 3197 | void addData(const QVector &key, const QVector &open, const QVector &high, const QVector &low, const QVector &close); 3198 | void removeDataBefore(double key); 3199 | void removeDataAfter(double key); 3200 | void removeData(double fromKey, double toKey); 3201 | void removeData(double key); 3202 | 3203 | // reimplemented virtual methods: 3204 | virtual void clearData(); 3205 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3206 | 3207 | // static methods: 3208 | static QCPFinancialDataMap timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); 3209 | 3210 | protected: 3211 | // property members: 3212 | QCPFinancialDataMap *mData; 3213 | ChartStyle mChartStyle; 3214 | double mWidth; 3215 | bool mTwoColored; 3216 | QBrush mBrushPositive, mBrushNegative; 3217 | QPen mPenPositive, mPenNegative; 3218 | 3219 | // reimplemented virtual methods: 3220 | virtual void draw(QCPPainter *painter); 3221 | virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; 3222 | virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 3223 | virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; 3224 | 3225 | // non-virtual methods: 3226 | void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end); 3227 | void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end); 3228 | double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const; 3229 | double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const; 3230 | void getVisibleDataBounds(QCPFinancialDataMap::const_iterator &lower, QCPFinancialDataMap::const_iterator &upper) const; 3231 | 3232 | friend class QCustomPlot; 3233 | friend class QCPLegend; 3234 | }; 3235 | 3236 | 3237 | class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem 3238 | { 3239 | Q_OBJECT 3240 | /// \cond INCLUDE_QPROPERTIES 3241 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3242 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3243 | /// \endcond 3244 | public: 3245 | QCPItemStraightLine(QCustomPlot *parentPlot); 3246 | virtual ~QCPItemStraightLine(); 3247 | 3248 | // getters: 3249 | QPen pen() const { return mPen; } 3250 | QPen selectedPen() const { return mSelectedPen; } 3251 | 3252 | // setters; 3253 | void setPen(const QPen &pen); 3254 | void setSelectedPen(const QPen &pen); 3255 | 3256 | // reimplemented virtual methods: 3257 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3258 | 3259 | QCPItemPosition * const point1; 3260 | QCPItemPosition * const point2; 3261 | 3262 | protected: 3263 | // property members: 3264 | QPen mPen, mSelectedPen; 3265 | 3266 | // reimplemented virtual methods: 3267 | virtual void draw(QCPPainter *painter); 3268 | 3269 | // non-virtual methods: 3270 | double distToStraightLine(const QVector2D &point1, const QVector2D &vec, const QVector2D &point) const; 3271 | QLineF getRectClippedStraightLine(const QVector2D &point1, const QVector2D &vec, const QRect &rect) const; 3272 | QPen mainPen() const; 3273 | }; 3274 | 3275 | 3276 | class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem 3277 | { 3278 | Q_OBJECT 3279 | /// \cond INCLUDE_QPROPERTIES 3280 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3281 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3282 | Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) 3283 | Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) 3284 | /// \endcond 3285 | public: 3286 | QCPItemLine(QCustomPlot *parentPlot); 3287 | virtual ~QCPItemLine(); 3288 | 3289 | // getters: 3290 | QPen pen() const { return mPen; } 3291 | QPen selectedPen() const { return mSelectedPen; } 3292 | QCPLineEnding head() const { return mHead; } 3293 | QCPLineEnding tail() const { return mTail; } 3294 | 3295 | // setters; 3296 | void setPen(const QPen &pen); 3297 | void setSelectedPen(const QPen &pen); 3298 | void setHead(const QCPLineEnding &head); 3299 | void setTail(const QCPLineEnding &tail); 3300 | 3301 | // reimplemented virtual methods: 3302 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3303 | 3304 | QCPItemPosition * const start; 3305 | QCPItemPosition * const end; 3306 | 3307 | protected: 3308 | // property members: 3309 | QPen mPen, mSelectedPen; 3310 | QCPLineEnding mHead, mTail; 3311 | 3312 | // reimplemented virtual methods: 3313 | virtual void draw(QCPPainter *painter); 3314 | 3315 | // non-virtual methods: 3316 | QLineF getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const; 3317 | QPen mainPen() const; 3318 | }; 3319 | 3320 | 3321 | class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem 3322 | { 3323 | Q_OBJECT 3324 | /// \cond INCLUDE_QPROPERTIES 3325 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3326 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3327 | Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) 3328 | Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) 3329 | /// \endcond 3330 | public: 3331 | QCPItemCurve(QCustomPlot *parentPlot); 3332 | virtual ~QCPItemCurve(); 3333 | 3334 | // getters: 3335 | QPen pen() const { return mPen; } 3336 | QPen selectedPen() const { return mSelectedPen; } 3337 | QCPLineEnding head() const { return mHead; } 3338 | QCPLineEnding tail() const { return mTail; } 3339 | 3340 | // setters; 3341 | void setPen(const QPen &pen); 3342 | void setSelectedPen(const QPen &pen); 3343 | void setHead(const QCPLineEnding &head); 3344 | void setTail(const QCPLineEnding &tail); 3345 | 3346 | // reimplemented virtual methods: 3347 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3348 | 3349 | QCPItemPosition * const start; 3350 | QCPItemPosition * const startDir; 3351 | QCPItemPosition * const endDir; 3352 | QCPItemPosition * const end; 3353 | 3354 | protected: 3355 | // property members: 3356 | QPen mPen, mSelectedPen; 3357 | QCPLineEnding mHead, mTail; 3358 | 3359 | // reimplemented virtual methods: 3360 | virtual void draw(QCPPainter *painter); 3361 | 3362 | // non-virtual methods: 3363 | QPen mainPen() const; 3364 | }; 3365 | 3366 | 3367 | class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem 3368 | { 3369 | Q_OBJECT 3370 | /// \cond INCLUDE_QPROPERTIES 3371 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3372 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3373 | Q_PROPERTY(QBrush brush READ brush WRITE setBrush) 3374 | Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) 3375 | /// \endcond 3376 | public: 3377 | QCPItemRect(QCustomPlot *parentPlot); 3378 | virtual ~QCPItemRect(); 3379 | 3380 | // getters: 3381 | QPen pen() const { return mPen; } 3382 | QPen selectedPen() const { return mSelectedPen; } 3383 | QBrush brush() const { return mBrush; } 3384 | QBrush selectedBrush() const { return mSelectedBrush; } 3385 | 3386 | // setters; 3387 | void setPen(const QPen &pen); 3388 | void setSelectedPen(const QPen &pen); 3389 | void setBrush(const QBrush &brush); 3390 | void setSelectedBrush(const QBrush &brush); 3391 | 3392 | // reimplemented virtual methods: 3393 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3394 | 3395 | QCPItemPosition * const topLeft; 3396 | QCPItemPosition * const bottomRight; 3397 | QCPItemAnchor * const top; 3398 | QCPItemAnchor * const topRight; 3399 | QCPItemAnchor * const right; 3400 | QCPItemAnchor * const bottom; 3401 | QCPItemAnchor * const bottomLeft; 3402 | QCPItemAnchor * const left; 3403 | 3404 | protected: 3405 | enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; 3406 | 3407 | // property members: 3408 | QPen mPen, mSelectedPen; 3409 | QBrush mBrush, mSelectedBrush; 3410 | 3411 | // reimplemented virtual methods: 3412 | virtual void draw(QCPPainter *painter); 3413 | virtual QPointF anchorPixelPoint(int anchorId) const; 3414 | 3415 | // non-virtual methods: 3416 | QPen mainPen() const; 3417 | QBrush mainBrush() const; 3418 | }; 3419 | 3420 | 3421 | class QCP_LIB_DECL QCPItemText : public QCPAbstractItem 3422 | { 3423 | Q_OBJECT 3424 | /// \cond INCLUDE_QPROPERTIES 3425 | Q_PROPERTY(QColor color READ color WRITE setColor) 3426 | Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) 3427 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3428 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3429 | Q_PROPERTY(QBrush brush READ brush WRITE setBrush) 3430 | Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) 3431 | Q_PROPERTY(QFont font READ font WRITE setFont) 3432 | Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) 3433 | Q_PROPERTY(QString text READ text WRITE setText) 3434 | Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) 3435 | Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) 3436 | Q_PROPERTY(double rotation READ rotation WRITE setRotation) 3437 | Q_PROPERTY(QMargins padding READ padding WRITE setPadding) 3438 | /// \endcond 3439 | public: 3440 | QCPItemText(QCustomPlot *parentPlot); 3441 | virtual ~QCPItemText(); 3442 | 3443 | // getters: 3444 | QColor color() const { return mColor; } 3445 | QColor selectedColor() const { return mSelectedColor; } 3446 | QPen pen() const { return mPen; } 3447 | QPen selectedPen() const { return mSelectedPen; } 3448 | QBrush brush() const { return mBrush; } 3449 | QBrush selectedBrush() const { return mSelectedBrush; } 3450 | QFont font() const { return mFont; } 3451 | QFont selectedFont() const { return mSelectedFont; } 3452 | QString text() const { return mText; } 3453 | Qt::Alignment positionAlignment() const { return mPositionAlignment; } 3454 | Qt::Alignment textAlignment() const { return mTextAlignment; } 3455 | double rotation() const { return mRotation; } 3456 | QMargins padding() const { return mPadding; } 3457 | 3458 | // setters; 3459 | void setColor(const QColor &color); 3460 | void setSelectedColor(const QColor &color); 3461 | void setPen(const QPen &pen); 3462 | void setSelectedPen(const QPen &pen); 3463 | void setBrush(const QBrush &brush); 3464 | void setSelectedBrush(const QBrush &brush); 3465 | void setFont(const QFont &font); 3466 | void setSelectedFont(const QFont &font); 3467 | void setText(const QString &text); 3468 | void setPositionAlignment(Qt::Alignment alignment); 3469 | void setTextAlignment(Qt::Alignment alignment); 3470 | void setRotation(double degrees); 3471 | void setPadding(const QMargins &padding); 3472 | 3473 | // reimplemented virtual methods: 3474 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3475 | 3476 | QCPItemPosition * const position; 3477 | QCPItemAnchor * const topLeft; 3478 | QCPItemAnchor * const top; 3479 | QCPItemAnchor * const topRight; 3480 | QCPItemAnchor * const right; 3481 | QCPItemAnchor * const bottomRight; 3482 | QCPItemAnchor * const bottom; 3483 | QCPItemAnchor * const bottomLeft; 3484 | QCPItemAnchor * const left; 3485 | 3486 | protected: 3487 | enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; 3488 | 3489 | // property members: 3490 | QColor mColor, mSelectedColor; 3491 | QPen mPen, mSelectedPen; 3492 | QBrush mBrush, mSelectedBrush; 3493 | QFont mFont, mSelectedFont; 3494 | QString mText; 3495 | Qt::Alignment mPositionAlignment; 3496 | Qt::Alignment mTextAlignment; 3497 | double mRotation; 3498 | QMargins mPadding; 3499 | 3500 | // reimplemented virtual methods: 3501 | virtual void draw(QCPPainter *painter); 3502 | virtual QPointF anchorPixelPoint(int anchorId) const; 3503 | 3504 | // non-virtual methods: 3505 | QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; 3506 | QFont mainFont() const; 3507 | QColor mainColor() const; 3508 | QPen mainPen() const; 3509 | QBrush mainBrush() const; 3510 | }; 3511 | 3512 | 3513 | class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem 3514 | { 3515 | Q_OBJECT 3516 | /// \cond INCLUDE_QPROPERTIES 3517 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3518 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3519 | Q_PROPERTY(QBrush brush READ brush WRITE setBrush) 3520 | Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) 3521 | /// \endcond 3522 | public: 3523 | QCPItemEllipse(QCustomPlot *parentPlot); 3524 | virtual ~QCPItemEllipse(); 3525 | 3526 | // getters: 3527 | QPen pen() const { return mPen; } 3528 | QPen selectedPen() const { return mSelectedPen; } 3529 | QBrush brush() const { return mBrush; } 3530 | QBrush selectedBrush() const { return mSelectedBrush; } 3531 | 3532 | // setters; 3533 | void setPen(const QPen &pen); 3534 | void setSelectedPen(const QPen &pen); 3535 | void setBrush(const QBrush &brush); 3536 | void setSelectedBrush(const QBrush &brush); 3537 | 3538 | // reimplemented virtual methods: 3539 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3540 | 3541 | QCPItemPosition * const topLeft; 3542 | QCPItemPosition * const bottomRight; 3543 | QCPItemAnchor * const topLeftRim; 3544 | QCPItemAnchor * const top; 3545 | QCPItemAnchor * const topRightRim; 3546 | QCPItemAnchor * const right; 3547 | QCPItemAnchor * const bottomRightRim; 3548 | QCPItemAnchor * const bottom; 3549 | QCPItemAnchor * const bottomLeftRim; 3550 | QCPItemAnchor * const left; 3551 | QCPItemAnchor * const center; 3552 | 3553 | protected: 3554 | enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; 3555 | 3556 | // property members: 3557 | QPen mPen, mSelectedPen; 3558 | QBrush mBrush, mSelectedBrush; 3559 | 3560 | // reimplemented virtual methods: 3561 | virtual void draw(QCPPainter *painter); 3562 | virtual QPointF anchorPixelPoint(int anchorId) const; 3563 | 3564 | // non-virtual methods: 3565 | QPen mainPen() const; 3566 | QBrush mainBrush() const; 3567 | }; 3568 | 3569 | 3570 | class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem 3571 | { 3572 | Q_OBJECT 3573 | /// \cond INCLUDE_QPROPERTIES 3574 | Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) 3575 | Q_PROPERTY(bool scaled READ scaled WRITE setScaled) 3576 | Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) 3577 | Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) 3578 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3579 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3580 | /// \endcond 3581 | public: 3582 | QCPItemPixmap(QCustomPlot *parentPlot); 3583 | virtual ~QCPItemPixmap(); 3584 | 3585 | // getters: 3586 | QPixmap pixmap() const { return mPixmap; } 3587 | bool scaled() const { return mScaled; } 3588 | Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } 3589 | Qt::TransformationMode transformationMode() const { return mTransformationMode; } 3590 | QPen pen() const { return mPen; } 3591 | QPen selectedPen() const { return mSelectedPen; } 3592 | 3593 | // setters; 3594 | void setPixmap(const QPixmap &pixmap); 3595 | void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); 3596 | void setPen(const QPen &pen); 3597 | void setSelectedPen(const QPen &pen); 3598 | 3599 | // reimplemented virtual methods: 3600 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3601 | 3602 | QCPItemPosition * const topLeft; 3603 | QCPItemPosition * const bottomRight; 3604 | QCPItemAnchor * const top; 3605 | QCPItemAnchor * const topRight; 3606 | QCPItemAnchor * const right; 3607 | QCPItemAnchor * const bottom; 3608 | QCPItemAnchor * const bottomLeft; 3609 | QCPItemAnchor * const left; 3610 | 3611 | protected: 3612 | enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; 3613 | 3614 | // property members: 3615 | QPixmap mPixmap; 3616 | QPixmap mScaledPixmap; 3617 | bool mScaled; 3618 | bool mScaledPixmapInvalidated; 3619 | Qt::AspectRatioMode mAspectRatioMode; 3620 | Qt::TransformationMode mTransformationMode; 3621 | QPen mPen, mSelectedPen; 3622 | 3623 | // reimplemented virtual methods: 3624 | virtual void draw(QCPPainter *painter); 3625 | virtual QPointF anchorPixelPoint(int anchorId) const; 3626 | 3627 | // non-virtual methods: 3628 | void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); 3629 | QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; 3630 | QPen mainPen() const; 3631 | }; 3632 | 3633 | 3634 | class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem 3635 | { 3636 | Q_OBJECT 3637 | /// \cond INCLUDE_QPROPERTIES 3638 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3639 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3640 | Q_PROPERTY(QBrush brush READ brush WRITE setBrush) 3641 | Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) 3642 | Q_PROPERTY(double size READ size WRITE setSize) 3643 | Q_PROPERTY(TracerStyle style READ style WRITE setStyle) 3644 | Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) 3645 | Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) 3646 | Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) 3647 | /// \endcond 3648 | public: 3649 | /*! 3650 | The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. 3651 | 3652 | \see setStyle 3653 | */ 3654 | enum TracerStyle { tsNone ///< The tracer is not visible 3655 | ,tsPlus ///< A plus shaped crosshair with limited size 3656 | ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect 3657 | ,tsCircle ///< A circle 3658 | ,tsSquare ///< A square 3659 | }; 3660 | Q_ENUMS(TracerStyle) 3661 | 3662 | QCPItemTracer(QCustomPlot *parentPlot); 3663 | virtual ~QCPItemTracer(); 3664 | 3665 | // getters: 3666 | QPen pen() const { return mPen; } 3667 | QPen selectedPen() const { return mSelectedPen; } 3668 | QBrush brush() const { return mBrush; } 3669 | QBrush selectedBrush() const { return mSelectedBrush; } 3670 | double size() const { return mSize; } 3671 | TracerStyle style() const { return mStyle; } 3672 | QCPGraph *graph() const { return mGraph; } 3673 | double graphKey() const { return mGraphKey; } 3674 | bool interpolating() const { return mInterpolating; } 3675 | 3676 | // setters; 3677 | void setPen(const QPen &pen); 3678 | void setSelectedPen(const QPen &pen); 3679 | void setBrush(const QBrush &brush); 3680 | void setSelectedBrush(const QBrush &brush); 3681 | void setSize(double size); 3682 | void setStyle(TracerStyle style); 3683 | void setGraph(QCPGraph *graph); 3684 | void setGraphKey(double key); 3685 | void setInterpolating(bool enabled); 3686 | 3687 | // reimplemented virtual methods: 3688 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3689 | 3690 | // non-virtual methods: 3691 | void updatePosition(); 3692 | 3693 | QCPItemPosition * const position; 3694 | 3695 | protected: 3696 | // property members: 3697 | QPen mPen, mSelectedPen; 3698 | QBrush mBrush, mSelectedBrush; 3699 | double mSize; 3700 | TracerStyle mStyle; 3701 | QCPGraph *mGraph; 3702 | double mGraphKey; 3703 | bool mInterpolating; 3704 | 3705 | // reimplemented virtual methods: 3706 | virtual void draw(QCPPainter *painter); 3707 | 3708 | // non-virtual methods: 3709 | QPen mainPen() const; 3710 | QBrush mainBrush() const; 3711 | }; 3712 | 3713 | 3714 | class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem 3715 | { 3716 | Q_OBJECT 3717 | /// \cond INCLUDE_QPROPERTIES 3718 | Q_PROPERTY(QPen pen READ pen WRITE setPen) 3719 | Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) 3720 | Q_PROPERTY(double length READ length WRITE setLength) 3721 | Q_PROPERTY(BracketStyle style READ style WRITE setStyle) 3722 | /// \endcond 3723 | public: 3724 | enum BracketStyle { bsSquare ///< A brace with angled edges 3725 | ,bsRound ///< A brace with round edges 3726 | ,bsCurly ///< A curly brace 3727 | ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression 3728 | }; 3729 | 3730 | QCPItemBracket(QCustomPlot *parentPlot); 3731 | virtual ~QCPItemBracket(); 3732 | 3733 | // getters: 3734 | QPen pen() const { return mPen; } 3735 | QPen selectedPen() const { return mSelectedPen; } 3736 | double length() const { return mLength; } 3737 | BracketStyle style() const { return mStyle; } 3738 | 3739 | // setters; 3740 | void setPen(const QPen &pen); 3741 | void setSelectedPen(const QPen &pen); 3742 | void setLength(double length); 3743 | void setStyle(BracketStyle style); 3744 | 3745 | // reimplemented virtual methods: 3746 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 3747 | 3748 | QCPItemPosition * const left; 3749 | QCPItemPosition * const right; 3750 | QCPItemAnchor * const center; 3751 | 3752 | protected: 3753 | // property members: 3754 | enum AnchorIndex {aiCenter}; 3755 | QPen mPen, mSelectedPen; 3756 | double mLength; 3757 | BracketStyle mStyle; 3758 | 3759 | // reimplemented virtual methods: 3760 | virtual void draw(QCPPainter *painter); 3761 | virtual QPointF anchorPixelPoint(int anchorId) const; 3762 | 3763 | // non-virtual methods: 3764 | QPen mainPen() const; 3765 | }; 3766 | 3767 | #endif // QCUSTOMPLOT_H 3768 | 3769 | -------------------------------------------------------------------------------- /QCustomPlot/widget.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include "ui_widget.h" 3 | #include 4 | #include 5 | 6 | Widget::Widget(QWidget *parent,double pi) : 7 | QWidget(parent), 8 | ui(new Ui::Widget) 9 | { 10 | ui->setupUi(this); 11 | PI = pi; 12 | setDemo(); 13 | 14 | } 15 | 16 | Widget::~Widget() 17 | { 18 | delete ui; 19 | } 20 | 21 | //吸引力计算 22 | double Widget::Compute_Attract(double current[2], double goal[2], double attract_gain, double Fa[2], double *aptr) 23 | { 24 | double r;//距离暂存 25 | double deltax,deltay;//差值暂存 26 | double angle_a;//角度暂存 27 | 28 | Fa[0] = 0; 29 | Fa[1] = 0; 30 | 31 | //计算距离 32 | deltax = goal[0] - current[0]; 33 | deltay = goal[1] - current[1]; 34 | r = sqrt(deltax*deltax + deltay*deltay); 35 | 36 | //计算角度 37 | //angle_a = sign(deltay) * acos(deltax/r); 38 | 39 | angle_a = atan2(deltay,deltax); 40 | 41 | *aptr = angle_a; 42 | 43 | //计算分量 44 | Fa[0] = attract_gain * r * cos(angle_a); 45 | Fa[1] = attract_gain * r * sin(angle_a); 46 | 47 | return r; 48 | } 49 | //斥力计算 50 | void Widget::Compute_Repulsion(double r_g, double current[2], const QVector &obs_x, const QVector &obs_y, int Obs_Number, double repulse_gain, double Po, double Fr[2], double *rptr) 51 | { 52 | double deltax,deltay;//差值暂存 53 | double r;//距离暂存 54 | double temp_x,temp_y;//当前坐标暂存 55 | double Fsum; 56 | double frtx,frty; 57 | double obs_distance[Obs_Number]; 58 | double obs_angle[Obs_Number]; 59 | 60 | temp_x = current[0]; 61 | temp_y = current[1]; 62 | 63 | Fr[0] = 0; 64 | Fr[1] = 0; 65 | 66 | //计算角度和距离 67 | for (int i = 0; i < Obs_Number; ++i) 68 | { 69 | /* code */ 70 | deltax = obs_x[i] - temp_x; 71 | deltay = obs_y[i] - temp_y; 72 | 73 | r = sqrt(deltax*deltax + deltay*deltay); 74 | 75 | obs_distance[i] = r; 76 | 77 | //obs_angle[i] = sign(deltay)*acos(deltax/r); 78 | 79 | obs_angle[i] = atan2 (deltay, deltax); 80 | } 81 | 82 | r_g = 1;//可以通过此处控制是否加入改进 83 | 84 | //计算斥力 85 | for (int i = 0; i < Obs_Number; ++i) 86 | { 87 | /* code */ 88 | if (obs_distance[i] > Po) 89 | { 90 | /* code */ 91 | frtx = 0; 92 | frty = 0; 93 | } 94 | else 95 | { 96 | //此处进行了改进,增加了当前位置到目标点距离这个影响因素。 97 | Fsum = - repulse_gain * r_g *(1/obs_distance[i] - 1/Po) * (1 / (obs_distance[i]*obs_distance[i]));//这个负号是因为斥力是由障碍物指向物体的,而计算出的角度是由物体指向障碍物的。 98 | frtx = Fsum * cos(obs_angle[i]); 99 | frty = Fsum * sin(obs_angle[i]); 100 | } 101 | Fr[0] += frtx; 102 | Fr[1] += frty; 103 | } 104 | 105 | *rptr = atan2(-Fr[1],-Fr[0]); 106 | } 107 | 108 | //计算路径,返回值是路径点数 109 | int Widget::Compute_Road(double start[2], double goal[2], const QVector &obs_x, const QVector &obs_y) 110 | { 111 | //引力增益系数 112 | double attract_gain = 7; 113 | //斥力增益系数 114 | double repulse_gain = 7; 115 | //障碍物影响距离 116 | double Po = 3; 117 | //障碍物个数 118 | double Obs_Number = obs_x.size (); 119 | //步长 120 | double StepLength = 0.2; 121 | //循环迭代最大次数 122 | int max_circletime = 200; 123 | 124 | int s = 0;//存储最后路径点数 125 | double position_angle; 126 | double xnext,ynext; 127 | double current_point[2]; 128 | 129 | double FsumX,FsumY; 130 | double Fa[2],Fr[2]; 131 | 132 | double r_temp;//存储当前位置到目标点距离 133 | 134 | double Fa_angle; 135 | double Fr_angle; 136 | 137 | double *faangle_ptr = &Fa_angle; 138 | double *frangle_ptr = &Fr_angle; 139 | 140 | current_point[0] = start[0]; 141 | current_point[1] = start[1]; 142 | 143 | //定义两个可变数组存放绘图的坐标数据 144 | QVector road_x(200), road_y(200); 145 | 146 | for(int i = 0; i < max_circletime; ++i) 147 | { 148 | //记录路径点 149 | road_x[i] = current_point[0]; 150 | road_y[i] = current_point[1]; 151 | 152 | //吸引力计算 153 | r_temp = Compute_Attract(current_point, goal, attract_gain, Fa, faangle_ptr); 154 | //斥力计算 155 | Compute_Repulsion(r_temp, current_point, obs_x, obs_y, Obs_Number, repulse_gain, Po, Fr, frangle_ptr); 156 | 157 | //计算合力 158 | FsumX = Fa[0] + Fr[0]; 159 | FsumY = Fa[1] + Fr[1]; 160 | 161 | //计算合力角度 162 | position_angle = atan2(FsumY,FsumX);//发现atan2更好用。返回值是-π~π; 163 | 164 | //通过此处可以控制是否改进障碍物在起始与目标点之间的情况 165 | if((Fa_angle == Fr_angle) && (FsumY < 0.0001) && (FsumX < 0.0001)) 166 | position_angle += 0.1;//施加一个扰动(逃逸力) 167 | 168 | //计算下一路径点 169 | xnext = current_point[0] + StepLength*cos(position_angle); 170 | ynext = current_point[1] + StepLength*sin(position_angle); 171 | 172 | //更新当前点 173 | current_point[0] = xnext; 174 | current_point[1] = ynext; 175 | 176 | s = i; 177 | 178 | //判断是否到达目标点 179 | if ((qAbs(goal[0] - current_point[0]) < 0.2) && (qAbs(goal[1] - current_point[1]) < 0.2)) 180 | { 181 | /* code */ 182 | s += 2; 183 | road_x[i+1] = current_point[0]; 184 | road_y[i+1] = current_point[1]; 185 | 186 | road_x[i+2] = goal[0]; 187 | road_y[i+2] = goal[1]; 188 | 189 | break; 190 | } 191 | } 192 | 193 | //定义两个可变数组存放绘图的坐标数据 194 | QVector road_xx(s+1), road_yy(s+1); 195 | for(int i = 0; i < s+1; ++i) 196 | { 197 | road_xx[i] = road_x[i]; 198 | road_yy[i] = road_y[i]; 199 | } 200 | //绘制路径 201 | // create empty curve objects and add them to customPlot: 202 | QCPCurve *road = new QCPCurve(ui->qCustomPlot->xAxis, ui->qCustomPlot->yAxis); 203 | ui->qCustomPlot->addPlottable(road); 204 | 205 | // pass the data to the curves: 206 | road->setData(road_xx, road_yy); 207 | // color the curves: 208 | road->setPen(QPen(Qt::black)); 209 | road->setName ("Road"); 210 | //road->setBrush(QBrush(QColor(0, 0, 255, 20))); 211 | 212 | // //绘制路径 213 | // //向绘图区域QCustomPlot(从widget提升来的)添加一条曲线 214 | // ui->qCustomPlot->addGraph(); 215 | 216 | // //添加数据 217 | // ui->qCustomPlot->graph(3)->setData(road_xx,road_yy); 218 | // ui->qCustomPlot->graph(3)->setPen(QPen(Qt::black)); 219 | // ui->qCustomPlot->graph(3)->setLineStyle(QCPGraph::lsLine ); 220 | // ui->qCustomPlot->graph(3)->setScatterStyle(QCPScatterStyle::ssNone); 221 | // ui->qCustomPlot->graph(3)->setName("Road"); 222 | 223 | //设置坐标轴标签名称 224 | ui->qCustomPlot->xAxis->setLabel("x"); 225 | ui->qCustomPlot->yAxis->setLabel("y"); 226 | 227 | //设置坐标轴显示范围,否则我们只能看到默认的范围 228 | ui->qCustomPlot->xAxis->setRange(0,10); 229 | ui->qCustomPlot->yAxis->setRange(0,10); 230 | 231 | //关闭自动刻度步长 232 | ui->qCustomPlot->xAxis->setAutoTickStep(false); 233 | ui->qCustomPlot->yAxis->setAutoTickStep(false); 234 | //关闭自动子刻度 235 | ui->qCustomPlot->xAxis->setAutoSubTicks(false); 236 | ui->qCustomPlot->yAxis->setAutoSubTicks(false); 237 | //设置主刻度步长1 238 | ui->qCustomPlot->xAxis->setTickStep (1); 239 | ui->qCustomPlot->yAxis->setTickStep (1); 240 | //设置子刻度数4,即分成5份 241 | ui->qCustomPlot->xAxis->setSubTickCount (4); 242 | ui->qCustomPlot->yAxis->setSubTickCount (4); 243 | //设置刻度长度5 244 | ui->qCustomPlot->xAxis->setTickLength (5, 0); 245 | ui->qCustomPlot->yAxis->setTickLength (5, 0); 246 | 247 | // //重绘,这里可以不用,官方例子有,执行setData函数后自动重绘 248 | // //我认为应该用于动态显示或者是改变坐标轴范围之后的动态显示,我们以后探索 249 | // ui->qCustomPlot->replot(); 250 | 251 | qDebug()<<"步数="< 0) 265 | return 1; 266 | else if(x == 0) 267 | return 0; 268 | else if(x < 0) 269 | return -1; 270 | else 271 | return 1; 272 | } 273 | void Widget::setDemo() 274 | { 275 | //QVector start(2),goal(2); 276 | //start<<0<<0; 277 | //goal<<10<<10; 278 | double start[2] = {1, 1}; 279 | double goal[2] = {9, 9}; 280 | //障碍物坐标 281 | //double Obstacle[7][2] = {{1,1}, {3,2.5}, {4,4.5}, {3,6}, {6,2}, {5,5.5}, {9,9}}; 282 | 283 | //绘制起点 284 | QVector start_x,start_y; 285 | start_x<qCustomPlot->addGraph(); 289 | //添加数据 290 | ui->qCustomPlot->graph(0)->setData(start_x,start_y); 291 | ui->qCustomPlot->graph(0)->setPen(QPen(Qt::darkGreen)); 292 | ui->qCustomPlot->graph(0)->setLineStyle(QCPGraph::lsNone); 293 | ui->qCustomPlot->graph(0)->setScatterStyle(QCPScatterStyle::ssDisc); 294 | ui->qCustomPlot->graph(0)->setName("Start"); 295 | 296 | 297 | //绘制障碍物点 298 | QVector obs_x; 299 | obs_x<<5; 300 | 301 | QVector obs_y;//定义坐标 302 | obs_y<<5; 303 | // QVector obs_x; 304 | // obs_x<<3<<6<<8; 305 | 306 | // QVector obs_y;//定义坐标 307 | // obs_y<<4<<3<<6; 308 | 309 | // QVector obs_x; 310 | // obs_x<<1<<2.5<<4<<6; 311 | 312 | // QVector obs_y;//定义坐标 313 | // obs_y<<2<<1<<5<<4; 314 | 315 | //向绘图区域QCustomPlot(从widget提升来的)添加一条曲线 316 | ui->qCustomPlot->addGraph(); 317 | //添加数据 318 | ui->qCustomPlot->graph(1)->setData(obs_x,obs_y); 319 | ui->qCustomPlot->graph(1)->setPen(QPen(Qt::red)); 320 | ui->qCustomPlot->graph(1)->setLineStyle(QCPGraph::lsNone); 321 | ui->qCustomPlot->graph(1)->setScatterStyle(QCPScatterStyle::ssDisc); 322 | ui->qCustomPlot->graph(1)->setName("Obstacle"); 323 | 324 | 325 | //绘制目标点 326 | QVector goal_x,goal_y; 327 | goal_x<qCustomPlot->addGraph(); 331 | //添加数据 332 | ui->qCustomPlot->graph(2)->setData(goal_x,goal_y); 333 | ui->qCustomPlot->graph(2)->setPen(QPen(Qt::blue)); 334 | ui->qCustomPlot->graph(2)->setLineStyle(QCPGraph::lsNone); 335 | ui->qCustomPlot->graph(2)->setScatterStyle(QCPScatterStyle::ssDisc); 336 | ui->qCustomPlot->graph(2)->setName("Goal"); 337 | 338 | //开启图例显示 339 | ui->qCustomPlot->legend->setVisible(true);//true false 340 | ui->qCustomPlot->legend->setFont(QFont("Helvetica", 9)); 341 | 342 | //重设图例位置为左上 343 | ui->qCustomPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignTop|Qt::AlignLeft); 344 | 345 | Compute_Road(start, goal, obs_x,obs_y); 346 | 347 | 348 | } 349 | -------------------------------------------------------------------------------- /QCustomPlot/widget.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGET_H 2 | #define WIDGET_H 3 | 4 | #include 5 | 6 | 7 | namespace Ui { 8 | class Widget; 9 | } 10 | 11 | class Widget : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | double PI; 17 | explicit Widget(QWidget *parent = 0,double pi = 3.1416); 18 | ~Widget(); 19 | //吸引力计算 20 | double Compute_Attract(double current[2], double goal[2], double attract_gain, double Fa[2], double *aptr); 21 | //斥力计算 22 | void Compute_Repulsion(double r, double current[2], const QVector &obs_x, const QVector &obs_y, int Obs_Number, double repulse_gain, double Po, double Fr[2], double *rptr); 23 | //计算路径,返回值是路径点数 24 | int Compute_Road(double start[2], double goal[2], const QVector &obs_x, const QVector &obs_y); 25 | //符号函数 26 | int sign(double x); 27 | //仿真入口 28 | void setDemo(); 29 | private: 30 | Ui::Widget *ui; 31 | }; 32 | 33 | #endif // WIDGET_H 34 | -------------------------------------------------------------------------------- /QCustomPlot/widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Widget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 580 10 | 590 11 | 12 | 13 | 14 | 15 | 1000 16 | 1000 17 | 18 | 19 | 20 | Artificial potential field simulation by xingkuizhang 21 | 22 | 23 | 24 | 25 | 20 26 | 30 27 | 550 28 | 550 29 | 30 | 31 | 32 | 33 | 550 34 | 550 35 | 36 | 37 | 38 | 39 | 40 | 41 | 220 42 | 10 43 | 81 44 | 16 45 | 46 | 47 | 48 | 二维空间图 49 | 50 | 51 | 52 | 53 | 54 | 55 | QCustomPlot 56 | QWidget 57 |
qcustomplot.h
58 | 1 59 |
60 |
61 | 62 | 63 |
64 | -------------------------------------------------------------------------------- /QCustomPlot/说明: -------------------------------------------------------------------------------- 1 | //改进算法成功与否还与系数设置有关,不合适的系数,改进算法也行不通 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Artificial Potential Field Method Simulation 2 | 毕设仿真项目的绘图程序,包含人工势场法的基本与改进算法,通过 qt 绘制展示结果。 3 | 4 | --------------------------------------------------------------------------------