diff --git a/src/barchart/barchartseries.cpp b/src/barchart/barchartseries.cpp index b43afc7..dfd66f5 100644 --- a/src/barchart/barchartseries.cpp +++ b/src/barchart/barchartseries.cpp @@ -1,78 +1,11 @@ #include #include "barchartseries.h" -#include "bargroup.h" + QTCOMMERCIALCHART_BEGIN_NAMESPACE BarChartSeries::BarChartSeries(QObject *parent) - : QChartSeries(parent) -{ -} - -bool BarChartSeries::setData(QAbstractItemModel* model) -{ - mModel = model; - return true; -} - -int BarChartSeries::min() -{ - Q_ASSERT(mModel->rowCount() > 0); - Q_ASSERT(mModel->columnCount() > 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 rowCount(); i++) { - for(int j=0; jcolumnCount(); j++) { - int temp = mModel->data(mModel->index(i,j)).toInt(); - if (temp < min) { - min = temp; - } - } - } - return min; -} - -int BarChartSeries::max() -{ - Q_ASSERT(mModel->rowCount() > 0); - Q_ASSERT(mModel->columnCount() > 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 rowCount(); i++) { - for(int j=0; jcolumnCount(); j++) { - int temp = mModel->data(mModel->index(i,j)).toInt(); - if (temp > max) { - max = temp; - } - } - } - return max; -} - - -int BarChartSeries::countRows() -{ - return mModel->rowCount(); -} - -int BarChartSeries::countColumns() -{ - return mModel->columnCount(); -} - -int BarChartSeries::countTotalItems() -{ - return mModel->rowCount() * mModel->columnCount(); -} - -int BarChartSeries::valueAt(int row, int column) + : BarChartSeriesBase(parent) { - return mModel->data(mModel->index(row,column)).toInt(); } #include "moc_barchartseries.cpp" diff --git a/src/barchart/barchartseries.h b/src/barchart/barchartseries.h index 7fa5cab..fd58706 100644 --- a/src/barchart/barchartseries.h +++ b/src/barchart/barchartseries.h @@ -3,37 +3,22 @@ #include #include -#include "qchartseries.h" -#include "qchartglobal.h" +#include "barchartseriesbase.h" -// TODO: Can this class be combined with series? class BarGroup; QTCOMMERCIALCHART_BEGIN_NAMESPACE // Container for series -class QTCOMMERCIALCHART_EXPORT BarChartSeries : public QChartSeries +class QTCOMMERCIALCHART_EXPORT BarChartSeries : public BarChartSeriesBase { Q_OBJECT public: BarChartSeries(QObject* parent=0); - // from QChartSeries + // from BarChartSeriesBase virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeBar; } - // TODO: Better data model? - virtual bool setData(QAbstractItemModel* model); - - // Methods to find out minimum and maximum values of data - int min(); - int max(); - int countRows(); - int countColumns(); // Count items in one series. - int countTotalItems(); - int valueAt(int row, int column); - -public Q_SLOTS: - private: QAbstractItemModel* mModel; diff --git a/src/barchart/barchartseriesbase.cpp b/src/barchart/barchartseriesbase.cpp new file mode 100644 index 0000000..4b7af76 --- /dev/null +++ b/src/barchart/barchartseriesbase.cpp @@ -0,0 +1,109 @@ +#include +#include +#include "barchartseriesbase.h" +#include "bargroup.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +BarChartSeriesBase::BarChartSeriesBase(QObject *parent) + : QChartSeries(parent) +{ +} + +bool BarChartSeriesBase::setData(QAbstractItemModel* model) +{ + mModel = model; + return true; +} + +int BarChartSeriesBase::min() +{ + Q_ASSERT(mModel->rowCount() > 0); + Q_ASSERT(mModel->columnCount() > 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 rowCount(); i++) { + for(int j=0; jcolumnCount(); j++) { + int temp = mModel->data(mModel->index(i,j)).toInt(); + if (temp < min) { + min = temp; + } + } + } + return min; +} + +int BarChartSeriesBase::max() +{ + Q_ASSERT(mModel->rowCount() > 0); + Q_ASSERT(mModel->columnCount() > 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 rowCount(); i++) { + for(int j=0; jcolumnCount(); j++) { + int temp = mModel->data(mModel->index(i,j)).toInt(); + if (temp > max) { + max = temp; + } + } + } + return max; +} + +int BarChartSeriesBase::maxColumnSum() +{ + Q_ASSERT(mModel->rowCount() > 0); + Q_ASSERT(mModel->columnCount() > 0); + + int max = INT_MIN; + + for (int col=0; col columnCount(); col++) { + int sum = columnSum(col); + if (sum > max) { + max = sum; + } + } + return max; +} + +int BarChartSeriesBase::countRows() +{ + return mModel->rowCount(); +} + +int BarChartSeriesBase::countColumns() +{ + return mModel->columnCount(); +} + +int BarChartSeriesBase::countTotalItems() +{ + return mModel->rowCount() * mModel->columnCount(); +} + +int BarChartSeriesBase::valueAt(int row, int column) +{ + QModelIndex index = mModel->index(row,column); + return mModel->data(index).toInt(); +} + +int BarChartSeriesBase::columnSum(int column) +{ + int sum(0); + int count = mModel->rowCount(); + + for (int row = 0; row < count; row++) { + sum += mModel->data(mModel->index(row,column)).toInt(); + } + return sum; +} + +#include "moc_barchartseriesbase.cpp" + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/barchartseriesbase.h b/src/barchart/barchartseriesbase.h new file mode 100644 index 0000000..c3b798c --- /dev/null +++ b/src/barchart/barchartseriesbase.h @@ -0,0 +1,49 @@ +#ifndef BARCHARTSERIESBASE_H +#define BARCHARTSERIESBASE_H + +#include +#include +#include "qchartseries.h" +#include "qchartglobal.h" + +class BarGroupBase; + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +// Container for series +class QTCOMMERCIALCHART_EXPORT BarChartSeriesBase : public QChartSeries +{ + Q_OBJECT +protected: + BarChartSeriesBase(QObject* parent=0); + +public: + // from QChartSeries + virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeInvalid; } + + // TODO: Better data model? + virtual bool setData(QAbstractItemModel* model); + + // 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 countRows(); + int countColumns(); // Count items in one series. + int countTotalItems(); + int valueAt(int row, int column); + + int columnSum(int column); + +public Q_SLOTS: + +private: + + QAbstractItemModel* mModel; + BarGroupBase* mBarGroup; +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // BARCHARTSERIESBASE_H diff --git a/src/barchart/bargroup.cpp b/src/barchart/bargroup.cpp index 81e7f60..883feaa 100644 --- a/src/barchart/bargroup.cpp +++ b/src/barchart/bargroup.cpp @@ -6,101 +6,9 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE BarGroup::BarGroup(BarChartSeries& series, QGraphicsItem *parent) : - ChartItem(parent) - ,mSeries(series) - ,mBarDefaultWidth(10) - ,mLayoutSet(false) - ,mLayoutDirty(true) + BarGroupBase(series,parent) { - dataChanged(); -} - -void BarGroup::setSize(const QSizeF& size) -{ - qDebug() << "BarGroup::setSize"; - mWidth = size.width(); - mHeight = size.height(); - layoutChanged(); - mLayoutSet = true; -} - -void BarGroup::setPlotDomain(const PlotDomain& data) -{ - qDebug() << "BarGroup::setPlotDomain"; - // TODO: - mPlotDomain = data; -} - -void BarGroup::setBarWidth( int w ) -{ - mBarDefaultWidth = w; -} - -int BarGroup::addColor( QColor color ) -{ - int colorIndex = mColors.count(); - mColors.append(color); - return colorIndex; -} - -void BarGroup::resetColors() -{ - mColors.clear(); -} - -void BarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - if (!mLayoutSet) { - qDebug() << "QBarChart::paint called without layout set. Aborting."; - return; - } - if (mLayoutDirty) { - // Layout or data has changed. Need to redraw. - foreach(QGraphicsItem* i, childItems()) { - i->paint(painter,option,widget); - mLayoutDirty = false; - } - } -} - -QRectF BarGroup::boundingRect() const -{ - return QRectF(0,0,mWidth,mHeight); -} - - -void BarGroup::dataChanged() -{ - qDebug() << "QBarChart::dataChanged mSeries"; - - // Find out maximum and minimum of all series - mMax = mSeries.max(); - mMin = mSeries.min(); - - // Delete old bars - // Is this correct way to delete childItems? - foreach (QGraphicsItem* item, childItems()) { - delete item; - } - - // Create new graphic items for bars - int totalItems = mSeries.countTotalItems(); - for (int i=0; iset(text); - childItems().append(label); - } - - // TODO: if (autolayout) { layoutChanged() } or something - mLayoutDirty = true; + mBarDefaultWidth = 10; } void BarGroup::layoutChanged() diff --git a/src/barchart/bargroup.h b/src/barchart/bargroup.h index 31b79ed..ba982ec 100644 --- a/src/barchart/bargroup.h +++ b/src/barchart/bargroup.h @@ -1,55 +1,26 @@ #ifndef QBARGROUP_H #define QBARGROUP_H -#include "chartitem_p.h" -#include "bar_p.h" +#include "bargroupbase.h" #include "barchartseries.h" #include QTCOMMERCIALCHART_BEGIN_NAMESPACE -class BarGroup : public ChartItem +// Base class for bar groups + +class BarGroup : public BarGroupBase { public: explicit BarGroup(BarChartSeries& series, QGraphicsItem *parent = 0); -public: // from ChartItem - void setSize(const QSizeF &size); - void setPlotDomain(const PlotDomain& data); - - // Layout "api" - void setPos(qreal x, qreal y); - void setBarWidth( int w ); // Default width for each bar - - int addColor( QColor color ); - void resetColors(); - - // From QGraphicsItem - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - QRectF boundingRect() const; - private: - void dataChanged(); // data of series has changed -> need to recalculate bar sizes + // From BarGroupBase void layoutChanged(); // layout has changed -> need to recalculate bar sizes private: - // Data - BarChartSeries& mSeries; - int mMin; // Min and max values of data. (updated when data is changed, used when drawing) - int mMax; - - int mHeight; // Layout spesific - int mWidth; - int mBarDefaultWidth; - - bool mLayoutSet; // True, if component has been laid out. - bool mLayoutDirty; - - QList mColors; // List of colors for series for now - - PlotDomain mPlotDomain; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/bargroupbase.cpp b/src/barchart/bargroupbase.cpp new file mode 100644 index 0000000..023e016 --- /dev/null +++ b/src/barchart/bargroupbase.cpp @@ -0,0 +1,122 @@ +#include "bargroupbase.h" +#include "bar_p.h" +#include "barlabel_p.h" +#include "separator_p.h" +#include "barchartseriesbase.h" +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +BarGroupBase::BarGroupBase(BarChartSeriesBase& series, QGraphicsItem *parent) + : ChartItem(parent) + ,mSeries(series) + ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready + ,mLayoutSet(false) + ,mLayoutDirty(true) + ,mTheme(0) + ,mSeparatorsVisible(true) +{ + dataChanged(); +} + +void BarGroupBase::setSeparatorsVisible(bool visible) +{ + mSeparatorsVisible = visible; +} + +void BarGroupBase::setSize(const QSizeF& size) +{ + mWidth = size.width(); + mHeight = size.height(); + layoutChanged(); + mLayoutSet = true; +} + +void BarGroupBase::setPlotDomain(const PlotDomain& data) +{ + qDebug() << "BarGroupBase::setPlotDomain"; + // TODO: +} + +void BarGroupBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + if (!mLayoutSet) { + qDebug() << "BarGroupBase::paint called without layout set. Aborting."; + return; + } + if (mLayoutDirty) { + // Layout or data has changed. Need to redraw. + foreach(QGraphicsItem* i, childItems()) { + i->paint(painter,option,widget); + } + } +} + +QRectF BarGroupBase::boundingRect() const +{ + return QRectF(0,0,mWidth,mHeight); +} + +void BarGroupBase::themeChanged(ChartTheme *theme) +{ + mTheme = theme; +} + +void BarGroupBase::setBarWidth( int w ) +{ + mBarDefaultWidth = w; +} + +int BarGroupBase::addColor( QColor color ) +{ + int colorIndex = mColors.count(); + mColors.append(color); + return colorIndex; +} + +void BarGroupBase::resetColors() +{ + mColors.clear(); +} + +void BarGroupBase::dataChanged() +{ + qDebug() << "BarGroupBase::dataChanged"; + + // Find out maximum and minimum of all series + mMax = mSeries.max(); + mMin = mSeries.min(); + + // Delete old bars + foreach (QGraphicsItem* item, childItems()) { + delete item; + } + + // Create new graphic items for bars + int totalItems = mSeries.countTotalItems(); + for (int i=0; iset(text); + childItems().append(label); + } + + count = mSeries.countColumns() - 1; // There is one less separator than columns + for (int i=0; isetColor(QColor(255,0,0,255)); // TODO: color for separations from theme + childItems().append(sep); + } + + // TODO: if (autolayout) { layoutChanged() } or something + mLayoutDirty = true; +} + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/bargroupbase.h b/src/barchart/bargroupbase.h new file mode 100644 index 0000000..06995f1 --- /dev/null +++ b/src/barchart/bargroupbase.h @@ -0,0 +1,64 @@ +#ifndef BARGROUPBASE_H +#define BARGROUPBASE_H + +#include "charttheme_p.h" +#include "chartitem_p.h" +//#include "barlabel_p.h" +//#include "bar_p.h" +#include "barchartseriesbase.h" +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +// Base Class for bar groups. Common implemantation of different groups. Not to be instantiated. + +class BarGroupBase : public ChartItem, public ChartThemeObserver +{ + +public: + BarGroupBase(BarChartSeriesBase& series, QGraphicsItem *parent = 0); + void setSeparatorsVisible(bool visible = true); + +public: // From ChartItem + void setSize(const QSizeF &size); + void setPlotDomain(const PlotDomain& data); + + // From QGraphicsItem + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + QRectF boundingRect() const; + + // From ChartThemeObserver + void themeChanged(ChartTheme *theme); + + // TODO: these may change with layout awarness. + void setBarWidth( int w ); + int addColor( QColor color ); + void resetColors(); + + virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes + virtual void layoutChanged() = 0; // layout has changed -> need to recalculate bar sizes + +protected: + + BarChartSeriesBase& mSeries; + + int mMin; // Min and max values of data. (updated when data is changed, used when drawing) + int mMax; + + int mHeight; // Layout spesific + int mWidth; + int mBarDefaultWidth; + + bool mLayoutSet; // True, if component has been laid out. + bool mLayoutDirty; + + QList mColors; // List of colors for series for now + + ChartTheme* mTheme; + bool mSeparatorsVisible; + +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // BARGROUPBASE_H diff --git a/src/barchart/percentbarchartseries.cpp b/src/barchart/percentbarchartseries.cpp index 880ad90..6581fbe 100644 --- a/src/barchart/percentbarchartseries.cpp +++ b/src/barchart/percentbarchartseries.cpp @@ -7,104 +7,10 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE PercentBarChartSeries::PercentBarChartSeries(QObject *parent) : - QChartSeries(parent) + BarChartSeriesBase(parent) { } -bool PercentBarChartSeries::setData(QAbstractItemModel* model) -{ - mModel = model; - return true; -} - -int PercentBarChartSeries::min() -{ - Q_ASSERT(mModel->rowCount() > 0); - Q_ASSERT(mModel->columnCount() > 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 rowCount(); i++) { - for(int j=0; jcolumnCount(); j++) { - int temp = mModel->data(mModel->index(i,j)).toInt(); - if (temp < min) { - min = temp; - } - } - } - return min; -} - -int PercentBarChartSeries::max() -{ - Q_ASSERT(mModel->rowCount() > 0); - Q_ASSERT(mModel->columnCount() > 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 rowCount(); i++) { - for(int j=0; jcolumnCount(); j++) { - int temp = mModel->data(mModel->index(i,j)).toInt(); - if (temp > max) { - max = temp; - } - } - } - return max; -} - -int PercentBarChartSeries::maxColumnSum() -{ - Q_ASSERT(mModel->rowCount() > 0); - Q_ASSERT(mModel->columnCount() > 0); - - int max = INT_MIN; - - for (int col=0; col columnCount(); col++) { - int sum = columnSum(col); - if (sum > max) { - max = sum; - } - } - return max; -} - -int PercentBarChartSeries::countRows() -{ - return mModel->rowCount(); -} - -int PercentBarChartSeries::countColumns() -{ - return mModel->columnCount(); -} - -int PercentBarChartSeries::countTotalItems() -{ - return mModel->rowCount() * mModel->columnCount(); -} - -int PercentBarChartSeries::valueAt(int row, int column) -{ - QModelIndex index = mModel->index(row,column); - return mModel->data(index).toInt(); -} - -int PercentBarChartSeries::columnSum(int column) -{ - int sum(0); - int count = mModel->rowCount(); - - for (int row = 0; row < count; row++) { - sum += mModel->data(mModel->index(row,column)).toInt(); - } - return sum; -} - #include "moc_percentbarchartseries.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/percentbarchartseries.h b/src/barchart/percentbarchartseries.h index a2cb80a..f8e32ee 100644 --- a/src/barchart/percentbarchartseries.h +++ b/src/barchart/percentbarchartseries.h @@ -3,36 +3,21 @@ #include #include -#include "qchartseries.h" +#include "barchartseriesbase.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE class PercentBarGroup; -class QTCOMMERCIALCHART_EXPORT PercentBarChartSeries : public QChartSeries +class QTCOMMERCIALCHART_EXPORT PercentBarChartSeries : public BarChartSeriesBase { Q_OBJECT public: PercentBarChartSeries(QObject* parent=0); - // from QChartSeries + // from BarChartSeriesBase virtual QChartSeriesType type() const { return QChartSeries::SeriesTypePercentBar; } - // TODO: Better data model? - virtual bool setData(QAbstractItemModel* model); - - // 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 countRows(); - int countColumns(); - int countTotalItems(); - int valueAt(int row, int column); - - int columnSum(int column); - public Q_SLOTS: private: diff --git a/src/barchart/percentbargroup.cpp b/src/barchart/percentbargroup.cpp index 76e9b79..c6eaee3 100644 --- a/src/barchart/percentbargroup.cpp +++ b/src/barchart/percentbargroup.cpp @@ -1,106 +1,15 @@ #include "percentbargroup.h" #include "bar_p.h" #include "barlabel_p.h" +#include "separator_p.h" #include QTCOMMERCIALCHART_BEGIN_NAMESPACE -PercentBarGroup::PercentBarGroup(PercentBarChartSeries& series, QGraphicsItem *parent) : - ChartItem(parent) - ,mSeries(series) - ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready - ,mLayoutSet(false) - ,mLayoutDirty(true) -{ - dataChanged(); -} - - -void PercentBarGroup::setSize(const QSizeF& size) -{ -// qDebug() << "PercentBarGroup::setSize"; - mWidth = size.width(); - mHeight = size.height(); - layoutChanged(); - mLayoutSet = true; -} - -void PercentBarGroup::setPlotDomain(const PlotDomain& data) -{ - qDebug() << "PercentBarGroup::setPlotDomain"; - // TODO: -} -void PercentBarGroup::setBarWidth( int w ) -{ - mBarDefaultWidth = w; -} - -int PercentBarGroup::addColor( QColor color ) -{ - int colorIndex = mColors.count(); - mColors.append(color); - return colorIndex; -} - -void PercentBarGroup::resetColors() -{ - mColors.clear(); -} - -void PercentBarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - if (!mLayoutSet) { - qDebug() << "QBarChart::paint called without layout set. Aborting."; - return; - } - if (mLayoutDirty) { - // Layout or data has changed. Need to redraw. - foreach(QGraphicsItem* i, childItems()) { - i->paint(painter,option,widget); - } - mLayoutDirty = false; - } -} - -QRectF PercentBarGroup::boundingRect() const -{ - return QRectF(0,0,mWidth,mHeight); -} - - -void PercentBarGroup::dataChanged() +PercentBarGroup::PercentBarGroup(PercentBarChartSeries& series, QGraphicsItem *parent) : + BarGroupBase(series, parent) { - qDebug() << "QBarChart::dataChanged mSeries"; - - // Find out maximum and minimum of all series - mMax = mSeries.max(); - mMin = mSeries.min(); - - // Delete old bars - // Is this correct way to delete childItems? - foreach (QGraphicsItem* item, childItems()) { - delete item; - } - - // Create new graphic items for bars - int totalItems = mSeries.countTotalItems(); - for (int i=0; iset(text); - childItems().append(label); - } - - // TODO: if (autolayout) { layoutChanged() } or something - mLayoutDirty = true; } void PercentBarGroup::layoutChanged() @@ -146,6 +55,18 @@ void PercentBarGroup::layoutChanged() labelIndex++; xPos += xStep; } + + // Position separators + int separatorIndex = labelIndex; // Separators are after labels in childItems(). TODO: better way to store these? + xPos = xStep + xStep/2; // Initial position is between first and second group. ie one and half steps from left. + for (int s=0; s < mSeries.countColumns() - 1; s++) { + Separator* sep = reinterpret_cast (childItems().at(separatorIndex)); + sep->setPos(xPos,0); + sep->setSize(QSizeF(1,mHeight)); + xPos += xStep; + separatorIndex++; + } + mLayoutDirty = true; } diff --git a/src/barchart/percentbargroup.h b/src/barchart/percentbargroup.h index 1db1250..49fe312 100644 --- a/src/barchart/percentbargroup.h +++ b/src/barchart/percentbargroup.h @@ -4,52 +4,23 @@ #include "chartitem_p.h" #include "bar_p.h" #include "percentbarchartseries.h" +#include "bargroupbase.h" #include QTCOMMERCIALCHART_BEGIN_NAMESPACE -class PercentBarGroup : public ChartItem +class PercentBarGroup : public BarGroupBase { public: PercentBarGroup(PercentBarChartSeries& series, QGraphicsItem *parent = 0); -public: // From ChartItem - void setSize(const QSizeF &size); - void setPlotDomain(const PlotDomain& data); - -public: - // Layout "api" - void setPos(qreal x, qreal y); - void setBarWidth( int w ); // Default width for each bar - - int addColor( QColor color ); - void resetColors(); - - // From QGraphicsItem - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - QRectF boundingRect() const; - private: - void dataChanged(); // data of series has changed -> need to recalculate bar sizes void layoutChanged(); // layout has changed -> need to recalculate bar sizes private: // Data - PercentBarChartSeries& mSeries; - int mMin; // Min and max values of data. (updated when data is changed, used when drawing) - int mMax; - - int mHeight; // Layout spesific - int mWidth; - int mBarDefaultWidth; - - bool mLayoutSet; // True, if component has been laid out. - bool mLayoutDirty; - - QList mColors; // List of colors for series for now - }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/separator.cpp b/src/barchart/separator.cpp new file mode 100644 index 0000000..12a1885 --- /dev/null +++ b/src/barchart/separator.cpp @@ -0,0 +1,49 @@ +#include "separator_p.h" +#include +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +Separator::Separator(QGraphicsItem *parent) + : ChartItem(parent) +{ +} + +void Separator::setPos(qreal x, qreal y) +{ + mXpos = x; + mYpos = y; +} + +void Separator::setColor(QColor color) +{ + mColor = color; +} + +void Separator::setSize(const QSizeF &size) +{ + mWidth = size.width(); + mHeight = size.height(); +} + +void Separator::setPlotDomain(const PlotDomain& data) +{ + +} + +void Separator::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + qDebug() << "separator::paint" << boundingRect(); + QPen pen(mColor); + painter->setPen(pen); + painter->drawLine(mXpos,mYpos,mXpos,mHeight); +} + +QRectF Separator::boundingRect() const +{ + QRectF r(mXpos,mYpos,mWidth,mHeight); + return r; +} + + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/separator_p.h b/src/barchart/separator_p.h new file mode 100644 index 0000000..2a59775 --- /dev/null +++ b/src/barchart/separator_p.h @@ -0,0 +1,36 @@ +#ifndef SEPARATOR_H +#define SEPARATOR_H + +#include "chartitem_p.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +class Separator : public ChartItem +{ +public: + Separator(QGraphicsItem *parent = 0); + + void setPos(qreal x, qreal y); + void setColor(QColor color); + + // From ChartItem + void setSize(const QSizeF &size); + void setPlotDomain(const PlotDomain& data); + + // From QGraphicsItem + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + QRectF boundingRect() const; + +private: + + QColor mColor; + qreal mXpos; + qreal mYpos; + qreal mHeight; + qreal mWidth; + +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // SEPARATOR_H diff --git a/src/barchart/stackedbarchartseries.cpp b/src/barchart/stackedbarchartseries.cpp index 548ec1b..7a5d542 100644 --- a/src/barchart/stackedbarchartseries.cpp +++ b/src/barchart/stackedbarchartseries.cpp @@ -5,104 +5,10 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE StackedBarChartSeries::StackedBarChartSeries(QObject *parent) : - QChartSeries(parent) + BarChartSeriesBase(parent) { } -bool StackedBarChartSeries::setData(QAbstractItemModel* model) -{ - mModel = model; - return true; -} - -int StackedBarChartSeries::min() -{ - Q_ASSERT(mModel->rowCount() > 0); - Q_ASSERT(mModel->columnCount() > 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 rowCount(); i++) { - for(int j=0; jcolumnCount(); j++) { - int temp = mModel->data(mModel->index(i,j)).toInt(); - if (temp < min) { - min = temp; - } - } - } - return min; -} - -int StackedBarChartSeries::max() -{ - Q_ASSERT(mModel->rowCount() > 0); - Q_ASSERT(mModel->columnCount() > 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 rowCount(); i++) { - for(int j=0; jcolumnCount(); j++) { - int temp = mModel->data(mModel->index(i,j)).toInt(); - if (temp > max) { - max = temp; - } - } - } - return max; -} - -int StackedBarChartSeries::maxColumnSum() -{ - Q_ASSERT(mModel->rowCount() > 0); - Q_ASSERT(mModel->columnCount() > 0); - - int max = INT_MIN; - - for (int col=0; col columnCount(); col++) { - int sum = columnSum(col); - if (sum > max) { - max = sum; - } - } - return max; -} - -int StackedBarChartSeries::countRows() -{ - return mModel->rowCount(); -} - -int StackedBarChartSeries::countColumns() -{ - return mModel->columnCount(); -} - -int StackedBarChartSeries::countTotalItems() -{ - return mModel->rowCount() * mModel->columnCount(); -} - -int StackedBarChartSeries::valueAt(int row, int column) -{ - QModelIndex index = mModel->index(row,column); - return mModel->data(index).toInt(); -} - -int StackedBarChartSeries::columnSum(int column) -{ - int sum(0); - int count = mModel->rowCount(); - - for (int row = 0; row < count; row++) { - sum += mModel->data(mModel->index(row,column)).toInt(); - } - return sum; -} - #include "moc_stackedbarchartseries.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/stackedbarchartseries.h b/src/barchart/stackedbarchartseries.h index 2526851..b34d3b9 100644 --- a/src/barchart/stackedbarchartseries.h +++ b/src/barchart/stackedbarchartseries.h @@ -3,13 +3,13 @@ #include #include -#include "qchartseries.h" +#include "barchartseriesbase.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE class StackedBarGroup; -class QTCOMMERCIALCHART_EXPORT StackedBarChartSeries : public QChartSeries +class QTCOMMERCIALCHART_EXPORT StackedBarChartSeries : public BarChartSeriesBase { Q_OBJECT public: @@ -18,22 +18,6 @@ public: // from QChartSeries virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeStackedBar; } - // TODO: Better data model? - virtual bool setData(QAbstractItemModel* model); - - // 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 countRows(); - int countColumns(); - int countTotalItems(); - int valueAt(int row, int column); - -private: - int columnSum(int column); - public Q_SLOTS: private: diff --git a/src/barchart/stackedbargroup.cpp b/src/barchart/stackedbargroup.cpp index 8924f52..b330fa7 100644 --- a/src/barchart/stackedbargroup.cpp +++ b/src/barchart/stackedbargroup.cpp @@ -1,130 +1,15 @@ #include "stackedbargroup.h" #include "bar_p.h" #include "barlabel_p.h" +#include "separator_p.h" #include #include QTCOMMERCIALCHART_BEGIN_NAMESPACE StackedBarGroup::StackedBarGroup(StackedBarChartSeries& series, QGraphicsItem *parent) : - ChartItem(parent) - ,mSeries(series) - ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready - ,mLayoutSet(false) - ,mLayoutDirty(true) - ,mTheme(0) - ,mSeparatorsVisible(true) + BarGroupBase(series,parent) { - dataChanged(); -} - -void StackedBarGroup::setSeparatorsVisible(bool visible) -{ - mSeparatorsVisible = visible; -} - -void StackedBarGroup::setSize(const QSizeF& size) -{ - mWidth = size.width(); - mHeight = size.height(); - layoutChanged(); - mLayoutSet = true; -} - -void StackedBarGroup::setPlotDomain(const PlotDomain& data) -{ - qDebug() << "StackedBarGroup::setPlotDomain"; - // TODO: -} - -void StackedBarGroup::themeChanged(ChartTheme *theme) -{ - mTheme = theme; -} - -void StackedBarGroup::setBarWidth( int w ) -{ - mBarDefaultWidth = w; -} - -int StackedBarGroup::addColor( QColor color ) -{ - int colorIndex = mColors.count(); - mColors.append(color); - return colorIndex; -} - -void StackedBarGroup::resetColors() -{ - mColors.clear(); -} - -void StackedBarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - if (!mLayoutSet) { - qDebug() << "QBarChart::paint called without layout set. Aborting."; - return; - } - if (mLayoutDirty) { - // Layout or data has changed. Need to redraw. - foreach(QGraphicsItem* i, childItems()) { - i->paint(painter,option,widget); - } - if (mSeparatorsVisible) { - //TODO: own class for separators (graphicsitem), because they may have style etc later. - // this is just to see that the positions are calculated correctly. - QPen pen(QColor(0,0,255,255)); - painter->setPen(pen); - for (int i=0; idrawLine(xp,0,xp,mHeight); - } - } -// mLayoutDirty = false; - } - -} - -QRectF StackedBarGroup::boundingRect() const -{ - return QRectF(0,0,mWidth,mHeight); -} - - -void StackedBarGroup::dataChanged() -{ - qDebug() << "QBarChart::dataChanged"; - - // Find out maximum and minimum of all series - mMax = mSeries.max(); - mMin = mSeries.min(); - - // Delete old bars - // Is this correct way to delete childItems? - foreach (QGraphicsItem* item, childItems()) { - delete item; - } - - // Create new graphic items for bars - int totalItems = mSeries.countTotalItems(); - for (int i=0; iset(text); - childItems().append(label); - } - - mSeparatorPositions.clear(); - - // TODO: if (autolayout) { layoutChanged() } or something - mLayoutDirty = true; } void StackedBarGroup::layoutChanged() @@ -178,12 +63,16 @@ void StackedBarGroup::layoutChanged() xPos += xStep; } + // Position separators - mSeparatorPositions.clear(); - xPos = xStep + xStep/2; // Initial position is between first and second group. ie one and half steps from left. + int separatorIndex = labelIndex; // Separators are after labels in childItems(). TODO: better way to store these? + xPos = xStep + xStep/2; // Initial position is between first and second group. ie one and half steps from left. for (int s=0; s < mSeries.countColumns() - 1; s++) { - mSeparatorPositions.append(xPos); + Separator* sep = reinterpret_cast (childItems().at(separatorIndex)); + sep->setPos(xPos,0); + sep->setSize(QSizeF(1,mHeight)); xPos += xStep; + separatorIndex++; } mLayoutDirty = true; diff --git a/src/barchart/stackedbargroup.h b/src/barchart/stackedbargroup.h index b3c860f..2a71810 100644 --- a/src/barchart/stackedbargroup.h +++ b/src/barchart/stackedbargroup.h @@ -1,67 +1,24 @@ #ifndef STACKEDBARGROUP_H #define STACKEDBARGROUP_H -#include "charttheme_p.h" -#include "chartitem_p.h" -#include "barlabel_p.h" -#include "bar_p.h" +#include "bargroupbase.h" #include "stackedbarchartseries.h" #include QTCOMMERCIALCHART_BEGIN_NAMESPACE -// TODO: derive this from ChartObjectInterface, when setSize is back in ChartItem -class StackedBarGroup : public ChartItem, public ChartThemeObserver +class StackedBarGroup : public BarGroupBase { public: StackedBarGroup(StackedBarChartSeries& series, QGraphicsItem *parent = 0); - // Bar chart spesific - void setSeparatorsVisible(bool visible = true); - -public: // From ChartItem - void setSize(const QSizeF &size); - void setPlotDomain(const PlotDomain& data); - - // From ChartThemeObserver - void themeChanged(ChartTheme *theme); - -public: // Layout "api" - void setPos(qreal x, qreal y); - void setBarWidth( int w ); // Default width for each bar - - int addColor( QColor color ); - void resetColors(); - - // From QGraphicsItem - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - QRectF boundingRect() const; - private: - - void dataChanged(); // data of series has changed -> need to recalculate bar sizes + // From BarGroupBase void layoutChanged(); // layout has changed -> need to recalculate bar sizes private: // Data - StackedBarChartSeries& mSeries; - int mMin; // Min and max values of data. (updated when data is changed, used when drawing) - int mMax; - - int mHeight; // Layout spesific - int mWidth; - int mBarDefaultWidth; - - bool mLayoutSet; // True, if component has been laid out. - bool mLayoutDirty; - - QList mColors; // List of colors for series for now - - ChartTheme* mTheme; - bool mSeparatorsVisible; - QList mSeparatorPositions; - }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/src.pro b/src/src.pro index f6e5061..e58ab42 100644 --- a/src/src.pro +++ b/src/src.pro @@ -32,12 +32,16 @@ SOURCES += \ qchartview.cpp \ qchartseries.cpp \ qchartaxis.cpp \ - charttheme.cpp + charttheme.cpp \ + barchart/separator.cpp \ + barchart/bargroupbase.cpp \ + barchart/barchartseriesbase.cpp PRIVATE_HEADERS += \ xylinechart/xylinechartitem_p.h \ barchart/barlabel_p.h \ barchart/bar_p.h \ + barchart/separator_p.h \ plotdomain_p.h \ qscatterseries_p.h \ qpieseries_p.h \ @@ -60,6 +64,8 @@ PUBLIC_HEADERS += \ barchart/stackedbargroup.h \ barchart/percentbarchartseries.h \ barchart/percentbargroup.h \ + barchart/barchartseriesbase.h \ + barchart/bargroupbase.h \ qchartview.h \ qchartaxis.h