##// END OF EJS Templates
Animation refactor...
Michal Klocek -
r530:d482058261e4
parent child
Show More
@@ -0,0 +1,13
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
3
4 SOURCES += \
5 $$PWD/axisanimation.cpp \
6 $$PWD/chartanimator.cpp \
7 $$PWD/xyanimation.cpp
8
9 PRIVATE_HEADERS += \
10 $$PWD/axisanimation_p.h \
11 $$PWD/chartanimator_p.h \
12 $$PWD/chartanimation_p.h \
13 $$PWD/xyanimation_p.h No newline at end of file
@@ -0,0 +1,45
1 #include "axisanimation_p.h"
2 #include <QTimer>
3
4 Q_DECLARE_METATYPE(QVector<qreal>)
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
8
9 AxisAnimation::AxisAnimation(AxisItem *axis): ChartAnimation(axis),
10 m_axis(axis)
11 {
12 }
13
14 AxisAnimation::~AxisAnimation()
15 {
16 }
17
18 QVariant AxisAnimation::interpolated(const QVariant &start, const QVariant & end, qreal progress ) const
19 {
20 QVector<qreal> startVector = qVariantValue<QVector<qreal> >(start);
21 QVector<qreal> endVecotr = qVariantValue<QVector<qreal> >(end);
22 QVector<qreal> result;
23
24 Q_ASSERT(startVector.count() == endVecotr.count()) ;
25
26 for(int i =0 ;i< startVector.count();i++){
27 qreal value = startVector[i] + ((endVecotr[i]- startVector[i]) * progress);//qBound(0.0, progress, 1.0));
28 result << value;
29 }
30 return qVariantFromValue(result);
31 }
32
33
34 void AxisAnimation::updateCurrentValue (const QVariant & value )
35 {
36 if(state()!=QAbstractAnimation::Stopped)//workaround
37 {
38 QVector<qreal> vector = qVariantValue<QVector<qreal> >(value);
39 Q_ASSERT(vector.count()!=0);
40 m_axis->setLayout(vector);
41 }
42
43 }
44
45 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,19
1 #ifndef CHARTANIMATION_H_
2 #define CHARTANIMATION_H_
3
4 #include "qchartglobal.h"
5 #include <QVariantAnimation>
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 class ChartAnimation: public QVariantAnimation
10 {
11 public:
12 ChartAnimation(QObject* parent=0):QVariantAnimation(parent){};
13 };
14
15 QTCOMMERCIALCHART_END_NAMESPACE
16
17
18
19 #endif /* AXISITEM_H_ */
@@ -0,0 +1,141
1 #include "chartanimator_p.h"
2 #include "axisanimation_p.h"
3 #include "xyanimation_p.h"
4 #include "xychartitem_p.h"
5 #include <QTimer>
6
7 Q_DECLARE_METATYPE(QVector<QPointF>)
8 Q_DECLARE_METATYPE(QVector<qreal>)
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
12 const static int duration = 1000;
13
14 ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
15 {
16 }
17
18 ChartAnimator::~ChartAnimator()
19 {
20 }
21
22 void ChartAnimator::addAnimation(AxisItem* item)
23 {
24 AxisAnimation* animation = static_cast<AxisAnimation*>(m_animations.value(item));
25
26 if(!animation) {
27 animation = new AxisAnimation(item);
28 m_animations.insert(item,animation);
29 }
30
31 item->setAnimator(this);
32 }
33
34 void ChartAnimator::addAnimation(XYChartItem* item)
35 {
36 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
37
38 if(!animation) {
39 animation = new XYAnimation(item);
40 m_animations.insert(item,animation);
41 }
42
43 item->setAnimator(this);
44 }
45
46 void ChartAnimator::removeAnimation(ChartItem* item)
47 {
48 item->setAnimator(0);
49 m_animations.remove(item);
50 }
51
52 void ChartAnimator::applyLayout(AxisItem* item , QVector<qreal>& newLayout)
53 {
54 AxisAnimation* animation = static_cast<AxisAnimation*>(m_animations.value(item));
55
56 if(!animation) return;
57
58 QVector<qreal> oldLayout = item->layout();
59
60 if(newLayout.count()==0) return;
61
62 if(item->zoomFactor()<0) {
63
64 QRectF rect = item->geometry();
65 oldLayout.resize(newLayout.count());
66
67 for(int i=0,j=oldLayout.count()-1;i<(oldLayout.count()+1)/2;i++,j--)
68 {
69 oldLayout[i]= item->axisType()==AxisItem::X_AXIS?rect.left():rect.bottom();
70 oldLayout[j]= item->axisType()==AxisItem::X_AXIS?rect.right():rect.top();
71 }
72
73 }
74 else {
75
76 int index = qMin(oldLayout.count()*item->zoomFactor(),newLayout.count()-1.0);
77 oldLayout.resize(newLayout.count());
78
79 for(int i=0;i<oldLayout.count();i++)
80 {
81 oldLayout[i]= oldLayout[index]; //axisType()==X_AXIS?rect.center.x():rect.center().y();
82 }
83 }
84
85 if(animation->state()!=QAbstractAnimation::Stopped) {
86 animation->stop();
87 }
88
89 animation->setDuration(duration);
90 animation->setEasingCurve(QEasingCurve::OutQuart);
91 QVariantAnimation::KeyValues value;
92 animation->setKeyValues(value); //workaround for wrong interpolation call
93 animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
94 animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
95
96 QTimer::singleShot(0,animation,SLOT(start()));
97 }
98
99 void ChartAnimator::applyLayout(XYChartItem* item, QVector<QPointF>& newPoints)
100 {
101
102 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
103
104 if(!animation) return;
105
106 QVector<QPointF> oldPoints = item->points();
107
108 if(newPoints.count()==0) return;
109
110 bool empty = oldPoints.count()==0;
111 oldPoints.resize(newPoints.size());
112
113 if(animation->state()!=QAbstractAnimation::Stopped) {
114 animation->stop();
115 }
116
117 animation->setDuration(duration);
118 if(!empty)
119 animation->setAnimationType(XYAnimation::MoveDownAnimation);
120 else
121 animation->setAnimationType(XYAnimation::LineDrawAnimation);
122 animation->setEasingCurve(QEasingCurve::OutQuart);
123 animation->setValues(oldPoints,newPoints);
124 QTimer::singleShot(0,animation,SLOT(start()));
125 }
126
127 void ChartAnimator::updateLayout(XYChartItem* item, QVector<QPointF>& newPoints)
128 {
129 XYAnimation* animation = static_cast<XYAnimation*>(m_animations.value(item));
130
131 if(!animation) return;
132
133 animation->setDuration(duration);
134 animation->setAnimationType(XYAnimation::MoveDownAnimation);
135 animation->setEasingCurve(QEasingCurve::OutQuart);
136 animation->updateValues(newPoints);
137
138 QTimer::singleShot(0,animation,SLOT(start()));
139 }
140
141 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,35
1 #ifndef CHARTANIMATOR_P_H_
2 #define CHARTANIMATOR_P_H_
3 #include "qchartglobal.h"
4 #include "chartanimation_p.h"
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
8 class ChartItem;
9 class XYChartItem;
10 class AxisItem;
11
12
13 class ChartAnimator : public QObject {
14
15 public:
16 ChartAnimator(QObject *parent = 0);
17 virtual ~ChartAnimator();
18
19 void addAnimation(AxisItem* item);
20 void addAnimation(XYChartItem* item);
21
22 void removeAnimation(ChartItem* item);
23
24 void animationStarted();
25 void applyLayout(XYChartItem* item, QVector<QPointF>& layout);
26 void updateLayout(XYChartItem* item, QVector<QPointF>& layout);
27 void applyLayout(AxisItem* item, QVector<qreal>& layout);
28
29 private:
30 QMap<ChartItem*,ChartAnimation*> m_animations;
31 };
32
33 QTCOMMERCIALCHART_END_NAMESPACE
34
35 #endif
@@ -0,0 +1,34
1 #ifndef XYCHARTANIMATION_P_H_
2 #define XYCHARTANIMATION_P_H_
3 #include "chartanimation_p.h"
4 #include <QPointF>
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
8 class XYChartItem;
9
10 class XYAnimation : public ChartAnimation
11 {
12 public:
13 enum Animation { LineDrawAnimation, MoveDownAnimation, MoveUpAnimation };
14 XYAnimation(XYChartItem *item);
15 ~XYAnimation();
16 void setAnimationType(Animation type);
17 void setValues(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints);
18 void updateValues(QVector<QPointF>& newPoints);
19
20 protected:
21 QVariant interpolated(const QVariant &start, const QVariant & end, qreal progress ) const;
22 void updateCurrentValue (const QVariant & value );
23 void updateState ( QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
24
25 private:
26 XYChartItem *m_item;
27 Animation m_type;
28 QVector<QPointF> m_points;
29 bool m_dirty;
30 };
31
32 QTCOMMERCIALCHART_END_NAMESPACE
33
34 #endif
@@ -1,44 +1,45
1 1 #include "chartwidget.h"
2 2 #include <QApplication>
3 3 #include <QMainWindow>
4 4 #include <qlineseries.h>
5 5 #include <cmath>
6 6
7 7 QTCOMMERCIALCHART_USE_NAMESPACE
8 8
9 9 #define PI 3.14159265358979
10 10
11 11 int main(int argc, char *argv[])
12 12 {
13 13 QApplication a(argc, argv);
14 14
15 15 QMainWindow window;
16 16
17 17 QLineSeries* series0 = new QLineSeries();
18 18 QPen blue(Qt::blue);
19 19 blue.setWidth(3);
20 20 series0->setPen(blue);
21 21 QLineSeries* series1 = new QLineSeries();
22 22 QPen red(Qt::red);
23 23 red.setWidth(3);
24 24 series1->setPen(red);
25 25
26 26 int numPoints = 100;
27 27
28 28 for (int x = 0; x <= numPoints; ++x) {
29 29 series0->add(x, fabs(sin(PI/50*x)*100));
30 30 series1->add(x, fabs(cos(PI/50*x)*100));
31 31 }
32 32
33 33 ChartWidget* chartWidget = new ChartWidget(&window);
34 34 chartWidget->setRenderHint(QPainter::Antialiasing);
35 35 chartWidget->setChartTitle("Zoom in/out line chart example");
36 chartWidget->setAnimationOptions(QChart::AllAnimations);
36 37 chartWidget->addSeries(series0);
37 38 chartWidget->addSeries(series1);
38 39
39 40 window.setCentralWidget(chartWidget);
40 41 window.resize(400, 300);
41 42 window.show();
42 43
43 44 return a.exec();
44 45 }
@@ -1,46 +1,26
1 1 #ifndef AXISANIMATIONITEM_H_
2 2 #define AXISANIMATIONITEM_H_
3 3
4 #include "domain_p.h"
5 4 #include "axisitem_p.h"
6 #include <QGraphicsItem>
7 #include <QVariantAnimation>
5 #include "chartanimation_p.h"
8 6
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
11 class AxisAnimator;
12
13 class AxisAnimationItem : public AxisItem
14 {
15 Q_OBJECT
16
17 public:
18 AxisAnimationItem(QChartAxis* axis,AxisType type = X_AXIS,QGraphicsItem* parent = 0);
19 ~AxisAnimationItem();
20 7
21 void setLabelsAngle(int angle);
22
23 protected:
24 virtual void updateLayout(QVector<qreal>& layout);
25
26 private:
27 AxisAnimator *m_animation;
28 };
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 9
30 class AxisAnimator: public QVariantAnimation
10 class AxisAnimation: public ChartAnimation
31 11 {
32 12 public:
33 AxisAnimator(AxisItem *axis,QObject *parent = 0);
34 ~AxisAnimator();
13 AxisAnimation(AxisItem *axis);
14 ~AxisAnimation();
35 15 protected:
36 16 virtual QVariant interpolated (const QVariant & from, const QVariant & to, qreal progress ) const;
37 17 virtual void updateCurrentValue (const QVariant & value );
38 18 private:
39 19 AxisItem* m_axis;
40 20 };
41 21
42 22 QTCOMMERCIALCHART_END_NAMESPACE
43 23
44 24
45 25
46 26 #endif /* AXISITEM_H_ */
@@ -1,103 +1,96
1 #ifndef XYCHARTANIMATOR_P_H_
2 #define XYCHARTANIMATOR_P_H_
3 #include "qchartglobal.h"
4 #include <QVariantAnimation>
5 #include <QPointF>
1 #include "xyanimation_p.h"
2 #include "xychartitem_p.h"
6 3
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9 template <class T, class U>
10 class XYChartAnimationItem;
4 Q_DECLARE_METATYPE(QVector<QPointF>)
11 5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 7
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 void setAnimationType(Animation type);
21
22 protected:
23 QVariant interpolated(const QVariant &start, const QVariant & end, qreal progress ) const;
24 void updateCurrentValue (const QVariant & value );
25 void updateState ( QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
26
27 private:
28 XYChartAnimationItem<T,U> *m_item;
29 Animation m_type;
30 };
31
32 template <class T, class U>
33 XYChartAnimator<T,U>::XYChartAnimator(XYChartAnimationItem<T,U> *item , QObject *parent):QVariantAnimation(parent),
8 XYAnimation::XYAnimation(XYChartItem *item):ChartAnimation(item),
34 9 m_item(item),
35 m_type(MoveDownAnimation)
10 m_type(MoveDownAnimation),
11 m_dirty(false)
36 12 {
37 13 }
38 14
39 template <class T,class U>
40 XYChartAnimator<T,U>::~XYChartAnimator()
15 XYAnimation::~XYAnimation()
41 16 {
42 17 }
43 18
44 template <class T,class U>
45 void XYChartAnimator<T,U>::setAnimationType(Animation type)
19 void XYAnimation::setAnimationType(Animation type)
46 20 {
47 21 m_type=type;
48 22 }
49 23
50 template <class T, class U>
51 QVariant XYChartAnimator<T,U>::interpolated(const QVariant &start, const QVariant & end, qreal progress ) const
24 void XYAnimation::setValues(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints)
52 25 {
53 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
54 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
55 QVector<QPointF> result;
56
57 switch(m_type) {
58
59 case MoveDownAnimation: {
60
61 Q_ASSERT(startVector.count() == endVector.count());
62 for(int i =0;i< startVector.count();i++) {
63 qreal x = startVector[i].x() + ((endVector[i].x()- startVector[i].x()) * progress);
64 qreal y = startVector[i].y() + ((endVector[i].y()- startVector[i].y()) * progress);
65 result << QPointF(x,y);
66 }
67
68 }
69 break;
70 case LineDrawAnimation:{
71 for(int i =0;i< endVector.count()* qBound(0.0, progress, 1.0);i++) {
72 result << endVector[i];
73 }
74 }
75 break;
76 default:
77 qWarning()<<"Unknow type of animation";
78 break;
79 }
80
81 return qVariantFromValue(result);
26 setKeyValueAt(0.0, qVariantFromValue(oldPoints));
27 setKeyValueAt(1.0, qVariantFromValue(newPoints));
28 m_points = newPoints;
29 m_dirty=false;
82 30 }
83 31
84 template <class T, class U>
85 void XYChartAnimator<T,U>::updateCurrentValue (const QVariant & value )
32 void XYAnimation::updateValues(QVector<QPointF>& newPoints)
86 33 {
87 if(state()!=QAbstractAnimation::Stopped){ //workaround
88 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
89 m_item->setGeometry(vector);
90 }
34 if(state()!=QAbstractAnimation::Stopped) {
35 stop();
36 m_dirty=true;
37 }
38
39 if(m_dirty) {
40 m_points=newPoints;
41 m_dirty=false;
42 }
43
44 setKeyValueAt(0.0, qVariantFromValue(m_points));
45 setKeyValueAt(1.0, qVariantFromValue(newPoints));
91 46 }
92 47
93 template <class T, class U>
94 void XYChartAnimator<T,U>::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
48 QVariant XYAnimation::interpolated(const QVariant &start, const QVariant & end, qreal progress ) const
95 49 {
96 Q_UNUSED(oldState)
97 if (newState==QAbstractAnimation::Running) m_item->animationStarted();
98 QVariantAnimation::updateState(newState,oldState);
50 QVector<QPointF> startVector = qVariantValue<QVector<QPointF> >(start);
51 QVector<QPointF> endVector = qVariantValue<QVector<QPointF> >(end);
52 QVector<QPointF> result;
53
54 switch(m_type) {
55
56 case MoveDownAnimation: {
57
58 Q_ASSERT(startVector.count() == endVector.count());
59 for(int i =0;i< startVector.count();i++) {
60 qreal x = startVector[i].x() + ((endVector[i].x()- startVector[i].x()) * progress);
61 qreal y = startVector[i].y() + ((endVector[i].y()- startVector[i].y()) * progress);
62 result << QPointF(x,y);
63 }
64
65 }
66 break;
67 case LineDrawAnimation:{
68 for(int i =0;i< endVector.count()* qBound(0.0, progress, 1.0);i++) {
69 result << endVector[i];
70 }
71 }
72 break;
73 default:
74 qWarning()<<"Unknow type of animation";
75 break;
76 }
77
78 return qVariantFromValue(result);
99 79 }
100 80
101 QTCOMMERCIALCHART_END_NAMESPACE
81 void XYAnimation::updateCurrentValue (const QVariant & value )
82 {
83 if(state()!=QAbstractAnimation::Stopped){ //workaround
84 QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
85 m_item->setGeometry(vector);
86 }
87 }
102 88
103 #endif /* XYCHARTANIMATOR_P_H_ */
89 void XYAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
90 {
91 Q_UNUSED(oldState)
92 if (newState==QAbstractAnimation::Running) m_dirty=true;
93 QVariantAnimation::updateState(newState,oldState);
94 }
95
96 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,66 +1,65
1 1 #ifndef AREACHARTITEM_H
2 2 #define AREACHARTITEM_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "linechartitem_p.h"
6 6 #include <QPen>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 class ChartPresenter;
11 10 class QAreaSeries;
12 11 class AreaChartItem;
13 12
14 13 class AreaChartItem : public QObject ,public ChartItem
15 14 {
16 15 Q_OBJECT
17 16 public:
18 17 AreaChartItem(QAreaSeries* areaSeries, QGraphicsItem *parent = 0);
19 18 ~ AreaChartItem();
20 19
21 20 //from QGraphicsItem
22 21 QRectF boundingRect() const;
23 22 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
24 23 QPainterPath shape() const;
25 24
26 25 void setPen(const QPen& pen);
27 26 void setBrush(const QBrush& brush);
28 27 void setPointsVisible(bool visible);
29 28 void updatePath();
30 29 public slots:
31 30 void handleUpdated();
32 31 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
33 32 void handleGeometryChanged(const QRectF& size);
34 33
35 34 private:
36 35 QAreaSeries* m_series;
37 36 LineChartItem* m_upper;
38 37 LineChartItem* m_lower;
39 38 QPainterPath m_path;
40 39 QRectF m_rect;
41 40 QRectF m_clipRect;
42 41 QPen m_pen;
43 42 QBrush m_brush;
44 43 };
45 44
46 45 class AreaBoundItem : public LineChartItem
47 46 {
48 47 public:
49 48 AreaBoundItem(AreaChartItem* item,QLineSeries* lineSeries):LineChartItem(lineSeries),
50 49 m_item(item){};
51 50
52 51 ~AreaBoundItem(){};
53 52
54 53 void setGeometry(QVector<QPointF>& points){
55 54 LineChartItem::setGeometry(points);
56 55 m_item->updatePath();
57 56 }
58 57
59 58 private:
60 59 AreaChartItem* m_item;
61 60
62 61 };
63 62
64 63 QTCOMMERCIALCHART_END_NAMESPACE
65 64
66 65 #endif
@@ -1,16 +1,14
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 $$PWD/axisanimationitem.cpp \
6 5 $$PWD/axisitem.cpp \
7 6 $$PWD/qchartaxis.cpp \
8 7 $$PWD/qchartaxiscategories.cpp
9 8
10 9 PRIVATE_HEADERS += \
11 $$PWD/axisanimationitem_p.h \
12 10 $$PWD/axisitem_p.h
13 11
14 12 PUBLIC_HEADERS += \
15 13 $$PWD/qchartaxis.h \
16 14 $$PWD/qchartaxiscategories.h No newline at end of file
@@ -1,430 +1,436
1 1 #include "axisitem_p.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 #include "chartanimator_p.h"
4 5 #include <QPainter>
5 6 #include <QDebug>
6 7
7 8 static int label_padding = 5;
8 9
9 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 11
11 AxisItem::AxisItem(QChartAxis* axis,AxisType type,QGraphicsItem* parent) :
12 AxisItem::AxisItem(QChartAxis* axis,ChartPresenter* presenter,AxisType type,QGraphicsItem* parent) :
12 13 ChartItem(parent),
14 m_presenter(presenter),
13 15 m_chartAxis(axis),
14 16 m_type(type),
15 17 m_labelsAngle(0),
16 18 m_grid(parent),
17 19 m_shades(parent),
18 20 m_labels(parent),
19 21 m_axis(parent),
20 22 m_min(0),
21 23 m_max(0),
22 24 m_ticksCount(0),
23 25 m_zoomFactor(0)
24 26 {
25 27 //initial initialization
26 28 m_axis.setZValue(ChartPresenter::AxisZValue);
27 29 m_shades.setZValue(ChartPresenter::ShadesZValue);
28 30 m_grid.setZValue(ChartPresenter::GridZValue);
29 31 setFlags(QGraphicsItem::ItemHasNoContents);
30 32
31 33 QObject::connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
32 34 QObject::connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
33 35
34 36 handleAxisUpdated();
35 37 }
36 38
37 39 AxisItem::~AxisItem()
38 40 {
39 41 }
40 42
41 43 QRectF AxisItem::boundingRect() const
42 44 {
43 45 return QRectF();
44 46 }
45 47
46 48 void AxisItem::createItems(int count)
47 49 {
50
48 51 if(m_axis.children().size()==0)
49 52 m_axis.addToGroup(new QGraphicsLineItem());
50 53 for (int i = 0; i < count; ++i) {
51 54 m_grid.addToGroup(new QGraphicsLineItem());
52 55 m_labels.addToGroup(new QGraphicsSimpleTextItem());
53 if(m_grid.childItems().size()%2) m_shades.addToGroup(new QGraphicsRectItem());
54 56 m_axis.addToGroup(new QGraphicsLineItem());
57 if((m_grid.childItems().size())%2 && m_grid.childItems().size()>2) m_shades.addToGroup(new QGraphicsRectItem());
55 58 }
56 59 }
57 60
58 61 void AxisItem::deleteItems(int count)
59 62 {
60 63 QList<QGraphicsItem *> lines = m_grid.childItems();
61 64 QList<QGraphicsItem *> labels = m_labels.childItems();
62 65 QList<QGraphicsItem *> shades = m_shades.childItems();
63 66 QList<QGraphicsItem *> axis = m_axis.childItems();
64 67
65 68 for (int i = 0; i < count; ++i) {
69 if(lines.size()%2 && lines.size()>1) delete(shades.takeLast());
66 70 delete(lines.takeLast());
67 71 delete(labels.takeLast());
68 if(lines.size()%2) delete(shades.takeLast());
69 72 delete(axis.takeLast());
70 73 }
71 74 }
72 75
73 76 void AxisItem::updateLayout(QVector<qreal>& layout)
74 77 {
75 setLayout(layout);
78 if(m_animator){
79 m_animator->applyLayout(this,layout);
80 }
81 else setLayout(layout);
76 82 }
77 83
78 84 QStringList AxisItem::createLabels(int ticks, qreal min, qreal max) const
79 85 {
80 86 Q_ASSERT(max>=min);
81 87 Q_ASSERT(ticks>0);
82 88
83 89 QStringList labels;
84 90
85 91 QChartAxisCategories* categories = m_chartAxis->categories();
86 92
87 93 for(int i=0; i< ticks; i++) {
88 94 qreal value = min + (i * (max - min)/ (ticks-1));
89 95 if(categories->count()==0) {
90 96 labels << QString::number(value);
91 97 }
92 98 else {
93 99 QString label = categories->label(value);
94 100 labels << label;
95 101 }
96 102 }
97 103 return labels;
98 104 }
99 105
100 106 void AxisItem::setAxisOpacity(qreal opacity)
101 107 {
102 108 m_axis.setOpacity(opacity);
103 109 }
104 110
105 111 qreal AxisItem::axisOpacity() const
106 112 {
107 113 return m_axis.opacity();
108 114 }
109 115
110 116 void AxisItem::setGridOpacity(qreal opacity)
111 117 {
112 118 m_grid.setOpacity(opacity);
113 119 }
114 120
115 121 qreal AxisItem::gridOpacity() const
116 122 {
117 123 return m_grid.opacity();
118 124 }
119 125
120 126 void AxisItem::setLabelsOpacity(qreal opacity)
121 127 {
122 128 m_labels.setOpacity(opacity);
123 129 }
124 130
125 131 qreal AxisItem::labelsOpacity() const
126 132 {
127 133 return m_labels.opacity();
128 134 }
129 135
130 136 void AxisItem::setShadesOpacity(qreal opacity)
131 137 {
132 138 m_shades.setOpacity(opacity);
133 139 }
134 140
135 141 qreal AxisItem::shadesOpacity() const
136 142 {
137 143 return m_shades.opacity();
138 144 }
139 145
140 146 void AxisItem::setLabelsAngle(int angle)
141 147 {
142 148 foreach(QGraphicsItem* item , m_labels.childItems()) {
143 149 QPointF center = item->boundingRect().center();
144 150 item->setRotation(angle);
145 151 }
146 152
147 153 m_labelsAngle=angle;
148 154 }
149 155
150 156 void AxisItem::setLabelsPen(const QPen& pen)
151 157 {
152 158 foreach(QGraphicsItem* item , m_labels.childItems()) {
153 159 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
154 160 }
155 161 }
156 162
157 163 void AxisItem::setLabelsBrush(const QBrush& brush)
158 164 {
159 165 foreach(QGraphicsItem* item , m_labels.childItems()) {
160 166 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
161 167 }
162 168 }
163 169
164 170 void AxisItem::setLabelsFont(const QFont& font)
165 171 {
166 172 foreach(QGraphicsItem* item , m_labels.childItems()) {
167 173 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
168 174 }
169 175 }
170 176
171 177 void AxisItem::setShadesBrush(const QBrush& brush)
172 178 {
173 179 foreach(QGraphicsItem* item , m_shades.childItems()) {
174 180 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
175 181 }
176 182 }
177 183
178 184 void AxisItem::setShadesPen(const QPen& pen)
179 185 {
180 186 foreach(QGraphicsItem* item , m_shades.childItems()) {
181 187 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
182 188 }
183 189 }
184 190
185 191 void AxisItem::setAxisPen(const QPen& pen)
186 192 {
187 193 foreach(QGraphicsItem* item , m_axis.childItems()) {
188 194 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
189 195 }
190 196 }
191 197
192 198 void AxisItem::setGridPen(const QPen& pen)
193 199 {
194 200 foreach(QGraphicsItem* item , m_grid.childItems()) {
195 201 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
196 202 }
197 203 }
198 204
199 205 QVector<qreal> AxisItem::calculateLayout() const
200 206 {
201 207 Q_ASSERT(m_ticksCount>=2);
202 208
203 209 QVector<qreal> points;
204 210 points.resize(m_ticksCount);
205 211
206 212 switch (m_type)
207 213 {
208 214 case X_AXIS:
209 215 {
210 216 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
211 217 for (int i = 0; i < m_ticksCount; ++i) {
212 218 int x = i * deltaX + m_rect.left();
213 219 points[i] = x;
214 220 }
215 221 }
216 222 break;
217 223 case Y_AXIS:
218 224 {
219 225 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
220 226 for (int i = 0; i < m_ticksCount; ++i) {
221 227 int y = i * -deltaY + m_rect.bottom();
222 228 points[i] = y;
223 229 }
224 230 }
225 231 break;
226 232 }
227 233 return points;
228 234 }
229 235
230 236 void AxisItem::setLayout(QVector<qreal>& layout)
231 237 {
232 238 int diff = m_layoutVector.size() - layout.size();
233 239
234 240 if(diff>0) {
235 241 deleteItems(diff);
236 242 }
237 243 else if(diff<0) {
238 244 createItems(-diff);
239 245 }
240 246
241 247 if(diff!=0) handleAxisUpdated();
242 248
243 QStringList ticksList = createLabels(m_ticksCount,m_min,m_max);
249 QStringList ticksList = createLabels(layout.size(),m_min,m_max);
244 250
245 251 QList<QGraphicsItem *> lines = m_grid.childItems();
246 252 QList<QGraphicsItem *> labels = m_labels.childItems();
247 253 QList<QGraphicsItem *> shades = m_shades.childItems();
248 254 QList<QGraphicsItem *> axis = m_axis.childItems();
249 255
250 256 Q_ASSERT(labels.size() == ticksList.size());
251 257 Q_ASSERT(layout.size() == ticksList.size());
258 Q_ASSERT(layout.size() == m_ticksCount);
252 259
253 260 switch (m_type)
254 261 {
255 262 case X_AXIS:
256 263 {
257 264 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
258 265 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
259 266
260 267 for (int i = 0; i < layout.size(); ++i) {
261 268 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
262 269 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
263 270 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
264 271 labelItem->setText(ticksList.at(i));
265 272 QPointF center = labelItem->boundingRect().center();
266 273 labelItem->setTransformOriginPoint(center.x(), center.y());
267 274 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
268 if(i%2 && i+1 < layout.size()) {
275 if(i%2 && i+1 < layout.size() && i>1) {
269 276 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2));
270 277 rectItem->setRect(layout[i],m_rect.top(),layout[i+1]-layout[i],m_rect.height());
271 278 }
272 279 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
273 280 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
274 281 }
275 282 }
276 283 break;
277 284
278 285 case Y_AXIS:
279 286 {
280 287 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
281 288 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
282 289
283 290 for (int i = 0; i < layout.size(); ++i) {
284 291 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
285 292 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
286 293 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
287 294 labelItem->setText(ticksList.at(i));
288 295 QPointF center = labelItem->boundingRect().center();
289 296 labelItem->setTransformOriginPoint(center.x(), center.y());
290 297 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
291 if(i%2 && i+1 < layout.size()) {
298 if(i%2 && i+1 < layout.size() && i>1) {
292 299 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2));
293 300 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i]-layout[i+1]);
294 301 }
295 302 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
296 303 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
297 304 }
298 305 }
299 306 break;
300 307 default:
301 308 qDebug()<<"Unknown axis type";
302 309 break;
303 310 }
304 311
305 //if(diff!=0) handleAxisUpdated();
306 312 m_layoutVector=layout;
307 313 }
308 314
309 315 bool AxisItem::isEmpty()
310 316 {
311 317 return m_rect.isEmpty() || m_min==m_max || m_ticksCount==0;
312 318 }
313 319
314 320 //handlers
315 321
316 322 void AxisItem::handleAxisCategoriesUpdated()
317 323 {
318 324 if(isEmpty()) return;
319 325 updateLayout(m_layoutVector);
320 326 }
321 327
322 328 void AxisItem::handleAxisUpdated()
323 329 {
324 330
325 331 int count = m_chartAxis->ticksCount();
326 332
327 333 if(m_ticksCount!=count){
328 334 //handleTicksCountChanged(count);
329 335 }
330 336
331 337 if(isEmpty()) return;
332 338
333 339 if(m_chartAxis->isAxisVisible()) {
334 340 setAxisOpacity(100);
335 341 }
336 342 else {
337 343 setAxisOpacity(0);
338 344 }
339 345
340 346 if(m_chartAxis->isGridVisible()) {
341 347 setGridOpacity(100);
342 348 }
343 349 else {
344 350 setGridOpacity(0);
345 351 }
346 352
347 353 if(m_chartAxis->labelsVisible())
348 354 {
349 355 setLabelsOpacity(100);
350 356 }
351 357 else {
352 358 setLabelsOpacity(0);
353 359 }
354 360
355 361 if(m_chartAxis->shadesVisible()) {
356 362 setShadesOpacity(m_chartAxis->shadesOpacity());
357 363 }
358 364 else {
359 365 setShadesOpacity(0);
360 366 }
361 367
362 368 setLabelsAngle(m_chartAxis->labelsAngle());
363 369 setAxisPen(m_chartAxis->axisPen());
364 370 setLabelsPen(m_chartAxis->labelsPen());
365 371 setLabelsBrush(m_chartAxis->labelsBrush());
366 372 setLabelsFont(m_chartAxis->labelsFont());
367 373 setGridPen(m_chartAxis->gridPen());
368 374 setShadesPen(m_chartAxis->shadesPen());
369 375 setShadesBrush(m_chartAxis->shadesBrush());
370 376
371 377 }
372 378
373 379 void AxisItem::handleTicksCountChanged(int count)
374 380 {
375 381 m_ticksCount=count;
376 382
377 383 if(isEmpty()) return;
378 384 QVector<qreal> layout = calculateLayout();
379 385 updateLayout(layout);
380 386 }
381 387
382 388 void AxisItem::handleRangeChanged(qreal min, qreal max)
383 389 {
384 390
385 391 if(m_min<min || m_max>max){
386 392 m_zoomFactor = (min + (max-min)/2 - m_min)/(m_max - m_min);
387 393 }
388 394 else
389 395 m_zoomFactor=-1;
390 396
391 397 m_min = min;
392 398 m_max = max;
393 399
400
394 401 m_ticksCount = qrand()%10;
395 402
396 403 while(m_ticksCount<2){
397 404 m_ticksCount = qrand()%10;
398 405 }
399 406
400 407 qDebug()<<"Warning : This is testing . Simulating new random ticks "<< m_ticksCount;
401 408 //m_chartAxis->setTicksCount(m_ticksCount);
402 409
403 410 if(isEmpty()) return;
404 411 QVector<qreal> layout = calculateLayout();
405 412 updateLayout(layout);
406 413
407 414 }
408 415
409 416 void AxisItem::handleGeometryChanged(const QRectF& rect)
410 417 {
411
412 418 m_rect = rect;
413 419 if(isEmpty()) return;
414 420 QVector<qreal> layout = calculateLayout();
415 421 updateLayout(layout);
416 422 }
417 423
418 424 //painter
419 425
420 426 void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
421 427 {
422 428 Q_UNUSED(painter);
423 429 Q_UNUSED(option);
424 430 Q_UNUSED(widget);
425 431 }
426 432
427 433 //TODO "nice numbers algorithm"
428 434 #include "moc_axisitem_p.cpp"
429 435
430 436 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,93 +1,98
1 1 #ifndef AXISITEM_H_
2 2 #define AXISITEM_H_
3 3
4 4 #include "domain_p.h"
5 5 #include "chartitem_p.h"
6 6 #include <QGraphicsItem>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class QChartAxis;
11 class ChartPresenter;
11 12
12 13 class AxisItem : public QObject, public ChartItem
13 14 {
14 15 Q_OBJECT
15 16 public:
16 17 enum AxisType{X_AXIS,Y_AXIS};
17 18
18 AxisItem(QChartAxis* axis,AxisType type = X_AXIS,QGraphicsItem* parent = 0);
19 AxisItem(QChartAxis* axis,ChartPresenter* presenter,AxisType type = X_AXIS,QGraphicsItem* parent = 0);
19 20 ~AxisItem();
20 21
21 22 //from QGraphicsItem
22 23 QRectF boundingRect() const;
23 24 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
24 25
25 26 AxisType axisType() const {return m_type;};
26 27
27 28 void setAxisOpacity(qreal opacity);
28 29 qreal axisOpacity() const;
29 30
30 31 void setGridOpacity(qreal opacity);
31 32 qreal gridOpacity() const;
32 33
33 34 void setLabelsOpacity(qreal opacity);
34 35 qreal labelsOpacity() const;
35 36
36 37 void setShadesOpacity(qreal opacity);
37 38 qreal shadesOpacity() const;
38 39
39 40 void setLabelsAngle(int angle);
40 41 int labelsAngle()const { return m_labelsAngle; }
41 42
42 43 void setShadesBrush(const QBrush& brush);
43 44 void setShadesPen(const QPen& pen);
44 45
45 46 void setAxisPen(const QPen& pen);
46 47 void setGridPen(const QPen& pen);
47 48
48 49 void setLabelsPen(const QPen& pen);
49 50 void setLabelsBrush(const QBrush& brush);
50 51 void setLabelsFont(const QFont& font);
51 52
52 53 inline QRectF geometry() const { return m_rect; }
54 inline QVector<qreal> layout() { return m_layoutVector;};
53 55 inline qreal zoomFactor() const { return m_zoomFactor;}
54 56
55 57 public slots:
56 58 void handleAxisUpdated();
57 59 void handleAxisCategoriesUpdated();
58 60 void handleRangeChanged(qreal min , qreal max);
59 61 void handleTicksCountChanged(int count);
60 62 void handleGeometryChanged(const QRectF& size);
61 63
62 public:
63 virtual void updateLayout(QVector<qreal>& layout);
64 void setLayout(QVector<qreal>& layout);
65 QVector<qreal> layout() { return m_layoutVector;};
66 64
67 65 private:
68 66 inline bool isEmpty();
69 67 void createItems(int count);
70 68 void deleteItems(int count);
69
71 70 QVector<qreal> calculateLayout() const;
71 void updateLayout(QVector<qreal>& layout);
72 void setLayout(QVector<qreal>& layout);
73
72 74 QStringList createLabels(int ticks, qreal min, qreal max) const;
73 75
74 76 private:
77 ChartPresenter* m_presenter;
75 78 QChartAxis* m_chartAxis;
76 79 AxisType m_type;
77 80 QRectF m_rect;
78 81 int m_labelsAngle;
79 82 QGraphicsItemGroup m_grid;
80 83 QGraphicsItemGroup m_shades;
81 84 QGraphicsItemGroup m_labels;
82 85 QGraphicsItemGroup m_axis;
83 86 QVector<qreal> m_layoutVector;
84 87 qreal m_min;
85 88 qreal m_max;
86 89 int m_ticksCount;
87 90 qreal m_zoomFactor;
88 91
92 friend class AxisAnimation;
93
89 94 };
90 95
91 96 QTCOMMERCIALCHART_END_NAMESPACE
92 97
93 98 #endif /* AXISITEM_H_ */
@@ -1,285 +1,283
1 1 #include "chartdataset_p.h"
2 2 #include "qchartaxis.h"
3 3 //series
4 4 #include "qlineseries.h"
5 5 #include "qareaseries.h"
6 6 #include "qbarseries.h"
7 7 #include "qstackedbarseries.h"
8 8 #include "qpercentbarseries.h"
9 9 #include "qpieseries.h"
10 10 #include "qscatterseries.h"
11 11 #include "qsplineseries.h"
12 12
13 13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 14
15 15 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
16 16 m_axisX(new QChartAxis(this)),
17 17 m_axisY(new QChartAxis(this)),
18 18 m_domainIndex(0),
19 19 m_axisXInitialized(false)
20 20 {
21 21 }
22 22
23 23 ChartDataSet::~ChartDataSet()
24 24 {
25 25 }
26 26
27 27 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
28 28 {
29 29 if(axisY==0) axisY = m_axisY;
30 30
31 31 QChartAxis* axis = m_seriesAxisMap.value(series);
32 32
33 33 if(axis) {
34 34 qWarning() << "Can not add series. Series already on the chart";
35 35 return;
36 36 }
37 37
38 38 if(!series->parent()){
39 39 series->setParent(this); // take ownership
40 40 };
41 41
42 42 if(!axisY->parent()){
43 43 axisY->setParent(this); // take ownership
44 44 }
45 45
46 46 Domain* domain = m_axisDomainMap.value(axisY);
47 47
48 48 if(!domain) {
49 49 domain = new Domain();
50 50
51 51 QObject::connect(axisY,SIGNAL(rangeChanged(qreal,qreal)),domain,SLOT(handleAxisRangeYChanged(qreal,qreal)));
52 52 QObject::connect(axisX(),SIGNAL(rangeChanged(qreal,qreal)),domain,SLOT(handleAxisRangeXChanged(qreal,qreal)));
53 53 //initialize
54 54 m_axisDomainMap.insert(axisY,domain);
55 55 emit axisAdded(axisY,domain);
56 56 }
57 57
58 58 if(!m_axisXInitialized){
59 59 emit axisAdded(axisX(),domain);
60 60 m_axisXInitialized=true;
61 61 }
62 62
63 63 calculateDomain(series,domain);
64 64
65 65 m_seriesAxisMap.insert(series,axisY);
66 66 emit seriesAdded(series,domain);
67 67
68 68 }
69 69
70 70 void ChartDataSet::removeSeries(QSeries* series)
71 71 {
72 72
73 73 QChartAxis* axis = m_seriesAxisMap.value(series);
74 74
75 75 if(!axis){
76 76 qWarning()<<"Can not remove series. Series not found on the chart.";
77 77 return;
78 78 }
79 79 emit seriesRemoved(series);
80 80 m_seriesAxisMap.remove(series);
81 81
82 82 if(series->parent()==this){
83 83 delete series;
84 84 series=0;
85 85 }
86 86
87 87 QList<QChartAxis*> axes = m_seriesAxisMap.values();
88 88
89 89 int i = axes.indexOf(axis);
90 90
91 91 if(i==-1){
92 92 Domain* domain = m_axisDomainMap.take(axis);
93 93 emit axisRemoved(axis);
94 94 if(axis!=axisY()){
95 95 if(axis->parent()==this){
96 96 delete axis;
97 97 axis=0;
98 98 }
99 99 }
100 100 delete domain;
101 101 }
102 102
103 103 if(m_seriesAxisMap.values().size()==0)
104 104 {
105 105 m_axisXInitialized=false;
106 106 emit axisRemoved(axisX());
107 107 }
108 108 }
109 109
110 110 void ChartDataSet::removeAllSeries()
111 111 {
112 112
113 113 QList<QSeries*> series = m_seriesAxisMap.keys();
114 114
115 115 foreach(QSeries* s , series) {
116 116 removeSeries(s);
117 117 }
118 118
119 119 Q_ASSERT(m_seriesAxisMap.count()==0);
120 120 Q_ASSERT(m_axisDomainMap.count()==0);
121 121
122 122 }
123 123
124 124 //to be removed with PIMPL
125 125 void ChartDataSet::calculateDomain(QSeries* series,Domain* domain) const
126 126 {
127 127 switch(series->type())
128 128 {
129 129 case QSeries::SeriesTypeLine:
130 130 case QSeries::SeriesTypeSpline:
131 131 case QSeries::SeriesTypeScatter:
132 132 {
133 133
134 134 QXYSeries* xySeries = static_cast<QXYSeries*>(series);
135 135
136 136 qreal minX(domain->minX());
137 137 qreal minY(domain->minY());
138 138 qreal maxX(domain->maxX());
139 139 qreal maxY(domain->maxY());
140 140
141 141 for (int i = 0; i < xySeries->count(); i++)
142 142 {
143 143 qreal x = xySeries->x(i);
144 144 qreal y = xySeries->y(i);
145 145 minX = qMin(minX, x);
146 146 minY = qMin(minY, y);
147 147 maxX = qMax(maxX, x);
148 148 maxY = qMax(maxY, y);
149 domain->setMinX(qMin(domain->minX(),x));
150 domain->setMinY(qMin(domain->minY(),y));
151 domain->setMaxX(qMax(domain->maxX(),x));
152 domain->setMaxY(qMax(domain->maxY(),y));
153 149 }
150
151 domain->setRange(minX, maxX, minY, maxY);
154 152 break;
155 153 }
156 154 case QSeries::SeriesTypeArea: {
157 155
158 156 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
159 157
160 158 QLineSeries* upperSeries = areaSeries->upperSeries();
161 159 QLineSeries* lowerSeries = areaSeries->lowerSeries();
162 160
163 161 for (int i = 0; i < upperSeries->count(); i++)
164 162 {
165 163 qreal x = upperSeries->x(i);
166 164 qreal y = upperSeries->y(i);
167 165 domain->setMinX(qMin(domain->minX(),x));
168 166 domain->setMinY(qMin(domain->minY(),y));
169 167 domain->setMaxX(qMax(domain->maxX(),x));
170 168 domain->setMaxY(qMax(domain->maxY(),y));
171 169 }
172 170 if(lowerSeries) {
173 171 for (int i = 0; i < lowerSeries->count(); i++)
174 172 {
175 173 qreal x = lowerSeries->x(i);
176 174 qreal y = lowerSeries->y(i);
177 175 domain->setMinX(qMin(domain->minX(),x));
178 176 domain->setMinY(qMin(domain->minY(),y));
179 177 domain->setMaxX(qMax(domain->maxX(),x));
180 178 domain->setMaxY(qMax(domain->maxY(),y));
181 179 }}
182 180 break;
183 181 }
184 182 case QSeries::SeriesTypeBar: {
185 183 qDebug() << "QChartSeries::SeriesTypeBar";
186 184 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
187 185 qreal x = barSeries->categoryCount();
188 186 qreal y = barSeries->max();
189 187 domain->setMinX(qMin(domain->minX(),x));
190 188 domain->setMinY(qMin(domain->minY(),y));
191 189 domain->setMaxX(qMax(domain->maxX(),x));
192 190 domain->setMaxY(qMax(domain->maxY(),y));
193 191 break;
194 192 }
195 193 case QSeries::SeriesTypeStackedBar: {
196 194 qDebug() << "QChartSeries::SeriesTypeStackedBar";
197 195
198 196 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
199 197 qreal x = stackedBarSeries->categoryCount();
200 198 qreal y = stackedBarSeries->maxCategorySum();
201 199 domain->setMinX(qMin(domain->minX(),x));
202 200 domain->setMinY(qMin(domain->minY(),y));
203 201 domain->setMaxX(qMax(domain->maxX(),x));
204 202 domain->setMaxY(qMax(domain->maxY(),y));
205 203 break;
206 204 }
207 205 case QSeries::SeriesTypePercentBar: {
208 206 qDebug() << "QChartSeries::SeriesTypePercentBar";
209 207
210 208 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
211 209 qreal x = percentBarSeries->categoryCount();
212 210 domain->setMinX(qMin(domain->minX(),x));
213 211 domain->setMinY(0);
214 212 domain->setMaxX(qMax(domain->maxX(),x));
215 213 domain->setMaxY(100);
216 214 break;
217 215 }
218 216
219 217 case QSeries::SeriesTypePie: {
220 218 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
221 219 // TODO: domain stuff
222 220 break;
223 221 }
224 222
225 223
226 224 default: {
227 225 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
228 226 return;
229 227 break;
230 228 }
231 229
232 230 }
233 231 }
234 232
235 233 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
236 234 {
237 235 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
238 236 while (i.hasNext()) {
239 237 i.next();
240 238 i.value()->zoomIn(rect,size);
241 239 }
242 240 }
243 241
244 242 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
245 243 {
246 244 QMapIterator<QChartAxis*, Domain*> i( m_axisDomainMap);
247 245 while (i.hasNext()) {
248 246 i.next();
249 247 i.value()->zoomOut(rect,size);
250 248 }
251 249 }
252 250
253 251 QChartAxis* ChartDataSet::axisY(QSeries* series) const
254 252 {
255 253 if(series == 0) return m_axisY;
256 254 return m_seriesAxisMap.value(series);
257 255 }
258 256
259 257 Domain* ChartDataSet::domain(QSeries* series) const
260 258 {
261 259 QChartAxis* axis = m_seriesAxisMap.value(series);
262 260 if(axis){
263 261 return m_axisDomainMap.value(axis);
264 262 }else
265 263 return 0;
266 264 }
267 265
268 266 Domain* ChartDataSet::domain(QChartAxis* axis) const
269 267 {
270 268 if(axis==axisX()) {
271 269 return m_axisDomainMap.value(axisY());
272 270 }
273 271 else {
274 272 return m_axisDomainMap.value(axis);
275 273 }
276 274 }
277 275
278 276 QChartAxis* ChartDataSet::axis(QSeries* series) const
279 277 {
280 278 return m_seriesAxisMap.value(series);
281 279 }
282 280
283 281 #include "moc_chartdataset_p.cpp"
284 282
285 283 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,24 +1,33
1 1 #ifndef CHARTITEM_H_
2 2 #define CHARTITEM_H_
3 3
4 4 #include "domain_p.h"
5 5 #include <QGraphicsItem>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 class ChartAnimationManager;
9 class ChartAnimator;
10 10
11 11 class ChartItem : public QGraphicsItem
12 12 {
13 13 enum ChartItemTypes{ AXIS_ITEM = UserType+1, XYLINE_ITEM};
14 14 public:
15 ChartItem(QGraphicsItem* parent = 0):QGraphicsItem(parent){};
15 ChartItem(QGraphicsItem* parent = 0):QGraphicsItem(parent),
16 m_animator(0){};
16 17 //TODO make pure
17 18 virtual void handleGeometryChanged(const QRectF&){};
18 19 virtual void handleDomainChanged(const Domain& domain){};
20
21 void setAnimator(ChartAnimator* animator){
22 m_animator=animator;
23 }
24
19 25 virtual ~ChartItem(){};
26
27 protected:
28 ChartAnimator* m_animator;
20 29 };
21 30
22 31 QTCOMMERCIALCHART_END_NAMESPACE
23 32
24 33 #endif /* CHARTITEM_H_ */
@@ -1,385 +1,382
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 #include "chartanimator_p.h"
6 7 //series
7 8 #include "qbarseries.h"
8 9 #include "qstackedbarseries.h"
9 10 #include "qpercentbarseries.h"
10 11 #include "qlineseries.h"
11 12 #include "qareaseries.h"
12 13 #include "qpieseries.h"
13 14 #include "qscatterseries.h"
14 15 #include "qsplineseries.h"
15 16 //items
16 17 #include "axisitem_p.h"
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 23 #include "piepresenter_p.h"
24 24 #include "scatterchartitem_p.h"
25 25 #include "splinechartitem_p.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
30 30 m_chart(chart),
31 m_animator(0),
31 32 m_dataset(dataset),
32 33 m_chartTheme(0),
33 34 m_zoomIndex(0),
34 35 m_marginSize(0),
35 36 m_rect(QRectF(QPoint(0,0),m_chart->size())),
36 37 m_options(QChart::NoAnimation)
37 38 {
38 39 createConnections();
39 40 setChartTheme(QChart::ChartThemeDefault);
40 41 }
41 42
42 43 ChartPresenter::~ChartPresenter()
43 44 {
44 45 }
45 46
46 47 void ChartPresenter::createConnections()
47 48 {
48 49 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
49 50 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
50 51 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
51 52 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
52 53 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
53 54 }
54 55
55 56
56 57 QRectF ChartPresenter::geometry() const
57 58 {
58 59 return m_rect;
59 60 }
60 61
61 62 void ChartPresenter::handleGeometryChanged()
62 63 {
63 64 QRectF rect(QPoint(0,0),m_chart->size());
64 65 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
65 66
66 67 //rewrite zoom stack
67 68 for(int i=0;i<m_zoomStack.count();i++){
68 69 QRectF r = m_zoomStack[i];
69 70 qreal w = rect.width()/m_rect.width();
70 71 qreal h = rect.height()/m_rect.height();
71 72 QPointF tl = r.topLeft();
72 73 tl.setX(tl.x()*w);
73 74 tl.setY(tl.y()*h);
74 75 QPointF br = r.bottomRight();
75 76 br.setX(br.x()*w);
76 77 br.setY(br.y()*h);
77 78 r.setTopLeft(tl);
78 79 r.setBottomRight(br);
79 80 m_zoomStack[i]=r;
80 81 }
81 82
82 83 m_rect = rect;
83 84 Q_ASSERT(m_rect.isValid());
84 85 emit geometryChanged(m_rect);
85 86 }
86 87
87 88 int ChartPresenter::margin() const
88 89 {
89 90 return m_marginSize;
90 91 }
91 92
92 93 void ChartPresenter::setMargin(int margin)
93 94 {
94 95 m_marginSize = margin;
95 96 }
96 97
97 98 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
98 99 {
100 AxisItem* item = new AxisItem(axis,this,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
99 101
100 AxisItem* item ;
101
102 if(!m_options.testFlag(QChart::GridAxisAnimations))
103 {
104 item = new AxisItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
105 }else{
106 item = new AxisAnimationItem(axis,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
102 if(m_options.testFlag(QChart::GridAxisAnimations)){
103 m_animator->addAnimation(item);
107 104 }
105
108 106 if(axis==m_dataset->axisX()){
109 107 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
110 108 //initialize
111 109 item->handleRangeChanged(domain->minX(),domain->maxX());
112 110 }
113 111 else{
114 112 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal)),item,SLOT(handleRangeChanged(qreal,qreal)));
115 113 //initialize
116 114 item->handleRangeChanged(domain->minY(),domain->maxY());
117
118 115 }
119 116
120 117 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
121 118 //initialize
122 119 item->handleGeometryChanged(m_rect);
123 120 m_chartTheme->decorate(axis,item);
124 121 m_axisItems.insert(axis,item);
122
125 123 }
126 124
127 125 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
128 126 {
129 127 AxisItem* item = m_axisItems.take(axis);
130 128 Q_ASSERT(item);
129 if(m_animator) m_animator->removeAnimation(item);
131 130 delete item;
132 131 }
133 132
134 133
135 134 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
136 135 {
137 136 switch(series->type())
138 137 {
139 138 case QSeries::SeriesTypeLine: {
140 139
141 140 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
142 LineChartItem* item;
141 LineChartItem* item = new LineChartItem(lineSeries,m_chart);
143 142 if(m_options.testFlag(QChart::SeriesAnimations)){
144 item = new LineChartAnimationItem(lineSeries,m_chart);
145 }else{
146 item = new LineChartItem(lineSeries,m_chart);
143 m_animator->addAnimation(item);
147 144 }
148 145 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
149 146 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
150 147 //initialize
151 148 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
152 149 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
153 150 //decorate
154 151 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
155 152 m_chartItems.insert(series,item);
156 153 break;
157 154 }
158 155
159 156 case QSeries::SeriesTypeArea: {
160 157
161 158 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
162 AreaChartItem* item;
159 AreaChartItem* item = new AreaChartItem(areaSeries,m_chart);
163 160 if(m_options.testFlag(QChart::SeriesAnimations)) {
164 item = new AreaChartItem(areaSeries,m_chart);
165 }
166 else {
167 item = new AreaChartItem(areaSeries,m_chart);
161 // m_animator->addAnimation(item);
168 162 }
169 163 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
170 164 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
171 165 //initialize
172 166 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
173 167 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
174 168 //decorate
175 169 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
176 170 m_chartItems.insert(series,item);
177 171 break;
178 172 }
179 173
180 174 case QSeries::SeriesTypeBar: {
181 175 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
182 176 BarPresenter* item = new BarPresenter(barSeries,m_chart);
183 177 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
184 178 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
185 179 // QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
186 180 m_chartItems.insert(series,item);
187 181 // m_axisXItem->setVisible(false);
188 182 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
189 183 break;
190 184 }
191 185
192 186 case QSeries::SeriesTypeStackedBar: {
193 187
194 188 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
195 189 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
196 190 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
197 191 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
198 192 // QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
199 193 m_chartItems.insert(series,item);
200 194 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
201 195 break;
202 196 }
203 197
204 198 case QSeries::SeriesTypePercentBar: {
205 199
206 200 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
207 201 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
208 202 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
209 203 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
210 204 // QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
211 205 m_chartItems.insert(series,item);
212 206 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
213 207 break;
214 208 }
215 209 case QSeries::SeriesTypeScatter: {
216 210 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
217 ScatterChartItem *item;
211 ScatterChartItem *item = new ScatterChartItem(scatterSeries, m_chart);
218 212 if(m_options.testFlag(QChart::SeriesAnimations)) {
219 item = new ScatterChartAnimationItem(scatterSeries,m_chart);
220 } else {
221 item = new ScatterChartItem(scatterSeries, m_chart);
213 m_animator->addAnimation(item);
222 214 }
223 215 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
224 216 item, SLOT(handleGeometryChanged(const QRectF&)));
225 217 QObject::connect(domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),
226 218 item, SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
227 219 //initialize
228 220 if (m_rect.isValid())
229 221 item->handleGeometryChanged(m_rect);
230 222 item->handleDomainChanged(domain->minX(), domain->maxX(), domain->minY(), domain->maxY());
231 223 //decorate
232 224 m_chartTheme->decorate(item, scatterSeries, m_chartItems.count());
233 225 m_chartItems.insert(scatterSeries, item);
234 226
235 227 break;
236 228 }
237 229 case QSeries::SeriesTypePie: {
238 230 QPieSeries *s = qobject_cast<QPieSeries *>(series);
239 231 PiePresenter* pie = new PiePresenter(m_chart, s);
240 232 m_chartTheme->decorate(pie, s, m_chartItems.count());
241 233 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
242 234
243 235 // Hide all from background when there is only piechart
244 236 // TODO: refactor this ugly code... should be one setting for this
245 237 if (m_chartItems.count() == 0) {
246 238 m_chart->axisX()->setAxisVisible(false);
247 239 m_chart->axisY()->setAxisVisible(false);
248 240 m_chart->axisX()->setGridVisible(false);
249 241 m_chart->axisY()->setGridVisible(false);
250 242 m_chart->axisX()->setLabelsVisible(false);
251 243 m_chart->axisY()->setLabelsVisible(false);
252 244 m_chart->axisX()->setShadesVisible(false);
253 245 m_chart->axisY()->setShadesVisible(false);
254 246 m_chart->setChartBackgroundBrush(Qt::transparent);
255 247 }
256 248
257 249 m_chartItems.insert(series, pie);
258 250 pie->handleGeometryChanged(m_rect);
259 251 break;
260 252 }
261 253
262 254 case QSeries::SeriesTypeSpline: {
263 255
264 256 QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series);
265 SplineChartItem* item;
257 SplineChartItem* item = new SplineChartItem(splineSeries, m_chart);
266 258 if(m_options.testFlag(QChart::SeriesAnimations)) {
267 item = new SplineChartAnimationItem(splineSeries, m_chart);
268 } else {
269 item = new SplineChartItem(splineSeries, m_chart);
259 m_animator->addAnimation(item);
270 260 }
271 261 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), item, SLOT(handleGeometryChanged(const QRectF&)));
272 262 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
273 263 //initialize
274 264 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
275 265 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
276 266 //decorate
277 267 m_chartTheme->decorate(item, splineSeries, m_chartItems.count());
278 268 m_chartItems.insert(splineSeries, item);
279 269 break;
280 270 }
281 271 default: {
282 272 qDebug()<< "Series type" << series->type() << "not implemented.";
283 273 break;
284 274 }
285 275 }
286 276
287 277 zoomReset();
288 278 }
289 279
290 280 void ChartPresenter::handleSeriesRemoved(QSeries* series)
291 281 {
292 282 ChartItem* item = m_chartItems.take(series);
283 Q_ASSERT(item);
284 if(m_animator) m_animator->removeAnimation(item);
293 285 delete item;
294 286 }
295 287
296 288 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
297 289 {
298 290 delete m_chartTheme;
299 291
300 292 m_chartTheme = ChartTheme::createTheme(theme);
301 293
302 294 m_chartTheme->decorate(m_chart);
303 295 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
304 296
305 297 int index=0;
306 298 while (i.hasNext()) {
307 299 i.next();
308 300 m_chartTheme->decorate(i.value(),i.key(),index);
309 301 index++;
310 302 }
311 303
312 304 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
313 305 while (j.hasNext()) {
314 306 j.next();
315 307 m_chartTheme->decorate(j.key(),j.value());
316 308 }
317 309 }
318 310
319 311 QChart::ChartTheme ChartPresenter::chartTheme()
320 312 {
321 313 return m_chartTheme->id();
322 314 }
323 315
324 316 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
325 317 {
326 318 if(m_options!=options) {
327 319
328 320 m_options=options;
329 321
322 if(m_options!=QChart::NoAnimation && !m_animator) {
323 m_animator= new ChartAnimator(this);
324 }
325
330 326 //recreate elements
331 327 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
332 328 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
333 329
334 330 foreach(QChartAxis* axis, axisList) {
335 331 handleAxisRemoved(axis);
336 332 handleAxisAdded(axis,m_dataset->domain(axis));
337 333 }
338 334 foreach(QSeries* series, seriesList) {
339 335 handleSeriesRemoved(series);
340 336 handleSeriesAdded(series,m_dataset->domain(series));
341 337 }
342 338 }
339
343 340 }
344 341
345 342 void ChartPresenter::zoomIn()
346 343 {
347 344 QRectF rect = geometry();
348 345 rect.setWidth(rect.width()/2);
349 346 rect.setHeight(rect.height()/2);
350 347 rect.moveCenter(geometry().center());
351 348 zoomIn(rect);
352 349 }
353 350
354 351 void ChartPresenter::zoomIn(const QRectF& rect)
355 352 {
356 353 QRectF r = rect.normalized();
357 354 r.translate(-m_marginSize, -m_marginSize);
358 355 m_dataset->zoomInDomain(r,geometry().size());
359 356 m_zoomStack<<r;
360 357 m_zoomIndex++;
361 358 }
362 359
363 360 void ChartPresenter::zoomOut()
364 361 {
365 362 if(m_zoomIndex==0) return;
366 363 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
367 364 m_zoomIndex--;
368 365 m_zoomStack.resize(m_zoomIndex);
369 366 }
370 367
371 368 void ChartPresenter::zoomReset()
372 369 {
373 370 m_zoomIndex=0;
374 371 m_zoomStack.resize(m_zoomIndex);
375 372 }
376 373
377 374 QChart::AnimationOptions ChartPresenter::animationOptions() const
378 375 {
379 376 return m_options;
380 377 }
381 378
382 379
383 380 #include "moc_chartpresenter_p.cpp"
384 381
385 382 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,82 +1,84
1 1 #ifndef CHARTPRESENTER_H_
2 2 #define CHARTPRESENTER_H_
3 3
4 4 #include "qchartglobal.h"
5 5 #include "qchart.h" //becouse of QChart::ChartThemeId //TODO
6 6 #include "qchartaxis.h"
7 7 #include <QRectF>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 class ChartItem;
12 12 class QSeries;
13 13 class ChartDataSet;
14 //class QChart;
15 14 class Domain;
16 15 class AxisItem;
17 16 class ChartTheme;
17 class ChartAnimator;
18 18
19 19 class ChartPresenter: public QObject
20 20 {
21 21 Q_OBJECT
22 22 public:
23 23 enum ZValues {
24 24 BackgroundZValue = -1,
25 25 ShadesZValue,
26 26 GridZValue,
27 27 AxisZValue,
28 28 LineChartZValue,
29 29 ScatterSeriesZValue,
30 30 PieSeriesZValue
31 31 };
32 32
33 33 ChartPresenter(QChart* chart,ChartDataSet *dataset);
34 34 virtual ~ChartPresenter();
35 35
36 36 void setMargin(int margin);
37 37 int margin() const;
38 38
39 39 QRectF geometry() const;
40 ChartAnimator* animator() const {return m_animator;};
40 41
41 42 void setChartTheme(QChart::ChartTheme theme);
42 43 QChart::ChartTheme chartTheme();
43 44
44 45 void setAnimationOptions(QChart::AnimationOptions options);
45 46 QChart::AnimationOptions animationOptions() const;
46 47
47 48 void zoomIn();
48 49 void zoomIn(const QRectF& rect);
49 50 void zoomOut();
50 51 void zoomReset();
51 52
52 53
53 54 private:
54 55 void createConnections();
55 56
56 57 public slots:
57 58 void handleSeriesAdded(QSeries* series,Domain* domain);
58 59 void handleSeriesRemoved(QSeries* series);
59 60 void handleAxisAdded(QChartAxis* axis,Domain* domain);
60 61 void handleAxisRemoved(QChartAxis* axis);
61 62 void handleGeometryChanged();
62 63
63 64 signals:
64 65 void geometryChanged(const QRectF& rect);
65 66
66 67 private:
67 68 QChart* m_chart;
69 ChartAnimator* m_animator;
68 70 ChartDataSet* m_dataset;
69 71 ChartTheme *m_chartTheme;
70 72 int m_zoomIndex;
71 73 int m_marginSize;
72 74 QMap<QSeries*,ChartItem*> m_chartItems;
73 75 QMap<QChartAxis*,AxisItem*> m_axisItems;
74 76 QVector<QRectF> m_zoomStack;
75 77 QRectF m_rect;
76 78 QChart::AnimationOptions m_options;
77 79
78 80 };
79 81
80 82 QTCOMMERCIALCHART_END_NAMESPACE
81 83
82 84 #endif /* CHARTPRESENTER_H_ */
@@ -1,54 +1,48
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"
7 6 #include <QPen>
8 7
9 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 9
11 class ChartPresenter;
12 10 class QLineSeries;
13 11
14 12 class LineChartItem : public XYChartItem
15 13 {
16 14 Q_OBJECT
17 15 public:
18 16 explicit LineChartItem(QLineSeries* series,QGraphicsItem *parent = 0);
19 17 ~ LineChartItem(){};
20 18
21 19 //from QGraphicsItem
22 20 QRectF boundingRect() const;
23 21 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
24 22 QPainterPath shape() const;
25 23
26 24 void setLinePen(const QPen& pen);
27 25 void setPointsVisible(bool visible);
28 26
29 27 public slots:
30 28 void handleUpdated();
31 29
32 30 protected:
33 31 virtual void setGeometry(QVector<QPointF>& points);
34 32
35 33 private:
36 34 void createPoints(int count);
37 35 void deletePoints(int count);
38 36
39 37 private:
40 38 QLineSeries* m_series;
41 39 QGraphicsItemGroup m_items;
42 40 QPainterPath m_path;
43 41 QRectF m_rect;
44 42 QPen m_pen;
45 43
46 template<class,class> friend class XYChartAnimator;
47
48 44 };
49 45
50 typedef XYChartAnimationItem<LineChartItem,QLineSeries> LineChartAnimationItem;
51
52 46 QTCOMMERCIALCHART_END_NAMESPACE
53 47
54 48 #endif
@@ -1,55 +1,51
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 "xychartanimationitem_p.h"
7 6 #include <QGraphicsItem>
8 7 #include <QPen>
9 8
10 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 10
12 11 class QScatterSeries;
13 12
14 13 class ScatterChartItem : public XYChartItem
15 14 {
16 15 Q_OBJECT
17 16 public:
18 17 explicit ScatterChartItem(QScatterSeries *series, QGraphicsItem *parent = 0);
19 18
20 19 public:
21 20 //from QGraphicsItem
22 21 QRectF boundingRect() const;
23 22 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
24 23
25 24 void setPen(const QPen& pen);
26 25 void setBrush(const QBrush& brush);
27 26
28 27 signals:
29 28 void clicked(QPointF coordinates);
30 29
31 30 public slots:
32 31 void handleUpdated();
33 32
34 33 private:
35 34 void createPoints(int count);
36 35 void deletePoints(int count);
37 36
38 37 protected:
39 38 virtual void setGeometry(QVector<QPointF>& points);
40 39
41 40 private:
42 41 QScatterSeries *m_series;
43 42 QGraphicsItemGroup m_items;
44 43 int m_shape;
45 44 int m_size;
46 45 QRectF m_rect;
47 46
48 template<class,class> friend class XYChartAnimator;
49 47 };
50 48
51 typedef XYChartAnimationItem<ScatterChartItem,QScatterSeries> ScatterChartAnimationItem;
52
53 49 QTCOMMERCIALCHART_END_NAMESPACE
54 50
55 51 #endif // SCATTERPRESENTER_H
@@ -1,47 +1,43
1 1 #ifndef SPLINECHARTITEM_P_H
2 2 #define SPLINECHARTITEM_P_H
3 3
4 4 #include "qsplineseries.h"
5 5 #include "xychartitem_p.h"
6 #include "xychartanimationitem_p.h"
7 6 #include <QGraphicsItem>
8 7
9 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 9
11 10 class SplineChartItem : public XYChartItem
12 11 {
13 12 Q_OBJECT
14 13 public:
15 14 SplineChartItem(QSplineSeries* series, QGraphicsItem *parent = 0);
16 15
17 16 //from QGraphicsItem
18 17 QRectF boundingRect() const;
19 18 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
20 19 QPainterPath shape() const;
21 20
22 21 void setLinePen(const QPen& pen);
23 22 void setPointsVisible(bool visible);
24 23
25 24 public slots:
26 25 void handleUpdated();
27 26
28 27 protected:
29 28 void setGeometry(QVector<QPointF>& points);
30 29
31 30 private:
32 31 QPointF calculateGeometryControlPoint(int index) const;
33 32
34 33 private:
35 34 QSplineSeries* m_series;
36 35 QPainterPath m_path;
37 36 QRectF m_rect;
38 37 QPen m_pen;
39 38
40 template<class,class> friend class XYChartAnimator;
41 39 };
42 40
43 typedef XYChartAnimationItem<SplineChartItem,QSplineSeries> SplineChartAnimationItem;
44
45 41 QTCOMMERCIALCHART_END_NAMESPACE
46 42
47 43 #endif // SPLINECHARTITEM_P_H
@@ -1,95 +1,96
1 1 !include( ../common.pri ):error( Couldn't find the common.pri file! )
2 2 TARGET = QtCommercialChart
3 3 DESTDIR = $$CHART_BUILD_LIB_DIR
4 4 TEMPLATE = lib
5 5 QT += core \
6 6 gui
7 7 CONFIG += debug_and_release
8 8 CONFIG(debug, debug|release):TARGET = QtCommercialChartd
9 9 SOURCES += \
10 10 chartdataset.cpp \
11 11 chartpresenter.cpp \
12 12 charttheme.cpp \
13 13 domain.cpp \
14 14 qchart.cpp \
15 15 qchartview.cpp \
16 16 qseries.cpp \
17 17 qlegend.cpp
18 18 PRIVATE_HEADERS += \
19 19 chartdataset_p.h \
20 20 chartitem_p.h \
21 21 chartpresenter_p.h \
22 22 charttheme_p.h \
23 23 domain_p.h
24 24 PUBLIC_HEADERS += \
25 25 qchart.h \
26 26 qchartglobal.h \
27 27 qseries.h \
28 28 qchartview.h \
29 29 qlegend.h
30
30
31 include(animations/animations.pri)
31 32 include(axis/axis.pri)
32 33 include(xychart/xychart.pri)
33 34 include(linechart/linechart.pri)
34 35 include(areachart/areachart.pri)
35 36 include(barchart/barchart.pri)
36 37 include(piechart/piechart.pri)
37 38 include(scatterseries/scatter.pri)
38 39 include(splinechart/splinechart.pri)
39 40
40 41 THEMES += themes/chartthemedefault_p.h \
41 42 themes/chartthemeicy_p.h \
42 43 themes/chartthemegrayscale_p.h \
43 44 themes/chartthemescientific_p.h \
44 45 themes/chartthemevanilla_p.h
45 46 HEADERS += $$PUBLIC_HEADERS
46 47 HEADERS += $$PRIVATE_HEADERS
47 48 HEADERS += $$THEMES
48 49 INCLUDEPATH += linechart \
49 50 barchart \
50 51 themes \
51 52 .
52 53 OBJECTS_DIR = $$CHART_BUILD_DIR/lib
53 54 MOC_DIR = $$CHART_BUILD_DIR/lib
54 55 UI_DIR = $$CHART_BUILD_DIR/lib
55 56 RCC_DIR = $$CHART_BUILD_DIR/lib
56 57 DEFINES += QTCOMMERCIALCHART_LIBRARY
57 58 public_headers.path = $$[QT_INSTALL_HEADERS]/QtCommercialChart
58 59 public_headers.files = $$PUBLIC_HEADERS
59 60 target.path = $$[QT_INSTALL_LIBS]
60 61 INSTALLS += target \
61 62 public_headers
62 63 install_build_public_headers.name = bild_public_headers
63 64 install_build_public_headers.output = $$CHART_BUILD_PUBLIC_HEADER_DIR/${QMAKE_FILE_BASE}.h
64 65 install_build_public_headers.input = PUBLIC_HEADERS
65 66 install_build_public_headers.commands = $$QMAKE_COPY \
66 67 ${QMAKE_FILE_NAME} \
67 68 $$CHART_BUILD_PUBLIC_HEADER_DIR
68 69 install_build_public_headers.CONFIG += target_predeps \
69 70 no_link
70 71 install_build_private_headers.name = bild_private_headers
71 72 install_build_private_headers.output = $$CHART_BUILD_PRIVATE_HEADER_DIR/${QMAKE_FILE_BASE}.h
72 73 install_build_private_headers.input = PRIVATE_HEADERS
73 74 install_build_private_headers.commands = $$QMAKE_COPY \
74 75 ${QMAKE_FILE_NAME} \
75 76 $$CHART_BUILD_PRIVATE_HEADER_DIR
76 77 install_build_private_headers.CONFIG += target_predeps \
77 78 no_link
78 79 QMAKE_EXTRA_COMPILERS += install_build_public_headers \
79 80 install_build_private_headers
80 81 chartversion.target = qchartversion_p.h
81 82 chartversion.commands = @echo \
82 83 "build_time" \
83 84 > \
84 85 $$chartversion.target;
85 86 chartversion.depends = $$HEADERS \
86 87 $$SOURCES
87 88 PRE_TARGETDEPS += qchartversion_p.h
88 89 QMAKE_CLEAN += qchartversion_p.h
89 90 QMAKE_EXTRA_TARGETS += chartversion
90 91 unix:QMAKE_DISTCLEAN += -r \
91 92 $$CHART_BUILD_HEADER_DIR \
92 93 $$CHART_BUILD_LIB_DIR
93 94 win32:QMAKE_DISTCLEAN += /Q \
94 95 $$CHART_BUILD_HEADER_DIR \
95 96 $$CHART_BUILD_LIB_DIR
@@ -1,14 +1,13
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 5 $$PWD/xychartitem.cpp \
6 6 $$PWD/qxyseries.cpp
7 7
8 8 PRIVATE_HEADERS += \
9 $$PWD/xychartitem_p.h \
10 $$PWD/xychartanimationitem_p.h \
11 $$PWD/xychartanimator_p.h
9 $$PWD/xychartitem_p.h
10
12 11
13 12 PUBLIC_HEADERS += \
14 13 $$PWD/qxyseries.h No newline at end of file
@@ -1,142 +1,147
1 1 #include "xychartitem_p.h"
2 2 #include "qxyseries.h"
3 3 #include "chartpresenter_p.h"
4 #include "chartanimator_p.h"
4 5 #include <QPainter>
5 6
6 7
7 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 9
9 10 //TODO: optimize : remove points which are not visible
10 11
11 XYChartItem::XYChartItem(QXYSeries* series,QGraphicsItem *parent):ChartItem(parent),
12 XYChartItem::XYChartItem(QXYSeries* series, QGraphicsItem *parent):ChartItem(parent),
12 13 m_minX(0),
13 14 m_maxX(0),
14 15 m_minY(0),
15 16 m_maxY(0),
16 17 m_series(series)
17 18 {
18 19 QObject::connect(series,SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
19 20 QObject::connect(series,SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
20 21 QObject::connect(series,SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
21 22
22 23 }
23 24
24 25 QPointF XYChartItem::calculateGeometryPoint(const QPointF& point) const
25 26 {
26 27 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
27 28 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
28 29 qreal x = (point.x() - m_minX)* deltaX;
29 30 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
30 31 return QPointF(x,y);
31 32 }
32 33
33 34
34 35 QPointF XYChartItem::calculateGeometryPoint(int index) const
35 36 {
36 37 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
37 38 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
38 39 qreal x = (m_series->x(index) - m_minX)* deltaX;
39 40 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
40 41 return QPointF(x,y);
41 42 }
42 43
43 44 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
44 45 {
45 46 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
46 47 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
47 48
48 49 QVector<QPointF> points;
49 50 points.reserve(m_series->count());
50 51 for (int i = 0; i < m_series->count(); ++i) {
51 52 qreal x = (m_series->x(i) - m_minX)* deltaX;
52 53 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
53 54 points << QPointF(x,y);
54 55 }
55 56 return points;
56 57 }
57 58
58 59 void XYChartItem::updatePoints(QVector<QPointF>& points)
59 60 {
60 setGeometry(points);
61 if(m_animator){
62 m_animator->applyLayout(this,points);
63 }
64 else setGeometry(points);
65
61 66 }
62 67
63 68 void XYChartItem::updatePoint(QVector<QPointF>& points)
64 69 {
65 70 setGeometry(points);
66 71 }
67 72
68 73 void XYChartItem::setGeometry(QVector<QPointF>& points)
69 74 {
70 75 m_points = points;
71 76 }
72 77
73 78 //handlers
74 79
75 80 void XYChartItem::handlePointAdded(int index)
76 81 {
77 82 Q_ASSERT(index<m_series->count());
78 83 Q_ASSERT(index>=0);
79 84
80 85 QPointF point = calculateGeometryPoint(index);
81 86 QVector<QPointF> points = m_points;
82 87 points.insert(index,point);
83 88 updatePoints(points);
84 89 update();
85 90 }
86 91 void XYChartItem::handlePointRemoved(int index)
87 92 {
88 93 Q_ASSERT(index<m_series->count());
89 94 Q_ASSERT(index>=0);
90 95 QPointF point = calculateGeometryPoint(index);
91 96 QVector<QPointF> points = m_points;
92 97 points.remove(index);
93 98 updatePoints(points);
94 99 update();
95 100 }
96 101
97 102 void XYChartItem::handlePointReplaced(int index)
98 103 {
99 104 Q_ASSERT(index<m_series->count());
100 105 Q_ASSERT(index>=0);
101 106 QPointF point = calculateGeometryPoint(index);
102 107 QVector<QPointF> points = m_points;
103 108 points.replace(index,point);
104 109 updatePoint(points);
105 110 update();
106 111 }
107 112
108 113 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
109 114 {
110 115 m_minX=minX;
111 116 m_maxX=maxX;
112 117 m_minY=minY;
113 118 m_maxY=maxY;
114 119
115 120 if(isEmpty()) return;
116 121 QVector<QPointF> points = calculateGeometryPoints();
117 122 updatePoints(points);
118 123 update();
119 124 }
120 125
121 126 void XYChartItem::handleGeometryChanged(const QRectF& rect)
122 127 {
123 128 Q_ASSERT(rect.isValid());
124 129 m_size=rect.size();
125 130 m_clipRect=rect.translated(-rect.topLeft());
126 131 setPos(rect.topLeft());
127 132
128 133 if(isEmpty()) return;
129 134 QVector<QPointF> points = calculateGeometryPoints();
130 135 updatePoints(points);
131 136 update();
132 137 }
133 138
134 139
135 140 bool XYChartItem::isEmpty()
136 141 {
137 142 return !m_clipRect.isValid() || m_maxX - m_minX == 0 || m_maxY - m_minY ==0 ;
138 143 }
139 144
140 145 #include "moc_xychartitem_p.cpp"
141 146
142 147 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,58 +1,57
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 explicit XYChartItem(QXYSeries* series,QGraphicsItem *parent = 0);
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 virtual void updatePoints(QVector<QPointF>& points);
32 virtual void updatePoint(QVector<QPointF>& points);
33 31 virtual void setGeometry(QVector<QPointF>& points);
34
35 32 QPointF calculateGeometryPoint(const QPointF& point) const;
36 33 QPointF calculateGeometryPoint(int index) const;
37 34 QVector<QPointF> calculateGeometryPoints() const;
38 35
39 36 private:
37 void updatePoints(QVector<QPointF>& points);
38 void updatePoint(QVector<QPointF>& points);
40 39 inline bool isEmpty();
41 40
42 41 private:
43 42 qreal m_minX;
44 43 qreal m_maxX;
45 44 qreal m_minY;
46 45 qreal m_maxY;
47 46 QXYSeries* m_series;
48 47 QSizeF m_size;
49 48 QRectF m_clipRect;
50 49 QVector<QPointF> m_points;
51 50
52 template<class,class> friend class XYChartAnimator;
51 friend class XYAnimation;
53 52
54 53 };
55 54
56 55 QTCOMMERCIALCHART_END_NAMESPACE
57 56
58 57 #endif
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now