##// END OF EJS Templates
Fix logarithmic axis point calculation...
Titta Heikkala -
r2611:f23ac1927350
parent child
Show More
@@ -1,97 +1,94
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "horizontalbarchartitem_p.h"
21 #include "horizontalbarchartitem_p.h"
22 #include "qabstractbarseries_p.h"
22 #include "qabstractbarseries_p.h"
23 #include "qbarset_p.h"
23 #include "qbarset_p.h"
24 #include "bar_p.h"
24 #include "bar_p.h"
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 HorizontalBarChartItem::HorizontalBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
28 HorizontalBarChartItem::HorizontalBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
29 : AbstractBarChartItem(series, item)
29 : AbstractBarChartItem(series, item)
30 {
30 {
31 }
31 }
32
32
33 void HorizontalBarChartItem::initializeLayout()
33 void HorizontalBarChartItem::initializeLayout()
34 {
34 {
35 qreal categoryCount = m_series->d_func()->categoryCount();
35 qreal categoryCount = m_series->d_func()->categoryCount();
36 qreal setCount = m_series->count();
36 qreal setCount = m_series->count();
37 qreal barWidth = m_series->d_func()->barWidth();
37 qreal barWidth = m_series->d_func()->barWidth();
38
38
39 m_layout.clear();
39 m_layout.clear();
40 for(int category = 0; category < categoryCount; category++) {
40 for(int category = 0; category < categoryCount; category++) {
41 for (int set = 0; set < setCount; set++) {
41 for (int set = 0; set < setCount; set++) {
42 QRectF rect;
42 QRectF rect;
43 QPointF topLeft;
43 QPointF topLeft;
44 QPointF bottomRight;
44 QPointF bottomRight;
45 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
45 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
46 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + set/setCount * barWidth), m_validData);
46 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + set/setCount * barWidth), m_validData);
47 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
47 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
48 } else {
48 } else {
49 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + set/setCount * barWidth), m_validData);
49 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + set/setCount * barWidth), m_validData);
50 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
50 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
51 }
51 }
52
52
53 if (!m_validData)
53 if (!m_validData)
54 return;
54 return;
55
55
56 rect.setTopLeft(topLeft);
56 rect.setTopLeft(topLeft);
57 rect.setBottomRight(bottomRight);
57 rect.setBottomRight(bottomRight);
58 m_layout.append(rect.normalized());
58 m_layout.append(rect.normalized());
59 }
59 }
60 }
60 }
61 }
61 }
62
62
63 QVector<QRectF> HorizontalBarChartItem::calculateLayout()
63 QVector<QRectF> HorizontalBarChartItem::calculateLayout()
64 {
64 {
65 QVector<QRectF> layout;
65 QVector<QRectF> layout;
66
66
67 // Use temporary qreals for accuracy
67 // Use temporary qreals for accuracy
68 qreal categoryCount = m_series->d_func()->categoryCount();
68 qreal categoryCount = m_series->d_func()->categoryCount();
69 qreal setCount = m_series->count();
69 qreal setCount = m_series->count();
70 qreal barWidth = m_series->d_func()->barWidth();
70 qreal barWidth = m_series->d_func()->barWidth();
71
71
72 for(int category = 0; category < categoryCount; category++) {
72 for(int category = 0; category < categoryCount; category++) {
73 for (int set = 0; set < setCount; set++) {
73 for (int set = 0; set < setCount; set++) {
74 qreal value = m_series->barSets().at(set)->at(category);
74 qreal value = m_series->barSets().at(set)->at(category);
75 QRectF rect;
75 QRectF rect;
76 QPointF topLeft;
76 QPointF topLeft;
77 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
77 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
78 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + set/setCount * barWidth), m_validData);
78 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + set/setCount * barWidth), m_validData);
79 else
79 else
80 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + set/setCount * barWidth), m_validData);
80 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + set/setCount * barWidth), m_validData);
81
81
82 QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(value, category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
82 QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(value, category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
83
83
84 if (!m_validData)
85 return QVector<QRectF>();
86
87 rect.setTopLeft(topLeft);
84 rect.setTopLeft(topLeft);
88 rect.setBottomRight(bottomRight);
85 rect.setBottomRight(bottomRight);
89 layout.append(rect.normalized());
86 layout.append(rect.normalized());
90 }
87 }
91 }
88 }
92 return layout;
89 return layout;
93 }
90 }
94
91
95 #include "moc_horizontalbarchartitem_p.cpp"
92 #include "moc_horizontalbarchartitem_p.cpp"
96
93
97 QTCOMMERCIALCHART_END_NAMESPACE
94 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,128 +1,126
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "horizontalpercentbarchartitem_p.h"
21 #include "horizontalpercentbarchartitem_p.h"
22 #include "qabstractbarseries_p.h"
22 #include "qabstractbarseries_p.h"
23 #include "qbarset_p.h"
23 #include "qbarset_p.h"
24 #include "bar_p.h"
24 #include "bar_p.h"
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 HorizontalPercentBarChartItem::HorizontalPercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
28 HorizontalPercentBarChartItem::HorizontalPercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
29 : AbstractBarChartItem(series, item)
29 : AbstractBarChartItem(series, item)
30 {
30 {
31 }
31 }
32
32
33 void HorizontalPercentBarChartItem::initializeLayout()
33 void HorizontalPercentBarChartItem::initializeLayout()
34 {
34 {
35 qreal categoryCount = m_series->d_func()->categoryCount();
35 qreal categoryCount = m_series->d_func()->categoryCount();
36 qreal setCount = m_series->count();
36 qreal setCount = m_series->count();
37 qreal barWidth = m_series->d_func()->barWidth();
37 qreal barWidth = m_series->d_func()->barWidth();
38
38
39 m_layout.clear();
39 m_layout.clear();
40 for(int category = 0; category < categoryCount; category++) {
40 for(int category = 0; category < categoryCount; category++) {
41 for (int set = 0; set < setCount; set++) {
41 for (int set = 0; set < setCount; set++) {
42 QRectF rect;
42 QRectF rect;
43 QPointF topLeft;
43 QPointF topLeft;
44 QPointF bottomRight;
44 QPointF bottomRight;
45 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
45 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
46 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
46 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
47 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
47 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
48 } else {
48 } else {
49 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
49 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
50 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
50 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
51 }
51 }
52
52
53 if (!m_validData)
53 if (!m_validData)
54 return;
54 return;
55
55
56 rect.setTopLeft(topLeft);
56 rect.setTopLeft(topLeft);
57 rect.setBottomRight(bottomRight);
57 rect.setBottomRight(bottomRight);
58 m_layout.append(rect.normalized());
58 m_layout.append(rect.normalized());
59 }
59 }
60 }
60 }
61 }
61 }
62
62
63 QVector<QRectF> HorizontalPercentBarChartItem::calculateLayout()
63 QVector<QRectF> HorizontalPercentBarChartItem::calculateLayout()
64 {
64 {
65 QVector<QRectF> layout;
65 QVector<QRectF> layout;
66
66
67 // Use temporary qreals for accuracy
67 // Use temporary qreals for accuracy
68 qreal categoryCount = m_series->d_func()->categoryCount();
68 qreal categoryCount = m_series->d_func()->categoryCount();
69 qreal setCount = m_series->count();
69 qreal setCount = m_series->count();
70 qreal barWidth = m_series->d_func()->barWidth();
70 qreal barWidth = m_series->d_func()->barWidth();
71
71
72 for(int category = 0; category < categoryCount; category++) {
72 for(int category = 0; category < categoryCount; category++) {
73 qreal sum = 0;
73 qreal sum = 0;
74 qreal categorySum = m_series->d_func()->categorySum(category);
74 qreal categorySum = m_series->d_func()->categorySum(category);
75 for (int set = 0; set < setCount; set++) {
75 for (int set = 0; set < setCount; set++) {
76 qreal value = m_series->barSets().at(set)->at(category);
76 qreal value = m_series->barSets().at(set)->at(category);
77 QRectF rect;
77 QRectF rect;
78 QPointF topLeft;
78 QPointF topLeft;
79 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
79 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
80 topLeft = domain()->calculateGeometryPoint(QPointF(set ? 100 * sum/categorySum : domain()->minX(), category - barWidth/2), m_validData);
80 topLeft = domain()->calculateGeometryPoint(QPointF(set ? 100 * sum/categorySum : domain()->minX(), category - barWidth/2), m_validData);
81 else
81 else
82 topLeft = domain()->calculateGeometryPoint(QPointF(set ? 100 * sum/categorySum : 0, category - barWidth/2), m_validData);
82 topLeft = domain()->calculateGeometryPoint(QPointF(set ? 100 * sum/categorySum : 0, category - barWidth/2), m_validData);
83 QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(100 * (value + sum)/categorySum, category + barWidth/2), m_validData);
83 QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(100 * (value + sum)/categorySum, category + barWidth/2), m_validData);
84
84
85 if (!m_validData)
86 return QVector<QRectF>();
87 rect.setTopLeft(topLeft);
85 rect.setTopLeft(topLeft);
88 rect.setBottomRight(bottomRight);
86 rect.setBottomRight(bottomRight);
89 layout.append(rect.normalized());
87 layout.append(rect.normalized());
90 sum +=value;
88 sum +=value;
91 }
89 }
92 }
90 }
93 return layout;
91 return layout;
94 }
92 }
95
93
96 void HorizontalPercentBarChartItem::handleUpdatedBars()
94 void HorizontalPercentBarChartItem::handleUpdatedBars()
97 {
95 {
98 // Handle changes in pen, brush, labels etc.
96 // Handle changes in pen, brush, labels etc.
99 int categoryCount = m_series->d_func()->categoryCount();
97 int categoryCount = m_series->d_func()->categoryCount();
100 int setCount = m_series->count();
98 int setCount = m_series->count();
101 int itemIndex(0);
99 int itemIndex(0);
102
100
103 for (int category = 0; category < categoryCount; category++) {
101 for (int category = 0; category < categoryCount; category++) {
104 for (int set = 0; set < setCount; set++) {
102 for (int set = 0; set < setCount; set++) {
105 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
103 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
106 Bar *bar = m_bars.at(itemIndex);
104 Bar *bar = m_bars.at(itemIndex);
107 bar->setPen(barSet->m_pen);
105 bar->setPen(barSet->m_pen);
108 bar->setBrush(barSet->m_brush);
106 bar->setBrush(barSet->m_brush);
109 bar->update();
107 bar->update();
110
108
111 QGraphicsTextItem *label = m_labels.at(itemIndex);
109 QGraphicsTextItem *label = m_labels.at(itemIndex);
112 int p = m_series->d_func()->percentageAt(set, category) * 100;
110 int p = m_series->d_func()->percentageAt(set, category) * 100;
113 QString vString(QString::number(p));
111 QString vString(QString::number(p));
114 vString.truncate(3);
112 vString.truncate(3);
115 vString.append("%");
113 vString.append("%");
116 label->setHtml(vString);
114 label->setHtml(vString);
117 label->setFont(barSet->m_labelFont);
115 label->setFont(barSet->m_labelFont);
118 label->setDefaultTextColor(barSet->m_labelBrush.color());
116 label->setDefaultTextColor(barSet->m_labelBrush.color());
119 label->update();
117 label->update();
120 itemIndex++;
118 itemIndex++;
121 }
119 }
122 }
120 }
123 }
121 }
124
122
125 #include "moc_horizontalpercentbarchartitem_p.cpp"
123 #include "moc_horizontalpercentbarchartitem_p.cpp"
126
124
127 QTCOMMERCIALCHART_END_NAMESPACE
125 QTCOMMERCIALCHART_END_NAMESPACE
128
126
@@ -1,108 +1,107
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "horizontalstackedbarchartitem_p.h"
21 #include "horizontalstackedbarchartitem_p.h"
22 #include "qabstractbarseries_p.h"
22 #include "qabstractbarseries_p.h"
23 #include "qbarset_p.h"
23 #include "qbarset_p.h"
24 #include "bar_p.h"
24 #include "bar_p.h"
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 HorizontalStackedBarChartItem::HorizontalStackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
28 HorizontalStackedBarChartItem::HorizontalStackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
29 : AbstractBarChartItem(series, item)
29 : AbstractBarChartItem(series, item)
30 {
30 {
31 }
31 }
32
32
33 void HorizontalStackedBarChartItem::initializeLayout()
33 void HorizontalStackedBarChartItem::initializeLayout()
34 {
34 {
35 qreal categoryCount = m_series->d_func()->categoryCount();
35 qreal categoryCount = m_series->d_func()->categoryCount();
36 qreal setCount = m_series->count();
36 qreal setCount = m_series->count();
37 qreal barWidth = m_series->d_func()->barWidth();
37 qreal barWidth = m_series->d_func()->barWidth();
38
38
39 m_layout.clear();
39 m_layout.clear();
40 for(int category = 0; category < categoryCount; category++) {
40 for(int category = 0; category < categoryCount; category++) {
41 for (int set = 0; set < setCount; set++) {
41 for (int set = 0; set < setCount; set++) {
42 QRectF rect;
42 QRectF rect;
43 QPointF topLeft;
43 QPointF topLeft;
44 QPointF bottomRight;
44 QPointF bottomRight;
45 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
45 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
46 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
46 topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
47 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
47 bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
48 } else {
48 } else {
49 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
49 topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
50 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
50 bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
51 }
51 }
52
52
53 if (!m_validData)
53 if (!m_validData)
54 return;
54 return;
55
55
56 rect.setTopLeft(topLeft);
56 rect.setTopLeft(topLeft);
57 rect.setBottomRight(bottomRight);
57 rect.setBottomRight(bottomRight);
58 m_layout.append(rect.normalized());
58 m_layout.append(rect.normalized());
59 }
59 }
60 }
60 }
61 }
61 }
62
62
63 QVector<QRectF> HorizontalStackedBarChartItem::calculateLayout()
63 QVector<QRectF> HorizontalStackedBarChartItem::calculateLayout()
64 {
64 {
65 QVector<QRectF> layout;
65 QVector<QRectF> layout;
66
66
67 // Use temporary qreals for accuracy
67 // Use temporary qreals for accuracy
68 qreal categoryCount = m_series->d_func()->categoryCount();
68 qreal categoryCount = m_series->d_func()->categoryCount();
69 qreal setCount = m_series->count();
69 qreal setCount = m_series->count();
70 qreal barWidth = m_series->d_func()->barWidth();
70 qreal barWidth = m_series->d_func()->barWidth();
71
71
72 for(int category = 0; category < categoryCount; category++) {
72 for(int category = 0; category < categoryCount; category++) {
73 qreal positiveSum = 0;
73 qreal positiveSum = 0;
74 qreal negativeSum = 0;
74 qreal negativeSum = 0;
75 for (int set = 0; set < setCount; set++) {
75 for (int set = 0; set < setCount; set++) {
76 qreal value = m_series->barSets().at(set)->at(category);
76 qreal value = m_series->barSets().at(set)->at(category);
77 QRectF rect;
77 QRectF rect;
78 QPointF topLeft;
78 QPointF topLeft;
79 QPointF bottomRight;
79 QPointF bottomRight;
80 if (value < 0) {
80 if (value < 0) {
81 bottomRight = domain()->calculateGeometryPoint(QPointF(value + negativeSum, category - barWidth / 2), m_validData);
81 bottomRight = domain()->calculateGeometryPoint(QPointF(value + negativeSum, category - barWidth / 2), m_validData);
82 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
82 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
83 topLeft = domain()->calculateGeometryPoint(QPointF(set ? negativeSum : domain()->minX(), category + barWidth / 2), m_validData);
83 topLeft = domain()->calculateGeometryPoint(QPointF(set ? negativeSum : domain()->minX(), category + barWidth / 2), m_validData);
84 else
84 else
85 topLeft = domain()->calculateGeometryPoint(QPointF(set ? negativeSum : 0, category + barWidth / 2), m_validData);
85 topLeft = domain()->calculateGeometryPoint(QPointF(set ? negativeSum : 0, category + barWidth / 2), m_validData);
86 negativeSum += value;
86 negativeSum += value;
87 } else {
87 } else {
88 bottomRight = domain()->calculateGeometryPoint(QPointF(value + positiveSum, category - barWidth / 2), m_validData);
88 bottomRight = domain()->calculateGeometryPoint(QPointF(value + positiveSum, category - barWidth / 2), m_validData);
89 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
89 if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
90 topLeft = domain()->calculateGeometryPoint(QPointF(set ? positiveSum : domain()->minX(), category + barWidth / 2), m_validData);
90 topLeft = domain()->calculateGeometryPoint(QPointF(set ? positiveSum : domain()->minX(), category + barWidth / 2), m_validData);
91 else
91 else
92 topLeft = domain()->calculateGeometryPoint(QPointF(set ? positiveSum : 0, category + barWidth / 2), m_validData);
92 topLeft = domain()->calculateGeometryPoint(QPointF(set ? positiveSum : 0, category + barWidth / 2), m_validData);
93 positiveSum += value;
93 positiveSum += value;
94 }
94 }
95 if (!m_validData)
95
96 return QVector<QRectF>();
97 rect.setTopLeft(topLeft);
96 rect.setTopLeft(topLeft);
98 rect.setBottomRight(bottomRight);
97 rect.setBottomRight(bottomRight);
99 layout.append(rect.normalized());
98 layout.append(rect.normalized());
100 }
99 }
101 }
100 }
102 return layout;
101 return layout;
103 }
102 }
104
103
105 #include "moc_horizontalstackedbarchartitem_p.cpp"
104 #include "moc_horizontalstackedbarchartitem_p.cpp"
106
105
107 QTCOMMERCIALCHART_END_NAMESPACE
106 QTCOMMERCIALCHART_END_NAMESPACE
108
107
@@ -1,97 +1,94
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "barchartitem_p.h"
21 #include "barchartitem_p.h"
22 #include "bar_p.h"
22 #include "bar_p.h"
23 #include "qabstractbarseries_p.h"
23 #include "qabstractbarseries_p.h"
24 #include "qbarset.h"
24 #include "qbarset.h"
25 #include "qbarset_p.h"
25 #include "qbarset_p.h"
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 BarChartItem::BarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
29 BarChartItem::BarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
30 AbstractBarChartItem(series, item)
30 AbstractBarChartItem(series, item)
31 {
31 {
32 }
32 }
33
33
34 void BarChartItem::initializeLayout()
34 void BarChartItem::initializeLayout()
35 {
35 {
36 qreal categoryCount = m_series->d_func()->categoryCount();
36 qreal categoryCount = m_series->d_func()->categoryCount();
37 qreal setCount = m_series->count();
37 qreal setCount = m_series->count();
38 qreal barWidth = m_series->d_func()->barWidth();
38 qreal barWidth = m_series->d_func()->barWidth();
39
39
40 m_layout.clear();
40 m_layout.clear();
41 for(int category = 0; category < categoryCount; category++) {
41 for(int category = 0; category < categoryCount; category++) {
42 for (int set = 0; set < setCount; set++) {
42 for (int set = 0; set < setCount; set++) {
43 QRectF rect;
43 QRectF rect;
44 QPointF topLeft;
44 QPointF topLeft;
45 QPointF bottomRight;
45 QPointF bottomRight;
46
46
47 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
47 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
48 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, domain()->minY()), m_validData);
48 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, domain()->minY()), m_validData);
49 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, domain()->minY()), m_validData);
49 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, domain()->minY()), m_validData);
50 } else {
50 } else {
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, 0), m_validData);
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, 0), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, 0), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, 0), m_validData);
53 }
53 }
54
54
55 if (!m_validData)
55 if (!m_validData)
56 return;
56 return;
57 rect.setTopLeft(topLeft);
57 rect.setTopLeft(topLeft);
58 rect.setBottomRight(bottomRight);
58 rect.setBottomRight(bottomRight);
59 m_layout.append(rect.normalized());
59 m_layout.append(rect.normalized());
60 }
60 }
61 }
61 }
62 }
62 }
63
63
64 QVector<QRectF> BarChartItem::calculateLayout()
64 QVector<QRectF> BarChartItem::calculateLayout()
65 {
65 {
66 QVector<QRectF> layout;
66 QVector<QRectF> layout;
67
67
68 // Use temporary qreals for accuracy
68 // Use temporary qreals for accuracy
69 qreal categoryCount = m_series->d_func()->categoryCount();
69 qreal categoryCount = m_series->d_func()->categoryCount();
70 qreal setCount = m_series->count();
70 qreal setCount = m_series->count();
71 qreal barWidth = m_series->d_func()->barWidth();
71 qreal barWidth = m_series->d_func()->barWidth();
72
72
73 for(int category = 0; category < categoryCount; category++) {
73 for(int category = 0; category < categoryCount; category++) {
74 for (int set = 0; set < setCount; set++) {
74 for (int set = 0; set < setCount; set++) {
75 qreal value = m_series->barSets().at(set)->at(category);
75 qreal value = m_series->barSets().at(set)->at(category);
76 QRectF rect;
76 QRectF rect;
77 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set)/(setCount) * barWidth, value), m_validData);
77 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set)/(setCount) * barWidth, value), m_validData);
78 QPointF bottomRight;
78 QPointF bottomRight;
79 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
79 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
80 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, domain()->minY()), m_validData);
80 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, domain()->minY()), m_validData);
81 else
81 else
82 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, 0), m_validData);
82 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, 0), m_validData);
83
83
84 if (!m_validData)
85 return QVector<QRectF>();
86
87 rect.setTopLeft(topLeft);
84 rect.setTopLeft(topLeft);
88 rect.setBottomRight(bottomRight);
85 rect.setBottomRight(bottomRight);
89 layout.append(rect.normalized());
86 layout.append(rect.normalized());
90 }
87 }
91 }
88 }
92 return layout;
89 return layout;
93 }
90 }
94
91
95 #include "moc_barchartitem_p.cpp"
92 #include "moc_barchartitem_p.cpp"
96
93
97 QTCOMMERCIALCHART_END_NAMESPACE
94 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,129 +1,127
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "percentbarchartitem_p.h"
21 #include "percentbarchartitem_p.h"
22 #include "bar_p.h"
22 #include "bar_p.h"
23 #include "qabstractbarseries_p.h"
23 #include "qabstractbarseries_p.h"
24 #include "qbarset.h"
24 #include "qbarset.h"
25 #include "qbarset_p.h"
25 #include "qbarset_p.h"
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
29 PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
30 AbstractBarChartItem(series, item)
30 AbstractBarChartItem(series, item)
31 {
31 {
32 }
32 }
33
33
34 void PercentBarChartItem::initializeLayout()
34 void PercentBarChartItem::initializeLayout()
35 {
35 {
36 qreal categoryCount = m_series->d_func()->categoryCount();
36 qreal categoryCount = m_series->d_func()->categoryCount();
37 qreal setCount = m_series->count();
37 qreal setCount = m_series->count();
38 qreal barWidth = m_series->d_func()->barWidth();
38 qreal barWidth = m_series->d_func()->barWidth();
39
39
40 m_layout.clear();
40 m_layout.clear();
41 for(int category = 0; category < categoryCount; category++) {
41 for(int category = 0; category < categoryCount; category++) {
42 for (int set = 0; set < setCount; set++) {
42 for (int set = 0; set < setCount; set++) {
43 QRectF rect;
43 QRectF rect;
44 QPointF topLeft;
44 QPointF topLeft;
45 QPointF bottomRight;
45 QPointF bottomRight;
46
46
47 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
47 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
48 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
48 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
49 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
49 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
50 } else {
50 } else {
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
53 }
53 }
54
54
55 if (!m_validData)
55 if (!m_validData)
56 return;
56 return;
57
57
58 rect.setTopLeft(topLeft);
58 rect.setTopLeft(topLeft);
59 rect.setBottomRight(bottomRight);
59 rect.setBottomRight(bottomRight);
60 m_layout.append(rect.normalized());
60 m_layout.append(rect.normalized());
61 }
61 }
62 }
62 }
63 }
63 }
64
64
65 QVector<QRectF> PercentBarChartItem::calculateLayout()
65 QVector<QRectF> PercentBarChartItem::calculateLayout()
66 {
66 {
67 QVector<QRectF> layout;
67 QVector<QRectF> layout;
68
68
69 // Use temporary qreals for accuracy
69 // Use temporary qreals for accuracy
70 qreal categoryCount = m_series->d_func()->categoryCount();
70 qreal categoryCount = m_series->d_func()->categoryCount();
71 qreal setCount = m_series->count();
71 qreal setCount = m_series->count();
72 qreal barWidth = m_series->d_func()->barWidth();
72 qreal barWidth = m_series->d_func()->barWidth();
73
73
74 for(int category = 0; category < categoryCount; category++) {
74 for(int category = 0; category < categoryCount; category++) {
75 qreal sum = 0;
75 qreal sum = 0;
76 qreal categorySum = m_series->d_func()->categorySum(category);
76 qreal categorySum = m_series->d_func()->categorySum(category);
77 for (int set = 0; set < setCount; set++) {
77 for (int set = 0; set < setCount; set++) {
78 qreal value = m_series->barSets().at(set)->at(category);
78 qreal value = m_series->barSets().at(set)->at(category);
79 QRectF rect;
79 QRectF rect;
80 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, 100 * (value + sum)/categorySum), m_validData);
80 QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, 100 * (value + sum)/categorySum), m_validData);
81 QPointF bottomRight;
81 QPointF bottomRight;
82 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
82 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
83 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? 100 * sum/categorySum : domain()->minY()), m_validData);
83 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? 100 * sum/categorySum : domain()->minY()), m_validData);
84 else
84 else
85 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? 100 * sum/categorySum : 0), m_validData);
85 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? 100 * sum/categorySum : 0), m_validData);
86
86
87 if (!m_validData)
88 return QVector<QRectF>();
89 rect.setTopLeft(topLeft);
87 rect.setTopLeft(topLeft);
90 rect.setBottomRight(bottomRight);
88 rect.setBottomRight(bottomRight);
91 layout.append(rect.normalized());
89 layout.append(rect.normalized());
92 sum +=value;
90 sum +=value;
93 }
91 }
94 }
92 }
95 return layout;
93 return layout;
96 }
94 }
97
95
98 void PercentBarChartItem::handleUpdatedBars()
96 void PercentBarChartItem::handleUpdatedBars()
99 {
97 {
100 // Handle changes in pen, brush, labels etc.
98 // Handle changes in pen, brush, labels etc.
101 int categoryCount = m_series->d_func()->categoryCount();
99 int categoryCount = m_series->d_func()->categoryCount();
102 int setCount = m_series->count();
100 int setCount = m_series->count();
103 int itemIndex(0);
101 int itemIndex(0);
104
102
105 for (int category = 0; category < categoryCount; category++) {
103 for (int category = 0; category < categoryCount; category++) {
106 for (int set = 0; set < setCount; set++) {
104 for (int set = 0; set < setCount; set++) {
107 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
105 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
108 Bar *bar = m_bars.at(itemIndex);
106 Bar *bar = m_bars.at(itemIndex);
109 bar->setPen(barSet->m_pen);
107 bar->setPen(barSet->m_pen);
110 bar->setBrush(barSet->m_brush);
108 bar->setBrush(barSet->m_brush);
111 bar->update();
109 bar->update();
112
110
113 QGraphicsTextItem *label = m_labels.at(itemIndex);
111 QGraphicsTextItem *label = m_labels.at(itemIndex);
114 int p = m_series->d_func()->percentageAt(set, category) * 100;
112 int p = m_series->d_func()->percentageAt(set, category) * 100;
115 QString vString(QString::number(p));
113 QString vString(QString::number(p));
116 vString.truncate(3);
114 vString.truncate(3);
117 vString.append("%");
115 vString.append("%");
118 label->setHtml(vString);
116 label->setHtml(vString);
119 label->setFont(barSet->m_labelFont);
117 label->setFont(barSet->m_labelFont);
120 label->setDefaultTextColor(barSet->m_labelBrush.color());
118 label->setDefaultTextColor(barSet->m_labelBrush.color());
121 label->update();
119 label->update();
122 itemIndex++;
120 itemIndex++;
123 }
121 }
124 }
122 }
125 }
123 }
126
124
127 #include "moc_percentbarchartitem_p.cpp"
125 #include "moc_percentbarchartitem_p.cpp"
128
126
129 QTCOMMERCIALCHART_END_NAMESPACE
127 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,108 +1,107
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "stackedbarchartitem_p.h"
21 #include "stackedbarchartitem_p.h"
22 #include "bar_p.h"
22 #include "bar_p.h"
23 #include "qbarset_p.h"
23 #include "qbarset_p.h"
24 #include "qabstractbarseries_p.h"
24 #include "qabstractbarseries_p.h"
25 #include "qbarset.h"
25 #include "qbarset.h"
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 StackedBarChartItem::StackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
29 StackedBarChartItem::StackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
30 AbstractBarChartItem(series, item)
30 AbstractBarChartItem(series, item)
31 {
31 {
32 }
32 }
33
33
34 void StackedBarChartItem::initializeLayout()
34 void StackedBarChartItem::initializeLayout()
35 {
35 {
36 qreal categoryCount = m_series->d_func()->categoryCount();
36 qreal categoryCount = m_series->d_func()->categoryCount();
37 qreal setCount = m_series->count();
37 qreal setCount = m_series->count();
38 qreal barWidth = m_series->d_func()->barWidth();
38 qreal barWidth = m_series->d_func()->barWidth();
39
39
40 m_layout.clear();
40 m_layout.clear();
41 for(int category = 0; category < categoryCount; category++) {
41 for(int category = 0; category < categoryCount; category++) {
42 for (int set = 0; set < setCount; set++) {
42 for (int set = 0; set < setCount; set++) {
43 QRectF rect;
43 QRectF rect;
44 QPointF topLeft;
44 QPointF topLeft;
45 QPointF bottomRight;
45 QPointF bottomRight;
46
46
47 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
47 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
48 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
48 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
49 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
49 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
50 } else {
50 } else {
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
51 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
52 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
53 }
53 }
54
54
55 if (!m_validData)
55 if (!m_validData)
56 return;
56 return;
57
57
58 rect.setTopLeft(topLeft);
58 rect.setTopLeft(topLeft);
59 rect.setBottomRight(bottomRight);
59 rect.setBottomRight(bottomRight);
60 m_layout.append(rect.normalized());
60 m_layout.append(rect.normalized());
61 }
61 }
62 }
62 }
63 }
63 }
64
64
65 QVector<QRectF> StackedBarChartItem::calculateLayout()
65 QVector<QRectF> StackedBarChartItem::calculateLayout()
66 {
66 {
67 QVector<QRectF> layout;
67 QVector<QRectF> layout;
68 // Use temporary qreals for accuracy
68 // Use temporary qreals for accuracy
69 qreal categoryCount = m_series->d_func()->categoryCount();
69 qreal categoryCount = m_series->d_func()->categoryCount();
70 qreal setCount = m_series->count();
70 qreal setCount = m_series->count();
71 qreal barWidth = m_series->d_func()->barWidth();
71 qreal barWidth = m_series->d_func()->barWidth();
72
72
73 for(int category = 0; category < categoryCount; category++) {
73 for(int category = 0; category < categoryCount; category++) {
74 qreal positiveSum = 0;
74 qreal positiveSum = 0;
75 qreal negativeSum = 0;
75 qreal negativeSum = 0;
76 for (int set = 0; set < setCount; set++) {
76 for (int set = 0; set < setCount; set++) {
77 qreal value = m_series->barSets().at(set)->at(category);
77 qreal value = m_series->barSets().at(set)->at(category);
78 QRectF rect;
78 QRectF rect;
79 QPointF topLeft;
79 QPointF topLeft;
80 QPointF bottomRight;
80 QPointF bottomRight;
81 if (value < 0) {
81 if (value < 0) {
82 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + negativeSum), m_validData);
82 bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + negativeSum), m_validData);
83 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
83 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
84 topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : domain()->minY()), m_validData);
84 topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : domain()->minY()), m_validData);
85 else
85 else
86 topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : 0), m_validData);
86 topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : 0), m_validData);
87 negativeSum += value;
87 negativeSum += value;
88 } else {
88 } else {
89 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + positiveSum), m_validData);
89 topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + positiveSum), m_validData);
90 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
90 if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
91 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : domain()->minY()), m_validData);
91 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : domain()->minY()), m_validData);
92 else
92 else
93 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : 0), m_validData);
93 bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : 0), m_validData);
94 positiveSum += value;
94 positiveSum += value;
95 }
95 }
96 if (!m_validData)
96
97 return QVector<QRectF>();
98 rect.setTopLeft(topLeft);
97 rect.setTopLeft(topLeft);
99 rect.setBottomRight(bottomRight);
98 rect.setBottomRight(bottomRight);
100 layout.append(rect.normalized());
99 layout.append(rect.normalized());
101 }
100 }
102 }
101 }
103 return layout;
102 return layout;
104 }
103 }
105
104
106 #include "moc_stackedbarchartitem_p.cpp"
105 #include "moc_stackedbarchartitem_p.cpp"
107
106
108 QTCOMMERCIALCHART_END_NAMESPACE
107 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,263 +1,274
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "logxlogydomain_p.h"
21 #include "logxlogydomain_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "qlogvalueaxis.h"
23 #include "qlogvalueaxis.h"
24 #include <qmath.h>
24 #include <qmath.h>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 LogXLogYDomain::LogXLogYDomain(QObject *parent)
28 LogXLogYDomain::LogXLogYDomain(QObject *parent)
29 : AbstractDomain(parent),
29 : AbstractDomain(parent),
30 m_logLeftX(0),
30 m_logLeftX(0),
31 m_logRightX(1),
31 m_logRightX(1),
32 m_logBaseX(10),
32 m_logBaseX(10),
33 m_logLeftY(0),
33 m_logLeftY(0),
34 m_logRightY(1),
34 m_logRightY(1),
35 m_logBaseY(10)
35 m_logBaseY(10)
36 {
36 {
37 }
37 }
38
38
39 LogXLogYDomain::~LogXLogYDomain()
39 LogXLogYDomain::~LogXLogYDomain()
40 {
40 {
41 }
41 }
42
42
43 void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
43 void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
44 {
44 {
45 bool axisXChanged = false;
45 bool axisXChanged = false;
46 bool axisYChanged = false;
46 bool axisYChanged = false;
47
47
48 adjustLogDomainRanges(minX, maxX);
48 adjustLogDomainRanges(minX, maxX);
49 adjustLogDomainRanges(minY, maxY);
49 adjustLogDomainRanges(minY, maxY);
50
50
51 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
51 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
52 m_minX = minX;
52 m_minX = minX;
53 m_maxX = maxX;
53 m_maxX = maxX;
54 axisXChanged = true;
54 axisXChanged = true;
55 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
55 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
56 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
56 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
57 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
57 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
58 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
58 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
59 if(!m_signalsBlocked)
59 if(!m_signalsBlocked)
60 emit rangeHorizontalChanged(m_minX, m_maxX);
60 emit rangeHorizontalChanged(m_minX, m_maxX);
61 }
61 }
62
62
63 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
63 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
64 m_minY = minY;
64 m_minY = minY;
65 m_maxY = maxY;
65 m_maxY = maxY;
66 axisYChanged = true;
66 axisYChanged = true;
67 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
67 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
68 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
68 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
69 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
69 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
70 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
70 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
71 if (!m_signalsBlocked)
71 if (!m_signalsBlocked)
72 emit rangeVerticalChanged(m_minY, m_maxY);
72 emit rangeVerticalChanged(m_minY, m_maxY);
73 }
73 }
74
74
75 if (axisXChanged || axisYChanged)
75 if (axisXChanged || axisYChanged)
76 emit updated();
76 emit updated();
77 }
77 }
78
78
79 void LogXLogYDomain::zoomIn(const QRectF &rect)
79 void LogXLogYDomain::zoomIn(const QRectF &rect)
80 {
80 {
81 storeZoomReset();
81 storeZoomReset();
82 qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
82 qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
83 qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
83 qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
84 qreal leftX = qPow(m_logBaseX, logLeftX);
84 qreal leftX = qPow(m_logBaseX, logLeftX);
85 qreal rightX = qPow(m_logBaseX, logRightX);
85 qreal rightX = qPow(m_logBaseX, logRightX);
86 qreal minX = leftX < rightX ? leftX : rightX;
86 qreal minX = leftX < rightX ? leftX : rightX;
87 qreal maxX = leftX > rightX ? leftX : rightX;
87 qreal maxX = leftX > rightX ? leftX : rightX;
88
88
89 qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height();
89 qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height();
90 qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height();
90 qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height();
91 qreal leftY = qPow(m_logBaseY, logLeftY);
91 qreal leftY = qPow(m_logBaseY, logLeftY);
92 qreal rightY = qPow(m_logBaseY, logRightY);
92 qreal rightY = qPow(m_logBaseY, logRightY);
93 qreal minY = leftY < rightY ? leftY : rightY;
93 qreal minY = leftY < rightY ? leftY : rightY;
94 qreal maxY = leftY > rightY ? leftY : rightY;
94 qreal maxY = leftY > rightY ? leftY : rightY;
95
95
96 setRange(minX, maxX, minY, maxY);
96 setRange(minX, maxX, minY, maxY);
97 }
97 }
98
98
99 void LogXLogYDomain::zoomOut(const QRectF &rect)
99 void LogXLogYDomain::zoomOut(const QRectF &rect)
100 {
100 {
101 storeZoomReset();
101 storeZoomReset();
102 const qreal factorX = m_size.width() / rect.width();
102 const qreal factorX = m_size.width() / rect.width();
103 const qreal factorY = m_size.height() / rect.height();
103 const qreal factorY = m_size.height() / rect.height();
104
104
105 qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX);
105 qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX);
106 qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX);
106 qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX);
107 qreal leftX = qPow(m_logBaseX, logLeftX);
107 qreal leftX = qPow(m_logBaseX, logLeftX);
108 qreal rightX = qPow(m_logBaseX, logRIghtX);
108 qreal rightX = qPow(m_logBaseX, logRIghtX);
109 qreal minX = leftX < rightX ? leftX : rightX;
109 qreal minX = leftX < rightX ? leftX : rightX;
110 qreal maxX = leftX > rightX ? leftX : rightX;
110 qreal maxX = leftX > rightX ? leftX : rightX;
111
111
112 qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY);
112 qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY);
113 qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY);
113 qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY);
114 qreal leftY = qPow(m_logBaseY, newLogMinY);
114 qreal leftY = qPow(m_logBaseY, newLogMinY);
115 qreal rightY = qPow(m_logBaseY, newLogMaxY);
115 qreal rightY = qPow(m_logBaseY, newLogMaxY);
116 qreal minY = leftY < rightY ? leftY : rightY;
116 qreal minY = leftY < rightY ? leftY : rightY;
117 qreal maxY = leftY > rightY ? leftY : rightY;
117 qreal maxY = leftY > rightY ? leftY : rightY;
118
118
119 setRange(minX, maxX, minY, maxY);
119 setRange(minX, maxX, minY, maxY);
120 }
120 }
121
121
122 void LogXLogYDomain::move(qreal dx, qreal dy)
122 void LogXLogYDomain::move(qreal dx, qreal dy)
123 {
123 {
124 qreal stepX = dx * qAbs(m_logRightX - m_logLeftX) / m_size.width();
124 qreal stepX = dx * qAbs(m_logRightX - m_logLeftX) / m_size.width();
125 qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX);
125 qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX);
126 qreal rightX = qPow(m_logBaseX, m_logRightX + stepX);
126 qreal rightX = qPow(m_logBaseX, m_logRightX + stepX);
127 qreal minX = leftX < rightX ? leftX : rightX;
127 qreal minX = leftX < rightX ? leftX : rightX;
128 qreal maxX = leftX > rightX ? leftX : rightX;
128 qreal maxX = leftX > rightX ? leftX : rightX;
129
129
130 qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height();
130 qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height();
131 qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY);
131 qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY);
132 qreal rightY = qPow(m_logBaseY, m_logRightY + stepY);
132 qreal rightY = qPow(m_logBaseY, m_logRightY + stepY);
133 qreal minY = leftY < rightY ? leftY : rightY;
133 qreal minY = leftY < rightY ? leftY : rightY;
134 qreal maxY = leftY > rightY ? leftY : rightY;
134 qreal maxY = leftY > rightY ? leftY : rightY;
135
135
136 setRange(minX, maxX, minY, maxY);
136 setRange(minX, maxX, minY, maxY);
137 }
137 }
138
138
139 QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const
139 QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const
140 {
140 {
141 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
142 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
143 qreal x(0);
144 qreal y(0);
141 if (point.x() > 0 && point.y() > 0) {
145 if (point.x() > 0 && point.y() > 0) {
142 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
146 x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
143 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
147 y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
144 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
145 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
146 ok = true;
148 ok = true;
147 return QPointF(x, y);
148 } else {
149 } else {
149 qWarning() << "Logarithm of negative value is undefined. Empty layout returned.";
150 qWarning() << "Logarithms of zero and negative values are undefined.";
150 ok = false;
151 ok = false;
151 return QPointF();
152 if (point.x() > 0)
153 x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
154 else
155 x = 0;
156 if (point.y() > 0) {
157 y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY
158 + m_size.height();
159 } else {
160 y = m_size.height();
161 }
152 }
162 }
163 return QPointF(x, y);
153 }
164 }
154
165
155 QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const
166 QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const
156 {
167 {
157 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
168 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
158 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
169 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
159
170
160 QVector<QPointF> result;
171 QVector<QPointF> result;
161 result.resize(vector.count());
172 result.resize(vector.count());
162
173
163 for (int i = 0; i < vector.count(); ++i) {
174 for (int i = 0; i < vector.count(); ++i) {
164 if (vector[i].x() > 0 && vector[i].y() > 0) {
175 if (vector[i].x() > 0 && vector[i].y() > 0) {
165 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
176 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
166 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
177 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
167 result[i].setX(x);
178 result[i].setX(x);
168 result[i].setY(y);
179 result[i].setY(y);
169 } else {
180 } else {
170 qWarning() << "Logarithm of negative value is undefined. Empty layout returned.";
181 qWarning() << "Logarithms of zero and negative values are undefined.";
171 return QVector<QPointF>();
182 return QVector<QPointF>();
172 }
183 }
173 }
184 }
174 return result;
185 return result;
175 }
186 }
176
187
177 QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const
188 QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const
178 {
189 {
179 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
190 const qreal deltaX = m_size.width() / qAbs(m_logRightX - m_logLeftX);
180 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
191 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
181 qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX);
192 qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX);
182 qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY);
193 qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY);
183 return QPointF(x, y);
194 return QPointF(x, y);
184 }
195 }
185
196
186 bool LogXLogYDomain::attachAxis(QAbstractAxis *axis)
197 bool LogXLogYDomain::attachAxis(QAbstractAxis *axis)
187 {
198 {
188 AbstractDomain::attachAxis(axis);
199 AbstractDomain::attachAxis(axis);
189 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
200 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
190
201
191 if (logAxis && logAxis->orientation() == Qt::Vertical) {
202 if (logAxis && logAxis->orientation() == Qt::Vertical) {
192 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
203 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
193 handleVerticalAxisBaseChanged(logAxis->base());
204 handleVerticalAxisBaseChanged(logAxis->base());
194 }
205 }
195
206
196 if (logAxis && logAxis->orientation() == Qt::Horizontal) {
207 if (logAxis && logAxis->orientation() == Qt::Horizontal) {
197 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
208 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
198 handleHorizontalAxisBaseChanged(logAxis->base());
209 handleHorizontalAxisBaseChanged(logAxis->base());
199 }
210 }
200
211
201 return true;
212 return true;
202 }
213 }
203
214
204 bool LogXLogYDomain::detachAxis(QAbstractAxis *axis)
215 bool LogXLogYDomain::detachAxis(QAbstractAxis *axis)
205 {
216 {
206 AbstractDomain::detachAxis(axis);
217 AbstractDomain::detachAxis(axis);
207 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
218 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
208
219
209 if (logAxis && logAxis->orientation() == Qt::Vertical)
220 if (logAxis && logAxis->orientation() == Qt::Vertical)
210 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
221 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
211
222
212 if (logAxis && logAxis->orientation() == Qt::Horizontal)
223 if (logAxis && logAxis->orientation() == Qt::Horizontal)
213 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
224 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
214
225
215 return true;
226 return true;
216 }
227 }
217
228
218 void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
229 void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
219 {
230 {
220 m_logBaseY = baseY;
231 m_logBaseY = baseY;
221 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
232 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
222 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
233 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
223 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
234 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
224 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
235 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
225 emit updated();
236 emit updated();
226 }
237 }
227
238
228 void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
239 void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
229 {
240 {
230 m_logBaseX = baseX;
241 m_logBaseX = baseX;
231 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
242 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
232 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
243 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
233 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
244 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
234 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
245 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
235 emit updated();
246 emit updated();
236 }
247 }
237
248
238 // operators
249 // operators
239
250
240 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
251 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
241 {
252 {
242 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX)
253 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX)
243 && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY)
254 && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY)
244 && qFuzzyIsNull(domain1.m_minX - domain2.m_minX)
255 && qFuzzyIsNull(domain1.m_minX - domain2.m_minX)
245 && qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
256 && qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
246 }
257 }
247
258
248
259
249 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
260 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
250 {
261 {
251 return !(domain1 == domain2);
262 return !(domain1 == domain2);
252 }
263 }
253
264
254
265
255 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain)
266 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain)
256 {
267 {
257 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
268 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
258 return dbg.maybeSpace();
269 return dbg.maybeSpace();
259 }
270 }
260
271
261 #include "moc_logxlogydomain_p.cpp"
272 #include "moc_logxlogydomain_p.cpp"
262
273
263 QTCOMMERCIALCHART_END_NAMESPACE
274 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,240 +1,241
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "logxydomain_p.h"
21 #include "logxydomain_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "qlogvalueaxis.h"
23 #include "qlogvalueaxis.h"
24 #include <qmath.h>
24 #include <qmath.h>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 LogXYDomain::LogXYDomain(QObject *parent)
28 LogXYDomain::LogXYDomain(QObject *parent)
29 : AbstractDomain(parent),
29 : AbstractDomain(parent),
30 m_logLeftX(0),
30 m_logLeftX(0),
31 m_logRightX(1),
31 m_logRightX(1),
32 m_logBaseX(10)
32 m_logBaseX(10)
33 {
33 {
34 }
34 }
35
35
36 LogXYDomain::~LogXYDomain()
36 LogXYDomain::~LogXYDomain()
37 {
37 {
38 }
38 }
39
39
40 void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
41 {
41 {
42 bool axisXChanged = false;
42 bool axisXChanged = false;
43 bool axisYChanged = false;
43 bool axisYChanged = false;
44
44
45 adjustLogDomainRanges(minX, maxX);
45 adjustLogDomainRanges(minX, maxX);
46
46
47 if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) {
47 if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) {
48 m_minX = minX;
48 m_minX = minX;
49 m_maxX = maxX;
49 m_maxX = maxX;
50 axisXChanged = true;
50 axisXChanged = true;
51 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
51 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
52 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
52 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
53 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
53 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
54 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
54 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
55 if(!m_signalsBlocked)
55 if(!m_signalsBlocked)
56 emit rangeHorizontalChanged(m_minX, m_maxX);
56 emit rangeHorizontalChanged(m_minX, m_maxX);
57 }
57 }
58
58
59 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
59 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
60 m_minY = minY;
60 m_minY = minY;
61 m_maxY = maxY;
61 m_maxY = maxY;
62 axisYChanged = true;
62 axisYChanged = true;
63 if (!m_signalsBlocked)
63 if (!m_signalsBlocked)
64 emit rangeVerticalChanged(m_minY, m_maxY);
64 emit rangeVerticalChanged(m_minY, m_maxY);
65 }
65 }
66
66
67 if (axisXChanged || axisYChanged)
67 if (axisXChanged || axisYChanged)
68 emit updated();
68 emit updated();
69 }
69 }
70
70
71 void LogXYDomain::zoomIn(const QRectF &rect)
71 void LogXYDomain::zoomIn(const QRectF &rect)
72 {
72 {
73 storeZoomReset();
73 storeZoomReset();
74 qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
74 qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
75 qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
75 qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
76 qreal leftX = qPow(m_logBaseX, logLeftX);
76 qreal leftX = qPow(m_logBaseX, logLeftX);
77 qreal rightX = qPow(m_logBaseX, logRightX);
77 qreal rightX = qPow(m_logBaseX, logRightX);
78 qreal minX = leftX < rightX ? leftX : rightX;
78 qreal minX = leftX < rightX ? leftX : rightX;
79 qreal maxX = leftX > rightX ? leftX : rightX;
79 qreal maxX = leftX > rightX ? leftX : rightX;
80
80
81 qreal dy = spanY() / m_size.height();
81 qreal dy = spanY() / m_size.height();
82 qreal minY = m_minY;
82 qreal minY = m_minY;
83 qreal maxY = m_maxY;
83 qreal maxY = m_maxY;
84
84
85 minY = maxY - dy * rect.bottom();
85 minY = maxY - dy * rect.bottom();
86 maxY = maxY - dy * rect.top();
86 maxY = maxY - dy * rect.top();
87
87
88 setRange(minX, maxX, minY, maxY);
88 setRange(minX, maxX, minY, maxY);
89 }
89 }
90
90
91 void LogXYDomain::zoomOut(const QRectF &rect)
91 void LogXYDomain::zoomOut(const QRectF &rect)
92 {
92 {
93 storeZoomReset();
93 storeZoomReset();
94 const qreal factorX = m_size.width() / rect.width();
94 const qreal factorX = m_size.width() / rect.width();
95
95
96 qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX);
96 qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 - factorX);
97 qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX);
97 qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2 * (1 + factorX);
98 qreal leftX = qPow(m_logBaseX, logLeftX);
98 qreal leftX = qPow(m_logBaseX, logLeftX);
99 qreal rightX = qPow(m_logBaseX, logRIghtX);
99 qreal rightX = qPow(m_logBaseX, logRIghtX);
100 qreal minX = leftX < rightX ? leftX : rightX;
100 qreal minX = leftX < rightX ? leftX : rightX;
101 qreal maxX = leftX > rightX ? leftX : rightX;
101 qreal maxX = leftX > rightX ? leftX : rightX;
102
102
103 qreal dy = spanY() / rect.height();
103 qreal dy = spanY() / rect.height();
104 qreal minY = m_minY;
104 qreal minY = m_minY;
105 qreal maxY = m_maxY;
105 qreal maxY = m_maxY;
106
106
107 maxY = minY + dy * rect.bottom();
107 maxY = minY + dy * rect.bottom();
108 minY = maxY - dy * m_size.height();
108 minY = maxY - dy * m_size.height();
109
109
110 setRange(minX, maxX, minY, maxY);
110 setRange(minX, maxX, minY, maxY);
111 }
111 }
112
112
113 void LogXYDomain::move(qreal dx, qreal dy)
113 void LogXYDomain::move(qreal dx, qreal dy)
114 {
114 {
115 qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width();
115 qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width();
116 qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX);
116 qreal leftX = qPow(m_logBaseX, m_logLeftX + stepX);
117 qreal rightX = qPow(m_logBaseX, m_logRightX + stepX);
117 qreal rightX = qPow(m_logBaseX, m_logRightX + stepX);
118 qreal minX = leftX < rightX ? leftX : rightX;
118 qreal minX = leftX < rightX ? leftX : rightX;
119 qreal maxX = leftX > rightX ? leftX : rightX;
119 qreal maxX = leftX > rightX ? leftX : rightX;
120
120
121 qreal y = spanY() / m_size.height();
121 qreal y = spanY() / m_size.height();
122 qreal minY = m_minY;
122 qreal minY = m_minY;
123 qreal maxY = m_maxY;
123 qreal maxY = m_maxY;
124
124
125 if (dy != 0) {
125 if (dy != 0) {
126 minY = minY + y * dy;
126 minY = minY + y * dy;
127 maxY = maxY + y * dy;
127 maxY = maxY + y * dy;
128 }
128 }
129 setRange(minX, maxX, minY, maxY);
129 setRange(minX, maxX, minY, maxY);
130 }
130 }
131
131
132 QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const
132 QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const
133 {
133 {
134 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
135 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
134
136
137 qreal x(0);
138 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
135 if (point.x() > 0) {
139 if (point.x() > 0) {
136 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
140 x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
137 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
138
139 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
140 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
141 ok = true;
141 ok = true;
142 return QPointF(x, y);
143 } else {
142 } else {
144 qWarning() << "Logarithm of negative value is undefined. Empty layout returned.";
143 x = 0;
144 qWarning() << "Logarithms of zero and negative values are undefined.";
145 ok = false;
145 ok = false;
146 return QPointF();
147 }
146 }
147 return QPointF(x, y);
148 }
148 }
149
149
150 QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const
150 QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const
151 {
151 {
152 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
152 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
153 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
153 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
154
154
155 QVector<QPointF> result;
155 QVector<QPointF> result;
156 result.resize(vector.count());
156 result.resize(vector.count());
157
157
158 for (int i = 0; i < vector.count(); ++i) {
158 for (int i = 0; i < vector.count(); ++i) {
159 if (vector[i].x() > 0) {
159 if (vector[i].x() > 0) {
160 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
160 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - m_logLeftX * deltaX;
161 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
161 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
162 result[i].setX(x);
162 result[i].setX(x);
163 result[i].setY(y);
163 result[i].setY(y);
164 } else {
164 } else {
165 qWarning() << "Logarithm of negative value is undefined. Empty layout returned.";
165 qWarning() << "Logarithms of zero and negative values are undefined.";
166 return QVector<QPointF>();
166 return QVector<QPointF>();
167 }
167 }
168
168 }
169 }
169 return result;
170 return result;
170 }
171 }
171
172
172 QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const
173 QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const
173 {
174 {
174 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
175 const qreal deltaX = m_size.width() / (m_logRightX - m_logLeftX);
175 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
176 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
176 qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX);
177 qreal x = qPow(m_logBaseX, m_logLeftX + point.x() / deltaX);
177 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
178 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
178 return QPointF(x, y);
179 return QPointF(x, y);
179 }
180 }
180
181
181 bool LogXYDomain::attachAxis(QAbstractAxis *axis)
182 bool LogXYDomain::attachAxis(QAbstractAxis *axis)
182 {
183 {
183 AbstractDomain::attachAxis(axis);
184 AbstractDomain::attachAxis(axis);
184 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
185 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
185
186
186 if (logAxis && logAxis->orientation() == Qt::Horizontal) {
187 if (logAxis && logAxis->orientation() == Qt::Horizontal) {
187 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
188 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
188 handleHorizontalAxisBaseChanged(logAxis->base());
189 handleHorizontalAxisBaseChanged(logAxis->base());
189 }
190 }
190
191
191 return true;
192 return true;
192 }
193 }
193
194
194 bool LogXYDomain::detachAxis(QAbstractAxis *axis)
195 bool LogXYDomain::detachAxis(QAbstractAxis *axis)
195 {
196 {
196 AbstractDomain::detachAxis(axis);
197 AbstractDomain::detachAxis(axis);
197 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
198 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
198
199
199 if (logAxis && logAxis->orientation() == Qt::Horizontal)
200 if (logAxis && logAxis->orientation() == Qt::Horizontal)
200 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
201 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
201
202
202 return true;
203 return true;
203 }
204 }
204
205
205 void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
206 void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
206 {
207 {
207 m_logBaseX = baseX;
208 m_logBaseX = baseX;
208 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
209 qreal logMinX = log10(m_minX) / log10(m_logBaseX);
209 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
210 qreal logMaxX = log10(m_maxX) / log10(m_logBaseX);
210 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
211 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
211 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
212 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
212 emit updated();
213 emit updated();
213 }
214 }
214
215
215 // operators
216 // operators
216
217
217 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2)
218 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2)
218 {
219 {
219 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX)
220 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX)
220 && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY)
221 && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY)
221 && qFuzzyIsNull(domain1.m_minX - domain2.m_minX)
222 && qFuzzyIsNull(domain1.m_minX - domain2.m_minX)
222 && qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
223 && qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
223 }
224 }
224
225
225
226
226 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2)
227 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2)
227 {
228 {
228 return !(domain1 == domain2);
229 return !(domain1 == domain2);
229 }
230 }
230
231
231
232
232 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain)
233 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain)
233 {
234 {
234 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
235 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
235 return dbg.maybeSpace();
236 return dbg.maybeSpace();
236 }
237 }
237
238
238 #include "moc_logxydomain_p.cpp"
239 #include "moc_logxydomain_p.cpp"
239
240
240 QTCOMMERCIALCHART_END_NAMESPACE
241 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,236 +1,237
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "xlogydomain_p.h"
21 #include "xlogydomain_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "qlogvalueaxis.h"
23 #include "qlogvalueaxis.h"
24 #include <qmath.h>
24 #include <qmath.h>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 XLogYDomain::XLogYDomain(QObject *parent)
28 XLogYDomain::XLogYDomain(QObject *parent)
29 : AbstractDomain(parent),
29 : AbstractDomain(parent),
30 m_logLeftY(0),
30 m_logLeftY(0),
31 m_logRightY(1),
31 m_logRightY(1),
32 m_logBaseY(10)
32 m_logBaseY(10)
33 {
33 {
34 }
34 }
35
35
36 XLogYDomain::~XLogYDomain()
36 XLogYDomain::~XLogYDomain()
37 {
37 {
38 }
38 }
39
39
40 void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
41 {
41 {
42 bool axisXChanged = false;
42 bool axisXChanged = false;
43 bool axisYChanged = false;
43 bool axisYChanged = false;
44
44
45 adjustLogDomainRanges(minY, maxY);
45 adjustLogDomainRanges(minY, maxY);
46
46
47 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
47 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
48 m_minX = minX;
48 m_minX = minX;
49 m_maxX = maxX;
49 m_maxX = maxX;
50 axisXChanged = true;
50 axisXChanged = true;
51 if(!m_signalsBlocked)
51 if(!m_signalsBlocked)
52 emit rangeHorizontalChanged(m_minX, m_maxX);
52 emit rangeHorizontalChanged(m_minX, m_maxX);
53 }
53 }
54
54
55 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
55 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
56 m_minY = minY;
56 m_minY = minY;
57 m_maxY = maxY;
57 m_maxY = maxY;
58 axisYChanged = true;
58 axisYChanged = true;
59 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
59 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
60 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
60 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
61 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
61 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
62 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
62 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
63 if (!m_signalsBlocked)
63 if (!m_signalsBlocked)
64 emit rangeVerticalChanged(m_minY, m_maxY);
64 emit rangeVerticalChanged(m_minY, m_maxY);
65 }
65 }
66
66
67 if (axisXChanged || axisYChanged)
67 if (axisXChanged || axisYChanged)
68 emit updated();
68 emit updated();
69 }
69 }
70
70
71 void XLogYDomain::zoomIn(const QRectF &rect)
71 void XLogYDomain::zoomIn(const QRectF &rect)
72 {
72 {
73 storeZoomReset();
73 storeZoomReset();
74 qreal dx = spanX() / m_size.width();
74 qreal dx = spanX() / m_size.width();
75 qreal maxX = m_maxX;
75 qreal maxX = m_maxX;
76 qreal minX = m_minX;
76 qreal minX = m_minX;
77
77
78 maxX = minX + dx * rect.right();
78 maxX = minX + dx * rect.right();
79 minX = minX + dx * rect.left();
79 minX = minX + dx * rect.left();
80
80
81 qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height();
81 qreal logLeftY = m_logRightY - rect.bottom() * (m_logRightY - m_logLeftY) / m_size.height();
82 qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height();
82 qreal logRightY = m_logRightY - rect.top() * (m_logRightY - m_logLeftY) / m_size.height();
83 qreal leftY = qPow(m_logBaseY, logLeftY);
83 qreal leftY = qPow(m_logBaseY, logLeftY);
84 qreal rightY = qPow(m_logBaseY, logRightY);
84 qreal rightY = qPow(m_logBaseY, logRightY);
85 qreal minY = leftY < rightY ? leftY : rightY;
85 qreal minY = leftY < rightY ? leftY : rightY;
86 qreal maxY = leftY > rightY ? leftY : rightY;
86 qreal maxY = leftY > rightY ? leftY : rightY;
87
87
88 setRange(minX, maxX, minY, maxY);
88 setRange(minX, maxX, minY, maxY);
89 }
89 }
90
90
91 void XLogYDomain::zoomOut(const QRectF &rect)
91 void XLogYDomain::zoomOut(const QRectF &rect)
92 {
92 {
93 storeZoomReset();
93 storeZoomReset();
94 qreal dx = spanX() / rect.width();
94 qreal dx = spanX() / rect.width();
95 qreal maxX = m_maxX;
95 qreal maxX = m_maxX;
96 qreal minX = m_minX;
96 qreal minX = m_minX;
97
97
98 minX = maxX - dx * rect.right();
98 minX = maxX - dx * rect.right();
99 maxX = minX + dx * m_size.width();
99 maxX = minX + dx * m_size.width();
100
100
101 const qreal factorY = m_size.height() / rect.height();
101 const qreal factorY = m_size.height() / rect.height();
102 qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY);
102 qreal newLogMinY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 - factorY);
103 qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY);
103 qreal newLogMaxY = m_logLeftY + (m_logRightY - m_logLeftY) / 2 * (1 + factorY);
104 qreal leftY = qPow(m_logBaseY, newLogMinY);
104 qreal leftY = qPow(m_logBaseY, newLogMinY);
105 qreal rightY = qPow(m_logBaseY, newLogMaxY);
105 qreal rightY = qPow(m_logBaseY, newLogMaxY);
106 qreal minY = leftY < rightY ? leftY : rightY;
106 qreal minY = leftY < rightY ? leftY : rightY;
107 qreal maxY = leftY > rightY ? leftY : rightY;
107 qreal maxY = leftY > rightY ? leftY : rightY;
108
108
109 setRange(minX, maxX, minY, maxY);
109 setRange(minX, maxX, minY, maxY);
110 }
110 }
111
111
112 void XLogYDomain::move(qreal dx, qreal dy)
112 void XLogYDomain::move(qreal dx, qreal dy)
113 {
113 {
114 qreal x = spanX() / m_size.width();
114 qreal x = spanX() / m_size.width();
115 qreal maxX = m_maxX;
115 qreal maxX = m_maxX;
116 qreal minX = m_minX;
116 qreal minX = m_minX;
117
117
118 if (dx != 0) {
118 if (dx != 0) {
119 minX = minX + x * dx;
119 minX = minX + x * dx;
120 maxX = maxX + x * dx;
120 maxX = maxX + x * dx;
121 }
121 }
122
122
123 qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height();
123 qreal stepY = dy * (m_logRightY - m_logLeftY) / m_size.height();
124 qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY);
124 qreal leftY = qPow(m_logBaseY, m_logLeftY + stepY);
125 qreal rightY = qPow(m_logBaseY, m_logRightY + stepY);
125 qreal rightY = qPow(m_logBaseY, m_logRightY + stepY);
126 qreal minY = leftY < rightY ? leftY : rightY;
126 qreal minY = leftY < rightY ? leftY : rightY;
127 qreal maxY = leftY > rightY ? leftY : rightY;
127 qreal maxY = leftY > rightY ? leftY : rightY;
128
128
129 setRange(minX, maxX, minY, maxY);
129 setRange(minX, maxX, minY, maxY);
130 }
130 }
131
131
132 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const
132 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point, bool &ok) const
133 {
133 {
134 if (point.y() > 0) {
134 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
135 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
135 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
136 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
137
136
138 qreal x = (point.x() - m_minX) * deltaX;
137 qreal x = (point.x() - m_minX) * deltaX;
139 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
138 qreal y(0);
139 if (point.y() > 0) {
140 y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
140 ok = true;
141 ok = true;
141 return QPointF(x, y);
142 } else {
142 } else {
143 qWarning() << "Logarithm of negative value is undefined. Empty layout returned.";
143 y = m_size.height();
144 qWarning() << "Logarithms of zero and negative values are undefined.";
144 ok = false;
145 ok = false;
145 return QPointF();
146 }
146 }
147 return QPointF(x, y);
147 }
148 }
148
149
149 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const
150 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF> &vector) const
150 {
151 {
151 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
152 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
152 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
153 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
153
154
154 QVector<QPointF> result;
155 QVector<QPointF> result;
155 result.resize(vector.count());
156 result.resize(vector.count());
156
157
157 for (int i = 0; i < vector.count(); ++i) {
158 for (int i = 0; i < vector.count(); ++i) {
158 if (vector[i].y() > 0) {
159 if (vector[i].y() > 0) {
159 qreal x = (vector[i].x() - m_minX) * deltaX;
160 qreal x = (vector[i].x() - m_minX) * deltaX;
160 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
161 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - m_logLeftY * -deltaY + m_size.height();
161 result[i].setX(x);
162 result[i].setX(x);
162 result[i].setY(y);
163 result[i].setY(y);
163 } else {
164 } else {
164 qWarning() << "Logarithm of negative value is undefined. Empty layout returned.";
165 qWarning() << "Logarithms of zero and negative values are undefined.";
165 return QVector<QPointF>();
166 return QVector<QPointF>();
166 }
167 }
167 }
168 }
168 return result;
169 return result;
169 }
170 }
170
171
171 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
172 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
172 {
173 {
173 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
174 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
174 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
175 const qreal deltaY = m_size.height() / qAbs(m_logRightY - m_logLeftY);
175 qreal x = point.x() / deltaX + m_minX;
176 qreal x = point.x() / deltaX + m_minX;
176 qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY);
177 qreal y = qPow(m_logBaseY, m_logLeftY + (m_size.height() - point.y()) / deltaY);
177 return QPointF(x, y);
178 return QPointF(x, y);
178 }
179 }
179
180
180 bool XLogYDomain::attachAxis(QAbstractAxis *axis)
181 bool XLogYDomain::attachAxis(QAbstractAxis *axis)
181 {
182 {
182 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
183 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
183
184
184 if (logAxis && logAxis->orientation() == Qt::Vertical) {
185 if (logAxis && logAxis->orientation() == Qt::Vertical) {
185 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
186 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
186 handleVerticalAxisBaseChanged(logAxis->base());
187 handleVerticalAxisBaseChanged(logAxis->base());
187 }
188 }
188 return AbstractDomain::attachAxis(axis);
189 return AbstractDomain::attachAxis(axis);
189 }
190 }
190
191
191 bool XLogYDomain::detachAxis(QAbstractAxis *axis)
192 bool XLogYDomain::detachAxis(QAbstractAxis *axis)
192 {
193 {
193 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
194 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
194
195
195 if (logAxis && logAxis->orientation() == Qt::Vertical)
196 if (logAxis && logAxis->orientation() == Qt::Vertical)
196 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
197 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
197
198
198 return AbstractDomain::detachAxis(axis);
199 return AbstractDomain::detachAxis(axis);
199 }
200 }
200
201
201 void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
202 void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
202 {
203 {
203 m_logBaseY = baseY;
204 m_logBaseY = baseY;
204 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
205 qreal logMinY = log10(m_minY) / log10(m_logBaseY);
205 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
206 qreal logMaxY = log10(m_maxY) / log10(m_logBaseY);
206 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
207 m_logLeftY = logMinY < logMaxY ? logMinY : logMaxY;
207 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
208 m_logRightY = logMinY > logMaxY ? logMinY : logMaxY;
208 emit updated();
209 emit updated();
209 }
210 }
210
211
211 // operators
212 // operators
212
213
213 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
214 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &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 QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
223 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
223 {
224 {
224 return !(domain1 == domain2);
225 return !(domain1 == domain2);
225 }
226 }
226
227
227
228
228 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
229 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
229 {
230 {
230 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
231 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
231 return dbg.maybeSpace();
232 return dbg.maybeSpace();
232 }
233 }
233
234
234 #include "moc_xlogydomain_p.cpp"
235 #include "moc_xlogydomain_p.cpp"
235
236
236 QTCOMMERCIALCHART_END_NAMESPACE
237 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now