##// END OF EJS Templates
Remove TODOs...
Miikka Heikkinen -
r2575:f9a133cb3e77
parent child
Show More
@@ -1,255 +1,252
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "qchart.h"
22 22 #include "qabstractaxis.h"
23 23 #include "qvalueaxis.h"
24 24 #include "qlogvalueaxis.h"
25 25 #include "declarativecategoryaxis.h"
26 26 #include "qbarcategoryaxis.h"
27 27 #include "declarativechart.h"
28 28 #include "declarativepolarchart.h"
29 29 #include "declarativexypoint.h"
30 30 #include "declarativelineseries.h"
31 31 #include "declarativesplineseries.h"
32 32 #include "declarativeareaseries.h"
33 33 #include "declarativescatterseries.h"
34 34 #include "declarativebarseries.h"
35 35 #include "declarativeboxplotseries.h"
36 36 #include "declarativepieseries.h"
37 37 #include "declarativeaxes.h"
38 38 #include "qvxymodelmapper.h"
39 39 #include "qhxymodelmapper.h"
40 40 #include "qhpiemodelmapper.h"
41 41 #include "qvpiemodelmapper.h"
42 42 #include "qhbarmodelmapper.h"
43 43 #include "qvbarmodelmapper.h"
44 44 #include "declarativemargins.h"
45 45 #include "qarealegendmarker.h"
46 46 #include "qbarlegendmarker.h"
47 47 #include "qpielegendmarker.h"
48 48 #include "qxylegendmarker.h"
49 49 #ifndef QT_ON_ARM
50 50 #include "qdatetimeaxis.h"
51 51 #endif
52 52 #include "shared_defines.h"
53 53 #include <QAbstractItemModel>
54 54 #ifdef CHARTS_FOR_QUICK2
55 55 #include <QtQml/QQmlExtensionPlugin>
56 56 #else
57 57 #include <QtDeclarative/qdeclarativeextensionplugin.h>
58 58 #include <QtDeclarative/qdeclarative.h>
59 59 #endif
60 60
61 61 QTCOMMERCIALCHART_USE_NAMESPACE
62 62
63 63 Q_DECLARE_METATYPE(QList<QPieSlice *>)
64 64 Q_DECLARE_METATYPE(QList<QBarSet *>)
65 65 Q_DECLARE_METATYPE(QList<QAbstractAxis *>)
66 66
67 67 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
68 68
69 // NOTE: Hackish fixes for Qt5 (beta2).
70 // These should not be needed or at least they are not needed in Qt4.
71
72 69 Q_DECLARE_METATYPE(DeclarativeChart *)
73 70 Q_DECLARE_METATYPE(DeclarativePolarChart *)
74 71 Q_DECLARE_METATYPE(DeclarativeMargins *)
75 72 Q_DECLARE_METATYPE(DeclarativeAreaSeries *)
76 73 Q_DECLARE_METATYPE(DeclarativeBarSeries *)
77 74 Q_DECLARE_METATYPE(DeclarativeBarSet *)
78 75 Q_DECLARE_METATYPE(DeclarativeBoxPlotSeries *)
79 76 Q_DECLARE_METATYPE(DeclarativeBoxSet *)
80 77 Q_DECLARE_METATYPE(DeclarativeLineSeries *)
81 78 Q_DECLARE_METATYPE(DeclarativePieSeries *)
82 79 Q_DECLARE_METATYPE(DeclarativeScatterSeries *)
83 80 Q_DECLARE_METATYPE(DeclarativeSplineSeries *)
84 81
85 82 Q_DECLARE_METATYPE(QAbstractAxis *)
86 83 Q_DECLARE_METATYPE(QValueAxis *)
87 84 Q_DECLARE_METATYPE(QBarCategoryAxis *)
88 85 Q_DECLARE_METATYPE(QCategoryAxis *)
89 86 Q_DECLARE_METATYPE(QDateTimeAxis *)
90 87 Q_DECLARE_METATYPE(QLogValueAxis *)
91 88
92 89 Q_DECLARE_METATYPE(QLegend *)
93 90 Q_DECLARE_METATYPE(QLegendMarker *)
94 91 Q_DECLARE_METATYPE(QAreaLegendMarker *)
95 92 Q_DECLARE_METATYPE(QBarLegendMarker *)
96 93 Q_DECLARE_METATYPE(QPieLegendMarker *)
97 94
98 95 Q_DECLARE_METATYPE(QHPieModelMapper *)
99 96 Q_DECLARE_METATYPE(QHXYModelMapper *)
100 97 Q_DECLARE_METATYPE(QPieModelMapper *)
101 98 Q_DECLARE_METATYPE(QHBarModelMapper *)
102 99 Q_DECLARE_METATYPE(QBarModelMapper *)
103 100 Q_DECLARE_METATYPE(QVBarModelMapper *)
104 101 Q_DECLARE_METATYPE(QVPieModelMapper *)
105 102 Q_DECLARE_METATYPE(QVXYModelMapper *)
106 103 Q_DECLARE_METATYPE(QXYLegendMarker *)
107 104 Q_DECLARE_METATYPE(QXYModelMapper *)
108 105
109 106 Q_DECLARE_METATYPE(QAbstractSeries *)
110 107 Q_DECLARE_METATYPE(QXYSeries *)
111 108 Q_DECLARE_METATYPE(QAbstractBarSeries *)
112 109 Q_DECLARE_METATYPE(QBarSeries *)
113 110 Q_DECLARE_METATYPE(QBarSet *)
114 111 Q_DECLARE_METATYPE(QAreaSeries *)
115 112 Q_DECLARE_METATYPE(QHorizontalBarSeries *)
116 113 Q_DECLARE_METATYPE(QHorizontalPercentBarSeries *)
117 114 Q_DECLARE_METATYPE(QHorizontalStackedBarSeries *)
118 115 Q_DECLARE_METATYPE(QLineSeries *)
119 116 Q_DECLARE_METATYPE(QPercentBarSeries *)
120 117 Q_DECLARE_METATYPE(QPieSeries *)
121 118 Q_DECLARE_METATYPE(QPieSlice *)
122 119 Q_DECLARE_METATYPE(QScatterSeries *)
123 120 Q_DECLARE_METATYPE(QSplineSeries *)
124 121 Q_DECLARE_METATYPE(QStackedBarSeries *)
125 122
126 123 #endif
127 124
128 125 QTCOMMERCIALCHART_BEGIN_NAMESPACE
129 126
130 127 class ChartQmlPlugin : public QDECLARATIVE_EXTENSION_PLUGIN
131 128 {
132 129 Q_OBJECT
133 130
134 131 #ifdef CHARTS_FOR_QUICK2
135 132 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
136 133 #else
137 134 # if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
138 135 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDeclarativeExtensionInterface")
139 136 # endif
140 137 #endif
141 138
142 139 public:
143 140 virtual void registerTypes(const char *uri)
144 141 {
145 142 Q_ASSERT(QLatin1String(uri) == QLatin1String("QtCommercial.Chart"));
146 143
147 144 qRegisterMetaType<QList<QPieSlice *> >();
148 145 qRegisterMetaType<QList<QBarSet *> >();
149 146 qRegisterMetaType<QList<QAbstractAxis *> >();
150 147
151 148 // QtCommercial.Chart 1.0
152 149 qmlRegisterType<DeclarativeChart>(uri, 1, 0, "ChartView");
153 150 qmlRegisterType<DeclarativeXYPoint>(uri, 1, 0, "XYPoint");
154 151 qmlRegisterType<DeclarativeScatterSeries>(uri, 1, 0, "ScatterSeries");
155 152 qmlRegisterType<DeclarativeLineSeries>(uri, 1, 0, "LineSeries");
156 153 qmlRegisterType<DeclarativeSplineSeries>(uri, 1, 0, "SplineSeries");
157 154 qmlRegisterType<DeclarativeAreaSeries>(uri, 1, 0, "AreaSeries");
158 155 qmlRegisterType<DeclarativeBarSeries>(uri, 1, 0, "BarSeries");
159 156 qmlRegisterType<DeclarativeStackedBarSeries>(uri, 1, 0, "StackedBarSeries");
160 157 qmlRegisterType<DeclarativePercentBarSeries>(uri, 1, 0, "PercentBarSeries");
161 158 qmlRegisterType<DeclarativePieSeries>(uri, 1, 0, "PieSeries");
162 159 qmlRegisterType<QPieSlice>(uri, 1, 0, "PieSlice");
163 160 qmlRegisterType<DeclarativeBarSet>(uri, 1, 0, "BarSet");
164 161 qmlRegisterType<QHXYModelMapper>(uri, 1, 0, "HXYModelMapper");
165 162 qmlRegisterType<QVXYModelMapper>(uri, 1, 0, "VXYModelMapper");
166 163 qmlRegisterType<QHPieModelMapper>(uri, 1, 0, "HPieModelMapper");
167 164 qmlRegisterType<QVPieModelMapper>(uri, 1, 0, "VPieModelMapper");
168 165 qmlRegisterType<QHBarModelMapper>(uri, 1, 0, "HBarModelMapper");
169 166 qmlRegisterType<QVBarModelMapper>(uri, 1, 0, "VBarModelMapper");
170 167 qmlRegisterType<QValueAxis>(uri, 1, 0, "ValuesAxis");
171 168 qmlRegisterType<QBarCategoryAxis>(uri, 1, 0, "BarCategoriesAxis");
172 169 qmlRegisterUncreatableType<QLegend>(uri, 1, 0, "Legend",
173 170 QLatin1String("Trying to create uncreatable: Legend."));
174 171 qmlRegisterUncreatableType<QXYSeries>(uri, 1, 0, "XYSeries",
175 172 QLatin1String("Trying to create uncreatable: XYSeries."));
176 173 qmlRegisterUncreatableType<QAbstractItemModel>(uri, 1, 0, "AbstractItemModel",
177 174 QLatin1String("Trying to create uncreatable: AbstractItemModel."));
178 175 qmlRegisterUncreatableType<QXYModelMapper>(uri, 1, 0, "XYModelMapper",
179 176 QLatin1String("Trying to create uncreatable: XYModelMapper."));
180 177 qmlRegisterUncreatableType<QPieModelMapper>(uri, 1, 0, "PieModelMapper",
181 178 QLatin1String("Trying to create uncreatable: PieModelMapper."));
182 179 qmlRegisterUncreatableType<QBarModelMapper>(uri, 1, 0, "BarModelMapper",
183 180 QLatin1String("Trying to create uncreatable: BarModelMapper."));
184 181 qmlRegisterUncreatableType<QAbstractSeries>(uri, 1, 0, "AbstractSeries",
185 182 QLatin1String("Trying to create uncreatable: AbstractSeries."));
186 183 qmlRegisterUncreatableType<QAbstractBarSeries>(uri, 1, 0, "AbstractBarSeries",
187 184 QLatin1String("Trying to create uncreatable: AbstractBarSeries."));
188 185 qmlRegisterUncreatableType<QAbstractAxis>(uri, 1, 0, "AbstractAxis",
189 186 QLatin1String("Trying to create uncreatable: AbstractAxis. Use specific types of axis instead."));
190 187 qmlRegisterUncreatableType<QBarSet>(uri, 1, 0, "BarSetBase",
191 188 QLatin1String("Trying to create uncreatable: BarsetBase."));
192 189 qmlRegisterUncreatableType<QPieSeries>(uri, 1, 0, "QPieSeries",
193 190 QLatin1String("Trying to create uncreatable: QPieSeries. Use PieSeries instead."));
194 191 qmlRegisterUncreatableType<DeclarativeAxes>(uri, 1, 0, "DeclarativeAxes",
195 192 QLatin1String("Trying to create uncreatable: DeclarativeAxes."));
196 193
197 194 // QtCommercial.Chart 1.1
198 195 qmlRegisterType<DeclarativeChart, 1>(uri, 1, 1, "ChartView");
199 196 qmlRegisterType<DeclarativeScatterSeries, 1>(uri, 1, 1, "ScatterSeries");
200 197 qmlRegisterType<DeclarativeLineSeries, 1>(uri, 1, 1, "LineSeries");
201 198 qmlRegisterType<DeclarativeSplineSeries, 1>(uri, 1, 1, "SplineSeries");
202 199 qmlRegisterType<DeclarativeAreaSeries, 1>(uri, 1, 1, "AreaSeries");
203 200 qmlRegisterType<DeclarativeBarSeries, 1>(uri, 1, 1, "BarSeries");
204 201 qmlRegisterType<DeclarativeStackedBarSeries, 1>(uri, 1, 1, "StackedBarSeries");
205 202 qmlRegisterType<DeclarativePercentBarSeries, 1>(uri, 1, 1, "PercentBarSeries");
206 203 qmlRegisterType<DeclarativeHorizontalBarSeries, 1>(uri, 1, 1, "HorizontalBarSeries");
207 204 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 1>(uri, 1, 1, "HorizontalStackedBarSeries");
208 205 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 1>(uri, 1, 1, "HorizontalPercentBarSeries");
209 206 qmlRegisterType<DeclarativePieSeries>(uri, 1, 1, "PieSeries");
210 207 qmlRegisterType<DeclarativeBarSet>(uri, 1, 1, "BarSet");
211 208 qmlRegisterType<QValueAxis>(uri, 1, 1, "ValueAxis");
212 209 #ifndef QT_ON_ARM
213 210 qmlRegisterType<QDateTimeAxis>(uri, 1, 1, "DateTimeAxis");
214 211 #endif
215 212 qmlRegisterType<DeclarativeCategoryAxis>(uri, 1, 1, "CategoryAxis");
216 213 qmlRegisterType<DeclarativeCategoryRange>(uri, 1, 1, "CategoryRange");
217 214 qmlRegisterType<QBarCategoryAxis>(uri, 1, 1, "BarCategoryAxis");
218 215 qmlRegisterUncreatableType<DeclarativeMargins>(uri, 1, 1, "Margins",
219 216 QLatin1String("Trying to create uncreatable: Margins."));
220 217
221 218 // QtCommercial.Chart 1.2
222 219 qmlRegisterType<DeclarativeChart, 2>(uri, 1, 2, "ChartView");
223 220 qmlRegisterType<DeclarativeScatterSeries, 2>(uri, 1, 2, "ScatterSeries");
224 221 qmlRegisterType<DeclarativeLineSeries, 2>(uri, 1, 2, "LineSeries");
225 222 qmlRegisterType<DeclarativeSplineSeries, 2>(uri, 1, 2, "SplineSeries");
226 223 qmlRegisterType<DeclarativeAreaSeries, 2>(uri, 1, 2, "AreaSeries");
227 224 qmlRegisterType<DeclarativeBarSeries, 2>(uri, 1, 2, "BarSeries");
228 225 qmlRegisterType<DeclarativeStackedBarSeries, 2>(uri, 1, 2, "StackedBarSeries");
229 226 qmlRegisterType<DeclarativePercentBarSeries, 2>(uri, 1, 2, "PercentBarSeries");
230 227 qmlRegisterType<DeclarativeHorizontalBarSeries, 2>(uri, 1, 2, "HorizontalBarSeries");
231 228 qmlRegisterType<DeclarativeHorizontalStackedBarSeries, 2>(uri, 1, 2, "HorizontalStackedBarSeries");
232 229 qmlRegisterType<DeclarativeHorizontalPercentBarSeries, 2>(uri, 1, 2, "HorizontalPercentBarSeries");
233 230
234 231 // QtCommercial.Chart 1.3
235 232 qmlRegisterType<DeclarativeChart, 3>(uri, 1, 3, "ChartView");
236 233 qmlRegisterType<DeclarativePolarChart, 1>(uri, 1, 3, "PolarChartView");
237 234 qmlRegisterType<DeclarativeSplineSeries, 3>(uri, 1, 3, "SplineSeries");
238 235 qmlRegisterType<DeclarativeScatterSeries, 3>(uri, 1, 3, "ScatterSeries");
239 236 qmlRegisterType<DeclarativeLineSeries, 3>(uri, 1, 3, "LineSeries");
240 237 qmlRegisterType<DeclarativeAreaSeries, 3>(uri, 1, 3, "AreaSeries");
241 238 qmlRegisterType<QLogValueAxis>(uri, 1, 3, "LogValueAxis");
242 239 qmlRegisterType<DeclarativeBoxPlotSeries>(uri, 1, 3, "BoxPlotSeries");
243 240 qmlRegisterType<DeclarativeBoxSet>(uri, 1, 3, "BoxSet");
244 241 }
245 242 };
246 243
247 244 #include "plugin.moc"
248 245
249 246 QTCOMMERCIALCHART_END_NAMESPACE
250 247
251 248 QTCOMMERCIALCHART_USE_NAMESPACE
252 249
253 250 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
254 251 Q_EXPORT_PLUGIN2(qtcommercialchartqml, QT_PREPEND_NAMESPACE(ChartQmlPlugin))
255 252 #endif
@@ -1,141 +1,136
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "axisanimation_p.h"
22 22 #include "chartaxiselement_p.h"
23 23 #include "qabstractaxis_p.h"
24 24
25 25 Q_DECLARE_METATYPE(QVector<qreal>)
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29
30 30 AxisAnimation::AxisAnimation(ChartAxisElement *axis)
31 31 : ChartAnimation(axis),
32 32 m_axis(axis),
33 33 m_type(DefaultAnimation)
34 34 {
35 35 setDuration(ChartAnimationDuration);
36 36 setEasingCurve(QEasingCurve::OutQuart);
37 37 }
38 38
39 39 AxisAnimation::~AxisAnimation()
40 40 {
41 41 }
42 42
43 43 void AxisAnimation::setAnimationType(Animation type)
44 44 {
45 45 if (state() != QAbstractAnimation::Stopped)
46 46 stop();
47 47 m_type = type;
48 48 }
49 49
50 50 void AxisAnimation::setAnimationPoint(const QPointF &point)
51 51 {
52 52 if (state() != QAbstractAnimation::Stopped)
53 53 stop();
54 54 m_point = point;
55 55 }
56 56
57 57 void AxisAnimation::setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayout)
58 58 {
59 59 if (state() != QAbstractAnimation::Stopped) stop();
60 60
61 // TODO: cannot return even if layout is empty
62 // New layout is not set properly without it (crash)
63 // if (newLayout.count() == 0)
64 // return;
65
66 61 switch (m_type) {
67 62 case ZoomOutAnimation: {
68 63 QRectF rect = m_axis->gridGeometry();
69 64 oldLayout.resize(newLayout.count());
70 65
71 66 for (int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
72 67 oldLayout[i] = m_axis->axis()->orientation() == Qt::Horizontal ? rect.left() : rect.bottom();
73 68 oldLayout[j] = m_axis->axis()->orientation() == Qt::Horizontal ? rect.right() : rect.top();
74 69 }
75 70 }
76 71 break;
77 72 case ZoomInAnimation: {
78 73 int index = qMin(oldLayout.count() * (m_axis->axis()->orientation() == Qt::Horizontal ? m_point.x() : (1 - m_point.y())), newLayout.count() - (qreal)1.0);
79 74 oldLayout.resize(newLayout.count());
80 75
81 76 for (int i = 0; i < oldLayout.count(); i++)
82 77 oldLayout[i] = oldLayout[index];
83 78 }
84 79 break;
85 80 case MoveForwardAnimation: {
86 81 oldLayout.resize(newLayout.count());
87 82
88 83 for (int i = 0, j = i + 1; i < oldLayout.count() - 1; ++i, ++j)
89 84 oldLayout[i] = oldLayout[j];
90 85 }
91 86 break;
92 87 case MoveBackwordAnimation: {
93 88 oldLayout.resize(newLayout.count());
94 89
95 90 for (int i = oldLayout.count() - 1, j = i - 1; i > 0; --i, --j)
96 91 oldLayout[i] = oldLayout[j];
97 92 }
98 93 break;
99 94 default: {
100 95 oldLayout.resize(newLayout.count());
101 96 QRectF rect = m_axis->gridGeometry();
102 97 for (int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
103 98 oldLayout[i] = m_axis->axis()->orientation() == Qt::Horizontal ? rect.left() : rect.top();
104 99 }
105 100 break;
106 101 }
107 102
108 103 QVariantAnimation::KeyValues value;
109 104 setKeyValues(value); //workaround for wrong interpolation call
110 105 setKeyValueAt(0.0, qVariantFromValue(oldLayout));
111 106 setKeyValueAt(1.0, qVariantFromValue(newLayout));
112 107 }
113 108
114 109 QVariant AxisAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
115 110 {
116 111 QVector<qreal> startVector = qvariant_cast<QVector<qreal> >(start);
117 112 QVector<qreal> endVecotr = qvariant_cast<QVector<qreal> >(end);
118 113 QVector<qreal> result;
119 114
120 115 Q_ASSERT(startVector.count() == endVecotr.count()) ;
121 116
122 117 for (int i = 0; i < startVector.count(); i++) {
123 118 qreal value = startVector[i] + ((endVecotr[i] - startVector[i]) * progress); //qBound(0.0, progress, 1.0));
124 119 result << value;
125 120 }
126 121 return qVariantFromValue(result);
127 122 }
128 123
129 124
130 125 void AxisAnimation::updateCurrentValue(const QVariant &value)
131 126 {
132 127 if (state() != QAbstractAnimation::Stopped) { //workaround
133 128 QVector<qreal> vector = qvariant_cast<QVector<qreal> >(value);
134 129 // Q_ASSERT(vector.count() != 0);
135 130 m_axis->setLayout(vector);
136 131 m_axis->updateGeometry();
137 132 }
138 133
139 134 }
140 135
141 136 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,191 +1,189
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "areachartitem_p.h"
22 22 #include "qareaseries.h"
23 23 #include "qareaseries_p.h"
24 24 #include "qlineseries.h"
25 25 #include "chartpresenter_p.h"
26 26 #include "abstractdomain_p.h"
27 27 #include <QPainter>
28 28 #include <QGraphicsSceneMouseEvent>
29 29 #include <QDebug>
30 30
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 //TODO: optimize : remove points which are not visible
35
36 34 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, QGraphicsItem* item)
37 35 : ChartItem(areaSeries->d_func(),item),
38 36 m_series(areaSeries),
39 37 m_upper(0),
40 38 m_lower(0),
41 39 m_pointsVisible(false)
42 40 {
43 41 setAcceptHoverEvents(true);
44 42 setZValue(ChartPresenter::LineChartZValue);
45 43 m_upper = new AreaBoundItem(this, m_series->upperSeries());
46 44 if (m_series->lowerSeries())
47 45 m_lower = new AreaBoundItem(this, m_series->lowerSeries());
48 46
49 47 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
50 48 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
51 49 QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
52 50 QObject::connect(this, SIGNAL(clicked(QPointF)), areaSeries, SIGNAL(clicked(QPointF)));
53 51 QObject::connect(this, SIGNAL(hovered(QPointF,bool)), areaSeries, SIGNAL(hovered(QPointF,bool)));
54 52
55 53 handleUpdated();
56 54 }
57 55
58 56 AreaChartItem::~AreaChartItem()
59 57 {
60 58 delete m_upper;
61 59 delete m_lower;
62 60 }
63 61
64 62 void AreaChartItem::setPresenter(ChartPresenter *presenter)
65 63 {
66 64 m_upper->setPresenter(presenter);
67 65 if (m_lower) {
68 66 m_lower->setPresenter(presenter);
69 67 }
70 68 ChartItem::setPresenter(presenter);
71 69 }
72 70
73 71 QRectF AreaChartItem::boundingRect() const
74 72 {
75 73 return m_rect;
76 74 }
77 75
78 76 QPainterPath AreaChartItem::shape() const
79 77 {
80 78 return m_path;
81 79 }
82 80
83 81 void AreaChartItem::updatePath()
84 82 {
85 83 QPainterPath path;
86 84 QRectF rect(QPointF(0,0),domain()->size());
87 85
88 86 path = m_upper->path();
89 87
90 88 if (m_lower) {
91 89 // Note: Polarcharts always draw area correctly only when both series have equal width or are
92 90 // fully displayed. If one series is partally off-chart, the connecting line between
93 91 // the series does not attach to the end of the partially hidden series but to the point
94 92 // where it intersects the axis line. The problem is especially noticeable when one of the series
95 93 // is entirely off-chart, in which case the connecting line connects two ends of the
96 94 // visible series.
97 95 // This happens because we get the paths from linechart, which omits off-chart segments.
98 96 // To properly fix, linechart would need to provide true full path, in right, left, and the rest
99 97 // portions to enable proper clipping. However, combining those to single visually unified area
100 98 // would be a nightmare, since they would have to be painted separately.
101 99 path.connectPath(m_lower->path().toReversed());
102 100 } else {
103 101 QPointF first = path.pointAtPercent(0);
104 102 QPointF last = path.pointAtPercent(1);
105 103 if (presenter()->chartType() == QChart::ChartTypeCartesian) {
106 104 path.lineTo(last.x(), rect.bottom());
107 105 path.lineTo(first.x(), rect.bottom());
108 106 } else { // polar
109 107 path.lineTo(rect.center());
110 108 }
111 109 }
112 110 path.closeSubpath();
113 111 prepareGeometryChange();
114 112 m_path = path;
115 113 m_rect = path.boundingRect();
116 114 update();
117 115 }
118 116
119 117 void AreaChartItem::handleUpdated()
120 118 {
121 119 setVisible(m_series->isVisible());
122 120 m_pointsVisible = m_series->pointsVisible();
123 121 m_linePen = m_series->pen();
124 122 m_brush = m_series->brush();
125 123 m_pointPen = m_series->pen();
126 124 m_pointPen.setWidthF(2 * m_pointPen.width());
127 125 setOpacity(m_series->opacity());
128 126 update();
129 127 }
130 128
131 129 void AreaChartItem::handleDomainUpdated()
132 130 {
133 131 AbstractDomain* d = m_upper->domain();
134 132
135 133 d->setSize(domain()->size());
136 134 d->setRange(domain()->minX(),domain()->maxX(),domain()->minY(),domain()->maxY());
137 135 m_upper->handleDomainUpdated();
138 136
139 137 if (m_lower) {
140 138 AbstractDomain* d = m_lower->domain();
141 139 d->setSize(domain()->size());
142 140 d->setRange(domain()->minX(),domain()->maxX(),domain()->minY(),domain()->maxY());
143 141 m_lower->handleDomainUpdated();
144 142 }
145 143 }
146 144
147 145 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
148 146 {
149 147 Q_UNUSED(widget)
150 148 Q_UNUSED(option)
151 149 painter->save();
152 150 painter->setPen(m_linePen);
153 151 painter->setBrush(m_brush);
154 152 QRectF clipRect = QRectF(QPointF(0, 0), domain()->size());
155 153 if (presenter()->chartType() == QChart::ChartTypePolar)
156 154 painter->setClipRegion(QRegion(clipRect.toRect(), QRegion::Ellipse));
157 155 else
158 156 painter->setClipRect(clipRect);
159 157 painter->drawPath(m_path);
160 158 if (m_pointsVisible) {
161 159 painter->setPen(m_pointPen);
162 160 painter->drawPoints(m_upper->geometryPoints());
163 161 if (m_lower)
164 162 painter->drawPoints(m_lower->geometryPoints());
165 163 }
166 164 painter->restore();
167 165 }
168 166
169 167 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
170 168 {
171 169 emit clicked(m_upper->domain()->calculateDomainPoint(event->pos()));
172 170 ChartItem::mousePressEvent(event);
173 171 }
174 172
175 173 void AreaChartItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
176 174 {
177 175 emit hovered(domain()->calculateDomainPoint(event->pos()), true);
178 176 event->accept();
179 177 // QGraphicsItem::hoverEnterEvent(event);
180 178 }
181 179
182 180 void AreaChartItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
183 181 {
184 182 emit hovered(domain()->calculateDomainPoint(event->pos()), false);
185 183 event->accept();
186 184 // QGraphicsItem::hoverEnterEvent(event);
187 185 }
188 186
189 187 #include "moc_areachartitem_p.cpp"
190 188
191 189 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,118 +1,117
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartcategoryaxisx_p.h"
22 22 #include "qcategoryaxis.h"
23 23 #include "qabstractaxis.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "abstractchartlayout_p.h"
26 26 #include <QGraphicsLayout>
27 27 #include <qmath.h>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 ChartCategoryAxisX::ChartCategoryAxisX(QCategoryAxis *axis, QGraphicsItem* item)
32 32 : HorizontalAxis(axis, item, true),
33 33 m_axis(axis)
34 34 {
35 35 QObject::connect(axis, SIGNAL(categoriesChanged()), this, SLOT(handleCategoriesChanged()));
36 36 }
37 37
38 38 ChartCategoryAxisX::~ChartCategoryAxisX()
39 39 {
40 40 }
41 41
42 42 QVector<qreal> ChartCategoryAxisX::calculateLayout() const
43 43 {
44 44 int tickCount = m_axis->categoriesLabels().count() + 1;
45 45 QVector<qreal> points;
46 46
47 47 if (tickCount < 2)
48 48 return points;
49 49
50 50 const QRectF &gridRect = gridGeometry();
51 51 qreal range = max() - min();
52 52 if (range > 0) {
53 53 points.resize(tickCount);
54 54 qreal scale = gridRect.width() / range;
55 55 for (int i = 0; i < tickCount; ++i) {
56 56 if (i < tickCount - 1) {
57 57 qreal x = (m_axis->startValue(m_axis->categoriesLabels().at(i)) - min()) * scale + gridRect.left();
58 58 points[i] = x;
59 59 } else {
60 60 qreal x = (m_axis->endValue(m_axis->categoriesLabels().at(i - 1)) - min()) * scale + gridRect.left();
61 61 points[i] = x;
62 62 }
63 63 }
64 64 }
65 65
66 66 return points;
67 67 }
68 68
69 69 void ChartCategoryAxisX::updateGeometry()
70 70 {
71 //TODO: this is not optimal when many categories :( , create only visible lables
72 71 setLabels(m_axis->categoriesLabels() << "");
73 72 HorizontalAxis::updateGeometry();
74 73 }
75 74
76 75 QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
77 76 {
78 77 Q_UNUSED(constraint)
79 78
80 79 QSizeF sh;
81 80 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
82 81 QStringList ticksList = m_axis->categoriesLabels();
83 82 qreal width = 0; // Width is irrelevant for X axes with interval labels
84 83 qreal height = 0;
85 84
86 85 switch (which) {
87 86 case Qt::MinimumSize: {
88 87 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), "...", axis()->labelsAngle());
89 88 height = boundingRect.height() + labelPadding() + base.height() + 1.0;
90 89 sh = QSizeF(width, height);
91 90 break;
92 91 }
93 92 case Qt::PreferredSize: {
94 93 qreal labelHeight = 0.0;
95 94 foreach (const QString& s, ticksList) {
96 95 QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle());
97 96 labelHeight = qMax(rect.height(), labelHeight);
98 97 }
99 98 height = labelHeight + labelPadding() + base.height() + 1.0;
100 99 sh = QSizeF(width, height);
101 100 break;
102 101 }
103 102 default:
104 103 break;
105 104 }
106 105
107 106 return sh;
108 107 }
109 108
110 109 void ChartCategoryAxisX::handleCategoriesChanged()
111 110 {
112 111 QGraphicsLayoutItem::updateGeometry();
113 112 presenter()->layout()->invalidate();
114 113 }
115 114
116 115 #include "moc_chartcategoryaxisx_p.cpp"
117 116
118 117 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,423 +1,420
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "polarchartaxisangular_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "abstractchartlayout_p.h"
24 24 #include "qabstractaxis.h"
25 25 #include "qabstractaxis_p.h"
26 26 #include <QDebug>
27 27 #include <qmath.h>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 PolarChartAxisAngular::PolarChartAxisAngular(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
32 32 : PolarChartAxis(axis, item, intervalAxis)
33 33 {
34 34 }
35 35
36 36 PolarChartAxisAngular::~PolarChartAxisAngular()
37 37 {
38 38 }
39 39
40 40 void PolarChartAxisAngular::updateGeometry()
41 41 {
42 42 QGraphicsLayoutItem::updateGeometry();
43 43
44 44 const QVector<qreal> &layout = this->layout();
45 45 if (layout.isEmpty())
46 46 return;
47 47
48 48 createAxisLabels(layout);
49 49 QStringList labelList = labels();
50 50 QPointF center = axisGeometry().center();
51 51 QList<QGraphicsItem *> arrowItemList = arrowItems();
52 52 QList<QGraphicsItem *> gridItemList = gridItems();
53 53 QList<QGraphicsItem *> labelItemList = labelItems();
54 54 QList<QGraphicsItem *> shadeItemList = shadeItems();
55 55 QGraphicsTextItem *title = titleItem();
56 56
57 57 QGraphicsEllipseItem *axisLine = static_cast<QGraphicsEllipseItem *>(arrowItemList.at(0));
58 58 axisLine->setRect(axisGeometry());
59 59
60 60 qreal radius = axisGeometry().height() / 2.0;
61 61
62 62 QRectF previousLabelRect;
63 63 QRectF firstLabelRect;
64 64
65 65 qreal labelHeight = 0;
66 66
67 67 bool firstShade = true;
68 68 bool nextTickVisible = false;
69 69 if (layout.size())
70 70 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > 360.0);
71 71
72 72 for (int i = 0; i < layout.size(); ++i) {
73 73 qreal angularCoordinate = layout.at(i);
74 74
75 75 QGraphicsLineItem *gridLineItem = static_cast<QGraphicsLineItem *>(gridItemList.at(i));
76 76 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
77 77 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labelItemList.at(i));
78 78 QGraphicsPathItem *shadeItem = 0;
79 79 if (i == 0)
80 80 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
81 81 else if (i % 2)
82 82 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
83 83
84 84 // Ignore ticks outside valid range
85 85 bool currentTickVisible = nextTickVisible;
86 86 if ((i == layout.size() - 1)
87 87 || layout.at(i + 1) < 0.0
88 88 || layout.at(i + 1) > 360.0) {
89 89 nextTickVisible = false;
90 90 } else {
91 91 nextTickVisible = true;
92 92 }
93 93
94 94 qreal labelCoordinate = angularCoordinate;
95 95 qreal labelVisible = currentTickVisible;
96 96 if (intervalAxis()) {
97 97 qreal farEdge;
98 98 if (i == (layout.size() - 1))
99 99 farEdge = 360.0;
100 100 else
101 101 farEdge = qMin(qreal(360.0), layout.at(i + 1));
102 102
103 103 // Adjust the labelCoordinate to show it if next tick is visible
104 104 if (nextTickVisible)
105 105 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
106 106
107 107 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
108 108 // Don't display label once the category gets too small near the axis
109 109 if (labelCoordinate < 5.0 || labelCoordinate > 355.0)
110 110 labelVisible = false;
111 111 else
112 112 labelVisible = true;
113 113 }
114 114
115 115 // Need this also in label calculations, so determine it first
116 116 QLineF tickLine(QLineF::fromPolar(radius - tickWidth(), 90.0 - angularCoordinate).p2(),
117 117 QLineF::fromPolar(radius + tickWidth(), 90.0 - angularCoordinate).p2());
118 118 tickLine.translate(center);
119 119
120 120 // Angular axis label
121 121 if (axis()->labelsVisible() && labelVisible) {
122 122 labelItem->setHtml(labelList.at(i));
123 123 const QRectF &rect = labelItem->boundingRect();
124 124 QPointF labelCenter = rect.center();
125 125 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
126 126 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
127 127 boundingRect.moveCenter(labelCenter);
128 128 QPointF positionDiff(rect.topLeft() - boundingRect.topLeft());
129 129
130 130 QPointF labelPoint;
131 131 if (intervalAxis()) {
132 132 QLineF labelLine = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate);
133 133 labelLine.translate(center);
134 134 labelPoint = labelLine.p2();
135 135 } else {
136 136 labelPoint = tickLine.p2();
137 137 }
138 138
139 139 QRectF labelRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
140 140 labelItem->setPos(labelRect.topLeft() + positionDiff);
141 141
142 142 // Store height for title calculations
143 143 qreal labelClearance = axisGeometry().top() - labelRect.top();
144 144 labelHeight = qMax(labelHeight, labelClearance);
145 145
146 146 // Label overlap detection
147 147 if (i && (previousLabelRect.intersects(labelRect) || firstLabelRect.intersects(labelRect))) {
148 148 labelVisible = false;
149 149 } else {
150 150 // Store labelRect for future comparison. Some area is deducted to make things look
151 151 // little nicer, as usually intersection happens at label corner with angular labels.
152 152 labelRect.adjust(-2.0, -4.0, -2.0, -4.0);
153 153 if (firstLabelRect.isEmpty())
154 154 firstLabelRect = labelRect;
155 155
156 156 previousLabelRect = labelRect;
157 157 labelVisible = true;
158 158 }
159 159 }
160 160
161 161 labelItem->setVisible(labelVisible);
162 162 if (!currentTickVisible) {
163 163 gridLineItem->setVisible(false);
164 164 tickItem->setVisible(false);
165 165 if (shadeItem)
166 166 shadeItem->setVisible(false);
167 167 continue;
168 168 }
169 169
170 170 // Angular grid line
171 171 QLineF gridLine = QLineF::fromPolar(radius, 90.0 - angularCoordinate);
172 172 gridLine.translate(center);
173 173 gridLineItem->setLine(gridLine);
174 174 gridLineItem->setVisible(true);
175 175
176 176 // Tick
177 177 tickItem->setLine(tickLine);
178 178 tickItem->setVisible(true);
179 179
180 180 // Shades
181 181 if (i % 2 || (i == 0 && !nextTickVisible)) {
182 182 QPainterPath path;
183 183 path.moveTo(center);
184 184 if (i == 0) {
185 185 // If first tick is also the last, we need to custom fill the first partial arc
186 186 // or it won't get filled.
187 187 path.arcTo(axisGeometry(), 90.0 - layout.at(0), layout.at(0));
188 188 path.closeSubpath();
189 189 } else {
190 190 qreal nextCoordinate;
191 191 if (!nextTickVisible) // Last visible tick
192 192 nextCoordinate = 360.0;
193 193 else
194 194 nextCoordinate = layout.at(i + 1);
195 195 qreal arcSpan = angularCoordinate - nextCoordinate;
196 196 path.arcTo(axisGeometry(), 90.0 - angularCoordinate, arcSpan);
197 197 path.closeSubpath();
198 198
199 199 // Add additional arc for first shade item if there is a partial arc to be filled
200 200 if (firstShade) {
201 201 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
202 202 if (layout.at(i - 1) > 0.0) {
203 203 QPainterPath specialPath;
204 204 specialPath.moveTo(center);
205 205 specialPath.arcTo(axisGeometry(), 90.0 - layout.at(i - 1), layout.at(i - 1));
206 206 specialPath.closeSubpath();
207 207 specialShadeItem->setPath(specialPath);
208 208 specialShadeItem->setVisible(true);
209 209 } else {
210 210 specialShadeItem->setVisible(false);
211 211 }
212 212 }
213 213 }
214 214 shadeItem->setPath(path);
215 215 shadeItem->setVisible(true);
216 216 firstShade = false;
217 217 }
218 218 }
219 219
220 220 // Title, centered above the chart
221 221 QString titleText = axis()->titleText();
222 222 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
223 223 QRectF dummyRect;
224 224 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), axisGeometry().width(), Qt::Horizontal, dummyRect));
225 225
226 226 QRectF titleBoundingRect = title->boundingRect();
227 227 QPointF titleCenter = center - titleBoundingRect.center();
228 228 title->setPos(titleCenter.x(), axisGeometry().top() - titlePadding() * 2.0 - titleBoundingRect.height() - labelHeight);
229 229 }
230 230 }
231 231
232 232 Qt::Orientation PolarChartAxisAngular::orientation() const
233 233 {
234 234 return Qt::Horizontal;
235 235 }
236 236
237 237 void PolarChartAxisAngular::createItems(int count)
238 238 {
239 239 if (arrowItems().count() == 0) {
240 240 // angular axis line
241 // TODO: need class similar to LineArrowItem for click handling?
242 241 QGraphicsEllipseItem *arrow = new QGraphicsEllipseItem(presenter()->rootItem());
243 242 arrow->setPen(axis()->linePen());
244 243 arrowGroup()->addToGroup(arrow);
245 244 }
246 245
247 246 for (int i = 0; i < count; ++i) {
248 247 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
249 248 QGraphicsLineItem *grid = new QGraphicsLineItem(presenter()->rootItem());
250 249 QGraphicsTextItem *label = new QGraphicsTextItem(presenter()->rootItem());
251 250 QGraphicsTextItem *title = titleItem();
252 251 arrow->setPen(axis()->linePen());
253 252 grid->setPen(axis()->gridLinePen());
254 253 label->setFont(axis()->labelsFont());
255 254 label->setDefaultTextColor(axis()->labelsBrush().color());
256 255 label->setRotation(axis()->labelsAngle());
257 256 title->setFont(axis()->titleFont());
258 257 title->setDefaultTextColor(axis()->titleBrush().color());
259 258 title->setHtml(axis()->titleText());
260 259 arrowGroup()->addToGroup(arrow);
261 260 gridGroup()->addToGroup(grid);
262 261 labelGroup()->addToGroup(label);
263 262 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
264 263 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
265 264 shade->setPen(axis()->shadesPen());
266 265 shade->setBrush(axis()->shadesBrush());
267 266 shadeGroup()->addToGroup(shade);
268 267 }
269 268 }
270 269 }
271 270
272 271 void PolarChartAxisAngular::handleArrowPenChanged(const QPen &pen)
273 272 {
274 273 bool first = true;
275 274 foreach (QGraphicsItem *item, arrowItems()) {
276 275 if (first) {
277 276 first = false;
278 277 // First arrow item is the outer circle of axis
279 278 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
280 279 } else {
281 280 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
282 281 }
283 282 }
284 283 }
285 284
286 285 void PolarChartAxisAngular::handleGridPenChanged(const QPen &pen)
287 286 {
288 287 foreach (QGraphicsItem *item, gridItems())
289 288 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
290 289 }
291 290
292 291 QSizeF PolarChartAxisAngular::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
293 292 {
294 293 Q_UNUSED(which);
295 294 Q_UNUSED(constraint);
296 295 return QSizeF(-1, -1);
297 296 }
298 297
299 298 qreal PolarChartAxisAngular::preferredAxisRadius(const QSizeF &maxSize)
300 299 {
301 300 qreal radius = maxSize.height() / 2.0;
302 301 if (maxSize.width() < maxSize.height())
303 302 radius = maxSize.width() / 2.0;
304 303
305 304 if (axis()->labelsVisible()) {
306 305 QVector<qreal> layout = calculateLayout();
307 306 if (layout.isEmpty())
308 307 return radius;
309 308
310 309 createAxisLabels(layout);
311 310 QStringList labelList = labels();
312 311 QFont font = axis()->labelsFont();
313 312
314 313 QRectF maxRect;
315 314 maxRect.setSize(maxSize);
316 315 maxRect.moveCenter(QPointF(0.0, 0.0));
317 316
318 317 // This is a horrible way to find out the maximum radius for angular axis and its labels.
319 318 // It just increments the radius down until everyhing fits the constraint size.
320 319 // Proper way would be to actually calculate it but this seems to work reasonably fast as it is.
321 320 bool nextTickVisible = false;
322 321 for (int i = 0; i < layout.size(); ) {
323 322 if ((i == layout.size() - 1)
324 323 || layout.at(i + 1) < 0.0
325 324 || layout.at(i + 1) > 360.0) {
326 325 nextTickVisible = false;
327 326 } else {
328 327 nextTickVisible = true;
329 328 }
330 329
331 330 qreal labelCoordinate = layout.at(i);
332 331 qreal labelVisible;
333 332
334 333 if (intervalAxis()) {
335 334 qreal farEdge;
336 335 if (i == (layout.size() - 1))
337 336 farEdge = 360.0;
338 337 else
339 338 farEdge = qMin(qreal(360.0), layout.at(i + 1));
340 339
341 340 // Adjust the labelCoordinate to show it if next tick is visible
342 341 if (nextTickVisible)
343 342 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
344 343
345 344 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
346 345 }
347 346
348 347 if (labelCoordinate < 0.0 || labelCoordinate > 360.0)
349 348 labelVisible = false;
350 349 else
351 350 labelVisible = true;
352 351
353 352 if (!labelVisible) {
354 353 i++;
355 354 continue;
356 355 }
357 356
358 357 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
359 358 QPointF labelPoint = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate).p2();
360 359
361 360 boundingRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
362 361 QRectF intersectRect = maxRect.intersected(boundingRect);
363 362 if (boundingRect.isEmpty() || intersectRect == boundingRect) {
364 363 i++;
365 364 } else {
366 365 qreal reduction(0.0);
367 366 // If there is no intersection, reduce by smallest dimension of label rect to be on the safe side
368 367 if (intersectRect.isEmpty()) {
369 368 reduction = qMin(boundingRect.height(), boundingRect.width());
370 369 } else {
371 370 // Approximate needed radius reduction is the amount label rect exceeds max rect in either dimension.
372 371 // Could be further optimized by figuring out the proper math how to calculate exact needed reduction.
373 372 reduction = qMax(boundingRect.height() - intersectRect.height(),
374 373 boundingRect.width() - intersectRect.width());
375 374 }
376 375 // Typically the approximated reduction is little low, so add one
377 376 radius -= (reduction + 1.0);
378 377
379 378 if (radius < 1.0) // safeguard
380 379 return 1.0;
381 380 }
382 381 }
383 382 }
384 383
385 384 if (!axis()->titleText().isEmpty() && axis()->isTitleVisible()) {
386 385 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
387 386
388 387 radius -= titlePadding() + (titleRect.height() / 2.0);
389 388 if (radius < 1.0) // safeguard
390 389 return 1.0;
391 390 }
392 391
393 392 return radius;
394 393 }
395 394
396 395 QRectF PolarChartAxisAngular::moveLabelToPosition(qreal angularCoordinate, QPointF labelPoint, QRectF labelRect) const
397 396 {
398 // TODO use fuzzy compare for "==" cases?
399 // TODO Adjust the rect position near 0, 90, 180, and 270 angles for smoother animation?
400 397 if (angularCoordinate == 0.0)
401 398 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
402 399 else if (angularCoordinate < 90.0)
403 400 labelRect.moveBottomLeft(labelPoint);
404 401 else if (angularCoordinate == 90.0)
405 402 labelRect.moveCenter(labelPoint + QPointF(labelRect.width() / 2.0 + 2.0, 0)); // +2 so that it does not hit the radial axis
406 403 else if (angularCoordinate < 180.0)
407 404 labelRect.moveTopLeft(labelPoint);
408 405 else if (angularCoordinate == 180.0)
409 406 labelRect.moveCenter(labelPoint + QPointF(0, labelRect.height() / 2.0));
410 407 else if (angularCoordinate < 270.0)
411 408 labelRect.moveTopRight(labelPoint);
412 409 else if (angularCoordinate == 270.0)
413 410 labelRect.moveCenter(labelPoint + QPointF(-labelRect.width() / 2.0 - 2.0, 0)); // -2 so that it does not hit the radial axis
414 411 else if (angularCoordinate < 360.0)
415 412 labelRect.moveBottomRight(labelPoint);
416 413 else
417 414 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
418 415 return labelRect;
419 416 }
420 417
421 418 #include "moc_polarchartaxisangular_p.cpp"
422 419
423 420 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,1014 +1,1009
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "qabstractaxis.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include "chartdataset_p.h"
24 24 #include "charttheme_p.h"
25 25 #include "qchart_p.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 /*!
30 30 \class QAbstractAxis
31 31 \brief The QAbstractAxis class is used for manipulating chart's axis.
32 32 \mainclass
33 33
34 34 Each series can be bound to one or more horizontal and vertical axes, but mixing axis types
35 35 that would result in different domains is not supported, such as specifying
36 36 QValueAxis and QLogValueAxis on the same orientation.
37 37
38 38 Properties and visibility of various axis elements such as axis line, title, labels, grid lines,
39 39 and shades can be individually controlled.
40 40 */
41 41
42 42 /*!
43 43 \qmlclass AbstractAxis QAbstractAxis
44 44 \brief The AbstractAxis is a base element used for specialized axis elements.
45 45
46 46 Each series can be bound to only one horizontal and vertical axis.
47 47
48 48 Properties and visibility of various axis elements such as axis line, title, labels, grid lines,
49 49 and shades can be individually controlled.
50 50 */
51 51
52 52 /*!
53 53 \enum QAbstractAxis::AxisType
54 54
55 55 The type of the series object.
56 56
57 57 \value AxisTypeNoAxis
58 58 \value AxisTypeValue
59 59 \value AxisTypeBarCategory
60 60 \value AxisTypeCategory
61 61 \value AxisTypeDateTime
62 62 \value AxisTypeLogValue
63 63 */
64 64
65 65 /*!
66 66 *\fn void QAbstractAxis::type() const
67 67 Returns the type of the axis
68 68 */
69 69
70 70 /*!
71 71 \property QAbstractAxis::lineVisible
72 72 The visibility of the axis line
73 73 */
74 74 /*!
75 75 \qmlproperty bool AbstractAxis::lineVisible
76 76 The visibility of the axis line
77 77 */
78 78
79 79 /*!
80 80 \property QAbstractAxis::linePen
81 81 The pen of the line.
82 82 */
83 83
84 84 /*!
85 85 \property QAbstractAxis::labelsVisible
86 86 Defines if axis labels are visible.
87 87 */
88 88 /*!
89 89 \qmlproperty bool AbstractAxis::labelsVisible
90 90 Defines if axis labels are visible.
91 91 */
92 92
93 93 /*!
94 94 \property QAbstractAxis::labelsPen
95 95 \deprecated
96 96 The pen of the labels.
97 97 */
98 98
99 99 /*!
100 100 \property QAbstractAxis::labelsBrush
101 101 The brush of the labels. Only the color of the brush is relevant.
102 102 */
103 103
104 104 /*!
105 105 \property QAbstractAxis::visible
106 106 The visibility of the axis.
107 107 */
108 108 /*!
109 109 \qmlproperty bool AbstractAxis::visible
110 110 The visibility of the axis.
111 111 */
112 112
113 113 /*!
114 114 \property QAbstractAxis::gridVisible
115 115 The visibility of the grid lines.
116 116 */
117 117 /*!
118 118 \qmlproperty bool AbstractAxis::gridVisible
119 119 The visibility of the grid lines.
120 120 */
121 121
122 122 /*!
123 123 \property QAbstractAxis::color
124 124 The color of the axis and ticks.
125 125 */
126 126 /*!
127 127 \qmlproperty color AbstractAxis::color
128 128 The color of the axis and ticks.
129 129 */
130 130
131 131 /*!
132 132 \property QAbstractAxis::gridLinePen
133 133 The pen of the grid line.
134 134 */
135 135
136 136 /*!
137 137 \property QAbstractAxis::labelsFont
138 138 The font of the axis labels.
139 139 */
140 140
141 141 /*!
142 142 \qmlproperty Font AbstractAxis::labelsFont
143 143 The font of the axis labels.
144 144
145 145 See the \l {Font} {QML Font Element} for detailed documentation.
146 146 */
147 147
148 148 /*!
149 149 \property QAbstractAxis::labelsColor
150 150 The color of the axis labels.
151 151 */
152 152 /*!
153 153 \qmlproperty color AbstractAxis::labelsColor
154 154 The color of the axis labels.
155 155 */
156 156
157 157 /*!
158 158 \property QAbstractAxis::labelsAngle
159 159 The angle of the axis labels in degrees.
160 160 */
161 161 /*!
162 162 \qmlproperty int AbstractAxis::labelsAngle
163 163 The angle of the axis labels in degrees.
164 164 */
165 165
166 166 /*!
167 167 \property QAbstractAxis::shadesVisible
168 168 The visibility of the axis shades.
169 169 */
170 170 /*!
171 171 \qmlproperty bool AbstractAxis::shadesVisible
172 172 The visibility of the axis shades.
173 173 */
174 174
175 175 /*!
176 176 \property QAbstractAxis::shadesColor
177 177 The fill (brush) color of the axis shades.
178 178 */
179 179 /*!
180 180 \qmlproperty color AbstractAxis::shadesColor
181 181 The fill (brush) color of the axis shades.
182 182 */
183 183
184 184 /*!
185 185 \property QAbstractAxis::shadesBorderColor
186 186 The border (pen) color of the axis shades.
187 187 */
188 188 /*!
189 189 \qmlproperty color AbstractAxis::shadesBorderColor
190 190 The border (pen) color of the axis shades.
191 191 */
192 192
193 193 /*!
194 194 \property QAbstractAxis::shadesPen
195 195 The pen of the axis shades (area between grid lines).
196 196 */
197 197
198 198 /*!
199 199 \property QAbstractAxis::shadesBrush
200 200 The brush of the axis shades (area between grid lines).
201 201 */
202 202
203 203 /*!
204 204 \property QAbstractAxis::titleVisible
205 205 The visibility of the axis title. By default the value is true.
206 206 */
207 207 /*!
208 208 \qmlproperty bool AbstractAxis::titleVisible
209 209 The visibility of the axis title. By default the value is true.
210 210 */
211 211
212 212 /*!
213 213 \property QAbstractAxis::titleText
214 214 The title of the axis. Empty by default. Axis titles support html formatting.
215 215 */
216 216 /*!
217 217 \qmlproperty String AbstractAxis::titleText
218 218 The title of the axis. Empty by default. Axis titles support html formatting.
219 219 */
220 220
221 221 /*!
222 222 \property QAbstractAxis::titlePen
223 223 \deprecated
224 224 The pen of the title text.
225 225 */
226 226
227 227 /*!
228 228 \property QAbstractAxis::titleBrush
229 229 The brush of the title text. Only the color of the brush is relevant.
230 230 */
231 231
232 232 /*!
233 233 \property QAbstractAxis::titleFont
234 234 The font of the title of the axis.
235 235 */
236 236 /*!
237 237 \qmlproperty Font AbstractAxis::titleFont
238 238 The font of the title of the axis.
239 239 */
240 240
241 241 /*!
242 242 \property QAbstractAxis::orientation
243 243 The orientation of the axis. Fixed to either Qt::Horizontal or Qt::Vertical when you add the axis to a chart.
244 244 */
245 245 /*!
246 246 \qmlproperty Qt.Orientation AbstractAxis::orientation
247 247 The orientation of the axis. Fixed to either Qt.Horizontal or Qt.Vertical when the axis is set to a series.
248 248 */
249 249
250 250 /*!
251 251 \property QAbstractAxis::alignment
252 252 The alignment of the axis. Can be Qt::AlignLeft, Qt::AlignRight, Qt::AlignBottom, or Qt::AlignTop.
253 253 */
254 254 /*!
255 255 \qmlproperty alignment AbstractAxis::alignment
256 256 The alignment of the axis. Can be Qt.AlignLeft, Qt.AlignRight, Qt.AlignBottom, or Qt.AlignTop.
257 257 */
258 258
259 259 /*!
260 260 \fn void QAbstractAxis::visibleChanged(bool visible)
261 261 Visibility of the axis has changed to \a visible.
262 262 */
263 263 /*!
264 264 \qmlsignal AbstractAxis::onVisibleChanged(bool visible)
265 265 Visibility of the axis has changed to \a visible.
266 266 */
267 267
268 268 /*!
269 269 \fn void QAbstractAxis::linePenChanged(const QPen& pen)
270 270 The pen of the line of the axis has changed to \a pen.
271 271 */
272 272
273 273 /*!
274 274 \fn void QAbstractAxis::lineVisibleChanged(bool visible)
275 275 Visibility of the axis line has changed to \a visible.
276 276 */
277 277 /*!
278 278 \qmlsignal AbstractAxis::onLineVisibleChanged(bool visible)
279 279 Visibility of the axis line has changed to \a visible.
280 280 */
281 281
282 282 /*!
283 283 \fn void QAbstractAxis::labelsVisibleChanged(bool visible)
284 284 Visibility of the labels of the axis has changed to \a visible.
285 285 */
286 286 /*!
287 287 \qmlsignal AbstractAxis::onLabelsVisibleChanged(bool visible)
288 288 Visibility of the labels of the axis has changed to \a visible.
289 289 */
290 290
291 291 /*!
292 292 \fn void QAbstractAxis::labelsFontChanged(const QFont& font)
293 293 The font of the axis labels has changed to \a font.
294 294 */
295 295 /*!
296 296 \qmlsignal AbstractAxis::onLabelsFontChanged(Font font)
297 297 The font of the axis labels has changed to \a font.
298 298 */
299 299
300 300 /*!
301 301 \fn void QAbstractAxis::labelsPenChanged(const QPen& pen)
302 302 \deprecated
303 303 The pen of the axis labels has changed to \a pen.
304 304 */
305 305
306 306 /*!
307 307 \fn void QAbstractAxis::labelsBrushChanged(const QBrush& brush)
308 308 The brush of the axis labels has changed to \a brush.
309 309 */
310 310
311 311 /*!
312 312 \fn void QAbstractAxis::labelsAngleChanged(int angle)
313 313 The angle of the axis labels has changed to \a angle.
314 314 */
315 315 /*!
316 316 \qmlsignal AbstractAxis::onLabelsAngleChanged(int angle)
317 317 The angle of the axis labels has changed to \a angle.
318 318 */
319 319
320 320 /*!
321 321 \fn void QAbstractAxis::gridVisibleChanged(bool visible)
322 322 Visibility of the grid lines of the axis has changed to \a visible.
323 323 */
324 324 /*!
325 325 \qmlsignal AbstractAxis::onGridVisibleChanged(bool visible)
326 326 Visibility of the grid lines of the axis has changed to \a visible.
327 327 */
328 328
329 329 /*!
330 330 \fn void QAbstractAxis::gridLinePenChanged(const QPen& pen)
331 331 The pen of the grid line has changed to \a pen.
332 332 */
333 333
334 334 /*!
335 335 \fn void QAbstractAxis::colorChanged(QColor color)
336 336 Emitted if the \a color of the axis is changed.
337 337 */
338 338 /*!
339 339 \qmlsignal AbstractAxis::onColorChanged(QColor color)
340 340 Emitted if the \a color of the axis is changed.
341 341 */
342 342
343 343 /*!
344 344 \fn void QAbstractAxis::labelsColorChanged(QColor color)
345 345 Emitted if the \a color of the axis labels is changed.
346 346 */
347 347 /*!
348 348 \qmlsignal AbstractAxis::onLabelsColorChanged(QColor color)
349 349 Emitted if the \a color of the axis labels is changed.
350 350 */
351 351
352 352 /*!
353 353 \fn void QAbstractAxis::titleVisibleChanged(bool visible)
354 354 Visibility of the title text of the axis has changed to \a visible.
355 355 */
356 356 /*!
357 357 \qmlsignal AbstractAxis::onTitleVisibleChanged(bool visible)
358 358 Visibility of the title text of the axis has changed to \a visible.
359 359 */
360 360
361 361 /*!
362 362 \fn void QAbstractAxis::titleTextChanged(const QString& text)
363 363 The text of the axis title has changed to \a text.
364 364 */
365 365 /*!
366 366 \qmlsignal AbstractAxis::onTitleTextChanged(String text)
367 367 The text of the axis title has changed to \a text.
368 368 */
369 369
370 370 /*!
371 371 \fn void QAbstractAxis::titlePenChanged(const QPen& pen)
372 372 \deprecated
373 373 The pen of the axis shades has changed to \a pen.
374 374 */
375 375
376 376 /*!
377 377 \fn void QAbstractAxis::titleBrushChanged(const QBrush& brush)
378 378 The brush of the axis title has changed to \a brush.
379 379 */
380 380
381 381 /*!
382 382 \fn void QAbstractAxis::titleFontChanged(const QFont& font)
383 383 The font of the axis title has changed to \a font.
384 384 */
385 385 /*!
386 386 \qmlsignal AbstractAxis::onTitleFontChanged(Font font)
387 387 The font of the axis title has changed to \a font.
388 388 */
389 389
390 390 /*!
391 391 \fn void QAbstractAxis::shadesVisibleChanged(bool)
392 392 Emitted if the visibility of the axis shades is changed to \a visible.
393 393 */
394 394 /*!
395 395 \qmlsignal AbstractAxis::onShadesVisibleChanged(bool visible)
396 396 Emitted if the visibility of the axis shades is changed to \a visible.
397 397 */
398 398
399 399 /*!
400 400 \fn void QAbstractAxis::shadesColorChanged(QColor color)
401 401 Emitted if the \a color of the axis shades is changed.
402 402 */
403 403 /*!
404 404 \qmlsignal AbstractAxis::onShadesColorChanged(QColor color)
405 405 Emitted if the \a color of the axis shades is changed.
406 406 */
407 407
408 408 /*!
409 409 \fn void QAbstractAxis::shadesBorderColorChanged(QColor)
410 410 Emitted if the border \a color of the axis shades is changed.
411 411 */
412 412 /*!
413 413 \qmlsignal AbstractAxis::onBorderColorChanged(QColor color)
414 414 Emitted if the border \a color of the axis shades is changed.
415 415 */
416 416
417 417 /*!
418 418 \fn void QAbstractAxis::shadesBrushChanged(const QBrush& brush)
419 419 The brush of the axis shades has changed to \a brush.
420 420 */
421 421
422 422 /*!
423 423 \fn void QAbstractAxis::shadesPenChanged(const QPen& pen)
424 424 The pen of the axis shades has changed to \a pen.
425 425 */
426 426
427 427 /*!
428 428 \internal
429 429 Constructs new axis object which is a child of \a parent. Ownership is taken by
430 430 QChart when axis added.
431 431 */
432 432
433 433 QAbstractAxis::QAbstractAxis(QAbstractAxisPrivate &d, QObject *parent)
434 434 : QObject(parent),
435 435 d_ptr(&d)
436 436 {
437 437 }
438 438
439 439 /*!
440 440 Destructor of the axis object. When axis is added to chart, chart object takes ownership.
441 441 */
442 442
443 443 QAbstractAxis::~QAbstractAxis()
444 444 {
445 445 if (d_ptr->m_chart)
446 446 qFatal("Still binded axis detected !");
447 447 }
448 448
449 449 /*!
450 450 Sets \a pen used to draw axis line and ticks.
451 451 */
452 452 void QAbstractAxis::setLinePen(const QPen &pen)
453 453 {
454 454 if (d_ptr->m_axisPen != pen) {
455 455 d_ptr->m_axisPen = pen;
456 456 emit linePenChanged(pen);
457 457 }
458 458 }
459 459
460 460 /*!
461 461 Returns pen used to draw axis and ticks.
462 462 */
463 463 QPen QAbstractAxis::linePen() const
464 464 {
465 465 if (d_ptr->m_axisPen == QChartPrivate::defaultPen())
466 466 return QPen();
467 467 else
468 468 return d_ptr->m_axisPen;
469 469 }
470 470
471 //TODO: remove me 2.0
472 471 void QAbstractAxis::setLinePenColor(QColor color)
473 472 {
474 473 QPen p = d_ptr->m_axisPen;
475 474 if (p.color() != color) {
476 475 p.setColor(color);
477 476 setLinePen(p);
478 477 emit colorChanged(color);
479 478 }
480 479 }
481 480
482 481 QColor QAbstractAxis::linePenColor() const
483 482 {
484 483 return linePen().color();
485 484 }
486 485
487 486 /*!
488 487 Sets if axis and ticks are \a visible.
489 488 */
490 489 void QAbstractAxis::setLineVisible(bool visible)
491 490 {
492 491 if (d_ptr->m_arrowVisible != visible) {
493 492 d_ptr->m_arrowVisible = visible;
494 493 emit lineVisibleChanged(visible);
495 494 }
496 495 }
497 496
498 497 bool QAbstractAxis::isLineVisible() const
499 498 {
500 499 return d_ptr->m_arrowVisible;
501 500 }
502 501
503 502 void QAbstractAxis::setGridLineVisible(bool visible)
504 503 {
505 504 if (d_ptr->m_gridLineVisible != visible) {
506 505 d_ptr->m_gridLineVisible = visible;
507 506 emit gridVisibleChanged(visible);
508 507 }
509 508 }
510 509
511 510 bool QAbstractAxis::isGridLineVisible() const
512 511 {
513 512 return d_ptr->m_gridLineVisible;
514 513 }
515 514
516 515 /*!
517 516 Sets \a pen used to draw grid line.
518 517 */
519 518 void QAbstractAxis::setGridLinePen(const QPen &pen)
520 519 {
521 520 if (d_ptr->m_gridLinePen != pen) {
522 521 d_ptr->m_gridLinePen = pen;
523 522 emit gridLinePenChanged(pen);
524 523 }
525 524 }
526 525
527 526 /*!
528 527 Returns pen used to draw grid.
529 528 */
530 529 QPen QAbstractAxis::gridLinePen() const
531 530 {
532 531 if (d_ptr->m_gridLinePen == QChartPrivate::defaultPen())
533 532 return QPen();
534 533 else
535 534 return d_ptr->m_gridLinePen;
536 535 }
537 536
538 537 void QAbstractAxis::setLabelsVisible(bool visible)
539 538 {
540 539 if (d_ptr->m_labelsVisible != visible) {
541 540 d_ptr->m_labelsVisible = visible;
542 541 emit labelsVisibleChanged(visible);
543 542 }
544 543 }
545 544
546 545 bool QAbstractAxis::labelsVisible() const
547 546 {
548 547 return d_ptr->m_labelsVisible;
549 548 }
550 549
551 550 void QAbstractAxis::setLabelsPen(const QPen &pen)
552 551 {
553 552 if (d_ptr->m_labelsPen != pen) {
554 553 d_ptr->m_labelsPen = pen;
555 554 emit labelsPenChanged(pen);
556 555 }
557 556 }
558 557
559 558 QPen QAbstractAxis::labelsPen() const
560 559 {
561 560 if (d_ptr->m_labelsPen == QChartPrivate::defaultPen())
562 561 return QPen();
563 562 else
564 563 return d_ptr->m_labelsPen;
565 564 }
566 565
567 566 /*!
568 567 Sets \a brush used to draw labels.
569 568 */
570 569 void QAbstractAxis::setLabelsBrush(const QBrush &brush)
571 570 {
572 571 if (d_ptr->m_labelsBrush != brush) {
573 572 d_ptr->m_labelsBrush = brush;
574 573 emit labelsBrushChanged(brush);
575 574 }
576 575 }
577 576
578 577 /*!
579 578 Returns brush used to draw labels.
580 579 */
581 580 QBrush QAbstractAxis::labelsBrush() const
582 581 {
583 582 if (d_ptr->m_labelsBrush == QChartPrivate::defaultBrush())
584 583 return QBrush();
585 584 else
586 585 return d_ptr->m_labelsBrush;
587 586 }
588 587
589 588 /*!
590 589 Sets \a font used to draw labels.
591 590 */
592 591 void QAbstractAxis::setLabelsFont(const QFont &font)
593 592 {
594 593 if (d_ptr->m_labelsFont != font) {
595 594 d_ptr->m_labelsFont = font;
596 595 emit labelsFontChanged(font);
597 596 }
598 597 }
599 598
600 599 /*!
601 600 Returns font used to draw labels.
602 601 */
603 602 QFont QAbstractAxis::labelsFont() const
604 603 {
605 604 if (d_ptr->m_labelsFont == QChartPrivate::defaultFont())
606 605 return QFont();
607 606 else
608 607 return d_ptr->m_labelsFont;
609 608 }
610 609
611 610 void QAbstractAxis::setLabelsAngle(int angle)
612 611 {
613 612 if (d_ptr->m_labelsAngle != angle) {
614 613 d_ptr->m_labelsAngle = angle;
615 614 emit labelsAngleChanged(angle);
616 615 }
617 616 }
618 617
619 618 int QAbstractAxis::labelsAngle() const
620 619 {
621 620 return d_ptr->m_labelsAngle;
622 621 }
623 //TODO: remove me 2.0
624 622 void QAbstractAxis::setLabelsColor(QColor color)
625 623 {
626 624 QBrush b = d_ptr->m_labelsBrush;
627 625 if (b.color() != color) {
628 626 b.setColor(color);
629 627 setLabelsBrush(b);
630 628 emit labelsColorChanged(color);
631 629 }
632 630 }
633 631
634 632 QColor QAbstractAxis::labelsColor() const
635 633 {
636 634 return labelsBrush().color();
637 635 }
638 636
639 637 void QAbstractAxis::setTitleVisible(bool visible)
640 638 {
641 639 if (d_ptr->m_titleVisible != visible) {
642 640 d_ptr->m_titleVisible = visible;
643 641 emit titleVisibleChanged(visible);
644 642 }
645 643 }
646 644
647 645 bool QAbstractAxis::isTitleVisible() const
648 646 {
649 647 return d_ptr->m_titleVisible;
650 648 }
651 649
652 650 void QAbstractAxis::setTitlePen(const QPen &pen)
653 651 {
654 652 if (d_ptr->m_titlePen != pen) {
655 653 d_ptr->m_titlePen = pen;
656 654 emit titlePenChanged(pen);
657 655 }
658 656 }
659 657
660 658 QPen QAbstractAxis::titlePen() const
661 659 {
662 660 if (d_ptr->m_titlePen == QChartPrivate::defaultPen())
663 661 return QPen();
664 662 else
665 663 return d_ptr->m_titlePen;
666 664 }
667 665
668 666 /*!
669 667 Sets \a brush used to draw title.
670 668 */
671 669 void QAbstractAxis::setTitleBrush(const QBrush &brush)
672 670 {
673 671 if (d_ptr->m_titleBrush != brush) {
674 672 d_ptr->m_titleBrush = brush;
675 673 emit titleBrushChanged(brush);
676 674 }
677 675 }
678 676
679 677 /*!
680 678 Returns brush used to draw title.
681 679 */
682 680 QBrush QAbstractAxis::titleBrush() const
683 681 {
684 682 if (d_ptr->m_titleBrush == QChartPrivate::defaultBrush())
685 683 return QBrush();
686 684 else
687 685 return d_ptr->m_titleBrush;
688 686 }
689 687
690 688 /*!
691 689 Sets \a font used to draw title.
692 690 */
693 691 void QAbstractAxis::setTitleFont(const QFont &font)
694 692 {
695 693 if (d_ptr->m_titleFont != font) {
696 694 d_ptr->m_titleFont = font;
697 695 emit titleFontChanged(font);
698 696 }
699 697 }
700 698
701 699 /*!
702 700 Returns font used to draw title.
703 701 */
704 702 QFont QAbstractAxis::titleFont() const
705 703 {
706 704 if (d_ptr->m_titleFont == QChartPrivate::defaultFont())
707 705 return QFont();
708 706 else
709 707 return d_ptr->m_titleFont;
710 708 }
711 709
712 710 void QAbstractAxis::setTitleText(const QString &title)
713 711 {
714 712 if (d_ptr->m_title != title) {
715 713 d_ptr->m_title = title;
716 714 emit titleTextChanged(title);
717 715 }
718 716 }
719 717
720 718 QString QAbstractAxis::titleText() const
721 719 {
722 720 return d_ptr->m_title;
723 721 }
724 722
725 723
726 724 void QAbstractAxis::setShadesVisible(bool visible)
727 725 {
728 726 if (d_ptr->m_shadesVisible != visible) {
729 727 d_ptr->m_shadesVisible = visible;
730 728 emit shadesVisibleChanged(visible);
731 729 }
732 730 }
733 731
734 732 bool QAbstractAxis::shadesVisible() const
735 733 {
736 734 return d_ptr->m_shadesVisible;
737 735 }
738 736
739 737 /*!
740 738 Sets \a pen used to draw shades.
741 739 */
742 740 void QAbstractAxis::setShadesPen(const QPen &pen)
743 741 {
744 742 if (d_ptr->m_shadesPen != pen) {
745 743 d_ptr->m_shadesPen = pen;
746 744 emit shadesPenChanged(pen);
747 745 }
748 746 }
749 747
750 748 /*!
751 749 Returns pen used to draw shades.
752 750 */
753 751 QPen QAbstractAxis::shadesPen() const
754 752 {
755 753 if (d_ptr->m_shadesPen == QChartPrivate::defaultPen())
756 754 return QPen();
757 755 else
758 756 return d_ptr->m_shadesPen;
759 757 }
760 758
761 759 /*!
762 760 Sets \a brush used to draw shades.
763 761 */
764 762 void QAbstractAxis::setShadesBrush(const QBrush &brush)
765 763 {
766 764 if (d_ptr->m_shadesBrush != brush) {
767 765 d_ptr->m_shadesBrush = brush;
768 766 emit shadesBrushChanged(brush);
769 767 }
770 768 }
771 769
772 770 /*!
773 771 Returns brush used to draw shades.
774 772 */
775 773 QBrush QAbstractAxis::shadesBrush() const
776 774 {
777 775 if (d_ptr->m_shadesBrush == QChartPrivate::defaultBrush())
778 776 return QBrush(Qt::SolidPattern);
779 777 else
780 778 return d_ptr->m_shadesBrush;
781 779 }
782 780
783 781 void QAbstractAxis::setShadesColor(QColor color)
784 782 {
785 783 QBrush b = d_ptr->m_shadesBrush;
786 784 if (b.color() != color) {
787 785 b.setColor(color);
788 786 setShadesBrush(b);
789 787 emit shadesColorChanged(color);
790 788 }
791 789 }
792 790
793 791 QColor QAbstractAxis::shadesColor() const
794 792 {
795 793 return shadesBrush().color();
796 794 }
797 795
798 796 void QAbstractAxis::setShadesBorderColor(QColor color)
799 797 {
800 798 QPen p = d_ptr->m_shadesPen;
801 799 if (p.color() != color) {
802 800 p.setColor(color);
803 801 setShadesPen(p);
804 802 emit shadesColorChanged(color);
805 803 }
806 804 }
807 805
808 806 QColor QAbstractAxis::shadesBorderColor() const
809 807 {
810 808 return shadesPen().color();
811 809 }
812 810
813 811
814 812 bool QAbstractAxis::isVisible() const
815 813 {
816 814 return d_ptr->m_visible;
817 815 }
818 816
819 817 /*!
820 818 Sets axis, shades, labels and grid lines to be visible.
821 819 */
822 820 void QAbstractAxis::setVisible(bool visible)
823 821 {
824 822 if (d_ptr->m_visible != visible) {
825 823 d_ptr->m_visible = visible;
826 824 emit visibleChanged(visible);
827 825 }
828 826 }
829 827
830 828
831 829 /*!
832 830 Sets axis, shades, labels and grid lines to be visible.
833 831 */
834 832 void QAbstractAxis::show()
835 833 {
836 834 setVisible(true);
837 835 }
838 836
839 837 /*!
840 838 Sets axis, shades, labels and grid lines to not be visible.
841 839 */
842 840 void QAbstractAxis::hide()
843 841 {
844 842 setVisible(false);
845 843 }
846 844
847 845 /*!
848 846 Sets the minimum value shown on the axis.
849 847 Depending on the actual axis type the \a min parameter is converted to appropriate type.
850 848 If the conversion is impossible then the function call does nothing
851 849 */
852 850 void QAbstractAxis::setMin(const QVariant &min)
853 851 {
854 852 d_ptr->setMin(min);
855 853 }
856 854
857 855 /*!
858 856 Sets the maximum value shown on the axis.
859 857 Depending on the actual axis type the \a max parameter is converted to appropriate type.
860 858 If the conversion is impossible then the function call does nothing
861 859 */
862 860 void QAbstractAxis::setMax(const QVariant &max)
863 861 {
864 862 d_ptr->setMax(max);
865 863 }
866 864
867 865 /*!
868 866 Sets the range shown on the axis.
869 867 Depending on the actual axis type the \a min and \a max parameters are converted to appropriate types.
870 868 If the conversion is impossible then the function call does nothing.
871 869 */
872 870 void QAbstractAxis::setRange(const QVariant &min, const QVariant &max)
873 871 {
874 872 d_ptr->setRange(min, max);
875 873 }
876 874
877 875
878 876 /*!
879 877 Returns the orientation in which the axis is being used (Vertical or Horizontal)
880 878 */
881 // NOTE: should have const but it breaks BC:
882 // http://techbase.kde.org/Policies/Binary_Compatibility_Examples#Change_the_CV-qualifiers_of_a_member_function
883 879 Qt::Orientation QAbstractAxis::orientation()
884 880 {
885 881 return d_ptr->orientation();
886 882 }
887 883
888 884 Qt::Alignment QAbstractAxis::alignment() const
889 885 {
890 886 return d_ptr->alignment();
891 887 }
892 888
893 889 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
894 890
895 891 QAbstractAxisPrivate::QAbstractAxisPrivate(QAbstractAxis *q)
896 892 : q_ptr(q),
897 893 m_chart(0),
898 894 m_alignment(0),
899 895 m_orientation(Qt::Orientation(0)),
900 896 m_visible(true),
901 897 m_arrowVisible(true),
902 898 m_axisPen(QChartPrivate::defaultPen()),
903 899 m_axisBrush(QChartPrivate::defaultBrush()),
904 900 m_gridLineVisible(true),
905 901 m_gridLinePen(QChartPrivate::defaultPen()),
906 902 m_labelsVisible(true),
907 903 m_labelsPen(QChartPrivate::defaultPen()),
908 904 m_labelsBrush(QChartPrivate::defaultBrush()),
909 905 m_labelsFont(QChartPrivate::defaultFont()),
910 906 m_labelsAngle(0),
911 907 m_titleVisible(true),
912 908 m_titlePen(QChartPrivate::defaultPen()),
913 909 m_titleBrush(QChartPrivate::defaultBrush()),
914 910 m_titleFont(QChartPrivate::defaultFont()),
915 911 m_shadesVisible(false),
916 912 m_shadesPen(QChartPrivate::defaultPen()),
917 913 m_shadesBrush(QChartPrivate::defaultBrush()),
918 914 m_shadesOpacity(1.0),
919 915 m_dirty(false)
920 916 {
921 917 }
922 918
923 919 QAbstractAxisPrivate::~QAbstractAxisPrivate()
924 920 {
925 921 }
926 922
927 923 void QAbstractAxisPrivate::setAlignment( Qt::Alignment alignment)
928 924 {
929 925 switch(alignment) {
930 926 case Qt::AlignTop:
931 927 case Qt::AlignBottom:
932 928 m_orientation = Qt::Horizontal;
933 929 break;
934 930 case Qt::AlignLeft:
935 931 case Qt::AlignRight:
936 932 m_orientation = Qt::Vertical;
937 933 break;
938 934 default:
939 935 qWarning()<<"No alignment specified !";
940 936 break;
941 937 };
942 938 m_alignment=alignment;
943 939 }
944 940
945 941 void QAbstractAxisPrivate::initializeTheme(ChartTheme* theme, bool forced)
946 942 {
947 //TODO: introduce axis brush
948 943 if (forced || QChartPrivate::defaultPen() == m_axisPen)
949 944 q_ptr->setLinePen(theme->axisLinePen());
950 945
951 946 if (forced || QChartPrivate::defaultPen() == m_gridLinePen)
952 947 q_ptr->setGridLinePen(theme->girdLinePen());
953 948
954 949 if (forced || QChartPrivate::defaultBrush() == m_labelsBrush)
955 950 q_ptr->setLabelsBrush(theme->labelBrush());
956 951 if (forced || QChartPrivate::defaultPen() == m_labelsPen)
957 952 q_ptr->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
958 953 if (forced || QChartPrivate::defaultFont() == m_labelsFont)
959 954 q_ptr->setLabelsFont(theme->labelFont());
960 955
961 956 if (forced || QChartPrivate::defaultBrush() == m_titleBrush)
962 957 q_ptr->setTitleBrush(theme->labelBrush());
963 958 if (forced || QChartPrivate::defaultPen() == m_titlePen)
964 959 q_ptr->setTitlePen(Qt::NoPen); // NoPen for performance reasons
965 960 if (forced || QChartPrivate::defaultFont() == m_titleFont) {
966 961 QFont font(m_labelsFont);
967 962 font.setBold(true);
968 963 q_ptr->setTitleFont(font);
969 964 }
970 965
971 966 if (forced || QChartPrivate::defaultBrush() == m_shadesBrush)
972 967 q_ptr->setShadesBrush(theme->backgroundShadesBrush());
973 968 if (forced || QChartPrivate::defaultPen() == m_shadesPen)
974 969 q_ptr->setShadesPen(theme->backgroundShadesPen());
975 970
976 971 bool axisX = m_orientation == Qt::Horizontal;
977 972 if (forced && (theme->backgroundShades() == ChartTheme::BackgroundShadesBoth
978 973 || (theme->backgroundShades() == ChartTheme::BackgroundShadesVertical && axisX)
979 974 || (theme->backgroundShades() == ChartTheme::BackgroundShadesHorizontal && !axisX))) {
980 975 q_ptr->setShadesVisible(true);
981 976 } else if (forced) {
982 977 q_ptr->setShadesVisible(false);
983 978 }
984 979 }
985 980
986 981 void QAbstractAxisPrivate::handleRangeChanged(qreal min, qreal max)
987 982 {
988 983 setRange(min,max);
989 984 }
990 985
991 986 void QAbstractAxisPrivate::initializeGraphics(QGraphicsItem* parent)
992 987 {
993 988 Q_UNUSED(parent);
994 989 }
995 990
996 991 void QAbstractAxisPrivate::initializeAnimations(QChart::AnimationOptions options)
997 992 {
998 993 ChartAxisElement *axis = m_item.data();
999 994 Q_ASSERT(axis);
1000 995 if (axis->animation())
1001 996 axis->animation()->stopAndDestroyLater();
1002 997
1003 998 if (options.testFlag(QChart::GridAxisAnimations))
1004 999 axis->setAnimation(new AxisAnimation(axis));
1005 1000 else
1006 1001 axis->setAnimation(0);
1007 1002 }
1008 1003
1009 1004
1010 1005
1011 1006 #include "moc_qabstractaxis.cpp"
1012 1007 #include "moc_qabstractaxis_p.cpp"
1013 1008
1014 1009 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,193 +1,193
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QABSTRACTAXIS_H
22 22 #define QABSTRACTAXIS_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <QPen>
26 26 #include <QFont>
27 27 #include <QVariant>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 class QAbstractAxisPrivate;
32 32
33 33 class QTCOMMERCIALCHART_EXPORT QAbstractAxis : public QObject
34 34 {
35 35 Q_OBJECT
36 36 //visibility
37 37 Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
38 38 //arrow
39 39 Q_PROPERTY(bool lineVisible READ isLineVisible WRITE setLineVisible NOTIFY lineVisibleChanged)
40 40 Q_PROPERTY(QPen linePen READ linePen WRITE setLinePen NOTIFY linePenChanged)
41 41 Q_PROPERTY(QColor color READ linePenColor WRITE setLinePenColor NOTIFY colorChanged)
42 42 //labels
43 43 Q_PROPERTY(bool labelsVisible READ labelsVisible WRITE setLabelsVisible NOTIFY labelsVisibleChanged)
44 44 Q_PROPERTY(QPen labelsPen READ labelsPen WRITE setLabelsPen NOTIFY labelsPenChanged)
45 45 Q_PROPERTY(QBrush labelsBrush READ labelsBrush WRITE setLabelsBrush NOTIFY labelsBrushChanged)
46 46 Q_PROPERTY(int labelsAngle READ labelsAngle WRITE setLabelsAngle NOTIFY labelsAngleChanged)
47 47 Q_PROPERTY(QFont labelsFont READ labelsFont WRITE setLabelsFont NOTIFY labelsFontChanged)
48 48 Q_PROPERTY(QColor labelsColor READ labelsColor WRITE setLabelsColor NOTIFY labelsColorChanged)
49 49 //grid
50 50 Q_PROPERTY(bool gridVisible READ isGridLineVisible WRITE setGridLineVisible NOTIFY gridVisibleChanged)
51 51 Q_PROPERTY(QPen gridLinePen READ gridLinePen WRITE setGridLinePen NOTIFY gridLinePenChanged)
52 52 //shades
53 53 Q_PROPERTY(bool shadesVisible READ shadesVisible WRITE setShadesVisible NOTIFY shadesVisibleChanged)
54 54 Q_PROPERTY(QColor shadesColor READ shadesColor WRITE setShadesColor NOTIFY shadesColorChanged)
55 55 Q_PROPERTY(QColor shadesBorderColor READ shadesBorderColor WRITE setShadesBorderColor NOTIFY shadesBorderColorChanged)
56 56 Q_PROPERTY(QPen shadesPen READ shadesPen WRITE setShadesPen NOTIFY shadesPenChanged)
57 57 Q_PROPERTY(QBrush shadesBrush READ shadesBrush WRITE setShadesBrush NOTIFY shadesBrushChanged)
58 58 //title
59 59 Q_PROPERTY(QString titleText READ titleText WRITE setTitleText NOTIFY titleTextChanged)
60 60 Q_PROPERTY(QPen titlePen READ titlePen WRITE setTitlePen NOTIFY titlePenChanged)
61 61 Q_PROPERTY(QBrush titleBrush READ titleBrush WRITE setTitleBrush NOTIFY titleBrushChanged)
62 62 Q_PROPERTY(bool titleVisible READ isTitleVisible WRITE setTitleVisible NOTIFY titleVisibleChanged)
63 63 Q_PROPERTY(QFont titleFont READ titleFont WRITE setTitleFont NOTIFY titleFontChanged)
64 64 //orientation
65 65 Q_PROPERTY(Qt::Orientation orientation READ orientation)
66 66 //aligment
67 67 Q_PROPERTY(Qt::Alignment alignment READ alignment)
68 68
69 69 public:
70 70
71 71 enum AxisType {
72 72 AxisTypeNoAxis = 0x0,
73 73 AxisTypeValue = 0x1,
74 74 AxisTypeBarCategory = 0x2,
75 75 AxisTypeCategory = 0x3,
76 76 AxisTypeDateTime = 0x4,
77 77 AxisTypeLogValue = 0x5
78 78 };
79 79
80 80 Q_DECLARE_FLAGS(AxisTypes, AxisType)
81 81
82 82 protected:
83 83 explicit QAbstractAxis(QAbstractAxisPrivate &d, QObject *parent = 0);
84 84
85 85 public:
86 86 ~QAbstractAxis();
87 87
88 88 virtual AxisType type() const = 0;
89 89
90 90 //visibility handling
91 91 bool isVisible() const;
92 92 void setVisible(bool visible = true);
93 93 void show();
94 94 void hide();
95 95
96 96 //arrow handling
97 97 bool isLineVisible() const;
98 98 void setLineVisible(bool visible = true);
99 99 void setLinePen(const QPen &pen);
100 100 QPen linePen() const;
101 101 void setLinePenColor(QColor color);
102 102 QColor linePenColor() const;
103 103
104 104 //grid handling
105 105 bool isGridLineVisible() const;
106 106 void setGridLineVisible(bool visible = true);
107 107 void setGridLinePen(const QPen &pen);
108 108 QPen gridLinePen() const;
109 109
110 110 //labels handling
111 111 bool labelsVisible() const;
112 112 void setLabelsVisible(bool visible = true);
113 113 void setLabelsPen(const QPen &pen);
114 114 QPen labelsPen() const;
115 115 void setLabelsBrush(const QBrush &brush);
116 116 QBrush labelsBrush() const;
117 117 void setLabelsFont(const QFont &font);
118 118 QFont labelsFont() const;
119 119 void setLabelsAngle(int angle);
120 120 int labelsAngle() const;
121 121 void setLabelsColor(QColor color);
122 122 QColor labelsColor() const;
123 123
124 124 //title handling
125 125 bool isTitleVisible() const;
126 126 void setTitleVisible(bool visible = true);
127 127 void setTitlePen(const QPen &pen);
128 128 QPen titlePen() const;
129 129 void setTitleBrush(const QBrush &brush);
130 130 QBrush titleBrush() const;
131 131 void setTitleFont(const QFont &font);
132 132 QFont titleFont() const;
133 133 void setTitleText(const QString &title);
134 134 QString titleText() const;
135 135
136 136 //shades handling
137 137 bool shadesVisible() const;
138 138 void setShadesVisible(bool visible = true);
139 139 void setShadesPen(const QPen &pen);
140 140 QPen shadesPen() const;
141 141 void setShadesBrush(const QBrush &brush);
142 142 QBrush shadesBrush() const;
143 143 void setShadesColor(QColor color);
144 144 QColor shadesColor() const;
145 145 void setShadesBorderColor(QColor color);
146 146 QColor shadesBorderColor() const;
147 147
148 Qt::Orientation orientation(); //TODO: missing const <- BC (2.0)
148 Qt::Orientation orientation();
149 149 Qt::Alignment alignment() const;
150 150
151 151 //range handling
152 152 void setMin(const QVariant &min);
153 153 void setMax(const QVariant &max);
154 154 void setRange(const QVariant &min, const QVariant &max);
155 155
156 156 Q_SIGNALS:
157 157 void visibleChanged(bool visible);
158 158 void linePenChanged(const QPen &pen);
159 159 void lineVisibleChanged(bool visible);
160 160 void labelsVisibleChanged(bool visible);
161 161 void labelsPenChanged(const QPen &pen);
162 162 void labelsBrushChanged(const QBrush &brush);
163 163 void labelsFontChanged(const QFont &pen);
164 164 void labelsAngleChanged(int angle);
165 165 void gridLinePenChanged(const QPen &pen);
166 166 void gridVisibleChanged(bool visible);
167 167 void colorChanged(QColor color);
168 168 void labelsColorChanged(QColor color);
169 169 void titleTextChanged(const QString &title);
170 170 void titlePenChanged(const QPen &pen);
171 171 void titleBrushChanged(const QBrush &brush);
172 172 void titleVisibleChanged(bool visible);
173 173 void titleFontChanged(const QFont &font);
174 174 void shadesVisibleChanged(bool visible);
175 175 void shadesColorChanged(QColor color);
176 176 void shadesBorderColorChanged(QColor color);
177 177 void shadesPenChanged(const QPen &pen);
178 178 void shadesBrushChanged(const QBrush &brush);
179 179
180 180 protected:
181 181 QScopedPointer<QAbstractAxisPrivate> d_ptr;
182 182 Q_DISABLE_COPY(QAbstractAxis)
183 183 friend class ChartDataSet;
184 184 friend class ChartPresenter;
185 185 friend class ChartThemeManager;
186 186 friend class AbstractDomain;
187 187 friend class ChartAxisElement;
188 188 friend class XYChart;
189 189 };
190 190
191 191 QTCOMMERCIALCHART_END_NAMESPACE
192 192
193 193 #endif // QABSTRACTAXIS_H
@@ -1,84 +1,83
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef QVALUEAXIS_H
22 22 #define QVALUEAXIS_H
23 23
24 24 #include "qabstractaxis.h"
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 class QValueAxisPrivate;
29 29
30 30 class QTCOMMERCIALCHART_EXPORT QValueAxis : public QAbstractAxis
31 31 {
32 32 Q_OBJECT
33 33 Q_PROPERTY(int tickCount READ tickCount WRITE setTickCount NOTIFY tickCountChanged)
34 34 Q_PROPERTY(bool niceNumbersEnabled READ niceNumbersEnabled WRITE setNiceNumbersEnabled)
35 35 Q_PROPERTY(qreal min READ min WRITE setMin NOTIFY minChanged)
36 36 Q_PROPERTY(qreal max READ max WRITE setMax NOTIFY maxChanged)
37 37 Q_PROPERTY(QString labelFormat READ labelFormat WRITE setLabelFormat NOTIFY labelFormatChanged)
38 38
39 39 public:
40 40 explicit QValueAxis(QObject *parent = 0);
41 41 ~QValueAxis();
42 42
43 43 protected:
44 44 QValueAxis(QValueAxisPrivate &d, QObject *parent = 0);
45 45
46 46 public:
47 47 AxisType type() const;
48 48
49 49 //range handling
50 50 void setMin(qreal min);
51 51 qreal min() const;
52 52 void setMax(qreal max);
53 53 qreal max() const;
54 54 void setRange(qreal min, qreal max);
55 55
56 56 //ticks handling
57 57 void setTickCount(int count);
58 58 int tickCount() const;
59 59
60 60 void setLabelFormat(const QString &format);
61 61 QString labelFormat() const;
62 62
63 //TODO: deprecated! (2.0)
64 63 void setNiceNumbersEnabled(bool enable = true);
65 64 bool niceNumbersEnabled() const;
66 65
67 66 public Q_SLOTS:
68 67 void applyNiceNumbers();
69 68
70 69 Q_SIGNALS:
71 70 void minChanged(qreal min);
72 71 void maxChanged(qreal max);
73 72 void rangeChanged(qreal min, qreal max);
74 73 void tickCountChanged(int tickCount);
75 74 void labelFormatChanged(const QString &format);
76 75
77 76 private:
78 77 Q_DECLARE_PRIVATE(QValueAxis)
79 78 Q_DISABLE_COPY(QValueAxis)
80 79 };
81 80
82 81 QTCOMMERCIALCHART_END_NAMESPACE
83 82
84 83 #endif // QVALUEAXIS_H
@@ -1,70 +1,70
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QVALUEAXIS_P_H
31 31 #define QVALUEAXIS_P_H
32 32
33 33 #include "qvalueaxis.h"
34 34 #include "qabstractaxis_p.h"
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 class QValueAxisPrivate : public QAbstractAxisPrivate
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 QValueAxisPrivate(QValueAxis *q);
43 43 ~QValueAxisPrivate();
44 44
45 45 public:
46 46 void initializeGraphics(QGraphicsItem* parent);
47 47 void initializeDomain(AbstractDomain *domain);
48 48
49 49 qreal min() { return m_min; };
50 50 qreal max() { return m_max; };
51 51 void setRange(qreal min,qreal max);
52 52
53 53 protected:
54 54 void setMin(const QVariant &min);
55 55 void setMax(const QVariant &max);
56 56 void setRange(const QVariant &min, const QVariant &max);
57 57
58 58 private:
59 59 qreal m_min;
60 60 qreal m_max;
61 61 int m_tickCount;
62 62 QString m_format;
63 63 bool m_applying;
64 bool m_niceNumbersEnabled; //TODO: this deprecated (2.0)
64 bool m_niceNumbersEnabled;
65 65 Q_DECLARE_PUBLIC(QValueAxis)
66 66 };
67 67
68 68 QTCOMMERCIALCHART_END_NAMESPACE
69 69
70 70 #endif // QVALUEAXIS_P_H
@@ -1,180 +1,179
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTPRESENTER_H
31 31 #define CHARTPRESENTER_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "qchart.h" //because of QChart::ChartThemeId
35 35 #include <QRectF>
36 36 #include <QMargins>
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 class ChartItem;
41 41 class AxisItem;
42 42 class QAbstractSeries;
43 43 class ChartDataSet;
44 44 class AbstractDomain;
45 45 class ChartAxisElement;
46 46 class ChartAnimator;
47 47 class ChartBackground;
48 48 class ChartTitle;
49 49 class ChartAnimation;
50 50 class AbstractChartLayout;
51 51
52 52 class ChartPresenter: public QObject
53 53 {
54 54 Q_OBJECT
55 55 public:
56 56 enum ZValues {
57 57 BackgroundZValue = -1,
58 58 PlotAreaZValue,
59 59 ShadesZValue,
60 60 GridZValue,
61 61 AxisZValue,
62 62 SeriesZValue,
63 63 LineChartZValue = SeriesZValue,
64 64 SplineChartZValue = SeriesZValue,
65 65 BarSeriesZValue = SeriesZValue,
66 66 ScatterSeriesZValue = SeriesZValue,
67 67 PieSeriesZValue = SeriesZValue,
68 68 BoxPlotSeriesZValue = SeriesZValue,
69 69 LegendZValue,
70 70 TopMostZValue
71 71 };
72 72
73 73 enum State {
74 74 ShowState,
75 75 ScrollUpState,
76 76 ScrollDownState,
77 77 ScrollLeftState,
78 78 ScrollRightState,
79 79 ZoomInState,
80 80 ZoomOutState
81 81 };
82 82
83 83 ChartPresenter(QChart *chart, QChart::ChartType type);
84 84 virtual ~ChartPresenter();
85 85
86 86
87 87 void setGeometry(QRectF rect);
88 88 QRectF geometry() const;
89 89
90 90 QGraphicsItem *rootItem(){ return m_chart; }
91 91 ChartBackground *backgroundElement();
92 92 QAbstractGraphicsShapeItem *plotAreaElement();
93 93 ChartTitle *titleElement();
94 94 QList<ChartAxisElement *> axisItems() const;
95 95 QList<ChartItem *> chartItems() const;
96 96
97 97 QLegend *legend();
98 98
99 99 void setBackgroundBrush(const QBrush &brush);
100 100 QBrush backgroundBrush() const;
101 101
102 102 void setBackgroundPen(const QPen &pen);
103 103 QPen backgroundPen() const;
104 104
105 105 void setBackgroundRoundness(qreal diameter);
106 106 qreal backgroundRoundness() const;
107 107
108 108 void setPlotAreaBackgroundBrush(const QBrush &brush);
109 109 QBrush plotAreaBackgroundBrush() const;
110 110
111 111 void setPlotAreaBackgroundPen(const QPen &pen);
112 112 QPen plotAreaBackgroundPen() const;
113 113
114 114 void setTitle(const QString &title);
115 115 QString title() const;
116 116
117 117 void setTitleFont(const QFont &font);
118 118 QFont titleFont() const;
119 119
120 120 void setTitleBrush(const QBrush &brush);
121 121 QBrush titleBrush() const;
122 122
123 123 void setBackgroundVisible(bool visible);
124 124 bool isBackgroundVisible() const;
125 125
126 126 void setPlotAreaBackgroundVisible(bool visible);
127 127 bool isPlotAreaBackgroundVisible() const;
128 128
129 129 void setBackgroundDropShadowEnabled(bool enabled);
130 130 bool isBackgroundDropShadowEnabled() const;
131 131
132 132 void setVisible(bool visible);
133 133
134 134 void setAnimationOptions(QChart::AnimationOptions options);
135 135 QChart::AnimationOptions animationOptions() const;
136 136
137 137 void startAnimation(ChartAnimation *animation);
138 138
139 //TODO refactor
140 139 void setState(State state,QPointF point);
141 140 State state() const { return m_state; }
142 141 QPointF statePoint() const { return m_statePoint; }
143 142 AbstractChartLayout *layout();
144 143
145 144 QChart::ChartType chartType() const { return m_chart->chartType(); }
146 145 QChart *chart() { return m_chart; }
147 146
148 147 static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0);
149 148 static QString truncatedText(const QFont &font, const QString &text, qreal angle, qreal maxSize,
150 149 Qt::Orientation constraintOrientation, QRectF &boundingRect);
151 150 private:
152 151 void createBackgroundItem();
153 152 void createPlotAreaBackgroundItem();
154 153 void createTitleItem();
155 154
156 155 public Q_SLOTS:
157 156 void handleSeriesAdded(QAbstractSeries *series);
158 157 void handleSeriesRemoved(QAbstractSeries *series);
159 158 void handleAxisAdded(QAbstractAxis *axis);
160 159 void handleAxisRemoved(QAbstractAxis *axis);
161 160
162 161 private:
163 162 QChart *m_chart;
164 163 QList<ChartItem *> m_chartItems;
165 164 QList<ChartAxisElement *> m_axisItems;
166 165 QList<QAbstractSeries *> m_series;
167 166 QList<QAbstractAxis *> m_axes;
168 167 QChart::AnimationOptions m_options;
169 168 State m_state;
170 169 QPointF m_statePoint;
171 170 AbstractChartLayout *m_layout;
172 171 ChartBackground *m_background;
173 172 QAbstractGraphicsShapeItem *m_plotAreaBackground;
174 173 ChartTitle *m_title;
175 174 QRectF m_rect;
176 175 };
177 176
178 177 QTCOMMERCIALCHART_END_NAMESPACE
179 178
180 179 #endif /* CHARTPRESENTER_H */
@@ -1,248 +1,245
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 #include "qabstractseries_p.h"
21 21 #include "qabstractaxis_p.h"
22 22 #include <QTime>
23 23 //themes
24 24 #include "chartthemesystem_p.h"
25 25 #include "chartthemelight_p.h"
26 26 #include "chartthemebluecerulean_p.h"
27 27 #include "chartthemedark_p.h"
28 28 #include "chartthemebrownsand_p.h"
29 29 #include "chartthemebluencs_p.h"
30 30 #include "chartthemehighcontrast_p.h"
31 31 #include "chartthemeblueicy_p.h"
32 32
33 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 34
35 35 ChartThemeManager::ChartThemeManager(QChart* chart) :
36 36 m_chart(chart)
37 37 {
38 38 qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
39 39 }
40 40
41 41
42 42 void ChartThemeManager::setTheme(QChart::ChartTheme theme)
43 43 {
44 44 if (m_theme.isNull() || theme != m_theme->id()) {
45 45 switch (theme) {
46 46 case QChart::ChartThemeLight:
47 47 m_theme.reset(new ChartThemeLight());
48 48 break;
49 49 case QChart::ChartThemeBlueCerulean:
50 50 m_theme.reset(new ChartThemeBlueCerulean());
51 51 break;
52 52 case QChart::ChartThemeDark:
53 53 m_theme.reset(new ChartThemeDark());
54 54 break;
55 55 case QChart::ChartThemeBrownSand:
56 56 m_theme.reset(new ChartThemeBrownSand());
57 57 break;
58 58 case QChart::ChartThemeBlueNcs:
59 59 m_theme.reset(new ChartThemeBlueNcs());
60 60 break;
61 61 case QChart::ChartThemeHighContrast:
62 62 m_theme.reset(new ChartThemeHighContrast());
63 63 break;
64 64 case QChart::ChartThemeBlueIcy:
65 65 m_theme.reset(new ChartThemeBlueIcy());
66 66 break;
67 67 default:
68 68 m_theme.reset(new ChartThemeSystem());
69 69 break;
70 70 }
71 71
72 72 if (!m_theme.isNull()) {
73 73 decorateChart(m_chart,m_theme.data());
74 74 decorateLegend(m_chart->legend(),m_theme.data());
75 75 foreach (QAbstractAxis* axis, m_axisList)
76 76 axis->d_ptr->initializeTheme(m_theme.data(), true);
77 77 foreach (QAbstractSeries* series, m_seriesMap.keys())
78 78 series->d_ptr->initializeTheme(m_seriesMap[series], m_theme.data(), true);
79 79 }
80 80 }
81 81 }
82 82
83 83 // decorateChart is only called when theme is forcibly initialized
84 84 void ChartThemeManager::decorateChart(QChart *chart, ChartTheme *theme) const
85 85 {
86 86 chart->setBackgroundBrush(theme->chartBackgroundGradient());
87 87
88 88 QPen pen(Qt::transparent);
89 89 QBrush brush;
90 90 chart->setPlotAreaBackgroundBrush(brush);
91 91 chart->setPlotAreaBackgroundPen(pen);
92 92 chart->setPlotAreaBackgroundVisible(false);
93 93
94 94 chart->setTitleFont(theme->masterFont());
95 95 chart->setTitleBrush(theme->labelBrush());
96 96 chart->setDropShadowEnabled(theme->isBackgroundDropShadowEnabled());
97 97 }
98 98
99 99 // decorateLegend is only called when theme is forcibly initialized
100 100 void ChartThemeManager::decorateLegend(QLegend *legend, ChartTheme *theme) const
101 101 {
102 102 legend->setPen(theme->axisLinePen());
103 103 legend->setBrush(theme->chartBackgroundGradient());
104 104 legend->setFont(theme->labelFont());
105 105 legend->setLabelBrush(theme->labelBrush());
106 106 }
107 107
108 108 int ChartThemeManager::createIndexKey(QList<int> keys) const
109 109 {
110 110 qSort(keys);
111 111
112 112 int key = 0;
113 113 QList<int>::iterator i;
114 114 i = keys.begin();
115 115
116 116 while (i != keys.end()) {
117 117 if (*i != key)
118 118 break;
119 119 key++;
120 120 i++;
121 121 }
122 122
123 123 return key;
124 124 }
125 125
126 126 int ChartThemeManager::seriesCount(QAbstractSeries::SeriesType type) const
127 127 {
128 128 int count = 0;
129 129 QList<QAbstractSeries *> series = m_seriesMap.keys();
130 130 foreach(QAbstractSeries *s, series) {
131 131 if (s->type() == type)
132 132 count++;
133 133 }
134 134 return count;
135 135 }
136 136
137 137 void ChartThemeManager::handleSeriesAdded(QAbstractSeries *series)
138 138 {
139 139 int key = createIndexKey(m_seriesMap.values());
140 140 m_seriesMap.insert(series,key);
141 141 series->d_ptr->initializeTheme(key,m_theme.data(),false);
142 142 }
143 143
144 144 void ChartThemeManager::handleSeriesRemoved(QAbstractSeries *series)
145 145 {
146 146 m_seriesMap.remove(series);
147 147 }
148 148
149 149 void ChartThemeManager::handleAxisAdded(QAbstractAxis *axis)
150 150 {
151 151 m_axisList.append(axis);
152 152 axis->d_ptr->initializeTheme(m_theme.data(),false);
153 153 }
154 154
155 155 void ChartThemeManager::handleAxisRemoved(QAbstractAxis *axis)
156 156 {
157 157 m_axisList.removeAll(axis);
158 158 }
159 159
160 160 void ChartThemeManager::updateSeries(QAbstractSeries *series)
161 161 {
162 162 if(m_seriesMap.contains(series)){
163 163 series->d_ptr->initializeTheme(m_seriesMap[series],m_theme.data(),false);
164 164 }
165 165 }
166 166 QList<QGradient> ChartThemeManager::generateSeriesGradients(const QList<QColor>& colors)
167 167 {
168 168 QList<QGradient> result;
169 169 // Generate gradients in HSV color space
170 170 foreach (const QColor &color, colors) {
171 171 QLinearGradient g;
172 172 qreal h = color.hsvHueF();
173 173 qreal s = color.hsvSaturationF();
174 174
175 // TODO: tune the algorithm to give nice results with most base colors defined in
176 // most themes. The rest of the gradients we can define manually in theme specific
177 // implementation.
178 175 QColor start = color;
179 176 start.setHsvF(h, 0.0, 1.0);
180 177 g.setColorAt(0.0, start);
181 178
182 179 g.setColorAt(0.5, color);
183 180
184 181 QColor end = color;
185 182 end.setHsvF(h, s, 0.25);
186 183 g.setColorAt(1.0, end);
187 184
188 185 result << g;
189 186 }
190 187
191 188 return result;
192 189 }
193 190
194 191
195 192 QColor ChartThemeManager::colorAt(const QColor &start, const QColor &end, qreal pos)
196 193 {
197 194 Q_ASSERT(pos >= 0.0 && pos <= 1.0);
198 195 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
199 196 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
200 197 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
201 198 QColor c;
202 199 c.setRgbF(r, g, b);
203 200 return c;
204 201 }
205 202
206 203 QColor ChartThemeManager::colorAt(const QGradient &gradient, qreal pos)
207 204 {
208 205 Q_ASSERT(pos >= 0 && pos <= 1.0);
209 206
210 207 QGradientStops stops = gradient.stops();
211 208 int count = stops.count();
212 209
213 210 // find previous stop relative to position
214 211 QGradientStop prev = stops.first();
215 212 for (int i = 0; i < count; i++) {
216 213 QGradientStop stop = stops.at(i);
217 214 if (pos > stop.first)
218 215 prev = stop;
219 216
220 217 // given position is actually a stop position?
221 218 if (pos == stop.first) {
222 219 //qDebug() << "stop color" << pos;
223 220 return stop.second;
224 221 }
225 222 }
226 223
227 224 // find next stop relative to position
228 225 QGradientStop next = stops.last();
229 226 for (int i = count - 1; i >= 0; i--) {
230 227 QGradientStop stop = stops.at(i);
231 228 if (pos < stop.first)
232 229 next = stop;
233 230 }
234 231
235 232 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
236 233
237 234 qreal range = next.first - prev.first;
238 235 qreal posDelta = pos - prev.first;
239 236 qreal relativePos = posDelta / range;
240 237
241 238 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
242 239
243 240 return colorAt(prev.second, next.second, relativePos);
244 241 }
245 242
246 243 #include "moc_chartthememanager_p.cpp"
247 244
248 245 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,89 +1,82
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QLEGENDMARKERPRIVATE_H
31 31 #define QLEGENDMARKERPRIVATE_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include <QGraphicsObject>
35 35 #include <QBrush>
36 36 #include <QPen>
37 37 #include <QGraphicsLayoutItem>
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 // TODO: check these
42 41 class QAbstractSeries;
43 class QAreaSeries;
44 class QXYSeries;
45 class QBarSet;
46 class QAbstractBarSeries;
47 class QPieSlice;
48 42 class QLegend;
49 class QPieSeries;
50 43
51 44 class QLegendMarker;
52 45 class LegendMarkerItem;
53 46
54 47 class QLegendMarkerPrivate : public QObject
55 48 {
56 49 Q_OBJECT
57 50 public:
58 51 explicit QLegendMarkerPrivate(QLegendMarker *q, QLegend *legend);
59 52 virtual ~QLegendMarkerPrivate();
60 53
61 54 // Helper for now. (or declare LegendLayout as friend)
62 55 LegendMarkerItem* item() const { return m_item; }
63 56
64 57 virtual QAbstractSeries* series() = 0;
65 58 virtual QObject* relatedObject() = 0;
66 59
67 60 void invalidateLegend();
68 61
69 62 public Q_SLOTS:
70 63 virtual void updated() = 0;
71 64
72 65 protected:
73 66 LegendMarkerItem *m_item;
74 67 QLegend *m_legend;
75 68 bool m_customLabel;
76 69 bool m_customBrush;
77 70 bool m_customPen;
78 71
79 72 private:
80 73 QLegendMarker *q_ptr;
81 74
82 75 friend class QLegendPrivate;
83 76 friend class LegendMarkerItem;
84 77 Q_DECLARE_PUBLIC(QLegendMarker)
85 78 };
86 79
87 80 QTCOMMERCIALCHART_END_NAMESPACE
88 81
89 82 #endif // QLEGENDMARKERPRIVATE_H
@@ -1,207 +1,206
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "scatterchartitem_p.h"
22 22 #include "qscatterseries.h"
23 23 #include "qscatterseries_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "abstractdomain_p.h"
26 26 #include "qchart.h"
27 27 #include <QPainter>
28 28 #include <QGraphicsScene>
29 29 #include <QDebug>
30 30 #include <QGraphicsSceneMouseEvent>
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 ScatterChartItem::ScatterChartItem(QScatterSeries *series, QGraphicsItem *item)
35 35 : XYChart(series,item),
36 36 m_series(series),
37 37 m_items(this),
38 38 m_visible(true),
39 39 m_shape(QScatterSeries::MarkerShapeRectangle),
40 40 m_size(15)
41 41 {
42 42 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
43 43 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
44 44 QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
45 45
46 46 setZValue(ChartPresenter::ScatterSeriesZValue);
47 47 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
48 48
49 49 handleUpdated();
50 50
51 51 m_items.setHandlesChildEvents(false);
52 52 }
53 53
54 54 QRectF ScatterChartItem::boundingRect() const
55 55 {
56 56 return m_rect;
57 57 }
58 58
59 59 void ScatterChartItem::createPoints(int count)
60 60 {
61 61 for (int i = 0; i < count; ++i) {
62 62
63 63 QGraphicsItem *item = 0;
64 64
65 65 switch (m_shape) {
66 66 case QScatterSeries::MarkerShapeCircle: {
67 67 item = new CircleMarker(0, 0, m_size, m_size, this);
68 68 const QRectF &rect = item->boundingRect();
69 69 item->setPos(-rect.width() / 2, -rect.height() / 2);
70 70 break;
71 71 }
72 72 case QScatterSeries::MarkerShapeRectangle:
73 73 item = new RectangleMarker(0, 0, m_size, m_size, this);
74 74 item->setPos(-m_size / 2, -m_size / 2);
75 75 break;
76 76 default:
77 77 qWarning() << "Unsupported marker type";
78 78 break;
79 79 }
80 80 m_items.addToGroup(item);
81 81 }
82 82 }
83 83
84 84 void ScatterChartItem::deletePoints(int count)
85 85 {
86 86 QList<QGraphicsItem *> items = m_items.childItems();
87 87
88 88 for (int i = 0; i < count; ++i) {
89 89 QGraphicsItem *item = items.takeLast();
90 90 m_markerMap.remove(item);
91 91 delete(item);
92 92 }
93 93 }
94 94
95 95 void ScatterChartItem::markerSelected(QGraphicsItem *marker)
96 96 {
97 97 emit XYChart::clicked(m_markerMap[marker]);
98 98 }
99 99
100 100 void ScatterChartItem::markerHovered(QGraphicsItem *marker, bool state)
101 101 {
102 102 emit XYChart::hovered(m_markerMap[marker], state);
103 103 }
104 104
105 105 void ScatterChartItem::updateGeometry()
106 106 {
107 107
108 108 const QVector<QPointF>& points = geometryPoints();
109 109
110 110 if (points.size() == 0) {
111 111 deletePoints(m_items.childItems().count());
112 112 return;
113 113 }
114 114
115 115 int diff = m_items.childItems().size() - points.size();
116 116
117 117 if (diff > 0)
118 118 deletePoints(diff);
119 119 else if (diff < 0)
120 120 createPoints(-diff);
121 121
122 122 if (diff != 0)
123 123 handleUpdated();
124 124
125 125 QList<QGraphicsItem *> items = m_items.childItems();
126 126
127 127 QRectF clipRect(QPointF(0,0),domain()->size());
128 128
129 129 QVector<bool> offGridStatus = offGridStatusVector();
130 130 const int seriesLastIndex = m_series->count() - 1;
131 131
132 132 for (int i = 0; i < points.size(); i++) {
133 133 QGraphicsItem *item = items.at(i);
134 134 const QPointF &point = points.at(i);
135 135 const QRectF &rect = item->boundingRect();
136 136 // During remove animation series may have different number of points,
137 137 // so ensure we don't go over the index. Animation handling itself ensures that
138 138 // if there is actually no points in the series, then it won't generate a fake point,
139 139 // so we can be assured there is always at least one point in m_series here.
140 140 // Note that marker map values can be technically incorrect during the animation,
141 141 // if it was caused by an insert, but this shouldn't be a problem as the points are
142 142 // fake anyway. After remove animation stops, geometry is updated to correct one.
143 143 m_markerMap[item] = m_series->at(qMin(seriesLastIndex, i));
144 144 item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2);
145 145
146 146 if (!m_visible || offGridStatus.at(i))
147 147 item->setVisible(false);
148 148 else
149 149 item->setVisible(true);
150 150 }
151 151
152 152 prepareGeometryChange();
153 153 m_rect = clipRect;
154 154 }
155 155
156 156 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
157 157 {
158 158 Q_UNUSED(painter)
159 159 Q_UNUSED(option)
160 160 Q_UNUSED(widget)
161 161 }
162 162
163 163 void ScatterChartItem::setPen(const QPen &pen)
164 164 {
165 165 foreach (QGraphicsItem *item , m_items.childItems())
166 166 static_cast<QAbstractGraphicsShapeItem*>(item)->setPen(pen);
167 167 }
168 168
169 169 void ScatterChartItem::setBrush(const QBrush &brush)
170 170 {
171 171 foreach (QGraphicsItem *item , m_items.childItems())
172 172 static_cast<QAbstractGraphicsShapeItem*>(item)->setBrush(brush);
173 173 }
174 174
175 175 void ScatterChartItem::handleUpdated()
176 176 {
177 177 int count = m_items.childItems().count();
178 178
179 179 if (count == 0)
180 180 return;
181 181
182 182 bool recreate = m_visible != m_series->isVisible()
183 183 || m_size != m_series->markerSize()
184 184 || m_shape != m_series->markerShape();
185 185
186 186 m_visible = m_series->isVisible();
187 187 m_size = m_series->markerSize();
188 188 m_shape = m_series->markerShape();
189 189 setOpacity(m_series->opacity());
190 190
191 191 if (recreate) {
192 // TODO: optimize handleUpdate to recreate points only in case shape changed
193 192 deletePoints(count);
194 193 createPoints(count);
195 194
196 195 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
197 196 updateGeometry();
198 197 }
199 198
200 199 setPen(m_series->pen());
201 200 setBrush(m_series->brush());
202 201 update();
203 202 }
204 203
205 204 #include "moc_scatterchartitem_p.cpp"
206 205
207 206 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,191 +1,189
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 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 Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise 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 "xychart_p.h"
22 22 #include "qxyseries.h"
23 23 #include "qxyseries_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "abstractdomain_p.h"
26 26 #include "qxymodelmapper.h"
27 27 #include "qabstractaxis_p.h"
28 28 #include <QPainter>
29 29 #include <QAbstractItemModel>
30 30
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 //TODO: optimize : remove points which are not visible
35
36 34 XYChart::XYChart(QXYSeries *series, QGraphicsItem *item):
37 35 ChartItem(series->d_func(),item),
38 36 m_series(series),
39 37 m_animation(0),
40 38 m_dirty(true)
41 39 {
42 40 QObject::connect(series, SIGNAL(pointReplaced(int)), this, SLOT(handlePointReplaced(int)));
43 41 QObject::connect(series, SIGNAL(pointsReplaced()), this, SLOT(handlePointsReplaced()));
44 42 QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
45 43 QObject::connect(series, SIGNAL(pointRemoved(int)), this, SLOT(handlePointRemoved(int)));
46 44 QObject::connect(this, SIGNAL(clicked(QPointF)), series, SIGNAL(clicked(QPointF)));
47 45 QObject::connect(this, SIGNAL(hovered(QPointF,bool)), series, SIGNAL(hovered(QPointF,bool)));
48 46 }
49 47
50 48 void XYChart::setGeometryPoints(const QVector<QPointF> &points)
51 49 {
52 50 m_points = points;
53 51 }
54 52
55 53 void XYChart::setAnimation(XYAnimation *animation)
56 54 {
57 55 m_animation = animation;
58 56 }
59 57
60 58 void XYChart::setDirty(bool dirty)
61 59 {
62 60 m_dirty = dirty;
63 61 }
64 62
65 63 // Returns a vector with same size as geometryPoints vector, indicating
66 64 // the off grid status of points.
67 65 QVector<bool> XYChart::offGridStatusVector()
68 66 {
69 67 qreal minX = domain()->minX();
70 68 qreal maxX = domain()->maxX();
71 69 qreal minY = domain()->minY();
72 70 qreal maxY = domain()->maxY();
73 71
74 72 QVector<bool> returnVector;
75 73 returnVector.resize(m_points.size());
76 74 // During remove animation series may have different number of points,
77 75 // so ensure we don't go over the index. No need to check for zero points, this
78 76 // will not be called in such a situation.
79 77 const int seriesLastIndex = m_series->count() - 1;
80 78
81 79 for (int i = 0; i < m_points.size(); i++) {
82 80 const QPointF &seriesPoint = m_series->at(qMin(seriesLastIndex, i));
83 81 if (seriesPoint.x() < minX
84 82 || seriesPoint.x() > maxX
85 83 || seriesPoint.y() < minY
86 84 || seriesPoint.y() > maxY) {
87 85 returnVector[i] = true;
88 86 } else {
89 87 returnVector[i] = false;
90 88 }
91 89 }
92 90 return returnVector;
93 91 }
94 92
95 93 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
96 94 {
97 95
98 96 if (m_animation) {
99 97 m_animation->setup(oldPoints, newPoints, index);
100 98 m_points = newPoints;
101 99 setDirty(false);
102 100 presenter()->startAnimation(m_animation);
103 101 } else {
104 102 m_points = newPoints;
105 103 updateGeometry();
106 104 }
107 105 }
108 106
109 107 //handlers
110 108
111 109 void XYChart::handlePointAdded(int index)
112 110 {
113 111 Q_ASSERT(index < m_series->count());
114 112 Q_ASSERT(index >= 0);
115 113
116 114 QVector<QPointF> points;
117 115
118 116 if (m_dirty || m_points.isEmpty()) {
119 117 points = domain()->calculateGeometryPoints(m_series->points());
120 118 } else {
121 119 points = m_points;
122 120 QPointF point = domain()->calculateGeometryPoint(m_series->points()[index], m_validData);
123 121 if (!m_validData)
124 122 m_points.clear();
125 123 else
126 124 points.insert(index, point);
127 125 }
128 126
129 127 updateChart(m_points, points, index);
130 128 }
131 129
132 130 void XYChart::handlePointRemoved(int index)
133 131 {
134 132 Q_ASSERT(index <= m_series->count());
135 133 Q_ASSERT(index >= 0);
136 134
137 135 QVector<QPointF> points;
138 136
139 137 if (m_dirty || m_points.isEmpty()) {
140 138 points = domain()->calculateGeometryPoints(m_series->points());
141 139 } else {
142 140 points = m_points;
143 141 points.remove(index);
144 142 }
145 143
146 144 updateChart(m_points, points, index);
147 145 }
148 146
149 147 void XYChart::handlePointReplaced(int index)
150 148 {
151 149 Q_ASSERT(index < m_series->count());
152 150 Q_ASSERT(index >= 0);
153 151
154 152 QVector<QPointF> points;
155 153
156 154 if (m_dirty || m_points.isEmpty()) {
157 155 points = domain()->calculateGeometryPoints(m_series->points());
158 156 } else {
159 157 QPointF point = domain()->calculateGeometryPoint(m_series->points()[index], m_validData);
160 158 if (!m_validData)
161 159 m_points.clear();
162 160 points = m_points;
163 161 if (m_validData)
164 162 points.replace(index, point);
165 163 }
166 164
167 165 updateChart(m_points, points, index);
168 166 }
169 167
170 168 void XYChart::handlePointsReplaced()
171 169 {
172 170 // All the points were replaced -> recalculate
173 171 QVector<QPointF> points = domain()->calculateGeometryPoints(m_series->points());
174 172 updateChart(m_points, points, -1);
175 173 }
176 174
177 175 void XYChart::handleDomainUpdated()
178 176 {
179 177 if (isEmpty()) return;
180 178 QVector<QPointF> points = domain()->calculateGeometryPoints(m_series->points());
181 179 updateChart(m_points, points);
182 180 }
183 181
184 182 bool XYChart::isEmpty()
185 183 {
186 184 return domain()->isEmpty() || m_series->points().isEmpty();
187 185 }
188 186
189 187 #include "moc_xychart_p.cpp"
190 188
191 189 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now