##// END OF EJS Templates
Updates axis drawing code...
Michal Klocek -
r2133:8c175959daec
parent child
Show More
@@ -1,64 +1,66
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "charts.h"
22 22 #include "qchart.h"
23 23 #include "qbarseries.h"
24 24 #include "qbarset.h"
25 25 #include "qvalueaxis.h"
26 26 #include "qbarcategoryaxis.h"
27 27
28 28 class BarCategoryAxisX: public Chart
29 29 {
30 30 public:
31 31 QString name() { return "AxisX"; }
32 32 QString category() { return QObject::tr("Axis"); }
33 33 QString subCategory() { return "BarCategoryAxis"; }
34 34
35 35 QChart *createChart(const DataTable &table)
36 36 {
37 37 QChart *chart = new QChart();
38 38 chart->setTitle(" BarCateogry X , Value Y");
39 39
40 40 QString name("Series ");
41 41 QBarSeries *series = new QBarSeries(chart);
42 42 QValueAxis *valueaxis = new QValueAxis();
43 43 QBarCategoryAxis *barcategory = new QBarCategoryAxis();
44 44 for (int i(0); i < table.count(); i++) {
45 45 QBarSet *set = new QBarSet("Bar set " + QString::number(i));
46 46 foreach (Data data, table[i])
47 47 *set << data.first.y();
48 48 series->append(set);
49 49 }
50 50 chart->addSeries(series);
51 51
52 52 int count = series->barSets().first()->count();
53 53
54 for (int i = 0; i < count; i++)
55 barcategory->append(QString::number(i));
54
55 for (int i = 0; i < count; i++) {
56 barcategory->append("BarSet " + QString::number(i));
57 }
56 58
57 59 chart->setAxisY(valueaxis, series);
58 60 chart->setAxisX(barcategory, series);
59 61
60 62 return chart;
61 63 }
62 64 };
63 65
64 66 DECLARE_CHART(BarCategoryAxisX);
@@ -1,64 +1,65
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "charts.h"
22 22 #include "qchart.h"
23 23 #include "qhorizontalbarseries.h"
24 24 #include "qbarset.h"
25 25 #include "qvalueaxis.h"
26 26 #include "qbarcategoryaxis.h"
27 27
28 28 class BarCategoryAxisY: public Chart
29 29 {
30 30 public:
31 31 QString name() { return "AxisY"; }
32 32 QString category() { return QObject::tr("Axis"); }
33 33 QString subCategory() { return "BarCategoryAxis"; }
34 34
35 35 QChart *createChart(const DataTable &table)
36 36 {
37 37 QChart *chart = new QChart();
38 38 chart->setTitle(" BarCateogry Y , Value X");
39 39
40 40 QString name("Series ");
41 41 QHorizontalBarSeries *series = new QHorizontalBarSeries(chart);
42 42 QValueAxis *valueaxis = new QValueAxis();
43 43 QBarCategoryAxis *barcategory = new QBarCategoryAxis();
44 44 for (int i(0); i < table.count(); i++) {
45 45 QBarSet *set = new QBarSet("Bar set " + QString::number(i));
46 46 foreach(Data data, table[i])
47 47 *set << data.first.y();
48 48 series->append(set);
49 49 }
50 50 chart->addSeries(series);
51 51
52 52 int count = series->barSets().first()->count();
53 53
54 for (int i = 0; i < count; i++)
55 barcategory->append(QString::number(i));
54 for (int i = 0; i < count; i++) {
55 barcategory->append("BarSet " + QString::number(i));
56 }
56 57
57 58 chart->setAxisX(valueaxis, series);
58 59 chart->setAxisY(barcategory, series);
59 60
60 61 return chart;
61 62 }
62 63 };
63 64
64 65 DECLARE_CHART(BarCategoryAxisY);
@@ -1,147 +1,148
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartbarcategoryaxisx_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qbarcategoryaxis_p.h"
24 24 #include <QFontMetrics>
25 25 #include <QDebug>
26 26 #include <qmath.h>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 ChartBarCategoryAxisX::ChartBarCategoryAxisX(QBarCategoryAxis *axis, ChartPresenter *presenter)
31 31 : HorizontalAxis(axis, presenter, true),
32 32 m_categoriesAxis(axis)
33 33 {
34 34
35 35 }
36 36
37 37 ChartBarCategoryAxisX::~ChartBarCategoryAxisX()
38 38 {
39 39 }
40 40
41 41 QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
42 42 {
43 int count = m_categoriesAxis->d_ptr->count();
43 QVector<qreal> points;
44 44
45 Q_ASSERT(count >= 1);
45 const QRectF& gridRect = gridGeometry();
46 qreal range = max() - min();
46 47
47 QVector<qreal> points;
48 points.resize(count + 2);
48 const qreal delta = gridRect.width()/range;
49 49
50 const QRectF &gridRect = gridGeometry();
50 if(delta<2) return points;
51
52 qreal offset =-min()-0.5;
53
54 offset = int(offset * delta)%int(delta);
51 55
52 const qreal delta = gridRect.width() / (count);
53 qreal offset = -min() - 0.5;
56 int count = qFloor(range);
54 57
55 if (delta < 1)
56 return points;
58 if(count < 1 ) return points;
57 59
58 if (offset < 0)
59 offset = int(offset * gridRect.width() / (max() - min())) % int(delta) + delta;
60 else
61 offset = int(offset * gridRect.width() / (max() - min())) % int(delta);
60 points.resize(count+2);
62 61
63 for (int i = -1; i < count + 1; ++i) {
62 for (int i = 0; i < count+2; ++i) {
64 63 qreal x = offset + i * delta + gridRect.left();
65 points[i + 1] = x;
64 points[i] = x;
66 65 }
66
67 67 return points;
68 68 }
69 69
70 70 QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const
71 71 {
72 72 QStringList result ;
73 73 const QRectF &gridRect = gridGeometry();
74 74
75 75 qreal d = (max() - min()) / gridRect.width();
76 76 for (int i = 0; i < layout.count() - 1; ++i) {
77 77 qreal x = qFloor((((layout[i] + layout[i + 1]) / 2 - gridRect.left()) * d + min() + 0.5));
78 78 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
79 79 result << m_categoriesAxis->categories().at(x);
80 80 } else {
81 81 // No label for x coordinate
82 82 result << "";
83 83 }
84 84 }
85 85 result << "";
86 86 return result;
87 87 }
88 88
89 89
90 90 void ChartBarCategoryAxisX::updateGeometry()
91 91 {
92 92 const QVector<qreal>& layout = ChartAxis::layout();
93 93 if (layout.isEmpty())
94 94 return;
95 95 setLabels(createCategoryLabels(layout));
96 96 HorizontalAxis::updateGeometry();
97 97 }
98 98
99 99 void ChartBarCategoryAxisX::handleAxisUpdated()
100 100 {
101 101 if (m_categoriesAxis->categories() != m_categories) {
102 102 m_categories = m_categoriesAxis->categories();
103 103 if (ChartAxis::layout().count() == m_categoriesAxis->d_ptr->count() + 2)
104 104 updateGeometry();
105 105 }
106 106 ChartAxis::handleAxisUpdated();
107 107 }
108 108
109 109 QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
110 110 {
111 111 Q_UNUSED(constraint)
112 112
113 113 QFontMetrics fn(font());
114 114 QSizeF sh;
115 115 QSizeF base = ChartAxis::sizeHint(which, constraint);
116 116 QStringList ticksList = createCategoryLabels(ChartAxis::layout());
117 qreal width = 0;
118 qreal height = 0;
119
120 switch (which) {
121 case Qt::MinimumSize:
122 width = fn.boundingRect("...").width();
123 height = fn.height() + labelPadding();
124 width = qMax(width, base.width());
125 height += base.height();
126 sh = QSizeF(width, height);
127 break;
128 case Qt::PreferredSize: {
129
130 for (int i = 0; i < ticksList.size(); ++i) {
131 QRectF rect = fn.boundingRect(ticksList.at(i));
132 width += rect.width();
133 height = qMax(rect.height() + labelPadding(), height);
134 }
135 width = qMax(width, base.width());
136 height += base.height();
137 sh = QSizeF(width, height);
138 break;
139 }
140 default:
141 break;
142 }
143 117
144 return sh;
118 qreal width=0;
119 qreal height=0;
120
121 switch (which) {
122 case Qt::MinimumSize:
123 width = fn.boundingRect("...").width();
124 height = fn.height()+labelPadding();
125 width=qMax(width,base.width());
126 height += base.height();
127 sh = QSizeF(width,height);
128 break;
129 case Qt::PreferredSize:{
130
131 for (int i = 0; i < ticksList.size(); ++i)
132 {
133 QRectF rect = fn.boundingRect(ticksList.at(i));
134 width += rect.width();
135 }
136 height = fn.height()+labelPadding();
137 width = qMax(width,base.width());
138 height += base.height();
139 sh = QSizeF(width,height);
140 break;
141 }
142 default:
143 break;
144 }
145 return sh;
145 146 }
146 147
147 148 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,144 +1,146
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartbarcategoryaxisy_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qbarcategoryaxis_p.h"
24 24 #include <qmath.h>
25 25 #include <QFontMetrics>
26 #include <QDebug>
26 27
27 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 29
29 30 ChartBarCategoryAxisY::ChartBarCategoryAxisY(QBarCategoryAxis *axis, ChartPresenter *presenter)
30 31 : VerticalAxis(axis, presenter, true),
31 32 m_categoriesAxis(axis)
32 33 {
33 34 }
34 35
35 36 ChartBarCategoryAxisY::~ChartBarCategoryAxisY()
36 37 {
37 38 }
38 39
39 40 QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
40 41 {
41 42 int count = m_categoriesAxis->d_ptr->count();
42 43
43 44 Q_ASSERT(count >= 1);
44 45
45 46 QVector<qreal> points;
46 47 points.resize(count + 2);
47 48
48 49 const QRectF &gridRect = gridGeometry();
49 50
50 51 const qreal delta = gridRect.height() / (count);
51 52 qreal offset = - min() - 0.5;
52 53
53 54 if (delta < 1)
54 55 return points;
55 56
56 57 if (offset < 0)
57 58 offset = int(offset * gridRect.height() / (max() - min())) % int(delta) + delta;
58 59 else
59 60 offset = int(offset * gridRect.height() / (max() - min())) % int(delta);
60 61
61 62 for (int i = -1; i < count + 1; ++i) {
62 63 int y = gridRect.bottom() - i * delta - offset;
63 64 points[i + 1] = y;
64 65 }
65 66 return points;
66 67 }
67 68
68 69 QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const
69 70 {
70 71 QStringList result;
71 72 const QRectF &gridRect = gridGeometry();
72 73 qreal d = (max() - min()) / gridRect.height();
73 74 for (int i = 0; i < layout.count() - 1; ++i) {
74 75 qreal x = qFloor(((gridRect.height() - (layout[i + 1] + layout[i]) / 2 + gridRect.top()) * d + min() + 0.5));
75 76 if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
76 77 result << m_categoriesAxis->categories().at(x);
77 78 } else {
78 79 // No label for x coordinate
79 80 result << "";
80 81 }
81 82 }
82 83 result << "";
83 84 return result;
84 85 }
85 86
86 87 void ChartBarCategoryAxisY::updateGeometry()
87 88 {
88 89 const QVector<qreal>& layout = ChartAxis::layout();
89 90 if (layout.isEmpty())
90 91 return;
91 92 setLabels(createCategoryLabels(layout));
92 93 VerticalAxis::updateGeometry();
93 94 }
94 95
95 96 void ChartBarCategoryAxisY::handleAxisUpdated()
96 97 {
97 98
98 99 if (m_categoriesAxis->categories() != m_categories) {
99 100 m_categories = m_categoriesAxis->categories();
100 101 if (ChartAxis::layout().count() == m_categoriesAxis->d_ptr->count() + 2)
101 102 updateGeometry();
102 103 }
103 104 ChartAxis::handleAxisUpdated();
104 105 }
105 106
106 107 QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
107 108 {
108 109 Q_UNUSED(constraint)
109 110
110 111 QFontMetrics fn(font());
111 112 QSizeF sh;
112 113 QSizeF base = ChartAxis::sizeHint(which, constraint);
113 114 QStringList ticksList = createCategoryLabels(ChartAxis::layout());
114 qreal width = 0;
115 qreal height = 0;
116
117 switch (which) {
118 case Qt::MinimumSize:
119 width = fn.boundingRect("...").width() + labelPadding();
120 height = fn.height();
121 width += base.width();
122 height = qMax(height, base.height());
123 sh = QSizeF(width, height);
124 break;
125 case Qt::PreferredSize: {
126
127 for (int i = 0; i < ticksList.size(); ++i) {
128 QRectF rect = fn.boundingRect(ticksList.at(i));
129 height += rect.height();
130 width = qMax(rect.width() + labelPadding(), width);
131 }
132 height = qMax(height, base.height());
133 width += base.width();
134 sh = QSizeF(width, height);
135 break;
136 }
137 default:
138 break;
139 }
140 115
141 return sh;
116 qreal width=0;
117 qreal height=0;
118
119 switch (which) {
120 case Qt::MinimumSize:
121 width = fn.boundingRect("...").width() + labelPadding();
122 height = fn.height();
123 width+=base.width();
124 height=qMax(height,base.height());
125 sh = QSizeF(width,height);
126 break;
127 case Qt::PreferredSize:{
128
129 for (int i = 0; i < ticksList.size(); ++i)
130 {
131 QRectF rect = fn.boundingRect(ticksList.at(i));
132 height+=rect.height();
133 width=qMax(rect.width()+labelPadding() +1 ,width); //one pixel torelance
134 }
135 height=qMax(height,base.height());
136 width+=base.width();
137 sh = QSizeF(width,height);
138 break;
139 }
140 default:
141 break;
142 }
143 return sh;
142 144 }
143 145
144 146 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,503 +1,502
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "qabstractaxis_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "chartlayout_p.h"
26 26 #include "domain_p.h"
27 27 #include <qmath.h>
28 28 #include <QDateTime>
29 29 #include <QValueAxis>
30 30 #include <QGraphicsLayout>
31 31 #include <QFontMetrics>
32 32
33 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 34
35 35 ChartAxis::ChartAxis(QAbstractAxis *axis, ChartPresenter *presenter, bool intervalAxis)
36 36 : ChartElement(presenter),
37 37 m_chartAxis(axis),
38 38 m_labelsAngle(0),
39 39 m_grid(new QGraphicsItemGroup(presenter->rootItem())),
40 40 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
41 41 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
42 42 m_arrow(new QGraphicsItemGroup(presenter->rootItem())),
43 43 m_title(new QGraphicsSimpleTextItem(presenter->rootItem())),
44 44 m_min(0),
45 45 m_max(0),
46 46 m_animation(0),
47 47 m_labelPadding(5),
48 48 m_intervalAxis(intervalAxis)
49 49 {
50 50 //initial initialization
51 51 m_arrow->setZValue(ChartPresenter::AxisZValue);
52 52 m_arrow->setHandlesChildEvents(false);
53 53 m_labels->setZValue(ChartPresenter::AxisZValue);
54 54 m_shades->setZValue(ChartPresenter::ShadesZValue);
55 55 m_grid->setZValue(ChartPresenter::GridZValue);
56 56
57 57 QObject::connect(m_chartAxis->d_ptr.data(), SIGNAL(updated()), this, SLOT(handleAxisUpdated()));
58 58
59 59 QGraphicsSimpleTextItem item;
60 60 m_font = item.font();
61 61
62 62 }
63 63
64 64 ChartAxis::~ChartAxis()
65 65 {
66 66 }
67 67
68 68 void ChartAxis::setAnimation(AxisAnimation *animation)
69 69 {
70 70 m_animation = animation;
71 71 }
72 72
73 73 void ChartAxis::setLayout(QVector<qreal> &layout)
74 74 {
75 75 m_layoutVector = layout;
76 76 }
77 77
78 78 void ChartAxis::createItems(int count)
79 79 {
80 80 if (m_arrow->children().size() == 0)
81 81 m_arrow->addToGroup(new AxisItem(this, presenter()->rootItem()));
82 82
83 83 if (m_intervalAxis && m_grid->children().size() == 0) {
84 84 for (int i = 0 ; i < 2 ; i ++)
85 85 m_grid->addToGroup(new QGraphicsLineItem(presenter()->rootItem()));
86 86 }
87 87
88 88 for (int i = 0; i < count; ++i) {
89 89 m_grid->addToGroup(new QGraphicsLineItem(presenter()->rootItem()));
90 90 m_labels->addToGroup(new QGraphicsSimpleTextItem(presenter()->rootItem()));
91 91 m_arrow->addToGroup(new QGraphicsLineItem(presenter()->rootItem()));
92 92 if ((m_grid->childItems().size()) % 2 && m_grid->childItems().size() > 2)
93 93 m_shades->addToGroup(new QGraphicsRectItem(presenter()->rootItem()));
94 94 }
95 95 }
96 96
97 97 void ChartAxis::deleteItems(int count)
98 98 {
99 99 QList<QGraphicsItem *> lines = m_grid->childItems();
100 100 QList<QGraphicsItem *> labels = m_labels->childItems();
101 101 QList<QGraphicsItem *> shades = m_shades->childItems();
102 102 QList<QGraphicsItem *> axis = m_arrow->childItems();
103 103
104 104 for (int i = 0; i < count; ++i) {
105 105 if (lines.size() % 2 && lines.size() > 1)
106 106 delete(shades.takeLast());
107 107 delete(lines.takeLast());
108 108 delete(labels.takeLast());
109 109 delete(axis.takeLast());
110 110 }
111 111 }
112 112
113 113 void ChartAxis::updateLayout(QVector<qreal> &layout)
114 114 {
115 115 int diff = m_layoutVector.size() - layout.size();
116 116
117 117 if (diff > 0)
118 118 deleteItems(diff);
119 119 else if (diff < 0)
120 120 createItems(-diff);
121 121
122 122 if (diff < 0) handleAxisUpdated();
123 123
124 124 if (m_animation) {
125 125 switch (presenter()->state()) {
126 126 case ChartPresenter::ZoomInState:
127 127 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
128 128 m_animation->setAnimationPoint(presenter()->statePoint());
129 129 break;
130 130 case ChartPresenter::ZoomOutState:
131 131 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
132 132 m_animation->setAnimationPoint(presenter()->statePoint());
133 133 break;
134 134 case ChartPresenter::ScrollUpState:
135 135 case ChartPresenter::ScrollLeftState:
136 136 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
137 137 break;
138 138 case ChartPresenter::ScrollDownState:
139 139 case ChartPresenter::ScrollRightState:
140 140 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
141 141 break;
142 142 case ChartPresenter::ShowState:
143 143 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
144 144 break;
145 145 }
146 146 m_animation->setValues(m_layoutVector, layout);
147 147 presenter()->startAnimation(m_animation);
148 148 } else {
149 149 setLayout(layout);
150 150 updateGeometry();
151 151 }
152 152 }
153 153
154 154 void ChartAxis::setArrowOpacity(qreal opacity)
155 155 {
156 156 m_arrow->setOpacity(opacity);
157 157 }
158 158
159 159 qreal ChartAxis::arrowOpacity() const
160 160 {
161 161 return m_arrow->opacity();
162 162 }
163 163
164 164 void ChartAxis::setArrowVisibility(bool visible)
165 165 {
166 166 m_arrow->setOpacity(visible);
167 167 }
168 168
169 169 void ChartAxis::setGridOpacity(qreal opacity)
170 170 {
171 171 m_grid->setOpacity(opacity);
172 172 }
173 173
174 174 qreal ChartAxis::gridOpacity() const
175 175 {
176 176 return m_grid->opacity();
177 177 }
178 178
179 179 void ChartAxis::setGridVisibility(bool visible)
180 180 {
181 181 m_grid->setOpacity(visible);
182 182 }
183 183
184 184 void ChartAxis::setLabelsOpacity(qreal opacity)
185 185 {
186 186 m_labels->setOpacity(opacity);
187 187 }
188 188
189 189 qreal ChartAxis::labelsOpacity() const
190 190 {
191 191 return m_labels->opacity();
192 192 }
193 193
194 194 void ChartAxis::setLabelsVisibility(bool visible)
195 195 {
196 196 m_labels->setOpacity(visible);
197 197 }
198 198
199 199 void ChartAxis::setShadesOpacity(qreal opacity)
200 200 {
201 201 m_shades->setOpacity(opacity);
202 202 }
203 203
204 204 qreal ChartAxis::shadesOpacity() const
205 205 {
206 206 return m_shades->opacity();
207 207 }
208 208
209 209 void ChartAxis::setShadesVisibility(bool visible)
210 210 {
211 211 m_shades->setVisible(visible);
212 212 }
213 213
214 214 void ChartAxis::setLabelsAngle(int angle)
215 215 {
216 216 foreach (QGraphicsItem *item, m_labels->childItems())
217 217 item->setRotation(angle);
218 218
219 219 m_labelsAngle = angle;
220 220 }
221 221
222 222 void ChartAxis::setLabelsPen(const QPen &pen)
223 223 {
224 224 foreach (QGraphicsItem *item , m_labels->childItems())
225 225 static_cast<QGraphicsSimpleTextItem *>(item)->setPen(pen);
226 226 }
227 227
228 228 void ChartAxis::setLabelsBrush(const QBrush &brush)
229 229 {
230 230 foreach (QGraphicsItem *item , m_labels->childItems())
231 231 static_cast<QGraphicsSimpleTextItem *>(item)->setBrush(brush);
232 232 }
233 233
234 234 void ChartAxis::setLabelsFont(const QFont &font)
235 235 {
236 236 foreach (QGraphicsItem *item , m_labels->childItems())
237 237 static_cast<QGraphicsSimpleTextItem *>(item)->setFont(font);
238 238
239 239 if (m_font != font) {
240 240 m_font = font;
241 241 foreach (QGraphicsItem *item , m_labels->childItems())
242 242 static_cast<QGraphicsSimpleTextItem *>(item)->setFont(font);
243 243 QGraphicsLayoutItem::updateGeometry();
244 244 presenter()->layout()->invalidate();
245 245 }
246 246 }
247 247
248 248 void ChartAxis::setShadesBrush(const QBrush &brush)
249 249 {
250 250 foreach (QGraphicsItem *item , m_shades->childItems())
251 251 static_cast<QGraphicsRectItem *>(item)->setBrush(brush);
252 252 }
253 253
254 254 void ChartAxis::setShadesPen(const QPen &pen)
255 255 {
256 256 foreach (QGraphicsItem *item , m_shades->childItems())
257 257 static_cast<QGraphicsRectItem *>(item)->setPen(pen);
258 258 }
259 259
260 260 void ChartAxis::setArrowPen(const QPen &pen)
261 261 {
262 262 foreach (QGraphicsItem *item , m_arrow->childItems())
263 263 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
264 264 }
265 265
266 266 void ChartAxis::setGridPen(const QPen &pen)
267 267 {
268 268 foreach (QGraphicsItem *item , m_grid->childItems())
269 269 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
270 270 }
271 271
272 272 void ChartAxis::setLabelPadding(int padding)
273 273 {
274 274 m_labelPadding = padding;
275 275 }
276 276
277 277 bool ChartAxis::isEmpty()
278 278 {
279 279 return !m_axisRect.isValid() || m_gridRect.isEmpty() || qFuzzyIsNull(m_min - m_max);
280 280 }
281 281
282 282 void ChartAxis::handleDomainUpdated()
283 283 {
284 284 Domain *domain = qobject_cast<Domain *>(sender());
285 285 qreal min(0);
286 286 qreal max(0);
287 287
288 288 if (m_chartAxis->orientation() == Qt::Horizontal) {
289 289 min = domain->minX();
290 290 max = domain->maxX();
291 291 } else if (m_chartAxis->orientation() == Qt::Vertical) {
292 292 min = domain->minY();
293 293 max = domain->maxY();
294 294 }
295 295
296 296 if (!qFuzzyIsNull(m_min - min) || !qFuzzyIsNull(m_max - max)) {
297 297 m_min = min;
298 298 m_max = max;
299 299
300 300 if (!isEmpty()) {
301 301
302 302 QVector<qreal> layout = calculateLayout();
303 303 updateLayout(layout);
304 QSizeF before = effectiveSizeHint(Qt::MinimumSize);
305
306 QSizeF after = sizeHint(Qt::MinimumSize);
304 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
305 QSizeF after = sizeHint(Qt::PreferredSize);
307 306
308 307 if (before != after) {
309 308 QGraphicsLayoutItem::updateGeometry();
310 309 //we don't want to call invalidate on layout, since it will change minimum size of component,
311 310 //which we would like to avoid since it causes nasty flips when scrolling or zooming,
312 311 //instead recalculate layout and use plotArea for extra space.
313 312 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
314 313 }
315 314 }
316 315 }
317 316 }
318 317
319 318 void ChartAxis::handleAxisUpdated()
320 319 {
321 320 if (isEmpty())
322 321 return;
323 322
324 323 bool visible = m_chartAxis->isVisible();
325 324
326 325 setArrowVisibility(visible && m_chartAxis->isLineVisible());
327 326 setGridVisibility(visible && m_chartAxis->isGridLineVisible());
328 327 setLabelsVisibility(visible && m_chartAxis->labelsVisible());
329 328 setShadesVisibility(visible && m_chartAxis->shadesVisible());
330 329 setLabelsAngle(m_chartAxis->labelsAngle());
331 330 setArrowPen(m_chartAxis->linePen());
332 331 setLabelsPen(m_chartAxis->labelsPen());
333 332 setLabelsBrush(m_chartAxis->labelsBrush());
334 333 setLabelsFont(m_chartAxis->labelsFont());
335 334 setGridPen(m_chartAxis->gridLinePen());
336 335 setShadesPen(m_chartAxis->shadesPen());
337 336 setShadesBrush(m_chartAxis->shadesBrush());
338 337 setTitleText(m_chartAxis->title());
339 338 }
340 339
341 340 void ChartAxis::setTitleText(const QString &title)
342 341 {
343 342 if (m_titleText != title) {
344 343 m_titleText = title;
345 344 m_axisRect = QRect();
346 345 QGraphicsLayoutItem::updateGeometry();
347 346 presenter()->layout()->invalidate();
348 347 }
349 348 }
350 349
351 350 void ChartAxis::hide()
352 351 {
353 352 setArrowVisibility(false);
354 353 setGridVisibility(false);
355 354 setLabelsVisibility(false);
356 355 setShadesVisibility(false);
357 356 }
358 357
359 358 void ChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
360 359 {
361 360 m_gridRect = grid;
362 361 m_axisRect = axis;
363 362
364 363 if (isEmpty())
365 364 return;
366 365
367 366 if (!m_titleText.isNull()) {
368 367 QFontMetrics fn(m_title->font());
369 368
370 369 int size(0);
371 370
372 371 if (orientation() == Qt::Horizontal)
373 372 size = grid.width();
374 373 else if (orientation() == Qt::Vertical)
375 374 size = grid.height();
376 375
377 376 if (fn.boundingRect(m_titleText).width() > size) {
378 377 QString string = m_titleText + "...";
379 378 while (fn.boundingRect(string).width() > size && string.length() > 3)
380 379 string.remove(string.length() - 4, 1);
381 380 m_title->setText(string);
382 381 } else {
383 382 m_title->setText(m_titleText);
384 383 }
385 384
386 385 QPointF center = grid.center() - m_title->boundingRect().center();
387 386 if (orientation() == Qt::Horizontal) {
388 387 m_title->setPos(center.x(), m_axisRect.bottom() - m_title->boundingRect().height());
389 388 } else if (orientation() == Qt::Vertical) {
390 389 m_title->setTransformOriginPoint(m_title->boundingRect().center());
391 390 m_title->setRotation(270);
392 391 m_title->setPos(m_axisRect.left() - m_title->boundingRect().width() / 2 + m_title->boundingRect().height() / 2, center.y());
393 392 }
394 393 }
395 394
396 395 QVector<qreal> layout = calculateLayout();
397 396 updateLayout(layout);
398 397
399 398 }
400 399
401 400 void ChartAxis::axisSelected()
402 401 {
403 402 //TODO: axis clicked;
404 403 }
405 404
406 405 Qt::Orientation ChartAxis::orientation() const
407 406 {
408 407 return m_chartAxis->orientation();
409 408 }
410 409
411 410 Qt::Alignment ChartAxis::alignment() const
412 411 {
413 412 return m_chartAxis->alignment();
414 413 }
415 414
416 415 bool ChartAxis::isVisible()
417 416 {
418 417 return m_chartAxis->isVisible();
419 418 }
420 419
421 420 void ChartAxis::setLabels(const QStringList &labels)
422 421 {
423 422 m_labelsList = labels;
424 423 }
425 424
426 425 QSizeF ChartAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
427 426 {
428 427
429 428 Q_UNUSED(constraint);
430 429 QFontMetrics fn(m_title->font());
431 430 QSizeF sh;
432 431
433 432 if (m_titleText.isNull())
434 433 return sh;
435 434
436 435 switch (which) {
437 436 case Qt::MinimumSize:
438 437 if (orientation() == Qt::Horizontal)
439 438 sh = QSizeF(fn.boundingRect("...").width(), fn.height());
440 439 else if (orientation() == Qt::Vertical)
441 440 sh = QSizeF(fn.height(), fn.boundingRect("...").width());
442 441 break;
443 442 case Qt::MaximumSize:
444 443 case Qt::PreferredSize:
445 444 if (orientation() == Qt::Horizontal)
446 445 sh = QSizeF(fn.boundingRect(m_chartAxis->title()).width(), fn.height());
447 446 else if (orientation() == Qt::Vertical)
448 447 sh = QSizeF(fn.height(), fn.boundingRect(m_chartAxis->title()).width());
449 448 break;
450 449 default:
451 450 break;
452 451 }
453 452
454 453 return sh;
455 454 }
456 455
457 456 QStringList ChartAxis::createValueLabels(int ticks) const
458 457 {
459 458 Q_ASSERT(m_max > m_min);
460 459 Q_ASSERT(ticks > 1);
461 460
462 461 QStringList labels;
463 462
464 463 int n = qMax(int(-qFloor(log10((m_max - m_min) / (ticks - 1)))), 0);
465 464 n++;
466 465
467 466 QValueAxis *axis = qobject_cast<QValueAxis *>(m_chartAxis);
468 467
469 468 QString format = axis->labelFormat();
470 469
471 470 if (format.isNull()) {
472 471 for (int i = 0; i < ticks; i++) {
473 472 qreal value = m_min + (i * (m_max - m_min) / (ticks - 1));
474 473 labels << QString::number(value, 'f', n);
475 474 }
476 475 } else {
477 476 QByteArray array = format.toAscii();
478 477 for (int i = 0; i < ticks; i++) {
479 478 qreal value = m_min + (i * (m_max - m_min) / (ticks - 1));
480 479 labels << QString().sprintf(array, value);
481 480 }
482 481 }
483 482
484 483 return labels;
485 484 }
486 485
487 486 QStringList ChartAxis::createDateTimeLabels(const QString &format, int ticks) const
488 487 {
489 488 Q_ASSERT(m_max > m_min);
490 489 Q_ASSERT(ticks > 1);
491 490 QStringList labels;
492 491 int n = qMax(int(-floor(log10((m_max - m_min) / (ticks - 1)))), 0);
493 492 n++;
494 493 for (int i = 0; i < ticks; i++) {
495 494 qreal value = m_min + (i * (m_max - m_min) / (ticks - 1));
496 495 labels << QDateTime::fromMSecsSinceEpoch(value).toString(format);
497 496 }
498 497 return labels;
499 498 }
500 499
501 500 #include "moc_chartaxis_p.cpp"
502 501
503 502 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,137 +1,159
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "horizontalaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include <QFontMetrics>
24 #include <qmath.h>
24 25 #include <QDebug>
25 26
26 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 28
28 29 HorizontalAxis::HorizontalAxis(QAbstractAxis *axis, ChartPresenter *presenter, bool intervalAxis)
29 30 : ChartAxis(axis, presenter, intervalAxis)
30 31 {
31 32 }
32 33
33 34 HorizontalAxis::~HorizontalAxis()
34 35 {
35 36 }
36 37
37 38 void HorizontalAxis::updateGeometry()
38 39 {
39 40 const QVector<qreal>& layout = ChartAxis::layout();
40 41
41 42 if (layout.isEmpty())
42 43 return;
43 44
44 QStringList ticksList = labels();
45 QStringList labelList = labels();
45 46
46 47 QList<QGraphicsItem *> lines = lineItems();
47 48 QList<QGraphicsItem *> labels = labelItems();
48 49 QList<QGraphicsItem *> shades = shadeItems();
49 50 QList<QGraphicsItem *> axis = arrowItems();
50 51
51 Q_ASSERT(labels.size() == ticksList.size());
52 Q_ASSERT(layout.size() == ticksList.size());
52 Q_ASSERT(labels.size() == labelList.size());
53 Q_ASSERT(layout.size() == labelList.size());
53 54
54 55 const QRectF &axisRect = axisGeometry();
55 56 const QRectF &gridRect = gridGeometry();
56 57
57 58 //arrow
58 59 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem *>(axis.at(0));
59 60
60 61 if (alignment() == Qt::AlignTop)
61 62 arrowItem->setLine(gridRect.left(), axisRect.bottom(), gridRect.right(), axisRect.bottom());
62 63 else if (alignment() == Qt::AlignBottom)
63 64 arrowItem->setLine(gridRect.left(), axisRect.top(), gridRect.right(), axisRect.top());
64 65
65 66 qreal width = 0;
67 QFontMetrics fn(font());
66 68
67 69 for (int i = 0; i < layout.size(); ++i) {
68 70
69 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
70 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(axis.at(i + 1));
71 //items
72 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem*>(lines.at(i));
73 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem*>(axis.at(i + 1));
71 74 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labels.at(i));
72 75
73 76 //grid line
74 77 gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom());
75 78
76 //label text
77 labelItem->setText(ticksList.at(i));
78 const QRectF &rect = labelItem->boundingRect();
79 //label text wrapping
80 if(intervalAxis()&& i+1!=layout.size()) {
81 //wrapping in case of interval axis
82 const qreal delta = layout[i+1] - layout[i];
83 QString text = labelList.at(i);
84 if (fn.boundingRect(text).width() > delta )
85 {
86 QString label = text + "...";
87 while (fn.boundingRect(label).width() > delta && label.length() > 3)
88 label.remove(label.length() - 4, 1);
89 labelItem->setText(label);
90 }
91 else {
92 labelItem->setText(text);
93 }
94 }else{
95 labelItem->setText(labelList.at(i));
96 }
97
98 //label transformation origin point
99 const QRectF& rect = labelItem->boundingRect();
79 100 QPointF center = rect.center();
80 101 labelItem->setTransformOriginPoint(center.x(), center.y());
81 102
82 103 //ticks and label position
83 104 if (alignment() == Qt::AlignTop) {
84 105 labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() - labelPadding());
85 106 tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding());
86 107 } else if (alignment() == Qt::AlignBottom) {
87 108 labelItem->setPos(layout[i] - center.x(), axisRect.top() + labelPadding());
88 109 tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding());
89 110 }
90 111
91 if (intervalAxis() && i + 1 != layout.size()) {
92 const qreal delta = (layout[i + 1] - layout[i]) / 2;
112 //label in beetwen
113 if(intervalAxis()&& i+1!=layout.size()) {
114 const qreal delta = (layout[i+1] - layout[i])/2;
93 115 labelItem->setPos(layout[i] + delta - center.x(), labelItem->pos().y());
94 116 }
95 117
96 //overlap detection
97 if (labelItem->pos().x() <= width ||
118 //label overlap detection
119 if(labelItem->pos().x() <= width ||
98 120 labelItem->pos().x() < axisRect.left() ||
99 121 labelItem->pos().x() + rect.width() > axisRect.right()) {
100 122 labelItem->setVisible(false);
101 gridItem->setVisible(false);
102 tickItem->setVisible(false);
103 } else {
123 }
124 else {
104 125 labelItem->setVisible(true);
105 gridItem->setVisible(true);
106 tickItem->setVisible(true);
107 width = rect.width() + labelItem->pos().x();
126 width=rect.width()+labelItem->pos().x();
108 127 }
109 128
110 129 //shades
111 130 if ((i + 1) % 2 && i > 1) {
112 131 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
113 132 rectItem->setRect(layout[i - 1], gridRect.top(), layout[i] - layout[i - 1], gridRect.height());
114 133 }
115 134
116 135 // check if the grid line and the axis tick should be shown
117 136 qreal x = gridItem->line().p1().x();
118 137 if (x < gridRect.left() || x > gridRect.right()) {
119 138 gridItem->setVisible(false);
120 139 tickItem->setVisible(false);
121 if (intervalAxis() && (labelItem->pos().x() < gridRect.left() || labelItem->pos().x() + rect.width() > gridRect.right()))
122 labelItem->setVisible(false);
140 }else{
141 gridItem->setVisible(true);
142 tickItem->setVisible(true);
123 143 }
124 144
125 145 }
126 146
127 147 //begin/end grid line in case labels between
128 148 if (intervalAxis()) {
129 149 QGraphicsLineItem *gridLine;
130 150 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
131 151 gridLine->setLine(gridRect.right(), gridRect.top(), gridRect.right(), gridRect.bottom());
132 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size() + 1));
152 gridLine->setVisible(true);
153 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
133 154 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.left(), gridRect.bottom());
155 gridLine->setVisible(true);
134 156 }
135 157 }
136 158
137 159 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,117 +1,117
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartvalueaxisx_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "qvalueaxis.h"
25 25 #include "chartlayout_p.h"
26 26 #include <QGraphicsLayout>
27 27 #include <QFontMetrics>
28 28 #include <qmath.h>
29 29
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 ChartValueAxisX::ChartValueAxisX(QValueAxis *axis, ChartPresenter *presenter)
34 34 : HorizontalAxis(axis, presenter),
35 35 m_tickCount(0), m_axis(axis)
36 36 {
37 37 }
38 38
39 39 ChartValueAxisX::~ChartValueAxisX()
40 40 {
41 41 }
42 42
43 43 QVector<qreal> ChartValueAxisX::calculateLayout() const
44 44 {
45 45 Q_ASSERT(m_tickCount >= 2);
46 46
47 47 QVector<qreal> points;
48 48 points.resize(m_tickCount);
49 49
50 50 const QRectF &gridRect = gridGeometry();
51 51 const qreal deltaX = gridRect.width() / (m_tickCount - 1);
52 52 for (int i = 0; i < m_tickCount; ++i) {
53 53 int x = i * deltaX + gridRect.left();
54 54 points[i] = x;
55 55 }
56 56 return points;
57 57 }
58 58
59 59 void ChartValueAxisX::updateGeometry()
60 60 {
61 61 const QVector<qreal>& layout = ChartAxis::layout();
62 62 if (layout.isEmpty())
63 63 return;
64 64 setLabels(createValueLabels(layout.size()));
65 65 HorizontalAxis::updateGeometry();
66 66 }
67 67
68 68 void ChartValueAxisX::handleAxisUpdated()
69 69 {
70 70 if (m_tickCount != m_axis->tickCount()) {
71 71 m_tickCount = m_axis->tickCount();
72 72 presenter()->layout()->invalidate();
73 73 }
74 74
75 75 ChartAxis::handleAxisUpdated();
76 76 }
77 77
78 78 QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
79 79 {
80 80 Q_UNUSED(constraint)
81 81
82 82 QFontMetrics fn(font());
83 83 QSizeF sh;
84 84
85 85 QSizeF base = ChartAxis::sizeHint(which, constraint);
86 86 QStringList ticksList = createValueLabels(m_tickCount);
87 87 qreal width = 0;
88 88 qreal height = 0;
89 89
90 90 switch (which) {
91 case Qt::MinimumSize: {
92 int count = qMax(ticksList.last().count(), ticksList.first().count());
91 case Qt::MinimumSize:{
92 int count = qMax(ticksList.last().count(),ticksList.first().count());
93 count = qMin(count,5);
93 94 width = fn.averageCharWidth() * count;
94 95 height = fn.height() + labelPadding();
95 width = qMax(width, base.width());
96 width = qMax(width,base.width());
96 97 height += base.height();
97 sh = QSizeF(width, height);
98 sh = QSizeF(width,height);
98 99 break;
99 100 }
100 case Qt::PreferredSize: {
101 for (int i = 0; i < ticksList.size(); ++i) {
102 width += fn.averageCharWidth() * ticksList.at(i).count();
103 }
104 height = fn.height() + labelPadding();
105 width = qMax(width, base.width());
106 height += base.height();
107 sh = QSizeF(width, height);
101 case Qt::PreferredSize:{
102 int count = qMax(ticksList.last().count(),ticksList.first().count());
103 width=fn.averageCharWidth() * count;
104 height=fn.height()+labelPadding();
105 width=qMax(width,base.width());
106 height+=base.height();
107 sh = QSizeF(width,height);
108 108 break;
109 109 }
110 110 default:
111 111 break;
112 112 }
113 113
114 114 return sh;
115 115 }
116 116
117 117 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,117 +1,117
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartvalueaxisy_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "qvalueaxis.h"
25 25 #include "chartlayout_p.h"
26 26 #include <QGraphicsLayout>
27 27 #include <QFontMetrics>
28 28 #include <qmath.h>
29 #include <QDebug>
29 30
30 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 32
32 33 ChartValueAxisY::ChartValueAxisY(QValueAxis *axis, ChartPresenter *presenter)
33 34 : VerticalAxis(axis, presenter),
34 35 m_tickCount(0),
35 36 m_axis(axis)
36 37 {
37 38 }
38 39
39 40 ChartValueAxisY::~ChartValueAxisY()
40 41 {
41 42 }
42 43
43 44 QVector<qreal> ChartValueAxisY::calculateLayout() const
44 45 {
45 46 Q_ASSERT(m_tickCount >= 2);
46 47
47 48 QVector<qreal> points;
48 49 points.resize(m_tickCount);
49 50
50 51 const QRectF &gridRect = gridGeometry();
51 52
52 53 const qreal deltaY = gridRect.height() / (m_tickCount - 1);
53 54 for (int i = 0; i < m_tickCount; ++i) {
54 55 int y = i * -deltaY + gridRect.bottom();
55 56 points[i] = y;
56 57 }
57 58
58 59 return points;
59 60 }
60 61
61 62 void ChartValueAxisY::updateGeometry()
62 63 {
63 64 const QVector<qreal> &layout = ChartAxis::layout();
64 65 if (layout.isEmpty())
65 66 return;
66 67 setLabels(createValueLabels(layout.size()));
67 68 VerticalAxis::updateGeometry();
68 69 }
69 70
70 71 void ChartValueAxisY::handleAxisUpdated()
71 72 {
72 73 if (m_tickCount != m_axis->tickCount()) {
73 74 m_tickCount = m_axis->tickCount();
74 75 presenter()->layout()->invalidate();
75 76 }
76 77
77 78 ChartAxis::handleAxisUpdated();
78 79 }
79 80
80 81 QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
81 82 {
82 83 Q_UNUSED(constraint)
83 84
84 85 QFontMetrics fn(font());
85 86 QSizeF sh;
86 87 QSizeF base = ChartAxis::sizeHint(which, constraint);
87 88 QStringList ticksList = createValueLabels(m_tickCount);
88 89 qreal width = 0;
89 90 qreal height = 0;
90 91
91 92 switch (which) {
92 93 case Qt::MinimumSize: {
93 int count = qMax(ticksList.first().count() , ticksList.last().count());
94 width = fn.averageCharWidth() * count + labelPadding();
95 height = fn.height();
96 height = qMax(height, base.height());
94 width = fn.boundingRect("...").width() + labelPadding();
97 95 width += base.width();
98 sh = QSizeF(width, height);
96 height = fn.height();
97 height = qMax(height,base.height());
98 sh = QSizeF(width,height);
99 99 break;
100 100 }
101 case Qt::PreferredSize: {
102 for (int i = 0; i < ticksList.size(); ++i) {
103 width = qMax(qreal(fn.averageCharWidth() * ticksList.at(i).count()) + labelPadding(), width);
104 height += fn.height();
105 }
106 height = qMax(height, base.height());
101 case Qt::PreferredSize:
102 {
103 int count = qMax(ticksList.first().count() , ticksList.last().count());
104 width = count*fn.averageCharWidth() + labelPadding() + 2; //two pixels of tolerance
107 105 width += base.width();
108 sh = QSizeF(width, height);
106 height = fn.height() * ticksList.count();
107 height = qMax(height,base.height());
108 sh = QSizeF(width,height);
109 109 break;
110 110 }
111 111 default:
112 112 break;
113 113 }
114 114 return sh;
115 115 }
116 116
117 117 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,144 +1,154
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "verticalaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include <QFontMetrics>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 VerticalAxis::VerticalAxis(QAbstractAxis *axis, ChartPresenter *presenter, bool intervalAxis)
28 28 : ChartAxis(axis, presenter, intervalAxis)
29 29 {
30 30
31 31 }
32 32
33 33 VerticalAxis::~VerticalAxis()
34 34 {
35 35
36 36 }
37 37
38 38 void VerticalAxis::updateGeometry()
39 39 {
40 40 const QVector<qreal> &layout = ChartAxis::layout();
41 41
42 42 if (layout.isEmpty())
43 43 return;
44 44
45 45 QStringList labelList = labels();
46 46
47 47 QList<QGraphicsItem *> lines = lineItems();
48 48 QList<QGraphicsItem *> labels = labelItems();
49 49 QList<QGraphicsItem *> shades = shadeItems();
50 50 QList<QGraphicsItem *> axis = arrowItems();
51 51
52 52 Q_ASSERT(labels.size() == labelList.size());
53 53 Q_ASSERT(layout.size() == labelList.size());
54 54
55 55 const QRectF &axisRect = axisGeometry();
56 56 const QRectF &gridRect = gridGeometry();
57 57
58 58 qreal height = axisRect.bottom();
59 59
60 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem *>(axis.at(0));
61 60
62 if (alignment() == Qt::AlignLeft)
63 lineItem->setLine(axisRect.right() , gridRect.top(), axisRect.right(), gridRect.bottom());
64 else if (alignment() == Qt::AlignRight)
65 lineItem->setLine(axisRect.left() , gridRect.top(), axisRect.left(), gridRect.bottom());
61 //arrow
62 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(axis.at(0));
63
64 //arrow position
65 if (alignment()==Qt::AlignLeft)
66 arrowItem->setLine( axisRect.right() , gridRect.top(), axisRect.right(), gridRect.bottom());
67 else if(alignment()==Qt::AlignRight)
68 arrowItem->setLine( axisRect.left() , gridRect.top(), axisRect.left(), gridRect.bottom());
66 69
67 70 QFontMetrics fn(font());
68 71
69 72 for (int i = 0; i < layout.size(); ++i) {
70 73
74 //items
71 75 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
72 76 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(axis.at(i + 1));
73 77 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labels.at(i));
74 78
75 79 //grid line
76 80 gridItem->setLine(gridRect.left() , layout[i], gridRect.right(), layout[i]);
77 81
78 //label text
82 //label text wrapping
79 83 QString text = labelList.at(i);
80 84 if (fn.boundingRect(text).width() > axisRect.right() - axisRect.left() - labelPadding()) {
81 85 QString label = text + "...";
82 86 while (fn.boundingRect(label).width() > axisRect.right() - axisRect.left() - labelPadding() && label.length() > 3)
83 87 label.remove(label.length() - 4, 1);
84 88 labelItem->setText(label);
85 89 } else {
86 90 labelItem->setText(text);
87 91 }
92 //label transformation origin point
88 93 const QRectF &rect = labelItem->boundingRect();
94
89 95 QPointF center = rect.center();
90 96 labelItem->setTransformOriginPoint(center.x(), center.y());
91 97
92 98 //ticks and label position
93 99 if (alignment() == Qt::AlignLeft) {
94 100 labelItem->setPos(axisRect.right() - rect.width() - labelPadding() , layout[i] - center.y());
95 101 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
96 102 } else if (alignment() == Qt::AlignRight) {
97 103 labelItem->setPos(axisRect.left() + labelPadding() , layout[i] - center.y());
98 104 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
99 105 }
100 if (intervalAxis() && i + 1 != layout.size()) {
101 const qreal delta = (layout[i + 1] - layout[i]) / 2;
106
107 //label in beetwen
108 if(intervalAxis()&& i+1!=layout.size()) {
109 const qreal delta = (layout[i+1] - layout[i])/2;
102 110 labelItem->setPos(labelItem->pos().x() , layout[i] + delta - center.y());
103 111 }
104 112
105 //overlap detection
106 if (labelItem->pos().y() + rect.height() > height ||
107 labelItem->pos().y() + rect.height() > axisRect.bottom() ||
108 labelItem->pos().y() < axisRect.top()) {
113 //label overlap detection
114 if(labelItem->pos().y() + rect.height() > height ||
115 labelItem->pos().y() + rect.height()/2 > gridRect.bottom() ||
116 labelItem->pos().y() + rect.height()/2 < gridRect.top()) {
109 117 labelItem->setVisible(false);
110 gridItem->setVisible(false);
111 tickItem->setVisible(false);
112 } else {
118 }
119 else {
113 120 labelItem->setVisible(true);
114 gridItem->setVisible(true);
115 height = labelItem->pos().y();
121 height=labelItem->pos().y();
116 122 }
117 123
118 124 //shades
119 125 if ((i + 1) % 2 && i > 1) {
120 126 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem *>(shades.at(i / 2 - 1));
121 127 rectItem->setRect(gridRect.left(), layout[i], gridRect.width(), layout[i - 1] - layout[i]);
122 128 }
123 129
124 130 // check if the grid line and the axis tick should be shown
125 131 qreal y = gridItem->line().p1().y();
126 if (y < gridRect.top() || y > gridRect.bottom()) {
132 if ((y < gridRect.top() || y > gridRect.bottom()))
133 {
127 134 gridItem->setVisible(false);
128 135 tickItem->setVisible(false);
129 if (intervalAxis() && (labelItem->pos().y() < gridRect.top() || labelItem->pos().y() + rect.height() > gridRect.bottom()))
130 labelItem->setVisible(false);
136 }else{
137 gridItem->setVisible(true);
138 tickItem->setVisible(true);
131 139 }
132 140
133 141 }
134 142 //begin/end grid line in case labels between
135 143 if (intervalAxis()) {
136 144 QGraphicsLineItem *gridLine;
137 145 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size()));
138 146 gridLine->setLine(gridRect.left(), gridRect.top(), gridRect.right(), gridRect.top());
139 gridLine = static_cast<QGraphicsLineItem *>(lines.at(layout.size() + 1));
147 gridLine->setVisible(true);
148 gridLine = static_cast<QGraphicsLineItem*>(lines.at(layout.size()+1));
140 149 gridLine->setLine(gridRect.left(), gridRect.bottom(), gridRect.right(), gridRect.bottom());
150 gridLine->setVisible(true);
141 151 }
142 152 }
143 153
144 154 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,331 +1,351
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartlayout_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qlegend_p.h"
24 24 #include "chartaxis_p.h"
25 25 #include "charttitle_p.h"
26 26 #include "chartbackground_p.h"
27 27 #include "legendmarker_p.h"
28 28 #include <QDebug>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 static const qreal golden_ratio = 0.25;
32 static const qreal golden_ratio = 0.4;
33 33
34 34 ChartLayout::ChartLayout(ChartPresenter *presenter)
35 35 : m_presenter(presenter),
36 36 m_margins(20, 20, 20, 20),
37 37 m_minChartRect(0, 0, 200, 200)
38 38 {
39 39
40 40 }
41 41
42 42 ChartLayout::~ChartLayout()
43 43 {
44 44
45 45 }
46 46
47 47 void ChartLayout::setGeometry(const QRectF &rect)
48 48 {
49 49 if (!rect.isValid())
50 50 return;
51 51
52 52 QList<ChartAxis *> axes = m_presenter->axisItems();
53 53 QList<ChartElement *> charts = m_presenter->chartItems();
54 54 ChartTitle *title = m_presenter->titleElement();
55 55 QLegend *legend = m_presenter->legend();
56 56 ChartBackground *background = m_presenter->backgroundElement();
57 57
58 58 QRectF contentGeometry = calculateBackgroundGeometry(rect, background);
59 59
60 60 contentGeometry = calculateContentGeometry(contentGeometry);
61 61
62 62 if (title && title->isVisible())
63 63 contentGeometry = calculateTitleGeometry(contentGeometry, title);
64 64
65 65 if (legend->isAttachedToChart() && legend->isVisible())
66 66 contentGeometry = calculateLegendGeometry(contentGeometry, legend);
67 67
68 68 contentGeometry = calculateAxisGeometry(contentGeometry, axes);
69 69
70 70 m_chartsRect = calculateChartsGeometry(contentGeometry, charts);
71 71
72 72 QGraphicsLayout::setGeometry(rect);
73 73 }
74 74
75 75 QRectF ChartLayout::calculateContentGeometry(const QRectF &geometry) const
76 76 {
77 77 return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom());
78 78 }
79 79
80 80 QRectF ChartLayout::calculateContentMinimum(const QRectF &minimum) const
81 81 {
82 82 return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom());
83 83 }
84 84
85 85
86 86 QRectF ChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const
87 87 {
88 88 qreal left, top, right, bottom;
89 89 getContentsMargins(&left, &top, &right, &bottom);
90 90 QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom);
91 91 if (background)
92 92 background->setRect(backgroundGeometry);
93 93 return backgroundGeometry;
94 94 }
95 95
96 96 QRectF ChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const
97 97 {
98 98 qreal left, top, right, bottom;
99 99 getContentsMargins(&left, &top, &right, &bottom);
100 100 return minimum.adjusted(0, 0, left + right, top + bottom);
101 101 }
102 102
103 103
104 104 QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QList<ChartAxis *>& axes) const
105 105 {
106 QSizeF left;
107 QSizeF right;
108 QSizeF bottom;
109 QSizeF top;
106 QSizeF left(0,0);
107 QSizeF minLeft(0,0);
108 QSizeF right(0,0);
109 QSizeF minRight(0,0);
110 QSizeF bottom(0,0);
111 QSizeF minBottom(0,0);
112 QSizeF top(0,0);
113 QSizeF minTop(0,0);
110 114 int leftCount = 0;
111 115 int rightCount = 0;
112 116 int topCount = 0;
113 117 int bottomCount = 0;
114 118
115 119 foreach (ChartAxis *axis , axes) {
116 120
117 121 if (!axis->isVisible())
118 122 continue;
119 123
120 QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize);
124 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
125 //this is used to get single thick font size
126 QSizeF minSize = axis->effectiveSizeHint(Qt::MinimumSize);
121 127
122 128 switch (axis->alignment()) {
123 129 case Qt::AlignLeft:
124 left.setWidth(left.width() + size.width());
125 left.setHeight(qMax(left.height(), size.height()));
126 leftCount++;
127 break;
130 left.setWidth(left.width()+size.width());
131 left.setHeight(qMax(left.height(),size.height()));
132 minLeft.setWidth(minLeft.width()+minSize.width());
133 minLeft.setHeight(qMax(minLeft.height(),minSize.height()));
134 leftCount++;
135 break;
128 136 case Qt::AlignRight:
129 right.setWidth(right.width() + size.width());
130 right.setHeight(qMax(right.height(), size.height()));
137 right.setWidth(right.width()+size.width());
138 right.setHeight(qMax(right.height(),size.height()));
139 minRight.setWidth(minRight.width()+minSize.width());
140 minRight.setHeight(qMax(minRight.height(),minSize.height()));
131 141 rightCount++;
132 142 break;
133 143 case Qt::AlignTop:
134 top.setWidth(qMax(top.width(), size.width()));
135 top.setHeight(top.height() + size.height());
144 top.setWidth(qMax(top.width(),size.width()));
145 top.setHeight(top.height()+size.height());
146 minTop.setWidth(qMax(minTop.width(),minSize.width()));
147 minTop.setHeight(minTop.height()+minSize.height());
136 148 topCount++;
137 149 break;
138 150 case Qt::AlignBottom:
139 151 bottom.setWidth(qMax(bottom.width(), size.width()));
140 152 bottom.setHeight(bottom.height() + size.height());
153 minBottom.setWidth(qMax(minBottom.width(),minSize.width()));
154 minBottom.setHeight(minBottom.height() + minSize.height());
141 155 bottomCount++;
142 156 break;
143 157 }
144 158 }
145 159
146 left.setWidth(qMax(qMax(top.width() / 2, bottom.width() / 2), left.width()));
147 left.setWidth(qMin(left.width(), golden_ratio * geometry.width()));
148 right.setWidth(qMax(qMax(top.width() / 2, bottom.width() / 2), right.width()));
149 right.setWidth(qMin(right.width(), golden_ratio * geometry.width()));
150 top.setHeight(qMax(qMax(left.height() / 2, right.height() / 2), top.height()));
151 bottom.setHeight(qMax(qMax(left.height() / 2, right.height() / 2), bottom.height()));
160 int horizontal = leftCount + rightCount;
161 qreal hratio = 0 ;
162 if(horizontal>0)
163 hratio = (golden_ratio*geometry.width())/horizontal;
164
165 if(leftCount>0)
166 left.setWidth(qMin(left.width(),hratio*leftCount));
167 if(rightCount>0)
168 right.setWidth(qMin(right.width(),hratio*rightCount));
152 169
153 QRectF chartRect = geometry.adjusted(left.width(), top.height(), -right.width(), -bottom.height());
170 qreal minHeight = qMax(minLeft.height(),minRight.height());
171 qreal minWidth = qMax(minTop.width(),minBottom.width());
172
173 QRectF chartRect = geometry.adjusted(qMax(left.width(),minWidth/2), qMax(top.height(), minHeight/2),-qMax(right.width(),minWidth/2),-qMax(bottom.height(),minHeight/2));
154 174
155 175 qreal leftOffset = 0;
156 176 qreal rightOffset = 0;
157 177 qreal topOffset = 0;
158 178 qreal bottomOffset = 0;
159 179
160 foreach(ChartAxis * axis , axes) {
180 foreach(ChartAxis* axis , axes) {
161 181
162 182 if (!axis->isVisible())
163 183 continue;
164 184
165 QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize);
185 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
166 186
167 switch (axis->alignment()) {
168 case Qt::AlignLeft: {
169 qreal width = qMin(size.width(), left.width() / leftCount);
170 leftOffset += width;
171 axis->setGeometry(QRect(chartRect.left() - leftOffset, chartRect.top() - (size.height() + 1) / 2, width, chartRect.height() + size.height() + 2), chartRect);
187 switch(axis->alignment()){
188 case Qt::AlignLeft:{
189 qreal width = qMin(size.width(),(left.width()/leftCount));
190 leftOffset+=width;
191 axis->setGeometry(QRect(chartRect.left()-leftOffset, geometry.top(),width, geometry.bottom()),chartRect);
172 192 break;
173 193 }
174 case Qt::AlignRight: {
175 qreal width = qMin(size.width(), right.width() / rightCount);
176 axis->setGeometry(QRect(chartRect.right() + rightOffset, chartRect.top() - (size.height() + 1) / 2, width, chartRect.height() + size.height() + 2), chartRect);
177 rightOffset += width;
194 case Qt::AlignRight:{
195 qreal width = qMin(size.width(),(right.width()/rightCount));
196 axis->setGeometry(QRect(chartRect.right()+rightOffset,geometry.top(),width,geometry.bottom()),chartRect);
197 rightOffset+=width;
178 198 break;
179 199 }
180 200 case Qt::AlignTop:
181 201 axis->setGeometry(QRect(geometry.left(), chartRect.top() - topOffset - size.height(), geometry.width(), size.height()), chartRect);
182 202 topOffset += size.height();
183 203 break;
184 204 case Qt::AlignBottom:
185 205 axis->setGeometry(QRect(geometry.left(), chartRect.bottom() + bottomOffset, geometry.width(), size.height()), chartRect);
186 206 bottomOffset += size.height();
187 207 break;
188 208 }
189 209 }
190 210
191 211 return chartRect;
192 212 }
193 213
194 214 QRectF ChartLayout::calculateAxisMinimum(const QRectF &minimum, const QList<ChartAxis *>& axes) const
195 215 {
196 216 QSizeF left;
197 217 QSizeF right;
198 218 QSizeF bottom;
199 219 QSizeF top;
200 220
201 221 foreach (ChartAxis *axis , axes) {
202 222
203 223 QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize);
204 224
205 225 if (!axis->isVisible())
206 226 continue;
207 227
208 228 switch (axis->alignment()) {
209 229 case Qt::AlignLeft:
210 230 left.setWidth(left.width() + size.width());
211 231 left.setHeight(qMax(left.height() * 2, size.height()));
212 232 break;
213 233 case Qt::AlignRight:
214 234 right.setWidth(right.width() + size.width());
215 235 right.setHeight(qMax(right.height() * 2, size.height()));
216 236 break;
217 237 case Qt::AlignTop:
218 238 top.setWidth(qMax(top.width(), size.width()));
219 239 top.setHeight(top.height() + size.height());
220 240 break;
221 241 case Qt::AlignBottom:
222 242 bottom.setWidth(qMax(bottom.width(), size.width()));
223 243 bottom.setHeight(bottom.height() + size.height());
224 244 break;
225 245 }
226 246 }
227 247 return minimum.adjusted(0, 0, left.width() + right.width() + qMax(top.width(), bottom.width()), top.height() + bottom.height() + qMax(left.height(), right.height()));
228 248 }
229 249
230 250 QRectF ChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const
231 251 {
232 252 QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1));
233 253 QRectF legendRect;
234 254 QRectF result;
235 255
236 256 switch (legend->alignment()) {
237 257 case Qt::AlignTop: {
238 258 legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height()));
239 259 result = geometry.adjusted(0, legendRect.height(), 0, 0);
240 260 break;
241 261 }
242 262 case Qt::AlignBottom: {
243 263 legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height()));
244 264 result = geometry.adjusted(0, 0, 0, -legendRect.height());
245 265 break;
246 266 }
247 267 case Qt::AlignLeft: {
248 268 qreal width = qMin(size.width(), geometry.width() * golden_ratio);
249 269 legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height()));
250 270 result = geometry.adjusted(width, 0, 0, 0);
251 271 break;
252 272 }
253 273 case Qt::AlignRight: {
254 274 qreal width = qMin(size.width(), geometry.width() * golden_ratio);
255 275 legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height()));
256 276 result = geometry.adjusted(0, 0, -width, 0);
257 277 break;
258 278 }
259 279 default: {
260 280 legendRect = QRectF(0, 0, 0, 0);
261 281 result = geometry;
262 282 break;
263 283 }
264 284 }
265 285
266 286 legend->setGeometry(legendRect);
267 287
268 288 return result;
269 289 }
270 290
271 291
272 292 QRectF ChartLayout::calculateChartsGeometry(const QRectF &geometry, const QList<ChartElement *>& charts) const
273 293 {
274 294 Q_ASSERT(geometry.isValid());
275 295 foreach (ChartElement *chart, charts)
276 296 chart->handleGeometryChanged(geometry);
277 297 return geometry;
278 298 }
279 299
280 300 QRectF ChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const
281 301 {
282 302 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1));
283 303 return geometry.adjusted(0, 0, minSize.width(), minSize.height());
284 304 }
285 305
286 306 QRectF ChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const
287 307 {
288 308 title->setGeometry(geometry);
289 309 QPointF center = geometry.center() - title->boundingRect().center();
290 title->setPos(center.x(), title->pos().y());
291 return geometry.adjusted(0, title->boundingRect().height(), 0, 0);
310 title->setPos(center.x(),title->pos().y());
311 return geometry.adjusted(0,title->boundingRect().height()+1,0,0);
292 312 }
293 313
294 314 QRectF ChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const
295 315 {
296 316 QSizeF min = title->sizeHint(Qt::MinimumSize);
297 317 return minimum.adjusted(0, 0, min.width(), min.height());
298 318 }
299 319
300 320 QSizeF ChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
301 321 {
302 322 Q_UNUSED(constraint);
303 323 if (which == Qt::MinimumSize) {
304 324 QList<ChartAxis *> axes = m_presenter->axisItems();
305 325 ChartTitle *title = m_presenter->titleElement();
306 326 QLegend *legend = m_presenter->legend();
307 327 QRectF minimumRect(0, 0, 0, 0);
308 328 minimumRect = calculateBackgroundMinimum(minimumRect);
309 329 minimumRect = calculateContentMinimum(minimumRect);
310 330 minimumRect = calculateTitleMinimum(minimumRect, title);
311 331 minimumRect = calculateLegendMinimum(minimumRect, legend);
312 332 minimumRect = calculateAxisMinimum(minimumRect, axes);
313 333 return minimumRect.united(m_minChartRect).size().toSize();
314 334 }
315 335 return QSize(-1, -1);
316 336 }
317 337
318 338 void ChartLayout::setMargins(const QMargins &margins)
319 339 {
320 340 if (m_margins != margins) {
321 341 m_margins = margins;
322 342 updateGeometry();
323 343 }
324 344 }
325 345
326 346 QMargins ChartLayout::margins() const
327 347 {
328 348 return m_margins;
329 349 }
330 350
331 351 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,94 +1,94
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "charttitle_p.h"
22 22 #include <QFont>
23 23 #include <QFontMetrics>
24 24 #include <QDebug>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 ChartTitle::ChartTitle(QGraphicsItem *parent)
29 29 : QGraphicsSimpleTextItem(parent)
30 30 {
31 31
32 32 }
33 33
34 34 ChartTitle::~ChartTitle()
35 35 {
36 36
37 37 }
38 38
39 39 void ChartTitle::setText(const QString &text)
40 40 {
41 41 m_text = text;
42 42 }
43 43
44 44 QString ChartTitle::text() const
45 45 {
46 46 return m_text;
47 47 }
48 48
49 49 void ChartTitle::setGeometry(const QRectF &rect)
50 50 {
51 51 QFontMetrics fn(font());
52 52
53 53 int width = rect.width();
54 54
55 55 if (fn.boundingRect(m_text).width() > width) {
56 56 QString string = m_text + "...";
57 57 while (fn.boundingRect(string).width() > width && string.length() > 3)
58 58 string.remove(string.length() - 4, 1);
59 59 QGraphicsSimpleTextItem::setText(string);
60 60 } else {
61 61 QGraphicsSimpleTextItem::setText(m_text);
62 62 }
63 63
64 64 setPos(rect.topLeft());
65 65 }
66 66
67 67
68 68 QSizeF ChartTitle::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
69 69 {
70 70 Q_UNUSED(constraint);
71 71 QFontMetrics fn(font());
72 72 QSizeF sh;
73 73
74 74 switch (which) {
75 75 case Qt::MinimumSize:
76 76 sh = QSizeF(fn.boundingRect("...").width(), fn.height());
77 77 break;
78 78 case Qt::PreferredSize:
79 sh = QSizeF(fn.boundingRect(m_text).width(), fn.height());
79 sh = fn.boundingRect(m_text).size();
80 80 break;
81 81 case Qt::MaximumSize:
82 sh = QSizeF(fn.boundingRect(m_text).width(), fn.height());
82 sh = fn.boundingRect(m_text).size();
83 83 break;
84 84 case Qt::MinimumDescent:
85 85 sh = QSizeF(0, fn.descent());
86 86 break;
87 87 default:
88 88 break;
89 89 }
90 90
91 91 return sh;
92 92 }
93 93
94 94 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now