##// END OF EJS Templates
Qml improved and changes on Box item drawing...
Mika Salmela -
r2528:2219fb4b2e1c
parent child
Show More
@@ -0,0 +1,31
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 import QtQuick 1.1
22 import QtCommercial.Chart 1.1
23
24 BoxSet {
25 id: myNewBox
26 label: "Foo"
27 values: [5, 6, 7, 8, 9]
28 Component.onCompleted: {
29 console.log("BoxSet completed")
30 }
31 }
@@ -37,7 +37,7 int main(int argc, char *argv[])
37 37
38 38 //![2]
39 39 QBoxPlotSeries *series = new QBoxPlotSeries();
40 series->setName("Box & Whiskers");
40 series->setName("Cargotec");
41 41 //![2]
42 42
43 43 QFile stockData(":stock");
@@ -55,14 +55,13 int main(int argc, char *argv[])
55 55 //![3]
56 56 QChart *chart = new QChart();
57 57 chart->addSeries(series);
58 chart->setTitle("Simple boxplotchart example");
58 chart->setTitle("Cargotec's share deviation 2012")
59 59 chart->setAnimationOptions(QChart::SeriesAnimations);
60 60 //![3]
61 61
62 62 //![4]
63 QBarCategoryAxis *axis = new QBarCategoryAxis();
64 63 chart->createDefaultAxes();
65 chart->setAxisX(axis, series);
64 chart->axisY()->setMin(15.0);
66 65 //![4]
67 66
68 67 //![5]
@@ -1,8 +1,24
1 Jan 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0
1 #Jan 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0
2 2 #0 1 2 3 4 5 6 7 8 9
3 Feb 4.3 5.1 3.9 4.5 4.4 4.9 5.0 4.7 4.1 4.6 4.4 4.3 4.8 4.4 4.2 4.5 4.4
4 Mar 1.0 1.2 2.0 2.4 2.5 3.0 3.5 3.7 4.0 4.7 5.0
5 Apr 4.6 4.7 5.2 7.3 8.4 8.8 9.1 8.3 7.4 6.4 5.3
6 May 3.5 7.2 5.4 6.3 7.4 8.3 8.8 3.3 5.4 5.7 3.9
3 #Feb 4.3 5.1 3.2 4.5 4.4 4.9 5.0 4.7 4.1 4.6 4.4 4.3 4.8 4.4 4.2 4.5 4.4
4 #Mar 1.0 1.2 2.0 2.4 2.5 3.0 3.5 3.7 4.0 4.7 5.0
5 #Apr 4.6 4.7 5.2 7.3 8.4 8.8 9.1 8.3 7.4 6.4 5.3
6 #May 3.5 7.2 5.4 6.3 7.4 8.3 8.8 3.3 5.4 5.7 3.9
7 #Jun 2.5 4.6 7.3 4.6 7.8 9.0 7.4
8 #Jul 4.7 3.8 5.7 6.4 6.9 4.6 7.2 5.9
7 9 #0 1 2 3 4 5 6 7 8 9 10
8 10 # * * *
11 #Top 18.0 18.5 19.0 19.5 19.7 20.0 20.5 20.75 21.0 21.5 22.1
12 #Tok 19.0 19.5 21.0 21.5 21.7 22.0 22.5 22.75 23.0 23.5 24.0
13 Jan 27,74 27,28 27,86 28,05 28,64 27,47 28,30 28,22 28,72 26,50 26,62 26,50 26,15 26,47 26,41 25,78 24,82 24,89 24,88 24,60 23,85
14 Feb 31,79 30,62 30,67 31,37 31,16 31,22 32,02 32,70 31,60 31,24 30,98 30,79 31,10 30,79 31,53 30,92 30,00 30,58 30,37 29,40 28,60
15 Mar 28,64 28,34 29,13 29,43 30,75 29,77 29,72 30,52 31,12 33,05 32,51 32,69 31,83 32,47 31,41 31,39 31,78 30,08 29,46 31,58 31,39 31,41
16 Apr 25,96 26,62 26,19 30,37 28,78 27,50 28,90 28,40 28,86 28,90 27,91 27,32 27,99 26,86 26,68 27,57 27,50 28,96 28,50
17 May 20,85 21,08 21,98 21,61 21,45 21,73 21,71 22,27 21,14 20,65 21,95 22,23 23,17 24,26 24,17 22,97 23,53 24,49 24,51 25,46 25,65
18 Jun 18,08 17,19 17,36 17,21 17,31 18,19 18,30 17,53 17,35 17,80 17,17 16,95 18,25 20,52 20,61 21,40 20,45 19,43 19,11 19,74
19 Jul 17,75 18,24 17,57 16,53 15,98 16,06 16,64 17,69 17,91 18,00 18,03 18,14 18,10 17,86 18,12 18,53 18,43 18,30 19,03 18,76 18,79 18,33
20 Aug 18,69 18,54 18,39 18,49 18,96 18,72 19,25 19,70 20,13 19,74 19,27 18,25 17,72 18,02 18,20 18,24 18,60 18,22 18,60 17,98 17,27 16,70 17,19
21 Sep 18,35 18,82 18,96 19,96 19,75 20,55 20,68 21,19 21,14 21,48 21,45 20,74 20,97 20,18 19,66 19,54 18,89 18,39 18,26 18,86
22 Oct 16,95 16,80 16,45 16,89 17,38 17,12 16,85 17,59 17,65 17,46 17,43 17,30 17,87 18,61 18,55 18,59 19,27 19,54 20,02 19,23 18,05 18,52 18,71
23 Now 19,36 19,29 18,22 18,74 19,05 19,13 18,67 18,19 17,94 18,04 17,49 17,53 17,64 18,00 18,21 18,19 18,30 18,11 18,17 17,76 17,80 17,52
24 Dec 19,95 20,19 20,15 20,42 20,39 20,65 20,39 19,86 19,48 19,70 19,94 19,82 20,25 20,21 19,63 19,55
@@ -34,15 +34,45 ChartView {
34 34 BoxPlotSeries {
35 35 id: plotSeries
36 36 name: "Income"
37 axisX: BarCategoryAxis { categories: ["Jan", "Feb", "Mar", "Apr", "May"] }
37 //axisX: BarCategoryAxis { categories: ["Jan", "Feb", "Mar", "Apr", "May"] }
38 38 BoxSet { values: [3, 4, 4.4, 6, 7] }
39 BoxSet { values: [5, 6, 7.5, 8, 12] }
40 BoxSet { values: [2, 5, 5.7, 8, 9] }
41 BoxSet { values: [5, 6, 6.8, 7, 8] }
42 BoxSet { values: [4, 5, 5.2, 6, 7] }
39 BoxSet { label: "Tok"; values: [5, 6, 7.5, 8, 12] }
40 BoxSet { label: "Kol"; values: [2, 5, 5.7, 8, 9] }
41 BoxSet { label: "Nel"; values: [5, 6, 6.8, 7, 8] }
42 BoxSet { label: "Vii"; values: [4, 5, 5.2, 6, 7] }
43 43 }
44 44 //![2]
45 45
46 Rectangle {
47 id: moreButton
48 width: 50
49 height: 50
50 color: "gray"
51 MouseArea {
52 anchors.fill: parent
53 onClicked: {
54 var com = Qt.createComponent("box.qml")
55 if (com.status == Component.Ready) {
56 var obj = com.createObject(moreButton)
57 obj.lowerExtreme = 1.2
58 console.log("lowerExtreme = " + obj.lowerExtreme)
59 obj.lowerQuartile = 2.2
60 console.log("lowerQuartile = " + obj.lowerQuartile)
61 obj.median = 3.2
62 console.log("median = " + obj.median)
63 obj.upperQuartile = 4.2
64 console.log("upperQuartile = " + obj.upperQuartile)
65 obj.upperExtreme = 5.2
66 console.log("upperExtreme = " + obj.upperExtreme)
67 obj.label = "mik"
68 console.log("label = " + obj.label)
69 plotSeries.append(obj)
70 } else {
71 console.log(com.errorString())
72 }
73 }
74 }
75 }
46 76
47 77 //![3]
48 78 }
@@ -8,4 +8,5 SOURCES += main.cpp
8 8 include(qmlapplicationviewer/qmlapplicationviewer.pri)
9 9
10 10 OTHER_FILES += \
11 qml/qmlboxplot/main.qml
11 qml/qmlboxplot/main.qml \
12 qml/qmlboxplot/box.qml
@@ -1,5 +1,6
1 1 <RCC>
2 2 <qresource prefix="/">
3 3 <file>qml/qmlboxplot/main.qml</file>
4 <file>qml/qmlboxplot/box.qml</file>
4 5 </qresource>
5 6 </RCC>
@@ -21,16 +21,15
21 21 #include "declarativebarseries.h"
22 22 #include "declarativeboxplotseries.h"
23 23 #include "qboxset.h"
24 #include "qvbarmodelmapper.h"
25 #include "qhbarmodelmapper.h"
24 #include "qvboxplotmodelmapper.h"
26 25
27 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 27
29 DeclarativeBoxSet::DeclarativeBoxSet(QObject *parent)
30 : QBoxSet("", parent)
28 DeclarativeBoxSet::DeclarativeBoxSet(const QString label, QObject *parent)
29 : QBoxSet(label, parent)
31 30 {
32 31 connect(this, SIGNAL(valuesAdded(int,int)), this, SLOT(handleCountChanged(int,int)));
33 connect(this, SIGNAL(valuesRemoved(int,int)), this, SLOT(handleCountChanged(int,int)));
32 //connect(this, SIGNAL(valuesRemoved(int,int)), this, SLOT(handleCountChanged(int,int)));
34 33 }
35 34
36 35 void DeclarativeBoxSet::handleCountChanged(int index, int count)
@@ -56,6 +55,7 void DeclarativeBoxSet::setValues(QVariantList values)
56 55 }
57 56 }
58 57
58 // Declarative box&whiskers series =====================================================
59 59
60 60 DeclarativeBoxPlotSeries::DeclarativeBoxPlotSeries(QDeclarativeItem *parent) :
61 61 QBoxPlotSeries(parent),
@@ -76,13 +76,13 void DeclarativeBoxPlotSeries::componentComplete()
76 76 foreach (QObject *child, children()) {
77 77 if (qobject_cast<DeclarativeBoxSet *>(child)) {
78 78 QBoxPlotSeries::append(qobject_cast<DeclarativeBoxSet *>(child));
79 } else if (qobject_cast<QVBarModelMapper *>(child)) {
80 QVBarModelMapper *mapper = qobject_cast<QVBarModelMapper *>(child);
79 } else if (qobject_cast<QVBoxPlotModelMapper *>(child)) {
80 QVBoxPlotModelMapper *mapper = qobject_cast<QVBoxPlotModelMapper *>(child);
81 mapper->setSeries(this);
82 }// else if (qobject_cast<QHBarModelMapper *>(child)) { // TODO: Horisontal
83 //QHBarModelMapper *mapper = qobject_cast<QHBarModelMapper *>(child); //TODO
81 84 //mapper->setSeries(this);
82 } else if (qobject_cast<QHBarModelMapper *>(child)) {
83 QHBarModelMapper *mapper = qobject_cast<QHBarModelMapper *>(child);
84 //mapper->setSeries(this);
85 }
85 //}
86 86 }
87 87 }
88 88
@@ -100,6 +100,7 void DeclarativeBoxPlotSeries::appendSeriesChildren(QDeclarativeListProperty<QOb
100 100
101 101 DeclarativeBoxSet *DeclarativeBoxPlotSeries::at(int index)
102 102 {
103 qDebug() << "DeclarativeBoxPlotSeries::at";
103 104 QList<QBoxSet *> setList = boxSets();
104 105 if (index >= 0 && index < setList.count())
105 106 return qobject_cast<DeclarativeBoxSet *>(setList[index]);
@@ -107,9 +108,9 DeclarativeBoxSet *DeclarativeBoxPlotSeries::at(int index)
107 108 return 0;
108 109 }
109 110
110 DeclarativeBoxSet *DeclarativeBoxPlotSeries::insert(int index, QVariantList values)
111 DeclarativeBoxSet *DeclarativeBoxPlotSeries::insert(int index, const QString label, QVariantList values)
111 112 {
112 DeclarativeBoxSet *barset = new DeclarativeBoxSet(this);
113 DeclarativeBoxSet *barset = new DeclarativeBoxSet(label, this);
113 114 barset->setValues(values);
114 115 if (QBoxPlotSeries::insert(index, barset))
115 116 return barset;
@@ -33,10 +33,16 class DeclarativeBoxSet : public QBoxSet
33 33 {
34 34 Q_OBJECT
35 35 Q_PROPERTY(QVariantList values READ values WRITE setValues)
36 Q_PROPERTY(QString label READ label WRITE setLabel)
36 37 Q_PROPERTY(int count READ count NOTIFY countChanged)
38 Q_PROPERTY(qreal lowerExtreme READ lowerExtreme WRITE setLowerExtreme)
39 Q_PROPERTY(qreal lowerQuartile READ lowerQuartile WRITE setLowerQuartile)
40 Q_PROPERTY(qreal median READ median WRITE setMedian)
41 Q_PROPERTY(qreal upperQuartile READ upperQuartile WRITE setUpperQuartile)
42 Q_PROPERTY(qreal upperExtreme READ upperExtreme WRITE setUpperExtreme)
37 43
38 44 public:
39 explicit DeclarativeBoxSet(QObject *parent = 0);
45 explicit DeclarativeBoxSet(const QString label = "", QObject *parent = 0);
40 46 QVariantList values();
41 47 void setValues(QVariantList values);
42 48
@@ -77,8 +83,9 public:
77 83
78 84 public:
79 85 Q_INVOKABLE DeclarativeBoxSet *at(int index);
80 Q_INVOKABLE DeclarativeBoxSet *append(QVariantList values) { return insert(count(), values); }
81 Q_INVOKABLE DeclarativeBoxSet *insert(int index, QVariantList values);
86 Q_INVOKABLE DeclarativeBoxSet *append(const QString label, QVariantList values) { return insert(count(), label, values); }
87 Q_INVOKABLE void append(DeclarativeBoxSet *box) { QBoxPlotSeries::append(box); }
88 Q_INVOKABLE DeclarativeBoxSet *insert(int index, const QString label, QVariantList values);
82 89 Q_INVOKABLE bool remove(QBoxSet *boxset) { return QBoxPlotSeries::remove(boxset); }
83 90 Q_INVOKABLE void clear() { return QBoxPlotSeries::clear(); }
84 91
@@ -33,7 +33,9 BoxPlotChartItem::BoxPlotChartItem(QBoxPlotSeries *series, QGraphicsItem* item)
33 33 ChartItem(series->d_func(), item),
34 34 m_series(series),
35 35 m_animation(0),
36 m_animate(0)
36 m_animate(0),
37 m_domainMaxY(0.0),
38 m_domainMinY(0.0)
37 39 {
38 40 connect(series, SIGNAL(boxsetsRemoved(QList<QBoxSet*>)), this, SLOT(handleBoxsetRemove(QList<QBoxSet*>)));
39 41 connect(series->d_func(), SIGNAL(restructuredBoxes()), this, SLOT(handleDataStructureChanged()));
@@ -151,6 +153,12 void BoxPlotChartItem::handleDomainUpdated()
151 153 foreach (BoxWhiskers *item, m_boxTable.values()) {
152 154 // Update the domain size for each BoxWhisker item
153 155 item->setDomainSize(domain()->size());
156 if (domain()->minY() != m_domainMinY || domain()->maxY() != m_domainMaxY) {
157 item->updateGeometry();
158 m_domainMinY = domain()->minY();
159 m_domainMaxY = domain()->maxY();
160 qDebug() << "Updating";
161 }
154 162
155 163 // If the animation is set, start the animation for each BoxWhisker item
156 164 if (m_animation) {
@@ -76,6 +76,8 protected:
76 76
77 77 BoxPlotAnimation *m_animation;
78 78 bool m_animate;
79 qreal m_domainMaxY;
80 qreal m_domainMinY;
79 81
80 82 QRectF m_boundingRect;
81 83
@@ -117,7 +117,8 void BoxWhiskers::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
117 117 //painter->setClipRect(parentItem()->boundingRect());
118 118 painter->setPen(m_pen);
119 119 painter->setBrush(m_brush);
120 qreal spanY = m_data.m_maxY - m_data.m_minY;
120 //qreal spanY = m_data.m_maxY - m_data.m_minY;
121 qreal spanY = m_domain->maxY() - m_domain->minY();
121 122 //painter->setClipRect(parentItem()->boundingRect());
122 123 painter->scale(m_domainSize.width() / m_data.m_boxItems, m_domainSize.height() / spanY);
123 124 painter->drawPath(m_boxPath);
@@ -134,55 +135,71 void BoxWhiskers::updateGeometry()
134 135 qreal left = 0.25 * columnWidth + columnWidth * m_data.m_seriesIndex;
135 136 qreal right = 0.75 * columnWidth + columnWidth * m_data.m_seriesIndex;
136 137 qreal middle = 0.5 * columnWidth + columnWidth * m_data.m_seriesIndex;
138 qreal domainMaxY = m_domain->maxY();
139 qreal domainMinY = m_domain->minY();
140
141 qreal tmpUE = m_data.m_upperExtreme;
142 if (tmpUE > domainMaxY) tmpUE = domainMaxY;
143 if (tmpUE < domainMinY) tmpUE = domainMinY;
144 qreal tmpUQ = m_data.m_upperQuartile;
145 if (tmpUQ > domainMaxY) tmpUQ = domainMaxY;
146 if (tmpUQ < domainMinY) tmpUQ = domainMinY;
147 qreal tmpLQ = m_data.m_lowerQuartile;
148 if (tmpLQ > domainMaxY) tmpLQ = domainMaxY;
149 if (tmpLQ < domainMinY) tmpLQ = domainMinY;
150 qreal tmpLE = m_data.m_lowerExtreme;
151 if (tmpLE > domainMaxY) tmpLE = domainMaxY;
152 if (tmpLE < domainMinY) tmpLE = domainMinY;
137 153
138 154 //whisker = 0.35 0.75
139 155
140 156 // Upper whisker
141 path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
142 path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
143 path.moveTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
144 path.lineTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_upperQuartile);
145 path.closeSubpath();
157 if (m_data.m_upperExtreme <= domainMaxY && m_data.m_upperExtreme >= domainMinY) {
158 path.moveTo(left + m_data.m_index, domainMaxY - m_data.m_upperExtreme);
159 path.lineTo(right + m_data.m_index, domainMaxY - m_data.m_upperExtreme);
160 }
161 if ((tmpUE - tmpUQ) > 0.0) {
162 path.moveTo(middle + m_data.m_index, domainMaxY - tmpUE);
163 path.lineTo(middle + m_data.m_index, domainMaxY - tmpUQ);
164 path.closeSubpath();
165 }
146 166
147 167 // Middle Box
148 path.addRect(left + m_data.m_index, m_data.m_maxY - m_data.m_upperQuartile,
149 0.5 * columnWidth, m_data.m_upperQuartile - m_data.m_lowerQuartile);
168 if ((tmpUQ - tmpLQ) > 0.0)
169 path.addRect(left + m_data.m_index, domainMaxY - tmpUQ, 0.5 * columnWidth, tmpUQ - tmpLQ);
150 170
151 171 // Median/mean line
152 path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_median);
153 path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_median);
172 if (m_data.m_median < domainMaxY && m_data.m_median > domainMinY) {
173 path.moveTo(left + m_data.m_index, domainMaxY - m_data.m_median);
174 path.lineTo(right + m_data.m_index, domainMaxY - m_data.m_median);
175 }
154 176
155 177 // Lower whisker
156 path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
157 path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
158 path.moveTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
159 path.lineTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_lowerQuartile);
178 if (m_data.m_lowerExtreme <= domainMaxY && m_data.m_lowerExtreme >= domainMinY) {
179 path.moveTo(left + m_data.m_index, domainMaxY - m_data.m_lowerExtreme);
180 path.lineTo(right + m_data.m_index, domainMaxY - m_data.m_lowerExtreme);
181 }
182 if ((tmpLQ - tmpLE) > 0.0) {
183 path.moveTo(middle + m_data.m_index, domainMaxY - tmpLE);
184 path.lineTo(middle + m_data.m_index, domainMaxY - tmpLQ);
185 }
186
160 187 path.closeSubpath();
161 188
162 189 m_boxPath = path;
163 190
164 191 updateBoundingRect();
165
166 // qreal scaleY = m_domainSize.height() / (m_data.m_maxY - m_data.m_minY);
167 // qreal scaleX = m_domainSize.width() / m_data.m_boxItems;
168 // QRectF br = path.boundingRect();
169 // m_boundingRect = QRectF( br.x() * scaleX, br.y() * scaleY, br.width() * scaleX, br.height() * scaleY);
170
171 if (m_data.m_index == 5) {
172 //qDebug() << "myValue = " << myValue;
173 //qDebug() << "m_data.m_upperExtreme" << m_data.m_upperExtreme;
174 //qDebug() << "m_boundingRect = " << m_boundingRect;
175 // qDebug() << "x = " << m_boundingRect.x() << ", y = " << m_boundingRect.y() << ", width = "
176 // << m_boundingRect.width() << ", height = " << m_boundingRect.height();
177 }
178 192 }
179 193
180 194 void BoxWhiskers::updateBoundingRect()
181 195 {
182 qreal scaleY = m_domainSize.height() / (m_data.m_maxY - m_data.m_minY);
196 //qreal scaleY = m_domainSize.height() / (m_data.m_maxY - m_data.m_minY);
197 qreal scaleY = m_domainSize.height() / (m_domain->maxY() - m_domain->minY());
183 198 qreal scaleX = m_domainSize.width() / m_data.m_boxItems;
184 199 QRectF br = m_boxPath.boundingRect();
185 m_boundingRect = QRectF( br.x() * scaleX, br.y() * scaleY, br.width() * scaleX, br.height() * scaleY);
200
201 m_boundingRect = QRectF( br.x() * scaleX, br.y() * scaleY,
202 br.width() * scaleX, br.height() * scaleY);
186 203 }
187 204
188 205 #include "moc_boxwhiskers_p.cpp"
General Comments 0
You need to be logged in to leave comments. Login now