##// END OF EJS Templates
Fix text item margins...
Miikka Heikkinen -
r2592:621c955c10d2
parent child
Show More
@@ -1,195 +1,197
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 "cartesianchartaxis_p.h"
21 #include "cartesianchartaxis_p.h"
22 #include "qabstractaxis.h"
22 #include "qabstractaxis.h"
23 #include "qabstractaxis_p.h"
23 #include "qabstractaxis_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "abstractchartlayout_p.h"
25 #include "abstractchartlayout_p.h"
26 #include "abstractdomain_p.h"
26 #include "abstractdomain_p.h"
27 #include "linearrowitem_p.h"
27 #include "linearrowitem_p.h"
28 #include <QValueAxis>
28 #include <QValueAxis>
29 #include <QLogValueAxis>
29 #include <QLogValueAxis>
30 #include <QGraphicsLayout>
30 #include <QGraphicsLayout>
31 #include <QTextDocument>
31
32
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
34
34 CartesianChartAxis::CartesianChartAxis(QAbstractAxis *axis, QGraphicsItem *item , bool intervalAxis)
35 CartesianChartAxis::CartesianChartAxis(QAbstractAxis *axis, QGraphicsItem *item , bool intervalAxis)
35 : ChartAxisElement(axis, item, intervalAxis)
36 : ChartAxisElement(axis, item, intervalAxis)
36 {
37 {
37 Q_ASSERT(item);
38 Q_ASSERT(item);
38 }
39 }
39
40
40
41
41 CartesianChartAxis::~CartesianChartAxis()
42 CartesianChartAxis::~CartesianChartAxis()
42 {
43 {
43 }
44 }
44
45
45 void CartesianChartAxis::createItems(int count)
46 void CartesianChartAxis::createItems(int count)
46 {
47 {
47 if (arrowItems().size() == 0) {
48 if (arrowItems().size() == 0) {
48 QGraphicsLineItem *arrow = new LineArrowItem(this, this);
49 QGraphicsLineItem *arrow = new LineArrowItem(this, this);
49 arrow->setPen(axis()->linePen());
50 arrow->setPen(axis()->linePen());
50 arrowGroup()->addToGroup(arrow);
51 arrowGroup()->addToGroup(arrow);
51 }
52 }
52
53
53 if (intervalAxis() && gridItems().size() == 0) {
54 if (intervalAxis() && gridItems().size() == 0) {
54 for (int i = 0 ; i < 2 ; i ++){
55 for (int i = 0 ; i < 2 ; i ++){
55 QGraphicsLineItem *item = new QGraphicsLineItem(this);
56 QGraphicsLineItem *item = new QGraphicsLineItem(this);
56 item->setPen(axis()->gridLinePen());
57 item->setPen(axis()->gridLinePen());
57 gridGroup()->addToGroup(item);
58 gridGroup()->addToGroup(item);
58 }
59 }
59 }
60 }
60
61
61 for (int i = 0; i < count; ++i) {
62 for (int i = 0; i < count; ++i) {
62 QGraphicsLineItem *arrow = new QGraphicsLineItem(this);
63 QGraphicsLineItem *arrow = new QGraphicsLineItem(this);
63 QGraphicsLineItem *grid = new QGraphicsLineItem(this);
64 QGraphicsLineItem *grid = new QGraphicsLineItem(this);
64 QGraphicsTextItem *label = new QGraphicsTextItem(this);
65 QGraphicsTextItem *label = new QGraphicsTextItem(this);
66 label->document()->setDocumentMargin(ChartPresenter::textMargin());
65 QGraphicsTextItem *title = titleItem();
67 QGraphicsTextItem *title = titleItem();
66 arrow->setPen(axis()->linePen());
68 arrow->setPen(axis()->linePen());
67 grid->setPen(axis()->gridLinePen());
69 grid->setPen(axis()->gridLinePen());
68 label->setFont(axis()->labelsFont());
70 label->setFont(axis()->labelsFont());
69 label->setDefaultTextColor(axis()->labelsBrush().color());
71 label->setDefaultTextColor(axis()->labelsBrush().color());
70 label->setRotation(axis()->labelsAngle());
72 label->setRotation(axis()->labelsAngle());
71 title->setFont(axis()->titleFont());
73 title->setFont(axis()->titleFont());
72 title->setDefaultTextColor(axis()->titleBrush().color());
74 title->setDefaultTextColor(axis()->titleBrush().color());
73 title->setHtml(axis()->titleText());
75 title->setHtml(axis()->titleText());
74 arrowGroup()->addToGroup(arrow);
76 arrowGroup()->addToGroup(arrow);
75 gridGroup()->addToGroup(grid);
77 gridGroup()->addToGroup(grid);
76 labelGroup()->addToGroup(label);
78 labelGroup()->addToGroup(label);
77
79
78 if ((gridItems().size()) % 2 && gridItems().size() > 2) {
80 if ((gridItems().size()) % 2 && gridItems().size() > 2) {
79 QGraphicsRectItem* shades = new QGraphicsRectItem(this);
81 QGraphicsRectItem* shades = new QGraphicsRectItem(this);
80 shades->setPen(axis()->shadesPen());
82 shades->setPen(axis()->shadesPen());
81 shades->setBrush(axis()->shadesBrush());
83 shades->setBrush(axis()->shadesBrush());
82 shadeGroup()->addToGroup(shades);
84 shadeGroup()->addToGroup(shades);
83 }
85 }
84 }
86 }
85
87
86 }
88 }
87
89
88 void CartesianChartAxis::deleteItems(int count)
90 void CartesianChartAxis::deleteItems(int count)
89 {
91 {
90 QList<QGraphicsItem *> lines = gridItems();
92 QList<QGraphicsItem *> lines = gridItems();
91 QList<QGraphicsItem *> labels = labelItems();
93 QList<QGraphicsItem *> labels = labelItems();
92 QList<QGraphicsItem *> shades = shadeItems();
94 QList<QGraphicsItem *> shades = shadeItems();
93 QList<QGraphicsItem *> axis = arrowItems();
95 QList<QGraphicsItem *> axis = arrowItems();
94
96
95 for (int i = 0; i < count; ++i) {
97 for (int i = 0; i < count; ++i) {
96 if (lines.size() % 2 && lines.size() > 1)
98 if (lines.size() % 2 && lines.size() > 1)
97 delete(shades.takeLast());
99 delete(shades.takeLast());
98 delete(lines.takeLast());
100 delete(lines.takeLast());
99 delete(labels.takeLast());
101 delete(labels.takeLast());
100 delete(axis.takeLast());
102 delete(axis.takeLast());
101 }
103 }
102 }
104 }
103
105
104 void CartesianChartAxis::updateLayout(QVector<qreal> &layout)
106 void CartesianChartAxis::updateLayout(QVector<qreal> &layout)
105 {
107 {
106 int diff = ChartAxisElement::layout().size() - layout.size();
108 int diff = ChartAxisElement::layout().size() - layout.size();
107
109
108 if (diff > 0)
110 if (diff > 0)
109 deleteItems(diff);
111 deleteItems(diff);
110 else if (diff < 0)
112 else if (diff < 0)
111 createItems(-diff);
113 createItems(-diff);
112
114
113 if (animation()) {
115 if (animation()) {
114 switch (presenter()->state()) {
116 switch (presenter()->state()) {
115 case ChartPresenter::ZoomInState:
117 case ChartPresenter::ZoomInState:
116 animation()->setAnimationType(AxisAnimation::ZoomInAnimation);
118 animation()->setAnimationType(AxisAnimation::ZoomInAnimation);
117 animation()->setAnimationPoint(presenter()->statePoint());
119 animation()->setAnimationPoint(presenter()->statePoint());
118 break;
120 break;
119 case ChartPresenter::ZoomOutState:
121 case ChartPresenter::ZoomOutState:
120 animation()->setAnimationType(AxisAnimation::ZoomOutAnimation);
122 animation()->setAnimationType(AxisAnimation::ZoomOutAnimation);
121 animation()->setAnimationPoint(presenter()->statePoint());
123 animation()->setAnimationPoint(presenter()->statePoint());
122 break;
124 break;
123 case ChartPresenter::ScrollUpState:
125 case ChartPresenter::ScrollUpState:
124 case ChartPresenter::ScrollLeftState:
126 case ChartPresenter::ScrollLeftState:
125 animation()->setAnimationType(AxisAnimation::MoveBackwordAnimation);
127 animation()->setAnimationType(AxisAnimation::MoveBackwordAnimation);
126 break;
128 break;
127 case ChartPresenter::ScrollDownState:
129 case ChartPresenter::ScrollDownState:
128 case ChartPresenter::ScrollRightState:
130 case ChartPresenter::ScrollRightState:
129 animation()->setAnimationType(AxisAnimation::MoveForwardAnimation);
131 animation()->setAnimationType(AxisAnimation::MoveForwardAnimation);
130 break;
132 break;
131 case ChartPresenter::ShowState:
133 case ChartPresenter::ShowState:
132 animation()->setAnimationType(AxisAnimation::DefaultAnimation);
134 animation()->setAnimationType(AxisAnimation::DefaultAnimation);
133 break;
135 break;
134 }
136 }
135 animation()->setValues(ChartAxisElement::layout(), layout);
137 animation()->setValues(ChartAxisElement::layout(), layout);
136 presenter()->startAnimation(animation());
138 presenter()->startAnimation(animation());
137 } else {
139 } else {
138 setLayout(layout);
140 setLayout(layout);
139 updateGeometry();
141 updateGeometry();
140 }
142 }
141 }
143 }
142
144
143 bool CartesianChartAxis::isEmpty()
145 bool CartesianChartAxis::isEmpty()
144 {
146 {
145 return axisGeometry().isEmpty()
147 return axisGeometry().isEmpty()
146 || gridGeometry().isEmpty()
148 || gridGeometry().isEmpty()
147 || qFuzzyCompare(min(), max());
149 || qFuzzyCompare(min(), max());
148 }
150 }
149
151
150 void CartesianChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
152 void CartesianChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
151 {
153 {
152 m_gridRect = grid;
154 m_gridRect = grid;
153 setAxisGeometry(axis);
155 setAxisGeometry(axis);
154
156
155 if (isEmpty())
157 if (isEmpty())
156 return;
158 return;
157
159
158 QVector<qreal> layout = calculateLayout();
160 QVector<qreal> layout = calculateLayout();
159 updateLayout(layout);
161 updateLayout(layout);
160 }
162 }
161
163
162 QSizeF CartesianChartAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
164 QSizeF CartesianChartAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
163 {
165 {
164 Q_UNUSED(which);
166 Q_UNUSED(which);
165 Q_UNUSED(constraint);
167 Q_UNUSED(constraint);
166 return QSizeF();
168 return QSizeF();
167 }
169 }
168
170
169 void CartesianChartAxis::handleArrowPenChanged(const QPen &pen)
171 void CartesianChartAxis::handleArrowPenChanged(const QPen &pen)
170 {
172 {
171 foreach (QGraphicsItem *item, arrowItems())
173 foreach (QGraphicsItem *item, arrowItems())
172 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
174 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
173 }
175 }
174
176
175 void CartesianChartAxis::handleGridPenChanged(const QPen &pen)
177 void CartesianChartAxis::handleGridPenChanged(const QPen &pen)
176 {
178 {
177 foreach (QGraphicsItem *item, gridItems())
179 foreach (QGraphicsItem *item, gridItems())
178 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
180 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
179 }
181 }
180
182
181 void CartesianChartAxis::handleShadesBrushChanged(const QBrush &brush)
183 void CartesianChartAxis::handleShadesBrushChanged(const QBrush &brush)
182 {
184 {
183 foreach (QGraphicsItem *item, shadeItems())
185 foreach (QGraphicsItem *item, shadeItems())
184 static_cast<QGraphicsRectItem *>(item)->setBrush(brush);
186 static_cast<QGraphicsRectItem *>(item)->setBrush(brush);
185 }
187 }
186
188
187 void CartesianChartAxis::handleShadesPenChanged(const QPen &pen)
189 void CartesianChartAxis::handleShadesPenChanged(const QPen &pen)
188 {
190 {
189 foreach (QGraphicsItem *item, shadeItems())
191 foreach (QGraphicsItem *item, shadeItems())
190 static_cast<QGraphicsRectItem *>(item)->setPen(pen);
192 static_cast<QGraphicsRectItem *>(item)->setPen(pen);
191 }
193 }
192
194
193 #include "moc_cartesianchartaxis_p.cpp"
195 #include "moc_cartesianchartaxis_p.cpp"
194
196
195 QTCOMMERCIALCHART_END_NAMESPACE
197 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,352 +1,354
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 "chartaxiselement_p.h"
21 #include "chartaxiselement_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include "abstractchartlayout_p.h"
24 #include "abstractchartlayout_p.h"
25 #include <qmath.h>
25 #include <qmath.h>
26 #include <QDateTime>
26 #include <QDateTime>
27 #include <QTextDocument>
27
28
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
30
30 static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.lhjztL]*([dicuoxfegXFEG])";
31 static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.lhjztL]*([dicuoxfegXFEG])";
31 static QRegExp *labelFormatMatcher = 0;
32 static QRegExp *labelFormatMatcher = 0;
32 class StaticLabelFormatMatcherDeleter
33 class StaticLabelFormatMatcherDeleter
33 {
34 {
34 public:
35 public:
35 StaticLabelFormatMatcherDeleter() {}
36 StaticLabelFormatMatcherDeleter() {}
36 ~StaticLabelFormatMatcherDeleter() { delete labelFormatMatcher; }
37 ~StaticLabelFormatMatcherDeleter() { delete labelFormatMatcher; }
37 };
38 };
38 static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter;
39 static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter;
39
40
40 ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
41 ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
41 : ChartElement(item),
42 : ChartElement(item),
42 m_axis(axis),
43 m_axis(axis),
43 m_animation(0),
44 m_animation(0),
44 m_grid(new QGraphicsItemGroup(item)),
45 m_grid(new QGraphicsItemGroup(item)),
45 m_arrow(new QGraphicsItemGroup(item)),
46 m_arrow(new QGraphicsItemGroup(item)),
46 m_shades(new QGraphicsItemGroup(item)),
47 m_shades(new QGraphicsItemGroup(item)),
47 m_labels(new QGraphicsItemGroup(item)),
48 m_labels(new QGraphicsItemGroup(item)),
48 m_title(new QGraphicsTextItem(item)),
49 m_title(new QGraphicsTextItem(item)),
49 m_intervalAxis(intervalAxis)
50 m_intervalAxis(intervalAxis)
50
51
51 {
52 {
52 //initial initialization
53 //initial initialization
53 m_arrow->setHandlesChildEvents(false);
54 m_arrow->setHandlesChildEvents(false);
54 m_arrow->setZValue(ChartPresenter::AxisZValue);
55 m_arrow->setZValue(ChartPresenter::AxisZValue);
55 m_labels->setZValue(ChartPresenter::AxisZValue);
56 m_labels->setZValue(ChartPresenter::AxisZValue);
56 m_shades->setZValue(ChartPresenter::ShadesZValue);
57 m_shades->setZValue(ChartPresenter::ShadesZValue);
57 m_grid->setZValue(ChartPresenter::GridZValue);
58 m_grid->setZValue(ChartPresenter::GridZValue);
58 m_title->setZValue(ChartPresenter::GridZValue);
59 m_title->setZValue(ChartPresenter::GridZValue);
60 m_title->document()->setDocumentMargin(ChartPresenter::textMargin());
59 handleVisibleChanged(axis->isVisible());
61 handleVisibleChanged(axis->isVisible());
60 connectSlots();
62 connectSlots();
61
63
62 setFlag(QGraphicsItem::ItemHasNoContents, true);
64 setFlag(QGraphicsItem::ItemHasNoContents, true);
63 }
65 }
64
66
65 ChartAxisElement::~ChartAxisElement()
67 ChartAxisElement::~ChartAxisElement()
66 {
68 {
67 }
69 }
68
70
69 void ChartAxisElement::connectSlots()
71 void ChartAxisElement::connectSlots()
70 {
72 {
71 QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool)));
73 QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool)));
72 QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool)));
74 QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool)));
73 QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool)));
75 QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool)));
74 QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
76 QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
75 QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool)));
77 QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool)));
76 QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int)));
78 QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int)));
77 QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&)));
79 QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&)));
78 QObject::connect(axis(), SIGNAL(labelsPenChanged(const QPen&)), this, SLOT(handleLabelsPenChanged(const QPen&)));
80 QObject::connect(axis(), SIGNAL(labelsPenChanged(const QPen&)), this, SLOT(handleLabelsPenChanged(const QPen&)));
79 QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&)));
81 QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&)));
80 QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&)));
82 QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&)));
81 QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&)));
83 QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&)));
82 QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&)));
84 QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&)));
83 QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&)));
85 QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&)));
84 QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&)));
86 QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&)));
85 QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&)));
87 QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&)));
86 QObject::connect(axis(), SIGNAL(titlePenChanged(const QPen&)), this, SLOT(handleTitlePenChanged(const QPen&)));
88 QObject::connect(axis(), SIGNAL(titlePenChanged(const QPen&)), this, SLOT(handleTitlePenChanged(const QPen&)));
87 QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&)));
89 QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&)));
88 QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool)));
90 QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool)));
89 QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal)));
91 QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal)));
90 }
92 }
91
93
92 void ChartAxisElement::handleArrowVisibleChanged(bool visible)
94 void ChartAxisElement::handleArrowVisibleChanged(bool visible)
93 {
95 {
94 m_arrow->setVisible(visible);
96 m_arrow->setVisible(visible);
95 }
97 }
96
98
97 void ChartAxisElement::handleGridVisibleChanged(bool visible)
99 void ChartAxisElement::handleGridVisibleChanged(bool visible)
98 {
100 {
99 m_grid->setVisible(visible);
101 m_grid->setVisible(visible);
100 }
102 }
101
103
102 void ChartAxisElement::handleLabelsVisibleChanged(bool visible)
104 void ChartAxisElement::handleLabelsVisibleChanged(bool visible)
103 {
105 {
104 QGraphicsLayoutItem::updateGeometry();
106 QGraphicsLayoutItem::updateGeometry();
105 presenter()->layout()->invalidate();
107 presenter()->layout()->invalidate();
106 m_labels->setVisible(visible);
108 m_labels->setVisible(visible);
107 }
109 }
108
110
109 void ChartAxisElement::handleShadesVisibleChanged(bool visible)
111 void ChartAxisElement::handleShadesVisibleChanged(bool visible)
110 {
112 {
111 m_shades->setVisible(visible);
113 m_shades->setVisible(visible);
112 }
114 }
113
115
114 void ChartAxisElement::handleTitleVisibleChanged(bool visible)
116 void ChartAxisElement::handleTitleVisibleChanged(bool visible)
115 {
117 {
116 QGraphicsLayoutItem::updateGeometry();
118 QGraphicsLayoutItem::updateGeometry();
117 presenter()->layout()->invalidate();
119 presenter()->layout()->invalidate();
118 m_title->setVisible(visible);
120 m_title->setVisible(visible);
119 }
121 }
120
122
121 void ChartAxisElement::handleLabelsAngleChanged(int angle)
123 void ChartAxisElement::handleLabelsAngleChanged(int angle)
122 {
124 {
123 foreach (QGraphicsItem *item, m_labels->childItems())
125 foreach (QGraphicsItem *item, m_labels->childItems())
124 item->setRotation(angle);
126 item->setRotation(angle);
125
127
126 QGraphicsLayoutItem::updateGeometry();
128 QGraphicsLayoutItem::updateGeometry();
127 presenter()->layout()->invalidate();
129 presenter()->layout()->invalidate();
128 }
130 }
129
131
130 void ChartAxisElement::handleLabelsPenChanged(const QPen &pen)
132 void ChartAxisElement::handleLabelsPenChanged(const QPen &pen)
131 {
133 {
132 Q_UNUSED(pen)
134 Q_UNUSED(pen)
133 }
135 }
134
136
135 void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush)
137 void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush)
136 {
138 {
137 foreach (QGraphicsItem *item, m_labels->childItems())
139 foreach (QGraphicsItem *item, m_labels->childItems())
138 static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color());
140 static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color());
139 }
141 }
140
142
141 void ChartAxisElement::handleLabelsFontChanged(const QFont &font)
143 void ChartAxisElement::handleLabelsFontChanged(const QFont &font)
142 {
144 {
143 foreach (QGraphicsItem *item, m_labels->childItems())
145 foreach (QGraphicsItem *item, m_labels->childItems())
144 static_cast<QGraphicsTextItem *>(item)->setFont(font);
146 static_cast<QGraphicsTextItem *>(item)->setFont(font);
145 QGraphicsLayoutItem::updateGeometry();
147 QGraphicsLayoutItem::updateGeometry();
146 presenter()->layout()->invalidate();
148 presenter()->layout()->invalidate();
147 }
149 }
148
150
149 void ChartAxisElement::handleTitleTextChanged(const QString &title)
151 void ChartAxisElement::handleTitleTextChanged(const QString &title)
150 {
152 {
151 QGraphicsLayoutItem::updateGeometry();
153 QGraphicsLayoutItem::updateGeometry();
152 presenter()->layout()->invalidate();
154 presenter()->layout()->invalidate();
153 m_title->setHtml(title);
155 m_title->setHtml(title);
154 }
156 }
155
157
156 void ChartAxisElement::handleTitlePenChanged(const QPen &pen)
158 void ChartAxisElement::handleTitlePenChanged(const QPen &pen)
157 {
159 {
158 Q_UNUSED(pen)
160 Q_UNUSED(pen)
159 }
161 }
160
162
161 void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush)
163 void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush)
162 {
164 {
163 m_title->setDefaultTextColor(brush.color());
165 m_title->setDefaultTextColor(brush.color());
164 }
166 }
165
167
166 void ChartAxisElement::handleTitleFontChanged(const QFont &font)
168 void ChartAxisElement::handleTitleFontChanged(const QFont &font)
167 {
169 {
168 if (m_title->font() != font) {
170 if (m_title->font() != font) {
169 m_title->setFont(font);
171 m_title->setFont(font);
170 QGraphicsLayoutItem::updateGeometry();
172 QGraphicsLayoutItem::updateGeometry();
171 presenter()->layout()->invalidate();
173 presenter()->layout()->invalidate();
172 }
174 }
173 }
175 }
174
176
175 void ChartAxisElement::handleVisibleChanged(bool visible)
177 void ChartAxisElement::handleVisibleChanged(bool visible)
176 {
178 {
177 setVisible(visible);
179 setVisible(visible);
178 if (!visible) {
180 if (!visible) {
179 m_grid->setVisible(visible);
181 m_grid->setVisible(visible);
180 m_arrow->setVisible(visible);
182 m_arrow->setVisible(visible);
181 m_shades->setVisible(visible);
183 m_shades->setVisible(visible);
182 m_labels->setVisible(visible);
184 m_labels->setVisible(visible);
183 m_title->setVisible(visible);
185 m_title->setVisible(visible);
184 } else {
186 } else {
185 m_grid->setVisible(axis()->isGridLineVisible());
187 m_grid->setVisible(axis()->isGridLineVisible());
186 m_arrow->setVisible(axis()->isLineVisible());
188 m_arrow->setVisible(axis()->isLineVisible());
187 m_shades->setVisible(axis()->shadesVisible());
189 m_shades->setVisible(axis()->shadesVisible());
188 m_labels->setVisible(axis()->labelsVisible());
190 m_labels->setVisible(axis()->labelsVisible());
189 m_title->setVisible(axis()->isTitleVisible());
191 m_title->setVisible(axis()->isTitleVisible());
190 }
192 }
191
193
192 if (presenter()) presenter()->layout()->invalidate();
194 if (presenter()) presenter()->layout()->invalidate();
193 }
195 }
194
196
195 void ChartAxisElement::handleRangeChanged(qreal min, qreal max)
197 void ChartAxisElement::handleRangeChanged(qreal min, qreal max)
196 {
198 {
197 Q_UNUSED(min);
199 Q_UNUSED(min);
198 Q_UNUSED(max);
200 Q_UNUSED(max);
199
201
200 if (!isEmpty()) {
202 if (!isEmpty()) {
201 QVector<qreal> layout = calculateLayout();
203 QVector<qreal> layout = calculateLayout();
202 updateLayout(layout);
204 updateLayout(layout);
203 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
205 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
204 QSizeF after = sizeHint(Qt::PreferredSize);
206 QSizeF after = sizeHint(Qt::PreferredSize);
205
207
206 if (before != after) {
208 if (before != after) {
207 QGraphicsLayoutItem::updateGeometry();
209 QGraphicsLayoutItem::updateGeometry();
208 // We don't want to call invalidate on layout, since it will change minimum size of
210 // We don't want to call invalidate on layout, since it will change minimum size of
209 // component, which we would like to avoid since it causes nasty flips when scrolling
211 // component, which we would like to avoid since it causes nasty flips when scrolling
210 // or zooming, instead recalculate layout and use plotArea for extra space.
212 // or zooming, instead recalculate layout and use plotArea for extra space.
211 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
213 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
212 }
214 }
213 }
215 }
214 }
216 }
215
217
216 bool ChartAxisElement::isEmpty()
218 bool ChartAxisElement::isEmpty()
217 {
219 {
218 return axisGeometry().isEmpty()
220 return axisGeometry().isEmpty()
219 || gridGeometry().isEmpty()
221 || gridGeometry().isEmpty()
220 || qFuzzyCompare(min(), max());
222 || qFuzzyCompare(min(), max());
221 }
223 }
222
224
223 qreal ChartAxisElement::min() const
225 qreal ChartAxisElement::min() const
224 {
226 {
225 return m_axis->d_ptr->min();
227 return m_axis->d_ptr->min();
226 }
228 }
227
229
228 qreal ChartAxisElement::max() const
230 qreal ChartAxisElement::max() const
229 {
231 {
230 return m_axis->d_ptr->max();
232 return m_axis->d_ptr->max();
231 }
233 }
232
234
233 static void appendFormattedLabel(const QString &capStr, const QByteArray &array,
235 static void appendFormattedLabel(const QString &capStr, const QByteArray &array,
234 QStringList &labels, qreal value)
236 QStringList &labels, qreal value)
235 {
237 {
236 if (capStr.isEmpty()) {
238 if (capStr.isEmpty()) {
237 labels << QString();
239 labels << QString();
238 } else if (capStr.at(0) == QLatin1Char('d')
240 } else if (capStr.at(0) == QLatin1Char('d')
239 || capStr.at(0) == QLatin1Char('i')
241 || capStr.at(0) == QLatin1Char('i')
240 || capStr.at(0) == QLatin1Char('c')) {
242 || capStr.at(0) == QLatin1Char('c')) {
241 labels << QString().sprintf(array, (qint64)value);
243 labels << QString().sprintf(array, (qint64)value);
242 } else if (capStr.at(0) == QLatin1Char('u')
244 } else if (capStr.at(0) == QLatin1Char('u')
243 || capStr.at(0) == QLatin1Char('o')
245 || capStr.at(0) == QLatin1Char('o')
244 || capStr.at(0) == QLatin1Char('x')
246 || capStr.at(0) == QLatin1Char('x')
245 || capStr.at(0) == QLatin1Char('X')) {
247 || capStr.at(0) == QLatin1Char('X')) {
246 labels << QString().sprintf(array, (quint64)value);
248 labels << QString().sprintf(array, (quint64)value);
247 } else if (capStr.at(0) == QLatin1Char('f')
249 } else if (capStr.at(0) == QLatin1Char('f')
248 || capStr.at(0) == QLatin1Char('F')
250 || capStr.at(0) == QLatin1Char('F')
249 || capStr.at(0) == QLatin1Char('e')
251 || capStr.at(0) == QLatin1Char('e')
250 || capStr.at(0) == QLatin1Char('E')
252 || capStr.at(0) == QLatin1Char('E')
251 || capStr.at(0) == QLatin1Char('g')
253 || capStr.at(0) == QLatin1Char('g')
252 || capStr.at(0) == QLatin1Char('G')) {
254 || capStr.at(0) == QLatin1Char('G')) {
253 labels << QString().sprintf(array, value);
255 labels << QString().sprintf(array, value);
254 } else {
256 } else {
255 labels << QString();
257 labels << QString();
256 }
258 }
257 }
259 }
258
260
259 QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks, const QString &format)
261 QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks, const QString &format)
260 {
262 {
261 QStringList labels;
263 QStringList labels;
262
264
263 if (max <= min || ticks < 1)
265 if (max <= min || ticks < 1)
264 return labels;
266 return labels;
265
267
266 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
268 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
267 n++;
269 n++;
268
270
269 if (format.isNull()) {
271 if (format.isNull()) {
270 for (int i = 0; i < ticks; i++) {
272 for (int i = 0; i < ticks; i++) {
271 qreal value = min + (i * (max - min) / (ticks - 1));
273 qreal value = min + (i * (max - min) / (ticks - 1));
272 labels << QString::number(value, 'f', n);
274 labels << QString::number(value, 'f', n);
273 }
275 }
274 } else {
276 } else {
275 QByteArray array = format.toLatin1();
277 QByteArray array = format.toLatin1();
276 QString capStr;
278 QString capStr;
277 if (!labelFormatMatcher)
279 if (!labelFormatMatcher)
278 labelFormatMatcher = new QRegExp(labelFormatMatchString);
280 labelFormatMatcher = new QRegExp(labelFormatMatchString);
279 if (labelFormatMatcher->indexIn(format, 0) != -1)
281 if (labelFormatMatcher->indexIn(format, 0) != -1)
280 capStr = labelFormatMatcher->cap(1);
282 capStr = labelFormatMatcher->cap(1);
281 for (int i = 0; i < ticks; i++) {
283 for (int i = 0; i < ticks; i++) {
282 qreal value = min + (i * (max - min) / (ticks - 1));
284 qreal value = min + (i * (max - min) / (ticks - 1));
283 appendFormattedLabel(capStr, array, labels, value);
285 appendFormattedLabel(capStr, array, labels, value);
284 }
286 }
285 }
287 }
286
288
287 return labels;
289 return labels;
288 }
290 }
289
291
290 QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString &format)
292 QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString &format)
291 {
293 {
292 QStringList labels;
294 QStringList labels;
293
295
294 if (max <= min || ticks < 1)
296 if (max <= min || ticks < 1)
295 return labels;
297 return labels;
296
298
297 int n = 0;
299 int n = 0;
298 if (ticks > 1)
300 if (ticks > 1)
299 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
301 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
300 n++;
302 n++;
301
303
302 int firstTick;
304 int firstTick;
303 if (base > 1)
305 if (base > 1)
304 firstTick = ceil(log10(min) / log10(base));
306 firstTick = ceil(log10(min) / log10(base));
305 else
307 else
306 firstTick = ceil(log10(max) / log10(base));
308 firstTick = ceil(log10(max) / log10(base));
307
309
308 if (format.isNull()) {
310 if (format.isNull()) {
309 for (int i = firstTick; i < ticks + firstTick; i++) {
311 for (int i = firstTick; i < ticks + firstTick; i++) {
310 qreal value = qPow(base, i);
312 qreal value = qPow(base, i);
311 labels << QString::number(value, 'f', n);
313 labels << QString::number(value, 'f', n);
312 }
314 }
313 } else {
315 } else {
314 QByteArray array = format.toLatin1();
316 QByteArray array = format.toLatin1();
315 QString capStr;
317 QString capStr;
316 if (!labelFormatMatcher)
318 if (!labelFormatMatcher)
317 labelFormatMatcher = new QRegExp(labelFormatMatchString);
319 labelFormatMatcher = new QRegExp(labelFormatMatchString);
318 if (labelFormatMatcher->indexIn(format, 0) != -1)
320 if (labelFormatMatcher->indexIn(format, 0) != -1)
319 capStr = labelFormatMatcher->cap(1);
321 capStr = labelFormatMatcher->cap(1);
320 for (int i = firstTick; i < ticks + firstTick; i++) {
322 for (int i = firstTick; i < ticks + firstTick; i++) {
321 qreal value = qPow(base, i);
323 qreal value = qPow(base, i);
322 appendFormattedLabel(capStr, array, labels, value);
324 appendFormattedLabel(capStr, array, labels, value);
323 }
325 }
324 }
326 }
325
327
326 return labels;
328 return labels;
327 }
329 }
328
330
329 QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,const QString &format)
331 QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,const QString &format)
330 {
332 {
331 QStringList labels;
333 QStringList labels;
332
334
333 if (max <= min || ticks < 1)
335 if (max <= min || ticks < 1)
334 return labels;
336 return labels;
335
337
336 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
338 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
337 n++;
339 n++;
338 for (int i = 0; i < ticks; i++) {
340 for (int i = 0; i < ticks; i++) {
339 qreal value = min + (i * (max - min) / (ticks - 1));
341 qreal value = min + (i * (max - min) / (ticks - 1));
340 labels << QDateTime::fromMSecsSinceEpoch(value).toString(format);
342 labels << QDateTime::fromMSecsSinceEpoch(value).toString(format);
341 }
343 }
342 return labels;
344 return labels;
343 }
345 }
344
346
345 void ChartAxisElement::axisSelected()
347 void ChartAxisElement::axisSelected()
346 {
348 {
347 emit clicked();
349 emit clicked();
348 }
350 }
349
351
350 #include "moc_chartaxiselement_p.cpp"
352 #include "moc_chartaxiselement_p.cpp"
351
353
352 QTCOMMERCIALCHART_END_NAMESPACE
354 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,151 +1,151
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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef CHARTAXISELEMENT_H
30 #ifndef CHARTAXISELEMENT_H
31 #define CHARTAXISELEMENT_H
31 #define CHARTAXISELEMENT_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "chartelement_p.h"
34 #include "chartelement_p.h"
35 #include "axisanimation_p.h"
35 #include "axisanimation_p.h"
36 #include <QGraphicsItem>
36 #include <QGraphicsItem>
37 #include <QGraphicsLayoutItem>
37 #include <QGraphicsLayoutItem>
38 #include <QFont>
38 #include <QFont>
39
39
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41
41
42 class ChartPresenter;
42 class ChartPresenter;
43 class QAbstractAxis;
43 class QAbstractAxis;
44
44
45 class ChartAxisElement : public ChartElement, public QGraphicsLayoutItem
45 class ChartAxisElement : public ChartElement, public QGraphicsLayoutItem
46 {
46 {
47 Q_OBJECT
47 Q_OBJECT
48
48
49 using QGraphicsLayoutItem::setGeometry;
49 using QGraphicsLayoutItem::setGeometry;
50 public:
50 public:
51 ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis = false);
51 ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis = false);
52 ~ChartAxisElement();
52 ~ChartAxisElement();
53
53
54 virtual QRectF gridGeometry() const = 0;
54 virtual QRectF gridGeometry() const = 0;
55 virtual void setGeometry(const QRectF &axis, const QRectF &grid) = 0;
55 virtual void setGeometry(const QRectF &axis, const QRectF &grid) = 0;
56 virtual bool isEmpty() = 0;
56 virtual bool isEmpty() = 0;
57
57
58 void setAnimation(AxisAnimation *animation) { m_animation = animation; }
58 void setAnimation(AxisAnimation *animation) { m_animation = animation; }
59 AxisAnimation *animation() const { return m_animation; }
59 AxisAnimation *animation() const { return m_animation; }
60
60
61 QAbstractAxis *axis() const { return m_axis; }
61 QAbstractAxis *axis() const { return m_axis; }
62 void setLayout(QVector<qreal> &layout) { m_layout = layout; }
62 void setLayout(QVector<qreal> &layout) { m_layout = layout; }
63 QVector<qreal> &layout() { return m_layout; } // Modifiable reference
63 QVector<qreal> &layout() { return m_layout; } // Modifiable reference
64 inline qreal labelPadding() const { return qreal(1.0); }
64 inline qreal labelPadding() const { return qreal(4.0); }
65 inline qreal titlePadding() const { return qreal(1.0); }
65 inline qreal titlePadding() const { return qreal(2.0); }
66 void setLabels(const QStringList &labels) { m_labelsList = labels; }
66 void setLabels(const QStringList &labels) { m_labelsList = labels; }
67 QStringList labels() const { return m_labelsList; }
67 QStringList labels() const { return m_labelsList; }
68
68
69 qreal min() const;
69 qreal min() const;
70 qreal max() const;
70 qreal max() const;
71
71
72 QRectF axisGeometry() const { return m_axisRect; }
72 QRectF axisGeometry() const { return m_axisRect; }
73 void setAxisGeometry(const QRectF &axisGeometry) { m_axisRect = axisGeometry; }
73 void setAxisGeometry(const QRectF &axisGeometry) { m_axisRect = axisGeometry; }
74
74
75 void axisSelected();
75 void axisSelected();
76
76
77 //this flag indicates that axis is used to show intervals it means labels are in between ticks
77 //this flag indicates that axis is used to show intervals it means labels are in between ticks
78 bool intervalAxis() const { return m_intervalAxis; }
78 bool intervalAxis() const { return m_intervalAxis; }
79
79
80 static QStringList createValueLabels(qreal max, qreal min, int ticks, const QString &format);
80 static QStringList createValueLabels(qreal max, qreal min, int ticks, const QString &format);
81 static QStringList createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString &format);
81 static QStringList createLogValueLabels(qreal min, qreal max, qreal base, int ticks, const QString &format);
82 static QStringList createDateTimeLabels(qreal max, qreal min, int ticks, const QString &format);
82 static QStringList createDateTimeLabels(qreal max, qreal min, int ticks, const QString &format);
83
83
84 // from QGraphicsLayoutItem
84 // from QGraphicsLayoutItem
85 QRectF boundingRect() const
85 QRectF boundingRect() const
86 {
86 {
87 return QRectF();
87 return QRectF();
88 }
88 }
89
89
90 // from QGraphicsLayoutItem
90 // from QGraphicsLayoutItem
91 void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
91 void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)
92 {
92 {
93 }
93 }
94
94
95 protected:
95 protected:
96 virtual QVector<qreal> calculateLayout() const = 0;
96 virtual QVector<qreal> calculateLayout() const = 0;
97 virtual void updateLayout(QVector<qreal> &layout) = 0;
97 virtual void updateLayout(QVector<qreal> &layout) = 0;
98
98
99 QList<QGraphicsItem *> gridItems() { return m_grid->childItems(); }
99 QList<QGraphicsItem *> gridItems() { return m_grid->childItems(); }
100 QList<QGraphicsItem *> labelItems() { return m_labels->childItems(); }
100 QList<QGraphicsItem *> labelItems() { return m_labels->childItems(); }
101 QList<QGraphicsItem *> shadeItems() { return m_shades->childItems(); }
101 QList<QGraphicsItem *> shadeItems() { return m_shades->childItems(); }
102 QList<QGraphicsItem *> arrowItems() { return m_arrow->childItems(); }
102 QList<QGraphicsItem *> arrowItems() { return m_arrow->childItems(); }
103 QGraphicsTextItem *titleItem() const { return m_title.data(); }
103 QGraphicsTextItem *titleItem() const { return m_title.data(); }
104 QGraphicsItemGroup *gridGroup() { return m_grid.data(); }
104 QGraphicsItemGroup *gridGroup() { return m_grid.data(); }
105 QGraphicsItemGroup *labelGroup() { return m_labels.data(); }
105 QGraphicsItemGroup *labelGroup() { return m_labels.data(); }
106 QGraphicsItemGroup *shadeGroup() { return m_shades.data(); }
106 QGraphicsItemGroup *shadeGroup() { return m_shades.data(); }
107 QGraphicsItemGroup *arrowGroup() { return m_arrow.data(); }
107 QGraphicsItemGroup *arrowGroup() { return m_arrow.data(); }
108
108
109 public Q_SLOTS:
109 public Q_SLOTS:
110 void handleVisibleChanged(bool visible);
110 void handleVisibleChanged(bool visible);
111 void handleArrowVisibleChanged(bool visible);
111 void handleArrowVisibleChanged(bool visible);
112 void handleGridVisibleChanged(bool visible);
112 void handleGridVisibleChanged(bool visible);
113 void handleLabelsVisibleChanged(bool visible);
113 void handleLabelsVisibleChanged(bool visible);
114 void handleShadesVisibleChanged(bool visible);
114 void handleShadesVisibleChanged(bool visible);
115 void handleLabelsAngleChanged(int angle);
115 void handleLabelsAngleChanged(int angle);
116 virtual void handleShadesBrushChanged(const QBrush &brush) = 0;
116 virtual void handleShadesBrushChanged(const QBrush &brush) = 0;
117 virtual void handleShadesPenChanged(const QPen &pen) = 0;
117 virtual void handleShadesPenChanged(const QPen &pen) = 0;
118 virtual void handleArrowPenChanged(const QPen &pen) = 0;
118 virtual void handleArrowPenChanged(const QPen &pen) = 0;
119 virtual void handleGridPenChanged(const QPen &pen) = 0;
119 virtual void handleGridPenChanged(const QPen &pen) = 0;
120 void handleLabelsPenChanged(const QPen &pen);
120 void handleLabelsPenChanged(const QPen &pen);
121 void handleLabelsBrushChanged(const QBrush &brush);
121 void handleLabelsBrushChanged(const QBrush &brush);
122 void handleLabelsFontChanged(const QFont &font);
122 void handleLabelsFontChanged(const QFont &font);
123 void handleTitlePenChanged(const QPen &pen);
123 void handleTitlePenChanged(const QPen &pen);
124 void handleTitleBrushChanged(const QBrush &brush);
124 void handleTitleBrushChanged(const QBrush &brush);
125 void handleTitleFontChanged(const QFont &font);
125 void handleTitleFontChanged(const QFont &font);
126 void handleTitleTextChanged(const QString &title);
126 void handleTitleTextChanged(const QString &title);
127 void handleTitleVisibleChanged(bool visible);
127 void handleTitleVisibleChanged(bool visible);
128 void handleRangeChanged(qreal min, qreal max);
128 void handleRangeChanged(qreal min, qreal max);
129
129
130 Q_SIGNALS:
130 Q_SIGNALS:
131 void clicked();
131 void clicked();
132
132
133 private:
133 private:
134 void connectSlots();
134 void connectSlots();
135
135
136 QAbstractAxis *m_axis;
136 QAbstractAxis *m_axis;
137 AxisAnimation *m_animation;
137 AxisAnimation *m_animation;
138 QVector<qreal> m_layout;
138 QVector<qreal> m_layout;
139 QStringList m_labelsList;
139 QStringList m_labelsList;
140 QRectF m_axisRect;
140 QRectF m_axisRect;
141 QScopedPointer<QGraphicsItemGroup> m_grid;
141 QScopedPointer<QGraphicsItemGroup> m_grid;
142 QScopedPointer<QGraphicsItemGroup> m_arrow;
142 QScopedPointer<QGraphicsItemGroup> m_arrow;
143 QScopedPointer<QGraphicsItemGroup> m_shades;
143 QScopedPointer<QGraphicsItemGroup> m_shades;
144 QScopedPointer<QGraphicsItemGroup> m_labels;
144 QScopedPointer<QGraphicsItemGroup> m_labels;
145 QScopedPointer<QGraphicsTextItem> m_title;
145 QScopedPointer<QGraphicsTextItem> m_title;
146 bool m_intervalAxis;
146 bool m_intervalAxis;
147 };
147 };
148
148
149 QTCOMMERCIALCHART_END_NAMESPACE
149 QTCOMMERCIALCHART_END_NAMESPACE
150
150
151 #endif /* CHARTAXISELEMENT_H */
151 #endif /* CHARTAXISELEMENT_H */
@@ -1,420 +1,422
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 "polarchartaxisangular_p.h"
21 #include "polarchartaxisangular_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "abstractchartlayout_p.h"
23 #include "abstractchartlayout_p.h"
24 #include "qabstractaxis.h"
24 #include "qabstractaxis.h"
25 #include "qabstractaxis_p.h"
25 #include "qabstractaxis_p.h"
26 #include <QDebug>
26 #include <QDebug>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QTextDocument>
28
29
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
31
31 PolarChartAxisAngular::PolarChartAxisAngular(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
32 PolarChartAxisAngular::PolarChartAxisAngular(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
32 : PolarChartAxis(axis, item, intervalAxis)
33 : PolarChartAxis(axis, item, intervalAxis)
33 {
34 {
34 }
35 }
35
36
36 PolarChartAxisAngular::~PolarChartAxisAngular()
37 PolarChartAxisAngular::~PolarChartAxisAngular()
37 {
38 {
38 }
39 }
39
40
40 void PolarChartAxisAngular::updateGeometry()
41 void PolarChartAxisAngular::updateGeometry()
41 {
42 {
42 QGraphicsLayoutItem::updateGeometry();
43 QGraphicsLayoutItem::updateGeometry();
43
44
44 const QVector<qreal> &layout = this->layout();
45 const QVector<qreal> &layout = this->layout();
45 if (layout.isEmpty())
46 if (layout.isEmpty())
46 return;
47 return;
47
48
48 createAxisLabels(layout);
49 createAxisLabels(layout);
49 QStringList labelList = labels();
50 QStringList labelList = labels();
50 QPointF center = axisGeometry().center();
51 QPointF center = axisGeometry().center();
51 QList<QGraphicsItem *> arrowItemList = arrowItems();
52 QList<QGraphicsItem *> arrowItemList = arrowItems();
52 QList<QGraphicsItem *> gridItemList = gridItems();
53 QList<QGraphicsItem *> gridItemList = gridItems();
53 QList<QGraphicsItem *> labelItemList = labelItems();
54 QList<QGraphicsItem *> labelItemList = labelItems();
54 QList<QGraphicsItem *> shadeItemList = shadeItems();
55 QList<QGraphicsItem *> shadeItemList = shadeItems();
55 QGraphicsTextItem *title = titleItem();
56 QGraphicsTextItem *title = titleItem();
56
57
57 QGraphicsEllipseItem *axisLine = static_cast<QGraphicsEllipseItem *>(arrowItemList.at(0));
58 QGraphicsEllipseItem *axisLine = static_cast<QGraphicsEllipseItem *>(arrowItemList.at(0));
58 axisLine->setRect(axisGeometry());
59 axisLine->setRect(axisGeometry());
59
60
60 qreal radius = axisGeometry().height() / 2.0;
61 qreal radius = axisGeometry().height() / 2.0;
61
62
62 QRectF previousLabelRect;
63 QRectF previousLabelRect;
63 QRectF firstLabelRect;
64 QRectF firstLabelRect;
64
65
65 qreal labelHeight = 0;
66 qreal labelHeight = 0;
66
67
67 bool firstShade = true;
68 bool firstShade = true;
68 bool nextTickVisible = false;
69 bool nextTickVisible = false;
69 if (layout.size())
70 if (layout.size())
70 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > 360.0);
71 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > 360.0);
71
72
72 for (int i = 0; i < layout.size(); ++i) {
73 for (int i = 0; i < layout.size(); ++i) {
73 qreal angularCoordinate = layout.at(i);
74 qreal angularCoordinate = layout.at(i);
74
75
75 QGraphicsLineItem *gridLineItem = static_cast<QGraphicsLineItem *>(gridItemList.at(i));
76 QGraphicsLineItem *gridLineItem = static_cast<QGraphicsLineItem *>(gridItemList.at(i));
76 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
77 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
77 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labelItemList.at(i));
78 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labelItemList.at(i));
78 QGraphicsPathItem *shadeItem = 0;
79 QGraphicsPathItem *shadeItem = 0;
79 if (i == 0)
80 if (i == 0)
80 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
81 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
81 else if (i % 2)
82 else if (i % 2)
82 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
83 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
83
84
84 // Ignore ticks outside valid range
85 // Ignore ticks outside valid range
85 bool currentTickVisible = nextTickVisible;
86 bool currentTickVisible = nextTickVisible;
86 if ((i == layout.size() - 1)
87 if ((i == layout.size() - 1)
87 || layout.at(i + 1) < 0.0
88 || layout.at(i + 1) < 0.0
88 || layout.at(i + 1) > 360.0) {
89 || layout.at(i + 1) > 360.0) {
89 nextTickVisible = false;
90 nextTickVisible = false;
90 } else {
91 } else {
91 nextTickVisible = true;
92 nextTickVisible = true;
92 }
93 }
93
94
94 qreal labelCoordinate = angularCoordinate;
95 qreal labelCoordinate = angularCoordinate;
95 qreal labelVisible = currentTickVisible;
96 qreal labelVisible = currentTickVisible;
96 if (intervalAxis()) {
97 if (intervalAxis()) {
97 qreal farEdge;
98 qreal farEdge;
98 if (i == (layout.size() - 1))
99 if (i == (layout.size() - 1))
99 farEdge = 360.0;
100 farEdge = 360.0;
100 else
101 else
101 farEdge = qMin(qreal(360.0), layout.at(i + 1));
102 farEdge = qMin(qreal(360.0), layout.at(i + 1));
102
103
103 // Adjust the labelCoordinate to show it if next tick is visible
104 // Adjust the labelCoordinate to show it if next tick is visible
104 if (nextTickVisible)
105 if (nextTickVisible)
105 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
106 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
106
107
107 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
108 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
108 // Don't display label once the category gets too small near the axis
109 // Don't display label once the category gets too small near the axis
109 if (labelCoordinate < 5.0 || labelCoordinate > 355.0)
110 if (labelCoordinate < 5.0 || labelCoordinate > 355.0)
110 labelVisible = false;
111 labelVisible = false;
111 else
112 else
112 labelVisible = true;
113 labelVisible = true;
113 }
114 }
114
115
115 // Need this also in label calculations, so determine it first
116 // Need this also in label calculations, so determine it first
116 QLineF tickLine(QLineF::fromPolar(radius - tickWidth(), 90.0 - angularCoordinate).p2(),
117 QLineF tickLine(QLineF::fromPolar(radius - tickWidth(), 90.0 - angularCoordinate).p2(),
117 QLineF::fromPolar(radius + tickWidth(), 90.0 - angularCoordinate).p2());
118 QLineF::fromPolar(radius + tickWidth(), 90.0 - angularCoordinate).p2());
118 tickLine.translate(center);
119 tickLine.translate(center);
119
120
120 // Angular axis label
121 // Angular axis label
121 if (axis()->labelsVisible() && labelVisible) {
122 if (axis()->labelsVisible() && labelVisible) {
122 labelItem->setHtml(labelList.at(i));
123 labelItem->setHtml(labelList.at(i));
123 const QRectF &rect = labelItem->boundingRect();
124 const QRectF &rect = labelItem->boundingRect();
124 QPointF labelCenter = rect.center();
125 QPointF labelCenter = rect.center();
125 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
126 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
126 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
127 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
127 boundingRect.moveCenter(labelCenter);
128 boundingRect.moveCenter(labelCenter);
128 QPointF positionDiff(rect.topLeft() - boundingRect.topLeft());
129 QPointF positionDiff(rect.topLeft() - boundingRect.topLeft());
129
130
130 QPointF labelPoint;
131 QPointF labelPoint;
131 if (intervalAxis()) {
132 if (intervalAxis()) {
132 QLineF labelLine = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate);
133 QLineF labelLine = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate);
133 labelLine.translate(center);
134 labelLine.translate(center);
134 labelPoint = labelLine.p2();
135 labelPoint = labelLine.p2();
135 } else {
136 } else {
136 labelPoint = tickLine.p2();
137 labelPoint = tickLine.p2();
137 }
138 }
138
139
139 QRectF labelRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
140 QRectF labelRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
140 labelItem->setPos(labelRect.topLeft() + positionDiff);
141 labelItem->setPos(labelRect.topLeft() + positionDiff);
141
142
142 // Store height for title calculations
143 // Store height for title calculations
143 qreal labelClearance = axisGeometry().top() - labelRect.top();
144 qreal labelClearance = axisGeometry().top() - labelRect.top();
144 labelHeight = qMax(labelHeight, labelClearance);
145 labelHeight = qMax(labelHeight, labelClearance);
145
146
146 // Label overlap detection
147 // Label overlap detection
147 if (i && (previousLabelRect.intersects(labelRect) || firstLabelRect.intersects(labelRect))) {
148 if (i && (previousLabelRect.intersects(labelRect) || firstLabelRect.intersects(labelRect))) {
148 labelVisible = false;
149 labelVisible = false;
149 } else {
150 } else {
150 // Store labelRect for future comparison. Some area is deducted to make things look
151 // Store labelRect for future comparison. Some area is deducted to make things look
151 // little nicer, as usually intersection happens at label corner with angular labels.
152 // little nicer, as usually intersection happens at label corner with angular labels.
152 labelRect.adjust(-2.0, -4.0, -2.0, -4.0);
153 labelRect.adjust(-2.0, -4.0, -2.0, -4.0);
153 if (firstLabelRect.isEmpty())
154 if (firstLabelRect.isEmpty())
154 firstLabelRect = labelRect;
155 firstLabelRect = labelRect;
155
156
156 previousLabelRect = labelRect;
157 previousLabelRect = labelRect;
157 labelVisible = true;
158 labelVisible = true;
158 }
159 }
159 }
160 }
160
161
161 labelItem->setVisible(labelVisible);
162 labelItem->setVisible(labelVisible);
162 if (!currentTickVisible) {
163 if (!currentTickVisible) {
163 gridLineItem->setVisible(false);
164 gridLineItem->setVisible(false);
164 tickItem->setVisible(false);
165 tickItem->setVisible(false);
165 if (shadeItem)
166 if (shadeItem)
166 shadeItem->setVisible(false);
167 shadeItem->setVisible(false);
167 continue;
168 continue;
168 }
169 }
169
170
170 // Angular grid line
171 // Angular grid line
171 QLineF gridLine = QLineF::fromPolar(radius, 90.0 - angularCoordinate);
172 QLineF gridLine = QLineF::fromPolar(radius, 90.0 - angularCoordinate);
172 gridLine.translate(center);
173 gridLine.translate(center);
173 gridLineItem->setLine(gridLine);
174 gridLineItem->setLine(gridLine);
174 gridLineItem->setVisible(true);
175 gridLineItem->setVisible(true);
175
176
176 // Tick
177 // Tick
177 tickItem->setLine(tickLine);
178 tickItem->setLine(tickLine);
178 tickItem->setVisible(true);
179 tickItem->setVisible(true);
179
180
180 // Shades
181 // Shades
181 if (i % 2 || (i == 0 && !nextTickVisible)) {
182 if (i % 2 || (i == 0 && !nextTickVisible)) {
182 QPainterPath path;
183 QPainterPath path;
183 path.moveTo(center);
184 path.moveTo(center);
184 if (i == 0) {
185 if (i == 0) {
185 // If first tick is also the last, we need to custom fill the first partial arc
186 // If first tick is also the last, we need to custom fill the first partial arc
186 // or it won't get filled.
187 // or it won't get filled.
187 path.arcTo(axisGeometry(), 90.0 - layout.at(0), layout.at(0));
188 path.arcTo(axisGeometry(), 90.0 - layout.at(0), layout.at(0));
188 path.closeSubpath();
189 path.closeSubpath();
189 } else {
190 } else {
190 qreal nextCoordinate;
191 qreal nextCoordinate;
191 if (!nextTickVisible) // Last visible tick
192 if (!nextTickVisible) // Last visible tick
192 nextCoordinate = 360.0;
193 nextCoordinate = 360.0;
193 else
194 else
194 nextCoordinate = layout.at(i + 1);
195 nextCoordinate = layout.at(i + 1);
195 qreal arcSpan = angularCoordinate - nextCoordinate;
196 qreal arcSpan = angularCoordinate - nextCoordinate;
196 path.arcTo(axisGeometry(), 90.0 - angularCoordinate, arcSpan);
197 path.arcTo(axisGeometry(), 90.0 - angularCoordinate, arcSpan);
197 path.closeSubpath();
198 path.closeSubpath();
198
199
199 // Add additional arc for first shade item if there is a partial arc to be filled
200 // Add additional arc for first shade item if there is a partial arc to be filled
200 if (firstShade) {
201 if (firstShade) {
201 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
202 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
202 if (layout.at(i - 1) > 0.0) {
203 if (layout.at(i - 1) > 0.0) {
203 QPainterPath specialPath;
204 QPainterPath specialPath;
204 specialPath.moveTo(center);
205 specialPath.moveTo(center);
205 specialPath.arcTo(axisGeometry(), 90.0 - layout.at(i - 1), layout.at(i - 1));
206 specialPath.arcTo(axisGeometry(), 90.0 - layout.at(i - 1), layout.at(i - 1));
206 specialPath.closeSubpath();
207 specialPath.closeSubpath();
207 specialShadeItem->setPath(specialPath);
208 specialShadeItem->setPath(specialPath);
208 specialShadeItem->setVisible(true);
209 specialShadeItem->setVisible(true);
209 } else {
210 } else {
210 specialShadeItem->setVisible(false);
211 specialShadeItem->setVisible(false);
211 }
212 }
212 }
213 }
213 }
214 }
214 shadeItem->setPath(path);
215 shadeItem->setPath(path);
215 shadeItem->setVisible(true);
216 shadeItem->setVisible(true);
216 firstShade = false;
217 firstShade = false;
217 }
218 }
218 }
219 }
219
220
220 // Title, centered above the chart
221 // Title, centered above the chart
221 QString titleText = axis()->titleText();
222 QString titleText = axis()->titleText();
222 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
223 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
223 QRectF dummyRect;
224 QRectF dummyRect;
224 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), axisGeometry().width(), Qt::Horizontal, dummyRect));
225 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), axisGeometry().width(), Qt::Horizontal, dummyRect));
225
226
226 QRectF titleBoundingRect = title->boundingRect();
227 QRectF titleBoundingRect = title->boundingRect();
227 QPointF titleCenter = center - titleBoundingRect.center();
228 QPointF titleCenter = center - titleBoundingRect.center();
228 title->setPos(titleCenter.x(), axisGeometry().top() - titlePadding() * 2.0 - titleBoundingRect.height() - labelHeight);
229 title->setPos(titleCenter.x(), axisGeometry().top() - titlePadding() * 2.0 - titleBoundingRect.height() - labelHeight);
229 }
230 }
230 }
231 }
231
232
232 Qt::Orientation PolarChartAxisAngular::orientation() const
233 Qt::Orientation PolarChartAxisAngular::orientation() const
233 {
234 {
234 return Qt::Horizontal;
235 return Qt::Horizontal;
235 }
236 }
236
237
237 void PolarChartAxisAngular::createItems(int count)
238 void PolarChartAxisAngular::createItems(int count)
238 {
239 {
239 if (arrowItems().count() == 0) {
240 if (arrowItems().count() == 0) {
240 // angular axis line
241 // angular axis line
241 QGraphicsEllipseItem *arrow = new QGraphicsEllipseItem(presenter()->rootItem());
242 QGraphicsEllipseItem *arrow = new QGraphicsEllipseItem(presenter()->rootItem());
242 arrow->setPen(axis()->linePen());
243 arrow->setPen(axis()->linePen());
243 arrowGroup()->addToGroup(arrow);
244 arrowGroup()->addToGroup(arrow);
244 }
245 }
245
246
246 for (int i = 0; i < count; ++i) {
247 for (int i = 0; i < count; ++i) {
247 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
248 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
248 QGraphicsLineItem *grid = new QGraphicsLineItem(presenter()->rootItem());
249 QGraphicsLineItem *grid = new QGraphicsLineItem(presenter()->rootItem());
249 QGraphicsTextItem *label = new QGraphicsTextItem(presenter()->rootItem());
250 QGraphicsTextItem *label = new QGraphicsTextItem(presenter()->rootItem());
251 label->document()->setDocumentMargin(ChartPresenter::textMargin());
250 QGraphicsTextItem *title = titleItem();
252 QGraphicsTextItem *title = titleItem();
251 arrow->setPen(axis()->linePen());
253 arrow->setPen(axis()->linePen());
252 grid->setPen(axis()->gridLinePen());
254 grid->setPen(axis()->gridLinePen());
253 label->setFont(axis()->labelsFont());
255 label->setFont(axis()->labelsFont());
254 label->setDefaultTextColor(axis()->labelsBrush().color());
256 label->setDefaultTextColor(axis()->labelsBrush().color());
255 label->setRotation(axis()->labelsAngle());
257 label->setRotation(axis()->labelsAngle());
256 title->setFont(axis()->titleFont());
258 title->setFont(axis()->titleFont());
257 title->setDefaultTextColor(axis()->titleBrush().color());
259 title->setDefaultTextColor(axis()->titleBrush().color());
258 title->setHtml(axis()->titleText());
260 title->setHtml(axis()->titleText());
259 arrowGroup()->addToGroup(arrow);
261 arrowGroup()->addToGroup(arrow);
260 gridGroup()->addToGroup(grid);
262 gridGroup()->addToGroup(grid);
261 labelGroup()->addToGroup(label);
263 labelGroup()->addToGroup(label);
262 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
264 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
263 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
265 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
264 shade->setPen(axis()->shadesPen());
266 shade->setPen(axis()->shadesPen());
265 shade->setBrush(axis()->shadesBrush());
267 shade->setBrush(axis()->shadesBrush());
266 shadeGroup()->addToGroup(shade);
268 shadeGroup()->addToGroup(shade);
267 }
269 }
268 }
270 }
269 }
271 }
270
272
271 void PolarChartAxisAngular::handleArrowPenChanged(const QPen &pen)
273 void PolarChartAxisAngular::handleArrowPenChanged(const QPen &pen)
272 {
274 {
273 bool first = true;
275 bool first = true;
274 foreach (QGraphicsItem *item, arrowItems()) {
276 foreach (QGraphicsItem *item, arrowItems()) {
275 if (first) {
277 if (first) {
276 first = false;
278 first = false;
277 // First arrow item is the outer circle of axis
279 // First arrow item is the outer circle of axis
278 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
280 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
279 } else {
281 } else {
280 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
282 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
281 }
283 }
282 }
284 }
283 }
285 }
284
286
285 void PolarChartAxisAngular::handleGridPenChanged(const QPen &pen)
287 void PolarChartAxisAngular::handleGridPenChanged(const QPen &pen)
286 {
288 {
287 foreach (QGraphicsItem *item, gridItems())
289 foreach (QGraphicsItem *item, gridItems())
288 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
290 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
289 }
291 }
290
292
291 QSizeF PolarChartAxisAngular::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
293 QSizeF PolarChartAxisAngular::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
292 {
294 {
293 Q_UNUSED(which);
295 Q_UNUSED(which);
294 Q_UNUSED(constraint);
296 Q_UNUSED(constraint);
295 return QSizeF(-1, -1);
297 return QSizeF(-1, -1);
296 }
298 }
297
299
298 qreal PolarChartAxisAngular::preferredAxisRadius(const QSizeF &maxSize)
300 qreal PolarChartAxisAngular::preferredAxisRadius(const QSizeF &maxSize)
299 {
301 {
300 qreal radius = maxSize.height() / 2.0;
302 qreal radius = maxSize.height() / 2.0;
301 if (maxSize.width() < maxSize.height())
303 if (maxSize.width() < maxSize.height())
302 radius = maxSize.width() / 2.0;
304 radius = maxSize.width() / 2.0;
303
305
304 if (axis()->labelsVisible()) {
306 if (axis()->labelsVisible()) {
305 QVector<qreal> layout = calculateLayout();
307 QVector<qreal> layout = calculateLayout();
306 if (layout.isEmpty())
308 if (layout.isEmpty())
307 return radius;
309 return radius;
308
310
309 createAxisLabels(layout);
311 createAxisLabels(layout);
310 QStringList labelList = labels();
312 QStringList labelList = labels();
311 QFont font = axis()->labelsFont();
313 QFont font = axis()->labelsFont();
312
314
313 QRectF maxRect;
315 QRectF maxRect;
314 maxRect.setSize(maxSize);
316 maxRect.setSize(maxSize);
315 maxRect.moveCenter(QPointF(0.0, 0.0));
317 maxRect.moveCenter(QPointF(0.0, 0.0));
316
318
317 // This is a horrible way to find out the maximum radius for angular axis and its labels.
319 // This is a horrible way to find out the maximum radius for angular axis and its labels.
318 // It just increments the radius down until everyhing fits the constraint size.
320 // It just increments the radius down until everyhing fits the constraint size.
319 // Proper way would be to actually calculate it but this seems to work reasonably fast as it is.
321 // Proper way would be to actually calculate it but this seems to work reasonably fast as it is.
320 bool nextTickVisible = false;
322 bool nextTickVisible = false;
321 for (int i = 0; i < layout.size(); ) {
323 for (int i = 0; i < layout.size(); ) {
322 if ((i == layout.size() - 1)
324 if ((i == layout.size() - 1)
323 || layout.at(i + 1) < 0.0
325 || layout.at(i + 1) < 0.0
324 || layout.at(i + 1) > 360.0) {
326 || layout.at(i + 1) > 360.0) {
325 nextTickVisible = false;
327 nextTickVisible = false;
326 } else {
328 } else {
327 nextTickVisible = true;
329 nextTickVisible = true;
328 }
330 }
329
331
330 qreal labelCoordinate = layout.at(i);
332 qreal labelCoordinate = layout.at(i);
331 qreal labelVisible;
333 qreal labelVisible;
332
334
333 if (intervalAxis()) {
335 if (intervalAxis()) {
334 qreal farEdge;
336 qreal farEdge;
335 if (i == (layout.size() - 1))
337 if (i == (layout.size() - 1))
336 farEdge = 360.0;
338 farEdge = 360.0;
337 else
339 else
338 farEdge = qMin(qreal(360.0), layout.at(i + 1));
340 farEdge = qMin(qreal(360.0), layout.at(i + 1));
339
341
340 // Adjust the labelCoordinate to show it if next tick is visible
342 // Adjust the labelCoordinate to show it if next tick is visible
341 if (nextTickVisible)
343 if (nextTickVisible)
342 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
344 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
343
345
344 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
346 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
345 }
347 }
346
348
347 if (labelCoordinate < 0.0 || labelCoordinate > 360.0)
349 if (labelCoordinate < 0.0 || labelCoordinate > 360.0)
348 labelVisible = false;
350 labelVisible = false;
349 else
351 else
350 labelVisible = true;
352 labelVisible = true;
351
353
352 if (!labelVisible) {
354 if (!labelVisible) {
353 i++;
355 i++;
354 continue;
356 continue;
355 }
357 }
356
358
357 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
359 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
358 QPointF labelPoint = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate).p2();
360 QPointF labelPoint = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate).p2();
359
361
360 boundingRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
362 boundingRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
361 QRectF intersectRect = maxRect.intersected(boundingRect);
363 QRectF intersectRect = maxRect.intersected(boundingRect);
362 if (boundingRect.isEmpty() || intersectRect == boundingRect) {
364 if (boundingRect.isEmpty() || intersectRect == boundingRect) {
363 i++;
365 i++;
364 } else {
366 } else {
365 qreal reduction(0.0);
367 qreal reduction(0.0);
366 // If there is no intersection, reduce by smallest dimension of label rect to be on the safe side
368 // If there is no intersection, reduce by smallest dimension of label rect to be on the safe side
367 if (intersectRect.isEmpty()) {
369 if (intersectRect.isEmpty()) {
368 reduction = qMin(boundingRect.height(), boundingRect.width());
370 reduction = qMin(boundingRect.height(), boundingRect.width());
369 } else {
371 } else {
370 // Approximate needed radius reduction is the amount label rect exceeds max rect in either dimension.
372 // Approximate needed radius reduction is the amount label rect exceeds max rect in either dimension.
371 // Could be further optimized by figuring out the proper math how to calculate exact needed reduction.
373 // Could be further optimized by figuring out the proper math how to calculate exact needed reduction.
372 reduction = qMax(boundingRect.height() - intersectRect.height(),
374 reduction = qMax(boundingRect.height() - intersectRect.height(),
373 boundingRect.width() - intersectRect.width());
375 boundingRect.width() - intersectRect.width());
374 }
376 }
375 // Typically the approximated reduction is little low, so add one
377 // Typically the approximated reduction is little low, so add one
376 radius -= (reduction + 1.0);
378 radius -= (reduction + 1.0);
377
379
378 if (radius < 1.0) // safeguard
380 if (radius < 1.0) // safeguard
379 return 1.0;
381 return 1.0;
380 }
382 }
381 }
383 }
382 }
384 }
383
385
384 if (!axis()->titleText().isEmpty() && axis()->isTitleVisible()) {
386 if (!axis()->titleText().isEmpty() && axis()->isTitleVisible()) {
385 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
387 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
386
388
387 radius -= titlePadding() + (titleRect.height() / 2.0);
389 radius -= titlePadding() + (titleRect.height() / 2.0);
388 if (radius < 1.0) // safeguard
390 if (radius < 1.0) // safeguard
389 return 1.0;
391 return 1.0;
390 }
392 }
391
393
392 return radius;
394 return radius;
393 }
395 }
394
396
395 QRectF PolarChartAxisAngular::moveLabelToPosition(qreal angularCoordinate, QPointF labelPoint, QRectF labelRect) const
397 QRectF PolarChartAxisAngular::moveLabelToPosition(qreal angularCoordinate, QPointF labelPoint, QRectF labelRect) const
396 {
398 {
397 if (angularCoordinate == 0.0)
399 if (angularCoordinate == 0.0)
398 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
400 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
399 else if (angularCoordinate < 90.0)
401 else if (angularCoordinate < 90.0)
400 labelRect.moveBottomLeft(labelPoint);
402 labelRect.moveBottomLeft(labelPoint);
401 else if (angularCoordinate == 90.0)
403 else if (angularCoordinate == 90.0)
402 labelRect.moveCenter(labelPoint + QPointF(labelRect.width() / 2.0 + 2.0, 0)); // +2 so that it does not hit the radial axis
404 labelRect.moveCenter(labelPoint + QPointF(labelRect.width() / 2.0 + 2.0, 0)); // +2 so that it does not hit the radial axis
403 else if (angularCoordinate < 180.0)
405 else if (angularCoordinate < 180.0)
404 labelRect.moveTopLeft(labelPoint);
406 labelRect.moveTopLeft(labelPoint);
405 else if (angularCoordinate == 180.0)
407 else if (angularCoordinate == 180.0)
406 labelRect.moveCenter(labelPoint + QPointF(0, labelRect.height() / 2.0));
408 labelRect.moveCenter(labelPoint + QPointF(0, labelRect.height() / 2.0));
407 else if (angularCoordinate < 270.0)
409 else if (angularCoordinate < 270.0)
408 labelRect.moveTopRight(labelPoint);
410 labelRect.moveTopRight(labelPoint);
409 else if (angularCoordinate == 270.0)
411 else if (angularCoordinate == 270.0)
410 labelRect.moveCenter(labelPoint + QPointF(-labelRect.width() / 2.0 - 2.0, 0)); // -2 so that it does not hit the radial axis
412 labelRect.moveCenter(labelPoint + QPointF(-labelRect.width() / 2.0 - 2.0, 0)); // -2 so that it does not hit the radial axis
411 else if (angularCoordinate < 360.0)
413 else if (angularCoordinate < 360.0)
412 labelRect.moveBottomRight(labelPoint);
414 labelRect.moveBottomRight(labelPoint);
413 else
415 else
414 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
416 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
415 return labelRect;
417 return labelRect;
416 }
418 }
417
419
418 #include "moc_polarchartaxisangular_p.cpp"
420 #include "moc_polarchartaxisangular_p.cpp"
419
421
420 QTCOMMERCIALCHART_END_NAMESPACE
422 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,289 +1,291
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 "polarchartaxisradial_p.h"
21 #include "polarchartaxisradial_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "abstractchartlayout_p.h"
23 #include "abstractchartlayout_p.h"
24 #include "qabstractaxis_p.h"
24 #include "qabstractaxis_p.h"
25 #include "linearrowitem_p.h"
25 #include "linearrowitem_p.h"
26 #include <QTextDocument>
26
27
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
29
29 PolarChartAxisRadial::PolarChartAxisRadial(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
30 PolarChartAxisRadial::PolarChartAxisRadial(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
30 : PolarChartAxis(axis, item, intervalAxis)
31 : PolarChartAxis(axis, item, intervalAxis)
31 {
32 {
32 }
33 }
33
34
34 PolarChartAxisRadial::~PolarChartAxisRadial()
35 PolarChartAxisRadial::~PolarChartAxisRadial()
35 {
36 {
36 }
37 }
37
38
38 void PolarChartAxisRadial::updateGeometry()
39 void PolarChartAxisRadial::updateGeometry()
39 {
40 {
40 const QVector<qreal> &layout = this->layout();
41 const QVector<qreal> &layout = this->layout();
41 if (layout.isEmpty())
42 if (layout.isEmpty())
42 return;
43 return;
43
44
44 createAxisLabels(layout);
45 createAxisLabels(layout);
45 QStringList labelList = labels();
46 QStringList labelList = labels();
46 QPointF center = axisGeometry().center();
47 QPointF center = axisGeometry().center();
47 QList<QGraphicsItem *> arrowItemList = arrowItems();
48 QList<QGraphicsItem *> arrowItemList = arrowItems();
48 QList<QGraphicsItem *> gridItemList = gridItems();
49 QList<QGraphicsItem *> gridItemList = gridItems();
49 QList<QGraphicsItem *> labelItemList = labelItems();
50 QList<QGraphicsItem *> labelItemList = labelItems();
50 QList<QGraphicsItem *> shadeItemList = shadeItems();
51 QList<QGraphicsItem *> shadeItemList = shadeItems();
51 QGraphicsTextItem* title = titleItem();
52 QGraphicsTextItem* title = titleItem();
52 qreal radius = axisGeometry().height() / 2.0;
53 qreal radius = axisGeometry().height() / 2.0;
53
54
54 QLineF line(center, center + QPointF(0, -radius));
55 QLineF line(center, center + QPointF(0, -radius));
55 QGraphicsLineItem *axisLine = static_cast<QGraphicsLineItem *>(arrowItemList.at(0));
56 QGraphicsLineItem *axisLine = static_cast<QGraphicsLineItem *>(arrowItemList.at(0));
56 axisLine->setLine(line);
57 axisLine->setLine(line);
57
58
58 QRectF previousLabelRect;
59 QRectF previousLabelRect;
59 bool firstShade = true;
60 bool firstShade = true;
60 bool nextTickVisible = false;
61 bool nextTickVisible = false;
61 if (layout.size())
62 if (layout.size())
62 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > radius);
63 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > radius);
63
64
64 for (int i = 0; i < layout.size(); ++i) {
65 for (int i = 0; i < layout.size(); ++i) {
65 qreal radialCoordinate = layout.at(i);
66 qreal radialCoordinate = layout.at(i);
66
67
67 QGraphicsEllipseItem *gridItem = static_cast<QGraphicsEllipseItem *>(gridItemList.at(i));
68 QGraphicsEllipseItem *gridItem = static_cast<QGraphicsEllipseItem *>(gridItemList.at(i));
68 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
69 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
69 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labelItemList.at(i));
70 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labelItemList.at(i));
70 QGraphicsPathItem *shadeItem = 0;
71 QGraphicsPathItem *shadeItem = 0;
71 if (i == 0)
72 if (i == 0)
72 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
73 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
73 else if (i % 2)
74 else if (i % 2)
74 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
75 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
75
76
76 // Ignore ticks outside valid range
77 // Ignore ticks outside valid range
77 bool currentTickVisible = nextTickVisible;
78 bool currentTickVisible = nextTickVisible;
78 if ((i == layout.size() - 1)
79 if ((i == layout.size() - 1)
79 || layout.at(i + 1) < 0.0
80 || layout.at(i + 1) < 0.0
80 || layout.at(i + 1) > radius) {
81 || layout.at(i + 1) > radius) {
81 nextTickVisible = false;
82 nextTickVisible = false;
82 } else {
83 } else {
83 nextTickVisible = true;
84 nextTickVisible = true;
84 }
85 }
85
86
86 qreal labelCoordinate = radialCoordinate;
87 qreal labelCoordinate = radialCoordinate;
87 qreal labelVisible = currentTickVisible;
88 qreal labelVisible = currentTickVisible;
88 qreal labelPad = labelPadding() / 2.0;
89 qreal labelPad = labelPadding() / 2.0;
89 if (intervalAxis()) {
90 if (intervalAxis()) {
90 qreal farEdge;
91 qreal farEdge;
91 if (i == (layout.size() - 1))
92 if (i == (layout.size() - 1))
92 farEdge = radius;
93 farEdge = radius;
93 else
94 else
94 farEdge = qMin(radius, layout.at(i + 1));
95 farEdge = qMin(radius, layout.at(i + 1));
95
96
96 // Adjust the labelCoordinate to show it if next tick is visible
97 // Adjust the labelCoordinate to show it if next tick is visible
97 if (nextTickVisible)
98 if (nextTickVisible)
98 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
99 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
99
100
100 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
101 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
101 if (labelCoordinate > 0.0 && labelCoordinate < radius)
102 if (labelCoordinate > 0.0 && labelCoordinate < radius)
102 labelVisible = true;
103 labelVisible = true;
103 else
104 else
104 labelVisible = false;
105 labelVisible = false;
105 }
106 }
106
107
107 // Radial axis label
108 // Radial axis label
108 if (axis()->labelsVisible() && labelVisible) {
109 if (axis()->labelsVisible() && labelVisible) {
109 labelItem->setHtml(labelList.at(i));
110 labelItem->setHtml(labelList.at(i));
110 QRectF labelRect = labelItem->boundingRect();
111 QRectF labelRect = labelItem->boundingRect();
111 QPointF labelCenter = labelRect.center();
112 QPointF labelCenter = labelRect.center();
112 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
113 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
113 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
114 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
114 boundingRect.moveCenter(labelCenter);
115 boundingRect.moveCenter(labelCenter);
115 QPointF positionDiff(labelRect.topLeft() - boundingRect.topLeft());
116 QPointF positionDiff(labelRect.topLeft() - boundingRect.topLeft());
116 QPointF labelPoint = center;
117 QPointF labelPoint = center;
117 if (intervalAxis())
118 if (intervalAxis())
118 labelPoint += QPointF(labelPad, -labelCoordinate - (boundingRect.height() / 2.0));
119 labelPoint += QPointF(labelPad, -labelCoordinate - (boundingRect.height() / 2.0));
119 else
120 else
120 labelPoint += QPointF(labelPad, labelPad - labelCoordinate);
121 labelPoint += QPointF(labelPad, labelPad - labelCoordinate);
121 labelRect.moveTopLeft(labelPoint);
122 labelRect.moveTopLeft(labelPoint);
122 labelItem->setPos(labelRect.topLeft() + positionDiff);
123 labelItem->setPos(labelRect.topLeft() + positionDiff);
123
124
124 // Label overlap detection
125 // Label overlap detection
125 labelRect.setSize(boundingRect.size());
126 labelRect.setSize(boundingRect.size());
126 if ((i && previousLabelRect.intersects(labelRect))
127 if ((i && previousLabelRect.intersects(labelRect))
127 || !axisGeometry().contains(labelRect)) {
128 || !axisGeometry().contains(labelRect)) {
128 labelVisible = false;
129 labelVisible = false;
129 } else {
130 } else {
130 previousLabelRect = labelRect;
131 previousLabelRect = labelRect;
131 labelVisible = true;
132 labelVisible = true;
132 }
133 }
133 }
134 }
134
135
135 labelItem->setVisible(labelVisible);
136 labelItem->setVisible(labelVisible);
136 if (!currentTickVisible) {
137 if (!currentTickVisible) {
137 gridItem->setVisible(false);
138 gridItem->setVisible(false);
138 tickItem->setVisible(false);
139 tickItem->setVisible(false);
139 if (shadeItem)
140 if (shadeItem)
140 shadeItem->setVisible(false);
141 shadeItem->setVisible(false);
141 continue;
142 continue;
142 }
143 }
143
144
144 // Radial grid line
145 // Radial grid line
145 QRectF gridRect;
146 QRectF gridRect;
146 gridRect.setWidth(radialCoordinate * 2.0);
147 gridRect.setWidth(radialCoordinate * 2.0);
147 gridRect.setHeight(radialCoordinate * 2.0);
148 gridRect.setHeight(radialCoordinate * 2.0);
148 gridRect.moveCenter(center);
149 gridRect.moveCenter(center);
149
150
150 gridItem->setRect(gridRect);
151 gridItem->setRect(gridRect);
151 gridItem->setVisible(true);
152 gridItem->setVisible(true);
152
153
153 // Tick
154 // Tick
154 QLineF tickLine(-tickWidth(), 0.0, tickWidth(), 0.0);
155 QLineF tickLine(-tickWidth(), 0.0, tickWidth(), 0.0);
155 tickLine.translate(center.rx(), gridRect.top());
156 tickLine.translate(center.rx(), gridRect.top());
156 tickItem->setLine(tickLine);
157 tickItem->setLine(tickLine);
157 tickItem->setVisible(true);
158 tickItem->setVisible(true);
158
159
159 // Shades
160 // Shades
160 if (i % 2 || (i == 0 && !nextTickVisible)) {
161 if (i % 2 || (i == 0 && !nextTickVisible)) {
161 QPainterPath path;
162 QPainterPath path;
162 if (i == 0) {
163 if (i == 0) {
163 // If first tick is also the last, we need to custom fill the inner circle
164 // If first tick is also the last, we need to custom fill the inner circle
164 // or it won't get filled.
165 // or it won't get filled.
165 QRectF innerCircle(0.0, 0.0, layout.at(0) * 2.0, layout.at(0) * 2.0);
166 QRectF innerCircle(0.0, 0.0, layout.at(0) * 2.0, layout.at(0) * 2.0);
166 innerCircle.moveCenter(center);
167 innerCircle.moveCenter(center);
167 path.addEllipse(innerCircle);
168 path.addEllipse(innerCircle);
168 } else {
169 } else {
169 QRectF otherGridRect;
170 QRectF otherGridRect;
170 if (!nextTickVisible) { // Last visible tick
171 if (!nextTickVisible) { // Last visible tick
171 otherGridRect = axisGeometry();
172 otherGridRect = axisGeometry();
172 } else {
173 } else {
173 qreal otherGridRectDimension = layout.at(i + 1) * 2.0;
174 qreal otherGridRectDimension = layout.at(i + 1) * 2.0;
174 otherGridRect.setWidth(otherGridRectDimension);
175 otherGridRect.setWidth(otherGridRectDimension);
175 otherGridRect.setHeight(otherGridRectDimension);
176 otherGridRect.setHeight(otherGridRectDimension);
176 otherGridRect.moveCenter(center);
177 otherGridRect.moveCenter(center);
177 }
178 }
178 path.addEllipse(gridRect);
179 path.addEllipse(gridRect);
179 path.addEllipse(otherGridRect);
180 path.addEllipse(otherGridRect);
180
181
181 // Add additional shading in first visible shade item if there is a partial tick
182 // Add additional shading in first visible shade item if there is a partial tick
182 // to be filled at the center (log & category axes)
183 // to be filled at the center (log & category axes)
183 if (firstShade) {
184 if (firstShade) {
184 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
185 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
185 if (layout.at(i - 1) > 0.0) {
186 if (layout.at(i - 1) > 0.0) {
186 QRectF innerCircle(0.0, 0.0, layout.at(i - 1) * 2.0, layout.at(i - 1) * 2.0);
187 QRectF innerCircle(0.0, 0.0, layout.at(i - 1) * 2.0, layout.at(i - 1) * 2.0);
187 innerCircle.moveCenter(center);
188 innerCircle.moveCenter(center);
188 QPainterPath specialPath;
189 QPainterPath specialPath;
189 specialPath.addEllipse(innerCircle);
190 specialPath.addEllipse(innerCircle);
190 specialShadeItem->setPath(specialPath);
191 specialShadeItem->setPath(specialPath);
191 specialShadeItem->setVisible(true);
192 specialShadeItem->setVisible(true);
192 } else {
193 } else {
193 specialShadeItem->setVisible(false);
194 specialShadeItem->setVisible(false);
194 }
195 }
195 }
196 }
196 }
197 }
197 shadeItem->setPath(path);
198 shadeItem->setPath(path);
198 shadeItem->setVisible(true);
199 shadeItem->setVisible(true);
199 firstShade = false;
200 firstShade = false;
200 }
201 }
201 }
202 }
202
203
203 // Title, along the 0 axis
204 // Title, along the 0 axis
204 QString titleText = axis()->titleText();
205 QString titleText = axis()->titleText();
205 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
206 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
206 QRectF dummyRect;
207 QRectF dummyRect;
207 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), radius, Qt::Horizontal, dummyRect));
208 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), radius, Qt::Horizontal, dummyRect));
208
209
209 QRectF titleBoundingRect = title->boundingRect();
210 QRectF titleBoundingRect = title->boundingRect();
210 QPointF titleCenter = titleBoundingRect.center();
211 QPointF titleCenter = titleBoundingRect.center();
211 QPointF arrowCenter = axisLine->boundingRect().center();
212 QPointF arrowCenter = axisLine->boundingRect().center();
212 QPointF titleCenterDiff = arrowCenter - titleCenter;
213 QPointF titleCenterDiff = arrowCenter - titleCenter;
213 title->setPos(titleCenterDiff.x() - titlePadding() - (titleBoundingRect.height() / 2.0), titleCenterDiff.y());
214 title->setPos(titleCenterDiff.x() - titlePadding() - (titleBoundingRect.height() / 2.0), titleCenterDiff.y());
214 title->setTransformOriginPoint(titleCenter);
215 title->setTransformOriginPoint(titleCenter);
215 title->setRotation(270.0);
216 title->setRotation(270.0);
216 }
217 }
217
218
218 QGraphicsLayoutItem::updateGeometry();
219 QGraphicsLayoutItem::updateGeometry();
219 }
220 }
220
221
221 Qt::Orientation PolarChartAxisRadial::orientation() const
222 Qt::Orientation PolarChartAxisRadial::orientation() const
222 {
223 {
223 return Qt::Vertical;
224 return Qt::Vertical;
224 }
225 }
225
226
226 void PolarChartAxisRadial::createItems(int count)
227 void PolarChartAxisRadial::createItems(int count)
227 {
228 {
228 if (arrowItems().count() == 0) {
229 if (arrowItems().count() == 0) {
229 // radial axis center line
230 // radial axis center line
230 QGraphicsLineItem *arrow = new LineArrowItem(this, presenter()->rootItem());
231 QGraphicsLineItem *arrow = new LineArrowItem(this, presenter()->rootItem());
231 arrow->setPen(axis()->linePen());
232 arrow->setPen(axis()->linePen());
232 arrowGroup()->addToGroup(arrow);
233 arrowGroup()->addToGroup(arrow);
233 }
234 }
234
235
235 for (int i = 0; i < count; ++i) {
236 for (int i = 0; i < count; ++i) {
236 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
237 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
237 QGraphicsEllipseItem *grid = new QGraphicsEllipseItem(presenter()->rootItem());
238 QGraphicsEllipseItem *grid = new QGraphicsEllipseItem(presenter()->rootItem());
238 QGraphicsTextItem *label = new QGraphicsTextItem(presenter()->rootItem());
239 QGraphicsTextItem *label = new QGraphicsTextItem(presenter()->rootItem());
240 label->document()->setDocumentMargin(ChartPresenter::textMargin());
239 QGraphicsTextItem *title = titleItem();
241 QGraphicsTextItem *title = titleItem();
240 arrow->setPen(axis()->linePen());
242 arrow->setPen(axis()->linePen());
241 grid->setPen(axis()->gridLinePen());
243 grid->setPen(axis()->gridLinePen());
242 label->setFont(axis()->labelsFont());
244 label->setFont(axis()->labelsFont());
243 label->setDefaultTextColor(axis()->labelsBrush().color());
245 label->setDefaultTextColor(axis()->labelsBrush().color());
244 label->setRotation(axis()->labelsAngle());
246 label->setRotation(axis()->labelsAngle());
245 title->setFont(axis()->titleFont());
247 title->setFont(axis()->titleFont());
246 title->setDefaultTextColor(axis()->titleBrush().color());
248 title->setDefaultTextColor(axis()->titleBrush().color());
247 title->setHtml(axis()->titleText());
249 title->setHtml(axis()->titleText());
248 arrowGroup()->addToGroup(arrow);
250 arrowGroup()->addToGroup(arrow);
249 gridGroup()->addToGroup(grid);
251 gridGroup()->addToGroup(grid);
250 labelGroup()->addToGroup(label);
252 labelGroup()->addToGroup(label);
251 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
253 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
252 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
254 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
253 shade->setPen(axis()->shadesPen());
255 shade->setPen(axis()->shadesPen());
254 shade->setBrush(axis()->shadesBrush());
256 shade->setBrush(axis()->shadesBrush());
255 shadeGroup()->addToGroup(shade);
257 shadeGroup()->addToGroup(shade);
256 }
258 }
257 }
259 }
258 }
260 }
259
261
260 void PolarChartAxisRadial::handleArrowPenChanged(const QPen &pen)
262 void PolarChartAxisRadial::handleArrowPenChanged(const QPen &pen)
261 {
263 {
262 foreach (QGraphicsItem *item, arrowItems())
264 foreach (QGraphicsItem *item, arrowItems())
263 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
265 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
264 }
266 }
265
267
266 void PolarChartAxisRadial::handleGridPenChanged(const QPen &pen)
268 void PolarChartAxisRadial::handleGridPenChanged(const QPen &pen)
267 {
269 {
268 foreach (QGraphicsItem *item, gridItems())
270 foreach (QGraphicsItem *item, gridItems())
269 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
271 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
270 }
272 }
271
273
272 QSizeF PolarChartAxisRadial::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
274 QSizeF PolarChartAxisRadial::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
273 {
275 {
274 Q_UNUSED(which);
276 Q_UNUSED(which);
275 Q_UNUSED(constraint);
277 Q_UNUSED(constraint);
276 return QSizeF(-1.0, -1.0);
278 return QSizeF(-1.0, -1.0);
277 }
279 }
278
280
279 qreal PolarChartAxisRadial::preferredAxisRadius(const QSizeF &maxSize)
281 qreal PolarChartAxisRadial::preferredAxisRadius(const QSizeF &maxSize)
280 {
282 {
281 qreal radius = maxSize.height() / 2.0;
283 qreal radius = maxSize.height() / 2.0;
282 if (maxSize.width() < maxSize.height())
284 if (maxSize.width() < maxSize.height())
283 radius = maxSize.width() / 2.0;
285 radius = maxSize.width() / 2.0;
284 return radius;
286 return radius;
285 }
287 }
286
288
287 #include "moc_polarchartaxisradial_p.cpp"
289 #include "moc_polarchartaxisradial_p.cpp"
288
290
289 QTCOMMERCIALCHART_END_NAMESPACE
291 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,229 +1,229
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 "verticalaxis_p.h"
21 #include "verticalaxis_p.h"
22 #include "qabstractaxis.h"
22 #include "qabstractaxis.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include <QDebug>
24 #include <QDebug>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 VerticalAxis::VerticalAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
28 VerticalAxis::VerticalAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
29 : CartesianChartAxis(axis, item, intervalAxis)
29 : CartesianChartAxis(axis, item, intervalAxis)
30 {
30 {
31 }
31 }
32
32
33 VerticalAxis::~VerticalAxis()
33 VerticalAxis::~VerticalAxis()
34 {
34 {
35 }
35 }
36
36
37 void VerticalAxis::updateGeometry()
37 void VerticalAxis::updateGeometry()
38 {
38 {
39 const QVector<qreal> &layout = ChartAxisElement::layout();
39 const QVector<qreal> &layout = ChartAxisElement::layout();
40
40
41 if (layout.isEmpty())
41 if (layout.isEmpty())
42 return;
42 return;
43
43
44 QStringList labelList = labels();
44 QStringList labelList = labels();
45
45
46 QList<QGraphicsItem *> lines = gridItems();
46 QList<QGraphicsItem *> lines = gridItems();
47 QList<QGraphicsItem *> labels = labelItems();
47 QList<QGraphicsItem *> labels = labelItems();
48 QList<QGraphicsItem *> shades = shadeItems();
48 QList<QGraphicsItem *> shades = shadeItems();
49 QList<QGraphicsItem *> arrow = arrowItems();
49 QList<QGraphicsItem *> arrow = arrowItems();
50 QGraphicsTextItem *title = titleItem();
50 QGraphicsTextItem *title = titleItem();
51
51
52 Q_ASSERT(labels.size() == labelList.size());
52 Q_ASSERT(labels.size() == labelList.size());
53 Q_ASSERT(layout.size() == labelList.size());
53 Q_ASSERT(layout.size() == labelList.size());
54
54
55 const QRectF &axisRect = axisGeometry();
55 const QRectF &axisRect = axisGeometry();
56 const QRectF &gridRect = gridGeometry();
56 const QRectF &gridRect = gridGeometry();
57
57
58 qreal height = axisRect.bottom();
58 qreal height = axisRect.bottom();
59
59
60
60
61 //arrow
61 //arrow
62 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(arrow.at(0));
62 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(arrow.at(0));
63
63
64 //arrow position
64 //arrow position
65 if (axis()->alignment() == Qt::AlignLeft)
65 if (axis()->alignment() == Qt::AlignLeft)
66 arrowItem->setLine(axisRect.right(), gridRect.top(), axisRect.right(), gridRect.bottom());
66 arrowItem->setLine(axisRect.right(), gridRect.top(), axisRect.right(), gridRect.bottom());
67 else if (axis()->alignment() == Qt::AlignRight)
67 else if (axis()->alignment() == Qt::AlignRight)
68 arrowItem->setLine(axisRect.left(), gridRect.top(), axisRect.left(), gridRect.bottom());
68 arrowItem->setLine(axisRect.left(), gridRect.top(), axisRect.left(), gridRect.bottom());
69
69
70 //title
70 //title
71 QRectF titleBoundingRect;
71 QRectF titleBoundingRect;
72 QString titleText = axis()->titleText();
72 QString titleText = axis()->titleText();
73 qreal availableSpace = axisRect.width() - labelPadding();
73 qreal availableSpace = axisRect.width() - labelPadding();
74 if (!titleText.isEmpty() && titleItem()->isVisible()) {
74 if (!titleText.isEmpty() && titleItem()->isVisible()) {
75 availableSpace -= titlePadding() * 2.0;
75 availableSpace -= titlePadding() * 2.0;
76 qreal minimumLabelWidth = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").width();
76 qreal minimumLabelWidth = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...").width();
77 QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0),
77 QString truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0),
78 gridRect.height(), Qt::Horizontal, titleBoundingRect);
78 gridRect.height(), Qt::Horizontal, titleBoundingRect);
79 qreal titleSpace = availableSpace - minimumLabelWidth;
79 qreal titleSpace = availableSpace - minimumLabelWidth;
80 if (titleSpace < titleBoundingRect.width()) {
80 if (titleSpace < titleBoundingRect.height()) {
81 // Need to also truncate title vertically (multiline title)
81 // Need to also truncate title vertically (multiline title)
82 bool skip = false;
82 bool skip = false;
83 if (truncatedTitle.endsWith("...")) {
83 if (truncatedTitle.endsWith("...")) {
84 if (truncatedTitle.size() == 3)
84 if (truncatedTitle.size() == 3)
85 skip = true; // Already truncated to minimum
85 skip = true; // Already truncated to minimum
86 else
86 else
87 truncatedTitle.chop(3);
87 truncatedTitle.chop(3);
88 }
88 }
89 if (!skip)
89 if (!skip)
90 truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0),
90 truncatedTitle = ChartPresenter::truncatedText(axis()->titleFont(), truncatedTitle, qreal(0.0),
91 titleSpace, Qt::Vertical, titleBoundingRect);
91 titleSpace, Qt::Vertical, titleBoundingRect);
92 }
92 }
93 title->setHtml(truncatedTitle);
93 title->setHtml(truncatedTitle);
94
94
95 titleBoundingRect = title->boundingRect();
95 titleBoundingRect = title->boundingRect();
96
96
97 QPointF center = gridRect.center() - titleBoundingRect.center();
97 QPointF center = gridRect.center() - titleBoundingRect.center();
98 if (axis()->alignment() == Qt::AlignLeft)
98 if (axis()->alignment() == Qt::AlignLeft)
99 title->setPos(axisRect.left() - titleBoundingRect.width() / 2.0 + titleBoundingRect.height() / 2.0 + titlePadding(), center.y());
99 title->setPos(axisRect.left() - titleBoundingRect.width() / 2.0 + titleBoundingRect.height() / 2.0 + titlePadding(), center.y());
100 else if (axis()->alignment() == Qt::AlignRight)
100 else if (axis()->alignment() == Qt::AlignRight)
101 title->setPos(axisRect.right() - titleBoundingRect.width() / 2.0 - titleBoundingRect.height() / 2.0 - titlePadding(), center.y());
101 title->setPos(axisRect.right() - titleBoundingRect.width() / 2.0 - titleBoundingRect.height() / 2.0 - titlePadding(), center.y());
102
102
103 title->setTransformOriginPoint(titleBoundingRect.center());
103 title->setTransformOriginPoint(titleBoundingRect.center());
104 title->setRotation(270);
104 title->setRotation(270);
105
105
106 availableSpace -= titleBoundingRect.height();
106 availableSpace -= titleBoundingRect.height();
107 }
107 }
108
108
109 for (int i = 0; i < layout.size(); ++i) {
109 for (int i = 0; i < layout.size(); ++i) {
110 //items
110 //items
111 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
111 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
112 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrow.at(i + 1));
112 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrow.at(i + 1));
113 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
113 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
114
114
115 //grid line
115 //grid line
116 gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]);
116 gridItem->setLine(gridRect.left(), layout[i], gridRect.right(), layout[i]);
117
117
118 //label text wrapping
118 //label text wrapping
119 QString text = labelList.at(i);
119 QString text = labelList.at(i);
120 QRectF boundingRect;
120 QRectF boundingRect;
121 labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(),
121 labelItem->setHtml(ChartPresenter::truncatedText(axis()->labelsFont(), text, axis()->labelsAngle(),
122 availableSpace, Qt::Horizontal, boundingRect));
122 availableSpace, Qt::Horizontal, boundingRect));
123
123
124 //label transformation origin point
124 //label transformation origin point
125 const QRectF &rect = labelItem->boundingRect();
125 const QRectF &rect = labelItem->boundingRect();
126 QPointF center = rect.center();
126 QPointF center = rect.center();
127 labelItem->setTransformOriginPoint(center.x(), center.y());
127 labelItem->setTransformOriginPoint(center.x(), center.y());
128 qreal widthDiff = rect.width() - boundingRect.width();
128 qreal widthDiff = rect.width() - boundingRect.width();
129 qreal heightDiff = rect.height() - boundingRect.height();
129 qreal heightDiff = rect.height() - boundingRect.height();
130
130
131 //ticks and label position
131 //ticks and label position
132 if (axis()->alignment() == Qt::AlignLeft) {
132 if (axis()->alignment() == Qt::AlignLeft) {
133 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0) - labelPadding(), layout[i] - center.y());
133 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2.0) - labelPadding(), layout[i] - center.y());
134 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
134 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
135 } else if (axis()->alignment() == Qt::AlignRight) {
135 } else if (axis()->alignment() == Qt::AlignRight) {
136 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0), layout[i] - center.y());
136 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2.0), layout[i] - center.y());
137 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
137 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
138 }
138 }
139
139
140 //label in between
140 //label in between
141 bool forceHide = false;
141 bool forceHide = false;
142 if (intervalAxis() && (i + 1) != layout.size()) {
142 if (intervalAxis() && (i + 1) != layout.size()) {
143 qreal lowerBound = qMin(layout[i], gridRect.bottom());
143 qreal lowerBound = qMin(layout[i], gridRect.bottom());
144 qreal upperBound = qMax(layout[i + 1], gridRect.top());
144 qreal upperBound = qMax(layout[i + 1], gridRect.top());
145 const qreal delta = lowerBound - upperBound;
145 const qreal delta = lowerBound - upperBound;
146 // Hide label in case visible part of the category at the grid edge is too narrow
146 // Hide label in case visible part of the category at the grid edge is too narrow
147 if (delta < boundingRect.height()
147 if (delta < boundingRect.height()
148 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
148 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
149 forceHide = true;
149 forceHide = true;
150 } else {
150 } else {
151 labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y());
151 labelItem->setPos(labelItem->pos().x() , lowerBound - (delta / 2.0) - center.y());
152 }
152 }
153 }
153 }
154
154
155 //label overlap detection - compensate one pixel for rounding errors
155 //label overlap detection - compensate one pixel for rounding errors
156 if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
156 if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
157 (labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom() ||
157 (labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom() ||
158 labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0)) {
158 labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0)) {
159 labelItem->setVisible(false);
159 labelItem->setVisible(false);
160 }
160 }
161 else {
161 else {
162 labelItem->setVisible(true);
162 labelItem->setVisible(true);
163 height=labelItem->pos().y();
163 height=labelItem->pos().y();
164 }
164 }
165
165
166 //shades
166 //shades
167 if ((i + 1) % 2 && i > 1) {
167 if ((i + 1) % 2 && i > 1) {
168 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
168 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
169 qreal lowerBound = qMin(layout[i - 1], gridRect.bottom());
169 qreal lowerBound = qMin(layout[i - 1], gridRect.bottom());
170 qreal upperBound = qMax(layout[i], gridRect.top());
170 qreal upperBound = qMax(layout[i], gridRect.top());
171 rectItem->setRect(gridRect.left(), upperBound, gridRect.width(), lowerBound - upperBound);
171 rectItem->setRect(gridRect.left(), upperBound, gridRect.width(), lowerBound - upperBound);
172 if (rectItem->rect().height() <= 0.0)
172 if (rectItem->rect().height() <= 0.0)
173 rectItem->setVisible(false);
173 rectItem->setVisible(false);
174 else
174 else
175 rectItem->setVisible(true);
175 rectItem->setVisible(true);
176 }
176 }
177
177
178 // check if the grid line and the axis tick should be shown
178 // check if the grid line and the axis tick should be shown
179 qreal y = gridItem->line().p1().y();
179 qreal y = gridItem->line().p1().y();
180 if ((y < gridRect.top() || y > gridRect.bottom()))
180 if ((y < gridRect.top() || y > gridRect.bottom()))
181 {
181 {
182 gridItem->setVisible(false);
182 gridItem->setVisible(false);
183 tickItem->setVisible(false);
183 tickItem->setVisible(false);
184 }else{
184 }else{
185 gridItem->setVisible(true);
185 gridItem->setVisible(true);
186 tickItem->setVisible(true);
186 tickItem->setVisible(true);
187 }
187 }
188
188
189 }
189 }
190 //begin/end grid line in case labels between
190 //begin/end grid line in case labels between
191 if (intervalAxis()) {
191 if (intervalAxis()) {
192 QGraphicsLineItem *gridLine;
192 QGraphicsLineItem *gridLine;
193 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
193 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
194 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
194 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
195 gridLine->setVisible(true);
195 gridLine->setVisible(true);
196 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size() + 1));
196 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size() + 1));
197 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
197 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
198 gridLine->setVisible(true);
198 gridLine->setVisible(true);
199 }
199 }
200 }
200 }
201
201
202 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
202 QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
203 {
203 {
204 Q_UNUSED(constraint);
204 Q_UNUSED(constraint);
205 QSizeF sh(0, 0);
205 QSizeF sh(0, 0);
206
206
207 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
207 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
208 return sh;
208 return sh;
209
209
210 switch (which) {
210 switch (which) {
211 case Qt::MinimumSize: {
211 case Qt::MinimumSize: {
212 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), "...");
212 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), "...");
213 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
213 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
214 break;
214 break;
215 }
215 }
216 case Qt::MaximumSize:
216 case Qt::MaximumSize:
217 case Qt::PreferredSize: {
217 case Qt::PreferredSize: {
218 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
218 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
219 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
219 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
220 break;
220 break;
221 }
221 }
222 default:
222 default:
223 break;
223 break;
224 }
224 }
225
225
226 return sh;
226 return sh;
227 }
227 }
228
228
229 QTCOMMERCIALCHART_END_NAMESPACE
229 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,221 +1,224
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 "abstractbarchartitem_p.h"
21 #include "abstractbarchartitem_p.h"
22 #include "bar_p.h"
22 #include "bar_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "qabstractbarseries.h"
25 #include "qabstractbarseries.h"
26 #include "qabstractbarseries_p.h"
26 #include "qabstractbarseries_p.h"
27 #include "qchart.h"
27 #include "qchart.h"
28 #include "chartpresenter_p.h"
28 #include "chartpresenter_p.h"
29 #include "charttheme_p.h"
29 #include "charttheme_p.h"
30 #include "baranimation_p.h"
30 #include "baranimation_p.h"
31 #include "chartdataset_p.h"
31 #include "chartdataset_p.h"
32 #include <QPainter>
32 #include <QPainter>
33 #include <QTextDocument>
33
34
34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35
36
36 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
37 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
37 ChartItem(series->d_func(),item),
38 ChartItem(series->d_func(),item),
38 m_animation(0),
39 m_animation(0),
39 m_series(series)
40 m_series(series)
40 {
41 {
41
42
42 setFlag(ItemClipsChildrenToShape);
43 setFlag(ItemClipsChildrenToShape);
43 connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged()));
44 connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged()));
44 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleUpdatedBars()));
45 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleUpdatedBars()));
45 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
46 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
46 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
47 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
47 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleVisibleChanged()));
48 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleVisibleChanged()));
48 connect(series, SIGNAL(opacityChanged()), this, SLOT(handleOpacityChanged()));
49 connect(series, SIGNAL(opacityChanged()), this, SLOT(handleOpacityChanged()));
49 setZValue(ChartPresenter::BarSeriesZValue);
50 setZValue(ChartPresenter::BarSeriesZValue);
50 handleDataStructureChanged();
51 handleDataStructureChanged();
51 handleVisibleChanged();
52 handleVisibleChanged();
52 handleUpdatedBars();
53 handleUpdatedBars();
53 }
54 }
54
55
55 AbstractBarChartItem::~AbstractBarChartItem()
56 AbstractBarChartItem::~AbstractBarChartItem()
56 {
57 {
57 }
58 }
58
59
59 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
60 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
60 {
61 {
61 Q_UNUSED(painter);
62 Q_UNUSED(painter);
62 Q_UNUSED(option);
63 Q_UNUSED(option);
63 Q_UNUSED(widget);
64 Q_UNUSED(widget);
64 }
65 }
65
66
66 QRectF AbstractBarChartItem::boundingRect() const
67 QRectF AbstractBarChartItem::boundingRect() const
67 {
68 {
68 return m_rect;
69 return m_rect;
69 }
70 }
70
71
71 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
72 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
72 {
73 {
73 QSizeF size = geometry().size();
74 QSizeF size = geometry().size();
74 if (geometry().size().isValid()) {
75 if (geometry().size().isValid()) {
75 if (m_animation) {
76 if (m_animation) {
76 if (m_layout.count() == 0 || m_oldSize != size) {
77 if (m_layout.count() == 0 || m_oldSize != size) {
77 initializeLayout();
78 initializeLayout();
78 m_oldSize = size;
79 m_oldSize = size;
79 }
80 }
80 m_animation->setup(m_layout, layout);
81 m_animation->setup(m_layout, layout);
81 presenter()->startAnimation(m_animation);
82 presenter()->startAnimation(m_animation);
82 } else {
83 } else {
83 setLayout(layout);
84 setLayout(layout);
84 update();
85 update();
85 }
86 }
86 }
87 }
87 }
88 }
88
89
89 void AbstractBarChartItem::setAnimation(BarAnimation *animation)
90 void AbstractBarChartItem::setAnimation(BarAnimation *animation)
90 {
91 {
91 m_animation = animation;
92 m_animation = animation;
92 }
93 }
93
94
94 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
95 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
95 {
96 {
96 if (layout.count() != m_bars.count())
97 if (layout.count() != m_bars.count())
97 return;
98 return;
98
99
99 m_layout = layout;
100 m_layout = layout;
100
101
101 for (int i = 0; i < m_bars.count(); i++) {
102 for (int i = 0; i < m_bars.count(); i++) {
102 m_bars.at(i)->setRect(layout.at(i));
103 m_bars.at(i)->setRect(layout.at(i));
103 QGraphicsTextItem *label = m_labels.at(i);
104 QGraphicsTextItem *label = m_labels.at(i);
104 label->setPos(layout.at(i).center() - label->boundingRect().center());
105 label->setPos(layout.at(i).center() - label->boundingRect().center());
105
106
106 }
107 }
107 }
108 }
108 //handlers
109 //handlers
109
110
110 void AbstractBarChartItem::handleDomainUpdated()
111 void AbstractBarChartItem::handleDomainUpdated()
111 {
112 {
112 m_domainMinX = domain()->minX();
113 m_domainMinX = domain()->minX();
113 m_domainMaxX = domain()->maxX();
114 m_domainMaxX = domain()->maxX();
114 m_domainMinY = domain()->minY();
115 m_domainMinY = domain()->minY();
115 m_domainMaxY = domain()->maxY();
116 m_domainMaxY = domain()->maxY();
116
117
117 QRectF rect(QPointF(0,0),domain()->size());
118 QRectF rect(QPointF(0,0),domain()->size());
118
119
119 if(m_rect != rect){
120 if(m_rect != rect){
120 prepareGeometryChange();
121 prepareGeometryChange();
121 m_rect = rect;
122 m_rect = rect;
122 }
123 }
123
124
124 handleLayoutChanged();
125 handleLayoutChanged();
125 }
126 }
126
127
127 void AbstractBarChartItem::handleLayoutChanged()
128 void AbstractBarChartItem::handleLayoutChanged()
128 {
129 {
129 if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
130 if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
130 return; // rect size zero.
131 return; // rect size zero.
131 QVector<QRectF> layout = calculateLayout();
132 QVector<QRectF> layout = calculateLayout();
132 applyLayout(layout);
133 applyLayout(layout);
133 handleUpdatedBars();
134 handleUpdatedBars();
134 }
135 }
135
136
136 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
137 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
137 {
138 {
138 foreach (QGraphicsTextItem *label, m_labels)
139 foreach (QGraphicsTextItem *label, m_labels)
139 label->setVisible(visible);
140 label->setVisible(visible);
140 update();
141 update();
141 }
142 }
142
143
143 void AbstractBarChartItem::handleDataStructureChanged()
144 void AbstractBarChartItem::handleDataStructureChanged()
144 {
145 {
145 foreach (QGraphicsItem *item, childItems())
146 foreach (QGraphicsItem *item, childItems())
146 delete item;
147 delete item;
147
148
148 m_bars.clear();
149 m_bars.clear();
149 m_labels.clear();
150 m_labels.clear();
150 m_layout.clear();
151 m_layout.clear();
151
152
152 // Create new graphic items for bars
153 // Create new graphic items for bars
153 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
154 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
154 for (int s = 0; s < m_series->count(); s++) {
155 for (int s = 0; s < m_series->count(); s++) {
155 QBarSet *set = m_series->d_func()->barsetAt(s);
156 QBarSet *set = m_series->d_func()->barsetAt(s);
156
157
157 // Bars
158 // Bars
158 Bar *bar = new Bar(set, c, this);
159 Bar *bar = new Bar(set, c, this);
159 m_bars.append(bar);
160 m_bars.append(bar);
160 connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,QBarSet*)));
161 connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,QBarSet*)));
161 connect(bar, SIGNAL(hovered(bool,QBarSet*)), m_series, SIGNAL(hovered(bool,QBarSet*)));
162 connect(bar, SIGNAL(hovered(bool,QBarSet*)), m_series, SIGNAL(hovered(bool,QBarSet*)));
162 connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
163 connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
163 connect(bar, SIGNAL(hovered(bool,QBarSet*)), set, SIGNAL(hovered(bool)));
164 connect(bar, SIGNAL(hovered(bool,QBarSet*)), set, SIGNAL(hovered(bool)));
164 // m_layout.append(QRectF(0, 0, 1, 1));
165 // m_layout.append(QRectF(0, 0, 1, 1));
165
166
166 // Labels
167 // Labels
167 m_labels.append(new QGraphicsTextItem(this));
168 QGraphicsTextItem *newLabel = new QGraphicsTextItem(this);
169 newLabel->document()->setDocumentMargin(ChartPresenter::textMargin());
170 m_labels.append(newLabel);
168 }
171 }
169 }
172 }
170
173
171 if(themeManager()) themeManager()->updateSeries(m_series);
174 if(themeManager()) themeManager()->updateSeries(m_series);
172 handleLayoutChanged();
175 handleLayoutChanged();
173 handleVisibleChanged();
176 handleVisibleChanged();
174 }
177 }
175
178
176 void AbstractBarChartItem::handleVisibleChanged()
179 void AbstractBarChartItem::handleVisibleChanged()
177 {
180 {
178 bool visible = m_series->isVisible();
181 bool visible = m_series->isVisible();
179 if (visible)
182 if (visible)
180 handleLabelsVisibleChanged(m_series->isLabelsVisible());
183 handleLabelsVisibleChanged(m_series->isLabelsVisible());
181 else
184 else
182 handleLabelsVisibleChanged(visible);
185 handleLabelsVisibleChanged(visible);
183
186
184 foreach (QGraphicsItem *bar, m_bars)
187 foreach (QGraphicsItem *bar, m_bars)
185 bar->setVisible(visible);
188 bar->setVisible(visible);
186 }
189 }
187
190
188 void AbstractBarChartItem::handleOpacityChanged()
191 void AbstractBarChartItem::handleOpacityChanged()
189 {
192 {
190 foreach (QGraphicsItem *item, childItems())
193 foreach (QGraphicsItem *item, childItems())
191 item->setOpacity(m_series->opacity());
194 item->setOpacity(m_series->opacity());
192 }
195 }
193
196
194 void AbstractBarChartItem::handleUpdatedBars()
197 void AbstractBarChartItem::handleUpdatedBars()
195 {
198 {
196 // Handle changes in pen, brush, labels etc.
199 // Handle changes in pen, brush, labels etc.
197 int categoryCount = m_series->d_func()->categoryCount();
200 int categoryCount = m_series->d_func()->categoryCount();
198 int setCount = m_series->count();
201 int setCount = m_series->count();
199 int itemIndex(0);
202 int itemIndex(0);
200
203
201 for (int category = 0; category < categoryCount; category++) {
204 for (int category = 0; category < categoryCount; category++) {
202 for (int set = 0; set < setCount; set++) {
205 for (int set = 0; set < setCount; set++) {
203 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
206 QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
204 Bar *bar = m_bars.at(itemIndex);
207 Bar *bar = m_bars.at(itemIndex);
205 bar->setPen(barSet->m_pen);
208 bar->setPen(barSet->m_pen);
206 bar->setBrush(barSet->m_brush);
209 bar->setBrush(barSet->m_brush);
207 bar->update();
210 bar->update();
208
211
209 QGraphicsTextItem *label = m_labels.at(itemIndex);
212 QGraphicsTextItem *label = m_labels.at(itemIndex);
210 label->setHtml(QString("%1").arg(barSet->value(category)));
213 label->setHtml(QString("%1").arg(barSet->value(category)));
211 label->setFont(barSet->m_labelFont);
214 label->setFont(barSet->m_labelFont);
212 label->setDefaultTextColor(barSet->m_labelBrush.color());
215 label->setDefaultTextColor(barSet->m_labelBrush.color());
213 label->update();
216 label->update();
214 itemIndex++;
217 itemIndex++;
215 }
218 }
216 }
219 }
217 }
220 }
218
221
219 #include "moc_abstractbarchartitem_p.cpp"
222 #include "moc_abstractbarchartitem_p.cpp"
220
223
221 QTCOMMERCIALCHART_END_NAMESPACE
224 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,478 +1,484
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 #include "chartpresenter_p.h"
20 #include "chartpresenter_p.h"
21 #include "qchart.h"
21 #include "qchart.h"
22 #include "chartitem_p.h"
22 #include "chartitem_p.h"
23 #include "qchart_p.h"
23 #include "qchart_p.h"
24 #include "qabstractaxis.h"
24 #include "qabstractaxis.h"
25 #include "qabstractaxis_p.h"
25 #include "qabstractaxis_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "chartanimation_p.h"
27 #include "chartanimation_p.h"
28 #include "qabstractseries_p.h"
28 #include "qabstractseries_p.h"
29 #include "qareaseries.h"
29 #include "qareaseries.h"
30 #include "chartaxiselement_p.h"
30 #include "chartaxiselement_p.h"
31 #include "chartbackground_p.h"
31 #include "chartbackground_p.h"
32 #include "cartesianchartlayout_p.h"
32 #include "cartesianchartlayout_p.h"
33 #include "polarchartlayout_p.h"
33 #include "polarchartlayout_p.h"
34 #include "charttitle_p.h"
34 #include "charttitle_p.h"
35 #include <QTimer>
35 #include <QTimer>
36 #include <QTextDocument>
36
37
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
39
39 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
40 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
40 : QObject(chart),
41 : QObject(chart),
41 m_chart(chart),
42 m_chart(chart),
42 m_options(QChart::NoAnimation),
43 m_options(QChart::NoAnimation),
43 m_state(ShowState),
44 m_state(ShowState),
44 m_background(0),
45 m_background(0),
45 m_plotAreaBackground(0),
46 m_plotAreaBackground(0),
46 m_title(0)
47 m_title(0)
47 {
48 {
48 if (type == QChart::ChartTypeCartesian)
49 if (type == QChart::ChartTypeCartesian)
49 m_layout = new CartesianChartLayout(this);
50 m_layout = new CartesianChartLayout(this);
50 else if (type == QChart::ChartTypePolar)
51 else if (type == QChart::ChartTypePolar)
51 m_layout = new PolarChartLayout(this);
52 m_layout = new PolarChartLayout(this);
52 Q_ASSERT(m_layout);
53 Q_ASSERT(m_layout);
53 }
54 }
54
55
55 ChartPresenter::~ChartPresenter()
56 ChartPresenter::~ChartPresenter()
56 {
57 {
57
58
58 }
59 }
59
60
60 void ChartPresenter::setGeometry(const QRectF rect)
61 void ChartPresenter::setGeometry(const QRectF rect)
61 {
62 {
62 if (m_rect != rect) {
63 if (m_rect != rect) {
63 m_rect = rect;
64 m_rect = rect;
64 foreach (ChartItem *chart, m_chartItems) {
65 foreach (ChartItem *chart, m_chartItems) {
65 chart->domain()->setSize(rect.size());
66 chart->domain()->setSize(rect.size());
66 chart->setPos(rect.topLeft());
67 chart->setPos(rect.topLeft());
67 }
68 }
68 }
69 }
69 }
70 }
70
71
71 QRectF ChartPresenter::geometry() const
72 QRectF ChartPresenter::geometry() const
72 {
73 {
73 return m_rect;
74 return m_rect;
74 }
75 }
75
76
76 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
77 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
77 {
78 {
78 axis->d_ptr->initializeGraphics(rootItem());
79 axis->d_ptr->initializeGraphics(rootItem());
79 axis->d_ptr->initializeAnimations(m_options);
80 axis->d_ptr->initializeAnimations(m_options);
80 ChartAxisElement *item = axis->d_ptr->axisItem();
81 ChartAxisElement *item = axis->d_ptr->axisItem();
81 item->setPresenter(this);
82 item->setPresenter(this);
82 item->setThemeManager(m_chart->d_ptr->m_themeManager);
83 item->setThemeManager(m_chart->d_ptr->m_themeManager);
83 m_axisItems<<item;
84 m_axisItems<<item;
84 m_axes<<axis;
85 m_axes<<axis;
85 m_layout->invalidate();
86 m_layout->invalidate();
86 }
87 }
87
88
88 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
89 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
89 {
90 {
90 ChartAxisElement *item = axis->d_ptr->m_item.take();
91 ChartAxisElement *item = axis->d_ptr->m_item.take();
91 item->hide();
92 item->hide();
92 item->disconnect();
93 item->disconnect();
93 item->deleteLater();
94 item->deleteLater();
94 m_axisItems.removeAll(item);
95 m_axisItems.removeAll(item);
95 m_axes.removeAll(axis);
96 m_axes.removeAll(axis);
96 m_layout->invalidate();
97 m_layout->invalidate();
97 }
98 }
98
99
99
100
100 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
101 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
101 {
102 {
102 series->d_ptr->initializeGraphics(rootItem());
103 series->d_ptr->initializeGraphics(rootItem());
103 series->d_ptr->initializeAnimations(m_options);
104 series->d_ptr->initializeAnimations(m_options);
104 ChartItem *chart = series->d_ptr->chartItem();
105 ChartItem *chart = series->d_ptr->chartItem();
105 chart->setPresenter(this);
106 chart->setPresenter(this);
106 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
107 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
107 chart->domain()->setSize(m_rect.size());
108 chart->domain()->setSize(m_rect.size());
108 chart->setPos(m_rect.topLeft());
109 chart->setPos(m_rect.topLeft());
109 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
110 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
110 m_chartItems<<chart;
111 m_chartItems<<chart;
111 m_series<<series;
112 m_series<<series;
112 m_layout->invalidate();
113 m_layout->invalidate();
113 }
114 }
114
115
115 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
116 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
116 {
117 {
117 ChartItem *chart = series->d_ptr->m_item.take();
118 ChartItem *chart = series->d_ptr->m_item.take();
118 chart->hide();
119 chart->hide();
119 chart->disconnect();
120 chart->disconnect();
120 chart->deleteLater();
121 chart->deleteLater();
121 m_chartItems.removeAll(chart);
122 m_chartItems.removeAll(chart);
122 m_series.removeAll(series);
123 m_series.removeAll(series);
123 m_layout->invalidate();
124 m_layout->invalidate();
124 }
125 }
125
126
126 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
127 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
127 {
128 {
128 if (m_options != options) {
129 if (m_options != options) {
129 QChart::AnimationOptions oldOptions = m_options;
130 QChart::AnimationOptions oldOptions = m_options;
130 m_options = options;
131 m_options = options;
131 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
132 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
132 foreach (QAbstractSeries *series, m_series)
133 foreach (QAbstractSeries *series, m_series)
133 series->d_ptr->initializeAnimations(m_options);
134 series->d_ptr->initializeAnimations(m_options);
134 }
135 }
135 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
136 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
136 foreach (QAbstractAxis *axis, m_axes)
137 foreach (QAbstractAxis *axis, m_axes)
137 axis->d_ptr->initializeAnimations(m_options);
138 axis->d_ptr->initializeAnimations(m_options);
138 }
139 }
139 m_layout->invalidate(); // So that existing animations don't just stop halfway
140 m_layout->invalidate(); // So that existing animations don't just stop halfway
140 }
141 }
141 }
142 }
142
143
143 void ChartPresenter::setState(State state,QPointF point)
144 void ChartPresenter::setState(State state,QPointF point)
144 {
145 {
145 m_state=state;
146 m_state=state;
146 m_statePoint=point;
147 m_statePoint=point;
147 }
148 }
148
149
149 QChart::AnimationOptions ChartPresenter::animationOptions() const
150 QChart::AnimationOptions ChartPresenter::animationOptions() const
150 {
151 {
151 return m_options;
152 return m_options;
152 }
153 }
153
154
154 void ChartPresenter::createBackgroundItem()
155 void ChartPresenter::createBackgroundItem()
155 {
156 {
156 if (!m_background) {
157 if (!m_background) {
157 m_background = new ChartBackground(rootItem());
158 m_background = new ChartBackground(rootItem());
158 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
159 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
159 m_background->setBrush(QChartPrivate::defaultBrush());
160 m_background->setBrush(QChartPrivate::defaultBrush());
160 m_background->setZValue(ChartPresenter::BackgroundZValue);
161 m_background->setZValue(ChartPresenter::BackgroundZValue);
161 }
162 }
162 }
163 }
163
164
164 void ChartPresenter::createPlotAreaBackgroundItem()
165 void ChartPresenter::createPlotAreaBackgroundItem()
165 {
166 {
166 if (!m_plotAreaBackground) {
167 if (!m_plotAreaBackground) {
167 if (m_chart->chartType() == QChart::ChartTypeCartesian)
168 if (m_chart->chartType() == QChart::ChartTypeCartesian)
168 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
169 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
169 else
170 else
170 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
171 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
171 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
172 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
172 // antialising artifacts with axis lines for some reason.
173 // antialising artifacts with axis lines for some reason.
173 m_plotAreaBackground->setPen(QPen(Qt::transparent));
174 m_plotAreaBackground->setPen(QPen(Qt::transparent));
174 m_plotAreaBackground->setBrush(Qt::NoBrush);
175 m_plotAreaBackground->setBrush(Qt::NoBrush);
175 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
176 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
176 m_plotAreaBackground->setVisible(false);
177 m_plotAreaBackground->setVisible(false);
177 }
178 }
178 }
179 }
179
180
180 void ChartPresenter::createTitleItem()
181 void ChartPresenter::createTitleItem()
181 {
182 {
182 if (!m_title) {
183 if (!m_title) {
183 m_title = new ChartTitle(rootItem());
184 m_title = new ChartTitle(rootItem());
184 m_title->setZValue(ChartPresenter::BackgroundZValue);
185 m_title->setZValue(ChartPresenter::BackgroundZValue);
185 }
186 }
186 }
187 }
187
188
188 void ChartPresenter::startAnimation(ChartAnimation *animation)
189 void ChartPresenter::startAnimation(ChartAnimation *animation)
189 {
190 {
190 animation->stop();
191 animation->stop();
191 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
192 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
192 }
193 }
193
194
194 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
195 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
195 {
196 {
196 createBackgroundItem();
197 createBackgroundItem();
197 m_background->setBrush(brush);
198 m_background->setBrush(brush);
198 m_layout->invalidate();
199 m_layout->invalidate();
199 }
200 }
200
201
201 QBrush ChartPresenter::backgroundBrush() const
202 QBrush ChartPresenter::backgroundBrush() const
202 {
203 {
203 if (!m_background)
204 if (!m_background)
204 return QBrush();
205 return QBrush();
205 return m_background->brush();
206 return m_background->brush();
206 }
207 }
207
208
208 void ChartPresenter::setBackgroundPen(const QPen &pen)
209 void ChartPresenter::setBackgroundPen(const QPen &pen)
209 {
210 {
210 createBackgroundItem();
211 createBackgroundItem();
211 m_background->setPen(pen);
212 m_background->setPen(pen);
212 m_layout->invalidate();
213 m_layout->invalidate();
213 }
214 }
214
215
215 QPen ChartPresenter::backgroundPen() const
216 QPen ChartPresenter::backgroundPen() const
216 {
217 {
217 if (!m_background)
218 if (!m_background)
218 return QPen();
219 return QPen();
219 return m_background->pen();
220 return m_background->pen();
220 }
221 }
221
222
222 void ChartPresenter::setBackgroundRoundness(qreal diameter)
223 void ChartPresenter::setBackgroundRoundness(qreal diameter)
223 {
224 {
224 createBackgroundItem();
225 createBackgroundItem();
225 m_background->setDiameter(diameter);
226 m_background->setDiameter(diameter);
226 m_layout->invalidate();
227 m_layout->invalidate();
227 }
228 }
228
229
229 qreal ChartPresenter::backgroundRoundness() const
230 qreal ChartPresenter::backgroundRoundness() const
230 {
231 {
231 if (!m_background)
232 if (!m_background)
232 return 0;
233 return 0;
233 return m_background->diameter();
234 return m_background->diameter();
234 }
235 }
235
236
236 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
237 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
237 {
238 {
238 createPlotAreaBackgroundItem();
239 createPlotAreaBackgroundItem();
239 m_plotAreaBackground->setBrush(brush);
240 m_plotAreaBackground->setBrush(brush);
240 m_layout->invalidate();
241 m_layout->invalidate();
241 }
242 }
242
243
243 QBrush ChartPresenter::plotAreaBackgroundBrush() const
244 QBrush ChartPresenter::plotAreaBackgroundBrush() const
244 {
245 {
245 if (!m_plotAreaBackground)
246 if (!m_plotAreaBackground)
246 return QBrush();
247 return QBrush();
247 return m_plotAreaBackground->brush();
248 return m_plotAreaBackground->brush();
248 }
249 }
249
250
250 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
251 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
251 {
252 {
252 createPlotAreaBackgroundItem();
253 createPlotAreaBackgroundItem();
253 m_plotAreaBackground->setPen(pen);
254 m_plotAreaBackground->setPen(pen);
254 m_layout->invalidate();
255 m_layout->invalidate();
255 }
256 }
256
257
257 QPen ChartPresenter::plotAreaBackgroundPen() const
258 QPen ChartPresenter::plotAreaBackgroundPen() const
258 {
259 {
259 if (!m_plotAreaBackground)
260 if (!m_plotAreaBackground)
260 return QPen();
261 return QPen();
261 return m_plotAreaBackground->pen();
262 return m_plotAreaBackground->pen();
262 }
263 }
263
264
264 void ChartPresenter::setTitle(const QString &title)
265 void ChartPresenter::setTitle(const QString &title)
265 {
266 {
266 createTitleItem();
267 createTitleItem();
267 m_title->setText(title);
268 m_title->setText(title);
268 m_layout->invalidate();
269 m_layout->invalidate();
269 }
270 }
270
271
271 QString ChartPresenter::title() const
272 QString ChartPresenter::title() const
272 {
273 {
273 if (!m_title)
274 if (!m_title)
274 return QString();
275 return QString();
275 return m_title->text();
276 return m_title->text();
276 }
277 }
277
278
278 void ChartPresenter::setTitleFont(const QFont &font)
279 void ChartPresenter::setTitleFont(const QFont &font)
279 {
280 {
280 createTitleItem();
281 createTitleItem();
281 m_title->setFont(font);
282 m_title->setFont(font);
282 m_layout->invalidate();
283 m_layout->invalidate();
283 }
284 }
284
285
285 QFont ChartPresenter::titleFont() const
286 QFont ChartPresenter::titleFont() const
286 {
287 {
287 if (!m_title)
288 if (!m_title)
288 return QFont();
289 return QFont();
289 return m_title->font();
290 return m_title->font();
290 }
291 }
291
292
292 void ChartPresenter::setTitleBrush(const QBrush &brush)
293 void ChartPresenter::setTitleBrush(const QBrush &brush)
293 {
294 {
294 createTitleItem();
295 createTitleItem();
295 m_title->setDefaultTextColor(brush.color());
296 m_title->setDefaultTextColor(brush.color());
296 m_layout->invalidate();
297 m_layout->invalidate();
297 }
298 }
298
299
299 QBrush ChartPresenter::titleBrush() const
300 QBrush ChartPresenter::titleBrush() const
300 {
301 {
301 if (!m_title)
302 if (!m_title)
302 return QBrush();
303 return QBrush();
303 return QBrush(m_title->defaultTextColor());
304 return QBrush(m_title->defaultTextColor());
304 }
305 }
305
306
306 void ChartPresenter::setBackgroundVisible(bool visible)
307 void ChartPresenter::setBackgroundVisible(bool visible)
307 {
308 {
308 createBackgroundItem();
309 createBackgroundItem();
309 m_background->setVisible(visible);
310 m_background->setVisible(visible);
310 }
311 }
311
312
312
313
313 bool ChartPresenter::isBackgroundVisible() const
314 bool ChartPresenter::isBackgroundVisible() const
314 {
315 {
315 if (!m_background)
316 if (!m_background)
316 return false;
317 return false;
317 return m_background->isVisible();
318 return m_background->isVisible();
318 }
319 }
319
320
320 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
321 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
321 {
322 {
322 createPlotAreaBackgroundItem();
323 createPlotAreaBackgroundItem();
323 m_plotAreaBackground->setVisible(visible);
324 m_plotAreaBackground->setVisible(visible);
324 }
325 }
325
326
326 bool ChartPresenter::isPlotAreaBackgroundVisible() const
327 bool ChartPresenter::isPlotAreaBackgroundVisible() const
327 {
328 {
328 if (!m_plotAreaBackground)
329 if (!m_plotAreaBackground)
329 return false;
330 return false;
330 return m_plotAreaBackground->isVisible();
331 return m_plotAreaBackground->isVisible();
331 }
332 }
332
333
333 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
334 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
334 {
335 {
335 createBackgroundItem();
336 createBackgroundItem();
336 m_background->setDropShadowEnabled(enabled);
337 m_background->setDropShadowEnabled(enabled);
337 }
338 }
338
339
339 bool ChartPresenter::isBackgroundDropShadowEnabled() const
340 bool ChartPresenter::isBackgroundDropShadowEnabled() const
340 {
341 {
341 if (!m_background)
342 if (!m_background)
342 return false;
343 return false;
343 return m_background->isDropShadowEnabled();
344 return m_background->isDropShadowEnabled();
344 }
345 }
345
346
346
347
347 AbstractChartLayout *ChartPresenter::layout()
348 AbstractChartLayout *ChartPresenter::layout()
348 {
349 {
349 return m_layout;
350 return m_layout;
350 }
351 }
351
352
352 QLegend *ChartPresenter::legend()
353 QLegend *ChartPresenter::legend()
353 {
354 {
354 return m_chart->legend();
355 return m_chart->legend();
355 }
356 }
356
357
357 void ChartPresenter::setVisible(bool visible)
358 void ChartPresenter::setVisible(bool visible)
358 {
359 {
359 m_chart->setVisible(visible);
360 m_chart->setVisible(visible);
360 }
361 }
361
362
362 ChartBackground *ChartPresenter::backgroundElement()
363 ChartBackground *ChartPresenter::backgroundElement()
363 {
364 {
364 return m_background;
365 return m_background;
365 }
366 }
366
367
367 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
368 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
368 {
369 {
369 return m_plotAreaBackground;
370 return m_plotAreaBackground;
370 }
371 }
371
372
372 QList<ChartAxisElement *> ChartPresenter::axisItems() const
373 QList<ChartAxisElement *> ChartPresenter::axisItems() const
373 {
374 {
374 return m_axisItems;
375 return m_axisItems;
375 }
376 }
376
377
377 QList<ChartItem *> ChartPresenter::chartItems() const
378 QList<ChartItem *> ChartPresenter::chartItems() const
378 {
379 {
379 return m_chartItems;
380 return m_chartItems;
380 }
381 }
381
382
382 ChartTitle *ChartPresenter::titleElement()
383 ChartTitle *ChartPresenter::titleElement()
383 {
384 {
384 return m_title;
385 return m_title;
385 }
386 }
386
387
387 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
388 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
388 {
389 {
389 static QGraphicsTextItem dummyTextItem;
390 static QGraphicsTextItem dummyTextItem;
391 static bool initMargin = true;
392 if (initMargin) {
393 dummyTextItem.document()->setDocumentMargin(textMargin());
394 initMargin = false;
395 }
390
396
391 dummyTextItem.setFont(font);
397 dummyTextItem.setFont(font);
392 dummyTextItem.setHtml(text);
398 dummyTextItem.setHtml(text);
393 QRectF boundingRect = dummyTextItem.boundingRect();
399 QRectF boundingRect = dummyTextItem.boundingRect();
394
400
395 // Take rotation into account
401 // Take rotation into account
396 if (angle) {
402 if (angle) {
397 QTransform transform;
403 QTransform transform;
398 transform.rotate(angle);
404 transform.rotate(angle);
399 boundingRect = transform.mapRect(boundingRect);
405 boundingRect = transform.mapRect(boundingRect);
400 }
406 }
401
407
402 return boundingRect;
408 return boundingRect;
403 }
409 }
404
410
405 // boundingRect parameter returns the rotated bounding rect of the text
411 // boundingRect parameter returns the rotated bounding rect of the text
406 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
412 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
407 qreal maxSize, Qt::Orientation constraintOrientation,
413 qreal maxSize, Qt::Orientation constraintOrientation,
408 QRectF &boundingRect)
414 QRectF &boundingRect)
409 {
415 {
410 QString truncatedString(text);
416 QString truncatedString(text);
411 boundingRect = textBoundingRect(font, truncatedString, angle);
417 boundingRect = textBoundingRect(font, truncatedString, angle);
412 qreal checkDimension = ((constraintOrientation == Qt::Horizontal)
418 qreal checkDimension = ((constraintOrientation == Qt::Horizontal)
413 ? boundingRect.width() : boundingRect.height());
419 ? boundingRect.width() : boundingRect.height());
414 if (checkDimension > maxSize) {
420 if (checkDimension > maxSize) {
415 // It can be assumed that almost any amount of string manipulation is faster
421 // It can be assumed that almost any amount of string manipulation is faster
416 // than calculating one bounding rectangle, so first prepare a list of truncated strings
422 // than calculating one bounding rectangle, so first prepare a list of truncated strings
417 // to try.
423 // to try.
418 static const char *truncateMatchString = "&#?[0-9a-zA-Z]*;$";
424 static const char *truncateMatchString = "&#?[0-9a-zA-Z]*;$";
419 static QRegExp truncateMatcher(truncateMatchString);
425 static QRegExp truncateMatcher(truncateMatchString);
420
426
421 QVector<QString> testStrings(text.length());
427 QVector<QString> testStrings(text.length());
422 int count(0);
428 int count(0);
423 static QLatin1Char closeTag('>');
429 static QLatin1Char closeTag('>');
424 static QLatin1Char openTag('<');
430 static QLatin1Char openTag('<');
425 static QLatin1Char semiColon(';');
431 static QLatin1Char semiColon(';');
426 static QLatin1String ellipsis("...");
432 static QLatin1String ellipsis("...");
427 while (truncatedString.length() > 1) {
433 while (truncatedString.length() > 1) {
428 int chopIndex(-1);
434 int chopIndex(-1);
429 int chopCount(1);
435 int chopCount(1);
430 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
436 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
431
437
432 if (lastChar == closeTag)
438 if (lastChar == closeTag)
433 chopIndex = truncatedString.lastIndexOf(openTag);
439 chopIndex = truncatedString.lastIndexOf(openTag);
434 else if (lastChar == semiColon)
440 else if (lastChar == semiColon)
435 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
441 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
436
442
437 if (chopIndex != -1)
443 if (chopIndex != -1)
438 chopCount = truncatedString.length() - chopIndex;
444 chopCount = truncatedString.length() - chopIndex;
439 truncatedString.chop(chopCount);
445 truncatedString.chop(chopCount);
440 testStrings[count] = truncatedString + ellipsis;
446 testStrings[count] = truncatedString + ellipsis;
441 count++;
447 count++;
442 }
448 }
443
449
444 // Binary search for best fit
450 // Binary search for best fit
445 int minIndex(0);
451 int minIndex(0);
446 int maxIndex(count - 1);
452 int maxIndex(count - 1);
447 int bestIndex(count);
453 int bestIndex(count);
448 QRectF checkRect;
454 QRectF checkRect;
449 while (maxIndex >= minIndex) {
455 while (maxIndex >= minIndex) {
450 int mid = (maxIndex + minIndex) / 2;
456 int mid = (maxIndex + minIndex) / 2;
451 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
457 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
452 checkDimension = ((constraintOrientation == Qt::Horizontal)
458 checkDimension = ((constraintOrientation == Qt::Horizontal)
453 ? checkRect.width() : checkRect.height());
459 ? checkRect.width() : checkRect.height());
454 if (checkDimension > maxSize) {
460 if (checkDimension > maxSize) {
455 // Checked index too large, all under this are also too large
461 // Checked index too large, all under this are also too large
456 minIndex = mid + 1;
462 minIndex = mid + 1;
457 } else {
463 } else {
458 // Checked index fits, all over this also fit
464 // Checked index fits, all over this also fit
459 maxIndex = mid - 1;
465 maxIndex = mid - 1;
460 bestIndex = mid;
466 bestIndex = mid;
461 boundingRect = checkRect;
467 boundingRect = checkRect;
462 }
468 }
463 }
469 }
464 // Default to "..." if nothing fits
470 // Default to "..." if nothing fits
465 if (bestIndex == count) {
471 if (bestIndex == count) {
466 boundingRect = textBoundingRect(font, ellipsis, angle);
472 boundingRect = textBoundingRect(font, ellipsis, angle);
467 truncatedString = ellipsis;
473 truncatedString = ellipsis;
468 } else {
474 } else {
469 truncatedString = testStrings.at(bestIndex);
475 truncatedString = testStrings.at(bestIndex);
470 }
476 }
471 }
477 }
472
478
473 return truncatedString;
479 return truncatedString;
474 }
480 }
475
481
476 #include "moc_chartpresenter_p.cpp"
482 #include "moc_chartpresenter_p.cpp"
477
483
478 QTCOMMERCIALCHART_END_NAMESPACE
484 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,179 +1,180
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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef CHARTPRESENTER_H
30 #ifndef CHARTPRESENTER_H
31 #define CHARTPRESENTER_H
31 #define CHARTPRESENTER_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "qchart.h" //because of QChart::ChartThemeId
34 #include "qchart.h" //because of QChart::ChartThemeId
35 #include <QRectF>
35 #include <QRectF>
36 #include <QMargins>
36 #include <QMargins>
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 class ChartItem;
40 class ChartItem;
41 class AxisItem;
41 class AxisItem;
42 class QAbstractSeries;
42 class QAbstractSeries;
43 class ChartDataSet;
43 class ChartDataSet;
44 class AbstractDomain;
44 class AbstractDomain;
45 class ChartAxisElement;
45 class ChartAxisElement;
46 class ChartAnimator;
46 class ChartAnimator;
47 class ChartBackground;
47 class ChartBackground;
48 class ChartTitle;
48 class ChartTitle;
49 class ChartAnimation;
49 class ChartAnimation;
50 class AbstractChartLayout;
50 class AbstractChartLayout;
51
51
52 class ChartPresenter: public QObject
52 class ChartPresenter: public QObject
53 {
53 {
54 Q_OBJECT
54 Q_OBJECT
55 public:
55 public:
56 enum ZValues {
56 enum ZValues {
57 BackgroundZValue = -1,
57 BackgroundZValue = -1,
58 PlotAreaZValue,
58 PlotAreaZValue,
59 ShadesZValue,
59 ShadesZValue,
60 GridZValue,
60 GridZValue,
61 AxisZValue,
61 AxisZValue,
62 SeriesZValue,
62 SeriesZValue,
63 LineChartZValue = SeriesZValue,
63 LineChartZValue = SeriesZValue,
64 SplineChartZValue = SeriesZValue,
64 SplineChartZValue = SeriesZValue,
65 BarSeriesZValue = SeriesZValue,
65 BarSeriesZValue = SeriesZValue,
66 ScatterSeriesZValue = SeriesZValue,
66 ScatterSeriesZValue = SeriesZValue,
67 PieSeriesZValue = SeriesZValue,
67 PieSeriesZValue = SeriesZValue,
68 BoxPlotSeriesZValue = SeriesZValue,
68 BoxPlotSeriesZValue = SeriesZValue,
69 LegendZValue,
69 LegendZValue,
70 TopMostZValue
70 TopMostZValue
71 };
71 };
72
72
73 enum State {
73 enum State {
74 ShowState,
74 ShowState,
75 ScrollUpState,
75 ScrollUpState,
76 ScrollDownState,
76 ScrollDownState,
77 ScrollLeftState,
77 ScrollLeftState,
78 ScrollRightState,
78 ScrollRightState,
79 ZoomInState,
79 ZoomInState,
80 ZoomOutState
80 ZoomOutState
81 };
81 };
82
82
83 ChartPresenter(QChart *chart, QChart::ChartType type);
83 ChartPresenter(QChart *chart, QChart::ChartType type);
84 virtual ~ChartPresenter();
84 virtual ~ChartPresenter();
85
85
86
86
87 void setGeometry(QRectF rect);
87 void setGeometry(QRectF rect);
88 QRectF geometry() const;
88 QRectF geometry() const;
89
89
90 QGraphicsItem *rootItem(){ return m_chart; }
90 QGraphicsItem *rootItem(){ return m_chart; }
91 ChartBackground *backgroundElement();
91 ChartBackground *backgroundElement();
92 QAbstractGraphicsShapeItem *plotAreaElement();
92 QAbstractGraphicsShapeItem *plotAreaElement();
93 ChartTitle *titleElement();
93 ChartTitle *titleElement();
94 QList<ChartAxisElement *> axisItems() const;
94 QList<ChartAxisElement *> axisItems() const;
95 QList<ChartItem *> chartItems() const;
95 QList<ChartItem *> chartItems() const;
96
96
97 QLegend *legend();
97 QLegend *legend();
98
98
99 void setBackgroundBrush(const QBrush &brush);
99 void setBackgroundBrush(const QBrush &brush);
100 QBrush backgroundBrush() const;
100 QBrush backgroundBrush() const;
101
101
102 void setBackgroundPen(const QPen &pen);
102 void setBackgroundPen(const QPen &pen);
103 QPen backgroundPen() const;
103 QPen backgroundPen() const;
104
104
105 void setBackgroundRoundness(qreal diameter);
105 void setBackgroundRoundness(qreal diameter);
106 qreal backgroundRoundness() const;
106 qreal backgroundRoundness() const;
107
107
108 void setPlotAreaBackgroundBrush(const QBrush &brush);
108 void setPlotAreaBackgroundBrush(const QBrush &brush);
109 QBrush plotAreaBackgroundBrush() const;
109 QBrush plotAreaBackgroundBrush() const;
110
110
111 void setPlotAreaBackgroundPen(const QPen &pen);
111 void setPlotAreaBackgroundPen(const QPen &pen);
112 QPen plotAreaBackgroundPen() const;
112 QPen plotAreaBackgroundPen() const;
113
113
114 void setTitle(const QString &title);
114 void setTitle(const QString &title);
115 QString title() const;
115 QString title() const;
116
116
117 void setTitleFont(const QFont &font);
117 void setTitleFont(const QFont &font);
118 QFont titleFont() const;
118 QFont titleFont() const;
119
119
120 void setTitleBrush(const QBrush &brush);
120 void setTitleBrush(const QBrush &brush);
121 QBrush titleBrush() const;
121 QBrush titleBrush() const;
122
122
123 void setBackgroundVisible(bool visible);
123 void setBackgroundVisible(bool visible);
124 bool isBackgroundVisible() const;
124 bool isBackgroundVisible() const;
125
125
126 void setPlotAreaBackgroundVisible(bool visible);
126 void setPlotAreaBackgroundVisible(bool visible);
127 bool isPlotAreaBackgroundVisible() const;
127 bool isPlotAreaBackgroundVisible() const;
128
128
129 void setBackgroundDropShadowEnabled(bool enabled);
129 void setBackgroundDropShadowEnabled(bool enabled);
130 bool isBackgroundDropShadowEnabled() const;
130 bool isBackgroundDropShadowEnabled() const;
131
131
132 void setVisible(bool visible);
132 void setVisible(bool visible);
133
133
134 void setAnimationOptions(QChart::AnimationOptions options);
134 void setAnimationOptions(QChart::AnimationOptions options);
135 QChart::AnimationOptions animationOptions() const;
135 QChart::AnimationOptions animationOptions() const;
136
136
137 void startAnimation(ChartAnimation *animation);
137 void startAnimation(ChartAnimation *animation);
138
138
139 void setState(State state,QPointF point);
139 void setState(State state,QPointF point);
140 State state() const { return m_state; }
140 State state() const { return m_state; }
141 QPointF statePoint() const { return m_statePoint; }
141 QPointF statePoint() const { return m_statePoint; }
142 AbstractChartLayout *layout();
142 AbstractChartLayout *layout();
143
143
144 QChart::ChartType chartType() const { return m_chart->chartType(); }
144 QChart::ChartType chartType() const { return m_chart->chartType(); }
145 QChart *chart() { return m_chart; }
145 QChart *chart() { return m_chart; }
146
146
147 static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0);
147 static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0);
148 static QString truncatedText(const QFont &font, const QString &text, qreal angle, qreal maxSize,
148 static QString truncatedText(const QFont &font, const QString &text, qreal angle, qreal maxSize,
149 Qt::Orientation constraintOrientation, QRectF &boundingRect);
149 Qt::Orientation constraintOrientation, QRectF &boundingRect);
150 inline static qreal textMargin() { return qreal(0.5); }
150 private:
151 private:
151 void createBackgroundItem();
152 void createBackgroundItem();
152 void createPlotAreaBackgroundItem();
153 void createPlotAreaBackgroundItem();
153 void createTitleItem();
154 void createTitleItem();
154
155
155 public Q_SLOTS:
156 public Q_SLOTS:
156 void handleSeriesAdded(QAbstractSeries *series);
157 void handleSeriesAdded(QAbstractSeries *series);
157 void handleSeriesRemoved(QAbstractSeries *series);
158 void handleSeriesRemoved(QAbstractSeries *series);
158 void handleAxisAdded(QAbstractAxis *axis);
159 void handleAxisAdded(QAbstractAxis *axis);
159 void handleAxisRemoved(QAbstractAxis *axis);
160 void handleAxisRemoved(QAbstractAxis *axis);
160
161
161 private:
162 private:
162 QChart *m_chart;
163 QChart *m_chart;
163 QList<ChartItem *> m_chartItems;
164 QList<ChartItem *> m_chartItems;
164 QList<ChartAxisElement *> m_axisItems;
165 QList<ChartAxisElement *> m_axisItems;
165 QList<QAbstractSeries *> m_series;
166 QList<QAbstractSeries *> m_series;
166 QList<QAbstractAxis *> m_axes;
167 QList<QAbstractAxis *> m_axes;
167 QChart::AnimationOptions m_options;
168 QChart::AnimationOptions m_options;
168 State m_state;
169 State m_state;
169 QPointF m_statePoint;
170 QPointF m_statePoint;
170 AbstractChartLayout *m_layout;
171 AbstractChartLayout *m_layout;
171 ChartBackground *m_background;
172 ChartBackground *m_background;
172 QAbstractGraphicsShapeItem *m_plotAreaBackground;
173 QAbstractGraphicsShapeItem *m_plotAreaBackground;
173 ChartTitle *m_title;
174 ChartTitle *m_title;
174 QRectF m_rect;
175 QRectF m_rect;
175 };
176 };
176
177
177 QTCOMMERCIALCHART_END_NAMESPACE
178 QTCOMMERCIALCHART_END_NAMESPACE
178
179
179 #endif /* CHARTPRESENTER_H */
180 #endif /* CHARTPRESENTER_H */
@@ -1,87 +1,88
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 "charttitle_p.h"
21 #include "charttitle_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include <QFont>
23 #include <QFont>
24 #include <QFontMetrics>
24 #include <QFontMetrics>
25 #include <QDebug>
25 #include <QDebug>
26 #include <QTextDocument>
26
27
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
29
29 ChartTitle::ChartTitle(QGraphicsItem *parent)
30 ChartTitle::ChartTitle(QGraphicsItem *parent)
30 : QGraphicsTextItem(parent)
31 : QGraphicsTextItem(parent)
31 {
32 {
32
33 document()->setDocumentMargin(ChartPresenter::textMargin());
33 }
34 }
34
35
35 ChartTitle::~ChartTitle()
36 ChartTitle::~ChartTitle()
36 {
37 {
37
38
38 }
39 }
39
40
40 void ChartTitle::setText(const QString &text)
41 void ChartTitle::setText(const QString &text)
41 {
42 {
42 m_text = text;
43 m_text = text;
43 }
44 }
44
45
45 QString ChartTitle::text() const
46 QString ChartTitle::text() const
46 {
47 {
47 return m_text;
48 return m_text;
48 }
49 }
49
50
50 void ChartTitle::setGeometry(const QRectF &rect)
51 void ChartTitle::setGeometry(const QRectF &rect)
51 {
52 {
52 QRectF dummyRect;
53 QRectF dummyRect;
53 QGraphicsTextItem::setHtml(ChartPresenter::truncatedText(font(), m_text, qreal(0.0), rect.width(), Qt::Horizontal, dummyRect));
54 QGraphicsTextItem::setHtml(ChartPresenter::truncatedText(font(), m_text, qreal(0.0), rect.width(), Qt::Horizontal, dummyRect));
54 setPos(rect.topLeft());
55 setPos(rect.topLeft());
55 }
56 }
56
57
57
58
58 QSizeF ChartTitle::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
59 QSizeF ChartTitle::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
59 {
60 {
60 Q_UNUSED(constraint);
61 Q_UNUSED(constraint);
61 QSizeF sh;
62 QSizeF sh;
62
63
63 switch (which) {
64 switch (which) {
64 case Qt::MinimumSize: {
65 case Qt::MinimumSize: {
65 QRectF titleRect = ChartPresenter::textBoundingRect(font(), "...");
66 QRectF titleRect = ChartPresenter::textBoundingRect(font(), "...");
66 sh = QSizeF(titleRect.width(), titleRect.height());
67 sh = QSizeF(titleRect.width(), titleRect.height());
67 break;
68 break;
68 }
69 }
69 case Qt::PreferredSize:
70 case Qt::PreferredSize:
70 case Qt::MaximumSize: {
71 case Qt::MaximumSize: {
71 QRectF titleRect = ChartPresenter::textBoundingRect(font(), m_text);
72 QRectF titleRect = ChartPresenter::textBoundingRect(font(), m_text);
72 sh = QSizeF(titleRect.width(), titleRect.height());
73 sh = QSizeF(titleRect.width(), titleRect.height());
73 break;
74 break;
74 }
75 }
75 case Qt::MinimumDescent: {
76 case Qt::MinimumDescent: {
76 QFontMetrics fn(font());
77 QFontMetrics fn(font());
77 sh = QSizeF(0, fn.descent());
78 sh = QSizeF(0, fn.descent());
78 break;
79 break;
79 }
80 }
80 default:
81 default:
81 break;
82 break;
82 }
83 }
83
84
84 return sh;
85 return sh;
85 }
86 }
86
87
87 QTCOMMERCIALCHART_END_NAMESPACE
88 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,186 +1,189
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 <QPainter>
21 #include <QPainter>
22 #include <QGraphicsSceneEvent>
22 #include <QGraphicsSceneEvent>
23 #include <QGraphicsTextItem>
23 #include <QGraphicsTextItem>
24 #include <QTextDocument>
24
25
25 #include "qlegend.h"
26 #include "qlegend.h"
26 #include "qlegend_p.h"
27 #include "qlegend_p.h"
27 #include "qlegendmarker.h"
28 #include "qlegendmarker.h"
28 #include "qlegendmarker_p.h"
29 #include "qlegendmarker_p.h"
29 #include "legendmarkeritem_p.h"
30 #include "legendmarkeritem_p.h"
30 #include "chartpresenter_p.h"
31 #include "chartpresenter_p.h"
31
32
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
34
34 LegendMarkerItem::LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent) :
35 LegendMarkerItem::LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent) :
35 QGraphicsObject(parent),
36 QGraphicsObject(parent),
36 m_marker(marker),
37 m_marker(marker),
37 m_markerRect(0,0,10.0,10.0),
38 m_markerRect(0,0,10.0,10.0),
38 m_boundingRect(0,0,0,0),
39 m_boundingRect(0,0,0,0),
39 m_textItem(new QGraphicsTextItem(this)),
40 m_textItem(new QGraphicsTextItem(this)),
40 m_rectItem(new QGraphicsRectItem(this)),
41 m_rectItem(new QGraphicsRectItem(this)),
41 m_margin(1),
42 m_margin(3),
42 m_space(2),
43 m_space(4),
43 m_hovering(false),
44 m_hovering(false),
44 m_pressPos(0, 0)
45 m_pressPos(0, 0)
45 {
46 {
46 m_rectItem->setRect(m_markerRect);
47 m_rectItem->setRect(m_markerRect);
48 m_textItem->document()->setDocumentMargin(ChartPresenter::textMargin());
47 setAcceptHoverEvents(true);
49 setAcceptHoverEvents(true);
48 }
50 }
49
51
50 LegendMarkerItem::~LegendMarkerItem()
52 LegendMarkerItem::~LegendMarkerItem()
51 {
53 {
52 if (m_hovering) {
54 if (m_hovering) {
53 emit m_marker->q_ptr->hovered(false);
55 emit m_marker->q_ptr->hovered(false);
54 }
56 }
55 }
57 }
56
58
57 void LegendMarkerItem::setPen(const QPen &pen)
59 void LegendMarkerItem::setPen(const QPen &pen)
58 {
60 {
59 m_rectItem->setPen(pen);
61 m_rectItem->setPen(pen);
60 }
62 }
61
63
62 QPen LegendMarkerItem::pen() const
64 QPen LegendMarkerItem::pen() const
63 {
65 {
64 return m_rectItem->pen();
66 return m_rectItem->pen();
65 }
67 }
66
68
67 void LegendMarkerItem::setBrush(const QBrush &brush)
69 void LegendMarkerItem::setBrush(const QBrush &brush)
68 {
70 {
69 m_rectItem->setBrush(brush);
71 m_rectItem->setBrush(brush);
70 }
72 }
71
73
72 QBrush LegendMarkerItem::brush() const
74 QBrush LegendMarkerItem::brush() const
73 {
75 {
74 return m_rectItem->brush();
76 return m_rectItem->brush();
75 }
77 }
76
78
77 void LegendMarkerItem::setFont(const QFont &font)
79 void LegendMarkerItem::setFont(const QFont &font)
78 {
80 {
79 m_textItem->setFont(font);
81 m_textItem->setFont(font);
80 QFontMetrics fn(font);
82 QFontMetrics fn(font);
81 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
83 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
82 updateGeometry();
84 updateGeometry();
83 }
85 }
84
86
85 QFont LegendMarkerItem::font() const
87 QFont LegendMarkerItem::font() const
86 {
88 {
87 return m_textItem->font();
89 return m_textItem->font();
88 }
90 }
89
91
90 void LegendMarkerItem::setLabel(const QString label)
92 void LegendMarkerItem::setLabel(const QString label)
91 {
93 {
92 m_label = label;
94 m_label = label;
93 updateGeometry();
95 updateGeometry();
94 }
96 }
95
97
96 QString LegendMarkerItem::label() const
98 QString LegendMarkerItem::label() const
97 {
99 {
98 return m_label;
100 return m_label;
99 }
101 }
100
102
101 void LegendMarkerItem::setLabelBrush(const QBrush &brush)
103 void LegendMarkerItem::setLabelBrush(const QBrush &brush)
102 {
104 {
103 m_textItem->setDefaultTextColor(brush.color());
105 m_textItem->setDefaultTextColor(brush.color());
104 }
106 }
105
107
106 QBrush LegendMarkerItem::labelBrush() const
108 QBrush LegendMarkerItem::labelBrush() const
107 {
109 {
108 return QBrush(m_textItem->defaultTextColor());
110 return QBrush(m_textItem->defaultTextColor());
109 }
111 }
110
112
111 void LegendMarkerItem::setGeometry(const QRectF &rect)
113 void LegendMarkerItem::setGeometry(const QRectF &rect)
112 {
114 {
113 qreal width = rect.width();
115 qreal width = rect.width();
114 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
116 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
115 QRectF truncatedRect;
117 QRectF truncatedRect;
116
118
117 m_textItem->setHtml(ChartPresenter::truncatedText(m_textItem->font(), m_label, qreal(0.0), width - x, Qt::Horizontal, truncatedRect));
119 m_textItem->setHtml(ChartPresenter::truncatedText(m_textItem->font(), m_label, qreal(0.0), width - x, Qt::Horizontal, truncatedRect));
118
120
119 qreal y = qMax(m_markerRect.height() + 2 * m_margin, truncatedRect.height() + 2 * m_margin);
121 qreal y = qMax(m_markerRect.height() + 2 * m_margin, truncatedRect.height() + 2 * m_margin);
120
122
121 const QRectF &textRect = m_textItem->boundingRect();
123 const QRectF &textRect = m_textItem->boundingRect();
122
124
123 m_textItem->setPos(x - m_margin, y / 2 - textRect.height() / 2);
125 m_textItem->setPos(x - m_margin, y / 2 - textRect.height() / 2);
124 m_rectItem->setRect(m_markerRect);
126 m_rectItem->setRect(m_markerRect);
125 m_rectItem->setPos(m_margin, y / 2 - m_markerRect.height() / 2);
127 // The textMargin adjustments to position are done to make default case rects less blurry with anti-aliasing
128 m_rectItem->setPos(m_margin - ChartPresenter::textMargin(), y / 2.0 - m_markerRect.height() / 2.0 + ChartPresenter::textMargin());
126
129
127 prepareGeometryChange();
130 prepareGeometryChange();
128 m_boundingRect = QRectF(0, 0, x + textRect.width() + m_margin, y);
131 m_boundingRect = QRectF(0, 0, x + textRect.width() + m_margin, y);
129 }
132 }
130
133
131 QRectF LegendMarkerItem::boundingRect() const
134 QRectF LegendMarkerItem::boundingRect() const
132 {
135 {
133 return m_boundingRect;
136 return m_boundingRect;
134 }
137 }
135
138
136 void LegendMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
139 void LegendMarkerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
137 {
140 {
138 Q_UNUSED(option)
141 Q_UNUSED(option)
139 Q_UNUSED(widget)
142 Q_UNUSED(widget)
140 Q_UNUSED(painter)
143 Q_UNUSED(painter)
141 }
144 }
142
145
143 QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
146 QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
144 {
147 {
145 Q_UNUSED(constraint)
148 Q_UNUSED(constraint)
146
149
147 QSizeF sh;
150 QSizeF sh;
148
151
149 switch (which) {
152 switch (which) {
150 case Qt::MinimumSize: {
153 case Qt::MinimumSize: {
151 QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(), "...");
154 QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(), "...");
152 sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(),
155 sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(),
153 qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin));
156 qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin));
154 break;
157 break;
155 }
158 }
156 case Qt::PreferredSize: {
159 case Qt::PreferredSize: {
157 QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(), m_label);
160 QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(), m_label);
158 sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(),
161 sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(),
159 qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin));
162 qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin));
160 break;
163 break;
161 }
164 }
162 default:
165 default:
163 break;
166 break;
164 }
167 }
165
168
166 return sh;
169 return sh;
167 }
170 }
168
171
169 void LegendMarkerItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
172 void LegendMarkerItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
170 {
173 {
171 Q_UNUSED(event)
174 Q_UNUSED(event)
172 m_hovering = true;
175 m_hovering = true;
173 emit m_marker->q_ptr->hovered(true);
176 emit m_marker->q_ptr->hovered(true);
174 }
177 }
175
178
176 void LegendMarkerItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
179 void LegendMarkerItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
177 {
180 {
178 Q_UNUSED(event)
181 Q_UNUSED(event)
179 m_hovering = false;
182 m_hovering = false;
180 emit m_marker->q_ptr->hovered(false);
183 emit m_marker->q_ptr->hovered(false);
181 }
184 }
182
185
183
186
184 #include "moc_legendmarkeritem_p.cpp"
187 #include "moc_legendmarkeritem_p.cpp"
185
188
186 QTCOMMERCIALCHART_END_NAMESPACE
189 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now