From e1dfbbf1ecbae1f8c42363d6ad81668fbd3a1906 2012-02-09 15:30:57 From: sauimone Date: 2012-02-09 15:30:57 Subject: [PATCH] model prototyping for bar chart --- diff --git a/src/barchart/barchartmodel.cpp b/src/barchart/barchartmodel.cpp new file mode 100644 index 0000000..5bbd11c --- /dev/null +++ b/src/barchart/barchartmodel.cpp @@ -0,0 +1,99 @@ +#include +#include "barchartmodel_p.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +BarChartModel::BarChartModel(QObject *parent) : + QObject(parent) +{ +} + +void BarChartModel::addSeries(BarChartSeriesBase& series) +{ + mSeries.append(&series); + emit modelUpdated(); +} + +void BarChartModel::removeSeries(BarChartSeriesBase& series) +{ + int i = mSeries.indexOf(&series); + if (-1 == i) { + return; + } + mSeries.removeAt(i); + emit modelUpdated(); +} + +int BarChartModel::countSeries() +{ + return mSeries.count(); +} + +int BarChartModel::countItemsInSeries() +{ + int count(0); + for (int i=0; icountItems(); + if (temp > count) { + count = temp; + } + } + return count; +} + +int BarChartModel::countTotalItems() +{ + int total = mSeries.count() * countItemsInSeries(); + return total; +} + +int BarChartModel::min() +{ + Q_ASSERT(mSeries.count() > 0); + // TODO: make min and max members and update them when data changes. + // This is slower since they are checked every time, even if data is same since previous call. + int min = INT_MAX; + + for (int i=0; i min(); + if (temp < min) { + min = temp; + } + } + return min; +} + +int BarChartModel::max() +{ + Q_ASSERT(mSeries.count() > 0); + + // TODO: make min and max members and update them when data changes. + // This is slower since they are checked every time, even if data is same since previous call. + int max = INT_MIN; + + for (int i=0; i min(); + if (temp > max) { + max = temp; + } + } + return max; +} + +qreal BarChartModel::valueAt(int series, int item) +{ + if ((series < 0) || (series >= mSeries.count())) { + // No series, no value. + return 0; + } else if ((item < 0) || (item >= mSeries.at(series)->countItems())) { + // No item, no value. + return 0; + } + + return mSeries.at(series)->valueAt(item); +} + +#include "moc_barchartmodel_p.cpp" + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/barchartmodel_p.h b/src/barchart/barchartmodel_p.h new file mode 100644 index 0000000..808c74c --- /dev/null +++ b/src/barchart/barchartmodel_p.h @@ -0,0 +1,45 @@ +#ifndef BARCHARTMODEL_H +#define BARCHARTMODEL_H + +#include +#include "barchartseries.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +// Model for bar chart. +// TODO: Implement as QAbstractItemModel? + +class BarChartModel : public QObject //, public QAbstractItemModel +{ + Q_OBJECT +public: + explicit BarChartModel(QObject *parent = 0); + + // Takes reference, Series are owned by QChart or model? + void addSeries(BarChartSeriesBase& series); + void removeSeries(BarChartSeriesBase& series); + + int countSeries(); // Number of series in model + int countItemsInSeries(); // Maximum number of items in series + int countTotalItems(); // Total items in all series. Includes empty items. + + int max(); // Maximum value of all series + int min(); // Minimum value of all series + qreal valueAt(int series, int item); + +signals: + void modelUpdated(); + +public slots: + +private: + + // Data + QList mSeries; + + BarChartModel* mSingle; +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // BARCHARTMODEL_H diff --git a/src/barchart/barchartseriesbase.cpp b/src/barchart/barchartseriesbase.cpp index 4b7af76..6958c6c 100644 --- a/src/barchart/barchartseriesbase.cpp +++ b/src/barchart/barchartseriesbase.cpp @@ -7,15 +7,22 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE BarChartSeriesBase::BarChartSeriesBase(QObject *parent) : QChartSeries(parent) + ,mData(0) { } - -bool BarChartSeriesBase::setData(QAbstractItemModel* model) +/* +bool BarChartSeriesBase::setModel(QAbstractItemModel* model) { mModel = model; return true; } - +*/ +bool BarChartSeriesBase::setData(QList& data) +{ + mData = &data; + return true; +} +/* int BarChartSeriesBase::min() { Q_ASSERT(mModel->rowCount() > 0); @@ -103,6 +110,48 @@ int BarChartSeriesBase::columnSum(int column) } return sum; } +*/ +qreal BarChartSeriesBase::min() +{ + Q_ASSERT(mData != 0); + + int count = mData->count(); + int min = INT_MAX; + + for (int i=0; iat(i) < min) { + min = mData->at(i); + } + } + return min; +} + +qreal BarChartSeriesBase::max() +{ + Q_ASSERT(mData != 0); + + int count = mData->count(); + int max = INT_MIN; + + for (int i=0; iat(i) > max) { + max = mData->at(i); + } + } + return max; +} + +int BarChartSeriesBase::countItems() +{ + Q_ASSERT(mData != 0); + return mData->count(); +} + +qreal BarChartSeriesBase::valueAt(int item) +{ + Q_ASSERT(mData != 0); + return mData->at(item); +} #include "moc_barchartseriesbase.cpp" diff --git a/src/barchart/barchartseriesbase.h b/src/barchart/barchartseriesbase.h index c3b798c..7b25046 100644 --- a/src/barchart/barchartseriesbase.h +++ b/src/barchart/barchartseriesbase.h @@ -22,19 +22,25 @@ public: virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeInvalid; } // TODO: Better data model? - virtual bool setData(QAbstractItemModel* model); +// virtual bool setModel(QAbstractItemModel* model); + virtual bool setData(QList& data); // Methods to find out minimum and maximum values of data - int min(); - int max(); - int maxColumnSum(); // returns maximum sum of items in all columns. +// int min(); // TODO: remove +// int max(); // TODO: remove +// int maxColumnSum(); // TODO: move to model. returns maximum sum of items in all columns. - int countRows(); - int countColumns(); // Count items in one series. - int countTotalItems(); - int valueAt(int row, int column); +// int countRows(); // TODO: remove. +// int countColumns(); // TODO: remove. Count items in one series. +// int countTotalItems(); // TODO: move to model +// int valueAt(int row, int column); // TODO: move to model - int columnSum(int column); +// int columnSum(int column); // TODO: move to model + + qreal min(); + qreal max(); + int countItems(); + qreal valueAt(int item); public Q_SLOTS: @@ -42,6 +48,9 @@ private: QAbstractItemModel* mModel; BarGroupBase* mBarGroup; + + QList* mData; + }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/bargroup.cpp b/src/barchart/bargroup.cpp index 883feaa..f52955b 100644 --- a/src/barchart/bargroup.cpp +++ b/src/barchart/bargroup.cpp @@ -15,45 +15,50 @@ void BarGroup::layoutChanged() { // Scale bars to new layout // Layout for bars: + /* if (mSeries.countRows() <= 0) { // Nothing to do. return; } +*/ + if (mModel.countSeries() <= 0) { + return; + } // TODO: better way to auto-layout? // Use reals for accurancy (we might get some compiler warnings... :) - int columnCount = mSeries.countColumns(); - int rowCount = mSeries.countRows(); + int itemCount = mModel.countItemsInSeries(); + int seriesCount = mModel.countSeries(); qreal tW = mWidth; qreal tH = mHeight; qreal tM = mMax; qreal scale = (tH/tM); - qreal tC = columnCount+1; + qreal tC = itemCount+1; qreal xStepPerSeries = (tW/tC); // Scaling. int itemIndex(0); - int labelIndex = mSeries.countColumns() * mSeries.countRows(); + int labelIndex = itemCount * seriesCount; - for (int column=0; column < columnCount; column++) { - qreal xPos = xStepPerSeries * column + ((tW + mBarDefaultWidth*rowCount)/(columnCount*2)); + for (int item=0; item < itemCount; item++) { + qreal xPos = xStepPerSeries * item + ((tW + mBarDefaultWidth*seriesCount)/(itemCount*2)); qreal yPos = mHeight; - for (int row = 0; row < rowCount; row++) { - qreal barHeight = mSeries.valueAt(row, column) * scale; + for (int series = 0; series < seriesCount; series++) { + qreal barHeight = mModel.valueAt(series, item) * scale; Bar* bar = reinterpret_cast (childItems().at(itemIndex)); // TODO: width settable per bar? bar->resize(mBarDefaultWidth, barHeight); - bar->setColor(mColors.at(row)); + bar->setColor(mColors.at(series)); bar->setPos(xPos, yPos-barHeight); // item*posStep+startPos + series * mBarDefaultWidth, mHeight); itemIndex++; xPos += mBarDefaultWidth; } // TODO: Layout for labels, remove magic number - xPos = xStepPerSeries * column + ((tW + mBarDefaultWidth*rowCount)/(columnCount*2)); + xPos = xStepPerSeries * item + ((tW + mBarDefaultWidth*seriesCount)/(itemCount*2)); BarLabel* label = reinterpret_cast (childItems().at(labelIndex)); label->setPos(xPos, mHeight + 20); labelIndex++; diff --git a/src/barchart/bargroupbase.cpp b/src/barchart/bargroupbase.cpp index 6a3bd97..d691732 100644 --- a/src/barchart/bargroupbase.cpp +++ b/src/barchart/bargroupbase.cpp @@ -9,13 +9,14 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE BarGroupBase::BarGroupBase(BarChartSeriesBase& series, QGraphicsItem *parent) : ChartItem(parent) - ,mSeries(series) +// ,mSeries(series) ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready ,mLayoutSet(false) ,mLayoutDirty(true) ,mTheme(0) ,mSeparatorsVisible(true) { + mModel.addSeries(series); dataChanged(); } @@ -69,9 +70,10 @@ void BarGroupBase::dataChanged() { qDebug() << "BarGroupBase::dataChanged"; - // Find out maximum and minimum of all series - mMax = mSeries.max(); - mMin = mSeries.min(); + // Find out maximum and minimum of all series. + // TODO: is this actually needed? +// mMax = mModel.max(); +// mMin = mModel.min(); // Delete old bars foreach (QGraphicsItem* item, childItems()) { @@ -79,14 +81,14 @@ void BarGroupBase::dataChanged() } // Create new graphic items for bars - int totalItems = mSeries.countTotalItems(); + int totalItems = mModel.countTotalItems(); // mSeries.countTotalItems(); for (int i=0; isetColor(QColor(255,0,0,255)); // TODO: color for separations from theme diff --git a/src/barchart/bargroupbase.h b/src/barchart/bargroupbase.h index 8dfff8e..a2c9a97 100644 --- a/src/barchart/bargroupbase.h +++ b/src/barchart/bargroupbase.h @@ -6,17 +6,18 @@ //#include "barlabel_p.h" //#include "bar_p.h" #include "barchartseriesbase.h" +#include "barchartmodel_p.h" #include QTCOMMERCIALCHART_BEGIN_NAMESPACE // Base Class for bar groups. Common implemantation of different groups. Not to be instantiated. - class BarGroupBase : public QObject, public ChartItem { Q_OBJECT public: BarGroupBase(BarChartSeriesBase& series, QGraphicsItem *parent = 0); +// BarGroupBase(BarChartModel& model, QGraphicsItem *parent = 0); void setSeparatorsVisible(bool visible = true); public: // From ChartItem @@ -46,9 +47,10 @@ protected slots: protected: - BarChartSeriesBase& mSeries; + //BarChartSeriesBase& mSeries; - int mMin; // Min and max values of data. (updated when data is changed, used when drawing) + // TODO: consider these. + int mMin; // Min and max values of data. (updated when data is changed, used when drawing) int mMax; int mHeight; // Layout spesific @@ -63,6 +65,8 @@ protected: ChartTheme* mTheme; bool mSeparatorsVisible; + BarChartModel mModel; + }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/percentbargroup.cpp b/src/barchart/percentbargroup.cpp index c6eaee3..94beb34 100644 --- a/src/barchart/percentbargroup.cpp +++ b/src/barchart/percentbargroup.cpp @@ -14,6 +14,7 @@ PercentBarGroup::PercentBarGroup(PercentBarChartSeries& series, QGraphicsItem *p void PercentBarGroup::layoutChanged() { + /* // Scale bars to new layout // Layout for bars: if (mSeries.countRows() <= 0) { @@ -66,7 +67,7 @@ void PercentBarGroup::layoutChanged() xPos += xStep; separatorIndex++; } - +*/ mLayoutDirty = true; } diff --git a/src/barchart/stackedbargroup.cpp b/src/barchart/stackedbargroup.cpp index b330fa7..9accb73 100644 --- a/src/barchart/stackedbargroup.cpp +++ b/src/barchart/stackedbargroup.cpp @@ -14,6 +14,7 @@ StackedBarGroup::StackedBarGroup(StackedBarChartSeries& series, QGraphicsItem *p void StackedBarGroup::layoutChanged() { +/* // Scale bars to new layout // Layout for bars: if (mSeries.countRows() <= 0) { @@ -74,7 +75,7 @@ void StackedBarGroup::layoutChanged() xPos += xStep; separatorIndex++; } - +*/ mLayoutDirty = true; } diff --git a/src/src.pro b/src/src.pro index d054ce8..384b67c 100644 --- a/src/src.pro +++ b/src/src.pro @@ -14,12 +14,13 @@ SOURCES += barchart/barchartseries.cpp \ barchart/percentbarchartseries.cpp \ barchart/percentbargroup.cpp \ barchart/barlabel.cpp \ - linechart/linechartanimationitem.cpp \ - linechart/linechartitem.cpp \ - linechart/qlinechartseries.cpp \ + barchart/barchartmodel.cpp \ barchart/separator.cpp \ barchart/bargroupbase.cpp \ barchart/barchartseriesbase.cpp \ + linechart/linechartanimationitem.cpp \ + linechart/linechartitem.cpp \ + linechart/qlinechartseries.cpp \ qscatterseries.cpp \ #scatterpresentation.cpp \ qchart.cpp \ @@ -37,6 +38,7 @@ PRIVATE_HEADERS += linechart/linechartitem_p.h \ barchart/barlabel_p.h \ barchart/bar_p.h \ barchart/separator_p.h \ + barchart/barchartmodel_p.h \ qscatterseries_p.h \ #scatterpresentation.h \ axisitem_p.h \