##// END OF EJS Templates
Refactor animation to fit line,spline,scatter...
Michal Klocek -
r476:b6fb05e4e56f
parent child
Show More
@@ -0,0 +1,100
1 #ifndef XYCHARTANIMATIONITEM_P_H_
2 #define XYCHARTANIMATIONITEM_P_H_
3 #include "qchartglobal.h"
4 #include "xychartanimator_p.h"
5 #include <QPointF>
6 #include <QTimer>
7 #include <QGraphicsItem>
8
9 Q_DECLARE_METATYPE(QVector<QPointF>)
10
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12
13
14 const static int duration = 1000;
15
16 template <class T , class U>
17 class XYChartAnimationItem : public T {
18
19 public:
20 XYChartAnimationItem(U *series, QGraphicsItem *parent = 0);
21 virtual ~XYChartAnimationItem();
22
23 void animationStarted();
24
25 protected:
26 virtual void updatePoints(QVector<QPointF>& newPoints);
27 virtual void updatePoint(QVector<QPointF>& newPoints);
28
29 private:
30 XYChartAnimator<T,U> *m_animation;
31 QVector<QPointF> m_points;
32 bool m_dirty;
33 };
34
35 template <class T, class U>
36 XYChartAnimationItem<T,U>::XYChartAnimationItem(U *series,QGraphicsItem *parent):
37 T(series,parent),
38 m_animation(new XYChartAnimator<T,U>(this,this)),
39 m_dirty(false)
40 {
41 }
42
43 template <class T, class U>
44 XYChartAnimationItem<T,U>::~XYChartAnimationItem()
45 {
46 }
47
48 template <class T, class U>
49 void XYChartAnimationItem<T,U>::updatePoints(QVector<QPointF>& newPoints)
50 {
51 QVector<QPointF> oldPoints = T::points();
52
53 if(newPoints.count()==0) return;
54 oldPoints.resize(newPoints.size());
55
56 if(m_animation->state()!=QAbstractAnimation::Stopped){
57 m_animation->stop();
58 }
59
60 m_animation->setDuration(duration);
61 m_animation->setEasingCurve(QEasingCurve::InOutBack);
62 m_animation->setKeyValueAt(0.0, qVariantFromValue(oldPoints));
63 m_animation->setKeyValueAt(1.0, qVariantFromValue(newPoints));
64 QTimer::singleShot(0,m_animation,SLOT(start()));
65
66 m_points = newPoints;
67 m_dirty=false;
68 }
69
70 template <class T, class U>
71 void XYChartAnimationItem<T,U>::updatePoint(QVector<QPointF>& newPoints)
72 {
73
74 if(m_animation->state()!=QAbstractAnimation::Stopped) {
75 m_animation->stop();
76 m_dirty=true;
77 }
78
79 if(m_dirty) {
80 m_points=newPoints;
81 m_dirty=false;
82 }
83
84 m_animation->setDuration(duration);
85 m_animation->setEasingCurve(QEasingCurve::InOutBack);
86 m_animation->setKeyValueAt(0.0, qVariantFromValue(m_points));
87 m_animation->setKeyValueAt(1.0, qVariantFromValue(newPoints));
88
89 QTimer::singleShot(0,m_animation,SLOT(start()));
90 }
91
92 template <class T, class U>
93 void XYChartAnimationItem<T,U>::animationStarted()
94 {
95 m_dirty=true;
96 }
97
98 QTCOMMERCIALCHART_END_NAMESPACE
99
100 #endif
@@ -0,0 +1,96
1 #ifndef XYCHARTANIMATOR_P_H_
2 #define XYCHARTANIMATOR_P_H_
3 #include "qchartglobal.h"
4 #include <QVariantAnimation>
5 #include <QPointF>
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 template <class T, class U>
10 class XYChartAnimationItem;
11
12
13 template <class T, class U>
14 class XYChartAnimator : public QVariantAnimation
15 {
16 public:
17 enum Animation { LineDrawAnimation, MoveDownAnimation, MoveUpAnimation };
18 XYChartAnimator(XYChartAnimationItem<T,U> *item, QObject *parent = 0 );
19 ~XYChartAnimator();
20
21 protected:
22 QVariant interpolated(const QVariant &start, const QVariant & end, qreal progress ) const;
23 void updateCurrentValue (const QVariant & value );
24 void updateState ( QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
25
26 private:
27 XYChartAnimationItem<T,U> *m_item;
28 Animation m_type;
29 };
30
31 template <class T, class U>
32 XYChartAnimator<T,U>::XYChartAnimator(XYChartAnimationItem<T,U> *item , QObject *parent):QVariantAnimation(parent),
33 m_item(item),
34 m_type(MoveDownAnimation)
35 {
36 }
37
38 template <class T,class U>
39 XYChartAnimator<T,U>::~XYChartAnimator()
40 {
41 }
42
43 template <class T, class U>
44 QVariant XYChartAnimator<T,U>::interpolated(const QVariant &start, const QVariant & end, qreal progress ) const
45 {
46 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
47 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
48 QVector<QPointF> result;
49
50 switch(m_type) {
51
52 case MoveDownAnimation: {
53
54 Q_ASSERT(startVector.count() == endVector.count());
55 for(int i =0;i< startVector.count();i++) {
56 qreal x = startVector[i].x() + ((endVector[i].x()- startVector[i].x()) * progress);
57 qreal y = startVector[i].y() + ((endVector[i].y()- startVector[i].y()) * progress);
58 result << QPointF(x,y);
59 }
60
61 }
62 break;
63 case LineDrawAnimation:{
64 for(int i =0;i< endVector.count()* qBound(0.0, progress, 1.0);i++) {
65 result << endVector[i];
66 }
67 }
68 break;
69 default:
70 qWarning()<<"Unknow type of animation";
71 break;
72 }
73
74 return qVariantFromValue(result);
75 }
76
77 template <class T, class U>
78 void XYChartAnimator<T,U>::updateCurrentValue (const QVariant & value )
79 {
80 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
81 if(state()!=QAbstractAnimation::Stopped){ //workaround
82 m_item->setGeometry(vector);
83 }
84 }
85
86 template <class T, class U>
87 void XYChartAnimator<T,U>::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
88 {
89 Q_UNUSED(oldState)
90 if (newState==QAbstractAnimation::Running) m_item->animationStarted();
91 QVariantAnimation::updateState(newState,oldState);
92 }
93
94 QTCOMMERCIALCHART_END_NAMESPACE
95
96 #endif /* XYCHARTANIMATOR_P_H_ */
@@ -1,59 +1,70
1 1 #include "chartview.h"
2 2 #include <qlineseries.h>
3 #include <qscatterseries.h>
4 #include <qsplineseries.h>
3 5 #include <QTime>
4 6
5 7 ChartView::ChartView(QWidget* parent):QChartView(parent),
6 8 m_index(0)
7 9 {
10 setChartTitle("Three random line charts");
11
8 12 QObject::connect(&m_timer,SIGNAL(timeout()),this,SLOT(handleTimeout()));
9 13 m_timer.setInterval(3000);
10 14
11 15 QTime now = QTime::currentTime();
12 16 qsrand((uint)now.msec());
13 17
14 18 QLineSeries* series0 = new QLineSeries(this);
15 19 QPen blue(Qt::blue);
16 20 blue.setWidth(3);
17 21 series0->setPen(blue);
18 QLineSeries* series1 = new QLineSeries(this);
22 QScatterSeries* series1 = new QScatterSeries(this);
19 23 QPen red(Qt::red);
20 24 red.setWidth(3);
21 25 series1->setPen(red);
22 QLineSeries* series2 = new QLineSeries(this);
26 series1->setBrush(Qt::white);
27 QSplineSeries* series2 = new QSplineSeries(this);
23 28 QPen green(Qt::green);
24 29 green.setWidth(3);
25 30 series2->setPen(green);
26 31
27 32 int numPoints = 10;
28 33
29 34 for (int x = 0; x <= numPoints; ++x) {
30 series0->add(x, qrand() % 100);
31 series1->add(x, qrand() % 100);
32 series2->add(x, qrand() % 100);
35 qreal y = qrand() % 100;
36 series0->add(x,y);
37 series1->add(x,y);
38 series2->add(x,y);
33 39 }
34 40
35 addSeries(series0);
36
37 41 m_series<<series0;
42 m_titles<<chartTitle()+": LineChart";
38 43 m_series<<series1;
44 m_titles<<chartTitle()+": ScatterChart";
39 45 m_series<<series2;
46 m_titles<<chartTitle()+": SplineChart";
47
48 addSeries(series0);
49 setChartTitle(m_titles.at(0));
40 50
41 51 m_timer.start();
42 52 }
43 53
44 54 ChartView::~ChartView()
45 55 {
46 56 if(m_series.size()==0) return;
47 57 removeSeries(m_series.at(m_index));
48 58 qDeleteAll(m_series);
49 59 }
50 60
51 61 void ChartView::handleTimeout()
52 62 {
53 63 if(m_series.size()==0) return;
54 64
55 65 removeSeries(m_series.at(m_index));
56 66 m_index++;
57 67 m_index=m_index%m_series.size();
58 68 addSeries(m_series.at(m_index));
69 setChartTitle(m_titles.at(m_index));
59 70 }
@@ -1,25 +1,26
1 1 #ifndef CHARTVIEW_H_
2 2 #define CHARTVIEW_H_
3 3
4 4 #include <qchartview.h>
5 5 #include <QTimer>
6 6
7 7 QTCOMMERCIALCHART_USE_NAMESPACE
8 8
9 9 class ChartView: public QChartView
10 10 {
11 11 Q_OBJECT
12 12 public:
13 13 ChartView(QWidget* parent=0);
14 14 virtual ~ChartView();
15 15
16 16 public slots:
17 17 void handleTimeout();
18 18
19 19 private:
20 20 QTimer m_timer;
21 21 QList<QSeries*> m_series;
22 QStringList m_titles;
22 23 int m_index;
23 24 };
24 25
25 26 #endif /* CHARTVIEW_H_ */
@@ -1,17 +1,16
1 1 #include "chartview.h"
2 2 #include <QApplication>
3 3 #include <QMainWindow>
4 4
5 5 int main(int argc, char *argv[])
6 6 {
7 7 QApplication a(argc, argv);
8 8 QMainWindow window;
9 9 ChartView chartView(&window);
10 10 chartView.setRenderHint(QPainter::Antialiasing);
11 chartView.setChartTitle("Three random line charts");
12 11 chartView.setAnimationOptions(QChart::AllAnimations);
13 12 window.setCentralWidget(&chartView);
14 13 window.resize(400, 300);
15 14 window.show();
16 15 return a.exec();
17 16 }
@@ -1,371 +1,386
1 1 #include "qchart.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartdataset_p.h"
5 5 #include "charttheme_p.h"
6 6 //series
7 7 #include "qbarseries.h"
8 8 #include "qstackedbarseries.h"
9 9 #include "qpercentbarseries.h"
10 10 #include "qlineseries.h"
11 11 #include "qareaseries.h"
12 12 #include "qpieseries.h"
13 13 #include "qscatterseries.h"
14 14 #include "qsplineseries.h"
15 15 //items
16 16 #include "axisitem_p.h"
17 17 #include "axisanimationitem_p.h"
18 18 #include "areachartitem_p.h"
19 19 #include "barpresenter_p.h"
20 20 #include "stackedbarpresenter_p.h"
21 21 #include "percentbarpresenter_p.h"
22 22 #include "linechartitem_p.h"
23 #include "linechartanimationitem_p.h"
24 23 #include "piepresenter_p.h"
25 24 #include "scatterchartitem_p.h"
26 25 #include "splinechartitem_p.h"
27 26
28 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 28
30 29 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
31 30 m_chart(chart),
32 31 m_dataset(dataset),
33 32 m_chartTheme(0),
34 33 m_zoomIndex(0),
35 34 m_marginSize(0),
36 35 m_rect(QRectF(QPoint(0,0),m_chart->size())),
37 36 m_options(QChart::NoAnimation)
38 37 {
39 38 createConnections();
40 39 setChartTheme(QChart::ChartThemeDefault);
41 40 }
42 41
43 42 ChartPresenter::~ChartPresenter()
44 43 {
45 44 }
46 45
47 46 void ChartPresenter::createConnections()
48 47 {
49 48 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
50 49 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
51 50 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
52 51 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
53 52 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
54 53 }
55 54
56 55
57 56 QRectF ChartPresenter::geometry() const
58 57 {
59 58 return m_rect;
60 59 }
61 60
62 61 void ChartPresenter::handleGeometryChanged()
63 62 {
64 63 QRectF rect(QPoint(0,0),m_chart->size());
65 64 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
66 65
67 66 //rewrite zoom stack
68 67 for(int i=0;i<m_zoomStack.count();i++){
69 68 QRectF r = m_zoomStack[i];
70 69 qreal w = rect.width()/m_rect.width();
71 70 qreal h = rect.height()/m_rect.height();
72 71 QPointF tl = r.topLeft();
73 72 tl.setX(tl.x()*w);
74 73 tl.setY(tl.y()*h);
75 74 QPointF br = r.bottomRight();
76 75 br.setX(br.x()*w);
77 76 br.setY(br.y()*h);
78 77 r.setTopLeft(tl);
79 78 r.setBottomRight(br);
80 79 m_zoomStack[i]=r;
81 80 }
82 81
83 82 m_rect = rect;
84 83 Q_ASSERT(m_rect.isValid());
85 84 emit geometryChanged(m_rect);
86 85 }
87 86
88 87 int ChartPresenter::margin() const
89 88 {
90 89 return m_marginSize;
91 90 }
92 91
93 92 void ChartPresenter::setMargin(int margin)
94 93 {
95 94 m_marginSize = margin;
96 95 }
97 96
98 97 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
99 98 {
100 99
101 100 AxisItem* item ;
102 101
103 102 if(!m_options.testFlag(QChart::GridAxisAnimations))
104 103 {
105 104 item = new AxisItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
106 105 }else{
107 106 item = new AxisAnimationItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
108 107 }
109 108 if(axis==m_dataset->axisX()){
110 109 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
111 110 //initialize
112 111 item->handleRangeChanged(domain->minX(),domain->maxX());
113 112 item->handleTicksCountChanged(4);
114 113 }
115 114 else{
116 115 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
117 116 //initialize
118 117 item->handleRangeChanged(domain->minY(),domain->maxY());
119 118 item->handleTicksCountChanged(4);
120 119 }
121 120
122 121 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
123 122 //initialize
124 123 item->handleGeometryChanged(m_rect);
125 124 m_chartTheme->decorate(axis,item);
126 125 m_axisItems.insert(axis,item);
127 126 }
128 127
129 128 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
130 129 {
131 130 AxisItem* item = m_axisItems.take(axis);
132 131 Q_ASSERT(item);
133 132 delete item;
134 133 }
135 134
136 135
137 136 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
138 137 {
139 138 switch(series->type())
140 139 {
141 140 case QSeries::SeriesTypeLine: {
142 141
143 142 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
144 143 LineChartItem* item;
145 144 if(m_options.testFlag(QChart::SeriesAnimations)){
146 item = new LineChartAnimationItem(lineSeries,m_chart);
145 item = new LineChartAnimationItem(lineSeries,m_chart);
147 146 }else{
148 147 item = new LineChartItem(lineSeries,m_chart);
149 148 }
150 149 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
151 150 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
152 151 //initialize
153 152 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
154 153 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
155 154 //decorate
156 155 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
157 156 m_chartItems.insert(series,item);
158 157 break;
159 158 }
160 159
161 160 case QSeries::SeriesTypeArea: {
162 161
163 162 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
164 163 AreaChartItem* item;
165 164 if(m_options.testFlag(QChart::SeriesAnimations)) {
166 165 item = new AreaChartItem(areaSeries,m_chart);
167 166 }
168 167 else {
169 168 item = new AreaChartItem(areaSeries,m_chart);
170 169 }
171 170 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
172 171 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
173 172 //initialize
174 173 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
175 174 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
176 175 //decorate
177 176 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
178 177 m_chartItems.insert(series,item);
179 178 break;
180 179 }
181 180
182 181 case QSeries::SeriesTypeBar: {
183 182 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
184 183 BarPresenter* item = new BarPresenter(barSeries,m_chart);
185 184 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
186 185 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
187 186 // QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
188 187 m_chartItems.insert(series,item);
189 188 // m_axisXItem->setVisible(false);
190 189 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
191 190 break;
192 191 }
193 192
194 193 case QSeries::SeriesTypeStackedBar: {
195 194
196 195 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
197 196 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
198 197 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
199 198 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
200 199 // QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
201 200 m_chartItems.insert(series,item);
202 201 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
203 202 break;
204 203 }
205 204
206 205 case QSeries::SeriesTypePercentBar: {
207 206
208 207 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
209 208 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
210 209 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
211 210 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
212 211 // QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
213 212 m_chartItems.insert(series,item);
214 213 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
215 214 break;
216 215 }
217 216 case QSeries::SeriesTypeScatter: {
218 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
219 ScatterChartItem *scatterPresenter = new ScatterChartItem(scatterSeries, m_chart);
220 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
221 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
222 QObject::connect(domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),
223 scatterPresenter, SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
224 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
225 m_chartItems.insert(scatterSeries, scatterPresenter);
226 if (m_rect.isValid())
227 scatterPresenter->handleGeometryChanged(m_rect);
228 scatterPresenter->handleDomainChanged(domain->minX(), domain->maxX(), domain->minY(), domain->maxY());
229 break;
230 }
217 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
218 ScatterChartItem *item;
219 if(m_options.testFlag(QChart::SeriesAnimations)) {
220 item = new ScatterChartAnimationItem(scatterSeries,m_chart);
221 } else {
222 item = new ScatterChartItem(scatterSeries, m_chart);
223 }
224 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
225 item, SLOT(handleGeometryChanged(const QRectF&)));
226 QObject::connect(domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),
227 item, SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
228 //initialize
229 if (m_rect.isValid())
230 item->handleGeometryChanged(m_rect);
231 item->handleDomainChanged(domain->minX(), domain->maxX(), domain->minY(), domain->maxY());
232 //decorate
233 m_chartTheme->decorate(item, scatterSeries, m_chartItems.count());
234 m_chartItems.insert(scatterSeries, item);
235
236 break;
237 }
231 238 case QSeries::SeriesTypePie: {
232 239 QPieSeries *s = qobject_cast<QPieSeries *>(series);
233 240 PiePresenter* pie = new PiePresenter(m_chart, s);
234 241 m_chartTheme->decorate(pie, s, m_chartItems.count());
235 242 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
236 243
237 244 // Hide all from background when there is only piechart
238 245 // TODO: refactor this ugly code... should be one setting for this
239 246 if (m_chartItems.count() == 0) {
240 247 m_chart->axisX()->setAxisVisible(false);
241 248 m_chart->axisY()->setAxisVisible(false);
242 249 m_chart->axisX()->setGridVisible(false);
243 250 m_chart->axisY()->setGridVisible(false);
244 251 m_chart->axisX()->setLabelsVisible(false);
245 252 m_chart->axisY()->setLabelsVisible(false);
246 253 m_chart->axisX()->setShadesVisible(false);
247 254 m_chart->axisY()->setShadesVisible(false);
248 255 m_chart->setChartBackgroundBrush(Qt::transparent);
249 256 }
250 257
251 258 m_chartItems.insert(series, pie);
252 259 pie->handleGeometryChanged(m_rect);
253 260 break;
254 261 }
255 262
256 263 case QSeries::SeriesTypeSpline: {
257 QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series);
258 SplineChartItem* splinePresenter = new SplineChartItem(splineSeries, m_chart);
259 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), splinePresenter, SLOT(handleGeometryChanged(const QRectF&)));
260 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),splinePresenter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
261 //initialize
262 splinePresenter->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
263 m_chartTheme->decorate(splinePresenter, splineSeries, m_chartItems.count());
264 m_chartItems.insert(splineSeries, splinePresenter);
265 break;
266 }
264
265 QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series);
266 SplineChartItem* item;
267 if(m_options.testFlag(QChart::SeriesAnimations)) {
268 item = new SplineChartAnimationItem(splineSeries, m_chart);
269 } else {
270 item = new SplineChartItem(splineSeries, m_chart);
271 }
272 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), item, SLOT(handleGeometryChanged(const QRectF&)));
273 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
274 //initialize
275 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
276 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
277 //decorate
278 m_chartTheme->decorate(item, splineSeries, m_chartItems.count());
279 m_chartItems.insert(splineSeries, item);
280 break;
281 }
267 282 default: {
268 283 qDebug()<< "Series type" << series->type() << "not implemented.";
269 284 break;
270 285 }
271 286 }
272 287
273 288 zoomReset();
274 289 }
275 290
276 291 void ChartPresenter::handleSeriesRemoved(QSeries* series)
277 292 {
278 293 ChartItem* item = m_chartItems.take(series);
279 294 delete item;
280 295 }
281 296
282 297 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
283 298 {
284 299 delete m_chartTheme;
285 300
286 301 m_chartTheme = ChartTheme::createTheme(theme);
287 302
288 303 m_chartTheme->decorate(m_chart);
289 304 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
290 305
291 306 int index=0;
292 307 while (i.hasNext()) {
293 308 i.next();
294 309 m_chartTheme->decorate(i.value(),i.key(),index);
295 310 index++;
296 311 }
297 312
298 313 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
299 314 while (j.hasNext()) {
300 315 j.next();
301 316 m_chartTheme->decorate(j.key(),j.value());
302 317 }
303 318 }
304 319
305 320 QChart::ChartTheme ChartPresenter::chartTheme()
306 321 {
307 322 return m_chartTheme->id();
308 323 }
309 324
310 325 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
311 326 {
312 327 if(m_options!=options) {
313 328
314 329 m_options=options;
315 330
316 331 //recreate elements
317 332 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
318 333 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
319 334
320 335 foreach(QChartAxis* axis, axisList) {
321 336 handleAxisRemoved(axis);
322 337 handleAxisAdded(axis,m_dataset->domain(axis));
323 338 }
324 339 foreach(QSeries* series, seriesList) {
325 340 handleSeriesRemoved(series);
326 341 handleSeriesAdded(series,m_dataset->domain(series));
327 342 }
328 343 }
329 344 }
330 345
331 346 void ChartPresenter::zoomIn()
332 347 {
333 348 QRectF rect = geometry();
334 349 rect.setWidth(rect.width()/2);
335 350 rect.setHeight(rect.height()/2);
336 351 rect.moveCenter(geometry().center());
337 352 zoomIn(rect);
338 353 }
339 354
340 355 void ChartPresenter::zoomIn(const QRectF& rect)
341 356 {
342 357 QRectF r = rect.normalized();
343 358 r.translate(-m_marginSize, -m_marginSize);
344 359 m_dataset->zoomInDomain(r,geometry().size());
345 360 m_zoomStack<<r;
346 361 m_zoomIndex++;
347 362 }
348 363
349 364 void ChartPresenter::zoomOut()
350 365 {
351 366 if(m_zoomIndex==0) return;
352 367 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
353 368 m_zoomIndex--;
354 369 m_zoomStack.resize(m_zoomIndex);
355 370 }
356 371
357 372 void ChartPresenter::zoomReset()
358 373 {
359 374 m_zoomIndex=0;
360 375 m_zoomStack.resize(m_zoomIndex);
361 376 }
362 377
363 378 QChart::AnimationOptions ChartPresenter::animationOptions() const
364 379 {
365 380 return m_options;
366 381 }
367 382
368 383
369 384 #include "moc_chartpresenter_p.cpp"
370 385
371 386 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,328 +1,329
1 1 #include "charttheme_p.h"
2 2 #include "qchart.h"
3 3 #include "qchartaxis.h"
4 4 #include <QTime>
5 5
6 6 //series
7 7 #include "qbarset.h"
8 8 #include "qbarseries.h"
9 9 #include "qstackedbarseries.h"
10 10 #include "qpercentbarseries.h"
11 11 #include "qlineseries.h"
12 12 #include "qareaseries.h"
13 13 #include "qscatterseries.h"
14 14 #include "qpieseries.h"
15 15 #include "qpieslice.h"
16 16 #include "qsplineseries.h"
17 17
18 18 //items
19 19 #include "axisitem_p.h"
20 20 #include "barpresenter_p.h"
21 21 #include "stackedbarpresenter_p.h"
22 22 #include "percentbarpresenter_p.h"
23 23 #include "linechartitem_p.h"
24 24 #include "areachartitem_p.h"
25 25 #include "scatterchartitem_p.h"
26 26 #include "piepresenter_p.h"
27 27 #include "splinechartitem_p.h"
28 28
29 29 //themes
30 30 #include "chartthemevanilla_p.h"
31 31 #include "chartthemeicy_p.h"
32 32 #include "chartthemegrayscale_p.h"
33 33 #include "chartthemescientific_p.h"
34 34
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 /* TODO
39 39 case QChart::ChartThemeUnnamed1:
40 40 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
41 41 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
42 42 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
43 43 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
44 44 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
45 45
46 46 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
47 47 m_gradientEndColor = QColor(QRgb(0xffafafaf));
48 48 */
49 49
50 50 ChartTheme::ChartTheme(QChart::ChartTheme id)
51 51 {
52 52 m_id = id;
53 53 m_seriesColor.append(QRgb(0xff000000));
54 54 m_seriesColor.append(QRgb(0xff707070));
55 55 m_gradientStartColor = QColor(QRgb(0xffffffff));
56 56 m_gradientEndColor = QColor(QRgb(0xffafafaf));
57 57
58 58 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
59 59 }
60 60
61 61
62 62 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
63 63 {
64 64 switch(theme) {
65 65 case QChart::ChartThemeDefault:
66 66 return new ChartTheme();
67 67 case QChart::ChartThemeVanilla:
68 68 return new ChartThemeVanilla();
69 69 case QChart::ChartThemeIcy:
70 70 return new ChartThemeIcy();
71 71 case QChart::ChartThemeGrayscale:
72 72 return new ChartThemeGrayscale();
73 73 case QChart::ChartThemeScientific:
74 74 return new ChartThemeScientific();
75 75 }
76 76 }
77 77
78 78 void ChartTheme::decorate(QChart* chart)
79 79 {
80 80 QLinearGradient backgroundGradient;
81 81 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
82 82 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
83 83 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
84 84 chart->setChartBackgroundBrush(backgroundGradient);
85 85 }
86 86 //TODO helper to by removed later
87 87 void ChartTheme::decorate(ChartItem* item, QSeries* series,int count)
88 88 {
89 89 switch(series->type())
90 90 {
91 91 case QSeries::SeriesTypeLine: {
92 92 QLineSeries* s = static_cast<QLineSeries*>(series);
93 93 LineChartItem* i = static_cast<LineChartItem*>(item);
94 94 decorate(i,s,count);
95 95 break;
96 96 }
97 97 case QSeries::SeriesTypeArea: {
98 98 QAreaSeries* s = static_cast<QAreaSeries*>(series);
99 99 AreaChartItem* i = static_cast<AreaChartItem*>(item);
100 100 decorate(i,s,count);
101 101 break;
102 102 }
103 103 case QSeries::SeriesTypeBar: {
104 104 QBarSeries* b = static_cast<QBarSeries*>(series);
105 105 BarPresenter* i = static_cast<BarPresenter*>(item);
106 106 decorate(i,b,count);
107 107 break;
108 108 }
109 109 case QSeries::SeriesTypeStackedBar: {
110 110 QStackedBarSeries* s = static_cast<QStackedBarSeries*>(series);
111 111 StackedBarPresenter* i = static_cast<StackedBarPresenter*>(item);
112 112 decorate(i,s,count);
113 113 break;
114 114 }
115 115 case QSeries::SeriesTypePercentBar: {
116 116 QPercentBarSeries* s = static_cast<QPercentBarSeries*>(series);
117 117 PercentBarPresenter* i = static_cast<PercentBarPresenter*>(item);
118 118 decorate(i,s,count);
119 119 break;
120 120 }
121 121 case QSeries::SeriesTypeScatter: {
122 122 QScatterSeries* s = qobject_cast<QScatterSeries*>(series);
123 123 Q_ASSERT(s);
124 124 ScatterChartItem* i = static_cast<ScatterChartItem*>(item);
125 125 Q_ASSERT(i);
126 126 decorate(i, s, count);
127 127 break;
128 128 }
129 129 case QSeries::SeriesTypePie: {
130 130 QPieSeries* s = static_cast<QPieSeries*>(series);
131 131 PiePresenter* i = static_cast<PiePresenter*>(item);
132 132 decorate(i,s,count);
133 133 break;
134 134 }
135 135 default:
136 136 qDebug()<<"Wrong item to be decorated by theme";
137 137 break;
138 138 }
139 139
140 140 }
141 141
142 142 void ChartTheme::decorate(AreaChartItem* item, QAreaSeries* series,int count)
143 143 {
144 144 QPen pen;
145 145 QBrush brush;
146 146
147 147 if(pen != series->pen()){
148 148 item->setPen(series->pen());
149 149 }else{
150 150 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
151 151 pen.setWidthF(2);
152 152 item->setPen(pen);
153 153 }
154 154
155 155 if(brush != series->brush()){
156 156 item->setBrush(series->brush());
157 157 }else{
158 158 QBrush brush(m_seriesColor.at(count%m_seriesColor.size()));
159 159 item->setBrush(brush);
160 160 }
161 161 }
162 162
163 163
164 164 void ChartTheme::decorate(LineChartItem* item, QLineSeries* series,int count)
165 165 {
166 166 QPen pen;
167 167 if(pen != series->pen()){
168 item->setPen(series->pen());
168 item->setLinePen(series->pen());
169 169 return;
170 170 }
171 171 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
172 172 pen.setWidthF(2);
173 item->setPen(pen);
173 item->setLinePen(pen);
174 174 }
175 175
176 176 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int count)
177 177 {
178 178 QList<QBarSet*> sets = series->barSets();
179 179 for (int i=0; i<series->barsetCount(); i++) {
180 180 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
181 181 }
182 182 }
183 183
184 184 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int count)
185 185 {
186 186 QList<QBarSet*> sets = series->barSets();
187 187 for (int i=0; i<series->barsetCount(); i++) {
188 188 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
189 189 }
190 190 }
191 191
192 192 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int count)
193 193 {
194 194 QList<QBarSet*> sets = series->barSets();
195 195 for (int i=0; i<series->barsetCount(); i++) {
196 196 sets.at(i)->setBrush(QBrush(m_seriesColor.at(i%m_seriesColor.count())));
197 197 }
198 198 }
199 199
200 200 void ChartTheme::decorate(ScatterChartItem* item, QScatterSeries* series, int count)
201 201 {
202 202 Q_ASSERT(item);
203 203 Q_ASSERT(series);
204 204
205 205 QColor color = m_seriesColor.at(count % m_seriesColor.size());
206 206 // TODO: define alpha in the theme? or in the series?
207 207 //color.setAlpha(120);
208 208
209 209 QBrush brush(color, Qt::SolidPattern);
210 210 item->setBrush(Qt::blue);
211 211
212 212 QPen pen(brush, 3);
213 213 pen.setColor(color);
214 214 item->setPen(pen);
215 215 }
216 216
217 217 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
218 218 {
219 219 // create a list of slice colors based on current theme
220 220 int i = 0;
221 221 QList<QColor> colors;
222 222 while (colors.count() < series->count()) {
223 223
224 224 // get base color
225 225 QColor c = m_seriesColor[i++];
226 226 i = i % m_seriesColor.count();
227 227
228 228 // dont use black colors... looks bad
229 229 if (c == Qt::black)
230 230 continue;
231 231
232 232 // by default use the "raw" theme color
233 233 if (!colors.contains(c)) {
234 234 colors << c;
235 235 continue;
236 236 }
237 237 // ...ok we need to generate something that looks like the same color
238 238 // but different lightness
239 239
240 240 int tryCount = 0;
241 241 while (tryCount++ < 100) {
242 242
243 243 // find maximum value we can raise the lightness
244 244 int lMax = 255;
245 245 if (lMax > 255 - c.red())
246 246 lMax = 255 - c.red();
247 247 if (lMax > 255 - c.green())
248 248 lMax = 255 - c.green();
249 249 if (lMax > 255 - c.blue())
250 250 lMax = 255 - c.blue();
251 251
252 252 // find maximum value we can make it darker
253 253 int dMax = 255;
254 254 if (dMax > c.red())
255 255 dMax = c.red();
256 256 if (dMax > c.green())
257 257 dMax = c.green();
258 258 if (dMax > c.blue())
259 259 dMax = c.blue();
260 260
261 261 int max = dMax + lMax;
262 262 if (max == 0) {
263 263 // no room to make color lighter or darker...
264 264 qDebug() << "cannot generate a color for pie!";
265 265 break;
266 266 }
267 267
268 268 // generate random color
269 269 int r = c.red() - dMax;
270 270 int g = c.green() - dMax;
271 271 int b = c.blue() - dMax;
272 272 int d = qrand() % max;
273 273 c.setRgb(r+d, g+d, b+d);
274 274
275 275 // found a unique color?
276 276 if (!colors.contains(c))
277 277 break;
278 278 }
279 279
280 280 qDebug() << "generated a color for pie" << c;
281 281 colors << c;
282 282 }
283 283
284 284 // finally update colors
285 285 foreach (QPieSlice* s, series->slices()) {
286 286 QColor c = colors.takeFirst();
287 287 s->setSlicePen(c);
288 288 s->setSliceBrush(c);
289 289 }
290 290 }
291 291
292 292
293 293 void ChartTheme::decorate(QChartAxis* axis,AxisItem* item)
294 294 {
295 295 //TODO: dummy defults for now
296 296 axis->setLabelsBrush(Qt::black);
297 297 axis->setLabelsPen(Qt::NoPen);
298 298 axis->setShadesPen(Qt::NoPen);
299 299 axis->setShadesOpacity(0.5);
300 300 }
301 301
302 302 void ChartTheme::decorate(SplineChartItem* item, QSplineSeries* series, int count)
303 303 {
304 304 Q_ASSERT(item);
305 305 Q_ASSERT(series);
306 306
307 307 QPen pen;
308
308 309 if(pen != series->pen()){
309 item->setPen(series->pen());
310 return;
310 item->setLinePen(series->pen());
311 }else{
312 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
313 pen.setWidthF(series->pen().widthF());
314 item->setLinePen(series->pen());
311 315 }
312 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
313 pen.setWidthF(series->pen().widthF());
314 item->setPen(pen);
315 316
316 317 // QColor color = m_seriesColor.at(count % m_seriesColor.size());
317 318 // TODO: define alpha in the theme? or in the series?
318 319 //color.setAlpha(120);
319 320
320 321 // QBrush brush(color, Qt::SolidPattern);
321 322 // presenter->m_markerBrush = brush;
322 323
323 324 // QPen pen(brush, 3);
324 325 // pen.setColor(color);
325 326 // presenter->m_markerPen = pen;
326 327 }
327 328
328 329 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,14 +1,12
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 $$PWD/linechartanimationitem.cpp \
6 5 $$PWD/linechartitem.cpp \
7 6 $$PWD/qlineseries.cpp
8 7
9 8 PRIVATE_HEADERS += \
10 $$PWD/linechartitem_p.h \
11 $$PWD/linechartanimationitem_p.h
9 $$PWD/linechartitem_p.h
12 10
13 11 PUBLIC_HEADERS += \
14 12 $$PWD/qlineseries.h No newline at end of file
@@ -1,112 +1,111
1 1 #include "linechartanimationitem_p.h"
2 2 #include "linechartitem_p.h"
3 3 #include <QPropertyAnimation>
4 4 #include <QTimer>
5 5
6 6 Q_DECLARE_METATYPE(QVector<QPointF>)
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 const static int duration = 500;
11 11
12 12 LineChartAnimationItem::LineChartAnimationItem(QLineSeries* series,QGraphicsItem *parent):
13 13 LineChartItem(series,parent),
14 14 m_animation(new LineChartAnimatator(this,this)),
15 15 m_dirty(false)
16 16 {
17 17 }
18 18
19 19 LineChartAnimationItem::~LineChartAnimationItem()
20 20 {
21 21 }
22 22
23 23 void LineChartAnimationItem::updatePoints(QVector<QPointF>& newPoints)
24 24 {
25 25 QVector<QPointF> oldPoints = points();
26 26 LineChartItem::updatePoints(newPoints);
27 27
28 28 if(newPoints.count()==0) return;
29 29 oldPoints.resize(newPoints.size());
30 30
31 31 if(m_animation->state()!=QAbstractAnimation::Stopped){
32 32 m_animation->stop();
33 33 }
34 34
35 35 m_animation->setDuration(duration);
36 36 m_animation->setEasingCurve(QEasingCurve::InOutBack);
37 37 m_animation->setKeyValueAt(0.0, qVariantFromValue(oldPoints));
38 38 m_animation->setKeyValueAt(1.0, qVariantFromValue(newPoints));
39 39 QTimer::singleShot(0,m_animation,SLOT(start()));
40 40
41
42 41 m_points = newPoints;
43 42 m_dirty=false;
44 43
45 44 }
46 45
47 46 void LineChartAnimationItem::updatePoint(int index,QPointF& newPoint)
48 47 {
49 48
50 49 if(m_animation->state()!=QAbstractAnimation::Stopped){
51 50 m_animation->stop();
52 51 m_dirty=true;
53 52 }
54 53
55 54 if(m_dirty){
56 55 m_points=points();
57 56 m_dirty=false;
58 57 }
59 58
60 59 LineChartItem::updatePoint(index,newPoint);
61 60
62 61 m_animation->setDuration(duration);
63 62 m_animation->setEasingCurve(QEasingCurve::InOutBack);
64 63 m_animation->setKeyValueAt(0.0, qVariantFromValue(m_points));
65 64 m_animation->setKeyValueAt(1.0, qVariantFromValue( points()));
66 65
67 66 QTimer::singleShot(0,this,SLOT(startAnimation()));
68 67
69 68
70 69 }
71 70
72 71 void LineChartAnimationItem::startAnimation()
73 72 {
74 73 m_dirty=true;
75 74 m_animation->start();
76 75 }
77 76
78 77 LineChartAnimatator::LineChartAnimatator(LineChartAnimationItem *item , QObject *parent):QVariantAnimation(parent),
79 78 m_item(item)
80 79 {
81 80 }
82 81
83 82 LineChartAnimatator::~LineChartAnimatator()
84 83 {
85 84 }
86 85
87 86 QVariant LineChartAnimatator::interpolated(const QVariant &start, const QVariant & end, qreal progress ) const
88 87 {
89 88 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
90 89 QVector<QPointF> endVecotr = qVariantValue<QVector<QPointF> >(end);
91 90 QVector<QPointF> result;
92 91 Q_ASSERT(startVector.count() == endVecotr.count());
93 92
94 93 for(int i =0 ;i< startVector.count();i++){
95 94 qreal x = startVector[i].x() + ((endVecotr[i].x()- startVector[i].x()) * progress);//qBound(0.0, progress, 1.0));
96 95 qreal y = startVector[i].y() + ((endVecotr[i].y()- startVector[i].y()) * progress);//qBound(0.0, progress, 1.0));
97 96 result << QPointF(x,y);
98 97 }
99 98 return qVariantFromValue(result);
100 99 }
101 100
102 101 void LineChartAnimatator::updateCurrentValue (const QVariant & value )
103 102 {
104 103 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
105 104 if(state()!=QAbstractAnimation::Stopped){ //workaround
106 105 m_item->setGeometry(vector);
107 106 }
108 107 }
109 108
110 109 #include "moc_linechartanimationitem_p.cpp"
111 110
112 111 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,124 +1,123
1 1 #include "linechartitem_p.h"
2 2 #include "qlineseries.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 LineChartItem::LineChartItem(QLineSeries* series,QGraphicsItem *parent):XYChartItem(series,parent),
12 12 m_series(series),
13 13 m_items(this)
14 14 {
15 15 //m_items.setZValue(ChartPresenter::LineChartZValue);
16 16 setZValue(ChartPresenter::LineChartZValue);
17 17 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
18 18
19 19 handleUpdated();
20 20 }
21 21
22 22 QRectF LineChartItem::boundingRect() const
23 23 {
24 24 return m_rect;
25 25 }
26 26
27 27 QPainterPath LineChartItem::shape() const
28 28 {
29 29 return m_path;
30 30 }
31 31
32 32 void LineChartItem::createPoints(int count)
33 33 {
34 34 for (int i = 0; i < count; ++i) {
35 35 QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3);
36 36 m_items.addToGroup(item);
37 37 }
38 38 }
39 39
40 40 void LineChartItem::deletePoints(int count)
41 41 {
42 42 QList<QGraphicsItem *> items = m_items.childItems();
43 43
44 44 for (int i = 0; i < count; ++i) {
45 45 delete(items.takeLast());
46 46 }
47 47 }
48 48
49 49 void LineChartItem::setGeometry(QVector<QPointF>& points)
50 50 {
51 51 if(points.size()==0) return;
52 52
53 53 int diff = XYChartItem::points().size() - points.size();
54 54
55 55 if(diff>0) {
56 56 deletePoints(diff);
57 57 }
58 58 else if(diff<0) {
59 59 createPoints(-diff);
60 60 }
61 61
62 62 QList<QGraphicsItem*> items = m_items.childItems();
63 63
64 64 QPainterPath path;
65 65 const QPointF& point = points.at(0);
66 66 path.moveTo(point);
67 67 QGraphicsItem* item = items.at(0);
68 68 item->setPos(point.x()-1,point.y()-1);
69 69 if(!clipRect().contains(point)) {
70 70 item->setVisible(false);
71 71 }
72 72 else {
73 73 item->setVisible(true);
74 74 }
75 75
76 76 for(int i=1; i< points.size();i++) {
77 77 QGraphicsItem* item = items.at(i);
78 78 const QPointF& point = points.at(i);
79 79 item->setPos(point.x()-1,point.y()-1);
80 80 if(!clipRect().contains(point)) {
81 81 item->setVisible(false);
82 82 }
83 83 else {
84 84 item->setVisible(true);
85 85 }
86 86 path.lineTo(point);
87 87 }
88 88
89 89 prepareGeometryChange();
90 90 m_path = path;
91 91 m_rect = path.boundingRect();
92 92
93 93 XYChartItem::setGeometry(points);
94 94 }
95 95
96 void LineChartItem::setPen(const QPen& pen)
96 void LineChartItem::setLinePen(const QPen& pen)
97 97 {
98 98 m_pen = pen;
99 99 }
100 100
101
102 101 void LineChartItem::handleUpdated()
103 102 {
104 103 m_items.setVisible(m_series->pointsVisible());
105 setPen(m_series->pen());
104 setLinePen(m_series->pen());
106 105 update();
107 106 }
108 107
109 108 //painter
110 109
111 110 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
112 111 {
113 112 Q_UNUSED(widget);
114 113 Q_UNUSED(option);
115 114 painter->save();
116 115 painter->setPen(m_pen);
117 116 painter->setClipRect(clipRect());
118 117 painter->drawPath(m_path);
119 118 painter->restore();
120 119 }
121 120
122 121 #include "moc_linechartitem_p.cpp"
123 122
124 123 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,51 +1,54
1 1 #ifndef LINECHARTITEM_H
2 2 #define LINECHARTITEM_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "xychartitem_p.h"
6 #include "xychartanimationitem_p.h"
6 7 #include <QPen>
7 8
8 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 10
10 11 class ChartPresenter;
11 12 class QLineSeries;
12 13
13 14 class LineChartItem : public XYChartItem
14 15 {
15 16 Q_OBJECT
16 17 public:
17 18 explicit LineChartItem(QLineSeries* series,QGraphicsItem *parent = 0);
18 19 ~ LineChartItem(){};
19 20
20 21 //from QGraphicsItem
21 22 QRectF boundingRect() const;
22 23 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
23 24 QPainterPath shape() const;
24 25
25 void setPen(const QPen& pen);
26 void setLinePen(const QPen& pen);
26 27 void setPointsVisible(bool visible);
27 28
28 29 public slots:
29 30 void handleUpdated();
30 31
31 32 protected:
32 33 virtual void setGeometry(QVector<QPointF>& points);
33 34
34 35 private:
35 36 void createPoints(int count);
36 37 void deletePoints(int count);
37 38
38 39 private:
39 40 QLineSeries* m_series;
40 41 QGraphicsItemGroup m_items;
41 42 QPainterPath m_path;
42 43 QRectF m_rect;
43 44 QPen m_pen;
44 45
45 friend class LineChartAnimatator;
46 template<class,class> friend class XYChartAnimator;
46 47
47 48 };
48 49
50 typedef XYChartAnimationItem<LineChartItem,QLineSeries> LineChartAnimationItem;
51
49 52 QTCOMMERCIALCHART_END_NAMESPACE
50 53
51 54 #endif
@@ -1,277 +1,288
1 1 #include "qchart.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartdataset_p.h"
5 5 #include <QGraphicsScene>
6 6 #include <QGraphicsSceneResizeEvent>
7 7 #include <QDebug>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 /*!
12 12 \enum QChart::ChartTheme
13 13
14 14 This enum describes the theme used by the chart.
15 15
16 16 \value ChartThemeDefault
17 17 \value ChartThemeVanilla
18 18 \value ChartThemeIcy
19 19 \value ChartThemeGrayscale
20 20 \value ChartThemeScientific
21 21 */
22 22
23 23 /*!
24 24 \enum QChart::AnimationOption
25 25
26 26 For enabling/disabling animations. Defaults to NoAnimation.
27 27
28 28 \value NoAnimation
29 29 \value GridAxisAnimations
30 30 \value SeriesAnimations
31 31 \value AllAnimations
32 32 */
33 33
34 34 /*!
35 35 \class QChart
36 36 \brief QtCommercial chart API.
37 37
38 38 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
39 39 representation of different types of QChartSeries and other chart related objects like
40 40 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
41 41 convenience class QChartView instead of QChart.
42 42 \sa QChartView
43 43 */
44 44
45 45 /*!
46 46 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
47 47 */
48 48 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
49 49 m_backgroundItem(0),
50 50 m_titleItem(0),
51 51 m_dataset(new ChartDataSet(this)),
52 52 m_presenter(new ChartPresenter(this,m_dataset))
53 53 {
54 54 }
55 55
56 56 /*!
57 57 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
58 58 */
59 59 QChart::~QChart()
60 60 {
61 61 }
62 62
63 63 /*!
64 64 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
65 65 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
66 66 the y axis).
67 67 */
68 68 void QChart::addSeries(QSeries* series, QChartAxis* axisY)
69 69 {
70 70 m_dataset->addSeries(series, axisY);
71 71 }
72 72
73 73 /*!
74 74 Removes the \a series specified in a perameter from the QChartView.
75 75 It releses its ownership of the specified QChartSeries object.
76 76 It does not delete the pointed QChartSeries data object
77 77 \sa addSeries(), removeAllSeries()
78 78 */
79 79 void QChart::removeSeries(QSeries* series)
80 80 {
81 81 m_dataset->removeSeries(series);
82 82 }
83 83
84 84 /*!
85 85 Removes all the QChartSeries that have been added to the QChartView
86 86 It also deletes the pointed QChartSeries data objects
87 87 \sa addSeries(), removeSeries()
88 88 */
89 89 void QChart::removeAllSeries()
90 90 {
91 91 m_dataset->removeAllSeries();
92 92 }
93 93
94 94 /*!
95 95 Sets the \a brush that is used for painting the background of the chart area.
96 96 */
97 97 void QChart::setChartBackgroundBrush(const QBrush& brush)
98 98 {
99 99 createChartBackgroundItem();
100 100 m_backgroundItem->setBrush(brush);
101 101 m_backgroundItem->update();
102 102 }
103 103
104 104 /*!
105 105 Sets the \a pen that is used for painting the background of the chart area.
106 106 */
107 107 void QChart::setChartBackgroundPen(const QPen& pen)
108 108 {
109 109 createChartBackgroundItem();
110 110 m_backgroundItem->setPen(pen);
111 111 m_backgroundItem->update();
112 112 }
113 113
114 114 /*!
115 115 Sets the chart \a title. The description text that is rendered above the chart.
116 116 */
117 117 void QChart::setChartTitle(const QString& title)
118 118 {
119 119 createChartTitleItem();
120 m_titleItem->setPlainText(title);
120 m_titleItem->setText(title);
121 }
122
123 /*!
124 Gets the chart \a title. The description text that is rendered above the chart.
125 */
126 QString QChart::chartTitle() const
127 {
128 if(m_titleItem)
129 return m_titleItem->text();
130 else
131 return QString();
121 132 }
122 133
123 134 /*!
124 135 Sets the \a font that is used for rendering the description text that is rendered above the chart.
125 136 */
126 137 void QChart::setChartTitleFont(const QFont& font)
127 138 {
128 139 createChartTitleItem();
129 140 m_titleItem->setFont(font);
130 141 }
131 142
132 143 void QChart::createChartBackgroundItem()
133 144 {
134 145 if(!m_backgroundItem) {
135 146 m_backgroundItem = new QGraphicsRectItem(this);
136 147 m_backgroundItem->setPen(Qt::NoPen);
137 148 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
138 149 }
139 150 }
140 151
141 152 void QChart::createChartTitleItem()
142 153 {
143 154 if(!m_titleItem) {
144 m_titleItem = new QGraphicsTextItem(this);
155 m_titleItem = new QGraphicsSimpleTextItem(this);
145 156 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
146 157 }
147 158 }
148 159
149 160 /*!
150 161 Returns the chart margin, which is the distance between the widget edge and the part of the chart where the actual data can be displayed.
151 162 \sa setMargin()
152 163 */
153 164 int QChart::margin() const
154 165 {
155 166 return m_presenter->margin();
156 167 }
157 168
158 169 /*!
159 170 Sets the chart \a margin, which is the distance between the widget edge and the part of the chart where the actual data can be displayed.
160 171 \sa margin()
161 172 */
162 173 void QChart::setMargin(int margin)
163 174 {
164 175 m_presenter->setMargin(margin);
165 176 }
166 177
167 178 /*!
168 179 Sets the \a theme used by the chart for rendering the graphical representation of the data
169 180 \sa ChartTheme, chartTheme()
170 181 */
171 182 void QChart::setChartTheme(QChart::ChartTheme theme)
172 183 {
173 184 m_presenter->setChartTheme(theme);
174 185 }
175 186
176 187 /*!
177 188 Returns the theme enum used by the chart.
178 189 \sa ChartTheme, setChartTheme()
179 190 */
180 191 QChart::ChartTheme QChart::chartTheme() const
181 192 {
182 193 return m_presenter->chartTheme();
183 194 }
184 195
185 196 /*!
186 197 Zooms in the view by a factor of 2
187 198 */
188 199 void QChart::zoomIn()
189 200 {
190 201 m_presenter->zoomIn();
191 202 }
192 203
193 204 /*!
194 205 Zooms in the view to a maximum level at which \a rect is still fully visible.
195 206 */
196 207 void QChart::zoomIn(const QRectF& rect)
197 208 {
198 209
199 210 if(!rect.isValid()) return;
200 211 m_presenter->zoomIn(rect);
201 212 }
202 213
203 214 /*!
204 215 Restores the view zoom level to the previous one.
205 216 */
206 217 void QChart::zoomOut()
207 218 {
208 219 m_presenter->zoomOut();
209 220 }
210 221
211 222 /*!
212 223 Resets to the default view.
213 224 */
214 225 void QChart::zoomReset()
215 226 {
216 227 m_presenter->zoomReset();
217 228 }
218 229
219 230 /*!
220 231 Returns the pointer to the x axis object of the chart
221 232 */
222 233 QChartAxis* QChart::axisX() const
223 234 {
224 235 return m_dataset->axisX();
225 236 }
226 237
227 238 /*!
228 239 Returns the pointer to the y axis object of the chart
229 240 */
230 241 QChartAxis* QChart::axisY() const
231 242 {
232 243 return m_dataset->axisY();
233 244 }
234 245
235 246 /*!
236 247 Resizes and updates the chart area using the \a event data
237 248 */
238 249 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
239 250 {
240 251
241 252 m_rect = QRectF(QPoint(0,0),event->newSize());
242 253 QRectF rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
243 254
244 255 // recalculate title position
245 256 if (m_titleItem) {
246 257 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
247 258 m_titleItem->setPos(center.x(),m_rect.top()/2 + margin()/2);
248 259 }
249 260
250 261 //recalculate background gradient
251 262 if (m_backgroundItem) {
252 263 m_backgroundItem->setRect(rect);
253 264 }
254 265
255 266 QGraphicsWidget::resizeEvent(event);
256 267 update();
257 268 }
258 269
259 270 /*!
260 271 Sets animation \a options for the chart
261 272 */
262 273 void QChart::setAnimationOptions(AnimationOptions options)
263 274 {
264 275 m_presenter->setAnimationOptions(options);
265 276 }
266 277
267 278 /*!
268 279 Returns animation options for the chart
269 280 */
270 281 QChart::AnimationOptions QChart::animationOptions() const
271 282 {
272 283 return m_presenter->animationOptions();
273 284 }
274 285
275 286 #include "moc_qchart.cpp"
276 287
277 288 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,95 +1,96
1 1 #ifndef QCHART_H
2 2 #define QCHART_H
3 3
4 4 #include <qchartglobal.h>
5 5 #include <qseries.h>
6 6 #include <QGraphicsWidget>
7 7 #include <QLinearGradient>
8 8 #include <QFont>
9 9
10 10 class QGraphicsSceneResizeEvent;
11 11
12 12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 13
14 14 class AxisItem;
15 15 class QSeries;
16 16 class PlotDomain;
17 17 class BarPresenter;
18 18 class QChartAxis;
19 19 class ChartTheme;
20 20 class ChartItem;
21 21 class ChartDataSet;
22 22 class ChartPresenter;
23 23
24 24 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
25 25 {
26 26 Q_OBJECT
27 27 public:
28 28 enum ChartTheme {
29 29 ChartThemeDefault,
30 30 ChartThemeVanilla,
31 31 ChartThemeIcy,
32 32 ChartThemeGrayscale,
33 33 ChartThemeScientific
34 34 //ChartThemeUnnamed1
35 35 /*! The default theme follows the GUI style of the Operating System */
36 36 };
37 37
38 38 enum AnimationOption {
39 39 NoAnimation = 0x0,
40 40 GridAxisAnimations = 0x1,
41 41 SeriesAnimations =0x2,
42 42 AllAnimations = 0x3
43 43 };
44 44 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
45 45
46 46 public:
47 47 QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
48 48 ~QChart();
49 49
50 50 void addSeries(QSeries* series, QChartAxis* axisY = 0);
51 51 void removeSeries(QSeries* series); //returns ownership , deletes axis if no series attached
52 52 void removeAllSeries(); // deletes series and axis
53 53
54 54 void setMargin(int margin);
55 55 int margin() const;
56 56 void setChartTheme(QChart::ChartTheme theme);
57 57 QChart::ChartTheme chartTheme() const;
58 58
59 59 void setChartTitle(const QString& title);
60 QString chartTitle() const;
60 61 void setChartTitleFont(const QFont& font);
61 62 void setChartBackgroundBrush(const QBrush& brush);
62 63 void setChartBackgroundPen(const QPen& pen);
63 64
64 65 void setAnimationOptions(AnimationOptions options);
65 66 AnimationOptions animationOptions() const;
66 67
67 68 void zoomIn();
68 69 void zoomIn(const QRectF& rect);
69 70 void zoomOut();
70 71 void zoomReset();
71 72
72 73 QChartAxis* axisX() const;
73 74 QChartAxis* axisY() const;
74 75
75 76 protected:
76 77 void resizeEvent(QGraphicsSceneResizeEvent *event);
77 78
78 79 private:
79 80 inline void createChartBackgroundItem();
80 81 inline void createChartTitleItem();
81 82
82 83 private:
83 84 Q_DISABLE_COPY(QChart)
84 85 QGraphicsRectItem* m_backgroundItem;
85 QGraphicsTextItem* m_titleItem;
86 QGraphicsSimpleTextItem* m_titleItem;
86 87 QRectF m_rect;
87 88 ChartDataSet *m_dataset;
88 89 ChartPresenter *m_presenter;
89 90 };
90 91
91 92 QTCOMMERCIALCHART_END_NAMESPACE
92 93
93 94 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
94 95
95 96 #endif
@@ -1,351 +1,359
1 1 #include "qchartview.h"
2 2 #include "qchart.h"
3 3 #include "qchartaxis.h"
4 4 #include <QGraphicsView>
5 5 #include <QGraphicsScene>
6 6 #include <QRubberBand>
7 7 #include <QResizeEvent>
8 8 #include <QDebug>
9 9
10 10 /*!
11 11 \enum QChartView::RubberBandPolicy
12 12
13 13 This enum describes the different types of rubber bands that can be used for zoom rect selection
14 14
15 15 \value NoRubberBand
16 16 \value VerticalRubberBand
17 17 \value HorizonalRubberBand
18 18 \value RectangleRubberBand
19 19 */
20 20
21 21 /*!
22 22 \class QChartView
23 23 \brief Standalone charting widget.
24 24
25 25 QChartView is a standalone widget that can display charts. It does not require separate
26 26 QGraphicsScene to work. It manages the graphical representation of different types of
27 27 QChartSeries and other chart related objects like QChartAxis and QChartLegend. If you want to
28 28 display a chart in your existing QGraphicsScene, you can use the QChart class instead.
29 29
30 30 \sa QChart
31 31 */
32 32
33 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 34
35 35 /*!
36 36 Constructs a chartView object which is a child of a\a parent.
37 37 */
38 38 QChartView::QChartView(QWidget *parent) :
39 39 QGraphicsView(parent),
40 40 m_scene(new QGraphicsScene(this)),
41 41 m_chart(new QChart()),
42 42 m_rubberBand(0),
43 43 m_verticalRubberBand(false),
44 44 m_horizonalRubberBand(false)
45 45 {
46 46 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
47 47 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
48 48 setScene(m_scene);
49 49 m_chart->setMargin(50);
50 50 m_scene->addItem(m_chart);
51 51 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
52 52 }
53 53
54 54
55 55 /*!
56 56 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
57 57 */
58 58 QChartView::~QChartView()
59 59 {
60 60 }
61 61
62 62 /*!
63 63 Resizes and updates the chart area using the \a event data
64 64 */
65 65 void QChartView::resizeEvent(QResizeEvent *event)
66 66 {
67 67 m_scene->setSceneRect(0,0,size().width(),size().height());
68 68 m_chart->resize(size());
69 69 QWidget::resizeEvent(event);
70 70 }
71 71
72 72 /*!
73 73 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
74 74 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
75 75 the y axis).
76 76 \sa removeSeries(), removeAllSeries()
77 77 */
78 78 void QChartView::addSeries(QSeries* series,QChartAxis *axisY)
79 79 {
80 80 m_chart->addSeries(series,axisY);
81 81 }
82 82
83 83 /*!
84 84 Removes the \a series specified in a perameter from the QChartView.
85 85 It releses its ownership of the specified QChartSeries object.
86 86 It does not delete the pointed QChartSeries data object
87 87 \sa addSeries(), removeAllSeries()
88 88 */
89 89 void QChartView::removeSeries(QSeries* series)
90 90 {
91 91 m_chart->removeSeries(series);
92 92 }
93 93
94 94 /*!
95 95 Removes all the QChartSeries that have been added to the QChartView
96 96 It also deletes the pointed QChartSeries data objects
97 97 \sa addSeries(), removeSeries()
98 98 */
99 99 void QChartView::removeAllSeries()
100 100 {
101 101 m_chart->removeAllSeries();
102 102 }
103 103
104 104 /*!
105 105 Zooms in the view by a factor of 2
106 106 */
107 107 void QChartView::zoomIn()
108 108 {
109 109 m_chart->zoomIn();
110 110 }
111 111
112 112 /*!
113 113 Zooms in the view to a maximum level at which \a rect is still fully visible.
114 114 */
115 115 void QChartView::zoomIn(const QRect& rect)
116 116 {
117 117 m_chart->zoomIn(rect);
118 118 }
119 119
120 120 /*!
121 121 Restores the view zoom level to the previous one.
122 122 */
123 123 void QChartView::zoomOut()
124 124 {
125 125 m_chart->zoomOut();
126 126 }
127 127
128 128 /*!
129 129 Returns the chart margin, which is the distance between the widget edge and the part of the chart where the actual data can be displayed.
130 130 */
131 131 int QChartView::margin() const
132 132 {
133 133 return m_chart->margin();
134 134 }
135 135
136 136 /*!
137 137 Sets the chart \a title. A description text that is rendered above the chart.
138 138 */
139 139 void QChartView::setChartTitle(const QString& title)
140 140 {
141 141 m_chart->setChartTitle(title);
142 142 }
143 143
144 144 /*!
145 Gets the chart \a title. A description text that is rendered above the chart.
146 */
147 QString QChartView::chartTitle() const
148 {
149 return m_chart->chartTitle();
150 }
151
152 /*!
145 153 Sets the \a font that is used for rendering the description text that is rendered above the chart.
146 154 */
147 155 void QChartView::setChartTitleFont(const QFont& font)
148 156 {
149 157 m_chart->setChartTitleFont(font);
150 158 }
151 159
152 160 /*!
153 161 Sets the \a brush that is used for painting the background of the chart area of the QChartView widget.
154 162 */
155 163 void QChartView::setChartBackgroundBrush(const QBrush& brush)
156 164 {
157 165 m_chart->setChartBackgroundBrush(brush);
158 166 }
159 167
160 168 /*!
161 169 Sets the \a pen that is used for painting the background of the chart area of the QChartView widget.
162 170 */
163 171 void QChartView::setChartBackgroundPen(const QPen& pen)
164 172 {
165 173 m_chart->setChartBackgroundPen(pen);
166 174 }
167 175
168 176 /*!
169 177 Sets the RubberBandPlicy to \a policy. Selected policy determines the way zooming is performed.
170 178 */
171 179 void QChartView::setRubberBandPolicy(const RubberBandPolicy policy)
172 180 {
173 181 switch(policy) {
174 182 case VerticalRubberBand:
175 183 m_verticalRubberBand = true;
176 184 m_horizonalRubberBand = false;
177 185 break;
178 186 case HorizonalRubberBand:
179 187 m_verticalRubberBand = false;
180 188 m_horizonalRubberBand = true;
181 189 break;
182 190 case RectangleRubberBand:
183 191 m_verticalRubberBand = true;
184 192 m_horizonalRubberBand = true;
185 193 break;
186 194 case NoRubberBand:
187 195 default:
188 196 delete m_rubberBand;
189 197 m_rubberBand=0;
190 198 m_horizonalRubberBand = false;
191 199 m_verticalRubberBand = false;
192 200 return;
193 201 }
194 202 if(!m_rubberBand) {
195 203 m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
196 204 m_rubberBand->setEnabled(true);
197 205 }
198 206 }
199 207
200 208 /*!
201 209 Returns the RubberBandPolicy that is currently being used by the widget.
202 210 */
203 211 QChartView::RubberBandPolicy QChartView::rubberBandPolicy() const
204 212 {
205 213 if(m_horizonalRubberBand && m_verticalRubberBand) return RectangleRubberBand;
206 214 if(m_horizonalRubberBand) return HorizonalRubberBand;
207 215 if(m_verticalRubberBand) return VerticalRubberBand;
208 216 return NoRubberBand;
209 217 }
210 218
211 219 /*!
212 220 If Left mouse button is pressed and the RubberBandPolicy is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
213 221 If different mouse button is pressed and/or the RubberBandPolicy is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
214 222 */
215 223 void QChartView::mousePressEvent(QMouseEvent *event)
216 224 {
217 225 if(m_rubberBand && m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) {
218 226
219 227 int margin = m_chart->margin();
220 228 QRect rect(margin, margin, width() - 2 * margin, height() - 2 * margin);
221 229
222 230 if (rect.contains(event->pos())) {
223 231 m_rubberBandOrigin = event->pos();
224 232 m_rubberBand->setGeometry(QRect(m_rubberBandOrigin, QSize()));
225 233 m_rubberBand->show();
226 234 event->accept();
227 235 }
228 236 }
229 237 else {
230 238 QGraphicsView::mousePressEvent(event);
231 239 }
232 240 }
233 241
234 242 /*!
235 243 If RubberBand rectange specification has been initiated in pressEvent then \a event data is used to update RubberBand geometry.
236 244 In other case the defualt QGraphicsView::mouseMoveEvent implementation is called.
237 245 */
238 246 void QChartView::mouseMoveEvent(QMouseEvent *event)
239 247 {
240 248 if(m_rubberBand && m_rubberBand->isVisible()) {
241 249 int margin = m_chart->margin();
242 250 QRect rect(margin, margin, width() - 2 * margin, height() - 2 * margin);
243 251 int width = event->pos().x() - m_rubberBandOrigin.x();
244 252 int height = event->pos().y() - m_rubberBandOrigin.y();
245 253 if(!m_verticalRubberBand) {
246 254 m_rubberBandOrigin.setY(rect.top());
247 255 height = rect.height();
248 256 }
249 257 if(!m_horizonalRubberBand) {
250 258 m_rubberBandOrigin.setX(rect.left());
251 259 width= rect.width();
252 260 }
253 261 m_rubberBand->setGeometry(QRect(m_rubberBandOrigin.x(),m_rubberBandOrigin.y(), width,height).normalized());
254 262 }
255 263 else {
256 264 QGraphicsView::mouseMoveEvent(event);
257 265 }
258 266 }
259 267
260 268 /*!
261 269 If left mouse button is release and RubberBand is enabled then \a event is accepted and the view is zoomed in to rect specified by RubberBand
262 270 If it is the right mouse button \a event then RubberBand is dissmissed and zoom is canceled.
263 271 */
264 272 void QChartView::mouseReleaseEvent(QMouseEvent *event)
265 273 {
266 274 if(m_rubberBand) {
267 275 if (event->button() == Qt::LeftButton && m_rubberBand->isVisible()) {
268 276 m_rubberBand->hide();
269 277 QRect rect = m_rubberBand->geometry();
270 278 m_chart->zoomIn(rect);
271 279 event->accept();
272 280 }
273 281
274 282 if(event->button()==Qt::RightButton)
275 283 m_chart->zoomReset();
276 284 }
277 285 else {
278 286 QGraphicsView::mouseReleaseEvent(event);
279 287 }
280 288 }
281 289
282 290 /*!
283 291 Pressing + and - keys performs zoomIn() and zoomOut() respectivly.
284 292 In other \a event is passed to the QGraphicsView::keyPressEvent() implementation
285 293 */
286 294 void QChartView::keyPressEvent(QKeyEvent *event)
287 295 {
288 296 switch (event->key()) {
289 297 case Qt::Key_Plus:
290 298 zoomIn();
291 299 break;
292 300 case Qt::Key_Minus:
293 301 zoomOut();
294 302 break;
295 303 default:
296 304 QGraphicsView::keyPressEvent(event);
297 305 break;
298 306 }
299 307 }
300 308
301 309 /*!
302 310 Sets the \a theme used by the chart for rendering the graphical representation of the data
303 311 \sa QChart::ChartTheme, chartTheme()
304 312 */
305 313 void QChartView::setChartTheme(QChart::ChartTheme theme)
306 314 {
307 315 m_chart->setChartTheme(theme);
308 316 }
309 317
310 318 /*!
311 319 Returns the theme enum used by the chart.
312 320 \sa setChartTheme()
313 321 */
314 322 QChart::ChartTheme QChartView::chartTheme() const
315 323 {
316 324 return m_chart->chartTheme();
317 325 }
318 326
319 327 /*!
320 328 Returns the pointer to the x axis object of the chart
321 329 */
322 330 QChartAxis* QChartView::axisX() const
323 331 {
324 332 return m_chart->axisX();
325 333 }
326 334
327 335 /*!
328 336 Returns the pointer to the y axis object of the chart
329 337 */
330 338 QChartAxis* QChartView::axisY() const
331 339 {
332 340 return m_chart->axisY();
333 341 }
334 342
335 343 /*!
336 344 Sets animation \a options for the chart
337 345 */
338 346 void QChartView::setAnimationOptions(QChart::AnimationOptions options)
339 347 {
340 348 m_chart->setAnimationOptions(options);
341 349 }
342 350
343 351 /*!
344 352 Returns animation options for the chart
345 353 */
346 354 QChart::AnimationOptions QChartView::animationOptions() const
347 355 {
348 356 return m_chart->animationOptions();
349 357 }
350 358
351 359 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,74 +1,75
1 1 #ifndef QCHARTWIDGET_H
2 2 #define QCHARTWIDGET_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "qseries.h"
6 6 #include "qchart.h"
7 7 #include <QGraphicsView>
8 8
9 9 class QGraphicsScene;
10 10 class QRubberBand;
11 11
12 12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 13
14 14 class QChart;
15 15
16 16 class QTCOMMERCIALCHART_EXPORT QChartView : public QGraphicsView
17 17 {
18 18 public:
19 19 enum RubberBandPolicy { NoRubberBand, VerticalRubberBand, HorizonalRubberBand, RectangleRubberBand };
20 20
21 21 explicit QChartView(QWidget *parent = 0);
22 22 ~QChartView();
23 23
24 24 //implement from QWidget
25 25 void resizeEvent(QResizeEvent *event);
26 26
27 27 void addSeries(QSeries* series,QChartAxis* axisY=0);// takes series ownership , takes axis ownership
28 28 void removeSeries(QSeries* series); //returns ownership , deletes axis if no series attached
29 29 void removeAllSeries(); // deletes series and axis
30 30 int margin() const;
31 31
32 32 void setChartTitle(const QString& title);
33 QString chartTitle() const;
33 34 void setChartTitleFont(const QFont& font);
34 35 void setChartBackgroundBrush(const QBrush& brush);
35 36 void setChartBackgroundPen(const QPen& pen);
36 37
37 38 void zoomIn();
38 39 void zoomIn(const QRect& rect);
39 40 void zoomOut();
40 41
41 42 void setRubberBandPolicy(const RubberBandPolicy );
42 43 RubberBandPolicy rubberBandPolicy() const;
43 44
44 45 void setChartTheme(QChart::ChartTheme theme);
45 46 QChart::ChartTheme chartTheme() const;
46 47
47 48 void setAnimationOptions(QChart::AnimationOptions options);
48 49 QChart::AnimationOptions animationOptions() const;
49 50
50 51 QChartAxis* axisX() const;
51 52 QChartAxis* axisY() const;
52 53
53 54 protected:
54 55 void mousePressEvent(QMouseEvent *event);
55 56 void mouseMoveEvent(QMouseEvent *event);
56 57 void mouseReleaseEvent(QMouseEvent *event);
57 58 void keyPressEvent(QKeyEvent *event);
58 59
59 60
60 61 private:
61 62 QGraphicsScene *m_scene;
62 63 QChart* m_chart;
63 64 QPoint m_rubberBandOrigin;
64 65 QRubberBand* m_rubberBand;
65 66 bool m_verticalRubberBand;
66 67 bool m_horizonalRubberBand;
67 68 Q_DISABLE_COPY(QChartView)
68 69
69 70
70 71 };
71 72
72 73 QTCOMMERCIALCHART_END_NAMESPACE
73 74
74 75 #endif // QCHARTWIDGET_H
@@ -1,178 +1,178
1 1 #include "scatterchartitem_p.h"
2 2 #include "qscatterseries.h"
3 3 #include "chartpresenter_p.h"
4 4 #include <QPainter>
5 5 #include <QGraphicsScene>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 ScatterChartItem::ScatterChartItem(QScatterSeries *series, QGraphicsObject *parent) :
9 ScatterChartItem::ScatterChartItem(QScatterSeries *series, QGraphicsItem *parent) :
10 10 XYChartItem(series,parent),
11 11 m_series(series),
12 12 m_items(this),
13 13 m_shape(QScatterSeries::MarkerShapeRectangle),
14 14 m_size(10)
15 15
16 16 {
17 17 Q_ASSERT(parent);
18 18 Q_ASSERT(series);
19 19
20 20 connect(m_series,SIGNAL(updated()), this, SLOT(handleUpdated()));
21 21
22 22 setZValue(ChartPresenter::ScatterSeriesZValue);
23 23 setFlags(QGraphicsItem::ItemHasNoContents);
24 24 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
25 25
26 26 handleUpdated();
27 27
28 28 // TODO: how to draw a drop shadow?
29 29 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
30 30 // dropShadow->setOffset(2.0);
31 31 // dropShadow->setBlurRadius(2.0);
32 32 // setGraphicsEffect(dropShadow);
33 33 }
34 34
35 35
36 36 QRectF ScatterChartItem::boundingRect() const
37 37 {
38 38 return m_rect;
39 39 }
40 40
41 41 void ScatterChartItem::createPoints(int count)
42 42 {
43 43 for (int i = 0; i < count; ++i) {
44 44
45 45 QGraphicsItem *item;
46 46
47 47 switch (m_shape) {
48 48 case QScatterSeries::MarkerShapeDefault:
49 49 // Fallthrough, defaults to circle
50 50 case QScatterSeries::MarkerShapeCircle:
51 51 item = new QGraphicsEllipseItem(0,0,m_size,m_size);
52 52 break;
53 53 case QScatterSeries::MarkerShapeRectangle:
54 54 item = new QGraphicsRectItem(0,0,m_size,m_size);
55 55 break;
56 56 case QScatterSeries::MarkerShapeRoundedRectangle:
57 57 //m_path.addRoundedRect(x, y, size, size, size / 4.0, size / 4.0);
58 58 break;
59 59 case QScatterSeries::MarkerShapeTiltedRectangle:
60 60 // TODO: tilt the rectangle
61 61 //m_path.addRect(x, y, size, size);
62 62 //break;
63 63 case QScatterSeries::MarkerShapeTriangle:
64 64 //QPolygonF polygon;
65 65 //polygon << QPointF(0.0, -size) << QPointF(size / 2.0, 0.0) << QPointF(-size / 2, 0.0);
66 66 // TODO: the position is not exactly right...
67 67 //m_path.addPolygon(polygon.translated(x + size / 2.0, y + size));
68 68 break;
69 69 }
70 70 m_items.addToGroup(item);
71 71 }
72 72 }
73 73
74 74 void ScatterChartItem::deletePoints(int count)
75 75 {
76 76 QList<QGraphicsItem *> items = m_items.childItems();
77 77
78 78 for (int i = 0; i < count; ++i) {
79 79 delete(items.takeLast());
80 80 }
81 81 }
82 82
83 83 /*
84 84
85 85 void ScatterChartItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
86 86 {
87 87
88 88 QPointF clickedPoint(
89 89 m_minX + (event->lastPos().x() / m_clippingRect.width()) * (m_maxX-m_minX),
90 90 m_maxY - (event->lastPos().y() / m_clippingRect.height()) * (m_maxY-m_minY));
91 91 emit clicked(clickedPoint);
92 92
93 93 }
94 94 */
95 95
96 96 void ScatterChartItem::setGeometry(QVector<QPointF>& points)
97 97 {
98 98 if(points.size()==0) return;
99 99
100 100 int diff = XYChartItem::points().size() - points.size();
101 101
102 102 if(diff>0) {
103 103 deletePoints(diff);
104 104 }
105 105 else if(diff<0) {
106 106 createPoints(-diff);
107 107 }
108 108
109 109 if(diff!=0) handleUpdated();
110 110
111 111 QList<QGraphicsItem*> items = m_items.childItems();
112 112
113 113 for(int i=0; i< points.size();i++) {
114 114 QGraphicsItem* item = items.at(i);
115 115 const QPointF& point = points.at(i);
116 116 item->setPos(point.x()-1,point.y()-1);
117 117 if(!clipRect().contains(point)) {
118 118 item->setVisible(false);
119 119 }
120 120 else {
121 121 item->setVisible(true);
122 122 }
123 123 }
124 124
125 125 prepareGeometryChange();
126 126 m_rect = clipRect();
127 127 XYChartItem::setGeometry(points);
128 128 }
129 129
130 130
131 131 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
132 132 {
133 133 Q_UNUSED(painter);
134 134 Q_UNUSED(option);
135 135 Q_UNUSED(widget);
136 136 }
137 137
138 138 void ScatterChartItem::setPen(const QPen& pen)
139 139 {
140 140 foreach(QGraphicsItem* item , m_items.childItems()) {
141 141 static_cast<QAbstractGraphicsShapeItem*>(item)->setPen(pen);
142 142 }
143 143 }
144 144
145 145 void ScatterChartItem::setBrush(const QBrush& brush)
146 146 {
147 147 foreach(QGraphicsItem* item , m_items.childItems()) {
148 148 static_cast<QAbstractGraphicsShapeItem*>(item)->setBrush(brush);
149 149 }
150 150 }
151 151
152 152 void ScatterChartItem::handleUpdated()
153 153 {
154 154
155 155 int count = m_items.childItems().count();
156 156
157 157 if(count==0) return;
158 158
159 159 bool recreate = m_size != m_series->size() || m_shape != m_series->shape();
160 160
161 161 //TODO: only rewrite on size change
162 162
163 163 m_size = m_series->size();
164 164 m_shape = m_series->shape();
165 165
166 166 if(recreate){
167 167 deletePoints(count);
168 168 createPoints(count);
169 169 }
170 170
171 171 setPen(m_series->pen());
172 172 setBrush(m_series->brush());
173 173
174 174 }
175 175
176 176 #include "moc_scatterchartitem_p.cpp"
177 177
178 178 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,50 +1,55
1 1 #ifndef SCATTERPRESENTER_H
2 2 #define SCATTERPRESENTER_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "xychartitem_p.h"
6 #include <QObject>
6 #include "xychartanimationitem_p.h"
7 #include <QGraphicsItem>
7 8 #include <QPen>
8 9
9 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 11
11 12 class QScatterSeries;
12 13
13 14 class ScatterChartItem : public XYChartItem
14 15 {
15 16 Q_OBJECT
16 17 public:
17 explicit ScatterChartItem(QScatterSeries *series, QGraphicsObject *parent = 0);
18 explicit ScatterChartItem(QScatterSeries *series, QGraphicsItem *parent = 0);
18 19
19 20 public:
20 21 //from QGraphicsItem
21 22 QRectF boundingRect() const;
22 23 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
23 24
24 25 void setPen(const QPen& pen);
25 26 void setBrush(const QBrush& brush);
26 27
27 28 signals:
28 29 void clicked(QPointF coordinates);
29 30
30 31 public slots:
31 32 void handleUpdated();
32 33
33 34 private:
34 35 void createPoints(int count);
35 36 void deletePoints(int count);
36 37
37 38 protected:
38 39 virtual void setGeometry(QVector<QPointF>& points);
39 40
40 41 private:
41 42 QScatterSeries *m_series;
42 43 QGraphicsItemGroup m_items;
43 44 int m_shape;
44 45 int m_size;
45 46 QRectF m_rect;
47
48 template<class,class> friend class XYChartAnimator;
46 49 };
47 50
51 typedef XYChartAnimationItem<ScatterChartItem,QScatterSeries> ScatterChartAnimationItem;
52
48 53 QTCOMMERCIALCHART_END_NAMESPACE
49 54
50 55 #endif // SCATTERPRESENTER_H
@@ -1,84 +1,103
1 1 #include "splinechartitem_p.h"
2 #include "chartpresenter_p.h"
2 3 #include <QPainter>
3 4
4 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 6
6 SplineChartItem::SplineChartItem(QSplineSeries* series, QGraphicsObject *parent) :
7 SplineChartItem::SplineChartItem(QSplineSeries* series, QGraphicsItem *parent) :
7 8 XYChartItem(series, parent),
8 9 m_series(series)
9 10 {
11 setZValue(ChartPresenter::LineChartZValue);
12 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
13 handleUpdated();
10 14 }
11 15
12 16 QRectF SplineChartItem::boundingRect() const
13 17 {
14 18 return m_rect;
15 19 }
16 20
17 21 QPainterPath SplineChartItem::shape() const
18 22 {
19 23 return m_path;
20 24 }
21 25
22 26 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
23 27 {
24 28 return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
25 29 }
26 30
27 31 void SplineChartItem::setGeometry(QVector<QPointF>& points)
28 32 {
33
29 34 if(points.size()==0) return;
30 35
31 36 QPainterPath splinePath;
32 37 const QPointF& point = points.at(0);
33 38 splinePath.moveTo(point);
34 39
35 40 for (int i = 0; i < points.size() - 1; i++)
36 41 {
37 42 const QPointF& point = points.at(i + 1);
38 43 splinePath.cubicTo(calculateGeometryControlPoint(2 * i), calculateGeometryControlPoint(2 * i + 1), point);
39 44 }
40 45
41 46 prepareGeometryChange();
42 47 m_path = splinePath;
43 48 m_rect = splinePath.boundingRect();
44 49 XYChartItem::setGeometry(points);
45 50 }
46 51
47 void SplineChartItem::setPen(const QPen& pen)
52 void SplineChartItem::setLinePen(const QPen& pen)
48 53 {
49 54 m_pen = pen;
55 qDebug()<<pen;
50 56 }
51 57
58 //handlers
59
60 void SplineChartItem::handleUpdated()
61 {
62 //m_items.setVisible(m_series->pointsVisible());
63 setLinePen(m_series->pen());
64 update();
65 }
66
67 //painter
52 68
53 69 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
54 70 {
55 71 Q_UNUSED(widget);
56 72 Q_UNUSED(option);
57 73 painter->save();
58 74 painter->setClipRect(clipRect());
75 painter->setPen(m_pen);
59 76 painter->drawPath(m_path);
60 77
61 78 const QVector<QPointF> points = XYChartItem::points();
62 79
63 80 for (int i = 0; i < points.size() - 1; i++)
64 81 {
65 82 painter->setPen(Qt::red);
66 83 painter->drawEllipse(points[i], 2, 2);
67 84
68 85 painter->setPen(Qt::blue);
69 86 // painter->drawLine(m_series->at(i), m_series->controlPoint(2 * i));
70 87 // painter->drawLine(m_series->at(i + 1), m_series->controlPoint(2 * i + 1));
71 88 // painter->drawEllipse(calculateGeometryControlPoint(2 * i), 4, 4);
72 89 // painter->drawEllipse(calculateGeometryControlPoint(2 * i + 1), 4, 4);
73 90 }
74 91 if (points.count() > 0)
75 92 {
76 93 painter->setPen(Qt::red);
77 94 painter->drawEllipse(points[points.count() - 1], 2, 2);
78 95 }
79 96 painter->restore();
80 97 }
81 98
99
100
82 101 #include "moc_splinechartitem_p.cpp"
83 102
84 103 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,40 +1,47
1 1 #ifndef SPLINECHARTITEM_P_H
2 2 #define SPLINECHARTITEM_P_H
3 3
4 #include "chartitem_p.h"
5 #include <QObject>
6 4 #include "qsplineseries.h"
7 5 #include "xychartitem_p.h"
6 #include "xychartanimationitem_p.h"
7 #include <QGraphicsItem>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 class SplineChartItem : public XYChartItem
12 12 {
13 13 Q_OBJECT
14 14 public:
15 SplineChartItem(QSplineSeries* series, QGraphicsObject *parent = 0);
15 SplineChartItem(QSplineSeries* series, QGraphicsItem *parent = 0);
16 16
17 17 //from QGraphicsItem
18 18 QRectF boundingRect() const;
19 19 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
20 20 QPainterPath shape() const;
21 21
22 void setPen(const QPen& pen);
22 void setLinePen(const QPen& pen);
23 23 void setPointsVisible(bool visible);
24 24
25 public slots:
26 void handleUpdated();
27
25 28 protected:
26 29 void setGeometry(QVector<QPointF>& points);
27 30
28 31 private:
29 32 QPointF calculateGeometryControlPoint(int index) const;
30 33
31 34 private:
32 35 QSplineSeries* m_series;
33 36 QPainterPath m_path;
34 37 QRectF m_rect;
35 38 QPen m_pen;
39
40 template<class,class> friend class XYChartAnimator;
36 41 };
37 42
43 typedef XYChartAnimationItem<SplineChartItem,QSplineSeries> SplineChartAnimationItem;
44
38 45 QTCOMMERCIALCHART_END_NAMESPACE
39 46
40 47 #endif // SPLINECHARTITEM_P_H
@@ -1,12 +1,14
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 5 $$PWD/xychartitem.cpp \
6 $$PWD/qxyseries.cpp
6 $$PWD/qxyseries.cpp
7 7
8 8 PRIVATE_HEADERS += \
9 9 $$PWD/xychartitem_p.h \
10 $$PWD/xychartanimationitem_p.h \
11 $$PWD/xychartanimator_p.h
10 12
11 13 PUBLIC_HEADERS += \
12 14 $$PWD/qxyseries.h No newline at end of file
@@ -1,143 +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
59 58 void XYChartItem::updatePoints(QVector<QPointF>& points)
60 59 {
61 60 setGeometry(points);
62 61 }
63 62
64 void XYChartItem::updatePoint(int index,QPointF& newPoint)
63 void XYChartItem::updatePoint(QVector<QPointF>& points)
65 64 {
66 m_points.replace(index,newPoint);
67 setGeometry(m_points);
65 setGeometry(points);
68 66 }
69 67
70 68 void XYChartItem::setGeometry(QVector<QPointF>& points)
71 69 {
72 70 m_points = points;
73 71 }
74 72
75 73 //handlers
76 74
77 75 void XYChartItem::handlePointAdded(int index)
78 76 {
79 77 Q_ASSERT(index<m_series->count());
80 78 Q_ASSERT(index>=0);
81 79
82 80 QPointF point = calculateGeometryPoint(index);
83 81 QVector<QPointF> points = m_points;
84 82 points.insert(index,point);
85 83 updatePoints(points);
86 84 update();
87 85 }
88 86 void XYChartItem::handlePointRemoved(int index)
89 87 {
90 88 Q_ASSERT(index<m_series->count());
91 89 Q_ASSERT(index>=0);
92
93 90 QPointF point = calculateGeometryPoint(index);
94 91 QVector<QPointF> points = m_points;
95 92 points.remove(index);
96 93 updatePoints(points);
97 94 update();
98 95 }
99 96
100 97 void XYChartItem::handlePointReplaced(int index)
101 98 {
102 99 Q_ASSERT(index<m_series->count());
103 100 Q_ASSERT(index>=0);
104 101 QPointF point = calculateGeometryPoint(index);
105 updatePoint(index,point);
102 QVector<QPointF> points = m_points;
103 m_points.replace(index,point);
104 updatePoint(points);
106 105 update();
107 106 }
108 107
109 108 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
110 109 {
111 110 m_minX=minX;
112 111 m_maxX=maxX;
113 112 m_minY=minY;
114 113 m_maxY=maxY;
115 114
116 115 if(isEmpty()) return;
117 116 QVector<QPointF> points = calculateGeometryPoints();
118 117 updatePoints(points);
119 118 update();
120 119 }
121 120
122 121 void XYChartItem::handleGeometryChanged(const QRectF& rect)
123 122 {
124 123 Q_ASSERT(rect.isValid());
125 124 m_size=rect.size();
126 125 m_clipRect=rect.translated(-rect.topLeft());
127 126 setPos(rect.topLeft());
128 127
129 128 if(isEmpty()) return;
130 129 QVector<QPointF> points = calculateGeometryPoints();
131 130 updatePoints(points);
132 131 update();
133 132 }
134 133
135 134
136 135 bool XYChartItem::isEmpty()
137 136 {
138 137 return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ;
139 138 }
140 139
141 140 #include "moc_xychartitem_p.cpp"
142 141
143 142 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,55 +1,58
1 1 #ifndef XYCHARTITEM_H
2 2 #define XYCHARTITEM_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "chartitem_p.h"
6 6 #include <QPen>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class ChartPresenter;
11 11 class QXYSeries;
12 12
13 13 class XYChartItem : public QObject , public ChartItem
14 14 {
15 15 Q_OBJECT
16 16 public:
17 17 explicit XYChartItem(QXYSeries* series,QGraphicsItem *parent = 0);
18 18 ~ XYChartItem(){};
19 19
20 20 QVector<QPointF> points() const {return m_points;}
21 21 QRectF clipRect() const { return m_clipRect;}
22 22
23 23 public slots:
24 24 void handlePointAdded(int index);
25 25 void handlePointRemoved(int index);
26 26 void handlePointReplaced(int index);
27 27 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
28 28 void handleGeometryChanged(const QRectF& size);
29 29
30 30 protected:
31 31 virtual void updatePoints(QVector<QPointF>& points);
32 virtual void updatePoint(int index,QPointF& newPoint);
32 virtual void updatePoint(QVector<QPointF>& points);
33 33 virtual void setGeometry(QVector<QPointF>& points);
34
34 35 QPointF calculateGeometryPoint(const QPointF& point) const;
35 36 QPointF calculateGeometryPoint(int index) const;
36 37 QVector<QPointF> calculateGeometryPoints() const;
37 38
38 39 private:
39 40 inline bool isEmpty();
40 41
41 42 private:
42 43 qreal m_minX;
43 44 qreal m_maxX;
44 45 qreal m_minY;
45 46 qreal m_maxY;
46 47 QXYSeries* m_series;
47 48 QSizeF m_size;
48 49 QRectF m_clipRect;
49 50 QVector<QPointF> m_points;
50 51
52 template<class,class> friend class XYChartAnimator;
53
51 54 };
52 55
53 56 QTCOMMERCIALCHART_END_NAMESPACE
54 57
55 58 #endif
General Comments 0
You need to be logged in to leave comments. Login now