From 494db513d752ba894f317e199f0063e13525e985 2012-05-15 13:33:28 From: sauimone Date: 2012-05-15 13:33:28 Subject: [PATCH] new series: groupedbarseries --- diff --git a/examples/barchart/main.cpp b/examples/barchart/main.cpp index a1013bb..3a24175 100644 --- a/examples/barchart/main.cpp +++ b/examples/barchart/main.cpp @@ -43,11 +43,11 @@ int main(int argc, char *argv[]) QBarSet *set3 = new QBarSet("Mary"); QBarSet *set4 = new QBarSet("Samantha"); - *set0 << 1 << 2 << 3 << 4 << 5 << 6; - *set1 << 5 << 0 << 0 << 4 << 0 << 7; - *set2 << 3 << 5 << 8 << 13 << 8 << 5; - *set3 << 5 << 6 << 7 << 3 << 4 << 5; - *set4 << 9 << 7 << 5 << 3 << 1 << 2; + *set0 << QPointF(0.0, 1) << QPointF(1.0, 2) << QPointF(2.0, 3) << QPointF(3.0, 4) << QPointF(4.0, 5) << QPointF(5.0, 6); + *set1 << QPointF(0.2, 2) << QPointF(1.2, 3) << QPointF(2.2, 4) << QPointF(3.2, 5) << QPointF(4.2, 6) << QPointF(5.2, 7); + *set2 << QPointF(0.4, 3) << QPointF(1.4, 4) << QPointF(2.4, 5) << QPointF(3.4, 6) << QPointF(4.4, 7) << QPointF(5.4, 8); + *set3 << QPointF(0.6, 4) << QPointF(1.6, 5) << QPointF(2.6, 6) << QPointF(3.6, 7) << QPointF(4.6, 8) << QPointF(5.6, 9); + *set4 << QPointF(0.8, 5) << QPointF(1.8, 6) << QPointF(2.8, 7) << QPointF(3.8, 8) << QPointF(4.8, 9) << QPointF(5.8, 10); //![2] //![3] @@ -58,6 +58,7 @@ int main(int argc, char *argv[]) series->appendBarSet(set2); series->appendBarSet(set3); series->appendBarSet(set4); + //![3] //![4] diff --git a/examples/examples.pro b/examples/examples.pro index 4a1f7d6..cacdadf 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -19,4 +19,5 @@ SUBDIRS += \ stackedbarchart \ stackedbarchartdrilldown \ zoomlinechart \ - modeldata + modeldata \ + groupedbarchart diff --git a/examples/groupedbarchart/groupedbarchart.pro b/examples/groupedbarchart/groupedbarchart.pro new file mode 100644 index 0000000..463f173 --- /dev/null +++ b/examples/groupedbarchart/groupedbarchart.pro @@ -0,0 +1,8 @@ +!include( ../examples.pri ) { + error( "Couldn't find the examples.pri file!" ) +} + +TARGET = groupedbarchart +SOURCES += main.cpp + +!system_build:mac: QMAKE_POST_LINK += "$$MAC_POST_LINK_PREFIX $$MAC_EXAMPLES_BIN_DIR" diff --git a/examples/groupedbarchart/main.cpp b/examples/groupedbarchart/main.cpp new file mode 100644 index 0000000..9f4fcbd --- /dev/null +++ b/examples/groupedbarchart/main.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** 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 +#include +#include +#include +#include +#include + +QTCOMMERCIALCHART_USE_NAMESPACE + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + +//![1] + QBarCategories categories; + categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun"; +//![1] + +//![2] + QBarSet *set0 = new QBarSet("Jane"); + QBarSet *set1 = new QBarSet("John"); + QBarSet *set2 = new QBarSet("Axel"); + QBarSet *set3 = new QBarSet("Mary"); + QBarSet *set4 = new QBarSet("Samantha"); + + *set0 << 1 << 2 << 3 << 4 << 5 << 6; + *set1 << 5 << 0 << 0 << 4 << 0 << 7; + *set2 << 3 << 5 << 8 << 13 << 8 << 5; + *set3 << 5 << 6 << 7 << 3 << 4 << 5; + *set4 << 9 << 7 << 5 << 3 << 1 << 2; +//![2] + +//![3] + QGroupedBarSeries* series = new QGroupedBarSeries(); + series->setCategories(categories); + series->appendBarSet(set0); + series->appendBarSet(set1); + series->appendBarSet(set2); + series->appendBarSet(set3); + series->appendBarSet(set4); + +//![3] + +//![4] + QChart* chart = new QChart(); + chart->addSeries(series); + chart->setTitle("Simple grouped barchart example"); +//![4] + +//![5] + chart->legend()->setVisible(true); + chart->legend()->setAlignment(QLegend::AlignmentBottom); + chart->axisY()->setNiceNumbersEnabled(true); +//![5] + +//![6] + QChartView* chartView = new QChartView(chart); + chartView->setRenderHint(QPainter::Antialiasing); +//![6] + +//![7] + QMainWindow window; + window.setCentralWidget(chartView); + window.resize(400, 300); + window.show(); +//![7] + + return a.exec(); +} diff --git a/src/barchart/barchart.pri b/src/barchart/barchart.pri index 34619ad..0fc09ba 100644 --- a/src/barchart/barchart.pri +++ b/src/barchart/barchart.pri @@ -5,27 +5,32 @@ SOURCES += \ $$PWD/bar.cpp \ $$PWD/barchartitem.cpp \ $$PWD/percentbarchartitem.cpp \ + $$PWD/groupedbarchartitem.cpp \ $$PWD/qbarseries.cpp \ $$PWD/qbarset.cpp \ $$PWD/qpercentbarseries.cpp \ $$PWD/qstackedbarseries.cpp \ + $$PWD/qgroupedbarseries.cpp \ $$PWD/stackedbarchartitem.cpp \ - $$PWD/barlabel.cpp + $$PWD/barlabel.cpp \ PRIVATE_HEADERS += \ $$PWD/bar_p.h \ $$PWD/barchartitem_p.h \ $$PWD/percentbarchartitem_p.h \ $$PWD/stackedbarchartitem_p.h \ + $$PWD/groupedbarchartitem_p.h \ $$PWD/barlabel_p.h \ $$PWD/qbarset_p.h \ $$PWD/qbarseries_p.h \ $$PWD/qstackedbarseries_p.h\ - $$PWD/qpercentbarseries_p.h + $$PWD/qpercentbarseries_p.h \ + $$PWD/qgroupedbarseries_p.h \ PUBLIC_HEADERS += \ $$PWD/qbarseries.h \ $$PWD/qbarset.h \ $$PWD/qpercentbarseries.h \ - $$PWD/qstackedbarseries.h + $$PWD/qstackedbarseries.h \ + $$PWD/qgroupedbarseries.h diff --git a/src/barchart/barchartitem.cpp b/src/barchart/barchartitem.cpp index d442541..25d53c9 100644 --- a/src/barchart/barchartitem.cpp +++ b/src/barchart/barchartitem.cpp @@ -111,30 +111,32 @@ QVector BarChartItem::calculateLayout() // Domain: qreal width = geometry().width(); qreal height = geometry().height(); - qreal range = m_domainMaxY - m_domainMinY; - qreal scale = (height / range); + qreal rangeY = m_domainMaxY - m_domainMinY; + qreal rangeX = m_domainMaxX - m_domainMinX; + qreal scaleY = (height / rangeY); + qreal scaleX = (width / rangeX); qreal categoryWidth = width / categoryCount; - qreal barWidth = categoryWidth / (setCount+1); + qreal barWidth = categoryWidth - categoryWidth * m_series->d_func()->barMargin(); int itemIndex(0); for (int category = 0; category < categoryCount; category++) { - qreal xPos = categoryWidth * category + barWidth / 2 + geometry().topLeft().x(); - qreal yPos = height + scale * m_domainMinY + geometry().topLeft().y(); + qreal yPos = height + scaleY * m_domainMinY + geometry().topLeft().y(); for (int set = 0; set < setCount; set++) { QBarSet* barSet = m_series->d_func()->barsetAt(set); + qreal xPos = (barSet->at(category).x() - m_domainMinX) * scaleX + m_rect.left() - barWidth/2; + qreal barHeight = barSet->at(category).y() * scaleY; - qreal barHeight = barSet->at(category) * scale; Bar* bar = m_bars.at(itemIndex); - QRectF rect(xPos, yPos - barHeight, barWidth, barHeight); + layout.append(rect); bar->setPen(barSet->pen()); bar->setBrush(barSet->brush()); BarLabel* label = m_labels.at(itemIndex); - if (!qFuzzyIsNull(barSet->at(category))) { - label->setText(QString::number(barSet->at(category))); + if (!qFuzzyIsNull(barSet->at(category).y())) { + label->setText(QString::number(barSet->at(category).y())); } else { label->setText(QString("")); } @@ -144,9 +146,9 @@ QVector BarChartItem::calculateLayout() label->setFont(barSet->labelFont()); itemIndex++; - xPos += barWidth; } } + return layout; } diff --git a/src/barchart/groupedbarchartitem.cpp b/src/barchart/groupedbarchartitem.cpp new file mode 100644 index 0000000..9cb0b08 --- /dev/null +++ b/src/barchart/groupedbarchartitem.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** 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 "groupedbarchartitem_p.h" +#include "bar_p.h" +#include "barlabel_p.h" +#include "qbarset_p.h" +#include "qbarseries_p.h" +#include "qbarset.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +GroupedBarChartItem::GroupedBarChartItem(QBarSeries *series, ChartPresenter *presenter) : + BarChartItem(series, presenter) +{ +} + +QVector GroupedBarChartItem::calculateLayout() +{ + QVector layout; + + // Use temporary qreals for accurancy + qreal categoryCount = m_series->categoryCount(); + qreal setCount = m_series->barsetCount(); + + // Domain: + qreal width = geometry().width(); + qreal height = geometry().height(); + qreal range = m_domainMaxY - m_domainMinY; + qreal scale = (height / range); + qreal categoryWidth = width / categoryCount; + qreal barWidth = categoryWidth / (setCount+1); + + int itemIndex(0); + for (int category = 0; category < categoryCount; category++) { + qreal xPos = categoryWidth * category + barWidth / 2 + geometry().topLeft().x(); + qreal yPos = height + scale * m_domainMinY + geometry().topLeft().y(); + for (int set = 0; set < setCount; set++) { + QBarSet* barSet = m_series->d_func()->barsetAt(set); + + qreal barHeight = barSet->at(category).y() * scale; + Bar* bar = m_bars.at(itemIndex); + + QRectF rect(xPos, yPos - barHeight, barWidth, barHeight); + layout.append(rect); + bar->setPen(barSet->pen()); + bar->setBrush(barSet->brush()); + + BarLabel* label = m_labels.at(itemIndex); + + if (!qFuzzyIsNull(barSet->at(category).y())) { + label->setText(QString::number(barSet->at(category).y())); + } else { + label->setText(QString("")); + } + + label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2) + ,yPos - barHeight/2 - label->boundingRect().height()/2); + label->setFont(barSet->labelFont()); + + itemIndex++; + xPos += barWidth; + } + } + return layout; +} + +#include "moc_groupedbarchartitem_p.cpp" + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/groupedbarchartitem_p.h b/src/barchart/groupedbarchartitem_p.h new file mode 100644 index 0000000..7f920d8 --- /dev/null +++ b/src/barchart/groupedbarchartitem_p.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** 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 GROUPEDBARCHARTITEM_H +#define GROUPEDBARCHARTITEM_H + +#include "barchartitem_p.h" +#include "qstackedbarseries.h" +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +class GroupedBarChartItem : public BarChartItem +{ + Q_OBJECT +public: + GroupedBarChartItem(QBarSeries *series, ChartPresenter *presenter); + +private: + // From BarChartItem + virtual QVector calculateLayout(); + +private: + + // Data +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // GROUPEDBARCHARTITEM_H diff --git a/src/barchart/percentbarchartitem.cpp b/src/barchart/percentbarchartitem.cpp index 3b3061c..2bb360a 100644 --- a/src/barchart/percentbarchartitem.cpp +++ b/src/barchart/percentbarchartitem.cpp @@ -55,7 +55,7 @@ QVector PercentBarChartItem::calculateLayout() qreal yPos = height + domainScale * m_domainMinY + geometry().topLeft().y(); for (int set=0; set < m_series->barsetCount(); set++) { QBarSet* barSet = m_series->d_func()->barsetAt(set); - qreal barHeight = barSet->at(category) * percentage * domainScale; + qreal barHeight = barSet->at(category).y() * percentage * domainScale; Bar* bar = m_bars.at(itemIndex); bar->setPen(barSet->pen()); bar->setBrush(barSet->brush()); diff --git a/src/barchart/qbarseries.cpp b/src/barchart/qbarseries.cpp index 4a67b5e..c78e37e 100644 --- a/src/barchart/qbarseries.cpp +++ b/src/barchart/qbarseries.cpp @@ -260,9 +260,9 @@ void QBarSeries::setLabelsVisible(bool visible) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -QBarSeriesPrivate::QBarSeriesPrivate(/*QBarCategories categories,*/ QBarSeries *q) : +QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) : QAbstractSeriesPrivate(q), -// m_categories(categories), + m_barMargin(0.05), // Default value is 5% of category width m_mapCategories(-1), m_mapBarBottom(-1), m_mapBarTop(-1) @@ -274,6 +274,22 @@ void QBarSeriesPrivate::setCategories(QBarCategories categories) m_categories = categories; } +void QBarSeriesPrivate::setBarMargin(qreal margin) +{ + if (margin > 1.0) { + margin = 1.0; + } else if (margin < 0.0) { + margin = 0.0; + } + + m_barMargin = margin; + emit updatedBars(); +} + +qreal QBarSeriesPrivate::barMargin() +{ + return m_barMargin; +} QBarSet* QBarSeriesPrivate::barsetAt(int index) { @@ -295,7 +311,7 @@ qreal QBarSeriesPrivate::min() for (int i = 0; i < m_barSets.count(); i++) { int categoryCount = m_barSets.at(i)->count(); for (int j = 0; j < categoryCount; j++) { - qreal temp = m_barSets.at(i)->at(j); + qreal temp = m_barSets.at(i)->at(j).y(); if (temp < min) min = temp; } @@ -313,7 +329,7 @@ qreal QBarSeriesPrivate::max() for (int i = 0; i < m_barSets.count(); i++) { int categoryCount = m_barSets.at(i)->count(); for (int j = 0; j < categoryCount; j++) { - qreal temp = m_barSets.at(i)->at(j); + qreal temp = m_barSets.at(i)->at(j).y(); if (temp > max) max = temp; } @@ -332,7 +348,7 @@ qreal QBarSeriesPrivate::valueAt(int set, int category) return 0; } - return m_barSets.at(set)->at(category); + return m_barSets.at(set)->at(category).y(); } qreal QBarSeriesPrivate::percentageAt(int set, int category) @@ -345,7 +361,7 @@ qreal QBarSeriesPrivate::percentageAt(int set, int category) return 0; } - qreal value = m_barSets.at(set)->at(category); + qreal value = m_barSets.at(set)->at(category).y(); qreal sum = categorySum(category); if ( qFuzzyIsNull(sum) ) { return 0; @@ -360,7 +376,7 @@ qreal QBarSeriesPrivate::categorySum(int category) int count = m_barSets.count(); // Count sets for (int set = 0; set < count; set++) { if (category < m_barSets.at(set)->count()) - sum += m_barSets.at(set)->at(category); + sum += m_barSets.at(set)->at(category).y(); } return sum; } @@ -371,7 +387,7 @@ qreal QBarSeriesPrivate::absoluteCategorySum(int category) int count = m_barSets.count(); // Count sets for (int set = 0; set < count; set++) { if (category < m_barSets.at(set)->count()) - sum += qAbs(m_barSets.at(set)->at(category)); + sum += qAbs(m_barSets.at(set)->at(category).y()); } return sum; } diff --git a/src/barchart/qbarseries.h b/src/barchart/qbarseries.h index ec9b408..347a328 100644 --- a/src/barchart/qbarseries.h +++ b/src/barchart/qbarseries.h @@ -39,7 +39,7 @@ class QTCOMMERCIALCHART_EXPORT QBarSeries : public QAbstractSeries { Q_OBJECT public: - explicit QBarSeries(/*QBarCategories categories,*/ QObject *parent = 0); + explicit QBarSeries(QObject *parent = 0); virtual ~QBarSeries(); QAbstractSeries::SeriesType type() const; @@ -55,9 +55,6 @@ public: QBarCategories categories() const; void setLabelsVisible(bool visible = true); -// TODO: -// void setGroupedDrawing(bool on = true); // By default this is on. Bars are grouped next to each other. If off, bars are drawn at their x-position (propably on top of each other) -// void setBarMargin(int margin); // Margin that is left between bars (if drawn as grouped bars) void setModel(QAbstractItemModel *model); // void setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation = Qt::Vertical); @@ -75,6 +72,7 @@ protected: friend class BarChartItem; friend class PercentBarChartItem; friend class StackedBarChartItem; + friend class GroupedBarChartItem; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/barchart/qbarseries_p.h b/src/barchart/qbarseries_p.h index ba311f6..a0dd270 100644 --- a/src/barchart/qbarseries_p.h +++ b/src/barchart/qbarseries_p.h @@ -15,8 +15,10 @@ class QBarSeriesPrivate : public QAbstractSeriesPrivate { Q_OBJECT public: - QBarSeriesPrivate(/*QBarCategories categories,*/ QBarSeries *parent); + QBarSeriesPrivate(QBarSeries *parent); void setCategories(QBarCategories categories); + void setBarMargin(qreal margin); + qreal barMargin(); void scaleDomain(Domain& domain); Chart* createGraphics(ChartPresenter* presenter); @@ -57,6 +59,7 @@ protected: QList m_barSets; QBarCategories m_categories; + qreal m_barMargin; int m_mapCategories; int m_mapBarBottom; int m_mapBarTop; diff --git a/src/barchart/qbarset.cpp b/src/barchart/qbarset.cpp index abf9b2b..7500cb0 100644 --- a/src/barchart/qbarset.cpp +++ b/src/barchart/qbarset.cpp @@ -84,12 +84,38 @@ QString QBarSet::name() const return d_ptr->m_name; } +void QBarSet::append(const QPointF value) +{ + d_ptr->m_values.append(value); + emit d_ptr->restructuredBars(); +} + + +void QBarSet::append(const QList values) +{ + for (int i=0; im_values.append(values.at(i)); + } + emit d_ptr->restructuredBars(); +} + /*! Appends new value \a value to the end of set. */ void QBarSet::append(const qreal value) { - d_ptr->m_values.append(value); + append(QPointF(d_ptr->m_values.count(), value)); +// d_ptr->m_values.append(value); +} + + +void QBarSet::append(const QList values) +{ + int index = d_ptr->m_values.count(); + for (int i=0; im_values.append(QPointF(index,values.at(i))); + index++; + } emit d_ptr->restructuredBars(); } @@ -102,6 +128,12 @@ QBarSet& QBarSet::operator << (const qreal &value) return *this; } +QBarSet& QBarSet::operator << (const QPointF &value) +{ + append(value); + return *this; +} + /*! Inserts new \a value on the \a index position. The value that is currently at this postion is moved to postion index + 1 @@ -109,7 +141,7 @@ QBarSet& QBarSet::operator << (const qreal &value) */ void QBarSet::insert(const int index, const qreal value) { - d_ptr->m_values.insert(index, value); + d_ptr->m_values.insert(index, QPointF(index, value)); // emit d_ptr->updatedBars(); } @@ -128,14 +160,14 @@ void QBarSet::remove(const int index) */ void QBarSet::replace(const int index, const qreal value) { - d_ptr->m_values.replace(index,value); + d_ptr->m_values.replace(index,QPointF(index,value)); emit d_ptr->updatedBars(); } /*! - Returns value of set indexed by \a index + Returns value of set indexed by \a index. Note that all appended values are stored internally as QPointF */ -qreal QBarSet::at(const int index) const +QPointF QBarSet::at(const int index) const { if (index < 0 || index >= d_ptr->m_values.count()) return 0.0; @@ -146,7 +178,7 @@ qreal QBarSet::at(const int index) const /*! Returns value of set indexed by \a index */ -qreal QBarSet::operator [] (int index) const +QPointF QBarSet::operator [](const int index) const { return d_ptr->m_values.at(index); } @@ -166,7 +198,8 @@ qreal QBarSet::sum() const { qreal total(0); for (int i=0; i < d_ptr->m_values.count(); i++) { - total += d_ptr->m_values.at(i); + //total += d_ptr->m_values.at(i); + total += d_ptr->m_values.at(i).y(); } return total; } diff --git a/src/barchart/qbarset.h b/src/barchart/qbarset.h index 3f08fae..3235c08 100644 --- a/src/barchart/qbarset.h +++ b/src/barchart/qbarset.h @@ -41,23 +41,19 @@ public: void setName(const QString name); QString name() const; -// TODO: -// void append(const QPointF value); // Appends bar with x-value -// void append(const QList value); // Same with list + void append(const QPointF value); // Appends bar with x-value + void append(const QList values); // Same with list void append(const qreal value); // TODO: change so, that count becomes x-value + void append(const QList values); // Append list of values. Using index as x-value -// TODO: -// void append(const QList values); // Append list of values. Using index as x-value - - QBarSet& operator << (const qreal &value); // TODO: change implementations so, that count becomes x-value -// TODO: -// QBarSet& operator << (const QPointF &value); // Appends bar with x-value + QBarSet& operator << (const qreal &value); // TODO: change implementations so, that count becomes x-value + QBarSet& operator << (const QPointF &value); // Appends bar with x-value void insert(const int index, const qreal value); // TODO: internal reindexing (what happens, if there are points with real x values?) void remove(const int index); // TODO: internal reindexing (what happens, if there are points with real x values?) void replace(const int index, const qreal value); - qreal at(const int index) const; - qreal operator [] (int index) const; + QPointF at(const int index) const; + QPointF operator [] (const int index) const; int count() const; qreal sum() const; diff --git a/src/barchart/qbarset_p.h b/src/barchart/qbarset_p.h index ac738b8..a992436 100644 --- a/src/barchart/qbarset_p.h +++ b/src/barchart/qbarset_p.h @@ -23,8 +23,7 @@ Q_SIGNALS: public: QBarSet * const q_ptr; QString m_name; - QList m_values; // TODO: replace with map (category, value) - QMap m_mappedValues; + QList m_values; QPen m_pen; QBrush m_brush; QPen m_labelPen; diff --git a/src/barchart/qgroupedbarseries.cpp b/src/barchart/qgroupedbarseries.cpp new file mode 100644 index 0000000..ec0762b --- /dev/null +++ b/src/barchart/qgroupedbarseries.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** 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 "qgroupedbarseries.h" +#include "qgroupedbarseries_p.h" +#include "groupedbarchartitem_p.h" +#include "chartdataset_p.h" +#include "charttheme_p.h" +#include "chartanimator_p.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +/*! + \class QGroupedBarSeries + \brief part of QtCommercial chart API. + \mainclass + + QGroupedBarSeries represents a series of data shown as bars. All bars in same category are + grouped next to each other. One QGroupedBarSeries can contain multiple QBarSet data sets. + QGroupedBarSeries groups the data from sets to categories, which are defined by QStringList. + + See the \l {GroupedbarChart Example} {grouped bar chart example} to learn how to create a grouped bar chart. + \image examples_groupedbarchart.png + + \sa QBarSet, QPercentBarSeries, QBarSeries, QStackedBarSeries +*/ + +/*! + \fn virtual QSeriesType QGroupedBarSeries::type() const + \brief Returns type of series. + \sa QSeriesType +*/ + +/*! + Constructs empty QGroupedBarSeries. Parameter \a categories defines the categories for chart. + QGroupedBarSeries is QObject which is a child of a \a parent. +*/ +QGroupedBarSeries::QGroupedBarSeries(QObject *parent) + : QBarSeries(*new QGroupedBarSeriesPrivate(this), parent) +{ +} + +QAbstractSeries::SeriesType QGroupedBarSeries::type() const +{ + return QAbstractSeries::SeriesTypeGroupedBar; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QGroupedBarSeriesPrivate::QGroupedBarSeriesPrivate(/*QBarCategories categories,*/ QGroupedBarSeries *q) : QBarSeriesPrivate(/*categories,*/q) +{ + +} + +void QGroupedBarSeriesPrivate::scaleDomain(Domain& domain) +{ + qreal minX(domain.minX()); + qreal minY(domain.minY()); + qreal maxX(domain.maxX()); + qreal maxY(domain.maxY()); + int tickXCount(domain.tickXCount()); + int tickYCount(domain.tickYCount()); + + qreal x = m_categories.count(); + qreal y = maxCategorySum(); + minX = qMin(minX, x); + minY = qMin(minY, y); + maxX = qMax(maxX, x); + maxY = qMax(maxY, y); + tickXCount = x+1; + + domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount); +} + + +Chart* QGroupedBarSeriesPrivate::createGraphics(ChartPresenter* presenter) +{ + Q_Q(QGroupedBarSeries); + + GroupedBarChartItem* bar = new GroupedBarChartItem(q,presenter); + if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) { + presenter->animator()->addAnimation(bar); + } + presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q)); + return bar; +} + +#include "moc_qgroupedbarseries.cpp" + +QTCOMMERCIALCHART_END_NAMESPACE + diff --git a/src/barchart/qgroupedbarseries.h b/src/barchart/qgroupedbarseries.h new file mode 100644 index 0000000..c18e886 --- /dev/null +++ b/src/barchart/qgroupedbarseries.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** 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 GROUPEDBARSERIES_H +#define GROUPEDBARSERIES_H + +#include +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +class QGroupedBarSeriesPrivate; + +class QTCOMMERCIALCHART_EXPORT QGroupedBarSeries : public QBarSeries +{ + Q_OBJECT +public: + explicit QGroupedBarSeries(QObject *parent = 0); + QAbstractSeries::SeriesType type() const; + +private: + Q_DECLARE_PRIVATE(QGroupedBarSeries) + Q_DISABLE_COPY(QGroupedBarSeries) +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // GROUPEDBARSERIES_H diff --git a/src/barchart/qgroupedbarseries_p.h b/src/barchart/qgroupedbarseries_p.h new file mode 100644 index 0000000..796673c --- /dev/null +++ b/src/barchart/qgroupedbarseries_p.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +// W A R N I N G +// ------------- +// +// This file is not part of the QtCommercial Chart API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QGROUPEDBARSERIES_P_H +#define QGROUPEDBARSERIES_P_H + +#include "qbarseries_p.h" +#include "domain_p.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + + +class QGroupedBarSeriesPrivate: public QBarSeriesPrivate +{ +public: + QGroupedBarSeriesPrivate(QGroupedBarSeries* q); + Chart* createGraphics(ChartPresenter* presenter); + void scaleDomain(Domain& domain); + +private: + Q_DECLARE_PUBLIC(QGroupedBarSeries) +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // QGROUPEDBARSERIES_P_H diff --git a/src/barchart/stackedbarchartitem.cpp b/src/barchart/stackedbarchartitem.cpp index e4192ee..385cd96 100644 --- a/src/barchart/stackedbarchartitem.cpp +++ b/src/barchart/stackedbarchartitem.cpp @@ -53,7 +53,7 @@ QVector StackedBarChartItem::calculateLayout() for (int set=0; set < m_series->barsetCount(); set++) { QBarSet* barSet = m_series->d_func()->barsetAt(set); - qreal barHeight = barSet->at(category) * scale; + qreal barHeight = barSet->at(category).y() * scale; Bar* bar = m_bars.at(itemIndex); bar->setPen(barSet->pen()); bar->setBrush(barSet->brush()); @@ -62,8 +62,8 @@ QVector StackedBarChartItem::calculateLayout() BarLabel* label = m_labels.at(itemIndex); - if (!qFuzzyIsNull(barSet->at(category))) { - label->setText(QString::number(barSet->at(category))); + if (!qFuzzyIsNull(barSet->at(category).y())) { + label->setText(QString::number(barSet->at(category).y())); } else { label->setText(QString("")); } diff --git a/src/chartdataset.cpp b/src/chartdataset.cpp index 16ab992..707cc1e 100644 --- a/src/chartdataset.cpp +++ b/src/chartdataset.cpp @@ -88,7 +88,7 @@ void ChartDataSet::addSeries(QAbstractSeries* series, QAxis *axisY) series->d_ptr->scaleDomain(*domain); - if(series->type() == QAbstractSeries::SeriesTypeBar + if(series->type() == QAbstractSeries::SeriesTypeGroupedBar || series->type() == QAbstractSeries::SeriesTypeStackedBar || series->type() == QAbstractSeries::SeriesTypePercentBar) { QBarSeries* barSeries = static_cast(series); diff --git a/src/qabstractseries.h b/src/qabstractseries.h index 0b34cf8..ac1ecb4 100644 --- a/src/qabstractseries.h +++ b/src/qabstractseries.h @@ -46,6 +46,7 @@ public: SeriesTypeBar, SeriesTypeStackedBar, SeriesTypePercentBar, + SeriesTypeGroupedBar, SeriesTypePie, SeriesTypeScatter, SeriesTypeSpline diff --git a/test/auto/qbarset/tst_qbarset.cpp b/test/auto/qbarset/tst_qbarset.cpp index b254042..050b9a4 100644 --- a/test/auto/qbarset/tst_qbarset.cpp +++ b/test/auto/qbarset/tst_qbarset.cpp @@ -140,7 +140,7 @@ void tst_QBarSet::append() for (int i=0; iappend(value); - QCOMPARE(m_barset->at(i), value); + QCOMPARE(m_barset->at(i).y(), value); sum += value; value += 1.0; } @@ -166,7 +166,7 @@ void tst_QBarSet::appendOperator() for (int i=0; iat(i), value); + QCOMPARE(m_barset->at(i).y(), value); sum += value; value += 1.0; } @@ -185,20 +185,20 @@ void tst_QBarSet::insert() QVERIFY(qFuzzyIsNull(m_barset->sum())); m_barset->insert(0, 1.0); // 1.0 - QCOMPARE(m_barset->at(0), 1.0); + QCOMPARE(m_barset->at(0).y(), 1.0); QCOMPARE(m_barset->count(), 1); QVERIFY(qFuzzyCompare(m_barset->sum(), 1.0)); m_barset->insert(0, 2.0); // 2.0 1.0 - QCOMPARE(m_barset->at(0), 2.0); - QCOMPARE(m_barset->at(1), 1.0); + QCOMPARE(m_barset->at(0).y(), 2.0); + QCOMPARE(m_barset->at(1).y(), 1.0); QCOMPARE(m_barset->count(), 2); QVERIFY(qFuzzyCompare(m_barset->sum(), 3.0)); m_barset->insert(1, 3.0); // 2.0 3.0 1.0 - QCOMPARE(m_barset->at(1), 3.0); - QCOMPARE(m_barset->at(0), 2.0); - QCOMPARE(m_barset->at(2), 1.0); + QCOMPARE(m_barset->at(1).y(), 3.0); + QCOMPARE(m_barset->at(0).y(), 2.0); + QCOMPARE(m_barset->at(2).y(), 1.0); QCOMPARE(m_barset->count(), 3); QVERIFY(qFuzzyCompare(m_barset->sum(), 6.0)); } @@ -221,15 +221,15 @@ void tst_QBarSet::remove() QCOMPARE(m_barset->sum(), 10.0); m_barset->remove(2); // 1.0 2.0 4.0 - QCOMPARE(m_barset->at(0), 1.0); - QCOMPARE(m_barset->at(1), 2.0); - QCOMPARE(m_barset->at(2), 4.0); + QCOMPARE(m_barset->at(0).y(), 1.0); + QCOMPARE(m_barset->at(1).y(), 2.0); + QCOMPARE(m_barset->at(2).y(), 4.0); QCOMPARE(m_barset->count(), 3); QCOMPARE(m_barset->sum(), 7.0); m_barset->remove(0); // 2.0 4.0 - QCOMPARE(m_barset->at(0), 2.0); - QCOMPARE(m_barset->at(1), 4.0); + QCOMPARE(m_barset->at(0).y(), 2.0); + QCOMPARE(m_barset->at(1).y(), 4.0); QCOMPARE(m_barset->count(), 2); QCOMPARE(m_barset->sum(), 6.0); } @@ -255,15 +255,15 @@ void tst_QBarSet::replace() m_barset->replace(0, 5.0); // 5.0 2.0 3.0 4.0 QCOMPARE(m_barset->count(), 4); QCOMPARE(m_barset->sum(), 14.0); - QCOMPARE(m_barset->at(0), 5.0); + QCOMPARE(m_barset->at(0).y(), 5.0); m_barset->replace(3, 6.0); QCOMPARE(m_barset->count(), 4); // 5.0 2.0 3.0 6.0 QCOMPARE(m_barset->sum(), 16.0); - QCOMPARE(m_barset->at(0), 5.0); - QCOMPARE(m_barset->at(1), 2.0); - QCOMPARE(m_barset->at(2), 3.0); - QCOMPARE(m_barset->at(3), 6.0); + QCOMPARE(m_barset->at(0).y(), 5.0); + QCOMPARE(m_barset->at(1).y(), 2.0); + QCOMPARE(m_barset->at(2).y(), 3.0); + QCOMPARE(m_barset->at(3).y(), 6.0); } void tst_QBarSet::at_data() @@ -281,10 +281,10 @@ void tst_QBarSet::at() m_barset->append(3.0); m_barset->append(4.0); - QCOMPARE(m_barset->at(0), 1.0); - QCOMPARE(m_barset->at(1), 2.0); - QCOMPARE(m_barset->at(2), 3.0); - QCOMPARE(m_barset->at(3), 4.0); + QCOMPARE(m_barset->at(0).y(), 1.0); + QCOMPARE(m_barset->at(1).y(), 2.0); + QCOMPARE(m_barset->at(2).y(), 3.0); + QCOMPARE(m_barset->at(3).y(), 4.0); } void tst_QBarSet::atOperator_data() @@ -302,10 +302,10 @@ void tst_QBarSet::atOperator() m_barset->append(3.0); m_barset->append(4.0); - QCOMPARE(m_barset->operator [](0), 1.0); - QCOMPARE(m_barset->operator [](1), 2.0); - QCOMPARE(m_barset->operator [](2), 3.0); - QCOMPARE(m_barset->operator [](3), 4.0); + QCOMPARE(m_barset->operator [](0).y(), 1.0); + QCOMPARE(m_barset->operator [](1).y(), 2.0); + QCOMPARE(m_barset->operator [](2).y(), 3.0); + QCOMPARE(m_barset->operator [](3).y(), 4.0); } void tst_QBarSet::count_data()