diff --git a/examples/boxplotchart/main.cpp b/examples/boxplotchart/main.cpp
index e20af3a..8518401 100644
--- a/examples/boxplotchart/main.cpp
+++ b/examples/boxplotchart/main.cpp
@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
//![2]
QBoxPlotSeries *series = new QBoxPlotSeries();
- series->setName("Box & Whiskers");
+ series->setName("Cargotec");
//![2]
QFile stockData(":stock");
@@ -55,14 +55,13 @@ int main(int argc, char *argv[])
//![3]
QChart *chart = new QChart();
chart->addSeries(series);
- chart->setTitle("Simple boxplotchart example");
+ chart->setTitle("Cargotec's share deviation 2012")
chart->setAnimationOptions(QChart::SeriesAnimations);
//![3]
//![4]
- QBarCategoryAxis *axis = new QBarCategoryAxis();
chart->createDefaultAxes();
- chart->setAxisX(axis, series);
+ chart->axisY()->setMin(15.0);
//![4]
//![5]
diff --git a/examples/boxplotchart/stock_data.txt b/examples/boxplotchart/stock_data.txt
index bf32f81..18d7417 100644
--- a/examples/boxplotchart/stock_data.txt
+++ b/examples/boxplotchart/stock_data.txt
@@ -1,8 +1,24 @@
-Jan 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0
+#Jan 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0
#0 1 2 3 4 5 6 7 8 9
-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
-Mar 1.0 1.2 2.0 2.4 2.5 3.0 3.5 3.7 4.0 4.7 5.0
-Apr 4.6 4.7 5.2 7.3 8.4 8.8 9.1 8.3 7.4 6.4 5.3
-May 3.5 7.2 5.4 6.3 7.4 8.3 8.8 3.3 5.4 5.7 3.9
+#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
+#Mar 1.0 1.2 2.0 2.4 2.5 3.0 3.5 3.7 4.0 4.7 5.0
+#Apr 4.6 4.7 5.2 7.3 8.4 8.8 9.1 8.3 7.4 6.4 5.3
+#May 3.5 7.2 5.4 6.3 7.4 8.3 8.8 3.3 5.4 5.7 3.9
+#Jun 2.5 4.6 7.3 4.6 7.8 9.0 7.4
+#Jul 4.7 3.8 5.7 6.4 6.9 4.6 7.2 5.9
#0 1 2 3 4 5 6 7 8 9 10
# * * *
+#Top 18.0 18.5 19.0 19.5 19.7 20.0 20.5 20.75 21.0 21.5 22.1
+#Tok 19.0 19.5 21.0 21.5 21.7 22.0 22.5 22.75 23.0 23.5 24.0
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
diff --git a/examples/qmlboxplot/qml/qmlboxplot/box.qml b/examples/qmlboxplot/qml/qmlboxplot/box.qml
new file mode 100644
index 0000000..09726a3
--- /dev/null
+++ b/examples/qmlboxplot/qml/qmlboxplot/box.qml
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Commercial Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import QtCommercial.Chart 1.1
+
+BoxSet {
+ id: myNewBox
+ label: "Foo"
+ values: [5, 6, 7, 8, 9]
+ Component.onCompleted: {
+ console.log("BoxSet completed")
+ }
+}
diff --git a/examples/qmlboxplot/qml/qmlboxplot/main.qml b/examples/qmlboxplot/qml/qmlboxplot/main.qml
index d07c709..e492927 100644
--- a/examples/qmlboxplot/qml/qmlboxplot/main.qml
+++ b/examples/qmlboxplot/qml/qmlboxplot/main.qml
@@ -34,15 +34,45 @@ ChartView {
BoxPlotSeries {
id: plotSeries
name: "Income"
- axisX: BarCategoryAxis { categories: ["Jan", "Feb", "Mar", "Apr", "May"] }
+ //axisX: BarCategoryAxis { categories: ["Jan", "Feb", "Mar", "Apr", "May"] }
BoxSet { values: [3, 4, 4.4, 6, 7] }
- BoxSet { values: [5, 6, 7.5, 8, 12] }
- BoxSet { values: [2, 5, 5.7, 8, 9] }
- BoxSet { values: [5, 6, 6.8, 7, 8] }
- BoxSet { values: [4, 5, 5.2, 6, 7] }
+ BoxSet { label: "Tok"; values: [5, 6, 7.5, 8, 12] }
+ BoxSet { label: "Kol"; values: [2, 5, 5.7, 8, 9] }
+ BoxSet { label: "Nel"; values: [5, 6, 6.8, 7, 8] }
+ BoxSet { label: "Vii"; values: [4, 5, 5.2, 6, 7] }
}
//![2]
+ Rectangle {
+ id: moreButton
+ width: 50
+ height: 50
+ color: "gray"
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ var com = Qt.createComponent("box.qml")
+ if (com.status == Component.Ready) {
+ var obj = com.createObject(moreButton)
+ obj.lowerExtreme = 1.2
+ console.log("lowerExtreme = " + obj.lowerExtreme)
+ obj.lowerQuartile = 2.2
+ console.log("lowerQuartile = " + obj.lowerQuartile)
+ obj.median = 3.2
+ console.log("median = " + obj.median)
+ obj.upperQuartile = 4.2
+ console.log("upperQuartile = " + obj.upperQuartile)
+ obj.upperExtreme = 5.2
+ console.log("upperExtreme = " + obj.upperExtreme)
+ obj.label = "mik"
+ console.log("label = " + obj.label)
+ plotSeries.append(obj)
+ } else {
+ console.log(com.errorString())
+ }
+ }
+ }
+ }
//![3]
}
diff --git a/examples/qmlboxplot/qmlboxplot.pro b/examples/qmlboxplot/qmlboxplot.pro
index 194aef3..d7ec0d5 100644
--- a/examples/qmlboxplot/qmlboxplot.pro
+++ b/examples/qmlboxplot/qmlboxplot.pro
@@ -8,4 +8,5 @@ SOURCES += main.cpp
include(qmlapplicationviewer/qmlapplicationviewer.pri)
OTHER_FILES += \
- qml/qmlboxplot/main.qml
+ qml/qmlboxplot/main.qml \
+ qml/qmlboxplot/box.qml
diff --git a/examples/qmlboxplot/resources.qrc b/examples/qmlboxplot/resources.qrc
index 49a98f1..aabf72c 100644
--- a/examples/qmlboxplot/resources.qrc
+++ b/examples/qmlboxplot/resources.qrc
@@ -1,5 +1,6 @@
qml/qmlboxplot/main.qml
+ qml/qmlboxplot/box.qml
diff --git a/plugins/declarative/declarativeboxplotseries.cpp b/plugins/declarative/declarativeboxplotseries.cpp
index 195fed6..48097c8 100644
--- a/plugins/declarative/declarativeboxplotseries.cpp
+++ b/plugins/declarative/declarativeboxplotseries.cpp
@@ -21,16 +21,15 @@
#include "declarativebarseries.h"
#include "declarativeboxplotseries.h"
#include "qboxset.h"
-#include "qvbarmodelmapper.h"
-#include "qhbarmodelmapper.h"
+#include "qvboxplotmodelmapper.h"
QTCOMMERCIALCHART_BEGIN_NAMESPACE
-DeclarativeBoxSet::DeclarativeBoxSet(QObject *parent)
- : QBoxSet("", parent)
+DeclarativeBoxSet::DeclarativeBoxSet(const QString label, QObject *parent)
+ : QBoxSet(label, parent)
{
connect(this, SIGNAL(valuesAdded(int,int)), this, SLOT(handleCountChanged(int,int)));
- connect(this, SIGNAL(valuesRemoved(int,int)), this, SLOT(handleCountChanged(int,int)));
+ //connect(this, SIGNAL(valuesRemoved(int,int)), this, SLOT(handleCountChanged(int,int)));
}
void DeclarativeBoxSet::handleCountChanged(int index, int count)
@@ -56,6 +55,7 @@ void DeclarativeBoxSet::setValues(QVariantList values)
}
}
+// Declarative box&whiskers series =====================================================
DeclarativeBoxPlotSeries::DeclarativeBoxPlotSeries(QDeclarativeItem *parent) :
QBoxPlotSeries(parent),
@@ -76,13 +76,13 @@ void DeclarativeBoxPlotSeries::componentComplete()
foreach (QObject *child, children()) {
if (qobject_cast(child)) {
QBoxPlotSeries::append(qobject_cast(child));
- } else if (qobject_cast(child)) {
- QVBarModelMapper *mapper = qobject_cast(child);
+ } else if (qobject_cast(child)) {
+ QVBoxPlotModelMapper *mapper = qobject_cast(child);
+ mapper->setSeries(this);
+ }// else if (qobject_cast(child)) { // TODO: Horisontal
+ //QHBarModelMapper *mapper = qobject_cast(child); //TODO
//mapper->setSeries(this);
- } else if (qobject_cast(child)) {
- QHBarModelMapper *mapper = qobject_cast(child);
- //mapper->setSeries(this);
- }
+ //}
}
}
@@ -100,6 +100,7 @@ void DeclarativeBoxPlotSeries::appendSeriesChildren(QDeclarativeListProperty setList = boxSets();
if (index >= 0 && index < setList.count())
return qobject_cast(setList[index]);
@@ -107,9 +108,9 @@ DeclarativeBoxSet *DeclarativeBoxPlotSeries::at(int index)
return 0;
}
-DeclarativeBoxSet *DeclarativeBoxPlotSeries::insert(int index, QVariantList values)
+DeclarativeBoxSet *DeclarativeBoxPlotSeries::insert(int index, const QString label, QVariantList values)
{
- DeclarativeBoxSet *barset = new DeclarativeBoxSet(this);
+ DeclarativeBoxSet *barset = new DeclarativeBoxSet(label, this);
barset->setValues(values);
if (QBoxPlotSeries::insert(index, barset))
return barset;
diff --git a/plugins/declarative/declarativeboxplotseries.h b/plugins/declarative/declarativeboxplotseries.h
index 7fac07a..eed2ea1 100644
--- a/plugins/declarative/declarativeboxplotseries.h
+++ b/plugins/declarative/declarativeboxplotseries.h
@@ -33,10 +33,16 @@ class DeclarativeBoxSet : public QBoxSet
{
Q_OBJECT
Q_PROPERTY(QVariantList values READ values WRITE setValues)
+ Q_PROPERTY(QString label READ label WRITE setLabel)
Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(qreal lowerExtreme READ lowerExtreme WRITE setLowerExtreme)
+ Q_PROPERTY(qreal lowerQuartile READ lowerQuartile WRITE setLowerQuartile)
+ Q_PROPERTY(qreal median READ median WRITE setMedian)
+ Q_PROPERTY(qreal upperQuartile READ upperQuartile WRITE setUpperQuartile)
+ Q_PROPERTY(qreal upperExtreme READ upperExtreme WRITE setUpperExtreme)
public:
- explicit DeclarativeBoxSet(QObject *parent = 0);
+ explicit DeclarativeBoxSet(const QString label = "", QObject *parent = 0);
QVariantList values();
void setValues(QVariantList values);
@@ -77,8 +83,9 @@ public:
public:
Q_INVOKABLE DeclarativeBoxSet *at(int index);
- Q_INVOKABLE DeclarativeBoxSet *append(QVariantList values) { return insert(count(), values); }
- Q_INVOKABLE DeclarativeBoxSet *insert(int index, QVariantList values);
+ Q_INVOKABLE DeclarativeBoxSet *append(const QString label, QVariantList values) { return insert(count(), label, values); }
+ Q_INVOKABLE void append(DeclarativeBoxSet *box) { QBoxPlotSeries::append(box); }
+ Q_INVOKABLE DeclarativeBoxSet *insert(int index, const QString label, QVariantList values);
Q_INVOKABLE bool remove(QBoxSet *boxset) { return QBoxPlotSeries::remove(boxset); }
Q_INVOKABLE void clear() { return QBoxPlotSeries::clear(); }
diff --git a/src/boxplotchart/boxplotchartitem.cpp b/src/boxplotchart/boxplotchartitem.cpp
index 7fb1531..b201dff 100644
--- a/src/boxplotchart/boxplotchartitem.cpp
+++ b/src/boxplotchart/boxplotchartitem.cpp
@@ -33,7 +33,9 @@ BoxPlotChartItem::BoxPlotChartItem(QBoxPlotSeries *series, QGraphicsItem* item)
ChartItem(series->d_func(), item),
m_series(series),
m_animation(0),
- m_animate(0)
+ m_animate(0),
+ m_domainMaxY(0.0),
+ m_domainMinY(0.0)
{
connect(series, SIGNAL(boxsetsRemoved(QList)), this, SLOT(handleBoxsetRemove(QList)));
connect(series->d_func(), SIGNAL(restructuredBoxes()), this, SLOT(handleDataStructureChanged()));
@@ -151,6 +153,12 @@ void BoxPlotChartItem::handleDomainUpdated()
foreach (BoxWhiskers *item, m_boxTable.values()) {
// Update the domain size for each BoxWhisker item
item->setDomainSize(domain()->size());
+ if (domain()->minY() != m_domainMinY || domain()->maxY() != m_domainMaxY) {
+ item->updateGeometry();
+ m_domainMinY = domain()->minY();
+ m_domainMaxY = domain()->maxY();
+ qDebug() << "Updating";
+ }
// If the animation is set, start the animation for each BoxWhisker item
if (m_animation) {
diff --git a/src/boxplotchart/boxplotchartitem_p.h b/src/boxplotchart/boxplotchartitem_p.h
index 5453036..7eefb67 100644
--- a/src/boxplotchart/boxplotchartitem_p.h
+++ b/src/boxplotchart/boxplotchartitem_p.h
@@ -76,6 +76,8 @@ protected:
BoxPlotAnimation *m_animation;
bool m_animate;
+ qreal m_domainMaxY;
+ qreal m_domainMinY;
QRectF m_boundingRect;
diff --git a/src/boxplotchart/boxwhiskers.cpp b/src/boxplotchart/boxwhiskers.cpp
index 805657a..242ffb9 100644
--- a/src/boxplotchart/boxwhiskers.cpp
+++ b/src/boxplotchart/boxwhiskers.cpp
@@ -117,7 +117,8 @@ void BoxWhiskers::paint(QPainter *painter, const QStyleOptionGraphicsItem *optio
//painter->setClipRect(parentItem()->boundingRect());
painter->setPen(m_pen);
painter->setBrush(m_brush);
- qreal spanY = m_data.m_maxY - m_data.m_minY;
+ //qreal spanY = m_data.m_maxY - m_data.m_minY;
+ qreal spanY = m_domain->maxY() - m_domain->minY();
//painter->setClipRect(parentItem()->boundingRect());
painter->scale(m_domainSize.width() / m_data.m_boxItems, m_domainSize.height() / spanY);
painter->drawPath(m_boxPath);
@@ -134,55 +135,71 @@ void BoxWhiskers::updateGeometry()
qreal left = 0.25 * columnWidth + columnWidth * m_data.m_seriesIndex;
qreal right = 0.75 * columnWidth + columnWidth * m_data.m_seriesIndex;
qreal middle = 0.5 * columnWidth + columnWidth * m_data.m_seriesIndex;
+ qreal domainMaxY = m_domain->maxY();
+ qreal domainMinY = m_domain->minY();
+
+ qreal tmpUE = m_data.m_upperExtreme;
+ if (tmpUE > domainMaxY) tmpUE = domainMaxY;
+ if (tmpUE < domainMinY) tmpUE = domainMinY;
+ qreal tmpUQ = m_data.m_upperQuartile;
+ if (tmpUQ > domainMaxY) tmpUQ = domainMaxY;
+ if (tmpUQ < domainMinY) tmpUQ = domainMinY;
+ qreal tmpLQ = m_data.m_lowerQuartile;
+ if (tmpLQ > domainMaxY) tmpLQ = domainMaxY;
+ if (tmpLQ < domainMinY) tmpLQ = domainMinY;
+ qreal tmpLE = m_data.m_lowerExtreme;
+ if (tmpLE > domainMaxY) tmpLE = domainMaxY;
+ if (tmpLE < domainMinY) tmpLE = domainMinY;
//whisker = 0.35 0.75
// Upper whisker
- path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
- path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
- path.moveTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_upperExtreme);
- path.lineTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_upperQuartile);
- path.closeSubpath();
+ if (m_data.m_upperExtreme <= domainMaxY && m_data.m_upperExtreme >= domainMinY) {
+ path.moveTo(left + m_data.m_index, domainMaxY - m_data.m_upperExtreme);
+ path.lineTo(right + m_data.m_index, domainMaxY - m_data.m_upperExtreme);
+ }
+ if ((tmpUE - tmpUQ) > 0.0) {
+ path.moveTo(middle + m_data.m_index, domainMaxY - tmpUE);
+ path.lineTo(middle + m_data.m_index, domainMaxY - tmpUQ);
+ path.closeSubpath();
+ }
// Middle Box
- path.addRect(left + m_data.m_index, m_data.m_maxY - m_data.m_upperQuartile,
- 0.5 * columnWidth, m_data.m_upperQuartile - m_data.m_lowerQuartile);
+ if ((tmpUQ - tmpLQ) > 0.0)
+ path.addRect(left + m_data.m_index, domainMaxY - tmpUQ, 0.5 * columnWidth, tmpUQ - tmpLQ);
// Median/mean line
- path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_median);
- path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_median);
+ if (m_data.m_median < domainMaxY && m_data.m_median > domainMinY) {
+ path.moveTo(left + m_data.m_index, domainMaxY - m_data.m_median);
+ path.lineTo(right + m_data.m_index, domainMaxY - m_data.m_median);
+ }
// Lower whisker
- path.moveTo(left + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
- path.lineTo(right + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
- path.moveTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_lowerExtreme);
- path.lineTo(middle + m_data.m_index, m_data.m_maxY - m_data.m_lowerQuartile);
+ if (m_data.m_lowerExtreme <= domainMaxY && m_data.m_lowerExtreme >= domainMinY) {
+ path.moveTo(left + m_data.m_index, domainMaxY - m_data.m_lowerExtreme);
+ path.lineTo(right + m_data.m_index, domainMaxY - m_data.m_lowerExtreme);
+ }
+ if ((tmpLQ - tmpLE) > 0.0) {
+ path.moveTo(middle + m_data.m_index, domainMaxY - tmpLE);
+ path.lineTo(middle + m_data.m_index, domainMaxY - tmpLQ);
+ }
+
path.closeSubpath();
m_boxPath = path;
updateBoundingRect();
-
-// qreal scaleY = m_domainSize.height() / (m_data.m_maxY - m_data.m_minY);
-// qreal scaleX = m_domainSize.width() / m_data.m_boxItems;
-// QRectF br = path.boundingRect();
-// m_boundingRect = QRectF( br.x() * scaleX, br.y() * scaleY, br.width() * scaleX, br.height() * scaleY);
-
- if (m_data.m_index == 5) {
- //qDebug() << "myValue = " << myValue;
- //qDebug() << "m_data.m_upperExtreme" << m_data.m_upperExtreme;
- //qDebug() << "m_boundingRect = " << m_boundingRect;
-// qDebug() << "x = " << m_boundingRect.x() << ", y = " << m_boundingRect.y() << ", width = "
-// << m_boundingRect.width() << ", height = " << m_boundingRect.height();
- }
}
void BoxWhiskers::updateBoundingRect()
{
- qreal scaleY = m_domainSize.height() / (m_data.m_maxY - m_data.m_minY);
+ //qreal scaleY = m_domainSize.height() / (m_data.m_maxY - m_data.m_minY);
+ qreal scaleY = m_domainSize.height() / (m_domain->maxY() - m_domain->minY());
qreal scaleX = m_domainSize.width() / m_data.m_boxItems;
QRectF br = m_boxPath.boundingRect();
- m_boundingRect = QRectF( br.x() * scaleX, br.y() * scaleY, br.width() * scaleX, br.height() * scaleY);
+
+ m_boundingRect = QRectF( br.x() * scaleX, br.y() * scaleY,
+ br.width() * scaleX, br.height() * scaleY);
}
#include "moc_boxwhiskers_p.cpp"