##// END OF EJS Templates
Added support for data from model to QBarSeries. Various fixes and small modifications to data from model support to other series
Marek Rosa -
r630:dd8db9a3a988
parent child
Show More
@@ -1,23 +1,23
1 1 TEMPLATE = subdirs
2 2 SUBDIRS += linechart \
3 3 zoomlinechart \
4 4 colorlinechart \
5 5 barchart \
6 6 stackedbarchart \
7 7 percentbarchart \
8 8 scatterchart \
9 9 piechart \
10 10 piechartdrilldown \
11 11 dynamiclinechart \
12 12 axischart \
13 13 multichart \
14 14 gdpbarchart \
15 15 presenterchart \
16 16 chartview \
17 17 scatterinteractions \
18 18 splinechart \
19 19 areachart \
20 20 stackedbarchartdrilldown \
21 21 customcolors \
22 22 tablemodelchart \
23 ekgchart
23 #ekgchart
@@ -1,114 +1,116
1 1 #include "splinewidget.h"
2 2 #include "qchartview.h"
3 3 #include "qlineseries.h"
4 4 #include <QGridLayout>
5 5 #include <QPushButton>
6 6 #include "qchartaxis.h"
7 7 #include <qmath.h>
8 #include <QTime>
8 9
9 10 QTCOMMERCIALCHART_USE_NAMESPACE
10 11
11 12 SplineWidget::SplineWidget(QWidget *parent)
12 13 : QWidget(parent)
13 14 {
14 15 // qsrand(time(NULL));
16 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
15 17 //! [1]
16 18 //create QSplineSeries
17 19 series = new QSplineSeries(this);
18 20 //! [1]
19 21
20 22 //! [2]
21 23 // customize the series presentation settings
22 24 QPen seriesPen(Qt::blue);
23 25 seriesPen.setWidth(3);
24 26 // series->setPen(seriesPen);
25 27 //! [2]
26 28
27 29 //! [add points to series]
28 30 //add data points to the series
29 31 series->add(QPointF(150, 100));
30 32 series->add(QPointF(200, 130));
31 33 series->add(QPointF(250, 120));
32 34 series->add(QPointF(300, 140));
33 35 series->add(QPointF(350, 160));
34 36 //! [add points to series]
35 37
36 38 QSplineSeries* series2 = new QSplineSeries;
37 39
38 40 series2->add(QPointF(400, 120));
39 41 series2->add(QPointF(450, 150));
40 42 series2->add(QPointF(500, 145));
41 43 series2->add(QPointF(550, 170));
42 44
43 45 // series->add(QPointF(600, 190));
44 46 // series->add(QPointF(650, 210));
45 47 // series->add(QPointF(700, 190));
46 48 // series->add(QPointF(750, 180));
47 49 // series->add(QPointF(800, 170));
48 50 QSplineSeries* series3 = new QSplineSeries;
49 51 series3->add(QPointF(600, 190));
50 52 series3->add(QPointF(650, 210));
51 53 series3->add(QPointF(700, 190));
52 54 series3->add(QPointF(750, 180));
53 55 series3->add(QPointF(800, 170));
54 56
55 57 //! [3]
56 58 // create chart view
57 59 QChartView* chart = new QChartView;
58 60 chart->addSeries(series);
59 61 chart->addSeries(series2);
60 62 chart->addSeries(series3);
61 63
62 64 chart->setChartTitle("Spline chart example");
63 65 chart->axisX()->setMax(1500);
64 66 chart->axisY()->setMax(500);
65 67
66 68 chart->setMinimumSize(800,600);
67 69 //! [3]
68 70
69 71 //! [4]
70 72 //add new data point button
71 73 QPushButton* addButton = new QPushButton("Add new point");
72 74 connect(addButton, SIGNAL(clicked()), this, SLOT(addNewPoint()));
73 75
74 76 // remove the last data point in the series
75 77 QPushButton* removeButton = new QPushButton("Remove point");
76 78 connect(removeButton, SIGNAL(clicked()), this, SLOT(removePoint()));
77 79 //! [4]
78 80
79 81 //! [5]
80 82 //butttons layout
81 83 QVBoxLayout* buttonsLayout = new QVBoxLayout;
82 84 buttonsLayout->addWidget(addButton);
83 85 buttonsLayout->addWidget(removeButton);
84 86 buttonsLayout->addStretch();
85 87
86 88 QGridLayout* mainLayout = new QGridLayout;
87 89 mainLayout->addWidget(chart, 1, 0);
88 90 mainLayout->addLayout(buttonsLayout, 1, 1);
89 91 setLayout(mainLayout);
90 92 //! [5]
91 93 }
92 94
93 95 //! [add point]
94 96 void SplineWidget::addNewPoint()
95 97 {
96 98 if (series->count() > 0)
97 99 series->add(QPointF(series->x(series->count() - 1) + 40 + qrand()%40, qAbs(series->y(series->count() - 1) - 50 + qrand()%100)));
98 100 else
99 101 series->add(QPointF(50, 50 + qrand()%50));
100 102 }
101 103 //! [add point]
102 104
103 105 //! [remove point]
104 106 void SplineWidget::removePoint()
105 107 {
106 108 if (series->count() > 0)
107 109 series->remove(QPointF(series->x(series->count() - 1), series->y(series->count() - 1)));
108 110 }
109 111 //! [remove point]
110 112
111 113 SplineWidget::~SplineWidget()
112 114 {
113 115
114 116 }
@@ -1,151 +1,204
1 1 #include "customtablemodel.h"
2 #include <QVector>
2 3
3 4 CustomTableModel::CustomTableModel(QObject *parent) :
4 5 QAbstractTableModel(parent)
5 6 {
6 m_points.append(QPointF(10, 50));
7 m_labels.append("Apples");
8 m_points.append(QPointF(60, 70));
9 m_labels.append("Oranges");
10 m_points.append(QPointF(110, 50));
11 m_labels.append("Bananas");
12 m_points.append(QPointF(140, 40));
13 m_labels.append("Lemons");
14 m_points.append(QPointF(200, 150));
15 m_labels.append("Plums");
16 m_points.append(QPointF(225, 75));
17 m_labels.append("Pearls");
7 // m_points.append(QPointF(10, 50));
8 // m_labels.append("Apples");
9 // m_points.append(QPointF(60, 70));
10 // m_labels.append("Oranges");
11 // m_points.append(QPointF(110, 50));
12 // m_labels.append("Bananas");
13 // m_points.append(QPointF(140, 40));
14 // m_labels.append("Lemons");
15 // m_points.append(QPointF(200, 150));
16 // m_labels.append("Plums");
17 // m_points.append(QPointF(225, 75));
18 // m_labels.append("Pearls");
19
20 // m_data
21 for (int i = 0; i < 6; i++)
22 {
23 QVector<qreal>* dataVec = new QVector<qreal>(6);
24 for (int k = 0; k < dataVec->size(); k++)
25 if (k%2 == 0)
26 dataVec->replace(k, i * 50 + qrand()%20);
27 else
28 dataVec->replace(k, qrand()%100);
29 m_data.append(dataVec);
30 m_labels.append(QString("Row: %1").arg((i + 1)));
31 }
18 32 }
19 33
20 34 int CustomTableModel::rowCount(const QModelIndex & parent) const
21 35 {
22 36 Q_UNUSED(parent)
23 return m_points.count();
37 // return m_points.count();
38 return m_data.count();
24 39 }
25 40
26 41 int CustomTableModel::columnCount(const QModelIndex & parent) const
27 42 {
28 43 Q_UNUSED(parent)
29 return 3;
44 // return 3;
45 return 6;
30 46 }
31 47
32 48 QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation, int role ) const
33 49 {
34 50 if (role != Qt::DisplayRole)
35 51 return QVariant();
36 52
37 53 if (orientation == Qt::Horizontal)
38 54 {
39 55 switch(section)
40 56 {
41 case 0:
42 return "x";
43 case 1:
44 return "y";
45 case 2:
57 // case 0:
58 // return "x";
59 // case 1:
60 // return "y";
61 // case 2:
62 case 6:
46 63 return "Fruit";
47 64 default:
48 return "What?";
65 if (section%2 == 0)
66 return "x";
67 else
68 return "y";
69 // return "What?";
49 70 }
50 71 }
51 72 else
52 73 return QString("%1").arg(section + 1);
53 74 }
54 75
55 76 QVariant CustomTableModel::data(const QModelIndex & index, int role) const
56 77 {
57 78 if (role == Qt::DisplayRole)
58 79 {
59 80 switch(index.column())
60 81 {
61 case 0:
62 return m_points[index.row()].x();
63 case 1:
64 return m_points[index.row()].y();
65 case 2:
82 // case 0:
83 // return m_points[index.row()].x();
84 // case 1:
85 // return m_points[index.row()].y();
86 // case 2:
87 case 6:
66 88 return m_labels[index.row()];
67 89 default:
90 return m_data[index.row()]->at(index.column());
68 91 break;
69 92 }
70 93 }
71 94 else if (role == Qt::EditRole)
72 95 {
73 96 switch(index.column())
74 97 {
75 case 0:
76 return m_points[index.row()].x();
77 case 1:
78 return m_points[index.row()].y();
79 case 2:
98 // case 0:
99 // return m_points[index.row()].x();
100 // case 1:
101 // return m_points[index.row()].y();
102 // case 2:
103 case 6:
80 104 return m_labels[index.row()];
81 105 default:
106 return m_data[index.row()]->at(index.column());
82 107 break;
83 108 }
84 109 }
85 110 return QVariant();
86 111 }
87 112
88 113 bool CustomTableModel::setData ( const QModelIndex & index, const QVariant & value, int role)
89 114 {
90 115 if (index.isValid() && role == Qt::EditRole)
91 116 {
92 117 switch(index.column())
93 118 {
94 case 0:
95 m_points[index.row()].setX(value.toDouble());
96 break;
97 case 1:
98 m_points[index.row()].setY(value.toDouble());
99 break;
100 case 2:
119 // case 0:
120 // m_points[index.row()].setX(value.toDouble());
121 // break;
122 // case 1:
123 // m_points[index.row()].setY(value.toDouble());
124 // break;
125 // case 2:
126 case 6:
101 127 m_labels.replace(index.row(), value.toString());
102 128 break;
103 129 default:
104 return false;
130 m_data[index.row()]->replace(index.column(), value.toDouble());
131 break;
132 // return false;
105 133 }
106 134 emit dataChanged(index, index);
107 135 return true;
108 136 }
109 137 return false;
110 138 }
111 139
112 140 Qt::ItemFlags CustomTableModel::flags ( const QModelIndex & index ) const
113 141 {
114 142 // if (!index.isValid())
115 143 // return Qt::ItemIsEnabled;
116 144 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
117 145 }
118 146
119 147 bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & parent)
120 148 {
121 149 Q_UNUSED(parent)
122 150
123 151 if (row < 0)
124 152 row = 0;
125 153 beginInsertRows(QModelIndex(), row /*dataTable.count()*/, row + count - 1);
126 154 for (int i = row; i < row + count; i++)
127 155 {
128 m_points.insert(row, QPointF(10,20));
129 m_labels.insert(row,("a"));
156 // m_points.insert(row, QPointF(10,20));
157 QVector<qreal>* dataVec = new QVector<qreal>(6);
158 for (int k = 0; k < dataVec->size(); k++)
159 if (k%2 == 0)
160 // dataVec->replace(k, i * 50 + qrand()%20);
161 {
162 int difference = 0;
163 if (row < m_data.size())
164 {
165 if (row - 1 >= 0)
166 {
167 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));
169 }
170 else
171 dataVec->replace(k, qrand()%20);
172 }
173 else
174 dataVec->replace(k, m_data[row - 1]->at(k) + qrand()%20);
175 }
176 else
177 dataVec->replace(k, qrand()%100);
178 m_data.insert(row, dataVec);
179 m_labels.insert(row,(QString("Row: %1").arg(row + 1)));
130 180 }
131 181 endInsertRows();
132 182 return true;
133 183 }
134 184
135 185 bool CustomTableModel::removeRows ( int row, int count, const QModelIndex & parent)
136 186 {
137 187 if (row > this->rowCount() - 1)
138 188 return false;
139 189 if (row < 0)
140 190 row = 0;
141 191 if (row + count > rowCount())
142 192 return false;
143 193 beginRemoveRows(parent, row, row + count - 1);
144 194 for (int i = row; i < row + count; i++)
145 195 {
146 m_points.removeAt(row);
196 // m_points.removeAt(row);
197 QVector<qreal>* item = m_data.at(row);
198 m_data.removeAt(row);
199 delete item;
147 200 m_labels.removeAt(row);
148 201 }
149 202 endRemoveRows();
150 203 return true;
151 204 }
@@ -1,33 +1,34
1 1 #ifndef XYPOINTSMODEL_H
2 2 #define XYPOINTSMODEL_H
3 3
4 4 #include <QAbstractTableModel>
5 5 #include <QPointF>
6 6 #include <QStringList>
7 7
8 8 class CustomTableModel : public QAbstractTableModel
9 9 {
10 10 Q_OBJECT
11 11 public:
12 12 explicit CustomTableModel(QObject *parent = 0);
13 13
14 14 int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
15 15 int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
16 16 QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
17 17 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
18 18 bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
19 19 Qt::ItemFlags flags ( const QModelIndex & index ) const;
20 20 bool insertRows ( int row, int count, const QModelIndex & parent = QModelIndex() );
21 21 bool removeRows ( int row, int count, const QModelIndex & parent = QModelIndex() );
22 22
23 23 //signals:
24 24
25 25 //public slots:
26 26 private:
27 QList<QVector<qreal>* > m_data;
27 28 QList<QPointF> m_points;
28 29 QStringList m_labels;
29 30
30 31
31 32 };
32 33
33 34 #endif // XYPOINTSMODEL_H
@@ -1,133 +1,249
1 1 #include "tablewidget.h"
2 2 #include <QGridLayout>
3 3 #include <QTableView>
4 4 #include <QStyledItemDelegate>
5 5 #include "qlineseries.h"
6 6 #include "qsplineseries.h"
7 7 #include "qscatterseries.h"
8 8 #include "customtablemodel.h"
9 9 #include "qpieseries.h"
10 #include "qareaseries.h"
11 #include "qbarseries.h"
10 12 #include <QPushButton>
11 13 #include <QRadioButton>
14 #include <QTime>
12 15
13 16 TableWidget::TableWidget(QWidget *parent)
14 17 : QWidget(parent)
15 18 {
16 19 setGeometry(100, 100, 1000, 600);
20 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
17 21 // create simple model for storing data
18 22 // user's table data model
19 23 m_model = new CustomTableModel;
20 24 tableView = new QTableView;
21 25 tableView->setModel(m_model);
22 tableView->setMinimumSize(340, 480);
26 tableView->setMinimumHeight(240);
27 // tableView->setMinimumSize(340, 480);
23 28 // tableView->setItemDelegate(new QStyledItemDelegate);
24 29 chartView = new QChartView(this);
30 chartView->setRenderHint(QPainter::Antialiasing);
25 31 chartView->setMinimumSize(640, 480);
26 32
27 33 // create
28 34 // QLineSeries* series = new QLineSeries;
29 35 // QSplineSeries* series = new QSplineSeries;
30 36 // QScatterSeries* series = new QScatterSeries;
31 37 // series->setModel(m_model);
32 38 // series->setModelMapping(0,1, Qt::Vertical);
33 39
34 40 // QPieSeries* pieSeries = new QPieSeries;
35 41 // pieSeries->setModel(model);
36 42 // pieSeries
37 43
38 44 // chartView->addSeries(series);
39 45
40 46 // add, remove data buttons
41 47 QPushButton* addRowAboveButton = new QPushButton("Add row above");
42 48 connect(addRowAboveButton, SIGNAL(clicked()), this, SLOT(addRowAbove()));
43 49
44 50 QPushButton* addRowBelowButton = new QPushButton("Add row below");
45 51 connect(addRowBelowButton, SIGNAL(clicked()), this, SLOT(addRowBelow()));
46 52
47 53 QPushButton* removeRowButton = new QPushButton("Remove row");
48 54 connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
49 55
50 56 // buttons layout
51 57 QVBoxLayout* buttonsLayout = new QVBoxLayout;
52 58 buttonsLayout->addWidget(addRowAboveButton);
53 59 buttonsLayout->addWidget(addRowBelowButton);
54 60 buttonsLayout->addWidget(removeRowButton);
55 61 buttonsLayout->addStretch();
56 62
57 63 // chart type radio buttons
58 64 lineRadioButton = new QRadioButton("Line");
59 65 splineRadioButton = new QRadioButton("Spline");
60 66 scatterRadioButton = new QRadioButton("Scatter");
61 67 pieRadioButton = new QRadioButton("Pie");
68 areaRadioButton = new QRadioButton("Area");
69 barRadioButton = new QRadioButton("Bar");
62 70
63 71 connect(lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
64 72 connect(splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
65 73 connect(scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
66 74 connect(pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
75 connect(areaRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
76 connect(barRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
67 77 lineRadioButton->setChecked(true);
68 78
69 79 // radio buttons layout
70 QHBoxLayout* radioLayout = new QHBoxLayout;
80 QVBoxLayout* radioLayout = new QVBoxLayout;
71 81 radioLayout->addWidget(lineRadioButton);
72 82 radioLayout->addWidget(splineRadioButton);
73 83 radioLayout->addWidget(scatterRadioButton);
74 84 radioLayout->addWidget(pieRadioButton);
85 radioLayout->addWidget(areaRadioButton);
86 radioLayout->addWidget(barRadioButton);
87 radioLayout->addStretch();
75 88
76 89 // create main layout
77 90 QGridLayout* mainLayout = new QGridLayout;
78 mainLayout->addLayout(buttonsLayout, 0, 1);
79 mainLayout->addLayout(radioLayout, 0, 2);
91 mainLayout->addLayout(buttonsLayout, 1, 0);
92 mainLayout->addLayout(radioLayout, 2, 0);
80 93 mainLayout->addWidget(tableView, 1, 1);
81 mainLayout->addWidget(chartView, 1, 2);
94 mainLayout->addWidget(chartView, 2, 1);
82 95 setLayout(mainLayout);
96 lineRadioButton->setFocus();
83 97 }
84 98
85 99 void TableWidget::addRowAbove()
86 100 {
87 101 // m_model->insertRow(m_model->rowCount());
88 102 m_model->insertRow(tableView->currentIndex().row());
89 103
90 104 }
91 105
92 106 void TableWidget::addRowBelow()
93 107 {
94 108 // m_model->insertRow(m_model->rowCount());
95 109 m_model->insertRow(tableView->currentIndex().row() + 1);
96 110
97 111 }
98 112
99 113 void TableWidget::removeRow()
100 114 {
101 115 // m_model->removeRow(m_model->rowCount() - 1);
102 116 m_model->removeRow(tableView->currentIndex().row());
103 117 }
104 118
105 119 void TableWidget::updateChartType()
106 120 {
107 121 chartView->removeAllSeries();
108 122
109 123 if (lineRadioButton->isChecked())
124 {
125 // series 1
126 series = new QLineSeries;
127 series->setModel(m_model);
128 series->setModelMapping(0,1, Qt::Vertical);
129 // series->setModelMapping(0,1, Qt::Horizontal);
130 chartView->addSeries(series);
131
132 // series 2
110 133 series = new QLineSeries;
134 series->setModel(m_model);
135 series->setModelMapping(2,3, Qt::Vertical);
136 // series->setModelMapping(2,3, Qt::Horizontal);
137 chartView->addSeries(series);
138
139 // series 3
140 series = new QLineSeries;
141 series->setModel(m_model);
142 series->setModelMapping(4,5, Qt::Vertical);
143 // series->setModelMapping(4,5, Qt::Horizontal);
144 chartView->addSeries(series);
145 }
111 146 else if (splineRadioButton->isChecked())
147 {
148 // series 1
112 149 series = new QSplineSeries;
150 series->setModel(m_model);
151 series->setModelMapping(0,1, Qt::Vertical);
152 // series->setModelMapping(0,1, Qt::Horizontal);
153 chartView->addSeries(series);
154
155 // series 2
156 series = new QSplineSeries;
157 series->setModel(m_model);
158 series->setModelMapping(2,3, Qt::Vertical);
159 // series->setModelMapping(2,3, Qt::Horizontal);
160 chartView->addSeries(series);
161
162 // series 3
163 series = new QSplineSeries;
164 series->setModel(m_model);
165 series->setModelMapping(4,5, Qt::Vertical);
166 // series->setModelMapping(4,5, Qt::Horizontal);
167 chartView->addSeries(series);
168 }
113 169 else if (scatterRadioButton->isChecked())
170 {
171 // series 1
114 172 series = new QScatterSeries;
173 series->setModel(m_model);
174 series->setModelMapping(0,1, Qt::Vertical);
175 // series->setModelMapping(0,1, Qt::Horizontal);
176 chartView->addSeries(series);
177
178 // series 2
179 series = new QScatterSeries;
180 series->setModel(m_model);
181 series->setModelMapping(2,3, Qt::Vertical);
182 // series->setModelMapping(2,3, Qt::Horizontal);
183 chartView->addSeries(series);
184
185 // series 3
186 series = new QScatterSeries;
187 series->setModel(m_model);
188 series->setModelMapping(4,5, Qt::Vertical);
189 // series->setModelMapping(4,5, Qt::Horizontal);
190 chartView->addSeries(series);
191 }
115 192 else if (pieRadioButton->isChecked())
116 193 {
194 // pie 1
117 195 QPieSeries* pieSeries = new QPieSeries;
118 196 pieSeries->setModel(m_model);
119 pieSeries->setModelMapping(0,2, Qt::Vertical);
197 pieSeries->setModelMapping(0,0, Qt::Horizontal);
198 pieSeries->setLabelsVisible(true);
199 pieSeries->setPieSize(0.4);
200 pieSeries->setPiePosition(0.2, 0.35);
201 chartView->addSeries(pieSeries);
202
203 // pie 2
204 pieSeries = new QPieSeries;
205 pieSeries->setModel(m_model);
206 pieSeries->setModelMapping(1,1, Qt::Horizontal);
120 207 pieSeries->setLabelsVisible(true);
208 pieSeries->setPieSize(0.4);
209 pieSeries->setPiePosition(0.8, 0.35);
121 210 chartView->addSeries(pieSeries);
122 return;
211
212 // pie 3
213 pieSeries = new QPieSeries;
214 pieSeries->setModel(m_model);
215 pieSeries->setModelMapping(2,2, Qt::Horizontal);
216 pieSeries->setLabelsVisible(true);
217 pieSeries->setPieSize(0.4);
218 pieSeries->setPiePosition(0.5, 0.65);
219 chartView->addSeries(pieSeries);
220 }
221 else if (areaRadioButton->isChecked())
222 {
223 QLineSeries* upperLineSeries = new QLineSeries;
224 upperLineSeries->setModel(m_model);
225 upperLineSeries->setModelMapping(0, 1, Qt::Vertical);
226 QLineSeries* lowerLineSeries = new QLineSeries;
227 lowerLineSeries->setModel(m_model);
228 lowerLineSeries->setModelMapping(2, 3, Qt::Vertical);
229 QAreaSeries* areaSeries = new QAreaSeries(upperLineSeries, lowerLineSeries);
230 chartView->addSeries(areaSeries);
231 }
232 else if (barRadioButton->isChecked())
233 {
234 QBarSeries* barSeries = new QBarSeries(QStringList());
235 barSeries->setModel(m_model);
236 barSeries->setModelMapping(5, 2, 4, Qt::Vertical);
237 barSeries->setToolTipEnabled(true);
238 chartView->addSeries(barSeries);
123 239 }
124 240
125 series->setModel(m_model);
126 series->setModelMapping(0,1, Qt::Vertical);
127 chartView->addSeries(series);
241 // series->setModel(m_model);
242 // series->setModelMapping(0,1, Qt::Vertical);
243 // chartView->addSeries(series);
128 244 }
129 245
130 246 TableWidget::~TableWidget()
131 247 {
132 248
133 249 }
@@ -1,41 +1,43
1 1 #ifndef TABLEWIDGET_H
2 2 #define TABLEWIDGET_H
3 3
4 4 #include <QtGui/QWidget>
5 5 #include "qchartview.h"
6 6 #include "qxyseries.h"
7 7
8 8 QTCOMMERCIALCHART_USE_NAMESPACE
9 9
10 10 class CustomTableModel;
11 11 class QTableView;
12 12 class QRadioButton;
13 13 //class QSeries;
14 14
15 15 class TableWidget : public QWidget
16 16 {
17 17 Q_OBJECT
18 18
19 19 public:
20 20 TableWidget(QWidget *parent = 0);
21 21 ~TableWidget();
22 22
23 23
24 24 public slots:
25 25 void addRowAbove();
26 26 void addRowBelow();
27 27 void removeRow();
28 28 void updateChartType();
29 29
30 30 private:
31 31 QChartView* chartView;
32 32 QXYSeries* series;
33 33 CustomTableModel* m_model;
34 34 QTableView* tableView;
35 35 QRadioButton* lineRadioButton;
36 36 QRadioButton* splineRadioButton;
37 37 QRadioButton* scatterRadioButton;
38 38 QRadioButton* pieRadioButton;
39 QRadioButton* areaRadioButton;
40 QRadioButton* barRadioButton;
39 41 };
40 42
41 43 #endif // TABLEWIDGET_H
@@ -1,129 +1,148
1 1 #include "qareaseries.h"
2 2 #include "qlineseries.h"
3 3
4 4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 5
6 6 /*!
7 7 \class QAreaSeries
8 8 \brief The QAreaSeries class is used for making area charts.
9 9
10 10 \mainclass
11 11
12 12 An area chart is used to show quantitative data. It is based on line chart, in the way that area between axis and the line
13 13 is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance,
14 14 which defines "upper" boundary of the area. "Lower" boundary is defined by default by axis X. Instead of axis X "lower" boundary can be specified by other line.
15 15 In that case QAreaSeries should be initiated with two QLineSerie instances. Please note terms "upper" and "lower" boundary can be misleading in cases
16 16 where "lower" boundary had bigger values than the "upper" one, however the main point that area between these two boundary lines will be filled.
17 17
18 18 \image areachart.png
19 19
20 20 Creating basic area chart is simple:
21 21 \code
22 22 QLineSeries* lineSeries = new QLineSeries();
23 23 series->add(0, 6);
24 24 series->add(2, 4);
25 25 QAreaSeries* areaSeries = new QAreaSeries(lineSeries);
26 26 ...
27 27 chartView->addSeries(areaSeries);
28 28 \endcode
29 29 */
30 30
31 31 /*!
32 32 \fn virtual QSeriesType QAreaSeries::type() const
33 33 \brief Returns type of series.
34 34 \sa QSeries, QSeriesType
35 35 */
36 36
37 37 /*!
38 38 \fn QLineSeries* QAreaSeries::upperSeries() const
39 39 \brief Returns upperSeries used to define one of area boundaries.
40 40 */
41 41
42 42 /*!
43 43 \fn QLineSeries* QAreaSeries::lowerSeries() const
44 44 \brief Returns lowerSeries used to define one of area boundaries. Note if QAreaSeries where counstucted wihtout a\ lowerSeries
45 45 this function return Null pointer.
46 46 */
47 47
48 48 /*!
49 49 \fn QPen QAreaSeries::pen() const
50 50 \brief Returns the pen used to draw line for this series.
51 51 \sa setPen()
52 52 */
53 53
54 54 /*!
55 55 \fn QPen QAreaSeries::brush() const
56 56 \brief Returns the brush used to draw line for this series.
57 57 \sa setBrush()
58 58 */
59 59
60 60 /*!
61 61 \fn bool QAreaSeries::pointsVisible() const
62 62 \brief Returns if the points are drawn for this series.
63 63 \sa setPointsVisible()
64 64 */
65 65
66 66 /*!
67 67 \fn void QAreaSeries::clicked(const QPointF& point)
68 68 \brief Signal is emitted when user clicks the \a point on area chart.
69 69 */
70 70
71 71 /*!
72 72 \fn void QAreaSeries::updated()
73 73 \brief \internal
74 74 */
75 75
76 76 /*!
77 77 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
78 78 upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead.
79 79 When series object is added to QChartView or QChart instance ownerships is transfered.
80 80 */
81 81 QAreaSeries::QAreaSeries(QLineSeries* upperSeries,QLineSeries* lowerSeries):QSeries(upperSeries),
82 82 m_upperSeries(upperSeries),
83 83 m_lowerSeries(lowerSeries),
84 84 m_pointsVisible(false)
85 85 {
86 86 }
87 87 /*!
88 88 Destroys the object. Series added to QChartView or QChart instances are owned by those,
89 89 and are deleted when mentioned object are destroyed.
90 90 */
91 91 QAreaSeries::~QAreaSeries()
92 92 {
93 93 }
94 94
95 95 /*!
96 96 Sets \a pen used for drawing area outline.
97 97 */
98 98 void QAreaSeries::setPen(const QPen& pen)
99 99 {
100 100 if(m_pen!=pen){
101 101 m_pen=pen;
102 102 emit updated();
103 103 }
104 104 }
105 105
106 106 /*!
107 107 Sets \a brush used for filling the area.
108 108 */
109 109 void QAreaSeries::setBrush(const QBrush& brush)
110 110 {
111 111 if(m_brush!=brush){
112 112 m_brush=brush;
113 113 emit updated();
114 114 }
115 115 }
116 116 /*!
117 117 Sets if data points are \a visible and should be drawn on line.
118 118 */
119 119 void QAreaSeries::setPointsVisible(bool visible)
120 120 {
121 121 if(m_pointsVisible!=visible){
122 122 m_pointsVisible=visible;
123 123 emit updated();
124 124 }
125 125 }
126 126
127 //bool QAreaSeries::setModel(QAbstractItemModel* model)
128 //{
129 // m_upperSeries->setModel(model);
130 // if (m_lowerSeries)
131 // m_lowerSeries->setModel(model);
132 // return true;
133 //}
134
135 //void QAreaSeries::setModelMappingUpper(int modelX, int modelY, Qt::Orientation orientation)
136 //{
137 // m_upperSeries->setModelMapping(modelX, modelY, orientation);
138 //}
139
140 //void QAreaSeries::setModelMappingLower(int modelX, int modelY, Qt::Orientation orientation)
141 //{
142 // if (m_lowerSeries)
143 // m_lowerSeries->setModelMapping(modelX, modelY, orientation);
144 //}
145
127 146 #include "moc_qareaseries.cpp"
128 147
129 148 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,49 +1,53
1 1 #ifndef QAREASERIES_H_
2 2 #define QAREASERIES_H_
3 3
4 4 #include "qchartglobal.h"
5 5 #include "qseries.h"
6 6 #include <QDebug>
7 7 #include <QPen>
8 8 #include <QBrush>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11 class QLineSeries;
12 12
13 13 class QTCOMMERCIALCHART_EXPORT QAreaSeries : public QSeries
14 14 {
15 15 Q_OBJECT
16 16 public:
17 17 QAreaSeries(QLineSeries* upperSeries,QLineSeries* lowerSeries=0);
18 18 virtual ~QAreaSeries();
19 19
20 20 public: // from QChartSeries
21 21 virtual QSeriesType type() const { return QSeries::SeriesTypeArea;}
22 22
23 23 QLineSeries* upperSeries() const { return m_upperSeries;}
24 24 QLineSeries* lowerSeries() const { return m_lowerSeries;}
25 25
26 26 void setPen(const QPen& pen);
27 27 QPen pen() const { return m_pen;}
28 28
29 29 void setBrush(const QBrush& brush);
30 30 QBrush brush() const { return m_brush;}
31 31
32 32 void setPointsVisible(bool visible);
33 33 bool pointsVisible() const {return m_pointsVisible;}
34 34
35 // bool setModel(QAbstractItemModel* model);
36 // void setModelMappingUpper(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
37 // void setModelMappingLower(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
38
35 39 signals:
36 40 void updated();
37 41 void clicked(const QPointF& point);
38 42
39 43 private:
40 44 QBrush m_brush;
41 45 QPen m_pen;
42 46 QLineSeries* m_upperSeries;
43 47 QLineSeries* m_lowerSeries;
44 48 bool m_pointsVisible;
45 49 };
46 50
47 51 QTCOMMERCIALCHART_END_NAMESPACE
48 52
49 53 #endif
@@ -1,242 +1,347
1 1 #include <QDebug>
2 2 #include "qbarseries.h"
3 3 #include "qbarset.h"
4 4 #include "barchartmodel_p.h"
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 /*!
9 9 \class QBarSeries
10 10 \brief part of QtCommercial chart API.
11 11
12 12 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
13 13 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
14 14 by QStringList.
15 15
16 16 \mainclass
17 17
18 18 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
19 19 */
20 20
21 21 /*!
22 22 \fn virtual QSeriesType QBarSeries::type() const
23 23 \brief Returns type of series.
24 24 \sa QSeries, QSeriesType
25 25 */
26 26
27 27 /*!
28 28 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
29 29 \brief \internal \a pos \a tip
30 30 */
31 31
32 32 /*!
33 33 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
34 34 QBarSeries is QObject which is a child of a \a parent.
35 35 */
36 36 QBarSeries::QBarSeries(QStringList categories, QObject *parent)
37 37 : QSeries(parent)
38 38 ,mModel(new BarChartModel(categories, this))
39 39 {
40 40 m_model = NULL;
41 41 m_mapCategories = -1;
42 42 m_mapBarBottom = -1;
43 43 m_mapBarTop = -1;
44 m_mapOrientation = Qt::Vertical;
44 45 }
45 46
46 47 /*!
47 48 Adds a set of bars to series. Takes ownership of \a set.
48 49 Connects the clicked(QString) and rightClicked(QString) signals
49 50 of \a set to this series
50 51 */
51 52 void QBarSeries::addBarSet(QBarSet *set)
52 53 {
53 54 mModel->addBarSet(set);
54 55 connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
55 56 connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
57 connect(set, SIGNAL(changed()), this, SLOT(barsetChanged()));
56 58 }
57 59
58 60 /*!
59 61 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
60 62 Disconnects the clicked(QString) and rightClicked(QString) signals
61 63 of \a set from this series
62 64 */
63 65 void QBarSeries::removeBarSet(QBarSet *set)
64 66 {
65 67 disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
66 68 disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
67 69 mModel->removeBarSet(set);
68 70 }
69 71
70 72 /*!
71 73 Returns number of sets in series.
72 74 */
73 75 int QBarSeries::barsetCount()
74 76 {
75 if(m_model)
76 return m_mapBarTop - m_mapBarBottom;
77 else
77 // if(m_model)
78 // return m_mapBarTop - m_mapBarBottom;
79 // else
78 80 return mModel->barsetCount();
79 81 }
80 82
81 83 /*!
82 84 Returns number of categories in series
83 85 */
84 86 int QBarSeries::categoryCount()
85 87 {
86 88 return mModel->categoryCount();
87 89 }
88 90
89 91 /*!
90 92 Returns a list of sets in series. Keeps ownership of sets.
91 93 */
92 94 QList<QBarSet*> QBarSeries::barSets()
93 95 {
94 96 return mModel->barSets();
95 97 }
96 98
97 99 /*!
98 100 \internal \a index
99 101 */
100 102 QBarSet* QBarSeries::barsetAt(int index)
101 103 {
102 104 return mModel->setAt(index);
103 105 }
104 106
105 107 /*!
106 108 \internal \a category
107 109 */
108 110 QString QBarSeries::categoryName(int category)
109 111 {
110 112 return mModel->categoryName(category);
111 113 }
112 114
113 115 /*!
114 116 Enables or disables tooltip depending on parameter \a enabled.
115 117 Tooltip shows the name of set, when mouse is hovering on top of bar.
116 118 Calling without parameter \a enabled, enables the tooltip
117 119 */
118 120 void QBarSeries::setToolTipEnabled(bool enabled)
119 121 {
120 122 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
121 123 if (enabled) {
122 124 for (int i=0; i<mModel->barsetCount(); i++) {
123 125 QBarSet *set = mModel->setAt(i);
124 126 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
125 127 }
126 128 } else {
127 129 for (int i=0; i<mModel->barsetCount(); i++) {
128 130 QBarSet *set = mModel->setAt(i);
129 131 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
130 132 }
131 133 }
132 134 }
133 135
134 136 /*!
135 137 Enables or disables separators depending on parameter \a enabled.
136 138 Separators are visual elements that are drawn between categories.
137 139 Calling without parameter \a enabled, enables the separators
138 140 */
139 141 void QBarSeries::setSeparatorsVisible(bool visible)
140 142 {
141 143 mSeparatorsVisible = visible;
142 144 emit enableSeparators(visible);
143 145 }
144 146
145 147
146 148 /*!
147 149 \internal \a category
148 150 */
149 151 void QBarSeries::barsetClicked(QString category)
150 152 {
151 153 emit clicked(qobject_cast<QBarSet*>(sender()), category);
152 154 }
153 155
154 156 /*!
155 157 \internal \a category
156 158 */
157 159 void QBarSeries::barsetRightClicked(QString category)
158 160 {
159 161 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
160 162 }
161 163
162 164
163 165 /*!
164 166 \internal
165 167 */
166 168 qreal QBarSeries::min()
167 169 {
168 170 return mModel->min();
169 171 }
170 172
171 173 /*!
172 174 \internal
173 175 */
174 176 qreal QBarSeries::max()
175 177 {
176 178 return mModel->max();
177 179 }
178 180
179 181 /*!
180 182 \internal \a set \a category
181 183 */
182 184 qreal QBarSeries::valueAt(int set, int category)
183 185 {
184 186 return mModel->valueAt(set,category);
185 187 }
186 188
187 189 /*!
188 190 \internal \a set \a category
189 191 */
190 192 qreal QBarSeries::percentageAt(int set, int category)
191 193 {
192 194 return mModel->percentageAt(set,category);
193 195 }
194 196
195 197 /*!
196 198 \internal \a category
197 199 */
198 200 qreal QBarSeries::categorySum(int category)
199 201 {
200 202 return mModel->categorySum(category);
201 203 }
202 204
203 205 /*!
204 206 \internal
205 207 */
206 208 qreal QBarSeries::maxCategorySum()
207 209 {
208 210 return mModel->maxCategorySum();
209 211 }
210 212
211 213 /*!
212 214 \internal
213 215 */
214 216 BarChartModel& QBarSeries::model()
215 217 {
216 218 return *mModel;
217 219 }
218 220
219 221 bool QBarSeries::separatorsVisible()
220 222 {
221 223 return mSeparatorsVisible;
222 224 }
223 225
224 226 bool QBarSeries::setModel(QAbstractItemModel* model)
225 227 {
228 // disconnect signals from old model
229 if(m_model)
230 {
231 disconnect(m_model, 0, this, 0);
232 m_mapCategories = -1;
233 m_mapBarBottom = -1;
234 m_mapBarTop = -1;
235 m_mapOrientation = Qt::Vertical;
236 }
237
238 // set new model
239 if(model)
240 {
226 241 m_model = model;
227 242 return true;
228 243 }
244 else
245 {
246 m_model = NULL;
247 return false;
248 }
249 }
229 250
230 251 // TODO
231 void QBarSeries::setModelMappingCategories(int /*modelColumn*/)
252 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
253 {
254 if (m_model == NULL)
255 return;
256 m_mapCategories = categories;
257 m_mapBarBottom = bottomBoundry;
258 m_mapBarTop = topBoundry;
259 m_mapOrientation = orientation;
260
261 // connect the signals
262 if (m_mapOrientation == Qt::Vertical)
263 {
264 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
265 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
266 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
267 }
268 else
232 269 {
270 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
271 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
272 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
233 273 }
234 274
235 // TODO
236 void QBarSeries::setModelMappingBarRange(int /*bottomBoundry*/, int /*topBoundry*/)
275
276 // create the initial bars
277 delete mModel;
278 if (m_mapOrientation == Qt::Vertical)
279 {
280 QStringList categories;
281 for (int k = 0; k < m_model->columnCount(); k++)
282 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
283 mModel = new BarChartModel(categories, this);
284
285 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++)
286 {
287 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
288 for(int m = 0; m < m_model->columnCount(); m++)
289 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
290 addBarSet(barSet);
291 }
292 }
293 else
294 {
295 QStringList categories;
296 for (int k = 0; k < m_model->rowCount(); k++)
297 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
298 mModel = new BarChartModel(categories, this);
299
300 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++)
301 {
302 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
303 for(int m = 0; m < m_model->rowCount(); m++)
304 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
305 addBarSet(barSet);
306 }
307 }
308 }
309
310 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
311 {
312 Q_UNUSED(bottomRight)
313
314 if (m_mapOrientation == Qt::Vertical)
315 {
316 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop)
317 barsetAt(topLeft.row())->setValue(topLeft.column(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
318 // else if (topLeft.column() == m_mapCategories)
319 // slices().at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
320 }
321 else
322 {
323 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop)
324 barsetAt(topLeft.column())->setValue(topLeft.row(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
325 // else if (topLeft.row() == m_mapCategories)
326 // slices().at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
327 }
328 }
329
330 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int /*start*/, int /*end*/)
331 {
332 //
333 }
334
335 void QBarSeries::modelDataRemoved(QModelIndex /*parent*/, int /*start*/, int /*end*/)
336 {
337 //
338 }
339
340 void QBarSeries::barsetChanged()
237 341 {
342 // mModel->
238 343 }
239 344
240 345 #include "moc_qbarseries.cpp"
241 346
242 347 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,81 +1,88
1 1 #ifndef BARSERIES_H
2 2 #define BARSERIES_H
3 3
4 4 #include "qseries.h"
5 5 #include <QStringList>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 class QBarSet;
10 10 class BarChartModel;
11 11 class BarCategory;
12 12
13 13 // Container for series
14 14 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
15 15 {
16 16 Q_OBJECT
17 17 public:
18 18 QBarSeries(QStringList categories, QObject* parent=0);
19 19
20 20 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
21 21
22 22 void addBarSet(QBarSet *set); // Takes ownership of set
23 23 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
24 24 int barsetCount();
25 25 int categoryCount();
26 26 QList<QBarSet*> barSets();
27 27
28 28 bool setModel(QAbstractItemModel* model);
29 29 QAbstractItemModel* modelExt() {return m_model;}
30 void setModelMappingCategories(int modelColumn);
31 void setModelMappingBarRange(int bottomBoundry, int topBoundry);
30 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
32 31
33 32 public:
34 33 // TODO: Functions below this are not part of api and will be moved
35 34 // to private implementation, when we start using it
36 35 // TODO: TO PIMPL --->
37 36 QBarSet* barsetAt(int index);
38 37 QString categoryName(int category);
39 38 qreal min();
40 39 qreal max();
41 40 qreal valueAt(int set, int category);
42 41 qreal percentageAt(int set, int category);
43 42 qreal categorySum(int category);
44 43 qreal maxCategorySum();
45 44 BarChartModel& model();
46 45 bool separatorsVisible();
47 46 // <--- TO PIMPL
48 47
49 48 signals:
50 49 //void changed(int index);
51 50 void clicked(QBarSet* barset, QString category); // Up to user of api, what to do with these signals
52 51 void rightClicked(QBarSet* barset, QString category);
53 52
54 53 // TODO: internal signals, these to private implementation.
55 54 // TODO: TO PIMPL --->
56 55 void enableSeparators(bool enable);
57 56 void showToolTip(QPoint pos, QString tip);
58 57 // <--- TO PIMPL
59 58
60 59 public Q_SLOTS:
61 60 void setToolTipEnabled(bool enabled=true); // enables tooltips
62 61 void setSeparatorsVisible(bool visible=true); // enables separators between categories
63 62
64 63 // TODO: TO PIMPL --->
65 64 void barsetClicked(QString category);
66 65 void barsetRightClicked(QString category);
67 66 // <--- TO PIMPL
68 67
68 private Q_SLOTS:
69 // slots for updating bars when data in model changes
70 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
71 void modelDataAdded(QModelIndex parent, int start, int end);
72 void modelDataRemoved(QModelIndex parent, int start, int end);
73 void barsetChanged();
74
69 75 protected:
70 76 BarChartModel* mModel;
71 77 bool mSeparatorsVisible;
72 78
73 79 QAbstractItemModel* m_model;
74 80 int m_mapCategories;
75 81 int m_mapBarBottom;
76 82 int m_mapBarTop;
83 Qt::Orientation m_mapOrientation;
77 84 };
78 85
79 86 QTCOMMERCIALCHART_END_NAMESPACE
80 87
81 88 #endif // BARSERIES_H
@@ -1,193 +1,194
1 1 #include "qbarset.h"
2 2 #include <QDebug>
3 3 #include <QToolTip>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 /*!
8 8 \class QBarSet
9 9 \brief part of QtCommercial chart API.
10 10
11 11 QBarSet represents one set of bars. Set of bars contains one data value for each category.
12 12 First value of set is assumed to belong to first category, second to second category and so on.
13 13 If set has fewer values than there are categories, then the missing values are assumed to be
14 14 at the end of set. For missing values in middle of a set, numerical value of zero is used.
15 15
16 16 \mainclass
17 17
18 18 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
19 19 */
20 20
21 21 /*!
22 22 \fn void QBarSet::clicked(QString category)
23 23 \brief signals that set has been clicked
24 24 Parameter \a category describes on which category was clicked
25 25 */
26 26
27 27 /*!
28 28 \fn void QBarSet::rightClicked(QString category)
29 29 \brief signals that set has been clicked with right mouse button
30 30 Parameter \a category describes on which category was clicked
31 31 */
32 32
33 33 /*!
34 34 \fn void QBarSet::hoverEnter(QPoint pos)
35 35 \brief signals that mouse has entered over the set at position \a pos.
36 36 */
37 37
38 38 /*!
39 39 \fn void QBarSet::hoverLeave()
40 40 \brief signals that mouse has left from the set.
41 41 */
42 42
43 43 /*!
44 44 \fn void QBarSet::toggleFloatingValues()
45 45 \brief \internal
46 46 */
47 47
48 48 /*!
49 49 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
50 50 \brief \internal \a pos \a tip
51 51 */
52 52
53 53
54 54 /*!
55 55 Constructs QBarSet with a name of \a name and with parent of \a parent
56 56 */
57 57 QBarSet::QBarSet(QString name, QObject *parent)
58 58 : QObject(parent)
59 59 ,mName(name)
60 60 {
61 61 }
62 62
63 63 /*!
64 64 Sets new \a name for set.
65 65 */
66 66 void QBarSet::setName(QString name)
67 67 {
68 68 mName = name;
69 69 }
70 70
71 71 /*!
72 72 Returns name of the set.
73 73 */
74 74 QString QBarSet::name()
75 75 {
76 76 return mName;
77 77 }
78 78
79 79 /*!
80 80 Appends new value \a value to the end of set.
81 81 */
82 82 QBarSet& QBarSet::operator << (const qreal &value)
83 83 {
84 84 mValues.append(value);
85 85 return *this;
86 86 }
87 87
88 88 /*!
89 89 Returns count of values in set.
90 90 */
91 91 int QBarSet::count()
92 92 {
93 93 return mValues.count();
94 94 }
95 95
96 96 /*!
97 97 Returns value of set indexed by \a index
98 98 */
99 99 qreal QBarSet::valueAt(int index)
100 100 {
101 101 return mValues.at(index);
102 102 }
103 103
104 104 /*!
105 105 Sets a new value \a value to set, indexed by \a index
106 106 */
107 107 void QBarSet::setValue(int index, qreal value)
108 108 {
109 109 mValues.replace(index,value);
110 emit changed();
110 111 }
111 112
112 113 /*!
113 114 Returns total sum of all values in barset.
114 115 */
115 116 qreal QBarSet::total()
116 117 {
117 118 qreal total(0);
118 119 for (int i=0; i<mValues.count(); i++) {
119 120 total += mValues.at(i);
120 121 }
121 122 return total;
122 123 }
123 124
124 125 /*!
125 126 Sets pen for set. Bars of this set are drawn using \a pen
126 127 */
127 128 void QBarSet::setPen(const QPen pen)
128 129 {
129 130 mPen = pen;
130 131 emit changed();
131 132 }
132 133
133 134 /*!
134 135 Returns pen of the set.
135 136 */
136 137 QPen QBarSet::pen() const
137 138 {
138 139 return mPen;
139 140 }
140 141
141 142 /*!
142 143 Sets brush for the set. Bars of this set are drawn using \a brush
143 144 */
144 145 void QBarSet::setBrush(const QBrush brush)
145 146 {
146 147 mBrush = brush;
147 148 emit changed();
148 149 }
149 150
150 151 /*!
151 152 Returns brush of the set.
152 153 */
153 154 QBrush QBarSet::brush() const
154 155 {
155 156 return mBrush;
156 157 }
157 158
158 159 /*!
159 160 Sets the pen for floating values that are drawn on top of this set
160 161 */
161 162 void QBarSet::setFloatingValuePen(const QPen pen)
162 163 {
163 164 mFloatingValuePen = pen;
164 165 }
165 166
166 167 /*!
167 168 Returns the pen for floating values that are drawn on top of this set
168 169 */
169 170 QPen QBarSet::floatingValuePen() const
170 171 {
171 172 return mFloatingValuePen;
172 173 }
173 174
174 175 /*!
175 176 \internal \a pos
176 177 */
177 178 void QBarSet::barHoverEnterEvent(QPoint pos)
178 179 {
179 180 emit showToolTip(pos, mName);
180 181 emit hoverEnter(pos);
181 182 }
182 183
183 184 /*!
184 185 \internal
185 186 */
186 187 void QBarSet::barHoverLeaveEvent()
187 188 {
188 189 // Emit signal to user of charts
189 190 emit hoverLeave();
190 191 }
191 192
192 193 #include "moc_qbarset.cpp"
193 194 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,572 +1,588
1 1 #include "qpieseries.h"
2 2 #include "qpieslice.h"
3 3 #include <QDebug>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 /*!
8 8 \class QPieSeries
9 9 \brief Pie series API for QtCommercial Charts
10 10
11 11 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
12 12 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
13 13 The actual slice size is determined by that relative value.
14 14
15 15 By default the pie is defined as a full pie but it can be a partial pie.
16 16 This can be done by setting a starting angle and angle span to the series.
17 17 */
18 18
19 19 /*!
20 20 Constructs a series object which is a child of \a parent.
21 21 */
22 22 QPieSeries::QPieSeries(QObject *parent) :
23 23 QSeries(parent),
24 24 m_pieRelativeHorPos(0.5),
25 25 m_pieRelativeVerPos(0.5),
26 26 m_pieRelativeSize(0.7),
27 27 m_pieStartAngle(0),
28 28 m_pieEndAngle(360),
29 29 m_total(0)
30 30 {
31 31
32 32 }
33 33
34 34 /*!
35 35 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
36 36 */
37 37 QPieSeries::~QPieSeries()
38 38 {
39 39
40 40 }
41 41
42 42 /*!
43 43 Returns QChartSeries::SeriesTypePie.
44 44 */
45 45 QSeries::QSeriesType QPieSeries::type() const
46 46 {
47 47 return QSeries::SeriesTypePie;
48 48 }
49 49
50 50 /*!
51 51 Sets an array of \a slices to the series replacing the existing slices.
52 52 Slice ownership is passed to the series.
53 53 */
54 54 void QPieSeries::replace(QList<QPieSlice*> slices)
55 55 {
56 56 clear();
57 57 add(slices);
58 58 }
59 59
60 60 /*!
61 61 Adds an array of \a slices to the series.
62 62 Slice ownership is passed to the series.
63 63 */
64 64 void QPieSeries::add(QList<QPieSlice*> slices)
65 65 {
66 66 foreach (QPieSlice* s, slices) {
67 67 s->setParent(this);
68 68 m_slices << s;
69 69 }
70 70
71 71 updateDerivativeData();
72 72
73 73 foreach (QPieSlice* s, slices) {
74 74 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
75 75 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
76 76 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
77 77 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
78 78 }
79 79
80 80 emit added(slices);
81 81 }
82 82
83 83 /*!
84 84 Adds a single \a slice to the series.
85 85 Slice ownership is passed to the series.
86 86 */
87 87 void QPieSeries::add(QPieSlice* slice)
88 88 {
89 89 add(QList<QPieSlice*>() << slice);
90 90 }
91 91
92 92 /*!
93 93 Adds a single \a slice to the series and returns a reference to the series.
94 94 Slice ownership is passed to the series.
95 95 */
96 96 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
97 97 {
98 98 add(slice);
99 99 return *this;
100 100 }
101 101
102 102
103 103 /*!
104 104 Adds a single slice to the series with give \a value and \a name.
105 105 Slice ownership is passed to the series.
106 106 */
107 107 QPieSlice* QPieSeries::add(qreal value, QString name)
108 108 {
109 109 QPieSlice* slice = new QPieSlice(value, name);
110 110 add(slice);
111 111 return slice;
112 112 }
113 113
114 114 void QPieSeries::insert(int i, QPieSlice* slice)
115 115 {
116 116 Q_ASSERT(i <= m_slices.count());
117 117 slice->setParent(this);
118 118 m_slices.insert(i, slice);
119 119
120 120 updateDerivativeData();
121 121
122 122 connect(slice, SIGNAL(changed()), this, SLOT(sliceChanged()));
123 123 connect(slice, SIGNAL(clicked()), this, SLOT(sliceClicked()));
124 124 connect(slice, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
125 125 connect(slice, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
126 126
127 127 emit added(QList<QPieSlice*>() << slice);
128 128 }
129 129
130 130 /*!
131 131 Removes a single \a slice from the series and deletes the slice.
132 132
133 133 Do not reference this pointer after this call.
134 134 */
135 135 void QPieSeries::remove(QPieSlice* slice)
136 136 {
137 137 if (!m_slices.removeOne(slice)) {
138 138 Q_ASSERT(0); // TODO: how should this be reported?
139 139 return;
140 140 }
141 141
142 142 updateDerivativeData();
143 143
144 144 emit removed(QList<QPieSlice*>() << slice);
145 145
146 146 delete slice;
147 147 slice = NULL;
148 148 }
149 149
150 150 /*!
151 151 Clears all slices from the series.
152 152 */
153 153 void QPieSeries::clear()
154 154 {
155 155 if (m_slices.count() == 0)
156 156 return;
157 157
158 158 QList<QPieSlice*> slices = m_slices;
159 159 foreach (QPieSlice* s, m_slices) {
160 160 m_slices.removeOne(s);
161 161 delete s;
162 162 }
163 163
164 164 updateDerivativeData();
165 165
166 166 emit removed(slices);
167 167 }
168 168
169 169 /*!
170 170 Counts the number of the slices in this series.
171 171 */
172 172 int QPieSeries::count() const
173 173 {
174 174 return m_slices.count();
175 175 }
176 176
177 177 /*!
178 178 Returns true is the series is empty.
179 179 */
180 180 bool QPieSeries::isEmpty() const
181 181 {
182 182 return m_slices.isEmpty();
183 183 }
184 184
185 185 /*!
186 186 Returns a list of slices that belong to this series.
187 187 */
188 188 QList<QPieSlice*> QPieSeries::slices() const
189 189 {
190 190 return m_slices;
191 191 }
192 192
193 193 /*!
194 194 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
195 195
196 196 The factors are relative to the chart rectangle where:
197 197
198 198 \a relativeHorizontalPosition 0.0 means the absolute left.
199 199 \a relativeHorizontalPosition 1.0 means the absolute right.
200 200 \a relativeVerticalPosition 0.0 means the absolute top.
201 201 \a relativeVerticalPosition 1.0 means the absolute bottom.
202 202
203 203 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
204 204
205 205 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
206 206 */
207 207 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
208 208 {
209 209 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
210 210 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
211 211 return;
212 212
213 213 if (m_pieRelativeHorPos != relativeHorizontalPosition || m_pieRelativeVerPos != relativeVerticalPosition) {
214 214 m_pieRelativeHorPos = relativeHorizontalPosition;
215 215 m_pieRelativeVerPos = relativeVerticalPosition;
216 216 emit piePositionChanged();
217 217 }
218 218 }
219 219
220 220 /*!
221 221 Gets the horizontal position of the pie.
222 222
223 223 The returned value is relative to the chart rectangle where:
224 224
225 225 0.0 means the absolute left.
226 226 1.0 means the absolute right.
227 227
228 228 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
229 229
230 230 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
231 231 */
232 232 qreal QPieSeries::pieHorizontalPosition() const
233 233 {
234 234 return m_pieRelativeHorPos;
235 235 }
236 236
237 237 /*!
238 238 Gets the vertical position position of the pie.
239 239
240 240 The returned value is relative to the chart rectangle where:
241 241
242 242 0.0 means the absolute top.
243 243 1.0 means the absolute bottom.
244 244
245 245 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
246 246
247 247 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
248 248 */
249 249 qreal QPieSeries::pieVerticalPosition() const
250 250 {
251 251 return m_pieRelativeVerPos;
252 252 }
253 253
254 254 /*!
255 255 Sets the relative size of the pie.
256 256
257 257 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
258 258
259 259 Default value is 0.7.
260 260
261 261 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
262 262 */
263 263 void QPieSeries::setPieSize(qreal relativeSize)
264 264 {
265 265 if (relativeSize < 0.0 || relativeSize > 1.0)
266 266 return;
267 267
268 268 if (m_pieRelativeSize != relativeSize) {
269 269 m_pieRelativeSize = relativeSize;
270 270 emit pieSizeChanged();
271 271 }
272 272 }
273 273
274 274 /*!
275 275 Gets the relative size of the pie.
276 276
277 277 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
278 278
279 279 Default value is 0.7.
280 280
281 281 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
282 282 */
283 283 qreal QPieSeries::pieSize() const
284 284 {
285 285 return m_pieRelativeSize;
286 286 }
287 287
288 288
289 289 /*!
290 290 Sets the end angle of the pie.
291 291
292 292 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
293 293
294 294 \a angle must be less than pie end angle. Default value is 0.
295 295
296 296 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
297 297 */
298 298 void QPieSeries::setPieStartAngle(qreal angle)
299 299 {
300 300 if (angle >= 0 && angle <= 360 && angle != m_pieStartAngle && angle <= m_pieEndAngle) {
301 301 m_pieStartAngle = angle;
302 302 updateDerivativeData();
303 303 }
304 304 }
305 305
306 306 /*!
307 307 Gets the start angle of the pie.
308 308
309 309 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
310 310
311 311 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
312 312 */
313 313 qreal QPieSeries::pieStartAngle() const
314 314 {
315 315 return m_pieStartAngle;
316 316 }
317 317
318 318 /*!
319 319 Sets the end angle of the pie.
320 320
321 321 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
322 322
323 323 \a angle must be greater than start angle.
324 324
325 325 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
326 326 */
327 327 void QPieSeries::setPieEndAngle(qreal angle)
328 328 {
329 329 if (angle >= 0 && angle <= 360 && angle != m_pieEndAngle && angle >= m_pieStartAngle) {
330 330 m_pieEndAngle = angle;
331 331 updateDerivativeData();
332 332 }
333 333 }
334 334
335 335 /*!
336 336 Returns the end angle of the pie.
337 337
338 338 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
339 339
340 340 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
341 341 */
342 342 qreal QPieSeries::pieEndAngle() const
343 343 {
344 344 return m_pieEndAngle;
345 345 }
346 346
347 347 /*!
348 348 Sets the all the slice labels \a visible or invisible.
349 349
350 350 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
351 351 */
352 352 void QPieSeries::setLabelsVisible(bool visible)
353 353 {
354 354 foreach (QPieSlice* s, m_slices)
355 355 s->setLabelVisible(visible);
356 356 }
357 357
358 358 /*!
359 359 Returns the sum of all slice values in this series.
360 360
361 361 \sa QPieSlice::value(), QPieSlice::setValue()
362 362 */
363 363 qreal QPieSeries::total() const
364 364 {
365 365 return m_total;
366 366 }
367 367
368 368 /*!
369 369 \fn void QPieSeries::changed()
370 370
371 371 This signal emitted when something has changed in the series.
372 372
373 373 \sa QPieSeries::ChangeSet, QPieSlice::changed()
374 374 */
375 375
376 376 /*!
377 377 \fn void QPieSeries::clicked(QPieSlice* slice)
378 378
379 379 This signal is emitted when a \a slice has been clicked.
380 380
381 381 \sa QPieSlice::clicked()
382 382 */
383 383
384 384 /*!
385 385 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
386 386
387 387 This signal is emitted when user has hovered over a \a slice.
388 388
389 389 \sa QPieSlice::hoverEnter()
390 390 */
391 391
392 392 /*!
393 393 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
394 394
395 395 This signal is emitted when user has hovered away from a \a slice.
396 396
397 397 \sa QPieSlice::hoverLeave()
398 398 */
399 399
400 400 void QPieSeries::sliceChanged()
401 401 {
402 402 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
403 403 Q_ASSERT(m_slices.contains(slice));
404 404 updateDerivativeData();
405 405 }
406 406
407 407 void QPieSeries::sliceClicked()
408 408 {
409 409 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
410 410 Q_ASSERT(m_slices.contains(slice));
411 411 emit clicked(slice);
412 412 }
413 413
414 414 void QPieSeries::sliceHoverEnter()
415 415 {
416 416 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
417 417 Q_ASSERT(m_slices.contains(slice));
418 418 emit hoverEnter(slice);
419 419 }
420 420
421 421 void QPieSeries::sliceHoverLeave()
422 422 {
423 423 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
424 424 Q_ASSERT(m_slices.contains(slice));
425 425 emit hoverLeave(slice);
426 426 }
427 427
428 428 void QPieSeries::updateDerivativeData()
429 429 {
430 430 m_total = 0;
431 431
432 432 // nothing to do?
433 433 if (m_slices.count() == 0)
434 434 return;
435 435
436 436 // calculate total
437 437 foreach (QPieSlice* s, m_slices)
438 438 m_total += s->value();
439 439
440 440 // nothing to show..
441 441 if (m_total == 0)
442 442 return;
443 443
444 444 // update slice attributes
445 445 qreal sliceAngle = m_pieStartAngle;
446 446 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
447 447 QVector<QPieSlice*> changed;
448 448 foreach (QPieSlice* s, m_slices) {
449 449
450 450 bool isChanged = false;
451 451
452 452 qreal percentage = s->value() / m_total;
453 453 if (s->m_percentage != percentage) {
454 454 s->m_percentage = percentage;
455 455 isChanged = true;
456 456 }
457 457
458 458 qreal sliceSpan = pieSpan * percentage;
459 459 if (s->m_angleSpan != sliceSpan) {
460 460 s->m_angleSpan = sliceSpan;
461 461 isChanged = true;
462 462 }
463 463
464 464 if (s->m_startAngle != sliceAngle) {
465 465 s->m_startAngle = sliceAngle;
466 466 isChanged = true;
467 467 }
468 468 sliceAngle += sliceSpan;
469 469
470 470 if (isChanged)
471 471 changed << s;
472 472 }
473 473
474 474 // emit signals
475 475 foreach (QPieSlice* s, changed)
476 476 emit s->changed();
477 477 }
478 478
479 479 bool QPieSeries::setModel(QAbstractItemModel* model)
480 480 {
481 481 // disconnect signals from old model
482 482 if(m_model)
483 483 {
484 disconnect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0, 0);
485 disconnect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), 0, 0);
486 disconnect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), 0, 0);
484 disconnect(m_model, 0, this, 0);
485 m_mapValues = -1;
486 m_mapLabels = -1;
487 m_mapOrientation = Qt::Vertical;
487 488 }
488 489
489 // set new model if not NULL and connect necessary signals from it
490 // set new model
490 491 if(model)
491 492 {
492 493 m_model = model;
493 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
494 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
495 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
496 }
497
498 494 return true;
499 495 }
496 else
497 {
498 m_model = NULL;
499 return false;
500 }
501 }
500 502
501 503 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
502 504 {
505 if (m_model == NULL)
506 return;
503 507 m_mapValues = modelValuesLine;
504 508 m_mapLabels = modelLabelsLine;
505 509 m_mapOrientation = orientation;
506 510
507 if (m_model == NULL)
508 return;
511 // connect the signals
512 if (m_mapOrientation == Qt::Vertical)
513 {
514 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
515 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
516 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
517 }
518 else
519 {
520 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
521 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
522 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
523 }
509 524
525 // create the initial slices set
510 526 if (m_mapOrientation == Qt::Vertical)
511 527 for (int i = 0; i < m_model->rowCount(); i++)
512 528 add(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
513 529 else
514 530 for (int i = 0; i < m_model->columnCount(); i++)
515 531 add(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
516 532
517 533
518 534 }
519 535
520 536 void QPieSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
521 537 {
522 538 Q_UNUSED(bottomRight)
523 539
524 540 if (m_mapOrientation == Qt::Vertical)
525 541 {
526 542 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
527 543 if (topLeft.column() == m_mapValues)
528 544 slices().at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
529 545 else if (topLeft.column() == m_mapLabels)
530 546 slices().at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
531 547 }
532 548 else
533 549 {
534 550 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
535 if (topLeft.column() == m_mapValues)
551 if (topLeft.row() == m_mapValues)
536 552 slices().at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
537 else if (topLeft.column() == m_mapLabels)
553 else if (topLeft.row() == m_mapLabels)
538 554 slices().at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
539 555 }
540 556 }
541 557
542 558 void QPieSeries::modelDataAdded(QModelIndex parent, int start, int end)
543 559 {
544 560 Q_UNUSED(parent)
545 561 Q_UNUSED(end)
546 562
547 563 QPieSlice* newSlice = new QPieSlice;
548 564 newSlice->setLabelVisible(true);
549 565 if (m_mapOrientation == Qt::Vertical)
550 566 {
551 567 newSlice->setValue(m_model->data(m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
552 568 newSlice->setLabel(m_model->data(m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
553 569 }
554 570 else
555 571 {
556 572 newSlice->setValue(m_model->data(m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
557 573 newSlice->setLabel(m_model->data(m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
558 574 }
559 575
560 576 insert(start, newSlice);
561 577 }
562 578
563 579 void QPieSeries::modelDataRemoved(QModelIndex parent, int start, int end)
564 580 {
565 581 Q_UNUSED(parent)
566 582 Q_UNUSED(end)
567 583 remove(slices().at(start));
568 584 }
569 585
570 586 #include "moc_qpieseries.cpp"
571 587
572 588 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,333 +1,361
1 1 #include "qxyseries.h"
2 2
3 3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 /*!
6 6 \class QXYSeries
7 7 \brief The QXYSeries class is a base class for line, spline and scatter series.
8 8 */
9 9
10 10 /*!
11 11 \fn QPen QXYSeries::pen() const
12 12 \brief Returns pen used to draw points for series.
13 13 \sa setPen()
14 14 */
15 15
16 16 /*!
17 17 \fn QBrush QXYSeries::brush() const
18 18 \brief Returns brush used to draw points for series.
19 19 \sa setBrush()
20 20 */
21 21
22 22 /*!
23 23 \fn void QXYSeries::clicked(const QPointF& point)
24 24 \brief Signal is emitted when user clicks the \a point on chart.
25 25 */
26 26
27 27 /*!
28 28 \fn void QXYSeries::pointReplaced(int index)
29 29 \brief \internal \a index
30 30 */
31 31
32 32 /*!
33 33 \fn void QXYSeries::pointAdded(int index)
34 34 \brief \internal \a index
35 35 */
36 36
37 37 /*!
38 38 \fn void QXYSeries::pointRemoved(int index)
39 39 \brief \internal \a index
40 40 */
41 41
42 42 /*!
43 43 \fn void QXYSeries::updated()
44 44 \brief \internal
45 45 */
46 46
47 47 /*!
48 48 Constructs empty series object which is a child of \a parent.
49 49 When series object is added to QChartView or QChart instance ownerships is transfered.
50 50 */
51 51 QXYSeries::QXYSeries(QObject* parent):QSeries(parent)
52 52 {
53 53 m_mapX = -1;
54 54 m_mapY = -1;
55 55 m_mapOrientation = Qt::Vertical;
56 56 // m_mapYOrientation = Qt::Vertical;
57 57 }
58 58 /*!
59 59 Destroys the object. Series added to QChartView or QChart instances are owned by those,
60 60 and are deleted when mentioned object are destroyed.
61 61 */
62 62 QXYSeries::~QXYSeries()
63 63 {
64 64 }
65 65
66 66 /*!
67 67 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
68 68 */
69 69 void QXYSeries::add(qreal x,qreal y)
70 70 {
71 71 Q_ASSERT(m_x.size() == m_y.size());
72 72 m_x<<x;
73 73 m_y<<y;
74 74 emit pointAdded(m_x.size()-1);
75 75 }
76 76
77 77 /*!
78 78 This is an overloaded function.
79 79 Adds data \a point to the series. Points are connected with lines on the chart.
80 80 */
81 81 void QXYSeries::add(const QPointF& point)
82 82 {
83 83 add(point.x(),point.y());
84 84 }
85 85
86 86 /*!
87 87 This is an overloaded function.
88 88 Adds list of data \a points to the series. Points are connected with lines on the chart.
89 89 */
90 90 void QXYSeries::add(const QList<QPointF> points)
91 91 {
92 92 foreach(const QPointF& point , points) {
93 93 add(point.x(),point.y());
94 94 }
95 95 }
96 96
97 97 /*!
98 98 Modifies \a y value for given \a x a value.
99 99 */
100 100 void QXYSeries::replace(qreal x,qreal y)
101 101 {
102 102 int index = m_x.indexOf(x);
103 103 m_x[index]=x;
104 104 m_y[index]=y;
105 105 emit pointReplaced(index);
106 106 }
107 107
108 108 /*!
109 109 This is an overloaded function.
110 110 Replaces current y value of for given \a point x value with \a point y value.
111 111 */
112 112 void QXYSeries::replace(const QPointF& point)
113 113 {
114 114 replace(point.x(),point.y());
115 115 }
116 116
117 117 /*!
118 118 Removes first \a x value and related y value.
119 119 */
120 120 void QXYSeries::remove(qreal x)
121 121 {
122 122 int index = m_x.indexOf(x);
123 123
124 124 if(index==-1) return;
125 125
126 126 m_x.remove(index);
127 127 m_y.remove(index);
128 128
129 129 emit pointRemoved(index);
130 130 }
131 131
132 132 /*!
133 133 Removes current \a x and \a y value.
134 134 */
135 135 void QXYSeries::remove(qreal x,qreal y)
136 136 {
137 137 int index =-1;
138 138 do{
139 139 index = m_x.indexOf(x,index+1);
140 140 }while(index !=-1 && m_y.at(index)!=y);
141 141
142 142 if(index==-1) return;
143 143
144 144 m_x.remove(index);
145 145 m_y.remove(index);
146 146 emit pointRemoved(index);
147 147 }
148 148
149 149 /*!
150 150 Removes current \a point x value. Note \a point y value is ignored.
151 151 */
152 152 void QXYSeries::remove(const QPointF& point)
153 153 {
154 154 remove(point.x(),point.y());
155 155 }
156 156
157 157 /*!
158 158 Removes all data points from the series.
159 159 */
160 160 void QXYSeries::removeAll()
161 161 {
162 162 m_x.clear();
163 163 m_y.clear();
164 164 }
165 165
166 166 /*!
167 167 \internal \a pos
168 168 */
169 169 qreal QXYSeries::x(int pos) const
170 170 {
171 171 if (m_model)
172 172 if (m_mapOrientation == Qt::Vertical)
173 173 // consecutive data is read from model's column
174 174 return m_model->data(m_model->index(pos, m_mapX), Qt::DisplayRole).toDouble();
175 175 else
176 176 // consecutive data is read from model's row
177 177 return m_model->data(m_model->index(m_mapX, pos), Qt::DisplayRole).toDouble();
178 178 else
179 179 // model is not specified, return the data from series' internal data store
180 180 return m_x.at(pos);
181 181 }
182 182
183 183 /*!
184 184 \internal \a pos
185 185 */
186 186 qreal QXYSeries::y(int pos) const
187 187 {
188 188 if (m_model)
189 189 if (m_mapOrientation == Qt::Vertical)
190 190 // consecutive data is read from model's column
191 191 return m_model->data(m_model->index(pos, m_mapY), Qt::DisplayRole).toDouble();
192 192 else
193 193 // consecutive data is read from model's row
194 194 return m_model->data(m_model->index(m_mapY, pos), Qt::DisplayRole).toDouble();
195 195 else
196 196 // model is not specified, return the data from series' internal data store
197 197 return m_y.at(pos);
198 198 }
199 199
200 200 /*!
201 201 Returns number of data points within series.
202 202 */
203 203 int QXYSeries::count() const
204 204 {
205 205 Q_ASSERT(m_x.size() == m_y.size());
206 206
207 207 if (m_model) {
208 208 if (m_mapOrientation == Qt::Vertical)
209 209 // data is in a column, so return the number of items in single column
210 210 return m_model->rowCount();
211 211 else
212 212 // data is in a row, so return the number of items in single row
213 213 return m_model->columnCount();
214 214 }
215 215
216 216 // model is not specified, return the number of points in the series internal data store
217 217 return m_x.size();
218 218 }
219 219
220 220 /*!
221 221 Returns the data points of the series.
222 222 */
223 223 QList<QPointF> QXYSeries::data()
224 224 {
225 225 QList<QPointF> data;
226 226 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
227 227 data.append(QPointF(m_x.at(i), m_y.at(i)));
228 228 return data;
229 229 }
230 230
231 231
232 232 /*!
233 233 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
234 234 pen from chart theme is used.
235 235 \sa QChart::setChartTheme()
236 236 */
237 237 void QXYSeries::setPen(const QPen& pen)
238 238 {
239 239 if(pen!=m_pen){
240 240 m_pen=pen;
241 241 emit updated();
242 242 }
243 243 }
244 244
245 245 /*!
246 246 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
247 247 from chart theme setting is used.
248 248 \sa QChart::setChartTheme()
249 249 */
250 250
251 251 void QXYSeries::setBrush(const QBrush& brush)
252 252 {
253 253 if(brush!=m_brush){
254 254 m_brush=brush;
255 255 emit updated();
256 256 }
257 257 }
258 258
259 259
260 260 /*!
261 261 Stream operator for adding a data \a point to the series.
262 262 \sa add()
263 263 */
264 264
265 265 QXYSeries& QXYSeries::operator<< (const QPointF &point)
266 266 {
267 267 add(point);
268 268 return *this;
269 269 }
270 270
271 271
272 272 /*!
273 273 Stream operator for adding a list of \a points to the series.
274 274 \sa add()
275 275 */
276 276
277 277 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
278 278 {
279 279 add(points);
280 280 return *this;
281 281 }
282 282
283 283
284 284 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
285 285 {
286 286 Q_UNUSED(bottomRight)
287 287
288 288 if (m_mapOrientation == Qt::Vertical)
289 289 emit pointReplaced(topLeft.row());
290 290 else
291 291 emit pointReplaced(topLeft.column());
292 292 }
293 293
294 294 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
295 295 {
296 296 Q_UNUSED(parent)
297 297 Q_UNUSED(end)
298 298 emit pointAdded(start);
299 299 }
300 300
301 301 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
302 302 {
303 303 Q_UNUSED(parent)
304 304 Q_UNUSED(end)
305 305 emit pointRemoved(start);
306 306 }
307 307
308 308 bool QXYSeries::setModel(QAbstractItemModel* model) {
309
310 // disconnect signals from old model
311 if(m_model)
312 {
313 disconnect(m_model, 0, this, 0);
314 m_mapX = -1;
315 m_mapY = -1;
316 m_mapOrientation = Qt::Vertical;
317 }
318
319 // set new model
320 if(model)
321 {
309 322 m_model = model;
310 // for (int i = 0; i < m_model->rowCount(); i++)
311 // emit pointAdded(i);
312 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
313 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
314 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
315 323 return true;
316 324 }
325 else
326 {
327 m_model = NULL;
328 return false;
329 }
330 }
317 331
318 332 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
319 333 {
334 if (m_model == NULL)
335 return;
320 336 m_mapX = modelX;
321 337 m_mapY = modelY;
322 338 m_mapOrientation = orientation;
339 if (m_mapOrientation == Qt::Vertical)
340 {
341 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
342 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
343 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
344 }
345 else
346 {
347 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
348 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
349 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
350 }
323 351 }
324 352
325 353 //void QXYSeries::setModelMappingY(int modelLineIndex, Qt::Orientation orientation)
326 354 //{
327 355 // m_mapY = modelLineIndex;
328 356 // m_mapYOrientation = orientation;
329 357 //}
330 358
331 359 #include "moc_qxyseries.cpp"
332 360
333 361 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now