@@ -1,169 +1,181 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | import QtQuick 1.1 |
|
22 | 22 | import QtCommercial.Chart 1.0 |
|
23 | 23 | |
|
24 | 24 | Rectangle { |
|
25 | 25 | width: 360 |
|
26 | 26 | height: 360 |
|
27 | 27 | |
|
28 | 28 | //![1] |
|
29 | 29 | ChartView { |
|
30 | 30 | id: chartView |
|
31 | 31 | title: "Weather forecast" |
|
32 | 32 | //![1] |
|
33 | 33 | anchors.top: parent.top |
|
34 | 34 | anchors.bottom: weatherImageRow.top |
|
35 | 35 | anchors.left: parent.left |
|
36 | 36 | anchors.right: parent.right |
|
37 | 37 | legend.alignment: Qt.AlignTop |
|
38 | 38 | |
|
39 | 39 | //![2] |
|
40 |
Bar |
|
|
41 |
|
|
|
42 | id: categoriesAxis | |
|
43 | categories: ["Mo", "Tu", "We", "Th", "Fr", "Sa" ] | |
|
40 | BarCategoriesAxis { | |
|
41 | id: myBarCategoryAxis | |
|
42 | categories: ["Mo", "Tu", "We", "Th", "Fr"] | |
|
44 | 43 |
|
|
45 | 44 | |
|
45 | BarSeries { | |
|
46 | id: myBarSeries | |
|
46 | 47 | BarSet { |
|
47 | 48 | id: rainfallSet |
|
48 | 49 | label: "Rainfall" |
|
49 | 50 | } |
|
50 | 51 | } |
|
51 | 52 | |
|
52 | ScatterSeries { | |
|
53 | ValuesAxis{ | |
|
54 | id: myValuesAxisY | |
|
55 | min: 0 | |
|
56 | max: 10 | |
|
57 | } | |
|
58 | ||
|
59 | LineSeries { | |
|
53 | 60 | id: maxTempSeries |
|
54 | 61 | name: "Max. temperature" |
|
55 | 62 | } |
|
56 | 63 | |
|
57 |
|
|
|
64 | LineSeries { | |
|
58 | 65 | id: minTempSeries |
|
59 | 66 | name: "Min. temperature" |
|
60 | 67 | } |
|
61 | 68 | //![2] |
|
69 | ||
|
70 | Component.onCompleted: { | |
|
71 | setAxisX(myBarCategoryAxis,myBarSeries) | |
|
72 | setAxisX(myBarCategoryAxis,maxTempSeries) | |
|
73 | setAxisX(myBarCategoryAxis,minTempSeries) | |
|
74 | setAxisY(myValuesAxisY,maxTempSeries) | |
|
75 | setAxisY(myValuesAxisY,minTempSeries) | |
|
76 | setAxisY(myValuesAxisY,myBarSeries) | |
|
77 | } | |
|
62 | 78 |
|
|
63 | 79 | |
|
64 | 80 | // A timer to refresh the forecast every 5 minutes |
|
65 | 81 | Timer { |
|
66 | 82 | interval: 300000 |
|
67 | 83 | repeat: true |
|
68 | 84 | triggeredOnStart: true |
|
69 | 85 | running: true |
|
70 | 86 | onTriggered: { |
|
71 | 87 | if (weatherAppKey != "") { |
|
72 | 88 | //![3] |
|
73 | 89 | // Make HTTP GET request and parse the result |
|
74 | 90 | var xhr = new XMLHttpRequest; |
|
75 | 91 | xhr.open("GET", |
|
76 | 92 | "http://free.worldweatheronline.com/feed/weather.ashx?q=Jyv%c3%a4skyl%c3%a4,Finland&format=json&num_of_days=5&key=" |
|
77 | 93 | + weatherAppKey); |
|
78 | 94 | xhr.onreadystatechange = function() { |
|
79 | 95 | if (xhr.readyState == XMLHttpRequest.DONE) { |
|
80 | 96 | var a = JSON.parse(xhr.responseText); |
|
81 | 97 | parseWeatherData(a); |
|
82 | 98 | } |
|
83 | 99 | } |
|
84 | 100 | xhr.send(); |
|
85 | 101 | //![3] |
|
86 | 102 | } else { |
|
87 | 103 | // No app key for worldweatheronline.com given by the user -> use static data |
|
88 | 104 | var responseText = "{ \"data\": { \"current_condition\": [ {\"cloudcover\": \"10\", \"humidity\": \"61\", \"observation_time\": \"06:26 AM\", \"precipMM\": \"0.0\", \"pressure\": \"1022\", \"temp_C\": \"6\", \"temp_F\": \"43\", \"visibility\": \"10\", \"weatherCode\": \"113\", \"weatherDesc\": [ {\"value\": \"Sunny\" } ], \"weatherIconUrl\": [ {\"value\": \"http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0001_sunny.png\" } ], \"winddir16Point\": \"SE\", \"winddirDegree\": \"140\", \"windspeedKmph\": \"7\", \"windspeedMiles\": \"4\" } ], \"request\": [ {\"query\": \"Jyvaskyla, Finland\", \"type\": \"City\" } ], \"weather\": [ {\"date\": \"2012-05-09\", \"precipMM\": \"0.4\", \"tempMaxC\": \"14\", \"tempMaxF\": \"57\", \"tempMinC\": \"7\", \"tempMinF\": \"45\", \"weatherCode\": \"116\", \"weatherDesc\": [ {\"value\": \"Partly Cloudy\" } ], \"weatherIconUrl\": [ {\"value\": \"http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0002_sunny_intervals.png\" } ], \"winddir16Point\": \"S\", \"winddirDegree\": \"179\", \"winddirection\": \"S\", \"windspeedKmph\": \"20\", \"windspeedMiles\": \"12\" }, {\"date\": \"2012-05-10\", \"precipMM\": \"2.4\", \"tempMaxC\": \"13\", \"tempMaxF\": \"55\", \"tempMinC\": \"8\", \"tempMinF\": \"46\", \"weatherCode\": \"266\", \"weatherDesc\": [ {\"value\": \"Light drizzle\" } ], \"weatherIconUrl\": [ {\"value\": \"http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0017_cloudy_with_light_rain.png\" } ], \"winddir16Point\": \"SW\", \"winddirDegree\": \"219\", \"winddirection\": \"SW\", \"windspeedKmph\": \"21\", \"windspeedMiles\": \"13\" }, {\"date\": \"2012-05-11\", \"precipMM\": \"11.1\", \"tempMaxC\": \"15\", \"tempMaxF\": \"59\", \"tempMinC\": \"7\", \"tempMinF\": \"44\", \"weatherCode\": \"266\", \"weatherDesc\": [ {\"value\": \"Light drizzle\" } ], \"weatherIconUrl\": [ {\"value\": \"http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0017_cloudy_with_light_rain.png\" } ], \"winddir16Point\": \"SSW\", \"winddirDegree\": \"200\", \"winddirection\": \"SSW\", \"windspeedKmph\": \"20\", \"windspeedMiles\": \"12\" }, {\"date\": \"2012-05-12\", \"precipMM\": \"2.8\", \"tempMaxC\": \"7\", \"tempMaxF\": \"44\", \"tempMinC\": \"2\", \"tempMinF\": \"35\", \"weatherCode\": \"317\", \"weatherDesc\": [ {\"value\": \"Light sleet\" } ], \"weatherIconUrl\": [ {\"value\": \"http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0021_cloudy_with_sleet.png\" } ], \"winddir16Point\": \"NW\", \"winddirDegree\": \"311\", \"winddirection\": \"NW\", \"windspeedKmph\": \"24\", \"windspeedMiles\": \"15\" }, {\"date\": \"2012-05-13\", \"precipMM\": \"0.4\", \"tempMaxC\": \"6\", \"tempMaxF\": \"42\", \"tempMinC\": \"2\", \"tempMinF\": \"35\", \"weatherCode\": \"116\", \"weatherDesc\": [ {\"value\": \"Partly Cloudy\" } ], \"weatherIconUrl\": [ {\"value\": \"http:\/\/www.worldweatheronline.com\/images\/wsymbols01_png_64\/wsymbol_0002_sunny_intervals.png\" } ], \"winddir16Point\": \"WNW\", \"winddirDegree\": \"281\", \"winddirection\": \"WNW\", \"windspeedKmph\": \"21\", \"windspeedMiles\": \"13\" } ] }}"; |
|
89 | 105 | var a = JSON.parse(responseText); |
|
90 | 106 | parseWeatherData(a); |
|
91 | 107 | } |
|
92 | 108 | } |
|
93 | 109 | } |
|
94 | 110 | |
|
95 | 111 | Row { |
|
96 | 112 | id: weatherImageRow |
|
97 | 113 | anchors.bottom: poweredByText.top |
|
98 | 114 | anchors.bottomMargin: 10 |
|
99 | 115 | anchors.left: parent.left |
|
100 | 116 | anchors.leftMargin: 25 |
|
101 | 117 | anchors.right: parent.right |
|
102 | 118 | anchors.rightMargin: 25 |
|
103 | 119 | |
|
104 | 120 | ListModel { |
|
105 | 121 | id: weatherImageModel |
|
106 | 122 | } |
|
107 | 123 | |
|
108 | 124 | Repeater { |
|
109 | 125 | id: repeater |
|
110 | 126 | model: weatherImageModel |
|
111 | 127 | delegate: Image { |
|
112 | 128 | source: imageSource |
|
113 | 129 | width: weatherImageRow.width / weatherImageModel.count |
|
114 | 130 | height: width |
|
115 | 131 | fillMode: Image.PreserveAspectCrop |
|
116 | 132 | } |
|
117 | 133 | } |
|
118 | 134 | } |
|
119 | 135 | |
|
120 | 136 | Text { |
|
121 | 137 | id: poweredByText |
|
122 | 138 | anchors.bottom: parent.bottom |
|
123 | 139 | anchors.bottomMargin: 10 |
|
124 | 140 | anchors.left: parent.left |
|
125 | 141 | anchors.leftMargin: 25 |
|
126 | 142 | text: "Powered by World Weather Online" |
|
127 | 143 | } |
|
128 | 144 | |
|
129 | 145 | function parseWeatherData(weatherData) { |
|
130 | 146 | // Clear previous values |
|
131 | chartView.axisX.min = 0; | |
|
132 | chartView.axisX.max = 5; | |
|
133 | chartView.axisY.min = 0; | |
|
134 | chartView.axisY.max = 5; | |
|
135 | 147 | maxTempSeries.clear(); |
|
136 | 148 | minTempSeries.clear(); |
|
137 | 149 | weatherImageModel.clear(); |
|
138 | 150 | |
|
139 | 151 | //![4] |
|
140 | 152 | // Loop through the parsed JSON |
|
141 | 153 | for (var i in weatherData.data.weather) { |
|
142 | 154 | var weatherObj = weatherData.data.weather[i]; |
|
143 | 155 | //![4] |
|
144 | 156 | |
|
145 | 157 | //![5] |
|
146 | 158 | // Store temperature values, rainfall and weather icon |
|
147 | 159 | maxTempSeries.append(i, weatherObj.tempMaxC); |
|
148 | 160 | minTempSeries.append(i, weatherObj.tempMinC); |
|
149 | 161 | rainfallSet.append(i, weatherObj.precipMM); |
|
150 | ||
|
151 | 162 | weatherImageModel.append({"imageSource":weatherObj.weatherIconUrl[0].value}); |
|
152 | 163 | //![5] |
|
153 | 164 | |
|
154 | 165 | // Update scale of the chart |
|
155 | chartView.axisX.min = 0; | |
|
156 | chartView.axisX.max = i; | |
|
157 |
|
|
|
158 |
|
|
|
159 | while (chartView.axisY.max <= Number(weatherObj.tempMaxC)) | |
|
160 | chartView.axisY.max = chartView.axisY.max + 10; | |
|
166 | chartView.axisY().max = Math.max(chartView.axisY().max,weatherObj.tempMaxC) | |
|
167 | chartView.axisY().max = Math.max(chartView.axisY().max,weatherObj.tempMinC) | |
|
168 | chartView.axisX().min = 0; | |
|
169 | chartView.axisX().max = i+1; | |
|
161 | 170 | |
|
162 | 171 | // Set the x-axis labels to the dates of the forecast |
|
163 |
var xLabels = |
|
|
164 |
xLabels[Number(i) |
|
|
165 | xLabels[(Number(i) * 2) + 1] = weatherObj.date.substring(5, 10); | |
|
166 |
|
|
|
172 | var xLabels = myBarCategoryAxis.categories; | |
|
173 | xLabels[Number(i)] = weatherObj.date.substring(5, 10); | |
|
174 | myBarCategoryAxis.categories = xLabels; | |
|
175 | myBarCategoryAxis.visible = true; | |
|
167 | 176 | } |
|
177 | ||
|
178 | ||
|
168 | 179 | } |
|
180 | ||
|
169 | 181 | } |
@@ -1,156 +1,155 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | #ifndef DECLARATIVECHART_H |
|
22 | 22 | #define DECLARATIVECHART_H |
|
23 | 23 | |
|
24 | 24 | #include <QtCore/QtGlobal> |
|
25 | 25 | #include <QDeclarativeItem> |
|
26 | 26 | #include <qchart.h> |
|
27 | 27 | |
|
28 | 28 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
29 | 29 | |
|
30 | 30 | // TODO: Derive from QChart for easier definition of properties? |
|
31 | 31 | class DeclarativeChart : public QDeclarativeItem |
|
32 | 32 | // TODO: for QTQUICK2: extend QQuickPainterItem instead |
|
33 | 33 | //class DeclarativeChart : public QQuickPaintedItem, public Chart |
|
34 | 34 | { |
|
35 | 35 | Q_OBJECT |
|
36 | 36 | Q_PROPERTY(Theme theme READ theme WRITE setTheme) |
|
37 | 37 | Q_PROPERTY(Animation animationOptions READ animationOptions WRITE setAnimationOptions) |
|
38 | 38 | Q_PROPERTY(QString title READ title WRITE setTitle) |
|
39 | 39 | Q_PROPERTY(QFont titleFont READ titleFont WRITE setTitleFont) |
|
40 | 40 | Q_PROPERTY(QColor titleColor READ titleColor WRITE setTitleColor NOTIFY titleColorChanged) |
|
41 | Q_PROPERTY(QAbstractAxis *axisX READ axisX) | |
|
42 | Q_PROPERTY(QAbstractAxis *axisY READ axisY) | |
|
43 | 41 | Q_PROPERTY(QLegend *legend READ legend) |
|
44 | 42 | Q_PROPERTY(int count READ count) |
|
45 | 43 | Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged) |
|
46 | 44 | Q_PROPERTY(bool dropShadowEnabled READ dropShadowEnabled WRITE setDropShadowEnabled NOTIFY dropShadowEnabledChanged) |
|
47 | 45 | Q_PROPERTY(qreal topMargin READ topMargin NOTIFY topMarginChanged) |
|
48 | 46 | Q_PROPERTY(qreal bottomMargin READ bottomMargin NOTIFY bottomMarginChanged) |
|
49 | 47 | Q_PROPERTY(qreal leftMargin READ leftMargin NOTIFY leftMarginChanged) |
|
50 | 48 | Q_PROPERTY(qreal rightMargin READ rightMargin NOTIFY rightMarginChanged) |
|
51 | 49 | Q_ENUMS(Animation) |
|
52 | 50 | Q_ENUMS(Theme) |
|
53 | 51 | Q_ENUMS(SeriesType) |
|
54 | 52 | |
|
55 | 53 | public: |
|
56 | 54 | // duplicating enums from QChart to make the QML api namings 1-to-1 with the C++ api |
|
57 | 55 | enum Theme { |
|
58 | 56 | ChartThemeLight = 0, |
|
59 | 57 | ChartThemeBlueCerulean, |
|
60 | 58 | ChartThemeDark, |
|
61 | 59 | ChartThemeBrownSand, |
|
62 | 60 | ChartThemeBlueNcs, |
|
63 | 61 | ChartThemeHighContrast, |
|
64 | 62 | ChartThemeBlueIcy |
|
65 | 63 | }; |
|
66 | 64 | |
|
67 | 65 | enum Animation { |
|
68 | 66 | NoAnimation = 0x0, |
|
69 | 67 | GridAxisAnimations = 0x1, |
|
70 | 68 | SeriesAnimations =0x2, |
|
71 | 69 | AllAnimations = 0x3 |
|
72 | 70 | }; |
|
73 | 71 | |
|
74 | 72 | enum SeriesType { |
|
75 | 73 | SeriesTypeLine, |
|
76 | 74 | SeriesTypeArea, |
|
77 | 75 | SeriesTypeBar, |
|
78 | 76 | SeriesTypeStackedBar, |
|
79 | 77 | SeriesTypePercentBar, |
|
80 | 78 | SeriesTypePie, |
|
81 | 79 | SeriesTypeScatter, |
|
82 | 80 | SeriesTypeSpline |
|
83 | 81 | }; |
|
84 | 82 | |
|
85 | 83 | public: |
|
86 | 84 | DeclarativeChart(QDeclarativeItem *parent = 0); |
|
87 | 85 | ~DeclarativeChart(); |
|
88 | 86 | |
|
89 | 87 | public: // From QDeclarativeItem/QGraphicsItem |
|
90 | 88 | void childEvent(QChildEvent *event); |
|
91 | 89 | void componentComplete(); |
|
92 | 90 | void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); |
|
93 | 91 | void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); |
|
94 | 92 | |
|
95 | 93 | public: |
|
96 | 94 | void setTheme(DeclarativeChart::Theme theme); |
|
97 | 95 | DeclarativeChart::Theme theme(); |
|
98 | 96 | void setAnimationOptions(DeclarativeChart::Animation animations); |
|
99 | 97 | DeclarativeChart::Animation animationOptions(); |
|
100 | 98 | void setTitle(QString title); |
|
101 | 99 | QString title(); |
|
102 | 100 | QLegend *legend(); |
|
103 | 101 | QFont titleFont() const; |
|
104 | 102 | void setTitleFont(const QFont& font); |
|
105 | 103 | void setTitleColor(QColor color); |
|
106 | 104 | QColor titleColor(); |
|
107 | 105 | void setBackgroundColor(QColor color); |
|
108 | 106 | QColor backgroundColor(); |
|
109 | 107 | int count(); |
|
110 | 108 | void setDropShadowEnabled(bool enabled); |
|
111 | 109 | bool dropShadowEnabled(); |
|
112 | 110 | qreal topMargin(); |
|
113 | 111 | qreal bottomMargin(); |
|
114 | 112 | qreal leftMargin(); |
|
115 | 113 | qreal rightMargin(); |
|
116 | 114 | |
|
117 | QAbstractAxis *axisX(QAbstractSeries *series = 0); | |
|
118 | QAbstractAxis *axisY(QAbstractSeries *series = 0); | |
|
115 | ||
|
119 | 116 | |
|
120 | 117 | public: |
|
121 | 118 | Q_INVOKABLE QAbstractSeries *series(int index); |
|
122 | 119 | Q_INVOKABLE QAbstractSeries *series(QString seriesName); |
|
123 | 120 | Q_INVOKABLE QAbstractSeries *createSeries(DeclarativeChart::SeriesType type, QString name = ""); |
|
124 | 121 | Q_INVOKABLE void setAxisX(QAbstractAxis* axis, QAbstractSeries *series = 0); |
|
125 | 122 | Q_INVOKABLE void setAxisY(QAbstractAxis* axis, QAbstractSeries *series = 0); |
|
126 | 123 | Q_INVOKABLE void createDefaultAxes(); |
|
124 | Q_INVOKABLE QAbstractAxis *axisX(QAbstractSeries *series = 0); | |
|
125 | Q_INVOKABLE QAbstractAxis *axisY(QAbstractSeries *series = 0); | |
|
127 | 126 | |
|
128 | 127 | Q_INVOKABLE void zoom(qreal factor); |
|
129 | 128 | Q_INVOKABLE void scrollLeft(qreal pixels); |
|
130 | 129 | Q_INVOKABLE void scrollRight(qreal pixels); |
|
131 | 130 | Q_INVOKABLE void scrollUp(qreal pixels); |
|
132 | 131 | Q_INVOKABLE void scrollDown(qreal pixels); |
|
133 | 132 | |
|
134 | 133 | Q_SIGNALS: |
|
135 | 134 | void axisLabelsChanged(); |
|
136 | 135 | void titleColorChanged(QColor color); |
|
137 | 136 | void backgroundColorChanged(); |
|
138 | 137 | void dropShadowEnabledChanged(bool enabled); |
|
139 | 138 | void topMarginChanged(qreal margin); |
|
140 | 139 | void bottomMarginChanged(qreal margin); |
|
141 | 140 | void leftMarginChanged(qreal margin); |
|
142 | 141 | void rightMarginChanged(qreal margin); |
|
143 | 142 | |
|
144 | 143 | public Q_SLOTS: |
|
145 | 144 | void handleMarginsChanged(QRectF newMargins); |
|
146 | 145 | |
|
147 | 146 | private: |
|
148 | 147 | // Extending QChart with DeclarativeChart is not possible because QObject does not support |
|
149 | 148 | // multi inheritance, so we now have a QChart as a member instead |
|
150 | 149 | QChart *m_chart; |
|
151 | 150 | QRectF m_chartMargins; |
|
152 | 151 | }; |
|
153 | 152 | |
|
154 | 153 | QTCOMMERCIALCHART_END_NAMESPACE |
|
155 | 154 | |
|
156 | 155 | #endif // DECLARATIVECHART_H |
@@ -1,165 +1,165 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | // W A R N I N G |
|
22 | 22 | // ------------- |
|
23 | 23 | // |
|
24 | 24 | // This file is not part of the QtCommercial 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 CHARTAXIS_H |
|
31 | 31 | #define CHARTAXIS_H |
|
32 | 32 | |
|
33 | 33 | #include "qchartglobal.h" |
|
34 | 34 | #include "chart_p.h" |
|
35 | 35 | #include "axisanimation_p.h" |
|
36 | 36 | #include <QGraphicsItem> |
|
37 | 37 | #include <QFont> |
|
38 | 38 | |
|
39 | 39 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
40 | 40 | |
|
41 | 41 | class QAbstractAxis; |
|
42 | 42 | class ChartPresenter; |
|
43 | 43 | |
|
44 | 44 | class ChartAxis : public Chart |
|
45 | 45 | { |
|
46 | 46 | Q_OBJECT |
|
47 | 47 | public: |
|
48 | 48 | enum AxisType{ X_AXIS,Y_AXIS }; |
|
49 | 49 | |
|
50 | 50 | ChartAxis(QAbstractAxis *axis, ChartPresenter *presenter); |
|
51 | 51 | ~ChartAxis(); |
|
52 | 52 | |
|
53 | 53 | virtual AxisType axisType() const = 0; |
|
54 | 54 | |
|
55 | 55 | void setAxisOpacity(qreal opacity); |
|
56 | 56 | qreal axisOpacity() const; |
|
57 | 57 | |
|
58 | 58 | void setGridOpacity(qreal opacity); |
|
59 | 59 | qreal gridOpacity() const; |
|
60 | 60 | |
|
61 | 61 | void setLabelsOpacity(qreal opacity); |
|
62 | 62 | qreal labelsOpacity() const; |
|
63 | 63 | |
|
64 | 64 | void setShadesOpacity(qreal opacity); |
|
65 | 65 | qreal shadesOpacity() const; |
|
66 | 66 | |
|
67 | 67 | void setLabelsAngle(int angle); |
|
68 | 68 | int labelsAngle()const { return m_labelsAngle; } |
|
69 | 69 | |
|
70 | 70 | void setShadesBrush(const QBrush &brush); |
|
71 | 71 | void setShadesPen(const QPen &pen); |
|
72 | 72 | |
|
73 | 73 | void setAxisPen(const QPen &pen); |
|
74 | 74 | void setGridPen(const QPen &pen); |
|
75 | 75 | |
|
76 | 76 | void setLabelsPen(const QPen &pen); |
|
77 | 77 | void setLabelsBrush(const QBrush &brush); |
|
78 | 78 | void setLabelsFont(const QFont &font); |
|
79 | 79 | |
|
80 | 80 | void setLayout(QVector<qreal> &layout); |
|
81 | 81 | QVector<qreal> layout() const { return m_layoutVector; } |
|
82 | 82 | |
|
83 | 83 | void setAnimation(AxisAnimation* animation); |
|
84 | 84 | ChartAnimation* animation() const { return m_animation; }; |
|
85 | 85 | |
|
86 | 86 | QRectF geometry() const { return m_rect; } |
|
87 | 87 | |
|
88 | 88 | qreal minimumWidth(); |
|
89 | 89 | qreal minimumHeight(); |
|
90 | 90 | |
|
91 | 91 | protected: |
|
92 | 92 | virtual void updateGeometry() = 0; |
|
93 | 93 | virtual QVector<qreal> calculateLayout() const = 0; |
|
94 | 94 | void createNumberLabels(QStringList &labels,qreal min, qreal max,int ticks) const; |
|
95 | 95 | void createCategoryLabels(QStringList &labels,qreal min, qreal max,const QStringList &categories) const; |
|
96 | 96 | |
|
97 | 97 | public Q_SLOTS: |
|
98 | void handleAxisUpdated(); | |
|
98 | virtual void handleAxisUpdated(); | |
|
99 | 99 | void handleAxisCategoriesUpdated(); |
|
100 | 100 | void handleRangeChanged(qreal min , qreal max,int tickCount); |
|
101 | 101 | void handleGeometryChanged(const QRectF &size); |
|
102 | 102 | |
|
103 | 103 | private: |
|
104 | 104 | inline bool isEmpty(); |
|
105 | 105 | void createItems(int count); |
|
106 | 106 | void deleteItems(int count); |
|
107 | 107 | void updateLayout(QVector<qreal> &layout); |
|
108 | 108 | void axisSelected(); |
|
109 | 109 | |
|
110 | 110 | protected: |
|
111 | 111 | QAbstractAxis* m_chartAxis; |
|
112 | 112 | QRectF m_rect; |
|
113 | 113 | int m_labelsAngle; |
|
114 | 114 | QScopedPointer<QGraphicsItemGroup> m_grid; |
|
115 | 115 | QScopedPointer<QGraphicsItemGroup> m_shades; |
|
116 | 116 | QScopedPointer<QGraphicsItemGroup> m_labels; |
|
117 | 117 | QScopedPointer<QGraphicsItemGroup> m_axis; |
|
118 | 118 | QVector<qreal> m_layoutVector; |
|
119 | 119 | qreal m_min; |
|
120 | 120 | qreal m_max; |
|
121 | 121 | int m_ticksCount; |
|
122 | 122 | AxisAnimation *m_animation; |
|
123 | 123 | qreal m_minWidth; |
|
124 | 124 | qreal m_minHeight; |
|
125 | 125 | QFont m_font; |
|
126 | 126 | |
|
127 | 127 | friend class AxisAnimation; |
|
128 | 128 | friend class AxisItem; |
|
129 | 129 | |
|
130 | 130 | }; |
|
131 | 131 | |
|
132 | 132 | class AxisItem: public QGraphicsLineItem |
|
133 | 133 | { |
|
134 | 134 | |
|
135 | 135 | public: |
|
136 | 136 | explicit AxisItem(ChartAxis *axis, QGraphicsItem *parent = 0) : QGraphicsLineItem(parent), m_axis(axis) {} |
|
137 | 137 | |
|
138 | 138 | protected: |
|
139 | 139 | void mousePressEvent(QGraphicsSceneMouseEvent *event) |
|
140 | 140 | { |
|
141 | 141 | Q_UNUSED(event) |
|
142 | 142 | m_axis->axisSelected(); |
|
143 | 143 | } |
|
144 | 144 | |
|
145 | 145 | QRectF boundingRect() const |
|
146 | 146 | { |
|
147 | 147 | return shape().boundingRect(); |
|
148 | 148 | } |
|
149 | 149 | |
|
150 | 150 | QPainterPath shape() const |
|
151 | 151 | { |
|
152 | 152 | QPainterPath path = QGraphicsLineItem::shape(); |
|
153 | 153 | QRectF rect = path.boundingRect(); |
|
154 | 154 | path.addRect(rect.adjusted(0,0,m_axis->axisType()!=ChartAxis::X_AXIS?8:0,m_axis->axisType()!=ChartAxis::Y_AXIS?8:0)); |
|
155 | 155 | return path; |
|
156 | 156 | } |
|
157 | 157 | |
|
158 | 158 | private: |
|
159 | 159 | ChartAxis* m_axis; |
|
160 | 160 | |
|
161 | 161 | }; |
|
162 | 162 | |
|
163 | 163 | QTCOMMERCIALCHART_END_NAMESPACE |
|
164 | 164 | |
|
165 | 165 | #endif /* AXISITEM_H_ */ |
@@ -1,109 +1,119 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | #include "chartcategoriesaxisx_p.h" |
|
22 | 22 | #include "qabstractaxis.h" |
|
23 | 23 | #include "chartpresenter_p.h" |
|
24 | 24 | #include "chartanimator_p.h" |
|
25 | 25 | #include <QGraphicsLayout> |
|
26 | 26 | #include <QDebug> |
|
27 | 27 | #include <QFontMetrics> |
|
28 | 28 | #include <QBarCategoriesAxis> |
|
29 | 29 | |
|
30 | 30 | static int label_padding = 5; |
|
31 | 31 | |
|
32 | 32 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
33 | 33 | |
|
34 | 34 | ChartCategoriesAxisX::ChartCategoriesAxisX(QBarCategoriesAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter), |
|
35 | 35 | m_categoriesAxis(axis) |
|
36 | 36 | { |
|
37 | 37 | |
|
38 | 38 | } |
|
39 | 39 | |
|
40 | 40 | ChartCategoriesAxisX::~ChartCategoriesAxisX() |
|
41 | 41 | { |
|
42 | 42 | } |
|
43 | 43 | |
|
44 | 44 | QVector<qreal> ChartCategoriesAxisX::calculateLayout() const |
|
45 | 45 | { |
|
46 | 46 | Q_ASSERT(m_ticksCount>=2); |
|
47 | 47 | |
|
48 | 48 | QVector<qreal> points; |
|
49 | 49 | points.resize(m_ticksCount); |
|
50 | 50 | |
|
51 | 51 | // TODO: shift logic |
|
52 | 52 | const qreal deltaX = m_rect.width()/(m_ticksCount-1); |
|
53 | 53 | for (int i = 0; i < m_ticksCount; ++i) { |
|
54 | 54 | int x = i * deltaX + m_rect.left(); |
|
55 | 55 | points[i] = x; |
|
56 | 56 | } |
|
57 | 57 | return points; |
|
58 | 58 | } |
|
59 | 59 | |
|
60 | 60 | void ChartCategoriesAxisX::updateGeometry() |
|
61 | 61 | { |
|
62 | 62 | const QVector<qreal>& layout = ChartAxis::layout(); |
|
63 | 63 | |
|
64 | 64 | m_minWidth = 0; |
|
65 | 65 | m_minHeight = 0; |
|
66 | 66 | |
|
67 | 67 | if(layout.isEmpty()) return; |
|
68 | 68 | |
|
69 | 69 | QStringList ticksList; |
|
70 | 70 | |
|
71 | 71 | createCategoryLabels(ticksList,m_min,m_max,m_categoriesAxis->categories()); |
|
72 | 72 | |
|
73 | 73 | QList<QGraphicsItem *> lines = m_grid->childItems(); |
|
74 | 74 | QList<QGraphicsItem *> labels = m_labels->childItems(); |
|
75 | 75 | QList<QGraphicsItem *> shades = m_shades->childItems(); |
|
76 | 76 | QList<QGraphicsItem *> axis = m_axis->childItems(); |
|
77 | 77 | |
|
78 | 78 | Q_ASSERT(labels.size() == ticksList.size()); |
|
79 | 79 | Q_ASSERT(layout.size() == ticksList.size()); |
|
80 | 80 | |
|
81 | 81 | QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0)); |
|
82 | 82 | lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom()); |
|
83 | 83 | |
|
84 | 84 | for (int i = 0; i < layout.size(); ++i) { |
|
85 | 85 | QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i)); |
|
86 | 86 | lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom()); |
|
87 | 87 | QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i)); |
|
88 | 88 | if (i>=1) { |
|
89 | 89 | labelItem->setText(ticksList.at(i-1)); |
|
90 | 90 | const QRectF& rect = labelItem->boundingRect(); |
|
91 | 91 | QPointF center = rect.center(); |
|
92 | 92 | labelItem->setTransformOriginPoint(center.x(), center.y()); |
|
93 | 93 | labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding); |
|
94 | 94 | m_minWidth+=rect.width(); |
|
95 | 95 | m_minHeight=qMax(rect.height()+label_padding,m_minHeight); |
|
96 | 96 | }else{ |
|
97 | 97 | labelItem->setVisible(false); |
|
98 | 98 | } |
|
99 | 99 | |
|
100 | 100 | if ((i+1)%2 && i>1) { |
|
101 | 101 | QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1)); |
|
102 | 102 | rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height()); |
|
103 | 103 | } |
|
104 | 104 | lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1)); |
|
105 | 105 | lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5); |
|
106 | 106 | } |
|
107 | 107 | } |
|
108 | 108 | |
|
109 | void ChartCategoriesAxisX::handleAxisUpdated() | |
|
110 | { | |
|
111 | if(m_categoriesAxis->categories()!=m_categories) | |
|
112 | { | |
|
113 | m_categories=m_categoriesAxis->categories(); | |
|
114 | if(ChartAxis::layout().count()==m_categories.size()+1) updateGeometry(); | |
|
115 | } | |
|
116 | ChartAxis::handleAxisUpdated(); | |
|
117 | } | |
|
118 | ||
|
109 | 119 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -1,59 +1,62 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | // W A R N I N G |
|
22 | 22 | // ------------- |
|
23 | 23 | // |
|
24 | 24 | // This file is not part of the QtCommercial 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 CHARTCATEGORIESAXISX_H |
|
31 | 31 | #define CHARTCATEGORIESAXISX_H |
|
32 | 32 | |
|
33 | 33 | #include "chartaxis_p.h" |
|
34 | 34 | |
|
35 | 35 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
36 | 36 | |
|
37 | 37 | class QAbstractAxis; |
|
38 | 38 | class ChartPresenter; |
|
39 | 39 | class QBarCategoriesAxis; |
|
40 | 40 | |
|
41 | 41 | class ChartCategoriesAxisX : public ChartAxis |
|
42 | 42 | { |
|
43 | 43 | public: |
|
44 | 44 | ChartCategoriesAxisX(QBarCategoriesAxis *axis, ChartPresenter *presenter); |
|
45 | 45 | ~ChartCategoriesAxisX(); |
|
46 | 46 | |
|
47 | 47 | AxisType axisType() const { return X_AXIS;} |
|
48 | 48 | |
|
49 | 49 | protected: |
|
50 | 50 | QVector<qreal> calculateLayout() const; |
|
51 | 51 | void updateGeometry(); |
|
52 | Q_SLOTS | |
|
53 | void handleAxisUpdated(); | |
|
52 | 54 | |
|
53 | 55 | private: |
|
56 | QStringList m_categories; | |
|
54 | 57 | QBarCategoriesAxis *m_categoriesAxis; |
|
55 | 58 | }; |
|
56 | 59 | |
|
57 | 60 | QTCOMMERCIALCHART_END_NAMESPACE |
|
58 | 61 | |
|
59 | 62 | #endif /* CHARTCATEGORIESAXISX_H */ |
@@ -1,108 +1,120 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | #include "chartcategoriesaxisy_p.h" |
|
22 | 22 | #include "qabstractaxis.h" |
|
23 | 23 | #include "chartpresenter_p.h" |
|
24 | 24 | #include "chartanimator_p.h" |
|
25 | 25 | #include <QGraphicsLayout> |
|
26 | 26 | #include <QDebug> |
|
27 | 27 | #include <QFontMetrics> |
|
28 | 28 | #include <QBarCategoriesAxis> |
|
29 | 29 | |
|
30 | 30 | static int label_padding = 5; |
|
31 | 31 | |
|
32 | 32 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
33 | 33 | |
|
34 | 34 | ChartCategoriesAxisY::ChartCategoriesAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter) |
|
35 | 35 | { |
|
36 | 36 | } |
|
37 | 37 | |
|
38 | 38 | ChartCategoriesAxisY::~ChartCategoriesAxisY() |
|
39 | 39 | { |
|
40 | 40 | } |
|
41 | 41 | |
|
42 | 42 | QVector<qreal> ChartCategoriesAxisY::calculateLayout() const |
|
43 | 43 | { |
|
44 | 44 | Q_ASSERT(m_ticksCount>=2); |
|
45 | 45 | |
|
46 | 46 | QVector<qreal> points; |
|
47 | 47 | points.resize(m_ticksCount); |
|
48 | 48 | |
|
49 | 49 | const qreal deltaY = m_rect.height()/(m_ticksCount-1); |
|
50 | 50 | for (int i = 0; i < m_ticksCount; ++i) { |
|
51 | 51 | int y = i * -deltaY + m_rect.bottom(); |
|
52 | 52 | points[i] = y; |
|
53 | 53 | } |
|
54 | 54 | |
|
55 | 55 | return points; |
|
56 | 56 | } |
|
57 | 57 | |
|
58 | 58 | void ChartCategoriesAxisY::updateGeometry() |
|
59 | 59 | { |
|
60 | 60 | const QVector<qreal>& layout = ChartAxis::layout(); |
|
61 | 61 | |
|
62 | 62 | m_minWidth = 0; |
|
63 | 63 | m_minHeight = 0; |
|
64 | 64 | |
|
65 | 65 | if(layout.isEmpty()) return; |
|
66 | 66 | |
|
67 | 67 | QStringList ticksList; |
|
68 | 68 | |
|
69 | 69 | createCategoryLabels(ticksList,m_min,m_max,m_categoriesAxis->categories()); |
|
70 | 70 | |
|
71 | 71 | QList<QGraphicsItem *> lines = m_grid->childItems(); |
|
72 | 72 | QList<QGraphicsItem *> labels = m_labels->childItems(); |
|
73 | 73 | QList<QGraphicsItem *> shades = m_shades->childItems(); |
|
74 | 74 | QList<QGraphicsItem *> axis = m_axis->childItems(); |
|
75 | 75 | |
|
76 | 76 | Q_ASSERT(labels.size() == ticksList.size()); |
|
77 | 77 | Q_ASSERT(layout.size() == ticksList.size()); |
|
78 | 78 | |
|
79 | 79 | QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0)); |
|
80 | 80 | lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom()); |
|
81 | 81 | |
|
82 | 82 | for (int i = 0; i < layout.size(); ++i) { |
|
83 | 83 | QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i)); |
|
84 | 84 | lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom()); |
|
85 | 85 | QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i)); |
|
86 | 86 | if(i>=1){ |
|
87 | 87 | labelItem->setText(ticksList.at(i-1)); |
|
88 | 88 | const QRectF& rect = labelItem->boundingRect(); |
|
89 | 89 | QPointF center = rect.center(); |
|
90 | 90 | labelItem->setTransformOriginPoint(center.x(), center.y()); |
|
91 | 91 | labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding); |
|
92 | 92 | m_minWidth+=rect.width(); |
|
93 | 93 | m_minHeight=qMax(rect.height()+label_padding,m_minHeight); |
|
94 | 94 | }else{ |
|
95 | 95 | labelItem->setVisible(false); |
|
96 | 96 | } |
|
97 | 97 | |
|
98 | 98 | |
|
99 | 99 | if ((i+1)%2 && i>1) { |
|
100 | 100 | QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1)); |
|
101 | 101 | rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height()); |
|
102 | 102 | } |
|
103 | 103 | lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1)); |
|
104 | 104 | lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5); |
|
105 | 105 | } |
|
106 | 106 | } |
|
107 | 107 | |
|
108 | ||
|
109 | void ChartCategoriesAxisY::handleAxisUpdated() | |
|
110 | { | |
|
111 | ||
|
112 | if(m_categoriesAxis->categories()!=m_categories) | |
|
113 | { | |
|
114 | m_categories=m_categoriesAxis->categories(); | |
|
115 | if(ChartAxis::layout().count()==m_categories.size()+1) updateGeometry(); | |
|
116 | } | |
|
117 | ChartAxis::handleAxisUpdated(); | |
|
118 | } | |
|
119 | ||
|
108 | 120 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -1,59 +1,61 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | // W A R N I N G |
|
22 | 22 | // ------------- |
|
23 | 23 | // |
|
24 | 24 | // This file is not part of the QtCommercial 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 CHARTCATEGORIESAXISY_H |
|
31 | 31 | #define CHARTCATEGORIESAXISY_H |
|
32 | 32 | |
|
33 | 33 | #include "chartaxis_p.h" |
|
34 | 34 | |
|
35 | 35 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
36 | 36 | |
|
37 | 37 | class QAbstractAxis; |
|
38 | 38 | class QBarCategoriesAxis; |
|
39 | 39 | class ChartPresenter; |
|
40 | 40 | |
|
41 | 41 | class ChartCategoriesAxisY : public ChartAxis |
|
42 | 42 | { |
|
43 | 43 | public: |
|
44 | 44 | ChartCategoriesAxisY(QAbstractAxis *axis, ChartPresenter *presenter); |
|
45 | 45 | ~ChartCategoriesAxisY(); |
|
46 | 46 | |
|
47 | 47 | AxisType axisType() const { return Y_AXIS;} |
|
48 | 48 | |
|
49 | 49 | protected: |
|
50 | 50 | QVector<qreal> calculateLayout() const; |
|
51 | 51 | void updateGeometry(); |
|
52 | ||
|
52 | Q_SLOTS | |
|
53 | void handleAxisUpdated(); | |
|
53 | 54 | private: |
|
55 | QStringList m_categories; | |
|
54 | 56 | QBarCategoriesAxis *m_categoriesAxis; |
|
55 | 57 | }; |
|
56 | 58 | |
|
57 | 59 | QTCOMMERCIALCHART_END_NAMESPACE |
|
58 | 60 | |
|
59 | 61 | #endif /* CHARTCATEGORIESAXISY_H */ |
@@ -1,379 +1,383 | |||
|
1 | 1 | /**************************************************************************** |
|
2 | 2 | ** |
|
3 | 3 | ** Copyright (C) 2012 Digia Plc |
|
4 | 4 | ** All rights reserved. |
|
5 | 5 | ** For any questions to Digia, please use contact form at http://qt.digia.com |
|
6 | 6 | ** |
|
7 | 7 | ** This file is part of the Qt Commercial Charts Add-on. |
|
8 | 8 | ** |
|
9 | 9 | ** $QT_BEGIN_LICENSE$ |
|
10 | 10 | ** Licensees holding valid Qt Commercial licenses may use this file in |
|
11 | 11 | ** accordance with the Qt Commercial License Agreement provided with the |
|
12 | 12 | ** Software or, alternatively, in accordance with the terms contained in |
|
13 | 13 | ** a written agreement between you and Digia. |
|
14 | 14 | ** |
|
15 | 15 | ** If you have questions regarding the use of this file, please use |
|
16 | 16 | ** contact form at http://qt.digia.com |
|
17 | 17 | ** $QT_END_LICENSE$ |
|
18 | 18 | ** |
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | #include "qbarcategoriesaxis.h" |
|
22 | 22 | #include "qbarcategoriesaxis_p.h" |
|
23 | 23 | #include "chartcategoriesaxisx_p.h" |
|
24 | 24 | #include "chartcategoriesaxisy_p.h" |
|
25 | 25 | #include <qmath.h> |
|
26 | 26 | #include <QDebug> |
|
27 | 27 | |
|
28 | 28 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
29 | 29 | /*! |
|
30 | 30 | \class QBarCategoriesAxis |
|
31 | 31 | \brief The QBarCategoriesAxis class is used for manipulating chart's axis. |
|
32 | 32 | \mainclass |
|
33 | 33 | |
|
34 | 34 | BarCategoriesAxis can be setup to show axis line with tick marks, grid lines and shades. |
|
35 | 35 | Categories are drawn between ticks. |
|
36 | 36 | */ |
|
37 | 37 | |
|
38 | 38 | /*! |
|
39 | 39 | \qmlclass BarCategoriesAxis QBarCategoriesAxis |
|
40 | 40 | \brief The Axis element is used for manipulating chart's axes. |
|
41 | 41 | |
|
42 | 42 | Axis can be setup to show axis line with tick marks, grid lines and shades. |
|
43 | 43 | Categories are drawn between ticks. |
|
44 | 44 | |
|
45 | 45 | To access BarCategoriesAxis you can use ChartView API. For example: |
|
46 | 46 | \code |
|
47 | 47 | ChartView { |
|
48 | 48 | BarCategoriesAxis { |
|
49 | 49 | id: categoryAxis |
|
50 | 50 | categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun" ] |
|
51 | 51 | } |
|
52 | 52 | // Add a few series... |
|
53 | 53 | } |
|
54 | 54 | \endcode |
|
55 | 55 | */ |
|
56 | 56 | |
|
57 | 57 | /*! |
|
58 | 58 | \property QBarCategoriesAxis::categories |
|
59 | 59 | Defines the categories of axis |
|
60 | 60 | */ |
|
61 | 61 | /*! |
|
62 | 62 | \qmlproperty QStringList BarCategoriesAxis::categories |
|
63 | 63 | Defines the categories of axis |
|
64 | 64 | */ |
|
65 | 65 | |
|
66 | 66 | /*! |
|
67 | 67 | \property QBarCategoriesAxis::min |
|
68 | 68 | Defines the minimum value on the axis. |
|
69 | 69 | */ |
|
70 | 70 | /*! |
|
71 | 71 | \qmlproperty real BarCategoriesAxis::min |
|
72 | 72 | Defines the minimum value on the axis. |
|
73 | 73 | */ |
|
74 | 74 | |
|
75 | 75 | /*! |
|
76 | 76 | \property QBarCategoriesAxis::max |
|
77 | 77 | Defines the maximum value on the axis. |
|
78 | 78 | */ |
|
79 | 79 | /*! |
|
80 | 80 | \qmlproperty real BarCategoriesAxis::max |
|
81 | 81 | Defines the maximum value on the axis. |
|
82 | 82 | */ |
|
83 | 83 | |
|
84 | 84 | /*! |
|
85 | 85 | \fn void QBarCategoriesAxis::minChanged(const QString &min) |
|
86 | 86 | Axis emits signal when \a min of axis has changed. |
|
87 | 87 | */ |
|
88 | 88 | |
|
89 | 89 | /*! |
|
90 | 90 | \fn void QBarCategoriesAxis::maxChanged(const QString &max) |
|
91 | 91 | Axis emits signal when \a max of axis has changed. |
|
92 | 92 | */ |
|
93 | 93 | |
|
94 | 94 | /*! |
|
95 | 95 | \fn void QBarCategoriesAxis::rangeChanged(const QString &min, const QString &max) |
|
96 | 96 | Axis emits signal when \a min or \a max of axis has changed. |
|
97 | 97 | */ |
|
98 | 98 | |
|
99 | 99 | /*! |
|
100 | 100 | Constructs an axis object which is a child of \a parent. |
|
101 | 101 | */ |
|
102 | 102 | QBarCategoriesAxis::QBarCategoriesAxis(QObject *parent): |
|
103 | 103 | QAbstractAxis(*new QBarCategoriesAxisPrivate(this),parent) |
|
104 | 104 | { |
|
105 | 105 | } |
|
106 | 106 | |
|
107 | 107 | /*! |
|
108 | 108 | Destroys the object |
|
109 | 109 | */ |
|
110 | 110 | QBarCategoriesAxis::~QBarCategoriesAxis() |
|
111 | 111 | { |
|
112 | 112 | } |
|
113 | 113 | |
|
114 | 114 | /*! |
|
115 | 115 | \internal |
|
116 | 116 | */ |
|
117 | 117 | QBarCategoriesAxis::QBarCategoriesAxis(QBarCategoriesAxisPrivate &d,QObject *parent):QAbstractAxis(d,parent) |
|
118 | 118 | { |
|
119 | 119 | |
|
120 | 120 | } |
|
121 | 121 | |
|
122 | 122 | /*! |
|
123 | 123 | Appends \a categories to axis |
|
124 | 124 | */ |
|
125 | 125 | void QBarCategoriesAxis::append(const QStringList &categories) |
|
126 | 126 | { |
|
127 | 127 | if(categories.isEmpty()) return; |
|
128 | 128 | |
|
129 | 129 | Q_D(QBarCategoriesAxis); |
|
130 | 130 | if (d->m_categories.isEmpty()) { |
|
131 | 131 | d->m_categories.append(categories); |
|
132 | 132 | setRange(categories.first(),categories.last()); |
|
133 | 133 | }else{ |
|
134 | 134 | d->m_categories.append(categories); |
|
135 | 135 | } |
|
136 | ||
|
136 | emit d->updated(); | |
|
137 | 137 | emit categoriesChanged(); |
|
138 | 138 | } |
|
139 | 139 | |
|
140 | 140 | /*! |
|
141 | 141 | Appends \a category to axis |
|
142 | 142 | */ |
|
143 | 143 | void QBarCategoriesAxis::append(const QString &category) |
|
144 | 144 | { |
|
145 | 145 | Q_D(QBarCategoriesAxis); |
|
146 | 146 | if (d->m_categories.isEmpty()) { |
|
147 | 147 | d->m_categories.append(category); |
|
148 | 148 | setRange(category,category); |
|
149 | 149 | }else{ |
|
150 | 150 | d->m_categories.append(category); |
|
151 | 151 | } |
|
152 | emit d->updated(); | |
|
152 | 153 | emit categoriesChanged(); |
|
153 | 154 | } |
|
154 | 155 | |
|
155 | 156 | /*! |
|
156 | 157 | Removes \a category from axis |
|
157 | 158 | */ |
|
158 | 159 | void QBarCategoriesAxis::remove(const QString &category) |
|
159 | 160 | { |
|
160 | 161 | Q_D(QBarCategoriesAxis); |
|
161 | 162 | if (d->m_categories.contains(category)) { |
|
162 | 163 | d->m_categories.removeAt(d->m_categories.indexOf(category)); |
|
163 | 164 | setRange(d->m_categories.first(),d->m_categories.last()); |
|
165 | emit d->updated(); | |
|
164 | 166 | emit categoriesChanged(); |
|
165 | 167 | } |
|
166 | 168 | } |
|
167 | 169 | |
|
168 | 170 | /*! |
|
169 | 171 | Inserts \a category to axis at \a index |
|
170 | 172 | */ |
|
171 | 173 | void QBarCategoriesAxis::insert(int index, const QString &category) |
|
172 | 174 | { |
|
173 | 175 | Q_D(QBarCategoriesAxis); |
|
174 | 176 | if (d->m_categories.isEmpty()) { |
|
175 | 177 | d->m_categories.insert(index,category); |
|
176 | 178 | setRange(category,category); |
|
177 | 179 | }else{ |
|
178 | 180 | d->m_categories.insert(index,category); |
|
179 | 181 | } |
|
182 | emit d->updated(); | |
|
180 | 183 | emit categoriesChanged(); |
|
181 | 184 | } |
|
182 | 185 | |
|
183 | 186 | /*! |
|
184 | 187 | Removes all categories. |
|
185 | 188 | */ |
|
186 | 189 | void QBarCategoriesAxis::clear() |
|
187 | 190 | { |
|
188 | 191 | Q_D(QBarCategoriesAxis); |
|
189 | 192 | d->m_categories.clear(); |
|
190 | 193 | setRange(QString::null,QString::null); |
|
194 | emit d->updated(); | |
|
191 | 195 | emit categoriesChanged(); |
|
192 | 196 | } |
|
193 | 197 | |
|
194 | 198 | void QBarCategoriesAxis::setCategories(const QStringList &categories) |
|
195 | 199 | { |
|
196 | 200 | Q_D(QBarCategoriesAxis); |
|
197 | 201 | if(d->m_categories!=categories){ |
|
198 | 202 | d->m_categories = categories; |
|
199 | 203 | setRange(categories.first(),categories.last()); |
|
204 | emit d->updated(); | |
|
200 | 205 | emit categoriesChanged(); |
|
201 | 206 | } |
|
202 | 207 | } |
|
203 | 208 | |
|
204 | 209 | QStringList QBarCategoriesAxis::categories() |
|
205 | 210 | { |
|
206 | 211 | Q_D(QBarCategoriesAxis); |
|
207 | 212 | return d->m_categories; |
|
208 | 213 | } |
|
209 | 214 | |
|
210 | 215 | /*! |
|
211 | 216 | Returns number of categories. |
|
212 | 217 | */ |
|
213 | 218 | int QBarCategoriesAxis::count() const |
|
214 | 219 | { |
|
215 | 220 | Q_D(const QBarCategoriesAxis); |
|
216 | 221 | return d->m_categories.count(); |
|
217 | 222 | } |
|
218 | 223 | |
|
219 | 224 | /*! |
|
220 | 225 | Returns category at \a index. Index must be valid. |
|
221 | 226 | */ |
|
222 | 227 | QString QBarCategoriesAxis::at(int index) const |
|
223 | 228 | { |
|
224 | 229 | Q_D(const QBarCategoriesAxis); |
|
225 | 230 | return d->m_categories.at(index); |
|
226 | 231 | } |
|
227 | 232 | |
|
228 | 233 | /*! |
|
229 | 234 | Sets minimum category to \a min. |
|
230 | 235 | */ |
|
231 | 236 | void QBarCategoriesAxis::setMin(const QString& min) |
|
232 | 237 | { |
|
233 | 238 | Q_D(QBarCategoriesAxis); |
|
234 | 239 | setRange(min,d->m_maxCategory); |
|
235 | 240 | } |
|
236 | 241 | |
|
237 | 242 | /*! |
|
238 | 243 | Returns minimum category. |
|
239 | 244 | */ |
|
240 | 245 | QString QBarCategoriesAxis::min() const |
|
241 | 246 | { |
|
242 | 247 | Q_D(const QBarCategoriesAxis); |
|
243 | 248 | return d->m_minCategory; |
|
244 | 249 | } |
|
245 | 250 | |
|
246 | 251 | /*! |
|
247 | 252 | Sets maximum category to \a max. |
|
248 | 253 | */ |
|
249 | 254 | void QBarCategoriesAxis::setMax(const QString& max) |
|
250 | 255 | { |
|
251 | 256 | Q_D(QBarCategoriesAxis); |
|
252 | 257 | setRange(d->m_minCategory,max); |
|
253 | 258 | } |
|
254 | 259 | |
|
255 | 260 | /*! |
|
256 | 261 | Returns maximum category |
|
257 | 262 | */ |
|
258 | 263 | QString QBarCategoriesAxis::max() const |
|
259 | 264 | { |
|
260 | 265 | Q_D(const QBarCategoriesAxis); |
|
261 | 266 | return d->m_maxCategory; |
|
262 | 267 | } |
|
263 | 268 | |
|
264 | 269 | /*! |
|
265 | 270 | Sets range from \a minCategory to \a maxCategory |
|
266 | 271 | */ |
|
267 | 272 | void QBarCategoriesAxis::setRange(const QString& minCategory, const QString& maxCategory) |
|
268 | 273 | { |
|
269 | 274 | Q_D(QBarCategoriesAxis); |
|
270 | 275 | |
|
271 | 276 | int minIndex = d->m_categories.indexOf(minCategory); |
|
272 | 277 | if (minIndex == -1) { |
|
273 | 278 | return; |
|
274 | 279 | } |
|
275 | 280 | int maxIndex = d->m_categories.indexOf(maxCategory); |
|
276 | 281 | if (maxIndex == -1) { |
|
277 | 282 | return; |
|
278 | 283 | } |
|
279 | 284 | |
|
280 | 285 | if (maxIndex <= minIndex) { |
|
281 | 286 | // max must be greater than min |
|
282 | 287 | return; |
|
283 | 288 | } |
|
284 | 289 | |
|
285 | 290 | bool changed = false; |
|
286 | if (!qFuzzyIsNull(d->m_min - (minIndex))) { | |
|
291 | if (!qFuzzyIsNull(d->m_min - (minIndex))||d->m_minCategory!=minCategory) { | |
|
287 | 292 | d->m_minCategory = minCategory; |
|
288 | 293 | d->m_min = minIndex; |
|
289 | 294 | emit minChanged(minCategory); |
|
290 | 295 | changed = true; |
|
291 | 296 | } |
|
292 | 297 | |
|
293 | if (!qFuzzyIsNull(d->m_max - (maxIndex))) { | |
|
298 | if (!qFuzzyIsNull(d->m_max - (maxIndex))||d->m_maxCategory!=maxCategory ) { | |
|
294 | 299 | d->m_max = maxIndex; |
|
295 | 300 | d->m_maxCategory = maxCategory; |
|
296 | 301 | emit maxChanged(maxCategory); |
|
297 | 302 | changed = true; |
|
298 | 303 | } |
|
299 | 304 | |
|
300 | 305 | if (changed) { |
|
301 | 306 | d->emitRange(); |
|
302 | emit categoriesChanged(); | |
|
303 | 307 | } |
|
304 | 308 | } |
|
305 | 309 | |
|
306 | 310 | /*! |
|
307 | 311 | Returns the type of the axis |
|
308 | 312 | */ |
|
309 | 313 | QAbstractAxis::AxisType QBarCategoriesAxis::type() const |
|
310 | 314 | { |
|
311 | 315 | return AxisTypeCategories; |
|
312 | 316 | } |
|
313 | 317 | |
|
314 | 318 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
315 | 319 | |
|
316 | 320 | QBarCategoriesAxisPrivate::QBarCategoriesAxisPrivate(QBarCategoriesAxis* q): |
|
317 | 321 | QAbstractAxisPrivate(q) |
|
318 | 322 | { |
|
319 | 323 | |
|
320 | 324 | } |
|
321 | 325 | |
|
322 | 326 | QBarCategoriesAxisPrivate::~QBarCategoriesAxisPrivate() |
|
323 | 327 | { |
|
324 | 328 | |
|
325 | 329 | } |
|
326 | 330 | |
|
327 | 331 | void QBarCategoriesAxisPrivate::setMin(const QVariant &min) |
|
328 | 332 | { |
|
329 | 333 | setRange(min,m_maxCategory); |
|
330 | 334 | } |
|
331 | 335 | |
|
332 | 336 | void QBarCategoriesAxisPrivate::setMax(const QVariant &max) |
|
333 | 337 | { |
|
334 | 338 | setRange(m_minCategory,max); |
|
335 | 339 | } |
|
336 | 340 | |
|
337 | 341 | void QBarCategoriesAxisPrivate::setRange(const QVariant &min, const QVariant &max) |
|
338 | 342 | { |
|
339 | 343 | Q_Q(QBarCategoriesAxis); |
|
340 | 344 | QString value1 = min.toString(); |
|
341 | 345 | QString value2 = max.toString(); |
|
342 | 346 | q->setRange(value1,value2); |
|
343 | 347 | } |
|
344 | 348 | |
|
345 | 349 | int QBarCategoriesAxisPrivate::ticksCount() const |
|
346 | 350 | { |
|
347 | 351 | return m_categories.count()+1; |
|
348 | 352 | } |
|
349 | 353 | |
|
350 | 354 | void QBarCategoriesAxisPrivate::handleAxisRangeChanged(qreal min, qreal max,int count) |
|
351 | 355 | { |
|
352 | 356 | m_min = min; |
|
353 | 357 | m_max = max; |
|
354 | 358 | m_ticksCount = count; |
|
355 | 359 | } |
|
356 | 360 | |
|
357 | 361 | ChartAxis* QBarCategoriesAxisPrivate::createGraphics(ChartPresenter* presenter) |
|
358 | 362 | { |
|
359 | 363 | Q_Q( QBarCategoriesAxis); |
|
360 | 364 | if(m_orientation == Qt::Vertical){ |
|
361 | 365 | return new ChartCategoriesAxisY(q,presenter); |
|
362 | 366 | }else{ |
|
363 | 367 | return new ChartCategoriesAxisX(q,presenter); |
|
364 | 368 | } |
|
365 | 369 | } |
|
366 | 370 | |
|
367 | 371 | void QBarCategoriesAxisPrivate::emitRange() |
|
368 | 372 | { |
|
369 | 373 | Q_Q( QBarCategoriesAxis); |
|
370 | 374 | if(!q->signalsBlocked()) { |
|
371 | 375 | emit changed(m_min -0.5, m_max +0.5, qCeil(m_max + 0.5) -qCeil(m_min - 0.5) +1, false); |
|
372 | 376 | } |
|
373 | 377 | } |
|
374 | 378 | |
|
375 | 379 | |
|
376 | 380 | #include "moc_qbarcategoriesaxis.cpp" |
|
377 | 381 | #include "moc_qbarcategoriesaxis_p.cpp" |
|
378 | 382 | |
|
379 | 383 | QTCOMMERCIALCHART_END_NAMESPACE |
General Comments 0
You need to be logged in to leave comments.
Login now