##// END OF EJS Templates
QXYSeries: model data orientation added. QBarSeries: some model data function placeholders
Marek Rosa -
r527:b700a12da54b
parent child
Show More
@@ -1,123 +1,126
1 1 #include "customtablemodel.h"
2 2
3 3 CustomTableModel::CustomTableModel(QObject *parent) :
4 4 QAbstractTableModel(parent)
5 5 {
6 6 m_points.append(QPointF(10, 50));
7 7 m_labels.append("Apples");
8 8 m_points.append(QPointF(60, 70));
9 9 m_labels.append("Oranges");
10 10 m_points.append(QPointF(110, 50));
11 11 m_labels.append("Bananas");
12 12 m_points.append(QPointF(140, 40));
13 13 m_labels.append("Lemons");
14 14 m_points.append(QPointF(200, 150));
15 15 m_labels.append("Plums");
16 m_points.append(QPointF(225, 75));
17 m_labels.append("Pearls");
16 18 }
17 19
18 20 int CustomTableModel::rowCount(const QModelIndex & parent) const
19 21 {
20 22 return m_points.count();
21 23 }
22 24
23 25 int CustomTableModel::columnCount(const QModelIndex & parent) const
24 26 {
25 return 3;
27 return 2;
26 28 }
27 29
28 30 QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation, int role ) const
29 31 {
30 32 if (role != Qt::DisplayRole)
31 33 return QVariant();
32 34
33 35 if (orientation == Qt::Horizontal)
34 36 {
35 37 switch(section)
36 38 {
37 39 case 0:
38 40 return "x";
39 41 case 1:
40 42 return "y";
41 43 case 2:
42 44 return "Fruit";
43 default: "What?";
45 default:
46 return "What?";
44 47 }
45 48 }
46 49 else
47 50 return QString("%1").arg(section + 1);
48 51 }
49 52
50 53 QVariant CustomTableModel::data(const QModelIndex & index, int role) const
51 54 {
52 55 if (role == Qt::DisplayRole)
53 56 {
54 57 switch(index.column())
55 58 {
56 59 case 0:
57 60 return m_points[index.row()].x();
58 61 case 1:
59 62 return m_points[index.row()].y();
60 63 case 2:
61 64 return m_labels[index.row()];
62 65 default:
63 66 return QVariant();
64 67 }
65 68 }
66 69 else if (role == Qt::EditRole)
67 70 {
68 71 switch(index.column())
69 72 {
70 73 case 0:
71 74 return m_points[index.row()].x();
72 75 case 1:
73 76 return m_points[index.row()].y();
74 77 case 2:
75 78 return m_labels[index.row()];
76 79 default:
77 80 return QVariant();
78 81 }
79 82 }
80 83 }
81 84
82 85 bool CustomTableModel::setData ( const QModelIndex & index, const QVariant & value, int role)
83 86 {
84 87 if (index.isValid() && role == Qt::EditRole)
85 88 {
86 89 switch(index.column())
87 90 {
88 91 case 0:
89 92 m_points[index.row()].setX(value.toDouble());
90 93 break;
91 94 case 1:
92 95 m_points[index.row()].setY(value.toDouble());
93 96 break;
94 97 case 2:
95 98 m_labels.replace(index.row(), value.toString());
96 99 break;
97 100 default:
98 101 return false;
99 102 }
100 103 emit dataChanged(index, index);
101 104 return true;
102 105 }
103 106 return false;
104 107 }
105 108
106 109 Qt::ItemFlags CustomTableModel::flags ( const QModelIndex & index ) const
107 110 {
108 if (!index.isValid())
109 return Qt::ItemIsEnabled;
111 // if (!index.isValid())
112 // return Qt::ItemIsEnabled;
110 113 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
111 114 }
112 115
113 116 bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & parent)
114 117 {
115 118 beginInsertRows(QModelIndex(), row /*dataTable.count()*/, row + count - 1);
116 119 for (int i = 0; i < count; i++)
117 120 {
118 121 m_points.append(QPointF());
119 122 m_labels.append("");
120 123 }
121 124 endInsertRows();
122 125 return true;
123 126 }
@@ -1,54 +1,54
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 "customtablemodel.h"
8 8 #include "qpieseries.h"
9 9
10 10 TableWidget::TableWidget(QWidget *parent)
11 11 : QWidget(parent)
12 12 {
13 13
14 14
15 15 // create simple model for storing data
16 16 // user's table data model
17 17 CustomTableModel* model = new CustomTableModel;
18 18 QTableView* tableView = new QTableView;
19 19 tableView->setModel(model);
20 20 tableView->setMinimumSize(340, 480);
21 21 // tableView->setItemDelegate(new QStyledItemDelegate);
22 22 chartView = new QChartView;
23 23 chartView->setMinimumSize(640, 480);
24 24
25 25 // create
26 26 // QLineSeries* series = new QLineSeries;
27 27 QSplineSeries* series = new QSplineSeries;
28 28 series->setModel(model);
29 series->setModelMappingX(0);
30 series->setModelMappingY(1);
29 series->setModelMapping(0,1, Qt::Vertical);
30 // series->setModelMappingY(1);
31 31
32 32 // series->add(QPointF(150, 100));
33 33 // series->add(QPointF(200, 130));
34 34 // series->add(QPointF(250, 120));
35 35 // series->add(QPointF(300, 140));
36 36 // series->add(QPointF(350, 160));
37 37
38 38 // QPieSeries* pieSeries = new QPieSeries;
39 39 // pieSeries->setModel(model);
40 40 // pieSeries
41 41
42 42 chartView->addSeries(series);
43 43
44 44 // create main layout
45 45 QGridLayout* mainLayout = new QGridLayout;
46 46 mainLayout->addWidget(tableView, 1, 1);
47 47 mainLayout->addWidget(chartView, 1, 2);
48 48 setLayout(mainLayout);
49 49 }
50 50
51 51 TableWidget::~TableWidget()
52 52 {
53 53
54 54 }
@@ -1,227 +1,245
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 }
41 41
42 42 /*!
43 43 Adds a set of bars to series. Takes ownership of \a set.
44 44 Connects the clicked(QString) and rightClicked(QString) signals
45 45 of \a set to this series
46 46 */
47 47 void QBarSeries::addBarSet(QBarSet *set)
48 48 {
49 49 mModel->addBarSet(set);
50 50 connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
51 51 connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
52 52 }
53 53
54 54 /*!
55 55 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
56 56 Disconnects the clicked(QString) and rightClicked(QString) signals
57 57 of \a set from this series
58 58 */
59 59 void QBarSeries::removeBarSet(QBarSet *set)
60 60 {
61 61 disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
62 62 disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
63 63 mModel->removeBarSet(set);
64 64 }
65 65
66 66 /*!
67 67 Returns number of sets in series.
68 68 */
69 69 int QBarSeries::barsetCount()
70 70 {
71 return mModel->barsetCount();
71 if(m_model)
72 return m_mapBarTop - m_mapBarBottom;
73 else
74 return mModel->barsetCount();
72 75 }
73 76
74 77 /*!
75 78 Returns number of categories in series
76 79 */
77 80 int QBarSeries::categoryCount()
78 81 {
79 82 return mModel->categoryCount();
80 83 }
81 84
82 85 /*!
83 86 Returns a list of sets in series. Keeps ownership of sets.
84 87 */
85 88 QList<QBarSet*> QBarSeries::barSets()
86 89 {
87 90 return mModel->barSets();
88 91 }
89 92
90 93 /*!
91 94 \internal \a index
92 95 */
93 96 QBarSet* QBarSeries::barsetAt(int index)
94 97 {
95 98 return mModel->setAt(index);
96 99 }
97 100
98 101 /*!
99 102 Returns legend of series.
100 103 */
101 104 QList<QSeries::LegendEntry> QBarSeries::legendEntries()
102 105 {
103 106 return mModel->legendEntries();
104 107 }
105 108
106 109 /*!
107 110 \internal \a category
108 111 */
109 112 QString QBarSeries::categoryName(int category)
110 113 {
111 114 return mModel->categoryName(category);
112 115 }
113 116
114 117 /*!
115 118 Enables or disables tooltip depending on parameter \a enabled.
116 119 Tooltip shows the name of set, when mouse is hovering on top of bar.
117 120 Calling without parameter \a enabled, enables the tooltip
118 121 */
119 122 void QBarSeries::setToolTipEnabled(bool enabled)
120 123 {
121 124 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
122 125 if (enabled) {
123 126 for (int i=0; i<mModel->barsetCount(); i++) {
124 127 QBarSet *set = mModel->setAt(i);
125 128 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
126 129 }
127 130 } else {
128 131 for (int i=0; i<mModel->barsetCount(); i++) {
129 132 QBarSet *set = mModel->setAt(i);
130 133 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
131 134 }
132 135 }
133 136 }
134 137
135 138 /*!
136 139 Enables or disables separators depending on parameter \a enabled.
137 140 Separators are visual elements that are drawn between categories.
138 141 Calling without parameter \a enabled, enables the separators
139 142 */
140 143 void QBarSeries::setSeparatorsVisible(bool visible)
141 144 {
142 145 mSeparatorsVisible = visible;
143 146 emit enableSeparators(visible);
144 147 }
145 148
146 149
147 150 /*!
148 151 \internal \a category
149 152 */
150 153 void QBarSeries::barsetClicked(QString category)
151 154 {
152 155 emit clicked(qobject_cast<QBarSet*>(sender()), category);
153 156 }
154 157
155 158 /*!
156 159 \internal \a category
157 160 */
158 161 void QBarSeries::barsetRightClicked(QString category)
159 162 {
160 163 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
161 164 }
162 165
163 166
164 167 /*!
165 168 \internal
166 169 */
167 170 qreal QBarSeries::min()
168 171 {
169 172 return mModel->min();
170 173 }
171 174
172 175 /*!
173 176 \internal
174 177 */
175 178 qreal QBarSeries::max()
176 179 {
177 180 return mModel->max();
178 181 }
179 182
180 183 /*!
181 184 \internal \a set \a category
182 185 */
183 186 qreal QBarSeries::valueAt(int set, int category)
184 187 {
185 188 return mModel->valueAt(set,category);
186 189 }
187 190
188 191 /*!
189 192 \internal \a set \a category
190 193 */
191 194 qreal QBarSeries::percentageAt(int set, int category)
192 195 {
193 196 return mModel->percentageAt(set,category);
194 197 }
195 198
196 199 /*!
197 200 \internal \a category
198 201 */
199 202 qreal QBarSeries::categorySum(int category)
200 203 {
201 204 return mModel->categorySum(category);
202 205 }
203 206
204 207 /*!
205 208 \internal
206 209 */
207 210 qreal QBarSeries::maxCategorySum()
208 211 {
209 212 return mModel->maxCategorySum();
210 213 }
211 214
212 215 /*!
213 216 \internal
214 217 */
215 218 BarChartModel& QBarSeries::model()
216 219 {
217 220 return *mModel;
218 221 }
219 222
220 223 bool QBarSeries::separatorsVisible()
221 224 {
222 225 return mSeparatorsVisible;
223 226 }
224 227
228 bool QBarSeries::setModel(QAbstractItemModel* model)
229 {
230 m_model = model;
231 }
232
233 void QBarSeries::setModelMappingCategories(int modelColumn)
234 {
235 //
236 }
237
238 void QBarSeries::setModelMappingBarRange(int bottomBoundry, int topBoundry)
239 {
240 //
241 }
242
225 243 #include "moc_qbarseries.cpp"
226 244
227 245 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,72 +1,82
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 QList<QSeries::LegendEntry> legendEntries();
28 28
29 bool setModel(QAbstractItemModel* model);
30 QAbstractItemModel* modelExt() {return m_model;}
31 void setModelMappingCategories(int modelColumn);
32 void setModelMappingBarRange(int bottomBoundry, int topBoundry);
33
29 34 public:
30 35 // TODO: Functions below this are not part of api and will be moved
31 36 // to private implementation, when we start using it
32 37 // TODO: TO PIMPL --->
33 38 QBarSet* barsetAt(int index);
34 39 QString categoryName(int category);
35 40 qreal min();
36 41 qreal max();
37 42 qreal valueAt(int set, int category);
38 43 qreal percentageAt(int set, int category);
39 44 qreal categorySum(int category);
40 45 qreal maxCategorySum();
41 46 BarChartModel& model();
42 47 bool separatorsVisible();
43 48 // <--- TO PIMPL
44 49
45 50 signals:
46 51 //void changed(int index);
47 52 void clicked(QBarSet* barset, QString category); // Up to user of api, what to do with these signals
48 53 void rightClicked(QBarSet* barset, QString category);
49 54
50 55 // TODO: internal signals, these to private implementation.
51 56 // TODO: TO PIMPL --->
52 57 void enableSeparators(bool enable);
53 58 void showToolTip(QPoint pos, QString tip);
54 59 // <--- TO PIMPL
55 60
56 61 public Q_SLOTS:
57 62 void setToolTipEnabled(bool enabled=true); // enables tooltips
58 63 void setSeparatorsVisible(bool visible=true); // enables separators between categories
59 64
60 65 // TODO: TO PIMPL --->
61 66 void barsetClicked(QString category);
62 67 void barsetRightClicked(QString category);
63 68 // <--- TO PIMPL
64 69
65 70 protected:
66 71 BarChartModel* mModel;
67 72 bool mSeparatorsVisible;
73
74 QAbstractItemModel* m_model;
75 int m_mapCategories;
76 int m_mapBarBottom;
77 int m_mapBarTop;
68 78 };
69 79
70 80 QTCOMMERCIALCHART_END_NAMESPACE
71 81
72 82 #endif // BARSERIES_H
@@ -1,148 +1,154
1 1 #include "qsplineseries.h"
2 2
3 3 /*!
4 4 \class QSplineSeries
5 5 \brief Series type used to store data needed to draw a spline.
6 6
7 7 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
8 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 12 \fn QSeriesType QSplineSeries::type() const
13 13 Returns the type of the series
14 14 */
15 15
16 16 /*!
17 17 \fn QSeriesType QSplineSeries::controlPoint(int index) const
18 18 Returns the control point specified by \a index
19 19 */
20 20
21 21 QTCOMMERCIALCHART_BEGIN_NAMESPACE
22 22
23 23 /*!
24 24 Constructs empty series object which is a child of \a parent.
25 25 When series object is added to QChartView or QChart instance then the ownerships is transfered.
26 26 */
27 27
28 28 QSplineSeries::QSplineSeries(QObject *parent) :
29 29 QLineSeries(parent)
30 30 {
31 31 connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
32 32 connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
33 33 connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
34 34 }
35 35
36 36 /*!
37 37 \internal
38 38 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
39 39 */
40 40 void QSplineSeries::calculateControlPoints()
41 41 {
42 42
43 43 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
44 44 // CPOL License
45 45
46 46 int n = count() - 1;
47 47 if (n == 1)
48 48 { // Special case: Bezier curve should be a straight line.
49 49 // firstControlPoints = new Point[1];
50 50 // 3P1 = 2P0 + P3
51 51 m_controlPoints.append(QPointF((2 * x(0) + x(1)) / 3, (2 * y(0) + y(1)) / 3));
52 52
53 53 // P2 = 2P1 P0
54 54 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - x(0), 2 * m_controlPoints[0].y() - y(0)));
55 55 return;
56 56 }
57 57
58 58 // Calculate first Bezier control points
59 59 // Right hand side vector
60 60 // Set of equations for P0 to Pn points.
61 61 //
62 62 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
63 63 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
64 64 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
65 65 // | . . . . . . . . . . . . | | ... | | ... |
66 66 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
67 67 // | . . . . . . . . . . . . | | ... | | ... |
68 68 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
69 69 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
70 70 //
71 71 QList<qreal> rhs;
72 72 rhs.append(x(0) + 2 * x(1));
73 73
74 74 // Set right hand side X values
75 75 for (int i = 1; i < n - 1; ++i)
76 76 rhs.append(4 * x(i) + 2 * x(i + 1));
77 77
78 78 rhs.append((8 * x(n - 1) + x(n)) / 2.0);
79 79 // Get first control points X-values
80 80 QList<qreal> xControl = getFirstControlPoints(rhs);
81 81 rhs[0] = y(0) + 2 * y(1);
82 82
83 83 // Set right hand side Y values
84 84 for (int i = 1; i < n - 1; ++i)
85 85 rhs[i] = 4 * y(i) + 2 * y(i + 1);
86 86
87 87 rhs[n - 1] = (8 * y(n - 1) + y(n)) / 2.0;
88 88 // Get first control points Y-values
89 89 QList<qreal> yControl = getFirstControlPoints(rhs);
90 90
91 91 // Fill output arrays.
92 92 for (int i = 0; i < n; ++i)
93 93 {
94 94 // First control point
95 95 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
96 96 // Second control point
97 97 if (i < n - 1)
98 98 m_controlPoints.append(QPointF(2 * x(i + 1) - xControl[i + 1], 2 * y(i + 1) - yControl[i + 1]));
99 99 else
100 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 105 \internal
106 106 */
107 107 QList<qreal> QSplineSeries::getFirstControlPoints(QList<qreal> rhs)
108 108 {
109 109 QList<qreal> x; // Solution vector.
110 110 QList<qreal> tmp; // Temp workspace.
111 111
112 112 qreal b = 2.0;
113 113 x.append(rhs[0] / b);
114 114 tmp.append(0);
115 115 for (int i = 1; i < rhs.size(); i++) // Decomposition and forward substitution.
116 116 {
117 117 tmp.append(1 / b);
118 118 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
119 119 x.append((rhs[i] - x[i - 1]) / b);
120 120 }
121 121 for (int i = 1; i < rhs.size(); i++)
122 122 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
123 123
124 124 return x;
125 125 }
126 126
127 127 /*!
128 128 \internal
129 129 Updates the control points, besed on currently avaiable knots.
130 130 */
131 131 void QSplineSeries::updateControlPoints()
132 132 {
133 133 if(count() > 1)
134 134 {
135 135 m_controlPoints.clear();
136 136 calculateControlPoints();
137 137 }
138 138 }
139 139
140 140 bool QSplineSeries::setModel(QAbstractItemModel* model)
141 141 {
142 142 QXYSeries::setModel(model);
143 // calculateControlPoints();
144 }
145
146 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
147 {
148 QLineSeries::setModelMapping(modelX, modelY, orientation);
143 149 calculateControlPoints();
144 150 }
145 151
146 152 #include "moc_qsplineseries.cpp"
147 153
148 154 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,44 +1,46
1 1 #ifndef QSPLINESERIES_H
2 2 #define QSPLINESERIES_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include <QtGlobal>
6 6 #include "qlineseries.h"
7 7 #include <QList>
8 8 #include <QPointF>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 class QTCOMMERCIALCHART_EXPORT QSplineSeries : public QLineSeries
13 13 {
14 14 Q_OBJECT
15 15 public:
16 16
17 17 QSplineSeries(QObject *parent = 0);
18 18 QSeriesType type() const {return QSeries::SeriesTypeSpline;}
19 19
20 20 // int count() const { return m_x.size(); }
21 21 QPointF controlPoint(int index) const {return m_controlPoints[index];}
22 22 bool setModel(QAbstractItemModel* model);
23 23
24 void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
25
24 26 // TODO: allow the user to set custom control points
25 27 // void setCustomControlPoints(QList<QPointsF> controlPoints);
26 28 // bool calculateControlPointsAutomatically();
27 29 // void setCalculateControlPointsAutomatically();
28 30
29 31
30 32 private:
31 33 void calculateControlPoints();
32 34 QList<qreal> getFirstControlPoints(QList<qreal> rhs);
33 35
34 36 private slots:
35 37 void updateControlPoints();
36 38
37 39 private:
38 40 QList<QPointF> m_controlPoints;
39 41
40 42 };
41 43
42 44 QTCOMMERCIALCHART_END_NAMESPACE
43 45
44 46 #endif // QSPLINESERIES_H
@@ -1,254 +1,286
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::pointReplaced(int index)
24 24 \brief \internal \a index
25 25 */
26 26
27 27 /*!
28 28 \fn void QXYSeries::pointAdded(int index)
29 29 \brief \internal \a index
30 30 */
31 31
32 32 /*!
33 33 \fn void QXYSeries::pointRemoved(int index)
34 34 \brief \internal \a index
35 35 */
36 36
37 37 /*!
38 38 \fn void QXYSeries::updated()
39 39 \brief \internal
40 40 */
41 41
42 42 /*!
43 43 Constructs empty series object which is a child of \a parent.
44 44 When series object is added to QChartView or QChart instance ownerships is transfered.
45 45 */
46 46 QXYSeries::QXYSeries(QObject* parent):QSeries(parent)
47 47 {
48 m_model = 0;
49 m_mapX = 0;
50 m_mapY = 1;
48 m_model = NULL;
49 m_mapX = -1;
50 m_mapY = -1;
51 m_mapOrientation = Qt::Vertical;
52 // m_mapYOrientation = Qt::Vertical;
51 53 }
52 54 /*!
53 55 Destroys the object. Series added to QChartView or QChart instances are owned by those,
54 56 and are deleted when mentioned object are destroyed.
55 57 */
56 58 QXYSeries::~QXYSeries()
57 59 {
58 60 }
59 61
60 62 /*!
61 63 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
62 64 */
63 65 void QXYSeries::add(qreal x,qreal y)
64 66 {
65 67 Q_ASSERT(m_x.size() == m_y.size());
66 68 m_x<<x;
67 69 m_y<<y;
68 70 emit pointAdded(m_x.size()-1);
69 71 }
70 72
71 73 /*!
72 74 This is an overloaded function.
73 75 Adds data \a point to the series. Points are connected with lines on the chart.
74 76 */
75 77 void QXYSeries::add(const QPointF& point)
76 78 {
77 79 add(point.x(),point.y());
78 80 }
79 81
80 82 /*!
81 83 This is an overloaded function.
82 84 Adds list of data \a points to the series. Points are connected with lines on the chart.
83 85 */
84 86 void QXYSeries::add(const QList<QPointF> points)
85 87 {
86 88 foreach(const QPointF& point , points) {
87 89 add(point.x(),point.y());
88 90 }
89 91 }
90 92
91 93 /*!
92 94 Modifies \a y value for given \a x a value.
93 95 */
94 96 void QXYSeries::replace(qreal x,qreal y)
95 97 {
96 98 int index = m_x.indexOf(x);
97 99 m_x[index]=x;
98 100 m_y[index]=y;
99 101 emit pointReplaced(index);
100 102 }
101 103
102 104 /*!
103 105 This is an overloaded function.
104 106 Replaces current y value of for given \a point x value with \a point y value.
105 107 */
106 108 void QXYSeries::replace(const QPointF& point)
107 109 {
108 110 replace(point.x(),point.y());
109 111 }
110 112
111 113 /*!
112 114 Removes current \a x and y value.
113 115 */
114 116 void QXYSeries::remove(qreal x)
115 117 {
116 118 int index = m_x.indexOf(x);
117 119 emit pointRemoved(index);
118 120 m_x.remove(index);
119 121 m_y.remove(index);
120 122 }
121 123
122 124 /*!
123 125 Removes current \a point x value. Note \a point y value is ignored.
124 126 */
125 127 void QXYSeries::remove(const QPointF& point)
126 128 {
127 129 remove(point.x());
128 130 }
129 131
130 132 /*!
131 133 Removes all data points from the series.
132 134 */
133 135 void QXYSeries::removeAll()
134 136 {
135 137 m_x.clear();
136 138 m_y.clear();
137 139 }
138 140
139 141 /*!
140 142 \internal \a pos
141 143 */
142 144 qreal QXYSeries::x(int pos) const
143 145 {
144 146 if (m_model)
145 return m_model->data(m_model->index(pos, m_mapX), Qt::DisplayRole).toDouble();
147 if (m_mapOrientation == Qt::Vertical)
148 // consecutive data is read from model's column
149 return m_model->data(m_model->index(pos, m_mapX), Qt::DisplayRole).toDouble();
150 else
151 // consecutive data is read from model's row
152 return m_model->data(m_model->index(m_mapX, pos), Qt::DisplayRole).toDouble();
146 153 else
154 // model is not specified, return the data from series' internal data store
147 155 return m_x.at(pos);
148 156 }
149 157
150 158 /*!
151 159 \internal \a pos
152 160 */
153 161 qreal QXYSeries::y(int pos) const
154 162 {
155 163 if (m_model)
156 return m_model->data(m_model->index(pos, m_mapY), Qt::DisplayRole).toDouble();
164 if (m_mapOrientation == Qt::Vertical)
165 // consecutive data is read from model's column
166 return m_model->data(m_model->index(pos, m_mapY), Qt::DisplayRole).toDouble();
167 else
168 // consecutive data is read from model's row
169 return m_model->data(m_model->index(m_mapY, pos), Qt::DisplayRole).toDouble();
157 170 else
171 // model is not specified, return the data from series' internal data store
158 172 return m_y.at(pos);
159 173 }
160 174
161 175 /*!
162 176 Returns number of data points within series.
163 177 */
164 178 int QXYSeries::count() const
165 179 {
166 180 Q_ASSERT(m_x.size() == m_y.size());
167 181
168 // int k = m_model->rowCount();
169 182 if (m_model)
170 return m_model->rowCount();
183 if (m_mapOrientation == Qt::Vertical)
184 // data is in a column, so return the number of items in single column
185 return m_model->rowCount();
186 else
187 // data is in a row, so return the number of items in single row
188 m_model->columnCount();
171 189 else
190 // model is not specified, return the number of points in the series internal data store
172 191 return m_x.size();
173 192 }
174 193
175 194 /*!
176 195 Returns the data points of the series.
177 196 */
178 197 QList<QPointF> QXYSeries::data()
179 198 {
180 199 QList<QPointF> data;
181 200 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
182 201 data.append(QPointF(m_x.at(i), m_y.at(i)));
183 202 return data;
184 203 }
185 204
186 205
187 206 /*!
188 207 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
189 208 pen from chart theme is used.
190 209 \sa QChart::setChartTheme()
191 210 */
192 211 void QXYSeries::setPen(const QPen& pen)
193 212 {
194 213 if(pen!=m_pen){
195 214 m_pen=pen;
196 215 emit updated();
197 216 }
198 217 }
199 218
200 219 /*!
201 220 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
202 221 from chart theme setting is used.
203 222 \sa QChart::setChartTheme()
204 223 */
205 224
206 225 void QXYSeries::setBrush(const QBrush& brush)
207 226 {
208 227 if(brush!=m_brush){
209 228 m_brush=brush;
210 229 emit updated();
211 230 }
212 231 }
213 232
214 233
215 234 /*!
216 235 Stream operator for adding a data \a point to the series.
217 236 \sa add()
218 237 */
219 238
220 239 QXYSeries& QXYSeries::operator<< (const QPointF &point)
221 240 {
222 241 add(point);
223 242 return *this;
224 243 }
225 244
226 245
227 246 /*!
228 247 Stream operator for adding a list of \a points to the series.
229 248 \sa add()
230 249 */
231 250
232 251 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
233 252 {
234 253 add(points);
235 254 return *this;
236 255 }
237 256
238 257
239 258 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
240 259 {
241 260 emit pointReplaced(topLeft.row());
242 261 }
243 262
244 263 bool QXYSeries::setModel(QAbstractItemModel* model) {
245 264 m_model = model;
246 for (int i = 0; i < m_model->rowCount(); i++)
247 emit pointAdded(i);
265 // for (int i = 0; i < m_model->rowCount(); i++)
266 // emit pointAdded(i);
248 267 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
249 // connect(m_model,SIGNAL(), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
268 // connect(m_model,SIGNAL(), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
250 269 }
251 270
271 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
272 {
273 m_mapX = modelX;
274 m_mapY = modelY;
275 m_mapOrientation = orientation;
276 }
277
278 //void QXYSeries::setModelMappingY(int modelLineIndex, Qt::Orientation orientation)
279 //{
280 // m_mapY = modelLineIndex;
281 // m_mapYOrientation = orientation;
282 //}
283
252 284 #include "moc_qxyseries.cpp"
253 285
254 286 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,71 +1,73
1 1 #ifndef QXYSERIES_H_
2 2 #define QXYSERIES_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
12 12 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QSeries
13 13 {
14 14 Q_OBJECT
15 15 protected:
16 16 QXYSeries(QObject* parent=0);
17 17 virtual ~QXYSeries();
18 18
19 19 public:
20 20 void add(qreal x, qreal y);
21 21 void add(const QPointF& point);
22 22 void add(const QList<QPointF> points);
23 23 void replace(qreal x,qreal y);
24 24 void replace(const QPointF& point);
25 25 void remove(qreal x);
26 26 void remove(const QPointF& point);
27 27 void removeAll();
28 28
29 29 int count() const;
30 30 qreal x(int pos) const;
31 31 qreal y(int pos) const;
32 32 QList<QPointF> data();
33 33
34 34 QXYSeries& operator << (const QPointF &point);
35 35 QXYSeries& operator << (const QList<QPointF> points);
36 36
37 37 void setPen(const QPen& pen);
38 38 QPen pen() const {return m_pen;}
39 39 void setBrush(const QBrush& pen);
40 40 QBrush brush() const {return m_brush;}
41 41
42 42 bool setModel(QAbstractItemModel* model);
43 43 QAbstractItemModel* model() {return m_model;}
44 44
45 void setModelMappingX(int modelColumn) {m_mapX = modelColumn;}
46 void setModelMappingY(int modelColumn) {m_mapY = modelColumn;}
45 void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
46 // void setModelMappingY(int modelLineIndex, Qt::Orientation orientation = Qt::Vertical);
47 47
48 48 private slots:
49 49 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
50 50
51 51 signals:
52 52 void updated();
53 53 void pointReplaced(int index);
54 54 void pointRemoved(int index);
55 55 void pointAdded(int index);
56 56
57 57 protected:
58 58 QVector<qreal> m_x;
59 59 QVector<qreal> m_y;
60 60
61 61 QPen m_pen;
62 62 QBrush m_brush;
63 63
64 64 QAbstractItemModel* m_model;
65 65 int m_mapX;
66 Qt::Orientation m_mapOrientation;
66 67 int m_mapY;
68 // Qt::Orientation m_mapYOrientation;
67 69 };
68 70
69 71 QTCOMMERCIALCHART_END_NAMESPACE
70 72
71 73 #endif
@@ -1,142 +1,142
1 1 #include "xychartitem_p.h"
2 2 #include "qxyseries.h"
3 3 #include "chartpresenter_p.h"
4 4 #include <QPainter>
5 5
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 //TODO: optimize : remove points which are not visible
10 10
11 11 XYChartItem::XYChartItem(QXYSeries* series,QGraphicsItem *parent):ChartItem(parent),
12 12 m_minX(0),
13 13 m_maxX(0),
14 14 m_minY(0),
15 15 m_maxY(0),
16 16 m_series(series)
17 17 {
18 18 QObject::connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
19 19 QObject::connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
20 20 QObject::connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
21 21
22 22 }
23 23
24 24 QPointF XYChartItem::calculateGeometryPoint(const QPointF& point) const
25 25 {
26 26 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
27 27 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
28 28 qreal x = (point.x() - m_minX)* deltaX;
29 29 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
30 30 return QPointF(x,y);
31 31 }
32 32
33 33
34 34 QPointF XYChartItem::calculateGeometryPoint(int index) const
35 35 {
36 36 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
37 37 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
38 38 qreal x = (m_series->x(index) - m_minX)* deltaX;
39 39 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
40 40 return QPointF(x,y);
41 41 }
42 42
43 43 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
44 44 {
45 45 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
46 46 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
47 47
48 48 QVector<QPointF> points;
49 49 points.reserve(m_series->count());
50 50 for (int i = 0; i < m_series->count(); ++i) {
51 51 qreal x = (m_series->x(i) - m_minX)* deltaX;
52 52 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
53 53 points << QPointF(x,y);
54 54 }
55 55 return points;
56 56 }
57 57
58 58 void XYChartItem::updatePoints(QVector<QPointF>& points)
59 59 {
60 60 setGeometry(points);
61 61 }
62 62
63 63 void XYChartItem::updatePoint(QVector<QPointF>& points)
64 64 {
65 65 setGeometry(points);
66 66 }
67 67
68 68 void XYChartItem::setGeometry(QVector<QPointF>& points)
69 69 {
70 70 m_points = points;
71 71 }
72 72
73 73 //handlers
74 74
75 75 void XYChartItem::handlePointAdded(int index)
76 76 {
77 77 Q_ASSERT(index<m_series->count());
78 78 Q_ASSERT(index>=0);
79 79
80 80 QPointF point = calculateGeometryPoint(index);
81 81 QVector<QPointF> points = m_points;
82 82 points.insert(index,point);
83 83 updatePoints(points);
84 84 update();
85 85 }
86 86 void XYChartItem::handlePointRemoved(int index)
87 87 {
88 88 Q_ASSERT(index<m_series->count());
89 89 Q_ASSERT(index>=0);
90 90 QPointF point = calculateGeometryPoint(index);
91 91 QVector<QPointF> points = m_points;
92 92 points.remove(index);
93 93 updatePoints(points);
94 94 update();
95 95 }
96 96
97 97 void XYChartItem::handlePointReplaced(int index)
98 98 {
99 99 Q_ASSERT(index<m_series->count());
100 100 Q_ASSERT(index>=0);
101 101 QPointF point = calculateGeometryPoint(index);
102 102 QVector<QPointF> points = m_points;
103 m_points.replace(index,point);
104 updatePoint(m_points);
103 points.replace(index,point);
104 updatePoint(points);
105 105 update();
106 106 }
107 107
108 108 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
109 109 {
110 110 m_minX=minX;
111 111 m_maxX=maxX;
112 112 m_minY=minY;
113 113 m_maxY=maxY;
114 114
115 115 if(isEmpty()) return;
116 116 QVector<QPointF> points = calculateGeometryPoints();
117 117 updatePoints(points);
118 118 update();
119 119 }
120 120
121 121 void XYChartItem::handleGeometryChanged(const QRectF& rect)
122 122 {
123 123 Q_ASSERT(rect.isValid());
124 124 m_size=rect.size();
125 125 m_clipRect=rect.translated(-rect.topLeft());
126 126 setPos(rect.topLeft());
127 127
128 128 if(isEmpty()) return;
129 129 QVector<QPointF> points = calculateGeometryPoints();
130 130 updatePoints(points);
131 131 update();
132 132 }
133 133
134 134
135 135 bool XYChartItem::isEmpty()
136 136 {
137 137 return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ;
138 138 }
139 139
140 140 #include "moc_xychartitem_p.cpp"
141 141
142 142 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now