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 #include <QtTest/QtTest>
21 #include <QStandardItemModel>
22 #include <QPointF>
23 #include <QPair>
24 #include <QString>
25 #include <KChartChart>
26 #include <KChartCartesianCoordinatePlane>
27 #include <KChartBarDiagram>
28 #include <KChartPlotter>
29 #include <KChartGridAttributes>
30 
31 
32 using namespace KChart;
33 
34 class NumericDataModel : public QStandardItemModel
35 {
36     Q_OBJECT
37 public:
setYValues(const QList<qreal> & values)38     void setYValues( const QList< qreal > &values )
39     {
40         min = QPointF( 0, 1e9 );
41         max = QPointF( values.size() - 1, -1e9 );
42         setRowCount( values.size() );
43         setColumnCount( 1 );
44         for ( int i = 0; i < values.size(); i++ ) {
45             min.setY( qMin( min.y(), values[ i ] ) );
46             max.setY( qMax( max.y(), values[ i ] ) );
47 
48             QModelIndex idx = index( i, 0 );
49             QStandardItemModel::setData( idx, values[ i ] );
50         }
51     }
52 
setXyValues(const QList<QPointF> & values)53     void setXyValues( const QList< QPointF > &values )
54     {
55         min = QPointF( 1e9, 1e9 );
56         max = QPointF( -1e9, -1e9 );
57         setRowCount( values.size() );
58         setColumnCount( 2 );
59         for ( int i = 0; i < values.size(); i++ ) {
60             min.setX( qMin( min.x(), values[ i ].x() ) );
61             max.setX( qMax( max.x(), values[ i ].x() ) );
62             min.setY( qMin( min.y(), values[ i ].y() ) );
63             max.setY( qMax( max.y(), values[ i ].y() ) );
64 
65             QModelIndex idx = index( i, 0 );
66             QStandardItemModel::setData( idx, values[ i ].x() );
67             idx = index( i, 1 );
68             QStandardItemModel::setData( idx, values[ i ].y() );
69         }
70     }
71 
72     QPointF min;
73     QPointF max;
74 };
75 
76 class TestCartesianPlanes : public QObject {
77     Q_OBJECT
78 private Q_SLOTS:
79 
80     void init();
81     void cleanup();
82     void testIntialOwnership();
83     void testDiagramOwnership();
84     void testIsometricScalingSettings();
85     void testZoomFactorsSettings();
86     void testRangeSettingsBars();
87     void testRangeSettingsPlotter();
88     void testGlobalGridAttributesSettings();
89     void testGridAttributesSettings();
90     void testAxesCalcModesSettings();
91 
92 private:
93     void doTestRangeSettings( AbstractCartesianDiagram *diagram, const QPointF &min, const QPointF &max );
94 
95     Chart *m_chart;
96     BarDiagram *m_bars;
97     Plotter *m_plotter;
98     CartesianCoordinatePlane *m_plane;
99     NumericDataModel *m_model;
100 
101 };
102 
init()103 void TestCartesianPlanes::init()
104 {
105     m_chart = new Chart( nullptr );
106     m_model = new NumericDataModel();
107     m_model->setParent( m_chart );
108     m_bars = new BarDiagram( m_chart );
109     m_bars->setModel( m_model );
110     m_plotter = new Plotter( m_chart );
111     m_plotter->setModel( m_model );
112     m_plane = new CartesianCoordinatePlane( m_chart );
113     m_chart->addCoordinatePlane( m_plane );
114     m_plane->setReferenceCoordinatePlane( m_chart->coordinatePlane() );
115     qDebug() << m_plotter->datasetDimension();
116 }
117 
cleanup()118 void TestCartesianPlanes::cleanup()
119 {
120     delete m_chart;
121 }
122 
123 
testIntialOwnership()124 void TestCartesianPlanes::testIntialOwnership()
125 {
126     AbstractCoordinatePlane *plane = m_chart->coordinatePlane();
127     QCOMPARE( m_plane->referenceCoordinatePlane(), m_chart->coordinatePlane() );
128     m_chart->takeCoordinatePlane( nullptr );
129     delete plane;
130     QCOMPARE( m_plane->referenceCoordinatePlane(), (AbstractCoordinatePlane*)nullptr );
131 }
132 
testDiagramOwnership()133 void TestCartesianPlanes::testDiagramOwnership()
134 {
135     m_plane->addDiagram( m_bars );
136     QCOMPARE( m_plane->diagrams().size(), 1 );
137     m_plane->addDiagram( m_plotter );
138     QCOMPARE( m_plane->diagrams().size(), 2 );
139     QCOMPARE( dynamic_cast< BarDiagram * >( m_plane->diagram() ), m_bars );
140     m_plane->takeDiagram( m_bars );
141     QCOMPARE( m_plane->diagrams().size(), 1 );
142     QCOMPARE( dynamic_cast< Plotter * >( m_plane->diagram() ), m_plotter );
143     m_plane->replaceDiagram( m_bars,  m_plotter );
144     QCOMPARE( m_plane->diagrams().size(), 1 );
145     QCOMPARE( dynamic_cast< BarDiagram * >( m_plane->diagram() ), m_bars );
146     m_plane->takeDiagram( m_bars );
147     QCOMPARE( m_plane->diagrams().size(), 0 );
148     delete m_bars;
149 }
150 
testIsometricScalingSettings()151 void TestCartesianPlanes::testIsometricScalingSettings()
152 {
153     QVERIFY( m_plane->doesIsometricScaling() == false );
154     m_plane->setIsometricScaling( true );
155     QVERIFY( m_plane->doesIsometricScaling() == true );
156 }
157 
testZoomFactorsSettings()158 void TestCartesianPlanes::testZoomFactorsSettings()
159 {
160     QCOMPARE( m_plane->zoomFactorX(), 1.0 );
161     QCOMPARE( m_plane->zoomFactorY(), 1.0 );
162     QCOMPARE( m_plane->zoomCenter(), QPointF( 0.5, 0.5 ) );
163     m_plane->setZoomFactorX( 1.5 );
164     m_plane->setZoomFactorY( 1.5 );
165     m_plane->setZoomCenter( QPointF( 1.0, 1.0 ) );
166     QCOMPARE( m_plane->zoomFactorX(), 1.5 );
167     QCOMPARE( m_plane->zoomFactorY(), 1.5 );
168     QCOMPARE( m_plane->zoomCenter(), QPointF( 1.0, 1.0 ) );
169 }
170 
doTestRangeSettings(AbstractCartesianDiagram * diagram,const QPointF & min,const QPointF & max)171 void TestCartesianPlanes::doTestRangeSettings( AbstractCartesianDiagram *diagram,
172                                                const QPointF &min, const QPointF &max )
173 {
174     m_plane->addDiagram( diagram );
175     // the range is null when auto adjustment is turned off - check that...
176     m_plane->setAutoAdjustHorizontalRangeToData( 100 );
177     m_plane->setAutoAdjustVerticalRangeToData( 100 );
178 
179     {
180         const QPair< qreal, qreal > hrange = m_plane->horizontalRange();
181         const QPair< qreal, qreal > vrange = m_plane->verticalRange();
182         QCOMPARE( hrange.first, qreal( 0.0 ) );
183         QCOMPARE( hrange.second, qreal( 0.0 ) );
184         QCOMPARE( vrange.first, qreal( 0.0 ) );
185         QCOMPARE( vrange.second, qreal( 0.0 ) );
186     }
187 
188     // now check that auto adjustment works when enabled
189     m_plane->setAutoAdjustHorizontalRangeToData( 67 );
190     m_plane->setAutoAdjustVerticalRangeToData( 67 );
191     {
192         const QPair< qreal, qreal > hrange = m_plane->horizontalRange();
193         const QPair< qreal, qreal > vrange = m_plane->verticalRange();
194         QCOMPARE( hrange.first, min.x() );
195         QCOMPARE( hrange.second, max.x() );
196         QCOMPARE( vrange.first, min.y() );
197         QCOMPARE( vrange.second, max.y() );
198     }
199 
200     {
201         QPair< qreal, qreal> hboundaries( diagram->dataBoundaries().first.x(),
202                                           diagram->dataBoundaries().second.x() );
203         QPair< qreal, qreal> vboundaries( int( diagram->dataBoundaries().first.y() + 0.5 ),
204                                           int( diagram->dataBoundaries().second.y() + 0.5 ) );
205         m_plane->setHorizontalRange( hboundaries );
206         m_plane->setVerticalRange( vboundaries );
207         const QPair< qreal, qreal > newhb = m_plane->horizontalRange();
208         const QPair< qreal, qreal > newvb = m_plane->verticalRange();
209         QCOMPARE( newhb.first, hboundaries.first );
210         QCOMPARE( newhb.second, hboundaries.second );
211         QCOMPARE( newvb.first, vboundaries.first );
212         QCOMPARE( newvb.second, vboundaries.second );
213     }
214 }
215 
testRangeSettingsBars()216 void TestCartesianPlanes::testRangeSettingsBars()
217 {
218     QList< qreal > points;
219     points << 40 << 45 << 42 << 34 << 34;
220     m_model->setYValues( points );
221     // data point "0" is shown at "0.5" in bar diagrams, which requires some data range hackery.
222     // we correct for that like so:
223     m_model->max.rx() += 1;
224 
225     doTestRangeSettings( m_bars, m_model->min, m_model->max );
226 }
227 
testRangeSettingsPlotter()228 void TestCartesianPlanes::testRangeSettingsPlotter()
229 {
230     QList< QPointF > points;
231     points << QPointF( 0.0, 40.0 ) << QPointF( 1.0, 45.0 ) << QPointF( 2.0, 42.0 )
232            << QPointF( 3.0, 34.0 ) << QPointF( 4.0, 34.0 );
233     m_model->setXyValues( points );
234     doTestRangeSettings( m_plotter, m_model->min, m_model->max );
235 }
236 
testGlobalGridAttributesSettings()237 void TestCartesianPlanes::testGlobalGridAttributesSettings()
238 {
239     GridAttributes ga = m_plane->globalGridAttributes();
240     QVERIFY( ga.isGridVisible() == true );
241     ga.setGridVisible( false );
242     m_plane->setGlobalGridAttributes( ga );
243     QVERIFY( m_plane->globalGridAttributes().isGridVisible() == false );
244     //reset to normal
245     ga.setGridVisible( true );
246     QVERIFY( m_plane->globalGridAttributes().isGridVisible() == false );
247     m_plane->setGlobalGridAttributes( ga );
248     QVERIFY( m_plane->globalGridAttributes().isGridVisible() == true );
249 }
250 
testGridAttributesSettings()251 void TestCartesianPlanes::testGridAttributesSettings()
252 {
253     GridAttributes gh = m_plane->gridAttributes( Qt::Horizontal );
254     GridAttributes gv = m_plane->gridAttributes( Qt::Vertical );
255     QVERIFY( gh.isGridVisible() == true );
256     QVERIFY( gv.isGridVisible() == true );
257     gh.setGridVisible( false );
258     m_plane->setGridAttributes( Qt::Horizontal, gh );
259     QVERIFY( m_plane->hasOwnGridAttributes( Qt::Horizontal ) == true );
260     QVERIFY( m_plane->hasOwnGridAttributes( Qt::Vertical ) == false );
261     QVERIFY( m_plane->gridAttributes( Qt::Horizontal ).isGridVisible() == false );
262     QVERIFY( m_plane->gridAttributes( Qt::Vertical ).isGridVisible() == true );
263     gv.setGridVisible( false );
264     m_plane->setGridAttributes( Qt::Vertical, gv );
265     QVERIFY( m_plane->hasOwnGridAttributes( Qt::Horizontal ) == true );
266     QVERIFY( m_plane->hasOwnGridAttributes( Qt::Vertical ) == true );
267     QVERIFY( m_plane->gridAttributes( Qt::Horizontal ).isGridVisible() == false );
268     QVERIFY( m_plane->gridAttributes( Qt::Vertical ).isGridVisible() == false );
269     m_plane->resetGridAttributes( Qt::Horizontal );
270     m_plane->resetGridAttributes( Qt::Vertical );
271     QVERIFY( m_plane->gridAttributes( Qt::Horizontal ).isGridVisible() == true );
272     QVERIFY( m_plane->gridAttributes( Qt::Vertical ).isGridVisible() == true );
273     QVERIFY( m_plane->hasOwnGridAttributes( Qt::Horizontal ) == false );
274     QVERIFY( m_plane->hasOwnGridAttributes( Qt::Vertical ) == false );
275 }
276 
testAxesCalcModesSettings()277 void TestCartesianPlanes::testAxesCalcModesSettings()
278 {
279     QCOMPARE( m_plane->axesCalcModeX(), AbstractCoordinatePlane::Linear );
280     QCOMPARE( m_plane->axesCalcModeY(), AbstractCoordinatePlane::Linear );
281     m_plane->setAxesCalcModes( AbstractCoordinatePlane::Logarithmic );
282     QCOMPARE( m_plane->axesCalcModeX(), AbstractCoordinatePlane::Logarithmic );
283     QCOMPARE( m_plane->axesCalcModeY(), AbstractCoordinatePlane::Logarithmic );
284     m_plane->setAxesCalcModeX( AbstractCoordinatePlane::Linear );
285     QCOMPARE( m_plane->axesCalcModeX(), AbstractCoordinatePlane::Linear );
286     QCOMPARE( m_plane->axesCalcModeY(), AbstractCoordinatePlane::Logarithmic );
287     m_plane->setAxesCalcModeY( AbstractCoordinatePlane::Linear );
288     QCOMPARE( m_plane->axesCalcModeX(), AbstractCoordinatePlane::Linear );
289     QCOMPARE( m_plane->axesCalcModeY(), AbstractCoordinatePlane::Linear );
290 }
291 
292 
293 QTEST_MAIN(TestCartesianPlanes)
294 
295 #include "main.moc"
296