@@ -1,138 +1,138 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/chartbarcategoryaxisx_p.h> |
|
19 | #include <private/chartbarcategoryaxisx_p.h> | |
20 | #include <private/chartpresenter_p.h> |
|
20 | #include <private/chartpresenter_p.h> | |
21 | #include <private/qbarcategoryaxis_p.h> |
|
21 | #include <private/qbarcategoryaxis_p.h> | |
22 | #include <private/abstractchartlayout_p.h> |
|
22 | #include <private/abstractchartlayout_p.h> | |
23 | #include <QtCore/QDebug> |
|
23 | #include <QtCore/QDebug> | |
24 | #include <QtCore/QtMath> |
|
24 | #include <QtCore/QtMath> | |
25 |
|
25 | |||
26 | QT_CHARTS_BEGIN_NAMESPACE |
|
26 | QT_CHARTS_BEGIN_NAMESPACE | |
27 |
|
27 | |||
28 | ChartBarCategoryAxisX::ChartBarCategoryAxisX(QBarCategoryAxis *axis, QGraphicsItem* item) |
|
28 | ChartBarCategoryAxisX::ChartBarCategoryAxisX(QBarCategoryAxis *axis, QGraphicsItem* item) | |
29 | : HorizontalAxis(axis, item, true), |
|
29 | : HorizontalAxis(axis, item, true), | |
30 | m_categoriesAxis(axis) |
|
30 | m_categoriesAxis(axis) | |
31 | { |
|
31 | { | |
32 | QObject::connect(m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged())); |
|
32 | QObject::connect(m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged())); | |
33 | handleCategoriesChanged(); |
|
33 | handleCategoriesChanged(); | |
34 | } |
|
34 | } | |
35 |
|
35 | |||
36 | ChartBarCategoryAxisX::~ChartBarCategoryAxisX() |
|
36 | ChartBarCategoryAxisX::~ChartBarCategoryAxisX() | |
37 | { |
|
37 | { | |
38 | } |
|
38 | } | |
39 |
|
39 | |||
40 | QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const |
|
40 | QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const | |
41 | { |
|
41 | { | |
42 | QVector<qreal> points; |
|
42 | QVector<qreal> points; | |
43 | const QRectF& gridRect = gridGeometry(); |
|
43 | const QRectF& gridRect = gridGeometry(); | |
44 | qreal range = max() - min(); |
|
44 | qreal range = max() - min(); | |
45 | const qreal delta = gridRect.width() / range; |
|
45 | const qreal delta = gridRect.width() / range; | |
46 |
|
46 | |||
47 | if (delta < 2) |
|
47 | if (delta < 2) | |
48 | return points; |
|
48 | return points; | |
49 |
|
49 | |||
50 | qreal adjustedMin = min() + 0.5; |
|
50 | qreal adjustedMin = min() + 0.5; | |
51 |
qreal offset = ( |
|
51 | qreal offset = (qCeil(adjustedMin) - adjustedMin) * delta; | |
52 |
|
52 | |||
53 | int count = qFloor(range); |
|
53 | int count = qFloor(range); | |
54 | if (count < 1) |
|
54 | if (count < 1) | |
55 | return points; |
|
55 | return points; | |
56 |
|
56 | |||
57 | points.resize(count + 2); |
|
57 | points.resize(count + 2); | |
58 |
|
58 | |||
59 | for (int i = 0; i < count + 2; ++i) |
|
59 | for (int i = 0; i < count + 2; ++i) | |
60 | points[i] = offset + (qreal(i) * delta) + gridRect.left(); |
|
60 | points[i] = offset + (qreal(i) * delta) + gridRect.left(); | |
61 |
|
61 | |||
62 | return points; |
|
62 | return points; | |
63 | } |
|
63 | } | |
64 |
|
64 | |||
65 | QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const |
|
65 | QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const | |
66 | { |
|
66 | { | |
67 | QStringList result ; |
|
67 | QStringList result ; | |
68 | const QRectF &gridRect = gridGeometry(); |
|
68 | const QRectF &gridRect = gridGeometry(); | |
69 | qreal d = (max() - min()) / gridRect.width(); |
|
69 | qreal d = (max() - min()) / gridRect.width(); | |
70 |
|
70 | |||
71 | for (int i = 0; i < layout.count() - 1; ++i) { |
|
71 | for (int i = 0; i < layout.count() - 1; ++i) { | |
72 | qreal x = qFloor((((layout[i] + layout[i + 1]) / 2 - gridRect.left()) * d + min() + 0.5)); |
|
72 | qreal x = qFloor((((layout[i] + layout[i + 1]) / 2 - gridRect.left()) * d + min() + 0.5)); | |
73 | if (x < max() && (x >= 0) && x < m_categoriesAxis->categories().count()) { |
|
73 | if (x < max() && (x >= 0) && x < m_categoriesAxis->categories().count()) { | |
74 | result << m_categoriesAxis->categories().at(x); |
|
74 | result << m_categoriesAxis->categories().at(x); | |
75 | } else { |
|
75 | } else { | |
76 | // No label for x coordinate |
|
76 | // No label for x coordinate | |
77 | result << QString(); |
|
77 | result << QString(); | |
78 | } |
|
78 | } | |
79 | } |
|
79 | } | |
80 | result << QString(); |
|
80 | result << QString(); | |
81 | return result; |
|
81 | return result; | |
82 | } |
|
82 | } | |
83 |
|
83 | |||
84 |
|
84 | |||
85 | void ChartBarCategoryAxisX::updateGeometry() |
|
85 | void ChartBarCategoryAxisX::updateGeometry() | |
86 | { |
|
86 | { | |
87 | const QVector<qreal>& layout = ChartAxisElement::layout(); |
|
87 | const QVector<qreal>& layout = ChartAxisElement::layout(); | |
88 | if (layout.isEmpty()) |
|
88 | if (layout.isEmpty()) | |
89 | return; |
|
89 | return; | |
90 | setLabels(createCategoryLabels(layout)); |
|
90 | setLabels(createCategoryLabels(layout)); | |
91 | HorizontalAxis::updateGeometry(); |
|
91 | HorizontalAxis::updateGeometry(); | |
92 | } |
|
92 | } | |
93 |
|
93 | |||
94 | void ChartBarCategoryAxisX::handleCategoriesChanged() |
|
94 | void ChartBarCategoryAxisX::handleCategoriesChanged() | |
95 | { |
|
95 | { | |
96 | QGraphicsLayoutItem::updateGeometry(); |
|
96 | QGraphicsLayoutItem::updateGeometry(); | |
97 | if(presenter()) presenter()->layout()->invalidate(); |
|
97 | if(presenter()) presenter()->layout()->invalidate(); | |
98 | } |
|
98 | } | |
99 |
|
99 | |||
100 | QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
|
100 | QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const | |
101 | { |
|
101 | { | |
102 | Q_UNUSED(constraint) |
|
102 | Q_UNUSED(constraint) | |
103 |
|
103 | |||
104 | QSizeF sh; |
|
104 | QSizeF sh; | |
105 | QSizeF base = HorizontalAxis::sizeHint(which, constraint); |
|
105 | QSizeF base = HorizontalAxis::sizeHint(which, constraint); | |
106 | QStringList ticksList = m_categoriesAxis->categories(); |
|
106 | QStringList ticksList = m_categoriesAxis->categories(); | |
107 |
|
107 | |||
108 | qreal width = 0; // Width is irrelevant for X axes with interval labels |
|
108 | qreal width = 0; // Width is irrelevant for X axes with interval labels | |
109 | qreal height = 0; |
|
109 | qreal height = 0; | |
110 |
|
110 | |||
111 | switch (which) { |
|
111 | switch (which) { | |
112 | case Qt::MinimumSize: { |
|
112 | case Qt::MinimumSize: { | |
113 | QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), |
|
113 | QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), | |
114 | QStringLiteral("..."), |
|
114 | QStringLiteral("..."), | |
115 | axis()->labelsAngle()); |
|
115 | axis()->labelsAngle()); | |
116 | height = boundingRect.height() + labelPadding() + base.height() + 1.0; |
|
116 | height = boundingRect.height() + labelPadding() + base.height() + 1.0; | |
117 | sh = QSizeF(width, height); |
|
117 | sh = QSizeF(width, height); | |
118 | break; |
|
118 | break; | |
119 | } |
|
119 | } | |
120 | case Qt::PreferredSize:{ |
|
120 | case Qt::PreferredSize:{ | |
121 | qreal labelHeight = 0.0; |
|
121 | qreal labelHeight = 0.0; | |
122 | foreach (const QString& s, ticksList) { |
|
122 | foreach (const QString& s, ticksList) { | |
123 | QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); |
|
123 | QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); | |
124 | labelHeight = qMax(rect.height(), labelHeight); |
|
124 | labelHeight = qMax(rect.height(), labelHeight); | |
125 | } |
|
125 | } | |
126 | height = labelHeight + labelPadding() + base.height() + 1.0; |
|
126 | height = labelHeight + labelPadding() + base.height() + 1.0; | |
127 | sh = QSizeF(width, height); |
|
127 | sh = QSizeF(width, height); | |
128 | break; |
|
128 | break; | |
129 | } |
|
129 | } | |
130 | default: |
|
130 | default: | |
131 | break; |
|
131 | break; | |
132 | } |
|
132 | } | |
133 | return sh; |
|
133 | return sh; | |
134 | } |
|
134 | } | |
135 |
|
135 | |||
136 | #include "moc_chartbarcategoryaxisx_p.cpp" |
|
136 | #include "moc_chartbarcategoryaxisx_p.cpp" | |
137 |
|
137 | |||
138 | QT_CHARTS_END_NAMESPACE |
|
138 | QT_CHARTS_END_NAMESPACE |
@@ -1,140 +1,140 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/chartbarcategoryaxisy_p.h> |
|
19 | #include <private/chartbarcategoryaxisy_p.h> | |
20 | #include <private/chartpresenter_p.h> |
|
20 | #include <private/chartpresenter_p.h> | |
21 | #include <private/qbarcategoryaxis_p.h> |
|
21 | #include <private/qbarcategoryaxis_p.h> | |
22 | #include <private/abstractchartlayout_p.h> |
|
22 | #include <private/abstractchartlayout_p.h> | |
23 | #include <QtCore/QtMath> |
|
23 | #include <QtCore/QtMath> | |
24 | #include <QtCore/QDebug> |
|
24 | #include <QtCore/QDebug> | |
25 |
|
25 | |||
26 | QT_CHARTS_BEGIN_NAMESPACE |
|
26 | QT_CHARTS_BEGIN_NAMESPACE | |
27 |
|
27 | |||
28 | ChartBarCategoryAxisY::ChartBarCategoryAxisY(QBarCategoryAxis *axis, QGraphicsItem* item) |
|
28 | ChartBarCategoryAxisY::ChartBarCategoryAxisY(QBarCategoryAxis *axis, QGraphicsItem* item) | |
29 | : VerticalAxis(axis, item, true), |
|
29 | : VerticalAxis(axis, item, true), | |
30 | m_categoriesAxis(axis) |
|
30 | m_categoriesAxis(axis) | |
31 | { |
|
31 | { | |
32 | QObject::connect( m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged())); |
|
32 | QObject::connect( m_categoriesAxis,SIGNAL(categoriesChanged()),this, SLOT(handleCategoriesChanged())); | |
33 | handleCategoriesChanged(); |
|
33 | handleCategoriesChanged(); | |
34 | } |
|
34 | } | |
35 |
|
35 | |||
36 | ChartBarCategoryAxisY::~ChartBarCategoryAxisY() |
|
36 | ChartBarCategoryAxisY::~ChartBarCategoryAxisY() | |
37 | { |
|
37 | { | |
38 | } |
|
38 | } | |
39 |
|
39 | |||
40 | QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const |
|
40 | QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const | |
41 | { |
|
41 | { | |
42 | QVector<qreal> points; |
|
42 | QVector<qreal> points; | |
43 | const QRectF& gridRect = gridGeometry(); |
|
43 | const QRectF& gridRect = gridGeometry(); | |
44 | qreal range = max() - min(); |
|
44 | qreal range = max() - min(); | |
45 | const qreal delta = gridRect.height() / range; |
|
45 | const qreal delta = gridRect.height() / range; | |
46 |
|
46 | |||
47 | if (delta < 2) |
|
47 | if (delta < 2) | |
48 | return points; |
|
48 | return points; | |
49 |
|
49 | |||
50 | qreal adjustedMin = min() + 0.5; |
|
50 | qreal adjustedMin = min() + 0.5; | |
51 |
qreal offset = ( |
|
51 | qreal offset = (qCeil(adjustedMin) - adjustedMin) * delta; | |
52 |
|
52 | |||
53 | int count = qFloor(range); |
|
53 | int count = qFloor(range); | |
54 | if (count < 1) |
|
54 | if (count < 1) | |
55 | return points; |
|
55 | return points; | |
56 |
|
56 | |||
57 | points.resize(count + 2); |
|
57 | points.resize(count + 2); | |
58 |
|
58 | |||
59 | for (int i = 0; i < count + 2; ++i) |
|
59 | for (int i = 0; i < count + 2; ++i) | |
60 | points[i] = gridRect.bottom() - (qreal(i) * delta) - offset; |
|
60 | points[i] = gridRect.bottom() - (qreal(i) * delta) - offset; | |
61 |
|
61 | |||
62 | return points; |
|
62 | return points; | |
63 | } |
|
63 | } | |
64 |
|
64 | |||
65 | QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const |
|
65 | QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const | |
66 | { |
|
66 | { | |
67 | QStringList result; |
|
67 | QStringList result; | |
68 | const QRectF &gridRect = gridGeometry(); |
|
68 | const QRectF &gridRect = gridGeometry(); | |
69 | qreal d = (max() - min()) / gridRect.height(); |
|
69 | qreal d = (max() - min()) / gridRect.height(); | |
70 |
|
70 | |||
71 | for (int i = 0; i < layout.count() - 1; ++i) { |
|
71 | for (int i = 0; i < layout.count() - 1; ++i) { | |
72 | qreal x = qFloor(((gridRect.height() - (layout[i + 1] + layout[i]) / 2 + gridRect.top()) * d + min() + 0.5)); |
|
72 | qreal x = qFloor(((gridRect.height() - (layout[i + 1] + layout[i]) / 2 + gridRect.top()) * d + min() + 0.5)); | |
73 | if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) { |
|
73 | if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) { | |
74 | result << m_categoriesAxis->categories().at(x); |
|
74 | result << m_categoriesAxis->categories().at(x); | |
75 | } else { |
|
75 | } else { | |
76 | // No label for x coordinate |
|
76 | // No label for x coordinate | |
77 | result << QString(); |
|
77 | result << QString(); | |
78 | } |
|
78 | } | |
79 | } |
|
79 | } | |
80 | result << QString(); |
|
80 | result << QString(); | |
81 | return result; |
|
81 | return result; | |
82 | } |
|
82 | } | |
83 |
|
83 | |||
84 | void ChartBarCategoryAxisY::updateGeometry() |
|
84 | void ChartBarCategoryAxisY::updateGeometry() | |
85 | { |
|
85 | { | |
86 | const QVector<qreal>& layout = ChartAxisElement::layout(); |
|
86 | const QVector<qreal>& layout = ChartAxisElement::layout(); | |
87 | if (layout.isEmpty()) |
|
87 | if (layout.isEmpty()) | |
88 | return; |
|
88 | return; | |
89 | setLabels(createCategoryLabels(layout)); |
|
89 | setLabels(createCategoryLabels(layout)); | |
90 | VerticalAxis::updateGeometry(); |
|
90 | VerticalAxis::updateGeometry(); | |
91 | } |
|
91 | } | |
92 |
|
92 | |||
93 | void ChartBarCategoryAxisY::handleCategoriesChanged() |
|
93 | void ChartBarCategoryAxisY::handleCategoriesChanged() | |
94 | { |
|
94 | { | |
95 | QGraphicsLayoutItem::updateGeometry(); |
|
95 | QGraphicsLayoutItem::updateGeometry(); | |
96 | if(presenter()) presenter()->layout()->invalidate(); |
|
96 | if(presenter()) presenter()->layout()->invalidate(); | |
97 | } |
|
97 | } | |
98 |
|
98 | |||
99 | QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
|
99 | QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const | |
100 | { |
|
100 | { | |
101 | Q_UNUSED(constraint) |
|
101 | Q_UNUSED(constraint) | |
102 |
|
102 | |||
103 | QSizeF sh; |
|
103 | QSizeF sh; | |
104 | QSizeF base = VerticalAxis::sizeHint(which, constraint); |
|
104 | QSizeF base = VerticalAxis::sizeHint(which, constraint); | |
105 | QStringList ticksList = m_categoriesAxis->categories(); |
|
105 | QStringList ticksList = m_categoriesAxis->categories(); | |
106 | qreal width = 0; |
|
106 | qreal width = 0; | |
107 | qreal height = 0; // Height is irrelevant for Y axes with interval labels |
|
107 | qreal height = 0; // Height is irrelevant for Y axes with interval labels | |
108 |
|
108 | |||
109 | switch (which) { |
|
109 | switch (which) { | |
110 | case Qt::MinimumSize: { |
|
110 | case Qt::MinimumSize: { | |
111 | QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), |
|
111 | QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), | |
112 | QStringLiteral("..."), |
|
112 | QStringLiteral("..."), | |
113 | axis()->labelsAngle()); |
|
113 | axis()->labelsAngle()); | |
114 | width = boundingRect.width() + labelPadding() + base.width() + 1.0; |
|
114 | width = boundingRect.width() + labelPadding() + base.width() + 1.0; | |
115 | if (base.width() > 0.0) |
|
115 | if (base.width() > 0.0) | |
116 | width += labelPadding(); |
|
116 | width += labelPadding(); | |
117 | sh = QSizeF(width, height); |
|
117 | sh = QSizeF(width, height); | |
118 | break; |
|
118 | break; | |
119 | } |
|
119 | } | |
120 | case Qt::PreferredSize:{ |
|
120 | case Qt::PreferredSize:{ | |
121 | qreal labelWidth = 0.0; |
|
121 | qreal labelWidth = 0.0; | |
122 | foreach (const QString& s, ticksList) { |
|
122 | foreach (const QString& s, ticksList) { | |
123 | QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); |
|
123 | QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); | |
124 | labelWidth = qMax(rect.width(), labelWidth); |
|
124 | labelWidth = qMax(rect.width(), labelWidth); | |
125 | } |
|
125 | } | |
126 | width = labelWidth + labelPadding() + base.width() + 1.0; |
|
126 | width = labelWidth + labelPadding() + base.width() + 1.0; | |
127 | if (base.width() > 0.0) |
|
127 | if (base.width() > 0.0) | |
128 | width += labelPadding(); |
|
128 | width += labelPadding(); | |
129 | sh = QSizeF(width, height); |
|
129 | sh = QSizeF(width, height); | |
130 | break; |
|
130 | break; | |
131 | } |
|
131 | } | |
132 | default: |
|
132 | default: | |
133 | break; |
|
133 | break; | |
134 | } |
|
134 | } | |
135 | return sh; |
|
135 | return sh; | |
136 | } |
|
136 | } | |
137 |
|
137 | |||
138 | #include "moc_chartbarcategoryaxisy_p.cpp" |
|
138 | #include "moc_chartbarcategoryaxisy_p.cpp" | |
139 |
|
139 | |||
140 | QT_CHARTS_END_NAMESPACE |
|
140 | QT_CHARTS_END_NAMESPACE |
@@ -1,390 +1,391 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/chartaxiselement_p.h> |
|
19 | #include <private/chartaxiselement_p.h> | |
20 | #include <private/qabstractaxis_p.h> |
|
20 | #include <private/qabstractaxis_p.h> | |
21 | #include <private/chartpresenter_p.h> |
|
21 | #include <private/chartpresenter_p.h> | |
22 | #include <private/abstractchartlayout_p.h> |
|
22 | #include <private/abstractchartlayout_p.h> | |
23 | #include <QtCore/QtMath> |
|
23 | #include <QtCore/QtMath> | |
24 | #include <QtCore/QDateTime> |
|
24 | #include <QtCore/QDateTime> | |
25 | #include <QtGui/QTextDocument> |
|
25 | #include <QtGui/QTextDocument> | |
|
26 | #include <cmath> | |||
26 |
|
27 | |||
27 | QT_CHARTS_BEGIN_NAMESPACE |
|
28 | QT_CHARTS_BEGIN_NAMESPACE | |
28 |
|
29 | |||
29 | static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.\\'lhjztL]*([dicuoxfegXFEG])"; |
|
30 | static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.\\'lhjztL]*([dicuoxfegXFEG])"; | |
30 | static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.(\\d+)([defgiEG])(.*)$"; |
|
31 | static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.(\\d+)([defgiEG])(.*)$"; | |
31 | static QRegExp *labelFormatMatcher = 0; |
|
32 | static QRegExp *labelFormatMatcher = 0; | |
32 | static QRegExp *labelFormatMatcherLocalized = 0; |
|
33 | static QRegExp *labelFormatMatcherLocalized = 0; | |
33 | class StaticLabelFormatMatcherDeleter |
|
34 | class StaticLabelFormatMatcherDeleter | |
34 | { |
|
35 | { | |
35 | public: |
|
36 | public: | |
36 | StaticLabelFormatMatcherDeleter() {} |
|
37 | StaticLabelFormatMatcherDeleter() {} | |
37 | ~StaticLabelFormatMatcherDeleter() { |
|
38 | ~StaticLabelFormatMatcherDeleter() { | |
38 | delete labelFormatMatcher; |
|
39 | delete labelFormatMatcher; | |
39 | delete labelFormatMatcherLocalized; |
|
40 | delete labelFormatMatcherLocalized; | |
40 | } |
|
41 | } | |
41 | }; |
|
42 | }; | |
42 | static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter; |
|
43 | static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter; | |
43 |
|
44 | |||
44 | ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis) |
|
45 | ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis) | |
45 | : ChartElement(item), |
|
46 | : ChartElement(item), | |
46 | m_axis(axis), |
|
47 | m_axis(axis), | |
47 | m_animation(0), |
|
48 | m_animation(0), | |
48 | m_grid(new QGraphicsItemGroup(item)), |
|
49 | m_grid(new QGraphicsItemGroup(item)), | |
49 | m_arrow(new QGraphicsItemGroup(item)), |
|
50 | m_arrow(new QGraphicsItemGroup(item)), | |
50 | m_shades(new QGraphicsItemGroup(item)), |
|
51 | m_shades(new QGraphicsItemGroup(item)), | |
51 | m_labels(new QGraphicsItemGroup(item)), |
|
52 | m_labels(new QGraphicsItemGroup(item)), | |
52 | m_title(new QGraphicsTextItem(item)), |
|
53 | m_title(new QGraphicsTextItem(item)), | |
53 | m_intervalAxis(intervalAxis) |
|
54 | m_intervalAxis(intervalAxis) | |
54 |
|
55 | |||
55 | { |
|
56 | { | |
56 | //initial initialization |
|
57 | //initial initialization | |
57 | m_arrow->setHandlesChildEvents(false); |
|
58 | m_arrow->setHandlesChildEvents(false); | |
58 | m_arrow->setZValue(ChartPresenter::AxisZValue); |
|
59 | m_arrow->setZValue(ChartPresenter::AxisZValue); | |
59 | m_labels->setZValue(ChartPresenter::AxisZValue); |
|
60 | m_labels->setZValue(ChartPresenter::AxisZValue); | |
60 | m_shades->setZValue(ChartPresenter::ShadesZValue); |
|
61 | m_shades->setZValue(ChartPresenter::ShadesZValue); | |
61 | m_grid->setZValue(ChartPresenter::GridZValue); |
|
62 | m_grid->setZValue(ChartPresenter::GridZValue); | |
62 | m_title->setZValue(ChartPresenter::GridZValue); |
|
63 | m_title->setZValue(ChartPresenter::GridZValue); | |
63 | m_title->document()->setDocumentMargin(ChartPresenter::textMargin()); |
|
64 | m_title->document()->setDocumentMargin(ChartPresenter::textMargin()); | |
64 | handleVisibleChanged(axis->isVisible()); |
|
65 | handleVisibleChanged(axis->isVisible()); | |
65 | connectSlots(); |
|
66 | connectSlots(); | |
66 |
|
67 | |||
67 | setFlag(QGraphicsItem::ItemHasNoContents, true); |
|
68 | setFlag(QGraphicsItem::ItemHasNoContents, true); | |
68 | } |
|
69 | } | |
69 |
|
70 | |||
70 | ChartAxisElement::~ChartAxisElement() |
|
71 | ChartAxisElement::~ChartAxisElement() | |
71 | { |
|
72 | { | |
72 | } |
|
73 | } | |
73 |
|
74 | |||
74 | void ChartAxisElement::connectSlots() |
|
75 | void ChartAxisElement::connectSlots() | |
75 | { |
|
76 | { | |
76 | QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool))); |
|
77 | QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool))); | |
77 | QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool))); |
|
78 | QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool))); | |
78 | QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool))); |
|
79 | QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool))); | |
79 | QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool))); |
|
80 | QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool))); | |
80 | QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool))); |
|
81 | QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool))); | |
81 | QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int))); |
|
82 | QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int))); | |
82 | QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&))); |
|
83 | QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&))); | |
83 | QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&))); |
|
84 | QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&))); | |
84 | QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&))); |
|
85 | QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&))); | |
85 | QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&))); |
|
86 | QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&))); | |
86 | QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&))); |
|
87 | QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&))); | |
87 | QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&))); |
|
88 | QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&))); | |
88 | QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&))); |
|
89 | QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&))); | |
89 | QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&))); |
|
90 | QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&))); | |
90 | QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&))); |
|
91 | QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&))); | |
91 | QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool))); |
|
92 | QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool))); | |
92 | QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal))); |
|
93 | QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal))); | |
93 | } |
|
94 | } | |
94 |
|
95 | |||
95 | void ChartAxisElement::handleArrowVisibleChanged(bool visible) |
|
96 | void ChartAxisElement::handleArrowVisibleChanged(bool visible) | |
96 | { |
|
97 | { | |
97 | m_arrow->setVisible(visible); |
|
98 | m_arrow->setVisible(visible); | |
98 | } |
|
99 | } | |
99 |
|
100 | |||
100 | void ChartAxisElement::handleGridVisibleChanged(bool visible) |
|
101 | void ChartAxisElement::handleGridVisibleChanged(bool visible) | |
101 | { |
|
102 | { | |
102 | m_grid->setVisible(visible); |
|
103 | m_grid->setVisible(visible); | |
103 | } |
|
104 | } | |
104 |
|
105 | |||
105 | void ChartAxisElement::handleLabelsVisibleChanged(bool visible) |
|
106 | void ChartAxisElement::handleLabelsVisibleChanged(bool visible) | |
106 | { |
|
107 | { | |
107 | QGraphicsLayoutItem::updateGeometry(); |
|
108 | QGraphicsLayoutItem::updateGeometry(); | |
108 | presenter()->layout()->invalidate(); |
|
109 | presenter()->layout()->invalidate(); | |
109 | m_labels->setVisible(visible); |
|
110 | m_labels->setVisible(visible); | |
110 | } |
|
111 | } | |
111 |
|
112 | |||
112 | void ChartAxisElement::handleShadesVisibleChanged(bool visible) |
|
113 | void ChartAxisElement::handleShadesVisibleChanged(bool visible) | |
113 | { |
|
114 | { | |
114 | m_shades->setVisible(visible); |
|
115 | m_shades->setVisible(visible); | |
115 | } |
|
116 | } | |
116 |
|
117 | |||
117 | void ChartAxisElement::handleTitleVisibleChanged(bool visible) |
|
118 | void ChartAxisElement::handleTitleVisibleChanged(bool visible) | |
118 | { |
|
119 | { | |
119 | QGraphicsLayoutItem::updateGeometry(); |
|
120 | QGraphicsLayoutItem::updateGeometry(); | |
120 | presenter()->layout()->invalidate(); |
|
121 | presenter()->layout()->invalidate(); | |
121 | m_title->setVisible(visible); |
|
122 | m_title->setVisible(visible); | |
122 | } |
|
123 | } | |
123 |
|
124 | |||
124 | void ChartAxisElement::handleLabelsAngleChanged(int angle) |
|
125 | void ChartAxisElement::handleLabelsAngleChanged(int angle) | |
125 | { |
|
126 | { | |
126 | foreach (QGraphicsItem *item, m_labels->childItems()) |
|
127 | foreach (QGraphicsItem *item, m_labels->childItems()) | |
127 | item->setRotation(angle); |
|
128 | item->setRotation(angle); | |
128 |
|
129 | |||
129 | QGraphicsLayoutItem::updateGeometry(); |
|
130 | QGraphicsLayoutItem::updateGeometry(); | |
130 | presenter()->layout()->invalidate(); |
|
131 | presenter()->layout()->invalidate(); | |
131 | } |
|
132 | } | |
132 |
|
133 | |||
133 | void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush) |
|
134 | void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush) | |
134 | { |
|
135 | { | |
135 | foreach (QGraphicsItem *item, m_labels->childItems()) |
|
136 | foreach (QGraphicsItem *item, m_labels->childItems()) | |
136 | static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color()); |
|
137 | static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color()); | |
137 | } |
|
138 | } | |
138 |
|
139 | |||
139 | void ChartAxisElement::handleLabelsFontChanged(const QFont &font) |
|
140 | void ChartAxisElement::handleLabelsFontChanged(const QFont &font) | |
140 | { |
|
141 | { | |
141 | foreach (QGraphicsItem *item, m_labels->childItems()) |
|
142 | foreach (QGraphicsItem *item, m_labels->childItems()) | |
142 | static_cast<QGraphicsTextItem *>(item)->setFont(font); |
|
143 | static_cast<QGraphicsTextItem *>(item)->setFont(font); | |
143 | QGraphicsLayoutItem::updateGeometry(); |
|
144 | QGraphicsLayoutItem::updateGeometry(); | |
144 | presenter()->layout()->invalidate(); |
|
145 | presenter()->layout()->invalidate(); | |
145 | } |
|
146 | } | |
146 |
|
147 | |||
147 | void ChartAxisElement::handleTitleTextChanged(const QString &title) |
|
148 | void ChartAxisElement::handleTitleTextChanged(const QString &title) | |
148 | { |
|
149 | { | |
149 | QGraphicsLayoutItem::updateGeometry(); |
|
150 | QGraphicsLayoutItem::updateGeometry(); | |
150 | presenter()->layout()->invalidate(); |
|
151 | presenter()->layout()->invalidate(); | |
151 | if (title.isEmpty() || !m_title->isVisible()) |
|
152 | if (title.isEmpty() || !m_title->isVisible()) | |
152 | m_title->setHtml(title); |
|
153 | m_title->setHtml(title); | |
153 | } |
|
154 | } | |
154 |
|
155 | |||
155 | void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush) |
|
156 | void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush) | |
156 | { |
|
157 | { | |
157 | m_title->setDefaultTextColor(brush.color()); |
|
158 | m_title->setDefaultTextColor(brush.color()); | |
158 | } |
|
159 | } | |
159 |
|
160 | |||
160 | void ChartAxisElement::handleTitleFontChanged(const QFont &font) |
|
161 | void ChartAxisElement::handleTitleFontChanged(const QFont &font) | |
161 | { |
|
162 | { | |
162 | if (m_title->font() != font) { |
|
163 | if (m_title->font() != font) { | |
163 | m_title->setFont(font); |
|
164 | m_title->setFont(font); | |
164 | QGraphicsLayoutItem::updateGeometry(); |
|
165 | QGraphicsLayoutItem::updateGeometry(); | |
165 | presenter()->layout()->invalidate(); |
|
166 | presenter()->layout()->invalidate(); | |
166 | } |
|
167 | } | |
167 | } |
|
168 | } | |
168 |
|
169 | |||
169 | void ChartAxisElement::handleVisibleChanged(bool visible) |
|
170 | void ChartAxisElement::handleVisibleChanged(bool visible) | |
170 | { |
|
171 | { | |
171 | setVisible(visible); |
|
172 | setVisible(visible); | |
172 | if (!visible) { |
|
173 | if (!visible) { | |
173 | m_grid->setVisible(visible); |
|
174 | m_grid->setVisible(visible); | |
174 | m_arrow->setVisible(visible); |
|
175 | m_arrow->setVisible(visible); | |
175 | m_shades->setVisible(visible); |
|
176 | m_shades->setVisible(visible); | |
176 | m_labels->setVisible(visible); |
|
177 | m_labels->setVisible(visible); | |
177 | m_title->setVisible(visible); |
|
178 | m_title->setVisible(visible); | |
178 | } else { |
|
179 | } else { | |
179 | m_grid->setVisible(axis()->isGridLineVisible()); |
|
180 | m_grid->setVisible(axis()->isGridLineVisible()); | |
180 | m_arrow->setVisible(axis()->isLineVisible()); |
|
181 | m_arrow->setVisible(axis()->isLineVisible()); | |
181 | m_shades->setVisible(axis()->shadesVisible()); |
|
182 | m_shades->setVisible(axis()->shadesVisible()); | |
182 | m_labels->setVisible(axis()->labelsVisible()); |
|
183 | m_labels->setVisible(axis()->labelsVisible()); | |
183 | m_title->setVisible(axis()->isTitleVisible()); |
|
184 | m_title->setVisible(axis()->isTitleVisible()); | |
184 | } |
|
185 | } | |
185 |
|
186 | |||
186 | if (presenter()) presenter()->layout()->invalidate(); |
|
187 | if (presenter()) presenter()->layout()->invalidate(); | |
187 | } |
|
188 | } | |
188 |
|
189 | |||
189 | void ChartAxisElement::handleRangeChanged(qreal min, qreal max) |
|
190 | void ChartAxisElement::handleRangeChanged(qreal min, qreal max) | |
190 | { |
|
191 | { | |
191 | Q_UNUSED(min); |
|
192 | Q_UNUSED(min); | |
192 | Q_UNUSED(max); |
|
193 | Q_UNUSED(max); | |
193 |
|
194 | |||
194 | if (!isEmpty()) { |
|
195 | if (!isEmpty()) { | |
195 | QVector<qreal> layout = calculateLayout(); |
|
196 | QVector<qreal> layout = calculateLayout(); | |
196 | updateLayout(layout); |
|
197 | updateLayout(layout); | |
197 | QSizeF before = effectiveSizeHint(Qt::PreferredSize); |
|
198 | QSizeF before = effectiveSizeHint(Qt::PreferredSize); | |
198 | QSizeF after = sizeHint(Qt::PreferredSize); |
|
199 | QSizeF after = sizeHint(Qt::PreferredSize); | |
199 |
|
200 | |||
200 | if (before != after) { |
|
201 | if (before != after) { | |
201 | QGraphicsLayoutItem::updateGeometry(); |
|
202 | QGraphicsLayoutItem::updateGeometry(); | |
202 | // We don't want to call invalidate on layout, since it will change minimum size of |
|
203 | // We don't want to call invalidate on layout, since it will change minimum size of | |
203 | // component, which we would like to avoid since it causes nasty flips when scrolling |
|
204 | // component, which we would like to avoid since it causes nasty flips when scrolling | |
204 | // or zooming, instead recalculate layout and use plotArea for extra space. |
|
205 | // or zooming, instead recalculate layout and use plotArea for extra space. | |
205 | presenter()->layout()->setGeometry(presenter()->layout()->geometry()); |
|
206 | presenter()->layout()->setGeometry(presenter()->layout()->geometry()); | |
206 | } |
|
207 | } | |
207 | } |
|
208 | } | |
208 | } |
|
209 | } | |
209 |
|
210 | |||
210 | bool ChartAxisElement::isEmpty() |
|
211 | bool ChartAxisElement::isEmpty() | |
211 | { |
|
212 | { | |
212 | return axisGeometry().isEmpty() |
|
213 | return axisGeometry().isEmpty() | |
213 | || gridGeometry().isEmpty() |
|
214 | || gridGeometry().isEmpty() | |
214 | || qFuzzyCompare(min(), max()); |
|
215 | || qFuzzyCompare(min(), max()); | |
215 | } |
|
216 | } | |
216 |
|
217 | |||
217 | qreal ChartAxisElement::min() const |
|
218 | qreal ChartAxisElement::min() const | |
218 | { |
|
219 | { | |
219 | return m_axis->d_ptr->min(); |
|
220 | return m_axis->d_ptr->min(); | |
220 | } |
|
221 | } | |
221 |
|
222 | |||
222 | qreal ChartAxisElement::max() const |
|
223 | qreal ChartAxisElement::max() const | |
223 | { |
|
224 | { | |
224 | return m_axis->d_ptr->max(); |
|
225 | return m_axis->d_ptr->max(); | |
225 | } |
|
226 | } | |
226 |
|
227 | |||
227 | QString ChartAxisElement::formatLabel(const QString &formatSpec, const QByteArray &array, |
|
228 | QString ChartAxisElement::formatLabel(const QString &formatSpec, const QByteArray &array, | |
228 | qreal value, int precision, const QString &preStr, |
|
229 | qreal value, int precision, const QString &preStr, | |
229 | const QString &postStr) const |
|
230 | const QString &postStr) const | |
230 | { |
|
231 | { | |
231 | QString retVal; |
|
232 | QString retVal; | |
232 | if (!formatSpec.isEmpty()) { |
|
233 | if (!formatSpec.isEmpty()) { | |
233 | if (formatSpec.at(0) == QLatin1Char('d') |
|
234 | if (formatSpec.at(0) == QLatin1Char('d') | |
234 | || formatSpec.at(0) == QLatin1Char('i') |
|
235 | || formatSpec.at(0) == QLatin1Char('i') | |
235 | || formatSpec.at(0) == QLatin1Char('c')) { |
|
236 | || formatSpec.at(0) == QLatin1Char('c')) { | |
236 | if (presenter()->localizeNumbers()) |
|
237 | if (presenter()->localizeNumbers()) | |
237 | retVal = preStr + presenter()->locale().toString(qint64(value)) + postStr; |
|
238 | retVal = preStr + presenter()->locale().toString(qint64(value)) + postStr; | |
238 | else |
|
239 | else | |
239 | retVal = QString().sprintf(array, qint64(value)); |
|
240 | retVal = QString().sprintf(array, qint64(value)); | |
240 | } else if (formatSpec.at(0) == QLatin1Char('u') |
|
241 | } else if (formatSpec.at(0) == QLatin1Char('u') | |
241 | || formatSpec.at(0) == QLatin1Char('o') |
|
242 | || formatSpec.at(0) == QLatin1Char('o') | |
242 | || formatSpec.at(0) == QLatin1Char('x') |
|
243 | || formatSpec.at(0) == QLatin1Char('x') | |
243 | || formatSpec.at(0) == QLatin1Char('X')) { |
|
244 | || formatSpec.at(0) == QLatin1Char('X')) { | |
244 | // These formats are not supported by localized numbers |
|
245 | // These formats are not supported by localized numbers | |
245 | retVal = QString().sprintf(array, quint64(value)); |
|
246 | retVal = QString().sprintf(array, quint64(value)); | |
246 | } else if (formatSpec.at(0) == QLatin1Char('f') |
|
247 | } else if (formatSpec.at(0) == QLatin1Char('f') | |
247 | || formatSpec.at(0) == QLatin1Char('F') |
|
248 | || formatSpec.at(0) == QLatin1Char('F') | |
248 | || formatSpec.at(0) == QLatin1Char('e') |
|
249 | || formatSpec.at(0) == QLatin1Char('e') | |
249 | || formatSpec.at(0) == QLatin1Char('E') |
|
250 | || formatSpec.at(0) == QLatin1Char('E') | |
250 | || formatSpec.at(0) == QLatin1Char('g') |
|
251 | || formatSpec.at(0) == QLatin1Char('g') | |
251 | || formatSpec.at(0) == QLatin1Char('G')) { |
|
252 | || formatSpec.at(0) == QLatin1Char('G')) { | |
252 | if (presenter()->localizeNumbers()) { |
|
253 | if (presenter()->localizeNumbers()) { | |
253 | retVal = preStr |
|
254 | retVal = preStr | |
254 | + presenter()->locale().toString(value, formatSpec.at(0).toLatin1(), |
|
255 | + presenter()->locale().toString(value, formatSpec.at(0).toLatin1(), | |
255 | precision) |
|
256 | precision) | |
256 | + postStr; |
|
257 | + postStr; | |
257 | } else { |
|
258 | } else { | |
258 | retVal = QString().sprintf(array, value); |
|
259 | retVal = QString().sprintf(array, value); | |
259 | } |
|
260 | } | |
260 | } |
|
261 | } | |
261 | } |
|
262 | } | |
262 | return retVal; |
|
263 | return retVal; | |
263 | } |
|
264 | } | |
264 |
|
265 | |||
265 | QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks, |
|
266 | QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks, | |
266 | const QString &format) const |
|
267 | const QString &format) const | |
267 | { |
|
268 | { | |
268 | QStringList labels; |
|
269 | QStringList labels; | |
269 |
|
270 | |||
270 | if (max <= min || ticks < 1) |
|
271 | if (max <= min || ticks < 1) | |
271 | return labels; |
|
272 | return labels; | |
272 |
|
273 | |||
273 | if (format.isNull()) { |
|
274 | if (format.isNull()) { | |
274 | int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0) + 1; |
|
275 | int n = qMax(int(-qFloor(std::log10((max - min) / (ticks - 1)))), 0) + 1; | |
275 | for (int i = 0; i < ticks; i++) { |
|
276 | for (int i = 0; i < ticks; i++) { | |
276 | qreal value = min + (i * (max - min) / (ticks - 1)); |
|
277 | qreal value = min + (i * (max - min) / (ticks - 1)); | |
277 | labels << presenter()->numberToString(value, 'f', n); |
|
278 | labels << presenter()->numberToString(value, 'f', n); | |
278 | } |
|
279 | } | |
279 | } else { |
|
280 | } else { | |
280 | QByteArray array = format.toLatin1(); |
|
281 | QByteArray array = format.toLatin1(); | |
281 | QString formatSpec; |
|
282 | QString formatSpec; | |
282 | QString preStr; |
|
283 | QString preStr; | |
283 | QString postStr; |
|
284 | QString postStr; | |
284 | int precision = 6; // Six is the default precision in Qt API |
|
285 | int precision = 6; // Six is the default precision in Qt API | |
285 | if (presenter()->localizeNumbers()) { |
|
286 | if (presenter()->localizeNumbers()) { | |
286 | if (!labelFormatMatcherLocalized) |
|
287 | if (!labelFormatMatcherLocalized) | |
287 | labelFormatMatcherLocalized |
|
288 | labelFormatMatcherLocalized | |
288 | = new QRegExp(QString::fromLatin1(labelFormatMatchLocalizedString)); |
|
289 | = new QRegExp(QString::fromLatin1(labelFormatMatchLocalizedString)); | |
289 | if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) { |
|
290 | if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) { | |
290 | preStr = labelFormatMatcherLocalized->cap(1); |
|
291 | preStr = labelFormatMatcherLocalized->cap(1); | |
291 | if (!labelFormatMatcherLocalized->cap(2).isEmpty()) |
|
292 | if (!labelFormatMatcherLocalized->cap(2).isEmpty()) | |
292 | precision = labelFormatMatcherLocalized->cap(2).toInt(); |
|
293 | precision = labelFormatMatcherLocalized->cap(2).toInt(); | |
293 | formatSpec = labelFormatMatcherLocalized->cap(3); |
|
294 | formatSpec = labelFormatMatcherLocalized->cap(3); | |
294 | postStr = labelFormatMatcherLocalized->cap(4); |
|
295 | postStr = labelFormatMatcherLocalized->cap(4); | |
295 | } |
|
296 | } | |
296 | } else { |
|
297 | } else { | |
297 | if (!labelFormatMatcher) |
|
298 | if (!labelFormatMatcher) | |
298 | labelFormatMatcher = new QRegExp(QString::fromLatin1(labelFormatMatchString)); |
|
299 | labelFormatMatcher = new QRegExp(QString::fromLatin1(labelFormatMatchString)); | |
299 | if (labelFormatMatcher->indexIn(format, 0) != -1) |
|
300 | if (labelFormatMatcher->indexIn(format, 0) != -1) | |
300 | formatSpec = labelFormatMatcher->cap(1); |
|
301 | formatSpec = labelFormatMatcher->cap(1); | |
301 | } |
|
302 | } | |
302 | for (int i = 0; i < ticks; i++) { |
|
303 | for (int i = 0; i < ticks; i++) { | |
303 | qreal value = min + (i * (max - min) / (ticks - 1)); |
|
304 | qreal value = min + (i * (max - min) / (ticks - 1)); | |
304 | labels << formatLabel(formatSpec, array, value, precision, preStr, postStr); |
|
305 | labels << formatLabel(formatSpec, array, value, precision, preStr, postStr); | |
305 | } |
|
306 | } | |
306 | } |
|
307 | } | |
307 |
|
308 | |||
308 | return labels; |
|
309 | return labels; | |
309 | } |
|
310 | } | |
310 |
|
311 | |||
311 | QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks, |
|
312 | QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks, | |
312 | const QString &format) const |
|
313 | const QString &format) const | |
313 | { |
|
314 | { | |
314 | QStringList labels; |
|
315 | QStringList labels; | |
315 |
|
316 | |||
316 | if (max <= min || ticks < 1) |
|
317 | if (max <= min || ticks < 1) | |
317 | return labels; |
|
318 | return labels; | |
318 |
|
319 | |||
319 | int firstTick; |
|
320 | int firstTick; | |
320 | if (base > 1) |
|
321 | if (base > 1) | |
321 |
firstTick = |
|
322 | firstTick = qCeil(std::log10(min) / std::log10(base)); | |
322 | else |
|
323 | else | |
323 |
firstTick = |
|
324 | firstTick = qCeil(std::log10(max) / std::log10(base)); | |
324 |
|
325 | |||
325 | if (format.isNull()) { |
|
326 | if (format.isNull()) { | |
326 | int n = 0; |
|
327 | int n = 0; | |
327 | if (ticks > 1) |
|
328 | if (ticks > 1) | |
328 | n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0); |
|
329 | n = qMax(int(-qFloor(std::log10((max - min) / (ticks - 1)))), 0); | |
329 | n++; |
|
330 | n++; | |
330 | for (int i = firstTick; i < ticks + firstTick; i++) { |
|
331 | for (int i = firstTick; i < ticks + firstTick; i++) { | |
331 | qreal value = qPow(base, i); |
|
332 | qreal value = qPow(base, i); | |
332 | labels << presenter()->numberToString(value, 'f', n); |
|
333 | labels << presenter()->numberToString(value, 'f', n); | |
333 | } |
|
334 | } | |
334 | } else { |
|
335 | } else { | |
335 | QByteArray array = format.toLatin1(); |
|
336 | QByteArray array = format.toLatin1(); | |
336 | QString formatSpec; |
|
337 | QString formatSpec; | |
337 | QString preStr; |
|
338 | QString preStr; | |
338 | QString postStr; |
|
339 | QString postStr; | |
339 | int precision = 6; // Six is the default precision in Qt API |
|
340 | int precision = 6; // Six is the default precision in Qt API | |
340 | if (presenter()->localizeNumbers()) { |
|
341 | if (presenter()->localizeNumbers()) { | |
341 | if (!labelFormatMatcherLocalized) |
|
342 | if (!labelFormatMatcherLocalized) | |
342 | labelFormatMatcherLocalized = |
|
343 | labelFormatMatcherLocalized = | |
343 | new QRegExp(QString::fromLatin1(labelFormatMatchLocalizedString)); |
|
344 | new QRegExp(QString::fromLatin1(labelFormatMatchLocalizedString)); | |
344 | if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) { |
|
345 | if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) { | |
345 | preStr = labelFormatMatcherLocalized->cap(1); |
|
346 | preStr = labelFormatMatcherLocalized->cap(1); | |
346 | if (!labelFormatMatcherLocalized->cap(2).isEmpty()) |
|
347 | if (!labelFormatMatcherLocalized->cap(2).isEmpty()) | |
347 | precision = labelFormatMatcherLocalized->cap(2).toInt(); |
|
348 | precision = labelFormatMatcherLocalized->cap(2).toInt(); | |
348 | formatSpec = labelFormatMatcherLocalized->cap(3); |
|
349 | formatSpec = labelFormatMatcherLocalized->cap(3); | |
349 | postStr = labelFormatMatcherLocalized->cap(4); |
|
350 | postStr = labelFormatMatcherLocalized->cap(4); | |
350 | } |
|
351 | } | |
351 | } else { |
|
352 | } else { | |
352 | if (!labelFormatMatcher) |
|
353 | if (!labelFormatMatcher) | |
353 | labelFormatMatcher = new QRegExp(QString::fromLatin1(labelFormatMatchString)); |
|
354 | labelFormatMatcher = new QRegExp(QString::fromLatin1(labelFormatMatchString)); | |
354 | if (labelFormatMatcher->indexIn(format, 0) != -1) |
|
355 | if (labelFormatMatcher->indexIn(format, 0) != -1) | |
355 | formatSpec = labelFormatMatcher->cap(1); |
|
356 | formatSpec = labelFormatMatcher->cap(1); | |
356 | } |
|
357 | } | |
357 | for (int i = firstTick; i < ticks + firstTick; i++) { |
|
358 | for (int i = firstTick; i < ticks + firstTick; i++) { | |
358 | qreal value = qPow(base, i); |
|
359 | qreal value = qPow(base, i); | |
359 | labels << formatLabel(formatSpec, array, value, precision, preStr, postStr); |
|
360 | labels << formatLabel(formatSpec, array, value, precision, preStr, postStr); | |
360 | } |
|
361 | } | |
361 | } |
|
362 | } | |
362 |
|
363 | |||
363 | return labels; |
|
364 | return labels; | |
364 | } |
|
365 | } | |
365 |
|
366 | |||
366 | QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks, |
|
367 | QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks, | |
367 | const QString &format) const |
|
368 | const QString &format) const | |
368 | { |
|
369 | { | |
369 | QStringList labels; |
|
370 | QStringList labels; | |
370 |
|
371 | |||
371 | if (max <= min || ticks < 1) |
|
372 | if (max <= min || ticks < 1) | |
372 | return labels; |
|
373 | return labels; | |
373 |
|
374 | |||
374 |
int n = qMax(int(- |
|
375 | int n = qMax(int(-qFloor(std::log10((max - min) / (ticks - 1)))), 0); | |
375 | n++; |
|
376 | n++; | |
376 | for (int i = 0; i < ticks; i++) { |
|
377 | for (int i = 0; i < ticks; i++) { | |
377 | qreal value = min + (i * (max - min) / (ticks - 1)); |
|
378 | qreal value = min + (i * (max - min) / (ticks - 1)); | |
378 | labels << presenter()->locale().toString(QDateTime::fromMSecsSinceEpoch(value), format); |
|
379 | labels << presenter()->locale().toString(QDateTime::fromMSecsSinceEpoch(value), format); | |
379 | } |
|
380 | } | |
380 | return labels; |
|
381 | return labels; | |
381 | } |
|
382 | } | |
382 |
|
383 | |||
383 | void ChartAxisElement::axisSelected() |
|
384 | void ChartAxisElement::axisSelected() | |
384 | { |
|
385 | { | |
385 | emit clicked(); |
|
386 | emit clicked(); | |
386 | } |
|
387 | } | |
387 |
|
388 | |||
388 | #include "moc_chartaxiselement_p.cpp" |
|
389 | #include "moc_chartaxiselement_p.cpp" | |
389 |
|
390 | |||
390 | QT_CHARTS_END_NAMESPACE |
|
391 | QT_CHARTS_END_NAMESPACE |
@@ -1,135 +1,136 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/chartlogvalueaxisx_p.h> |
|
19 | #include <private/chartlogvalueaxisx_p.h> | |
20 | #include <private/chartpresenter_p.h> |
|
20 | #include <private/chartpresenter_p.h> | |
21 | #include <QtCharts/QLogValueAxis> |
|
21 | #include <QtCharts/QLogValueAxis> | |
22 | #include <private/abstractchartlayout_p.h> |
|
22 | #include <private/abstractchartlayout_p.h> | |
23 | #include <QtWidgets/QGraphicsLayout> |
|
23 | #include <QtWidgets/QGraphicsLayout> | |
24 | #include <QtCore/QtMath> |
|
24 | #include <QtCore/QtMath> | |
25 | #include <QtCore/QDebug> |
|
25 | #include <QtCore/QDebug> | |
|
26 | #include <cmath> | |||
26 |
|
27 | |||
27 | QT_CHARTS_BEGIN_NAMESPACE |
|
28 | QT_CHARTS_BEGIN_NAMESPACE | |
28 |
|
29 | |||
29 | ChartLogValueAxisX::ChartLogValueAxisX(QLogValueAxis *axis, QGraphicsItem *item) |
|
30 | ChartLogValueAxisX::ChartLogValueAxisX(QLogValueAxis *axis, QGraphicsItem *item) | |
30 | : HorizontalAxis(axis, item), |
|
31 | : HorizontalAxis(axis, item), | |
31 | m_axis(axis) |
|
32 | m_axis(axis) | |
32 | { |
|
33 | { | |
33 | QObject::connect(m_axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal))); |
|
34 | QObject::connect(m_axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal))); | |
34 | QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); |
|
35 | QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); | |
35 | } |
|
36 | } | |
36 |
|
37 | |||
37 | ChartLogValueAxisX::~ChartLogValueAxisX() |
|
38 | ChartLogValueAxisX::~ChartLogValueAxisX() | |
38 | { |
|
39 | { | |
39 | } |
|
40 | } | |
40 |
|
41 | |||
41 | QVector<qreal> ChartLogValueAxisX::calculateLayout() const |
|
42 | QVector<qreal> ChartLogValueAxisX::calculateLayout() const | |
42 | { |
|
43 | { | |
43 | QVector<qreal> points; |
|
44 | QVector<qreal> points; | |
44 |
|
45 | |||
45 | qreal logMax = log10(m_axis->max()) / log10(m_axis->base()); |
|
46 | qreal logMax = std::log10(m_axis->max()) / std::log10(m_axis->base()); | |
46 | qreal logMin = log10(m_axis->min()) / log10(m_axis->base()); |
|
47 | qreal logMin = std::log10(m_axis->min()) / std::log10(m_axis->base()); | |
47 | qreal leftEdge = logMin < logMax ? logMin : logMax; |
|
48 | qreal leftEdge = logMin < logMax ? logMin : logMax; | |
48 |
qreal ceilEdge = |
|
49 | qreal ceilEdge = qCeil(leftEdge); | |
49 |
int tickCount = qAbs( |
|
50 | int tickCount = qAbs(qCeil(logMax) - qCeil(logMin)); | |
50 |
|
51 | |||
51 | points.resize(tickCount); |
|
52 | points.resize(tickCount); | |
52 | const QRectF &gridRect = gridGeometry(); |
|
53 | const QRectF &gridRect = gridGeometry(); | |
53 | const qreal deltaX = gridRect.width() / qAbs(logMax - logMin); |
|
54 | const qreal deltaX = gridRect.width() / qAbs(logMax - logMin); | |
54 | for (int i = 0; i < tickCount; ++i) |
|
55 | for (int i = 0; i < tickCount; ++i) | |
55 | points[i] = (ceilEdge + qreal(i)) * deltaX - leftEdge * deltaX + gridRect.left(); |
|
56 | points[i] = (ceilEdge + qreal(i)) * deltaX - leftEdge * deltaX + gridRect.left(); | |
56 |
|
57 | |||
57 | return points; |
|
58 | return points; | |
58 | } |
|
59 | } | |
59 |
|
60 | |||
60 | void ChartLogValueAxisX::updateGeometry() |
|
61 | void ChartLogValueAxisX::updateGeometry() | |
61 | { |
|
62 | { | |
62 | const QVector<qreal>& layout = ChartAxisElement::layout(); |
|
63 | const QVector<qreal>& layout = ChartAxisElement::layout(); | |
63 | setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat())); |
|
64 | setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat())); | |
64 | HorizontalAxis::updateGeometry(); |
|
65 | HorizontalAxis::updateGeometry(); | |
65 | } |
|
66 | } | |
66 |
|
67 | |||
67 | void ChartLogValueAxisX::handleBaseChanged(qreal base) |
|
68 | void ChartLogValueAxisX::handleBaseChanged(qreal base) | |
68 | { |
|
69 | { | |
69 | Q_UNUSED(base); |
|
70 | Q_UNUSED(base); | |
70 | QGraphicsLayoutItem::updateGeometry(); |
|
71 | QGraphicsLayoutItem::updateGeometry(); | |
71 | if(presenter()) presenter()->layout()->invalidate(); |
|
72 | if(presenter()) presenter()->layout()->invalidate(); | |
72 | } |
|
73 | } | |
73 |
|
74 | |||
74 | void ChartLogValueAxisX::handleLabelFormatChanged(const QString &format) |
|
75 | void ChartLogValueAxisX::handleLabelFormatChanged(const QString &format) | |
75 | { |
|
76 | { | |
76 | Q_UNUSED(format); |
|
77 | Q_UNUSED(format); | |
77 | QGraphicsLayoutItem::updateGeometry(); |
|
78 | QGraphicsLayoutItem::updateGeometry(); | |
78 | if(presenter()) presenter()->layout()->invalidate(); |
|
79 | if(presenter()) presenter()->layout()->invalidate(); | |
79 | } |
|
80 | } | |
80 |
|
81 | |||
81 | QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
|
82 | QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const | |
82 | { |
|
83 | { | |
83 | Q_UNUSED(constraint) |
|
84 | Q_UNUSED(constraint) | |
84 |
|
85 | |||
85 | QSizeF sh; |
|
86 | QSizeF sh; | |
86 |
|
87 | |||
87 | QSizeF base = HorizontalAxis::sizeHint(which, constraint); |
|
88 | QSizeF base = HorizontalAxis::sizeHint(which, constraint); | |
88 | QStringList ticksList; |
|
89 | QStringList ticksList; | |
89 | qreal logMax = log10(m_axis->max()) / log10(m_axis->base()); |
|
90 | qreal logMax = std::log10(m_axis->max()) / std::log10(m_axis->base()); | |
90 | qreal logMin = log10(m_axis->min()) / log10(m_axis->base()); |
|
91 | qreal logMin = std::log10(m_axis->min()) / std::log10(m_axis->base()); | |
91 |
int tickCount = qAbs( |
|
92 | int tickCount = qAbs(qCeil(logMax) - qCeil(logMin)); | |
92 | if (m_axis->max() > m_axis->min() && tickCount > 0) |
|
93 | if (m_axis->max() > m_axis->min() && tickCount > 0) | |
93 | ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat()); |
|
94 | ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat()); | |
94 | else |
|
95 | else | |
95 | ticksList.append(QStringLiteral(" ")); |
|
96 | ticksList.append(QStringLiteral(" ")); | |
96 | // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past |
|
97 | // Width of horizontal axis sizeHint indicates the maximum distance labels can extend past | |
97 | // first and last ticks. Base width is irrelevant. |
|
98 | // first and last ticks. Base width is irrelevant. | |
98 | qreal width = 0; |
|
99 | qreal width = 0; | |
99 | qreal height = 0; |
|
100 | qreal height = 0; | |
100 |
|
101 | |||
101 | switch (which) { |
|
102 | switch (which) { | |
102 | case Qt::MinimumSize:{ |
|
103 | case Qt::MinimumSize:{ | |
103 | QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), |
|
104 | QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), | |
104 | QStringLiteral("..."), |
|
105 | QStringLiteral("..."), | |
105 | axis()->labelsAngle()); |
|
106 | axis()->labelsAngle()); | |
106 | width = boundingRect.width() / 2.0; |
|
107 | width = boundingRect.width() / 2.0; | |
107 | height = boundingRect.height() + labelPadding() + base.height() + 1.0; |
|
108 | height = boundingRect.height() + labelPadding() + base.height() + 1.0; | |
108 | sh = QSizeF(width, height); |
|
109 | sh = QSizeF(width, height); | |
109 | break; |
|
110 | break; | |
110 | } |
|
111 | } | |
111 | case Qt::PreferredSize: { |
|
112 | case Qt::PreferredSize: { | |
112 | qreal labelHeight = 0.0; |
|
113 | qreal labelHeight = 0.0; | |
113 | qreal firstWidth = -1.0; |
|
114 | qreal firstWidth = -1.0; | |
114 | foreach (const QString& s, ticksList) { |
|
115 | foreach (const QString& s, ticksList) { | |
115 | QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); |
|
116 | QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); | |
116 | labelHeight = qMax(rect.height(), labelHeight); |
|
117 | labelHeight = qMax(rect.height(), labelHeight); | |
117 | width = rect.width(); |
|
118 | width = rect.width(); | |
118 | if (firstWidth < 0.0) |
|
119 | if (firstWidth < 0.0) | |
119 | firstWidth = width; |
|
120 | firstWidth = width; | |
120 | } |
|
121 | } | |
121 | height = labelHeight + labelPadding() + base.height() + 1.0; |
|
122 | height = labelHeight + labelPadding() + base.height() + 1.0; | |
122 | width = qMax(width, firstWidth) / 2.0; |
|
123 | width = qMax(width, firstWidth) / 2.0; | |
123 | sh = QSizeF(width, height); |
|
124 | sh = QSizeF(width, height); | |
124 | break; |
|
125 | break; | |
125 | } |
|
126 | } | |
126 | default: |
|
127 | default: | |
127 | break; |
|
128 | break; | |
128 | } |
|
129 | } | |
129 |
|
130 | |||
130 | return sh; |
|
131 | return sh; | |
131 | } |
|
132 | } | |
132 |
|
133 | |||
133 | #include "moc_chartlogvalueaxisx_p.cpp" |
|
134 | #include "moc_chartlogvalueaxisx_p.cpp" | |
134 |
|
135 | |||
135 | QT_CHARTS_END_NAMESPACE |
|
136 | QT_CHARTS_END_NAMESPACE |
@@ -1,135 +1,136 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/chartlogvalueaxisy_p.h> |
|
19 | #include <private/chartlogvalueaxisy_p.h> | |
20 | #include <private/chartpresenter_p.h> |
|
20 | #include <private/chartpresenter_p.h> | |
21 | #include <QtCharts/QLogValueAxis> |
|
21 | #include <QtCharts/QLogValueAxis> | |
22 | #include <private/abstractchartlayout_p.h> |
|
22 | #include <private/abstractchartlayout_p.h> | |
23 | #include <QtWidgets/QGraphicsLayout> |
|
23 | #include <QtWidgets/QGraphicsLayout> | |
24 | #include <QtCore/QtMath> |
|
24 | #include <QtCore/QtMath> | |
25 | #include <QtCore/QDebug> |
|
25 | #include <QtCore/QDebug> | |
|
26 | #include <cmath> | |||
26 |
|
27 | |||
27 | QT_CHARTS_BEGIN_NAMESPACE |
|
28 | QT_CHARTS_BEGIN_NAMESPACE | |
28 |
|
29 | |||
29 | ChartLogValueAxisY::ChartLogValueAxisY(QLogValueAxis *axis, QGraphicsItem *item) |
|
30 | ChartLogValueAxisY::ChartLogValueAxisY(QLogValueAxis *axis, QGraphicsItem *item) | |
30 | : VerticalAxis(axis, item), |
|
31 | : VerticalAxis(axis, item), | |
31 | m_axis(axis) |
|
32 | m_axis(axis) | |
32 | { |
|
33 | { | |
33 | QObject::connect(m_axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal))); |
|
34 | QObject::connect(m_axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal))); | |
34 | QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); |
|
35 | QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); | |
35 | } |
|
36 | } | |
36 |
|
37 | |||
37 | ChartLogValueAxisY::~ChartLogValueAxisY() |
|
38 | ChartLogValueAxisY::~ChartLogValueAxisY() | |
38 | { |
|
39 | { | |
39 | } |
|
40 | } | |
40 |
|
41 | |||
41 | QVector<qreal> ChartLogValueAxisY::calculateLayout() const |
|
42 | QVector<qreal> ChartLogValueAxisY::calculateLayout() const | |
42 | { |
|
43 | { | |
43 | QVector<qreal> points; |
|
44 | QVector<qreal> points; | |
44 | qreal logMax = log10(m_axis->max()) / log10(m_axis->base()); |
|
45 | qreal logMax = std::log10(m_axis->max()) / std::log10(m_axis->base()); | |
45 | qreal logMin = log10(m_axis->min()) / log10(m_axis->base()); |
|
46 | qreal logMin = std::log10(m_axis->min()) / std::log10(m_axis->base()); | |
46 | qreal leftEdge = logMin < logMax ? logMin : logMax; |
|
47 | qreal leftEdge = logMin < logMax ? logMin : logMax; | |
47 |
qreal ceilEdge = |
|
48 | qreal ceilEdge = qCeil(leftEdge); | |
48 |
int tickCount = qAbs( |
|
49 | int tickCount = qAbs(qCeil(logMax) - qCeil(logMin)); | |
49 |
|
50 | |||
50 | points.resize(tickCount); |
|
51 | points.resize(tickCount); | |
51 | const QRectF &gridRect = gridGeometry(); |
|
52 | const QRectF &gridRect = gridGeometry(); | |
52 | const qreal deltaY = gridRect.height() / qAbs(logMax - logMin); |
|
53 | const qreal deltaY = gridRect.height() / qAbs(logMax - logMin); | |
53 | for (int i = 0; i < tickCount; ++i) |
|
54 | for (int i = 0; i < tickCount; ++i) | |
54 | points[i] = (ceilEdge + qreal(i)) * -deltaY - leftEdge * -deltaY + gridRect.bottom(); |
|
55 | points[i] = (ceilEdge + qreal(i)) * -deltaY - leftEdge * -deltaY + gridRect.bottom(); | |
55 |
|
56 | |||
56 | return points; |
|
57 | return points; | |
57 | } |
|
58 | } | |
58 |
|
59 | |||
59 |
|
60 | |||
60 | void ChartLogValueAxisY::updateGeometry() |
|
61 | void ChartLogValueAxisY::updateGeometry() | |
61 | { |
|
62 | { | |
62 | const QVector<qreal> &layout = ChartAxisElement::layout(); |
|
63 | const QVector<qreal> &layout = ChartAxisElement::layout(); | |
63 | setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat())); |
|
64 | setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat())); | |
64 | VerticalAxis::updateGeometry(); |
|
65 | VerticalAxis::updateGeometry(); | |
65 | } |
|
66 | } | |
66 |
|
67 | |||
67 | void ChartLogValueAxisY::handleBaseChanged(qreal base) |
|
68 | void ChartLogValueAxisY::handleBaseChanged(qreal base) | |
68 | { |
|
69 | { | |
69 | Q_UNUSED(base); |
|
70 | Q_UNUSED(base); | |
70 | QGraphicsLayoutItem::updateGeometry(); |
|
71 | QGraphicsLayoutItem::updateGeometry(); | |
71 | if(presenter()) presenter()->layout()->invalidate(); |
|
72 | if(presenter()) presenter()->layout()->invalidate(); | |
72 | } |
|
73 | } | |
73 |
|
74 | |||
74 | void ChartLogValueAxisY::handleLabelFormatChanged(const QString &format) |
|
75 | void ChartLogValueAxisY::handleLabelFormatChanged(const QString &format) | |
75 | { |
|
76 | { | |
76 | Q_UNUSED(format); |
|
77 | Q_UNUSED(format); | |
77 | QGraphicsLayoutItem::updateGeometry(); |
|
78 | QGraphicsLayoutItem::updateGeometry(); | |
78 | if(presenter()) presenter()->layout()->invalidate(); |
|
79 | if(presenter()) presenter()->layout()->invalidate(); | |
79 | } |
|
80 | } | |
80 |
|
81 | |||
81 | QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
|
82 | QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const | |
82 | { |
|
83 | { | |
83 | Q_UNUSED(constraint) |
|
84 | Q_UNUSED(constraint) | |
84 |
|
85 | |||
85 | QSizeF sh; |
|
86 | QSizeF sh; | |
86 |
|
87 | |||
87 | QSizeF base = VerticalAxis::sizeHint(which, constraint); |
|
88 | QSizeF base = VerticalAxis::sizeHint(which, constraint); | |
88 | QStringList ticksList; |
|
89 | QStringList ticksList; | |
89 | qreal logMax = log10(m_axis->max()) / log10(m_axis->base()); |
|
90 | qreal logMax = std::log10(m_axis->max()) / std::log10(m_axis->base()); | |
90 | qreal logMin = log10(m_axis->min()) / log10(m_axis->base()); |
|
91 | qreal logMin = std::log10(m_axis->min()) / std::log10(m_axis->base()); | |
91 |
int tickCount = qAbs( |
|
92 | int tickCount = qAbs(qCeil(logMax) - qCeil(logMin)); | |
92 | if (m_axis->max() > m_axis->min() && tickCount > 0) |
|
93 | if (m_axis->max() > m_axis->min() && tickCount > 0) | |
93 | ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat()); |
|
94 | ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat()); | |
94 | else |
|
95 | else | |
95 | ticksList.append(QStringLiteral(" ")); |
|
96 | ticksList.append(QStringLiteral(" ")); | |
96 | qreal width = 0; |
|
97 | qreal width = 0; | |
97 | // Height of vertical axis sizeHint indicates the maximum distance labels can extend past |
|
98 | // Height of vertical axis sizeHint indicates the maximum distance labels can extend past | |
98 | // first and last ticks. Base height is irrelevant. |
|
99 | // first and last ticks. Base height is irrelevant. | |
99 | qreal height = 0; |
|
100 | qreal height = 0; | |
100 |
|
101 | |||
101 | switch (which) { |
|
102 | switch (which) { | |
102 | case Qt::MinimumSize: { |
|
103 | case Qt::MinimumSize: { | |
103 | QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), |
|
104 | QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), | |
104 | QStringLiteral("..."), |
|
105 | QStringLiteral("..."), | |
105 | axis()->labelsAngle()); |
|
106 | axis()->labelsAngle()); | |
106 | width = boundingRect.width() + labelPadding() + base.width() + 1.0; |
|
107 | width = boundingRect.width() + labelPadding() + base.width() + 1.0; | |
107 | height = boundingRect.height() / 2.0; |
|
108 | height = boundingRect.height() / 2.0; | |
108 | sh = QSizeF(width, height); |
|
109 | sh = QSizeF(width, height); | |
109 | break; |
|
110 | break; | |
110 | } |
|
111 | } | |
111 | case Qt::PreferredSize: { |
|
112 | case Qt::PreferredSize: { | |
112 | qreal labelWidth = 0.0; |
|
113 | qreal labelWidth = 0.0; | |
113 | qreal firstHeight = -1.0; |
|
114 | qreal firstHeight = -1.0; | |
114 | foreach (const QString& s, ticksList) { |
|
115 | foreach (const QString& s, ticksList) { | |
115 | QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); |
|
116 | QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); | |
116 | labelWidth = qMax(rect.width(), labelWidth); |
|
117 | labelWidth = qMax(rect.width(), labelWidth); | |
117 | height = rect.height(); |
|
118 | height = rect.height(); | |
118 | if (firstHeight < 0.0) |
|
119 | if (firstHeight < 0.0) | |
119 | firstHeight = height; |
|
120 | firstHeight = height; | |
120 | } |
|
121 | } | |
121 | width = labelWidth + labelPadding() + base.width() + 2.0; //two pixels of tolerance |
|
122 | width = labelWidth + labelPadding() + base.width() + 2.0; //two pixels of tolerance | |
122 | height = qMax(height, firstHeight) / 2.0; |
|
123 | height = qMax(height, firstHeight) / 2.0; | |
123 | sh = QSizeF(width, height); |
|
124 | sh = QSizeF(width, height); | |
124 | break; |
|
125 | break; | |
125 | } |
|
126 | } | |
126 | default: |
|
127 | default: | |
127 | break; |
|
128 | break; | |
128 | } |
|
129 | } | |
129 |
|
130 | |||
130 | return sh; |
|
131 | return sh; | |
131 | } |
|
132 | } | |
132 |
|
133 | |||
133 | #include "moc_chartlogvalueaxisy_p.cpp" |
|
134 | #include "moc_chartlogvalueaxisy_p.cpp" | |
134 |
|
135 | |||
135 | QT_CHARTS_END_NAMESPACE |
|
136 | QT_CHARTS_END_NAMESPACE |
@@ -1,88 +1,89 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/polarchartlogvalueaxisangular_p.h> |
|
19 | #include <private/polarchartlogvalueaxisangular_p.h> | |
20 | #include <private/abstractchartlayout_p.h> |
|
20 | #include <private/abstractchartlayout_p.h> | |
21 | #include <private/chartpresenter_p.h> |
|
21 | #include <private/chartpresenter_p.h> | |
22 | #include <QtCharts/QLogValueAxis> |
|
22 | #include <QtCharts/QLogValueAxis> | |
23 | #include <QtCore/QtMath> |
|
23 | #include <QtCore/QtMath> | |
24 | #include <QtCore/QDebug> |
|
24 | #include <QtCore/QDebug> | |
|
25 | #include <cmath> | |||
25 |
|
26 | |||
26 | QT_CHARTS_BEGIN_NAMESPACE |
|
27 | QT_CHARTS_BEGIN_NAMESPACE | |
27 |
|
28 | |||
28 | PolarChartLogValueAxisAngular::PolarChartLogValueAxisAngular(QLogValueAxis *axis, QGraphicsItem *item) |
|
29 | PolarChartLogValueAxisAngular::PolarChartLogValueAxisAngular(QLogValueAxis *axis, QGraphicsItem *item) | |
29 | : PolarChartAxisAngular(axis, item) |
|
30 | : PolarChartAxisAngular(axis, item) | |
30 | { |
|
31 | { | |
31 | QObject::connect(axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal))); |
|
32 | QObject::connect(axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal))); | |
32 | QObject::connect(axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); |
|
33 | QObject::connect(axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); | |
33 | } |
|
34 | } | |
34 |
|
35 | |||
35 | PolarChartLogValueAxisAngular::~PolarChartLogValueAxisAngular() |
|
36 | PolarChartLogValueAxisAngular::~PolarChartLogValueAxisAngular() | |
36 | { |
|
37 | { | |
37 | } |
|
38 | } | |
38 |
|
39 | |||
39 | QVector<qreal> PolarChartLogValueAxisAngular::calculateLayout() const |
|
40 | QVector<qreal> PolarChartLogValueAxisAngular::calculateLayout() const | |
40 | { |
|
41 | { | |
41 | QLogValueAxis *logValueAxis = static_cast<QLogValueAxis *>(axis()); |
|
42 | QLogValueAxis *logValueAxis = static_cast<QLogValueAxis *>(axis()); | |
42 | const qreal logMax = log10(logValueAxis->max()) / log10(logValueAxis->base()); |
|
43 | const qreal logMax = std::log10(logValueAxis->max()) / std::log10(logValueAxis->base()); | |
43 | const qreal logMin = log10(logValueAxis->min()) / log10(logValueAxis->base()); |
|
44 | const qreal logMin = std::log10(logValueAxis->min()) / std::log10(logValueAxis->base()); | |
44 | const qreal startEdge = logMin < logMax ? logMin : logMax; |
|
45 | const qreal startEdge = logMin < logMax ? logMin : logMax; | |
45 | const qreal delta = 360.0 / qAbs(logMax - logMin); |
|
46 | const qreal delta = 360.0 / qAbs(logMax - logMin); | |
46 |
const qreal initialSpan = ( |
|
47 | const qreal initialSpan = (qCeil(startEdge) - startEdge) * delta; | |
47 |
int tickCount = qAbs( |
|
48 | int tickCount = qAbs(qCeil(logMax) - qCeil(logMin)); | |
48 |
|
49 | |||
49 | QVector<qreal> points; |
|
50 | QVector<qreal> points; | |
50 | points.resize(tickCount); |
|
51 | points.resize(tickCount); | |
51 |
|
52 | |||
52 | for (int i = 0; i < tickCount; ++i) { |
|
53 | for (int i = 0; i < tickCount; ++i) { | |
53 | qreal angularCoordinate = initialSpan + (delta * qreal(i)); |
|
54 | qreal angularCoordinate = initialSpan + (delta * qreal(i)); | |
54 | points[i] = angularCoordinate; |
|
55 | points[i] = angularCoordinate; | |
55 | } |
|
56 | } | |
56 |
|
57 | |||
57 | return points; |
|
58 | return points; | |
58 | } |
|
59 | } | |
59 |
|
60 | |||
60 | void PolarChartLogValueAxisAngular::createAxisLabels(const QVector<qreal> &layout) |
|
61 | void PolarChartLogValueAxisAngular::createAxisLabels(const QVector<qreal> &layout) | |
61 | { |
|
62 | { | |
62 | QLogValueAxis *logValueAxis = static_cast<QLogValueAxis *>(axis()); |
|
63 | QLogValueAxis *logValueAxis = static_cast<QLogValueAxis *>(axis()); | |
63 | setLabels(createLogValueLabels(logValueAxis->min(), |
|
64 | setLabels(createLogValueLabels(logValueAxis->min(), | |
64 | logValueAxis->max(), |
|
65 | logValueAxis->max(), | |
65 | logValueAxis->base(), |
|
66 | logValueAxis->base(), | |
66 | layout.size(), |
|
67 | layout.size(), | |
67 | logValueAxis->labelFormat())); |
|
68 | logValueAxis->labelFormat())); | |
68 | } |
|
69 | } | |
69 |
|
70 | |||
70 | void PolarChartLogValueAxisAngular::handleBaseChanged(qreal base) |
|
71 | void PolarChartLogValueAxisAngular::handleBaseChanged(qreal base) | |
71 | { |
|
72 | { | |
72 | Q_UNUSED(base); |
|
73 | Q_UNUSED(base); | |
73 | QGraphicsLayoutItem::updateGeometry(); |
|
74 | QGraphicsLayoutItem::updateGeometry(); | |
74 | if (presenter()) |
|
75 | if (presenter()) | |
75 | presenter()->layout()->invalidate(); |
|
76 | presenter()->layout()->invalidate(); | |
76 | } |
|
77 | } | |
77 |
|
78 | |||
78 | void PolarChartLogValueAxisAngular::handleLabelFormatChanged(const QString &format) |
|
79 | void PolarChartLogValueAxisAngular::handleLabelFormatChanged(const QString &format) | |
79 | { |
|
80 | { | |
80 | Q_UNUSED(format); |
|
81 | Q_UNUSED(format); | |
81 | QGraphicsLayoutItem::updateGeometry(); |
|
82 | QGraphicsLayoutItem::updateGeometry(); | |
82 | if (presenter()) |
|
83 | if (presenter()) | |
83 | presenter()->layout()->invalidate(); |
|
84 | presenter()->layout()->invalidate(); | |
84 | } |
|
85 | } | |
85 |
|
86 | |||
86 | #include "moc_polarchartlogvalueaxisangular_p.cpp" |
|
87 | #include "moc_polarchartlogvalueaxisangular_p.cpp" | |
87 |
|
88 | |||
88 | QT_CHARTS_END_NAMESPACE |
|
89 | QT_CHARTS_END_NAMESPACE |
@@ -1,93 +1,94 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/polarchartlogvalueaxisradial_p.h> |
|
19 | #include <private/polarchartlogvalueaxisradial_p.h> | |
20 | #include <private/abstractchartlayout_p.h> |
|
20 | #include <private/abstractchartlayout_p.h> | |
21 | #include <private/chartpresenter_p.h> |
|
21 | #include <private/chartpresenter_p.h> | |
22 | #include <QtCharts/QLogValueAxis> |
|
22 | #include <QtCharts/QLogValueAxis> | |
23 | #include <QtCore/QtMath> |
|
23 | #include <QtCore/QtMath> | |
24 | #include <QtCore/QDebug> |
|
24 | #include <QtCore/QDebug> | |
|
25 | #include <cmath> | |||
25 |
|
26 | |||
26 | QT_CHARTS_BEGIN_NAMESPACE |
|
27 | QT_CHARTS_BEGIN_NAMESPACE | |
27 |
|
28 | |||
28 | PolarChartLogValueAxisRadial::PolarChartLogValueAxisRadial(QLogValueAxis *axis, QGraphicsItem *item) |
|
29 | PolarChartLogValueAxisRadial::PolarChartLogValueAxisRadial(QLogValueAxis *axis, QGraphicsItem *item) | |
29 | : PolarChartAxisRadial(axis, item) |
|
30 | : PolarChartAxisRadial(axis, item) | |
30 | { |
|
31 | { | |
31 | QObject::connect(axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal))); |
|
32 | QObject::connect(axis, SIGNAL(baseChanged(qreal)), this, SLOT(handleBaseChanged(qreal))); | |
32 | QObject::connect(axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); |
|
33 | QObject::connect(axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); | |
33 | } |
|
34 | } | |
34 |
|
35 | |||
35 | PolarChartLogValueAxisRadial::~PolarChartLogValueAxisRadial() |
|
36 | PolarChartLogValueAxisRadial::~PolarChartLogValueAxisRadial() | |
36 | { |
|
37 | { | |
37 | } |
|
38 | } | |
38 |
|
39 | |||
39 | QVector<qreal> PolarChartLogValueAxisRadial::calculateLayout() const |
|
40 | QVector<qreal> PolarChartLogValueAxisRadial::calculateLayout() const | |
40 | { |
|
41 | { | |
41 | QLogValueAxis *logValueAxis = static_cast<QLogValueAxis *>(axis()); |
|
42 | QLogValueAxis *logValueAxis = static_cast<QLogValueAxis *>(axis()); | |
42 | const qreal logMax = log10(logValueAxis->max()) / log10(logValueAxis->base()); |
|
43 | const qreal logMax = std::log10(logValueAxis->max()) / std::log10(logValueAxis->base()); | |
43 | const qreal logMin = log10(logValueAxis->min()) / log10(logValueAxis->base()); |
|
44 | const qreal logMin = std::log10(logValueAxis->min()) / std::log10(logValueAxis->base()); | |
44 | const qreal innerEdge = logMin < logMax ? logMin : logMax; |
|
45 | const qreal innerEdge = logMin < logMax ? logMin : logMax; | |
45 | const qreal outerEdge = logMin > logMax ? logMin : logMax; |
|
46 | const qreal outerEdge = logMin > logMax ? logMin : logMax; | |
46 | const qreal delta = (axisGeometry().width() / 2.0) / qAbs(logMax - logMin); |
|
47 | const qreal delta = (axisGeometry().width() / 2.0) / qAbs(logMax - logMin); | |
47 |
const qreal initialSpan = ( |
|
48 | const qreal initialSpan = (qCeil(innerEdge) - innerEdge) * delta; | |
48 |
int tickCount = qAbs( |
|
49 | int tickCount = qAbs(qCeil(logMax) - qCeil(logMin)); | |
49 |
|
50 | |||
50 | // Extra tick if outer edge is exactly at the tick |
|
51 | // Extra tick if outer edge is exactly at the tick | |
51 |
if (outerEdge == |
|
52 | if (outerEdge == qCeil(outerEdge)) | |
52 | tickCount++; |
|
53 | tickCount++; | |
53 |
|
54 | |||
54 | QVector<qreal> points; |
|
55 | QVector<qreal> points; | |
55 | points.resize(tickCount); |
|
56 | points.resize(tickCount); | |
56 |
|
57 | |||
57 | for (int i = 0; i < tickCount; ++i) { |
|
58 | for (int i = 0; i < tickCount; ++i) { | |
58 | qreal radialCoordinate = initialSpan + (delta * qreal(i)); |
|
59 | qreal radialCoordinate = initialSpan + (delta * qreal(i)); | |
59 | points[i] = radialCoordinate; |
|
60 | points[i] = radialCoordinate; | |
60 | } |
|
61 | } | |
61 |
|
62 | |||
62 | return points; |
|
63 | return points; | |
63 | } |
|
64 | } | |
64 |
|
65 | |||
65 | void PolarChartLogValueAxisRadial::createAxisLabels(const QVector<qreal> &layout) |
|
66 | void PolarChartLogValueAxisRadial::createAxisLabels(const QVector<qreal> &layout) | |
66 | { |
|
67 | { | |
67 | QLogValueAxis *logValueAxis = static_cast<QLogValueAxis *>(axis()); |
|
68 | QLogValueAxis *logValueAxis = static_cast<QLogValueAxis *>(axis()); | |
68 | setLabels(createLogValueLabels(logValueAxis->min(), |
|
69 | setLabels(createLogValueLabels(logValueAxis->min(), | |
69 | logValueAxis->max(), |
|
70 | logValueAxis->max(), | |
70 | logValueAxis->base(), |
|
71 | logValueAxis->base(), | |
71 | layout.size(), |
|
72 | layout.size(), | |
72 | logValueAxis->labelFormat())); |
|
73 | logValueAxis->labelFormat())); | |
73 | } |
|
74 | } | |
74 |
|
75 | |||
75 | void PolarChartLogValueAxisRadial::handleBaseChanged(qreal base) |
|
76 | void PolarChartLogValueAxisRadial::handleBaseChanged(qreal base) | |
76 | { |
|
77 | { | |
77 | Q_UNUSED(base); |
|
78 | Q_UNUSED(base); | |
78 | QGraphicsLayoutItem::updateGeometry(); |
|
79 | QGraphicsLayoutItem::updateGeometry(); | |
79 | if (presenter()) |
|
80 | if (presenter()) | |
80 | presenter()->layout()->invalidate(); |
|
81 | presenter()->layout()->invalidate(); | |
81 | } |
|
82 | } | |
82 |
|
83 | |||
83 | void PolarChartLogValueAxisRadial::handleLabelFormatChanged(const QString &format) |
|
84 | void PolarChartLogValueAxisRadial::handleLabelFormatChanged(const QString &format) | |
84 | { |
|
85 | { | |
85 | Q_UNUSED(format); |
|
86 | Q_UNUSED(format); | |
86 | QGraphicsLayoutItem::updateGeometry(); |
|
87 | QGraphicsLayoutItem::updateGeometry(); | |
87 | if (presenter()) |
|
88 | if (presenter()) | |
88 | presenter()->layout()->invalidate(); |
|
89 | presenter()->layout()->invalidate(); | |
89 | } |
|
90 | } | |
90 |
|
91 | |||
91 | #include "moc_polarchartlogvalueaxisradial_p.cpp" |
|
92 | #include "moc_polarchartlogvalueaxisradial_p.cpp" | |
92 |
|
93 | |||
93 | QT_CHARTS_END_NAMESPACE |
|
94 | QT_CHARTS_END_NAMESPACE |
@@ -1,263 +1,264 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/abstractdomain_p.h> |
|
19 | #include <private/abstractdomain_p.h> | |
20 | #include <private/qabstractaxis_p.h> |
|
20 | #include <private/qabstractaxis_p.h> | |
21 | #include <QtCore/QtMath> |
|
21 | #include <QtCore/QtMath> | |
|
22 | #include <cmath> | |||
22 |
|
23 | |||
23 | QT_CHARTS_BEGIN_NAMESPACE |
|
24 | QT_CHARTS_BEGIN_NAMESPACE | |
24 |
|
25 | |||
25 | AbstractDomain::AbstractDomain(QObject *parent) |
|
26 | AbstractDomain::AbstractDomain(QObject *parent) | |
26 | : QObject(parent), |
|
27 | : QObject(parent), | |
27 | m_minX(0), |
|
28 | m_minX(0), | |
28 | m_maxX(0), |
|
29 | m_maxX(0), | |
29 | m_minY(0), |
|
30 | m_minY(0), | |
30 | m_maxY(0), |
|
31 | m_maxY(0), | |
31 | m_signalsBlocked(false), |
|
32 | m_signalsBlocked(false), | |
32 | m_zoomed(false), |
|
33 | m_zoomed(false), | |
33 | m_zoomResetMinX(0), |
|
34 | m_zoomResetMinX(0), | |
34 | m_zoomResetMaxX(0), |
|
35 | m_zoomResetMaxX(0), | |
35 | m_zoomResetMinY(0), |
|
36 | m_zoomResetMinY(0), | |
36 | m_zoomResetMaxY(0) |
|
37 | m_zoomResetMaxY(0) | |
37 |
|
38 | |||
38 | { |
|
39 | { | |
39 | } |
|
40 | } | |
40 |
|
41 | |||
41 | AbstractDomain::~AbstractDomain() |
|
42 | AbstractDomain::~AbstractDomain() | |
42 | { |
|
43 | { | |
43 | } |
|
44 | } | |
44 |
|
45 | |||
45 | void AbstractDomain::setSize(const QSizeF &size) |
|
46 | void AbstractDomain::setSize(const QSizeF &size) | |
46 | { |
|
47 | { | |
47 | if (m_size != size) { |
|
48 | if (m_size != size) { | |
48 | m_size=size; |
|
49 | m_size=size; | |
49 | emit updated(); |
|
50 | emit updated(); | |
50 | } |
|
51 | } | |
51 | } |
|
52 | } | |
52 |
|
53 | |||
53 | QSizeF AbstractDomain::size() const |
|
54 | QSizeF AbstractDomain::size() const | |
54 | { |
|
55 | { | |
55 | return m_size; |
|
56 | return m_size; | |
56 | } |
|
57 | } | |
57 |
|
58 | |||
58 | void AbstractDomain::setRangeX(qreal min, qreal max) |
|
59 | void AbstractDomain::setRangeX(qreal min, qreal max) | |
59 | { |
|
60 | { | |
60 | setRange(min, max, m_minY, m_maxY); |
|
61 | setRange(min, max, m_minY, m_maxY); | |
61 | } |
|
62 | } | |
62 |
|
63 | |||
63 | void AbstractDomain::setRangeY(qreal min, qreal max) |
|
64 | void AbstractDomain::setRangeY(qreal min, qreal max) | |
64 | { |
|
65 | { | |
65 | setRange(m_minX, m_maxX, min, max); |
|
66 | setRange(m_minX, m_maxX, min, max); | |
66 | } |
|
67 | } | |
67 |
|
68 | |||
68 | void AbstractDomain::setMinX(qreal min) |
|
69 | void AbstractDomain::setMinX(qreal min) | |
69 | { |
|
70 | { | |
70 | setRange(min, m_maxX, m_minY, m_maxY); |
|
71 | setRange(min, m_maxX, m_minY, m_maxY); | |
71 | } |
|
72 | } | |
72 |
|
73 | |||
73 | void AbstractDomain::setMaxX(qreal max) |
|
74 | void AbstractDomain::setMaxX(qreal max) | |
74 | { |
|
75 | { | |
75 | setRange(m_minX, max, m_minY, m_maxY); |
|
76 | setRange(m_minX, max, m_minY, m_maxY); | |
76 | } |
|
77 | } | |
77 |
|
78 | |||
78 | void AbstractDomain::setMinY(qreal min) |
|
79 | void AbstractDomain::setMinY(qreal min) | |
79 | { |
|
80 | { | |
80 | setRange(m_minX, m_maxX, min, m_maxY); |
|
81 | setRange(m_minX, m_maxX, min, m_maxY); | |
81 | } |
|
82 | } | |
82 |
|
83 | |||
83 | void AbstractDomain::setMaxY(qreal max) |
|
84 | void AbstractDomain::setMaxY(qreal max) | |
84 | { |
|
85 | { | |
85 | setRange(m_minX, m_maxX, m_minY, max); |
|
86 | setRange(m_minX, m_maxX, m_minY, max); | |
86 | } |
|
87 | } | |
87 |
|
88 | |||
88 | qreal AbstractDomain::spanX() const |
|
89 | qreal AbstractDomain::spanX() const | |
89 | { |
|
90 | { | |
90 | Q_ASSERT(m_maxX >= m_minX); |
|
91 | Q_ASSERT(m_maxX >= m_minX); | |
91 | return m_maxX - m_minX; |
|
92 | return m_maxX - m_minX; | |
92 | } |
|
93 | } | |
93 |
|
94 | |||
94 | qreal AbstractDomain::spanY() const |
|
95 | qreal AbstractDomain::spanY() const | |
95 | { |
|
96 | { | |
96 | Q_ASSERT(m_maxY >= m_minY); |
|
97 | Q_ASSERT(m_maxY >= m_minY); | |
97 | return m_maxY - m_minY; |
|
98 | return m_maxY - m_minY; | |
98 | } |
|
99 | } | |
99 |
|
100 | |||
100 | bool AbstractDomain::isEmpty() const |
|
101 | bool AbstractDomain::isEmpty() const | |
101 | { |
|
102 | { | |
102 | return qFuzzyCompare(spanX(), 0) || qFuzzyCompare(spanY(), 0) || m_size.isEmpty(); |
|
103 | return qFuzzyCompare(spanX(), 0) || qFuzzyCompare(spanY(), 0) || m_size.isEmpty(); | |
103 | } |
|
104 | } | |
104 |
|
105 | |||
105 | QPointF AbstractDomain::calculateDomainPoint(const QPointF &point) const |
|
106 | QPointF AbstractDomain::calculateDomainPoint(const QPointF &point) const | |
106 | { |
|
107 | { | |
107 | const qreal deltaX = m_size.width() / (m_maxX - m_minX); |
|
108 | const qreal deltaX = m_size.width() / (m_maxX - m_minX); | |
108 | const qreal deltaY = m_size.height() / (m_maxY - m_minY); |
|
109 | const qreal deltaY = m_size.height() / (m_maxY - m_minY); | |
109 | qreal x = point.x() / deltaX + m_minX; |
|
110 | qreal x = point.x() / deltaX + m_minX; | |
110 | qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY; |
|
111 | qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY; | |
111 | return QPointF(x, y); |
|
112 | return QPointF(x, y); | |
112 | } |
|
113 | } | |
113 |
|
114 | |||
114 | // handlers |
|
115 | // handlers | |
115 |
|
116 | |||
116 | void AbstractDomain::handleVerticalAxisRangeChanged(qreal min, qreal max) |
|
117 | void AbstractDomain::handleVerticalAxisRangeChanged(qreal min, qreal max) | |
117 | { |
|
118 | { | |
118 | setRangeY(min, max); |
|
119 | setRangeY(min, max); | |
119 | } |
|
120 | } | |
120 |
|
121 | |||
121 | void AbstractDomain::handleHorizontalAxisRangeChanged(qreal min, qreal max) |
|
122 | void AbstractDomain::handleHorizontalAxisRangeChanged(qreal min, qreal max) | |
122 | { |
|
123 | { | |
123 | setRangeX(min, max); |
|
124 | setRangeX(min, max); | |
124 | } |
|
125 | } | |
125 |
|
126 | |||
126 | void AbstractDomain::blockRangeSignals(bool block) |
|
127 | void AbstractDomain::blockRangeSignals(bool block) | |
127 | { |
|
128 | { | |
128 | if (m_signalsBlocked!=block) { |
|
129 | if (m_signalsBlocked!=block) { | |
129 | m_signalsBlocked=block; |
|
130 | m_signalsBlocked=block; | |
130 | if (!block) { |
|
131 | if (!block) { | |
131 | emit rangeHorizontalChanged(m_minX,m_maxX); |
|
132 | emit rangeHorizontalChanged(m_minX,m_maxX); | |
132 | emit rangeVerticalChanged(m_minY,m_maxY); |
|
133 | emit rangeVerticalChanged(m_minY,m_maxY); | |
133 | } |
|
134 | } | |
134 | } |
|
135 | } | |
135 | } |
|
136 | } | |
136 |
|
137 | |||
137 | void AbstractDomain::zoomReset() |
|
138 | void AbstractDomain::zoomReset() | |
138 | { |
|
139 | { | |
139 | if (m_zoomed) { |
|
140 | if (m_zoomed) { | |
140 | setRange(m_zoomResetMinX, |
|
141 | setRange(m_zoomResetMinX, | |
141 | m_zoomResetMaxX, |
|
142 | m_zoomResetMaxX, | |
142 | m_zoomResetMinY, |
|
143 | m_zoomResetMinY, | |
143 | m_zoomResetMaxY); |
|
144 | m_zoomResetMaxY); | |
144 | m_zoomed = false; |
|
145 | m_zoomed = false; | |
145 | } |
|
146 | } | |
146 | } |
|
147 | } | |
147 |
|
148 | |||
148 | void AbstractDomain::storeZoomReset() |
|
149 | void AbstractDomain::storeZoomReset() | |
149 | { |
|
150 | { | |
150 | if (!m_zoomed) { |
|
151 | if (!m_zoomed) { | |
151 | m_zoomed = true; |
|
152 | m_zoomed = true; | |
152 | m_zoomResetMinX = m_minX; |
|
153 | m_zoomResetMinX = m_minX; | |
153 | m_zoomResetMaxX = m_maxX; |
|
154 | m_zoomResetMaxX = m_maxX; | |
154 | m_zoomResetMinY = m_minY; |
|
155 | m_zoomResetMinY = m_minY; | |
155 | m_zoomResetMaxY = m_maxY; |
|
156 | m_zoomResetMaxY = m_maxY; | |
156 | } |
|
157 | } | |
157 | } |
|
158 | } | |
158 |
|
159 | |||
159 | //algorithm defined by Paul S.Heckbert GraphicalGems I |
|
160 | //algorithm defined by Paul S.Heckbert GraphicalGems I | |
160 |
|
161 | |||
161 | void AbstractDomain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount) |
|
162 | void AbstractDomain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount) | |
162 | { |
|
163 | { | |
163 | qreal range = niceNumber(max - min, true); //range with ceiling |
|
164 | qreal range = niceNumber(max - min, true); //range with ceiling | |
164 | qreal step = niceNumber(range / (ticksCount - 1), false); |
|
165 | qreal step = niceNumber(range / (ticksCount - 1), false); | |
165 | min = qFloor(min / step); |
|
166 | min = qFloor(min / step); | |
166 | max = qCeil(max / step); |
|
167 | max = qCeil(max / step); | |
167 | ticksCount = int(max - min) + 1; |
|
168 | ticksCount = int(max - min) + 1; | |
168 | min *= step; |
|
169 | min *= step; | |
169 | max *= step; |
|
170 | max *= step; | |
170 | } |
|
171 | } | |
171 |
|
172 | |||
172 | //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n |
|
173 | //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n | |
173 |
|
174 | |||
174 | qreal AbstractDomain::niceNumber(qreal x, bool ceiling) |
|
175 | qreal AbstractDomain::niceNumber(qreal x, bool ceiling) | |
175 | { |
|
176 | { | |
176 | qreal z = qPow(10, qFloor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x |
|
177 | qreal z = qPow(10, qFloor(std::log10(x))); //find corresponding number of the form of 10^n than is smaller than x | |
177 | qreal q = x / z; //q<10 && q>=1; |
|
178 | qreal q = x / z; //q<10 && q>=1; | |
178 |
|
179 | |||
179 | if (ceiling) { |
|
180 | if (ceiling) { | |
180 | if (q <= 1.0) q = 1; |
|
181 | if (q <= 1.0) q = 1; | |
181 | else if (q <= 2.0) q = 2; |
|
182 | else if (q <= 2.0) q = 2; | |
182 | else if (q <= 5.0) q = 5; |
|
183 | else if (q <= 5.0) q = 5; | |
183 | else q = 10; |
|
184 | else q = 10; | |
184 | } else { |
|
185 | } else { | |
185 | if (q < 1.5) q = 1; |
|
186 | if (q < 1.5) q = 1; | |
186 | else if (q < 3.0) q = 2; |
|
187 | else if (q < 3.0) q = 2; | |
187 | else if (q < 7.0) q = 5; |
|
188 | else if (q < 7.0) q = 5; | |
188 | else q = 10; |
|
189 | else q = 10; | |
189 | } |
|
190 | } | |
190 | return q * z; |
|
191 | return q * z; | |
191 | } |
|
192 | } | |
192 |
|
193 | |||
193 | bool AbstractDomain::attachAxis(QAbstractAxis *axis) |
|
194 | bool AbstractDomain::attachAxis(QAbstractAxis *axis) | |
194 | { |
|
195 | { | |
195 | if (axis->orientation() == Qt::Vertical) { |
|
196 | if (axis->orientation() == Qt::Vertical) { | |
196 | QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal))); |
|
197 | QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal))); | |
197 | QObject::connect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal))); |
|
198 | QObject::connect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal))); | |
198 | } |
|
199 | } | |
199 |
|
200 | |||
200 | if (axis->orientation() == Qt::Horizontal) { |
|
201 | if (axis->orientation() == Qt::Horizontal) { | |
201 | QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal))); |
|
202 | QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal))); | |
202 | QObject::connect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal))); |
|
203 | QObject::connect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal))); | |
203 | } |
|
204 | } | |
204 |
|
205 | |||
205 | return true; |
|
206 | return true; | |
206 | } |
|
207 | } | |
207 |
|
208 | |||
208 | bool AbstractDomain::detachAxis(QAbstractAxis *axis) |
|
209 | bool AbstractDomain::detachAxis(QAbstractAxis *axis) | |
209 | { |
|
210 | { | |
210 | if (axis->orientation() == Qt::Vertical) { |
|
211 | if (axis->orientation() == Qt::Vertical) { | |
211 | QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal))); |
|
212 | QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal))); | |
212 | QObject::disconnect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal))); |
|
213 | QObject::disconnect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal))); | |
213 | } |
|
214 | } | |
214 |
|
215 | |||
215 | if (axis->orientation() == Qt::Horizontal) { |
|
216 | if (axis->orientation() == Qt::Horizontal) { | |
216 | QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal))); |
|
217 | QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal))); | |
217 | QObject::disconnect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal))); |
|
218 | QObject::disconnect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal))); | |
218 | } |
|
219 | } | |
219 |
|
220 | |||
220 | return true; |
|
221 | return true; | |
221 | } |
|
222 | } | |
222 |
|
223 | |||
223 | // operators |
|
224 | // operators | |
224 |
|
225 | |||
225 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const AbstractDomain &domain1, const AbstractDomain &domain2) |
|
226 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const AbstractDomain &domain1, const AbstractDomain &domain2) | |
226 | { |
|
227 | { | |
227 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) |
|
228 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) | |
228 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) |
|
229 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) | |
229 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) |
|
230 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) | |
230 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); |
|
231 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); | |
231 | } |
|
232 | } | |
232 |
|
233 | |||
233 |
|
234 | |||
234 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const AbstractDomain &domain1, const AbstractDomain &domain2) |
|
235 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const AbstractDomain &domain1, const AbstractDomain &domain2) | |
235 | { |
|
236 | { | |
236 | return !(domain1 == domain2); |
|
237 | return !(domain1 == domain2); | |
237 | } |
|
238 | } | |
238 |
|
239 | |||
239 |
|
240 | |||
240 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const AbstractDomain &domain) |
|
241 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const AbstractDomain &domain) | |
241 | { |
|
242 | { | |
242 | #ifdef QT_NO_TEXTSTREAM |
|
243 | #ifdef QT_NO_TEXTSTREAM | |
243 | Q_UNUSED(domain) |
|
244 | Q_UNUSED(domain) | |
244 | #else |
|
245 | #else | |
245 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; |
|
246 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; | |
246 | #endif |
|
247 | #endif | |
247 | return dbg.maybeSpace(); |
|
248 | return dbg.maybeSpace(); | |
248 | } |
|
249 | } | |
249 |
|
250 | |||
250 | // This function adjusts min/max ranges to failsafe values if negative/zero values are attempted. |
|
251 | // This function adjusts min/max ranges to failsafe values if negative/zero values are attempted. | |
251 | void AbstractDomain::adjustLogDomainRanges(qreal &min, qreal &max) |
|
252 | void AbstractDomain::adjustLogDomainRanges(qreal &min, qreal &max) | |
252 | { |
|
253 | { | |
253 | if (min <= 0) { |
|
254 | if (min <= 0) { | |
254 | min = 1.0; |
|
255 | min = 1.0; | |
255 | if (max <= min) |
|
256 | if (max <= min) | |
256 | max = min + 1.0; |
|
257 | max = min + 1.0; | |
257 | } |
|
258 | } | |
258 | } |
|
259 | } | |
259 |
|
260 | |||
260 |
|
261 | |||
261 | #include "moc_abstractdomain_p.cpp" |
|
262 | #include "moc_abstractdomain_p.cpp" | |
262 |
|
263 | |||
263 | QT_CHARTS_END_NAMESPACE |
|
264 | QT_CHARTS_END_NAMESPACE |
@@ -1,276 +1,277 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/logxlogydomain_p.h> |
|
19 | #include <private/logxlogydomain_p.h> | |
20 | #include <private/qabstractaxis_p.h> |
|
20 | #include <private/qabstractaxis_p.h> | |
21 | #include <QtCharts/QLogValueAxis> |
|
21 | #include <QtCharts/QLogValueAxis> | |
22 | #include <QtCore/QtMath> |
|
22 | #include <QtCore/QtMath> | |
|
23 | #include <cmath> | |||
23 |
|
24 | |||
24 | QT_CHARTS_BEGIN_NAMESPACE |
|
25 | QT_CHARTS_BEGIN_NAMESPACE | |
25 |
|
26 | |||
26 | LogXLogYDomain::LogXLogYDomain(QObject *parent) |
|
27 | LogXLogYDomain::LogXLogYDomain(QObject *parent) | |
27 | : AbstractDomain(parent), |
|
28 | : AbstractDomain(parent), | |
28 | m_logLeftX(0), |
|
29 | m_logLeftX(0), | |
29 | m_logRightX(1), |
|
30 | m_logRightX(1), | |
30 | m_logBaseX(10), |
|
31 | m_logBaseX(10), | |
31 | m_logLeftY(0), |
|
32 | m_logLeftY(0), | |
32 | m_logRightY(1), |
|
33 | m_logRightY(1), | |
33 | m_logBaseY(10) |
|
34 | m_logBaseY(10) | |
34 | { |
|
35 | { | |
35 | } |
|
36 | } | |
36 |
|
37 | |||
37 | LogXLogYDomain::~LogXLogYDomain() |
|
38 | LogXLogYDomain::~LogXLogYDomain() | |
38 | { |
|
39 | { | |
39 | } |
|
40 | } | |
40 |
|
41 | |||
41 | void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) |
|
42 | void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) | |
42 | { |
|
43 | { | |
43 | bool axisXChanged = false; |
|
44 | bool axisXChanged = false; | |
44 | bool axisYChanged = false; |
|
45 | bool axisYChanged = false; | |
45 |
|
46 | |||
46 | adjustLogDomainRanges(minX, maxX); |
|
47 | adjustLogDomainRanges(minX, maxX); | |
47 | adjustLogDomainRanges(minY, maxY); |
|
48 | adjustLogDomainRanges(minY, maxY); | |
48 |
|
49 | |||
49 | if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) { |
|
50 | if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) { | |
50 | m_minX = minX; |
|
51 | m_minX = minX; | |
51 | m_maxX = maxX; |
|
52 | m_maxX = maxX; | |
52 | axisXChanged = true; |
|
53 | axisXChanged = true; | |
53 | qreal logMinX = log10(m_minX) / log10(m_logBaseX); |
|
54 | qreal logMinX = std::log10(m_minX) / std::log10(m_logBaseX); | |
54 | qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); |
|
55 | qreal logMaxX = std::log10(m_maxX) / std::log10(m_logBaseX); | |
55 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; |
|
56 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; | |
56 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; |
|
57 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; | |
57 | if(!m_signalsBlocked) |
|
58 | if(!m_signalsBlocked) | |
58 | emit rangeHorizontalChanged(m_minX, m_maxX); |
|
59 | emit rangeHorizontalChanged(m_minX, m_maxX); | |
59 | } |
|
60 | } | |
60 |
|
61 | |||
61 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { |
|
62 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { | |
62 | m_minY = minY; |
|
63 | m_minY = minY; | |
63 | m_maxY = maxY; |
|
64 | m_maxY = maxY; | |
64 | axisYChanged = true; |
|
65 | axisYChanged = true; | |
65 | qreal logMinY = log10(m_minY) / log10(m_logBaseY); |
|
66 | qreal logMinY = std::log10(m_minY) / std::log10(m_logBaseY); | |
66 | qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); |
|
67 | qreal logMaxY = std::log10(m_maxY) / std::log10(m_logBaseY); | |
67 | m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; |
|
68 | m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; | |
68 | m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; |
|
69 | m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; | |
69 | if (!m_signalsBlocked) |
|
70 | if (!m_signalsBlocked) | |
70 | emit rangeVerticalChanged(m_minY, m_maxY); |
|
71 | emit rangeVerticalChanged(m_minY, m_maxY); | |
71 | } |
|
72 | } | |
72 |
|
73 | |||
73 | if (axisXChanged || axisYChanged) |
|
74 | if (axisXChanged || axisYChanged) | |
74 | emit updated(); |
|
75 | emit updated(); | |
75 | } |
|
76 | } | |
76 |
|
77 | |||
77 | void LogXLogYDomain::zoomIn(const QRectF &rect) |
|
78 | void LogXLogYDomain::zoomIn(const QRectF &rect) | |
78 | { |
|
79 | { | |
79 | storeZoomReset(); |
|
80 | storeZoomReset(); | |
80 | qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; |
|
81 | qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; | |
81 | qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; |
|
82 | qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; | |
82 | qreal leftX = qPow(m_logBaseX, logLeftX); |
|
83 | qreal leftX = qPow(m_logBaseX, logLeftX); | |
83 | qreal rightX = qPow(m_logBaseX, logRightX); |
|
84 | qreal rightX = qPow(m_logBaseX, logRightX); | |
84 | qreal minX = leftX < rightX ? leftX : rightX; |
|
85 | qreal minX = leftX < rightX ? leftX : rightX; | |
85 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
86 | qreal maxX = leftX > rightX ? leftX : rightX; | |
86 |
|
87 | |||
87 | qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height(); |
|
88 | qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height(); | |
88 | qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height(); |
|
89 | qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height(); | |
89 | qreal leftY = qPow(m_logBaseY, logLeftY); |
|
90 | qreal leftY = qPow(m_logBaseY, logLeftY); | |
90 | qreal rightY = qPow(m_logBaseY, logRightY); |
|
91 | qreal rightY = qPow(m_logBaseY, logRightY); | |
91 | qreal minY = leftY < rightY ? leftY : rightY; |
|
92 | qreal minY = leftY < rightY ? leftY : rightY; | |
92 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
93 | qreal maxY = leftY > rightY ? leftY : rightY; | |
93 |
|
94 | |||
94 | setRange(minX, maxX, minY, maxY); |
|
95 | setRange(minX, maxX, minY, maxY); | |
95 | } |
|
96 | } | |
96 |
|
97 | |||
97 | void LogXLogYDomain::zoomOut(const QRectF &rect) |
|
98 | void LogXLogYDomain::zoomOut(const QRectF &rect) | |
98 | { |
|
99 | { | |
99 | storeZoomReset(); |
|
100 | storeZoomReset(); | |
100 | const qreal factorX = m_size.width() / rect.width(); |
|
101 | const qreal factorX = m_size.width() / rect.width(); | |
101 | const qreal factorY = m_size.height() / rect.height(); |
|
102 | const qreal factorY = m_size.height() / rect.height(); | |
102 |
|
103 | |||
103 | qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX); |
|
104 | qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX); | |
104 | qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX); |
|
105 | qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX); | |
105 | qreal leftX = qPow(m_logBaseX, logLeftX); |
|
106 | qreal leftX = qPow(m_logBaseX, logLeftX); | |
106 | qreal rightX = qPow(m_logBaseX, logRIghtX); |
|
107 | qreal rightX = qPow(m_logBaseX, logRIghtX); | |
107 | qreal minX = leftX < rightX ? leftX : rightX; |
|
108 | qreal minX = leftX < rightX ? leftX : rightX; | |
108 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
109 | qreal maxX = leftX > rightX ? leftX : rightX; | |
109 |
|
110 | |||
110 | qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY); |
|
111 | qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY); | |
111 | qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY); |
|
112 | qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY); | |
112 | qreal leftY = qPow(m_logBaseY, newLogMinY); |
|
113 | qreal leftY = qPow(m_logBaseY, newLogMinY); | |
113 | qreal rightY = qPow(m_logBaseY, newLogMaxY); |
|
114 | qreal rightY = qPow(m_logBaseY, newLogMaxY); | |
114 | qreal minY = leftY < rightY ? leftY : rightY; |
|
115 | qreal minY = leftY < rightY ? leftY : rightY; | |
115 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
116 | qreal maxY = leftY > rightY ? leftY : rightY; | |
116 |
|
117 | |||
117 | setRange(minX, maxX, minY, maxY); |
|
118 | setRange(minX, maxX, minY, maxY); | |
118 | } |
|
119 | } | |
119 |
|
120 | |||
120 | void LogXLogYDomain::move(qreal dx, qreal dy) |
|
121 | void LogXLogYDomain::move(qreal dx, qreal dy) | |
121 | { |
|
122 | { | |
122 | qreal stepX = dx * qAbs(m_logRightX - m_logLeftX) / m_size.width(); |
|
123 | qreal stepX = dx * qAbs(m_logRightX - m_logLeftX) / m_size.width(); | |
123 | qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); |
|
124 | qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); | |
124 | qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); |
|
125 | qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); | |
125 | qreal minX = leftX < rightX ? leftX : rightX; |
|
126 | qreal minX = leftX < rightX ? leftX : rightX; | |
126 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
127 | qreal maxX = leftX > rightX ? leftX : rightX; | |
127 |
|
128 | |||
128 | qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height(); |
|
129 | qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height(); | |
129 | qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY); |
|
130 | qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY); | |
130 | qreal rightY = qPow(m_logBaseY, m_logRightY + stepY); |
|
131 | qreal rightY = qPow(m_logBaseY, m_logRightY + stepY); | |
131 | qreal minY = leftY < rightY ? leftY : rightY; |
|
132 | qreal minY = leftY < rightY ? leftY : rightY; | |
132 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
133 | qreal maxY = leftY > rightY ? leftY : rightY; | |
133 |
|
134 | |||
134 | setRange(minX, maxX, minY, maxY); |
|
135 | setRange(minX, maxX, minY, maxY); | |
135 | } |
|
136 | } | |
136 |
|
137 | |||
137 | QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const |
|
138 | QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const | |
138 | { |
|
139 | { | |
139 | const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); |
|
140 | const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); | |
140 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); |
|
141 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); | |
141 | qreal x(0); |
|
142 | qreal x(0); | |
142 | qreal y(0); |
|
143 | qreal y(0); | |
143 | if (point.x() > 0 && point.y() > 0) { |
|
144 | if (point.x() > 0 && point.y() > 0) { | |
144 | x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; |
|
145 | x = (std::log10(point.x()) / std::log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; | |
145 | y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); |
|
146 | y = (std::log10(point.y()) / std::log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); | |
146 | ok = true; |
|
147 | ok = true; | |
147 | } else { |
|
148 | } else { | |
148 | qWarning() << "Logarithms of zero and negative values are undefined."; |
|
149 | qWarning() << "Logarithms of zero and negative values are undefined."; | |
149 | ok = false; |
|
150 | ok = false; | |
150 | if (point.x() > 0) |
|
151 | if (point.x() > 0) | |
151 | x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; |
|
152 | x = (std::log10(point.x()) / std::log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; | |
152 | else |
|
153 | else | |
153 | x = 0; |
|
154 | x = 0; | |
154 | if (point.y() > 0) { |
|
155 | if (point.y() > 0) { | |
155 | y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY |
|
156 | y = (std::log10(point.y()) / std::log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY | |
156 | + m_size.height(); |
|
157 | + m_size.height(); | |
157 | } else { |
|
158 | } else { | |
158 | y = m_size.height(); |
|
159 | y = m_size.height(); | |
159 | } |
|
160 | } | |
160 | } |
|
161 | } | |
161 | return QPointF(x, y); |
|
162 | return QPointF(x, y); | |
162 | } |
|
163 | } | |
163 |
|
164 | |||
164 | QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const |
|
165 | QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const | |
165 | { |
|
166 | { | |
166 | const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); |
|
167 | const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); | |
167 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); |
|
168 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); | |
168 |
|
169 | |||
169 | QVector<QPointF> result; |
|
170 | QVector<QPointF> result; | |
170 | result.resize(vector.count()); |
|
171 | result.resize(vector.count()); | |
171 |
|
172 | |||
172 | for (int i = 0; i < vector.count(); ++i) { |
|
173 | for (int i = 0; i < vector.count(); ++i) { | |
173 | if (vector[i].x() > 0 && vector[i].y() > 0) { |
|
174 | if (vector[i].x() > 0 && vector[i].y() > 0) { | |
174 | qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; |
|
175 | qreal x = (std::log10(vector[i].x()) / std::log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; | |
175 | qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); |
|
176 | qreal y = (std::log10(vector[i].y()) / std::log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); | |
176 | result[i].setX(x); |
|
177 | result[i].setX(x); | |
177 | result[i].setY(y); |
|
178 | result[i].setY(y); | |
178 | } else { |
|
179 | } else { | |
179 | qWarning() << "Logarithms of zero and negative values are undefined."; |
|
180 | qWarning() << "Logarithms of zero and negative values are undefined."; | |
180 | return QVector<QPointF>(); |
|
181 | return QVector<QPointF>(); | |
181 | } |
|
182 | } | |
182 | } |
|
183 | } | |
183 | return result; |
|
184 | return result; | |
184 | } |
|
185 | } | |
185 |
|
186 | |||
186 | QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const |
|
187 | QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const | |
187 | { |
|
188 | { | |
188 | const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); |
|
189 | const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX); | |
189 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); |
|
190 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); | |
190 | qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX); |
|
191 | qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX); | |
191 | qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY); |
|
192 | qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY); | |
192 | return QPointF(x, y); |
|
193 | return QPointF(x, y); | |
193 | } |
|
194 | } | |
194 |
|
195 | |||
195 | bool LogXLogYDomain::attachAxis(QAbstractAxis *axis) |
|
196 | bool LogXLogYDomain::attachAxis(QAbstractAxis *axis) | |
196 | { |
|
197 | { | |
197 | AbstractDomain::attachAxis(axis); |
|
198 | AbstractDomain::attachAxis(axis); | |
198 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
199 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
199 |
|
200 | |||
200 | if (logAxis && logAxis->orientation() == Qt::Vertical) { |
|
201 | if (logAxis && logAxis->orientation() == Qt::Vertical) { | |
201 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); |
|
202 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); | |
202 | handleVerticalAxisBaseChanged(logAxis->base()); |
|
203 | handleVerticalAxisBaseChanged(logAxis->base()); | |
203 | } |
|
204 | } | |
204 |
|
205 | |||
205 | if (logAxis && logAxis->orientation() == Qt::Horizontal) { |
|
206 | if (logAxis && logAxis->orientation() == Qt::Horizontal) { | |
206 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); |
|
207 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); | |
207 | handleHorizontalAxisBaseChanged(logAxis->base()); |
|
208 | handleHorizontalAxisBaseChanged(logAxis->base()); | |
208 | } |
|
209 | } | |
209 |
|
210 | |||
210 | return true; |
|
211 | return true; | |
211 | } |
|
212 | } | |
212 |
|
213 | |||
213 | bool LogXLogYDomain::detachAxis(QAbstractAxis *axis) |
|
214 | bool LogXLogYDomain::detachAxis(QAbstractAxis *axis) | |
214 | { |
|
215 | { | |
215 | AbstractDomain::detachAxis(axis); |
|
216 | AbstractDomain::detachAxis(axis); | |
216 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
217 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
217 |
|
218 | |||
218 | if (logAxis && logAxis->orientation() == Qt::Vertical) |
|
219 | if (logAxis && logAxis->orientation() == Qt::Vertical) | |
219 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); |
|
220 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); | |
220 |
|
221 | |||
221 | if (logAxis && logAxis->orientation() == Qt::Horizontal) |
|
222 | if (logAxis && logAxis->orientation() == Qt::Horizontal) | |
222 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); |
|
223 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); | |
223 |
|
224 | |||
224 | return true; |
|
225 | return true; | |
225 | } |
|
226 | } | |
226 |
|
227 | |||
227 | void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY) |
|
228 | void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY) | |
228 | { |
|
229 | { | |
229 | m_logBaseY = baseY; |
|
230 | m_logBaseY = baseY; | |
230 | qreal logMinY = log10(m_minY) / log10(m_logBaseY); |
|
231 | qreal logMinY = std::log10(m_minY) / std::log10(m_logBaseY); | |
231 | qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); |
|
232 | qreal logMaxY = std::log10(m_maxY) / std::log10(m_logBaseY); | |
232 | m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; |
|
233 | m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; | |
233 | m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; |
|
234 | m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; | |
234 | emit updated(); |
|
235 | emit updated(); | |
235 | } |
|
236 | } | |
236 |
|
237 | |||
237 | void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX) |
|
238 | void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX) | |
238 | { |
|
239 | { | |
239 | m_logBaseX = baseX; |
|
240 | m_logBaseX = baseX; | |
240 | qreal logMinX = log10(m_minX) / log10(m_logBaseX); |
|
241 | qreal logMinX = std::log10(m_minX) / std::log10(m_logBaseX); | |
241 | qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); |
|
242 | qreal logMaxX = std::log10(m_maxX) / std::log10(m_logBaseX); | |
242 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; |
|
243 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; | |
243 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; |
|
244 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; | |
244 | emit updated(); |
|
245 | emit updated(); | |
245 | } |
|
246 | } | |
246 |
|
247 | |||
247 | // operators |
|
248 | // operators | |
248 |
|
249 | |||
249 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2) |
|
250 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2) | |
250 | { |
|
251 | { | |
251 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) |
|
252 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) | |
252 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) |
|
253 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) | |
253 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) |
|
254 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) | |
254 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); |
|
255 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); | |
255 | } |
|
256 | } | |
256 |
|
257 | |||
257 |
|
258 | |||
258 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2) |
|
259 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2) | |
259 | { |
|
260 | { | |
260 | return !(domain1 == domain2); |
|
261 | return !(domain1 == domain2); | |
261 | } |
|
262 | } | |
262 |
|
263 | |||
263 |
|
264 | |||
264 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain) |
|
265 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain) | |
265 | { |
|
266 | { | |
266 | #ifdef QT_NO_TEXTSTREAM |
|
267 | #ifdef QT_NO_TEXTSTREAM | |
267 | Q_UNUSED(domain) |
|
268 | Q_UNUSED(domain) | |
268 | #else |
|
269 | #else | |
269 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; |
|
270 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; | |
270 | #endif |
|
271 | #endif | |
271 | return dbg.maybeSpace(); |
|
272 | return dbg.maybeSpace(); | |
272 | } |
|
273 | } | |
273 |
|
274 | |||
274 | #include "moc_logxlogydomain_p.cpp" |
|
275 | #include "moc_logxlogydomain_p.cpp" | |
275 |
|
276 | |||
276 | QT_CHARTS_END_NAMESPACE |
|
277 | QT_CHARTS_END_NAMESPACE |
@@ -1,271 +1,272 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/logxlogypolardomain_p.h> |
|
19 | #include <private/logxlogypolardomain_p.h> | |
20 | #include <private/qabstractaxis_p.h> |
|
20 | #include <private/qabstractaxis_p.h> | |
21 | #include <QtCharts/QLogValueAxis> |
|
21 | #include <QtCharts/QLogValueAxis> | |
22 | #include <QtCore/QtMath> |
|
22 | #include <QtCore/QtMath> | |
|
23 | #include <cmath> | |||
23 |
|
24 | |||
24 | QT_CHARTS_BEGIN_NAMESPACE |
|
25 | QT_CHARTS_BEGIN_NAMESPACE | |
25 |
|
26 | |||
26 | LogXLogYPolarDomain::LogXLogYPolarDomain(QObject *parent) |
|
27 | LogXLogYPolarDomain::LogXLogYPolarDomain(QObject *parent) | |
27 | : PolarDomain(parent), |
|
28 | : PolarDomain(parent), | |
28 | m_logLeftX(0), |
|
29 | m_logLeftX(0), | |
29 | m_logRightX(1), |
|
30 | m_logRightX(1), | |
30 | m_logBaseX(10), |
|
31 | m_logBaseX(10), | |
31 | m_logInnerY(0), |
|
32 | m_logInnerY(0), | |
32 | m_logOuterY(1), |
|
33 | m_logOuterY(1), | |
33 | m_logBaseY(10) |
|
34 | m_logBaseY(10) | |
34 | { |
|
35 | { | |
35 | } |
|
36 | } | |
36 |
|
37 | |||
37 | LogXLogYPolarDomain::~LogXLogYPolarDomain() |
|
38 | LogXLogYPolarDomain::~LogXLogYPolarDomain() | |
38 | { |
|
39 | { | |
39 | } |
|
40 | } | |
40 |
|
41 | |||
41 | void LogXLogYPolarDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) |
|
42 | void LogXLogYPolarDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) | |
42 | { |
|
43 | { | |
43 | bool axisXChanged = false; |
|
44 | bool axisXChanged = false; | |
44 | bool axisYChanged = false; |
|
45 | bool axisYChanged = false; | |
45 |
|
46 | |||
46 | adjustLogDomainRanges(minX, maxX); |
|
47 | adjustLogDomainRanges(minX, maxX); | |
47 | adjustLogDomainRanges(minY, maxY); |
|
48 | adjustLogDomainRanges(minY, maxY); | |
48 |
|
49 | |||
49 | if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) { |
|
50 | if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) { | |
50 | m_minX = minX; |
|
51 | m_minX = minX; | |
51 | m_maxX = maxX; |
|
52 | m_maxX = maxX; | |
52 | axisXChanged = true; |
|
53 | axisXChanged = true; | |
53 | qreal logMinX = log10(m_minX) / log10(m_logBaseX); |
|
54 | qreal logMinX = std::log10(m_minX) / std::log10(m_logBaseX); | |
54 | qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); |
|
55 | qreal logMaxX = std::log10(m_maxX) / std::log10(m_logBaseX); | |
55 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; |
|
56 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; | |
56 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; |
|
57 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; | |
57 | if (!m_signalsBlocked) |
|
58 | if (!m_signalsBlocked) | |
58 | emit rangeHorizontalChanged(m_minX, m_maxX); |
|
59 | emit rangeHorizontalChanged(m_minX, m_maxX); | |
59 | } |
|
60 | } | |
60 |
|
61 | |||
61 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { |
|
62 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { | |
62 | m_minY = minY; |
|
63 | m_minY = minY; | |
63 | m_maxY = maxY; |
|
64 | m_maxY = maxY; | |
64 | axisYChanged = true; |
|
65 | axisYChanged = true; | |
65 | qreal logMinY = log10(m_minY) / log10(m_logBaseY); |
|
66 | qreal logMinY = std::log10(m_minY) / std::log10(m_logBaseY); | |
66 | qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); |
|
67 | qreal logMaxY = std::log10(m_maxY) / std::log10(m_logBaseY); | |
67 | m_logInnerY = logMinY < logMaxY ? logMinY : logMaxY; |
|
68 | m_logInnerY = logMinY < logMaxY ? logMinY : logMaxY; | |
68 | m_logOuterY = logMinY > logMaxY ? logMinY : logMaxY; |
|
69 | m_logOuterY = logMinY > logMaxY ? logMinY : logMaxY; | |
69 | if (!m_signalsBlocked) |
|
70 | if (!m_signalsBlocked) | |
70 | emit rangeVerticalChanged(m_minY, m_maxY); |
|
71 | emit rangeVerticalChanged(m_minY, m_maxY); | |
71 | } |
|
72 | } | |
72 |
|
73 | |||
73 | if (axisXChanged || axisYChanged) |
|
74 | if (axisXChanged || axisYChanged) | |
74 | emit updated(); |
|
75 | emit updated(); | |
75 | } |
|
76 | } | |
76 |
|
77 | |||
77 | void LogXLogYPolarDomain::zoomIn(const QRectF &rect) |
|
78 | void LogXLogYPolarDomain::zoomIn(const QRectF &rect) | |
78 | { |
|
79 | { | |
79 | storeZoomReset(); |
|
80 | storeZoomReset(); | |
80 | qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; |
|
81 | qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; | |
81 | qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; |
|
82 | qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; | |
82 | qreal leftX = qPow(m_logBaseX, logLeftX); |
|
83 | qreal leftX = qPow(m_logBaseX, logLeftX); | |
83 | qreal rightX = qPow(m_logBaseX, logRightX); |
|
84 | qreal rightX = qPow(m_logBaseX, logRightX); | |
84 | qreal minX = leftX < rightX ? leftX : rightX; |
|
85 | qreal minX = leftX < rightX ? leftX : rightX; | |
85 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
86 | qreal maxX = leftX > rightX ? leftX : rightX; | |
86 |
|
87 | |||
87 | qreal logLeftY = m_logOuterY - rect.bottom() * (m_logOuterY - m_logInnerY) / m_size.height(); |
|
88 | qreal logLeftY = m_logOuterY - rect.bottom() * (m_logOuterY - m_logInnerY) / m_size.height(); | |
88 | qreal logRightY = m_logOuterY - rect.top() * (m_logOuterY - m_logInnerY) / m_size.height(); |
|
89 | qreal logRightY = m_logOuterY - rect.top() * (m_logOuterY - m_logInnerY) / m_size.height(); | |
89 | qreal leftY = qPow(m_logBaseY, logLeftY); |
|
90 | qreal leftY = qPow(m_logBaseY, logLeftY); | |
90 | qreal rightY = qPow(m_logBaseY, logRightY); |
|
91 | qreal rightY = qPow(m_logBaseY, logRightY); | |
91 | qreal minY = leftY < rightY ? leftY : rightY; |
|
92 | qreal minY = leftY < rightY ? leftY : rightY; | |
92 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
93 | qreal maxY = leftY > rightY ? leftY : rightY; | |
93 |
|
94 | |||
94 | setRange(minX, maxX, minY, maxY); |
|
95 | setRange(minX, maxX, minY, maxY); | |
95 | } |
|
96 | } | |
96 |
|
97 | |||
97 | void LogXLogYPolarDomain::zoomOut(const QRectF &rect) |
|
98 | void LogXLogYPolarDomain::zoomOut(const QRectF &rect) | |
98 | { |
|
99 | { | |
99 | storeZoomReset(); |
|
100 | storeZoomReset(); | |
100 | const qreal factorX = m_size.width() / rect.width(); |
|
101 | const qreal factorX = m_size.width() / rect.width(); | |
101 |
|
102 | |||
102 | qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 - factorX); |
|
103 | qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 - factorX); | |
103 | qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 + factorX); |
|
104 | qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 + factorX); | |
104 | qreal leftX = qPow(m_logBaseX, logLeftX); |
|
105 | qreal leftX = qPow(m_logBaseX, logLeftX); | |
105 | qreal rightX = qPow(m_logBaseX, logRIghtX); |
|
106 | qreal rightX = qPow(m_logBaseX, logRIghtX); | |
106 | qreal minX = leftX < rightX ? leftX : rightX; |
|
107 | qreal minX = leftX < rightX ? leftX : rightX; | |
107 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
108 | qreal maxX = leftX > rightX ? leftX : rightX; | |
108 |
|
109 | |||
109 | const qreal factorY = m_size.height() / rect.height(); |
|
110 | const qreal factorY = m_size.height() / rect.height(); | |
110 | qreal newLogMinY = m_logInnerY + (m_logOuterY - m_logInnerY) / 2.0 * (1.0 - factorY); |
|
111 | qreal newLogMinY = m_logInnerY + (m_logOuterY - m_logInnerY) / 2.0 * (1.0 - factorY); | |
111 | qreal newLogMaxY = m_logInnerY + (m_logOuterY - m_logInnerY) / 2.0 * (1.0 + factorY); |
|
112 | qreal newLogMaxY = m_logInnerY + (m_logOuterY - m_logInnerY) / 2.0 * (1.0 + factorY); | |
112 | qreal leftY = qPow(m_logBaseY, newLogMinY); |
|
113 | qreal leftY = qPow(m_logBaseY, newLogMinY); | |
113 | qreal rightY = qPow(m_logBaseY, newLogMaxY); |
|
114 | qreal rightY = qPow(m_logBaseY, newLogMaxY); | |
114 | qreal minY = leftY < rightY ? leftY : rightY; |
|
115 | qreal minY = leftY < rightY ? leftY : rightY; | |
115 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
116 | qreal maxY = leftY > rightY ? leftY : rightY; | |
116 |
|
117 | |||
117 | setRange(minX, maxX, minY, maxY); |
|
118 | setRange(minX, maxX, minY, maxY); | |
118 | } |
|
119 | } | |
119 |
|
120 | |||
120 | void LogXLogYPolarDomain::move(qreal dx, qreal dy) |
|
121 | void LogXLogYPolarDomain::move(qreal dx, qreal dy) | |
121 | { |
|
122 | { | |
122 | qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width(); |
|
123 | qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width(); | |
123 | qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); |
|
124 | qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); | |
124 | qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); |
|
125 | qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); | |
125 | qreal minX = leftX < rightX ? leftX : rightX; |
|
126 | qreal minX = leftX < rightX ? leftX : rightX; | |
126 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
127 | qreal maxX = leftX > rightX ? leftX : rightX; | |
127 |
|
128 | |||
128 | qreal stepY = dy * (m_logOuterY - m_logInnerY) / m_radius; |
|
129 | qreal stepY = dy * (m_logOuterY - m_logInnerY) / m_radius; | |
129 | qreal leftY = qPow(m_logBaseY, m_logInnerY + stepY); |
|
130 | qreal leftY = qPow(m_logBaseY, m_logInnerY + stepY); | |
130 | qreal rightY = qPow(m_logBaseY, m_logOuterY + stepY); |
|
131 | qreal rightY = qPow(m_logBaseY, m_logOuterY + stepY); | |
131 | qreal minY = leftY < rightY ? leftY : rightY; |
|
132 | qreal minY = leftY < rightY ? leftY : rightY; | |
132 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
133 | qreal maxY = leftY > rightY ? leftY : rightY; | |
133 |
|
134 | |||
134 | setRange(minX, maxX, minY, maxY); |
|
135 | setRange(minX, maxX, minY, maxY); | |
135 | } |
|
136 | } | |
136 |
|
137 | |||
137 | qreal LogXLogYPolarDomain::toAngularCoordinate(qreal value, bool &ok) const |
|
138 | qreal LogXLogYPolarDomain::toAngularCoordinate(qreal value, bool &ok) const | |
138 | { |
|
139 | { | |
139 | qreal retVal; |
|
140 | qreal retVal; | |
140 | if (value <= 0) { |
|
141 | if (value <= 0) { | |
141 | ok = false; |
|
142 | ok = false; | |
142 | retVal = 0.0; |
|
143 | retVal = 0.0; | |
143 | } else { |
|
144 | } else { | |
144 | ok = true; |
|
145 | ok = true; | |
145 | const qreal tickSpan = 360.0 / qAbs(m_logRightX - m_logLeftX); |
|
146 | const qreal tickSpan = 360.0 / qAbs(m_logRightX - m_logLeftX); | |
146 | const qreal logValue = log10(value) / log10(m_logBaseX); |
|
147 | const qreal logValue = std::log10(value) / std::log10(m_logBaseX); | |
147 | const qreal valueDelta = logValue - m_logLeftX; |
|
148 | const qreal valueDelta = logValue - m_logLeftX; | |
148 |
|
149 | |||
149 | retVal = valueDelta * tickSpan; |
|
150 | retVal = valueDelta * tickSpan; | |
150 | } |
|
151 | } | |
151 | return retVal; |
|
152 | return retVal; | |
152 | } |
|
153 | } | |
153 |
|
154 | |||
154 | qreal LogXLogYPolarDomain::toRadialCoordinate(qreal value, bool &ok) const |
|
155 | qreal LogXLogYPolarDomain::toRadialCoordinate(qreal value, bool &ok) const | |
155 | { |
|
156 | { | |
156 | qreal retVal; |
|
157 | qreal retVal; | |
157 | if (value <= 0) { |
|
158 | if (value <= 0) { | |
158 | ok = false; |
|
159 | ok = false; | |
159 | retVal = 0.0; |
|
160 | retVal = 0.0; | |
160 | } else { |
|
161 | } else { | |
161 | ok = true; |
|
162 | ok = true; | |
162 | const qreal tickSpan = m_radius / qAbs(m_logOuterY - m_logInnerY); |
|
163 | const qreal tickSpan = m_radius / qAbs(m_logOuterY - m_logInnerY); | |
163 | const qreal logValue = log10(value) / log10(m_logBaseY); |
|
164 | const qreal logValue = std::log10(value) / std::log10(m_logBaseY); | |
164 | const qreal valueDelta = logValue - m_logInnerY; |
|
165 | const qreal valueDelta = logValue - m_logInnerY; | |
165 |
|
166 | |||
166 | retVal = valueDelta * tickSpan; |
|
167 | retVal = valueDelta * tickSpan; | |
167 |
|
168 | |||
168 | if (retVal < 0.0) |
|
169 | if (retVal < 0.0) | |
169 | retVal = 0.0; |
|
170 | retVal = 0.0; | |
170 | } |
|
171 | } | |
171 | return retVal; |
|
172 | return retVal; | |
172 | } |
|
173 | } | |
173 |
|
174 | |||
174 | QPointF LogXLogYPolarDomain::calculateDomainPoint(const QPointF &point) const |
|
175 | QPointF LogXLogYPolarDomain::calculateDomainPoint(const QPointF &point) const | |
175 | { |
|
176 | { | |
176 | if (point == m_center) |
|
177 | if (point == m_center) | |
177 | return QPointF(0.0, m_minY); |
|
178 | return QPointF(0.0, m_minY); | |
178 |
|
179 | |||
179 | QLineF line(m_center, point); |
|
180 | QLineF line(m_center, point); | |
180 | qreal a = 90.0 - line.angle(); |
|
181 | qreal a = 90.0 - line.angle(); | |
181 | if (a < 0.0) |
|
182 | if (a < 0.0) | |
182 | a += 360.0; |
|
183 | a += 360.0; | |
183 |
|
184 | |||
184 | const qreal deltaX = 360.0 / qAbs(m_logRightX - m_logLeftX); |
|
185 | const qreal deltaX = 360.0 / qAbs(m_logRightX - m_logLeftX); | |
185 | a = qPow(m_logBaseX, m_logLeftX + (a / deltaX)); |
|
186 | a = qPow(m_logBaseX, m_logLeftX + (a / deltaX)); | |
186 |
|
187 | |||
187 | const qreal deltaY = m_radius / qAbs(m_logOuterY - m_logInnerY); |
|
188 | const qreal deltaY = m_radius / qAbs(m_logOuterY - m_logInnerY); | |
188 | qreal r = qPow(m_logBaseY, m_logInnerY + (line.length() / deltaY)); |
|
189 | qreal r = qPow(m_logBaseY, m_logInnerY + (line.length() / deltaY)); | |
189 |
|
190 | |||
190 | return QPointF(a, r); |
|
191 | return QPointF(a, r); | |
191 | } |
|
192 | } | |
192 |
|
193 | |||
193 | bool LogXLogYPolarDomain::attachAxis(QAbstractAxis *axis) |
|
194 | bool LogXLogYPolarDomain::attachAxis(QAbstractAxis *axis) | |
194 | { |
|
195 | { | |
195 | AbstractDomain::attachAxis(axis); |
|
196 | AbstractDomain::attachAxis(axis); | |
196 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
197 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
197 |
|
198 | |||
198 | if (logAxis && logAxis->orientation() == Qt::Horizontal) { |
|
199 | if (logAxis && logAxis->orientation() == Qt::Horizontal) { | |
199 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); |
|
200 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); | |
200 | handleHorizontalAxisBaseChanged(logAxis->base()); |
|
201 | handleHorizontalAxisBaseChanged(logAxis->base()); | |
201 | } else if (logAxis && logAxis->orientation() == Qt::Vertical){ |
|
202 | } else if (logAxis && logAxis->orientation() == Qt::Vertical){ | |
202 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); |
|
203 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); | |
203 | handleVerticalAxisBaseChanged(logAxis->base()); |
|
204 | handleVerticalAxisBaseChanged(logAxis->base()); | |
204 | } |
|
205 | } | |
205 |
|
206 | |||
206 | return true; |
|
207 | return true; | |
207 | } |
|
208 | } | |
208 |
|
209 | |||
209 | bool LogXLogYPolarDomain::detachAxis(QAbstractAxis *axis) |
|
210 | bool LogXLogYPolarDomain::detachAxis(QAbstractAxis *axis) | |
210 | { |
|
211 | { | |
211 | AbstractDomain::detachAxis(axis); |
|
212 | AbstractDomain::detachAxis(axis); | |
212 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
213 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
213 |
|
214 | |||
214 | if (logAxis && logAxis->orientation() == Qt::Horizontal) |
|
215 | if (logAxis && logAxis->orientation() == Qt::Horizontal) | |
215 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); |
|
216 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); | |
216 | else if (logAxis && logAxis->orientation() == Qt::Vertical) |
|
217 | else if (logAxis && logAxis->orientation() == Qt::Vertical) | |
217 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); |
|
218 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); | |
218 |
|
219 | |||
219 | return true; |
|
220 | return true; | |
220 | } |
|
221 | } | |
221 |
|
222 | |||
222 | void LogXLogYPolarDomain::handleHorizontalAxisBaseChanged(qreal baseX) |
|
223 | void LogXLogYPolarDomain::handleHorizontalAxisBaseChanged(qreal baseX) | |
223 | { |
|
224 | { | |
224 | m_logBaseX = baseX; |
|
225 | m_logBaseX = baseX; | |
225 | qreal logMinX = log10(m_minX) / log10(m_logBaseX); |
|
226 | qreal logMinX = std::log10(m_minX) / std::log10(m_logBaseX); | |
226 | qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); |
|
227 | qreal logMaxX = std::log10(m_maxX) / std::log10(m_logBaseX); | |
227 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; |
|
228 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; | |
228 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; |
|
229 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; | |
229 | emit updated(); |
|
230 | emit updated(); | |
230 | } |
|
231 | } | |
231 |
|
232 | |||
232 | void LogXLogYPolarDomain::handleVerticalAxisBaseChanged(qreal baseY) |
|
233 | void LogXLogYPolarDomain::handleVerticalAxisBaseChanged(qreal baseY) | |
233 | { |
|
234 | { | |
234 | m_logBaseY = baseY; |
|
235 | m_logBaseY = baseY; | |
235 | qreal logMinY = log10(m_minY) / log10(m_logBaseY); |
|
236 | qreal logMinY = std::log10(m_minY) / std::log10(m_logBaseY); | |
236 | qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); |
|
237 | qreal logMaxY = std::log10(m_maxY) / std::log10(m_logBaseY); | |
237 | m_logInnerY = logMinY < logMaxY ? logMinY : logMaxY; |
|
238 | m_logInnerY = logMinY < logMaxY ? logMinY : logMaxY; | |
238 | m_logOuterY = logMinY > logMaxY ? logMinY : logMaxY; |
|
239 | m_logOuterY = logMinY > logMaxY ? logMinY : logMaxY; | |
239 | emit updated(); |
|
240 | emit updated(); | |
240 | } |
|
241 | } | |
241 |
|
242 | |||
242 | // operators |
|
243 | // operators | |
243 |
|
244 | |||
244 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const LogXLogYPolarDomain &domain1, const LogXLogYPolarDomain &domain2) |
|
245 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const LogXLogYPolarDomain &domain1, const LogXLogYPolarDomain &domain2) | |
245 | { |
|
246 | { | |
246 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) |
|
247 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) | |
247 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) |
|
248 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) | |
248 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) |
|
249 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) | |
249 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); |
|
250 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); | |
250 | } |
|
251 | } | |
251 |
|
252 | |||
252 |
|
253 | |||
253 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const LogXLogYPolarDomain &domain1, const LogXLogYPolarDomain &domain2) |
|
254 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const LogXLogYPolarDomain &domain1, const LogXLogYPolarDomain &domain2) | |
254 | { |
|
255 | { | |
255 | return !(domain1 == domain2); |
|
256 | return !(domain1 == domain2); | |
256 | } |
|
257 | } | |
257 |
|
258 | |||
258 |
|
259 | |||
259 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYPolarDomain &domain) |
|
260 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYPolarDomain &domain) | |
260 | { |
|
261 | { | |
261 | #ifdef QT_NO_TEXTSTREAM |
|
262 | #ifdef QT_NO_TEXTSTREAM | |
262 | Q_UNUSED(domain) |
|
263 | Q_UNUSED(domain) | |
263 | #else |
|
264 | #else | |
264 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; |
|
265 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; | |
265 | #endif |
|
266 | #endif | |
266 | return dbg.maybeSpace(); |
|
267 | return dbg.maybeSpace(); | |
267 | } |
|
268 | } | |
268 |
|
269 | |||
269 | #include "moc_logxlogypolardomain_p.cpp" |
|
270 | #include "moc_logxlogypolardomain_p.cpp" | |
270 |
|
271 | |||
271 | QT_CHARTS_END_NAMESPACE |
|
272 | QT_CHARTS_END_NAMESPACE |
@@ -1,243 +1,244 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/logxydomain_p.h> |
|
19 | #include <private/logxydomain_p.h> | |
20 | #include <private/qabstractaxis_p.h> |
|
20 | #include <private/qabstractaxis_p.h> | |
21 | #include <QtCharts/QLogValueAxis> |
|
21 | #include <QtCharts/QLogValueAxis> | |
22 | #include <QtCore/QtMath> |
|
22 | #include <QtCore/QtMath> | |
|
23 | #include <cmath> | |||
23 |
|
24 | |||
24 | QT_CHARTS_BEGIN_NAMESPACE |
|
25 | QT_CHARTS_BEGIN_NAMESPACE | |
25 |
|
26 | |||
26 | LogXYDomain::LogXYDomain(QObject *parent) |
|
27 | LogXYDomain::LogXYDomain(QObject *parent) | |
27 | : AbstractDomain(parent), |
|
28 | : AbstractDomain(parent), | |
28 | m_logLeftX(0), |
|
29 | m_logLeftX(0), | |
29 | m_logRightX(1), |
|
30 | m_logRightX(1), | |
30 | m_logBaseX(10) |
|
31 | m_logBaseX(10) | |
31 | { |
|
32 | { | |
32 | } |
|
33 | } | |
33 |
|
34 | |||
34 | LogXYDomain::~LogXYDomain() |
|
35 | LogXYDomain::~LogXYDomain() | |
35 | { |
|
36 | { | |
36 | } |
|
37 | } | |
37 |
|
38 | |||
38 | void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) |
|
39 | void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) | |
39 | { |
|
40 | { | |
40 | bool axisXChanged = false; |
|
41 | bool axisXChanged = false; | |
41 | bool axisYChanged = false; |
|
42 | bool axisYChanged = false; | |
42 |
|
43 | |||
43 | adjustLogDomainRanges(minX, maxX); |
|
44 | adjustLogDomainRanges(minX, maxX); | |
44 |
|
45 | |||
45 | if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) { |
|
46 | if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) { | |
46 | m_minX = minX; |
|
47 | m_minX = minX; | |
47 | m_maxX = maxX; |
|
48 | m_maxX = maxX; | |
48 | axisXChanged = true; |
|
49 | axisXChanged = true; | |
49 | qreal logMinX = log10(m_minX) / log10(m_logBaseX); |
|
50 | qreal logMinX = std::log10(m_minX) / std::log10(m_logBaseX); | |
50 | qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); |
|
51 | qreal logMaxX = std::log10(m_maxX) / std::log10(m_logBaseX); | |
51 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; |
|
52 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; | |
52 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; |
|
53 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; | |
53 | if(!m_signalsBlocked) |
|
54 | if(!m_signalsBlocked) | |
54 | emit rangeHorizontalChanged(m_minX, m_maxX); |
|
55 | emit rangeHorizontalChanged(m_minX, m_maxX); | |
55 | } |
|
56 | } | |
56 |
|
57 | |||
57 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { |
|
58 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { | |
58 | m_minY = minY; |
|
59 | m_minY = minY; | |
59 | m_maxY = maxY; |
|
60 | m_maxY = maxY; | |
60 | axisYChanged = true; |
|
61 | axisYChanged = true; | |
61 | if (!m_signalsBlocked) |
|
62 | if (!m_signalsBlocked) | |
62 | emit rangeVerticalChanged(m_minY, m_maxY); |
|
63 | emit rangeVerticalChanged(m_minY, m_maxY); | |
63 | } |
|
64 | } | |
64 |
|
65 | |||
65 | if (axisXChanged || axisYChanged) |
|
66 | if (axisXChanged || axisYChanged) | |
66 | emit updated(); |
|
67 | emit updated(); | |
67 | } |
|
68 | } | |
68 |
|
69 | |||
69 | void LogXYDomain::zoomIn(const QRectF &rect) |
|
70 | void LogXYDomain::zoomIn(const QRectF &rect) | |
70 | { |
|
71 | { | |
71 | storeZoomReset(); |
|
72 | storeZoomReset(); | |
72 | qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; |
|
73 | qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; | |
73 | qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; |
|
74 | qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; | |
74 | qreal leftX = qPow(m_logBaseX, logLeftX); |
|
75 | qreal leftX = qPow(m_logBaseX, logLeftX); | |
75 | qreal rightX = qPow(m_logBaseX, logRightX); |
|
76 | qreal rightX = qPow(m_logBaseX, logRightX); | |
76 | qreal minX = leftX < rightX ? leftX : rightX; |
|
77 | qreal minX = leftX < rightX ? leftX : rightX; | |
77 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
78 | qreal maxX = leftX > rightX ? leftX : rightX; | |
78 |
|
79 | |||
79 | qreal dy = spanY() / m_size.height(); |
|
80 | qreal dy = spanY() / m_size.height(); | |
80 | qreal minY = m_minY; |
|
81 | qreal minY = m_minY; | |
81 | qreal maxY = m_maxY; |
|
82 | qreal maxY = m_maxY; | |
82 |
|
83 | |||
83 | minY = maxY - dy * rect.bottom(); |
|
84 | minY = maxY - dy * rect.bottom(); | |
84 | maxY = maxY - dy * rect.top(); |
|
85 | maxY = maxY - dy * rect.top(); | |
85 |
|
86 | |||
86 | setRange(minX, maxX, minY, maxY); |
|
87 | setRange(minX, maxX, minY, maxY); | |
87 | } |
|
88 | } | |
88 |
|
89 | |||
89 | void LogXYDomain::zoomOut(const QRectF &rect) |
|
90 | void LogXYDomain::zoomOut(const QRectF &rect) | |
90 | { |
|
91 | { | |
91 | storeZoomReset(); |
|
92 | storeZoomReset(); | |
92 | const qreal factorX = m_size.width() / rect.width(); |
|
93 | const qreal factorX = m_size.width() / rect.width(); | |
93 |
|
94 | |||
94 | qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX); |
|
95 | qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX); | |
95 | qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX); |
|
96 | qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX); | |
96 | qreal leftX = qPow(m_logBaseX, logLeftX); |
|
97 | qreal leftX = qPow(m_logBaseX, logLeftX); | |
97 | qreal rightX = qPow(m_logBaseX, logRIghtX); |
|
98 | qreal rightX = qPow(m_logBaseX, logRIghtX); | |
98 | qreal minX = leftX < rightX ? leftX : rightX; |
|
99 | qreal minX = leftX < rightX ? leftX : rightX; | |
99 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
100 | qreal maxX = leftX > rightX ? leftX : rightX; | |
100 |
|
101 | |||
101 | qreal dy = spanY() / rect.height(); |
|
102 | qreal dy = spanY() / rect.height(); | |
102 | qreal minY = m_minY; |
|
103 | qreal minY = m_minY; | |
103 | qreal maxY = m_maxY; |
|
104 | qreal maxY = m_maxY; | |
104 |
|
105 | |||
105 | maxY = minY + dy * rect.bottom(); |
|
106 | maxY = minY + dy * rect.bottom(); | |
106 | minY = maxY - dy * m_size.height(); |
|
107 | minY = maxY - dy * m_size.height(); | |
107 |
|
108 | |||
108 | setRange(minX, maxX, minY, maxY); |
|
109 | setRange(minX, maxX, minY, maxY); | |
109 | } |
|
110 | } | |
110 |
|
111 | |||
111 | void LogXYDomain::move(qreal dx, qreal dy) |
|
112 | void LogXYDomain::move(qreal dx, qreal dy) | |
112 | { |
|
113 | { | |
113 | qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width(); |
|
114 | qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width(); | |
114 | qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); |
|
115 | qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); | |
115 | qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); |
|
116 | qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); | |
116 | qreal minX = leftX < rightX ? leftX : rightX; |
|
117 | qreal minX = leftX < rightX ? leftX : rightX; | |
117 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
118 | qreal maxX = leftX > rightX ? leftX : rightX; | |
118 |
|
119 | |||
119 | qreal y = spanY() / m_size.height(); |
|
120 | qreal y = spanY() / m_size.height(); | |
120 | qreal minY = m_minY; |
|
121 | qreal minY = m_minY; | |
121 | qreal maxY = m_maxY; |
|
122 | qreal maxY = m_maxY; | |
122 |
|
123 | |||
123 | if (dy != 0) { |
|
124 | if (dy != 0) { | |
124 | minY = minY + y * dy; |
|
125 | minY = minY + y * dy; | |
125 | maxY = maxY + y * dy; |
|
126 | maxY = maxY + y * dy; | |
126 | } |
|
127 | } | |
127 | setRange(minX, maxX, minY, maxY); |
|
128 | setRange(minX, maxX, minY, maxY); | |
128 | } |
|
129 | } | |
129 |
|
130 | |||
130 | QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const |
|
131 | QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const | |
131 | { |
|
132 | { | |
132 | const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); |
|
133 | const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); | |
133 | const qreal deltaY = m_size.height() / (m_maxY - m_minY); |
|
134 | const qreal deltaY = m_size.height() / (m_maxY - m_minY); | |
134 |
|
135 | |||
135 | qreal x(0); |
|
136 | qreal x(0); | |
136 | qreal y = (point.y() - m_minY) * -deltaY + m_size.height(); |
|
137 | qreal y = (point.y() - m_minY) * -deltaY + m_size.height(); | |
137 | if (point.x() > 0) { |
|
138 | if (point.x() > 0) { | |
138 | x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; |
|
139 | x = (std::log10(point.x()) / std::log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; | |
139 | ok = true; |
|
140 | ok = true; | |
140 | } else { |
|
141 | } else { | |
141 | x = 0; |
|
142 | x = 0; | |
142 | qWarning() << "Logarithms of zero and negative values are undefined."; |
|
143 | qWarning() << "Logarithms of zero and negative values are undefined."; | |
143 | ok = false; |
|
144 | ok = false; | |
144 | } |
|
145 | } | |
145 | return QPointF(x, y); |
|
146 | return QPointF(x, y); | |
146 | } |
|
147 | } | |
147 |
|
148 | |||
148 | QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const |
|
149 | QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const | |
149 | { |
|
150 | { | |
150 | const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); |
|
151 | const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); | |
151 | const qreal deltaY = m_size.height() / (m_maxY - m_minY); |
|
152 | const qreal deltaY = m_size.height() / (m_maxY - m_minY); | |
152 |
|
153 | |||
153 | QVector<QPointF> result; |
|
154 | QVector<QPointF> result; | |
154 | result.resize(vector.count()); |
|
155 | result.resize(vector.count()); | |
155 |
|
156 | |||
156 | for (int i = 0; i < vector.count(); ++i) { |
|
157 | for (int i = 0; i < vector.count(); ++i) { | |
157 | if (vector[i].x() > 0) { |
|
158 | if (vector[i].x() > 0) { | |
158 | qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; |
|
159 | qreal x = (std::log10(vector[i].x()) / std::log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX; | |
159 | qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height(); |
|
160 | qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height(); | |
160 | result[i].setX(x); |
|
161 | result[i].setX(x); | |
161 | result[i].setY(y); |
|
162 | result[i].setY(y); | |
162 | } else { |
|
163 | } else { | |
163 | qWarning() << "Logarithms of zero and negative values are undefined."; |
|
164 | qWarning() << "Logarithms of zero and negative values are undefined."; | |
164 | return QVector<QPointF>(); |
|
165 | return QVector<QPointF>(); | |
165 | } |
|
166 | } | |
166 |
|
167 | |||
167 | } |
|
168 | } | |
168 | return result; |
|
169 | return result; | |
169 | } |
|
170 | } | |
170 |
|
171 | |||
171 | QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const |
|
172 | QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const | |
172 | { |
|
173 | { | |
173 | const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); |
|
174 | const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX); | |
174 | const qreal deltaY = m_size.height() / (m_maxY - m_minY); |
|
175 | const qreal deltaY = m_size.height() / (m_maxY - m_minY); | |
175 | qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX); |
|
176 | qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX); | |
176 | qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY; |
|
177 | qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY; | |
177 | return QPointF(x, y); |
|
178 | return QPointF(x, y); | |
178 | } |
|
179 | } | |
179 |
|
180 | |||
180 | bool LogXYDomain::attachAxis(QAbstractAxis *axis) |
|
181 | bool LogXYDomain::attachAxis(QAbstractAxis *axis) | |
181 | { |
|
182 | { | |
182 | AbstractDomain::attachAxis(axis); |
|
183 | AbstractDomain::attachAxis(axis); | |
183 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
184 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
184 |
|
185 | |||
185 | if (logAxis && logAxis->orientation() == Qt::Horizontal) { |
|
186 | if (logAxis && logAxis->orientation() == Qt::Horizontal) { | |
186 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); |
|
187 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); | |
187 | handleHorizontalAxisBaseChanged(logAxis->base()); |
|
188 | handleHorizontalAxisBaseChanged(logAxis->base()); | |
188 | } |
|
189 | } | |
189 |
|
190 | |||
190 | return true; |
|
191 | return true; | |
191 | } |
|
192 | } | |
192 |
|
193 | |||
193 | bool LogXYDomain::detachAxis(QAbstractAxis *axis) |
|
194 | bool LogXYDomain::detachAxis(QAbstractAxis *axis) | |
194 | { |
|
195 | { | |
195 | AbstractDomain::detachAxis(axis); |
|
196 | AbstractDomain::detachAxis(axis); | |
196 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
197 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
197 |
|
198 | |||
198 | if (logAxis && logAxis->orientation() == Qt::Horizontal) |
|
199 | if (logAxis && logAxis->orientation() == Qt::Horizontal) | |
199 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); |
|
200 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); | |
200 |
|
201 | |||
201 | return true; |
|
202 | return true; | |
202 | } |
|
203 | } | |
203 |
|
204 | |||
204 | void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX) |
|
205 | void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX) | |
205 | { |
|
206 | { | |
206 | m_logBaseX = baseX; |
|
207 | m_logBaseX = baseX; | |
207 | qreal logMinX = log10(m_minX) / log10(m_logBaseX); |
|
208 | qreal logMinX = std::log10(m_minX) / std::log10(m_logBaseX); | |
208 | qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); |
|
209 | qreal logMaxX = std::log10(m_maxX) / std::log10(m_logBaseX); | |
209 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; |
|
210 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; | |
210 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; |
|
211 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; | |
211 | emit updated(); |
|
212 | emit updated(); | |
212 | } |
|
213 | } | |
213 |
|
214 | |||
214 | // operators |
|
215 | // operators | |
215 |
|
216 | |||
216 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2) |
|
217 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2) | |
217 | { |
|
218 | { | |
218 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) |
|
219 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) | |
219 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) |
|
220 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) | |
220 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) |
|
221 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) | |
221 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); |
|
222 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); | |
222 | } |
|
223 | } | |
223 |
|
224 | |||
224 |
|
225 | |||
225 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2) |
|
226 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2) | |
226 | { |
|
227 | { | |
227 | return !(domain1 == domain2); |
|
228 | return !(domain1 == domain2); | |
228 | } |
|
229 | } | |
229 |
|
230 | |||
230 |
|
231 | |||
231 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain) |
|
232 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain) | |
232 | { |
|
233 | { | |
233 | #ifdef QT_NO_TEXTSTREAM |
|
234 | #ifdef QT_NO_TEXTSTREAM | |
234 | Q_UNUSED(domain) |
|
235 | Q_UNUSED(domain) | |
235 | #else |
|
236 | #else | |
236 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; |
|
237 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; | |
237 | #endif |
|
238 | #endif | |
238 | return dbg.maybeSpace(); |
|
239 | return dbg.maybeSpace(); | |
239 | } |
|
240 | } | |
240 |
|
241 | |||
241 | #include "moc_logxydomain_p.cpp" |
|
242 | #include "moc_logxydomain_p.cpp" | |
242 |
|
243 | |||
243 | QT_CHARTS_END_NAMESPACE |
|
244 | QT_CHARTS_END_NAMESPACE |
@@ -1,240 +1,241 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/logxypolardomain_p.h> |
|
19 | #include <private/logxypolardomain_p.h> | |
20 | #include <private/qabstractaxis_p.h> |
|
20 | #include <private/qabstractaxis_p.h> | |
21 | #include <QtCharts/QLogValueAxis> |
|
21 | #include <QtCharts/QLogValueAxis> | |
22 | #include <QtCore/QtMath> |
|
22 | #include <QtCore/QtMath> | |
|
23 | #include <cmath> | |||
23 |
|
24 | |||
24 | QT_CHARTS_BEGIN_NAMESPACE |
|
25 | QT_CHARTS_BEGIN_NAMESPACE | |
25 |
|
26 | |||
26 | LogXYPolarDomain::LogXYPolarDomain(QObject *parent) |
|
27 | LogXYPolarDomain::LogXYPolarDomain(QObject *parent) | |
27 | : PolarDomain(parent), |
|
28 | : PolarDomain(parent), | |
28 | m_logLeftX(0), |
|
29 | m_logLeftX(0), | |
29 | m_logRightX(1), |
|
30 | m_logRightX(1), | |
30 | m_logBaseX(10) |
|
31 | m_logBaseX(10) | |
31 | { |
|
32 | { | |
32 | } |
|
33 | } | |
33 |
|
34 | |||
34 | LogXYPolarDomain::~LogXYPolarDomain() |
|
35 | LogXYPolarDomain::~LogXYPolarDomain() | |
35 | { |
|
36 | { | |
36 | } |
|
37 | } | |
37 |
|
38 | |||
38 | void LogXYPolarDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) |
|
39 | void LogXYPolarDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) | |
39 | { |
|
40 | { | |
40 | bool axisXChanged = false; |
|
41 | bool axisXChanged = false; | |
41 | bool axisYChanged = false; |
|
42 | bool axisYChanged = false; | |
42 |
|
43 | |||
43 | adjustLogDomainRanges(minX, maxX); |
|
44 | adjustLogDomainRanges(minX, maxX); | |
44 |
|
45 | |||
45 | if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) { |
|
46 | if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) { | |
46 | m_minX = minX; |
|
47 | m_minX = minX; | |
47 | m_maxX = maxX; |
|
48 | m_maxX = maxX; | |
48 | axisXChanged = true; |
|
49 | axisXChanged = true; | |
49 | qreal logMinX = log10(m_minX) / log10(m_logBaseX); |
|
50 | qreal logMinX = std::log10(m_minX) / std::log10(m_logBaseX); | |
50 | qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); |
|
51 | qreal logMaxX = std::log10(m_maxX) / std::log10(m_logBaseX); | |
51 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; |
|
52 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; | |
52 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; |
|
53 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; | |
53 | if (!m_signalsBlocked) |
|
54 | if (!m_signalsBlocked) | |
54 | emit rangeHorizontalChanged(m_minX, m_maxX); |
|
55 | emit rangeHorizontalChanged(m_minX, m_maxX); | |
55 | } |
|
56 | } | |
56 |
|
57 | |||
57 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { |
|
58 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { | |
58 | m_minY = minY; |
|
59 | m_minY = minY; | |
59 | m_maxY = maxY; |
|
60 | m_maxY = maxY; | |
60 | axisYChanged = true; |
|
61 | axisYChanged = true; | |
61 | if (!m_signalsBlocked) |
|
62 | if (!m_signalsBlocked) | |
62 | emit rangeVerticalChanged(m_minY, m_maxY); |
|
63 | emit rangeVerticalChanged(m_minY, m_maxY); | |
63 | } |
|
64 | } | |
64 |
|
65 | |||
65 | if (axisXChanged || axisYChanged) |
|
66 | if (axisXChanged || axisYChanged) | |
66 | emit updated(); |
|
67 | emit updated(); | |
67 | } |
|
68 | } | |
68 |
|
69 | |||
69 | void LogXYPolarDomain::zoomIn(const QRectF &rect) |
|
70 | void LogXYPolarDomain::zoomIn(const QRectF &rect) | |
70 | { |
|
71 | { | |
71 | storeZoomReset(); |
|
72 | storeZoomReset(); | |
72 | qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; |
|
73 | qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; | |
73 | qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; |
|
74 | qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX; | |
74 | qreal leftX = qPow(m_logBaseX, logLeftX); |
|
75 | qreal leftX = qPow(m_logBaseX, logLeftX); | |
75 | qreal rightX = qPow(m_logBaseX, logRightX); |
|
76 | qreal rightX = qPow(m_logBaseX, logRightX); | |
76 | qreal minX = leftX < rightX ? leftX : rightX; |
|
77 | qreal minX = leftX < rightX ? leftX : rightX; | |
77 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
78 | qreal maxX = leftX > rightX ? leftX : rightX; | |
78 |
|
79 | |||
79 | qreal dy = spanY() / m_size.height(); |
|
80 | qreal dy = spanY() / m_size.height(); | |
80 | qreal minY = m_minY; |
|
81 | qreal minY = m_minY; | |
81 | qreal maxY = m_maxY; |
|
82 | qreal maxY = m_maxY; | |
82 |
|
83 | |||
83 | minY = maxY - dy * rect.bottom(); |
|
84 | minY = maxY - dy * rect.bottom(); | |
84 | maxY = maxY - dy * rect.top(); |
|
85 | maxY = maxY - dy * rect.top(); | |
85 |
|
86 | |||
86 | setRange(minX, maxX, minY, maxY); |
|
87 | setRange(minX, maxX, minY, maxY); | |
87 | } |
|
88 | } | |
88 |
|
89 | |||
89 | void LogXYPolarDomain::zoomOut(const QRectF &rect) |
|
90 | void LogXYPolarDomain::zoomOut(const QRectF &rect) | |
90 | { |
|
91 | { | |
91 | storeZoomReset(); |
|
92 | storeZoomReset(); | |
92 | const qreal factorX = m_size.width() / rect.width(); |
|
93 | const qreal factorX = m_size.width() / rect.width(); | |
93 |
|
94 | |||
94 | qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 - factorX); |
|
95 | qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 - factorX); | |
95 | qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 + factorX); |
|
96 | qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 + factorX); | |
96 | qreal leftX = qPow(m_logBaseX, logLeftX); |
|
97 | qreal leftX = qPow(m_logBaseX, logLeftX); | |
97 | qreal rightX = qPow(m_logBaseX, logRIghtX); |
|
98 | qreal rightX = qPow(m_logBaseX, logRIghtX); | |
98 | qreal minX = leftX < rightX ? leftX : rightX; |
|
99 | qreal minX = leftX < rightX ? leftX : rightX; | |
99 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
100 | qreal maxX = leftX > rightX ? leftX : rightX; | |
100 |
|
101 | |||
101 | qreal dy = spanY() / rect.height(); |
|
102 | qreal dy = spanY() / rect.height(); | |
102 | qreal minY = m_minY; |
|
103 | qreal minY = m_minY; | |
103 | qreal maxY = m_maxY; |
|
104 | qreal maxY = m_maxY; | |
104 |
|
105 | |||
105 | maxY = minY + dy * rect.bottom(); |
|
106 | maxY = minY + dy * rect.bottom(); | |
106 | minY = maxY - dy * m_size.height(); |
|
107 | minY = maxY - dy * m_size.height(); | |
107 |
|
108 | |||
108 | setRange(minX, maxX, minY, maxY); |
|
109 | setRange(minX, maxX, minY, maxY); | |
109 | } |
|
110 | } | |
110 |
|
111 | |||
111 | void LogXYPolarDomain::move(qreal dx, qreal dy) |
|
112 | void LogXYPolarDomain::move(qreal dx, qreal dy) | |
112 | { |
|
113 | { | |
113 | qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width(); |
|
114 | qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width(); | |
114 | qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); |
|
115 | qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX); | |
115 | qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); |
|
116 | qreal rightX = qPow(m_logBaseX, m_logRightX + stepX); | |
116 | qreal minX = leftX < rightX ? leftX : rightX; |
|
117 | qreal minX = leftX < rightX ? leftX : rightX; | |
117 | qreal maxX = leftX > rightX ? leftX : rightX; |
|
118 | qreal maxX = leftX > rightX ? leftX : rightX; | |
118 |
|
119 | |||
119 | qreal y = spanY() / m_radius; |
|
120 | qreal y = spanY() / m_radius; | |
120 | qreal minY = m_minY; |
|
121 | qreal minY = m_minY; | |
121 | qreal maxY = m_maxY; |
|
122 | qreal maxY = m_maxY; | |
122 |
|
123 | |||
123 | if (dy != 0) { |
|
124 | if (dy != 0) { | |
124 | minY = minY + y * dy; |
|
125 | minY = minY + y * dy; | |
125 | maxY = maxY + y * dy; |
|
126 | maxY = maxY + y * dy; | |
126 | } |
|
127 | } | |
127 | setRange(minX, maxX, minY, maxY); |
|
128 | setRange(minX, maxX, minY, maxY); | |
128 | } |
|
129 | } | |
129 |
|
130 | |||
130 | qreal LogXYPolarDomain::toAngularCoordinate(qreal value, bool &ok) const |
|
131 | qreal LogXYPolarDomain::toAngularCoordinate(qreal value, bool &ok) const | |
131 | { |
|
132 | { | |
132 | qreal retVal; |
|
133 | qreal retVal; | |
133 | if (value <= 0) { |
|
134 | if (value <= 0) { | |
134 | ok = false; |
|
135 | ok = false; | |
135 | retVal = 0.0; |
|
136 | retVal = 0.0; | |
136 | } else { |
|
137 | } else { | |
137 | ok = true; |
|
138 | ok = true; | |
138 | const qreal tickSpan = 360.0 / qAbs(m_logRightX - m_logLeftX); |
|
139 | const qreal tickSpan = 360.0 / qAbs(m_logRightX - m_logLeftX); | |
139 | const qreal logValue = log10(value) / log10(m_logBaseX); |
|
140 | const qreal logValue = std::log10(value) / std::log10(m_logBaseX); | |
140 | const qreal valueDelta = logValue - m_logLeftX; |
|
141 | const qreal valueDelta = logValue - m_logLeftX; | |
141 |
|
142 | |||
142 | retVal = valueDelta * tickSpan; |
|
143 | retVal = valueDelta * tickSpan; | |
143 | } |
|
144 | } | |
144 | return retVal; |
|
145 | return retVal; | |
145 | } |
|
146 | } | |
146 |
|
147 | |||
147 | qreal LogXYPolarDomain::toRadialCoordinate(qreal value, bool &ok) const |
|
148 | qreal LogXYPolarDomain::toRadialCoordinate(qreal value, bool &ok) const | |
148 | { |
|
149 | { | |
149 | ok = true; |
|
150 | ok = true; | |
150 | if (value < m_minY) |
|
151 | if (value < m_minY) | |
151 | value = m_minY; |
|
152 | value = m_minY; | |
152 |
|
153 | |||
153 | // Dont limit the max. The drawing should clip the stuff that goes out of the grid |
|
154 | // Dont limit the max. The drawing should clip the stuff that goes out of the grid | |
154 | qreal f = (value - m_minY) / (m_maxY - m_minY); |
|
155 | qreal f = (value - m_minY) / (m_maxY - m_minY); | |
155 |
|
156 | |||
156 | return f * m_radius; |
|
157 | return f * m_radius; | |
157 | } |
|
158 | } | |
158 |
|
159 | |||
159 | QPointF LogXYPolarDomain::calculateDomainPoint(const QPointF &point) const |
|
160 | QPointF LogXYPolarDomain::calculateDomainPoint(const QPointF &point) const | |
160 | { |
|
161 | { | |
161 | if (point == m_center) |
|
162 | if (point == m_center) | |
162 | return QPointF(0.0, m_minY); |
|
163 | return QPointF(0.0, m_minY); | |
163 |
|
164 | |||
164 | QLineF line(m_center, point); |
|
165 | QLineF line(m_center, point); | |
165 | qreal a = 90.0 - line.angle(); |
|
166 | qreal a = 90.0 - line.angle(); | |
166 | if (a < 0.0) |
|
167 | if (a < 0.0) | |
167 | a += 360.0; |
|
168 | a += 360.0; | |
168 |
|
169 | |||
169 | const qreal deltaX = 360.0 / qAbs(m_logRightX - m_logLeftX); |
|
170 | const qreal deltaX = 360.0 / qAbs(m_logRightX - m_logLeftX); | |
170 | a = qPow(m_logBaseX, m_logLeftX + (a / deltaX)); |
|
171 | a = qPow(m_logBaseX, m_logLeftX + (a / deltaX)); | |
171 |
|
172 | |||
172 | qreal r = m_minY + ((m_maxY - m_minY) * (line.length() / m_radius)); |
|
173 | qreal r = m_minY + ((m_maxY - m_minY) * (line.length() / m_radius)); | |
173 |
|
174 | |||
174 | return QPointF(a, r); |
|
175 | return QPointF(a, r); | |
175 | } |
|
176 | } | |
176 |
|
177 | |||
177 | bool LogXYPolarDomain::attachAxis(QAbstractAxis *axis) |
|
178 | bool LogXYPolarDomain::attachAxis(QAbstractAxis *axis) | |
178 | { |
|
179 | { | |
179 | AbstractDomain::attachAxis(axis); |
|
180 | AbstractDomain::attachAxis(axis); | |
180 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
181 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
181 |
|
182 | |||
182 | if (logAxis && logAxis->orientation() == Qt::Horizontal) { |
|
183 | if (logAxis && logAxis->orientation() == Qt::Horizontal) { | |
183 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); |
|
184 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); | |
184 | handleHorizontalAxisBaseChanged(logAxis->base()); |
|
185 | handleHorizontalAxisBaseChanged(logAxis->base()); | |
185 | } |
|
186 | } | |
186 |
|
187 | |||
187 | return true; |
|
188 | return true; | |
188 | } |
|
189 | } | |
189 |
|
190 | |||
190 | bool LogXYPolarDomain::detachAxis(QAbstractAxis *axis) |
|
191 | bool LogXYPolarDomain::detachAxis(QAbstractAxis *axis) | |
191 | { |
|
192 | { | |
192 | AbstractDomain::detachAxis(axis); |
|
193 | AbstractDomain::detachAxis(axis); | |
193 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
194 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
194 |
|
195 | |||
195 | if (logAxis && logAxis->orientation() == Qt::Horizontal) |
|
196 | if (logAxis && logAxis->orientation() == Qt::Horizontal) | |
196 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); |
|
197 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal))); | |
197 |
|
198 | |||
198 | return true; |
|
199 | return true; | |
199 | } |
|
200 | } | |
200 |
|
201 | |||
201 | void LogXYPolarDomain::handleHorizontalAxisBaseChanged(qreal baseX) |
|
202 | void LogXYPolarDomain::handleHorizontalAxisBaseChanged(qreal baseX) | |
202 | { |
|
203 | { | |
203 | m_logBaseX = baseX; |
|
204 | m_logBaseX = baseX; | |
204 | qreal logMinX = log10(m_minX) / log10(m_logBaseX); |
|
205 | qreal logMinX = std::log10(m_minX) / std::log10(m_logBaseX); | |
205 | qreal logMaxX = log10(m_maxX) / log10(m_logBaseX); |
|
206 | qreal logMaxX = std::log10(m_maxX) / std::log10(m_logBaseX); | |
206 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; |
|
207 | m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX; | |
207 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; |
|
208 | m_logRightX = logMinX > logMaxX ? logMinX : logMaxX; | |
208 | emit updated(); |
|
209 | emit updated(); | |
209 | } |
|
210 | } | |
210 |
|
211 | |||
211 | // operators |
|
212 | // operators | |
212 |
|
213 | |||
213 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const LogXYPolarDomain &domain1, const LogXYPolarDomain &domain2) |
|
214 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const LogXYPolarDomain &domain1, const LogXYPolarDomain &domain2) | |
214 | { |
|
215 | { | |
215 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) |
|
216 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) | |
216 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) |
|
217 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) | |
217 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) |
|
218 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) | |
218 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); |
|
219 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); | |
219 | } |
|
220 | } | |
220 |
|
221 | |||
221 |
|
222 | |||
222 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const LogXYPolarDomain &domain1, const LogXYPolarDomain &domain2) |
|
223 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const LogXYPolarDomain &domain1, const LogXYPolarDomain &domain2) | |
223 | { |
|
224 | { | |
224 | return !(domain1 == domain2); |
|
225 | return !(domain1 == domain2); | |
225 | } |
|
226 | } | |
226 |
|
227 | |||
227 |
|
228 | |||
228 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYPolarDomain &domain) |
|
229 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYPolarDomain &domain) | |
229 | { |
|
230 | { | |
230 | #ifdef QT_NO_TEXTSTREAM |
|
231 | #ifdef QT_NO_TEXTSTREAM | |
231 | Q_UNUSED(domain) |
|
232 | Q_UNUSED(domain) | |
232 | #else |
|
233 | #else | |
233 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; |
|
234 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; | |
234 | #endif |
|
235 | #endif | |
235 | return dbg.maybeSpace(); |
|
236 | return dbg.maybeSpace(); | |
236 | } |
|
237 | } | |
237 |
|
238 | |||
238 | #include "moc_logxypolardomain_p.cpp" |
|
239 | #include "moc_logxypolardomain_p.cpp" | |
239 |
|
240 | |||
240 | QT_CHARTS_END_NAMESPACE |
|
241 | QT_CHARTS_END_NAMESPACE |
@@ -1,239 +1,240 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/xlogydomain_p.h> |
|
19 | #include <private/xlogydomain_p.h> | |
20 | #include <private/qabstractaxis_p.h> |
|
20 | #include <private/qabstractaxis_p.h> | |
21 | #include <QtCharts/QLogValueAxis> |
|
21 | #include <QtCharts/QLogValueAxis> | |
22 | #include <QtCore/QtMath> |
|
22 | #include <QtCore/QtMath> | |
|
23 | #include <cmath> | |||
23 |
|
24 | |||
24 | QT_CHARTS_BEGIN_NAMESPACE |
|
25 | QT_CHARTS_BEGIN_NAMESPACE | |
25 |
|
26 | |||
26 | XLogYDomain::XLogYDomain(QObject *parent) |
|
27 | XLogYDomain::XLogYDomain(QObject *parent) | |
27 | : AbstractDomain(parent), |
|
28 | : AbstractDomain(parent), | |
28 | m_logLeftY(0), |
|
29 | m_logLeftY(0), | |
29 | m_logRightY(1), |
|
30 | m_logRightY(1), | |
30 | m_logBaseY(10) |
|
31 | m_logBaseY(10) | |
31 | { |
|
32 | { | |
32 | } |
|
33 | } | |
33 |
|
34 | |||
34 | XLogYDomain::~XLogYDomain() |
|
35 | XLogYDomain::~XLogYDomain() | |
35 | { |
|
36 | { | |
36 | } |
|
37 | } | |
37 |
|
38 | |||
38 | void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) |
|
39 | void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) | |
39 | { |
|
40 | { | |
40 | bool axisXChanged = false; |
|
41 | bool axisXChanged = false; | |
41 | bool axisYChanged = false; |
|
42 | bool axisYChanged = false; | |
42 |
|
43 | |||
43 | adjustLogDomainRanges(minY, maxY); |
|
44 | adjustLogDomainRanges(minY, maxY); | |
44 |
|
45 | |||
45 | if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) { |
|
46 | if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) { | |
46 | m_minX = minX; |
|
47 | m_minX = minX; | |
47 | m_maxX = maxX; |
|
48 | m_maxX = maxX; | |
48 | axisXChanged = true; |
|
49 | axisXChanged = true; | |
49 | if(!m_signalsBlocked) |
|
50 | if(!m_signalsBlocked) | |
50 | emit rangeHorizontalChanged(m_minX, m_maxX); |
|
51 | emit rangeHorizontalChanged(m_minX, m_maxX); | |
51 | } |
|
52 | } | |
52 |
|
53 | |||
53 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { |
|
54 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { | |
54 | m_minY = minY; |
|
55 | m_minY = minY; | |
55 | m_maxY = maxY; |
|
56 | m_maxY = maxY; | |
56 | axisYChanged = true; |
|
57 | axisYChanged = true; | |
57 | qreal logMinY = log10(m_minY) / log10(m_logBaseY); |
|
58 | qreal logMinY = std::log10(m_minY) / std::log10(m_logBaseY); | |
58 | qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); |
|
59 | qreal logMaxY = std::log10(m_maxY) / std::log10(m_logBaseY); | |
59 | m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; |
|
60 | m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; | |
60 | m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; |
|
61 | m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; | |
61 | if (!m_signalsBlocked) |
|
62 | if (!m_signalsBlocked) | |
62 | emit rangeVerticalChanged(m_minY, m_maxY); |
|
63 | emit rangeVerticalChanged(m_minY, m_maxY); | |
63 | } |
|
64 | } | |
64 |
|
65 | |||
65 | if (axisXChanged || axisYChanged) |
|
66 | if (axisXChanged || axisYChanged) | |
66 | emit updated(); |
|
67 | emit updated(); | |
67 | } |
|
68 | } | |
68 |
|
69 | |||
69 | void XLogYDomain::zoomIn(const QRectF &rect) |
|
70 | void XLogYDomain::zoomIn(const QRectF &rect) | |
70 | { |
|
71 | { | |
71 | storeZoomReset(); |
|
72 | storeZoomReset(); | |
72 | qreal dx = spanX() / m_size.width(); |
|
73 | qreal dx = spanX() / m_size.width(); | |
73 | qreal maxX = m_maxX; |
|
74 | qreal maxX = m_maxX; | |
74 | qreal minX = m_minX; |
|
75 | qreal minX = m_minX; | |
75 |
|
76 | |||
76 | maxX = minX + dx * rect.right(); |
|
77 | maxX = minX + dx * rect.right(); | |
77 | minX = minX + dx * rect.left(); |
|
78 | minX = minX + dx * rect.left(); | |
78 |
|
79 | |||
79 | qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height(); |
|
80 | qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height(); | |
80 | qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height(); |
|
81 | qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height(); | |
81 | qreal leftY = qPow(m_logBaseY, logLeftY); |
|
82 | qreal leftY = qPow(m_logBaseY, logLeftY); | |
82 | qreal rightY = qPow(m_logBaseY, logRightY); |
|
83 | qreal rightY = qPow(m_logBaseY, logRightY); | |
83 | qreal minY = leftY < rightY ? leftY : rightY; |
|
84 | qreal minY = leftY < rightY ? leftY : rightY; | |
84 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
85 | qreal maxY = leftY > rightY ? leftY : rightY; | |
85 |
|
86 | |||
86 | setRange(minX, maxX, minY, maxY); |
|
87 | setRange(minX, maxX, minY, maxY); | |
87 | } |
|
88 | } | |
88 |
|
89 | |||
89 | void XLogYDomain::zoomOut(const QRectF &rect) |
|
90 | void XLogYDomain::zoomOut(const QRectF &rect) | |
90 | { |
|
91 | { | |
91 | storeZoomReset(); |
|
92 | storeZoomReset(); | |
92 | qreal dx = spanX() / rect.width(); |
|
93 | qreal dx = spanX() / rect.width(); | |
93 | qreal maxX = m_maxX; |
|
94 | qreal maxX = m_maxX; | |
94 | qreal minX = m_minX; |
|
95 | qreal minX = m_minX; | |
95 |
|
96 | |||
96 | minX = maxX - dx * rect.right(); |
|
97 | minX = maxX - dx * rect.right(); | |
97 | maxX = minX + dx * m_size.width(); |
|
98 | maxX = minX + dx * m_size.width(); | |
98 |
|
99 | |||
99 | const qreal factorY = m_size.height() / rect.height(); |
|
100 | const qreal factorY = m_size.height() / rect.height(); | |
100 | qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY); |
|
101 | qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY); | |
101 | qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY); |
|
102 | qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY); | |
102 | qreal leftY = qPow(m_logBaseY, newLogMinY); |
|
103 | qreal leftY = qPow(m_logBaseY, newLogMinY); | |
103 | qreal rightY = qPow(m_logBaseY, newLogMaxY); |
|
104 | qreal rightY = qPow(m_logBaseY, newLogMaxY); | |
104 | qreal minY = leftY < rightY ? leftY : rightY; |
|
105 | qreal minY = leftY < rightY ? leftY : rightY; | |
105 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
106 | qreal maxY = leftY > rightY ? leftY : rightY; | |
106 |
|
107 | |||
107 | setRange(minX, maxX, minY, maxY); |
|
108 | setRange(minX, maxX, minY, maxY); | |
108 | } |
|
109 | } | |
109 |
|
110 | |||
110 | void XLogYDomain::move(qreal dx, qreal dy) |
|
111 | void XLogYDomain::move(qreal dx, qreal dy) | |
111 | { |
|
112 | { | |
112 | qreal x = spanX() / m_size.width(); |
|
113 | qreal x = spanX() / m_size.width(); | |
113 | qreal maxX = m_maxX; |
|
114 | qreal maxX = m_maxX; | |
114 | qreal minX = m_minX; |
|
115 | qreal minX = m_minX; | |
115 |
|
116 | |||
116 | if (dx != 0) { |
|
117 | if (dx != 0) { | |
117 | minX = minX + x * dx; |
|
118 | minX = minX + x * dx; | |
118 | maxX = maxX + x * dx; |
|
119 | maxX = maxX + x * dx; | |
119 | } |
|
120 | } | |
120 |
|
121 | |||
121 | qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height(); |
|
122 | qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height(); | |
122 | qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY); |
|
123 | qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY); | |
123 | qreal rightY = qPow(m_logBaseY, m_logRightY + stepY); |
|
124 | qreal rightY = qPow(m_logBaseY, m_logRightY + stepY); | |
124 | qreal minY = leftY < rightY ? leftY : rightY; |
|
125 | qreal minY = leftY < rightY ? leftY : rightY; | |
125 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
126 | qreal maxY = leftY > rightY ? leftY : rightY; | |
126 |
|
127 | |||
127 | setRange(minX, maxX, minY, maxY); |
|
128 | setRange(minX, maxX, minY, maxY); | |
128 | } |
|
129 | } | |
129 |
|
130 | |||
130 | QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const |
|
131 | QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const | |
131 | { |
|
132 | { | |
132 | const qreal deltaX = m_size.width() / (m_maxX - m_minX); |
|
133 | const qreal deltaX = m_size.width() / (m_maxX - m_minX); | |
133 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); |
|
134 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); | |
134 |
|
135 | |||
135 | qreal x = (point.x() - m_minX) * deltaX; |
|
136 | qreal x = (point.x() - m_minX) * deltaX; | |
136 | qreal y(0); |
|
137 | qreal y(0); | |
137 | if (point.y() > 0) { |
|
138 | if (point.y() > 0) { | |
138 | y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); |
|
139 | y = (std::log10(point.y()) / std::log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); | |
139 | ok = true; |
|
140 | ok = true; | |
140 | } else { |
|
141 | } else { | |
141 | y = m_size.height(); |
|
142 | y = m_size.height(); | |
142 | qWarning() << "Logarithms of zero and negative values are undefined."; |
|
143 | qWarning() << "Logarithms of zero and negative values are undefined."; | |
143 | ok = false; |
|
144 | ok = false; | |
144 | } |
|
145 | } | |
145 | return QPointF(x, y); |
|
146 | return QPointF(x, y); | |
146 | } |
|
147 | } | |
147 |
|
148 | |||
148 | QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const |
|
149 | QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const | |
149 | { |
|
150 | { | |
150 | const qreal deltaX = m_size.width() / (m_maxX - m_minX); |
|
151 | const qreal deltaX = m_size.width() / (m_maxX - m_minX); | |
151 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); |
|
152 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); | |
152 |
|
153 | |||
153 | QVector<QPointF> result; |
|
154 | QVector<QPointF> result; | |
154 | result.resize(vector.count()); |
|
155 | result.resize(vector.count()); | |
155 |
|
156 | |||
156 | for (int i = 0; i < vector.count(); ++i) { |
|
157 | for (int i = 0; i < vector.count(); ++i) { | |
157 | if (vector[i].y() > 0) { |
|
158 | if (vector[i].y() > 0) { | |
158 | qreal x = (vector[i].x() - m_minX) * deltaX; |
|
159 | qreal x = (vector[i].x() - m_minX) * deltaX; | |
159 | qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); |
|
160 | qreal y = (std::log10(vector[i].y()) / std::log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height(); | |
160 | result[i].setX(x); |
|
161 | result[i].setX(x); | |
161 | result[i].setY(y); |
|
162 | result[i].setY(y); | |
162 | } else { |
|
163 | } else { | |
163 | qWarning() << "Logarithms of zero and negative values are undefined."; |
|
164 | qWarning() << "Logarithms of zero and negative values are undefined."; | |
164 | return QVector<QPointF>(); |
|
165 | return QVector<QPointF>(); | |
165 | } |
|
166 | } | |
166 | } |
|
167 | } | |
167 | return result; |
|
168 | return result; | |
168 | } |
|
169 | } | |
169 |
|
170 | |||
170 | QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const |
|
171 | QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const | |
171 | { |
|
172 | { | |
172 | const qreal deltaX = m_size.width() / (m_maxX - m_minX); |
|
173 | const qreal deltaX = m_size.width() / (m_maxX - m_minX); | |
173 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); |
|
174 | const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY); | |
174 | qreal x = point.x() / deltaX + m_minX; |
|
175 | qreal x = point.x() / deltaX + m_minX; | |
175 | qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY); |
|
176 | qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY); | |
176 | return QPointF(x, y); |
|
177 | return QPointF(x, y); | |
177 | } |
|
178 | } | |
178 |
|
179 | |||
179 | bool XLogYDomain::attachAxis(QAbstractAxis *axis) |
|
180 | bool XLogYDomain::attachAxis(QAbstractAxis *axis) | |
180 | { |
|
181 | { | |
181 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
182 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
182 |
|
183 | |||
183 | if (logAxis && logAxis->orientation() == Qt::Vertical) { |
|
184 | if (logAxis && logAxis->orientation() == Qt::Vertical) { | |
184 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); |
|
185 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); | |
185 | handleVerticalAxisBaseChanged(logAxis->base()); |
|
186 | handleVerticalAxisBaseChanged(logAxis->base()); | |
186 | } |
|
187 | } | |
187 | return AbstractDomain::attachAxis(axis); |
|
188 | return AbstractDomain::attachAxis(axis); | |
188 | } |
|
189 | } | |
189 |
|
190 | |||
190 | bool XLogYDomain::detachAxis(QAbstractAxis *axis) |
|
191 | bool XLogYDomain::detachAxis(QAbstractAxis *axis) | |
191 | { |
|
192 | { | |
192 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
193 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
193 |
|
194 | |||
194 | if (logAxis && logAxis->orientation() == Qt::Vertical) |
|
195 | if (logAxis && logAxis->orientation() == Qt::Vertical) | |
195 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); |
|
196 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); | |
196 |
|
197 | |||
197 | return AbstractDomain::detachAxis(axis); |
|
198 | return AbstractDomain::detachAxis(axis); | |
198 | } |
|
199 | } | |
199 |
|
200 | |||
200 | void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY) |
|
201 | void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY) | |
201 | { |
|
202 | { | |
202 | m_logBaseY = baseY; |
|
203 | m_logBaseY = baseY; | |
203 | qreal logMinY = log10(m_minY) / log10(m_logBaseY); |
|
204 | qreal logMinY = std::log10(m_minY) / std::log10(m_logBaseY); | |
204 | qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); |
|
205 | qreal logMaxY = std::log10(m_maxY) / std::log10(m_logBaseY); | |
205 | m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; |
|
206 | m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY; | |
206 | m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; |
|
207 | m_logRightY = logMinY > logMaxY ? logMinY : logMaxY; | |
207 | emit updated(); |
|
208 | emit updated(); | |
208 | } |
|
209 | } | |
209 |
|
210 | |||
210 | // operators |
|
211 | // operators | |
211 |
|
212 | |||
212 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2) |
|
213 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2) | |
213 | { |
|
214 | { | |
214 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) |
|
215 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) | |
215 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) |
|
216 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) | |
216 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) |
|
217 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) | |
217 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); |
|
218 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); | |
218 | } |
|
219 | } | |
219 |
|
220 | |||
220 |
|
221 | |||
221 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2) |
|
222 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2) | |
222 | { |
|
223 | { | |
223 | return !(domain1 == domain2); |
|
224 | return !(domain1 == domain2); | |
224 | } |
|
225 | } | |
225 |
|
226 | |||
226 |
|
227 | |||
227 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain) |
|
228 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain) | |
228 | { |
|
229 | { | |
229 | #ifdef QT_NO_TEXTSTREAM |
|
230 | #ifdef QT_NO_TEXTSTREAM | |
230 | Q_UNUSED(domain) |
|
231 | Q_UNUSED(domain) | |
231 | #else |
|
232 | #else | |
232 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; |
|
233 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; | |
233 | #endif |
|
234 | #endif | |
234 | return dbg.maybeSpace(); |
|
235 | return dbg.maybeSpace(); | |
235 | } |
|
236 | } | |
236 |
|
237 | |||
237 | #include "moc_xlogydomain_p.cpp" |
|
238 | #include "moc_xlogydomain_p.cpp" | |
238 |
|
239 | |||
239 | QT_CHARTS_END_NAMESPACE |
|
240 | QT_CHARTS_END_NAMESPACE |
@@ -1,235 +1,236 | |||||
1 | /**************************************************************************** |
|
1 | /**************************************************************************** | |
2 | ** |
|
2 | ** | |
3 | ** Copyright (C) 2014 Digia Plc |
|
3 | ** Copyright (C) 2014 Digia Plc | |
4 | ** All rights reserved. |
|
4 | ** All rights reserved. | |
5 | ** For any questions to Digia, please use contact form at http://qt.io |
|
5 | ** For any questions to Digia, please use contact form at http://qt.io | |
6 | ** |
|
6 | ** | |
7 | ** This file is part of the Qt Charts module. |
|
7 | ** This file is part of the Qt Charts module. | |
8 | ** |
|
8 | ** | |
9 | ** Licensees holding valid commercial license for Qt may use this file in |
|
9 | ** Licensees holding valid commercial license for Qt may use this file in | |
10 | ** accordance with the Qt License Agreement provided with the Software |
|
10 | ** accordance with the Qt License Agreement provided with the Software | |
11 | ** or, alternatively, in accordance with the terms contained in a written |
|
11 | ** or, alternatively, in accordance with the terms contained in a written | |
12 | ** agreement between you and Digia. |
|
12 | ** agreement between you and Digia. | |
13 | ** |
|
13 | ** | |
14 | ** If you have questions regarding the use of this file, please use |
|
14 | ** If you have questions regarding the use of this file, please use | |
15 | ** contact form at http://qt.io |
|
15 | ** contact form at http://qt.io | |
16 | ** |
|
16 | ** | |
17 | ****************************************************************************/ |
|
17 | ****************************************************************************/ | |
18 |
|
18 | |||
19 | #include <private/xlogypolardomain_p.h> |
|
19 | #include <private/xlogypolardomain_p.h> | |
20 | #include <private/qabstractaxis_p.h> |
|
20 | #include <private/qabstractaxis_p.h> | |
21 | #include <QtCharts/QLogValueAxis> |
|
21 | #include <QtCharts/QLogValueAxis> | |
22 | #include <QtCore/QtMath> |
|
22 | #include <QtCore/QtMath> | |
|
23 | #include <cmath> | |||
23 |
|
24 | |||
24 | QT_CHARTS_BEGIN_NAMESPACE |
|
25 | QT_CHARTS_BEGIN_NAMESPACE | |
25 |
|
26 | |||
26 | XLogYPolarDomain::XLogYPolarDomain(QObject *parent) |
|
27 | XLogYPolarDomain::XLogYPolarDomain(QObject *parent) | |
27 | : PolarDomain(parent), |
|
28 | : PolarDomain(parent), | |
28 | m_logInnerY(0), |
|
29 | m_logInnerY(0), | |
29 | m_logOuterY(1), |
|
30 | m_logOuterY(1), | |
30 | m_logBaseY(10) |
|
31 | m_logBaseY(10) | |
31 | { |
|
32 | { | |
32 | } |
|
33 | } | |
33 |
|
34 | |||
34 | XLogYPolarDomain::~XLogYPolarDomain() |
|
35 | XLogYPolarDomain::~XLogYPolarDomain() | |
35 | { |
|
36 | { | |
36 | } |
|
37 | } | |
37 |
|
38 | |||
38 | void XLogYPolarDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) |
|
39 | void XLogYPolarDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) | |
39 | { |
|
40 | { | |
40 | bool axisXChanged = false; |
|
41 | bool axisXChanged = false; | |
41 | bool axisYChanged = false; |
|
42 | bool axisYChanged = false; | |
42 |
|
43 | |||
43 | adjustLogDomainRanges(minY, maxY); |
|
44 | adjustLogDomainRanges(minY, maxY); | |
44 |
|
45 | |||
45 | if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) { |
|
46 | if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) { | |
46 | m_minX = minX; |
|
47 | m_minX = minX; | |
47 | m_maxX = maxX; |
|
48 | m_maxX = maxX; | |
48 | axisXChanged = true; |
|
49 | axisXChanged = true; | |
49 | if (!m_signalsBlocked) |
|
50 | if (!m_signalsBlocked) | |
50 | emit rangeHorizontalChanged(m_minX, m_maxX); |
|
51 | emit rangeHorizontalChanged(m_minX, m_maxX); | |
51 | } |
|
52 | } | |
52 |
|
53 | |||
53 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { |
|
54 | if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) { | |
54 | m_minY = minY; |
|
55 | m_minY = minY; | |
55 | m_maxY = maxY; |
|
56 | m_maxY = maxY; | |
56 | axisYChanged = true; |
|
57 | axisYChanged = true; | |
57 | qreal logMinY = log10(m_minY) / log10(m_logBaseY); |
|
58 | qreal logMinY = std::log10(m_minY) / std::log10(m_logBaseY); | |
58 | qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); |
|
59 | qreal logMaxY = std::log10(m_maxY) / std::log10(m_logBaseY); | |
59 | m_logInnerY = logMinY < logMaxY ? logMinY : logMaxY; |
|
60 | m_logInnerY = logMinY < logMaxY ? logMinY : logMaxY; | |
60 | m_logOuterY = logMinY > logMaxY ? logMinY : logMaxY; |
|
61 | m_logOuterY = logMinY > logMaxY ? logMinY : logMaxY; | |
61 | if (!m_signalsBlocked) |
|
62 | if (!m_signalsBlocked) | |
62 | emit rangeVerticalChanged(m_minY, m_maxY); |
|
63 | emit rangeVerticalChanged(m_minY, m_maxY); | |
63 | } |
|
64 | } | |
64 |
|
65 | |||
65 | if (axisXChanged || axisYChanged) |
|
66 | if (axisXChanged || axisYChanged) | |
66 | emit updated(); |
|
67 | emit updated(); | |
67 | } |
|
68 | } | |
68 |
|
69 | |||
69 | void XLogYPolarDomain::zoomIn(const QRectF &rect) |
|
70 | void XLogYPolarDomain::zoomIn(const QRectF &rect) | |
70 | { |
|
71 | { | |
71 | storeZoomReset(); |
|
72 | storeZoomReset(); | |
72 | qreal dx = spanX() / m_size.width(); |
|
73 | qreal dx = spanX() / m_size.width(); | |
73 | qreal maxX = m_maxX; |
|
74 | qreal maxX = m_maxX; | |
74 | qreal minX = m_minX; |
|
75 | qreal minX = m_minX; | |
75 |
|
76 | |||
76 | maxX = minX + dx * rect.right(); |
|
77 | maxX = minX + dx * rect.right(); | |
77 | minX = minX + dx * rect.left(); |
|
78 | minX = minX + dx * rect.left(); | |
78 |
|
79 | |||
79 | qreal logLeftY = m_logOuterY - rect.bottom() * (m_logOuterY - m_logInnerY) / m_size.height(); |
|
80 | qreal logLeftY = m_logOuterY - rect.bottom() * (m_logOuterY - m_logInnerY) / m_size.height(); | |
80 | qreal logRightY = m_logOuterY - rect.top() * (m_logOuterY - m_logInnerY) / m_size.height(); |
|
81 | qreal logRightY = m_logOuterY - rect.top() * (m_logOuterY - m_logInnerY) / m_size.height(); | |
81 | qreal leftY = qPow(m_logBaseY, logLeftY); |
|
82 | qreal leftY = qPow(m_logBaseY, logLeftY); | |
82 | qreal rightY = qPow(m_logBaseY, logRightY); |
|
83 | qreal rightY = qPow(m_logBaseY, logRightY); | |
83 | qreal minY = leftY < rightY ? leftY : rightY; |
|
84 | qreal minY = leftY < rightY ? leftY : rightY; | |
84 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
85 | qreal maxY = leftY > rightY ? leftY : rightY; | |
85 |
|
86 | |||
86 | setRange(minX, maxX, minY, maxY); |
|
87 | setRange(minX, maxX, minY, maxY); | |
87 | } |
|
88 | } | |
88 |
|
89 | |||
89 | void XLogYPolarDomain::zoomOut(const QRectF &rect) |
|
90 | void XLogYPolarDomain::zoomOut(const QRectF &rect) | |
90 | { |
|
91 | { | |
91 | storeZoomReset(); |
|
92 | storeZoomReset(); | |
92 | qreal dx = spanX() / rect.width(); |
|
93 | qreal dx = spanX() / rect.width(); | |
93 | qreal maxX = m_maxX; |
|
94 | qreal maxX = m_maxX; | |
94 | qreal minX = m_minX; |
|
95 | qreal minX = m_minX; | |
95 |
|
96 | |||
96 | minX = maxX - dx * rect.right(); |
|
97 | minX = maxX - dx * rect.right(); | |
97 | maxX = minX + dx * m_size.width(); |
|
98 | maxX = minX + dx * m_size.width(); | |
98 |
|
99 | |||
99 | const qreal factorY = m_size.height() / rect.height(); |
|
100 | const qreal factorY = m_size.height() / rect.height(); | |
100 | qreal newLogMinY = m_logInnerY + (m_logOuterY - m_logInnerY) / 2.0 * (1.0 - factorY); |
|
101 | qreal newLogMinY = m_logInnerY + (m_logOuterY - m_logInnerY) / 2.0 * (1.0 - factorY); | |
101 | qreal newLogMaxY = m_logInnerY + (m_logOuterY - m_logInnerY) / 2.0 * (1.0 + factorY); |
|
102 | qreal newLogMaxY = m_logInnerY + (m_logOuterY - m_logInnerY) / 2.0 * (1.0 + factorY); | |
102 | qreal leftY = qPow(m_logBaseY, newLogMinY); |
|
103 | qreal leftY = qPow(m_logBaseY, newLogMinY); | |
103 | qreal rightY = qPow(m_logBaseY, newLogMaxY); |
|
104 | qreal rightY = qPow(m_logBaseY, newLogMaxY); | |
104 | qreal minY = leftY < rightY ? leftY : rightY; |
|
105 | qreal minY = leftY < rightY ? leftY : rightY; | |
105 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
106 | qreal maxY = leftY > rightY ? leftY : rightY; | |
106 |
|
107 | |||
107 | setRange(minX, maxX, minY, maxY); |
|
108 | setRange(minX, maxX, minY, maxY); | |
108 | } |
|
109 | } | |
109 |
|
110 | |||
110 | void XLogYPolarDomain::move(qreal dx, qreal dy) |
|
111 | void XLogYPolarDomain::move(qreal dx, qreal dy) | |
111 | { |
|
112 | { | |
112 | qreal x = spanX() / 360.0; |
|
113 | qreal x = spanX() / 360.0; | |
113 |
|
114 | |||
114 | qreal maxX = m_maxX; |
|
115 | qreal maxX = m_maxX; | |
115 | qreal minX = m_minX; |
|
116 | qreal minX = m_minX; | |
116 |
|
117 | |||
117 | if (dx != 0) { |
|
118 | if (dx != 0) { | |
118 | minX = minX + x * dx; |
|
119 | minX = minX + x * dx; | |
119 | maxX = maxX + x * dx; |
|
120 | maxX = maxX + x * dx; | |
120 | } |
|
121 | } | |
121 |
|
122 | |||
122 | qreal stepY = dy * (m_logOuterY - m_logInnerY) / m_radius; |
|
123 | qreal stepY = dy * (m_logOuterY - m_logInnerY) / m_radius; | |
123 | qreal leftY = qPow(m_logBaseY, m_logInnerY + stepY); |
|
124 | qreal leftY = qPow(m_logBaseY, m_logInnerY + stepY); | |
124 | qreal rightY = qPow(m_logBaseY, m_logOuterY + stepY); |
|
125 | qreal rightY = qPow(m_logBaseY, m_logOuterY + stepY); | |
125 | qreal minY = leftY < rightY ? leftY : rightY; |
|
126 | qreal minY = leftY < rightY ? leftY : rightY; | |
126 | qreal maxY = leftY > rightY ? leftY : rightY; |
|
127 | qreal maxY = leftY > rightY ? leftY : rightY; | |
127 |
|
128 | |||
128 | setRange(minX, maxX, minY, maxY); |
|
129 | setRange(minX, maxX, minY, maxY); | |
129 | } |
|
130 | } | |
130 |
|
131 | |||
131 | qreal XLogYPolarDomain::toAngularCoordinate(qreal value, bool &ok) const |
|
132 | qreal XLogYPolarDomain::toAngularCoordinate(qreal value, bool &ok) const | |
132 | { |
|
133 | { | |
133 | ok = true; |
|
134 | ok = true; | |
134 | qreal f = (value - m_minX) / (m_maxX - m_minX); |
|
135 | qreal f = (value - m_minX) / (m_maxX - m_minX); | |
135 | return f * 360.0; |
|
136 | return f * 360.0; | |
136 | } |
|
137 | } | |
137 |
|
138 | |||
138 | qreal XLogYPolarDomain::toRadialCoordinate(qreal value, bool &ok) const |
|
139 | qreal XLogYPolarDomain::toRadialCoordinate(qreal value, bool &ok) const | |
139 | { |
|
140 | { | |
140 | qreal retVal; |
|
141 | qreal retVal; | |
141 | if (value <= 0) { |
|
142 | if (value <= 0) { | |
142 | ok = false; |
|
143 | ok = false; | |
143 | retVal = 0.0; |
|
144 | retVal = 0.0; | |
144 | } else { |
|
145 | } else { | |
145 | ok = true; |
|
146 | ok = true; | |
146 | const qreal tickSpan = m_radius / qAbs(m_logOuterY - m_logInnerY); |
|
147 | const qreal tickSpan = m_radius / qAbs(m_logOuterY - m_logInnerY); | |
147 | const qreal logValue = log10(value) / log10(m_logBaseY); |
|
148 | const qreal logValue = std::log10(value) / std::log10(m_logBaseY); | |
148 | const qreal valueDelta = logValue - m_logInnerY; |
|
149 | const qreal valueDelta = logValue - m_logInnerY; | |
149 |
|
150 | |||
150 | retVal = valueDelta * tickSpan; |
|
151 | retVal = valueDelta * tickSpan; | |
151 |
|
152 | |||
152 | if (retVal < 0.0) |
|
153 | if (retVal < 0.0) | |
153 | retVal = 0.0; |
|
154 | retVal = 0.0; | |
154 | } |
|
155 | } | |
155 | return retVal; |
|
156 | return retVal; | |
156 | } |
|
157 | } | |
157 |
|
158 | |||
158 | QPointF XLogYPolarDomain::calculateDomainPoint(const QPointF &point) const |
|
159 | QPointF XLogYPolarDomain::calculateDomainPoint(const QPointF &point) const | |
159 | { |
|
160 | { | |
160 | if (point == m_center) |
|
161 | if (point == m_center) | |
161 | return QPointF(0.0, m_minY); |
|
162 | return QPointF(0.0, m_minY); | |
162 |
|
163 | |||
163 | QLineF line(m_center, point); |
|
164 | QLineF line(m_center, point); | |
164 | qreal a = 90.0 - line.angle(); |
|
165 | qreal a = 90.0 - line.angle(); | |
165 | if (a < 0.0) |
|
166 | if (a < 0.0) | |
166 | a += 360.0; |
|
167 | a += 360.0; | |
167 | a = ((a / 360.0) * (m_maxX - m_minX)) + m_minX; |
|
168 | a = ((a / 360.0) * (m_maxX - m_minX)) + m_minX; | |
168 |
|
169 | |||
169 | const qreal deltaY = m_radius / qAbs(m_logOuterY - m_logInnerY); |
|
170 | const qreal deltaY = m_radius / qAbs(m_logOuterY - m_logInnerY); | |
170 | qreal r = qPow(m_logBaseY, m_logInnerY + (line.length() / deltaY)); |
|
171 | qreal r = qPow(m_logBaseY, m_logInnerY + (line.length() / deltaY)); | |
171 |
|
172 | |||
172 | return QPointF(a, r); |
|
173 | return QPointF(a, r); | |
173 | } |
|
174 | } | |
174 |
|
175 | |||
175 | bool XLogYPolarDomain::attachAxis(QAbstractAxis *axis) |
|
176 | bool XLogYPolarDomain::attachAxis(QAbstractAxis *axis) | |
176 | { |
|
177 | { | |
177 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
178 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
178 |
|
179 | |||
179 | if (logAxis && logAxis->orientation() == Qt::Vertical) { |
|
180 | if (logAxis && logAxis->orientation() == Qt::Vertical) { | |
180 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); |
|
181 | QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); | |
181 | handleVerticalAxisBaseChanged(logAxis->base()); |
|
182 | handleVerticalAxisBaseChanged(logAxis->base()); | |
182 | } |
|
183 | } | |
183 | return AbstractDomain::attachAxis(axis); |
|
184 | return AbstractDomain::attachAxis(axis); | |
184 | } |
|
185 | } | |
185 |
|
186 | |||
186 | bool XLogYPolarDomain::detachAxis(QAbstractAxis *axis) |
|
187 | bool XLogYPolarDomain::detachAxis(QAbstractAxis *axis) | |
187 | { |
|
188 | { | |
188 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); |
|
189 | QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis); | |
189 |
|
190 | |||
190 | if (logAxis && logAxis->orientation() == Qt::Vertical) |
|
191 | if (logAxis && logAxis->orientation() == Qt::Vertical) | |
191 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); |
|
192 | QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal))); | |
192 |
|
193 | |||
193 | return AbstractDomain::detachAxis(axis); |
|
194 | return AbstractDomain::detachAxis(axis); | |
194 | } |
|
195 | } | |
195 |
|
196 | |||
196 | void XLogYPolarDomain::handleVerticalAxisBaseChanged(qreal baseY) |
|
197 | void XLogYPolarDomain::handleVerticalAxisBaseChanged(qreal baseY) | |
197 | { |
|
198 | { | |
198 | m_logBaseY = baseY; |
|
199 | m_logBaseY = baseY; | |
199 | qreal logMinY = log10(m_minY) / log10(m_logBaseY); |
|
200 | qreal logMinY = std::log10(m_minY) / std::log10(m_logBaseY); | |
200 | qreal logMaxY = log10(m_maxY) / log10(m_logBaseY); |
|
201 | qreal logMaxY = std::log10(m_maxY) / std::log10(m_logBaseY); | |
201 | m_logInnerY = logMinY < logMaxY ? logMinY : logMaxY; |
|
202 | m_logInnerY = logMinY < logMaxY ? logMinY : logMaxY; | |
202 | m_logOuterY = logMinY > logMaxY ? logMinY : logMaxY; |
|
203 | m_logOuterY = logMinY > logMaxY ? logMinY : logMaxY; | |
203 | emit updated(); |
|
204 | emit updated(); | |
204 | } |
|
205 | } | |
205 |
|
206 | |||
206 | // operators |
|
207 | // operators | |
207 |
|
208 | |||
208 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const XLogYPolarDomain &domain1, const XLogYPolarDomain &domain2) |
|
209 | bool QT_CHARTS_AUTOTEST_EXPORT operator== (const XLogYPolarDomain &domain1, const XLogYPolarDomain &domain2) | |
209 | { |
|
210 | { | |
210 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) |
|
211 | return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) | |
211 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) |
|
212 | && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) | |
212 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) |
|
213 | && qFuzzyIsNull(domain1.m_minX - domain2.m_minX) | |
213 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); |
|
214 | && qFuzzyIsNull(domain1.m_minY - domain2.m_minY)); | |
214 | } |
|
215 | } | |
215 |
|
216 | |||
216 |
|
217 | |||
217 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const XLogYPolarDomain &domain1, const XLogYPolarDomain &domain2) |
|
218 | bool QT_CHARTS_AUTOTEST_EXPORT operator!= (const XLogYPolarDomain &domain1, const XLogYPolarDomain &domain2) | |
218 | { |
|
219 | { | |
219 | return !(domain1 == domain2); |
|
220 | return !(domain1 == domain2); | |
220 | } |
|
221 | } | |
221 |
|
222 | |||
222 |
|
223 | |||
223 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYPolarDomain &domain) |
|
224 | QDebug QT_CHARTS_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYPolarDomain &domain) | |
224 | { |
|
225 | { | |
225 | #ifdef QT_NO_TEXTSTREAM |
|
226 | #ifdef QT_NO_TEXTSTREAM | |
226 | Q_UNUSED(domain) |
|
227 | Q_UNUSED(domain) | |
227 | #else |
|
228 | #else | |
228 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; |
|
229 | dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size; | |
229 | #endif |
|
230 | #endif | |
230 | return dbg.maybeSpace(); |
|
231 | return dbg.maybeSpace(); | |
231 | } |
|
232 | } | |
232 |
|
233 | |||
233 | #include "moc_xlogypolardomain_p.cpp" |
|
234 | #include "moc_xlogypolardomain_p.cpp" | |
234 |
|
235 | |||
235 | QT_CHARTS_END_NAMESPACE |
|
236 | QT_CHARTS_END_NAMESPACE |
General Comments 0
You need to be logged in to leave comments.
Login now