##// END OF EJS Templates
Bugfixes for layout...
Michal Klocek -
r1837:21f33dedea6d
parent child
Show More
@@ -1,159 +1,161
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartbarcategoryaxisx_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qbarcategoryaxis_p.h"
24 24 #include <QDebug>
25 25 #include <qmath.h>
26 26
27 27 static int label_padding = 5;
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 ChartCategoriesAxisX::ChartCategoriesAxisX(QBarCategoryAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
32 32 m_categoriesAxis(axis)
33 33 {
34 34
35 35 }
36 36
37 37 ChartCategoriesAxisX::~ChartCategoriesAxisX()
38 38 {
39 39 }
40 40
41 41 QVector<qreal> ChartCategoriesAxisX::calculateLayout() const
42 42 {
43 43 int count = m_categoriesAxis->d_ptr->count();
44 44
45 45 Q_ASSERT(count>=1);
46 46
47 47 QVector<qreal> points;
48 48 points.resize(count+2);
49 49
50 50 const qreal delta = m_rect.width()/(count);
51 51 qreal offset =-m_min-0.5;
52 52
53 if(delta<1) return points;
54
53 55 if(offset<=0) {
54 56 offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta) + delta;
55 57 }
56 58 else {
57 59 offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta);
58 60 }
59 61
60 62 points[0] = m_rect.left();
61 63 points[count+1] = m_rect.right();
62 64
63 65 for (int i = 0; i < count; ++i) {
64 66 qreal x = offset + i * delta + m_rect.left();
65 67 points[i+1] = x;
66 68 }
67 69 return points;
68 70 }
69 71
70 72 QStringList ChartCategoriesAxisX::createCategoryLabels(const QVector<qreal>& layout) const
71 73 {
72 74 QStringList result;
73 75 qreal d = (m_max - m_min)/m_rect.width();
74 76 for (int i = 0;i < layout.count()-1; ++i) {
75 77 qreal x = qFloor((((layout[i+1] + layout[i])/2-m_rect.left())*d + m_min+0.5));
76 78 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
77 79 result << m_categoriesAxis->categories().at(x);
78 80 }
79 81 else {
80 82 // No label for x coordinate
81 83 result << "";
82 84 }
83 85 }
84 86 result << "";
85 87 return result;
86 88 }
87 89
88 90
89 91 void ChartCategoriesAxisX::updateGeometry()
90 92 {
91 93 const QVector<qreal>& layout = ChartAxis::layout();
92 94
93 95 m_minWidth = 0;
94 96 m_minHeight = 0;
95 97
96 98 if(layout.isEmpty()) return;
97 99
98 100 QStringList ticksList = createCategoryLabels(layout);
99 101
100 102 QList<QGraphicsItem *> lines = m_grid->childItems();
101 103 QList<QGraphicsItem *> labels = m_labels->childItems();
102 104 QList<QGraphicsItem *> shades = m_shades->childItems();
103 105 QList<QGraphicsItem *> axis = m_arrow->childItems();
104 106
105 107 Q_ASSERT(labels.size() == ticksList.size());
106 108 Q_ASSERT(layout.size() == ticksList.size());
107 109
108 110 const qreal delta = m_rect.width()/(m_categoriesAxis->d_ptr->count());
109 111
110 112 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
111 113 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
112 114
113 115 qreal width = m_rect.left();
114 116 for (int i = 0; i < layout.size(); ++i) {
115 117 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
116 118 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
117 119 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
118 120 labelItem->setText(ticksList.at(i));
119 121 const QRectF& rect = labelItem->boundingRect();
120 122 QPointF center = rect.center();
121 123 labelItem->setTransformOriginPoint(center.x(), center.y());
122 124
123 125 if(i==0){
124 126 labelItem->setPos(layout[i+1] - (delta)/2 - center.x(), m_rect.bottom() + label_padding);
125 127 }else{
126 128 labelItem->setPos(layout[i] + (delta)/2 - center.x(), m_rect.bottom() + label_padding);
127 129 }
128 130
129 131 if(labelItem->pos().x()<=width || labelItem->pos().x()+ rect.width()>m_rect.right()) {
130 132 labelItem->setVisible(false);
131 133 }
132 134 else {
133 135 labelItem->setVisible(true);
134 136 width=rect.width()+labelItem->pos().x();
135 137 }
136 138
137 139 m_minWidth+=rect.width();
138 140 m_minHeight=qMax(rect.height()+label_padding,m_minHeight);
139 141
140 142 if ((i+1)%2 && i>1) {
141 143 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
142 144 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
143 145 }
144 146 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
145 147 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
146 148 }
147 149 }
148 150
149 151 void ChartCategoriesAxisX::handleAxisUpdated()
150 152 {
151 153 if(m_categoriesAxis->categories()!=m_categories)
152 154 {
153 155 m_categories=m_categoriesAxis->categories();
154 156 if(ChartAxis::layout().count()==m_categoriesAxis->d_ptr->count()+2) updateGeometry();
155 157 }
156 158 ChartAxis::handleAxisUpdated();
157 159 }
158 160
159 161 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,160 +1,163
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartbarcategoryaxisy_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qbarcategoryaxis_p.h"
24 24 #include <qmath.h>
25 #include <QDebug>
25 26
26 27 static int label_padding = 5;
27 28
28 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 30
30 31 ChartCategoriesAxisY::ChartCategoriesAxisY(QBarCategoryAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
31 32 m_categoriesAxis(axis)
32 33 {
33 34 }
34 35
35 36 ChartCategoriesAxisY::~ChartCategoriesAxisY()
36 37 {
37 38 }
38 39
39 40 QVector<qreal> ChartCategoriesAxisY::calculateLayout() const
40 41 {
41 42 int count = m_categoriesAxis->d_ptr->count();
42 43
43 44 Q_ASSERT(count>=1);
44 45
45 46 QVector<qreal> points;
46 47 points.resize(count+2);
47 48
48 49 const qreal delta = m_rect.height()/(count);
49 50 qreal offset = - m_min - 0.5;
50 51
52 if(delta<1) return points;
53
51 54 if(offset<=0) {
52 55 offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta) + delta;
53 56 }
54 57 else {
55 58 offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta);
56 59 }
57 60
58 61 points[0] = m_rect.bottom();
59 62 points[count+1] = m_rect.top();
60 63
61 64 for (int i = 0; i < count; ++i) {
62 65 int y = m_rect.bottom() - i * delta - offset;
63 66 points[i+1] = y;
64 67 }
65 68 return points;
66 69 }
67 70
68 71 QStringList ChartCategoriesAxisY::createCategoryLabels(const QVector<qreal>& layout) const
69 72 {
70 73 QStringList result;
71 74 qreal d = (m_max - m_min)/m_rect.height();
72 75 for (int i = 0;i < layout.count()-1; ++i) {
73 76 qreal x = qFloor(((m_rect.height()- (layout[i+1] + layout[i])/2 + m_rect.top())*d + m_min+0.5));
74 77 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
75 78 result << m_categoriesAxis->categories().at(x);
76 79 }
77 80 else {
78 81 // No label for x coordinate
79 82 result << "";
80 83 }
81 84 }
82 85 result << "";
83 86 return result;
84 87 }
85 88
86 89 void ChartCategoriesAxisY::updateGeometry()
87 90 {
88 91 const QVector<qreal>& layout = ChartAxis::layout();
89 92
90 93 m_minWidth = 0;
91 94 m_minHeight = 0;
92 95
93 96 if(layout.isEmpty()) return;
94 97
95 98 QStringList ticksList = createCategoryLabels(layout);
96 99
97 100 QList<QGraphicsItem *> lines = m_grid->childItems();
98 101 QList<QGraphicsItem *> labels = m_labels->childItems();
99 102 QList<QGraphicsItem *> shades = m_shades->childItems();
100 103 QList<QGraphicsItem *> axis = m_arrow->childItems();
101 104
102 105 Q_ASSERT(labels.size() == ticksList.size());
103 106 Q_ASSERT(layout.size() == ticksList.size());
104 107
105 108 const qreal delta = m_rect.height()/(m_categoriesAxis->d_ptr->count());
106 109
107 110 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
108 111 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
109 112
110 113 qreal height = m_rect.bottom();
111 114 for (int i = 0; i < layout.size(); ++i) {
112 115 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
113 116 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
114 117 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
115 118 labelItem->setText(ticksList.at(i));
116 119 const QRectF& rect = labelItem->boundingRect();
117 120 QPointF center = rect.center();
118 121 labelItem->setTransformOriginPoint(center.x(), center.y());
119 122
120 123 if(i==0) {
121 124 labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i+1] + (delta)/2 - center.y());
122 125 }
123 126 else {
124 127 labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i] - (delta)/2 - center.y());
125 128 }
126 129
127 130 if(labelItem->pos().y()+rect.height()>= height || labelItem->pos().y() < m_rect.top()) {
128 131 labelItem->setVisible(false);
129 132 }
130 133 else {
131 134 labelItem->setVisible(true);
132 135 height=labelItem->pos().y();
133 136 }
134 137
135 m_minWidth+=rect.width();
136 m_minHeight=qMax(rect.height()+label_padding,m_minHeight);
138 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
139 m_minHeight+=rect.height();
137 140
138 141 if ((i+1)%2 && i>1) {
139 142 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
140 143 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
141 144 }
142 145 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
143 146 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
144 147 }
145 148 }
146 149
147 150 void ChartCategoriesAxisY::handleAxisUpdated()
148 151 {
149 152
150 153 if(m_categoriesAxis->categories()!=m_categories)
151 154 {
152 155 m_categories=m_categoriesAxis->categories();
153 156 if(ChartAxis::layout().count()==m_categoriesAxis->d_ptr->count()+2) {
154 157 updateGeometry();
155 158 }
156 159 }
157 160 ChartAxis::handleAxisUpdated();
158 161 }
159 162
160 163 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,130 +1,130
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartcategoryaxisx_p.h"
22 22 #include "qcategoryaxis.h"
23 23 #include "qabstractaxis.h"
24 24 #include "chartpresenter_p.h"
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27 #include <qmath.h>
28 28
29 29 static int label_padding = 5;
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 ChartCategoryAxisX::ChartCategoryAxisX(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
34 34 {
35 35 }
36 36
37 37 ChartCategoryAxisX::~ChartCategoryAxisX()
38 38 {
39 39 }
40 40
41 41 QVector<qreal> ChartCategoryAxisX::calculateLayout() const
42 42 {
43 43 QCategoryAxis *axis = qobject_cast<QCategoryAxis *>(m_chartAxis);
44 44 int tickCount = axis->categoriesLabels().count() + 1;
45 45 QVector<qreal> points;
46 46
47 47 if (tickCount < 2)
48 48 return points;
49 49
50 50 points.resize(tickCount);
51 51
52 52 qreal scale = m_rect.width() / axis->max();
53 53 for (int i = 0; i < tickCount; ++i)
54 54 if (i < tickCount - 1) {
55 55 int x = axis->categoryStart(axis->categoriesLabels().at(i)) * scale + m_rect.left();
56 56 points[i] = x;
57 57 } else {
58 58 int x = axis->categoryEnd(axis->categoriesLabels().at(i - 1)) * scale + m_rect.left();
59 59 points[i] = x;
60 60 }
61 61
62 62 return points;
63 63 }
64 64
65 65 void ChartCategoryAxisX::updateGeometry()
66 66 {
67 67 const QVector<qreal>& layout = ChartAxis::layout();
68 68
69 69 m_minWidth = 0;
70 70 m_minHeight = 0;
71 71
72 72 if(layout.isEmpty()) return;
73 73
74 74 QCategoryAxis *intervalAxis = qobject_cast<QCategoryAxis *>(m_chartAxis);
75 75
76 76 QStringList ticksList = intervalAxis->categoriesLabels();
77 77
78 78 // createNumberLabels(ticksList,m_min,m_max,layout.size());
79 79
80 80 QList<QGraphicsItem *> lines = m_grid->childItems();
81 81 QList<QGraphicsItem *> labels = m_labels->childItems();
82 82 QList<QGraphicsItem *> shades = m_shades->childItems();
83 83 QList<QGraphicsItem *> axis = m_arrow->childItems();
84 84
85 85 // Q_ASSERT(labels.size() == ticksList.size());
86 86 // Q_ASSERT(layout.size() == ticksList.size());
87 87
88 88 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
89 89 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
90 90
91 91 // qreal width = 0;
92 92 for (int i = 0; i < layout.size(); ++i) {
93 93 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
94 94 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
95 95 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
96 96 if (i < ticksList.count()) {
97 97 labelItem->setText(ticksList.at(i));
98 98 }
99 99 const QRectF& rect = labelItem->boundingRect();
100 100 QPointF center = rect.center();
101 101 labelItem->setTransformOriginPoint(center.x(), center.y());
102 102 if (i < ticksList.count())
103 103 labelItem->setPos(layout[i] + (layout[i + 1] - layout[i]) / 2 - center.x(), m_rect.bottom() + label_padding);
104 104 else
105 105 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
106 106
107 107 if(labelItem->pos().x() > m_rect.width() + m_rect.left() - rect.width() / 2){
108 108 labelItem->setVisible(false);
109 109 lineItem->setVisible(false);
110 110 }
111 111
112 112 m_minWidth += rect.width();
113 m_minHeight = qMax(rect.height(), m_minHeight);
113 m_minHeight = qMax(rect.height()+ label_padding, m_minHeight);
114 114
115 115 if ((i + 1) % 2 && i > 1) {
116 116 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i / 2 - 1));
117 117 rectItem->setRect(layout[i - 1],m_rect.top(),layout[i]-layout[i - 1],m_rect.height());
118 118 }
119 119 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
120 120 lineItem->setLine(layout[i],m_rect.bottom(),layout[i], m_rect.bottom() + 5);
121 121 }
122 122 }
123 123
124 124 void ChartCategoryAxisX::handleAxisUpdated()
125 125 {
126 126 updateGeometry();
127 127 ChartAxis::handleAxisUpdated();
128 128 }
129 129
130 130 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,137 +1,138
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartcategoryaxisy_p.h"
22 22 #include "qcategoryaxis.h"
23 23 #include "qabstractaxis.h"
24 24 #include "chartpresenter_p.h"
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27 #include <qmath.h>
28 28
29
30 29 static int label_padding = 5;
31 30
32 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 32
34 33 ChartCategoryAxisY::ChartCategoryAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
35 34 {
36 35 }
37 36
38 37 ChartCategoryAxisY::~ChartCategoryAxisY()
39 38 {
40 39 }
41 40
42 41 QVector<qreal> ChartCategoryAxisY::calculateLayout() const
43 42 {
44 43 QCategoryAxis *axis = qobject_cast<QCategoryAxis *>(m_chartAxis);
45 44 int tickCount = axis->categoriesLabels().count() + 1;
46 45 QVector<qreal> points;
47 46
48 47 if (tickCount < 2)
49 48 return points;
50 49
51 50 points.resize(tickCount);
52 51
53 52 qreal scale = m_rect.height() / axis->max();
54 53 for (int i = 0; i < tickCount; ++i)
55 54 if (i < tickCount - 1) {
56 55 int y = -axis->categoryStart(axis->categoriesLabels().at(i)) * scale + m_rect.bottom();
57 56 points[i] = y;
58 57 } else {
59 58 int y = -axis->categoryEnd(axis->categoriesLabels().at(i - 1)) * scale + m_rect.bottom();
60 59 points[i] = y;
61 60 }
62 61
63 62 return points;
64 63 }
65 64
66 65 void ChartCategoryAxisY::updateGeometry()
67 66 {
68 67 const QVector<qreal> &layout = ChartAxis::layout();
69 68 m_minWidth = 0;
70 69 m_minHeight = 0;
71 70
72 if(layout.isEmpty()) return;
71 if(layout.isEmpty()) {
72 return;
73 }
73 74
74 75 QCategoryAxis *intervalAxis = qobject_cast<QCategoryAxis *>(m_chartAxis);
75 76
76 77 QStringList ticksList = intervalAxis->categoriesLabels();
77 78
78 79 QList<QGraphicsItem *> lines = m_grid->childItems();
79 80 QList<QGraphicsItem *> labels = m_labels->childItems();
80 81 QList<QGraphicsItem *> shades = m_shades->childItems();
81 82 QList<QGraphicsItem *> axis = m_arrow->childItems();
82 83
83 84 // Q_ASSERT(labels.size() == ticksList.size());
84 85 // Q_ASSERT(layout.size() == ticksList.size());
85 86
86 87 qreal height = 2*m_rect.bottom();
87 88
88 89 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
89 90 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
90 91
91 92 for (int i = 0; i < layout.size(); ++i) {
92 93 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
93 94 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
94 95 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
95 96
96 97 if (i < ticksList.count()) {
97 98 labelItem->setText(ticksList.at(i));
98 99 }
99 100 const QRectF& rect = labelItem->boundingRect();
100 101
101 102 QPointF center = rect.center();
102 103 labelItem->setTransformOriginPoint(center.x(), center.y());
103 104
104 105 if (i < ticksList.count())
105 106 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] + (layout[i + 1] - layout[i]) / 2 - center.y());
106 107 else
107 108 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
108 109
109 110 if(labelItem->pos().y()+rect.height()>height) {
110 111 labelItem->setVisible(false);
111 112 lineItem->setVisible(false);
112 113 }
113 114 else {
114 115 labelItem->setVisible(true);
115 116 lineItem->setVisible(true);
116 117 height=labelItem->pos().y();
117 118 }
118 119
119 120 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
120 121 m_minHeight+=rect.height();
121 122
122 123 if ((i+1)%2 && i>1) {
123 124 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
124 125 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
125 126 }
126 127 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
127 128 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
128 129 }
129 130 }
130 131
131 132 void ChartCategoryAxisY::handleAxisUpdated()
132 133 {
133 134 updateGeometry();
134 135 ChartAxis::handleAxisUpdated();
135 136 }
136 137
137 138 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,370 +1,371
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "qabstractaxis_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "domain_p.h"
26 26 #include <qmath.h>
27 27 #include <QDateTime>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 ChartAxis::ChartAxis(QAbstractAxis *axis,ChartPresenter *presenter) : ChartElement(presenter),
32 32 m_chartAxis(axis),
33 33 m_labelsAngle(0),
34 34 m_grid(new QGraphicsItemGroup(presenter->rootItem())),
35 35 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
36 36 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
37 37 m_arrow(new QGraphicsItemGroup(presenter->rootItem())),
38 38 m_min(0),
39 39 m_max(0),
40 40 m_animation(0),
41 41 m_minWidth(0),
42 42 m_minHeight(0)
43 43 {
44 44 //initial initialization
45 45 m_arrow->setZValue(ChartPresenter::AxisZValue);
46 46 m_arrow->setHandlesChildEvents(false);
47 47 m_labels->setZValue(ChartPresenter::AxisZValue);
48 48 m_shades->setZValue(ChartPresenter::ShadesZValue);
49 49 m_grid->setZValue(ChartPresenter::GridZValue);
50 50
51 51 QObject::connect(m_chartAxis->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
52 52
53 53 QGraphicsSimpleTextItem item;
54 54 m_font = item.font();
55
55 56 }
56 57
57 58 ChartAxis::~ChartAxis()
58 59 {
59 60 }
60 61
61 62 void ChartAxis::setAnimation(AxisAnimation* animation)
62 63 {
63 64 m_animation=animation;
64 65 }
65 66
66 67 void ChartAxis::setLayout(QVector<qreal> &layout)
67 68 {
68 69 m_layoutVector=layout;
69 70 }
70 71
71 72 void ChartAxis::createItems(int count)
72 73 {
73 74 if (m_arrow->children().size() == 0)
74 75 m_arrow->addToGroup(new AxisItem(this,presenter()->rootItem()));
75 76 for (int i = 0; i < count; ++i) {
76 77 m_grid->addToGroup(new QGraphicsLineItem(presenter()->rootItem()));
77 78 m_labels->addToGroup(new QGraphicsSimpleTextItem(presenter()->rootItem()));
78 79 m_arrow->addToGroup(new QGraphicsLineItem(presenter()->rootItem()));
79 80 if ((m_grid->childItems().size())%2 && m_grid->childItems().size()>2) m_shades->addToGroup(new QGraphicsRectItem(presenter()->rootItem()));
80 81 }
81 82 }
82 83
83 84 void ChartAxis::deleteItems(int count)
84 85 {
85 86 QList<QGraphicsItem *> lines = m_grid->childItems();
86 87 QList<QGraphicsItem *> labels = m_labels->childItems();
87 88 QList<QGraphicsItem *> shades = m_shades->childItems();
88 89 QList<QGraphicsItem *> axis = m_arrow->childItems();
89 90
90 91 for (int i = 0; i < count; ++i) {
91 92 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
92 93 delete(lines.takeLast());
93 94 delete(labels.takeLast());
94 95 delete(axis.takeLast());
95 96 }
96 97 }
97 98
98 99 void ChartAxis::updateLayout(QVector<qreal> &layout)
99 100 {
100 101 int diff = m_layoutVector.size() - layout.size();
101 102
102 103 if (diff>0) {
103 104 deleteItems(diff);
104 105 }
105 106 else if (diff<0) {
106 107 createItems(-diff);
107 108 }
108 109
109 110 if(diff<0) handleAxisUpdated();
110 111
111 112 if (m_animation) {
112 113 switch(presenter()->state()){
113 114 case ChartPresenter::ZoomInState:
114 115 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
115 116 m_animation->setAnimationPoint(presenter()->statePoint());
116 117 break;
117 118 case ChartPresenter::ZoomOutState:
118 119 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
119 120 m_animation->setAnimationPoint(presenter()->statePoint());
120 121 break;
121 122 case ChartPresenter::ScrollUpState:
122 123 case ChartPresenter::ScrollLeftState:
123 124 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
124 125 break;
125 126 case ChartPresenter::ScrollDownState:
126 127 case ChartPresenter::ScrollRightState:
127 128 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
128 129 break;
129 130 case ChartPresenter::ShowState:
130 131 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
131 132 break;
132 133 }
133 134 m_animation->setValues(m_layoutVector,layout);
134 135 presenter()->startAnimation(m_animation);
135 136 }
136 137 else {
137 138 setLayout(layout);
138 139 updateGeometry();
139 140 }
140 141 }
141 142
142 143 void ChartAxis::setArrowOpacity(qreal opacity)
143 144 {
144 145 m_arrow->setOpacity(opacity);
145 146 }
146 147
147 148 qreal ChartAxis::arrowOpacity() const
148 149 {
149 150 return m_arrow->opacity();
150 151 }
151 152
152 153 void ChartAxis::setArrowVisibility(bool visible)
153 154 {
154 155 m_arrow->setOpacity(visible);
155 156 }
156 157
157 158 void ChartAxis::setGridOpacity(qreal opacity)
158 159 {
159 160 m_grid->setOpacity(opacity);
160 161 }
161 162
162 163 qreal ChartAxis::gridOpacity() const
163 164 {
164 165 return m_grid->opacity();
165 166 }
166 167
167 168 void ChartAxis::setGridVisibility(bool visible)
168 169 {
169 170 m_grid->setOpacity(visible);
170 171 }
171 172
172 173 void ChartAxis::setLabelsOpacity(qreal opacity)
173 174 {
174 175 m_labels->setOpacity(opacity);
175 176 }
176 177
177 178 qreal ChartAxis::labelsOpacity() const
178 179 {
179 180 return m_labels->opacity();
180 181 }
181 182
182 183 void ChartAxis::setLabelsVisibility(bool visible)
183 184 {
184 185 m_labels->setOpacity(visible);
185 186 }
186 187
187 188 void ChartAxis::setShadesOpacity(qreal opacity)
188 189 {
189 190 m_shades->setOpacity(opacity);
190 191 }
191 192
192 193 qreal ChartAxis::shadesOpacity() const
193 194 {
194 195 return m_shades->opacity();
195 196 }
196 197
197 198 void ChartAxis::setShadesVisibility(bool visible)
198 199 {
199 200 m_shades->setVisible(visible);
200 201 }
201 202
202 203 void ChartAxis::setLabelsAngle(int angle)
203 204 {
204 205 foreach(QGraphicsItem* item , m_labels->childItems()) {
205 206 item->setRotation(angle);
206 207 }
207 208
208 209 m_labelsAngle=angle;
209 210 }
210 211
211 212 void ChartAxis::setLabelsPen(const QPen &pen)
212 213 {
213 214 foreach(QGraphicsItem* item , m_labels->childItems()) {
214 215 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
215 216 }
216 217 }
217 218
218 219 void ChartAxis::setLabelsBrush(const QBrush &brush)
219 220 {
220 221 foreach(QGraphicsItem* item , m_labels->childItems()) {
221 222 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
222 223 }
223 224 }
224 225
225 226 void ChartAxis::setLabelsFont(const QFont &font)
226 227 {
227 228 foreach(QGraphicsItem* item , m_labels->childItems()) {
228 229 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
229 230 }
230 231 m_font = font;
231 232 }
232 233
233 234 void ChartAxis::setShadesBrush(const QBrush &brush)
234 235 {
235 236 foreach(QGraphicsItem* item , m_shades->childItems()) {
236 237 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
237 238 }
238 239 }
239 240
240 241 void ChartAxis::setShadesPen(const QPen &pen)
241 242 {
242 243 foreach(QGraphicsItem* item , m_shades->childItems()) {
243 244 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
244 245 }
245 246 }
246 247
247 248 void ChartAxis::setArrowPen(const QPen &pen)
248 249 {
249 250 foreach(QGraphicsItem* item , m_arrow->childItems()) {
250 251 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
251 252 }
252 253 }
253 254
254 255 void ChartAxis::setGridPen(const QPen &pen)
255 256 {
256 257 foreach(QGraphicsItem* item , m_grid->childItems()) {
257 258 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
258 259 }
259 260 }
260 261
261 262 bool ChartAxis::isEmpty()
262 263 {
263 264 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max);
264 265 }
265 266
266 267 void ChartAxis::handleDomainUpdated()
267 268 {
268 269 Domain* domain = qobject_cast<Domain*>(sender());
269 270 qreal min(0);
270 271 qreal max(0);
271 272
272 273 if(m_chartAxis->orientation()==Qt::Horizontal) {
273 274 min = domain->minX();
274 275 max = domain->maxX();
275 276 }
276 277 else if (m_chartAxis->orientation()==Qt::Vertical)
277 278 {
278 279 min = domain->minY();
279 280 max = domain->maxY();
280 281 }
281 282
282 283 if (!qFuzzyIsNull(m_min - min) || !qFuzzyIsNull(m_max - max))
283 284 {
284 285 m_min = min;
285 286 m_max = max;
286 287
287 288 if (!isEmpty()) {
288 289 QVector<qreal> layout = calculateLayout();
289 290 updateLayout(layout);
290 291 }
291 292 }
292 293 }
293 294
294 295 void ChartAxis::handleAxisUpdated()
295 296 {
296 297 if(isEmpty()) return;
297 298
298 299
299 300 bool visible = m_chartAxis->isVisible();
300 301
301 302 setArrowVisibility(visible && m_chartAxis->isArrowVisible());
302 303 setGridVisibility(visible && m_chartAxis->isGridLineVisible());
303 304 setLabelsVisibility(visible && m_chartAxis->labelsVisible());
304 305 setShadesVisibility(visible && m_chartAxis->shadesVisible());
305 306 setLabelsAngle(m_chartAxis->labelsAngle());
306 307 setArrowPen(m_chartAxis->axisPen());
307 308 setLabelsPen(m_chartAxis->labelsPen());
308 309 setLabelsBrush(m_chartAxis->labelsBrush());
309 310 setLabelsFont(m_chartAxis->labelsFont());
310 311 setGridPen(m_chartAxis->gridLinePen());
311 312 setShadesPen(m_chartAxis->shadesPen());
312 313 setShadesBrush(m_chartAxis->shadesBrush());
313 314
314 315 }
315 316
316 317 void ChartAxis::hide()
317 318 {
318 319 setArrowVisibility(false);
319 320 setGridVisibility(false);
320 321 setLabelsVisibility(false);
321 322 setShadesVisibility(false);
322 323 }
323 324
324 325 void ChartAxis::handleGeometryChanged(const QRectF &rect)
325 326 {
326 327 if(m_rect != rect)
327 328 {
328 329 m_rect = rect;
329 330 if (isEmpty()) return;
330 331 QVector<qreal> layout = calculateLayout();
331 332 updateLayout(layout);
332 333 }
333 334 }
334 335
335 336
336 337 qreal ChartAxis::minimumWidth()
337 338 {
338 339 if(m_minWidth == 0) updateGeometry();
339 340 return m_minWidth;
340 341 }
341 342
342 343 qreal ChartAxis::minimumHeight()
343 344 {
344 345 if(m_minHeight == 0) updateGeometry();
345 346 return m_minHeight;
346 347 }
347 348
348 349
349 350 void ChartAxis::axisSelected()
350 351 {
351 352 qDebug()<<"TODO: axis clicked";
352 353 }
353 354
354 355
355 356 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int ticks) const
356 357 {
357 358 Q_ASSERT(max>min);
358 359 Q_ASSERT(ticks>1);
359 360
360 361 int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0);
361 362 n++;
362 363 for (int i=0; i< ticks; i++) {
363 364 qreal value = min + (i * (max - min)/ (ticks-1));
364 365 labels << QString::number(value,'f',n);
365 366 }
366 367 }
367 368
368 369 #include "moc_chartaxis_p.cpp"
369 370
370 371 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,166 +1,174
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartlayout_p.h"
22 22 #include "chartpresenter_p.h"
23 #include "qlegend_p.h"
23 24 #include "chartaxis_p.h"
24 #include <QDebug>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 ChartLayout::ChartLayout(ChartPresenter* presenter):
29 29 m_presenter(presenter),
30 30 m_marginBig(60),
31 31 m_marginSmall(20),
32 32 m_marginTiny(10),
33 m_chartMargins(QPointF(m_marginBig,m_marginBig),QPointF(m_marginBig,m_marginBig))
33 m_chartMargins(QPointF(m_marginBig,m_marginBig),QPointF(m_marginBig,m_marginBig)),
34 m_intialized(false)
34 35 {
35 36
36 37 }
37 38
38 39 ChartLayout::~ChartLayout()
39 40 {
40 41
41 42 }
42 43
43 44 void ChartLayout::setGeometry(const QRectF& rect)
44 45 {
45 46
46 47 if (!rect.isValid()) return;
47 48
48 49 QGraphicsLayout::setGeometry(rect);
49 50
51 if(!m_intialized){
52 m_presenter->setGeometry(rect);
53 m_intialized=true;
54 }
55
50 56 // check title size
51 57
52 58 QSize titleSize = QSize(0,0);
53 59
54 60 if (m_presenter->titleItem()) {
55 61 titleSize= m_presenter->titleItem()->boundingRect().size().toSize();
56 62 }
57 63
58 64 qreal axisHeight = 0;
59 65 qreal axisWidth = 0;
60 66
61 67 // check axis size
62 68
63 69 foreach (ChartAxis* axis,m_presenter->axisItems()){
64 70 if(axis->axisType() == ChartAxis::X_AXIS)
65 71 axisHeight = qMax(axis->minimumHeight(),axisHeight);
66 72 else
67 73 axisWidth = qMax(axis->minimumWidth(),axisWidth);
68 74 }
69 75
70 76 QLegend* legend = m_presenter->legend();
71 77
78 Q_ASSERT(legend);
79
72 80 qreal titlePadding = m_chartMargins.top()/2;
73 81
74 82 QRectF chartMargins = m_chartMargins;
75 83
76 84 // recalculate legend position
77 if (legend != 0 && legend->isVisible() && legend->isAttachedToChart()) {
85 if ((legend->isAttachedToChart() && legend->isVisible())) {
78 86
79 87 // Reserve some space for legend
80 88 switch (legend->alignment()) {
81 89
82 90 case Qt::AlignTop: {
83 91 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
84 92 int topMargin = 2*m_marginTiny + titleSize.height() + legendSize.height() + m_marginTiny;
85 93 chartMargins = QRect(QPoint(m_chartMargins.left(),topMargin),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
86 94 m_legendMargins = QRect(QPoint(chartMargins.left(),topMargin - (legendSize.height() + m_marginTiny)),QPoint(chartMargins.right(),rect.height()-topMargin + m_marginTiny));
87 95 titlePadding = m_marginTiny + m_marginTiny;
88 96 break;
89 97 }
90 98 case Qt::AlignBottom: {
91 99 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
92 int bottomMargin = m_marginTiny + m_marginSmall + legendSize.height() + m_marginTiny + axisHeight;
100 int bottomMargin = m_marginTiny + legendSize.height() + m_marginTiny + axisHeight;
93 101 chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomMargin));
94 102 m_legendMargins = QRect(QPoint(chartMargins.left(),rect.height()-bottomMargin + m_marginTiny + axisHeight),QPoint(chartMargins.right(),m_marginTiny + m_marginSmall));
95 103 titlePadding = chartMargins.top()/2;
96 104 break;
97 105 }
98 106 case Qt::AlignLeft: {
99 107 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
100 int leftPadding = m_marginTiny + m_marginSmall + legendSize.width() + m_marginTiny + axisWidth;
108 int leftPadding = m_marginTiny + legendSize.width() + m_marginTiny + axisWidth;
109
101 110 chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
102 111 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,chartMargins.top()),QPoint(rect.width()-leftPadding + m_marginTiny + axisWidth,chartMargins.bottom()));
103 112 titlePadding = chartMargins.top()/2;
104 113 break;
105 114 }
106 115 case Qt::AlignRight: {
107 116 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
108 int rightPadding = m_marginTiny + m_marginSmall + legendSize.width() + m_marginTiny;
117 int rightPadding = m_marginTiny + legendSize.width() + m_marginTiny;
109 118 chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
110 119 m_legendMargins = QRect(QPoint(rect.width()- rightPadding+ m_marginTiny ,chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,chartMargins.bottom()));
111 120 titlePadding = chartMargins.top()/2;
112 121 break;
113 122 }
114 123 default: {
115 124 break;
116 125 }
117 126 }
118 127
119 128 legend->setGeometry(rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
120 129 }
121 130
122 131 // recalculate title position
123 132 if (m_presenter->titleItem()) {
124 133 QPointF center = rect.center() - m_presenter->titleItem()->boundingRect().center();
125 134 m_presenter->titleItem()->setPos(center.x(),titlePadding);
126 135 }
127 136
128 137 //recalculate background gradient
129 138 if (m_presenter->backgroundItem()) {
130 139 m_presenter->backgroundItem()->setRect(rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
131 140 }
132 141
133 142 QRectF chartRect = rect.adjusted(chartMargins.left(),chartMargins.top(),-chartMargins.right(),-chartMargins.bottom());
134 143
135 144 if(m_presenter->geometry()!=chartRect && chartRect.isValid()){
136 145 m_presenter->setGeometry(chartRect);
137 146 }else if(chartRect.size().isEmpty()){
138 147 m_presenter->setGeometry(QRect(rect.width()/2,rect.height()/2,1,1));
139 148 }
140
141 149 }
142 150
143 151
144 152 QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
145 153 {
146 154 Q_UNUSED(constraint);
147 155 if(which == Qt::MinimumSize)
148 156 return QSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
149 157 else
150 158 return QSize(-1,-1);
151 159 }
152 160
153 161 void ChartLayout::setMarginsMinimum(const QRectF& margins)
154 162 {
155 163 if(m_chartMargins != margins){
156 164 m_chartMargins = margins;
157 165 updateGeometry();
158 166 }
159 167 }
160 168
161 169 QRectF ChartLayout::margins() const
162 170 {
163 171 return m_chartMargins;
164 172 }
165 173
166 174 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,63 +1,62
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef CHARTLAYOUT_H_
22 22 #define CHARTLAYOUT_H_
23 23 #include <QGraphicsLayout>
24 24 #include "qchartglobal.h"
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 class ChartPresenter;
29 29
30 30 class ChartLayout : public QGraphicsLayout
31 31 {
32 32 public:
33 33
34 34 ChartLayout(ChartPresenter* presenter);
35 35 virtual ~ChartLayout();
36 36
37 37 void setMarginsMinimum(const QRectF& margins);
38 38 QRectF margins() const;
39 39
40 40 void setGeometry(const QRectF& rect);
41 41
42 42 protected:
43 43 QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
44 44 int count() const { return 0; }
45 45 QGraphicsLayoutItem* itemAt(int) const { return 0; };
46 46 void removeAt(int){};
47 47
48 48 private:
49 49 ChartPresenter* m_presenter;
50 50 int m_marginBig;
51 51 int m_marginSmall;
52 52 int m_marginTiny;
53
54 53 QRectF m_chartMargins;
55 54 QRectF m_legendMargins;
56
55 bool m_intialized;
57 56
58 57
59 58 };
60 59
61 60 QTCOMMERCIALCHART_END_NAMESPACE
62 61
63 62 #endif
@@ -1,380 +1,381
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "legendlayout_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "legendmarker_p.h"
24 24 #include "qlegend_p.h"
25 #include <QDebug>
26 25
27 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 27
29 28 LegendLayout::LegendLayout(QLegend* legend):
30 29 m_legend(legend)
31 30 {
32 31
33 32 }
34 33
35 34 LegendLayout::~LegendLayout()
36 35 {
37 36
38 37 }
39 38
40 39 void LegendLayout::setOffset(qreal x, qreal y)
41 40 {
42 41 bool scrollHorizontal = true;
43 42 switch(m_legend->alignment()) {
44 43 case Qt::AlignTop:
45 44 case Qt::AlignBottom: {
46 45 scrollHorizontal = true;
47 46 break;
48 47 }
49 48 case Qt::AlignLeft:
50 49 case Qt::AlignRight: {
51 50 scrollHorizontal = false;
52 51 break;
53 52 }
54 53 }
55 54
56 55 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
57 56 if (!m_legend->isAttachedToChart()) {
58 57 scrollHorizontal = !scrollHorizontal;
59 58 }
60 59
61 60 QRectF boundingRect = geometry();
62 61
63 62 // Limit offset between m_minOffset and m_maxOffset
64 63 if (scrollHorizontal) {
65 64 if(m_width<=boundingRect.width()) return;
66 65
67 66 if (x != m_offsetX) {
68 67 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
69 68 m_legend->d_ptr->items()->setPos(-m_offsetX,boundingRect.top());
70 69 }
71 70 }
72 71 else {
73 72 if(m_height<=boundingRect.height()) return;
74 73
75 74 if (y != m_offsetY) {
76 75 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
77 76 m_legend->d_ptr->items()->setPos(boundingRect.left(),-m_offsetY);
78 77 }
79 78 }
80 79 }
81 80
82 81 QPointF LegendLayout::offset() const
83 82 {
84 83 return QPointF(m_offsetX,m_offsetY);
85 84 }
86 85
87 86 void LegendLayout::setGeometry(const QRectF& rect)
88 87 {
89
90 QGraphicsLayout::setGeometry(rect);
88 m_legend->d_ptr->items()->setVisible(m_legend->isVisible());
91 89
92 90 if(m_legend->isAttachedToChart()) {
91
93 92 setAttachedGeometry(rect);
94 93 }
95 94 else {
96 95 setDettachedGeometry(rect);
97 96 }
97
98 QGraphicsLayout::setGeometry(rect);
98 99 }
99 100
100 101 void LegendLayout::setAttachedGeometry(const QRectF& rect)
101 102 {
102 103 if (!rect.isValid()) return;
103 104
104 105 m_offsetX=0;
105 106 m_offsetY=0;
106 107
107 108 QSizeF size(0,0);
108 109
109 110 if( m_legend->d_ptr->markers().isEmpty()) return;
110 111
111 112 m_width=0;
112 113 m_height=0;
113 114
114 115 switch(m_legend->alignment()) {
115 116
116 117 case Qt::AlignTop:
117 118
118 119 case Qt::AlignBottom: {
119 120 QPointF point(0,0);
120 121 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
121 122 if (marker->isVisible()) {
122 123 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
123 124 marker->setPos(point.x(),rect.height()/2 - marker->boundingRect().height()/2);
124 125 const QRectF& rect = marker->boundingRect();
125 126 size = size.expandedTo(rect.size());
126 127 qreal w = rect.width();
127 128 m_width+=w;
128 129 point.setX(point.x() + w);
129 130 }
130 131 }
131 132 if(m_width<rect.width()) {
132 133 m_legend->d_ptr->items()->setPos(rect.width()/2-m_width/2,rect.top());
133 134
134 135 }
135 136 else {
136 137 m_legend->d_ptr->items()->setPos(rect.topLeft());
137 138 }
138 139 m_height=size.height();
139 140 }
140 141 break;
141 142 case Qt::AlignLeft:
142 143 case Qt::AlignRight: {
143 144 QPointF point(0,0);
144 145 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
145 146 if (marker->isVisible()) {
146 147 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
147 148 marker->setPos(point);
148 149 const QRectF& rect = marker->boundingRect();
149 150 qreal h = rect.height();
150 151 size = size.expandedTo(rect.size());
151 152 m_height+=h;
152 153 point.setY(point.y() + h);
153 154 }
154 155 }
155 156 if(m_height<rect.height()) {
156 157 m_legend->d_ptr->items()->setPos(rect.left(),rect.height()/2-m_height/2);
157 158 }
158 159 else {
159 160 m_legend->d_ptr->items()->setPos(rect.topLeft());
160 161 }
161 162 m_width=size.width();
162 163 }
163 164 break;
164 165 }
165 166
166 167 m_minOffsetX = 0;
167 168 m_minOffsetY = 0;
168 169 m_maxOffsetX = m_width - rect.width();
169 170 m_maxOffsetY = m_height - rect.height();
170 171 }
171 172
172 173 void LegendLayout::setDettachedGeometry(const QRectF& rect)
173 174 {
174 175 if (!rect.isValid()) return;
175 176
176 177 // Detached layout is different.
177 178 // In detached mode legend may have multiple rows and columns, so layout calculations
178 179 // differ a log from attached mode.
179 180 // Also the scrolling logic is bit different.
180 181
181 182 m_offsetX=0;
182 183 m_offsetY=0;
183 184
184 185 QSizeF size(0,0);
185 186
186 187 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
187 188
188 189 if(markers.isEmpty()) return;
189 190
190 191 switch (m_legend->alignment()) {
191 192 case Qt::AlignTop: {
192 193 QPointF point = rect.topLeft();
193 194 m_width = 0;
194 195 m_height = 0;
195 196 for (int i=0; i<markers.count(); i++) {
196 197 LegendMarker *marker = markers.at(i);
197 198 if (marker->isVisible()) {
198 199 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
199 200 marker->setPos(point.x(),point.y());
200 201 const QRectF& boundingRect = marker->boundingRect();
201 202 qreal w = boundingRect.width();
202 203 qreal h = boundingRect.height();
203 204 m_width = qMax(m_width,w);
204 205 m_height = qMax(m_height,h);
205 206 point.setX(point.x() + w);
206 207 if (point.x() + w > rect.topLeft().x() + rect.width()) {
207 208 // Next item would go off rect.
208 209 point.setX(rect.topLeft().x());
209 210 point.setY(point.y() + h);
210 211 if (i+1 < markers.count()) {
211 212 m_height += h;
212 213 }
213 214 }
214 215 }
215 216 }
216 217 m_legend->d_ptr->items()->setPos(rect.topLeft());
217 218
218 219 m_minOffsetX = 0;
219 220 m_minOffsetY = 0;
220 221 m_maxOffsetX = m_width - rect.width();
221 222 m_maxOffsetY = m_height - rect.height();
222 223 }
223 224 break;
224 225 case Qt::AlignBottom: {
225 226 QPointF point = rect.bottomLeft();
226 227 m_width = 0;
227 228 m_height = 0;
228 229 for (int i=0; i<markers.count(); i++) {
229 230 LegendMarker *marker = markers.at(i);
230 231 if (marker->isVisible()) {
231 232 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
232 233 const QRectF& boundingRect = marker->boundingRect();
233 234 qreal w = boundingRect.width();
234 235 qreal h = boundingRect.height();
235 236 m_width = qMax(m_width,w);
236 237 m_height = qMax(m_height,h);
237 238 marker->setPos(point.x(),point.y() - h);
238 239 point.setX(point.x() + w);
239 240 if (point.x() + w > rect.bottomLeft().x() + rect.width()) {
240 241 // Next item would go off rect.
241 242 point.setX(rect.bottomLeft().x());
242 243 point.setY(point.y() - h);
243 244 if (i+1 < markers.count()) {
244 245 m_height += h;
245 246 }
246 247 }
247 248 }
248 249 }
249 250 m_legend->d_ptr->items()->setPos(rect.topLeft());
250 251
251 252 m_minOffsetX = 0;
252 253 m_minOffsetY = qMin(rect.topLeft().y(), rect.topLeft().y() - m_height + rect.height());
253 254 m_maxOffsetX = m_width - rect.width();
254 255 m_maxOffsetY = 0;
255 256 }
256 257 break;
257 258 case Qt::AlignLeft: {
258 259 QPointF point = rect.topLeft();
259 260 m_width = 0;
260 261 m_height = 0;
261 262 qreal maxWidth = 0;
262 263 for (int i=0; i<markers.count(); i++) {
263 264 LegendMarker *marker = markers.at(i);
264 265 if (marker->isVisible()) {
265 266 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
266 267 const QRectF& boundingRect = marker->boundingRect();
267 268 qreal w = boundingRect.width();
268 269 qreal h = boundingRect.height();
269 270 m_height = qMax(m_height,h);
270 271 maxWidth = qMax(maxWidth,w);
271 272 marker->setPos(point.x(),point.y());
272 273 point.setY(point.y() + h);
273 274 if (point.y() + h > rect.topLeft().y() + rect.height()) {
274 275 // Next item would go off rect.
275 276 point.setX(point.x() + maxWidth);
276 277 point.setY(rect.topLeft().y());
277 278 if (i+1 < markers.count()) {
278 279 m_width += maxWidth;
279 280 maxWidth = 0;
280 281 }
281 282 }
282 283 }
283 284 }
284 285 m_width += maxWidth;
285 286 m_legend->d_ptr->items()->setPos(rect.topLeft());
286 287
287 288 m_minOffsetX = 0;
288 289 m_minOffsetY = 0;
289 290 m_maxOffsetX = m_width - rect.width();
290 291 m_maxOffsetY = m_height - rect.height();
291 292 }
292 293 break;
293 294 case Qt::AlignRight: {
294 295 QPointF point = rect.topRight();
295 296 m_width = 0;
296 297 m_height = 0;
297 298 qreal maxWidth = 0;
298 299 for (int i=0; i<markers.count(); i++) {
299 300 LegendMarker *marker = markers.at(i);
300 301 if (marker->isVisible()) {
301 302 marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
302 303 const QRectF& boundingRect = marker->boundingRect();
303 304 qreal w = boundingRect.width();
304 305 qreal h = boundingRect.height();
305 306 m_height = qMax(m_height,h);
306 307 maxWidth = qMax(maxWidth,w);
307 308 marker->setPos(point.x() - w,point.y());
308 309 point.setY(point.y() + h);
309 310 if (point.y() + h > rect.topLeft().y() + rect.height()) {
310 311 // Next item would go off rect.
311 312 point.setX(point.x() - maxWidth);
312 313 point.setY(rect.topLeft().y());
313 314 if (i+1 < markers.count()) {
314 315 m_width += maxWidth;
315 316 maxWidth = 0;
316 317 }
317 318 }
318 319 }
319 320 }
320 321 m_width += maxWidth;
321 322 m_legend->d_ptr->items()->setPos(rect.topLeft());
322 323
323 324 m_minOffsetX = qMin(rect.topLeft().x(), rect.topLeft().x() - m_width + rect.width());
324 325 m_minOffsetY = 0;
325 326 m_maxOffsetX = 0;
326 327 m_maxOffsetY = m_height - rect.height();
327 328 }
328 329 break;
329 330 default:
330 331 break;
331 332 }
332 333
333 334 }
334 335
335 336 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
336 337 {
337 338 QSizeF size(0, 0);
338 339 qreal left, top, right, bottom;
339 340 getContentsMargins(&left, &top, &right, &bottom);
340 341
341 342 if(which!=Qt::PreferredSize) return QSizeF(-1,-1);
342 343
343 344 if(constraint.isValid()) {
344 345 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
345 346 size = size.expandedTo(marker->effectiveSizeHint(which));
346 347 }
347 348 size = size.boundedTo(constraint);
348 349 }
349 350 else if (constraint.width() >= 0) {
350 351 qreal width = 0;
351 352 qreal height = 0;
352 353 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
353 354 width+=marker->effectiveSizeHint(which).width();
354 355 height=qMax(height,marker->effectiveSizeHint(which).height());
355 356 }
356 357
357 358 size = QSizeF(qMin(constraint.width(),width), height);
358 359 }
359 360 else if (constraint.height() >= 0) {
360 361 qreal width = 0;
361 362 qreal height = 0;
362 363 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
363 364 width=qMax(width,marker->effectiveSizeHint(which).width());
364 365 height+=height,marker->effectiveSizeHint(which).height();
365 366 }
366 367 size = QSizeF(width,qMin(constraint.height(),height));
367 368 }
368 369 else {
369 370 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
370 371 size = size.expandedTo(marker->effectiveSizeHint(which));
371 372 }
372 373 }
373 374 size += QSize(left + right, top + bottom);
374 375
375 376 return size;
376 377
377 378
378 379 }
379 380
380 381 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,537 +1,537
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qlegend.h"
22 22 #include "qlegend_p.h"
23 23 #include "qabstractseries.h"
24 24 #include "qabstractseries_p.h"
25 25 #include "qchart_p.h"
26 26 #include "legendlayout_p.h"
27 27 #include "legendmarker_p.h"
28 28 #include "qxyseries.h"
29 29 #include "qlineseries.h"
30 30 #include "qareaseries.h"
31 31 #include "qscatterseries.h"
32 32 #include "qsplineseries.h"
33 33 #include "qabstractbarseries.h"
34 34 #include "qstackedbarseries.h"
35 35 #include "qpercentbarseries.h"
36 36 #include "qbarset.h"
37 37 #include "qpieseries.h"
38 38 #include "qpieseries_p.h"
39 39 #include "qpieslice.h"
40 40 #include "chartpresenter_p.h"
41 41 #include <QPainter>
42 42 #include <QPen>
43 43 #include <QTimer>
44 44 #include <QGraphicsLayout>
45 45 #include <QGraphicsSceneEvent>
46 46
47 47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48 48
49 49 /*!
50 50 \class QLegend
51 51 \brief Legend object
52 52 \mainclass
53 53
54 54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
55 55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
56 56 handle the drawing manually.
57 57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
58 58
59 59 \image examples_percentbarchart_legend.png
60 60
61 61 \sa QChart
62 62 */
63 63 /*!
64 64 \qmlclass Legend QLegend
65 65 \brief Legend is part of QtCommercial Chart QML API.
66 66
67 67 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
68 68 series have been changed. Legend is used via ChartView class. For example:
69 69 \code
70 70 ChartView {
71 71 legend.visible: true
72 72 legend.alignment: Qt.AlignBottom
73 73 // Add a few series...
74 74 }
75 75 \endcode
76 76
77 77 \image examples_percentbarchart_legend.png
78 78 */
79 79
80 80 /*!
81 81 \property QLegend::alignment
82 82 \brief The alignment of the legend.
83 83
84 84 Legend paints on the defined position in the chart. The following alignments are supported:
85 85 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
86 86 */
87 87 /*!
88 88 \qmlproperty Qt.Alignment Legend::alignment
89 89 \brief The alignment of the legend.
90 90
91 91 Legend paints on the defined position in the chart. The following alignments are supported:
92 92 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
93 93 */
94 94
95 95 /*!
96 96 \property QLegend::backgroundVisible
97 97 Whether the legend background is visible or not.
98 98 */
99 99 /*!
100 100 \qmlproperty bool Legend::backgroundVisible
101 101 Whether the legend background is visible or not.
102 102 */
103 103
104 104 /*!
105 105 \property QLegend::color
106 106 The color of the legend, i.e. the background (brush) color. Note that if you change the color
107 107 of the legend, the style of the legend brush is set to Qt::SolidPattern.
108 108 */
109 109 /*!
110 110 \qmlproperty color Legend::color
111 111 The color of the legend, i.e. the background (brush) color.
112 112 */
113 113
114 114 /*!
115 115 \property QLegend::borderColor
116 116 The border color of the legend, i.e. the line color.
117 117 */
118 118 /*!
119 119 \qmlproperty color Legend::borderColor
120 120 The border color of the legend, i.e. the line color.
121 121 */
122 122
123 123 /*!
124 124 \property QLegend::font
125 125 The font of markers used by legend
126 126 */
127 127 /*!
128 128 \qmlproperty color Legend::font
129 129 The font of markers used by legend
130 130 */
131 131
132 132 /*!
133 133 \property QLegend::labelColor
134 134 The color of brush used to draw labels.
135 135 */
136 136 /*!
137 137 \qmlproperty color QLegend::labelColor
138 138 The color of brush used to draw labels.
139 139 */
140 140
141 141 /*!
142 142 \fn void QLegend::backgroundVisibleChanged(bool)
143 143 The visibility of the legend background changed to \a visible.
144 144 */
145 145
146 146 /*!
147 147 \fn void QLegend::colorChanged(QColor)
148 148 The color of the legend background changed to \a color.
149 149 */
150 150
151 151 /*!
152 152 \fn void QLegend::borderColorChanged(QColor)
153 153 The border color of the legend background changed to \a color.
154 154 */
155 155
156 156 /*!
157 157 \fn void QLegend::fontChanged(QFont)
158 158 The font of markers of the legend changed to \a font.
159 159 */
160 160
161 161 /*!
162 162 \fn void QLegend::labelColorChanged(QColor color)
163 163 This signal is emitted when the color of brush used to draw labels has changed to \a color.
164 164 */
165 165
166 166 /*!
167 167 Constructs the legend object and sets the parent to \a parent
168 168 */
169 169
170 170 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
171 171 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
172 172 {
173 173 setZValue(ChartPresenter::LegendZValue);
174 174 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
175 175 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
176 176 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
177 177 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
178 178 setLayout(d_ptr->m_layout);
179 179 }
180 180
181 181 /*!
182 182 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
183 183 */
184 184 QLegend::~QLegend()
185 185 {
186 186 }
187 187
188 188 /*!
189 189 \internal
190 190 */
191 191 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
192 192 {
193 193 Q_UNUSED(option)
194 194 Q_UNUSED(widget)
195 195 if(!d_ptr->m_backgroundVisible) return;
196 196
197 197 painter->setOpacity(opacity());
198 198 painter->setPen(d_ptr->m_pen);
199 199 painter->setBrush(d_ptr->m_brush);
200 200 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
201 201
202 202 }
203 203
204 204
205 205 /*!
206 206 Sets the \a brush of legend. Brush affects the background of legend.
207 207 */
208 208 void QLegend::setBrush(const QBrush &brush)
209 209 {
210 210 if (d_ptr->m_brush != brush) {
211 211 d_ptr->m_brush = brush;
212 212 update();
213 213 emit colorChanged(brush.color());
214 214 }
215 215 }
216 216
217 217 /*!
218 218 Returns the brush used by legend.
219 219 */
220 220 QBrush QLegend::brush() const
221 221 {
222 222 return d_ptr->m_brush;
223 223 }
224 224
225 225 void QLegend::setColor(QColor color)
226 226 {
227 227 QBrush b = d_ptr->m_brush;
228 228 if (b.style() != Qt::SolidPattern || b.color() != color) {
229 229 b.setStyle(Qt::SolidPattern);
230 230 b.setColor(color);
231 231 setBrush(b);
232 232 }
233 233 }
234 234
235 235 QColor QLegend::color()
236 236 {
237 237 return d_ptr->m_brush.color();
238 238 }
239 239
240 240 /*!
241 241 Sets the \a pen of legend. Pen affects the legend borders.
242 242 */
243 243 void QLegend::setPen(const QPen &pen)
244 244 {
245 245 if (d_ptr->m_pen != pen) {
246 246 d_ptr->m_pen = pen;
247 247 update();
248 248 emit borderColorChanged(pen.color());
249 249 }
250 250 }
251 251
252 252 /*!
253 253 Returns the pen used by legend
254 254 */
255 255
256 256 QPen QLegend::pen() const
257 257 {
258 258 return d_ptr->m_pen;
259 259 }
260 260
261 261 void QLegend::setFont(const QFont &font)
262 262 {
263 263 if (d_ptr->m_font != font) {
264 264 d_ptr->m_font = font;
265 265
266 266 foreach (LegendMarker *marker, d_ptr->markers()) {
267 267 marker->setFont(d_ptr->m_font);
268 268 }
269 269 layout()->invalidate();
270 270 emit fontChanged(font);
271 271 }
272 272 }
273 273
274 274 QFont QLegend::font() const
275 275 {
276 276 return d_ptr->m_font;
277 277 }
278 278
279 279 void QLegend::setBorderColor(QColor color)
280 280 {
281 281 QPen p = d_ptr->m_pen;
282 282 if (p.color() != color) {
283 283 p.setColor(color);
284 284 setPen(p);
285 285 }
286 286 }
287 287
288 288 QColor QLegend::borderColor()
289 289 {
290 290 return d_ptr->m_pen.color();
291 291 }
292 292
293 293 /*!
294 294 Set brush used to draw labels to \a brush.
295 295 */
296 296 void QLegend::setLabelBrush(const QBrush &brush)
297 297 {
298 298 if (d_ptr->m_labelBrush != brush) {
299 299 d_ptr->m_labelBrush = brush;
300 300 foreach (LegendMarker *marker, d_ptr->markers()) {
301 301 marker->setLabelBrush(d_ptr->m_labelBrush);
302 302 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
303 303 // instead of mapping it from label brush color
304 304 marker->setPen(brush.color());
305 305 }
306 306 emit labelColorChanged(brush.color());
307 307 }
308 308 }
309 309
310 310 /*!
311 311 Brush used to draw labels.
312 312 */
313 313 QBrush QLegend::labelBrush() const
314 314 {
315 315 return d_ptr->m_labelBrush;
316 316 }
317 317
318 318 void QLegend::setLabelColor(QColor color)
319 319 {
320 320 QBrush b = d_ptr->m_labelBrush;
321 321 if (b.style() != Qt::SolidPattern || b.color() != color) {
322 322 b.setStyle(Qt::SolidPattern);
323 323 b.setColor(color);
324 324 setLabelBrush(b);
325 325 }
326 326 }
327 327
328 328 QColor QLegend::labelColor() const
329 329 {
330 330 return d_ptr->m_labelBrush.color();
331 331 }
332 332
333 333
334 334 void QLegend::setAlignment(Qt::Alignment alignment)
335 335 {
336 336 if(d_ptr->m_alignment!=alignment) {
337 337 d_ptr->m_alignment = alignment;
338 338 updateGeometry();
339 339 if(isAttachedToChart()){
340 340 d_ptr->m_presenter->layout()->invalidate();
341 341 }else{
342 342 layout()->invalidate();
343 343 }
344 344 }
345 345 }
346 346
347 347 Qt::Alignment QLegend::alignment() const
348 348 {
349 349 return d_ptr->m_alignment;
350 350 }
351 351
352 352 /*!
353 353 Detaches the legend from chart. Chart won't change layout of the legend.
354 354 */
355 355 void QLegend::detachFromChart()
356 356 {
357 357 d_ptr->m_attachedToChart = false;
358 358 d_ptr->m_layout->invalidate();
359 359 setParent(0);
360 360
361 361 }
362 362
363 363 /*!
364 364 Attaches the legend to chart. Chart may change layout of the legend.
365 365 */
366 366 void QLegend::attachToChart()
367 367 {
368 368 d_ptr->m_attachedToChart = true;
369 369 d_ptr->m_layout->invalidate();
370 370 setParent(d_ptr->m_chart);
371 371 }
372 372
373 373 /*!
374 374 Returns true, if legend is attached to chart.
375 375 */
376 376 bool QLegend::isAttachedToChart()
377 377 {
378 378 return d_ptr->m_attachedToChart;
379 379 }
380 380
381 381 /*!
382 382 Sets the visibility of legend background to \a visible
383 383 */
384 384 void QLegend::setBackgroundVisible(bool visible)
385 385 {
386 386 if(d_ptr->m_backgroundVisible != visible) {
387 387 d_ptr->m_backgroundVisible = visible;
388 388 update();
389 389 emit backgroundVisibleChanged(visible);
390 390 }
391 391 }
392 392
393 393 /*!
394 394 Returns the visibility of legend background
395 395 */
396 396 bool QLegend::isBackgroundVisible() const
397 397 {
398 398 return d_ptr->m_backgroundVisible;
399 399 }
400 400
401 401 /*!
402 402 \internal \a event see QGraphicsWidget for details
403 403 */
404 404 void QLegend::hideEvent(QHideEvent *event)
405 405 {
406 QGraphicsWidget::hideEvent(event);
407 d_ptr->m_presenter->layout()->invalidate();
406 d_ptr->m_presenter->layout()->invalidate();
407 QGraphicsWidget::hideEvent(event);
408 408 }
409 409
410 410 /*!
411 411 \internal \a event see QGraphicsWidget for details
412 412 */
413 413 void QLegend::showEvent(QShowEvent *event)
414 414 {
415 QGraphicsWidget::showEvent(event);
416 d_ptr->m_presenter->layout()->invalidate();
415 d_ptr->m_presenter->layout()->invalidate();
416 QGraphicsWidget::showEvent(event);
417 417 }
418 418
419 419 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
420 420
421 421 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
422 422 q_ptr(q),
423 423 m_presenter(presenter),
424 424 m_layout(new LegendLayout(q)),
425 425 m_chart(chart),
426 426 m_items(new QGraphicsItemGroup(q)),
427 427 m_alignment(Qt::AlignTop),
428 428 m_brush(QBrush()),
429 429 m_pen(QPen()),
430 430 m_labelBrush(QBrush()),
431 431 m_diameter(5),
432 432 m_attachedToChart(true),
433 433 m_backgroundVisible(false)
434 434 {
435 435
436 436 }
437 437
438 438 QLegendPrivate::~QLegendPrivate()
439 439 {
440 440
441 441 }
442 442
443 443 void QLegendPrivate::setOffset(qreal x, qreal y)
444 444 {
445 445 m_layout->setOffset(x,y);
446 446 }
447 447
448 448 QPointF QLegendPrivate::offset() const
449 449 {
450 450 return m_layout->offset();
451 451 }
452 452
453 453 int QLegendPrivate::roundness(qreal size)
454 454 {
455 455 return 100*m_diameter/int(size);
456 456 }
457 457
458 458 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
459 459 {
460 460 Q_UNUSED(domain)
461 461
462 462 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
463 463
464 464 foreach(LegendMarker* marker, markers) {
465 465 marker->setFont(m_font);
466 466 marker->setLabelBrush(m_labelBrush);
467 467 marker->setVisible(series->isVisible());
468 468 m_items->addToGroup(marker);
469 469 m_markers<<marker;
470 470 }
471 471
472 472 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
473 473
474 474 if(series->type() == QAbstractSeries::SeriesTypePie) {
475 475 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
476 476 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
477 477 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
478 478 }
479 479
480 480 q_ptr->layout()->invalidate();
481 481 q_ptr->layout()->activate();
482 482 }
483 483
484 484 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
485 485 {
486 486 foreach (LegendMarker *marker, m_markers) {
487 487 if (marker->series() == series) {
488 488 delete marker;
489 489 m_markers.removeAll(marker);
490 490 }
491 491 }
492 492
493 493 if(series->type() == QAbstractSeries::SeriesTypePie)
494 494 {
495 495 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
496 496 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
497 497 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
498 498 }
499 499
500 500 q_ptr->layout()->invalidate();
501 501 }
502 502
503 503 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
504 504 {
505 505 // TODO: find out which markers are are added or removed. Update them
506 506 // TODO: better implementation
507 507 handleSeriesRemoved(series);
508 508 Domain domain;
509 509 handleSeriesAdded(series, &domain);
510 510 }
511 511
512 512 void QLegendPrivate::handleUpdatePieSeries()
513 513 {
514 514 //TODO: reimplement to be optimal
515 515 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
516 516 Q_ASSERT(series);
517 517 handleSeriesRemoved(series);
518 518 handleSeriesAdded(series, 0);
519 519 }
520 520
521 521 void QLegendPrivate::handleSeriesVisibleChanged()
522 522 {
523 523 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
524 524
525 525 foreach (LegendMarker* marker, m_markers) {
526 526 if (marker->series() == series) {
527 527 marker->setVisible(series->isVisible());
528 528 }
529 529 }
530 530
531 531 q_ptr->layout()->invalidate();
532 532 }
533 533
534 534 #include "moc_qlegend.cpp"
535 535 #include "moc_qlegend_p.cpp"
536 536
537 537 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,111 +1,110
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QLEGEND_H
22 22 #define QLEGEND_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <QGraphicsWidget>
26 26 #include <QPen>
27 27 #include <QBrush>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 class Domain;
32 32 class LegendMarker;
33 33 class QPieSlice;
34 34 class QXYSeries;
35 35 class QBarSet;
36 36 class QAbstractBarSeries;
37 37 class QPieSeries;
38 38 class QAreaSeries;
39 39 class LegendScrollButton;
40 40 class QChart;
41 41 class QLegendPrivate;
42 42
43 43 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget
44 44 {
45 45 Q_OBJECT
46 46 Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
47 47 Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible NOTIFY backgroundVisibleChanged)
48 48 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
49 49 Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged)
50 50 Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
51 51 Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor NOTIFY labelColorChanged)
52 52
53 53 private:
54 54 explicit QLegend(QChart *chart);
55 55
56 56 public:
57 57 ~QLegend();
58 58
59 59 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
60 60
61 61 void setBrush(const QBrush &brush);
62 62 QBrush brush() const;
63 63 void setColor(QColor color);
64 64 QColor color();
65 65
66 66 void setPen(const QPen &pen);
67 67 QPen pen() const;
68 68 void setBorderColor(QColor color);
69 69 QColor borderColor();
70 70
71 71 void setFont(const QFont &font);
72 72 QFont font() const;
73 73 void setLabelBrush(const QBrush &brush);
74 74 QBrush labelBrush() const;
75 75
76 76 void setLabelColor(QColor color);
77 77 QColor labelColor() const;
78 78
79 79 void setAlignment(Qt::Alignment alignment);
80 80 Qt::Alignment alignment() const;
81 81
82 82 void detachFromChart();
83 83 void attachToChart();
84 84 bool isAttachedToChart();
85 85
86 86 void setBackgroundVisible(bool visible = true);
87 87 bool isBackgroundVisible() const;
88 88
89
90 89 protected:
91 90 void hideEvent(QHideEvent *event);
92 91 void showEvent(QShowEvent *event);
93 92
94 93 Q_SIGNALS:
95 94 void backgroundVisibleChanged(bool visible);
96 95 void colorChanged(QColor color);
97 96 void borderColorChanged(QColor color);
98 97 void fontChanged(QFont font);
99 98 void labelColorChanged(QColor color);
100 99
101 100 private:
102 101 QScopedPointer<QLegendPrivate> d_ptr;
103 102 Q_DISABLE_COPY(QLegend)
104 103 friend class LegendScroller;
105 104 friend class LegendLayout;
106 105 friend class ChartLayout;
107 106 };
108 107
109 108 QTCOMMERCIALCHART_END_NAMESPACE
110 109
111 110 #endif // QLEGEND_H
General Comments 0
You need to be logged in to leave comments. Login now