@@ -101,6 +101,15 QAbstractItemModel* QAbstractSeries::model() const | |||
|
101 | 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 | 113 | void QAbstractSeries::setName(const QString& name) |
|
105 | 114 | { |
|
106 | 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): |
|
|
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 | 57 | virtual QSeriesType type() const = 0; |
|
58 | 58 | virtual bool setModel(QAbstractItemModel* model) = 0; |
|
59 | 59 | QAbstractItemModel* model() const; |
|
60 | int mapFirst() const; | |
|
61 | int mapCount() const; | |
|
60 | 62 | void setName(const QString& name); |
|
61 | 63 | QString name() const; |
|
62 | 64 |
@@ -56,6 +56,8 public: | |||
|
56 | 56 | protected: |
|
57 | 57 | QAbstractSeries *q_ptr; |
|
58 | 58 | QAbstractItemModel *m_model; |
|
59 | int m_mapFirst; | |
|
60 | int m_mapCount; | |
|
59 | 61 | QString m_name; |
|
60 | 62 | |
|
61 | 63 | friend class QAbstractSeries; |
@@ -207,10 +207,10 qreal QXYSeries::x(int pos) const | |||
|
207 | 207 | if (d->m_model) { |
|
208 | 208 | if (d->m_mapOrientation == Qt::Vertical) |
|
209 | 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 | 211 | else |
|
212 | 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 | 214 | } else { |
|
215 | 215 | // model is not specified, return the data from series' internal data store |
|
216 | 216 | return d->m_x.at(pos); |
@@ -226,10 +226,10 qreal QXYSeries::y(int pos) const | |||
|
226 | 226 | if (d->m_model) { |
|
227 | 227 | if (d->m_mapOrientation == Qt::Vertical) |
|
228 | 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 | 230 | else |
|
231 | 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 | 233 | } else { |
|
234 | 234 | // model is not specified, return the data from series' internal data store |
|
235 | 235 | return d->m_y.at(pos); |
@@ -247,11 +247,19 int QXYSeries::count() const | |||
|
247 | 247 | |
|
248 | 248 | if (d->m_model) { |
|
249 | 249 | if (d->m_mapOrientation == Qt::Vertical) { |
|
250 | // data is in a column. Return the number of mapped items | |
|
251 | return d->m_model->rowCount(); | |
|
250 | // data is in a column. Return the number of mapped items if the model's column have enough items | |
|
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 | 256 | } else { |
|
253 | // data is in a row. Return the number of mapped items | |
|
254 | return d->m_model->columnCount(); | |
|
257 | // data is in a row. Return the number of mapped items if the model's row have enough items | |
|
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 | 369 | \fn bool QXYSeries::setModel(QAbstractItemModel *model) |
|
378 | 370 | Sets the \a model to be used as a data source |
|
379 | 371 | \sa setModelMapping() |
@@ -413,7 +405,23 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientat | |||
|
413 | 405 | d->m_mapX = modelX; |
|
414 | 406 | d->m_mapY = modelY; |
|
415 | 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 | 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 | 501 | #include "moc_qxyseries.cpp" |
|
462 | 502 | #include "moc_qxyseries_p.cpp" |
|
463 | 503 |
@@ -69,9 +69,10 public: | |||
|
69 | 69 | |
|
70 | 70 | bool setModel(QAbstractItemModel *model); |
|
71 | 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 | void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight); | |
|
74 | //private Q_SLOTS: | |
|
75 | // void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight); | |
|
75 | 76 | |
|
76 | 77 | Q_SIGNALS: |
|
77 | 78 | void clicked(const QPointF &point); |
@@ -46,11 +46,20 public: | |||
|
46 | 46 | void scaleDomain(Domain& domain); |
|
47 | 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 | 54 | Q_SIGNALS: |
|
50 | 55 | void updated(); |
|
51 | 56 | void pointReplaced(int index); |
|
52 | 57 | void pointRemoved(int index); |
|
58 | void pointsRemoved(int start, int end); | |
|
53 | 59 | void pointAdded(int index); |
|
60 | void pointsAdded(int start, int end); | |
|
61 | ||
|
62 | ||
|
54 | 63 | |
|
55 | 64 | protected: |
|
56 | 65 | QVector<qreal> m_x; |
@@ -40,7 +40,9 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem | |||
|
40 | 40 | { |
|
41 | 41 | connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int))); |
|
42 | 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 | 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 | 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 | 109 | void XYChartItem::handlePointAdded(int index) |
|
108 | 110 | { |
|
109 | Q_ASSERT(index<m_series->count()); | |
|
110 |
Q_ASSERT(index> |
|
|
111 | if (m_series->model() == 0) { | |
|
112 | Q_ASSERT(index<m_series->count()); | |
|
113 | Q_ASSERT(index>=0); | |
|
114 | } | |
|
111 | 115 | QVector<QPointF> points = m_points; |
|
112 | 116 | QPointF point; |
|
113 | 117 | point = calculateGeometryPoint(index); |
@@ -115,16 +119,78 void XYChartItem::handlePointAdded(int index) | |||
|
115 | 119 | updateLayout(m_points, points, index); |
|
116 | 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 | 176 | void XYChartItem::handlePointRemoved(int index) |
|
119 | 177 | { |
|
120 | Q_ASSERT(index<m_series->count() + 1); | |
|
121 |
Q_ASSERT(index> |
|
|
178 | if (m_series->model() == 0) { | |
|
179 | Q_ASSERT(index<m_series->count() + 1); | |
|
180 | Q_ASSERT(index>=0); | |
|
181 | } | |
|
122 | 182 | QVector<QPointF> points = m_points; |
|
123 | 183 | points.remove(index); |
|
124 | 184 | updateLayout(m_points, points, index); |
|
125 | 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 | 194 | void XYChartItem::handlePointReplaced(int index) |
|
129 | 195 | { |
|
130 | 196 | Q_ASSERT(index<m_series->count()); |
@@ -43,7 +43,9 public: | |||
|
43 | 43 | |
|
44 | 44 | public Q_SLOTS: |
|
45 | 45 | void handlePointAdded(int index); |
|
46 | void handlePointsAdded(int start, int end); | |
|
46 | 47 | void handlePointRemoved(int index); |
|
48 | void handlePointsRemoved(int start, int end); | |
|
47 | 49 | void handlePointReplaced(int index); |
|
48 | 50 | void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY); |
|
49 | 51 | void handleGeometryChanged(const QRectF &size); |
@@ -52,6 +52,7 TableWidget::TableWidget(QWidget *parent) | |||
|
52 | 52 | // tableView->setItemDelegate(new QStyledItemDelegate); |
|
53 | 53 | m_chart = new QChart; |
|
54 | 54 | m_chart->legend()->setVisible(true); |
|
55 | // m_chart->setAnimationOptions(QChart::SeriesAnimations); | |
|
55 | 56 | m_chartView = new QChartView(m_chart); |
|
56 | 57 | m_chartView->setRenderHint(QPainter::Antialiasing); |
|
57 | 58 | m_chartView->setMinimumSize(640, 480); |
@@ -169,10 +170,10 void TableWidget::updateChartType(bool toggle) | |||
|
169 | 170 | m_series = new QLineSeries; |
|
170 | 171 | m_series->setModel(m_model); |
|
171 | 172 | m_series->setModelMapping(0,1, Qt::Vertical); |
|
172 |
|
|
|
173 | m_series->setModelMappingRange(4, 4); | |
|
173 | 174 | m_chart->addSeries(m_series); |
|
174 | 175 | seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper(); |
|
175 |
m_model->addMapping(seriesColorHex, QRect(0, |
|
|
176 | m_model->addMapping(seriesColorHex, QRect(0, 4, 2, 4)); | |
|
176 | 177 | |
|
177 | 178 | // series 2 |
|
178 | 179 | m_series = new QLineSeries; |
@@ -186,7 +187,7 void TableWidget::updateChartType(bool toggle) | |||
|
186 | 187 | m_series = new QLineSeries; |
|
187 | 188 | m_series->setModel(m_model); |
|
188 | 189 | m_series->setModelMapping(4,5, Qt::Vertical); |
|
189 |
|
|
|
190 | m_series->setModelMappingRange(2, -1); | |
|
190 | 191 | m_chart->addSeries(m_series); |
|
191 | 192 | seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper(); |
|
192 | 193 | m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000)); |
General Comments 0
You need to be logged in to leave comments.
Login now