##// END OF EJS Templates
XYSeries: added support for limited mapping area
Marek Rosa -
r734:cfecc74c9bfa
parent child
Show More
@@ -1,204 +1,214
1 #include "customtablemodel.h"
1 #include "customtablemodel.h"
2 #include <QVector>
2 #include <QVector>
3 #include <QTime>
3
4
4 CustomTableModel::CustomTableModel(QObject *parent) :
5 CustomTableModel::CustomTableModel(QObject *parent) :
5 QAbstractTableModel(parent)
6 QAbstractTableModel(parent)
6 {
7 {
7 // m_points.append(QPointF(10, 50));
8 // m_points.append(QPointF(10, 50));
8 // m_labels.append("Apples");
9 // m_labels.append("Apples");
9 // m_points.append(QPointF(60, 70));
10 // m_points.append(QPointF(60, 70));
10 // m_labels.append("Oranges");
11 // m_labels.append("Oranges");
11 // m_points.append(QPointF(110, 50));
12 // m_points.append(QPointF(110, 50));
12 // m_labels.append("Bananas");
13 // m_labels.append("Bananas");
13 // m_points.append(QPointF(140, 40));
14 // m_points.append(QPointF(140, 40));
14 // m_labels.append("Lemons");
15 // m_labels.append("Lemons");
15 // m_points.append(QPointF(200, 150));
16 // m_points.append(QPointF(200, 150));
16 // m_labels.append("Plums");
17 // m_labels.append("Plums");
17 // m_points.append(QPointF(225, 75));
18 // m_points.append(QPointF(225, 75));
18 // m_labels.append("Pearls");
19 // m_labels.append("Pearls");
19
20
21 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
22
20 // m_data
23 // m_data
21 for (int i = 0; i < 6; i++)
24 for (int i = 0; i < 6; i++)
22 {
25 {
23 QVector<qreal>* dataVec = new QVector<qreal>(6);
26 QVector<qreal>* dataVec = new QVector<qreal>(6);
24 for (int k = 0; k < dataVec->size(); k++)
27 for (int k = 0; k < dataVec->size(); k++)
25 if (k%2 == 0)
28 if (k%2 == 0)
26 dataVec->replace(k, i * 50 + qrand()%20);
29 dataVec->replace(k, i * 50 + qrand()%20);
27 else
30 else
28 dataVec->replace(k, qrand()%100);
31 dataVec->replace(k, qrand()%100);
29 m_data.append(dataVec);
32 m_data.append(dataVec);
30 m_labels.append(QString("Row: %1").arg((i + 1)));
33 m_labels.append(QString("Row: %1").arg((i + 1)));
31 }
34 }
32 }
35 }
33
36
34 int CustomTableModel::rowCount(const QModelIndex & parent) const
37 int CustomTableModel::rowCount(const QModelIndex & parent) const
35 {
38 {
36 Q_UNUSED(parent)
39 Q_UNUSED(parent)
37 // return m_points.count();
40 // return m_points.count();
38 return m_data.count();
41 return m_data.count();
39 }
42 }
40
43
41 int CustomTableModel::columnCount(const QModelIndex & parent) const
44 int CustomTableModel::columnCount(const QModelIndex & parent) const
42 {
45 {
43 Q_UNUSED(parent)
46 Q_UNUSED(parent)
44 // return 3;
47 // return 3;
45 return 6;
48 return 6;
46 }
49 }
47
50
48 QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation, int role ) const
51 QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation, int role ) const
49 {
52 {
50 if (role != Qt::DisplayRole)
53 if (role != Qt::DisplayRole)
51 return QVariant();
54 return QVariant();
52
55
53 if (orientation == Qt::Horizontal)
56 if (orientation == Qt::Horizontal)
54 {
57 {
55 switch(section)
58 switch(section)
56 {
59 {
57 // case 0:
60 // case 0:
58 // return "x";
61 // return "x";
59 // case 1:
62 // case 1:
60 // return "y";
63 // return "y";
61 // case 2:
64 // case 2:
62 case 6:
65 case 6:
63 return "Fruit";
66 return "Fruit";
64 default:
67 default:
65 if (section%2 == 0)
68 if (section%2 == 0)
66 return "x";
69 return "x";
67 else
70 else
68 return "y";
71 return "y";
69 // return "What?";
72 // return "What?";
70 }
73 }
71 }
74 }
72 else
75 else
73 return QString("%1").arg(section + 1);
76 return QString("%1").arg(section + 1);
74 }
77 }
75
78
76 QVariant CustomTableModel::data(const QModelIndex & index, int role) const
79 QVariant CustomTableModel::data(const QModelIndex & index, int role) const
77 {
80 {
78 if (role == Qt::DisplayRole)
81 if (role == Qt::DisplayRole)
79 {
82 {
80 switch(index.column())
83 switch(index.column())
81 {
84 {
82 // case 0:
85 // case 0:
83 // return m_points[index.row()].x();
86 // return m_points[index.row()].x();
84 // case 1:
87 // case 1:
85 // return m_points[index.row()].y();
88 // return m_points[index.row()].y();
86 // case 2:
89 // case 2:
87 case 6:
90 case 6:
88 return m_labels[index.row()];
91 return m_labels[index.row()];
89 default:
92 default:
90 return m_data[index.row()]->at(index.column());
93 return m_data[index.row()]->at(index.column());
91 break;
94 break;
92 }
95 }
93 }
96 }
94 else if (role == Qt::EditRole)
97 else if (role == Qt::EditRole)
95 {
98 {
96 switch(index.column())
99 switch(index.column())
97 {
100 {
98 // case 0:
101 // case 0:
99 // return m_points[index.row()].x();
102 // return m_points[index.row()].x();
100 // case 1:
103 // case 1:
101 // return m_points[index.row()].y();
104 // return m_points[index.row()].y();
102 // case 2:
105 // case 2:
103 case 6:
106 case 6:
104 return m_labels[index.row()];
107 return m_labels[index.row()];
105 default:
108 default:
106 return m_data[index.row()]->at(index.column());
109 return m_data[index.row()]->at(index.column());
107 break;
110 break;
108 }
111 }
109 }
112 }
110 return QVariant();
113 return QVariant();
111 }
114 }
112
115
113 bool CustomTableModel::setData ( const QModelIndex & index, const QVariant & value, int role)
116 bool CustomTableModel::setData ( const QModelIndex & index, const QVariant & value, int role)
114 {
117 {
115 if (index.isValid() && role == Qt::EditRole)
118 if (index.isValid() && role == Qt::EditRole)
116 {
119 {
117 switch(index.column())
120 switch(index.column())
118 {
121 {
119 // case 0:
122 // case 0:
120 // m_points[index.row()].setX(value.toDouble());
123 // m_points[index.row()].setX(value.toDouble());
121 // break;
124 // break;
122 // case 1:
125 // case 1:
123 // m_points[index.row()].setY(value.toDouble());
126 // m_points[index.row()].setY(value.toDouble());
124 // break;
127 // break;
125 // case 2:
128 // case 2:
126 case 6:
129 case 6:
127 m_labels.replace(index.row(), value.toString());
130 m_labels.replace(index.row(), value.toString());
128 break;
131 break;
129 default:
132 default:
130 m_data[index.row()]->replace(index.column(), value.toDouble());
133 m_data[index.row()]->replace(index.column(), value.toDouble());
131 break;
134 break;
132 // return false;
135 // return false;
133 }
136 }
134 emit dataChanged(index, index);
137 emit dataChanged(index, index);
135 return true;
138 return true;
136 }
139 }
137 return false;
140 return false;
138 }
141 }
139
142
140 Qt::ItemFlags CustomTableModel::flags ( const QModelIndex & index ) const
143 Qt::ItemFlags CustomTableModel::flags ( const QModelIndex & index ) const
141 {
144 {
142 // if (!index.isValid())
145 // if (!index.isValid())
143 // return Qt::ItemIsEnabled;
146 // return Qt::ItemIsEnabled;
144 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
147 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
145 }
148 }
146
149
147 bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & parent)
150 bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & parent)
148 {
151 {
149 Q_UNUSED(parent)
152 Q_UNUSED(parent)
150
153
151 if (row < 0)
154 if (row < 0)
152 row = 0;
155 row = 0;
153 beginInsertRows(QModelIndex(), row /*dataTable.count()*/, row + count - 1);
156 beginInsertRows(QModelIndex(), row /*dataTable.count()*/, row + count - 1);
154 for (int i = row; i < row + count; i++)
157 for (int i = row; i < row + count; i++)
155 {
158 {
156 // m_points.insert(row, QPointF(10,20));
159 // m_points.insert(row, QPointF(10,20));
157 QVector<qreal>* dataVec = new QVector<qreal>(6);
160 QVector<qreal>* dataVec = new QVector<qreal>(6);
158 for (int k = 0; k < dataVec->size(); k++)
161 for (int k = 0; k < dataVec->size(); k++)
159 if (k%2 == 0)
162 if (k%2 == 0)
160 // dataVec->replace(k, i * 50 + qrand()%20);
163 // dataVec->replace(k, i * 50 + qrand()%20);
161 {
164 {
162 int difference = 0;
165 int difference = 0;
163 if (row < m_data.size())
166 if (row < m_data.size())
164 {
167 {
165 if (row - 1 >= 0)
168 if (row - 1 >= 0)
166 {
169 {
167 difference = (int)(qAbs(m_data[row]->at(k) - m_data[row - 1]->at(k)));
170 difference = (int)(qAbs(m_data[row]->at(k) - m_data[row - 1]->at(k)));
168 dataVec->replace(k, m_data[row - 1]->at(k) + qrand()%qMax(1, difference));
171 dataVec->replace(k, m_data[row - 1]->at(k) + qrand()%qMax(1, difference));
169 }
172 }
170 else
173 else
171 dataVec->replace(k, qrand()%20);
174 dataVec->replace(k, qrand()%40 + 10);
172 }
175 }
173 else
176 else
174 dataVec->replace(k, m_data[row - 1]->at(k) + qrand()%20);
177 if (row - 1 >= 0)
178 {
179 dataVec->replace(k, m_data[row - 1]->at(k) + qrand()%40 + 10);
180 }
181 else
182 {
183 dataVec->replace(k, qrand()%40 + 10);
184 }
175 }
185 }
176 else
186 else
177 dataVec->replace(k, qrand()%100);
187 dataVec->replace(k, qrand()%100);
178 m_data.insert(row, dataVec);
188 m_data.insert(row, dataVec);
179 m_labels.insert(row,(QString("Row: %1").arg(row + 1)));
189 m_labels.insert(row,(QString("Row: %1").arg(row + 1)));
180 }
190 }
181 endInsertRows();
191 endInsertRows();
182 return true;
192 return true;
183 }
193 }
184
194
185 bool CustomTableModel::removeRows ( int row, int count, const QModelIndex & parent)
195 bool CustomTableModel::removeRows ( int row, int count, const QModelIndex & parent)
186 {
196 {
187 if (row > this->rowCount() - 1)
197 if (row > this->rowCount() - 1)
188 return false;
198 return false;
189 if (row < 0)
199 if (row < 0)
190 row = 0;
200 row = 0;
191 if (row + count > rowCount())
201 if (row + count > rowCount())
192 return false;
202 return false;
193 beginRemoveRows(parent, row, row + count - 1);
203 beginRemoveRows(parent, row, row + count - 1);
194 for (int i = row; i < row + count; i++)
204 for (int i = row; i < row + count; i++)
195 {
205 {
196 // m_points.removeAt(row);
206 // m_points.removeAt(row);
197 QVector<qreal>* item = m_data.at(row);
207 QVector<qreal>* item = m_data.at(row);
198 m_data.removeAt(row);
208 m_data.removeAt(row);
199 delete item;
209 delete item;
200 m_labels.removeAt(row);
210 m_labels.removeAt(row);
201 }
211 }
202 endRemoveRows();
212 endRemoveRows();
203 return true;
213 return true;
204 }
214 }
@@ -1,249 +1,251
1 #include "tablewidget.h"
1 #include "tablewidget.h"
2 #include <QGridLayout>
2 #include <QGridLayout>
3 #include <QTableView>
3 #include <QTableView>
4 #include <QStyledItemDelegate>
4 #include <QStyledItemDelegate>
5 #include "qlineseries.h"
5 #include "qlineseries.h"
6 #include "qsplineseries.h"
6 #include "qsplineseries.h"
7 #include "qscatterseries.h"
7 #include "qscatterseries.h"
8 #include "customtablemodel.h"
8 #include "customtablemodel.h"
9 #include "qpieseries.h"
9 #include "qpieseries.h"
10 #include "qareaseries.h"
10 #include "qareaseries.h"
11 #include "qbarseries.h"
11 #include "qbarseries.h"
12 #include <QPushButton>
12 #include <QPushButton>
13 #include <QRadioButton>
13 #include <QRadioButton>
14 #include <QTime>
14 #include <QTime>
15
15
16 TableWidget::TableWidget(QWidget *parent)
16 TableWidget::TableWidget(QWidget *parent)
17 : QWidget(parent)
17 : QWidget(parent)
18 {
18 {
19 setGeometry(100, 100, 1000, 600);
19 setGeometry(100, 100, 1000, 600);
20 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
20 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
21 // create simple model for storing data
21 // create simple model for storing data
22 // user's table data model
22 // user's table data model
23 m_model = new CustomTableModel;
23 m_model = new CustomTableModel;
24 tableView = new QTableView;
24 tableView = new QTableView;
25 tableView->setModel(m_model);
25 tableView->setModel(m_model);
26 tableView->setMinimumHeight(240);
26 tableView->setMinimumHeight(240);
27 // tableView->setMinimumSize(340, 480);
27 // tableView->setMinimumSize(340, 480);
28 // tableView->setItemDelegate(new QStyledItemDelegate);
28 // tableView->setItemDelegate(new QStyledItemDelegate);
29 chartView = new QChartView(this);
29 chartView = new QChartView(this);
30 chartView->setRenderHint(QPainter::Antialiasing);
30 chartView->setRenderHint(QPainter::Antialiasing);
31 chartView->setMinimumSize(640, 480);
31 chartView->setMinimumSize(640, 480);
32
32
33 // create
33 // create
34 // QLineSeries* series = new QLineSeries;
34 // QLineSeries* series = new QLineSeries;
35 // QSplineSeries* series = new QSplineSeries;
35 // QSplineSeries* series = new QSplineSeries;
36 // QScatterSeries* series = new QScatterSeries;
36 // QScatterSeries* series = new QScatterSeries;
37 // series->setModel(m_model);
37 // series->setModel(m_model);
38 // series->setModelMapping(0,1, Qt::Vertical);
38 // series->setModelMapping(0,1, Qt::Vertical);
39
39
40 // QPieSeries* pieSeries = new QPieSeries;
40 // QPieSeries* pieSeries = new QPieSeries;
41 // pieSeries->setModel(model);
41 // pieSeries->setModel(model);
42 // pieSeries
42 // pieSeries
43
43
44 // chartView->addSeries(series);
44 // chartView->addSeries(series);
45
45
46 // add, remove data buttons
46 // add, remove data buttons
47 QPushButton* addRowAboveButton = new QPushButton("Add row above");
47 QPushButton* addRowAboveButton = new QPushButton("Add row above");
48 connect(addRowAboveButton, SIGNAL(clicked()), this, SLOT(addRowAbove()));
48 connect(addRowAboveButton, SIGNAL(clicked()), this, SLOT(addRowAbove()));
49
49
50 QPushButton* addRowBelowButton = new QPushButton("Add row below");
50 QPushButton* addRowBelowButton = new QPushButton("Add row below");
51 connect(addRowBelowButton, SIGNAL(clicked()), this, SLOT(addRowBelow()));
51 connect(addRowBelowButton, SIGNAL(clicked()), this, SLOT(addRowBelow()));
52
52
53 QPushButton* removeRowButton = new QPushButton("Remove row");
53 QPushButton* removeRowButton = new QPushButton("Remove row");
54 connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
54 connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
55
55
56 // buttons layout
56 // buttons layout
57 QVBoxLayout* buttonsLayout = new QVBoxLayout;
57 QVBoxLayout* buttonsLayout = new QVBoxLayout;
58 buttonsLayout->addWidget(addRowAboveButton);
58 buttonsLayout->addWidget(addRowAboveButton);
59 buttonsLayout->addWidget(addRowBelowButton);
59 buttonsLayout->addWidget(addRowBelowButton);
60 buttonsLayout->addWidget(removeRowButton);
60 buttonsLayout->addWidget(removeRowButton);
61 buttonsLayout->addStretch();
61 buttonsLayout->addStretch();
62
62
63 // chart type radio buttons
63 // chart type radio buttons
64 lineRadioButton = new QRadioButton("Line");
64 lineRadioButton = new QRadioButton("Line");
65 splineRadioButton = new QRadioButton("Spline");
65 splineRadioButton = new QRadioButton("Spline");
66 scatterRadioButton = new QRadioButton("Scatter");
66 scatterRadioButton = new QRadioButton("Scatter");
67 pieRadioButton = new QRadioButton("Pie");
67 pieRadioButton = new QRadioButton("Pie");
68 areaRadioButton = new QRadioButton("Area");
68 areaRadioButton = new QRadioButton("Area");
69 barRadioButton = new QRadioButton("Bar");
69 barRadioButton = new QRadioButton("Bar");
70
70
71 connect(lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
71 connect(lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
72 connect(splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
72 connect(splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
73 connect(scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
73 connect(scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
74 connect(pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
74 connect(pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
75 connect(areaRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
75 connect(areaRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
76 connect(barRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
76 connect(barRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
77 lineRadioButton->setChecked(true);
77 lineRadioButton->setChecked(true);
78
78
79 // radio buttons layout
79 // radio buttons layout
80 QVBoxLayout* radioLayout = new QVBoxLayout;
80 QVBoxLayout* radioLayout = new QVBoxLayout;
81 radioLayout->addWidget(lineRadioButton);
81 radioLayout->addWidget(lineRadioButton);
82 radioLayout->addWidget(splineRadioButton);
82 radioLayout->addWidget(splineRadioButton);
83 radioLayout->addWidget(scatterRadioButton);
83 radioLayout->addWidget(scatterRadioButton);
84 radioLayout->addWidget(pieRadioButton);
84 radioLayout->addWidget(pieRadioButton);
85 radioLayout->addWidget(areaRadioButton);
85 radioLayout->addWidget(areaRadioButton);
86 radioLayout->addWidget(barRadioButton);
86 radioLayout->addWidget(barRadioButton);
87 radioLayout->addStretch();
87 radioLayout->addStretch();
88
88
89 // create main layout
89 // create main layout
90 QGridLayout* mainLayout = new QGridLayout;
90 QGridLayout* mainLayout = new QGridLayout;
91 mainLayout->addLayout(buttonsLayout, 1, 0);
91 mainLayout->addLayout(buttonsLayout, 1, 0);
92 mainLayout->addLayout(radioLayout, 2, 0);
92 mainLayout->addLayout(radioLayout, 2, 0);
93 mainLayout->addWidget(tableView, 1, 1);
93 mainLayout->addWidget(tableView, 1, 1);
94 mainLayout->addWidget(chartView, 2, 1);
94 mainLayout->addWidget(chartView, 2, 1);
95 setLayout(mainLayout);
95 setLayout(mainLayout);
96 lineRadioButton->setFocus();
96 lineRadioButton->setFocus();
97 }
97 }
98
98
99 void TableWidget::addRowAbove()
99 void TableWidget::addRowAbove()
100 {
100 {
101 // m_model->insertRow(m_model->rowCount());
101 // m_model->insertRow(m_model->rowCount());
102 m_model->insertRow(tableView->currentIndex().row());
102 m_model->insertRow(tableView->currentIndex().row());
103
103
104 }
104 }
105
105
106 void TableWidget::addRowBelow()
106 void TableWidget::addRowBelow()
107 {
107 {
108 // m_model->insertRow(m_model->rowCount());
108 // m_model->insertRow(m_model->rowCount());
109 m_model->insertRow(tableView->currentIndex().row() + 1);
109 m_model->insertRow(tableView->currentIndex().row() + 1);
110
110
111 }
111 }
112
112
113 void TableWidget::removeRow()
113 void TableWidget::removeRow()
114 {
114 {
115 // m_model->removeRow(m_model->rowCount() - 1);
115 // m_model->removeRow(m_model->rowCount() - 1);
116 m_model->removeRow(tableView->currentIndex().row());
116 m_model->removeRow(tableView->currentIndex().row());
117 }
117 }
118
118
119 void TableWidget::updateChartType()
119 void TableWidget::updateChartType()
120 {
120 {
121 chartView->removeAllSeries();
121 chartView->removeAllSeries();
122
122
123 if (lineRadioButton->isChecked())
123 if (lineRadioButton->isChecked())
124 {
124 {
125 // series 1
125 // series 1
126 series = new QLineSeries;
126 series = new QLineSeries;
127 series->setModel(m_model);
127 series->setModel(m_model);
128 series->setModelMapping(0,1, Qt::Vertical);
128 series->setModelMapping(0,1, Qt::Vertical);
129 series->setModelMappingShift(1, 4);
129 // series->setModelMapping(0,1, Qt::Horizontal);
130 // series->setModelMapping(0,1, Qt::Horizontal);
130 chartView->addSeries(series);
131 chartView->addSeries(series);
131
132
132 // series 2
133 // series 2
133 series = new QLineSeries;
134 series = new QLineSeries;
134 series->setModel(m_model);
135 series->setModel(m_model);
135 series->setModelMapping(2,3, Qt::Vertical);
136 series->setModelMapping(2,3, Qt::Vertical);
136 // series->setModelMapping(2,3, Qt::Horizontal);
137 // series->setModelMapping(2,3, Qt::Horizontal);
137 chartView->addSeries(series);
138 chartView->addSeries(series);
138
139
139 // series 3
140 // // series 3
140 series = new QLineSeries;
141 // series = new QLineSeries;
141 series->setModel(m_model);
142 // series->setModel(m_model);
142 series->setModelMapping(4,5, Qt::Vertical);
143 // series->setModelMapping(4,5, Qt::Vertical);
143 // series->setModelMapping(4,5, Qt::Horizontal);
144 //// series->setModelMapping(4,5, Qt::Horizontal);
144 chartView->addSeries(series);
145 // chartView->addSeries(series);
145 }
146 }
146 else if (splineRadioButton->isChecked())
147 else if (splineRadioButton->isChecked())
147 {
148 {
148 // series 1
149 // series 1
149 series = new QSplineSeries;
150 series = new QSplineSeries;
150 series->setModel(m_model);
151 series->setModel(m_model);
151 series->setModelMapping(0,1, Qt::Vertical);
152 series->setModelMapping(0,1, Qt::Vertical);
153 series->setModelMappingShift(1, 4);
152 // series->setModelMapping(0,1, Qt::Horizontal);
154 // series->setModelMapping(0,1, Qt::Horizontal);
153 chartView->addSeries(series);
155 chartView->addSeries(series);
154
156
155 // series 2
157 // series 2
156 series = new QSplineSeries;
158 series = new QSplineSeries;
157 series->setModel(m_model);
159 series->setModel(m_model);
158 series->setModelMapping(2,3, Qt::Vertical);
160 series->setModelMapping(2,3, Qt::Vertical);
159 // series->setModelMapping(2,3, Qt::Horizontal);
161 // series->setModelMapping(2,3, Qt::Horizontal);
160 chartView->addSeries(series);
162 chartView->addSeries(series);
161
163
162 // series 3
164 // series 3
163 series = new QSplineSeries;
165 series = new QSplineSeries;
164 series->setModel(m_model);
166 series->setModel(m_model);
165 series->setModelMapping(4,5, Qt::Vertical);
167 series->setModelMapping(4,5, Qt::Vertical);
166 // series->setModelMapping(4,5, Qt::Horizontal);
168 // series->setModelMapping(4,5, Qt::Horizontal);
167 chartView->addSeries(series);
169 chartView->addSeries(series);
168 }
170 }
169 else if (scatterRadioButton->isChecked())
171 else if (scatterRadioButton->isChecked())
170 {
172 {
171 // series 1
173 // series 1
172 series = new QScatterSeries;
174 series = new QScatterSeries;
173 series->setModel(m_model);
175 series->setModel(m_model);
174 series->setModelMapping(0,1, Qt::Vertical);
176 series->setModelMapping(0,1, Qt::Vertical);
175 // series->setModelMapping(0,1, Qt::Horizontal);
177 // series->setModelMapping(0,1, Qt::Horizontal);
176 chartView->addSeries(series);
178 chartView->addSeries(series);
177
179
178 // series 2
180 // series 2
179 series = new QScatterSeries;
181 series = new QScatterSeries;
180 series->setModel(m_model);
182 series->setModel(m_model);
181 series->setModelMapping(2,3, Qt::Vertical);
183 series->setModelMapping(2,3, Qt::Vertical);
182 // series->setModelMapping(2,3, Qt::Horizontal);
184 // series->setModelMapping(2,3, Qt::Horizontal);
183 chartView->addSeries(series);
185 chartView->addSeries(series);
184
186
185 // series 3
187 // series 3
186 series = new QScatterSeries;
188 series = new QScatterSeries;
187 series->setModel(m_model);
189 series->setModel(m_model);
188 series->setModelMapping(4,5, Qt::Vertical);
190 series->setModelMapping(4,5, Qt::Vertical);
189 // series->setModelMapping(4,5, Qt::Horizontal);
191 // series->setModelMapping(4,5, Qt::Horizontal);
190 chartView->addSeries(series);
192 chartView->addSeries(series);
191 }
193 }
192 else if (pieRadioButton->isChecked())
194 else if (pieRadioButton->isChecked())
193 {
195 {
194 // pie 1
196 // pie 1
195 QPieSeries* pieSeries = new QPieSeries;
197 QPieSeries* pieSeries = new QPieSeries;
196 pieSeries->setModel(m_model);
198 pieSeries->setModel(m_model);
197 pieSeries->setModelMapping(0,0, Qt::Vertical);
199 pieSeries->setModelMapping(0,0, Qt::Vertical);
198 pieSeries->setLabelsVisible(true);
200 pieSeries->setLabelsVisible(true);
199 pieSeries->setPieSize(0.4);
201 pieSeries->setPieSize(0.4);
200 pieSeries->setPiePosition(0.2, 0.35);
202 pieSeries->setPiePosition(0.2, 0.35);
201 chartView->addSeries(pieSeries);
203 chartView->addSeries(pieSeries);
202
204
203 // pie 2
205 // pie 2
204 pieSeries = new QPieSeries;
206 pieSeries = new QPieSeries;
205 pieSeries->setModel(m_model);
207 pieSeries->setModel(m_model);
206 pieSeries->setModelMapping(1,1, Qt::Vertical);
208 pieSeries->setModelMapping(1,1, Qt::Vertical);
207 pieSeries->setLabelsVisible(true);
209 pieSeries->setLabelsVisible(true);
208 pieSeries->setPieSize(0.4);
210 pieSeries->setPieSize(0.4);
209 pieSeries->setPiePosition(0.8, 0.35);
211 pieSeries->setPiePosition(0.8, 0.35);
210 chartView->addSeries(pieSeries);
212 chartView->addSeries(pieSeries);
211
213
212 // pie 3
214 // pie 3
213 pieSeries = new QPieSeries;
215 pieSeries = new QPieSeries;
214 pieSeries->setModel(m_model);
216 pieSeries->setModel(m_model);
215 pieSeries->setModelMapping(2,2, Qt::Vertical);
217 pieSeries->setModelMapping(2,2, Qt::Vertical);
216 pieSeries->setLabelsVisible(true);
218 pieSeries->setLabelsVisible(true);
217 pieSeries->setPieSize(0.4);
219 pieSeries->setPieSize(0.4);
218 pieSeries->setPiePosition(0.5, 0.65);
220 pieSeries->setPiePosition(0.5, 0.65);
219 chartView->addSeries(pieSeries);
221 chartView->addSeries(pieSeries);
220 }
222 }
221 else if (areaRadioButton->isChecked())
223 else if (areaRadioButton->isChecked())
222 {
224 {
223 QLineSeries* upperLineSeries = new QLineSeries;
225 QLineSeries* upperLineSeries = new QLineSeries;
224 upperLineSeries->setModel(m_model);
226 upperLineSeries->setModel(m_model);
225 upperLineSeries->setModelMapping(0, 1, Qt::Vertical);
227 upperLineSeries->setModelMapping(0, 1, Qt::Vertical);
226 QLineSeries* lowerLineSeries = new QLineSeries;
228 QLineSeries* lowerLineSeries = new QLineSeries;
227 lowerLineSeries->setModel(m_model);
229 lowerLineSeries->setModel(m_model);
228 lowerLineSeries->setModelMapping(2, 3, Qt::Vertical);
230 lowerLineSeries->setModelMapping(2, 3, Qt::Vertical);
229 QAreaSeries* areaSeries = new QAreaSeries(upperLineSeries, lowerLineSeries);
231 QAreaSeries* areaSeries = new QAreaSeries(upperLineSeries, lowerLineSeries);
230 chartView->addSeries(areaSeries);
232 chartView->addSeries(areaSeries);
231 }
233 }
232 else if (barRadioButton->isChecked())
234 else if (barRadioButton->isChecked())
233 {
235 {
234 QBarSeries* barSeries = new QBarSeries(QStringList());
236 QBarSeries* barSeries = new QBarSeries(QStringList());
235 barSeries->setModel(m_model);
237 barSeries->setModel(m_model);
236 barSeries->setModelMapping(5, 2, 4, Qt::Vertical);
238 barSeries->setModelMapping(5, 2, 4, Qt::Vertical);
237 barSeries->setToolTipEnabled(true);
239 barSeries->setToolTipEnabled(true);
238 chartView->addSeries(barSeries);
240 chartView->addSeries(barSeries);
239 }
241 }
240
242
241 // series->setModel(m_model);
243 // series->setModel(m_model);
242 // series->setModelMapping(0,1, Qt::Vertical);
244 // series->setModelMapping(0,1, Qt::Vertical);
243 // chartView->addSeries(series);
245 // chartView->addSeries(series);
244 }
246 }
245
247
246 TableWidget::~TableWidget()
248 TableWidget::~TableWidget()
247 {
249 {
248
250
249 }
251 }
@@ -1,380 +1,391
1 #include <QDebug>
1 #include <QDebug>
2 #include "qbarseries.h"
2 #include "qbarseries.h"
3 #include "qbarset.h"
3 #include "qbarset.h"
4 #include "barchartmodel_p.h"
4 #include "barchartmodel_p.h"
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 /*!
8 /*!
9 \class QBarSeries
9 \class QBarSeries
10 \brief part of QtCommercial chart API.
10 \brief part of QtCommercial chart API.
11
11
12 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
12 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
13 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
13 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
14 by QStringList.
14 by QStringList.
15
15
16 \mainclass
16 \mainclass
17
17
18 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
18 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
19 */
19 */
20
20
21 /*!
21 /*!
22 \fn virtual QSeriesType QBarSeries::type() const
22 \fn virtual QSeriesType QBarSeries::type() const
23 \brief Returns type of series.
23 \brief Returns type of series.
24 \sa QSeries, QSeriesType
24 \sa QSeries, QSeriesType
25 */
25 */
26
26
27 /*!
27 /*!
28 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
28 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
29 \brief \internal \a pos \a tip
29 \brief \internal \a pos \a tip
30 */
30 */
31
31
32 /*!
32 /*!
33 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
33 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
34 QBarSeries is QObject which is a child of a \a parent.
34 QBarSeries is QObject which is a child of a \a parent.
35 */
35 */
36 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent)
36 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent)
37 : QSeries(parent)
37 : QSeries(parent)
38 ,mModel(new BarChartModel(categories, this))
38 ,mModel(new BarChartModel(categories, this))
39 {
39 {
40 m_model = NULL;
40 m_model = NULL;
41 m_mapCategories = -1;
41 m_mapCategories = -1;
42 m_mapBarBottom = -1;
42 m_mapBarBottom = -1;
43 m_mapBarTop = -1;
43 m_mapBarTop = -1;
44 m_mapFirst = 0;
45 m_mapCount = 0;
44 m_mapOrientation = Qt::Vertical;
46 m_mapOrientation = Qt::Vertical;
45 }
47 }
46
48
47 /*!
49 /*!
48 Adds a set of bars to series. Takes ownership of \a set.
50 Adds a set of bars to series. Takes ownership of \a set.
49 Connects the clicked(QString) and rightClicked(QString) signals
51 Connects the clicked(QString) and rightClicked(QString) signals
50 of \a set to this series
52 of \a set to this series
51 */
53 */
52 void QBarSeries::addBarSet(QBarSet *set)
54 void QBarSeries::addBarSet(QBarSet *set)
53 {
55 {
54 mModel->addBarSet(set);
56 mModel->addBarSet(set);
55 connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
57 connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
56 connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
58 connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
57 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
59 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
58 emit updatedBars();
60 emit updatedBars();
59 }
61 }
60
62
61 /*!
63 /*!
62 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
64 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
63 Disconnects the clicked(QString) and rightClicked(QString) signals
65 Disconnects the clicked(QString) and rightClicked(QString) signals
64 of \a set from this series
66 of \a set from this series
65 */
67 */
66 void QBarSeries::removeBarSet(QBarSet *set)
68 void QBarSeries::removeBarSet(QBarSet *set)
67 {
69 {
68 disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
70 disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
69 disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
71 disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
70 mModel->removeBarSet(set);
72 mModel->removeBarSet(set);
71 emit updatedBars();
73 emit updatedBars();
72 }
74 }
73
75
74 void QBarSeries::insertBarSet(int i, QBarSet *set)
76 void QBarSeries::insertBarSet(int i, QBarSet *set)
75 {
77 {
76 mModel->insertBarSet(i, set);
78 mModel->insertBarSet(i, set);
77 // emit barsetChanged();
79 // emit barsetChanged();
78 }
80 }
79
81
80 void QBarSeries::insertCategory(int i, QString category)
82 void QBarSeries::insertCategory(int i, QString category)
81 {
83 {
82 mModel->insertCategory(i, category);
84 mModel->insertCategory(i, category);
83 }
85 }
84
86
85 void QBarSeries::removeCategory(int i)
87 void QBarSeries::removeCategory(int i)
86 {
88 {
87 mModel->removeCategory(i);
89 mModel->removeCategory(i);
88 }
90 }
89
91
90 /*!
92 /*!
91 Returns number of sets in series.
93 Returns number of sets in series.
92 */
94 */
93 int QBarSeries::barsetCount()
95 int QBarSeries::barsetCount()
94 {
96 {
95 // if(m_model)
97 // if(m_model)
96 // return m_mapBarTop - m_mapBarBottom;
98 // return m_mapBarTop - m_mapBarBottom;
97 // else
99 // else
98 return mModel->barsetCount();
100 return mModel->barsetCount();
99 }
101 }
100
102
101 /*!
103 /*!
102 Returns number of categories in series
104 Returns number of categories in series
103 */
105 */
104 int QBarSeries::categoryCount()
106 int QBarSeries::categoryCount()
105 {
107 {
106 return mModel->categoryCount();
108 return mModel->categoryCount();
107 }
109 }
108
110
109 /*!
111 /*!
110 Returns a list of sets in series. Keeps ownership of sets.
112 Returns a list of sets in series. Keeps ownership of sets.
111 */
113 */
112 QList<QBarSet*> QBarSeries::barSets()
114 QList<QBarSet*> QBarSeries::barSets()
113 {
115 {
114 return mModel->barSets();
116 return mModel->barSets();
115 }
117 }
116
118
117 /*!
119 /*!
118 \internal \a index
120 \internal \a index
119 */
121 */
120 QBarSet* QBarSeries::barsetAt(int index)
122 QBarSet* QBarSeries::barsetAt(int index)
121 {
123 {
122 return mModel->setAt(index);
124 return mModel->setAt(index);
123 }
125 }
124
126
125 /*!
127 /*!
126 \internal \a category
128 \internal \a category
127 */
129 */
128 QString QBarSeries::categoryName(int category)
130 QString QBarSeries::categoryName(int category)
129 {
131 {
130 return mModel->categoryName(category);
132 return mModel->categoryName(category);
131 }
133 }
132
134
133 /*!
135 /*!
134 Enables or disables tooltip depending on parameter \a enabled.
136 Enables or disables tooltip depending on parameter \a enabled.
135 Tooltip shows the name of set, when mouse is hovering on top of bar.
137 Tooltip shows the name of set, when mouse is hovering on top of bar.
136 Calling without parameter \a enabled, enables the tooltip
138 Calling without parameter \a enabled, enables the tooltip
137 */
139 */
138 void QBarSeries::setToolTipEnabled(bool enabled)
140 void QBarSeries::setToolTipEnabled(bool enabled)
139 {
141 {
140 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
142 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
141 if (enabled) {
143 if (enabled) {
142 for (int i=0; i<mModel->barsetCount(); i++) {
144 for (int i=0; i<mModel->barsetCount(); i++) {
143 QBarSet *set = mModel->setAt(i);
145 QBarSet *set = mModel->setAt(i);
144 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
146 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
145 }
147 }
146 } else {
148 } else {
147 for (int i=0; i<mModel->barsetCount(); i++) {
149 for (int i=0; i<mModel->barsetCount(); i++) {
148 QBarSet *set = mModel->setAt(i);
150 QBarSet *set = mModel->setAt(i);
149 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
151 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
150 }
152 }
151 }
153 }
152 }
154 }
153
155
154
156
155 /*!
157 /*!
156 \internal \a category
158 \internal \a category
157 */
159 */
158 void QBarSeries::barsetClicked(QString category)
160 void QBarSeries::barsetClicked(QString category)
159 {
161 {
160 emit clicked(qobject_cast<QBarSet*>(sender()), category);
162 emit clicked(qobject_cast<QBarSet*>(sender()), category);
161 }
163 }
162
164
163 /*!
165 /*!
164 \internal \a category
166 \internal \a category
165 */
167 */
166 void QBarSeries::barsetRightClicked(QString category)
168 void QBarSeries::barsetRightClicked(QString category)
167 {
169 {
168 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
170 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
169 }
171 }
170
172
171
173
172 /*!
174 /*!
173 \internal
175 \internal
174 */
176 */
175 qreal QBarSeries::min()
177 qreal QBarSeries::min()
176 {
178 {
177 return mModel->min();
179 return mModel->min();
178 }
180 }
179
181
180 /*!
182 /*!
181 \internal
183 \internal
182 */
184 */
183 qreal QBarSeries::max()
185 qreal QBarSeries::max()
184 {
186 {
185 return mModel->max();
187 return mModel->max();
186 }
188 }
187
189
188 /*!
190 /*!
189 \internal \a set \a category
191 \internal \a set \a category
190 */
192 */
191 qreal QBarSeries::valueAt(int set, int category)
193 qreal QBarSeries::valueAt(int set, int category)
192 {
194 {
193 return mModel->valueAt(set,category);
195 return mModel->valueAt(set,category);
194 }
196 }
195
197
196 /*!
198 /*!
197 \internal \a set \a category
199 \internal \a set \a category
198 */
200 */
199 qreal QBarSeries::percentageAt(int set, int category)
201 qreal QBarSeries::percentageAt(int set, int category)
200 {
202 {
201 return mModel->percentageAt(set,category);
203 return mModel->percentageAt(set,category);
202 }
204 }
203
205
204 /*!
206 /*!
205 \internal \a category
207 \internal \a category
206 */
208 */
207 qreal QBarSeries::categorySum(int category)
209 qreal QBarSeries::categorySum(int category)
208 {
210 {
209 return mModel->categorySum(category);
211 return mModel->categorySum(category);
210 }
212 }
211
213
212 /*!
214 /*!
213 \internal
215 \internal
214 */
216 */
215 qreal QBarSeries::maxCategorySum()
217 qreal QBarSeries::maxCategorySum()
216 {
218 {
217 return mModel->maxCategorySum();
219 return mModel->maxCategorySum();
218 }
220 }
219
221
220 /*!
222 /*!
221 \internal
223 \internal
222 */
224 */
223 BarChartModel& QBarSeries::model()
225 BarChartModel& QBarSeries::model()
224 {
226 {
225 return *mModel;
227 return *mModel;
226 }
228 }
227
229
228 bool QBarSeries::setModel(QAbstractItemModel* model)
230 bool QBarSeries::setModel(QAbstractItemModel* model)
229 {
231 {
230 // disconnect signals from old model
232 // disconnect signals from old model
231 if(m_model)
233 if(m_model)
232 {
234 {
233 disconnect(m_model, 0, this, 0);
235 disconnect(m_model, 0, this, 0);
234 m_mapCategories = -1;
236 m_mapCategories = -1;
235 m_mapBarBottom = -1;
237 m_mapBarBottom = -1;
236 m_mapBarTop = -1;
238 m_mapBarTop = -1;
239 m_mapFirst = 0;
240 m_mapCount = 0;
237 m_mapOrientation = Qt::Vertical;
241 m_mapOrientation = Qt::Vertical;
238 }
242 }
239
243
240 // set new model
244 // set new model
241 if(model)
245 if(model)
242 {
246 {
243 m_model = model;
247 m_model = model;
244 return true;
248 return true;
245 }
249 }
246 else
250 else
247 {
251 {
248 m_model = NULL;
252 m_model = NULL;
249 return false;
253 return false;
250 }
254 }
251 }
255 }
252
256
253 // TODO
257 // TODO
254 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
258 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
255 {
259 {
256 if (m_model == NULL)
260 if (m_model == NULL)
257 return;
261 return;
258 m_mapCategories = categories;
262 m_mapCategories = categories;
259 m_mapBarBottom = bottomBoundry;
263 m_mapBarBottom = bottomBoundry;
260 m_mapBarTop = topBoundry;
264 m_mapBarTop = topBoundry;
265 m_mapFirst = 1;
261 m_mapOrientation = orientation;
266 m_mapOrientation = orientation;
262
267
263 // connect the signals
268 // connect the signals
264 if (m_mapOrientation == Qt::Vertical)
269 if (m_mapOrientation == Qt::Vertical)
265 {
270 {
271 m_mapCount = m_model->rowCount();
266 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
272 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
267 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
273 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
268 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
274 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
269 }
275 }
270 else
276 else
271 {
277 {
278 m_mapCount = m_model->columnCount();
272 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
279 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
273 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
280 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
274 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
281 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
275 }
282 }
276
283
277
284
278 // create the initial bars
285 // create the initial bars
279 delete mModel;
286 delete mModel;
280 if (m_mapOrientation == Qt::Vertical)
287 if (m_mapOrientation == Qt::Vertical)
281 {
288 {
282 QStringList categories;
289 QStringList categories;
283 for (int k = 0; k < m_model->rowCount(); k++)
290 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
284 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
291 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
285 mModel = new BarChartModel(categories, this);
292 mModel = new BarChartModel(categories, this);
286
293
287 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++)
294 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++)
288 {
295 {
289 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
296 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
290 for(int m = 0; m < m_model->rowCount(); m++)
297 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
291 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
298 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
292 addBarSet(barSet);
299 addBarSet(barSet);
293 }
300 }
294 }
301 }
295 else
302 else
296 {
303 {
297 QStringList categories;
304 QStringList categories;
298 for (int k = 0; k < m_model->columnCount(); k++)
305 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
299 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
306 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
300 mModel = new BarChartModel(categories, this);
307 mModel = new BarChartModel(categories, this);
301
308
302 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++)
309 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++)
303 {
310 {
304 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
311 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
305 for(int m = 0; m < m_model->columnCount(); m++)
312 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
306 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
313 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
307 addBarSet(barSet);
314 addBarSet(barSet);
308 }
315 }
309 }
316 }
310 }
317 }
311
318
319 void QBarSeries::setModelMappingShift(int first, int count)
320 {
321 m_mapFirst = first;
322 m_mapCount = count;
323 }
324
312 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
325 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
313 {
326 {
314 Q_UNUSED(bottomRight)
327 Q_UNUSED(bottomRight)
315
328
316 if (m_mapOrientation == Qt::Vertical)
329 if (m_mapOrientation == Qt::Vertical)
317 {
330 {
318 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop)
331 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
319 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
332 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
320 // else if (topLeft.column() == m_mapCategories)
333 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
321 // slices().at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
322 }
334 }
323 else
335 else
324 {
336 {
325 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop)
337 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
326 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
338 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
327 // else if (topLeft.row() == m_mapCategories)
339 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
328 // slices().at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
329 }
340 }
330 }
341 }
331
342
332 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
343 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
333 {
344 {
334 if (m_mapOrientation == Qt::Vertical)
345 if (m_mapOrientation == Qt::Vertical)
335 {
346 {
336 insertCategory(start, QString("Row: %1").arg(start + 1));
347 insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
337 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
348 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
338 {
349 {
339 barsetAt(i)->insertValue(start, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
350 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
340 }
351 }
341 }
352 }
342 else
353 else
343 {
354 {
344 insertCategory(start, QString("Column: %1").arg(start + 1));
355 insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
345 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
356 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
346 {
357 {
347 barsetAt(i)->insertValue(start, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
358 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
348 }
359 }
349 }
360 }
350 emit restructuredBar(1);
361 emit restructuredBar(1);
351 }
362 }
352
363
353 void QBarSeries::modelDataRemoved(QModelIndex /*parent*/, int start, int /*end*/)
364 void QBarSeries::modelDataRemoved(QModelIndex /*parent*/, int start, int /*end*/)
354 {
365 {
355 removeCategory(start);
366 removeCategory(start - m_mapFirst);
356 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
367 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
357 {
368 {
358 barsetAt(i)->removeValue(start);
369 barsetAt(i)->removeValue(start - m_mapFirst);
359 }
370 }
360 emit restructuredBar(1);
371 emit restructuredBar(1);
361 }
372 }
362
373
363 void QBarSeries::barsetChanged()
374 void QBarSeries::barsetChanged()
364 {
375 {
365 emit updatedBars();
376 emit updatedBars();
366 }
377 }
367
378
368 QBarCategories QBarSeries::categories() const
379 QBarCategories QBarSeries::categories() const
369 {
380 {
370 QBarCategories categories;
381 QBarCategories categories;
371 int count = mModel->categoryCount();
382 int count = mModel->categoryCount();
372 for (int i=1; i<=count; i++) {
383 for (int i=1; i<=count; i++) {
373 categories.insert(i, mModel->categoryName(i-1));
384 categories.insert(i, mModel->categoryName(i-1));
374 }
385 }
375 return categories;
386 return categories;
376 }
387 }
377
388
378 #include "moc_qbarseries.cpp"
389 #include "moc_qbarseries.cpp"
379
390
380 QTCOMMERCIALCHART_END_NAMESPACE
391 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,95 +1,98
1 #ifndef BARSERIES_H
1 #ifndef BARSERIES_H
2 #define BARSERIES_H
2 #define BARSERIES_H
3
3
4 #include <qseries.h>
4 #include <qseries.h>
5 #include <QStringList>
5 #include <QStringList>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 typedef QStringList QBarCategories;
9 typedef QStringList QBarCategories;
10
10
11 class QBarSet;
11 class QBarSet;
12 class BarChartModel;
12 class BarChartModel;
13 class BarCategory;
13 class BarCategory;
14
14
15 // Container for series
15 // Container for series
16 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
16 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
17 {
17 {
18 Q_OBJECT
18 Q_OBJECT
19 public:
19 public:
20 QBarSeries(QStringList categories, QObject* parent=0);
20 QBarSeries(QStringList categories, QObject* parent=0);
21
21
22 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
22 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
23
23
24 void addBarSet(QBarSet *set); // Takes ownership of set
24 void addBarSet(QBarSet *set); // Takes ownership of set
25 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
25 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
26 void insertBarSet(int i, QBarSet *set);
26 void insertBarSet(int i, QBarSet *set);
27 void insertCategory(int i, QString category);
27 void insertCategory(int i, QString category);
28 void removeCategory(int i);
28 void removeCategory(int i);
29 int barsetCount();
29 int barsetCount();
30 int categoryCount();
30 int categoryCount();
31 QList<QBarSet*> barSets();
31 QList<QBarSet*> barSets();
32 QBarCategories categories() const;
32 QBarCategories categories() const;
33
33
34
34
35 bool setModel(QAbstractItemModel* model);
35 bool setModel(QAbstractItemModel* model);
36 QAbstractItemModel* modelExt() {return m_model;}
36 QAbstractItemModel* modelExt() {return m_model;}
37 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
37 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
38 void setModelMappingShift(int first, int count);
38
39
39 public:
40 public:
40 // TODO: Functions below this are not part of api and will be moved
41 // TODO: Functions below this are not part of api and will be moved
41 // to private implementation, when we start using it
42 // to private implementation, when we start using it
42 // TODO: TO PIMPL --->
43 // TODO: TO PIMPL --->
43 QBarSet* barsetAt(int index);
44 QBarSet* barsetAt(int index);
44 QString categoryName(int category);
45 QString categoryName(int category);
45 qreal min();
46 qreal min();
46 qreal max();
47 qreal max();
47 qreal valueAt(int set, int category);
48 qreal valueAt(int set, int category);
48 qreal percentageAt(int set, int category);
49 qreal percentageAt(int set, int category);
49 qreal categorySum(int category);
50 qreal categorySum(int category);
50 qreal maxCategorySum();
51 qreal maxCategorySum();
51 BarChartModel& model();
52 BarChartModel& model();
52 // <--- TO PIMPL
53 // <--- TO PIMPL
53
54
54 signals:
55 signals:
55 //void changed(int index);
56 //void changed(int index);
56 void clicked(QBarSet* barset, QString category); // Up to user of api, what to do with these signals
57 void clicked(QBarSet* barset, QString category); // Up to user of api, what to do with these signals
57 void rightClicked(QBarSet* barset, QString category);
58 void rightClicked(QBarSet* barset, QString category);
58
59
59 //
60 //
60 void updatedBars();
61 void updatedBars();
61 void restructuredBar(int);
62 void restructuredBar(int);
62
63
63 // TODO: internal signals, these to private implementation.
64 // TODO: internal signals, these to private implementation.
64 // TODO: TO PIMPL --->
65 // TODO: TO PIMPL --->
65 void showToolTip(QPoint pos, QString tip);
66 void showToolTip(QPoint pos, QString tip);
66 // <--- TO PIMPL
67 // <--- TO PIMPL
67
68
68 public Q_SLOTS:
69 public Q_SLOTS:
69 void setToolTipEnabled(bool enabled=true); // enables tooltips
70 void setToolTipEnabled(bool enabled=true); // enables tooltips
70
71
71 // TODO: TO PIMPL --->
72 // TODO: TO PIMPL --->
72 void barsetClicked(QString category);
73 void barsetClicked(QString category);
73 void barsetRightClicked(QString category);
74 void barsetRightClicked(QString category);
74 // <--- TO PIMPL
75 // <--- TO PIMPL
75
76
76 private Q_SLOTS:
77 private Q_SLOTS:
77 // slots for updating bars when data in model changes
78 // slots for updating bars when data in model changes
78 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
79 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
79 void modelDataAdded(QModelIndex parent, int start, int end);
80 void modelDataAdded(QModelIndex parent, int start, int end);
80 void modelDataRemoved(QModelIndex parent, int start, int end);
81 void modelDataRemoved(QModelIndex parent, int start, int end);
81 void barsetChanged();
82 void barsetChanged();
82
83
83 protected:
84 protected:
84 BarChartModel* mModel;
85 BarChartModel* mModel;
85
86
86 // QAbstractItemModel* m_model;
87 // QAbstractItemModel* m_model;
87 int m_mapCategories;
88 int m_mapCategories;
88 int m_mapBarBottom;
89 int m_mapBarBottom;
89 int m_mapBarTop;
90 int m_mapBarTop;
91 int m_mapFirst;
92 int m_mapCount;
90 Qt::Orientation m_mapOrientation;
93 Qt::Orientation m_mapOrientation;
91 };
94 };
92
95
93 QTCOMMERCIALCHART_END_NAMESPACE
96 QTCOMMERCIALCHART_END_NAMESPACE
94
97
95 #endif // BARSERIES_H
98 #endif // BARSERIES_H
@@ -1,155 +1,161
1 #include "qsplineseries.h"
1 #include "qsplineseries.h"
2
2
3 /*!
3 /*!
4 \class QSplineSeries
4 \class QSplineSeries
5 \brief Series type used to store data needed to draw a spline.
5 \brief Series type used to store data needed to draw a spline.
6
6
7 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
7 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
8 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
8 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
9 */
9 */
10
10
11 /*!
11 /*!
12 \fn QSeriesType QSplineSeries::type() const
12 \fn QSeriesType QSplineSeries::type() const
13 Returns the type of the series
13 Returns the type of the series
14 */
14 */
15
15
16 /*!
16 /*!
17 \fn QSeriesType QSplineSeries::controlPoint(int index) const
17 \fn QSeriesType QSplineSeries::controlPoint(int index) const
18 Returns the control point specified by \a index
18 Returns the control point specified by \a index
19 */
19 */
20
20
21 QTCOMMERCIALCHART_BEGIN_NAMESPACE
21 QTCOMMERCIALCHART_BEGIN_NAMESPACE
22
22
23 /*!
23 /*!
24 Constructs empty series object which is a child of \a parent.
24 Constructs empty series object which is a child of \a parent.
25 When series object is added to QChartView or QChart instance then the ownerships is transfered.
25 When series object is added to QChartView or QChart instance then the ownerships is transfered.
26 */
26 */
27
27
28 QSplineSeries::QSplineSeries(QObject *parent) :
28 QSplineSeries::QSplineSeries(QObject *parent) :
29 QLineSeries(parent)
29 QLineSeries(parent)
30 {
30 {
31 connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
31 connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
32 connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
32 connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
33 connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
33 connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
34 }
34 }
35
35
36 /*!
36 /*!
37 \internal
37 \internal
38 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
38 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
39 */
39 */
40 void QSplineSeries::calculateControlPoints()
40 void QSplineSeries::calculateControlPoints()
41 {
41 {
42
42
43 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
43 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
44 // CPOL License
44 // CPOL License
45
45
46 int n = count() - 1;
46 int n = count() - 1;
47 if (n == 1)
47 if (n == 1)
48 { // Special case: Bezier curve should be a straight line.
48 { // Special case: Bezier curve should be a straight line.
49 // firstControlPoints = new Point[1];
49 // firstControlPoints = new Point[1];
50 // 3P1 = 2P0 + P3
50 // 3P1 = 2P0 + P3
51 m_controlPoints.append(QPointF((2 * x(0) + x(1)) / 3, (2 * y(0) + y(1)) / 3));
51 m_controlPoints.append(QPointF((2 * x(0) + x(1)) / 3, (2 * y(0) + y(1)) / 3));
52
52
53 // P2 = 2P1 P0
53 // P2 = 2P1 P0
54 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - x(0), 2 * m_controlPoints[0].y() - y(0)));
54 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - x(0), 2 * m_controlPoints[0].y() - y(0)));
55 return;
55 return;
56 }
56 }
57
57
58 // Calculate first Bezier control points
58 // Calculate first Bezier control points
59 // Right hand side vector
59 // Right hand side vector
60 // Set of equations for P0 to Pn points.
60 // Set of equations for P0 to Pn points.
61 //
61 //
62 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
62 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
63 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
63 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
64 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
64 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
65 // | . . . . . . . . . . . . | | ... | | ... |
65 // | . . . . . . . . . . . . | | ... | | ... |
66 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
66 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
67 // | . . . . . . . . . . . . | | ... | | ... |
67 // | . . . . . . . . . . . . | | ... | | ... |
68 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
68 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
69 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
69 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
70 //
70 //
71 QList<qreal> rhs;
71 QList<qreal> rhs;
72 rhs.append(x(0) + 2 * x(1));
72 rhs.append(x(0) + 2 * x(1));
73
73
74 // Set right hand side X values
74 // Set right hand side X values
75 for (int i = 1; i < n - 1; ++i)
75 for (int i = 1; i < n - 1; ++i)
76 rhs.append(4 * x(i) + 2 * x(i + 1));
76 rhs.append(4 * x(i) + 2 * x(i + 1));
77
77
78 rhs.append((8 * x(n - 1) + x(n)) / 2.0);
78 rhs.append((8 * x(n - 1) + x(n)) / 2.0);
79 // Get first control points X-values
79 // Get first control points X-values
80 QList<qreal> xControl = getFirstControlPoints(rhs);
80 QList<qreal> xControl = getFirstControlPoints(rhs);
81 rhs[0] = y(0) + 2 * y(1);
81 rhs[0] = y(0) + 2 * y(1);
82
82
83 // Set right hand side Y values
83 // Set right hand side Y values
84 for (int i = 1; i < n - 1; ++i)
84 for (int i = 1; i < n - 1; ++i)
85 rhs[i] = 4 * y(i) + 2 * y(i + 1);
85 rhs[i] = 4 * y(i) + 2 * y(i + 1);
86
86
87 rhs[n - 1] = (8 * y(n - 1) + y(n)) / 2.0;
87 rhs[n - 1] = (8 * y(n - 1) + y(n)) / 2.0;
88 // Get first control points Y-values
88 // Get first control points Y-values
89 QList<qreal> yControl = getFirstControlPoints(rhs);
89 QList<qreal> yControl = getFirstControlPoints(rhs);
90
90
91 // Fill output arrays.
91 // Fill output arrays.
92 for (int i = 0; i < n; ++i)
92 for (int i = 0; i < n; ++i)
93 {
93 {
94 // First control point
94 // First control point
95 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
95 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
96 // Second control point
96 // Second control point
97 if (i < n - 1)
97 if (i < n - 1)
98 m_controlPoints.append(QPointF(2 * x(i + 1) - xControl[i + 1], 2 * y(i + 1) - yControl[i + 1]));
98 m_controlPoints.append(QPointF(2 * x(i + 1) - xControl[i + 1], 2 * y(i + 1) - yControl[i + 1]));
99 else
99 else
100 m_controlPoints.append(QPointF((x(n) + xControl[n - 1]) / 2, (y(n) + yControl[n - 1]) / 2));
100 m_controlPoints.append(QPointF((x(n) + xControl[n - 1]) / 2, (y(n) + yControl[n - 1]) / 2));
101 }
101 }
102 }
102 }
103
103
104 /*!
104 /*!
105 \internal
105 \internal
106 */
106 */
107 QList<qreal> QSplineSeries::getFirstControlPoints(QList<qreal> rhs)
107 QList<qreal> QSplineSeries::getFirstControlPoints(QList<qreal> rhs)
108 {
108 {
109 QList<qreal> x; // Solution vector.
109 QList<qreal> x; // Solution vector.
110 QList<qreal> tmp; // Temp workspace.
110 QList<qreal> tmp; // Temp workspace.
111
111
112 qreal b = 2.0;
112 qreal b = 2.0;
113 x.append(rhs[0] / b);
113 x.append(rhs[0] / b);
114 tmp.append(0);
114 tmp.append(0);
115 for (int i = 1; i < rhs.size(); i++) // Decomposition and forward substitution.
115 for (int i = 1; i < rhs.size(); i++) // Decomposition and forward substitution.
116 {
116 {
117 tmp.append(1 / b);
117 tmp.append(1 / b);
118 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
118 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
119 x.append((rhs[i] - x[i - 1]) / b);
119 x.append((rhs[i] - x[i - 1]) / b);
120 }
120 }
121 for (int i = 1; i < rhs.size(); i++)
121 for (int i = 1; i < rhs.size(); i++)
122 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
122 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
123
123
124 return x;
124 return x;
125 }
125 }
126
126
127 /*!
127 /*!
128 \internal
128 \internal
129 Updates the control points, besed on currently avaiable knots.
129 Updates the control points, besed on currently avaiable knots.
130 */
130 */
131 void QSplineSeries::updateControlPoints()
131 void QSplineSeries::updateControlPoints()
132 {
132 {
133 if(count() > 1)
133 if(count() > 1)
134 {
134 {
135 m_controlPoints.clear();
135 m_controlPoints.clear();
136 calculateControlPoints();
136 calculateControlPoints();
137 }
137 }
138 }
138 }
139
139
140 bool QSplineSeries::setModel(QAbstractItemModel* model)
140 bool QSplineSeries::setModel(QAbstractItemModel* model)
141 {
141 {
142 QXYSeries::setModel(model);
142 QXYSeries::setModel(model);
143 // calculateControlPoints();
143 // calculateControlPoints();
144 return true;
144 return true;
145 }
145 }
146
146
147 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
147 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
148 {
148 {
149 QLineSeries::setModelMapping(modelX, modelY, orientation);
149 QLineSeries::setModelMapping(modelX, modelY, orientation);
150 // calculateControlPoints();
151 }
152
153 void QSplineSeries::setModelMappingShift(int first, int count)
154 {
155 QLineSeries::setModelMappingShift(first, count);
150 calculateControlPoints();
156 calculateControlPoints();
151 }
157 }
152
158
153 #include "moc_qsplineseries.cpp"
159 #include "moc_qsplineseries.cpp"
154
160
155 QTCOMMERCIALCHART_END_NAMESPACE
161 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,46 +1,47
1 #ifndef QSPLINESERIES_H
1 #ifndef QSPLINESERIES_H
2 #define QSPLINESERIES_H
2 #define QSPLINESERIES_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QtGlobal>
5 #include <QtGlobal>
6 #include <qlineseries.h>
6 #include <qlineseries.h>
7 #include <QList>
7 #include <QList>
8 #include <QPointF>
8 #include <QPointF>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class QTCOMMERCIALCHART_EXPORT QSplineSeries : public QLineSeries
12 class QTCOMMERCIALCHART_EXPORT QSplineSeries : public QLineSeries
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 public:
15 public:
16
16
17 QSplineSeries(QObject *parent = 0);
17 QSplineSeries(QObject *parent = 0);
18 QSeriesType type() const {return QSeries::SeriesTypeSpline;}
18 QSeriesType type() const {return QSeries::SeriesTypeSpline;}
19
19
20 // int count() const { return m_x.size(); }
20 // int count() const { return m_x.size(); }
21 QPointF controlPoint(int index) const {return m_controlPoints[index];}
21 QPointF controlPoint(int index) const {return m_controlPoints[index];}
22 bool setModel(QAbstractItemModel* model);
22 bool setModel(QAbstractItemModel* model);
23
23
24 void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
24 void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
25 void setModelMappingShift(int first, int count);
25
26
26 // TODO: allow the user to set custom control points
27 // TODO: allow the user to set custom control points
27 // void setCustomControlPoints(QList<QPointsF> controlPoints);
28 // void setCustomControlPoints(QList<QPointsF> controlPoints);
28 // bool calculateControlPointsAutomatically();
29 // bool calculateControlPointsAutomatically();
29 // void setCalculateControlPointsAutomatically();
30 // void setCalculateControlPointsAutomatically();
30
31
31
32
32 private:
33 private:
33 void calculateControlPoints();
34 void calculateControlPoints();
34 QList<qreal> getFirstControlPoints(QList<qreal> rhs);
35 QList<qreal> getFirstControlPoints(QList<qreal> rhs);
35
36
36 private slots:
37 private slots:
37 void updateControlPoints();
38 void updateControlPoints();
38
39
39 private:
40 private:
40 QList<QPointF> m_controlPoints;
41 QList<QPointF> m_controlPoints;
41
42
42 };
43 };
43
44
44 QTCOMMERCIALCHART_END_NAMESPACE
45 QTCOMMERCIALCHART_END_NAMESPACE
45
46
46 #endif // QSPLINESERIES_H
47 #endif // QSPLINESERIES_H
@@ -1,361 +1,517
1 #include "qxyseries.h"
1 #include "qxyseries.h"
2
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4
4
5 /*!
5 /*!
6 \class QXYSeries
6 \class QXYSeries
7 \brief The QXYSeries class is a base class for line, spline and scatter series.
7 \brief The QXYSeries class is a base class for line, spline and scatter series.
8 */
8 */
9
9
10 /*!
10 /*!
11 \fn QPen QXYSeries::pen() const
11 \fn QPen QXYSeries::pen() const
12 \brief Returns pen used to draw points for series.
12 \brief Returns pen used to draw points for series.
13 \sa setPen()
13 \sa setPen()
14 */
14 */
15
15
16 /*!
16 /*!
17 \fn QBrush QXYSeries::brush() const
17 \fn QBrush QXYSeries::brush() const
18 \brief Returns brush used to draw points for series.
18 \brief Returns brush used to draw points for series.
19 \sa setBrush()
19 \sa setBrush()
20 */
20 */
21
21
22 /*!
22 /*!
23 \fn void QXYSeries::clicked(const QPointF& point)
23 \fn void QXYSeries::clicked(const QPointF& point)
24 \brief Signal is emitted when user clicks the \a point on chart.
24 \brief Signal is emitted when user clicks the \a point on chart.
25 */
25 */
26
26
27 /*!
27 /*!
28 \fn void QXYSeries::pointReplaced(int index)
28 \fn void QXYSeries::pointReplaced(int index)
29 \brief \internal \a index
29 \brief \internal \a index
30 */
30 */
31
31
32 /*!
32 /*!
33 \fn void QXYSeries::pointAdded(int index)
33 \fn void QXYSeries::pointAdded(int index)
34 \brief \internal \a index
34 \brief \internal \a index
35 */
35 */
36
36
37 /*!
37 /*!
38 \fn void QXYSeries::pointRemoved(int index)
38 \fn void QXYSeries::pointRemoved(int index)
39 \brief \internal \a index
39 \brief \internal \a index
40 */
40 */
41
41
42 /*!
42 /*!
43 \fn void QXYSeries::updated()
43 \fn void QXYSeries::updated()
44 \brief \internal
44 \brief \internal
45 */
45 */
46
46
47 /*!
47 /*!
48 Constructs empty series object which is a child of \a parent.
48 Constructs empty series object which is a child of \a parent.
49 When series object is added to QChartView or QChart instance ownerships is transfered.
49 When series object is added to QChartView or QChart instance ownerships is transfered.
50 */
50 */
51 QXYSeries::QXYSeries(QObject* parent):QSeries(parent)
51 QXYSeries::QXYSeries(QObject* parent):QSeries(parent)
52 {
52 {
53 m_mapX = -1;
53 m_mapX = -1;
54 m_mapY = -1;
54 m_mapY = -1;
55 m_mapFirst = 0;
56 m_mapCount = 0;
57 m_mapLimited = false;
55 m_mapOrientation = Qt::Vertical;
58 m_mapOrientation = Qt::Vertical;
56 // m_mapYOrientation = Qt::Vertical;
59 // m_mapYOrientation = Qt::Vertical;
57 }
60 }
58 /*!
61 /*!
59 Destroys the object. Series added to QChartView or QChart instances are owned by those,
62 Destroys the object. Series added to QChartView or QChart instances are owned by those,
60 and are deleted when mentioned object are destroyed.
63 and are deleted when mentioned object are destroyed.
61 */
64 */
62 QXYSeries::~QXYSeries()
65 QXYSeries::~QXYSeries()
63 {
66 {
64 }
67 }
65
68
66 /*!
69 /*!
67 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
70 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
68 */
71 */
69 void QXYSeries::add(qreal x,qreal y)
72 void QXYSeries::add(qreal x,qreal y)
70 {
73 {
71 Q_ASSERT(m_x.size() == m_y.size());
74 Q_ASSERT(m_x.size() == m_y.size());
72 m_x<<x;
75 m_x<<x;
73 m_y<<y;
76 m_y<<y;
74 emit pointAdded(m_x.size()-1);
77 emit pointAdded(m_x.size()-1);
75 }
78 }
76
79
77 /*!
80 /*!
78 This is an overloaded function.
81 This is an overloaded function.
79 Adds data \a point to the series. Points are connected with lines on the chart.
82 Adds data \a point to the series. Points are connected with lines on the chart.
80 */
83 */
81 void QXYSeries::add(const QPointF& point)
84 void QXYSeries::add(const QPointF& point)
82 {
85 {
83 add(point.x(),point.y());
86 add(point.x(),point.y());
84 }
87 }
85
88
86 /*!
89 /*!
87 This is an overloaded function.
90 This is an overloaded function.
88 Adds list of data \a points to the series. Points are connected with lines on the chart.
91 Adds list of data \a points to the series. Points are connected with lines on the chart.
89 */
92 */
90 void QXYSeries::add(const QList<QPointF> points)
93 void QXYSeries::add(const QList<QPointF> points)
91 {
94 {
92 foreach(const QPointF& point , points) {
95 foreach(const QPointF& point , points) {
93 add(point.x(),point.y());
96 add(point.x(),point.y());
94 }
97 }
95 }
98 }
96
99
97 /*!
100 /*!
98 Modifies \a y value for given \a x a value.
101 Modifies \a y value for given \a x a value.
99 */
102 */
100 void QXYSeries::replace(qreal x,qreal y)
103 void QXYSeries::replace(qreal x,qreal y)
101 {
104 {
102 int index = m_x.indexOf(x);
105 int index = m_x.indexOf(x);
103 m_x[index]=x;
106 m_x[index]=x;
104 m_y[index]=y;
107 m_y[index]=y;
105 emit pointReplaced(index);
108 emit pointReplaced(index);
106 }
109 }
107
110
108 /*!
111 /*!
109 This is an overloaded function.
112 This is an overloaded function.
110 Replaces current y value of for given \a point x value with \a point y value.
113 Replaces current y value of for given \a point x value with \a point y value.
111 */
114 */
112 void QXYSeries::replace(const QPointF& point)
115 void QXYSeries::replace(const QPointF& point)
113 {
116 {
114 replace(point.x(),point.y());
117 replace(point.x(),point.y());
115 }
118 }
116
119
117 /*!
120 /*!
118 Removes first \a x value and related y value.
121 Removes first \a x value and related y value.
119 */
122 */
120 void QXYSeries::remove(qreal x)
123 void QXYSeries::remove(qreal x)
121 {
124 {
122 int index = m_x.indexOf(x);
125 int index = m_x.indexOf(x);
123
126
124 if(index==-1) return;
127 if(index==-1) return;
125
128
126 m_x.remove(index);
129 m_x.remove(index);
127 m_y.remove(index);
130 m_y.remove(index);
128
131
129 emit pointRemoved(index);
132 emit pointRemoved(index);
130 }
133 }
131
134
132 /*!
135 /*!
133 Removes current \a x and \a y value.
136 Removes current \a x and \a y value.
134 */
137 */
135 void QXYSeries::remove(qreal x,qreal y)
138 void QXYSeries::remove(qreal x,qreal y)
136 {
139 {
137 int index =-1;
140 int index =-1;
138 do{
141 do{
139 index = m_x.indexOf(x,index+1);
142 index = m_x.indexOf(x,index+1);
140 }while(index !=-1 && m_y.at(index)!=y);
143 }while(index !=-1 && m_y.at(index)!=y);
141
144
142 if(index==-1) return;
145 if(index==-1) return;
143
146
144 m_x.remove(index);
147 m_x.remove(index);
145 m_y.remove(index);
148 m_y.remove(index);
146 emit pointRemoved(index);
149 emit pointRemoved(index);
147 }
150 }
148
151
149 /*!
152 /*!
150 Removes current \a point x value. Note \a point y value is ignored.
153 Removes current \a point x value. Note \a point y value is ignored.
151 */
154 */
152 void QXYSeries::remove(const QPointF& point)
155 void QXYSeries::remove(const QPointF& point)
153 {
156 {
154 remove(point.x(),point.y());
157 remove(point.x(),point.y());
155 }
158 }
156
159
157 /*!
160 /*!
158 Removes all data points from the series.
161 Removes all data points from the series.
159 */
162 */
160 void QXYSeries::removeAll()
163 void QXYSeries::removeAll()
161 {
164 {
162 m_x.clear();
165 m_x.clear();
163 m_y.clear();
166 m_y.clear();
164 }
167 }
165
168
166 /*!
169 /*!
167 \internal \a pos
170 \internal \a pos
168 */
171 */
169 qreal QXYSeries::x(int pos) const
172 qreal QXYSeries::x(int pos) const
170 {
173 {
171 if (m_model)
174 if (m_model)
172 if (m_mapOrientation == Qt::Vertical)
175 if (m_mapOrientation == Qt::Vertical)
173 // consecutive data is read from model's column
176 // consecutive data is read from model's column
174 return m_model->data(m_model->index(pos, m_mapX), Qt::DisplayRole).toDouble();
177 return m_model->data(m_model->index(pos + m_mapFirst, m_mapX), Qt::DisplayRole).toDouble();
175 else
178 else
176 // consecutive data is read from model's row
179 // consecutive data is read from model's row
177 return m_model->data(m_model->index(m_mapX, pos), Qt::DisplayRole).toDouble();
180 return m_model->data(m_model->index(m_mapX, pos + m_mapFirst), Qt::DisplayRole).toDouble();
178 else
181 else
179 // model is not specified, return the data from series' internal data store
182 // model is not specified, return the data from series' internal data store
180 return m_x.at(pos);
183 return m_x.at(pos);
181 }
184 }
182
185
183 /*!
186 /*!
184 \internal \a pos
187 \internal \a pos
185 */
188 */
186 qreal QXYSeries::y(int pos) const
189 qreal QXYSeries::y(int pos) const
187 {
190 {
188 if (m_model)
191 if (m_model)
189 if (m_mapOrientation == Qt::Vertical)
192 if (m_mapOrientation == Qt::Vertical)
190 // consecutive data is read from model's column
193 // consecutive data is read from model's column
191 return m_model->data(m_model->index(pos, m_mapY), Qt::DisplayRole).toDouble();
194 return m_model->data(m_model->index(pos + m_mapFirst, m_mapY), Qt::DisplayRole).toDouble();
192 else
195 else
193 // consecutive data is read from model's row
196 // consecutive data is read from model's row
194 return m_model->data(m_model->index(m_mapY, pos), Qt::DisplayRole).toDouble();
197 return m_model->data(m_model->index(m_mapY, pos + m_mapFirst), Qt::DisplayRole).toDouble();
195 else
198 else
196 // model is not specified, return the data from series' internal data store
199 // model is not specified, return the data from series' internal data store
197 return m_y.at(pos);
200 return m_y.at(pos);
198 }
201 }
199
202
200 /*!
203 /*!
201 Returns number of data points within series.
204 Returns number of data points within series.
202 */
205 */
203 int QXYSeries::count() const
206 int QXYSeries::count() const
204 {
207 {
205 Q_ASSERT(m_x.size() == m_y.size());
208 Q_ASSERT(m_x.size() == m_y.size());
206
209
207 if (m_model) {
210 if (m_model) {
208 if (m_mapOrientation == Qt::Vertical)
211 if (m_mapOrientation == Qt::Vertical)
209 // data is in a column, so return the number of items in single column
212 {
210 return m_model->rowCount();
213 // data is in a column. Return the number of mapped items if the model's column have enough items
214 // or the number of items that can be mapped
215 if (m_mapLimited)
216 return qMin(m_mapCount, qMax(m_model->rowCount() - m_mapFirst, 0));
217 else
218 return qMax(m_model->rowCount() - m_mapFirst, 0);
219 }
220 else
221 {
222 // data is in a row. Return the number of mapped items if the model's row have enough items
223 // or the number of items that can be mapped
224 if (m_mapLimited)
225 return qMin(m_mapCount, qMax(m_model->columnCount() - m_mapFirst, 0));
211 else
226 else
212 // data is in a row, so return the number of items in single row
227 return qMax(m_model->columnCount() - m_mapFirst, 0);
213 return m_model->columnCount();
228 }
214 }
229 }
215
230
216 // model is not specified, return the number of points in the series internal data store
231 // model is not specified, return the number of points in the series internal data store
217 return m_x.size();
232 return m_x.size();
218 }
233 }
219
234
220 /*!
235 /*!
221 Returns the data points of the series.
236 Returns the data points of the series.
222 */
237 */
223 QList<QPointF> QXYSeries::data()
238 QList<QPointF> QXYSeries::data()
224 {
239 {
225 QList<QPointF> data;
240 QList<QPointF> data;
226 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
241 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
227 data.append(QPointF(m_x.at(i), m_y.at(i)));
242 data.append(QPointF(m_x.at(i), m_y.at(i)));
228 return data;
243 return data;
229 }
244 }
230
245
231
246
232 /*!
247 /*!
233 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
248 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
234 pen from chart theme is used.
249 pen from chart theme is used.
235 \sa QChart::setChartTheme()
250 \sa QChart::setChartTheme()
236 */
251 */
237 void QXYSeries::setPen(const QPen& pen)
252 void QXYSeries::setPen(const QPen& pen)
238 {
253 {
239 if(pen!=m_pen){
254 if(pen!=m_pen){
240 m_pen=pen;
255 m_pen=pen;
241 emit updated();
256 emit updated();
242 }
257 }
243 }
258 }
244
259
245 /*!
260 /*!
246 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
261 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
247 from chart theme setting is used.
262 from chart theme setting is used.
248 \sa QChart::setChartTheme()
263 \sa QChart::setChartTheme()
249 */
264 */
250
265
251 void QXYSeries::setBrush(const QBrush& brush)
266 void QXYSeries::setBrush(const QBrush& brush)
252 {
267 {
253 if(brush!=m_brush){
268 if(brush!=m_brush){
254 m_brush=brush;
269 m_brush=brush;
255 emit updated();
270 emit updated();
256 }
271 }
257 }
272 }
258
273
259
274
260 /*!
275 /*!
261 Stream operator for adding a data \a point to the series.
276 Stream operator for adding a data \a point to the series.
262 \sa add()
277 \sa add()
263 */
278 */
264
279
265 QXYSeries& QXYSeries::operator<< (const QPointF &point)
280 QXYSeries& QXYSeries::operator<< (const QPointF &point)
266 {
281 {
267 add(point);
282 add(point);
268 return *this;
283 return *this;
269 }
284 }
270
285
271
286
272 /*!
287 /*!
273 Stream operator for adding a list of \a points to the series.
288 Stream operator for adding a list of \a points to the series.
274 \sa add()
289 \sa add()
275 */
290 */
276
291
277 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
292 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
278 {
293 {
279 add(points);
294 add(points);
280 return *this;
295 return *this;
281 }
296 }
282
297
283
298
284 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
299 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
285 {
300 {
286 Q_UNUSED(bottomRight)
301 Q_UNUSED(bottomRight)
287
302
288 if (m_mapOrientation == Qt::Vertical)
303 if (m_mapOrientation == Qt::Vertical)
289 emit pointReplaced(topLeft.row());
304 {
305 if (topLeft.row() >= m_mapFirst && (!m_mapLimited || topLeft.row() < m_mapFirst + m_mapCount))
306 emit pointReplaced(topLeft.row() - m_mapFirst);
307 }
290 else
308 else
291 emit pointReplaced(topLeft.column());
309 {
310 if (topLeft.column() >= m_mapFirst && (!m_mapLimited || topLeft.column() < m_mapFirst + m_mapCount))
311 emit pointReplaced(topLeft.column() - m_mapFirst);
312 }
313 }
314
315 void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
316 {
317 Q_UNUSED(parent)
318 // Q_UNUSED(end)
319
320 if (m_mapLimited)
321 {
322 if (start >= m_mapFirst + m_mapCount)
323 // the added data is below mapped area
324 // therefore it has no relevance
325 return;
326 else
327 {
328 // the added data is in the mapped area or before it and update is needed
329
330 // check how many mapped items there is currently (before new items are added)
331 // if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
332 // internal storage before new ones can be added
333 if (m_mapCount == count())
334 for (int i = 0; i < qMin(count(), end - start + 1); i++)
335 emit pointRemoved(count() - 1 - i);
336 }
337 }
338 else
339 {
340 // map is not limited (it includes all the items starting from m_mapFirst till the end of model)
341 // nothing to do
342 // emit pointAdded(qMax(start - m_mapFirst, 0));
343 }
292 }
344 }
293
345
294 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
346 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
295 {
347 {
296 Q_UNUSED(parent)
348 Q_UNUSED(parent)
297 Q_UNUSED(end)
349 // Q_UNUSED(end)
298 emit pointAdded(start);
350
351 if (m_mapLimited)
352 {
353 if (start >= m_mapFirst + m_mapCount)
354 // the added data is below mapped area
355 // therefore it has no relevance
356 return;
357 else
358 {
359 // the added data is in the mapped area or before it
360 // update needed
361 if (count() > 0)
362 for (int i = 0; i < qMin(m_mapCount, end - start + 1); i++)
363 emit pointAdded(qMax(start + i - m_mapFirst, 0));
364 }
365 }
366 else
367 {
368 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
369 for (int i = 0; i < end - start + 1; i++)
370 emit pointAdded(qMax(start + i - m_mapFirst, 0));
371 }
372 }
373
374 void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end)
375 {
376 Q_UNUSED(parent)
377 // Q_UNUSED(end)
378
379 if (m_mapLimited)
380 {
381 if (start >= m_mapFirst + m_mapCount)
382 // the removed data is below mapped area
383 // therefore it has no relevance
384 return;
385 else
386 {
387 // the removed data is in the mapped area or before it
388 // update needed
389 int itemsToRemove = qMin(count(), end - start + 1);
390 tempItemsRemoved = itemsToRemove;
391 int z = count();
392 z = z;
393 // if (itemsToRemove > 0)
394 // {
395 for (int i = 0; i < itemsToRemove; i++)
396 emit pointRemoved(qMax(start - m_mapFirst, 0));
397 }
398 }
399 else
400 {
401 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
402 for (int i = 0; i < end - start + 1; i++)
403 emit pointRemoved(qMax(start - m_mapFirst, 0));
404 }
299 }
405 }
300
406
301 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
407 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
302 {
408 {
303 Q_UNUSED(parent)
409 Q_UNUSED(parent)
304 Q_UNUSED(end)
410 Q_UNUSED(end)
305 emit pointRemoved(start);
411
412 // how many items there were before data was removed
413 // int oldCount = count() - 1;
414
415 if (m_mapLimited)
416 {
417 if (start >= m_mapFirst + m_mapCount)
418 // the removed data is below mapped area
419 // therefore it has no relevance
420 return;
421 else
422 {
423 // if there are excess items available (below the map) use them to repopulate mapped area
424 int extraItemsAvailable = 0;
425 if (m_mapOrientation == Qt::Vertical)
426 {
427 extraItemsAvailable = qMax(m_model->rowCount() - m_mapFirst, 0);
428 }
429 else
430 {
431 extraItemsAvailable = qMax(m_model->columnCount() - m_mapFirst, 0);
432 }
433
434 // int extraItemsNeeded = qMin(extraItemsAvailable, tempItemsRemoved);
435 for (int k = 0; k < tempItemsRemoved; k++)
436 if (start - m_mapFirst + k < extraItemsAvailable)
437 {
438 emit pointAdded(count() - m_mapFirst + k);
439 }
440 }
441 }
442 else
443 {
444 // emit pointRemoved(qMax(start - m_mapFirst, 0));
445 }
306 }
446 }
307
447
308 bool QXYSeries::setModel(QAbstractItemModel* model) {
448 bool QXYSeries::setModel(QAbstractItemModel* model) {
309
449
310 // disconnect signals from old model
450 // disconnect signals from old model
311 if(m_model)
451 if(m_model)
312 {
452 {
313 disconnect(m_model, 0, this, 0);
453 disconnect(m_model, 0, this, 0);
314 m_mapX = -1;
454 m_mapX = -1;
315 m_mapY = -1;
455 m_mapY = -1;
456 m_mapFirst = 0;
457 m_mapCount = 0;
458 m_mapLimited = false;
316 m_mapOrientation = Qt::Vertical;
459 m_mapOrientation = Qt::Vertical;
317 }
460 }
318
461
319 // set new model
462 // set new model
320 if(model)
463 if(model)
321 {
464 {
322 m_model = model;
465 m_model = model;
323 return true;
466 return true;
324 }
467 }
325 else
468 else
326 {
469 {
327 m_model = NULL;
470 m_model = NULL;
328 return false;
471 return false;
329 }
472 }
330 }
473 }
331
474
332 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
475 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
333 {
476 {
334 if (m_model == NULL)
477 if (m_model == NULL)
335 return;
478 return;
336 m_mapX = modelX;
479 m_mapX = modelX;
337 m_mapY = modelY;
480 m_mapY = modelY;
481 m_mapFirst = 0;
338 m_mapOrientation = orientation;
482 m_mapOrientation = orientation;
339 if (m_mapOrientation == Qt::Vertical)
483 if (m_mapOrientation == Qt::Vertical)
340 {
484 {
485 // m_mapCount = m_model->rowCount();
341 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
486 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
487 connect(m_model,SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
342 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
488 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
489 connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
343 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
490 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
344 }
491 }
345 else
492 else
346 {
493 {
494 // m_mapCount = m_model->columnCount();
347 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
495 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
496 connect(m_model,SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
348 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
497 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
498 connect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
349 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
499 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
350 }
500 }
351 }
501 }
352
502
353 //void QXYSeries::setModelMappingY(int modelLineIndex, Qt::Orientation orientation)
503 void QXYSeries::setModelMappingShift(int first, int count)
354 //{
504 {
355 // m_mapY = modelLineIndex;
505 m_mapFirst = first;
356 // m_mapYOrientation = orientation;
506 if (count == 0)
357 //}
507 m_mapLimited = false;
508 else
509 {
510 m_mapCount = count;
511 m_mapLimited = true;
512 }
513 }
358
514
359 #include "moc_qxyseries.cpp"
515 #include "moc_qxyseries.cpp"
360
516
361 QTCOMMERCIALCHART_END_NAMESPACE
517 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,77 +1,81
1 #ifndef QXYSERIES_H_
1 #ifndef QXYSERIES_H_
2 #define QXYSERIES_H_
2 #define QXYSERIES_H_
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qseries.h>
5 #include <qseries.h>
6 #include <QDebug>
6 #include <QDebug>
7 #include <QPen>
7 #include <QPen>
8 #include <QBrush>
8 #include <QBrush>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QSeries
12 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QSeries
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 protected:
15 protected:
16 QXYSeries(QObject* parent=0);
16 QXYSeries(QObject* parent=0);
17 virtual ~QXYSeries();
17 virtual ~QXYSeries();
18
18
19 public:
19 public:
20 void add(qreal x, qreal y);
20 void add(qreal x, qreal y);
21 void add(const QPointF& point);
21 void add(const QPointF& point);
22 void add(const QList<QPointF> points);
22 void add(const QList<QPointF> points);
23 void replace(qreal x,qreal y);
23 void replace(qreal x,qreal y);
24 void replace(const QPointF& point);
24 void replace(const QPointF& point);
25 void remove(qreal x);
25 void remove(qreal x);
26 void remove(qreal x, qreal y);
26 void remove(qreal x, qreal y);
27 void remove(const QPointF& point);
27 void remove(const QPointF& point);
28 void removeAll();
28 void removeAll();
29
29
30 int count() const;
30 int count() const;
31 qreal x(int pos) const;
31 qreal x(int pos) const;
32 qreal y(int pos) const;
32 qreal y(int pos) const;
33 QList<QPointF> data();
33 QList<QPointF> data();
34
34
35 QXYSeries& operator << (const QPointF &point);
35 QXYSeries& operator << (const QPointF &point);
36 QXYSeries& operator << (const QList<QPointF> points);
36 QXYSeries& operator << (const QList<QPointF> points);
37
37
38 void setPen(const QPen& pen);
38 void setPen(const QPen& pen);
39 QPen pen() const {return m_pen;}
39 QPen pen() const {return m_pen;}
40 void setBrush(const QBrush& pen);
40 void setBrush(const QBrush& pen);
41 QBrush brush() const {return m_brush;}
41 QBrush brush() const {return m_brush;}
42
42
43 bool setModel(QAbstractItemModel* model);
43 bool setModel(QAbstractItemModel* model);
44 QAbstractItemModel* model() {return m_model;}
44 QAbstractItemModel* model() {return m_model;}
45
45
46 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
46 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
47 // void setModelMappingY(int modelLineIndex, Qt::Orientation orientation = Qt::Vertical);
47 virtual void setModelMappingShift(int first, int count = 0);
48
48
49 private slots:
49 private slots:
50 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
50 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
51 void modelDataAboutToBeAdded(QModelIndex parent, int start, int end);
51 void modelDataAdded(QModelIndex parent, int start, int end);
52 void modelDataAdded(QModelIndex parent, int start, int end);
53 void modelDataAboutToBeRemoved(QModelIndex parent, int start, int end);
52 void modelDataRemoved(QModelIndex parent, int start, int end);
54 void modelDataRemoved(QModelIndex parent, int start, int end);
53
55
54 signals:
56 signals:
55 void clicked(const QPointF& point);
57 void clicked(const QPointF& point);
56 void updated();
58 void updated();
57 void pointReplaced(int index);
59 void pointReplaced(int index);
58 void pointRemoved(int index);
60 void pointRemoved(int index);
59 void pointAdded(int index);
61 void pointAdded(int index);
60
62
61 protected:
63 protected:
62 QVector<qreal> m_x;
64 QVector<qreal> m_x;
63 QVector<qreal> m_y;
65 QVector<qreal> m_y;
64
66
65 QPen m_pen;
67 QPen m_pen;
66 QBrush m_brush;
68 QBrush m_brush;
67
69
68 // QAbstractItemModel* m_model;
69 int m_mapX;
70 int m_mapX;
70 Qt::Orientation m_mapOrientation;
71 int m_mapY;
71 int m_mapY;
72 // Qt::Orientation m_mapYOrientation;
72 int m_mapFirst;
73 int m_mapCount;
74 bool m_mapLimited;
75 Qt::Orientation m_mapOrientation;
76 int tempItemsRemoved;
73 };
77 };
74
78
75 QTCOMMERCIALCHART_END_NAMESPACE
79 QTCOMMERCIALCHART_END_NAMESPACE
76
80
77 #endif
81 #endif
General Comments 0
You need to be logged in to leave comments. Login now