##// END OF EJS Templates
Log domains update when axis base changes. LogAxis fix for labelFormat
Marek Rosa -
r2293:f2379b79baf8
parent child
Show More
@@ -1,497 +1,508
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 "chartaxis_p.h"
21 #include "chartaxis_p.h"
22 #include "qabstractaxis.h"
22 #include "qabstractaxis.h"
23 #include "qabstractaxis_p.h"
23 #include "qabstractaxis_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "chartlayout_p.h"
25 #include "chartlayout_p.h"
26 #include "abstractdomain_p.h"
26 #include "abstractdomain_p.h"
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QDateTime>
28 #include <QDateTime>
29 #include <QValueAxis>
29 #include <QValueAxis>
30 #include <QLogValueAxis>
30 #include <QLogValueAxis>
31 #include <QGraphicsLayout>
31 #include <QGraphicsLayout>
32 #include <QFontMetrics>
32 #include <QFontMetrics>
33
33
34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35
35
36 ChartAxis::ChartAxis(QAbstractAxis *axis, QGraphicsItem* item , bool intervalAxis)
36 ChartAxis::ChartAxis(QAbstractAxis *axis, QGraphicsItem* item , bool intervalAxis)
37 : ChartElement(item),
37 : ChartElement(item),
38 m_axis(axis),
38 m_axis(axis),
39 m_labelsAngle(0),
39 m_labelsAngle(0),
40 m_grid(new QGraphicsItemGroup(item)),
40 m_grid(new QGraphicsItemGroup(item)),
41 m_arrow(new QGraphicsItemGroup(item)),
41 m_arrow(new QGraphicsItemGroup(item)),
42 m_shades(new QGraphicsItemGroup(item)),
42 m_shades(new QGraphicsItemGroup(item)),
43 m_labels(new QGraphicsItemGroup(item)),
43 m_labels(new QGraphicsItemGroup(item)),
44 m_title(new QGraphicsSimpleTextItem(item)),
44 m_title(new QGraphicsSimpleTextItem(item)),
45 m_animation(0),
45 m_animation(0),
46 m_labelPadding(5),
46 m_labelPadding(5),
47 m_intervalAxis(intervalAxis)
47 m_intervalAxis(intervalAxis)
48 {
48 {
49 Q_ASSERT(item);
49 Q_ASSERT(item);
50 //initial initialization
50 //initial initialization
51 m_arrow->setHandlesChildEvents(false);
51 m_arrow->setHandlesChildEvents(false);
52 m_arrow->setZValue(ChartPresenter::AxisZValue);
52 m_arrow->setZValue(ChartPresenter::AxisZValue);
53 m_arrow->setVisible(m_axis->isLineVisible());
53 m_arrow->setVisible(m_axis->isLineVisible());
54 m_labels->setZValue(ChartPresenter::AxisZValue);
54 m_labels->setZValue(ChartPresenter::AxisZValue);
55 m_labels->setVisible(m_axis->labelsVisible());
55 m_labels->setVisible(m_axis->labelsVisible());
56 m_shades->setZValue(ChartPresenter::ShadesZValue);
56 m_shades->setZValue(ChartPresenter::ShadesZValue);
57 m_shades->setVisible(m_axis->shadesVisible());
57 m_shades->setVisible(m_axis->shadesVisible());
58 m_grid->setZValue(ChartPresenter::GridZValue);
58 m_grid->setZValue(ChartPresenter::GridZValue);
59 m_grid->setVisible(m_axis->isGridLineVisible());
59 m_grid->setVisible(m_axis->isGridLineVisible());
60 m_title->setZValue(ChartPresenter::GridZValue);
60 m_title->setZValue(ChartPresenter::GridZValue);
61 connectSlots();
61 connectSlots();
62
62
63 setFlag(QGraphicsItem::ItemHasNoContents,true);
63 setFlag(QGraphicsItem::ItemHasNoContents,true);
64 }
64 }
65
65
66 void ChartAxis::connectSlots()
66 void ChartAxis::connectSlots()
67 {
67 {
68 QObject::connect(m_axis,SIGNAL(visibleChanged(bool)),this,SLOT(handleVisibleChanged(bool)));
68 QObject::connect(m_axis,SIGNAL(visibleChanged(bool)),this,SLOT(handleVisibleChanged(bool)));
69 QObject::connect(m_axis,SIGNAL(lineVisibleChanged(bool)),this,SLOT(handleArrowVisibleChanged(bool)));
69 QObject::connect(m_axis,SIGNAL(lineVisibleChanged(bool)),this,SLOT(handleArrowVisibleChanged(bool)));
70 QObject::connect(m_axis,SIGNAL(gridVisibleChanged(bool)),this,SLOT(handleGridVisibleChanged(bool)));
70 QObject::connect(m_axis,SIGNAL(gridVisibleChanged(bool)),this,SLOT(handleGridVisibleChanged(bool)));
71 QObject::connect(m_axis,SIGNAL(labelsVisibleChanged(bool)),this,SLOT(handleLabelsVisibleChanged(bool)));
71 QObject::connect(m_axis,SIGNAL(labelsVisibleChanged(bool)),this,SLOT(handleLabelsVisibleChanged(bool)));
72 QObject::connect(m_axis,SIGNAL(shadesVisibleChanged(bool)),this,SLOT(handleShadesVisibleChanged(bool)));
72 QObject::connect(m_axis,SIGNAL(shadesVisibleChanged(bool)),this,SLOT(handleShadesVisibleChanged(bool)));
73 QObject::connect(m_axis,SIGNAL(labelsAngleChanged(int)),this,SLOT(handleLabelsAngleChanged(int)));
73 QObject::connect(m_axis,SIGNAL(labelsAngleChanged(int)),this,SLOT(handleLabelsAngleChanged(int)));
74 QObject::connect(m_axis,SIGNAL(linePenChanged(const QPen&)),this,SLOT(handleArrowPenChanged(const QPen&)));
74 QObject::connect(m_axis,SIGNAL(linePenChanged(const QPen&)),this,SLOT(handleArrowPenChanged(const QPen&)));
75 QObject::connect(m_axis,SIGNAL(labelsPenChanged(const QPen&)),this,SLOT(handleLabelsPenChanged(const QPen&)));
75 QObject::connect(m_axis,SIGNAL(labelsPenChanged(const QPen&)),this,SLOT(handleLabelsPenChanged(const QPen&)));
76 QObject::connect(m_axis,SIGNAL(labelsBrushChanged(const QBrush&)),this,SLOT(handleLabelsBrushChanged(const QBrush&)));
76 QObject::connect(m_axis,SIGNAL(labelsBrushChanged(const QBrush&)),this,SLOT(handleLabelsBrushChanged(const QBrush&)));
77 QObject::connect(m_axis,SIGNAL(labelsFontChanged(const QFont&)),this,SLOT(handleLabelsFontChanged(const QFont&)));
77 QObject::connect(m_axis,SIGNAL(labelsFontChanged(const QFont&)),this,SLOT(handleLabelsFontChanged(const QFont&)));
78 QObject::connect(m_axis,SIGNAL(gridLinePenChanged(const QPen&)),this,SLOT(handleGridPenChanged(const QPen&)));
78 QObject::connect(m_axis,SIGNAL(gridLinePenChanged(const QPen&)),this,SLOT(handleGridPenChanged(const QPen&)));
79 QObject::connect(m_axis,SIGNAL(shadesPenChanged(const QPen&)),this,SLOT(handleShadesPenChanged(const QPen&)));
79 QObject::connect(m_axis,SIGNAL(shadesPenChanged(const QPen&)),this,SLOT(handleShadesPenChanged(const QPen&)));
80 QObject::connect(m_axis,SIGNAL(shadesBrushChanged(const QBrush&)),this,SLOT(handleShadesBrushChanged(const QBrush&)));
80 QObject::connect(m_axis,SIGNAL(shadesBrushChanged(const QBrush&)),this,SLOT(handleShadesBrushChanged(const QBrush&)));
81 QObject::connect(m_axis,SIGNAL(titleTextChanged(const QString&)),this,SLOT(handleTitleTextChanged(const QString&)));
81 QObject::connect(m_axis,SIGNAL(titleTextChanged(const QString&)),this,SLOT(handleTitleTextChanged(const QString&)));
82 QObject::connect(m_axis,SIGNAL(titleFontChanged(const QFont&)),this,SLOT(handleTitleFontChanged(const QFont&)));
82 QObject::connect(m_axis,SIGNAL(titleFontChanged(const QFont&)),this,SLOT(handleTitleFontChanged(const QFont&)));
83 QObject::connect(m_axis,SIGNAL(titlePenChanged(const QPen&)),this,SLOT(handleTitlePenChanged(const QPen&)));
83 QObject::connect(m_axis,SIGNAL(titlePenChanged(const QPen&)),this,SLOT(handleTitlePenChanged(const QPen&)));
84 QObject::connect(m_axis,SIGNAL(titleBrushChanged(const QBrush&)),this,SLOT(handleTitleBrushChanged(const QBrush&)));
84 QObject::connect(m_axis,SIGNAL(titleBrushChanged(const QBrush&)),this,SLOT(handleTitleBrushChanged(const QBrush&)));
85 QObject::connect(m_axis->d_ptr.data(),SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(handleRangeChanged(qreal,qreal)));
85 QObject::connect(m_axis->d_ptr.data(),SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(handleRangeChanged(qreal,qreal)));
86 }
86 }
87
87
88 ChartAxis::~ChartAxis()
88 ChartAxis::~ChartAxis()
89 {
89 {
90 }
90 }
91
91
92 void ChartAxis::setAnimation(AxisAnimation *animation)
92 void ChartAxis::setAnimation(AxisAnimation *animation)
93 {
93 {
94 m_animation = animation;
94 m_animation = animation;
95 }
95 }
96
96
97 void ChartAxis::setLayout(QVector<qreal> &layout)
97 void ChartAxis::setLayout(QVector<qreal> &layout)
98 {
98 {
99 m_layoutVector = layout;
99 m_layoutVector = layout;
100 }
100 }
101
101
102 void ChartAxis::createItems(int count)
102 void ChartAxis::createItems(int count)
103 {
103 {
104 if (m_arrow->childItems().size() == 0){
104 if (m_arrow->childItems().size() == 0){
105 QGraphicsLineItem* arrow = new ArrowItem(this, this);
105 QGraphicsLineItem* arrow = new ArrowItem(this, this);
106 arrow->setPen(m_axis->linePen());
106 arrow->setPen(m_axis->linePen());
107 m_arrow->addToGroup(arrow);
107 m_arrow->addToGroup(arrow);
108 }
108 }
109
109
110 if (m_intervalAxis && m_grid->childItems().size() == 0) {
110 if (m_intervalAxis && m_grid->childItems().size() == 0) {
111 for (int i = 0 ; i < 2 ; i ++){
111 for (int i = 0 ; i < 2 ; i ++){
112 QGraphicsLineItem* item = new QGraphicsLineItem(this);
112 QGraphicsLineItem* item = new QGraphicsLineItem(this);
113 item->setPen(m_axis->gridLinePen());
113 item->setPen(m_axis->gridLinePen());
114 m_grid->addToGroup(item);
114 m_grid->addToGroup(item);
115 }
115 }
116 }
116 }
117
117
118 for (int i = 0; i < count; ++i) {
118 for (int i = 0; i < count; ++i) {
119 QGraphicsLineItem* arrow = new QGraphicsLineItem(this);
119 QGraphicsLineItem* arrow = new QGraphicsLineItem(this);
120 arrow->setPen(m_axis->linePen());
120 arrow->setPen(m_axis->linePen());
121 QGraphicsLineItem* grid = new QGraphicsLineItem(this);
121 QGraphicsLineItem* grid = new QGraphicsLineItem(this);
122 grid->setPen(m_axis->gridLinePen());
122 grid->setPen(m_axis->gridLinePen());
123 QGraphicsSimpleTextItem* label = new QGraphicsSimpleTextItem(this);
123 QGraphicsSimpleTextItem* label = new QGraphicsSimpleTextItem(this);
124 label->setFont(m_axis->labelsFont());
124 label->setFont(m_axis->labelsFont());
125 label->setPen(m_axis->labelsPen());
125 label->setPen(m_axis->labelsPen());
126 label->setBrush(m_axis->labelsBrush());
126 label->setBrush(m_axis->labelsBrush());
127 m_arrow->addToGroup(arrow);
127 m_arrow->addToGroup(arrow);
128 m_grid->addToGroup(grid);
128 m_grid->addToGroup(grid);
129 m_labels->addToGroup(label);
129 m_labels->addToGroup(label);
130
130
131 if ((m_grid->childItems().size()) % 2 && m_grid->childItems().size() > 2){
131 if ((m_grid->childItems().size()) % 2 && m_grid->childItems().size() > 2){
132 QGraphicsRectItem* shades = new QGraphicsRectItem(this);
132 QGraphicsRectItem* shades = new QGraphicsRectItem(this);
133 shades->setPen(m_axis->shadesPen());
133 shades->setPen(m_axis->shadesPen());
134 shades->setBrush(m_axis->shadesBrush());
134 shades->setBrush(m_axis->shadesBrush());
135 m_shades->addToGroup(shades);
135 m_shades->addToGroup(shades);
136 }
136 }
137 }
137 }
138
138
139 }
139 }
140
140
141 void ChartAxis::deleteItems(int count)
141 void ChartAxis::deleteItems(int count)
142 {
142 {
143 QList<QGraphicsItem *> lines = m_grid->childItems();
143 QList<QGraphicsItem *> lines = m_grid->childItems();
144 QList<QGraphicsItem *> labels = m_labels->childItems();
144 QList<QGraphicsItem *> labels = m_labels->childItems();
145 QList<QGraphicsItem *> shades = m_shades->childItems();
145 QList<QGraphicsItem *> shades = m_shades->childItems();
146 QList<QGraphicsItem *> axis = m_arrow->childItems();
146 QList<QGraphicsItem *> axis = m_arrow->childItems();
147
147
148 for (int i = 0; i < count; ++i) {
148 for (int i = 0; i < count; ++i) {
149 if (lines.size() % 2 && lines.size() > 1)
149 if (lines.size() % 2 && lines.size() > 1)
150 delete(shades.takeLast());
150 delete(shades.takeLast());
151 delete(lines.takeLast());
151 delete(lines.takeLast());
152 delete(labels.takeLast());
152 delete(labels.takeLast());
153 delete(axis.takeLast());
153 delete(axis.takeLast());
154 }
154 }
155 }
155 }
156
156
157 void ChartAxis::updateLayout(QVector<qreal> &layout)
157 void ChartAxis::updateLayout(QVector<qreal> &layout)
158 {
158 {
159 int diff = m_layoutVector.size() - layout.size();
159 int diff = m_layoutVector.size() - layout.size();
160
160
161 if (diff > 0)
161 if (diff > 0)
162 deleteItems(diff);
162 deleteItems(diff);
163 else if (diff < 0)
163 else if (diff < 0)
164 createItems(-diff);
164 createItems(-diff);
165
165
166 if (m_animation) {
166 if (m_animation) {
167 switch (presenter()->state()) {
167 switch (presenter()->state()) {
168 case ChartPresenter::ZoomInState:
168 case ChartPresenter::ZoomInState:
169 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
169 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
170 m_animation->setAnimationPoint(presenter()->statePoint());
170 m_animation->setAnimationPoint(presenter()->statePoint());
171 break;
171 break;
172 case ChartPresenter::ZoomOutState:
172 case ChartPresenter::ZoomOutState:
173 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
173 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
174 m_animation->setAnimationPoint(presenter()->statePoint());
174 m_animation->setAnimationPoint(presenter()->statePoint());
175 break;
175 break;
176 case ChartPresenter::ScrollUpState:
176 case ChartPresenter::ScrollUpState:
177 case ChartPresenter::ScrollLeftState:
177 case ChartPresenter::ScrollLeftState:
178 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
178 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
179 break;
179 break;
180 case ChartPresenter::ScrollDownState:
180 case ChartPresenter::ScrollDownState:
181 case ChartPresenter::ScrollRightState:
181 case ChartPresenter::ScrollRightState:
182 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
182 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
183 break;
183 break;
184 case ChartPresenter::ShowState:
184 case ChartPresenter::ShowState:
185 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
185 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
186 break;
186 break;
187 }
187 }
188 m_animation->setValues(m_layoutVector, layout);
188 m_animation->setValues(m_layoutVector, layout);
189 presenter()->startAnimation(m_animation);
189 presenter()->startAnimation(m_animation);
190 } else {
190 } else {
191 setLayout(layout);
191 setLayout(layout);
192 updateGeometry();
192 updateGeometry();
193 }
193 }
194 }
194 }
195
195
196 void ChartAxis::setLabelPadding(int padding)
196 void ChartAxis::setLabelPadding(int padding)
197 {
197 {
198 m_labelPadding = padding;
198 m_labelPadding = padding;
199 }
199 }
200
200
201 bool ChartAxis::isEmpty()
201 bool ChartAxis::isEmpty()
202 {
202 {
203 return m_axisRect.isEmpty() || m_gridRect.isEmpty() || qFuzzyCompare(min(),max());
203 return m_axisRect.isEmpty() || m_gridRect.isEmpty() || qFuzzyCompare(min(),max());
204 }
204 }
205
205
206 void ChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
206 void ChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
207 {
207 {
208 m_gridRect = grid;
208 m_gridRect = grid;
209 m_axisRect = axis;
209 m_axisRect = axis;
210
210
211 if (isEmpty())
211 if (isEmpty())
212 return;
212 return;
213
213
214 QVector<qreal> layout = calculateLayout();
214 QVector<qreal> layout = calculateLayout();
215 updateLayout(layout);
215 updateLayout(layout);
216 }
216 }
217
217
218 qreal ChartAxis::min() const
218 qreal ChartAxis::min() const
219 {
219 {
220 return m_axis->d_ptr->min();
220 return m_axis->d_ptr->min();
221 }
221 }
222
222
223 qreal ChartAxis::max() const
223 qreal ChartAxis::max() const
224 {
224 {
225 return m_axis->d_ptr->max();
225 return m_axis->d_ptr->max();
226 }
226 }
227
227
228 QFont ChartAxis::font() const
228 QFont ChartAxis::font() const
229 {
229 {
230 return m_axis->labelsFont();
230 return m_axis->labelsFont();
231 }
231 }
232
232
233 QFont ChartAxis::titleFont() const
233 QFont ChartAxis::titleFont() const
234 {
234 {
235 return m_axis->titleFont();
235 return m_axis->titleFont();
236 }
236 }
237
237
238 QString ChartAxis::titleText() const
238 QString ChartAxis::titleText() const
239 {
239 {
240 return m_axis->titleText();
240 return m_axis->titleText();
241 }
241 }
242
242
243 void ChartAxis::axisSelected()
243 void ChartAxis::axisSelected()
244 {
244 {
245 emit clicked();
245 emit clicked();
246 }
246 }
247
247
248 Qt::Orientation ChartAxis::orientation() const
248 Qt::Orientation ChartAxis::orientation() const
249 {
249 {
250 return m_axis->orientation();
250 return m_axis->orientation();
251 }
251 }
252
252
253 Qt::Alignment ChartAxis::alignment() const
253 Qt::Alignment ChartAxis::alignment() const
254 {
254 {
255 return m_axis->alignment();
255 return m_axis->alignment();
256 }
256 }
257
257
258 void ChartAxis::setLabels(const QStringList &labels)
258 void ChartAxis::setLabels(const QStringList &labels)
259 {
259 {
260 m_labelsList = labels;
260 m_labelsList = labels;
261 }
261 }
262
262
263 QSizeF ChartAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
263 QSizeF ChartAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
264 {
264 {
265 Q_UNUSED(which);
265 Q_UNUSED(which);
266 Q_UNUSED(constraint);
266 Q_UNUSED(constraint);
267 return QSizeF();
267 return QSizeF();
268 }
268 }
269
269
270 //handlers
270 //handlers
271
271
272 void ChartAxis::handleArrowVisibleChanged(bool visible)
272 void ChartAxis::handleArrowVisibleChanged(bool visible)
273 {
273 {
274 m_arrow->setVisible(visible);
274 m_arrow->setVisible(visible);
275 }
275 }
276
276
277 void ChartAxis::handleGridVisibleChanged(bool visible)
277 void ChartAxis::handleGridVisibleChanged(bool visible)
278 {
278 {
279 m_grid->setVisible(visible);
279 m_grid->setVisible(visible);
280 }
280 }
281
281
282 void ChartAxis::handleLabelsVisibleChanged(bool visible)
282 void ChartAxis::handleLabelsVisibleChanged(bool visible)
283 {
283 {
284 m_labels->setVisible(visible);
284 m_labels->setVisible(visible);
285 }
285 }
286
286
287 void ChartAxis::handleShadesVisibleChanged(bool visible)
287 void ChartAxis::handleShadesVisibleChanged(bool visible)
288 {
288 {
289 m_shades->setVisible(visible);
289 m_shades->setVisible(visible);
290 }
290 }
291
291
292 void ChartAxis::handleLabelsAngleChanged(int angle)
292 void ChartAxis::handleLabelsAngleChanged(int angle)
293 {
293 {
294 foreach (QGraphicsItem *item, m_labels->childItems())
294 foreach (QGraphicsItem *item, m_labels->childItems())
295 item->setRotation(angle);
295 item->setRotation(angle);
296
296
297 m_labelsAngle = angle;
297 m_labelsAngle = angle;
298 }
298 }
299
299
300 void ChartAxis::handleLabelsPenChanged(const QPen &pen)
300 void ChartAxis::handleLabelsPenChanged(const QPen &pen)
301 {
301 {
302 foreach (QGraphicsItem *item , m_labels->childItems())
302 foreach (QGraphicsItem *item , m_labels->childItems())
303 static_cast<QGraphicsSimpleTextItem *>(item)->setPen(pen);
303 static_cast<QGraphicsSimpleTextItem *>(item)->setPen(pen);
304 }
304 }
305
305
306 void ChartAxis::handleLabelsBrushChanged(const QBrush &brush)
306 void ChartAxis::handleLabelsBrushChanged(const QBrush &brush)
307 {
307 {
308 foreach (QGraphicsItem *item , m_labels->childItems())
308 foreach (QGraphicsItem *item , m_labels->childItems())
309 static_cast<QGraphicsSimpleTextItem *>(item)->setBrush(brush);
309 static_cast<QGraphicsSimpleTextItem *>(item)->setBrush(brush);
310 }
310 }
311
311
312 void ChartAxis::handleLabelsFontChanged(const QFont &font)
312 void ChartAxis::handleLabelsFontChanged(const QFont &font)
313 {
313 {
314 foreach (QGraphicsItem *item , m_labels->childItems())
314 foreach (QGraphicsItem *item , m_labels->childItems())
315 static_cast<QGraphicsSimpleTextItem *>(item)->setFont(font);
315 static_cast<QGraphicsSimpleTextItem *>(item)->setFont(font);
316 QGraphicsLayoutItem::updateGeometry();
316 QGraphicsLayoutItem::updateGeometry();
317 presenter()->layout()->invalidate();
317 presenter()->layout()->invalidate();
318 }
318 }
319
319
320 void ChartAxis::handleShadesBrushChanged(const QBrush &brush)
320 void ChartAxis::handleShadesBrushChanged(const QBrush &brush)
321 {
321 {
322 foreach (QGraphicsItem *item , m_shades->childItems())
322 foreach (QGraphicsItem *item , m_shades->childItems())
323 static_cast<QGraphicsRectItem *>(item)->setBrush(brush);
323 static_cast<QGraphicsRectItem *>(item)->setBrush(brush);
324 }
324 }
325
325
326 void ChartAxis::handleShadesPenChanged(const QPen &pen)
326 void ChartAxis::handleShadesPenChanged(const QPen &pen)
327 {
327 {
328 foreach (QGraphicsItem *item , m_shades->childItems())
328 foreach (QGraphicsItem *item , m_shades->childItems())
329 static_cast<QGraphicsRectItem *>(item)->setPen(pen);
329 static_cast<QGraphicsRectItem *>(item)->setPen(pen);
330 }
330 }
331
331
332 void ChartAxis::handleArrowPenChanged(const QPen &pen)
332 void ChartAxis::handleArrowPenChanged(const QPen &pen)
333 {
333 {
334 foreach (QGraphicsItem *item , m_arrow->childItems())
334 foreach (QGraphicsItem *item , m_arrow->childItems())
335 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
335 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
336 }
336 }
337
337
338 void ChartAxis::handleGridPenChanged(const QPen &pen)
338 void ChartAxis::handleGridPenChanged(const QPen &pen)
339 {
339 {
340 foreach (QGraphicsItem *item , m_grid->childItems())
340 foreach (QGraphicsItem *item , m_grid->childItems())
341 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
341 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
342 }
342 }
343
343
344 void ChartAxis::handleTitleTextChanged(const QString &title)
344 void ChartAxis::handleTitleTextChanged(const QString &title)
345 {
345 {
346 Q_UNUSED(title)
346 Q_UNUSED(title)
347 QGraphicsLayoutItem::updateGeometry();
347 QGraphicsLayoutItem::updateGeometry();
348 presenter()->layout()->invalidate();
348 presenter()->layout()->invalidate();
349 }
349 }
350
350
351
351
352 void ChartAxis::handleTitlePenChanged(const QPen &pen)
352 void ChartAxis::handleTitlePenChanged(const QPen &pen)
353 {
353 {
354 m_title->setPen(pen);
354 m_title->setPen(pen);
355 }
355 }
356
356
357 void ChartAxis::handleTitleBrushChanged(const QBrush &brush)
357 void ChartAxis::handleTitleBrushChanged(const QBrush &brush)
358 {
358 {
359 m_title->setBrush(brush);
359 m_title->setBrush(brush);
360 }
360 }
361
361
362 void ChartAxis::handleTitleFontChanged(const QFont &font)
362 void ChartAxis::handleTitleFontChanged(const QFont &font)
363 {
363 {
364 if(m_title->font() != font){
364 if(m_title->font() != font){
365 m_title->setFont(font);
365 m_title->setFont(font);
366 QGraphicsLayoutItem::updateGeometry();
366 QGraphicsLayoutItem::updateGeometry();
367 presenter()->layout()->invalidate();
367 presenter()->layout()->invalidate();
368 }
368 }
369 }
369 }
370
370
371 void ChartAxis::handleVisibleChanged(bool visible)
371 void ChartAxis::handleVisibleChanged(bool visible)
372 {
372 {
373 setVisible(visible);
373 setVisible(visible);
374 }
374 }
375
375
376 void ChartAxis::handleRangeChanged(qreal min, qreal max)
376 void ChartAxis::handleRangeChanged(qreal min, qreal max)
377 {
377 {
378 Q_UNUSED(min);
378 Q_UNUSED(min);
379 Q_UNUSED(max);
379 Q_UNUSED(max);
380
380
381 if (!isEmpty()) {
381 if (!isEmpty()) {
382
382
383 QVector<qreal> layout = calculateLayout();
383 QVector<qreal> layout = calculateLayout();
384 updateLayout(layout);
384 updateLayout(layout);
385 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
385 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
386 QSizeF after = sizeHint(Qt::PreferredSize);
386 QSizeF after = sizeHint(Qt::PreferredSize);
387
387
388 if (before != after) {
388 if (before != after) {
389 QGraphicsLayoutItem::updateGeometry();
389 QGraphicsLayoutItem::updateGeometry();
390 //we don't want to call invalidate on layout, since it will change minimum size of component,
390 //we don't want to call invalidate on layout, since it will change minimum size of component,
391 //which we would like to avoid since it causes nasty flips when scrolling or zooming,
391 //which we would like to avoid since it causes nasty flips when scrolling or zooming,
392 //instead recalculate layout and use plotArea for extra space.
392 //instead recalculate layout and use plotArea for extra space.
393 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
393 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
394 }
394 }
395 }
395 }
396
396
397 }
397 }
398
398
399 //helpers
399 //helpers
400
400
401 QStringList ChartAxis::createValueLabels(qreal min, qreal max, int ticks,const QString& format)
401 QStringList ChartAxis::createValueLabels(qreal min, qreal max, int ticks,const QString& format)
402 {
402 {
403 //TODO: Q_ASSERT(m_max > m_min);
403 //TODO: Q_ASSERT(m_max > m_min);
404 //TODO: Q_ASSERT(ticks > 1);
404 //TODO: Q_ASSERT(ticks > 1);
405
405
406 QStringList labels;
406 QStringList labels;
407
407
408 if(max <= min || ticks < 1){
408 if(max <= min || ticks < 1){
409 return labels;
409 return labels;
410 }
410 }
411
411
412 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
412 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
413 n++;
413 n++;
414
414
415 if (format.isNull()) {
415 if (format.isNull()) {
416 for (int i = 0; i < ticks; i++) {
416 for (int i = 0; i < ticks; i++) {
417 qreal value = min + (i * (max - min) / (ticks - 1));
417 qreal value = min + (i * (max - min) / (ticks - 1));
418 labels << QString::number(value, 'f', n);
418 labels << QString::number(value, 'f', n);
419 }
419 }
420 } else {
420 } else {
421 QByteArray array = format.toLatin1();
421 QByteArray array = format.toLatin1();
422 for (int i = 0; i < ticks; i++) {
422 for (int i = 0; i < ticks; i++) {
423 qreal value = min + (i * (max - min) / (ticks - 1));
423 qreal value = min + (i * (max - min) / (ticks - 1));
424 if (format.contains("d")
424 if (format.contains("d")
425 || format.contains("i")
425 || format.contains("i")
426 || format.contains("c"))
426 || format.contains("c"))
427 labels << QString().sprintf(array, (qint64)value);
427 labels << QString().sprintf(array, (qint64)value);
428 else if (format.contains("u")
428 else if (format.contains("u")
429 || format.contains("o")
429 || format.contains("o")
430 || format.contains("x", Qt::CaseInsensitive))
430 || format.contains("x", Qt::CaseInsensitive))
431 labels << QString().sprintf(array, (quint64)value);
431 labels << QString().sprintf(array, (quint64)value);
432 else if (format.contains("f", Qt::CaseInsensitive)
432 else if (format.contains("f", Qt::CaseInsensitive)
433 || format.contains("e", Qt::CaseInsensitive)
433 || format.contains("e", Qt::CaseInsensitive)
434 || format.contains("g", Qt::CaseInsensitive))
434 || format.contains("g", Qt::CaseInsensitive))
435 labels << QString().sprintf(array, value);
435 labels << QString().sprintf(array, value);
436 }
436 }
437 }
437 }
438
438
439 return labels;
439 return labels;
440 }
440 }
441
441
442 QStringList ChartAxis::createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString& format)
442 QStringList ChartAxis::createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString& format)
443 {
443 {
444 // Q_ASSERT(m_max > m_min);
444 // Q_ASSERT(m_max > m_min);
445 // Q_ASSERT(ticks > 1);
445 // Q_ASSERT(ticks > 1);
446
446
447 QStringList labels;
447 QStringList labels;
448
448
449 int n = 0;
449 int n = 0;
450 if (ticks > 1)
450 if (ticks > 1)
451 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
451 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
452 n++;
452 n++;
453
453
454 int firstTick;
454 int firstTick;
455 if (base > 1)
455 if (base > 1)
456 firstTick = ceil(log10(min) / log10(base));
456 firstTick = ceil(log10(min) / log10(base));
457 else
457 else
458 firstTick = ceil(log10(max) / log10(base));
458 firstTick = ceil(log10(max) / log10(base));
459
459
460 if (format.isNull()) {
460 if (format.isNull()) {
461 for (int i = firstTick; i < ticks + firstTick; i++) {
461 for (int i = firstTick; i < ticks + firstTick; i++) {
462 qreal value = qPow(base, i);
462 qreal value = qPow(base, i);
463 labels << QString::number(value, 'f', n);
463 labels << QString::number(value, 'f', n);
464 }
464 }
465 } else {
465 } else {
466 QByteArray array = format.toLatin1();
466 QByteArray array = format.toLatin1();
467 for (int i = firstTick; i < ticks + firstTick; i++) {
467 for (int i = firstTick; i < ticks + firstTick; i++) {
468 qreal value = qPow(base, i);
468 qreal value = qPow(base, i);
469 labels << QString().sprintf(array, value);
469 if (format.contains("d")
470 || format.contains("i")
471 || format.contains("c"))
472 labels << QString().sprintf(array, (qint64)value);
473 else if (format.contains("u")
474 || format.contains("o")
475 || format.contains("x", Qt::CaseInsensitive))
476 labels << QString().sprintf(array, (quint64)value);
477 else if (format.contains("f", Qt::CaseInsensitive)
478 || format.contains("e", Qt::CaseInsensitive)
479 || format.contains("g", Qt::CaseInsensitive))
480 labels << QString().sprintf(array, value);
470 }
481 }
471 }
482 }
472
483
473 return labels;
484 return labels;
474 }
485 }
475
486
476 QStringList ChartAxis::createDateTimeLabels(qreal min, qreal max,int ticks,const QString& format)
487 QStringList ChartAxis::createDateTimeLabels(qreal min, qreal max,int ticks,const QString& format)
477 {
488 {
478 //TODO: Q_ASSERT(m_max > m_min);
489 //TODO: Q_ASSERT(m_max > m_min);
479 //TODO: Q_ASSERT(ticks > 1);
490 //TODO: Q_ASSERT(ticks > 1);
480 QStringList labels;
491 QStringList labels;
481
492
482 if(max <= min || ticks < 1) {
493 if(max <= min || ticks < 1) {
483 return labels;
494 return labels;
484 }
495 }
485
496
486 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
497 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
487 n++;
498 n++;
488 for (int i = 0; i < ticks; i++) {
499 for (int i = 0; i < ticks; i++) {
489 qreal value = min + (i * (max - min) / (ticks - 1));
500 qreal value = min + (i * (max - min) / (ticks - 1));
490 labels << QDateTime::fromMSecsSinceEpoch(value).toString(format);
501 labels << QDateTime::fromMSecsSinceEpoch(value).toString(format);
491 }
502 }
492 return labels;
503 return labels;
493 }
504 }
494
505
495 #include "moc_chartaxis_p.cpp"
506 #include "moc_chartaxis_p.cpp"
496
507
497 QTCOMMERCIALCHART_END_NAMESPACE
508 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,221 +1,225
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_logMinX(0),
31 m_logMaxX(1),
31 m_logMaxX(1),
32 m_logBaseX(10),
32 m_logBaseX(10),
33 m_logMinY(0),
33 m_logMinY(0),
34 m_logMaxY(1),
34 m_logMaxY(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 m_logMinX = log10(m_minX) / log10(m_logBaseX);
53 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
53 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
54 if(!m_signalsBlocked)
54 if(!m_signalsBlocked)
55 emit rangeHorizontalChanged(m_minX, m_maxX);
55 emit rangeHorizontalChanged(m_minX, m_maxX);
56 }
56 }
57
57
58 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
58 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
59 m_minY = minY;
59 m_minY = minY;
60 m_maxY = maxY;
60 m_maxY = maxY;
61 axisYChanged = true;
61 axisYChanged = true;
62 m_logMinY = log10(m_minY) / log10(m_logBaseY);
62 m_logMinY = log10(m_minY) / log10(m_logBaseY);
63 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
63 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
64 if(!m_signalsBlocked)
64 if(!m_signalsBlocked)
65 emit rangeVerticalChanged(m_minY, m_maxY);
65 emit rangeVerticalChanged(m_minY, m_maxY);
66 }
66 }
67
67
68 if (axisXChanged || axisYChanged)
68 if (axisXChanged || axisYChanged)
69 emit updated();
69 emit updated();
70 }
70 }
71
71
72 void LogXLogYDomain::zoomIn(const QRectF &rect)
72 void LogXLogYDomain::zoomIn(const QRectF &rect)
73 {
73 {
74 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
74 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
75 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
75 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
76 qreal minX = qPow(m_logBaseX, newLogMinX);
76 qreal minX = qPow(m_logBaseX, newLogMinX);
77 qreal maxX = qPow(m_logBaseX, newLogMaxX);
77 qreal maxX = qPow(m_logBaseX, newLogMaxX);
78
78
79 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
79 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
80 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
80 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
81 qreal minY = qPow(m_logBaseY, newLogMinY);
81 qreal minY = qPow(m_logBaseY, newLogMinY);
82 qreal maxY = qPow(m_logBaseY, newLogMaxY);
82 qreal maxY = qPow(m_logBaseY, newLogMaxY);
83
83
84 setRange(minX, maxX, minY, maxY);
84 setRange(minX, maxX, minY, maxY);
85 }
85 }
86
86
87 void LogXLogYDomain::zoomOut(const QRectF &rect)
87 void LogXLogYDomain::zoomOut(const QRectF &rect)
88 {
88 {
89 qreal ratioX = m_size.width()/rect.width();
89 qreal ratioX = m_size.width()/rect.width();
90 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
90 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
91 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
91 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
92 qreal minX = qPow(m_logBaseX, newLogMinX);
92 qreal minX = qPow(m_logBaseX, newLogMinX);
93 qreal maxX = qPow(m_logBaseX, newLogMaxX);
93 qreal maxX = qPow(m_logBaseX, newLogMaxX);
94
94
95 qreal ratioY = m_size.height()/rect.height();
95 qreal ratioY = m_size.height()/rect.height();
96 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
96 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
97 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
97 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
98 qreal minY = qPow(m_logBaseY, newLogMinY);
98 qreal minY = qPow(m_logBaseY, newLogMinY);
99 qreal maxY = qPow(m_logBaseY, newLogMaxY);
99 qreal maxY = qPow(m_logBaseY, newLogMaxY);
100
100
101 setRange(minX, maxX, minY, maxY);
101 setRange(minX, maxX, minY, maxY);
102 }
102 }
103
103
104 void LogXLogYDomain::move(qreal dx, qreal dy)
104 void LogXLogYDomain::move(qreal dx, qreal dy)
105 {
105 {
106 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
106 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
107 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
107 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
108 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
108 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
109
109
110 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
110 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
111 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
111 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
112 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
112 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
113
113
114 setRange(minX, maxX, minY, maxY);
114 setRange(minX, maxX, minY, maxY);
115 }
115 }
116
116
117 QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point) const
117 QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point) const
118 {
118 {
119 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
119 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
120 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
120 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
121 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
121 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
122 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
122 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
123 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
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();
124 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
125 return QPointF(x, y);
125 return QPointF(x, y);
126 }
126 }
127
127
128 QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
128 QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
129 {
129 {
130 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
130 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
131 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
131 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
132 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
132 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
133 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
133 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
134
134
135 QVector<QPointF> result;
135 QVector<QPointF> result;
136 result.resize(vector.count());
136 result.resize(vector.count());
137
137
138 for (int i = 0; i < vector.count(); ++i) {
138 for (int i = 0; i < vector.count(); ++i) {
139 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
139 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
140 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
140 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
141 result[i].setX(x);
141 result[i].setX(x);
142 result[i].setY(y);
142 result[i].setY(y);
143 }
143 }
144 return result;
144 return result;
145 }
145 }
146
146
147 QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const
147 QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const
148 {
148 {
149 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
149 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
150 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
150 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
151 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
151 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
152 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
152 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
153 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
153 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
154 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
154 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
155 return QPointF(x, y);
155 return QPointF(x, y);
156 }
156 }
157
157
158 bool LogXLogYDomain::attachAxis(QAbstractAxis* axis)
158 bool LogXLogYDomain::attachAxis(QAbstractAxis* axis)
159 {
159 {
160 AbstractDomain::attachAxis(axis);
160 AbstractDomain::attachAxis(axis);
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
162
162
163 if(logAxis && logAxis->orientation()==Qt::Vertical)
163 if(logAxis && logAxis->orientation()==Qt::Vertical)
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
165
165
166 if(logAxis && logAxis->orientation()==Qt::Horizontal)
166 if(logAxis && logAxis->orientation()==Qt::Horizontal)
167 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
167 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
168
168
169 return true;
169 return true;
170 }
170 }
171
171
172 bool LogXLogYDomain::detachAxis(QAbstractAxis* axis)
172 bool LogXLogYDomain::detachAxis(QAbstractAxis* axis)
173 {
173 {
174 AbstractDomain::detachAxis(axis);
174 AbstractDomain::detachAxis(axis);
175 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
175 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
176
176
177 if(logAxis && logAxis->orientation()==Qt::Vertical)
177 if(logAxis && logAxis->orientation()==Qt::Vertical)
178 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
178 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
179
179
180 if(logAxis && logAxis->orientation()==Qt::Horizontal)
180 if(logAxis && logAxis->orientation()==Qt::Horizontal)
181 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
181 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
182
182
183 return true;
183 return true;
184 }
184 }
185
185
186 void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
186 void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
187 {
187 {
188 m_logBaseY = baseY;
188 m_logBaseY = baseY;
189 m_logMinY = log10(m_minY) / log10(m_logBaseY);
190 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
189 }
191 }
190
192
191 void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
193 void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
192 {
194 {
193 m_logBaseX = baseX;
195 m_logBaseX = baseX;
196 m_logMinX = log10(m_minX) / log10(m_logBaseX);
197 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
194 }
198 }
195
199
196 // operators
200 // operators
197
201
198 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
202 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
199 {
203 {
200 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
204 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
201 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
205 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
202 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
206 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
203 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
207 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
204 }
208 }
205
209
206
210
207 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
211 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
208 {
212 {
209 return !(domain1 == domain2);
213 return !(domain1 == domain2);
210 }
214 }
211
215
212
216
213 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain)
217 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain)
214 {
218 {
215 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
219 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
216 return dbg.maybeSpace();
220 return dbg.maybeSpace();
217 }
221 }
218
222
219 #include "moc_logxlogydomain_p.cpp"
223 #include "moc_logxlogydomain_p.cpp"
220
224
221 QTCOMMERCIALCHART_END_NAMESPACE
225 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,210 +1,212
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_logMinX(0),
31 m_logMaxX(1),
31 m_logMaxX(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 m_logMinX = log10(m_minX) / log10(m_logBaseX);
50 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
50 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
51 if(!m_signalsBlocked)
51 if(!m_signalsBlocked)
52 emit rangeHorizontalChanged(m_minX, m_maxX);
52 emit rangeHorizontalChanged(m_minX, m_maxX);
53 }
53 }
54
54
55 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
55 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
56 m_minY = minY;
56 m_minY = minY;
57 m_maxY = maxY;
57 m_maxY = maxY;
58 axisYChanged = true;
58 axisYChanged = true;
59 if(!m_signalsBlocked)
59 if(!m_signalsBlocked)
60 emit rangeVerticalChanged(m_minY, m_maxY);
60 emit rangeVerticalChanged(m_minY, m_maxY);
61 }
61 }
62
62
63 if (axisXChanged || axisYChanged)
63 if (axisXChanged || axisYChanged)
64 emit updated();
64 emit updated();
65 }
65 }
66
66
67 void LogXYDomain::zoomIn(const QRectF &rect)
67 void LogXYDomain::zoomIn(const QRectF &rect)
68 {
68 {
69 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
69 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
70 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
70 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
71 qreal minX = qPow(m_logBaseX, newLogMinX);
71 qreal minX = qPow(m_logBaseX, newLogMinX);
72 qreal maxX = qPow(m_logBaseX, newLogMaxX);
72 qreal maxX = qPow(m_logBaseX, newLogMaxX);
73
73
74 qreal dy = spanY() / m_size.height();
74 qreal dy = spanY() / m_size.height();
75 qreal minY = m_minY;
75 qreal minY = m_minY;
76 qreal maxY = m_maxY;
76 qreal maxY = m_maxY;
77
77
78 minY = maxY - dy * rect.bottom();
78 minY = maxY - dy * rect.bottom();
79 maxY = maxY - dy * rect.top();
79 maxY = maxY - dy * rect.top();
80
80
81 setRange(minX, maxX, minY, maxY);
81 setRange(minX, maxX, minY, maxY);
82 }
82 }
83
83
84 void LogXYDomain::zoomOut(const QRectF &rect)
84 void LogXYDomain::zoomOut(const QRectF &rect)
85 {
85 {
86 qreal ratioX = m_size.width()/rect.width();
86 qreal ratioX = m_size.width()/rect.width();
87 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
87 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
88 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
88 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
89 qreal minX = qPow(m_logBaseX, newLogMinX);
89 qreal minX = qPow(m_logBaseX, newLogMinX);
90 qreal maxX = qPow(m_logBaseX, newLogMaxX);
90 qreal maxX = qPow(m_logBaseX, newLogMaxX);
91
91
92 qreal dy = spanY() / rect.height();
92 qreal dy = spanY() / rect.height();
93 qreal minY = m_minY;
93 qreal minY = m_minY;
94 qreal maxY = m_maxY;
94 qreal maxY = m_maxY;
95
95
96 maxY = minY + dy * rect.bottom();
96 maxY = minY + dy * rect.bottom();
97 minY = maxY - dy * m_size.height();
97 minY = maxY - dy * m_size.height();
98
98
99 setRange(minX, maxX, minY, maxY);
99 setRange(minX, maxX, minY, maxY);
100 }
100 }
101
101
102 void LogXYDomain::move(qreal dx, qreal dy)
102 void LogXYDomain::move(qreal dx, qreal dy)
103 {
103 {
104 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
104 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
105 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
105 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
106 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
106 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
107
107
108 qreal y = spanY() / m_size.height();
108 qreal y = spanY() / m_size.height();
109 qreal minY = m_minY;
109 qreal minY = m_minY;
110 qreal maxY = m_maxY;
110 qreal maxY = m_maxY;
111
111
112 if (dy != 0) {
112 if (dy != 0) {
113 minY = minY + y * dy;
113 minY = minY + y * dy;
114 maxY = maxY + y * dy;
114 maxY = maxY + y * dy;
115 }
115 }
116 setRange(minX, maxX, minY, maxY);
116 setRange(minX, maxX, minY, maxY);
117 }
117 }
118
118
119 QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point) const
119 QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point) const
120 {
120 {
121 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
121 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
122 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
122 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
123 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
123 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
124
124
125 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
125 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
126 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
126 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
127 return QPointF(x, y);
127 return QPointF(x, y);
128 }
128 }
129
129
130 QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
130 QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
131 {
131 {
132 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
132 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
133 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
133 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
134 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
134 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
135
135
136 QVector<QPointF> result;
136 QVector<QPointF> result;
137 result.resize(vector.count());
137 result.resize(vector.count());
138
138
139 for (int i = 0; i < vector.count(); ++i) {
139 for (int i = 0; i < vector.count(); ++i) {
140 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
140 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
141 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
141 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
142 result[i].setX(x);
142 result[i].setX(x);
143 result[i].setY(y);
143 result[i].setY(y);
144 }
144 }
145 return result;
145 return result;
146 }
146 }
147
147
148 QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const
148 QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const
149 {
149 {
150 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
150 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
151 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
151 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
152 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
152 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
153 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
153 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
154 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
154 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
155 return QPointF(x, y);
155 return QPointF(x, y);
156 }
156 }
157
157
158 bool LogXYDomain::attachAxis(QAbstractAxis* axis)
158 bool LogXYDomain::attachAxis(QAbstractAxis* axis)
159 {
159 {
160 AbstractDomain::attachAxis(axis);
160 AbstractDomain::attachAxis(axis);
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
162
162
163 if(logAxis && logAxis->orientation()==Qt::Horizontal)
163 if(logAxis && logAxis->orientation()==Qt::Horizontal)
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
165
165
166 return true;
166 return true;
167 }
167 }
168
168
169 bool LogXYDomain::detachAxis(QAbstractAxis* axis)
169 bool LogXYDomain::detachAxis(QAbstractAxis* axis)
170 {
170 {
171 AbstractDomain::detachAxis(axis);
171 AbstractDomain::detachAxis(axis);
172 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
172 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
173
173
174 if(logAxis && logAxis->orientation()==Qt::Horizontal)
174 if(logAxis && logAxis->orientation()==Qt::Horizontal)
175 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
175 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
176
176
177 return true;
177 return true;
178 }
178 }
179
179
180 void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
180 void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
181 {
181 {
182 m_logBaseX = baseX;
182 m_logBaseX = baseX;
183 m_logMinX = log10(m_minX) / log10(m_logBaseX);
184 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
183 }
185 }
184
186
185 // operators
187 // operators
186
188
187 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2)
189 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2)
188 {
190 {
189 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
191 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
190 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
192 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
191 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
193 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
192 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
194 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
193 }
195 }
194
196
195
197
196 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2)
198 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2)
197 {
199 {
198 return !(domain1 == domain2);
200 return !(domain1 == domain2);
199 }
201 }
200
202
201
203
202 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain)
204 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain)
203 {
205 {
204 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
206 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
205 return dbg.maybeSpace();
207 return dbg.maybeSpace();
206 }
208 }
207
209
208 #include "moc_logxydomain_p.cpp"
210 #include "moc_logxydomain_p.cpp"
209
211
210 QTCOMMERCIALCHART_END_NAMESPACE
212 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,209 +1,211
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_logMinY(0),
31 m_logMaxY(1),
31 m_logMaxY(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 m_logMinY = log10(m_minY) / log10(m_logBaseY);
58 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
58 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
59 if(!m_signalsBlocked)
59 if(!m_signalsBlocked)
60 emit rangeVerticalChanged(m_minY, m_maxY);
60 emit rangeVerticalChanged(m_minY, m_maxY);
61 }
61 }
62
62
63 if (axisXChanged || axisYChanged)
63 if (axisXChanged || axisYChanged)
64 emit updated();
64 emit updated();
65 }
65 }
66
66
67 void XLogYDomain::zoomIn(const QRectF &rect)
67 void XLogYDomain::zoomIn(const QRectF &rect)
68 {
68 {
69 qreal dx = spanX() / m_size.width();
69 qreal dx = spanX() / m_size.width();
70 qreal maxX = m_maxX;
70 qreal maxX = m_maxX;
71 qreal minX = m_minX;
71 qreal minX = m_minX;
72
72
73 maxX = minX + dx * rect.right();
73 maxX = minX + dx * rect.right();
74 minX = minX + dx * rect.left();
74 minX = minX + dx * rect.left();
75
75
76 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
76 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
77 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
77 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
78 qreal minY = qPow(m_logBaseY, newLogMinY);
78 qreal minY = qPow(m_logBaseY, newLogMinY);
79 qreal maxY = qPow(m_logBaseY, newLogMaxY);
79 qreal maxY = qPow(m_logBaseY, newLogMaxY);
80
80
81 setRange(minX, maxX, minY, maxY);
81 setRange(minX, maxX, minY, maxY);
82 }
82 }
83
83
84 void XLogYDomain::zoomOut(const QRectF &rect)
84 void XLogYDomain::zoomOut(const QRectF &rect)
85 {
85 {
86 qreal dx = spanX() / rect.width();
86 qreal dx = spanX() / rect.width();
87 qreal maxX = m_maxX;
87 qreal maxX = m_maxX;
88 qreal minX = m_minX;
88 qreal minX = m_minX;
89
89
90 minX = maxX - dx * rect.right();
90 minX = maxX - dx * rect.right();
91 maxX = minX + dx * m_size.width();
91 maxX = minX + dx * m_size.width();
92
92
93 qreal ratioY = m_size.height()/rect.height();
93 qreal ratioY = m_size.height()/rect.height();
94 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
94 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
95 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
95 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
96 qreal minY = qPow(m_logBaseY, newLogMinY);
96 qreal minY = qPow(m_logBaseY, newLogMinY);
97 qreal maxY = qPow(m_logBaseY, newLogMaxY);
97 qreal maxY = qPow(m_logBaseY, newLogMaxY);
98
98
99 setRange(minX, maxX, minY, maxY);
99 setRange(minX, maxX, minY, maxY);
100 }
100 }
101
101
102 void XLogYDomain::move(qreal dx, qreal dy)
102 void XLogYDomain::move(qreal dx, qreal dy)
103 {
103 {
104 qreal x = spanX() / m_size.width();
104 qreal x = spanX() / m_size.width();
105 qreal maxX = m_maxX;
105 qreal maxX = m_maxX;
106 qreal minX = m_minX;
106 qreal minX = m_minX;
107
107
108 if (dx != 0) {
108 if (dx != 0) {
109 minX = minX + x * dx;
109 minX = minX + x * dx;
110 maxX = maxX + x * dx;
110 maxX = maxX + x * dx;
111 }
111 }
112
112
113 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
113 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
114 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
114 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
115 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
115 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
116
116
117 setRange(minX, maxX, minY, maxY);
117 setRange(minX, maxX, minY, maxY);
118 }
118 }
119
119
120 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const
120 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const
121 {
121 {
122 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
122 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
123 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
123 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
124 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
124 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
125
125
126 qreal x = (point.x() - m_minX) * deltaX;
126 qreal x = (point.x() - m_minX) * deltaX;
127 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
127 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
128 return QPointF(x, y);
128 return QPointF(x, y);
129 }
129 }
130
130
131 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
131 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
132 {
132 {
133 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
133 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
134 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
134 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
135 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
135 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
136
136
137 QVector<QPointF> result;
137 QVector<QPointF> result;
138 result.resize(vector.count());
138 result.resize(vector.count());
139
139
140 for (int i = 0; i < vector.count(); ++i) {
140 for (int i = 0; i < vector.count(); ++i) {
141 qreal x = (vector[i].x() - m_minX) * deltaX;
141 qreal x = (vector[i].x() - m_minX) * deltaX;
142 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
142 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
143 result[i].setX(x);
143 result[i].setX(x);
144 result[i].setY(y);
144 result[i].setY(y);
145 }
145 }
146 return result;
146 return result;
147 }
147 }
148
148
149 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
149 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
150 {
150 {
151 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
151 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
152 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
152 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
153 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
153 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
154 qreal x = point.x() / deltaX + m_minX;
154 qreal x = point.x() / deltaX + m_minX;
155 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
155 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
156 return QPointF(x, y);
156 return QPointF(x, y);
157 }
157 }
158
158
159 bool XLogYDomain::attachAxis(QAbstractAxis* axis)
159 bool XLogYDomain::attachAxis(QAbstractAxis* axis)
160 {
160 {
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
162
162
163 if(logAxis && logAxis->orientation()==Qt::Vertical)
163 if(logAxis && logAxis->orientation()==Qt::Vertical)
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
165
165
166 return AbstractDomain::attachAxis(axis);
166 return AbstractDomain::attachAxis(axis);
167 }
167 }
168
168
169 bool XLogYDomain::detachAxis(QAbstractAxis* axis)
169 bool XLogYDomain::detachAxis(QAbstractAxis* axis)
170 {
170 {
171 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
171 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
172
172
173 if(logAxis && logAxis->orientation()==Qt::Vertical)
173 if(logAxis && logAxis->orientation()==Qt::Vertical)
174 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
174 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
175
175
176 return AbstractDomain::detachAxis(axis);
176 return AbstractDomain::detachAxis(axis);
177 }
177 }
178
178
179 void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
179 void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
180 {
180 {
181 m_logBaseY = baseY;
181 m_logBaseY = baseY;
182 m_logMinY = log10(m_minY) / log10(m_logBaseY);
183 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
182 }
184 }
183
185
184 // operators
186 // operators
185
187
186 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
188 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
187 {
189 {
188 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
190 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
189 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
191 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
190 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
192 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
191 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
193 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
192 }
194 }
193
195
194
196
195 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
197 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
196 {
198 {
197 return !(domain1 == domain2);
199 return !(domain1 == domain2);
198 }
200 }
199
201
200
202
201 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
203 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
202 {
204 {
203 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
205 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
204 return dbg.maybeSpace();
206 return dbg.maybeSpace();
205 }
207 }
206
208
207 #include "moc_xlogydomain_p.cpp"
209 #include "moc_xlogydomain_p.cpp"
208
210
209 QTCOMMERCIALCHART_END_NAMESPACE
211 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now