##// END OF EJS Templates
Added handling of model mapping, meaning mostly animation changes....
Mika Salmela -
r2480:9f82dd068147
parent child
Show More
@@ -0,0 +1,144
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 #include "customtablemodel.h"
22 #include <QVector>
23 #include <QTime>
24 #include <QRect>
25 #include <QColor>
26
27 const QString categories[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Nov", "Dec"};
28
29 CustomTableModel::CustomTableModel(QObject *parent) :
30 QAbstractTableModel(parent)
31 {
32 // qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
33
34 m_columnCount = 6;
35 m_rowCount = 5;
36 QVector<qreal>* dataVec_Jan = new QVector<qreal>(m_rowCount);
37 dataVec_Jan->insert(0, 3.0);
38 dataVec_Jan->insert(1, 4.0);
39 dataVec_Jan->insert(2, 4.4);
40 dataVec_Jan->insert(3, 6.0);
41 dataVec_Jan->insert(4, 7.0);
42 m_data.append(dataVec_Jan);
43
44 QVector<qreal>* dataVec_Feb = new QVector<qreal>(m_rowCount);
45 dataVec_Feb->insert(0, 5.0);
46 dataVec_Feb->insert(1, 6.0);
47 dataVec_Feb->insert(2, 7.5);
48 dataVec_Feb->insert(3, 8.0);
49 dataVec_Feb->insert(4, 12.0);
50 m_data.append(dataVec_Feb);
51
52 QVector<qreal>* dataVec_Mar = new QVector<qreal>(m_rowCount);
53 dataVec_Mar->insert(0, 3.0);
54 dataVec_Mar->insert(1, 4.0);
55 dataVec_Mar->insert(2, 5.7);
56 dataVec_Mar->insert(3, 8.0);
57 dataVec_Mar->insert(4, 9.0);
58 m_data.append(dataVec_Mar);
59
60 QVector<qreal>* dataVec_Apr = new QVector<qreal>(m_rowCount);
61 dataVec_Apr->insert(0, 5.0);
62 dataVec_Apr->insert(1, 6.0);
63 dataVec_Apr->insert(2, 6.8);
64 dataVec_Apr->insert(3, 7.0);
65 dataVec_Apr->insert(4, 8.0);
66 m_data.append(dataVec_Apr);
67
68 QVector<qreal>* dataVec_May = new QVector<qreal>(m_rowCount);
69 dataVec_May->insert(0, 4.0);
70 dataVec_May->insert(1, 5.0);
71 dataVec_May->insert(2, 5.2);
72 dataVec_May->insert(3, 6.0);
73 dataVec_May->insert(4, 7.0);
74 m_data.append(dataVec_May);
75
76 QVector<qreal>* dataVec_Jun = new QVector<qreal>(m_rowCount);
77 dataVec_Jun->insert(0, 4.0);
78 dataVec_Jun->insert(1, 7.0);
79 dataVec_Jun->insert(2, 8.2);
80 dataVec_Jun->insert(3, 9.0);
81 dataVec_Jun->insert(4, 10.0);
82 m_data.append(dataVec_Jun);
83 }
84
85 int CustomTableModel::rowCount(const QModelIndex &parent) const
86 {
87 Q_UNUSED(parent)
88 return m_rowCount;
89 }
90
91 int CustomTableModel::columnCount(const QModelIndex &parent) const
92 {
93 Q_UNUSED(parent)
94 return m_data.count();
95 }
96
97 QVariant CustomTableModel::headerData(int section, Qt::Orientation orientation, int role) const
98 {
99 if (role != Qt::DisplayRole)
100 return QVariant();
101
102 if (orientation == Qt::Horizontal)
103 return categories[section];
104 else
105 return QString("%1").arg(section + 1);
106 }
107
108 QVariant CustomTableModel::data(const QModelIndex &index, int role) const
109 {
110 if (role == Qt::DisplayRole) {
111 return m_data[index.column()]->at(index.row());
112 } else if (role == Qt::EditRole) {
113 return m_data[index.column()]->at(index.row());
114 } else if (role == Qt::BackgroundRole) {
115 QRect rect;
116 foreach (rect, m_mapping)
117 if (rect.contains(index.column(), index.row()))
118 return QColor(m_mapping.key(rect));
119
120 // cell not mapped return white color
121 return QColor(Qt::white);
122 }
123 return QVariant();
124 }
125
126 bool CustomTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
127 {
128 if (index.isValid() && role == Qt::EditRole) {
129 m_data[index.column()]->replace(index.row(), value.toDouble());
130 emit dataChanged(index, index);
131 return true;
132 }
133 return false;
134 }
135
136 Qt::ItemFlags CustomTableModel::flags(const QModelIndex &index) const
137 {
138 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
139 }
140
141 void CustomTableModel::addMapping(QString color, QRect area)
142 {
143 m_mapping.insertMulti(color, area);
144 }
@@ -0,0 +1,51
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 #ifndef CUSTOMTABLEMODEL_H
22 #define CUSTOMTABLEMODEL_H
23
24 #include <QAbstractTableModel>
25 #include <QHash>
26 #include <QRect>
27
28 class CustomTableModel : public QAbstractTableModel
29 {
30 Q_OBJECT
31 public:
32 explicit CustomTableModel(QObject *parent = 0);
33
34 int rowCount(const QModelIndex &parent = QModelIndex()) const;
35 int columnCount(const QModelIndex &parent = QModelIndex()) const;
36 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
37 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
38 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
39 Qt::ItemFlags flags(const QModelIndex &index) const;
40
41 void addMapping(QString color, QRect area);
42 void clearMapping() { m_mapping.clear(); }
43
44 private:
45 QList<QVector<qreal> * > m_data;
46 QHash<QString, QRect> m_mapping;
47 int m_columnCount;
48 int m_rowCount;
49 };
50
51 #endif // CUSTOMTABLEMODEL_H
@@ -53,7 +53,25 void BoxPlotAnimation::addBox(BoxWhiskers *box)
53 53 ChartAnimation *BoxPlotAnimation::boxAnimation(BoxWhiskers *box)
54 54 {
55 55 // TODO: Check for missing animation
56 return m_animations.value(box);
56 BoxWhiskersAnimation *animation = m_animations.value(box);
57 animation->m_moveMedianLine = false;
58
59 return animation;
60 }
61
62 ChartAnimation *BoxPlotAnimation::boxChangeAnimation(BoxWhiskers *box)
63 {
64 BoxWhiskersAnimation *animation = m_animations.value(box);
65 animation->m_moveMedianLine = true;
66 animation->setEndData(box->m_data);
67
68 return animation;
69 }
70
71 void BoxPlotAnimation::setAnimationStart(BoxWhiskers *box)
72 {
73 BoxWhiskersAnimation *animation = m_animations.value(box);
74 animation->setStartData(box->m_data);
57 75 }
58 76
59 77 //#include "moc_boxplotanimation_p.cpp"
@@ -48,6 +48,9 public:
48 48
49 49 void addBox(BoxWhiskers *box);
50 50 ChartAnimation *boxAnimation(BoxWhiskers *box);
51 ChartAnimation *boxChangeAnimation(BoxWhiskers *box);
52
53 void setAnimationStart(BoxWhiskers *box);
51 54
52 55 protected:
53 56 BoxPlotChartItem *m_item;
@@ -30,14 +30,6 Q_DECLARE_METATYPE(qreal)
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 BoxWhiskersAnimation::BoxWhiskersAnimation(BoxPlotChartItem *item)
34 : ChartAnimation(item),
35 m_item(item)
36 {
37 setDuration(ChartAnimationDuration);
38 setEasingCurve(QEasingCurve::OutQuart);
39 }
40
41 33 BoxWhiskersAnimation::BoxWhiskersAnimation(BoxWhiskers *box)
42 34 : ChartAnimation(box),
43 35 m_box(box)
@@ -61,21 +53,22 QVariant BoxWhiskersAnimation::interpolated(const QVariant &from, const QVariant
61 53 //qDebug() << "endData.m_median = " << endData.m_median;
62 54 }
63 55
64 result.m_lowerExtreme = endData.m_median + progress * (endData.m_lowerExtreme - endData.m_median);
65 result.m_lowerQuartile = endData.m_median + progress * (endData.m_lowerQuartile - endData.m_median);
66 result.m_median = endData.m_median;
67 result.m_upperQuartile = endData.m_median + progress * (endData.m_upperQuartile - endData.m_median);
68 result.m_upperExtreme = endData.m_median + progress * (endData.m_upperExtreme - endData.m_median);
56 if (m_moveMedianLine) {
57 result.m_lowerExtreme = startData.m_lowerExtreme + progress * (endData.m_lowerExtreme - startData.m_lowerExtreme);
58 result.m_lowerQuartile = startData.m_lowerQuartile + progress * (endData.m_lowerQuartile - startData.m_lowerQuartile);
59 result.m_median = startData.m_median + progress * (endData.m_median - startData.m_median);
60 result.m_upperQuartile = startData.m_upperQuartile + progress * (endData.m_upperQuartile - startData.m_upperQuartile);
61 result.m_upperExtreme = startData.m_upperExtreme + progress * (endData.m_upperExtreme - startData.m_upperExtreme);
62 } else {
63 result.m_lowerExtreme = endData.m_median + progress * (endData.m_lowerExtreme - endData.m_median);
64 result.m_lowerQuartile = endData.m_median + progress * (endData.m_lowerQuartile - endData.m_median);
65 result.m_median = endData.m_median;
66 result.m_upperQuartile = endData.m_median + progress * (endData.m_upperQuartile - endData.m_median);
67 result.m_upperExtreme = endData.m_median + progress * (endData.m_upperExtreme - endData.m_median);
68 }
69 69 result.m_index = endData.m_index;
70 70 result.m_boxItems = endData.m_boxItems;
71 71
72 // result.m_lowerExtreme = endData.m_lowerExtreme;
73 // result.m_lowerQuartile = endData.m_lowerQuartile;
74 // result.m_median = endData.m_median;
75 // result.m_upperQuartile = endData.m_upperQuartile;
76 // result.m_upperExtreme = endData.m_upperExtreme;
77 // result.m_index = endData.m_index;
78 // result.m_boxItems = endData.m_boxItems;
79 72
80 73 result.m_maxX = endData.m_maxX;
81 74 result.m_minX = endData.m_minX;
@@ -107,6 +100,15 void BoxWhiskersAnimation::setEndData(const BoxWhiskersData &endData)
107 100 setEndValue(qVariantFromValue(endData));
108 101 }
109 102
103 void BoxWhiskersAnimation::setStartData(const BoxWhiskersData &endData)
104 {
105 if (state() != QAbstractAnimation::Stopped)
106 stop();
107
108 setStartValue(qVariantFromValue(endData));
109 }
110
111
110 112 #include "moc_boxwhiskersanimation_p.cpp"
111 113
112 114 QTCOMMERCIALCHART_END_NAMESPACE
@@ -43,7 +43,6 class BoxWhiskersAnimation : public ChartAnimation
43 43 Q_OBJECT
44 44
45 45 public:
46 BoxWhiskersAnimation(BoxPlotChartItem *item);
47 46 BoxWhiskersAnimation(BoxWhiskers *box);
48 47 ~BoxWhiskersAnimation();
49 48
@@ -53,11 +52,16 public: // from QVariantAnimation
53 52
54 53 void setup(const BoxWhiskersData &startData, const BoxWhiskersData &endData);
55 54 void setEndData(const BoxWhiskersData &endData);
55 void setStartData(const BoxWhiskersData &endData);
56
57 void moveMedianLine(bool move);
56 58
57 59 protected:
60 friend class BoxPlotAnimation;
58 61 BoxPlotChartItem *m_item;
59 62 BoxWhiskers *m_box;
60 63 BoxWhiskersData *m_boxData;
64 bool m_moveMedianLine;
61 65 };
62 66
63 67 QTCOMMERCIALCHART_END_NAMESPACE
@@ -136,22 +136,16 void BoxPlotChartItem::handleDomainUpdated()
136 136
137 137 void BoxPlotChartItem::handleLayoutChanged()
138 138 {
139 //qDebug() << "BoxPlotChartItem::handleLayoutChanged() domain()->size() = " << domain()->size();
140 //foreach (BoxWhiskers *boxWhiskersItem, m_boxes)
141 // boxWhiskersItem->updateGeometry();
142 }
139 foreach (BoxWhiskers *item, m_boxTable.values()) {
140 if (m_animation)
141 m_animation->setAnimationStart(item);
143 142
144 void BoxPlotChartItem::handleSeriesRemove(QAbstractSeries *series)
145 {
146 qDebug() << "BoxPlotChartItem::handleSeriesRemove " << m_seriesIndex;
147 QBoxPlotSeries *removedSeries = static_cast<QBoxPlotSeries *>(series);
148 if (m_series == removedSeries) {
149 return;
143 bool dirty = updateBoxGeometry(item, item->m_data.m_index);
144 if (dirty && m_animation)
145 presenter()->startAnimation(m_animation->boxChangeAnimation(item));
146 else
147 item->updateGeometry();
150 148 }
151
152 m_seriesCount = m_seriesCount - 1;
153
154 handleDataStructureChanged();
155 149 }
156 150
157 151 QRectF BoxPlotChartItem::boundingRect() const
@@ -169,11 +163,17 QVector<QRectF> BoxPlotChartItem::calculateLayout()
169 163 return QVector<QRectF>();
170 164 }
171 165
172 void BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index)
166 bool BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index)
173 167 {
168 bool changed = false;
169
174 170 QBarSet *set = m_series->d_func()->barsetAt(index);
175 //QBarSet *set = m_barSets.at(index);
176 171 BoxWhiskersData &data = box->m_data;
172
173 if ((data.m_lowerExtreme != set->at(0)) || (data.m_lowerQuartile != set->at(1)) ||
174 (data.m_median != set->at(2)) || (data.m_upperQuartile != set->at(3)) || (data.m_upperExtreme != set->at(4)))
175 changed = true;
176
177 177 data.m_lowerExtreme = set->at(0);
178 178 data.m_lowerQuartile = set->at(1);
179 179 data.m_median = set->at(2);
@@ -189,6 +189,8 void BoxPlotChartItem::updateBoxGeometry(BoxWhiskers *box, int index)
189 189
190 190 data.m_seriesIndex = m_seriesIndex;
191 191 data.m_seriesCount = m_seriesCount;
192
193 return changed;
192 194 }
193 195
194 196 #include "moc_boxplotchartitem_p.cpp"
@@ -58,12 +58,11 public Q_SLOTS:
58 58 void handleDomainUpdated();
59 59 void handleLayoutChanged();
60 60 void handleUpdatedBars();
61 void handleSeriesRemove(QAbstractSeries *series);
62 61
63 62 private:
64 63 virtual QVector<QRectF> calculateLayout();
65 64 void initializeLayout();
66 void updateBoxGeometry(BoxWhiskers *box, int index);
65 bool updateBoxGeometry(BoxWhiskers *box, int index);
67 66
68 67 protected:
69 68 friend class QBoxPlotSeriesPrivate;
@@ -10,7 +10,9 contains(QT_MAJOR_VERSION, 5) {
10 10 }
11 11
12 12 SOURCES += main.cpp \
13 mainwidget.cpp
13 mainwidget.cpp \
14 customtablemodel.cpp
14 15
15 16 HEADERS += \
16 mainwidget.h
17 mainwidget.h \
18 customtablemodel.h
@@ -19,6 +19,10
19 19 ****************************************************************************/
20 20
21 21 #include "mainwidget.h"
22 #include "customtablemodel.h"
23 #include <QVBarModelMapper>
24 #include <QTableView>
25 #include <QHeaderView>
22 26 #include <QChartView>
23 27 #include <QBoxPlotSeries>
24 28 #include <QBarSet>
@@ -76,6 +80,19 MainWidget::MainWidget(QWidget *parent) :
76 80 initThemeCombo(grid);
77 81 initCheckboxes(grid);
78 82
83 m_model = new CustomTableModel;
84 QTableView *tableView = new QTableView;
85 tableView->setModel(m_model);
86 tableView->setMaximumWidth(200);
87 grid->addWidget(tableView, rowPos++, 0, 3, 2, Qt::AlignLeft);
88 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
89 tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
90 tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
91 #else
92 tableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
93 tableView->verticalHeader()->setResizeMode(QHeaderView::Stretch);
94 #endif
95
79 96 // add row with empty label to make all the other rows static
80 97 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
81 98 grid->setRowStretch(grid->rowCount() - 1, 1);
@@ -129,6 +146,12 void MainWidget::initCheckboxes(QGridLayout *grid)
129 146 connect(titleCheckBox, SIGNAL(toggled(bool)), this, SLOT(titleToggled(bool)));
130 147 titleCheckBox->setChecked(false);
131 148 grid->addWidget(titleCheckBox, rowPos++, 0);
149
150 QCheckBox *modelMapperCheckBox = new QCheckBox("Use model mapper");
151 connect(modelMapperCheckBox, SIGNAL(toggled(bool)), this, SLOT(modelMapperToggled(bool)));
152 modelMapperCheckBox->setChecked(false);
153 grid->addWidget(modelMapperCheckBox, rowPos++, 0);
154
132 155 }
133 156
134 157 void MainWidget::addSeries()
@@ -228,6 +251,27 void MainWidget::titleToggled(bool enabled)
228 251 m_chart->setTitle("");
229 252 }
230 253
254 void MainWidget::modelMapperToggled(bool enabled)
255 {
256 if (enabled) {
257 m_series[nSeries] = new QBoxPlotSeries();
258
259 int first = 0;
260 int count = 5;
261 QVBarModelMapper *mapper = new QVBarModelMapper(this);
262 mapper->setFirstBarSetColumn(0);
263 mapper->setLastBarSetColumn(5);
264 mapper->setFirstRow(first);
265 mapper->setRowCount(count);
266 mapper->setSeries(m_series[nSeries]);
267 mapper->setModel(m_model);
268 m_chart->addSeries(m_series[nSeries]);
269
270 nSeries++;
271 } else {
272 removeSeries();
273 }
274 }
231 275
232 276 void MainWidget::changeChartTheme(int themeIndex)
233 277 {
@@ -24,6 +24,7
24 24 #include "qchartglobal.h"
25 25 #include "qchart.h"
26 26 #include "qchartview.h"
27 #include "customtablemodel.h"
27 28 #include <QWidget>
28 29 #include <QBoxPlotSeries>
29 30 #include <QBarCategoryAxis>
@@ -51,6 +52,7 private slots:
51 52 void animationToggled(bool enabled);
52 53 void legendToggled(bool enabled);
53 54 void titleToggled(bool enabled);
55 void modelMapperToggled(bool enabled);
54 56 void changeChartTheme(int themeIndex);
55 57
56 58 private:
@@ -58,6 +60,7 private:
58 60 QChartView *m_chartView;
59 61 QGridLayout *m_scatterLayout;
60 62 QBarCategoryAxis *m_axis;
63 CustomTableModel *m_model;
61 64 int rowPos;
62 65 int nSeries;
63 66 int nNewBoxes;
General Comments 0
You need to be logged in to leave comments. Login now