diff --git a/src/barchart/barchartitem.cpp b/src/barchart/barchartitem.cpp index 919171e..b73da7b 100644 --- a/src/barchart/barchartitem.cpp +++ b/src/barchart/barchartitem.cpp @@ -41,7 +41,7 @@ BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) : { connect(series, SIGNAL(showToolTip(QPoint,QString)), this, SLOT(showToolTip(QPoint,QString))); connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged())); - connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int))); + connect(series, SIGNAL(restructuredBars()), this, SLOT(handleModelChanged())); setZValue(ChartPresenter::BarSeriesZValue); dataChanged(); } @@ -112,28 +112,22 @@ QVector BarChartItem::calculateLayout() { QVector layout; - // Use temporary qreals for accurancy (we might get some compiler warnings... :) + // 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 max = m_series->max(); - - // Domain: - if (m_domainMaxY > max) { - max = m_domainMaxY; - } - - qreal scale = (height / max); + 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; - qreal yPos = height; + qreal yPos = height + scale * m_domainMinY; for (int set = 0; set < setCount; set++) { QBarSet* barSet = m_series->barsetAt(set); @@ -209,6 +203,7 @@ void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal void BarChartItem::handleGeometryChanged(const QRectF &rect) { + prepareGeometryChange(); m_clipRect = rect.translated(-rect.topLeft()); m_rect = rect; handleLayoutChanged(); @@ -218,6 +213,10 @@ void BarChartItem::handleGeometryChanged(const QRectF &rect) void BarChartItem::handleLayoutChanged() { + if ((m_rect.width() <= 0) || (m_rect.height() <= 0)) { + // rect size zero. + return; + } QVector layout = calculateLayout(); applyLayout(layout); update(); diff --git a/src/barchart/barchartmodel.cpp b/src/barchart/barchartmodel.cpp index 9580b65..61f6716 100644 --- a/src/barchart/barchartmodel.cpp +++ b/src/barchart/barchartmodel.cpp @@ -152,7 +152,6 @@ qreal BarChartModel::percentageAt(int set, int category) const return value / total; } - qreal BarChartModel::categorySum(int category) const { qreal sum(0); @@ -165,6 +164,18 @@ qreal BarChartModel::categorySum(int category) const return sum; } +qreal BarChartModel::absoluteCategorySum(int category) const +{ + qreal sum(0); + int count = m_dataModel.count(); // Count sets + + for (int set = 0; set < count; set++) { + if (category < m_dataModel.at(set)->count()) + sum += qAbs(m_dataModel.at(set)->valueAt(category)); + } + return sum; +} + qreal BarChartModel::maxCategorySum() const { qreal max = INT_MIN; diff --git a/src/barchart/barchartmodel_p.h b/src/barchart/barchartmodel_p.h index 01ae848..c229d78 100644 --- a/src/barchart/barchartmodel_p.h +++ b/src/barchart/barchartmodel_p.h @@ -57,6 +57,7 @@ public: qreal percentageAt(int set, int category) const; qreal categorySum(int category) const; + qreal absoluteCategorySum(int category) const; qreal maxCategorySum() const; // returns maximum sum of sets in all categories. QString categoryName(int category); diff --git a/src/barchart/percentbarchartitem.cpp b/src/barchart/percentbarchartitem.cpp index fce1356..ad764ec 100644 --- a/src/barchart/percentbarchartitem.cpp +++ b/src/barchart/percentbarchartitem.cpp @@ -22,6 +22,7 @@ #include "bar_p.h" #include "barlabel_p.h" #include "qbarset.h" +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -43,14 +44,17 @@ QVector PercentBarChartItem::calculateLayout() qreal xStep = width / categoryCount; qreal xPos = xStep / 2 - barWidth / 2; + qreal range = m_domainMaxY - m_domainMinY; + qreal domainScale = (height / range); + int itemIndex(0); for (int category = 0; category < categoryCount; category++) { qreal colSum = m_series->categorySum(category); - qreal scale = (height / colSum); - qreal yPos = height; + qreal percentage = (100 / colSum); + qreal yPos = height + domainScale * m_domainMinY; for (int set=0; set < m_series->barsetCount(); set++) { QBarSet* barSet = m_series->barsetAt(set); - qreal barHeight = barSet->valueAt(category) * scale; + qreal barHeight = barSet->valueAt(category) * 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 8ff4614..236dfbe 100644 --- a/src/barchart/qbarseries.cpp +++ b/src/barchart/qbarseries.cpp @@ -75,7 +75,7 @@ void QBarSeries::appendBarSet(QBarSet *set) m_internalModel->appendBarSet(set); connect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons))); connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged())); - emit updatedBars(); + emit restructuredBars(); } /*! @@ -87,7 +87,36 @@ void QBarSeries::removeBarSet(QBarSet *set) { disconnect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons))); m_internalModel->removeBarSet(set); - emit updatedBars(); + emit restructuredBars(); +} + +/*! + Adds a list of barsets to series. Takes ownership of \a sets. + Connects the clicked(QString, Qt::MouseButtons) signals + of \a sets to this series +*/ +void QBarSeries::appendBarSets(QList sets) +{ + foreach (QBarSet* barset, sets) { + m_internalModel->appendBarSet(barset); + connect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons))); + connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged())); + } + emit restructuredBars(); +} + +/*! + Removes a list of barsets from series. Releases ownership of \a set. Doesnt delete \a sets. + Disconnects the clicked(QString, Qt::MouseButtons) signal + of \a sets from this series +*/ +void QBarSeries::removeBarSets(QList sets) +{ + foreach (QBarSet* barset, sets) { + disconnect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons))); + m_internalModel->removeBarSet(barset); + } + emit restructuredBars(); } void QBarSeries::insertBarSet(int i, QBarSet *set) @@ -220,6 +249,14 @@ qreal QBarSeries::categorySum(int category) } /*! + \internal \a category +*/ +qreal QBarSeries::absoluteCategorySum(int category) +{ + return m_internalModel->absoluteCategorySum(category); +} + +/*! \internal */ qreal QBarSeries::maxCategorySum() @@ -360,7 +397,7 @@ void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/) barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble()); } } - emit restructuredBar(1); + emit restructuredBars(); } void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end) @@ -373,7 +410,7 @@ void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end) { barsetAt(i)->removeValue(start - m_mapFirst); } - emit restructuredBar(1); + emit restructuredBars(); } void QBarSeries::barsetChanged() diff --git a/src/barchart/qbarseries.h b/src/barchart/qbarseries.h index 2b35535..cf4744a 100644 --- a/src/barchart/qbarseries.h +++ b/src/barchart/qbarseries.h @@ -41,8 +41,10 @@ public: virtual QSeriesType type() const { return QSeries::SeriesTypeBar; } - void appendBarSet(QBarSet *set); // Takes ownership of set + void appendBarSet(QBarSet *set); // Takes ownership of set void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set + void appendBarSets(QList sets); + void removeBarSets(QList sets); void insertBarSet(int i, QBarSet *set); void insertCategory(int i, QString category); void removeCategory(int i); @@ -69,6 +71,7 @@ public: qreal valueAt(int set, int category); qreal percentageAt(int set, int category); qreal categorySum(int category); + qreal absoluteCategorySum(int category); qreal maxCategorySum(); BarChartModel& model(); // <--- TO PIMPL @@ -78,7 +81,7 @@ Q_SIGNALS: // void updatedBars(); - void restructuredBar(int); + void restructuredBars(); // TODO: internal signals, these to private implementation. // TODO: TO PIMPL --->