##// END OF EJS Templates
QChart mapping functions: return QPoint(0, 0) if series type is Pie...
Marek Rosa -
r2351:bd26609a29ae
parent child
Show More
@@ -0,0 +1,5
1 !include( ../auto.pri ) {
2 error( "Couldn't find the auto.pri file!" )
3 }
4 HEADERS += ../qabstractaxis/tst_qabstractaxis.h
5 SOURCES += tst_qlogvalueaxis.cpp ../qabstractaxis/tst_qabstractaxis.cpp
@@ -0,0 +1,378
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #include "../qabstractaxis/tst_qabstractaxis.h"
22 #include "qlogvalueaxis.h"
23 #include <qlineseries.h>
24 #include <QDebug>
25
26 class tst_QLogValueAxis: public tst_QAbstractAxis
27 {
28 Q_OBJECT
29
30 public slots:
31 void initTestCase();
32 void cleanupTestCase();
33 void init();
34 void cleanup();
35
36 private slots:
37 // void qlogvalueaxis_data();
38 // void qlogvalueaxis();
39 // void max_raw_data();
40 // void max_raw();
41 // void max_data();
42 // void max();
43 // void max_animation_data();
44 // void max_animation();
45 void min_raw_data();
46 void min_raw();
47 void min_data();
48 void min();
49 void min_animation_data();
50 void min_animation();
51 // void range_raw_data();
52 // void range_raw();
53 // void range_data();
54 // void range();
55 // void range_animation_data();
56 // void range_animation();
57 // void noautoscale_data();
58 // void noautoscale();
59 // void autoscale_data();
60 // void autoscale();
61 void zoomIn();
62 // void zoomOut();
63
64 private:
65 QLogValueAxis* m_logvaluesaxis;
66 QLineSeries* m_series;
67 };
68
69 void tst_QLogValueAxis::initTestCase()
70 {
71 }
72
73 void tst_QLogValueAxis::cleanupTestCase()
74 {
75 }
76
77 void tst_QLogValueAxis::init()
78 {
79 m_logvaluesaxis = new QLogValueAxis();
80 m_series = new QLineSeries();
81 *m_series << QPointF(1, 1) << QPointF(100, 100);
82 tst_QAbstractAxis::init(m_logvaluesaxis,m_series);
83 m_chart->addSeries(m_series);
84 m_chart->createDefaultAxes();
85 }
86
87 void tst_QLogValueAxis::cleanup()
88 {
89 delete m_series;
90 delete m_logvaluesaxis;
91 m_series = 0;
92 m_logvaluesaxis = 0;
93 tst_QAbstractAxis::cleanup();
94 }
95
96 //void tst_QLogValueAxis::qlogvalueaxis_data()
97 //{
98 //}
99
100 //void tst_QLogValueAxis::qlogvalueaxis()
101 //{
102 // qabstractaxis();
103
104 // QVERIFY(qFuzzyCompare(m_logvaluesaxis->max(), 1));
105 // QVERIFY(qFuzzyCompare(m_logvaluesaxis->min(), 1));
106 // QCOMPARE(m_logvaluesaxis->type(), QAbstractAxis::AxisTypeLogValue);
107
108 // m_chart->setAxisX(m_logvaluesaxis, m_series);
109 // m_view->show();
110 // QTest::qWaitForWindowShown(m_view);
111
112 // QVERIFY(!qFuzzyCompare(m_logvaluesaxis->max(), 100));
113 // QVERIFY(!qFuzzyCompare(m_logvaluesaxis->min(), 0.1));
114 //}
115
116 //void tst_QLogValueAxis::max_raw_data()
117 //{
118 // QTest::addColumn<qreal>("max");
119 // QTest::addColumn<qreal>("expected");
120 // QTest::addColumn<bool>("minChanged");
121 // QTest::addColumn<bool>("maxChanged");
122 // QTest::newRow("-1.0") << (qreal)-1.0 << (qreal)1.0 << false << false;
123 // QTest::newRow("0.0") << (qreal)0.0 << (qreal)1.0 << false << false;
124 // QTest::newRow("0.5") << (qreal)0.5 << (qreal)0.5 << true << true;
125 // QTest::newRow("101.0") << (qreal)101.0 << (qreal)101.0 << false << true;
126 //}
127
128 //void tst_QLogValueAxis::max_raw()
129 //{
130 // QFETCH(qreal, max);
131 // QFETCH(qreal, expected);
132 // QFETCH(bool, minChanged);
133 // QFETCH(bool, maxChanged);
134
135 // QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal)));
136 // QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal)));
137 // QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal)));
138
139 // m_logvaluesaxis->setMax(max);
140 // QCOMPARE(m_logvaluesaxis->max(), expected);
141
142 // QCOMPARE(spy0.count(), (int)maxChanged);
143 // QCOMPARE(spy1.count(), (int)minChanged);
144 // QCOMPARE(spy2.count(), (int)maxChanged);
145
146 //}
147
148 //void tst_QLogValueAxis::max_data()
149 //{
150 // max_raw_data();
151 //}
152
153 //void tst_QLogValueAxis::max()
154 //{
155 // m_chart->setAxisX(m_logvaluesaxis, m_series);
156 // m_view->show();
157 // QTest::qWaitForWindowShown(m_view);
158 // max_raw();
159 //}
160
161 //void tst_QLogValueAxis::max_animation_data()
162 //{
163 // max_data();
164 //}
165
166 //void tst_QLogValueAxis::max_animation()
167 //{
168 // m_chart->setAnimationOptions(QChart::GridAxisAnimations);
169 // max();
170 //}
171
172 void tst_QLogValueAxis::min_raw_data()
173 {
174 QTest::addColumn<qreal>("min");
175 QTest::addColumn<qreal>("expected");
176 QTest::addColumn<bool>("minChanged");
177 QTest::addColumn<bool>("maxChanged");
178 QTest::newRow("-1.0") << (qreal)-1.0 << (qreal)1.0 << false << false;
179 QTest::newRow("0.0") << (qreal)0.0 << (qreal)1.0 << false << false;
180 QTest::newRow("0.5") << (qreal)0.5 << (qreal)0.5 << true << false;
181 QTest::newRow("101.0") << (qreal)101.0 << (qreal)101.0 << true << true;
182 }
183
184 void tst_QLogValueAxis::min_raw()
185 {
186 QFETCH(qreal, min);
187 QFETCH(qreal, expected);
188 QFETCH(bool, minChanged);
189 QFETCH(bool, maxChanged);
190
191 QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal)));
192 QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal)));
193 QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal)));
194
195 m_logvaluesaxis->setMin(min);
196 QCOMPARE(m_logvaluesaxis->min(), expected);
197
198 QCOMPARE(spy0.count(), (int)maxChanged);
199 QCOMPARE(spy1.count(), (int)minChanged);
200 QCOMPARE(spy2.count(), (int)minChanged);
201 }
202
203 void tst_QLogValueAxis::min_data()
204 {
205 min_raw_data();
206 }
207
208 void tst_QLogValueAxis::min()
209 {
210 m_chart->setAxisX(m_logvaluesaxis, m_series);
211 m_view->show();
212 QTest::qWaitForWindowShown(m_view);
213 min_raw();
214 }
215
216 void tst_QLogValueAxis::min_animation_data()
217 {
218 min_data();
219 }
220
221 void tst_QLogValueAxis::min_animation()
222 {
223 m_chart->setAnimationOptions(QChart::GridAxisAnimations);
224 min();
225 }
226
227 //void tst_QLogValueAxis::range_raw_data()
228 //{
229 // QTest::addColumn<qreal>("min");
230 // QTest::addColumn<qreal>("max");
231 // QTest::newRow("1.0 - 101.0") << (qreal)1.0 << (qreal)101.0;
232 // QTest::newRow("25.0 - 75.0") << (qreal)25.0 << (qreal)75.0;
233 // QTest::newRow("101.0") << (qreal)40.0 << (qreal)60.0;
234 //}
235
236 //void tst_QLogValueAxis::range_raw()
237 //{
238 // QFETCH(qreal, min);
239 // QFETCH(qreal, max);
240
241 // QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal)));
242 // QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal)));
243 // QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal)));
244
245 // m_logvaluesaxis->setRange(min, max);
246 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), min), "Min not equal");
247 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), max), "Max not equal");
248
249 // QCOMPARE(spy0.count(), 1);
250 // QCOMPARE(spy1.count(), 1);
251 // QCOMPARE(spy2.count(), 1);
252 //}
253
254 //void tst_QLogValueAxis::range_data()
255 //{
256 // range_raw_data();
257 //}
258
259 //void tst_QLogValueAxis::range()
260 //{
261 // m_chart->setAxisX(m_logvaluesaxis, m_series);
262 // m_view->show();
263 // QTest::qWaitForWindowShown(m_view);
264 // range_raw();
265 //}
266
267 //void tst_QLogValueAxis::range_animation_data()
268 //{
269 // range_data();
270 //}
271
272 //void tst_QLogValueAxis::range_animation()
273 //{
274 // m_chart->setAnimationOptions(QChart::GridAxisAnimations);
275 // range();
276 //}
277
278 //void tst_QLogValueAxis::noautoscale_data()
279 //{
280 // QTest::addColumn<qreal>("min");
281 // QTest::addColumn<qreal>("max");
282 // QTest::newRow("1.0 - 101.0") << (qreal)-1.0 << (qreal)101.0;
283 // QTest::newRow("25.0 - 75.0") << (qreal)25.0 << (qreal)75.0;
284 // QTest::newRow("101.0") << (qreal)40.0 << (qreal)60.0;
285 //}
286
287 //void tst_QLogValueAxis::noautoscale()
288 //{
289 // QFETCH(qreal, min);
290 // QFETCH(qreal, max);
291
292 // QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal)));
293 // QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal)));
294 // QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal)));
295
296 // m_logvaluesaxis->setRange(min, max);
297 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), min), "Min not equal");
298 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), max), "Max not equal");
299
300 // QCOMPARE(spy0.count(), 1);
301 // QCOMPARE(spy1.count(), 1);
302 // QCOMPARE(spy2.count(), 1);
303
304 // m_chart->setAxisX(m_logvaluesaxis, m_series);
305 // m_view->show();
306 // QTest::qWaitForWindowShown(m_view);
307 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), min), "Min not equal");
308 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), max), "Max not equal");
309 //}
310
311 //void tst_QLogValueAxis::autoscale_data()
312 //{
313
314 //}
315
316 //void tst_QLogValueAxis::autoscale()
317 //{
318 // QSignalSpy spy0(m_logvaluesaxis, SIGNAL(maxChanged(qreal)));
319 // QSignalSpy spy1(m_logvaluesaxis, SIGNAL(minChanged(qreal)));
320 // QSignalSpy spy2(m_logvaluesaxis, SIGNAL(rangeChanged(qreal,qreal)));
321
322 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), 0), "Min not equal");
323 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), 0), "Max not equal");
324 // m_chart->setAxisX(m_logvaluesaxis, m_series);
325
326 // QCOMPARE(spy0.count(), 1);
327 // QCOMPARE(spy1.count(), 1);
328 // QCOMPARE(spy2.count(), 1);
329
330 // m_view->show();
331 // QTest::qWaitForWindowShown(m_view);
332 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->min(), -100), "Min not equal");
333 // QVERIFY2(qFuzzyCompare(m_logvaluesaxis->max(), 100), "Max not equal");
334 //}
335
336 void tst_QLogValueAxis::zoomIn()
337 {
338 m_chart->setAxisX(m_logvaluesaxis, m_series);
339 m_view->show();
340 QTest::qWaitForWindowShown(m_view);
341 m_logvaluesaxis->setBase(2);
342 m_logvaluesaxis->setRange(0.5, 2);
343
344 QCOMPARE(m_logvaluesaxis->min(), (qreal)0.5);
345 QCOMPARE(m_logvaluesaxis->max(), (qreal)2.0);
346
347 m_chart->zoomOut();
348
349 QCOMPARE(m_logvaluesaxis->min(), (qreal)0.25);
350 QCOMPARE(m_logvaluesaxis->max(), (qreal)4.0);
351
352 m_chart->zoomIn();
353
354 QCOMPARE(m_logvaluesaxis->min(), (qreal)0.5);
355 QCOMPARE(m_logvaluesaxis->max(), (qreal)2.0);
356
357 m_logvaluesaxis->setRange(0.5, 1024);
358 m_chart->zoom(11.0);
359
360 QCOMPARE(m_logvaluesaxis->min(), (qreal)16.0);
361 QCOMPARE(m_logvaluesaxis->max(), (qreal)32.0);
362
363 m_logvaluesaxis->setRange(16, 64);
364 m_chart->zoom(1/3.0);
365
366 QCOMPARE(m_logvaluesaxis->min(), (qreal)4);
367 QCOMPARE(m_logvaluesaxis->max(), (qreal)256.0);
368
369 }
370
371 //void tst_QLogValueAxis::zoomOut()
372 //{
373
374 //}
375
376 QTEST_MAIN(tst_QLogValueAxis)
377 #include "tst_qlogvalueaxis.moc"
378
@@ -1,119 +1,123
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "view.h"
22 22 #include <QResizeEvent>
23 23 #include <QGraphicsScene>
24 24 #include <QChart>
25 25 #include <QLineSeries>
26 26 #include <QSplineSeries>
27 27 #include <QGraphicsTextItem>
28 28 #include "callout.h"
29 29 #include <QMouseEvent>
30 30
31 31 View::View(QWidget *parent)
32 32 : QGraphicsView(new QGraphicsScene, parent),
33 33 m_coordX(0),
34 34 m_coordY(0),
35 35 m_chart(0),
36 36 m_tooltip(0)
37 37 {
38 38 setDragMode(QGraphicsView::NoDrag);
39 39 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
40 40 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
41 41
42 42 // chart
43 43 m_chart = new QChart;
44 m_chart->setMinimumSize(800, 600);
44 m_chart->setMinimumSize(640, 480);
45 45 m_chart->setTitle("Hover the line to show callout. Click the line to make it stay");
46 46 m_chart->legend()->hide();
47 47 QLineSeries *series = new QLineSeries;
48 48 series->append(1, 3);
49 49 series->append(4, 5);
50 50 series->append(5, 4.5);
51 51 series->append(7, 1);
52 52 series->append(11, 2);
53 53 m_chart->addSeries(series);
54 54
55 55 QSplineSeries *series2 = new QSplineSeries;
56 56 series2->append(1.6, 1.4);
57 57 series2->append(2.4, 3.5);
58 58 series2->append(3.7, 2.5);
59 59 series2->append(7, 4);
60 60 series2->append(10, 2);
61 61 m_chart->addSeries(series2);
62 62
63 63 m_chart->createDefaultAxes();
64 64 m_chart->setAcceptHoverEvents(true);
65 65
66 66 setRenderHint(QPainter::Antialiasing);
67 67 scene()->addItem(m_chart);
68 68
69 69 m_coordX = new QGraphicsSimpleTextItem(m_chart);
70 70 m_coordX->setPos(m_chart->size().width()/2 - 50, m_chart->size().height());
71 71 m_coordX->setText("X: ");
72 72 m_coordY = new QGraphicsSimpleTextItem(m_chart);
73 73 m_coordY->setPos(m_chart->size().width()/2 + 50, m_chart->size().height());
74 74 m_coordY->setText("Y: ");
75 75
76 76 connect(series, SIGNAL(clicked(QPointF)), this, SLOT(keepCallout()));
77 77 connect(series, SIGNAL(hovered(QPointF, bool)), this, SLOT(tooltip(QPointF,bool)));
78 78
79 79 connect(series2, SIGNAL(clicked(QPointF)), this, SLOT(keepCallout()));
80 80 connect(series2, SIGNAL(hovered(QPointF, bool)), this, SLOT(tooltip(QPointF,bool)));
81 81
82 82 this->setMouseTracking(true);
83 83 }
84 84
85 85 void View::resizeEvent(QResizeEvent *event)
86 86 {
87 if (scene())
87 if (scene()) {
88 88 scene()->setSceneRect(QRect(QPoint(0, 0), event->size()));
89 m_chart->resize(event->size());
90 m_coordX->setPos(m_chart->size().width()/2 - 50, m_chart->size().height() - 20);
91 m_coordY->setPos(m_chart->size().width()/2 + 50, m_chart->size().height() - 20);
92 }
89 93 QGraphicsView::resizeEvent(event);
90 94 }
91 95
92 96 void View::mouseMoveEvent(QMouseEvent *event)
93 97 {
94 98 m_coordX->setText(QString("X: %1").arg(m_chart->mapToValue(event->pos()).x()));
95 99 m_coordY->setText(QString("Y: %1").arg(m_chart->mapToValue(event->pos()).y()));
96 100 QGraphicsView::mouseMoveEvent(event);
97 101 }
98 102
99 103 void View::keepCallout()
100 104 {
101 105 m_tooltip = new Callout(m_chart);
102 106 }
103 107
104 108 void View::tooltip(QPointF point, bool state)
105 109 {
106 110 if (m_tooltip == 0)
107 111 m_tooltip = new Callout(m_chart);
108 112
109 113 if (state) {
110 114 m_tooltip->setText(QString("X: %1 \nY: %2 ").arg(point.x()).arg(point.y()));
111 115 QXYSeries *series = qobject_cast<QXYSeries *>(sender());
112 116 m_tooltip->setAnchor(m_chart->mapToPosition(point, series));
113 117 m_tooltip->setPos(m_chart->mapToPosition(point, series) + QPoint(10, -50));
114 118 m_tooltip->setZValue(11);
115 119 m_tooltip->show();
116 120 } else {
117 121 m_tooltip->hide();
118 122 }
119 123 }
@@ -1,504 +1,510
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartdataset_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qchart.h"
24 24 #include "qchart_p.h"
25 25 #include "qvalueaxis.h"
26 26 #include "qbarcategoryaxis.h"
27 27 #include "qvalueaxis_p.h"
28 28 #include "qcategoryaxis.h"
29 29 #include "qabstractseries_p.h"
30 30 #include "qabstractbarseries.h"
31 31 #include "qstackedbarseries.h"
32 32 #include "qpercentbarseries.h"
33 33 #include "qpieseries.h"
34 34 #include "chartitem_p.h"
35 35 #include "xydomain_p.h"
36 36 #include "xlogydomain_p.h"
37 37 #include "logxydomain_p.h"
38 38 #include "logxlogydomain_p.h"
39 39
40 40 #ifndef QT_ON_ARM
41 41 #include "qdatetimeaxis.h"
42 42 #endif
43 43
44 44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
45 45
46 46 ChartDataSet::ChartDataSet(QChart *chart)
47 47 : QObject(chart),
48 48 m_chart(chart)
49 49 {
50 50
51 51 }
52 52
53 53 ChartDataSet::~ChartDataSet()
54 54 {
55 55 deleteAllSeries();
56 56 deleteAllAxes();
57 57 }
58 58
59 59 /*
60 60 * This method adds series to chartdataset, series ownership is taken from caller.
61 61 */
62 62 void ChartDataSet::addSeries(QAbstractSeries *series)
63 63 {
64 64 if (m_seriesList.contains(series)) {
65 65 qWarning() << QObject::tr("Can not add series. Series already on the chart.");
66 66 return;
67 67 }
68 68
69 69 series->d_ptr->initializeDomain();
70 70 m_seriesList.append(series);
71 71
72 72 series->setParent(this); // take ownership
73 73 series->d_ptr->m_chart = m_chart;
74 74
75 75 emit seriesAdded(series);
76 76 }
77 77
78 78 /*
79 79 * This method adds axis to chartdataset, axis ownership is taken from caller.
80 80 */
81 81 void ChartDataSet::addAxis(QAbstractAxis *axis,Qt::Alignment aligment)
82 82 {
83 83 if (m_axisList.contains(axis)) {
84 84 qWarning() << QObject::tr("Can not add axis. Axis already on the chart.");
85 85 return;
86 86 }
87 87
88 88 axis->d_ptr->setAlignment(aligment);
89 89
90 90 if(!axis->alignment()) {
91 91 qWarning()<< QObject::tr("No alignment specified !");
92 92 return;
93 93 };
94 94
95 95 QSharedPointer<AbstractDomain> domain(new XYDomain());
96 96 axis->d_ptr->initializeDomain(domain.data());
97 97
98 98 axis->setParent(this);
99 99 axis->d_ptr->m_chart = m_chart;
100 100 m_axisList.append(axis);
101 101
102 102 emit axisAdded(axis);
103 103 }
104 104
105 105 /*
106 106 * This method removes series form chartdataset, series ownership is passed back to caller.
107 107 */
108 108 void ChartDataSet::removeSeries(QAbstractSeries *series)
109 109 {
110 110
111 111 if (! m_seriesList.contains(series)) {
112 112 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
113 113 return;
114 114 }
115 115
116 116 QList<QAbstractAxis*> axes = series->d_ptr->m_axes;
117 117
118 118 foreach(QAbstractAxis* axis, axes) {
119 119 detachAxis(series,axis);
120 120 }
121 121
122 122 emit seriesRemoved(series);
123 123 m_seriesList.removeAll(series);
124 124
125 125 series->setParent(0);
126 126 series->d_ptr->m_chart = 0;
127 127 }
128 128
129 129 /*
130 130 * This method removes axis form chartdataset, series ownership is passed back to caller.
131 131 */
132 132 void ChartDataSet::removeAxis(QAbstractAxis *axis)
133 133 {
134 134 if (! m_axisList.contains(axis)) {
135 135 qWarning() << QObject::tr("Can not remove axis. Axis not found on the chart.");
136 136 return;
137 137 }
138 138
139 139 QList<QAbstractSeries*> series = axis->d_ptr->m_series;
140 140
141 141 foreach(QAbstractSeries* s, series) {
142 142 detachAxis(s,axis);
143 143 }
144 144
145 145 emit axisRemoved(axis);
146 146 m_axisList.removeAll(axis);
147 147
148 148 axis->setParent(0);
149 149 axis->d_ptr->m_chart = 0;
150 150 }
151 151
152 152 /*
153 153 * This method attaches axis to series, return true if success.
154 154 */
155 155 bool ChartDataSet::attachAxis(QAbstractSeries* series,QAbstractAxis *axis)
156 156 {
157 157 Q_ASSERT(series);
158 158 Q_ASSERT(axis);
159 159
160 160 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
161 161 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
162 162
163 163 if (!m_seriesList.contains(series)) {
164 164 qWarning() << QObject::tr("Can not find series on the chart.");
165 165 return false;
166 166 }
167 167
168 168 if (axis && !m_axisList.contains(axis)) {
169 169 qWarning() << QObject::tr("Can not find axis on the chart.");
170 170 return false;
171 171 }
172 172
173 173 if (attachedAxisList.contains(axis)) {
174 174 qWarning() << QObject::tr("Axis already attached to series.");
175 175 return false;
176 176 }
177 177
178 178 if (attachedSeriesList.contains(series)) {
179 179 qWarning() << QObject::tr("Axis already attached to series.");
180 180 return false;
181 181 }
182 182
183 183 AbstractDomain* domain = series->d_ptr->domain();
184 184 AbstractDomain::DomainType type = selectDomain(attachedAxisList<<axis);
185 185
186 186 if(type == AbstractDomain::UndefinedDomain) return false;
187 187
188 188 if(domain->type()!=type){
189 189 domain = createDomain(type);
190 190 }
191 191
192 192 if(!domain) return false;
193 193
194 194 if(!domain->attachAxis(axis)) return false;
195 195
196 196 if(domain!=series->d_ptr->domain()){
197 197 foreach(QAbstractAxis* axis,series->d_ptr->m_axes){
198 198 series->d_ptr->domain()->detachAxis(axis);
199 199 domain->attachAxis(axis);
200 200 }
201 201 series->d_ptr->setDomain(domain);
202 202 series->d_ptr->initializeDomain();
203 203 }
204 204
205 205 series->d_ptr->m_axes<<axis;
206 206 axis->d_ptr->m_series<<series;
207 207
208 208 series->d_ptr->initializeAxes();
209 209 axis->d_ptr->initializeDomain(domain);
210 210
211 211 return true;
212 212 }
213 213
214 214 /*
215 215 * This method detaches axis to series, return true if success.
216 216 */
217 217 bool ChartDataSet::detachAxis(QAbstractSeries* series,QAbstractAxis *axis)
218 218 {
219 219 Q_ASSERT(series);
220 220 Q_ASSERT(axis);
221 221
222 222 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
223 223 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
224 224 AbstractDomain* domain = series->d_ptr->domain();
225 225
226 226 if (!m_seriesList.contains(series)) {
227 227 qWarning() << QObject::tr("Can not find series on the chart.");
228 228 return false;
229 229 }
230 230
231 231 if (axis && !m_axisList.contains(axis)) {
232 232 qWarning() << QObject::tr("Can not find axis on the chart.");
233 233 return false;
234 234 }
235 235
236 236 if (!attachedAxisList.contains(axis)) {
237 237 qWarning() << QObject::tr("Axis not attached to series.");
238 238 return false;
239 239 }
240 240
241 241 Q_ASSERT(axis->d_ptr->m_series.contains(series));
242 242
243 243 domain->detachAxis(axis);
244 244 series->d_ptr->m_axes.removeAll(axis);
245 245 axis->d_ptr->m_series.removeAll(series);
246 246
247 247 return true;
248 248 }
249 249
250 250 void ChartDataSet::createDefaultAxes()
251 251 {
252 252 if (m_seriesList.isEmpty())
253 253 return;
254 254
255 255 QAbstractAxis::AxisTypes typeX(0);
256 256 QAbstractAxis::AxisTypes typeY(0);
257 257
258 258 // Remove possibly existing axes
259 259 deleteAllAxes();
260 260
261 261 Q_ASSERT(m_axisList.isEmpty());
262 262
263 263 // Select the required axis x and axis y types based on the types of the current series
264 264 foreach(QAbstractSeries* s, m_seriesList) {
265 265 typeX |= s->d_ptr->defaultAxisType(Qt::Horizontal);
266 266 typeY |= s->d_ptr->defaultAxisType(Qt::Vertical);
267 267 }
268 268
269 269 // Create the axes of the types selected
270 270 createAxes(typeX, Qt::Horizontal);
271 271 createAxes(typeY, Qt::Vertical);
272 272
273 273 }
274 274
275 275 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
276 276 {
277 277 QAbstractAxis *axis = 0;
278 278 //decide what axis should be created
279 279
280 280 switch (type) {
281 281 case QAbstractAxis::AxisTypeValue:
282 282 axis = new QValueAxis(this);
283 283 break;
284 284 case QAbstractAxis::AxisTypeBarCategory:
285 285 axis = new QBarCategoryAxis(this);
286 286 break;
287 287 case QAbstractAxis::AxisTypeCategory:
288 288 axis = new QCategoryAxis(this);
289 289 break;
290 290 #ifndef Q_WS_QWS
291 291 case QAbstractAxis::AxisTypeDateTime:
292 292 axis = new QDateTimeAxis(this);
293 293 break;
294 294 #endif
295 295 default:
296 296 axis = 0;
297 297 break;
298 298 }
299 299
300 300 if (axis) {
301 301 //create one axis for all
302 302
303 303 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
304 304
305 305 foreach(QAbstractSeries *s, m_seriesList) {
306 306 attachAxis(s,axis);
307 307 }
308 308
309 309 }
310 310 else if (!type.testFlag(QAbstractAxis::AxisTypeNoAxis)) {
311 311 //create separate axis
312 312 foreach(QAbstractSeries *s, m_seriesList) {
313 313 QAbstractAxis *axis = s->d_ptr->createDefaultAxis(orientation);
314 314 if(axis) {
315 315 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
316 316 attachAxis(s,axis);
317 317 }
318 318 }
319 319 }
320 320 }
321 321
322 322 void ChartDataSet::deleteAllSeries()
323 323 {
324 324 foreach (QAbstractSeries *s , m_seriesList){
325 325 removeSeries(s);
326 326 s->deleteLater();
327 327 }
328 328 Q_ASSERT(m_seriesList.count() == 0);
329 329 }
330 330
331 331 void ChartDataSet::deleteAllAxes()
332 332 {
333 333 foreach (QAbstractAxis *a , m_axisList){
334 334 removeAxis(a);
335 335 a->deleteLater();
336 336 }
337 337 Q_ASSERT(m_axisList.count() == 0);
338 338 }
339 339
340 340 void ChartDataSet::zoomInDomain(const QRectF &rect)
341 341 {
342 342 QList<AbstractDomain*> domains;
343 343 foreach(QAbstractSeries *s, m_seriesList) {
344 344 AbstractDomain* domain = s->d_ptr->domain();
345 345 s->d_ptr->m_domain->blockRangeSignals(true);
346 346 domains<<domain;
347 347 }
348 348
349 349 foreach(AbstractDomain *domain, domains)
350 350 domain->zoomIn(rect);
351 351
352 352 foreach(AbstractDomain *domain, domains)
353 353 domain->blockRangeSignals(false);
354 354 }
355 355
356 356 void ChartDataSet::zoomOutDomain(const QRectF &rect)
357 357 {
358 358 QList<AbstractDomain*> domains;
359 359 foreach(QAbstractSeries *s, m_seriesList) {
360 360 AbstractDomain* domain = s->d_ptr->domain();
361 361 s->d_ptr->m_domain->blockRangeSignals(true);
362 362 domains<<domain;
363 363 }
364 364
365 365 foreach(AbstractDomain *domain, domains)
366 366 domain->zoomOut(rect);
367 367
368 368 foreach(AbstractDomain *domain, domains)
369 369 domain->blockRangeSignals(false);
370 370 }
371 371
372 372 void ChartDataSet::scrollDomain(qreal dx, qreal dy)
373 373 {
374 374 QList<AbstractDomain*> domains;
375 375 foreach(QAbstractSeries *s, m_seriesList) {
376 376 AbstractDomain* domain = s->d_ptr->domain();
377 377 s->d_ptr->m_domain->blockRangeSignals(true);
378 378 domains<<domain;
379 379 }
380 380
381 381 foreach(AbstractDomain *domain, domains)
382 382 domain->move(dx, dy);
383 383
384 384 foreach(AbstractDomain *domain, domains)
385 385 domain->blockRangeSignals(false);
386 386 }
387 387
388 388 QPointF ChartDataSet::mapToValue(const QPointF &position, QAbstractSeries *series)
389 389 {
390 390 QPointF point;
391 391 if (series == 0 && !m_seriesList.isEmpty())
392 392 series = m_seriesList.first();
393 393
394 if (series && series->type() == QAbstractSeries::SeriesTypePie)
395 return point;
396
394 397 if (series && m_seriesList.contains(series))
395 point = series->d_ptr->m_domain->calculateDomainPoint(position);
398 point = series->d_ptr->m_domain->calculateDomainPoint(position - m_chart->plotArea().topLeft());
396 399 return point;
397 400 }
398 401
399 402 QPointF ChartDataSet::mapToPosition(const QPointF &value, QAbstractSeries *series)
400 403 {
401 404 QPointF point = m_chart->plotArea().topLeft();
402 405 if (series == 0 && !m_seriesList.isEmpty())
403 406 series = m_seriesList.first();
404 407
408 if (series && series->type() == QAbstractSeries::SeriesTypePie)
409 return QPoint(0, 0);
410
405 411 if (series && m_seriesList.contains(series))
406 412 point += series->d_ptr->m_domain->calculateGeometryPoint(value);
407 413 return point;
408 414 }
409 415
410 416 QList<QAbstractAxis*> ChartDataSet::axes() const
411 417 {
412 418 return m_axisList;
413 419 }
414 420
415 421 QList<QAbstractSeries *> ChartDataSet::series() const
416 422 {
417 423 return m_seriesList;
418 424 }
419 425
420 426 AbstractDomain::DomainType ChartDataSet::selectDomain(QList<QAbstractAxis*> axes)
421 427 {
422 428 enum Type {
423 429 Undefined = 0,
424 430 LogType = 0x1,
425 431 ValueType = 0x2
426 432 };
427 433
428 434 int horizontal(Undefined);
429 435 int vertical(Undefined);
430 436
431 437 foreach(QAbstractAxis* axis, axes)
432 438 {
433 439 switch(axis->type()) {
434 440 case QAbstractAxis::AxisTypeLogValue:
435 441
436 442 if(axis->orientation()==Qt::Horizontal) {
437 443 horizontal|=LogType;
438 444 }
439 445 if(axis->orientation()==Qt::Vertical) {
440 446 vertical|=LogType;
441 447 }
442 448
443 449 break;
444 450 case QAbstractAxis::AxisTypeValue:
445 451 case QAbstractAxis::AxisTypeBarCategory:
446 452 case QAbstractAxis::AxisTypeCategory:
447 453 case QAbstractAxis::AxisTypeDateTime:
448 454 if(axis->orientation()==Qt::Horizontal) {
449 455 horizontal|=ValueType;
450 456 }
451 457 if(axis->orientation()==Qt::Vertical) {
452 458 vertical|=ValueType;
453 459 }
454 460 break;
455 461 default:
456 462 qWarning()<<"Undefined type";
457 463 break;
458 464 }
459 465 }
460 466
461 467 if(vertical==Undefined) vertical=ValueType;
462 468 if(horizontal==Undefined) horizontal=ValueType;
463 469
464 470 if(vertical==ValueType && horizontal== ValueType) {
465 471 return AbstractDomain::XYDomain;
466 472 }
467 473
468 474 if(vertical==LogType && horizontal== ValueType) {
469 475 return AbstractDomain::XLogYDomain;
470 476 }
471 477
472 478 if(vertical==ValueType && horizontal== LogType) {
473 479 return AbstractDomain::LogXYDomain;
474 480 }
475 481
476 482 if(vertical==LogType && horizontal== LogType) {
477 483 return AbstractDomain::LogXLogYDomain;
478 484 }
479 485
480 486 return AbstractDomain::UndefinedDomain;
481 487 }
482 488
483 489
484 490 //refactor create factory
485 491 AbstractDomain* ChartDataSet::createDomain(AbstractDomain::DomainType type)
486 492 {
487 493 switch(type)
488 494 {
489 495 case AbstractDomain::LogXLogYDomain:
490 496 return new LogXLogYDomain();
491 497 case AbstractDomain::XYDomain:
492 498 return new XYDomain();
493 499 case AbstractDomain::XLogYDomain:
494 500 return new XLogYDomain();
495 501 case AbstractDomain::LogXYDomain:
496 502 return new LogXYDomain();
497 503 default:
498 504 return 0;
499 505 }
500 506 }
501 507
502 508 #include "moc_chartdataset_p.cpp"
503 509
504 510 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,231 +1,246
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "logxlogydomain_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include "qlogvalueaxis.h"
24 24 #include <qmath.h>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 LogXLogYDomain::LogXLogYDomain(QObject *parent)
29 29 : AbstractDomain(parent),
30 m_logMinX(0),
31 m_logMaxX(1),
30 m_logLeftX(0),
31 m_logRightX(1),
32 32 m_logBaseX(10),
33 m_logMinY(0),
34 m_logMaxY(1),
33 m_logLeftY(0),
34 m_logRightY(1),
35 35 m_logBaseY(10)
36 36 {
37 37 }
38 38
39 39 LogXLogYDomain::~LogXLogYDomain()
40 40 {
41 41 }
42 42
43 43 void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
44 44 {
45 45 bool axisXChanged = false;
46 46 bool axisYChanged = false;
47 47
48 48 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
49 49 m_minX = minX;
50 50 m_maxX = maxX;
51 51 axisXChanged = true;
52 m_logMinX = log10(m_minX) / log10(m_logBaseX);
53 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
52 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
53 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
54 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
55 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
54 56 if(!m_signalsBlocked)
55 57 emit rangeHorizontalChanged(m_minX, m_maxX);
56 58 }
57 59
58 60 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
59 61 m_minY = minY;
60 62 m_maxY = maxY;
61 63 axisYChanged = true;
62 m_logMinY = log10(m_minY) / log10(m_logBaseY);
63 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
64 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
65 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
66 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
67 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
64 68 if(!m_signalsBlocked)
65 69 emit rangeVerticalChanged(m_minY, m_maxY);
66 70 }
67 71
68 72 if (axisXChanged || axisYChanged)
69 73 emit updated();
70 74 }
71 75
72 76 void LogXLogYDomain::zoomIn(const QRectF &rect)
73 77 {
74 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
75 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
76 qreal minX = qPow(m_logBaseX, newLogMinX);
77 qreal maxX = qPow(m_logBaseX, newLogMaxX);
78 qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
79 qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
80 qreal leftX = qPow(m_logBaseX, logLeftX);
81 qreal rightX = qPow(m_logBaseX, logRightX);
82 qreal minX = leftX < rightX ? leftX : rightX;
83 qreal maxX = leftX > rightX ? leftX : rightX;
78 84
79 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
80 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
81 qreal minY = qPow(m_logBaseY, newLogMinY);
82 qreal maxY = qPow(m_logBaseY, newLogMaxY);
85 qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height();
86 qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height();
87 qreal leftY = qPow(m_logBaseY, logLeftY);
88 qreal rightY = qPow(m_logBaseY, logRightY);
89 qreal minY = leftY < rightY ? leftY : rightY;
90 qreal maxY = leftY > rightY ? leftY : rightY;
83 91
84 92 setRange(minX, maxX, minY, maxY);
85 93 }
86 94
87 95 void LogXLogYDomain::zoomOut(const QRectF &rect)
88 96 {
89 qreal ratioX = m_size.width()/rect.width();
90 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
91 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
92 qreal minX = qPow(m_logBaseX, newLogMinX);
93 qreal maxX = qPow(m_logBaseX, newLogMaxX);
97 const qreal factorX = m_size.width() / rect.width();
98 const qreal factorY = m_size.height() / rect.height();
94 99
95 qreal ratioY = m_size.height()/rect.height();
96 qreal newLogMinY = m_logMinY - (m_logMaxY - m_logMinY) / ratioY;
97 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
98 qreal minY = qPow(m_logBaseY, newLogMinY);
99 qreal maxY = qPow(m_logBaseY, newLogMaxY);
100 qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX);
101 qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX);
102 qreal leftX = qPow(m_logBaseX, logLeftX);
103 qreal rightX = qPow(m_logBaseX, logRIghtX);
104 qreal minX = leftX < rightX ? leftX : rightX;
105 qreal maxX = leftX > rightX ? leftX : rightX;
106
107 qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY);
108 qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY);
109 qreal leftY = qPow(m_logBaseY, newLogMinY);
110 qreal rightY = qPow(m_logBaseY, newLogMaxY);
111 qreal minY = leftY < rightY ? leftY : rightY;
112 qreal maxY = leftY > rightY ? leftY : rightY;
100 113
101 114 setRange(minX, maxX, minY, maxY);
102 115 }
103 116
104 117 void LogXLogYDomain::move(qreal dx, qreal dy)
105 118 {
106 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
107 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
108 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
119 qreal stepX = dx * qAbs(m_logRightX - m_logLeftX) / m_size.width();
120 qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX);
121 qreal rightX = qPow(m_logBaseX, m_logRightX + stepX);
122 qreal minX = leftX < rightX ? leftX : rightX;
123 qreal maxX = leftX > rightX ? leftX : rightX;
109 124
110 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
111 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
112 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
125 qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height();
126 qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY);
127 qreal rightY = qPow(m_logBaseY, m_logRightY + stepY);
128 qreal minY = leftY < rightY ? leftY : rightY;
129 qreal maxY = leftY > rightY ? leftY : rightY;
113 130
114 131 setRange(minX, maxX, minY, maxY);
115 132 }
116 133
117 134 QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point) const
118 135 {
119 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
120 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
121 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
122 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
123 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
124 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
136 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
137 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
138 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
139 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
125 140 return QPointF(x, y);
126 141 }
127 142
128 143 QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
129 144 {
130 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
131 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
132 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
133 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
145 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
146 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
134 147
135 148 QVector<QPointF> result;
136 149 result.resize(vector.count());
137 150
138 151 for (int i = 0; i < vector.count(); ++i) {
139 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
140 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
152 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
153 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
141 154 result[i].setX(x);
142 155 result[i].setY(y);
143 156 }
144 157 return result;
145 158 }
146 159
147 160 QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const
148 161 {
149 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
150 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
151 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
152 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
153 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
154 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
162 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
163 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
164 qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX);
165 qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY);
155 166 return QPointF(x, y);
156 167 }
157 168
158 169 bool LogXLogYDomain::attachAxis(QAbstractAxis* axis)
159 170 {
160 171 AbstractDomain::attachAxis(axis);
161 172 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
162 173
163 174 if(logAxis && logAxis->orientation()==Qt::Vertical) {
164 175 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
165 176 handleVerticalAxisBaseChanged(logAxis->base());
166 177 }
167 178
168 179 if(logAxis && logAxis->orientation()==Qt::Horizontal) {
169 180 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
170 181 handleHorizontalAxisBaseChanged(logAxis->base());
171 182 }
172 183
173 184 return true;
174 185 }
175 186
176 187 bool LogXLogYDomain::detachAxis(QAbstractAxis* axis)
177 188 {
178 189 AbstractDomain::detachAxis(axis);
179 190 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
180 191
181 192 if(logAxis && logAxis->orientation()==Qt::Vertical)
182 193 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
183 194
184 195 if(logAxis && logAxis->orientation()==Qt::Horizontal)
185 196 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
186 197
187 198 return true;
188 199 }
189 200
190 201 void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
191 202 {
192 203 m_logBaseY = baseY;
193 m_logMinY = log10(m_minY) / log10(m_logBaseY);
194 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
204 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
205 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
206 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
207 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
195 208 emit updated();
196 209 }
197 210
198 211 void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
199 212 {
200 213 m_logBaseX = baseX;
201 m_logMinX = log10(m_minX) / log10(m_logBaseX);
202 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
214 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
215 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
216 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
217 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
203 218 emit updated();
204 219 }
205 220
206 221 // operators
207 222
208 223 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
209 224 {
210 225 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
211 226 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
212 227 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
213 228 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
214 229 }
215 230
216 231
217 232 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
218 233 {
219 234 return !(domain1 == domain2);
220 235 }
221 236
222 237
223 238 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain)
224 239 {
225 240 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
226 241 return dbg.maybeSpace();
227 242 }
228 243
229 244 #include "moc_logxlogydomain_p.cpp"
230 245
231 246 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,79 +1,79
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef LOGXLOGYDOMAIN_H
31 31 #define LOGXLOGYDOMAIN_H
32 32 #include "abstractdomain_p.h"
33 33 #include <QRectF>
34 34 #include <QSizeF>
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT LogXLogYDomain: public AbstractDomain
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 explicit LogXLogYDomain(QObject *object = 0);
43 43 virtual ~LogXLogYDomain();
44 44
45 45 DomainType type(){ return AbstractDomain::LogXLogYDomain;}
46 46
47 47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
48 48
49 49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2);
50 50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2);
51 51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain);
52 52
53 53 void zoomIn(const QRectF &rect);
54 54 void zoomOut(const QRectF &rect);
55 55 void move(qreal dx, qreal dy);
56 56
57 57 QPointF calculateGeometryPoint(const QPointF &point) const;
58 58 QPointF calculateDomainPoint(const QPointF &point) const;
59 59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
60 60
61 61 bool attachAxis(QAbstractAxis* axis);
62 62 bool detachAxis(QAbstractAxis* axis);
63 63
64 64 public Q_SLOTS:
65 65 void handleVerticalAxisBaseChanged(qreal baseY);
66 66 void handleHorizontalAxisBaseChanged(qreal baseX);
67 67
68 68 private:
69 qreal m_logMinX;
70 qreal m_logMaxX;
69 qreal m_logLeftX;
70 qreal m_logRightX;
71 71 qreal m_logBaseX;
72 qreal m_logMinY;
73 qreal m_logMaxY;
72 qreal m_logLeftY;
73 qreal m_logRightY;
74 74 qreal m_logBaseY;
75 75 };
76 76
77 77 QTCOMMERCIALCHART_END_NAMESPACE
78 78
79 79 #endif // LOGXLOGYDOMAIN_H
@@ -1,215 +1,223
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "logxydomain_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include "qlogvalueaxis.h"
24 24 #include <qmath.h>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 LogXYDomain::LogXYDomain(QObject *parent)
29 29 : AbstractDomain(parent),
30 m_logMinX(0),
31 m_logMaxX(1),
30 m_logLeftX(0),
31 m_logRightX(1),
32 32 m_logBaseX(10)
33 33 {
34 34 }
35 35
36 36 LogXYDomain::~LogXYDomain()
37 37 {
38 38 }
39 39
40 40 void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
41 41 {
42 42 bool axisXChanged = false;
43 43 bool axisYChanged = false;
44 44
45 45 if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) {
46 46 m_minX = minX;
47 47 m_maxX = maxX;
48 48 axisXChanged = true;
49 m_logMinX = log10(m_minX) / log10(m_logBaseX);
50 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
49 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
50 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
51 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
52 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
51 53 if(!m_signalsBlocked)
52 54 emit rangeHorizontalChanged(m_minX, m_maxX);
53 55 }
54 56
55 57 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
56 58 m_minY = minY;
57 59 m_maxY = maxY;
58 60 axisYChanged = true;
59 61 if(!m_signalsBlocked)
60 62 emit rangeVerticalChanged(m_minY, m_maxY);
61 63 }
62 64
63 65 if (axisXChanged || axisYChanged)
64 66 emit updated();
65 67 }
66 68
67 69 void LogXYDomain::zoomIn(const QRectF &rect)
68 70 {
69 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
70 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
71 qreal minX = qPow(m_logBaseX, newLogMinX);
72 qreal maxX = qPow(m_logBaseX, newLogMaxX);
71 qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
72 qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
73 qreal leftX = qPow(m_logBaseX, logLeftX);
74 qreal rightX = qPow(m_logBaseX, logRightX);
75 qreal minX = leftX < rightX ? leftX : rightX;
76 qreal maxX = leftX > rightX ? leftX : rightX;
73 77
74 78 qreal dy = spanY() / m_size.height();
75 79 qreal minY = m_minY;
76 80 qreal maxY = m_maxY;
77 81
78 82 minY = maxY - dy * rect.bottom();
79 83 maxY = maxY - dy * rect.top();
80 84
81 85 setRange(minX, maxX, minY, maxY);
82 86 }
83 87
84 88 void LogXYDomain::zoomOut(const QRectF &rect)
85 89 {
86 qreal ratioX = m_size.width()/rect.width();
87 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
88 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
89 qreal minX = qPow(m_logBaseX, newLogMinX);
90 qreal maxX = qPow(m_logBaseX, newLogMaxX);
90 const qreal factorX = m_size.width() / rect.width();
91
92 qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX);
93 qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX);
94 qreal leftX = qPow(m_logBaseX, logLeftX);
95 qreal rightX = qPow(m_logBaseX, logRIghtX);
96 qreal minX = leftX < rightX ? leftX : rightX;
97 qreal maxX = leftX > rightX ? leftX : rightX;
91 98
92 99 qreal dy = spanY() / rect.height();
93 100 qreal minY = m_minY;
94 101 qreal maxY = m_maxY;
95 102
96 103 maxY = minY + dy * rect.bottom();
97 104 minY = maxY - dy * m_size.height();
98 105
99 106 setRange(minX, maxX, minY, maxY);
100 107 }
101 108
102 109 void LogXYDomain::move(qreal dx, qreal dy)
103 110 {
104 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
105 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
106 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
111 qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width();
112 qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX);
113 qreal rightX = qPow(m_logBaseX, m_logRightX + stepX);
114 qreal minX = leftX < rightX ? leftX : rightX;
115 qreal maxX = leftX > rightX ? leftX : rightX;
107 116
108 117 qreal y = spanY() / m_size.height();
109 118 qreal minY = m_minY;
110 119 qreal maxY = m_maxY;
111 120
112 121 if (dy != 0) {
113 122 minY = minY + y * dy;
114 123 maxY = maxY + y * dy;
115 124 }
116 125 setRange(minX, maxX, minY, maxY);
117 126 }
118 127
119 128 QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point) const
120 129 {
121 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
122 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
130 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
123 131 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
124 132
125 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
133 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
126 134 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
127 135 return QPointF(x, y);
128 136 }
129 137
130 138 QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
131 139 {
132 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
133 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
140 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
134 141 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
135 142
136 143 QVector<QPointF> result;
137 144 result.resize(vector.count());
138 145
139 146 for (int i = 0; i < vector.count(); ++i) {
140 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
147 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
141 148 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
142 149 result[i].setX(x);
143 150 result[i].setY(y);
144 151 }
145 152 return result;
146 153 }
147 154
148 155 QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const
149 156 {
150 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
151 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
157 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
152 158 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
153 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
159 qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX);
154 160 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
155 161 return QPointF(x, y);
156 162 }
157 163
158 164 bool LogXYDomain::attachAxis(QAbstractAxis* axis)
159 165 {
160 166 AbstractDomain::attachAxis(axis);
161 167 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
162 168
163 169 if(logAxis && logAxis->orientation()==Qt::Horizontal) {
164 170 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
165 171 handleHorizontalAxisBaseChanged(logAxis->base());
166 172 }
167 173
168 174 return true;
169 175 }
170 176
171 177 bool LogXYDomain::detachAxis(QAbstractAxis* axis)
172 178 {
173 179 AbstractDomain::detachAxis(axis);
174 180 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
175 181
176 182 if(logAxis && logAxis->orientation()==Qt::Horizontal)
177 183 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
178 184
179 185 return true;
180 186 }
181 187
182 188 void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
183 189 {
184 190 m_logBaseX = baseX;
185 m_logMinX = log10(m_minX) / log10(m_logBaseX);
186 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
191 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
192 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
193 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
194 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
187 195 emit updated();
188 196 }
189 197
190 198 // operators
191 199
192 200 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2)
193 201 {
194 202 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
195 203 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
196 204 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
197 205 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
198 206 }
199 207
200 208
201 209 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2)
202 210 {
203 211 return !(domain1 == domain2);
204 212 }
205 213
206 214
207 215 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain)
208 216 {
209 217 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
210 218 return dbg.maybeSpace();
211 219 }
212 220
213 221 #include "moc_logxydomain_p.cpp"
214 222
215 223 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,75 +1,75
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef LOGXYDOMAIN_H
31 31 #define LOGXYDOMAIN_H
32 32 #include "abstractdomain_p.h"
33 33 #include <QRectF>
34 34 #include <QSizeF>
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT LogXYDomain: public AbstractDomain
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 explicit LogXYDomain(QObject *object = 0);
43 43 virtual ~LogXYDomain();
44 44
45 45 DomainType type(){ return AbstractDomain::LogXYDomain;}
46 46
47 47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
48 48
49 49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2);
50 50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2);
51 51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain);
52 52
53 53 void zoomIn(const QRectF &rect);
54 54 void zoomOut(const QRectF &rect);
55 55 void move(qreal dx, qreal dy);
56 56
57 57 QPointF calculateGeometryPoint(const QPointF &point) const;
58 58 QPointF calculateDomainPoint(const QPointF &point) const;
59 59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
60 60
61 61 bool attachAxis(QAbstractAxis* axis);
62 62 bool detachAxis(QAbstractAxis* axis);
63 63
64 64 public Q_SLOTS:
65 65 void handleHorizontalAxisBaseChanged(qreal baseX);
66 66
67 67 private:
68 qreal m_logMinX;
69 qreal m_logMaxX;
68 qreal m_logLeftX;
69 qreal m_logRightX;
70 70 qreal m_logBaseX;
71 71 };
72 72
73 73 QTCOMMERCIALCHART_END_NAMESPACE
74 74
75 75 #endif // LOGXYDOMAIN_H
@@ -1,213 +1,220
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "xlogydomain_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include "qlogvalueaxis.h"
24 24 #include <qmath.h>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 XLogYDomain::XLogYDomain(QObject *parent)
29 29 : AbstractDomain(parent),
30 m_logMinY(0),
31 m_logMaxY(1),
30 m_logLeftY(0),
31 m_logRightY(1),
32 32 m_logBaseY(10)
33 33 {
34 34 }
35 35
36 36 XLogYDomain::~XLogYDomain()
37 37 {
38 38 }
39 39
40 40 void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
41 41 {
42 42 bool axisXChanged = false;
43 43 bool axisYChanged = false;
44 44
45 45 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
46 46 m_minX = minX;
47 47 m_maxX = maxX;
48 48 axisXChanged = true;
49 49 if(!m_signalsBlocked)
50 50 emit rangeHorizontalChanged(m_minX, m_maxX);
51 51 }
52 52
53 53 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
54 54 m_minY = minY;
55 55 m_maxY = maxY;
56 56 axisYChanged = true;
57 m_logMinY = log10(m_minY) / log10(m_logBaseY);
58 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
57 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
58 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
59 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
60 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
59 61 if(!m_signalsBlocked)
60 62 emit rangeVerticalChanged(m_minY, m_maxY);
61 63 }
62 64
63 65 if (axisXChanged || axisYChanged)
64 66 emit updated();
65 67 }
66 68
67 69 void XLogYDomain::zoomIn(const QRectF &rect)
68 70 {
69 71 qreal dx = spanX() / m_size.width();
70 72 qreal maxX = m_maxX;
71 73 qreal minX = m_minX;
72 74
73 75 maxX = minX + dx * rect.right();
74 76 minX = minX + dx * rect.left();
75 77
76 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
77 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
78 qreal minY = qPow(m_logBaseY, newLogMinY);
79 qreal maxY = qPow(m_logBaseY, newLogMaxY);
78 qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height();
79 qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height();
80 qreal leftY = qPow(m_logBaseY, logLeftY);
81 qreal rightY = qPow(m_logBaseY, logRightY);
82 qreal minY = leftY < rightY ? leftY : rightY;
83 qreal maxY = leftY > rightY ? leftY : rightY;
80 84
81 85 setRange(minX, maxX, minY, maxY);
82 86 }
83 87
84 88 void XLogYDomain::zoomOut(const QRectF &rect)
85 89 {
86 90 qreal dx = spanX() / rect.width();
87 91 qreal maxX = m_maxX;
88 92 qreal minX = m_minX;
89 93
90 94 minX = maxX - dx * rect.right();
91 95 maxX = minX + dx * m_size.width();
92 96
93 qreal ratioY = m_size.height()/rect.height();
94 qreal newLogMinY = m_logMinY - (m_logMaxY - m_logMinY) / ratioY;
95 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
96 qreal minY = qPow(m_logBaseY, newLogMinY);
97 qreal maxY = qPow(m_logBaseY, newLogMaxY);
97 const qreal factorY = m_size.height() / rect.height();
98 qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY);
99 qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY);
100 qreal leftY = qPow(m_logBaseY, newLogMinY);
101 qreal rightY = qPow(m_logBaseY, newLogMaxY);
102 qreal minY = leftY < rightY ? leftY : rightY;
103 qreal maxY = leftY > rightY ? leftY : rightY;
98 104
99 105 setRange(minX, maxX, minY, maxY);
100 106 }
101 107
102 108 void XLogYDomain::move(qreal dx, qreal dy)
103 109 {
104 110 qreal x = spanX() / m_size.width();
105 111 qreal maxX = m_maxX;
106 112 qreal minX = m_minX;
107 113
108 114 if (dx != 0) {
109 115 minX = minX + x * dx;
110 116 maxX = maxX + x * dx;
111 117 }
112 118
113 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
114 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
115 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
119 qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height();
120 qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY);
121 qreal rightY = qPow(m_logBaseY, m_logRightY + stepY);
122 qreal minY = leftY < rightY ? leftY : rightY;
123 qreal maxY = leftY > rightY ? leftY : rightY;
116 124
117 125 setRange(minX, maxX, minY, maxY);
118 126 }
119 127
120 128 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const
121 129 {
122 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
123 130 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
124 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
131 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
125 132
126 133 qreal x = (point.x() - m_minX) * deltaX;
127 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
134 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
128 135 return QPointF(x, y);
129 136 }
130 137
131 138 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
132 139 {
133 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
134 140 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
135 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
141 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
136 142
137 143 QVector<QPointF> result;
138 144 result.resize(vector.count());
139 145
140 146 for (int i = 0; i < vector.count(); ++i) {
141 147 qreal x = (vector[i].x() - m_minX) * deltaX;
142 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
148 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
143 149 result[i].setX(x);
144 150 result[i].setY(y);
145 151 }
146 152 return result;
147 153 }
148 154
149 155 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
150 156 {
151 157 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
152 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
153 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
158 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
154 159 qreal x = point.x() / deltaX + m_minX;
155 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
160 qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY);
156 161 return QPointF(x, y);
157 162 }
158 163
159 164 bool XLogYDomain::attachAxis(QAbstractAxis* axis)
160 165 {
161 166 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
162 167
163 168 if(logAxis && logAxis->orientation()==Qt::Vertical){
164 169 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
165 170 handleVerticalAxisBaseChanged(logAxis->base());
166 171 }
167 172 return AbstractDomain::attachAxis(axis);
168 173 }
169 174
170 175 bool XLogYDomain::detachAxis(QAbstractAxis* axis)
171 176 {
172 177 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
173 178
174 179 if(logAxis && logAxis->orientation()==Qt::Vertical)
175 180 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
176 181
177 182 return AbstractDomain::detachAxis(axis);
178 183 }
179 184
180 185 void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
181 186 {
182 187 m_logBaseY = baseY;
183 m_logMinY = log10(m_minY) / log10(m_logBaseY);
184 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
188 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
189 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
190 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
191 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
185 192 emit updated();
186 193 }
187 194
188 195 // operators
189 196
190 197 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
191 198 {
192 199 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
193 200 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
194 201 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
195 202 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
196 203 }
197 204
198 205
199 206 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
200 207 {
201 208 return !(domain1 == domain2);
202 209 }
203 210
204 211
205 212 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
206 213 {
207 214 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
208 215 return dbg.maybeSpace();
209 216 }
210 217
211 218 #include "moc_xlogydomain_p.cpp"
212 219
213 220 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,75 +1,75
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef XLOGYDOMAIN_H
31 31 #define XLOGYDOMAIN_H
32 32 #include "abstractdomain_p.h"
33 33 #include <QRectF>
34 34 #include <QSizeF>
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT XLogYDomain: public AbstractDomain
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 explicit XLogYDomain(QObject *object = 0);
43 43 virtual ~XLogYDomain();
44 44
45 45 DomainType type(){ return AbstractDomain::XLogYDomain;};
46 46
47 47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
48 48
49 49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2);
50 50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2);
51 51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain);
52 52
53 53 void zoomIn(const QRectF &rect);
54 54 void zoomOut(const QRectF &rect);
55 55 void move(qreal dx, qreal dy);
56 56
57 57 QPointF calculateGeometryPoint(const QPointF &point) const;
58 58 QPointF calculateDomainPoint(const QPointF &point) const;
59 59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
60 60
61 61 bool attachAxis(QAbstractAxis* axis);
62 62 bool detachAxis(QAbstractAxis* axis);
63 63
64 64 public Q_SLOTS:
65 65 void handleVerticalAxisBaseChanged(qreal baseY);
66 66
67 67 private:
68 qreal m_logMinY;
69 qreal m_logMaxY;
68 qreal m_logLeftY;
69 qreal m_logRightY;
70 70 qreal m_logBaseY;
71 71 };
72 72
73 73 QTCOMMERCIALCHART_END_NAMESPACE
74 74
75 75 #endif // XLOGYDOMAIN_H
@@ -1,53 +1,54
1 1 !include( ../tests.pri ) {
2 2 error( "Couldn't find the tests.pri file!" )
3 3 }
4 4
5 5 TEMPLATE = subdirs
6 6 SUBDIRS += \
7 7 qchartview \
8 8 qchart \
9 9 qlineseries \
10 10 qbarset \
11 11 qbarseries \
12 12 qstackedbarseries \
13 13 qpercentbarseries \
14 14 qpieslice qpieseries \
15 15 qpiemodelmapper \
16 16 qsplineseries \
17 17 qscatterseries \
18 18 qxymodelmapper \
19 19 qbarmodelmapper \
20 20 qhorizontalbarseries \
21 21 qhorizontalstackedbarseries \
22 22 qhorizontalpercentbarseries \
23 23 qvalueaxis \
24 qlogvalueaxis \
24 25 qcategoryaxis \
25 26 qbarcategoryaxis \
26 27 domain \
27 28 chartdataset \
28 29 qlegend
29 30
30 31 contains(QT_VERSION, ^4\\.[0-7]\\.[0-3]\\s*$) | contains(QT_VERSION, ^4\\.[0-6]\\..*) {
31 32 warning("QtCommercial.Charts QML API requires at least Qt 4.7.4. You are using $${QT_VERSION} so the QML API is disabled.")
32 33 } else {
33 34 SUBDIRS += qml
34 35
35 36 # Check if QtQuickTest is installed
36 37 exists($$(QTDIR)/lib/QtQuickTest.lib){
37 38 SUBDIRS += qml-qtquicktest
38 39 } else {
39 40 exists($$(QTDIR)/lib/libQtQuickTest.dylib){
40 41 SUBDIRS += qml-qtquicktest
41 42 } else {
42 43 warning("QtQuickTest not found; cannot build QML api unit tests")
43 44 }
44 45 }
45 46 }
46 47
47 48 !linux-arm*: {
48 49 SUBDIRS += \
49 50 qdatetimeaxis
50 51 }
51 52
52 53
53 54
General Comments 0
You need to be logged in to leave comments. Login now