XYSeries model with limits working.

This commit is contained in:
Marek Rosa 2012-04-03 10:28:21 +03:00
parent 6772dd97cf
commit 16b8c9450c
7 changed files with 162 additions and 130 deletions

View File

@ -17,7 +17,7 @@ SUBDIRS += \
splinechart \
stackedbarchart \
stackedbarchartdrilldown \
#tablemodelchart \
tablemodelchart \
zoomlinechart

View File

@ -98,7 +98,7 @@ QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation,
}
}
else
return QString("%1").arg(section + 1);
return QString("%1").arg(section /*+ 1*/);
}
QVariant CustomTableModel::data(const QModelIndex & index, int role) const
@ -203,7 +203,10 @@ bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & pare
{
if (i - 1 >= 0)
{
difference = (int)((qAbs(m_data[i]->at(k) - m_data[row - 1]->at(k)))/count);
if (row > 0)
difference = (int)((qAbs(m_data[i]->at(k) - m_data[row - 1]->at(k)))/count);
else
difference = (int)((qAbs(m_data[i]->at(k)/count)));
dataVec->replace(k, m_data[i - 1]->at(k) + qrand()%qMax(1, difference));
}
else

View File

@ -42,14 +42,15 @@ TableWidget::TableWidget(QWidget *parent)
// create simple model for storing data
// user's table data model
m_model = new CustomTableModel;
tableView = new QTableView;
tableView->setModel(m_model);
tableView->setMinimumHeight(240);
m_tableView = new QTableView;
m_tableView->setModel(m_model);
m_tableView->setMinimumHeight(240);
// tableView->setMinimumSize(340, 480);
// tableView->setItemDelegate(new QStyledItemDelegate);
chartView = new QChartView(this);
chartView->setRenderHint(QPainter::Antialiasing);
chartView->setMinimumSize(640, 480);
m_chart = new QChart;
m_chartView = new QChartView(m_chart);
m_chartView->setRenderHint(QPainter::Antialiasing);
m_chartView->setMinimumSize(640, 480);
// create
// QLineSeries* series = new QLineSeries;
@ -74,59 +75,59 @@ TableWidget::TableWidget(QWidget *parent)
QPushButton* removeRowButton = new QPushButton("Remove row");
connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
linesCountSpinBox = new QSpinBox;
linesCountSpinBox->setRange(1, 10);
linesCountSpinBox->setValue(1);
m_linesCountSpinBox = new QSpinBox;
m_linesCountSpinBox->setRange(1, 10);
m_linesCountSpinBox->setValue(1);
// buttons layout
QVBoxLayout* buttonsLayout = new QVBoxLayout;
buttonsLayout->addWidget(linesCountSpinBox);
buttonsLayout->addWidget(m_linesCountSpinBox);
buttonsLayout->addWidget(addRowAboveButton);
buttonsLayout->addWidget(addRowBelowButton);
buttonsLayout->addWidget(removeRowButton);
buttonsLayout->addStretch();
// chart type radio buttons
lineRadioButton = new QRadioButton("Line");
splineRadioButton = new QRadioButton("Spline");
scatterRadioButton = new QRadioButton("Scatter");
pieRadioButton = new QRadioButton("Pie");
areaRadioButton = new QRadioButton("Area");
barRadioButton = new QRadioButton("Bar");
m_lineRadioButton = new QRadioButton("Line");
m_splineRadioButton = new QRadioButton("Spline");
m_scatterRadioButton = new QRadioButton("Scatter");
m_pieRadioButton = new QRadioButton("Pie");
m_areaRadioButton = new QRadioButton("Area");
m_barRadioButton = new QRadioButton("Bar");
connect(lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(areaRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(barRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
lineRadioButton->setChecked(true);
connect(m_lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(m_splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(m_scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(m_pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(m_areaRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
connect(m_barRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
m_lineRadioButton->setChecked(true);
// radio buttons layout
QVBoxLayout* radioLayout = new QVBoxLayout;
radioLayout->addWidget(lineRadioButton);
radioLayout->addWidget(splineRadioButton);
radioLayout->addWidget(scatterRadioButton);
radioLayout->addWidget(pieRadioButton);
radioLayout->addWidget(areaRadioButton);
radioLayout->addWidget(barRadioButton);
radioLayout->addWidget(m_lineRadioButton);
radioLayout->addWidget(m_splineRadioButton);
radioLayout->addWidget(m_scatterRadioButton);
radioLayout->addWidget(m_pieRadioButton);
radioLayout->addWidget(m_areaRadioButton);
radioLayout->addWidget(m_barRadioButton);
radioLayout->addStretch();
// create main layout
QGridLayout* mainLayout = new QGridLayout;
mainLayout->addLayout(buttonsLayout, 1, 0);
mainLayout->addLayout(radioLayout, 2, 0);
mainLayout->addWidget(tableView, 1, 1);
mainLayout->addWidget(chartView, 2, 1);
mainLayout->addLayout(buttonsLayout, 1, 1);
mainLayout->addLayout(radioLayout, 2, 1);
mainLayout->addWidget(m_tableView, 1, 0);
mainLayout->addWidget(m_chartView, 2, 0);
setLayout(mainLayout);
lineRadioButton->setFocus();
m_lineRadioButton->setFocus();
}
void TableWidget::addRowAbove()
{
// m_model->insertRow(m_model->rowCount());
// m_model->insertRow(tableView->currentIndex().row());
m_model->insertRows(tableView->currentIndex().row(), linesCountSpinBox->value());
m_model->insertRows(m_tableView->currentIndex().row(), m_linesCountSpinBox->value());
}
@ -134,7 +135,7 @@ void TableWidget::addRowBelow()
{
// m_model->insertRow(m_model->rowCount());
// m_model->insertRow(tableView->currentIndex().row() + 1);
m_model->insertRows(tableView->currentIndex().row() + 1, linesCountSpinBox->value());
m_model->insertRows(m_tableView->currentIndex().row() + 1, m_linesCountSpinBox->value());
}
@ -142,14 +143,14 @@ void TableWidget::removeRow()
{
// m_model->removeRow(m_model->rowCount() - 1);
// m_model->removeRow(tableView->currentIndex().row());
m_model->removeRows(tableView->currentIndex().row(), qMin(m_model->rowCount() - tableView->currentIndex().row(), linesCountSpinBox->value()));
m_model->removeRows(m_tableView->currentIndex().row(), qMin(m_model->rowCount() - m_tableView->currentIndex().row(), m_linesCountSpinBox->value()));
}
void TableWidget::updateChartType()
{
chartView->removeAllSeries();
m_chart->removeAllSeries();
if (lineRadioButton->isChecked())
if (m_lineRadioButton->isChecked())
{
QPen pen;
pen.setWidth(2);
@ -157,15 +158,15 @@ void TableWidget::updateChartType()
QColor seriesColor("#8FBC8F");
// series 1
series = new QLineSeries;
series->setModel(m_model);
series->setModelMapping(0,1, Qt::Vertical);
series->setModelMappingShift(1, 4);
m_series = new QLineSeries;
m_series->setModel(m_model);
m_series->setModelMapping(0,1, Qt::Vertical);
m_series->setModelMappingShift(3, 3);
// series->setModelMapping(0,1, Qt::Horizontal);
pen.setColor(seriesColor);
series->setPen(pen);
chartView->addSeries(series);
m_series->setPen(pen);
m_chart->addSeries(m_series);
for (int i = 1; i <=4; i++)
{
m_model->setData(m_model->index(i, 0), seriesColor , Qt::BackgroundRole);
@ -176,15 +177,16 @@ void TableWidget::updateChartType()
seriesColor = QColor("#1E90FF");
// series 2
series = new QLineSeries;
series->setModel(m_model);
series->setModelMapping(2,3, Qt::Vertical);
m_series = new QLineSeries;
m_series->setModel(m_model);
m_series->setModelMapping(2,3, Qt::Vertical);
// series->setModelMapping(2,3, Qt::Horizontal);
pen.setColor(seriesColor);
series->setPen(pen);
chartView->addSeries(series);
m_series->setPen(pen);
// m_chart->addSeries(m_series);
chartView->axisX()->setRange(0, 500);
m_chart->axisX()->setRange(0, 500);
m_chart->axisY()->setRange(0, 120);
for (int i = 0; i < m_model->rowCount(); i++)
{
@ -198,56 +200,56 @@ void TableWidget::updateChartType()
//// series->setModelMapping(4,5, Qt::Horizontal);
// chartView->addSeries(series);
}
else if (splineRadioButton->isChecked())
else if (m_splineRadioButton->isChecked())
{
// series 1
series = new QSplineSeries;
series->setModel(m_model);
series->setModelMapping(0,1, Qt::Vertical);
series->setModelMappingShift(1, 4);
m_series = new QSplineSeries;
m_series->setModel(m_model);
m_series->setModelMapping(0,1, Qt::Vertical);
m_series->setModelMappingShift(1, 4);
// series->setModelMapping(0,1, Qt::Horizontal);
chartView->addSeries(series);
m_chart->addSeries(m_series);
// series 2
series = new QSplineSeries;
series->setModel(m_model);
series->setModelMapping(2,3, Qt::Vertical);
series->setModelMappingShift(0, 0);
m_series = new QSplineSeries;
m_series->setModel(m_model);
m_series->setModelMapping(2,3, Qt::Vertical);
m_series->setModelMappingShift(0, 0);
// series->setModelMapping(2,3, Qt::Horizontal);
chartView->addSeries(series);
m_chart->addSeries(m_series);
// series 3
series = new QSplineSeries;
series->setModel(m_model);
series->setModelMapping(4,5, Qt::Vertical);
series->setModelMappingShift(0, 0);
m_series = new QSplineSeries;
m_series->setModel(m_model);
m_series->setModelMapping(4,5, Qt::Vertical);
m_series->setModelMappingShift(0, 0);
// series->setModelMapping(4,5, Qt::Horizontal);
chartView->addSeries(series);
m_chart->addSeries(m_series);
}
else if (scatterRadioButton->isChecked())
else if (m_scatterRadioButton->isChecked())
{
// series 1
series = new QScatterSeries;
series->setModel(m_model);
series->setModelMapping(0,1, Qt::Vertical);
m_series = new QScatterSeries;
m_series->setModel(m_model);
m_series->setModelMapping(0,1, Qt::Vertical);
// series->setModelMapping(0,1, Qt::Horizontal);
chartView->addSeries(series);
m_chart->addSeries(m_series);
// series 2
series = new QScatterSeries;
series->setModel(m_model);
series->setModelMapping(2,3, Qt::Vertical);
m_series = new QScatterSeries;
m_series->setModel(m_model);
m_series->setModelMapping(2,3, Qt::Vertical);
// series->setModelMapping(2,3, Qt::Horizontal);
chartView->addSeries(series);
m_chart->addSeries(m_series);
// series 3
series = new QScatterSeries;
series->setModel(m_model);
series->setModelMapping(4,5, Qt::Vertical);
m_series = new QScatterSeries;
m_series->setModel(m_model);
m_series->setModelMapping(4,5, Qt::Vertical);
// series->setModelMapping(4,5, Qt::Horizontal);
chartView->addSeries(series);
m_chart->addSeries(m_series);
}
else if (pieRadioButton->isChecked())
else if (m_pieRadioButton->isChecked())
{
// pie 1
QPieSeries* pieSeries = new QPieSeries;
@ -256,7 +258,7 @@ void TableWidget::updateChartType()
pieSeries->setLabelsVisible(true);
pieSeries->setPieSize(0.4);
pieSeries->setPiePosition(0.2, 0.35);
chartView->addSeries(pieSeries);
m_chart->addSeries(pieSeries);
// pie 2
pieSeries = new QPieSeries;
@ -265,7 +267,7 @@ void TableWidget::updateChartType()
pieSeries->setLabelsVisible(true);
pieSeries->setPieSize(0.4);
pieSeries->setPiePosition(0.8, 0.35);
chartView->addSeries(pieSeries);
m_chart->addSeries(pieSeries);
// pie 3
pieSeries = new QPieSeries;
@ -274,9 +276,9 @@ void TableWidget::updateChartType()
pieSeries->setLabelsVisible(true);
pieSeries->setPieSize(0.4);
pieSeries->setPiePosition(0.5, 0.65);
chartView->addSeries(pieSeries);
m_chart->addSeries(pieSeries);
}
else if (areaRadioButton->isChecked())
else if (m_areaRadioButton->isChecked())
{
QLineSeries* upperLineSeries = new QLineSeries;
upperLineSeries->setModel(m_model);
@ -285,15 +287,15 @@ void TableWidget::updateChartType()
lowerLineSeries->setModel(m_model);
lowerLineSeries->setModelMapping(2, 3, Qt::Vertical);
QAreaSeries* areaSeries = new QAreaSeries(upperLineSeries, lowerLineSeries);
chartView->addSeries(areaSeries);
m_chart->addSeries(areaSeries);
}
else if (barRadioButton->isChecked())
else if (m_barRadioButton->isChecked())
{
QBarSeries* barSeries = new QBarSeries(QStringList());
barSeries->setModel(m_model);
barSeries->setModelMapping(5, 2, 4, Qt::Vertical);
barSeries->setToolTipEnabled(true);
chartView->addSeries(barSeries);
m_chart->addSeries(barSeries);
}
// series->setModel(m_model);

View File

@ -49,17 +49,18 @@ public:
void updateChartType();
private:
QChartView* chartView;
QXYSeries* series;
QChartView* m_chartView;
QChart* m_chart;
QXYSeries* m_series;
CustomTableModel* m_model;
QTableView* tableView;
QRadioButton* lineRadioButton;
QRadioButton* splineRadioButton;
QRadioButton* scatterRadioButton;
QRadioButton* pieRadioButton;
QRadioButton* areaRadioButton;
QRadioButton* barRadioButton;
QSpinBox* linesCountSpinBox;
QTableView* m_tableView;
QRadioButton* m_lineRadioButton;
QRadioButton* m_splineRadioButton;
QRadioButton* m_scatterRadioButton;
QRadioButton* m_pieRadioButton;
QRadioButton* m_areaRadioButton;
QRadioButton* m_barRadioButton;
QSpinBox* m_linesCountSpinBox;
};
#endif // TABLEWIDGET_H

View File

@ -345,10 +345,10 @@ void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
// if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
// internal storage before new ones can be added
int itemsToRemove = qMin(count() - (start - m_mapFirst), end - start + 1);
int itemsToRemove = qMin(count() - qMax(start - m_mapFirst, 0), end - start + 1);
if (m_mapCount == count()) {
for (int i = 0; i < itemsToRemove; i++)
emit pointRemoved(count() - 1 - i);
emit pointRemoved(qMin(end, count()) - i);
}
}
} else {
@ -372,14 +372,16 @@ void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
// the added data is in the mapped area or before it
// update needed
if (count() > 0) {
for (int i = 0; i < qMin(m_mapCount - (start - m_mapFirst), end - start + 1); i++)
emit pointAdded(qMax(start + i - m_mapFirst, 0));
int toBeAdded = qMin(m_mapCount - (start - m_mapFirst), end - start + 1);
for (int i = 0; i < toBeAdded; i++)
if (start + i >= m_mapFirst)
emit pointAdded(start + i);
}
}
} else {
// map is not limited (it included all the items starting from m_mapFirst till the end of model)
for (int i = 0; i < end - start + 1; i++)
emit pointAdded(qMax(start + i - m_mapFirst, 0));
emit pointAdded(start + i);
}
}
@ -403,12 +405,12 @@ void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end
// the max is the current number of items in storage (count())
int itemsToRemove = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
for (int i = 0; i < itemsToRemove; i++)
emit pointRemoved(qMax(start - m_mapFirst, 0));
emit pointRemoved(start);
}
} else {
// map is not limited (it included all the items starting from m_mapFirst till the end of model)
for (int i = 0; i < end - start + 1; i++)
emit pointRemoved(qMax(start - m_mapFirst, 0));
emit pointRemoved(start);
}
}
@ -428,18 +430,22 @@ void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
} else {
// if the current items count in the whole model is bigger than the index of the last item
// that was removed than it means there are some extra items available
int removedItemsCount = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
int extraItemsAvailable = 0;
if (m_mapOrientation == Qt::Vertical) {
extraItemsAvailable = qMax(m_model->rowCount() - end, 0);
// int temp1 = m_model->rowCount();
// int temp2 = (end - start + 1);
// int temp3 = qMax(end + 1, m_mapFirst + m_mapCount);
extraItemsAvailable = qMax(m_model->rowCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
} else {
extraItemsAvailable = qMax(m_model->columnCount() - end, 0);
extraItemsAvailable = qMax(m_model->columnCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
}
// if there are excess items available (below the mapped area) use them to repopulate mapped area
int removedItemsCount = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - qMax(start, m_mapFirst) + 1);
int toBeAdded = qMin(extraItemsAvailable, removedItemsCount);
for (int k = 0; k < toBeAdded; k++)
emit pointAdded(qMax(start - m_mapFirst, m_mapFirst) + k);
emit pointAdded(m_mapFirst + m_mapCount - removedItemsCount + k);
}
} else {
// data was removed from XYSeries interal storage. Nothing more to do

View File

@ -64,6 +64,7 @@ public:
virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
virtual void setModelMappingShift(int first, int count = 0);
int mapFirst() const { return m_mapFirst; }
private Q_SLOTS:
void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);

View File

@ -105,21 +105,40 @@ void XYChartItem::setLayout(QVector<QPointF> &points)
void XYChartItem::handlePointAdded(int index)
{
Q_ASSERT(index<m_series->count());
Q_ASSERT(index>=0);
QPointF point = calculateGeometryPoint(index);
QVector<QPointF> points = m_points;
points.insert(index,point);
updateLayout(m_points,points,index);
QPointF point;
if (m_series->model()) {
point = calculateGeometryPoint(index - m_series->mapFirst());
points.insert(index - m_series->mapFirst(), point);
updateLayout(m_points, points, index - m_series->mapFirst());
}
else {
// this checks do not work correctly if model is set
Q_ASSERT(index<m_series->count());
Q_ASSERT(index>=0);
point = calculateGeometryPoint(index);
points.insert(index, point);
updateLayout(m_points, points, index);
}
update();
}
void XYChartItem::handlePointRemoved(int index)
{
Q_ASSERT(index<m_series->count() + 1);
Q_ASSERT(index>=0);
{
QVector<QPointF> points = m_points;
points.remove(index);
updateLayout(m_points,points,index);
if (m_series->model()) {
if (index < m_series->mapFirst())
points.remove(0);
else
points.remove(index - m_series->mapFirst());
updateLayout(m_points, points, index - m_series->mapFirst());
}
else {
// this checks do not work correctly if model is set
Q_ASSERT(index<m_series->count() + 1);
Q_ASSERT(index>=0);
points.remove(index);
updateLayout(m_points, points, index);
}
update();
}
@ -149,21 +168,21 @@ void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal
void XYChartItem::handleGeometryChanged(const QRectF &rect)
{
Q_ASSERT(rect.isValid());
m_size=rect.size();
m_clipRect=rect.translated(-rect.topLeft());
setPos(rect.topLeft());
Q_ASSERT(rect.isValid());
m_size=rect.size();
m_clipRect=rect.translated(-rect.topLeft());
setPos(rect.topLeft());
if (isEmpty()) return;
QVector<QPointF> points = calculateGeometryPoints();
updateLayout(m_points,points);
update();
QVector<QPointF> points = calculateGeometryPoints();
updateLayout(m_points,points);
update();
}
bool XYChartItem::isEmpty()
{
return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY);
return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY);
}
void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)