summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@digia.com>2012-05-25 13:47:19 +0300
committerMichal Klocek <michal.klocek@digia.com>2012-05-25 13:49:11 +0300
commit51695bb27b0ea6cae78968b5b21021ea88320527 (patch)
tree37651f9b1f6b42f000a3dd1aa8b7dd7c38fd823b
parent897a83c64309456c739ecd282b297a28a123d567 (diff)
Refactors axis animation, line animations
-rw-r--r--src/animations/axisanimation.cpp75
-rw-r--r--src/animations/axisanimation_p.h11
-rw-r--r--src/animations/chartanimation_p.h1
-rw-r--r--src/animations/chartanimator.cpp102
-rw-r--r--src/animations/chartanimator_p.h12
-rw-r--r--src/animations/splineanimation.cpp7
-rw-r--r--src/animations/xyanimation.cpp80
-rw-r--r--src/animations/xyanimation_p.h8
-rw-r--r--src/areachart/areachartitem.cpp5
-rw-r--r--src/areachart/areachartitem_p.h4
-rw-r--r--src/axis/axis.pri4
-rw-r--r--src/axis/chartaxis.cpp215
-rw-r--r--src/axis/chartaxis_p.h35
-rw-r--r--src/axis/chartaxisx.cpp112
-rw-r--r--src/axis/chartaxisx_p.h46
-rw-r--r--src/axis/chartaxisy.cpp116
-rw-r--r--src/axis/chartaxisy_p.h46
-rw-r--r--src/chartpresenter.cpp70
-rw-r--r--src/chartpresenter_p.h22
-rw-r--r--src/splinechart/splinechartitem.cpp2
-rw-r--r--src/xychart/xychart.cpp99
-rw-r--r--src/xychart/xychart_p.h6
22 files changed, 690 insertions, 388 deletions
diff --git a/src/animations/axisanimation.cpp b/src/animations/axisanimation.cpp
index 9f694ed4..e27cf1cc 100644
--- a/src/animations/axisanimation.cpp
+++ b/src/animations/axisanimation.cpp
@@ -19,7 +19,9 @@
****************************************************************************/
#include "axisanimation_p.h"
+#include "chartaxis_p.h"
#include <QTimer>
+#include <QDebug>
Q_DECLARE_METATYPE(QVector<qreal>)
@@ -27,14 +29,84 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE
AxisAnimation::AxisAnimation(ChartAxis *axis): ChartAnimation(axis),
- m_axis(axis)
+ m_axis(axis),
+ m_type(DefaultAnimation)
{
+ setDuration(ChartAnimationDuration);
+ setEasingCurve(QEasingCurve::OutQuart);
}
AxisAnimation::~AxisAnimation()
{
}
+void AxisAnimation::setAnimationType(Animation type)
+{
+ if (state() != QAbstractAnimation::Stopped) stop();
+ m_type=type;
+}
+
+void AxisAnimation::setAnimationPoint(const QPointF& point)
+{
+ if (state() != QAbstractAnimation::Stopped) stop();
+ m_point=point;
+}
+
+void AxisAnimation::setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayout)
+{
+ if (state() != QAbstractAnimation::Stopped) stop();
+
+ if (newLayout.count() == 0)
+ return;
+
+ switch (m_type) {
+ case ZoomOutAnimation: {
+ QRectF rect = m_axis->geometry();
+ oldLayout.resize(newLayout.count());
+
+ for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
+ oldLayout[i] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.bottom();
+ oldLayout[j] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.right() : rect.top();
+ }
+ }
+ break;
+ case ZoomInAnimation: {
+ int index = qMin(oldLayout.count() * (m_axis->axisType() == ChartAxis::X_AXIS ? m_point.x() : (1 - m_point.y())), newLayout.count() - 1.0);
+ oldLayout.resize(newLayout.count());
+
+ for(int i = 0; i < oldLayout.count(); i++)
+ oldLayout[i]= oldLayout[index];
+ }
+ break;
+ case MoveForwardAnimation: {
+ oldLayout.resize(newLayout.count());
+
+ for(int i = 0, j = i + 1; i < oldLayout.count() - 1; ++i, ++j)
+ oldLayout[i]= oldLayout[j];
+ }
+ break;
+ case MoveBackwordAnimation: {
+ oldLayout.resize(newLayout.count());
+
+ for(int i = oldLayout.count() - 1, j = i - 1; i > 0; --i, --j)
+ oldLayout[i]= oldLayout[j];
+ }
+ break;
+ default: {
+ oldLayout.resize(newLayout.count());
+ QRectF rect = m_axis->geometry();
+ for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
+ oldLayout[i] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.top();
+ }
+ break;
+ }
+
+ QVariantAnimation::KeyValues value;
+ setKeyValues(value); //workaround for wrong interpolation call
+ setKeyValueAt(0.0, qVariantFromValue(oldLayout));
+ setKeyValueAt(1.0, qVariantFromValue(newLayout));
+}
+
QVariant AxisAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
{
QVector<qreal> startVector = qVariantValue<QVector<qreal> >(start);
@@ -58,6 +130,7 @@ void AxisAnimation::updateCurrentValue (const QVariant &value )
QVector<qreal> vector = qVariantValue<QVector<qreal> >(value);
Q_ASSERT(vector.count() != 0);
m_axis->setLayout(vector);
+ m_axis->updateGeometry();
}
}
diff --git a/src/animations/axisanimation_p.h b/src/animations/axisanimation_p.h
index ff2317cf..97ec839e 100644
--- a/src/animations/axisanimation_p.h
+++ b/src/animations/axisanimation_p.h
@@ -21,22 +21,29 @@
#ifndef AXISANIMATION_H
#define AXISANIMATION_H
-#include "chartaxis_p.h"
#include "chartanimation_p.h"
-
+#include <QPointF>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
+class ChartAxis;
+
class AxisAnimation: public ChartAnimation
{
public:
+ enum Animation { DefaultAnimation, ZoomOutAnimation, ZoomInAnimation, MoveForwardAnimation, MoveBackwordAnimation};
AxisAnimation(ChartAxis *axis);
~AxisAnimation();
+ void setAnimationType(Animation type);
+ void setAnimationPoint(const QPointF& point);
+ void setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayout);
protected:
QVariant interpolated(const QVariant &from, const QVariant &to, qreal progress ) const;
void updateCurrentValue(const QVariant &value );
private:
ChartAxis *m_axis;
+ Animation m_type;
+ QPointF m_point;
};
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/animations/chartanimation_p.h b/src/animations/chartanimation_p.h
index 0e855e8f..cba058cc 100644
--- a/src/animations/chartanimation_p.h
+++ b/src/animations/chartanimation_p.h
@@ -30,6 +30,7 @@ const static int ChartAnimationDuration = 1000;
class ChartAnimation: public QVariantAnimation
{
+ Q_OBJECT
public:
ChartAnimation(QObject *parent = 0):QVariantAnimation(parent){};
};
diff --git a/src/animations/chartanimator.cpp b/src/animations/chartanimator.cpp
index abc03667..be5a1b90 100644
--- a/src/animations/chartanimator.cpp
+++ b/src/animations/chartanimator.cpp
@@ -29,6 +29,7 @@
#include "areachartitem_p.h"
#include "splinechartitem_p.h"
#include "scatterchartitem_p.h"
+#include "chartaxis_p.h"
#include <QTimer>
Q_DECLARE_METATYPE(QVector<QPointF>)
@@ -37,27 +38,13 @@ Q_DECLARE_METATYPE(QVector<QRectF>)
QTCOMMERCIALCHART_BEGIN_NAMESPACE
-ChartAnimator::ChartAnimator(QObject *parent):QObject(parent),
- m_state(ShowState)
+ChartAnimator::ChartAnimator(QObject *parent):QObject(parent)
{
}
ChartAnimator::~ChartAnimator()
{
}
-
-void ChartAnimator::addAnimation(ChartAxis *item)
-{
- ChartAnimation *animation = m_animations.value(item);
-
- if (!animation) {
- animation = new AxisAnimation(item);
- m_animations.insert(item, animation);
- }
-
- item->setAnimator(this);
-}
-
void ChartAnimator::addAnimation(PieChartItem *item)
{
ChartAnimation *animation = m_animations.value(item);
@@ -89,75 +76,6 @@ void ChartAnimator::removeAnimation(Chart *item)
m_animations.remove(item);
}
-void ChartAnimator::updateLayout(ChartAxis *item , QVector<qreal> &newLayout)
-{
- AxisAnimation *animation = static_cast<AxisAnimation*>(m_animations.value(item));
-
- Q_ASSERT(animation);
-
- QVector<qreal> oldLayout = item->layout();
-
- if (newLayout.count() == 0)
- return;
-
- switch (m_state) {
- case ZoomOutState: {
- QRectF rect = item->geometry();
- oldLayout.resize(newLayout.count());
-
- for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
- oldLayout[i] = item->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.bottom();
- oldLayout[j] = item->axisType() == ChartAxis::X_AXIS ? rect.right() : rect.top();
- }
- }
- break;
- case ZoomInState: {
- int index = qMin(oldLayout.count() * (item->axisType() == ChartAxis::X_AXIS ? m_point.x() : (1 - m_point.y())), newLayout.count() - 1.0);
- oldLayout.resize(newLayout.count());
-
- for(int i = 0; i < oldLayout.count(); i++)
- oldLayout[i]= oldLayout[index];
- }
- break;
- case ScrollDownState:
- case ScrollRightState: {
- oldLayout.resize(newLayout.count());
-
- for(int i = 0, j = i + 1; i < oldLayout.count() - 1; ++i, ++j)
- oldLayout[i]= oldLayout[j];
- }
- break;
- case ScrollUpState:
- case ScrollLeftState: {
- oldLayout.resize(newLayout.count());
-
- for(int i = oldLayout.count() - 1, j = i - 1; i > 0; --i, --j)
- oldLayout[i]= oldLayout[j];
- }
- break;
- default: {
- oldLayout.resize(newLayout.count());
- QRectF rect = item->geometry();
- for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
- oldLayout[i] = item->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.top();
- }
- break;
- }
-
-
- if (animation->state() != QAbstractAnimation::Stopped)
- animation->stop();
-
- animation->setDuration(ChartAnimationDuration);
- animation->setEasingCurve(QEasingCurve::OutQuart);
- QVariantAnimation::KeyValues value;
- animation->setKeyValues(value); //workaround for wrong interpolation call
- animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout));
- animation->setKeyValueAt(1.0, qVariantFromValue(newLayout));
-
- QTimer::singleShot(0, animation, SLOT(start()));
-}
-
void ChartAnimator::addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool startupAnimation)
{
PieAnimation *animation = static_cast<PieAnimation *>(m_animations.value(item));
@@ -189,22 +107,6 @@ void ChartAnimator::updateLayout(BarChartItem *item, const QVector<QRectF> &oldL
QTimer::singleShot(0, animation, SLOT(start()));
}
-
-void ChartAnimator::setState(State state, const QPointF &point)
-{
- m_state = state;
- m_point = point;
-}
-
-void ChartAnimator::startAnimation(XYAnimation* animation)
-{
- Q_ASSERT(animation);
- if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
- animation->setDuration(ChartAnimationDuration);
- animation->setEasingCurve(QEasingCurve::OutQuart);
- QTimer::singleShot(0, animation, SLOT(start()));
-}
-
#include "moc_chartanimator_p.cpp"
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/animations/chartanimator_p.h b/src/animations/chartanimator_p.h
index d22d89fe..a9b747ad 100644
--- a/src/animations/chartanimator_p.h
+++ b/src/animations/chartanimator_p.h
@@ -42,33 +42,21 @@ class ChartAnimator : public QObject
{
Q_OBJECT
public:
- enum State{ShowState, ScrollUpState, ScrollDownState, ScrollLeftState, ScrollRightState, ZoomInState, ZoomOutState};
-
ChartAnimator(QObject *parent = 0);
virtual ~ChartAnimator();
- void addAnimation(ChartAxis *item);
void addAnimation(PieChartItem *item);
void addAnimation(BarChartItem *item);
void removeAnimation(Chart *item);
- void animationStarted();
- void updateLayout(ChartAxis *item, QVector<qreal> &layout);
-
void addAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData, bool isEmpty);
void removeAnimation(PieChartItem *item, PieSliceItem *sliceItem);
void updateAnimation(PieChartItem *item, PieSliceItem *sliceItem, const PieSliceData &sliceData);
void updateLayout(BarChartItem *item, const QVector<QRectF> &oldLayout, const QVector<QRectF> &newLayout);
- void setState(State state,const QPointF &point = QPointF());
-
- void startAnimation(XYAnimation* animation);
-
private:
QMap<Chart *, ChartAnimation *> m_animations;
- State m_state;
- QPointF m_point;
};
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/animations/splineanimation.cpp b/src/animations/splineanimation.cpp
index 700778a6..51fce1ac 100644
--- a/src/animations/splineanimation.cpp
+++ b/src/animations/splineanimation.cpp
@@ -94,7 +94,10 @@ QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &en
switch (animationType()) {
- case MoveDownAnimation: {
+ case RemovePointAnimation:
+ case AddPointAnimation:
+ case ReplacePointAnimation:
+ {
if (startPair.first.count() != endPair.first.count())
break;
Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
@@ -115,7 +118,7 @@ QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &en
}
break;
- case LineDrawAnimation:{
+ case NewAnimation:{
Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
int count = endPair.first.count()* qBound(qreal(0), progress, qreal(1));
for(int i = 0; i < count; i++) {
diff --git a/src/animations/xyanimation.cpp b/src/animations/xyanimation.cpp
index 104f84a6..2b9ada51 100644
--- a/src/animations/xyanimation.cpp
+++ b/src/animations/xyanimation.cpp
@@ -29,8 +29,10 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE
XYAnimation::XYAnimation(XYChart *item):ChartAnimation(item),
m_item(item),
m_dirty(false),
- m_type(MoveDownAnimation)
+ m_type(NewAnimation)
{
+ setDuration(ChartAnimationDuration);
+ setEasingCurve(QEasingCurve::OutQuart);
}
XYAnimation::~XYAnimation()
@@ -39,38 +41,48 @@ XYAnimation::~XYAnimation()
void XYAnimation::setAnimationType(Animation type)
{
- if (state() != QAbstractAnimation::Stopped) stop();
+ if (state() != QAbstractAnimation::Stopped) stop();
m_type=type;
}
-void XYAnimation::setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
+void XYAnimation::setValues(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints, int index)
{
- if (state() != QAbstractAnimation::Stopped) stop();
+ if (state() != QAbstractAnimation::Stopped) stop();
- int x = oldPoints.count();
- int y = newPoints.count();
-
- if (x != y && abs(x - y) != 1) {
- m_oldPoints = newPoints;
- oldPoints.resize(newPoints.size());
- setKeyValueAt(0.0, qVariantFromValue(oldPoints));
- setKeyValueAt(1.0, qVariantFromValue(newPoints));
- m_dirty = false;
+ if (m_item->isDirty()) {
+ m_oldPoints = oldPoints;
+ m_newPoints = newPoints;
+ m_dirty=false;
}
else {
- if (m_dirty) {
+ if(m_dirty) {
+ m_newPoints = newPoints;
m_oldPoints = oldPoints;
- m_dirty = false;
+ m_dirty=false;
+ }
+ }
+
+ int x = m_oldPoints.count();
+ int y = m_newPoints.count();
+
+ if (abs(x - y) == 1) {
+ if (y < x){
+ if(!newPoints.isEmpty()) m_newPoints.insert(index,newPoints[index]);
+ m_index=index;if(newPoints.isEmpty())
+ m_dirty=true;
+ }
+ if (y > x){
+ m_oldPoints.insert(index, x > 0 ? m_oldPoints[index-1] : newPoints[index]);//add
}
- oldPoints = newPoints;
- if (y < x)
- m_oldPoints.remove(index); //remove
- if (y > x)
- m_oldPoints.insert(index, x > 0 ? m_oldPoints[index-1] : newPoints[index]); //add
- setKeyValueAt(0.0, qVariantFromValue(m_oldPoints));
- setKeyValueAt(1.0, qVariantFromValue(newPoints));
- Q_ASSERT(m_oldPoints.count() == newPoints.count());
+ }else{
+ m_newPoints=newPoints;
+ m_dirty=false;
+ m_oldPoints.resize(m_newPoints.size());
}
+
+ setKeyValueAt(0.0, qVariantFromValue(m_oldPoints));
+ setKeyValueAt(1.0, qVariantFromValue(m_newPoints));
+
}
QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress ) const
@@ -81,8 +93,10 @@ QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, q
switch (m_type) {
- case MoveDownAnimation: {
-
+ case ReplacePointAnimation:
+ case AddPointAnimation:
+ case RemovePointAnimation:
+ {
if (startVector.count() != endVector.count())
break;
@@ -94,7 +108,7 @@ QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, q
}
break;
- case LineDrawAnimation: {
+ case NewAnimation: {
for(int i = 0; i < endVector.count() * qBound(qreal(0), progress, qreal(1)); i++)
result << endVector[i];
}
@@ -110,11 +124,23 @@ QVariant XYAnimation::interpolated(const QVariant &start, const QVariant &end, q
void XYAnimation::updateCurrentValue (const QVariant &value)
{
if(state()!=QAbstractAnimation::Stopped){ //workaround
- m_dirty = true;
QVector<QPointF> vector = qVariantValue<QVector<QPointF> >(value);
m_item->setGeometryPoints(vector);
m_item->updateGeometry();
+ m_item->setDirty(true);
}
}
+void XYAnimation::updateState( QAbstractAnimation::State newState, QAbstractAnimation::State oldState )
+{
+ if(oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped)
+ {
+ if(m_item->isDirty() && m_type==RemovePointAnimation){
+ if(!m_newPoints.isEmpty()) m_newPoints.remove(m_index);
+ m_item->setGeometryPoints(m_newPoints);
+ }
+ }
+}
+
+#include "moc_chartanimation_p.cpp"
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/animations/xyanimation_p.h b/src/animations/xyanimation_p.h
index 92d644f4..50b3478a 100644
--- a/src/animations/xyanimation_p.h
+++ b/src/animations/xyanimation_p.h
@@ -31,20 +31,22 @@ class XYChart;
class XYAnimation : public ChartAnimation
{
public:
- enum Animation { LineDrawAnimation, MoveDownAnimation, MoveUpAnimation };
+ enum Animation { AddPointAnimation, RemovePointAnimation, ReplacePointAnimation, NewAnimation };
XYAnimation(XYChart *item);
~XYAnimation();
- void setValues(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index);
+ void setValues(const QVector<QPointF> &oldPoints, const QVector<QPointF> &newPoints,int index);
void setAnimationType(Animation type);
Animation animationType() const { return m_type; };
protected:
QVariant interpolated(const QVariant &start, const QVariant &end, qreal progress ) const;
void updateCurrentValue (const QVariant &value );
-
+ void updateState( QAbstractAnimation::State newState, QAbstractAnimation::State oldState );
private:
XYChart *m_item;
QVector<QPointF> m_oldPoints;
+ QVector<QPointF> m_newPoints;
+ int m_index;
bool m_dirty;
Animation m_type;
};
diff --git a/src/areachart/areachartitem.cpp b/src/areachart/areachartitem.cpp
index 636f98ad..6735f67c 100644
--- a/src/areachart/areachartitem.cpp
+++ b/src/areachart/areachartitem.cpp
@@ -25,6 +25,7 @@
#include "chartpresenter_p.h"
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
+#include <QDebug>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -39,9 +40,9 @@ AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
m_pointsVisible(false)
{
setZValue(ChartPresenter::LineChartZValue);
- m_upper = new AreaBoundItem(this,m_series->upperSeries());
+ m_upper = new AreaBoundItem(this,m_series->upperSeries(),presenter);
if (m_series->lowerSeries())
- m_lower = new AreaBoundItem(this,m_series->lowerSeries());
+ m_lower = new AreaBoundItem(this,m_series->lowerSeries(),presenter);
QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
diff --git a/src/areachart/areachartitem_p.h b/src/areachart/areachartitem_p.h
index dbc7af3a..1e932717 100644
--- a/src/areachart/areachartitem_p.h
+++ b/src/areachart/areachartitem_p.h
@@ -75,7 +75,9 @@ private:
class AreaBoundItem : public LineChartItem
{
public:
- AreaBoundItem(AreaChartItem *item,QLineSeries *lineSeries) : LineChartItem(lineSeries, 0), m_item(item) {}
+ AreaBoundItem(AreaChartItem *item,QLineSeries *lineSeries,ChartPresenter* presenter) : LineChartItem(lineSeries, 0), m_item(item) {
+ setPresenter(presenter);
+ }
~AreaBoundItem() {}
void updateGeometry() {
diff --git a/src/axis/axis.pri b/src/axis/axis.pri
index 1579635e..96b8afe7 100644
--- a/src/axis/axis.pri
+++ b/src/axis/axis.pri
@@ -3,11 +3,15 @@ DEPENDPATH += $$PWD
SOURCES += \
$$PWD/chartaxis.cpp \
+ $$PWD/chartaxisx.cpp \
+ $$PWD/chartaxisy.cpp \
$$PWD/qaxis.cpp \
$$PWD/qaxiscategories.cpp
PRIVATE_HEADERS += \
$$PWD/chartaxis_p.h \
+ $$PWD/chartaxisx_p.h \
+ $$PWD/chartaxisy_p.h \
$$PWD/qaxis_p.h \
$$PWD/qaxiscategories_p.h
diff --git a/src/axis/chartaxis.cpp b/src/axis/chartaxis.cpp
index 24cd0211..612444d5 100644
--- a/src/axis/chartaxis.cpp
+++ b/src/axis/chartaxis.cpp
@@ -28,13 +28,10 @@
#include <QDebug>
#include <cmath>
-static int label_padding = 5;
-
QTCOMMERCIALCHART_BEGIN_NAMESPACE
-ChartAxis::ChartAxis(QAxis *axis,ChartPresenter *presenter,AxisType type) : Chart(presenter),
+ChartAxis::ChartAxis(QAxis *axis,ChartPresenter *presenter) : Chart(presenter),
m_chartAxis(axis),
- m_type(type),
m_labelsAngle(0),
m_grid(new QGraphicsItemGroup(presenter->rootItem())),
m_shades(new QGraphicsItemGroup(presenter->rootItem())),
@@ -42,7 +39,8 @@ ChartAxis::ChartAxis(QAxis *axis,ChartPresenter *presenter,AxisType type) : Char
m_axis(new QGraphicsItemGroup(presenter->rootItem())),
m_min(0),
m_max(0),
- m_ticksCount(0)
+ m_ticksCount(0),
+ m_animation(0)
{
//initial initialization
m_axis->setZValue(ChartPresenter::AxisZValue);
@@ -61,17 +59,26 @@ ChartAxis::~ChartAxis()
{
}
-void ChartAxis::createItems(int count)
+void ChartAxis::setAnimation(AxisAnimation* animation)
{
+ m_animation=animation;
+}
+void ChartAxis::setLayout(QVector<qreal> &layout)
+{
+ m_layoutVector=layout;
+}
+
+void ChartAxis::createItems(int count)
+{
if (m_axis->children().size() == 0)
- m_axis->addToGroup(new AxisItem(this));
+ m_axis->addToGroup(new AxisItem(this));
for (int i = 0; i < count; ++i) {
m_grid->addToGroup(new QGraphicsLineItem());
m_labels->addToGroup(new QGraphicsSimpleTextItem());
m_axis->addToGroup(new QGraphicsLineItem());
if ((m_grid->childItems().size())%2 && m_grid->childItems().size()>2) m_shades->addToGroup(new QGraphicsRectItem());
- }
+ }
}
void ChartAxis::deleteItems(int count)
@@ -91,16 +98,51 @@ void ChartAxis::deleteItems(int count)
void ChartAxis::updateLayout(QVector<qreal> &layout)
{
- if (animator()) {
- animator()->updateLayout(this,layout);
- } else {
+ int diff = m_layoutVector.size() - layout.size();
+
+ if (diff>0) {
+ deleteItems(diff);
+ }
+ else if (diff<0) {
+ createItems(-diff);
+ }
+
+ if( diff!=0) handleAxisUpdated();
+
+ if (m_animation) {
+ switch(presenter()->state()){
+ case ChartPresenter::ZoomInState:
+ m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
+ m_animation->setAnimationPoint(presenter()->statePoint());
+ break;
+ case ChartPresenter::ZoomOutState:
+ m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
+ m_animation->setAnimationPoint(presenter()->statePoint());
+ break;
+ case ChartPresenter::ScrollUpState:
+ case ChartPresenter::ScrollLeftState:
+ m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
+ break;
+ case ChartPresenter::ScrollDownState:
+ case ChartPresenter::ScrollRightState:
+ m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
+ break;
+ case ChartPresenter::ShowState:
+ m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
+ break;
+ }
+ m_animation->setValues(m_layoutVector,layout);
+ presenter()->startAnimation(m_animation);
+ }
+ else {
setLayout(layout);
+ updateGeometry();
}
}
bool ChartAxis::createLabels(QStringList &labels,qreal min, qreal max,int ticks) const
{
- Q_ASSERT(max>=min);
+ Q_ASSERT(max>min);
Q_ASSERT(ticks>1);
QAxisCategories* categories = m_chartAxis->categories();
@@ -112,6 +154,7 @@ bool ChartAxis::createLabels(QStringList &labels,qreal min, qreal max,int ticks)
n++;
for (int i=0; i< ticks; i++) {
qreal value = min + (i * (max - min)/ (ticks-1));
+ Q_UNUSED(value);
labels << QString::number(value,'f',n);
}
} else {
@@ -230,153 +273,6 @@ void ChartAxis::setGridPen(const QPen &pen)
}
}
-QVector<qreal> ChartAxis::calculateLayout() const
-{
- Q_ASSERT(m_ticksCount>=2);
-
- QVector<qreal> points;
- points.resize(m_ticksCount);
-
- switch (m_type)
- {
- case X_AXIS:
- {
- const qreal deltaX = m_rect.width()/(m_ticksCount-1);
- for (int i = 0; i < m_ticksCount; ++i) {
- int x = i * deltaX + m_rect.left();
- points[i] = x;
- }
- }
- break;
- case Y_AXIS:
- {
- const qreal deltaY = m_rect.height()/(m_ticksCount-1);
- for (int i = 0; i < m_ticksCount; ++i) {
- int y = i * -deltaY + m_rect.bottom();
- points[i] = y;
- }
- }
- break;
- }
- return points;
-}
-
-void ChartAxis::setLayout(QVector<qreal> &layout)
-{
- int diff = m_layoutVector.size() - layout.size();
-
- if (diff>0) {
- deleteItems(diff);
- } else if (diff<0) {
- createItems(-diff);
- }
-
- if( diff!=0) handleAxisUpdated();
-
- QStringList ticksList;
-
- bool categories = createLabels(ticksList,m_min,m_max,layout.size());
-
- QList<QGraphicsItem *> lines = m_grid->childItems();
- QList<QGraphicsItem *> labels = m_labels->childItems();
- QList<QGraphicsItem *> shades = m_shades->childItems();
- QList<QGraphicsItem *> axis = m_axis->childItems();
-
- Q_ASSERT(labels.size() == ticksList.size());
- Q_ASSERT(layout.size() == ticksList.size());
-
- qreal minWidth = 0;
- qreal minHeight = 0;
-
- switch (m_type)
- {
- case X_AXIS:
- {
- QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
-
- for (int i = 0; i < layout.size(); ++i) {
- QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
- QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
- if (!categories || i<1) {
- labelItem->setText(ticksList.at(i));
- const QRectF& rect = labelItem->boundingRect();
- minWidth+=rect.width();
- minHeight=qMax(rect.height(),minHeight);
- QPointF center = rect.center();
- labelItem->setTransformOriginPoint(center.x(), center.y());
- labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
- } else {
- labelItem->setText(ticksList.at(i));
- const QRectF& rect = labelItem->boundingRect();
- minWidth+=rect.width();
- minHeight=qMax(rect.height()+label_padding,minHeight);
- QPointF center = rect.center();
- labelItem->setTransformOriginPoint(center.x(), center.y());
- labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
- }
-
- if ((i+1)%2 && i>1) {
- QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
- }
- lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
- }
-
- }
- break;
-
- case Y_AXIS:
- {
- QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
-
- for (int i = 0; i < layout.size(); ++i) {
- QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
- QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
-
- if (!categories || i<1) {
- labelItem->setText(ticksList.at(i));
- const QRectF& rect = labelItem->boundingRect();
- minWidth=qMax(rect.width()+label_padding,minWidth);
- minHeight+=rect.height();
- QPointF center = rect.center();
- labelItem->setTransformOriginPoint(center.x(), center.y());
- labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
- } else {
- labelItem->setText(ticksList.at(i));
- const QRectF& rect = labelItem->boundingRect();
- minWidth=qMax(rect.width(),minWidth);
- minHeight+=rect.height();
- QPointF center = rect.center();
- labelItem->setTransformOriginPoint(center.x(), center.y());
- labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
- }
-
- if ((i+1)%2 && i>1) {
- QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
- }
- lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
- }
- }
- break;
- default:
- qWarning()<<"Unknown axis type";
- break;
- }
-
- m_layoutVector=layout;
-
- presenter()->setMinimumMarginWidth(this,minWidth);
- presenter()->setMinimumMarginHeight(this,minHeight);
-
-}
-
bool ChartAxis::isEmpty()
{
return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max) || m_ticksCount==0;
@@ -442,7 +338,6 @@ void ChartAxis::handleRangeChanged(qreal min, qreal max,int tickCount)
if (isEmpty()) return;
QVector<qreal> layout = calculateLayout();
updateLayout(layout);
-
}
void ChartAxis::handleGeometryChanged(const QRectF &rect)
diff --git a/src/axis/chartaxis_p.h b/src/axis/chartaxis_p.h
index bb6c6615..b55b9312 100644
--- a/src/axis/chartaxis_p.h
+++ b/src/axis/chartaxis_p.h
@@ -18,11 +18,12 @@
**
****************************************************************************/
-#ifndef AXIS_H
-#define AXIS_H
+#ifndef CHARTAXIS_H
+#define CHARTAXIS_H
#include "qchartglobal.h"
#include "chart_p.h"
+#include "axisanimation_p.h"
#include <QGraphicsItem>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -34,12 +35,12 @@ class ChartAxis : public Chart
{
Q_OBJECT
public:
- enum AxisType{X_AXIS,Y_AXIS};
+ enum AxisType{ X_AXIS,Y_AXIS };
- ChartAxis(QAxis *axis, ChartPresenter *presenter, AxisType type = X_AXIS);
+ ChartAxis(QAxis *axis, ChartPresenter *presenter);
~ChartAxis();
- AxisType axisType() const { return m_type; }
+ virtual AxisType axisType() const = 0;
void setAxisOpacity(qreal opacity);
qreal axisOpacity() const;
@@ -66,8 +67,18 @@ public:
void setLabelsBrush(const QBrush &brush);
void setLabelsFont(const QFont &font);
- inline QRectF geometry() const { return m_rect; }
- inline QVector<qreal> layout() { return m_layoutVector; }
+ void setLayout(QVector<qreal> &layout);
+ QVector<qreal> layout() const { return m_layoutVector; }
+
+ void setAnimation(AxisAnimation* animation);
+ ChartAnimation* animation() const { return m_animation; };
+
+ QRectF geometry() const { return m_rect; }
+
+protected:
+ virtual void updateGeometry() = 0;
+ virtual QVector<qreal> calculateLayout() const = 0;
+ bool createLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
public Q_SLOTS:
void handleAxisUpdated();
@@ -75,22 +86,15 @@ public Q_SLOTS:
void handleRangeChanged(qreal min , qreal max,int tickCount);
void handleGeometryChanged(const QRectF &size);
-
private:
inline bool isEmpty();
void createItems(int count);
void deleteItems(int count);
-
- QVector<qreal> calculateLayout() const;
void updateLayout(QVector<qreal> &layout);
- void setLayout(QVector<qreal> &layout);
-
- bool createLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
void axisSelected();
-private:
+protected:
QAxis* m_chartAxis;
- AxisType m_type;
QRectF m_rect;
int m_labelsAngle;
QScopedPointer<QGraphicsItemGroup> m_grid;
@@ -101,6 +105,7 @@ private:
qreal m_min;
qreal m_max;
int m_ticksCount;
+ AxisAnimation *m_animation;
friend class AxisAnimation;
friend class AxisItem;
diff --git a/src/axis/chartaxisx.cpp b/src/axis/chartaxisx.cpp
new file mode 100644
index 00000000..5414ed07
--- /dev/null
+++ b/src/axis/chartaxisx.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Commercial Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "chartaxisx_p.h"
+#include "qaxis.h"
+#include "qaxis_p.h"
+#include "qaxiscategories_p.h"
+#include "chartpresenter_p.h"
+#include "chartanimator_p.h"
+
+static int label_padding = 5;
+
+QTCOMMERCIALCHART_BEGIN_NAMESPACE
+
+ChartAxisX::ChartAxisX(QAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
+{
+}
+
+ChartAxisX::~ChartAxisX()
+{
+}
+
+QVector<qreal> ChartAxisX::calculateLayout() const
+{
+ Q_ASSERT(m_ticksCount>=2);
+
+ QVector<qreal> points;
+ points.resize(m_ticksCount);
+
+ const qreal deltaX = m_rect.width()/(m_ticksCount-1);
+ for (int i = 0; i < m_ticksCount; ++i) {
+ int x = i * deltaX + m_rect.left();
+ points[i] = x;
+ }
+ return points;
+}
+
+void ChartAxisX::updateGeometry()
+{
+ const QVector<qreal>& layout = ChartAxis::layout();
+
+ QStringList ticksList;
+
+ bool categories = createLabels(ticksList,m_min,m_max,layout.size());
+
+ QList<QGraphicsItem *> lines = m_grid->childItems();
+ QList<QGraphicsItem *> labels = m_labels->childItems();
+ QList<QGraphicsItem *> shades = m_shades->childItems();
+ QList<QGraphicsItem *> axis = m_axis->childItems();
+
+ Q_ASSERT(labels.size() == ticksList.size());
+ Q_ASSERT(layout.size() == ticksList.size());
+
+ qreal minWidth = 0;
+ qreal minHeight = 0;
+
+ QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
+ lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
+
+ for (int i = 0; i < layout.size(); ++i) {
+ QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
+ lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
+ QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
+ if (!categories || i<1) {
+ labelItem->setText(ticksList.at(i));
+ const QRectF& rect = labelItem->boundingRect();
+ minWidth+=rect.width();
+ minHeight=qMax(rect.height(),minHeight);
+ QPointF center = rect.center();
+ labelItem->setTransformOriginPoint(center.x(), center.y());
+ labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
+ }
+ else {
+ labelItem->setText(ticksList.at(i));
+ const QRectF& rect = labelItem->boundingRect();
+ minWidth+=rect.width();
+ minHeight=qMax(rect.height()+label_padding,minHeight);
+ QPointF center = rect.center();
+ labelItem->setTransformOriginPoint(center.x(), center.y());
+ labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
+ }
+
+ if ((i+1)%2 && i>1) {
+ QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
+ rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
+ }
+ lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
+ lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
+ }
+
+ presenter()->setMinimumMarginWidth(this,minWidth);
+ presenter()->setMinimumMarginHeight(this,minHeight);
+}
+
+QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/chartaxisx_p.h b/src/axis/chartaxisx_p.h
new file mode 100644
index 00000000..fa8e7ff1
--- /dev/null
+++ b/src/axis/chartaxisx_p.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Commercial Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CHARTAXISX_H
+#define CHARTAXISX_H
+
+#include "chartaxis_p.h"
+
+QTCOMMERCIALCHART_BEGIN_NAMESPACE
+
+class QAxis;
+class ChartPresenter;
+
+class ChartAxisX : public ChartAxis
+{
+public:
+ ChartAxisX(QAxis *axis, ChartPresenter *presenter);
+ ~ChartAxisX();
+
+ AxisType axisType() const { return X_AXIS;}
+
+protected:
+ QVector<qreal> calculateLayout() const;
+ void updateGeometry();
+};
+
+QTCOMMERCIALCHART_END_NAMESPACE
+
+#endif /* AXISITEM_H_ */
diff --git a/src/axis/chartaxisy.cpp b/src/axis/chartaxisy.cpp
new file mode 100644
index 00000000..b357aa7f
--- /dev/null
+++ b/src/axis/chartaxisy.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Commercial Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "chartaxisy_p.h"
+#include "qaxis.h"
+#include "qaxis_p.h"
+#include "qaxiscategories_p.h"
+#include "chartpresenter_p.h"
+#include "chartanimator_p.h"
+
+
+static int label_padding = 5;
+
+QTCOMMERCIALCHART_BEGIN_NAMESPACE
+
+ChartAxisY::ChartAxisY(QAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
+{
+}
+
+ChartAxisY::~ChartAxisY()
+{
+}
+
+QVector<qreal> ChartAxisY::calculateLayout() const
+{
+ Q_ASSERT(m_ticksCount>=2);
+
+ QVector<qreal> points;
+ points.resize(m_ticksCount);
+
+ const qreal deltaY = m_rect.height()/(m_ticksCount-1);
+ for (int i = 0; i < m_ticksCount; ++i) {
+ int y = i * -deltaY + m_rect.bottom();
+ points[i] = y;
+ }
+
+ return points;
+}
+
+void ChartAxisY::updateGeometry()
+{
+ const QVector<qreal> &layout = ChartAxis::layout();
+
+ QStringList ticksList;
+
+ bool categories = createLabels(ticksList,m_min,m_max,layout.size());
+
+ QList<QGraphicsItem *> lines = m_grid->childItems();
+ QList<QGraphicsItem *> labels = m_labels->childItems();
+ QList<QGraphicsItem *> shades = m_shades->childItems();
+ QList<QGraphicsItem *> axis = m_axis->childItems();
+
+ Q_ASSERT(labels.size() == ticksList.size());
+ Q_ASSERT(layout.size() == ticksList.size());
+
+ qreal minWidth = 0;
+ qreal minHeight = 0;
+
+ QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
+ lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
+
+ for (int i = 0; i < layout.size(); ++i) {
+ QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
+ lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
+ QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
+
+ if (!categories || i<1) {
+ labelItem->setText(ticksList.at(i));
+ const QRectF& rect = labelItem->boundingRect();
+ minWidth=qMax(rect.width()+label_padding,minWidth);
+ minHeight+=rect.height();
+ QPointF center = rect.center();
+ labelItem->setTransformOriginPoint(center.x(), center.y());
+ labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
+ }
+ else {
+ labelItem->setText(ticksList.at(i));
+ const QRectF& rect = labelItem->boundingRect();
+ minWidth=qMax(rect.width(),minWidth);
+ minHeight+=rect.height();
+ QPointF center = rect.center();
+ labelItem->setTransformOriginPoint(center.x(), center.y());
+ labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
+ }
+
+ if ((i+1)%2 && i>1) {
+ QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
+ rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
+ }
+ lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
+ lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
+ }
+
+ presenter()->setMinimumMarginWidth(this,minWidth);
+ presenter()->setMinimumMarginHeight(this,minHeight);
+
+}
+
+QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/chartaxisy_p.h b/src/axis/chartaxisy_p.h
new file mode 100644
index 00000000..a16801aa
--- /dev/null
+++ b/src/axis/chartaxisy_p.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Commercial Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CHARTAXISY_H
+#define CHARTAXISY_H
+
+#include "chartaxis_p.h"
+
+QTCOMMERCIALCHART_BEGIN_NAMESPACE
+
+class QAxis;
+class ChartPresenter;
+
+class ChartAxisY : public ChartAxis
+{
+public:
+ ChartAxisY(QAxis *axis, ChartPresenter *presenter);
+ ~ChartAxisY();
+
+ AxisType axisType() const { return Y_AXIS;}
+
+protected:
+ QVector<qreal> calculateLayout() const;
+ void updateGeometry();
+};
+
+QTCOMMERCIALCHART_END_NAMESPACE
+
+#endif /* AXISITEM_H_ */
diff --git a/src/chartpresenter.cpp b/src/chartpresenter.cpp
index 8a5d0bd1..1a767011 100644
--- a/src/chartpresenter.cpp
+++ b/src/chartpresenter.cpp
@@ -24,11 +24,15 @@
#include "chartdataset_p.h"
#include "charttheme_p.h"
#include "chartanimator_p.h"
+#include "chartanimation_p.h"
#include "qabstractseries_p.h"
#include "qareaseries.h"
#include "chartaxis_p.h"
+#include "chartaxisx_p.h"
+#include "chartaxisy_p.h"
#include "areachartitem_p.h"
#include "chartbackground_p.h"
+#include <QTimer>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -41,6 +45,7 @@ m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
m_options(QChart::NoAnimation),
m_minLeftMargin(0),
m_minBottomMargin(0),
+m_state(ShowState),
m_backgroundItem(0),
m_titleItem(0),
m_marginBig(60),
@@ -48,6 +53,7 @@ m_marginSmall(20),
m_marginTiny(10),
m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
{
+
}
ChartPresenter::~ChartPresenter()
@@ -112,10 +118,17 @@ void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
{
- ChartAxis* item = new ChartAxis(axis,this,axis==m_dataset->axisX()?ChartAxis::X_AXIS : ChartAxis::Y_AXIS);
+ ChartAxis* item;
+
+ if(axis == m_dataset->axisX()){
+ item = new ChartAxisX(axis,this);
+ }else{
+ item = new ChartAxisY(axis,this);
+ }
if(m_options.testFlag(QChart::GridAxisAnimations)){
- m_animator->addAnimation(item);
+ item->setAnimator(m_animator);
+ item->setAnimation(new AxisAnimation(item));
}
if(axis==m_dataset->axisX()){
@@ -244,21 +257,15 @@ void ChartPresenter::zoomIn(const QRectF& rect)
if (!r.isValid())
return;
- if (m_animator) {
- QPointF point(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
- m_animator->setState(ChartAnimator::ZoomInState,point);
- }
-
+ m_state = ZoomInState;
+ m_statePoint = QPointF(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
m_dataset->zoomInDomain(r,chartGeometry().size());
-
- if (m_animator)
- m_animator->setState(ChartAnimator::ShowState);
+ m_state = ShowState;
}
void ChartPresenter::zoomOut(qreal factor)
{
- if (m_animator)
- m_animator->setState(ChartAnimator::ZoomOutState);
+ m_state = ZoomOutState;
QRectF chartRect;
chartRect.setSize(chartGeometry().size());
@@ -268,27 +275,21 @@ void ChartPresenter::zoomOut(qreal factor)
rect.moveCenter(chartRect.center());
if (!rect.isValid())
return;
-
+ m_statePoint = QPointF(rect.center().x()/chartGeometry().width(),rect.center().y()/chartGeometry().height());
m_dataset->zoomOutDomain(rect, chartRect.size());
-
- if (m_animator)
- m_animator->setState(ChartAnimator::ShowState);
+ m_state = ShowState;
}
void ChartPresenter::scroll(int dx,int dy)
{
- if(m_animator){
- if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
- if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
- if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
- if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
- }
- m_dataset->scrollDomain(dx,dy,chartGeometry().size());
+ if(dx<0) m_state=ScrollLeftState;
+ if(dx>0) m_state=ScrollRightState;
+ if(dy<0) m_state=ScrollUpState;
+ if(dy>0) m_state=ScrollDownState;
- if(m_animator){
- m_animator->setState(ChartAnimator::ShowState);
- }
+ m_dataset->scrollDomain(dx,dy,chartGeometry().size());
+ m_state = ShowState;
}
QChart::AnimationOptions ChartPresenter::animationOptions() const
@@ -389,7 +390,6 @@ void ChartPresenter::updateLayout()
emit geometryChanged(m_chartRect);
}
-
}
void ChartPresenter::createChartBackgroundItem()
@@ -409,6 +409,22 @@ void ChartPresenter::createChartTitleItem()
}
}
+void ChartPresenter::handleAnimationFinished()
+{
+ m_animations.removeAll(qobject_cast<ChartAnimation*>(sender()));
+ if(m_animations.empty()) emit animationsFinished();
+}
+
+void ChartPresenter::startAnimation(ChartAnimation* animation)
+{
+ if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
+ QObject::connect(animation, SIGNAL(finished()),this,SLOT(handleAnimationFinished()),Qt::UniqueConnection);
+ if(!m_animations.isEmpty()){
+ m_animations.append(animation);
+ }
+ QTimer::singleShot(0, animation, SLOT(start()));
+}
+
#include "moc_chartpresenter_p.cpp"
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/chartpresenter_p.h b/src/chartpresenter_p.h
index 41bf3c4b..4abf4bee 100644
--- a/src/chartpresenter_p.h
+++ b/src/chartpresenter_p.h
@@ -35,6 +35,7 @@ class ChartAxis;
class ChartTheme;
class ChartAnimator;
class ChartBackground;
+class ChartAnimation;
class ChartPresenter: public QObject
{
@@ -51,6 +52,14 @@ public:
AxisZValue,
LegendZValue
};
+ enum State {ShowState,
+ ScrollUpState,
+ ScrollDownState,
+ ScrollLeftState,
+ ScrollRightState,
+ ZoomInState,
+ ZoomOutState
+ };
ChartPresenter(QChart* chart,ChartDataSet *dataset);
virtual ~ChartPresenter();
@@ -79,6 +88,9 @@ public:
qreal minimumLeftMargin() const { return m_minLeftMargin; }
qreal minimumBottomMargin() const { return m_minBottomMargin; }
+ void startAnimation(ChartAnimation* animation);
+ State state() const { return m_state; }
+ QPointF statePoint() const { return m_statePoint; }
public: //TODO: fix me
void resetAllElements();
void createChartBackgroundItem();
@@ -92,9 +104,12 @@ public Q_SLOTS:
void handleAxisRemoved(QAxis* axis);
void updateLayout();
+private Q_SLOTS:
+ void handleAnimationFinished();
+
Q_SIGNALS:
void geometryChanged(const QRectF& rect);
-
+ void animationsFinished();
private:
QChart* m_chart;
@@ -108,6 +123,10 @@ private:
QChart::AnimationOptions m_options;
qreal m_minLeftMargin;
qreal m_minBottomMargin;
+ State m_state;
+ QPointF m_statePoint;
+ QList<ChartAnimation*> m_animations;
+
public: //TODO: fixme
ChartBackground* m_backgroundItem;
QGraphicsSimpleTextItem* m_titleItem;
@@ -116,7 +135,6 @@ public: //TODO: fixme
int m_marginTiny;
QRectF m_chartMargins;
QRectF m_legendMargins;
-
};
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/splinechart/splinechartitem.cpp b/src/splinechart/splinechartitem.cpp
index 20997a77..019fe466 100644
--- a/src/splinechart/splinechartitem.cpp
+++ b/src/splinechart/splinechartitem.cpp
@@ -87,7 +87,7 @@ void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF>
if (m_animation) {
m_animation->setValues(oldPoints,newPoints,m_controlPoints,controlPoints,index);
- animator()->startAnimation(m_animation);
+ presenter()->startAnimation(m_animation);
}
else {
setGeometryPoints(newPoints);
diff --git a/src/xychart/xychart.cpp b/src/xychart/xychart.cpp
index eefd3c3b..d77fe93c 100644
--- a/src/xychart/xychart.cpp
+++ b/src/xychart/xychart.cpp
@@ -26,6 +26,7 @@
#include <QPainter>
#include <QAbstractItemModel>
#include "qxymodelmapper.h"
+#include <QDebug>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -37,7 +38,8 @@ m_maxX(0),
m_minY(0),
m_maxY(0),
m_series(series),
-m_animation(0)
+m_animation(0),
+m_dirty(true)
{
QObject::connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
QObject::connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
@@ -46,7 +48,7 @@ m_animation(0)
QObject::connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
}
-void XYChart::setGeometryPoints(QVector<QPointF>& points)
+void XYChart::setGeometryPoints(const QVector<QPointF>& points)
{
m_points = points;
}
@@ -61,6 +63,11 @@ void XYChart::setAnimation(XYAnimation* animation)
m_animation=animation;
}
+void XYChart::setDirty(bool dirty)
+{
+ m_dirty=dirty;
+}
+
QPointF XYChart::calculateGeometryPoint(const QPointF &point) const
{
const qreal deltaX = m_size.width()/(m_maxX-m_minX);
@@ -110,7 +117,9 @@ void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoin
{
if (m_animation) {
m_animation->setValues(oldPoints, newPoints, index);
- animator()->startAnimation(m_animation);
+ setGeometryPoints(newPoints);
+ setDirty(false);
+ presenter()->startAnimation(m_animation);
}
else {
setGeometryPoints(newPoints);
@@ -124,45 +133,65 @@ void XYChart::handlePointAdded(int index)
{
Q_ASSERT(index<m_series->count());
Q_ASSERT(index>=0);
- QVector<QPointF> points = m_points;
- QPointF point;
- point = calculateGeometryPoint(index);
- points.insert(index, point);
- if(m_animation) {
- m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
- }
+ QVector<QPointF> points;
+
+ if(m_animation) {
+ m_animation->setAnimationType(XYAnimation::AddPointAnimation);
+ }
- updateChart(m_points,points,index);
+ if(m_dirty) {
+ points = calculateGeometryPoints();
+ } else {
+ points = m_points;
+ QPointF point = calculateGeometryPoint(index);
+ points.insert(index, point);
+ }
+
+ updateChart(m_points,points,index);
}
void XYChart::handlePointRemoved(int index)
{
- Q_ASSERT(index<m_series->count() + 1);
- Q_ASSERT(index>=0);
- QVector<QPointF> points = m_points;
- points.remove(index);
+ Q_ASSERT(index<=m_series->count());
+ Q_ASSERT(index>=0);
- if(m_animation) {
- m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
- }
+ QVector<QPointF> points;
- updateChart(m_points,points,index);
+ if(m_animation) {
+ m_animation->setAnimationType(XYAnimation::RemovePointAnimation);
+ }
+
+ if(m_dirty) {
+ points = calculateGeometryPoints();
+ } else {
+ points = m_points;
+ points.remove(index);
+ }
+
+ updateChart(m_points,points,index);
}
void XYChart::handlePointReplaced(int index)
{
- Q_ASSERT(index<m_series->count());
- Q_ASSERT(index>=0);
- QPointF point = calculateGeometryPoint(index);
- QVector<QPointF> points = m_points;
- points.replace(index,point);
+ Q_ASSERT(index<m_series->count());
+ Q_ASSERT(index>=0);
- if(m_animation) {
- m_animation->setAnimationType(XYAnimation::MoveDownAnimation);
- }
+ QVector<QPointF> points;
- updateChart(m_points,points,index);
+ if(m_animation) {
+ m_animation->setAnimationType(XYAnimation::ReplacePointAnimation);
+ }
+
+ if(m_dirty) {
+ points = calculateGeometryPoints();
+ } else {
+ QPointF point = calculateGeometryPoint(index);
+ points = m_points;
+ points.replace(index,point);
+ }
+
+ updateChart(m_points,points,index);
}
void XYChart::handleReinitialized()
@@ -170,7 +199,7 @@ void XYChart::handleReinitialized()
QVector<QPointF> points = calculateGeometryPoints();
if(m_animation) {
- m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
+ m_animation->setAnimationType(XYAnimation::NewAnimation);
}
updateChart(m_points,points);
@@ -178,16 +207,19 @@ void XYChart::handleReinitialized()
void XYChart::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
{
+ qDebug()<<__FUNCTION__;
m_minX=minX;
m_maxX=maxX;
m_minY=minY;
m_maxY=maxY;
if (isEmpty()) return;
+
QVector<QPointF> points = calculateGeometryPoints();
if(m_animation) {
- m_animation->setAnimationType(XYAnimation::MoveDownAnimation);
+ m_animation->setAnimationType(XYAnimation::ReplacePointAnimation);
}
+
updateChart(m_points,points);
}
@@ -199,10 +231,13 @@ void XYChart::handleGeometryChanged(const QRectF &rect)
m_origin=rect.topLeft();
if (isEmpty()) return;
+
QVector<QPointF> points = calculateGeometryPoints();
+
if(m_animation) {
- m_animation->setAnimationType(XYAnimation::LineDrawAnimation);
- }
+ m_animation->setAnimationType(XYAnimation::NewAnimation);
+ }
+
updateChart(m_points,points);
}
diff --git a/src/xychart/xychart_p.h b/src/xychart/xychart_p.h
index 9c4f1628..dc6a014d 100644
--- a/src/xychart/xychart_p.h
+++ b/src/xychart/xychart_p.h
@@ -38,7 +38,7 @@ public:
explicit XYChart(QXYSeries *series, ChartPresenter *presenter);
~XYChart(){};
- void setGeometryPoints(QVector<QPointF>& points);
+ void setGeometryPoints(const QVector<QPointF>& points);
QVector<QPointF> geometryPoints() const { return m_points; }
void setClipRect(const QRectF &rect);
@@ -51,6 +51,9 @@ public:
ChartAnimation* animation() const { return m_animation; }
virtual void updateGeometry() = 0;
+ bool isDirty() const { return m_dirty; }
+ void setDirty(bool dirty);
+
public Q_SLOTS:
void handlePointAdded(int index);
void handlePointRemoved(int index);
@@ -83,6 +86,7 @@ private:
QRectF m_clipRect;
QVector<QPointF> m_points;
XYAnimation* m_animation;
+ bool m_dirty;
friend class AreaChartItem;