1 /*
2  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB.  All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (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 <https://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __KCHARTWIDGET_H__
21 #define __KCHARTWIDGET_H__
22 
23 #include "KChartGlobal.h"
24 
25 #include <QWidget>
26 
27 #include "KChartEnums.h"
28 #include "KChartHeaderFooter.h"
29 
30 QT_BEGIN_NAMESPACE
31 template <typename T> class QVector;
32 template <typename T1, typename T2> struct QPair;
33 QT_END_NAMESPACE
34 
35 namespace KChart {
36 
37     // some forward declarations
38     class AbstractDiagram;
39     class Chart;
40     class AbstractCoordinatePlane;
41     class TableModel;
42     class BarDiagram;
43     class LineDiagram;
44     class Plotter;
45     class PieDiagram;
46     class RingDiagram;
47     class PolarDiagram;
48     class Legend;
49     class Position;
50 
51     /**
52     * \class Widget KChartWidget.h
53     * \brief The KChart widget for usage without Interwiev.
54     *
55     * If you want to use KChart with Interview, use KChart::Chart instead.
56     */
57    class KCHART_EXPORT Widget : public QWidget
58     {
59         Q_OBJECT
60 
61         Q_DISABLE_COPY( Widget )
62         KCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC_QWIDGET( Widget )
63 
64     public:
65         /**
66          * Standard Qt-style Constructor
67          *
68          * Creates a new widget with all data initialized empty.
69          *
70          * \param parent the widget parent; passed on to QWidget
71          */
72        explicit Widget( QWidget* parent = nullptr );
73 
74         /** Destructor. */
75        ~Widget();
76         /** Sets the data in the given column using a QVector of qreal for the Y values. */
77         void setDataset( int column, const QVector< qreal > & data, const QString& title = QString() );
78         /** Sets the data in the given column using a QVector of QPairs
79          *  of qreal for the (X, Y) values. */
80         void setDataset( int column, const QVector< QPair< qreal, qreal > > &  data, const QString& title = QString() );
81         /** Sets the Y value data for a given cell. */
82         void setDataCell( int row, int column, qreal data );
83         /** Sets the data for a given column using an (X, Y) QPair of qreals. */
84         void setDataCell( int row, int column, QPair< qreal, qreal > data );
85         /** Resets all data. */
86         void resetData();
87 
88     public Q_SLOTS:
89         /** Sets all global leadings (borders). */
90         void setGlobalLeading( int left, int top, int right, int bottom );
91         /** Sets the left leading (border). */
92        void setGlobalLeadingLeft( int leading );
93         /** Sets the top leading (border). */
94        void setGlobalLeadingTop( int leading );
95         /** Sets the right leading (border). */
96        void setGlobalLeadingRight( int leading );
97         /** Sets the bottom leading (border). */
98        void setGlobalLeadingBottom( int leading );
99 
100     public:
101         /** Returns the left leading (border). */
102         int globalLeadingLeft() const;
103         /** Returns the top leading (border). */
104         int globalLeadingTop() const;
105         /** Returns the right leading (border). */
106         int globalLeadingRight() const;
107         /** Returns the bottom leading (border). */
108         int globalLeadingBottom() const;
109 
110         /** Returns the first of all headers. */
111         HeaderFooter* firstHeaderFooter();
112         /** Returns a list with all headers. */
113         QList<HeaderFooter*> allHeadersFooters();
114 
115         /** Adds a new header/footer with the given text to the position. */
116         void addHeaderFooter( const QString& text,
117                               HeaderFooter::HeaderFooterType type,
118                               Position position );
119 
120         /**
121           * Adds the existing header / footer object \a header.
122           * \sa replaceHeaderFooter, takeHeaderFooter
123         */
124         void addHeaderFooter( HeaderFooter* header );
125 
126         /**
127          * Replaces the old header (or footer, resp.), or appends the
128          * new header or footer, it there is none yet.
129          *
130          * @param header The header or footer to be used instead of the old one.
131          * This parameter must not be zero, or the method will do nothing.
132          *
133          * @param oldHeader The header or footer to be removed by the new one. This
134          * header or footer will be deleted automatically. If the parameter is omitted,
135          * the very first header or footer will be replaced. In case, there was no
136          * header and no footer yet, the new header or footer will just be added.
137          *
138          * \note If you want to re-use the old header or footer, call takeHeaderFooter and
139          * addHeaderFooter, instead of using replaceHeaderFooter.
140          *
141          * \sa addHeaderFooter, takeHeaderFooter
142          */
143         void replaceHeaderFooter( HeaderFooter* header,
144                                   HeaderFooter* oldHeader = nullptr );
145 
146         /** Remove the header (or footer, resp.) from the widget,
147          * without deleting it.
148          * The chart no longer owns the header or footer, so it is
149          * the caller's responsibility to delete the header or footer.
150          *
151          * \sa addHeaderFooter, replaceHeaderFooter
152          */
153         void takeHeaderFooter( HeaderFooter* header );
154 
155         /** Returns the first of all legends. */
156         Legend* legend();
157         /** Returns a list with all legends. */
158         QList<Legend*> allLegends();
159 
160         /** Adds an empty legend on the given position. */
161         void addLegend( Position position );
162         /** Adds a new, already existing, legend. */
163         void addLegend (Legend* legend );
164 
165         void replaceLegend( Legend* legend, Legend* oldLegend = nullptr );
166         void takeLegend( Legend* legend );
167 
168 
169         /** Returns a pointer to the current diagram. */
170         AbstractDiagram* diagram();
171 
172         /** If the current diagram is a BarDiagram, it is returnd; otherwise 0 is returned.
173           * This function provides type-safe casting.
174           */
175         BarDiagram* barDiagram();
176         /** If the current diagram is a LineDiagram, it is returnd; otherwise 0 is returned.
177          * This function provides type-safe casting.
178          */
179         LineDiagram* lineDiagram();
180         /** If the current diagram is a LineDiagram, it is returnd; otherwise 0 is returned.
181          * This function provides type-safe casting.
182          *
183          * \note Do not use lineDiagram for multi-dimensional diagrams, but use plotter instead
184          *
185          * \sa plotter
186          */
187         Plotter* plotter();
188         /** If the current diagram is a Plotter, it is returnd; otherwise 0 is returned.
189           * This function provides type-safe casting.
190           */
191         PieDiagram* pieDiagram();
192         /** If the current diagram is a RingDiagram, it is returnd; otherwise 0 is returned.
193           * This function provides type-safe casting.
194           */
195         RingDiagram* ringDiagram();
196         /** If the current diagram is a PolarDiagram, it is returnd; otherwise 0 is returned.
197           * This function provides type-safe casting.
198           */
199         PolarDiagram* polarDiagram();
200 
201         /** Returns a pointer to the current coordinate plane. */
202         AbstractCoordinatePlane* coordinatePlane();
203 
204 
205         enum ChartType { NoType, Bar, Line, Plot, Pie, Ring, Polar };
206 
207         /** Returns the type of the chart. */
208         ChartType type() const;
209 
210         /** Sub type values, matching the values defines for the respective Diagram classes. */
211         enum SubType { Normal, Stacked, Percent, Rows };
212 
213         /** Returns the sub-type of the chart. */
214         SubType subType() const;
215 
216     public Q_SLOTS:
217         /** Sets the type of the chart. */
218         void setType( ChartType chartType, SubType subType=Normal );
219         /** \brief Sets the type of the chart without changing the main type.
220           *
221           * Make sure to use a sub-type that matches the main type,
222           * so e.g. setting sub-type Rows makes sense for Bar charts only,
223           * and it will be ignored for all other chart types.
224           *
225           * \sa KChart::BarDiagram::BarType, KChart::LineDiagram::LineType
226           * \sa KChart::PieDiagram::PieType, KChart::RingDiagram::RingType
227           * \sa KChart::PolarDiagram::PolarType
228           */
229         void setSubType( SubType subType );
230 
231     private:
232         /** Justifies the model, so that the given rows and columns fit into it. */
233         void justifyModelSize( int rows, int columns );
234         /** Checks whether the given width matches with the one used until now. */
235        bool checkDatasetWidth( int width );
236     };
237 }
238 
239 #endif // KChartWidget_H
240