File indexing completed on 2024-04-14 03:39:22

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