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