File indexing completed on 2023-10-03 06:50:26
0001 /************************************************************************************* 0002 * Copyright (C) 2011 by Aleix Pol <aleixpol@kde.org> * 0003 * Copyright (C) 2012-2013 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com> * 0004 * * 0005 * This program is free software; you can redistribute it and/or * 0006 * modify it under the terms of the GNU General Public License * 0007 * as published by the Free Software Foundation; either version 2 * 0008 * of the License, or (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the Free Software * 0017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0018 *************************************************************************************/ 0019 0020 #ifndef PLOTTER2D_H 0021 #define PLOTTER2D_H 0022 0023 #include <QRectF> 0024 #include <QLineF> 0025 #include <QString> 0026 #include <QPair> 0027 #include <QColor> 0028 0029 #include "analitzaplotexport.h" 0030 #include <analitzaplot/plottingenums.h> 0031 0032 class QAbstractItemModel; 0033 class QPainter; 0034 class QPaintDevice; 0035 class QModelIndex; 0036 0037 namespace Analitza 0038 { 0039 class PlotItem; 0040 class Plotter2DPrivate; 0041 /** 0042 * \class Plotter2D 0043 * 0044 * \ingroup AnalitzaPlotModule 0045 * 0046 * \brief Render 2D plots. 0047 * 0048 * This class uses QPainter as backend for drawing plots. 0049 * The default value of showGrid is true. 0050 * The default grid color is Qt::lightGray. 0051 * The default background color is Qt::white. 0052 * The default value of autoGridStyle is true. 0053 */ 0054 0055 class ANALITZAPLOT_EXPORT Plotter2D 0056 { 0057 private: // private structs 0058 struct GridInfo; // interval structure for carry current grid state information across interval methods 0059 0060 public: 0061 explicit Plotter2D(const QSizeF& size); 0062 virtual ~Plotter2D(); 0063 0064 /** Sets whether we will draw the grid. */ 0065 void setShowGrid(bool show); 0066 //only works if showgrid is true. for polar grid it affects to subdivision of angles/rays 0067 void setShowMinorGrid(bool mt); 0068 0069 /** Returns whether we have chosen to draw the grid. */ 0070 bool showGrid() const {return m_showGrid; } 0071 0072 /** Returns whether we have chosen to draw the minor grid. */ 0073 bool showMinorGrid() const {return m_showMinorGrid; } 0074 0075 void setGridColor(const QColor &color) { m_gridColor = color; forceRepaint(); } 0076 0077 //default Qt::lightGray 0078 QColor gridColor() const { return m_gridColor; } 0079 0080 void setBackgroundColor(const QColor &color) { m_backgroundColor = color; forceRepaint(); } 0081 0082 // default Qt::white 0083 QColor backgroundColor() const { return m_backgroundColor; } 0084 0085 /** If true then we ignore the grid style suggested by setGridStyleHint, if false then we use as grid style the hint. */ 0086 void setAutoGridStyle(bool autogs) { m_autoGridStyle = autogs; forceRepaint(); } 0087 0088 /** Returns whether we will change automatically the grid style based on the curent plot. */ 0089 bool autoGridStyle() const { return m_autoGridStyle; } 0090 0091 /** Sets the suggested grid style. Only works if autoGridStyle is false. Note that we only accept CoordinateSystem::Cartesian or CoordinateSystem::Polar. */ 0092 void setGridStyleHint(GridStyle suggestedgs); 0093 0094 /** Sets whether it has to keep the aspect ratio (1:1 grid). */ 0095 void setKeepAspectRatio(bool ar); 0096 0097 /** Sets whether it is keeping the aspect ratio (1:1 grid). */ 0098 bool keepAspectRatio() const { return m_keepRatio; } 0099 0100 /** Force the functions from @p start to @p end to be recalculated. */ 0101 void updateFunctions(const QModelIndex & parent, int start, int end); 0102 0103 void setModel(QAbstractItemModel* f); 0104 QAbstractItemModel* model() const; 0105 0106 /** Sets the graph's viewport to @p v. */ 0107 void setViewport(const QRectF& vp, bool repaint=true); 0108 0109 //TODO doc 0110 //normlized current viewport, that includes scale information 0111 QRectF currentViewport() const { return viewport; } 0112 0113 //DEPRECATED 0114 QRectF lastViewport() const { return currentViewport(); } 0115 0116 /** Moves the viewport @p delta */ 0117 void moveViewport(const QPoint& delta); 0118 0119 void setXAxisLabel(const QString &label); 0120 void setYAxisLabel(const QString &label); 0121 0122 //by default linear 0123 void setScaleMode(ScaleMode sm) { m_scaleMode = sm; forceRepaint(); } 0124 ScaleMode scaleMode() const { return m_scaleMode; } 0125 0126 //default radiasn, this will afecto when scalemode is trig and for the angles in polargridmode 0127 void setAngleMode(AngleMode am) { m_angleMode = am; forceRepaint(); } 0128 AngleMode angleMode() const { return m_angleMode; } 0129 0130 void setShowTicks(Qt::Orientations o) { m_showTicks = o; forceRepaint(); } 0131 void setShowTickLabels(Qt::Orientations o) { m_showTickLabels = o; forceRepaint(); } 0132 //only works if showticks is true 0133 void setShowMinorTicks(bool mt) { m_showMinorTicks=mt; forceRepaint(); } 0134 bool minorTicksShown() const { return m_showMinorTicks; } 0135 0136 //these 2 only work when gridmode is polar, showpolar axis aumenta cuando esta lejos de origin 0137 void setShowPolarAxis(bool pt) { m_showPolarAxis = pt; forceRepaint(); } 0138 void setShowPolarAngles(bool pt) { m_showPolarAngles = pt; forceRepaint(); } 0139 0140 void setShowAxes(Qt::Orientations o) { m_showAxes = o; forceRepaint(); } 0141 0142 Qt::Orientations ticksShown() const { return m_showTickLabels; } 0143 0144 /** Zooms in to the Viewport center */ 0145 void zoomIn(bool repaint=true); 0146 0147 /** Zooms out taken ref center too*/ 0148 void zoomOut(bool repaint=true); 0149 0150 protected: 0151 virtual void drawGrid(QPaintDevice *qpd); 0152 virtual void drawFunctions(QPaintDevice *qpd); 0153 virtual void forceRepaint() = 0; 0154 virtual void viewportChanged() = 0; 0155 virtual int currentFunction() const = 0; 0156 virtual void modelChanged() = 0; 0157 virtual void showGridChanged() = 0; 0158 0159 protected: // utils 0160 QRectF lastUserViewport() const { return userViewport; } 0161 QRectF normalizeUserViewport(const QRectF &uvp); // from userViewport to viewport, this one uses current scale information 0162 void updateScale(bool repaint); 0163 0164 QPointF toWidget(const QPointF &) const; 0165 QPointF fromWidget(const QPoint& p) const; 0166 QPointF toViewport(const QPoint& mv) const; 0167 QPair<QPointF, QString> calcImage(const QPointF& ndp) const; 0168 QLineF slope(const QPointF& dp) const; 0169 0170 QLineF toWidget(const QLineF &) const; 0171 void setPaintedSize(const QSize& size); 0172 void setDevicePixelRatio(qreal dpr); 0173 void scaleViewport(qreal scale, const QPoint& center, bool repaint=true); 0174 0175 private: 0176 void drawAxes(QPainter* painter, GridStyle a) const; 0177 void drawCircles(QPainter* painter, const GridInfo& gridinfo, GridStyle gridStyle) const; 0178 void drawSquares(QPainter* painter, const GridInfo& gridinfo, GridStyle gridStyle) const; 0179 void drawMainAxes(QPainter* painter) const; 0180 void drawCartesianTickLabels(QPainter* painter, const GridInfo& gridinfo, CartesianAxis axis) const; 0181 void drawPolarTickLabels(QPainter* painter, const GridInfo& gridinfo) const; 0182 void drawGridTickLabels(QPainter* painter, const GridInfo& gridinfo, GridStyle gridStyle) const; 0183 PlotItem *itemAt(int row) const; 0184 int width() const { return m_size.width(); } 0185 int height() const { return m_size.height(); } 0186 0187 const GridInfo getGridInfo() const; // calculate correct grid params 0188 const QColor computeSubGridColor() const; 0189 const QString computeAngleLabelByFrac(unsigned int n, unsigned int d) const; // input npi/d return angle in m_angleMode 0190 const QString computeAngleLabelByStep(unsigned int k, unsigned int step) const; // input n*step*pi return angle in m_angleMode 0191 0192 bool m_showGrid; 0193 bool m_showMinorGrid; 0194 QColor m_gridColor; 0195 QColor m_backgroundColor; 0196 bool m_autoGridStyle; 0197 GridStyle m_gridStyleHint; 0198 //TODO set move auto tick labels 0199 0200 double rang_x, rang_y; 0201 bool m_keepRatio; 0202 bool m_dirty; // or m_updated; como ahora contamos con setmodel, es necesario que se actualicen los datos antes de pintar, es necesario que no sea dirty 0203 QRectF viewport; // normalized viewport (with scale information), this one is the current viewport (used in currentViewport) 0204 QRectF userViewport; // raw viewport that user sets by setViewport, so we need to normalized userViewport into viewport to include scale and aspect radio information 0205 QSizeF m_size; 0206 0207 friend class Plotter2DPrivate; 0208 Plotter2DPrivate* const d; 0209 0210 AngleMode m_angleMode; 0211 ScaleMode m_scaleMode; 0212 Qt::Orientations m_showTicks; 0213 Qt::Orientations m_showTickLabels; 0214 bool m_showMinorTicks; 0215 Qt::Orientations m_showAxes; 0216 bool m_showPolarAxis; 0217 bool m_showPolarAngles; 0218 QString m_axisXLabel; 0219 QString m_axisYLabel; 0220 0221 private: // constants 0222 static const QColor m_axeColor; 0223 static const QColor m_derivativeColor; 0224 static const QString PiSymbol; 0225 static const QString DegreeSymbol; 0226 static const QString GradianSymbol; 0227 static const double Pi6; // pi/6 0228 static const double Pi12; // pi/12 0229 static const double Pi36; // pi/36 0230 static const double ZoomInFactor; 0231 static const double ZoomOutFactor; 0232 }; 0233 0234 } 0235 0236 #endif // PLOTTER2D_H