##// END OF EJS Templates
QXYSeries: support for adding data to model when using custom mapping
Marek Rosa -
r1054:e65f6f3d183f
parent child
Show More
@@ -101,6 +101,15 QAbstractItemModel* QAbstractSeries::model() const
101 return d_ptr->m_model;
101 return d_ptr->m_model;
102 }
102 }
103
103
104 int QAbstractSeries::mapFirst() const
105 {
106 return d_ptr->m_mapFirst;
107 }
108 int QAbstractSeries::mapCount() const
109 {
110 return d_ptr->m_mapCount;
111 }
112
104 void QAbstractSeries::setName(const QString& name)
113 void QAbstractSeries::setName(const QString& name)
105 {
114 {
106 d_ptr->m_name = name;
115 d_ptr->m_name = name;
@@ -117,7 +126,11 QString QAbstractSeries::name() const
117
126
118 ///////////////////////////////////////////////////////////////////////////////////////////////////
127 ///////////////////////////////////////////////////////////////////////////////////////////////////
119
128
120 QAbstractSeriesPrivate::QAbstractSeriesPrivate(QAbstractSeries* q): q_ptr(q),m_model(0)
129 QAbstractSeriesPrivate::QAbstractSeriesPrivate(QAbstractSeries* q):
130 q_ptr(q),
131 m_model(0),
132 m_mapFirst(0),
133 m_mapCount(-1)
121 {
134 {
122 }
135 }
123
136
@@ -57,6 +57,8 public:
57 virtual QSeriesType type() const = 0;
57 virtual QSeriesType type() const = 0;
58 virtual bool setModel(QAbstractItemModel* model) = 0;
58 virtual bool setModel(QAbstractItemModel* model) = 0;
59 QAbstractItemModel* model() const;
59 QAbstractItemModel* model() const;
60 int mapFirst() const;
61 int mapCount() const;
60 void setName(const QString& name);
62 void setName(const QString& name);
61 QString name() const;
63 QString name() const;
62
64
@@ -56,6 +56,8 public:
56 protected:
56 protected:
57 QAbstractSeries *q_ptr;
57 QAbstractSeries *q_ptr;
58 QAbstractItemModel *m_model;
58 QAbstractItemModel *m_model;
59 int m_mapFirst;
60 int m_mapCount;
59 QString m_name;
61 QString m_name;
60
62
61 friend class QAbstractSeries;
63 friend class QAbstractSeries;
@@ -207,10 +207,10 qreal QXYSeries::x(int pos) const
207 if (d->m_model) {
207 if (d->m_model) {
208 if (d->m_mapOrientation == Qt::Vertical)
208 if (d->m_mapOrientation == Qt::Vertical)
209 // consecutive data is read from model's column
209 // consecutive data is read from model's column
210 return d->m_model->data(d->m_model->index(pos, d->m_mapX), Qt::DisplayRole).toDouble();
210 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapX), Qt::DisplayRole).toDouble();
211 else
211 else
212 // consecutive data is read from model's row
212 // consecutive data is read from model's row
213 return d->m_model->data(d->m_model->index(d->m_mapX, pos), Qt::DisplayRole).toDouble();
213 return d->m_model->data(d->m_model->index(d->m_mapX, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
214 } else {
214 } else {
215 // model is not specified, return the data from series' internal data store
215 // model is not specified, return the data from series' internal data store
216 return d->m_x.at(pos);
216 return d->m_x.at(pos);
@@ -226,10 +226,10 qreal QXYSeries::y(int pos) const
226 if (d->m_model) {
226 if (d->m_model) {
227 if (d->m_mapOrientation == Qt::Vertical)
227 if (d->m_mapOrientation == Qt::Vertical)
228 // consecutive data is read from model's column
228 // consecutive data is read from model's column
229 return d->m_model->data(d->m_model->index(pos, d->m_mapY), Qt::DisplayRole).toDouble();
229 return d->m_model->data(d->m_model->index(pos + d->m_mapFirst, d->m_mapY), Qt::DisplayRole).toDouble();
230 else
230 else
231 // consecutive data is read from model's row
231 // consecutive data is read from model's row
232 return d->m_model->data(d->m_model->index(d->m_mapY, pos), Qt::DisplayRole).toDouble();
232 return d->m_model->data(d->m_model->index(d->m_mapY, pos + d->m_mapFirst), Qt::DisplayRole).toDouble();
233 } else {
233 } else {
234 // model is not specified, return the data from series' internal data store
234 // model is not specified, return the data from series' internal data store
235 return d->m_y.at(pos);
235 return d->m_y.at(pos);
@@ -247,11 +247,19 int QXYSeries::count() const
247
247
248 if (d->m_model) {
248 if (d->m_model) {
249 if (d->m_mapOrientation == Qt::Vertical) {
249 if (d->m_mapOrientation == Qt::Vertical) {
250 // data is in a column. Return the number of mapped items
250 // data is in a column. Return the number of mapped items if the model's column have enough items
251 return d->m_model->rowCount();
251 // or the number of items that can be mapped
252 if (d->m_mapCount != -1)
253 return qMin(d->m_mapCount, qMax(d->m_model->rowCount() - d->m_mapFirst, 0));
254 else
255 return qMax(d->m_model->rowCount() - d->m_mapFirst, 0);
252 } else {
256 } else {
253 // data is in a row. Return the number of mapped items
257 // data is in a row. Return the number of mapped items if the model's row have enough items
254 return d->m_model->columnCount();
258 // or the number of items that can be mapped
259 if (d->m_mapCount != -1)
260 return qMin(d->m_mapCount, qMax(d->m_model->columnCount() - d->m_mapFirst, 0));
261 else
262 return qMax(d->m_model->columnCount() - d->m_mapFirst, 0);
255 }
263 }
256 }
264 }
257
265
@@ -358,22 +366,6 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
358 }
366 }
359
367
360 /*!
368 /*!
361 \internal
362 */
363 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
364 {
365 Q_UNUSED(bottomRight)
366 Q_D(QXYSeries);
367 if (d->m_mapOrientation == Qt::Vertical) {
368 if (topLeft.column() == d->m_mapX || topLeft.column() == d->m_mapY)
369 emit d->pointReplaced(topLeft.row());
370 } else {
371 if (topLeft.row() == d->m_mapX || topLeft.row() == d->m_mapY)
372 emit d->pointReplaced(topLeft.column());
373 }
374 }
375
376 /*!
377 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
369 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
378 Sets the \a model to be used as a data source
370 Sets the \a model to be used as a data source
379 \sa setModelMapping()
371 \sa setModelMapping()
@@ -413,7 +405,23 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientat
413 d->m_mapX = modelX;
405 d->m_mapX = modelX;
414 d->m_mapY = modelY;
406 d->m_mapY = modelY;
415 d->m_mapOrientation = orientation;
407 d->m_mapOrientation = orientation;
416 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
408
409 // connect the signals from the model
410 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
411 if (d->m_mapOrientation == Qt::Vertical) {
412 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
413 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
414 } else {
415 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
416 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
417 }
418 }
419
420 void QXYSeries::setModelMappingRange(int first, int count)
421 {
422 Q_D(QXYSeries);
423 d->m_mapFirst = first;
424 d->m_mapCount = count;
417 }
425 }
418
426
419 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
427 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -458,6 +466,38 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
458 return list << new XYLegendMarker(q,legend);
466 return list << new XYLegendMarker(q,legend);
459 }
467 }
460
468
469 void QXYSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
470 {
471 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
472 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
473 if (m_mapOrientation == Qt::Vertical) {
474 if ((column == m_mapX || column == m_mapY) // modified item is in a mapped column
475 && row >= m_mapFirst // modfied item in not before first item
476 && (m_mapCount == -1 || row < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
477 emit pointReplaced(row - m_mapFirst);
478 } else {
479 if ((row == m_mapX || row == m_mapY) // modified item is in a mapped row
480 && column >= m_mapFirst // modfied item in not before first item
481 && (m_mapCount == -1 || column < m_mapFirst + m_mapCount)) // map is not limited or item lays before the end of map
482 emit pointReplaced(column - m_mapFirst);
483 }
484 }
485 }
486 }
487
488
489 void QXYSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
490 {
491 Q_UNUSED(parent);
492 emit pointsAdded(start, end);
493 }
494
495 void QXYSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
496 {
497 Q_UNUSED(parent);
498 emit pointsRemoved(start, end);
499 }
500
461 #include "moc_qxyseries.cpp"
501 #include "moc_qxyseries.cpp"
462 #include "moc_qxyseries_p.cpp"
502 #include "moc_qxyseries_p.cpp"
463
503
@@ -69,9 +69,10 public:
69
69
70 bool setModel(QAbstractItemModel *model);
70 bool setModel(QAbstractItemModel *model);
71 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
71 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
72 void setModelMappingRange(int first, int count = -1);
72
73
73 private Q_SLOTS:
74 //private Q_SLOTS:
74 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
75 // void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
75
76
76 Q_SIGNALS:
77 Q_SIGNALS:
77 void clicked(const QPointF &point);
78 void clicked(const QPointF &point);
@@ -46,11 +46,20 public:
46 void scaleDomain(Domain& domain);
46 void scaleDomain(Domain& domain);
47 QList<LegendMarker*> createLegendMarker(QLegend* legend);
47 QList<LegendMarker*> createLegendMarker(QLegend* legend);
48
48
49 private Q_SLOTS:
50 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
51 void modelDataAdded(QModelIndex parent, int start, int end);
52 void modelDataRemoved(QModelIndex parent, int start, int end);
53
49 Q_SIGNALS:
54 Q_SIGNALS:
50 void updated();
55 void updated();
51 void pointReplaced(int index);
56 void pointReplaced(int index);
52 void pointRemoved(int index);
57 void pointRemoved(int index);
58 void pointsRemoved(int start, int end);
53 void pointAdded(int index);
59 void pointAdded(int index);
60 void pointsAdded(int start, int end);
61
62
54
63
55 protected:
64 protected:
56 QVector<qreal> m_x;
65 QVector<qreal> m_x;
@@ -40,7 +40,9 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem
40 {
40 {
41 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
41 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
42 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
42 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
43 connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
43 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
44 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
45 connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
44 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
46 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
45 }
47 }
46
48
@@ -106,8 +108,10 void XYChartItem::setLayout(QVector<QPointF> &points)
106
108
107 void XYChartItem::handlePointAdded(int index)
109 void XYChartItem::handlePointAdded(int index)
108 {
110 {
109 Q_ASSERT(index<m_series->count());
111 if (m_series->model() == 0) {
110 Q_ASSERT(index>=0);
112 Q_ASSERT(index<m_series->count());
113 Q_ASSERT(index>=0);
114 }
111 QVector<QPointF> points = m_points;
115 QVector<QPointF> points = m_points;
112 QPointF point;
116 QPointF point;
113 point = calculateGeometryPoint(index);
117 point = calculateGeometryPoint(index);
@@ -115,16 +119,78 void XYChartItem::handlePointAdded(int index)
115 updateLayout(m_points, points, index);
119 updateLayout(m_points, points, index);
116 update();
120 update();
117 }
121 }
122
123 void XYChartItem::handlePointsAdded(int start, int end)
124 {
125 if (m_series->model() == 0) {
126 for (int i = start; i <= end; i++)
127 handlePointAdded(i);
128 } else {
129 // series uses model as a data source
130 int first = m_series->mapFirst();
131 int count = m_series->mapCount();
132 int addedCount = end - start + 1;
133 if (count != -1 && start >= first + count) {
134 return;
135 }
136
137 // adding items to unlimited map
138 else if (count == -1 && start >= first) {
139 for (int i = start; i <= end; i++)
140 handlePointAdded(i - first);
141 } else if (count == - 1 && start < first) {
142 // not all newly added items
143 for (int i = first; i < first + addedCount; i++)
144 handlePointAdded(i - first);
145 }
146 // commented out code below does the same thing, but its more confusing.
147 // } else if (count == -1) {
148 // int begin = qMax(start, first);
149 // for (int i = begin; i < begin + (end - start + 1); i++)
150 // handlePointAdded(i - first);
151 // }
152
153 // adding items to limited map
154 else if (start >= first) {
155 // remove the items that will no longer fit into the map
156 // int toRemove = addedCount - (count - points().size());
157 for (int i = start; i <= end; i++) {
158 handlePointAdded(i - first);
159 }
160 if (m_points.size() > count)
161 for (int i = m_points.size() - 1; i >= count; i--)
162 handlePointRemoved(i);
163 // update();
164 } else {
165 //
166 for (int i = first; i < first + addedCount; i++) {
167 handlePointAdded(i - first);
168 }
169 if (m_points.size() > count)
170 for (int i = m_points.size() - 1; i >= count; i--)
171 handlePointRemoved(i);
172 }
173 }
174 }
175
118 void XYChartItem::handlePointRemoved(int index)
176 void XYChartItem::handlePointRemoved(int index)
119 {
177 {
120 Q_ASSERT(index<m_series->count() + 1);
178 if (m_series->model() == 0) {
121 Q_ASSERT(index>=0);
179 Q_ASSERT(index<m_series->count() + 1);
180 Q_ASSERT(index>=0);
181 }
122 QVector<QPointF> points = m_points;
182 QVector<QPointF> points = m_points;
123 points.remove(index);
183 points.remove(index);
124 updateLayout(m_points, points, index);
184 updateLayout(m_points, points, index);
125 update();
185 update();
126 }
186 }
127
187
188 void XYChartItem::handlePointsRemoved(int start, int end)
189 {
190 Q_UNUSED(start)
191 Q_UNUSED(end)
192 }
193
128 void XYChartItem::handlePointReplaced(int index)
194 void XYChartItem::handlePointReplaced(int index)
129 {
195 {
130 Q_ASSERT(index<m_series->count());
196 Q_ASSERT(index<m_series->count());
@@ -43,7 +43,9 public:
43
43
44 public Q_SLOTS:
44 public Q_SLOTS:
45 void handlePointAdded(int index);
45 void handlePointAdded(int index);
46 void handlePointsAdded(int start, int end);
46 void handlePointRemoved(int index);
47 void handlePointRemoved(int index);
48 void handlePointsRemoved(int start, int end);
47 void handlePointReplaced(int index);
49 void handlePointReplaced(int index);
48 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
50 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
49 void handleGeometryChanged(const QRectF &size);
51 void handleGeometryChanged(const QRectF &size);
@@ -52,6 +52,7 TableWidget::TableWidget(QWidget *parent)
52 // tableView->setItemDelegate(new QStyledItemDelegate);
52 // tableView->setItemDelegate(new QStyledItemDelegate);
53 m_chart = new QChart;
53 m_chart = new QChart;
54 m_chart->legend()->setVisible(true);
54 m_chart->legend()->setVisible(true);
55 // m_chart->setAnimationOptions(QChart::SeriesAnimations);
55 m_chartView = new QChartView(m_chart);
56 m_chartView = new QChartView(m_chart);
56 m_chartView->setRenderHint(QPainter::Antialiasing);
57 m_chartView->setRenderHint(QPainter::Antialiasing);
57 m_chartView->setMinimumSize(640, 480);
58 m_chartView->setMinimumSize(640, 480);
@@ -169,10 +170,10 void TableWidget::updateChartType(bool toggle)
169 m_series = new QLineSeries;
170 m_series = new QLineSeries;
170 m_series->setModel(m_model);
171 m_series->setModel(m_model);
171 m_series->setModelMapping(0,1, Qt::Vertical);
172 m_series->setModelMapping(0,1, Qt::Vertical);
172 // m_series->setModelMappingRange(1, 4);
173 m_series->setModelMappingRange(4, 4);
173 m_chart->addSeries(m_series);
174 m_chart->addSeries(m_series);
174 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
175 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
175 m_model->addMapping(seriesColorHex, QRect(0, 1, 2, 4));
176 m_model->addMapping(seriesColorHex, QRect(0, 4, 2, 4));
176
177
177 // series 2
178 // series 2
178 m_series = new QLineSeries;
179 m_series = new QLineSeries;
@@ -186,7 +187,7 void TableWidget::updateChartType(bool toggle)
186 m_series = new QLineSeries;
187 m_series = new QLineSeries;
187 m_series->setModel(m_model);
188 m_series->setModel(m_model);
188 m_series->setModelMapping(4,5, Qt::Vertical);
189 m_series->setModelMapping(4,5, Qt::Vertical);
189 // m_series->setModelMappingRange(2, 0);
190 m_series->setModelMappingRange(2, -1);
190 m_chart->addSeries(m_series);
191 m_chart->addSeries(m_series);
191 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
192 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
192 m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000));
193 m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000));
General Comments 0
You need to be logged in to leave comments. Login now