summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Salmela <mika.salmela@digia.com>2013-04-15 12:11:16 +0300
committerMika Salmela <mika.salmela@digia.com>2013-04-15 12:24:44 +0300
commit9f82dd06814707b9c6d1edd382eab7b2f13e1c1d (patch)
tree78280788583e9a4555bdfaaccacb68dccd4786fc
parente5122ae0e7148672b1893104c7777d404665f1ce (diff)
Added handling of model mapping, meaning mostly animation changes.
Change-Id: I2046f343faddc8032f941cc8d84a9151b1f664ae Reviewed-by: Mika Salmela <mika.salmela@digia.com>
-rw-r--r--src/animations/boxplotanimation.cpp20
-rw-r--r--src/animations/boxplotanimation_p.h3
-rw-r--r--src/animations/boxwhiskersanimation.cpp42
-rw-r--r--src/animations/boxwhiskersanimation_p.h6
-rw-r--r--src/boxplotchart/boxplotchartitem.cpp34
-rw-r--r--src/boxplotchart/boxplotchartitem_p.h3
-rw-r--r--tests/boxplottester/boxplottester.pro6
-rw-r--r--tests/boxplottester/customtablemodel.cpp144
-rw-r--r--tests/boxplottester/customtablemodel.h51
-rw-r--r--tests/boxplottester/mainwidget.cpp44
-rw-r--r--tests/boxplottester/mainwidget.h3
11 files changed, 314 insertions, 42 deletions
diff --git a/src/animations/boxplotanimation.cpp b/src/animations/boxplotanimation.cpp
index f645f678..d7e4f4d2 100644
--- a/src/animations/boxplotanimation.cpp
+++ b/src/animations/boxplotanimation.cpp
@@ -53,7 +53,25 @@ void BoxPlotAnimation::addBox(BoxWhiskers *box)
ChartAnimation *BoxPlotAnimation::boxAnimation(BoxWhiskers *box)
{
// TODO: Check for missing animation
- return m_animations.value(box);
+ BoxWhiskersAnimation *animation = m_animations.value(box);
+ animation->m_moveMedianLine = false;
+
+ return animation;
+}
+
+ChartAnimation *BoxPlotAnimation::boxChangeAnimation(BoxWhiskers *box)
+{
+ BoxWhiskersAnimation *animation = m_animations.value(box);
+ animation->m_moveMedianLine = true;
+ animation->setEndData(box->m_data);
+
+ return animation;
+}
+
+void BoxPlotAnimation::setAnimationStart(BoxWhiskers *box)
+{
+ BoxWhiskersAnimation *animation = m_animations.value(box);
+ animation->setStartData(box->m_data);
}
//#include "moc_boxplotanimation_p.cpp"
diff --git a/src/animations/boxplotanimation_p.h b/src/animations/boxplotanimation_p.h
index f4d95e9f..d59d2f93 100644
--- a/src/animations/boxplotanimation_p.h
+++ b/src/animations/boxplotanimation_p.h
@@ -48,6 +48,9 @@ public:
void addBox(BoxWhiskers *box);
ChartAnimation *boxAnimation(BoxWhiskers *box);
+ ChartAnimation *boxChangeAnimation(BoxWhiskers *box);
+
+ void setAnimationStart(BoxWhiskers *box);
protected:
BoxPlotChartItem *m_item;
diff --git a/src/animations/boxwhiskersanimation.cpp b/src/animations/boxwhiskersanimation.cpp
index d5770829..544256c2 100644
--- a/src/animations/boxwhiskersanimation.cpp
+++ b/src/animations/boxwhiskersanimation.cpp
@@ -30,14 +30,6 @@ Q_DECLARE_METATYPE(qreal)
QTCOMMERCIALCHART_BEGIN_NAMESPACE
-BoxWhiskersAnimation::BoxWhiskersAnimation(BoxPlotChartItem *item)
- : ChartAnimation(item),
- m_item(item)
-{
- setDuration(ChartAnimationDuration);
- setEasingCurve(QEasingCurve::OutQuart);
-}
-
BoxWhiskersAnimation::BoxWhiskersAnimation(BoxWhiskers *box)
: ChartAnimation(box),
m_box(box)
@@ -61,21 +53,22 @@ QVariant BoxWhiskersAnimation::interpolated(const QVariant &from, const QVariant
//qDebug() << "endData.m_median = " << endData.m_median;
}
- result.m_lowerExtreme = endData.m_median + progress * (endData.m_lowerExtreme - endData.m_median);
- result.m_lowerQuartile = endData.m_median + progress * (endData.m_lowerQuartile - endData.m_median);
- result.m_median = endData.m_median;
- result.m_upperQuartile = endData.m_median + progress * (endData.m_upperQuartile - endData.m_median);
- result.m_upperExtreme = endData.m_median + progress * (endData.m_upperExtreme - endData.m_median);
+ if (m_moveMedianLine) {
+ result.m_lowerExtreme = startData.m_lowerExtreme + progress * (endData.m_lowerExtreme - startData.m_lowerExtreme);
+ result.m_lowerQuartile = startData.m_lowerQuartile + progress * (endData.m_lowerQuartile - startData.m_lowerQuartile);
+ result.m_median = startData.m_median + progress * (endData.m_median - startData.m_median);
+ result.m_upperQuartile = startData.m_upperQuartile + progress * (endData.m_upperQuartile - startData.m_upperQuartile);
+ result.m_upperExtreme = startData.m_upperExtreme + progress * (endData.m_upperExtreme - startData.m_upperExtreme);
+ } else {
+ result.m_lowerExtreme = endData.m_median + progress * (endData.m_lowerExtreme - endData.m_median);
+ result.m_lowerQuartile = endData.m_median + progress * (endData.m_lowerQuartile - endData.m_median);
+ result.m_median = endData.m_median;
+ result.m_upperQuartile = endData.m_median + progress * (endData.m_upperQuartile - endData.m_median);
+ result.m_upperExtreme = endData.m_median + progress * (endData.m_upperExtreme - endData.m_median);
+ }
result.m_index = endData.m_index;
result.m_boxItems = endData.m_boxItems;
-// result.m_lowerExtreme = endData.m_lowerExtreme;
-// result.m_lowerQuartile = endData.m_lowerQuartile;
-// result.m_median = endData.m_median;
-// result.m_upperQuartile = endData.m_upperQuartile;
-// result.m_upperExtreme = endData.m_upperExtreme;
-// result.m_index = endData.m_index;
-// result.m_boxItems = endData.m_boxItems;
result.m_maxX = endData.m_maxX;
result.m_minX = endData.m_minX;
@@ -107,6 +100,15 @@ void BoxWhiskersAnimation::setEndData(const BoxWhiskersData &endData)
setEndValue(qVariantFromValue(endData));
}
+void BoxWhiskersAnimation::setStartData(const BoxWhiskersData &endData)
+{
+ if (state() != QAbstractAnimation::Stopped)
+ stop();
+
+ setStartValue(qVariantFromValue(endData));
+}
+
+
#include "moc_boxwhiskersanimation_p.cpp"
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/animations/boxwhiskersanimation_p.h b/src/animations/boxwhiskersanimation_p.h
index 3b8979fb..ad37743f 100644
--- a/src/animations/boxwhiskersanimation_p.h
+++ b/src/animations/boxwhiskersanimation_p.h
@@ -43,7 +43,6 @@ class BoxWhiskersAnimation : public ChartAnimation
Q_OBJECT
public:
- BoxWhiskersAnimation(BoxPlotChartItem *item);
BoxWhiskersAnimation(BoxWhiskers *box);
~BoxWhiskersAnimation();
@@ -53,11 +52,16 @@ public: // from QVariantAnimation
void setup(const BoxWhiskersData &startData, const BoxWhiskersData &endData);
void setEndData(const BoxWhiskersData &endData);
+ void setStartData(const BoxWhiskersData &endData);
+
+ void moveMedianLine(bool move);
protected:
+ friend class BoxPlotAnimation;
BoxPlotChartItem *m_item;
BoxWhiskers *m_box;
BoxWhiskersData *m_boxData;
+ bool m_moveMedianLine;
};
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/boxplotchart/boxplotchartitem.cpp b/src/boxplotchart/boxplotchartitem.cpp
index 03f1f402..9af4e0b7 100644
--- a/src/boxplotchart/boxplotchartitem.cpp
+++ b/src/boxplotchart/boxplotchartitem.cpp
@@ -136,22 +136,16 @@ void BoxPlotChartItem::handleDomainUpdated()
void BoxPlotChartItem::handleLayoutChanged()
{
- //qDebug() << "BoxPlotChartItem::handleLayoutChanged() domain()->size() = " << domain()->size();
- //foreach (BoxWhiskers *boxWhiskersItem, m_boxes)
- // boxWhiskersItem->updateGeometry();
-}
+ foreach (BoxWhiskers *item, m_boxTable.values()) {
+ if (m_animation)
+ m_animation->setAnimationStart(item);
-void BoxPlotChartItem::handleSeriesRemove(QAbstractSeries *series)
-{
- qDebug() << "BoxPlotChartItem::handleSeriesRemove " << m_seriesIndex;
- QBoxPlotSeries *removedSeries = static_cast<QBoxPlotSeries *>(series);
- if (m_series == removedSeries) {
- return;
+ bool dirty = updateBoxGeometry(item, item->m_data.m_index);
+ if (dirty && m_animation)
+ presenter()->startAnimation(m_animation->boxChangeAnimation(item));
+ else
+ item->updateGeometry();
}
-
- m_seriesCount = m_seriesCount - 1;
-
- handleDataStructureChanged();
}
QRectF BoxPlotChartItem::boundingRect() const
@@ -169,11 +163,17 @@ QVector<QRectF> BoxPlotChartItem::calculateLayout()
return QVector<QRectF>();
}
-void BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index)
+bool BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index)
{
+ bool changed = false;
+
QBarSet *set = m_series->d_func()->barsetAt(index);
- //QBarSet *set = m_barSets.at(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);
@@ -189,6 +189,8 @@ void BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index)
data.m_seriesIndex = m_seriesIndex;
data.m_seriesCount = m_seriesCount;
+
+ return changed;
}
#include "moc_boxplotchartitem_p.cpp"
diff --git a/src/boxplotchart/boxplotchartitem_p.h b/src/boxplotchart/boxplotchartitem_p.h
index 40813f47..342221e6 100644
--- a/src/boxplotchart/boxplotchartitem_p.h
+++ b/src/boxplotchart/boxplotchartitem_p.h
@@ -58,12 +58,11 @@ public Q_SLOTS:
void handleDomainUpdated();
void handleLayoutChanged();
void handleUpdatedBars();
- void handleSeriesRemove(QAbstractSeries *series);
private:
virtual QVector<QRectF> calculateLayout();
void initializeLayout();
- void updateBoxGeometry(BoxWhiskers *box, int index);
+ bool updateBoxGeometry(BoxWhiskers *box, int index);
protected:
friend class QBoxPlotSeriesPrivate;
diff --git a/tests/boxplottester/boxplottester.pro b/tests/boxplottester/boxplottester.pro
index 822f78da..57436c0a 100644
--- a/tests/boxplottester/boxplottester.pro
+++ b/tests/boxplottester/boxplottester.pro
@@ -10,7 +10,9 @@ contains(QT_MAJOR_VERSION, 5) {
}
SOURCES += main.cpp \
- mainwidget.cpp
+ mainwidget.cpp \
+ customtablemodel.cpp
HEADERS += \
- mainwidget.h
+ mainwidget.h \
+ customtablemodel.h
diff --git a/tests/boxplottester/customtablemodel.cpp b/tests/boxplottester/customtablemodel.cpp
new file mode 100644
index 00000000..54d47900
--- /dev/null
+++ b/tests/boxplottester/customtablemodel.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "customtablemodel.h"
+#include <QVector>
+#include <QTime>
+#include <QRect>
+#include <QColor>
+
+const QString categories[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Nov", "Dec"};
+
+CustomTableModel::CustomTableModel(QObject *parent) :
+ QAbstractTableModel(parent)
+{
+// qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
+
+ m_columnCount = 6;
+ m_rowCount = 5;
+ QVector<qreal>* dataVec_Jan = new QVector<qreal>(m_rowCount);
+ dataVec_Jan->insert(0, 3.0);
+ dataVec_Jan->insert(1, 4.0);
+ dataVec_Jan->insert(2, 4.4);
+ dataVec_Jan->insert(3, 6.0);
+ dataVec_Jan->insert(4, 7.0);
+ m_data.append(dataVec_Jan);
+
+ QVector<qreal>* dataVec_Feb = new QVector<qreal>(m_rowCount);
+ dataVec_Feb->insert(0, 5.0);
+ dataVec_Feb->insert(1, 6.0);
+ dataVec_Feb->insert(2, 7.5);
+ dataVec_Feb->insert(3, 8.0);
+ dataVec_Feb->insert(4, 12.0);
+ m_data.append(dataVec_Feb);
+
+ QVector<qreal>* dataVec_Mar = new QVector<qreal>(m_rowCount);
+ dataVec_Mar->insert(0, 3.0);
+ dataVec_Mar->insert(1, 4.0);
+ dataVec_Mar->insert(2, 5.7);
+ dataVec_Mar->insert(3, 8.0);
+ dataVec_Mar->insert(4, 9.0);
+ m_data.append(dataVec_Mar);
+
+ QVector<qreal>* dataVec_Apr = new QVector<qreal>(m_rowCount);
+ dataVec_Apr->insert(0, 5.0);
+ dataVec_Apr->insert(1, 6.0);
+ dataVec_Apr->insert(2, 6.8);
+ dataVec_Apr->insert(3, 7.0);
+ dataVec_Apr->insert(4, 8.0);
+ m_data.append(dataVec_Apr);
+
+ QVector<qreal>* dataVec_May = new QVector<qreal>(m_rowCount);
+ dataVec_May->insert(0, 4.0);
+ dataVec_May->insert(1, 5.0);
+ dataVec_May->insert(2, 5.2);
+ dataVec_May->insert(3, 6.0);
+ dataVec_May->insert(4, 7.0);
+ m_data.append(dataVec_May);
+
+ QVector<qreal>* dataVec_Jun = new QVector<qreal>(m_rowCount);
+ dataVec_Jun->insert(0, 4.0);
+ dataVec_Jun->insert(1, 7.0);
+ dataVec_Jun->insert(2, 8.2);
+ dataVec_Jun->insert(3, 9.0);
+ dataVec_Jun->insert(4, 10.0);
+ m_data.append(dataVec_Jun);
+}
+
+int CustomTableModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent)
+ return m_rowCount;
+}
+
+int CustomTableModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent)
+ return m_data.count();
+}
+
+QVariant CustomTableModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (orientation == Qt::Horizontal)
+ return categories[section];
+ else
+ return QString("%1").arg(section + 1);
+}
+
+QVariant CustomTableModel::data(const QModelIndex &index, int role) const
+{
+ if (role == Qt::DisplayRole) {
+ return m_data[index.column()]->at(index.row());
+ } else if (role == Qt::EditRole) {
+ return m_data[index.column()]->at(index.row());
+ } else if (role == Qt::BackgroundRole) {
+ QRect rect;
+ foreach (rect, m_mapping)
+ if (rect.contains(index.column(), index.row()))
+ return QColor(m_mapping.key(rect));
+
+ // cell not mapped return white color
+ return QColor(Qt::white);
+ }
+ return QVariant();
+}
+
+bool CustomTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (index.isValid() && role == Qt::EditRole) {
+ m_data[index.column()]->replace(index.row(), value.toDouble());
+ emit dataChanged(index, index);
+ return true;
+ }
+ return false;
+}
+
+Qt::ItemFlags CustomTableModel::flags(const QModelIndex &index) const
+{
+ return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
+}
+
+void CustomTableModel::addMapping(QString color, QRect area)
+{
+ m_mapping.insertMulti(color, area);
+}
diff --git a/tests/boxplottester/customtablemodel.h b/tests/boxplottester/customtablemodel.h
new file mode 100644
index 00000000..47d60fd7
--- /dev/null
+++ b/tests/boxplottester/customtablemodel.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef CUSTOMTABLEMODEL_H
+#define CUSTOMTABLEMODEL_H
+
+#include <QAbstractTableModel>
+#include <QHash>
+#include <QRect>
+
+class CustomTableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+public:
+ explicit CustomTableModel(QObject *parent = 0);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ void addMapping(QString color, QRect area);
+ void clearMapping() { m_mapping.clear(); }
+
+private:
+ QList<QVector<qreal> * > m_data;
+ QHash<QString, QRect> m_mapping;
+ int m_columnCount;
+ int m_rowCount;
+};
+
+#endif // CUSTOMTABLEMODEL_H
diff --git a/tests/boxplottester/mainwidget.cpp b/tests/boxplottester/mainwidget.cpp
index fe5303dd..eb3d3b15 100644
--- a/tests/boxplottester/mainwidget.cpp
+++ b/tests/boxplottester/mainwidget.cpp
@@ -19,6 +19,10 @@
****************************************************************************/
#include "mainwidget.h"
+#include "customtablemodel.h"
+#include <QVBarModelMapper>
+#include <QTableView>
+#include <QHeaderView>
#include <QChartView>
#include <QBoxPlotSeries>
#include <QBarSet>
@@ -76,6 +80,19 @@ MainWidget::MainWidget(QWidget *parent) :
initThemeCombo(grid);
initCheckboxes(grid);
+ m_model = new CustomTableModel;
+ QTableView *tableView = new QTableView;
+ tableView->setModel(m_model);
+ tableView->setMaximumWidth(200);
+ grid->addWidget(tableView, rowPos++, 0, 3, 2, Qt::AlignLeft);
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+ tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+#else
+ tableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
+ tableView->verticalHeader()->setResizeMode(QHeaderView::Stretch);
+#endif
+
// add row with empty label to make all the other rows static
grid->addWidget(new QLabel(""), grid->rowCount(), 0);
grid->setRowStretch(grid->rowCount() - 1, 1);
@@ -129,6 +146,12 @@ void MainWidget::initCheckboxes(QGridLayout *grid)
connect(titleCheckBox, SIGNAL(toggled(bool)), this, SLOT(titleToggled(bool)));
titleCheckBox->setChecked(false);
grid->addWidget(titleCheckBox, rowPos++, 0);
+
+ QCheckBox *modelMapperCheckBox = new QCheckBox("Use model mapper");
+ connect(modelMapperCheckBox, SIGNAL(toggled(bool)), this, SLOT(modelMapperToggled(bool)));
+ modelMapperCheckBox->setChecked(false);
+ grid->addWidget(modelMapperCheckBox, rowPos++, 0);
+
}
void MainWidget::addSeries()
@@ -228,6 +251,27 @@ void MainWidget::titleToggled(bool enabled)
m_chart->setTitle("");
}
+void MainWidget::modelMapperToggled(bool enabled)
+{
+ if (enabled) {
+ m_series[nSeries] = new QBoxPlotSeries();
+
+ int first = 0;
+ int count = 5;
+ QVBarModelMapper *mapper = new QVBarModelMapper(this);
+ mapper->setFirstBarSetColumn(0);
+ mapper->setLastBarSetColumn(5);
+ mapper->setFirstRow(first);
+ mapper->setRowCount(count);
+ mapper->setSeries(m_series[nSeries]);
+ mapper->setModel(m_model);
+ m_chart->addSeries(m_series[nSeries]);
+
+ nSeries++;
+ } else {
+ removeSeries();
+ }
+}
void MainWidget::changeChartTheme(int themeIndex)
{
diff --git a/tests/boxplottester/mainwidget.h b/tests/boxplottester/mainwidget.h
index 5e20c836..dc57991f 100644
--- a/tests/boxplottester/mainwidget.h
+++ b/tests/boxplottester/mainwidget.h
@@ -24,6 +24,7 @@
#include "qchartglobal.h"
#include "qchart.h"
#include "qchartview.h"
+#include "customtablemodel.h"
#include <QWidget>
#include <QBoxPlotSeries>
#include <QBarCategoryAxis>
@@ -51,6 +52,7 @@ private slots:
void animationToggled(bool enabled);
void legendToggled(bool enabled);
void titleToggled(bool enabled);
+ void modelMapperToggled(bool enabled);
void changeChartTheme(int themeIndex);
private:
@@ -58,6 +60,7 @@ private:
QChartView *m_chartView;
QGridLayout *m_scatterLayout;
QBarCategoryAxis *m_axis;
+ CustomTableModel *m_model;
int rowPos;
int nSeries;
int nNewBoxes;