From 223051b363f00d29541eeaa5bf9e2b1b1b117263 2012-03-21 14:17:24 From: sauimone Date: 2012-03-21 14:17:24 Subject: [PATCH] barchart animation mechanics working. still some todo --- diff --git a/src/animations/baranimation.cpp b/src/animations/baranimation.cpp index c061842..4ba119d 100644 --- a/src/animations/baranimation.cpp +++ b/src/animations/baranimation.cpp @@ -3,7 +3,9 @@ #include #include -Q_DECLARE_METATYPE(QVector) +Q_DECLARE_METATYPE(QVector) +//Q_DECLARE_METATYPE(BarLayout) // TODO? + QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -17,31 +19,35 @@ BarAnimation::~BarAnimation() { } -void BarAnimation::updateValues(const BarLayout& /*layout*/) +void BarAnimation::updateValues(const QVector& layout) { - // TODO: - qDebug() << "BarAnimation::updateValues"; + // TODO?: +// qDebug() << "BarAnimation::updateValues" << layout.count(); } QVariant BarAnimation::interpolated(const QVariant &from, const QVariant &to, qreal progress) const { - QVector startVector = qVariantValue > (from); - QVector endVector = qVariantValue > (to); - QVector result; + QVector startVector = qVariantValue > (from); + QVector endVector = qVariantValue > (to); + QVector result; Q_ASSERT(startVector.count() == endVector.count()) ; for(int i =0 ;i< startVector.count();i++){ - QSizeF value = startVector[i] + ((endVector[i]- endVector[i]) * progress); - result << value; + //QRectF value = startVector[i] + ((endVector[i] - startVector[i]) * progress); + QPointF topLeft = startVector[i].topLeft() + ((endVector[i].topLeft() - startVector[i].topLeft()) * progress); + QSizeF size = startVector[i].size() + ((endVector[i].size() - startVector[i].size()) * progress); + QRectF value(topLeft,size); + result << value; } return qVariantFromValue(result); } -void BarAnimation::updateCurrentValue(const QVariant &) +void BarAnimation::updateCurrentValue(const QVariant &value) { - // TODO? + QVector layout = qVariantValue >(value); + m_item->setLayout(layout); } #include "moc_baranimation_p.cpp" diff --git a/src/animations/baranimation_p.h b/src/animations/baranimation_p.h index aa14475..a6c7236 100644 --- a/src/animations/baranimation_p.h +++ b/src/animations/baranimation_p.h @@ -18,7 +18,7 @@ public: BarAnimation(BarChartItem *item); ~BarAnimation(); - void updateValues(const BarLayout& layout); + void updateValues(const QVector& layout); public: // from QVariantAnimation virtual QVariant interpolated (const QVariant & from, const QVariant & to, qreal progress ) const; diff --git a/src/animations/chartanimator.cpp b/src/animations/chartanimator.cpp index cebab1e..c3c719d 100644 --- a/src/animations/chartanimator.cpp +++ b/src/animations/chartanimator.cpp @@ -13,6 +13,7 @@ Q_DECLARE_METATYPE(QVector) Q_DECLARE_METATYPE(QVector) +Q_DECLARE_METATYPE(QVector) QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -267,12 +268,16 @@ void ChartAnimator::updateLayout(PieChartItem* item, QPieSlice *slice, const Pie animation->updateValue(slice, sliceData); } -void ChartAnimator::updateLayout(BarChartItem* item, const BarLayout &layout) +void ChartAnimator::updateLayout(BarChartItem* item, const QVector &oldLayout, const QVector &newLayout) { qDebug() << "ChartAnimator::updateLayout"; BarAnimation* animation = static_cast(m_animations.value(item)); Q_ASSERT(animation); - animation->updateValues(layout); +// animation->updateValues(layout); + animation->setDuration(duration); + animation->setKeyValueAt(0.0, qVariantFromValue(oldLayout)); + animation->setKeyValueAt(1.0, qVariantFromValue(newLayout)); + QTimer::singleShot(0,animation,SLOT(start())); } diff --git a/src/animations/chartanimator_p.h b/src/animations/chartanimator_p.h index ca3fbca..330f891 100644 --- a/src/animations/chartanimator_p.h +++ b/src/animations/chartanimator_p.h @@ -43,7 +43,7 @@ public: void updateLayout(PieChartItem* item, const PieLayout &layout); void updateLayout(PieChartItem* item, QPieSlice *slice, const PieSliceData &sliceData); - void updateLayout(BarChartItem* item, const BarLayout &layout); + void updateLayout(BarChartItem* item, const QVector &oldLayout, const QVector &newLayout); void setState(State state,const QPointF& point = QPointF()); diff --git a/src/barchart/barchartitem.cpp b/src/barchart/barchartitem.cpp index 26569d4..ea63963 100644 --- a/src/barchart/barchartitem.cpp +++ b/src/barchart/barchartitem.cpp @@ -20,7 +20,7 @@ BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) : mSeries(series) { connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString))); - connect(series, SIGNAL(updatedBars()), this, SLOT(layoutChanged())); + connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged())); //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged())); connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int))); setZValue(ChartPresenter::BarSeriesZValue); @@ -59,6 +59,7 @@ void BarChartItem::dataChanged() mBars.clear(); mFloatingValues.clear(); + mLayout.clear(); // Create new graphic items for bars for (int c=0; ccategoryCount(); c++) { @@ -72,6 +73,7 @@ void BarChartItem::dataChanged() connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString))); connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint))); connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent())); + mLayout.append(QRectF(0,0,0,0)); } } @@ -86,9 +88,11 @@ void BarChartItem::dataChanged() } } } - +/* void BarChartItem::layoutChanged() { + qDebug() << "Deprecated BarChartItem::layoutChanged called. aborting"; + return; // Scale bars to new layout // Layout for bars: if (mSeries->barsetCount() <= 0) { @@ -118,6 +122,8 @@ void BarChartItem::layoutChanged() qreal categoryWidth = width/categoryCount; qreal barWidth = categoryWidth / (setCount+1); + BarLayout layout; + int itemIndex(0); for (int category=0; category < categoryCount; category++) { qreal xPos = categoryWidth * category + barWidth/2; @@ -126,11 +132,18 @@ void BarChartItem::layoutChanged() qreal barHeight = mSeries->valueAt(set,category) * scale; Bar* bar = mBars.at(itemIndex); + QRectF rect(xPos,yPos-barHeight,mBarWidth,barHeight); + layout.insert(bar,rect); // TODO: width settable per bar? bar->setRect(xPos, yPos-barHeight,barWidth, barHeight); bar->setPen(mSeries->barsetAt(set)->pen()); bar->setBrush(mSeries->barsetAt(set)->brush()); +// bar->resize(mBarWidth, barHeight); +// layout.insert(bar,QSizeF(mBarWidth,barHeight)); + bar->setPen(mSeries->barsetAt(set)->pen()); + bar->setBrush(mSeries->barsetAt(set)->brush()); +// bar->setPos(xPos, yPos-barHeight); itemIndex++; xPos += barWidth; } @@ -160,32 +173,106 @@ void BarChartItem::layoutChanged() xPos += barWidth; } } - update(); +// update(); } - -BarLayout BarChartItem::calculateLayout() +*/ +QVector BarChartItem::calculateLayout() { +// layoutChanged(); +/* BarLayout layout; foreach(Bar* bar, mBars) { layout.insert(bar,bar->boundingRect()); } +*/ + QVector layout; + + // Use temporary qreals for accurancy (we might get some compiler warnings... :) + int categoryCount = mSeries->categoryCount(); + int setCount = mSeries->barsetCount(); + + qreal tW = mWidth; + qreal tH = mHeight; + qreal tM = mSeries->max(); + + // Domain: + if (mDomainMaxY > tM) { + tM = mDomainMaxY; + } + + qreal scale = (tH/tM); + qreal tC = categoryCount + 1; + qreal categoryWidth = tW/tC; + mBarWidth = categoryWidth / (setCount+1); + + int itemIndex(0); + for (int category=0; category < categoryCount; category++) { + qreal xPos = categoryWidth * category + categoryWidth /2 + mBarWidth/2; + qreal yPos = mHeight; + for (int set = 0; set < setCount; set++) { + qreal barHeight = mSeries->valueAt(set,category) * scale; + Bar* bar = mBars.at(itemIndex); + + QRectF rect(xPos,yPos-barHeight,mBarWidth,barHeight); + //layout.insert(bar,rect); + layout.append(rect); + // TODO: width settable per bar? +// bar->resize(mBarWidth, barHeight); +// layout.insert(bar,QSizeF(mBarWidth,barHeight)); + bar->setPen(mSeries->barsetAt(set)->pen()); + bar->setBrush(mSeries->barsetAt(set)->brush()); +// bar->setPos(xPos, yPos-barHeight); + itemIndex++; + xPos += mBarWidth; + } + } + + // Position floating values + itemIndex = 0; + for (int category=0; category < mSeries->categoryCount(); category++) { + qreal xPos = categoryWidth * category + categoryWidth/2 + mBarWidth; + qreal yPos = mHeight; + for (int set=0; set < mSeries->barsetCount(); set++) { + qreal barHeight = mSeries->valueAt(set,category) * scale; + BarValue* value = mFloatingValues.at(itemIndex); + + QBarSet* barSet = mSeries->barsetAt(set); + value->resize(100,50); // TODO: proper layout for this. + value->setPos(xPos, yPos-barHeight/2); + value->setPen(barSet->floatingValuePen()); + + if (mSeries->valueAt(set,category) != 0) { + value->setValueString(QString::number(mSeries->valueAt(set,category))); + } else { + value->setValueString(QString("")); + } + + itemIndex++; + xPos += mBarWidth; + } + } return layout; } -void BarChartItem::applyLayout(const BarLayout &layout) +void BarChartItem::applyLayout(const QVector &layout) { if (animator()) - animator()->updateLayout(this, layout); + animator()->updateLayout(this, mLayout, layout); else setLayout(layout); } -void BarChartItem::setLayout(const BarLayout &layout) +void BarChartItem::setLayout(const QVector &layout) { - foreach (Bar *bar, layout.keys()) { - bar->setRect(layout.value(bar)); + mLayout = layout; + + for (int i=0; isetSize(layout.at(i).size()); + //mBars.at(i)->setPos(layout.at(i).topLeft()); + mBars.at(i)->setRect(layout.at(i)); } + update(); } @@ -218,7 +305,7 @@ void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal mDomainMaxX = maxX; mDomainMinY = minY; mDomainMaxY = maxY; - layoutChanged(); + handleLayoutChanged(); /* int count = mSeries->categoryCount(); @@ -249,7 +336,8 @@ void BarChartItem::handleGeometryChanged(const QRectF& rect) void BarChartItem::handleLayoutChanged() { - BarLayout layout = calculateLayout(); + qDebug() << "BarChartItem::handleLayoutChanged"; + QVector layout = calculateLayout(); applyLayout(layout); update(); } diff --git a/src/barchart/barchartitem_p.h b/src/barchart/barchartitem_p.h index a61b12c..2455c3f 100644 --- a/src/barchart/barchartitem_p.h +++ b/src/barchart/barchartitem_p.h @@ -14,7 +14,7 @@ class BarValue; class QChartAxisCategories; class QChart; -typedef QHash BarLayout; +//typedef QVector BarLayout; class BarChartItem : public ChartItem { @@ -34,12 +34,13 @@ public: // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes private slots: - virtual void layoutChanged(); // layout has changed -> need to recalculate bar sizes + //virtual void layoutChanged(); // layout has changed -> need to recalculate bar sizes public: - BarLayout calculateLayout(); - void applyLayout(const BarLayout &layout); - void setLayout(const BarLayout &layout); + QVector calculateLayout(); + void applyLayout(const QVector &layout); + void setLayout(const QVector &layout); + void updateLayout(const QVector &layout); QRectF geometry() const { return m_rect;} @@ -65,6 +66,7 @@ protected: QRectF m_rect; bool mLayoutSet; // True, if component has been laid out. + QVector mLayout; // Not owned. QBarSeries* mSeries; diff --git a/src/barchart/qbarseries.cpp b/src/barchart/qbarseries.cpp index e54a57c..cd886b1 100644 --- a/src/barchart/qbarseries.cpp +++ b/src/barchart/qbarseries.cpp @@ -51,10 +51,12 @@ QBarSeries::QBarSeries(QStringList categories, QObject *parent) */ void QBarSeries::addBarSet(QBarSet *set) { + qDebug() << "add bar set"; mModel->addBarSet(set); connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString))); connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString))); connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged())); + emit updatedBars(); } /*! @@ -67,6 +69,7 @@ void QBarSeries::removeBarSet(QBarSet *set) disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString))); disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString))); mModel->removeBarSet(set); + emit updatedBars(); } void QBarSeries::insertBarSet(int i, QBarSet *set)