summaryrefslogtreecommitdiffstats
path: root/src/charts/boxplotchart/boxplotchartitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/charts/boxplotchart/boxplotchartitem.cpp')
-rw-r--r--src/charts/boxplotchart/boxplotchartitem.cpp215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/charts/boxplotchart/boxplotchartitem.cpp b/src/charts/boxplotchart/boxplotchartitem.cpp
new file mode 100644
index 00000000..ac1734d5
--- /dev/null
+++ b/src/charts/boxplotchart/boxplotchartitem.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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$
+**
+****************************************************************************/
+
+#include "boxplotchartitem_p.h"
+#include "qboxplotseries_p.h"
+#include "bar_p.h"
+#include "qboxset_p.h"
+#include "qabstractbarseries_p.h"
+#include "qboxset.h"
+#include "boxwhiskers_p.h"
+#include <QPainter>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+BoxPlotChartItem::BoxPlotChartItem(QBoxPlotSeries *series, QGraphicsItem *item) :
+ ChartItem(series->d_func(), item),
+ m_series(series),
+ m_animation(0)
+{
+ connect(series, SIGNAL(boxsetsRemoved(QList<QBoxSet *>)), this, SLOT(handleBoxsetRemove(QList<QBoxSet *>)));
+ connect(series->d_func(), SIGNAL(restructuredBoxes()), this, SLOT(handleDataStructureChanged()));
+ connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged()));
+ connect(series->d_func(), SIGNAL(updatedBoxes()), this, SLOT(handleUpdatedBars()));
+ connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdatedBars()));
+ // QBoxPlotSeriesPrivate calls handleDataStructureChanged(), don't do it here
+ setZValue(ChartPresenter::BoxPlotSeriesZValue);
+}
+
+BoxPlotChartItem::~BoxPlotChartItem()
+{
+}
+
+void BoxPlotChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(painter);
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+}
+
+void BoxPlotChartItem::setAnimation(BoxPlotAnimation *animation)
+{
+ m_animation = animation;
+ if (m_animation) {
+ foreach (BoxWhiskers *item, m_boxTable.values())
+ m_animation->addBox(item);
+ handleDomainUpdated();
+ }
+}
+
+void BoxPlotChartItem::handleDataStructureChanged()
+{
+ int setCount = m_series->count();
+
+ for (int s = 0; s < setCount; s++) {
+ QBoxSet *set = m_series->d_func()->boxSetAt(s);
+
+ BoxWhiskers *box = m_boxTable.value(set);
+ if (!box) {
+ // Item is not yet created, make a box and add it to hash table
+ box = new BoxWhiskers(set, domain(), this);
+ m_boxTable.insert(set, box);
+ connect(box, SIGNAL(clicked(QBoxSet *)), m_series, SIGNAL(clicked(QBoxSet *)));
+ connect(box, SIGNAL(hovered(bool, QBoxSet *)), m_series, SIGNAL(hovered(bool, QBoxSet *)));
+ connect(box, SIGNAL(clicked(QBoxSet *)), set, SIGNAL(clicked()));
+ connect(box, SIGNAL(hovered(bool, QBoxSet *)), set, SIGNAL(hovered(bool)));
+
+ // Set the decorative issues for the newly created box
+ // so that the brush and pen already defined for the set are kept.
+ if (set->brush() == Qt::NoBrush)
+ box->setBrush(m_series->brush());
+ else
+ box->setBrush(set->brush());
+ if (set->pen() == Qt::NoPen)
+ box->setPen(m_series->pen());
+ else
+ box->setPen(set->pen());
+ box->setBoxOutlined(m_series->boxOutlineVisible());
+ box->setBoxWidth(m_series->boxWidth());
+ }
+ updateBoxGeometry(box, s);
+
+ box->updateGeometry(domain());
+
+ if (m_animation)
+ m_animation->addBox(box);
+ }
+
+ handleDomainUpdated();
+}
+
+void BoxPlotChartItem::handleUpdatedBars()
+{
+ foreach (BoxWhiskers *item, m_boxTable.values()) {
+ item->setBrush(m_series->brush());
+ item->setPen(m_series->pen());
+ item->setBoxOutlined(m_series->boxOutlineVisible());
+ item->setBoxWidth(m_series->boxWidth());
+ }
+ // Override with QBoxSet specific settings
+ foreach (QBoxSet *set, m_boxTable.keys()) {
+ if (set->brush().style() != Qt::NoBrush)
+ m_boxTable.value(set)->setBrush(set->brush());
+ if (set->pen().style() != Qt::NoPen)
+ m_boxTable.value(set)->setPen(set->pen());
+ }
+}
+
+void BoxPlotChartItem::handleBoxsetRemove(QList<QBoxSet*> barSets)
+{
+ foreach (QBoxSet *set, barSets) {
+ BoxWhiskers *boxItem = m_boxTable.value(set);
+ m_boxTable.remove(set);
+ delete boxItem;
+ }
+}
+
+void BoxPlotChartItem::handleDomainUpdated()
+{
+ if ((domain()->size().width() <= 0) || (domain()->size().height() <= 0))
+ return;
+
+ // Set my bounding rect to same as domain size. Add one pixel at the top (-1.0) and the bottom as 0.0 would
+ // snip a bit off from the whisker at the grid line
+ m_boundingRect.setRect(0.0, -1.0, domain()->size().width(), domain()->size().height() + 1.0);
+
+ foreach (BoxWhiskers *item, m_boxTable.values()) {
+ item->updateGeometry(domain());
+
+ // If the animation is set, start the animation for each BoxWhisker item
+ if (m_animation)
+ presenter()->startAnimation(m_animation->boxAnimation(item));
+ }
+}
+
+void BoxPlotChartItem::handleLayoutChanged()
+{
+ foreach (BoxWhiskers *item, m_boxTable.values()) {
+ if (m_animation)
+ m_animation->setAnimationStart(item);
+
+ item->setBoxWidth(m_series->boxWidth());
+
+ bool dirty = updateBoxGeometry(item, item->m_data.m_index);
+ if (dirty && m_animation)
+ presenter()->startAnimation(m_animation->boxChangeAnimation(item));
+ else
+ item->updateGeometry(domain());
+ }
+}
+
+QRectF BoxPlotChartItem::boundingRect() const
+{
+ return m_boundingRect;
+}
+
+void BoxPlotChartItem::initializeLayout()
+{
+}
+
+QVector<QRectF> BoxPlotChartItem::calculateLayout()
+{
+ return QVector<QRectF>();
+}
+
+bool BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index)
+{
+ bool changed = false;
+
+ QBoxSet *set = m_series->d_func()->boxSetAt(index);
+ BoxWhiskersData &data = box->m_data;
+
+ if ((data.m_lowerExtreme != set->at(0)) || (data.m_lowerQuartile != set->at(1)) ||
+ (data.m_median != set->at(2)) || (data.m_upperQuartile != set->at(3)) || (data.m_upperExtreme != set->at(4))) {
+ changed = true;
+ }
+
+ data.m_lowerExtreme = set->at(0);
+ data.m_lowerQuartile = set->at(1);
+ data.m_median = set->at(2);
+ data.m_upperQuartile = set->at(3);
+ data.m_upperExtreme = set->at(4);
+ data.m_index = index;
+ data.m_boxItems = m_series->count();
+
+ data.m_maxX = domain()->maxX();
+ data.m_minX = domain()->minX();
+ data.m_maxY = domain()->maxY();
+ data.m_minY = domain()->minY();
+
+ data.m_seriesIndex = m_seriesIndex;
+ data.m_seriesCount = m_seriesCount;
+
+ return changed;
+}
+
+#include "moc_boxplotchartitem_p.cpp"
+
+QT_CHARTS_END_NAMESPACE