1 /************************************************************************************* 2 * Copyright (C) 2011 by Aleix Pol <aleixpol@kde.org> * 3 * Copyright (C) 2012-2013 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com> * 4 * * 5 * This program is free software; you can redistribute it and/or * 6 * modify it under the terms of the GNU General Public License * 7 * as published by the Free Software Foundation; either version 2 * 8 * of the License, or (at your option) any later version. * 9 * * 10 * This program is distributed in the hope that it will be useful, * 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 * GNU General Public License for more details. * 14 * * 15 * You should have received a copy of the GNU General Public License * 16 * along with this program; if not, write to the Free Software * 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 18 *************************************************************************************/ 19 20 #ifndef PLOTTER2D_H 21 #define PLOTTER2D_H 22 23 #include <QRectF> 24 #include <QLineF> 25 #include <QString> 26 #include <QPair> 27 #include <QColor> 28 29 #include "analitzaplotexport.h" 30 #include <analitzaplot/plottingenums.h> 31 32 class QAbstractItemModel; 33 class QPainter; 34 class QPaintDevice; 35 class QModelIndex; 36 37 namespace Analitza 38 { 39 class PlotItem; 40 class Plotter2DPrivate; 41 /** 42 * \class Plotter2D 43 * 44 * \ingroup AnalitzaPlotModule 45 * 46 * \brief Render 2D plots. 47 * 48 * This class uses QPainter as backend for drawing plots. 49 * The default value of showGrid is true. 50 * The default grid color is Qt::lightGray. 51 * The default background color is Qt::white. 52 * The default value of autoGridStyle is true. 53 */ 54 55 class ANALITZAPLOT_EXPORT Plotter2D 56 { 57 private: // private structs 58 struct GridInfo; // interval structure for carry current grid state information across interval methods 59 60 public: 61 explicit Plotter2D(const QSizeF& size); 62 virtual ~Plotter2D(); 63 64 /** Sets whether we will draw the grid. */ 65 void setShowGrid(bool show); 66 //only works if showgrid is true. for polar grid it affects to subdivision of angles/rays 67 void setShowMinorGrid(bool mt); 68 69 /** Returns whether we have chosen to draw the grid. */ showGrid()70 bool showGrid() const {return m_showGrid; } 71 72 /** Returns whether we have chosen to draw the minor grid. */ showMinorGrid()73 bool showMinorGrid() const {return m_showMinorGrid; } 74 setGridColor(const QColor & color)75 void setGridColor(const QColor &color) { m_gridColor = color; forceRepaint(); } 76 77 //default Qt::lightGray gridColor()78 QColor gridColor() const { return m_gridColor; } 79 setBackgroundColor(const QColor & color)80 void setBackgroundColor(const QColor &color) { m_backgroundColor = color; forceRepaint(); } 81 82 // default Qt::white backgroundColor()83 QColor backgroundColor() const { return m_backgroundColor; } 84 85 /** If true then we ignore the grid style suggested by setGridStyleHint, if false then we use as grid style the hint. */ setAutoGridStyle(bool autogs)86 void setAutoGridStyle(bool autogs) { m_autoGridStyle = autogs; forceRepaint(); } 87 88 /** Returns whether we will change automatically the grid style based on the curent plot. */ autoGridStyle()89 bool autoGridStyle() const { return m_autoGridStyle; } 90 91 /** Sets the suggested grid style. Only works if autoGridStyle is false. Note that we only accept CoordinateSystem::Cartesian or CoordinateSystem::Polar. */ 92 void setGridStyleHint(GridStyle suggestedgs); 93 94 /** Sets whether it has to keep the aspect ratio (1:1 grid). */ 95 void setKeepAspectRatio(bool ar); 96 97 /** Sets whether it is keeping the aspect ratio (1:1 grid). */ keepAspectRatio()98 bool keepAspectRatio() const { return m_keepRatio; } 99 100 /** Force the functions from @p start to @p end to be recalculated. */ 101 void updateFunctions(const QModelIndex & parent, int start, int end); 102 103 void setModel(QAbstractItemModel* f); 104 QAbstractItemModel* model() const; 105 106 /** Sets the graph's viewport to @p v. */ 107 void setViewport(const QRectF& vp, bool repaint=true); 108 109 //TODO doc 110 //normlized current viewport, that includes scale information currentViewport()111 QRectF currentViewport() const { return viewport; } 112 113 //DEPRECATED lastViewport()114 QRectF lastViewport() const { return currentViewport(); } 115 116 /** Moves the viewport @p delta */ 117 void moveViewport(const QPoint& delta); 118 119 void setXAxisLabel(const QString &label); 120 void setYAxisLabel(const QString &label); 121 122 //by default linear setScaleMode(ScaleMode sm)123 void setScaleMode(ScaleMode sm) { m_scaleMode = sm; forceRepaint(); } scaleMode()124 ScaleMode scaleMode() const { return m_scaleMode; } 125 126 //default radiasn, this will afecto when scalemode is trig and for the angles in polargridmode setAngleMode(AngleMode am)127 void setAngleMode(AngleMode am) { m_angleMode = am; forceRepaint(); } angleMode()128 AngleMode angleMode() const { return m_angleMode; } 129 setShowTicks(Qt::Orientations o)130 void setShowTicks(Qt::Orientations o) { m_showTicks = o; forceRepaint(); } setShowTickLabels(Qt::Orientations o)131 void setShowTickLabels(Qt::Orientations o) { m_showTickLabels = o; forceRepaint(); } 132 //only works if showticks is true setShowMinorTicks(bool mt)133 void setShowMinorTicks(bool mt) { m_showMinorTicks=mt; forceRepaint(); } minorTicksShown()134 bool minorTicksShown() const { return m_showMinorTicks; } 135 136 //these 2 only work when gridmode is polar, showpolar axis aumenta cuando esta lejos de origin setShowPolarAxis(bool pt)137 void setShowPolarAxis(bool pt) { m_showPolarAxis = pt; forceRepaint(); } setShowPolarAngles(bool pt)138 void setShowPolarAngles(bool pt) { m_showPolarAngles = pt; forceRepaint(); } 139 setShowAxes(Qt::Orientations o)140 void setShowAxes(Qt::Orientations o) { m_showAxes = o; forceRepaint(); } 141 ticksShown()142 Qt::Orientations ticksShown() const { return m_showTickLabels; } 143 144 /** Zooms in to the Viewport center */ 145 void zoomIn(bool repaint=true); 146 147 /** Zooms out taken ref center too*/ 148 void zoomOut(bool repaint=true); 149 150 protected: 151 virtual void drawGrid(QPaintDevice *qpd); 152 virtual void drawFunctions(QPaintDevice *qpd); 153 virtual void forceRepaint() = 0; 154 virtual void viewportChanged() = 0; 155 virtual int currentFunction() const = 0; 156 virtual void modelChanged() = 0; 157 virtual void showGridChanged() = 0; 158 159 protected: // utils lastUserViewport()160 QRectF lastUserViewport() const { return userViewport; } 161 QRectF normalizeUserViewport(const QRectF &uvp); // from userViewport to viewport, this one uses current scale information 162 void updateScale(bool repaint); 163 164 QPointF toWidget(const QPointF &) const; 165 QPointF fromWidget(const QPoint& p) const; 166 QPointF toViewport(const QPoint& mv) const; 167 QPair<QPointF, QString> calcImage(const QPointF& ndp) const; 168 QLineF slope(const QPointF& dp) const; 169 170 QLineF toWidget(const QLineF &) const; 171 void setPaintedSize(const QSize& size); 172 void setDevicePixelRatio(qreal dpr); 173 void scaleViewport(qreal scale, const QPoint& center, bool repaint=true); 174 175 private: 176 void drawAxes(QPainter* painter, GridStyle a) const; 177 void drawCircles(QPainter* painter, const GridInfo& gridinfo, GridStyle gridStyle) const; 178 void drawSquares(QPainter* painter, const GridInfo& gridinfo, GridStyle gridStyle) const; 179 void drawMainAxes(QPainter* painter) const; 180 void drawCartesianTickLabels(QPainter* painter, const GridInfo& gridinfo, CartesianAxis axis) const; 181 void drawPolarTickLabels(QPainter* painter, const GridInfo& gridinfo) const; 182 void drawGridTickLabels(QPainter* painter, const GridInfo& gridinfo, GridStyle gridStyle) const; 183 PlotItem *itemAt(int row) const; width()184 int width() const { return m_size.width(); } height()185 int height() const { return m_size.height(); } 186 187 const GridInfo getGridInfo() const; // calculate correct grid params 188 const QColor computeSubGridColor() const; 189 const QString computeAngleLabelByFrac(unsigned int n, unsigned int d) const; // input npi/d return angle in m_angleMode 190 const QString computeAngleLabelByStep(unsigned int k, unsigned int step) const; // input n*step*pi return angle in m_angleMode 191 192 bool m_showGrid; 193 bool m_showMinorGrid; 194 QColor m_gridColor; 195 QColor m_backgroundColor; 196 bool m_autoGridStyle; 197 GridStyle m_gridStyleHint; 198 //TODO set move auto tick labels 199 200 double rang_x, rang_y; 201 bool m_keepRatio; 202 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 203 QRectF viewport; // normalized viewport (with scale information), this one is the current viewport (used in currentViewport) 204 QRectF userViewport; // raw viewport that user sets by setViewport, so we need to normalized userViewport into viewport to include scale and aspect radio information 205 QSizeF m_size; 206 207 friend class Plotter2DPrivate; 208 Plotter2DPrivate* const d; 209 210 AngleMode m_angleMode; 211 ScaleMode m_scaleMode; 212 Qt::Orientations m_showTicks; 213 Qt::Orientations m_showTickLabels; 214 bool m_showMinorTicks; 215 Qt::Orientations m_showAxes; 216 bool m_showPolarAxis; 217 bool m_showPolarAngles; 218 QString m_axisXLabel; 219 QString m_axisYLabel; 220 221 private: // constants 222 static const QColor m_axeColor; 223 static const QColor m_derivativeColor; 224 static const QString PiSymbol; 225 static const QString DegreeSymbol; 226 static const QString GradianSymbol; 227 static const double Pi6; // pi/6 228 static const double Pi12; // pi/12 229 static const double Pi36; // pi/36 230 static const double ZoomInFactor; 231 static const double ZoomOutFactor; 232 }; 233 234 } 235 236 #endif // PLOTTER2D_H 237