summaryrefslogtreecommitdiffstats
path: root/src/charts/barchart
diff options
context:
space:
mode:
Diffstat (limited to 'src/charts/barchart')
-rw-r--r--src/charts/barchart/abstractbarchartitem.cpp268
-rw-r--r--src/charts/barchart/abstractbarchartitem_p.h96
-rw-r--r--src/charts/barchart/bar.cpp71
-rw-r--r--src/charts/barchart/bar_p.h66
-rw-r--r--src/charts/barchart/barchart.pri71
-rw-r--r--src/charts/barchart/horizontal/bar/horizontalbarchartitem.cpp94
-rw-r--r--src/charts/barchart/horizontal/bar/horizontalbarchartitem_p.h51
-rw-r--r--src/charts/barchart/horizontal/bar/qhorizontalbarseries.cpp126
-rw-r--r--src/charts/barchart/horizontal/bar/qhorizontalbarseries.h45
-rw-r--r--src/charts/barchart/horizontal/bar/qhorizontalbarseries_p.h50
-rw-r--r--src/charts/barchart/horizontal/percent/horizontalpercentbarchartitem.cpp140
-rw-r--r--src/charts/barchart/horizontal/percent/horizontalpercentbarchartitem_p.h52
-rw-r--r--src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries.cpp125
-rw-r--r--src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries.h45
-rw-r--r--src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries_p.h50
-rw-r--r--src/charts/barchart/horizontal/stacked/horizontalstackedbarchartitem.cpp107
-rw-r--r--src/charts/barchart/horizontal/stacked/horizontalstackedbarchartitem_p.h51
-rw-r--r--src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries.cpp121
-rw-r--r--src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries.h45
-rw-r--r--src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries_p.h50
-rw-r--r--src/charts/barchart/qabstractbarseries.cpp1030
-rw-r--r--src/charts/barchart/qabstractbarseries.h105
-rw-r--r--src/charts/barchart/qabstractbarseries_p.h118
-rw-r--r--src/charts/barchart/qbarmodelmapper.cpp561
-rw-r--r--src/charts/barchart/qbarmodelmapper.h69
-rw-r--r--src/charts/barchart/qbarmodelmapper_p.h96
-rw-r--r--src/charts/barchart/qbarset.cpp676
-rw-r--r--src/charts/barchart/qbarset.h120
-rw-r--r--src/charts/barchart/qbarset_p.h82
-rw-r--r--src/charts/barchart/qhbarmodelmapper.cpp258
-rw-r--r--src/charts/barchart/qhbarmodelmapper.h70
-rw-r--r--src/charts/barchart/qvbarmodelmapper.cpp258
-rw-r--r--src/charts/barchart/qvbarmodelmapper.h70
-rw-r--r--src/charts/barchart/vertical/bar/barchartitem.cpp125
-rw-r--r--src/charts/barchart/vertical/bar/barchartitem_p.h57
-rw-r--r--src/charts/barchart/vertical/bar/qbarseries.cpp125
-rw-r--r--src/charts/barchart/vertical/bar/qbarseries.h45
-rw-r--r--src/charts/barchart/vertical/bar/qbarseries_p.h52
-rw-r--r--src/charts/barchart/vertical/percent/percentbarchartitem.cpp171
-rw-r--r--src/charts/barchart/vertical/percent/percentbarchartitem_p.h59
-rw-r--r--src/charts/barchart/vertical/percent/qpercentbarseries.cpp126
-rw-r--r--src/charts/barchart/vertical/percent/qpercentbarseries.h46
-rw-r--r--src/charts/barchart/vertical/percent/qpercentbarseries_p.h51
-rw-r--r--src/charts/barchart/vertical/stacked/qstackedbarseries.cpp123
-rw-r--r--src/charts/barchart/vertical/stacked/qstackedbarseries.h46
-rw-r--r--src/charts/barchart/vertical/stacked/qstackedbarseries_p.h51
-rw-r--r--src/charts/barchart/vertical/stacked/stackedbarchartitem.cpp137
-rw-r--r--src/charts/barchart/vertical/stacked/stackedbarchartitem_p.h58
48 files changed, 6509 insertions, 0 deletions
diff --git a/src/charts/barchart/abstractbarchartitem.cpp b/src/charts/barchart/abstractbarchartitem.cpp
new file mode 100644
index 00000000..4cf8b366
--- /dev/null
+++ b/src/charts/barchart/abstractbarchartitem.cpp
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "abstractbarchartitem_p.h"
+#include "bar_p.h"
+#include "qbarset.h"
+#include "qbarset_p.h"
+#include "qabstractbarseries.h"
+#include "qabstractbarseries_p.h"
+#include "qchart.h"
+#include "chartpresenter_p.h"
+#include "charttheme_p.h"
+#include "baranimation_p.h"
+#include "chartdataset_p.h"
+#include <QPainter>
+#include <QTextDocument>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
+ ChartItem(series->d_func(),item),
+ m_animation(0),
+ m_series(series)
+{
+
+ setFlag(ItemClipsChildrenToShape);
+ connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutChanged()));
+ connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleUpdatedBars()));
+ connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
+ connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
+ connect(series, SIGNAL(visibleChanged()), this, SLOT(handleVisibleChanged()));
+ connect(series, SIGNAL(opacityChanged()), this, SLOT(handleOpacityChanged()));
+ connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(handleUpdatedBars()));
+ connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
+ connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
+ this, SLOT(handleLabelsPositionChanged()));
+ setZValue(ChartPresenter::BarSeriesZValue);
+ handleDataStructureChanged();
+ handleVisibleChanged();
+ handleUpdatedBars();
+}
+
+AbstractBarChartItem::~AbstractBarChartItem()
+{
+}
+
+void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(painter);
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+}
+
+QRectF AbstractBarChartItem::boundingRect() const
+{
+ return m_rect;
+}
+
+void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
+{
+ QSizeF size = geometry().size();
+ if (geometry().size().isValid()) {
+ if (m_animation) {
+ if (m_layout.count() == 0 || m_oldSize != size) {
+ initializeLayout();
+ m_oldSize = size;
+ }
+ m_animation->setup(m_layout, layout);
+ presenter()->startAnimation(m_animation);
+ } else {
+ setLayout(layout);
+ update();
+ }
+ }
+}
+
+void AbstractBarChartItem::setAnimation(BarAnimation *animation)
+{
+ m_animation = animation;
+}
+
+void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
+{
+ if (layout.count() != m_bars.count())
+ return;
+
+ m_layout = layout;
+
+ for (int i = 0; i < m_bars.count(); i++)
+ m_bars.at(i)->setRect(layout.at(i));
+
+ positionLabels();
+}
+//handlers
+
+void AbstractBarChartItem::handleDomainUpdated()
+{
+ m_domainMinX = domain()->minX();
+ m_domainMaxX = domain()->maxX();
+ m_domainMinY = domain()->minY();
+ m_domainMaxY = domain()->maxY();
+
+ QRectF rect(QPointF(0,0),domain()->size());
+
+ if(m_rect != rect){
+ prepareGeometryChange();
+ m_rect = rect;
+ }
+
+ handleLayoutChanged();
+}
+
+void AbstractBarChartItem::handleLayoutChanged()
+{
+ if ((m_rect.width() <= 0) || (m_rect.height() <= 0))
+ return; // rect size zero.
+ QVector<QRectF> layout = calculateLayout();
+ applyLayout(layout);
+ handleUpdatedBars();
+}
+
+void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
+{
+ foreach (QGraphicsTextItem *label, m_labels)
+ label->setVisible(visible);
+ update();
+}
+
+void AbstractBarChartItem::handleDataStructureChanged()
+{
+ foreach (QGraphicsItem *item, childItems())
+ delete item;
+
+ m_bars.clear();
+ m_labels.clear();
+ m_layout.clear();
+
+ // Create new graphic items for bars
+ for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
+ for (int s = 0; s < m_series->count(); s++) {
+ QBarSet *set = m_series->d_func()->barsetAt(s);
+
+ // Bars
+ Bar *bar = new Bar(set, c, this);
+ m_bars.append(bar);
+ connect(bar, SIGNAL(clicked(int,QBarSet*)), m_series, SIGNAL(clicked(int,QBarSet*)));
+ connect(bar, SIGNAL(hovered(bool,QBarSet*)), m_series, SIGNAL(hovered(bool,QBarSet*)));
+ connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), m_series, SIGNAL(hovered(bool, int, QBarSet*)));
+ connect(bar, SIGNAL(clicked(int,QBarSet*)), set, SIGNAL(clicked(int)));
+ connect(bar, SIGNAL(hovered(bool,QBarSet*)), set, SIGNAL(hovered(bool)));
+ connect(bar, SIGNAL(hovered(bool, int, QBarSet*)), set, SIGNAL(hovered(bool, int)));
+ // m_layout.append(QRectF(0, 0, 1, 1));
+
+ // Labels
+ QGraphicsTextItem *newLabel = new QGraphicsTextItem(this);
+ newLabel->document()->setDocumentMargin(ChartPresenter::textMargin());
+ m_labels.append(newLabel);
+ }
+ }
+
+ if(themeManager()) themeManager()->updateSeries(m_series);
+ handleLayoutChanged();
+ handleVisibleChanged();
+}
+
+void AbstractBarChartItem::handleVisibleChanged()
+{
+ bool visible = m_series->isVisible();
+ if (visible)
+ handleLabelsVisibleChanged(m_series->isLabelsVisible());
+ else
+ handleLabelsVisibleChanged(visible);
+
+ foreach (QGraphicsItem *bar, m_bars)
+ bar->setVisible(visible);
+}
+
+void AbstractBarChartItem::handleOpacityChanged()
+{
+ foreach (QGraphicsItem *item, childItems())
+ item->setOpacity(m_series->opacity());
+}
+
+void AbstractBarChartItem::handleUpdatedBars()
+{
+ if (!m_series->d_func()->blockBarUpdate()) {
+ // Handle changes in pen, brush, labels etc.
+ int categoryCount = m_series->d_func()->categoryCount();
+ int setCount = m_series->count();
+ int itemIndex(0);
+ static const QString valueTag(QLatin1String("@value"));
+
+ for (int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
+ Bar *bar = m_bars.at(itemIndex);
+ bar->setPen(barSet->m_pen);
+ bar->setBrush(barSet->m_brush);
+ bar->update();
+
+ QGraphicsTextItem *label = m_labels.at(itemIndex);
+ QString valueLabel;
+ if (presenter()) { // At startup presenter is not yet set, yet somehow update comes
+ if (m_series->labelsFormat().isEmpty()) {
+ valueLabel = presenter()->numberToString(barSet->value(category));
+ } else {
+ valueLabel = m_series->labelsFormat();
+ valueLabel.replace(valueTag,
+ presenter()->numberToString(barSet->value(category)));
+ }
+ }
+ label->setHtml(valueLabel);
+ label->setFont(barSet->m_labelFont);
+ label->setDefaultTextColor(barSet->m_labelBrush.color());
+ label->update();
+ itemIndex++;
+ }
+ }
+ }
+}
+
+void AbstractBarChartItem::handleLabelsPositionChanged()
+{
+ positionLabels();
+}
+
+void AbstractBarChartItem::positionLabels()
+{
+ for (int i = 0; i < m_layout.count(); i++) {
+ QGraphicsTextItem *label = m_labels.at(i);
+ qreal xPos = 0;
+ qreal yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
+
+ int offset = m_bars.at(i)->pen().width() / 2 + 2;
+ if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
+ xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
+ xPos = m_layout.at(i).right() - label->boundingRect().width() - offset;
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
+ xPos = m_layout.at(i).left() + offset;
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
+ xPos = m_layout.at(i).right() + offset;
+
+ label->setPos(xPos, yPos);
+ label->setZValue(zValue() + 1);
+ }
+}
+
+#include "moc_abstractbarchartitem_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/abstractbarchartitem_p.h b/src/charts/barchart/abstractbarchartitem_p.h
new file mode 100644
index 00000000..66551a62
--- /dev/null
+++ b/src/charts/barchart/abstractbarchartitem_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 ABSTRACTBARCHARTITEM_H
+#define ABSTRACTBARCHARTITEM_H
+
+#include "chartitem_p.h"
+#include "qabstractbarseries.h"
+#include <QPen>
+#include <QBrush>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class Bar;
+class QAxisCategories;
+class QChart;
+class BarAnimation;
+
+class AbstractBarChartItem : public ChartItem
+{
+ Q_OBJECT
+public:
+ AbstractBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item = 0);
+ virtual ~AbstractBarChartItem();
+
+public:
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ QRectF boundingRect() const;
+
+ virtual QVector<QRectF> calculateLayout() = 0;
+ virtual void initializeLayout() = 0;
+ virtual void applyLayout(const QVector<QRectF> &layout);
+ virtual void setAnimation(BarAnimation *animation);
+ void setLayout(const QVector<QRectF> &layout);
+ void updateLayout(const QVector<QRectF> &layout);
+ QRectF geometry() const { return m_rect;}
+
+public Q_SLOTS:
+ void handleDomainUpdated();
+ void handleLayoutChanged();
+ void handleLabelsVisibleChanged(bool visible);
+ void handleDataStructureChanged(); // structure of of series has changed, recreate graphic items
+ void handleVisibleChanged();
+ void handleOpacityChanged();
+ virtual void handleUpdatedBars();
+ void handleLabelsPositionChanged();
+ virtual void positionLabels();
+
+protected:
+
+ qreal m_domainMinX;
+ qreal m_domainMaxX;
+ qreal m_domainMinY;
+ qreal m_domainMaxY;
+
+ QRectF m_rect;
+ QVector<QRectF> m_layout;
+
+ BarAnimation *m_animation;
+
+ QAbstractBarSeries *m_series; // Not owned.
+ QList<Bar *> m_bars;
+ QList<QGraphicsTextItem *> m_labels;
+ QSizeF m_oldSize;
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // ABSTRACTBARCHARTITEM_H
diff --git a/src/charts/barchart/bar.cpp b/src/charts/barchart/bar.cpp
new file mode 100644
index 00000000..de6c442f
--- /dev/null
+++ b/src/charts/barchart/bar.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "bar_p.h"
+#include <QPainter>
+#include <QGraphicsSceneEvent>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+Bar::Bar(QBarSet *barset, int index, QGraphicsItem *parent) : QGraphicsRectItem(parent),
+ m_index(index),
+ m_barset(barset),
+ m_hovering(false)
+{
+ setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
+ setAcceptHoverEvents(true);
+}
+
+Bar::~Bar()
+{
+ // End hover event, if bar is deleted during it
+ if (m_hovering) {
+ emit hovered(false, m_barset);
+ emit hovered(false, m_index, m_barset);
+ }
+}
+
+void Bar::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event)
+ emit clicked(m_index, m_barset);
+ QGraphicsItem::mousePressEvent(event);
+}
+
+void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event)
+ m_hovering = true;
+ emit hovered(true, m_barset);
+ emit hovered(true, m_index, m_barset);
+
+}
+
+void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event)
+ m_hovering = false;
+ emit hovered(false, m_barset);
+ emit hovered(false, m_index, m_barset);
+}
+
+#include "moc_bar_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/bar_p.h b/src/charts/barchart/bar_p.h
new file mode 100644
index 00000000..0d46e2b6
--- /dev/null
+++ b/src/charts/barchart/bar_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 BAR_H
+#define BAR_H
+
+#include "qchartglobal.h"
+#include <QGraphicsRectItem>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QBarSet;
+
+// Single visual bar item of chart
+class Bar : public QObject, public QGraphicsRectItem
+{
+ Q_OBJECT
+public:
+ Bar(QBarSet *barset, int index, QGraphicsItem *parent = 0);
+ ~Bar();
+
+public:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+ void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+
+Q_SIGNALS:
+ void clicked(int index, QBarSet *barset);
+ void hovered(bool status, QBarSet *barset);
+ void hovered(bool status, int index, QBarSet *barset);
+
+private:
+ int m_index;
+ QBarSet *m_barset;
+ bool m_hovering;
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // BAR_H
diff --git a/src/charts/barchart/barchart.pri b/src/charts/barchart/barchart.pri
new file mode 100644
index 00000000..0e78d232
--- /dev/null
+++ b/src/charts/barchart/barchart.pri
@@ -0,0 +1,71 @@
+#Subdirectiores are defined here, because qt creator doesn't handle nested include(foo.pri) chains very well.
+
+INCLUDEPATH += $$PWD \
+ $$PWD/vertical/bar \
+ $$PWD/vertical/stacked \
+ $$PWD/vertical/percent \
+ $$PWD/horizontal/bar \
+ $$PWD/horizontal/stacked \
+ $$PWD/horizontal/percent
+
+DEPENDPATH += $$PWD \
+ $$PWD/vertical/bar \
+ $$PWD/vertical/stacked \
+ $$PWD/vertical/percent \
+ $$PWD/horizontal/bar \
+ $$PWD/horizontal/stacked \
+ $$PWD/horizontal/percent
+
+SOURCES += \
+ $$PWD/bar.cpp \
+ $$PWD/abstractbarchartitem.cpp \
+ $$PWD/qabstractbarseries.cpp \
+ $$PWD/qbarset.cpp \
+ $$PWD/qbarmodelmapper.cpp \
+ $$PWD/qvbarmodelmapper.cpp \
+ $$PWD/qhbarmodelmapper.cpp \
+ $$PWD/vertical/bar/qbarseries.cpp \
+ $$PWD/vertical/bar/barchartitem.cpp \
+ $$PWD/vertical/stacked/qstackedbarseries.cpp \
+ $$PWD/vertical/stacked/stackedbarchartitem.cpp \
+ $$PWD/vertical/percent/qpercentbarseries.cpp \
+ $$PWD/vertical/percent/percentbarchartitem.cpp \
+ $$PWD/horizontal/bar/qhorizontalbarseries.cpp \
+ $$PWD/horizontal/bar/horizontalbarchartitem.cpp \
+ $$PWD/horizontal/stacked/qhorizontalstackedbarseries.cpp \
+ $$PWD/horizontal/stacked/horizontalstackedbarchartitem.cpp \
+ $$PWD/horizontal/percent/qhorizontalpercentbarseries.cpp \
+ $$PWD/horizontal/percent/horizontalpercentbarchartitem.cpp
+
+PRIVATE_HEADERS += \
+ $$PWD/bar_p.h \
+ $$PWD/qbarset_p.h \
+ $$PWD/abstractbarchartitem_p.h \
+ $$PWD/qabstractbarseries_p.h \
+ $$PWD/qbarmodelmapper_p.h \
+ $$PWD/vertical/bar/qbarseries_p.h \
+ $$PWD/vertical/bar/barchartitem_p.h \
+ $$PWD/vertical/stacked/qstackedbarseries_p.h \
+ $$PWD/vertical/stacked/stackedbarchartitem_p.h \
+ $$PWD/vertical/percent/qpercentbarseries_p.h \
+ $$PWD/vertical/percent/percentbarchartitem_p.h \
+ $$PWD/horizontal/bar/qhorizontalbarseries_p.h \
+ $$PWD/horizontal/bar/horizontalbarchartitem_p.h \
+ $$PWD/horizontal/stacked/qhorizontalstackedbarseries_p.h \
+ $$PWD/horizontal/stacked/horizontalstackedbarchartitem_p.h \
+ $$PWD/horizontal/percent/qhorizontalpercentbarseries_p.h \
+ $$PWD/horizontal/percent/horizontalpercentbarchartitem_p.h
+
+PUBLIC_HEADERS += \
+ $$PWD/qabstractbarseries.h \
+ $$PWD/qbarset.h \
+ $$PWD/qbarmodelmapper.h \
+ $$PWD/qvbarmodelmapper.h \
+ $$PWD/qhbarmodelmapper.h \
+ $$PWD/vertical/bar/qbarseries.h \
+ $$PWD/vertical/stacked/qstackedbarseries.h \
+ $$PWD/vertical/percent/qpercentbarseries.h \
+ $$PWD/horizontal/bar/qhorizontalbarseries.h \
+ $$PWD/horizontal/stacked/qhorizontalstackedbarseries.h \
+ $$PWD/horizontal/percent/qhorizontalpercentbarseries.h
+
diff --git a/src/charts/barchart/horizontal/bar/horizontalbarchartitem.cpp b/src/charts/barchart/horizontal/bar/horizontalbarchartitem.cpp
new file mode 100644
index 00000000..d5370a2f
--- /dev/null
+++ b/src/charts/barchart/horizontal/bar/horizontalbarchartitem.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "horizontalbarchartitem_p.h"
+#include "qabstractbarseries_p.h"
+#include "qbarset_p.h"
+#include "bar_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+HorizontalBarChartItem::HorizontalBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
+ : AbstractBarChartItem(series, item)
+{
+}
+
+void HorizontalBarChartItem::initializeLayout()
+{
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ m_layout.clear();
+ for(int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QRectF rect;
+ QPointF topLeft;
+ QPointF bottomRight;
+ if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
+ topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + set/setCount * barWidth), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
+ } else {
+ topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + set/setCount * barWidth), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
+ }
+
+ if (!m_validData)
+ return;
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ m_layout.append(rect.normalized());
+ }
+ }
+}
+
+QVector<QRectF> HorizontalBarChartItem::calculateLayout()
+{
+ QVector<QRectF> layout;
+
+ // Use temporary qreals for accuracy
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ for(int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ qreal value = m_series->barSets().at(set)->at(category);
+ QRectF rect;
+ QPointF topLeft;
+ if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
+ topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2 + set/setCount * barWidth), m_validData);
+ else
+ topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2 + set/setCount * barWidth), m_validData);
+
+ QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(value, category - barWidth / 2 + (set + 1)/setCount * barWidth), m_validData);
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ layout.append(rect.normalized());
+ }
+ }
+ return layout;
+}
+
+#include "moc_horizontalbarchartitem_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/horizontal/bar/horizontalbarchartitem_p.h b/src/charts/barchart/horizontal/bar/horizontalbarchartitem_p.h
new file mode 100644
index 00000000..df7e793e
--- /dev/null
+++ b/src/charts/barchart/horizontal/bar/horizontalbarchartitem_p.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 HORIZONTALBARCHARTITEM_H
+#define HORIZONTALBARCHARTITEM_H
+
+#include "abstractbarchartitem_p.h"
+#include <QGraphicsItem>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class HorizontalBarChartItem : public AbstractBarChartItem
+{
+ Q_OBJECT
+public:
+ HorizontalBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item = 0);
+
+private:
+ virtual QVector<QRectF> calculateLayout();
+ void initializeLayout();
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // HORIZONTALBARCHARTITEM_H
diff --git a/src/charts/barchart/horizontal/bar/qhorizontalbarseries.cpp b/src/charts/barchart/horizontal/bar/qhorizontalbarseries.cpp
new file mode 100644
index 00000000..d381aadf
--- /dev/null
+++ b/src/charts/barchart/horizontal/bar/qhorizontalbarseries.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qhorizontalbarseries.h"
+#include "qhorizontalbarseries_p.h"
+#include "horizontalbarchartitem_p.h"
+#include "qbarcategoryaxis.h"
+
+#include "chartdataset_p.h"
+#include "charttheme_p.h"
+
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QHorizontalBarSeries
+ \inmodule Qt Charts
+ \brief Series for creating horizontal bar chart.
+ \mainclass
+
+ QHorizontalBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
+ as groups, where bars in same category are grouped next to each other. QHorizontalBarSeries groups the data
+ from sets to categories, which are defined by a QStringList.
+
+ See the \l {HorizontalBarChart Example} {horizontal bar chart example} to learn how to create a horizontal bar chart.
+ \image examples_horizontalbarchart.png
+
+ \sa QBarSet, QBarSeries, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries, QHorizontalStackedBarSeries, QHorizontalPercentBarSeries
+*/
+/*!
+ \qmltype HorizontalBarSeries
+ \instantiates QHorizontalBarSeries
+ \inqmlmodule QtCharts
+
+ \inherits AbstractBarSeries
+
+ \brief Series type for creating horizontal bar chart.
+
+ The following QML shows how to create a simple horizontal bar chart:
+ \snippet qmlchart/qml/qmlchart/View9.qml 1
+ \beginfloatleft
+ \image examples_qmlchart9.png
+ \endfloat
+ \clearfloat
+*/
+
+/*!
+ Constructs empty QHorizontalBarSeries.
+ QHorizontalBarSeries is QObject which is a child of a \a parent.
+*/
+QHorizontalBarSeries::QHorizontalBarSeries(QObject *parent)
+ : QAbstractBarSeries(*new QHorizontalBarSeriesPrivate(this), parent)
+{
+}
+
+/*!
+ Destructor.
+ Removes series from chart.
+*/
+QHorizontalBarSeries::~QHorizontalBarSeries()
+{
+ Q_D(QHorizontalBarSeries);
+ if (d->m_chart)
+ d->m_chart->removeSeries(this);
+}
+
+/*!
+ Returns QChartSeries::SeriesTypeHorizontalBar.
+*/
+QAbstractSeries::SeriesType QHorizontalBarSeries::type() const
+{
+ return QAbstractSeries::SeriesTypeHorizontalBar;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QHorizontalBarSeriesPrivate::QHorizontalBarSeriesPrivate(QHorizontalBarSeries *q)
+ : QAbstractBarSeriesPrivate(q)
+{
+
+}
+
+void QHorizontalBarSeriesPrivate::initializeDomain()
+{
+ qreal minX(domain()->minX());
+ qreal minY(domain()->minY());
+ qreal maxX(domain()->maxX());
+ qreal maxY(domain()->maxY());
+
+ qreal y = categoryCount();
+ minX = qMin(minX, min());
+ minY = qMin(minY, - (qreal)0.5);
+ maxX = qMax(maxX, max());
+ maxY = qMax(maxY, y - (qreal)0.5);
+
+ domain()->setRange(minX, maxX, minY, maxY);
+}
+
+void QHorizontalBarSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
+{
+ Q_Q(QHorizontalBarSeries);
+ HorizontalBarChartItem *bar = new HorizontalBarChartItem(q,parent);
+ m_item.reset(bar);
+ QAbstractSeriesPrivate::initializeGraphics(parent);
+}
+
+#include "moc_qhorizontalbarseries.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/horizontal/bar/qhorizontalbarseries.h b/src/charts/barchart/horizontal/bar/qhorizontalbarseries.h
new file mode 100644
index 00000000..b5cf137b
--- /dev/null
+++ b/src/charts/barchart/horizontal/bar/qhorizontalbarseries.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QHORIZONTALBARSERIES_H
+#define QHORIZONTALBARSERIES_H
+
+#include <QtCharts/qabstractbarseries.h>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QHorizontalBarSeriesPrivate;
+
+class QT_CHARTS_EXPORT QHorizontalBarSeries : public QAbstractBarSeries
+{
+ Q_OBJECT
+public:
+ explicit QHorizontalBarSeries(QObject *parent = 0);
+ ~QHorizontalBarSeries();
+ QAbstractSeries::SeriesType type() const;
+
+private:
+ Q_DECLARE_PRIVATE(QHorizontalBarSeries)
+ Q_DISABLE_COPY(QHorizontalBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QHORIZONTALBARSERIES_H
diff --git a/src/charts/barchart/horizontal/bar/qhorizontalbarseries_p.h b/src/charts/barchart/horizontal/bar/qhorizontalbarseries_p.h
new file mode 100644
index 00000000..d32ed320
--- /dev/null
+++ b/src/charts/barchart/horizontal/bar/qhorizontalbarseries_p.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QHORIZONTALBARSERIES_P_H
+#define QHORIZONTALBARSERIES_P_H
+
+#include "qabstractbarseries_p.h"
+#include "abstractdomain_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QHorizontalBarSeriesPrivate: public QAbstractBarSeriesPrivate
+{
+public:
+ QHorizontalBarSeriesPrivate(QHorizontalBarSeries *q);
+ void initializeGraphics(QGraphicsItem* parent);
+ void initializeDomain();
+private:
+ Q_DECLARE_PUBLIC(QHorizontalBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QHORIZONTALBARSERIES_P_H
diff --git a/src/charts/barchart/horizontal/percent/horizontalpercentbarchartitem.cpp b/src/charts/barchart/horizontal/percent/horizontalpercentbarchartitem.cpp
new file mode 100644
index 00000000..0bf9afbe
--- /dev/null
+++ b/src/charts/barchart/horizontal/percent/horizontalpercentbarchartitem.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "horizontalpercentbarchartitem_p.h"
+#include "qabstractbarseries_p.h"
+#include "qbarset_p.h"
+#include "bar_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+HorizontalPercentBarChartItem::HorizontalPercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
+ : AbstractBarChartItem(series, item)
+{
+}
+
+void HorizontalPercentBarChartItem::initializeLayout()
+{
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ m_layout.clear();
+ for(int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QRectF rect;
+ QPointF topLeft;
+ QPointF bottomRight;
+ if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
+ topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
+ } else {
+ topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
+ }
+
+ if (!m_validData)
+ return;
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ m_layout.append(rect.normalized());
+ }
+ }
+}
+
+QVector<QRectF> HorizontalPercentBarChartItem::calculateLayout()
+{
+ QVector<QRectF> layout;
+
+ // Use temporary qreals for accuracy
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ for(int category = 0; category < categoryCount; category++) {
+ qreal sum = 0;
+ qreal categorySum = m_series->d_func()->categorySum(category);
+ for (int set = 0; set < setCount; set++) {
+ qreal value = m_series->barSets().at(set)->at(category);
+ QRectF rect;
+ qreal topX = 0;
+ if (sum > 0)
+ topX = 100 * sum / categorySum;
+ qreal bottomX = 0;
+ qreal newSum = value + sum;
+ if (newSum > 0)
+ bottomX = 100 * newSum / categorySum;
+ QPointF topLeft;
+ if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
+ topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : domain()->minX(), category - barWidth/2), m_validData);
+ else
+ topLeft = domain()->calculateGeometryPoint(QPointF(set ? topX : 0, category - barWidth/2), m_validData);
+ QPointF bottomRight = domain()->calculateGeometryPoint(QPointF(bottomX, category + barWidth/2), m_validData);
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ layout.append(rect.normalized());
+ sum = newSum;
+ }
+ }
+ return layout;
+}
+
+void HorizontalPercentBarChartItem::handleUpdatedBars()
+{
+ // Handle changes in pen, brush, labels etc.
+ int categoryCount = m_series->d_func()->categoryCount();
+ int setCount = m_series->count();
+ int itemIndex(0);
+ static const QString valueTag(QLatin1String("@value"));
+
+ for (int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
+ Bar *bar = m_bars.at(itemIndex);
+ bar->setPen(barSet->m_pen);
+ bar->setBrush(barSet->m_brush);
+ bar->update();
+
+ QGraphicsTextItem *label = m_labels.at(itemIndex);
+ qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
+ QString vString(presenter()->numberToString(p, 'f', 0));
+ QString valueLabel;
+ if (m_series->labelsFormat().isEmpty()) {
+ vString.append(QStringLiteral("%"));
+ valueLabel = vString;
+ } else {
+ valueLabel = m_series->labelsFormat();
+ valueLabel.replace(valueTag, vString);
+ }
+ label->setHtml(valueLabel);
+ label->setFont(barSet->m_labelFont);
+ label->setDefaultTextColor(barSet->m_labelBrush.color());
+ label->update();
+ itemIndex++;
+ }
+ }
+}
+
+#include "moc_horizontalpercentbarchartitem_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
+
diff --git a/src/charts/barchart/horizontal/percent/horizontalpercentbarchartitem_p.h b/src/charts/barchart/horizontal/percent/horizontalpercentbarchartitem_p.h
new file mode 100644
index 00000000..e24cdcf0
--- /dev/null
+++ b/src/charts/barchart/horizontal/percent/horizontalpercentbarchartitem_p.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 HORIZONTALPERCENTBARCHARTITEM_P_H
+#define HORIZONTALPERCENTBARCHARTITEM_P_H
+
+#include "abstractbarchartitem_p.h"
+#include <QGraphicsItem>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class HorizontalPercentBarChartItem : public AbstractBarChartItem
+{
+ Q_OBJECT
+public:
+ HorizontalPercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item = 0);
+ void handleUpdatedBars();
+
+private:
+ virtual QVector<QRectF> calculateLayout();
+ void initializeLayout();
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // HORIZONTALPERCENTBARCHARTITEM_P_H
diff --git a/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries.cpp b/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries.cpp
new file mode 100644
index 00000000..bf915c85
--- /dev/null
+++ b/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qhorizontalpercentbarseries.h"
+#include "qhorizontalpercentbarseries_p.h"
+#include "horizontalpercentbarchartitem_p.h"
+
+#include "chartdataset_p.h"
+#include "charttheme_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QHorizontalPercentBarSeries
+ \inmodule Qt Charts
+ \brief Series for creating horizontal percent bar chart.
+ \mainclass
+
+ QHorizontalPercentBarSeries represents a series of data shown as bars. The purpose of this
+ class is to draw bars as groups, where bars in same category are grouped next to each other.
+ QHorizontalPercentBarSeries groups the data from sets to categories, which are defined by a
+ QStringList. Bars with zero value are not drawn.
+
+ See the \l {HorizontalPercentBarChart Example} {horizontal percent bar chart example} to learn
+ how to create a horizontal percent bar chart.
+ \image examples_horizontalpercentbarchart.png
+
+ \sa QBarSet, QBarSeries, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries,
+ QHorizontalStackedBarSeries, QHorizontalBarSeries
+*/
+/*!
+ \qmltype HorizontalPercentBarSeries
+ \instantiates QHorizontalPercentBarSeries
+ \inqmlmodule QtCharts
+
+ \inherits AbstractBarSeries
+
+ \brief Series type for creating horizontal precent bar chart.
+
+ The following QML shows how to create a simple horizontal percent bar chart:
+ \snippet qmlchart/qml/qmlchart/View11.qml 1
+ \beginfloatleft
+ \image examples_qmlchart11.png
+ \endfloat
+ \clearfloat
+*/
+
+/*!
+ Constructs empty QHorizontalPercentBarSeries.
+ QHorizontalPercentBarSeries is QObject which is a child of a \a parent.
+*/
+QHorizontalPercentBarSeries::QHorizontalPercentBarSeries(QObject *parent) :
+ QAbstractBarSeries(*new QHorizontalPercentBarSeriesPrivate(this), parent)
+{
+}
+
+/*!
+ Returns QAbstractSeries::SeriesTypeHorizontalPercentBar.
+*/
+QAbstractSeries::SeriesType QHorizontalPercentBarSeries::type() const
+{
+ return QAbstractSeries::SeriesTypeHorizontalPercentBar;
+}
+
+/*!
+ Destructor.
+ Removes series from chart.
+*/
+QHorizontalPercentBarSeries::~QHorizontalPercentBarSeries()
+{
+ Q_D(QHorizontalPercentBarSeries);
+ if (d->m_chart)
+ d->m_chart->removeSeries(this);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QHorizontalPercentBarSeriesPrivate::QHorizontalPercentBarSeriesPrivate(QHorizontalPercentBarSeries *q) : QAbstractBarSeriesPrivate(q)
+{
+
+}
+
+void QHorizontalPercentBarSeriesPrivate::initializeDomain()
+{
+ qreal minX(domain()->minX());
+ qreal minY(domain()->minY());
+ qreal maxX(domain()->maxX());
+ qreal maxY(domain()->maxY());
+
+ qreal y = categoryCount();
+ minX = 0;
+ maxX = 100;
+ minY = qMin(minY, - (qreal)0.5);
+ maxY = qMax(maxY, y - (qreal)0.5);
+
+ domain()->setRange(minX, maxX, minY, maxY);
+}
+
+void QHorizontalPercentBarSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
+{
+ Q_Q(QHorizontalPercentBarSeries);
+ HorizontalPercentBarChartItem *bar = new HorizontalPercentBarChartItem(q,parent);
+ m_item.reset(bar);
+ QAbstractSeriesPrivate::initializeGraphics(parent);
+}
+
+#include "moc_qhorizontalpercentbarseries.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries.h b/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries.h
new file mode 100644
index 00000000..0595532b
--- /dev/null
+++ b/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QHORIZONTALPERCENTBARSERIES_H
+#define QHORIZONTALPERCENTBARSERIES_H
+
+#include <QtCharts/qabstractbarseries.h>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QHorizontalPercentBarSeriesPrivate;
+
+class QT_CHARTS_EXPORT QHorizontalPercentBarSeries : public QAbstractBarSeries
+{
+ Q_OBJECT
+public:
+ explicit QHorizontalPercentBarSeries(QObject *parent = 0);
+ ~QHorizontalPercentBarSeries();
+ QAbstractSeries::SeriesType type() const;
+
+private:
+ Q_DECLARE_PRIVATE(QHorizontalPercentBarSeries)
+ Q_DISABLE_COPY(QHorizontalPercentBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QHORIZONTALPERCENTBARSERIES_H
diff --git a/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries_p.h b/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries_p.h
new file mode 100644
index 00000000..079f97bb
--- /dev/null
+++ b/src/charts/barchart/horizontal/percent/qhorizontalpercentbarseries_p.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QHORIZONTALPERCENTBARSERIES_P_H
+#define QHORIZONTALPERCENTBARSERIES_P_H
+
+#include "qabstractbarseries_p.h"
+#include "abstractdomain_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QHorizontalPercentBarSeriesPrivate: public QAbstractBarSeriesPrivate
+{
+public:
+ QHorizontalPercentBarSeriesPrivate(QHorizontalPercentBarSeries *q);
+ void initializeGraphics(QGraphicsItem* parent);
+ void initializeDomain();
+private:
+ Q_DECLARE_PUBLIC(QHorizontalPercentBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QHORIZONTALPERCENTBARSERIES_P_H
diff --git a/src/charts/barchart/horizontal/stacked/horizontalstackedbarchartitem.cpp b/src/charts/barchart/horizontal/stacked/horizontalstackedbarchartitem.cpp
new file mode 100644
index 00000000..fe6f162d
--- /dev/null
+++ b/src/charts/barchart/horizontal/stacked/horizontalstackedbarchartitem.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "horizontalstackedbarchartitem_p.h"
+#include "qabstractbarseries_p.h"
+#include "qbarset_p.h"
+#include "bar_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+HorizontalStackedBarChartItem::HorizontalStackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item)
+ : AbstractBarChartItem(series, item)
+{
+}
+
+void HorizontalStackedBarChartItem::initializeLayout()
+{
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ m_layout.clear();
+ for(int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QRectF rect;
+ QPointF topLeft;
+ QPointF bottomRight;
+ if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
+ topLeft = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category - barWidth / 2), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(domain()->minX(), category + barWidth / 2), m_validData);
+ } else {
+ topLeft = domain()->calculateGeometryPoint(QPointF(0, category - barWidth / 2), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(0, category + barWidth / 2), m_validData);
+ }
+
+ if (!m_validData)
+ return;
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ m_layout.append(rect.normalized());
+ }
+ }
+}
+
+QVector<QRectF> HorizontalStackedBarChartItem::calculateLayout()
+{
+ QVector<QRectF> layout;
+
+ // Use temporary qreals for accuracy
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ for(int category = 0; category < categoryCount; category++) {
+ qreal positiveSum = 0;
+ qreal negativeSum = 0;
+ for (int set = 0; set < setCount; set++) {
+ qreal value = m_series->barSets().at(set)->at(category);
+ QRectF rect;
+ QPointF topLeft;
+ QPointF bottomRight;
+ if (value < 0) {
+ bottomRight = domain()->calculateGeometryPoint(QPointF(value + negativeSum, category - barWidth / 2), m_validData);
+ if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
+ topLeft = domain()->calculateGeometryPoint(QPointF(set ? negativeSum : domain()->minX(), category + barWidth / 2), m_validData);
+ else
+ topLeft = domain()->calculateGeometryPoint(QPointF(set ? negativeSum : 0, category + barWidth / 2), m_validData);
+ negativeSum += value;
+ } else {
+ bottomRight = domain()->calculateGeometryPoint(QPointF(value + positiveSum, category - barWidth / 2), m_validData);
+ if (domain()->type() == AbstractDomain::LogXYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
+ topLeft = domain()->calculateGeometryPoint(QPointF(set ? positiveSum : domain()->minX(), category + barWidth / 2), m_validData);
+ else
+ topLeft = domain()->calculateGeometryPoint(QPointF(set ? positiveSum : 0, category + barWidth / 2), m_validData);
+ positiveSum += value;
+ }
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ layout.append(rect.normalized());
+ }
+ }
+ return layout;
+}
+
+#include "moc_horizontalstackedbarchartitem_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
+
diff --git a/src/charts/barchart/horizontal/stacked/horizontalstackedbarchartitem_p.h b/src/charts/barchart/horizontal/stacked/horizontalstackedbarchartitem_p.h
new file mode 100644
index 00000000..930a53a5
--- /dev/null
+++ b/src/charts/barchart/horizontal/stacked/horizontalstackedbarchartitem_p.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 HORIZONTALSTACKEDBARCHARTITEM_P_H
+#define HORIZONTALSTACKEDBARCHARTITEM_P_H
+
+#include "abstractbarchartitem_p.h"
+#include <QGraphicsItem>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class HorizontalStackedBarChartItem : public AbstractBarChartItem
+{
+ Q_OBJECT
+public:
+ HorizontalStackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item = 0);
+
+private:
+ virtual QVector<QRectF> calculateLayout();
+ void initializeLayout();
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // HORIZONTALSTACKEDBARCHARTITEM_P_H
diff --git a/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries.cpp b/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries.cpp
new file mode 100644
index 00000000..32c553bf
--- /dev/null
+++ b/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qhorizontalstackedbarseries.h"
+#include "qhorizontalstackedbarseries_p.h"
+#include "horizontalstackedbarchartitem_p.h"
+
+#include "chartdataset_p.h"
+#include "charttheme_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+/*!
+ \class QHorizontalStackedBarSeries
+ \inmodule Qt Charts
+ \brief Series for creating horizontal stacked bar chart.
+ \mainclass
+
+ QHorizontalStackedBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
+ as groups, where bars in same category are grouped next to each other. QHorizontalStackedBarSeries groups the data
+ from sets to categories, which are defined by a QStringList.
+
+ See the \l {HorizontalStackedBarChart Example} {horizontal stacked bar chart example} to learn how to create a horizontal stacked bar chart.
+ \image examples_horizontalstackedbarchart.png
+
+ \sa QBarSet, QBarSeries, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries, QHorizontalPercentBarSeries, QHorizontalBarSeries
+*/
+/*!
+ \qmltype HorizontalStackedBarSeries
+ \instantiates QHorizontalStackedBarSeries
+ \inqmlmodule QtCharts
+
+ \inherits AbstractBarSeries
+
+ \brief Series type for creating horizontal stacked bar chart.
+
+ The following QML shows how to create a simple horizontal stacked bar chart:
+ \snippet qmlchart/qml/qmlchart/View10.qml 1
+ \beginfloatleft
+ \image examples_qmlchart10.png
+ \endfloat
+ \clearfloat
+*/
+
+/*!
+ Constructs empty QHorizontalStackedBarSeries.
+ QHorizontalStackedBarSeries is QObject which is a child of a \a parent.
+*/
+QHorizontalStackedBarSeries::QHorizontalStackedBarSeries(QObject *parent)
+ : QAbstractBarSeries(*new QHorizontalStackedBarSeriesPrivate(this), parent)
+{
+}
+
+/*!
+ Destructor.
+ Removes series from chart.
+*/
+QHorizontalStackedBarSeries::~QHorizontalStackedBarSeries()
+{
+ Q_D(QHorizontalStackedBarSeries);
+ if (d->m_chart)
+ d->m_chart->removeSeries(this);
+}
+
+/*!
+ Returns QAbstractSeries::SeriesTypeHorizontalStackedBar.
+*/
+QAbstractSeries::SeriesType QHorizontalStackedBarSeries::type() const
+{
+ return QAbstractSeries::SeriesTypeHorizontalStackedBar;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QHorizontalStackedBarSeriesPrivate::QHorizontalStackedBarSeriesPrivate(QHorizontalStackedBarSeries *q) : QAbstractBarSeriesPrivate(q)
+{
+
+}
+
+void QHorizontalStackedBarSeriesPrivate::initializeDomain()
+{
+ qreal minX(domain()->minX());
+ qreal minY(domain()->minY());
+ qreal maxX(domain()->maxX());
+ qreal maxY(domain()->maxY());
+
+ qreal y = categoryCount();
+ minX = qMin(minX, bottom());
+ minY = qMin(minY, - (qreal)0.5);
+ maxX = qMax(maxX, top());
+ maxY = qMax(maxY, y - (qreal)0.5);
+
+ domain()->setRange(minX, maxX, minY, maxY);
+}
+
+void QHorizontalStackedBarSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
+{
+ Q_Q(QHorizontalStackedBarSeries);
+ HorizontalStackedBarChartItem *bar = new HorizontalStackedBarChartItem(q,parent);
+ m_item.reset(bar);
+ QAbstractSeriesPrivate::initializeGraphics(parent);
+}
+
+#include "moc_qhorizontalstackedbarseries.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries.h b/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries.h
new file mode 100644
index 00000000..fbcf4011
--- /dev/null
+++ b/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QHORIZONTALSTACKEDBARSERIES_H
+#define QHORIZONTALSTACKEDBARSERIES_H
+
+#include <QtCharts/qabstractbarseries.h>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QHorizontalStackedBarSeriesPrivate;
+
+class QT_CHARTS_EXPORT QHorizontalStackedBarSeries : public QAbstractBarSeries
+{
+ Q_OBJECT
+public:
+ explicit QHorizontalStackedBarSeries(QObject *parent = 0);
+ ~QHorizontalStackedBarSeries();
+ QAbstractSeries::SeriesType type() const;
+
+private:
+ Q_DECLARE_PRIVATE(QHorizontalStackedBarSeries)
+ Q_DISABLE_COPY(QHorizontalStackedBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QHORIZONTALSTACKEDBARSERIES_H
diff --git a/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries_p.h b/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries_p.h
new file mode 100644
index 00000000..ab643ebd
--- /dev/null
+++ b/src/charts/barchart/horizontal/stacked/qhorizontalstackedbarseries_p.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QHORIZONTALSTACKEDBARSERIES_P_H
+#define QHORIZONTALSTACKEDBARSERIES_P_H
+
+#include "qabstractbarseries_p.h"
+#include "abstractdomain_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QHorizontalStackedBarSeriesPrivate: public QAbstractBarSeriesPrivate
+{
+public:
+ QHorizontalStackedBarSeriesPrivate(QHorizontalStackedBarSeries *q);
+ void initializeGraphics(QGraphicsItem* parent);
+ void initializeDomain();
+private:
+ Q_DECLARE_PUBLIC(QHorizontalStackedBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QHORIZONTALSTACKEDBARSERIES_P_H
diff --git a/src/charts/barchart/qabstractbarseries.cpp b/src/charts/barchart/qabstractbarseries.cpp
new file mode 100644
index 00000000..08345112
--- /dev/null
+++ b/src/charts/barchart/qabstractbarseries.cpp
@@ -0,0 +1,1030 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qabstractbarseries.h"
+#include "qabstractbarseries_p.h"
+#include "qbarset.h"
+#include "qbarset_p.h"
+#include "abstractdomain_p.h"
+#include "chartdataset_p.h"
+#include "charttheme_p.h"
+#include "qvalueaxis.h"
+#include "qbarcategoryaxis.h"
+#include "qbarlegendmarker.h"
+#include "baranimation_p.h"
+#include "abstractbarchartitem_p.h"
+#include "qchart_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QAbstractBarSeries
+ \inmodule Qt Charts
+ \brief Series for creating a bar chart.
+ \mainclass
+
+ QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
+ the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
+ and y-value is the height of the bar. The category names are ignored with this series and x-axis
+ shows the x-values.
+
+ See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
+ \image examples_barchart.png
+
+ \sa QBarSet, QStackedBarSeries, QPercentBarSeries
+*/
+/*!
+ \qmltype AbstractBarSeries
+ \instantiates QAbstractBarSeries
+ \inqmlmodule QtCharts
+
+ \inherits AbstractSeries
+
+ \brief Series type for creating a bar chart.
+
+ The following QML shows how to create a simple bar chart:
+ \snippet qmlchart/qml/qmlchart/View6.qml 1
+
+ \beginfloatleft
+ \image examples_qmlchart6.png
+ \endfloat
+ \clearfloat
+*/
+
+/*!
+ \qmlproperty AbstractAxis AbstractBarSeries::axisX
+ The x axis used for the series. If you leave both axisX and axisXTop undefined, a BarCategoriesAxis is created for
+ the series.
+ \sa axisXTop
+*/
+
+/*!
+ \qmlproperty AbstractAxis AbstractBarSeries::axisY
+ The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
+ the series.
+ \sa axisYRight
+*/
+
+/*!
+ \qmlproperty AbstractAxis AbstractBarSeries::axisXTop
+ The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
+ axisXTop, but not both.
+ \sa axisX
+*/
+
+/*!
+ \qmlproperty AbstractAxis AbstractBarSeries::axisYRight
+ The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
+ or axisYRight, but not both.
+ \sa axisY
+*/
+
+/*!
+ \property QAbstractBarSeries::barWidth
+ The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
+ is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
+ is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
+ Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
+ \sa QBarSeries
+*/
+/*!
+ \qmlproperty real AbstractBarSeries::barWidth
+ The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
+ is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
+ is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
+ Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
+*/
+
+/*!
+ \property QAbstractBarSeries::count
+ Holds the number of sets in series.
+*/
+/*!
+ \qmlproperty int AbstractBarSeries::count
+ Holds the number of sets in series.
+*/
+
+/*!
+ \property QAbstractBarSeries::labelsVisible
+ Defines the visibility of the labels in series
+*/
+/*!
+ \qmlproperty bool AbstractBarSeries::labelsVisible
+ Defines the visibility of the labels in series
+*/
+
+/*!
+ \property QAbstractBarSeries::labelsFormat
+ The \a format used for showing labels in series.
+
+ QAbstractBarSeries supports the following format tag:
+ \table
+ \row
+ \li @value \li The value of the bar
+ \endtable
+
+ For example, the following usage of the format tags would produce labels that show the value
+ followed by unit ('u'):
+ \code
+ series->setLabelsFormat("@value u");
+ \endcode
+
+ By default, the labels shows the value of the bar. For percent bar series '%' is added after
+ the value. The labels are shown on the plot area, labels on the edge of the plot area are cut.
+ If the bars are close to each other the labels may overlap.
+
+ \sa QAbstractBarSeries::labelsVisible, QAbstractBarSeries::labelsPosition
+*/
+/*!
+ \qmlproperty string AbstractBarSeries::labelsFormat
+ The format used for showing labels in series.
+
+ \sa QAbstractBarSeries::labelsFormat, labelsVisible, labelsPosition
+*/
+/*!
+ \fn void QAbstractBarSeries::labelsFormatChanged(const QString &format)
+ Signal is emitted when the \a format of data value labels is changed.
+*/
+/*!
+ \qmlsignal XYSeries::onLabelsFormatChanged(string format)
+ Signal is emitted when the \a format of data value labels is changed.
+*/
+
+/*!
+ \enum QAbstractBarSeries::LabelsPosition
+
+ This enum describes the position of the data value labels.
+
+ \value LabelsCenter Label is in the center of the bar.
+ \value LabelsInsideEnd Label is inside the bar at the high end of it.
+ \value LabelsInsideBase Label is inside the bar at the low end of it.
+ \value LabelsOutsideEnd Label is outside the bar at the high end of it.
+ */
+
+/*!
+ \property QAbstractBarSeries::labelsPosition
+ Defines the \a position of value labels.
+
+ \sa QAbstractBarSeries::labelsVisible, QAbstractBarSeries::labelsFormat
+*/
+/*!
+ \qmlproperty string AbstractBarSeries::labelsPosition
+ Defines the \a position of value labels.
+
+ \sa labelsVisible, labelsFormat
+*/
+/*!
+ \fn void QAbstractBarSeries::labelsPositionChanged(QAbstractBarSeries::LabelsPosition position)
+ Signal is emitted when the \a position of value labels is changed.
+*/
+/*!
+ \qmlsignal AbstractBarSeries::onLabelsPositionChanged(LabelsPosition position)
+ Signal is emitted when the \a position of value labels is changed.
+*/
+
+/*!
+ \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
+ The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
+ Clicked bar inside set is indexed by \a index
+*/
+/*!
+ \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
+ The signal is emitted if the user clicks with a mouse on top of BarSet.
+ Clicked bar inside set is indexed by \a index
+*/
+
+/*!
+ \fn void QAbstractBarSeries::hovered(bool status, QBarSet* barset)
+
+ The signal is emitted if mouse is hovered on top of series.
+ Parameter \a barset is the pointer of barset, where hover happened.
+ Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
+*/
+
+/*!
+ \fn void QAbstractBarSeries::hovered(bool status, int index, QBarSet* barset)
+
+ The signal is emitted if mouse is hovered on top of series.
+ Parameter \a barset is the pointer of barset, where hover happened.
+ Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
+ Hovered bar inside the set is indexed by \a index.
+*/
+/*!
+ \qmlsignal AbstractBarSeries::onHovered(bool status, int index, BarSet barset)
+
+ The signal is emitted if mouse is hovered on top of series.
+ Parameter \a barset is the pointer of barset, where hover happened.
+ Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
+ Hovered bar inside the set is indexed by \a index.
+*/
+
+/*!
+ \fn void QAbstractBarSeries::countChanged()
+ This signal is emitted when barset count has been changed, for example by append or remove.
+*/
+/*!
+ \qmlsignal AbstractBarSeries::onCountChanged()
+ This signal is emitted when barset count has been changed, for example by append or remove.
+*/
+
+/*!
+ \fn void QAbstractBarSeries::labelsVisibleChanged()
+ This signal is emitted when labels visibility have changed.
+ \sa isLabelsVisible(), setLabelsVisible()
+*/
+
+/*!
+ \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
+ This signal is emitted when \a sets have been added to the series.
+ \sa append(), insert()
+*/
+/*!
+ \qmlsignal AbstractBarSeries::onBarsetsAdded(BarSet barset)
+ Emitted when \a barset has been added to the series.
+*/
+
+/*!
+ \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
+ This signal is emitted when \a sets have been removed from the series.
+ \sa remove()
+*/
+/*!
+ \qmlsignal AbstractBarSeries::onBarsetsRemoved(BarSet barset)
+ Emitted when \a barset has been removed from the series.
+*/
+
+/*!
+ \qmlmethod BarSet AbstractBarSeries::at(int index)
+ Returns bar set at \a index. Returns null if the index is not valid.
+*/
+
+/*!
+ \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
+ Adds a new bar set with \a label and \a values to \a index. Values is a list of reals.
+ For example:
+ \code
+ myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
+ \endcode
+*/
+
+/*!
+ \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
+ Inserts a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
+ If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
+ appended.
+ \sa AbstractBarSeries::append()
+*/
+
+/*!
+ \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
+ Removes the barset from the series. Returns true if successful, false otherwise.
+*/
+
+/*!
+ \qmlmethod AbstractBarSeries::clear()
+ Removes all barsets from the series.
+*/
+
+/*!
+ Destructs abstractbarseries and owned barsets.
+*/
+QAbstractBarSeries::~QAbstractBarSeries()
+{
+
+}
+
+/*!
+ \internal
+*/
+QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &o, QObject *parent)
+ : QAbstractSeries(o, parent)
+{
+ Q_D(QAbstractSeries);
+ QObject::connect(this, SIGNAL(countChanged()), d, SIGNAL(countChanged()));
+}
+
+/*!
+ Sets the width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
+ is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
+ is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
+ Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
+*/
+void QAbstractBarSeries::setBarWidth(qreal width)
+{
+ Q_D(QAbstractBarSeries);
+ d->setBarWidth(width);
+}
+
+/*!
+ Returns the width of the bars of the series.
+ \sa setBarWidth()
+*/
+qreal QAbstractBarSeries::barWidth() const
+{
+ Q_D(const QAbstractBarSeries);
+ return d->barWidth();
+}
+
+/*!
+ Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
+ Returns true, if appending succeeded.
+*/
+bool QAbstractBarSeries::append(QBarSet *set)
+{
+ Q_D(QAbstractBarSeries);
+ bool success = d->append(set);
+ if (success) {
+ QList<QBarSet *> sets;
+ sets.append(set);
+ set->setParent(this);
+ emit barsetsAdded(sets);
+ emit countChanged();
+ }
+ return success;
+}
+
+/*!
+ Removes barset from series. Releases ownership of \a set. Deletes the set, if remove
+ was successful.
+ Returns true, if set was removed.
+*/
+bool QAbstractBarSeries::remove(QBarSet *set)
+{
+ Q_D(QAbstractBarSeries);
+ bool success = d->remove(set);
+ if (success) {
+ QList<QBarSet *> sets;
+ sets.append(set);
+ set->setParent(0);
+ emit barsetsRemoved(sets);
+ emit countChanged();
+ delete set;
+ set = 0;
+ }
+ return success;
+}
+
+/*!
+ Takes a single \a set from the series. Does not delete the barset object.
+
+ NOTE: The series remains as the barset's parent object. You must set the
+ parent object to take full ownership.
+
+ Returns true if take was successful.
+*/
+bool QAbstractBarSeries::take(QBarSet *set)
+{
+ Q_D(QAbstractBarSeries);
+ bool success = d->remove(set);
+ if (success) {
+ QList<QBarSet *> sets;
+ sets.append(set);
+ emit barsetsRemoved(sets);
+ emit countChanged();
+ }
+ return success;
+}
+
+/*!
+ Adds a list of barsets to series. Takes ownership of \a sets.
+ Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
+ nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
+ and function returns false.
+*/
+bool QAbstractBarSeries::append(QList<QBarSet *> sets)
+{
+ Q_D(QAbstractBarSeries);
+ bool success = d->append(sets);
+ if (success) {
+ emit barsetsAdded(sets);
+ emit countChanged();
+ }
+ return success;
+}
+
+/*!
+ Insert a set of bars to series at \a index postion. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
+ Returns true, if inserting succeeded.
+
+*/
+bool QAbstractBarSeries::insert(int index, QBarSet *set)
+{
+ Q_D(QAbstractBarSeries);
+ bool success = d->insert(index, set);
+ if (success) {
+ QList<QBarSet *> sets;
+ sets.append(set);
+ emit barsetsAdded(sets);
+ emit countChanged();
+ }
+ return success;
+}
+
+/*!
+ Removes all barsets from the series. Deletes removed sets.
+*/
+void QAbstractBarSeries::clear()
+{
+ Q_D(QAbstractBarSeries);
+ QList<QBarSet *> sets = barSets();
+ bool success = d->remove(sets);
+ if (success) {
+ emit barsetsRemoved(sets);
+ emit countChanged();
+ foreach (QBarSet *set, sets)
+ delete set;
+ }
+}
+
+/*!
+ Returns number of sets in series.
+*/
+int QAbstractBarSeries::count() const
+{
+ Q_D(const QAbstractBarSeries);
+ return d->m_barSets.count();
+}
+
+/*!
+ Returns a list of sets in series. Keeps ownership of sets.
+ */
+QList<QBarSet *> QAbstractBarSeries::barSets() const
+{
+ Q_D(const QAbstractBarSeries);
+ return d->m_barSets;
+}
+
+/*!
+ Sets the visibility of labels in series to \a visible
+*/
+void QAbstractBarSeries::setLabelsVisible(bool visible)
+{
+ Q_D(QAbstractBarSeries);
+ if (d->m_labelsVisible != visible) {
+ d->setLabelsVisible(visible);
+ emit labelsVisibleChanged();
+ }
+}
+
+/*!
+ Returns the visibility of labels
+*/
+bool QAbstractBarSeries::isLabelsVisible() const
+{
+ Q_D(const QAbstractBarSeries);
+ return d->m_labelsVisible;
+}
+
+void QAbstractBarSeries::setLabelsFormat(const QString &format)
+{
+ Q_D(QAbstractBarSeries);
+ if (d->m_labelsFormat != format) {
+ d->m_labelsFormat = format;
+ emit labelsFormatChanged(format);
+ }
+}
+
+QString QAbstractBarSeries::labelsFormat() const
+{
+ Q_D(const QAbstractBarSeries);
+ return d->m_labelsFormat;
+}
+
+void QAbstractBarSeries::setLabelsPosition(QAbstractBarSeries::LabelsPosition position)
+{
+ Q_D(QAbstractBarSeries);
+ if (d->m_labelsPosition != position) {
+ d->m_labelsPosition = position;
+ emit labelsPositionChanged(position);
+ }
+}
+
+QAbstractBarSeries::LabelsPosition QAbstractBarSeries::labelsPosition() const
+{
+ Q_D(const QAbstractBarSeries);
+ return d->m_labelsPosition;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
+ QAbstractSeriesPrivate(q),
+ m_barWidth(0.5), // Default value is 50% of category width
+ m_labelsVisible(false),
+ m_visible(true),
+ m_blockBarUpdate(false),
+ m_labelsFormat(),
+ m_labelsPosition(QAbstractBarSeries::LabelsCenter)
+{
+}
+
+int QAbstractBarSeriesPrivate::categoryCount() const
+{
+ // No categories defined. return count of longest set.
+ int count = 0;
+ for (int i = 0; i < m_barSets.count(); i++) {
+ if (m_barSets.at(i)->count() > count)
+ count = m_barSets.at(i)->count();
+ }
+
+ return count;
+}
+
+void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
+{
+ if (width < 0.0)
+ width = 0.0;
+ m_barWidth = width;
+ emit updatedLayout();
+}
+
+qreal QAbstractBarSeriesPrivate::barWidth() const
+{
+ return m_barWidth;
+}
+
+QBarSet *QAbstractBarSeriesPrivate::barsetAt(int index)
+{
+ return m_barSets.at(index);
+}
+
+void QAbstractBarSeriesPrivate::setVisible(bool visible)
+{
+ m_visible = visible;
+ emit visibleChanged();
+}
+
+void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
+{
+ m_labelsVisible = visible;
+ emit labelsVisibleChanged(visible);
+}
+
+qreal QAbstractBarSeriesPrivate::min()
+{
+ if (m_barSets.count() <= 0)
+ return 0;
+
+ qreal min = INT_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);
+ if (temp < min)
+ min = temp;
+ }
+ }
+ return min;
+}
+
+qreal QAbstractBarSeriesPrivate::max()
+{
+ if (m_barSets.count() <= 0)
+ return 0;
+
+ qreal max = INT_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);
+ if (temp > max)
+ max = temp;
+ }
+ }
+
+ return max;
+}
+
+qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
+{
+ if ((set < 0) || (set >= m_barSets.count()))
+ return 0; // No set, no value.
+ else if ((category < 0) || (category >= m_barSets.at(set)->count()))
+ return 0; // No category, no value.
+
+ return m_barSets.at(set)->at(category);
+}
+
+qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
+{
+ if ((set < 0) || (set >= m_barSets.count()))
+ return 0; // No set, no value.
+ else if ((category < 0) || (category >= m_barSets.at(set)->count()))
+ return 0; // No category, no value.
+
+ qreal value = m_barSets.at(set)->at(category);
+ qreal sum = categorySum(category);
+ if (qFuzzyCompare(sum, 0))
+ return 0;
+
+ return value / sum;
+}
+
+qreal QAbstractBarSeriesPrivate::categorySum(int category)
+{
+ qreal sum(0);
+ 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);
+ }
+ return sum;
+}
+
+qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
+{
+ qreal sum(0);
+ 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));
+ }
+ return sum;
+}
+
+qreal QAbstractBarSeriesPrivate::maxCategorySum()
+{
+ qreal max = INT_MIN;
+ int count = categoryCount();
+ for (int i = 0; i < count; i++) {
+ qreal sum = categorySum(i);
+ if (sum > max)
+ max = sum;
+ }
+ return max;
+}
+
+qreal QAbstractBarSeriesPrivate::minX()
+{
+ if (m_barSets.count() <= 0)
+ return 0;
+
+ qreal min = INT_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)->d_ptr.data()->m_values.at(j).x();
+ if (temp < min)
+ min = temp;
+ }
+ }
+ return min;
+}
+
+qreal QAbstractBarSeriesPrivate::maxX()
+{
+ if (m_barSets.count() <= 0)
+ return 0;
+
+ qreal max = INT_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)->d_ptr.data()->m_values.at(j).x();
+ if (temp > max)
+ max = temp;
+ }
+ }
+
+ return max;
+}
+
+qreal QAbstractBarSeriesPrivate::categoryTop(int category)
+{
+ // Returns top (sum of all positive values) of category.
+ // Returns 0, if all values are negative
+ qreal top(0);
+ int count = m_barSets.count();
+ for (int set = 0; set < count; set++) {
+ if (category < m_barSets.at(set)->count()) {
+ qreal temp = m_barSets.at(set)->at(category);
+ if (temp > 0) {
+ top += temp;
+ }
+ }
+ }
+ return top;
+}
+
+qreal QAbstractBarSeriesPrivate::categoryBottom(int category)
+{
+ // Returns bottom (sum of all negative values) of category
+ // Returns 0, if all values are positive
+ qreal bottom(0);
+ int count = m_barSets.count();
+ for (int set = 0; set < count; set++) {
+ if (category < m_barSets.at(set)->count()) {
+ qreal temp = m_barSets.at(set)->at(category);
+ if (temp < 0) {
+ bottom += temp;
+ }
+ }
+ }
+ return bottom;
+}
+
+qreal QAbstractBarSeriesPrivate::top()
+{
+ // Returns top of all categories
+ qreal top(0);
+ int count = categoryCount();
+ for (int i = 0; i < count; i++) {
+ qreal temp = categoryTop(i);
+ if (temp > top)
+ top = temp;
+ }
+ return top;
+}
+
+qreal QAbstractBarSeriesPrivate::bottom()
+{
+ // Returns bottom of all categories
+ qreal bottom(0);
+ int count = categoryCount();
+ for (int i = 0; i < count; i++) {
+ qreal temp = categoryBottom(i);
+ if (temp < bottom)
+ bottom = temp;
+ }
+ return bottom;
+}
+
+bool QAbstractBarSeriesPrivate::blockBarUpdate()
+{
+ return m_blockBarUpdate;
+}
+
+void QAbstractBarSeriesPrivate::initializeDomain()
+{
+ qreal minX(domain()->minX());
+ qreal minY(domain()->minY());
+ qreal maxX(domain()->maxX());
+ qreal maxY(domain()->maxY());
+
+ qreal seriesMinX = this->minX();
+ qreal seriesMaxX = this->maxX();
+ qreal y = max();
+ minX = qMin(minX, seriesMinX - (qreal)0.5);
+ minY = qMin(minY, y);
+ maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
+ maxY = qMax(maxY, y);
+
+ domain()->setRange(minX, maxX, minY, maxY);
+}
+
+QList<QLegendMarker*> QAbstractBarSeriesPrivate::createLegendMarkers(QLegend* legend)
+{
+ Q_Q(QAbstractBarSeries);
+ QList<QLegendMarker*> markers;
+
+ foreach(QBarSet* set, q->barSets()) {
+ QBarLegendMarker* marker = new QBarLegendMarker(q,set,legend);
+ markers << marker;
+ }
+ return markers;
+}
+
+
+bool QAbstractBarSeriesPrivate::append(QBarSet *set)
+{
+ if ((m_barSets.contains(set)) || (set == 0))
+ return false; // Fail if set is already in list or set is null.
+
+ m_barSets.append(set);
+ QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
+ QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
+ QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
+
+ emit restructuredBars(); // this notifies barchartitem
+ return true;
+}
+
+bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
+{
+ if (!m_barSets.contains(set))
+ return false; // Fail if set is not in list
+
+ m_barSets.removeOne(set);
+ QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
+ QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
+ QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
+
+ emit restructuredBars(); // this notifies barchartitem
+ return true;
+}
+
+bool QAbstractBarSeriesPrivate::append(QList<QBarSet * > sets)
+{
+ foreach (QBarSet *set, sets) {
+ if ((set == 0) || (m_barSets.contains(set)))
+ return false; // Fail if any of the sets is null or is already appended.
+ if (sets.count(set) != 1)
+ return false; // Also fail if same set is more than once in given list.
+ }
+
+ foreach (QBarSet *set, sets) {
+ m_barSets.append(set);
+ QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
+ QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
+ QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
+ }
+
+ emit restructuredBars(); // this notifies barchartitem
+ return true;
+}
+
+bool QAbstractBarSeriesPrivate::remove(QList<QBarSet * > sets)
+{
+ if (sets.count() == 0)
+ return false;
+
+ foreach (QBarSet *set, sets) {
+ if ((set == 0) || (!m_barSets.contains(set)))
+ return false; // Fail if any of the sets is null or is not in series
+ if (sets.count(set) != 1)
+ return false; // Also fail if same set is more than once in given list.
+ }
+
+ foreach (QBarSet *set, sets) {
+ m_barSets.removeOne(set);
+ QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
+ QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
+ QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
+ }
+
+ emit restructuredBars(); // this notifies barchartitem
+
+ return true;
+}
+
+bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
+{
+ if ((m_barSets.contains(set)) || (set == 0))
+ return false; // Fail if set is already in list or set is null.
+
+ m_barSets.insert(index, set);
+ QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
+ QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
+ QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
+
+ emit restructuredBars(); // this notifies barchartitem
+ return true;
+}
+
+void QAbstractBarSeriesPrivate::initializeAxes()
+{
+ Q_Q(QAbstractBarSeries);
+
+ foreach(QAbstractAxis* axis, m_axes) {
+
+ if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
+ switch (q->type()) {
+ case QAbstractSeries::SeriesTypeHorizontalBar:
+ case QAbstractSeries::SeriesTypeHorizontalPercentBar:
+ case QAbstractSeries::SeriesTypeHorizontalStackedBar:
+ if (axis->orientation() == Qt::Vertical)
+ populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
+ break;
+ case QAbstractSeries::SeriesTypeBar:
+ case QAbstractSeries::SeriesTypePercentBar:
+ case QAbstractSeries::SeriesTypeStackedBar:
+ case QAbstractSeries::SeriesTypeBoxPlot:
+ if (axis->orientation() == Qt::Horizontal)
+ populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
+ break;
+ default:
+ qWarning() << "Unexpected series type";
+ break;
+ }
+ }
+ }
+}
+
+QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
+{
+ Q_Q(const QAbstractBarSeries);
+
+ switch (q->type()) {
+ case QAbstractSeries::SeriesTypeHorizontalBar:
+ case QAbstractSeries::SeriesTypeHorizontalPercentBar:
+ case QAbstractSeries::SeriesTypeHorizontalStackedBar:
+ if (orientation == Qt::Vertical)
+ return QAbstractAxis::AxisTypeBarCategory;
+ break;
+ case QAbstractSeries::SeriesTypeBar:
+ case QAbstractSeries::SeriesTypePercentBar:
+ case QAbstractSeries::SeriesTypeStackedBar:
+ case QAbstractSeries::SeriesTypeBoxPlot:
+ if (orientation == Qt::Horizontal)
+ return QAbstractAxis::AxisTypeBarCategory;
+ break;
+ default:
+ qWarning() << "Unexpected series type";
+ break;
+ }
+ return QAbstractAxis::AxisTypeValue;
+
+}
+
+void QAbstractBarSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
+{
+ QStringList categories;
+ if (axis->categories().isEmpty()) {
+ for (int i(1); i < categoryCount() + 1; i++)
+ categories << presenter()->numberToString(i);
+ axis->append(categories);
+ }
+}
+
+QAbstractAxis* QAbstractBarSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
+{
+ if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
+ return new QBarCategoryAxis;
+ else
+ return new QValueAxis;
+}
+
+void QAbstractBarSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
+{
+ m_blockBarUpdate = true; // Ensures that the bars are not updated before the theme is ready
+
+ const QList<QGradient> gradients = theme->seriesGradients();
+
+ qreal takeAtPos = 0.5;
+ qreal step = 0.2;
+ if (m_barSets.count() > 1) {
+ step = 1.0 / (qreal) m_barSets.count();
+ if (m_barSets.count() % gradients.count())
+ step *= gradients.count();
+ else
+ step *= (gradients.count() - 1);
+ }
+
+ for (int i(0); i < m_barSets.count(); i++) {
+ int colorIndex = (index + i) % gradients.count();
+ if (i > 0 && i %gradients.count() == 0) {
+ // There is no dedicated base color for each sets, generate more colors
+ takeAtPos += step;
+ if (takeAtPos == 1.0)
+ takeAtPos += step;
+ takeAtPos -= (int) takeAtPos;
+ }
+ if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->d_ptr->m_brush)
+ m_barSets.at(i)->setBrush(ChartThemeManager::colorAt(gradients.at(colorIndex), takeAtPos));
+
+ // Pick label color from the opposite end of the gradient.
+ // 0.3 as a boundary seems to work well.
+ if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->d_ptr->m_labelBrush) {
+ if (takeAtPos < 0.3)
+ m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 1));
+ else
+ m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0));
+ }
+ if (forced || QChartPrivate::defaultPen() == m_barSets.at(i)->d_ptr->m_pen) {
+ QColor c = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0);
+ m_barSets.at(i)->setPen(c);
+ }
+ }
+ m_blockBarUpdate = false;
+ emit updatedBars();
+}
+
+void QAbstractBarSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
+{
+ AbstractBarChartItem *bar = static_cast<AbstractBarChartItem *>(m_item.data());
+ Q_ASSERT(bar);
+ if (bar->animation())
+ bar->animation()->stopAndDestroyLater();
+
+ if (options.testFlag(QChart::SeriesAnimations))
+ bar->setAnimation(new BarAnimation(bar));
+ else
+ bar->setAnimation(0);
+ QAbstractSeriesPrivate::initializeAnimations(options);
+}
+
+#include "moc_qabstractbarseries.cpp"
+#include "moc_qabstractbarseries_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/qabstractbarseries.h b/src/charts/barchart/qabstractbarseries.h
new file mode 100644
index 00000000..85f32ff7
--- /dev/null
+++ b/src/charts/barchart/qabstractbarseries.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QABSTRACTBARSERIES_H
+#define QABSTRACTBARSERIES_H
+
+#include <QtCharts/qabstractseries.h>
+#include <QStringList>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QBarSet;
+class QAbstractBarSeriesPrivate;
+
+// Container for series
+class QT_CHARTS_EXPORT QAbstractBarSeries : public QAbstractSeries
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal barWidth READ barWidth WRITE setBarWidth)
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(bool labelsVisible READ isLabelsVisible WRITE setLabelsVisible NOTIFY labelsVisibleChanged)
+ Q_PROPERTY(QString labelsFormat READ labelsFormat WRITE setLabelsFormat NOTIFY labelsFormatChanged)
+ Q_PROPERTY(LabelsPosition labelsPosition READ labelsPosition WRITE setLabelsPosition NOTIFY labelsPositionChanged)
+ Q_ENUMS(LabelsPosition)
+
+public:
+ enum LabelsPosition {
+ LabelsCenter = 0,
+ LabelsInsideEnd,
+ LabelsInsideBase,
+ LabelsOutsideEnd
+ };
+
+public:
+ virtual ~QAbstractBarSeries();
+
+ void setBarWidth(qreal width);
+ qreal barWidth() const;
+
+ bool append(QBarSet *set);
+ bool remove(QBarSet *set);
+ bool take(QBarSet *set);
+ bool append(QList<QBarSet *> sets);
+ bool insert(int index, QBarSet *set);
+ int count() const;
+ QList<QBarSet *> barSets() const;
+ void clear();
+
+ void setLabelsVisible(bool visible = true);
+ bool isLabelsVisible() const;
+
+ void setLabelsFormat(const QString &format);
+ QString labelsFormat() const;
+
+ void setLabelsPosition(QAbstractBarSeries::LabelsPosition position);
+ QAbstractBarSeries::LabelsPosition labelsPosition() const;
+
+protected:
+ explicit QAbstractBarSeries(QAbstractBarSeriesPrivate &d, QObject *parent = 0);
+
+Q_SIGNALS:
+ void clicked(int index, QBarSet *barset);
+ void hovered(bool status, QBarSet *barset);
+ void hovered(bool status, int index, QBarSet *barset);
+ void countChanged();
+ void labelsVisibleChanged();
+ void labelsFormatChanged(const QString &format);
+ void labelsPositionChanged(QAbstractBarSeries::LabelsPosition position);
+
+ void barsetsAdded(QList<QBarSet *> sets);
+ void barsetsRemoved(QList<QBarSet *> sets);
+
+protected:
+ Q_DECLARE_PRIVATE(QAbstractBarSeries)
+ friend class AbstractBarChartItem;
+ friend class PercentBarChartItem;
+ friend class StackedBarChartItem;
+ friend class BoxPlotChartItem;
+ friend class BarChartItem;
+ friend class HorizontalBarChartItem;
+ friend class HorizontalStackedBarChartItem;
+ friend class HorizontalPercentBarChartItem;
+ friend class BarSet;
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QABSTRACTBARSERIES_H
diff --git a/src/charts/barchart/qabstractbarseries_p.h b/src/charts/barchart/qabstractbarseries_p.h
new file mode 100644
index 00000000..c7b0b827
--- /dev/null
+++ b/src/charts/barchart/qabstractbarseries_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QABSTRACTBARSERIES_P_H
+#define QABSTRACTBARSERIES_P_H
+
+#include <QtCharts/qabstractbarseries.h>
+#include "qabstractseries_p.h"
+#include <QStringList>
+#include <QAbstractSeries>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QBarModelMapper;
+class QBarCategoryAxis;
+class QLegendMarker;
+
+class QAbstractBarSeriesPrivate : public QAbstractSeriesPrivate
+{
+ Q_OBJECT
+public:
+ QAbstractBarSeriesPrivate(QAbstractBarSeries *parent);
+ int categoryCount() const;
+
+ void setBarWidth(qreal width);
+ qreal barWidth() const;
+
+ void setVisible(bool visible);
+ void setLabelsVisible(bool visible);
+
+ void initializeDomain();
+ void initializeAxes();
+ void initializeAnimations(QChart::AnimationOptions options);
+ void initializeTheme(int index, ChartTheme* theme, bool forced = false);
+
+ QList<QLegendMarker*> createLegendMarkers(QLegend *legend);
+
+ virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;
+ QAbstractAxis* createDefaultAxis(Qt::Orientation orientation) const;
+
+ bool append(QBarSet *set);
+ bool remove(QBarSet *set);
+ bool append(QList<QBarSet *> sets);
+ bool remove(QList<QBarSet *> sets);
+ bool insert(int index, QBarSet *set);
+
+ QBarSet *barsetAt(int index);
+ qreal min();
+ qreal max();
+ qreal valueAt(int set, int category);
+ qreal percentageAt(int set, int category);
+ qreal categorySum(int category);
+ qreal absoluteCategorySum(int category);
+ qreal maxCategorySum();
+ qreal minX();
+ qreal maxX();
+ qreal categoryTop(int category);
+ qreal categoryBottom(int category);
+ qreal top();
+ qreal bottom();
+
+ bool blockBarUpdate();
+
+Q_SIGNALS:
+ void clicked(int index, QBarSet *barset);
+ void updatedBars();
+ void updatedLayout();
+ void restructuredBars();
+ void labelsVisibleChanged(bool visible);
+ void visibleChanged();
+
+private:
+ void populateCategories(QBarCategoryAxis *axis);
+
+protected:
+ QList<QBarSet *> m_barSets;
+ qreal m_barWidth;
+ bool m_labelsVisible;
+ bool m_visible;
+ bool m_blockBarUpdate;
+ QString m_labelsFormat;
+ QAbstractBarSeries::LabelsPosition m_labelsPosition;
+
+private:
+ Q_DECLARE_PUBLIC(QAbstractBarSeries)
+ friend class HorizontalBarChartItem;
+ friend class BarChartItem;
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QABSTRACTBARSERIES_P_H
diff --git a/src/charts/barchart/qbarmodelmapper.cpp b/src/charts/barchart/qbarmodelmapper.cpp
new file mode 100644
index 00000000..459a72ca
--- /dev/null
+++ b/src/charts/barchart/qbarmodelmapper.cpp
@@ -0,0 +1,561 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qbarmodelmapper.h"
+#include "qbarmodelmapper_p.h"
+#include "qabstractbarseries.h"
+#include "qbarset.h"
+#include "qchart.h"
+#include <QAbstractItemModel>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+QBarModelMapper::QBarModelMapper(QObject *parent) :
+ QObject(parent),
+ d_ptr(new QBarModelMapperPrivate(this))
+{
+}
+
+QAbstractItemModel *QBarModelMapper::model() const
+{
+ Q_D(const QBarModelMapper);
+ return d->m_model;
+}
+
+void QBarModelMapper::setModel(QAbstractItemModel *model)
+{
+ if (model == 0)
+ return;
+
+ Q_D(QBarModelMapper);
+ if (d->m_model)
+ disconnect(d->m_model, 0, d, 0);
+
+ d->m_model = model;
+ d->initializeBarFromModel();
+ // connect signals from the model
+ connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
+ connect(d->m_model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), d, SLOT(modelHeaderDataUpdated(Qt::Orientation,int,int)));
+ connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
+ connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
+ connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
+ connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
+ connect(d->m_model, SIGNAL(destroyed()), d, SLOT(handleModelDestroyed()));
+}
+
+QAbstractBarSeries *QBarModelMapper::series() const
+{
+ Q_D(const QBarModelMapper);
+ return d->m_series;
+}
+
+void QBarModelMapper::setSeries(QAbstractBarSeries *series)
+{
+ Q_D(QBarModelMapper);
+ if (d->m_series)
+ disconnect(d->m_series, 0, d, 0);
+
+ if (series == 0)
+ return;
+
+ d->m_series = series;
+ d->initializeBarFromModel();
+ // connect the signals from the series
+ connect(d->m_series, SIGNAL(barsetsAdded(QList<QBarSet*>)), d, SLOT(barSetsAdded(QList<QBarSet*>)));
+ connect(d->m_series, SIGNAL(barsetsRemoved(QList<QBarSet*>)), d, SLOT(barSetsRemoved(QList<QBarSet*>)));
+ connect(d->m_series, SIGNAL(destroyed()), d, SLOT(handleSeriesDestroyed()));
+}
+
+/*!
+ Returns which row/column of the model contains the first values of the QBarSets in the series.
+ The default value is 0.
+*/
+int QBarModelMapper::first() const
+{
+ Q_D(const QBarModelMapper);
+ return d->m_first;
+}
+
+/*!
+ Sets which row of the model contains the \a first values of the QBarSets in the series.
+ The default value is 0.
+*/
+void QBarModelMapper::setFirst(int first)
+{
+ Q_D(QBarModelMapper);
+ d->m_first = qMax(first, 0);
+ d->initializeBarFromModel();
+}
+
+/*!
+ Returns the number of rows/columns of the model that are mapped as the data for QAbstractBarSeries
+ Minimal and default value is: -1 (count limited by the number of rows/columns in the model)
+*/
+int QBarModelMapper::count() const
+{
+ Q_D(const QBarModelMapper);
+ return d->m_count;
+}
+
+/*!
+ Sets the \a count of rows/columns of the model that are mapped as the data for QAbstractBarSeries
+ Minimal and default value is: -1 (count limited by the number of rows/columns in the model)
+*/
+void QBarModelMapper::setCount(int count)
+{
+ Q_D(QBarModelMapper);
+ d->m_count = qMax(count, -1);
+ d->initializeBarFromModel();
+}
+
+/*!
+ Returns the orientation that is used when QBarModelMapper accesses the model.
+ This mean whether the consecutive values of the bar set are read from row (Qt::Horizontal)
+ or from columns (Qt::Vertical)
+*/
+Qt::Orientation QBarModelMapper::orientation() const
+{
+ Q_D(const QBarModelMapper);
+ return d->m_orientation;
+}
+
+/*!
+ Returns the \a orientation that is used when QBarModelMapper accesses the model.
+ This mean whether the consecutive values of the pie are read from row (Qt::Horizontal)
+ or from columns (Qt::Vertical)
+*/
+void QBarModelMapper::setOrientation(Qt::Orientation orientation)
+{
+ Q_D(QBarModelMapper);
+ d->m_orientation = orientation;
+ d->initializeBarFromModel();
+}
+
+/*!
+ Returns which section of the model is used as the data source for the first bar set
+*/
+int QBarModelMapper::firstBarSetSection() const
+{
+ Q_D(const QBarModelMapper);
+ return d->m_firstBarSetSection;
+}
+
+/*!
+ Sets the model section that is used as the data source for the first bar set
+ Parameter \a firstBarSetSection specifies the section of the model.
+*/
+void QBarModelMapper::setFirstBarSetSection(int firstBarSetSection)
+{
+ Q_D(QBarModelMapper);
+ d->m_firstBarSetSection = qMax(-1, firstBarSetSection);
+ d->initializeBarFromModel();
+}
+
+/*!
+ Returns which section of the model is used as the data source for the last bar set
+*/
+int QBarModelMapper::lastBarSetSection() const
+{
+ Q_D(const QBarModelMapper);
+ return d->m_lastBarSetSection;
+}
+
+/*!
+ Sets the model section that is used as the data source for the last bar set
+ Parameter \a lastBarSetSection specifies the section of the model.
+*/
+void QBarModelMapper::setLastBarSetSection(int lastBarSetSection)
+{
+ Q_D(QBarModelMapper);
+ d->m_lastBarSetSection = qMax(-1, lastBarSetSection);
+ d->initializeBarFromModel();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QBarModelMapperPrivate::QBarModelMapperPrivate(QBarModelMapper *q) :
+ QObject(q),
+ m_series(0),
+ m_model(0),
+ m_first(0),
+ m_count(-1),
+ m_orientation(Qt::Vertical),
+ m_firstBarSetSection(-1),
+ m_lastBarSetSection(-1),
+ m_seriesSignalsBlock(false),
+ m_modelSignalsBlock(false),
+ q_ptr(q)
+{
+}
+
+void QBarModelMapperPrivate::blockModelSignals(bool block)
+{
+ m_modelSignalsBlock = block;
+}
+
+void QBarModelMapperPrivate::blockSeriesSignals(bool block)
+{
+ m_seriesSignalsBlock = block;
+}
+
+QBarSet *QBarModelMapperPrivate::barSet(QModelIndex index)
+{
+ if (!index.isValid())
+ return 0;
+
+ if (m_orientation == Qt::Vertical && index.column() >= m_firstBarSetSection && index.column() <= m_lastBarSetSection) {
+ if (index.row() >= m_first && (m_count == - 1 || index.row() < m_first + m_count)) {
+ return m_series->barSets().at(index.column() - m_firstBarSetSection);
+ }
+ } else if (m_orientation == Qt::Horizontal && index.row() >= m_firstBarSetSection && index.row() <= m_lastBarSetSection) {
+ if (index.column() >= m_first && (m_count == - 1 || index.column() < m_first + m_count))
+ return m_series->barSets().at(index.row() - m_firstBarSetSection);
+ }
+ return 0; // This part of model has not been mapped to any slice
+}
+
+QModelIndex QBarModelMapperPrivate::barModelIndex(int barSection, int posInBar)
+{
+ if (m_count != -1 && posInBar >= m_count)
+ return QModelIndex(); // invalid
+
+ if (barSection < m_firstBarSetSection || barSection > m_lastBarSetSection)
+ return QModelIndex(); // invalid
+
+ if (m_orientation == Qt::Vertical)
+ return m_model->index(posInBar + m_first, barSection);
+ else
+ return m_model->index(barSection, posInBar + m_first);
+}
+
+void QBarModelMapperPrivate::handleSeriesDestroyed()
+{
+ m_series = 0;
+}
+
+void QBarModelMapperPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
+{
+ Q_UNUSED(topLeft)
+ Q_UNUSED(bottomRight)
+
+ if (m_model == 0 || m_series == 0)
+ return;
+
+ if (m_modelSignalsBlock)
+ return;
+
+ blockSeriesSignals();
+ QModelIndex index;
+ for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
+ for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
+ index = topLeft.sibling(row, column);
+ QBarSet *bar = barSet(index);
+ if (bar) {
+ if (m_orientation == Qt::Vertical)
+ bar->replace(row - m_first, m_model->data(index).toReal());
+ else
+ bar->replace(column - m_first, m_model->data(index).toReal());
+ }
+ }
+ }
+ blockSeriesSignals(false);
+}
+
+void QBarModelMapperPrivate::modelHeaderDataUpdated(Qt::Orientation orientation, int first, int last)
+{
+ if (m_model == 0 || m_series == 0)
+ return;
+
+ if (m_modelSignalsBlock)
+ return;
+
+ blockSeriesSignals();
+ if (orientation != m_orientation) {
+ for (int section = first; section <= last; section++) {
+ if (section >= m_firstBarSetSection && section <= m_lastBarSetSection) {
+ QBarSet *bar = m_series->barSets().at(section - m_firstBarSetSection);
+ if (bar)
+ bar->setLabel(m_model->headerData(section, orientation).toString());
+ }
+ }
+ }
+ blockSeriesSignals(false);
+}
+
+void QBarModelMapperPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ if (m_modelSignalsBlock)
+ return;
+
+ blockSeriesSignals();
+ if (m_orientation == Qt::Vertical)
+ insertData(start, end);
+ else if (start <= m_firstBarSetSection || start <= m_lastBarSetSection) // if the changes affect the map - reinitialize
+ initializeBarFromModel();
+ blockSeriesSignals(false);
+}
+
+void QBarModelMapperPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ if (m_modelSignalsBlock)
+ return;
+
+ blockSeriesSignals();
+ if (m_orientation == Qt::Vertical)
+ removeData(start, end);
+ else if (start <= m_firstBarSetSection || start <= m_lastBarSetSection) // if the changes affect the map - reinitialize
+ initializeBarFromModel();
+ blockSeriesSignals(false);
+}
+
+void QBarModelMapperPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ if (m_modelSignalsBlock)
+ return;
+
+ blockSeriesSignals();
+ if (m_orientation == Qt::Horizontal)
+ insertData(start, end);
+ else if (start <= m_firstBarSetSection || start <= m_lastBarSetSection) // if the changes affect the map - reinitialize
+ initializeBarFromModel();
+ blockSeriesSignals(false);
+}
+
+void QBarModelMapperPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ if (m_modelSignalsBlock)
+ return;
+
+ blockSeriesSignals();
+ if (m_orientation == Qt::Horizontal)
+ removeData(start, end);
+ else if (start <= m_firstBarSetSection || start <= m_lastBarSetSection) // if the changes affect the map - reinitialize
+ initializeBarFromModel();
+ blockSeriesSignals(false);
+}
+
+void QBarModelMapperPrivate::handleModelDestroyed()
+{
+ m_model = 0;
+}
+
+void QBarModelMapperPrivate::insertData(int start, int end)
+{
+ Q_UNUSED(end)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+ // Currently barchart needs to be fully recalculated when change is made.
+ // Re-initialize
+ initializeBarFromModel();
+}
+
+void QBarModelMapperPrivate::removeData(int start, int end)
+{
+ Q_UNUSED(end)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+ // Currently barchart needs to be fully recalculated when change is made.
+ // Re-initialize
+ initializeBarFromModel();
+}
+
+void QBarModelMapperPrivate::barSetsAdded(QList<QBarSet *> sets)
+{
+ if (m_seriesSignalsBlock)
+ return;
+
+ if (sets.count() == 0)
+ return;
+
+ int firstIndex = m_series->barSets().indexOf(sets.at(0));
+ if (firstIndex == -1)
+ return;
+
+ int maxCount = 0;
+ for (int i = 0; i < sets.count(); i++) {
+ if (sets.at(i)->count() > m_count)
+ maxCount = sets.at(i)->count();
+ }
+
+ if (m_count != -1 && m_count < maxCount)
+ m_count = maxCount;
+
+ m_lastBarSetSection += sets.count();
+
+ blockModelSignals();
+ int modelCapacity = m_orientation == Qt::Vertical ? m_model->rowCount() - m_first : m_model->columnCount() - m_first;
+ if (maxCount > modelCapacity) {
+ if (m_orientation == Qt::Vertical)
+ m_model->insertRows(m_model->rowCount(), maxCount - modelCapacity);
+ else
+ m_model->insertColumns(m_model->columnCount(), maxCount - modelCapacity);
+ }
+
+ if (m_orientation == Qt::Vertical)
+ m_model->insertColumns(firstIndex + m_firstBarSetSection, sets.count());
+ else
+ m_model->insertRows(firstIndex + m_firstBarSetSection, sets.count());
+
+
+ for (int i = firstIndex + m_firstBarSetSection; i < firstIndex + m_firstBarSetSection + sets.count(); i++) {
+ m_model->setHeaderData(i, m_orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical, sets.at(i - firstIndex - m_firstBarSetSection)->label());
+ for (int j = 0; j < sets.at(i - firstIndex - m_firstBarSetSection)->count(); j++)
+ m_model->setData(barModelIndex(i, j), sets.at(i - firstIndex - m_firstBarSetSection)->at(j));
+ }
+ blockModelSignals(false);
+ initializeBarFromModel();
+}
+
+void QBarModelMapperPrivate::barSetsRemoved(QList<QBarSet *> sets)
+{
+ if (m_seriesSignalsBlock)
+ return;
+
+ if (sets.count() == 0)
+ return;
+
+ int firstIndex = m_barSets.indexOf(sets.at(0));
+ if (firstIndex == -1)
+ return;
+
+ m_lastBarSetSection -= sets.count();
+
+ for (int i = firstIndex + sets.count() - 1; i >= firstIndex; i--)
+ m_barSets.removeAt(i);
+
+ blockModelSignals();
+ if (m_orientation == Qt::Vertical)
+ m_model->removeColumns(firstIndex + m_firstBarSetSection, sets.count());
+ else
+ m_model->removeRows(firstIndex + m_firstBarSetSection, sets.count());
+ blockModelSignals(false);
+ initializeBarFromModel();
+}
+
+void QBarModelMapperPrivate::valuesAdded(int index, int count)
+{
+ if (m_seriesSignalsBlock)
+ return;
+
+ if (m_count != -1)
+ m_count += count;
+
+ int barSetIndex = m_barSets.indexOf(qobject_cast<QBarSet *>(QObject::sender()));
+
+ blockModelSignals();
+ if (m_orientation == Qt::Vertical)
+ m_model->insertRows(index + m_first, count);
+ else
+ m_model->insertColumns(index + m_first, count);
+
+ for (int j = index; j < index + count; j++)
+ m_model->setData(barModelIndex(barSetIndex + m_firstBarSetSection, j), m_barSets.at(barSetIndex)->at(j));
+
+ blockModelSignals(false);
+ initializeBarFromModel();
+}
+
+void QBarModelMapperPrivate::valuesRemoved(int index, int count)
+{
+ if (m_seriesSignalsBlock)
+ return;
+
+ if (m_count != -1)
+ m_count -= count;
+
+ blockModelSignals();
+ if (m_orientation == Qt::Vertical)
+ m_model->removeRows(index + m_first, count);
+ else
+ m_model->removeColumns(index + m_first, count);
+
+ blockModelSignals(false);
+ initializeBarFromModel();
+}
+
+void QBarModelMapperPrivate::barLabelChanged()
+{
+ if (m_seriesSignalsBlock)
+ return;
+
+ int barSetIndex = m_barSets.indexOf(qobject_cast<QBarSet *>(QObject::sender()));
+
+ blockModelSignals();
+ m_model->setHeaderData(barSetIndex + m_firstBarSetSection, m_orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical, m_barSets.at(barSetIndex)->label());
+ blockModelSignals(false);
+ initializeBarFromModel();
+}
+
+void QBarModelMapperPrivate::barValueChanged(int index)
+{
+ if (m_seriesSignalsBlock)
+ return;
+
+ int barSetIndex = m_barSets.indexOf(qobject_cast<QBarSet *>(QObject::sender()));
+
+ blockModelSignals();
+ m_model->setData(barModelIndex(barSetIndex + m_firstBarSetSection, index), m_barSets.at(barSetIndex)->at(index));
+ blockModelSignals(false);
+ initializeBarFromModel();
+}
+
+void QBarModelMapperPrivate::initializeBarFromModel()
+{
+ if (m_model == 0 || m_series == 0)
+ return;
+
+ blockSeriesSignals();
+ // clear current content
+ m_series->clear();
+ m_barSets.clear();
+
+ // create the initial bar sets
+ for (int i = m_firstBarSetSection; i <= m_lastBarSetSection; i++) {
+ int posInBar = 0;
+ QModelIndex barIndex = barModelIndex(i, posInBar);
+ // check if there is such model index
+ if (barIndex.isValid()) {
+ QBarSet *barSet = new QBarSet(m_model->headerData(i, m_orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical).toString());
+ while (barIndex.isValid()) {
+ barSet->append(m_model->data(barIndex, Qt::DisplayRole).toDouble());
+ posInBar++;
+ barIndex = barModelIndex(i, posInBar);
+ }
+ connect(barSet, SIGNAL(valuesAdded(int,int)), this, SLOT(valuesAdded(int,int)));
+ connect(barSet, SIGNAL(valuesRemoved(int,int)), this, SLOT(valuesRemoved(int,int)));
+ connect(barSet, SIGNAL(valueChanged(int)), this, SLOT(barValueChanged(int)));
+ connect(barSet, SIGNAL(labelChanged()), this, SLOT(barLabelChanged()));
+ m_series->append(barSet);
+ m_barSets.append(barSet);
+ } else {
+ break;
+ }
+ }
+ blockSeriesSignals(false);
+}
+
+#include "moc_qbarmodelmapper.cpp"
+#include "moc_qbarmodelmapper_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/qbarmodelmapper.h b/src/charts/barchart/qbarmodelmapper.h
new file mode 100644
index 00000000..a527165a
--- /dev/null
+++ b/src/charts/barchart/qbarmodelmapper.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QBARMODELMAPPER_H
+#define QBARMODELMAPPER_H
+
+#include <QtCharts/qchartglobal.h>
+#include <QObject>
+
+class QAbstractItemModel;
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QBarModelMapperPrivate;
+class QAbstractBarSeries;
+
+class QT_CHARTS_EXPORT QBarModelMapper : public QObject
+{
+ Q_OBJECT
+
+protected:
+ explicit QBarModelMapper(QObject *parent = 0);
+
+ QAbstractItemModel *model() const;
+ void setModel(QAbstractItemModel *model);
+
+ QAbstractBarSeries *series() const;
+ void setSeries(QAbstractBarSeries *series);
+
+ int first() const;
+ void setFirst(int first);
+
+ int count() const;
+ void setCount(int count);
+
+ int firstBarSetSection() const;
+ void setFirstBarSetSection(int firstBarSetSection);
+
+ int lastBarSetSection() const;
+ void setLastBarSetSection(int lastBarSetSection);
+
+ Qt::Orientation orientation() const;
+ void setOrientation(Qt::Orientation orientation);
+
+protected:
+ QBarModelMapperPrivate * const d_ptr;
+ Q_DECLARE_PRIVATE(QBarModelMapper)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QBARMODELMAPPER_H
diff --git a/src/charts/barchart/qbarmodelmapper_p.h b/src/charts/barchart/qbarmodelmapper_p.h
new file mode 100644
index 00000000..754ebec1
--- /dev/null
+++ b/src/charts/barchart/qbarmodelmapper_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QBARMODELMAPPER_P_H
+#define QBARMODELMAPPER_P_H
+
+#include <QObject>
+#include "qbarmodelmapper.h"
+
+class QModelIndex;
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QBarSet;
+
+class QBarModelMapperPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QBarModelMapperPrivate(QBarModelMapper *q);
+
+public Q_SLOTS:
+ // for the model
+ void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
+ void modelHeaderDataUpdated(Qt::Orientation orientation, int first, int last);
+ void modelRowsAdded(QModelIndex parent, int start, int end);
+ void modelRowsRemoved(QModelIndex parent, int start, int end);
+ void modelColumnsAdded(QModelIndex parent, int start, int end);
+ void modelColumnsRemoved(QModelIndex parent, int start, int end);
+ void handleModelDestroyed();
+
+ // for the series
+ void barSetsAdded(QList<QBarSet *> sets);
+ void barSetsRemoved(QList<QBarSet *> sets);
+ void valuesAdded(int index, int count);
+ void valuesRemoved(int index, int count);
+ void barLabelChanged();
+ void barValueChanged(int index);
+ void handleSeriesDestroyed();
+
+ void initializeBarFromModel();
+
+private:
+ QBarSet *barSet(QModelIndex index);
+ QModelIndex barModelIndex(int barSection, int posInBar);
+ void insertData(int start, int end);
+ void removeData(int start, int end);
+ void blockModelSignals(bool block = true);
+ void blockSeriesSignals(bool block = true);
+
+private:
+ QAbstractBarSeries *m_series;
+ QList<QBarSet *> m_barSets;
+ QAbstractItemModel *m_model;
+ int m_first;
+ int m_count;
+ Qt::Orientation m_orientation;
+ int m_firstBarSetSection;
+ int m_lastBarSetSection;
+ bool m_seriesSignalsBlock;
+ bool m_modelSignalsBlock;
+
+private:
+ QBarModelMapper *q_ptr;
+ Q_DECLARE_PUBLIC(QBarModelMapper)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QBARMODELMAPPER_P_H
diff --git a/src/charts/barchart/qbarset.cpp b/src/charts/barchart/qbarset.cpp
new file mode 100644
index 00000000..e378b327
--- /dev/null
+++ b/src/charts/barchart/qbarset.cpp
@@ -0,0 +1,676 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qbarset.h"
+#include "qbarset_p.h"
+#include "charthelpers_p.h"
+#include "qchart_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QBarSet
+ \inmodule Qt Charts
+ \brief Building block for different bar charts.
+
+ QBarSet represents one set of bars. Set of bars contains one data value for each category.
+ First value of set is assumed to belong to first category, second to second category and so on.
+ If set has fewer values than there are categories, then the missing values are assumed to be
+ at the end of set. For missing values in middle of a set, numerical value of zero is used.
+
+ \mainclass
+
+ \sa QAbstractBarSeries, QBarSeries, QStackedBarSeries, QPercentBarSeries
+*/
+/*!
+ \qmltype BarSet
+ \instantiates QBarSet
+ \inqmlmodule QtCharts
+
+ \brief Building block for different bar charts.
+
+ BarSet represents one set of bars. Set of bars contains one data value for each category.
+ First value of set is assumed to belong to first category, second to second category and so on.
+ If set has fewer values than there are categories, then the missing values are assumed to be
+ at the end of set. For missing values in middle of a set, numerical value of zero is used.
+ \sa AbstractBarSeries, BarSeries, StackedBarSeries, PercentBarSeries
+*/
+
+/*!
+ \property QBarSet::label
+ Defines the label of the bar set.
+*/
+/*!
+ \qmlproperty string BarSet::label
+ Defines the label of the bar set.
+*/
+
+/*!
+ \property QBarSet::pen
+ \brief Defines the pen used by the bar set.
+*/
+
+/*!
+ \property QBarSet::brush
+ \brief Defines the brush used by the bar set.
+*/
+
+/*!
+ \qmlproperty QString BarSet::brushFilename
+ The name of the file used as a brush for the set.
+*/
+
+/*!
+ \property QBarSet::labelBrush
+ \brief Defines the brush used by the bar set's label.
+*/
+
+/*!
+ \property QBarSet::labelFont
+ \brief Defines the font used by the bar set's label.
+*/
+
+/*!
+ \qmlproperty Font BarSet::labelFont
+ Defines the font used by the bar set's label.
+
+ See the Qt documentation for more details of Font.
+*/
+
+/*!
+ \property QBarSet::color
+ The fill (brush) color of the bar set.
+*/
+/*!
+ \qmlproperty color BarSet::color
+ The fill (brush) color of the bar set.
+*/
+
+/*!
+ \property QBarSet::borderColor
+ The line (pen) color of the bar set.
+*/
+/*!
+ \qmlproperty color BarSet::borderColor
+ The line (pen) color of the bar set.
+*/
+
+/*!
+ \qmlproperty real BarSet::borderWidth
+ The width of the border line. By default the width is 2.0.
+*/
+
+/*!
+ \property QBarSet::labelColor
+ The text (label) color of the bar set.
+*/
+/*!
+ \qmlproperty color BarSet::labelColor
+ The text (label) color of the bar set.
+*/
+
+/*!
+ \fn void QBarSet::clicked(int index)
+
+ The signal is emitted if the user clicks with a mouse on top of bar set.
+ Clicked bar inside set is indexed by \a index
+*/
+
+/*!
+ \fn void QBarSet::hovered(bool status)
+
+ The signal is emitted if mouse is hovered on top of bar set.
+ Parameter \a status is true, if mouse entered on top of bar set, false if mouse left from top of bar set.
+*/
+
+/*!
+ \fn void QBarSet::hovered(bool status, int index)
+
+ The signal is emitted if mouse is hovered on top of bar set.
+ Parameter \a status is true, if mouse entered on top of bar set, false if mouse left from top of bar set.
+ Hovered bar inside the set is indexed by \a index.
+*/
+
+
+/*!
+ \fn void QBarSet::labelChanged()
+ This signal is emitted when the label of the bar set has changed.
+ \sa label
+*/
+/*!
+ \qmlsignal BarSet::onLabelChanged()
+ This signal is emitted when the label of the bar set has changed.
+*/
+
+/*!
+ \fn void QBarSet::penChanged()
+ This signal is emitted when the pen of the bar set has changed.
+ \sa pen
+*/
+
+/*!
+ \fn void QBarSet::brushChanged()
+ This signal is emitted when the brush of the bar set has changed.
+ \sa brush
+*/
+
+/*!
+ \fn void QBarSet::labelBrushChanged()
+ This signal is emitted when the brush of the bar set's label has changed.
+ \sa labelBrush
+*/
+
+/*!
+ \fn void QBarSet::labelFontChanged()
+ This signal is emitted when the font of the bar set's label has changed.
+ \sa labelBrush
+*/
+
+/*!
+ \fn void QBarSet::colorChanged(QColor)
+ This signal is emitted when the fill (brush) color of the set has changed to \a color.
+*/
+/*!
+ \qmlsignal BarSet::onColorChanged(color color)
+ This signal is emitted when the fill (brush) color of the set has changed to \a color.
+*/
+
+/*!
+ \fn void QBarSet::borderColorChanged(QColor)
+ This signal is emitted when the line (pen) color of the set has changed to \a color.
+*/
+/*!
+ \qmlsignal BarSet::onBorderColorChanged(color color)
+ This signal is emitted when the line (pen) color of the set has changed to \a color.
+*/
+
+/*!
+ \fn void QBarSet::labelColorChanged(QColor)
+ This signal is emitted when the text (label) color of the set has changed to \a color.
+*/
+/*!
+ \qmlsignal BarSet::onLabelColorChanged(color color)
+ This signal is emitted when the text (label) color of the set has changed to \a color.
+*/
+
+/*!
+ \fn void QBarSet::valuesAdded(int index, int count)
+ This signal is emitted when new values have been added to the set.
+ Parameter \a index indicates the position of the first inserted value.
+ Parameter \a count is the number of inserted values.
+ \sa append(), insert()
+*/
+/*!
+ \qmlsignal BarSet::onValuesAdded(int index, int count)
+ This signal is emitted when new values have been added to the set.
+ Parameter \a index indicates the position of the first inserted value.
+ Parameter \a count is the number of inserted values.
+*/
+
+/*!
+ \fn void QBarSet::valuesRemoved(int index, int count)
+ This signal is emitted values have been removed from the set.
+ Parameter \a index indicates the position of the first removed value.
+ Parameter \a count is the number of removed values.
+ \sa remove()
+*/
+/*!
+ \qmlsignal BarSet::onValuesRemoved(int index, int count)
+ This signal is emitted values have been removed from the set.
+ Parameter \a index indicates the position of the first removed value.
+ Parameter \a count is the number of removed values.
+*/
+
+/*!
+ \fn void QBarSet::valueChanged(int index)
+ This signal is emitted values the value in the set has been modified.
+ Parameter \a index indicates the position of the modified value.
+ \sa at()
+*/
+/*!
+ \qmlsignal BarSet::onValueChanged(int index)
+ This signal is emitted values the value in the set has been modified.
+ Parameter \a index indicates the position of the modified value.
+*/
+
+/*!
+ \qmlproperty int BarSet::count
+ The count of values on the bar set
+*/
+
+/*!
+ \qmlproperty QVariantList BarSet::values
+ The values of the bar set. You can set either a list of reals or a list of points as values. If you set a list of
+ reals as values, the values are automatically completed to points by using the index of a value as it's
+ x-coordinate. For example the following sets have equal values:
+ \code
+ myBarSet1.values = [0, 5, 1, 5];
+ myBarSet2.values = [Qt.point(0, 0), Qt.point(1, 5), Qt.point(2, 1), Qt.point(3, 5)];
+ \endcode
+*/
+
+/*!
+ Constructs QBarSet with a label of \a label and with parent of \a parent.
+*/
+QBarSet::QBarSet(const QString label, QObject *parent)
+ : QObject(parent),
+ d_ptr(new QBarSetPrivate(label, this))
+{
+}
+
+/*!
+ Destroys the bar set.
+*/
+QBarSet::~QBarSet()
+{
+ // NOTE: d_ptr destroyed by QObject
+}
+
+/*!
+ Sets new \a label for set.
+*/
+void QBarSet::setLabel(const QString label)
+{
+ d_ptr->m_label = label;
+ emit labelChanged();
+}
+
+/*!
+ Returns label of the set.
+*/
+QString QBarSet::label() const
+{
+ return d_ptr->m_label;
+}
+
+/*!
+ Appends new value \a value to the end of set.
+*/
+void QBarSet::append(const qreal value)
+{
+ // Convert to QPointF
+ int index = d_ptr->m_values.count();
+ d_ptr->append(QPointF(d_ptr->m_values.count(), value));
+ emit valuesAdded(index, 1);
+}
+
+/*!
+ Appends a list of reals to set. Works like append with single real value. The \a values in list
+ are appended to end of bar set.
+ \sa append()
+*/
+void QBarSet::append(const QList<qreal> &values)
+{
+ int index = d_ptr->m_values.count();
+ d_ptr->append(values);
+ emit valuesAdded(index, values.count());
+}
+
+/*!
+ Convenience operator. Same as append, with real \a value.
+ \sa append()
+*/
+QBarSet &QBarSet::operator << (const qreal &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 position index + 1
+ \sa remove()
+*/
+void QBarSet::insert(const int index, const qreal value)
+{
+ d_ptr->insert(index, value);
+ emit valuesAdded(index, 1);
+}
+
+/*!
+ Removes \a count number of values from the set starting at \a index.
+ \sa insert()
+*/
+void QBarSet::remove(const int index, const int count)
+{
+ int removedCount = d_ptr->remove(index, count);
+ if (removedCount > 0)
+ emit valuesRemoved(index, removedCount);
+ return;
+}
+
+/*!
+ Sets a new value \a value to set, indexed by \a index.
+*/
+void QBarSet::replace(const int index, const qreal value)
+{
+ if (index >= 0 && index < d_ptr->m_values.count()) {
+ d_ptr->replace(index, value);
+ emit valueChanged(index);
+ }
+}
+
+
+/*!
+ Returns value of set indexed by \a index.
+ If the index is out of bounds 0.0 is returned.
+*/
+qreal QBarSet::at(const int index) const
+{
+ if (index < 0 || index >= d_ptr->m_values.count())
+ return 0;
+ return d_ptr->m_values.at(index).y();
+}
+
+/*!
+ Returns value of set indexed by \a index.
+ If the index is out of bounds 0.0 is returned.
+*/
+qreal QBarSet::operator [](const int index) const
+{
+ return at(index);
+}
+
+/*!
+ Returns count of values in set.
+*/
+int QBarSet::count() const
+{
+ return d_ptr->m_values.count();
+}
+
+/*!
+ Returns sum of all values in the bar set.
+*/
+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).y();
+ return total;
+}
+
+/*!
+ Sets pen for set. Bars of this set are drawn using \a pen
+*/
+void QBarSet::setPen(const QPen &pen)
+{
+ if (d_ptr->m_pen != pen) {
+ d_ptr->m_pen = pen;
+ emit d_ptr->updatedBars();
+ emit penChanged();
+ }
+}
+
+/*!
+ Returns pen of the set.
+*/
+QPen QBarSet::pen() const
+{
+ if (d_ptr->m_pen == QChartPrivate::defaultPen())
+ return QPen();
+ else
+ return d_ptr->m_pen;
+}
+
+/*!
+ Sets brush for the set. Bars of this set are drawn using \a brush.
+*/
+void QBarSet::setBrush(const QBrush &brush)
+{
+ if (d_ptr->m_brush != brush) {
+ d_ptr->m_brush = brush;
+ emit d_ptr->updatedBars();
+ emit brushChanged();
+ }
+}
+
+/*!
+ Returns brush of the set.
+*/
+QBrush QBarSet::brush() const
+{
+ if (d_ptr->m_brush == QChartPrivate::defaultBrush())
+ return QBrush();
+ else
+ return d_ptr->m_brush;
+}
+
+/*!
+ Sets \a brush of the values that are drawn on top of this bar set.
+*/
+void QBarSet::setLabelBrush(const QBrush &brush)
+{
+ if (d_ptr->m_labelBrush != brush) {
+ d_ptr->m_labelBrush = brush;
+ emit d_ptr->updatedBars();
+ emit labelBrushChanged();
+ }
+}
+
+/*!
+ Returns brush of the values that are drawn on top of this bar set.
+*/
+QBrush QBarSet::labelBrush() const
+{
+ if (d_ptr->m_labelBrush == QChartPrivate::defaultBrush())
+ return QBrush();
+ else
+ return d_ptr->m_labelBrush;
+}
+
+/*!
+ Sets the \a font for values that are drawn on top of this bar set.
+*/
+void QBarSet::setLabelFont(const QFont &font)
+{
+ if (d_ptr->m_labelFont != font) {
+ d_ptr->m_labelFont = font;
+ emit d_ptr->updatedBars();
+ emit labelFontChanged();
+ }
+
+}
+
+/*!
+ Returns the pen for values that are drawn on top of this bar set.
+*/
+QFont QBarSet::labelFont() const
+{
+ return d_ptr->m_labelFont;
+}
+
+/*!
+ Returns the color of the brush of bar set.
+*/
+QColor QBarSet::color()
+{
+ return brush().color();
+}
+
+/*!
+ Sets the \a color of brush for this bar set.
+*/
+void QBarSet::setColor(QColor color)
+{
+ QBrush b = brush();
+ if ((b.color() != color) || (b.style() == Qt::NoBrush)) {
+ b.setColor(color);
+ if (b.style() == Qt::NoBrush) {
+ // Set tyle to Qt::SolidPattern. (Default is Qt::NoBrush)
+ // This prevents theme to override color defined in QML side:
+ // BarSet { label: "Bob"; color:"red"; values: [1,2,3] }
+ // The color must be obeyed, since user wanted it.
+ b.setStyle(Qt::SolidPattern);
+ }
+ setBrush(b);
+ emit colorChanged(color);
+ }
+}
+
+/*!
+ Returns the color of pen of this bar set.
+*/
+QColor QBarSet::borderColor()
+{
+ return pen().color();
+}
+
+/*!
+ Sets the color of pen for this bar set.
+*/
+void QBarSet::setBorderColor(QColor color)
+{
+ QPen p = pen();
+ if (p.color() != color) {
+ p.setColor(color);
+ setPen(p);
+ emit borderColorChanged(color);
+ }
+}
+
+/*!
+ Returns the color of labels of this bar set.
+*/
+QColor QBarSet::labelColor()
+{
+ return labelBrush().color();
+}
+
+/*!
+ Sets the color of labels for this bar set.
+*/
+void QBarSet::setLabelColor(QColor color)
+{
+ QBrush b = labelBrush();
+ if (b == QBrush())
+ b.setStyle(Qt::SolidPattern);
+
+ if (b.color() != color) {
+ b.setColor(color);
+ setLabelBrush(b);
+ emit labelColorChanged(color);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QBarSetPrivate::QBarSetPrivate(const QString label, QBarSet *parent) : QObject(parent),
+ q_ptr(parent),
+ m_label(label),
+ m_pen(QChartPrivate::defaultPen()),
+ m_brush(QChartPrivate::defaultBrush()),
+ m_labelBrush(QChartPrivate::defaultBrush())
+{
+}
+
+QBarSetPrivate::~QBarSetPrivate()
+{
+}
+
+void QBarSetPrivate::append(QPointF value)
+{
+ if (isValidValue(value)) {
+ m_values.append(value);
+ emit restructuredBars();
+ }
+}
+
+void QBarSetPrivate::append(QList<QPointF> values)
+{
+ for (int i = 0; i < values.count(); i++) {
+ if (isValidValue(values.at(i)))
+ m_values.append(values.at(i));
+ }
+ emit restructuredBars();
+}
+
+void QBarSetPrivate::append(QList<qreal> values)
+{
+ int index = m_values.count();
+ for (int i = 0; i < values.count(); i++) {
+ if (isValidValue(values.at(i))) {
+ m_values.append(QPointF(index, values.at(i)));
+ index++;
+ }
+ }
+ emit restructuredBars();
+}
+
+void QBarSetPrivate::insert(const int index, const qreal value)
+{
+ m_values.insert(index, QPointF(index, value));
+ emit restructuredBars();
+}
+
+void QBarSetPrivate::insert(const int index, const QPointF value)
+{
+ m_values.insert(index, value);
+ emit restructuredBars();
+}
+
+int QBarSetPrivate::remove(const int index, const int count)
+{
+ int removeCount = count;
+
+ if ((index < 0) || (m_values.count() == 0))
+ return 0; // Invalid index or not values in list, remove nothing.
+ else if ((index + count) > m_values.count())
+ removeCount = m_values.count() - index; // Trying to remove more items than list has. Limit amount to be removed.
+
+ int c = 0;
+ while (c < removeCount) {
+ m_values.removeAt(index);
+ c++;
+ }
+ emit restructuredBars();
+ return removeCount;
+}
+
+void QBarSetPrivate::replace(const int index, const qreal value)
+{
+ m_values.replace(index, QPointF(index, value));
+ emit updatedLayout();
+}
+
+void QBarSetPrivate::replace(const int index, const QPointF value)
+{
+ m_values.replace(index, value);
+ emit updatedLayout();
+}
+
+qreal QBarSetPrivate::pos(const int index)
+{
+ if (index < 0 || index >= m_values.count())
+ return 0;
+ return m_values.at(index).x();
+}
+
+qreal QBarSetPrivate::value(const int index)
+{
+ if (index < 0 || index >= m_values.count())
+ return 0;
+ return m_values.at(index).y();
+}
+
+#include "moc_qbarset.cpp"
+#include "moc_qbarset_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/qbarset.h b/src/charts/barchart/qbarset.h
new file mode 100644
index 00000000..7d96dec4
--- /dev/null
+++ b/src/charts/barchart/qbarset.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QBARSET_H
+#define QBARSET_H
+
+#include <QtCharts/qchartglobal.h>
+#include <QPen>
+#include <QBrush>
+#include <QFont>
+
+QT_CHARTS_BEGIN_NAMESPACE
+class QBarSetPrivate;
+
+class QT_CHARTS_EXPORT QBarSet : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
+ Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
+ Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
+ Q_PROPERTY(QBrush labelBrush READ labelBrush WRITE setLabelBrush NOTIFY labelBrushChanged)
+ Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont NOTIFY labelFontChanged)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+ Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged)
+ Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor NOTIFY labelColorChanged)
+
+public:
+ explicit QBarSet(const QString label, QObject *parent = 0);
+ virtual ~QBarSet();
+
+ void setLabel(const QString label);
+ QString label() const;
+
+ void append(const qreal value);
+ void append(const QList<qreal> &values);
+
+ QBarSet &operator << (const qreal &value);
+
+ void insert(const int index, const qreal value);
+ void remove(const int index, const int count = 1);
+ void replace(const int index, const qreal value);
+ qreal at(const int index) const;
+ qreal operator [](const int index) const;
+ int count() const;
+ qreal sum() const;
+
+ void setPen(const QPen &pen);
+ QPen pen() const;
+
+ void setBrush(const QBrush &brush);
+ QBrush brush() const;
+
+ void setLabelBrush(const QBrush &brush);
+ QBrush labelBrush() const;
+
+ void setLabelFont(const QFont &font);
+ QFont labelFont() const;
+
+ QColor color();
+ void setColor(QColor color);
+
+ QColor borderColor();
+ void setBorderColor(QColor color);
+
+ QColor labelColor();
+ void setLabelColor(QColor color);
+
+Q_SIGNALS:
+ void clicked(int index);
+ void hovered(bool status);
+ void hovered(bool status, int index);
+ void penChanged();
+ void brushChanged();
+ void labelChanged();
+ void labelBrushChanged();
+ void labelFontChanged();
+ void colorChanged(QColor color);
+ void borderColorChanged(QColor color);
+ void labelColorChanged(QColor color);
+
+ void valuesAdded(int index, int count);
+ void valuesRemoved(int index, int count);
+ void valueChanged(int index);
+
+private:
+ QScopedPointer<QBarSetPrivate> d_ptr;
+ Q_DISABLE_COPY(QBarSet)
+ friend class QAbstractBarSeries;
+ friend class BarLegendMarker;
+ friend class AbstractBarChartItem;
+ friend class QAbstractBarSeriesPrivate;
+ friend class StackedBarChartItem;
+ friend class PercentBarChartItem;
+ friend class BarChartItem;
+ friend class HorizontalBarChartItem;
+ friend class HorizontalStackedBarChartItem;
+ friend class HorizontalPercentBarChartItem;
+ friend class BoxPlotChartItem;
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QBARSET_H
diff --git a/src/charts/barchart/qbarset_p.h b/src/charts/barchart/qbarset_p.h
new file mode 100644
index 00000000..d0b03efa
--- /dev/null
+++ b/src/charts/barchart/qbarset_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QBARSET_P_H
+#define QBARSET_P_H
+
+#include <qbarset.h>
+#include <QMap>
+#include <QPen>
+#include <QBrush>
+#include <QFont>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QBarSetPrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QBarSetPrivate(const QString label, QBarSet *parent);
+ ~QBarSetPrivate();
+
+ void append(QPointF value);
+ void append(QList<QPointF> values);
+ void append(QList<qreal> values);
+
+ void insert(const int index, const qreal value);
+ void insert(const int index, const QPointF value);
+ int remove(const int index, const int count);
+
+ void replace(const int index, const qreal value);
+ void replace(const int index, const QPointF value);
+
+ qreal pos(const int index);
+ qreal value(const int index);
+
+Q_SIGNALS:
+ void restructuredBars();
+ void updatedBars();
+ void updatedLayout();
+
+public:
+ QBarSet * const q_ptr;
+ QString m_label;
+ QList<QPointF> m_values;
+ QPen m_pen;
+ QBrush m_brush;
+ QBrush m_labelBrush;
+ QFont m_labelFont;
+
+ friend class QBarSet;
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QBARSETPRIVATE_P_H
diff --git a/src/charts/barchart/qhbarmodelmapper.cpp b/src/charts/barchart/qhbarmodelmapper.cpp
new file mode 100644
index 00000000..0312df40
--- /dev/null
+++ b/src/charts/barchart/qhbarmodelmapper.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qhbarmodelmapper.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QHBarModelMapper
+ \inmodule Qt Charts
+ \brief Horizontal model mapper for bar series.
+ \mainclass
+
+ Model mappers allow you to use QAbstractItemModel derived models as a data source for a chart series.
+ Horizontal model mapper is used to create a connection between QAbstractBarSeries and QAbstractItemModel derived model object.
+ Model mapper maintains equal size of all the BarSets.
+ Adding/removing value from the BarSet causes the the same change in the rest of the BarSets added to the same series.
+ \note Used model has to support adding/removing rows/columns and modifying the data of the cells.
+*/
+/*!
+ \qmltype HBarModelMapper
+ \instantiates QHBarModelMapper
+ \inqmlmodule QtCharts
+
+ \brief Horizontal model mapper for bar series.
+
+ HBarModelMapper allows you to use your own QAbstractItemModel derived model with data in rows as
+ a data source for any bar series. It is possible to use both QAbstractItemModel and bar series
+ data API to manipulate data. HBarModelMapper keeps the series and the model in sync.
+
+ The following QML example would create a bar series with three bar sets (assuming the model has
+ at least four rows). Each bar set would contain data starting from column 1. The name of a set
+ would be defined by the vertical header (of the row).
+ \code
+ BarSeries {
+ HBarModelMapper {
+ model: myCustomModel // QAbstractItemModel derived implementation
+ firstBarSetRow: 1
+ lastBarSetRow: 3
+ firstColumn: 1
+ }
+ }
+ \endcode
+*/
+
+/*!
+ \property QHBarModelMapper::series
+ \brief Defines the QPieSeries object that is used by the mapper.
+
+ All the data in the series is discarded when it is set to the mapper.
+ When new series is specified the old series is disconnected (it preserves its data)
+*/
+/*!
+ \qmlproperty AbstractBarSeries HBarModelMapper::series
+ Defines the AbstractBarSeries based object that is used by the mapper. All the data in the series is discarded when it is
+ set to the mapper. When new series is specified the old series is disconnected (it preserves its data).
+*/
+
+/*!
+ \property QHBarModelMapper::model
+ \brief Defines the model that is used by the mapper.
+*/
+/*!
+ \qmlproperty SomeModel HBarModelMapper::model
+ The QAbstractItemModel based model that is used by the mapper. You need to implement the model
+ and expose it to QML. Note: the model has to support adding/removing rows/columns and modifying
+ the data of the cells.
+*/
+
+/*!
+ \property QHBarModelMapper::firstBarSetRow
+ \brief Defines which column of the model is used as the data source for the first bar set.
+
+ Default value is: -1 (invalid mapping)
+*/
+/*!
+ \qmlproperty int HBarModelMapper::firstBarSetRow
+ Defines which column of the model is used as the data source for the first bar set. The default value is -1
+ (invalid mapping).
+*/
+
+/*!
+ \property QHBarModelMapper::lastBarSetRow
+ \brief Defines which column of the model is used as the data source for the last bar set.
+
+ Default value is: -1 (invalid mapping)
+*/
+/*!
+ \qmlproperty int HBarModelMapper::lastBarSetRow
+ Defines which column of the model is used as the data source for the last bar set. The default value is -1
+ (invalid mapping).
+*/
+
+/*!
+ \property QHBarModelMapper::firstColumn
+ \brief Defines which column of the model contains the first values of the QBarSets in the series.
+
+ Minimal and default value is: 0
+*/
+/*!
+ \qmlproperty int HBarModelMapper::firstColumn
+ Defines which column of the model contains the first values of the QBarSets in the series.
+ The default value is 0.
+*/
+
+/*!
+ \property QHBarModelMapper::columnCount
+ \brief Defines the number of columns of the model that are mapped as the data for QAbstractBarSeries.
+
+ Minimal and default value is: -1 (count limited by the number of columns in the model)
+*/
+/*!
+ \qmlproperty int HBarModelMapper::columnCount
+ Defines the number of columns of the model that are mapped as the data for QAbstractBarSeries. The default value is
+ -1 (count limited by the number of columns in the model)
+*/
+
+/*!
+ \fn void QHBarModelMapper::seriesReplaced()
+
+ Emitted when the series to which mapper is connected to has changed.
+*/
+
+/*!
+ \fn void QHBarModelMapper::modelReplaced()
+
+ Emitted when the model to which mapper is connected to has changed.
+*/
+
+/*!
+ \fn void QHBarModelMapper::firstBarSetRowChanged()
+
+ Emitted when the firstBarSetRow has changed.
+*/
+
+/*!
+ \fn void QHBarModelMapper::lastBarSetRowChanged()
+
+ Emitted when the lastBarSetRow has changed.
+*/
+
+/*!
+ \fn void QHBarModelMapper::firstColumnChanged()
+ Emitted when the firstColumn has changed.
+*/
+
+/*!
+ \fn void QHBarModelMapper::columnCountChanged()
+ Emitted when the columnCount has changed.
+*/
+
+/*!
+ Constructs a mapper object which is a child of \a parent.
+*/
+QHBarModelMapper::QHBarModelMapper(QObject *parent) :
+ QBarModelMapper(parent)
+{
+ QBarModelMapper::setOrientation(Qt::Horizontal);
+}
+
+QAbstractItemModel *QHBarModelMapper::model() const
+{
+ return QBarModelMapper::model();
+}
+
+void QHBarModelMapper::setModel(QAbstractItemModel *model)
+{
+ if (model != QBarModelMapper::model()) {
+ QBarModelMapper::setModel(model);
+ emit modelReplaced();
+ }
+}
+
+QAbstractBarSeries *QHBarModelMapper::series() const
+{
+ return QBarModelMapper::series();
+}
+
+void QHBarModelMapper::setSeries(QAbstractBarSeries *series)
+{
+ if (series != QBarModelMapper::series()) {
+ QBarModelMapper::setSeries(series);
+ emit seriesReplaced();
+ }
+}
+
+int QHBarModelMapper::firstBarSetRow() const
+{
+ return QBarModelMapper::firstBarSetSection();
+}
+
+void QHBarModelMapper::setFirstBarSetRow(int firstBarSetRow)
+{
+ if (firstBarSetRow != firstBarSetSection()) {
+ QBarModelMapper::setFirstBarSetSection(firstBarSetRow);
+ emit firstBarSetRowChanged();
+ }
+}
+
+int QHBarModelMapper::lastBarSetRow() const
+{
+ return QBarModelMapper::lastBarSetSection();
+}
+
+void QHBarModelMapper::setLastBarSetRow(int lastBarSetRow)
+{
+ if (lastBarSetRow != lastBarSetSection()) {
+ QBarModelMapper::setLastBarSetSection(lastBarSetRow);
+ emit lastBarSetRowChanged();
+ }
+}
+
+int QHBarModelMapper::firstColumn() const
+{
+ return QBarModelMapper::first();
+}
+
+void QHBarModelMapper::setFirstColumn(int firstColumn)
+{
+ if (firstColumn != first()) {
+ QBarModelMapper::setFirst(firstColumn);
+ emit firstColumnChanged();
+ }
+}
+
+int QHBarModelMapper::columnCount() const
+{
+ return QBarModelMapper::count();
+}
+
+void QHBarModelMapper::setColumnCount(int columnCount)
+{
+ if (columnCount != count()) {
+ QBarModelMapper::setCount(columnCount);
+ emit columnCountChanged();
+ }
+}
+
+#include "moc_qhbarmodelmapper.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/qhbarmodelmapper.h b/src/charts/barchart/qhbarmodelmapper.h
new file mode 100644
index 00000000..ee281aef
--- /dev/null
+++ b/src/charts/barchart/qhbarmodelmapper.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QHBARMODELMAPPER_H
+#define QHBARMODELMAPPER_H
+
+#include <QtCharts/QBarModelMapper>
+
+QT_CHARTS_BEGIN_NAMESPACE
+/* Comment line for syncqt to generate the fwd-include correctly, due to QTBUG-22432 */
+class QT_CHARTS_EXPORT QHBarModelMapper : public QBarModelMapper
+{
+ Q_OBJECT
+ Q_PROPERTY(QAbstractBarSeries *series READ series WRITE setSeries NOTIFY seriesReplaced)
+ Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelReplaced)
+ Q_PROPERTY(int firstBarSetRow READ firstBarSetRow WRITE setFirstBarSetRow NOTIFY firstBarSetRowChanged)
+ Q_PROPERTY(int lastBarSetRow READ lastBarSetRow WRITE setLastBarSetRow NOTIFY lastBarSetRowChanged)
+ Q_PROPERTY(int firstColumn READ firstColumn WRITE setFirstColumn NOTIFY firstColumnChanged)
+ Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount NOTIFY columnCountChanged)
+
+public:
+ explicit QHBarModelMapper(QObject *parent = 0);
+
+ QAbstractItemModel *model() const;
+ void setModel(QAbstractItemModel *model);
+
+ QAbstractBarSeries *series() const;
+ void setSeries(QAbstractBarSeries *series);
+
+ int firstBarSetRow() const;
+ void setFirstBarSetRow(int firstBarSetRow);
+
+ int lastBarSetRow() const;
+ void setLastBarSetRow(int lastBarSetRow);
+
+ int firstColumn() const;
+ void setFirstColumn(int firstColumn);
+
+ int columnCount() const;
+ void setColumnCount(int columnCount);
+
+Q_SIGNALS:
+ void seriesReplaced();
+ void modelReplaced();
+ void firstBarSetRowChanged();
+ void lastBarSetRowChanged();
+ void firstColumnChanged();
+ void columnCountChanged();
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QHBARMODELMAPPER_H
diff --git a/src/charts/barchart/qvbarmodelmapper.cpp b/src/charts/barchart/qvbarmodelmapper.cpp
new file mode 100644
index 00000000..a239e696
--- /dev/null
+++ b/src/charts/barchart/qvbarmodelmapper.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qvbarmodelmapper.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QVBarModelMapper
+ \inmodule Qt Charts
+ \brief Vertical model mapper for bar series.
+ \mainclass
+
+ Model mappers allow you to use QAbstractItemModel derived models as a data source for a chart series.
+ Vertical model mapper is used to create a connection between QAbstractBarSeries and QAbstractItemModel derived model object.
+ Model mapper maintains equal size of all the BarSets.
+ Adding/removing value from the BarSet causes the the same change in the rest of the BarSets added to the same series.
+ \note Used model has to support adding/removing rows/columns and modifying the data of the cells.
+*/
+/*!
+ \qmltype VBarModelMapper
+ \instantiates QVBarModelMapper
+ \inqmlmodule QtCharts
+
+ \inherits BarModelMapper
+
+ \brief Vertical model mapper for bar series.
+
+ VBarModelMapper allows you to use your own QAbstractItemModel derived model with data in columns
+ as a data source for any bar series. It is possible to use both QAbstractItemModel and bar
+ series data API to manipulate data. VBarModelMapper keeps the series and the model in sync.
+
+ The following QML example would create a bar series with three bar sets (assuming the model has
+ at least four columns). Each bar set would contain data starting from row 1. The name of a set
+ would be defined by the horizontal header (of the column).
+ \code
+ BarSeries {
+ VBarModelMapper {
+ model: myCustomModel // QAbstractItemModel derived implementation
+ firstBarSetColumn: 1
+ lastBarSetColumn: 3
+ firstRow: 1
+ }
+ }
+ \endcode
+*/
+
+/*!
+ \property QVBarModelMapper::series
+ \brief Defines the QBarSeries object that is used by the mapper.
+
+ All the data in the series is discarded when it is set to the mapper.
+ When new series is specified the old series is disconnected (it preserves its data)
+*/
+/*!
+ \qmlproperty AbstractBarSeries VBarModelMapper::series
+ Defines the AbstractBarSeries based object that is used by the mapper. All the data in the series is discarded when it is
+ set to the mapper. When new series is specified the old series is disconnected (it preserves its data).
+*/
+
+/*!
+ \property QVBarModelMapper::model
+ \brief Defines the model that is used by the mapper.
+*/
+/*!
+ \qmlproperty SomeModel VBarModelMapper::model
+ The QAbstractItemModel based model that is used by the mapper. You need to implement the model
+ and expose it to QML. Note: the model has to support adding/removing rows/columns and modifying
+ the data of the cells.
+*/
+
+/*!
+ \property QVBarModelMapper::firstBarSetColumn
+ \brief Defines which column of the model is used as the data source for the first bar set.
+
+ Default value is: -1 (invalid mapping)
+*/
+/*!
+ \qmlproperty int VBarModelMapper::firstBarSetColumn
+ Defines which column of the model is used as the data source for the first bar set. Default value
+ is: -1 (invalid mapping).
+*/
+
+/*!
+ \property QVBarModelMapper::lastBarSetColumn
+ \brief Defines which column of the model is used as the data source for the last bar set.
+
+ Default value is: -1 (invalid mapping)
+*/
+/*!
+ \qmlproperty int VBarModelMapper::lastBarSetColumn
+ Defines which column of the model is used as the data source for the last bar set. Default
+ value is: -1 (invalid mapping).
+*/
+
+/*!
+ \property QVBarModelMapper::firstRow
+ \brief Defines which row of the model contains the first values of the QBarSets in the series.
+
+ Minimal and default value is: 0
+*/
+/*!
+ \qmlproperty int VBarModelMapper::firstRow
+ Defines which row of the model contains the first values of the QBarSets in the series.
+ The default value is 0.
+*/
+
+/*!
+ \property QVBarModelMapper::rowCount
+ \brief Defines the number of rows of the model that are mapped as the data for QAbstractBarSeries.
+
+ Minimal and default value is: -1 (count limited by the number of rows in the model)
+*/
+/*!
+ \qmlproperty int VBarModelMapper::rowCount
+ Defines the number of rows of the model that are mapped as the data for QAbstractBarSeries. The default value is
+ -1 (count limited by the number of rows in the model)
+*/
+
+/*!
+ \fn void QVBarModelMapper::seriesReplaced()
+
+ Emitted when the series to which mapper is connected to has changed.
+*/
+
+/*!
+ \fn void QVBarModelMapper::modelReplaced()
+
+ Emitted when the model to which mapper is connected to has changed.
+*/
+
+/*!
+ \fn void QVBarModelMapper::firstBarSetColumnChanged()
+ Emitted when the firstBarSetColumn has changed.
+*/
+
+/*!
+ \fn void QVBarModelMapper::lastBarSetColumnChanged()
+ Emitted when the lastBarSetColumn has changed.
+*/
+
+/*!
+ \fn void QVBarModelMapper::firstRowChanged()
+ Emitted when the firstRow has changed.
+*/
+
+/*!
+ \fn void QVBarModelMapper::rowCountChanged()
+ Emitted when the rowCount has changed.
+*/
+
+/*!
+ Constructs a mapper object which is a child of \a parent.
+*/
+QVBarModelMapper::QVBarModelMapper(QObject *parent) :
+ QBarModelMapper(parent)
+{
+ QBarModelMapper::setOrientation(Qt::Vertical);
+}
+
+QAbstractItemModel *QVBarModelMapper::model() const
+{
+ return QBarModelMapper::model();
+}
+
+void QVBarModelMapper::setModel(QAbstractItemModel *model)
+{
+ if (model != QBarModelMapper::model()) {
+ QBarModelMapper::setModel(model);
+ emit modelReplaced();
+ }
+}
+
+QAbstractBarSeries *QVBarModelMapper::series() const
+{
+ return QBarModelMapper::series();
+}
+
+void QVBarModelMapper::setSeries(QAbstractBarSeries *series)
+{
+ if (series != QBarModelMapper::series()) {
+ QBarModelMapper::setSeries(series);
+ emit seriesReplaced();
+ }
+}
+
+int QVBarModelMapper::firstBarSetColumn() const
+{
+ return QBarModelMapper::firstBarSetSection();
+}
+
+void QVBarModelMapper::setFirstBarSetColumn(int firstBarSetColumn)
+{
+ if (firstBarSetColumn != firstBarSetSection()) {
+ QBarModelMapper::setFirstBarSetSection(firstBarSetColumn);
+ emit firstBarSetColumnChanged();
+ }
+}
+
+int QVBarModelMapper::lastBarSetColumn() const
+{
+ return QBarModelMapper::lastBarSetSection();
+}
+
+void QVBarModelMapper::setLastBarSetColumn(int lastBarSetColumn)
+{
+ if (lastBarSetColumn != lastBarSetSection()) {
+ QBarModelMapper::setLastBarSetSection(lastBarSetColumn);
+ emit lastBarSetColumnChanged();
+ }
+}
+
+int QVBarModelMapper::firstRow() const
+{
+ return QBarModelMapper::first();
+}
+
+void QVBarModelMapper::setFirstRow(int firstRow)
+{
+ if (firstRow != first()) {
+ QBarModelMapper::setFirst(firstRow);
+ emit firstRowChanged();
+ }
+}
+
+int QVBarModelMapper::rowCount() const
+{
+ return QBarModelMapper::count();
+}
+
+void QVBarModelMapper::setRowCount(int rowCount)
+{
+ if (rowCount != count()) {
+ QBarModelMapper::setCount(rowCount);
+ emit rowCountChanged();
+ }
+}
+
+#include "moc_qvbarmodelmapper.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/qvbarmodelmapper.h b/src/charts/barchart/qvbarmodelmapper.h
new file mode 100644
index 00000000..5f16ac72
--- /dev/null
+++ b/src/charts/barchart/qvbarmodelmapper.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QVBARMODELMAPPER_H
+#define QVBARMODELMAPPER_H
+
+#include <QtCharts/QBarModelMapper>
+
+QT_CHARTS_BEGIN_NAMESPACE
+/* Comment line for syncqt to generate the fwd-include correctly, due to QTBUG-22432 */
+class QT_CHARTS_EXPORT QVBarModelMapper : public QBarModelMapper
+{
+ Q_OBJECT
+ Q_PROPERTY(QAbstractBarSeries *series READ series WRITE setSeries NOTIFY seriesReplaced)
+ Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelReplaced)
+ Q_PROPERTY(int firstBarSetColumn READ firstBarSetColumn WRITE setFirstBarSetColumn NOTIFY firstBarSetColumnChanged)
+ Q_PROPERTY(int lastBarSetColumn READ lastBarSetColumn WRITE setLastBarSetColumn NOTIFY lastBarSetColumnChanged)
+ Q_PROPERTY(int firstRow READ firstRow WRITE setFirstRow NOTIFY firstRowChanged)
+ Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount NOTIFY rowCountChanged)
+
+public:
+ explicit QVBarModelMapper(QObject *parent = 0);
+
+ QAbstractItemModel *model() const;
+ void setModel(QAbstractItemModel *model);
+
+ QAbstractBarSeries *series() const;
+ void setSeries(QAbstractBarSeries *series);
+
+ int firstBarSetColumn() const;
+ void setFirstBarSetColumn(int firstBarSetColumn);
+
+ int lastBarSetColumn() const;
+ void setLastBarSetColumn(int lastBarSetColumn);
+
+ int firstRow() const;
+ void setFirstRow(int firstRow);
+
+ int rowCount() const;
+ void setRowCount(int rowCount);
+
+Q_SIGNALS:
+ void seriesReplaced();
+ void modelReplaced();
+ void firstBarSetColumnChanged();
+ void lastBarSetColumnChanged();
+ void firstRowChanged();
+ void rowCountChanged();
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QVBARMODELMAPPER_H
diff --git a/src/charts/barchart/vertical/bar/barchartitem.cpp b/src/charts/barchart/vertical/bar/barchartitem.cpp
new file mode 100644
index 00000000..86b63045
--- /dev/null
+++ b/src/charts/barchart/vertical/bar/barchartitem.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "barchartitem_p.h"
+#include "bar_p.h"
+#include "qabstractbarseries_p.h"
+#include "qbarset.h"
+#include "qbarset_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+BarChartItem::BarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
+ AbstractBarChartItem(series, item)
+{
+ connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
+ this, SLOT(handleLabelsPositionChanged()));
+ connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
+}
+
+void BarChartItem::initializeLayout()
+{
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ m_layout.clear();
+ for(int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QRectF rect;
+ QPointF topLeft;
+ QPointF bottomRight;
+
+ if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
+ topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, domain()->minY()), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, domain()->minY()), m_validData);
+ } else {
+ topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + set/setCount * barWidth, 0), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/setCount * barWidth, 0), m_validData);
+ }
+
+ if (!m_validData)
+ return;
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ m_layout.append(rect.normalized());
+ }
+ }
+}
+
+QVector<QRectF> BarChartItem::calculateLayout()
+{
+ QVector<QRectF> layout;
+
+ // Use temporary qreals for accuracy
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ for(int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ qreal value = m_series->barSets().at(set)->at(category);
+ QRectF rect;
+ QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set)/(setCount) * barWidth, value), m_validData);
+ QPointF bottomRight;
+ if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, domain()->minY()), m_validData);
+ else
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2 + (set + 1)/(setCount) * barWidth, 0), m_validData);
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ layout.append(rect.normalized());
+ }
+ }
+
+ return layout;
+}
+
+void BarChartItem::handleLabelsPositionChanged()
+{
+ positionLabels();
+}
+
+void BarChartItem::positionLabels()
+{
+ for (int i = 0; i < m_layout.count(); i++) {
+ QGraphicsTextItem *label = m_labels.at(i);
+ qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
+ qreal yPos = 0;
+
+ int offset = m_bars.at(i)->pen().width() / 2 + 2;
+ if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
+ yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
+ yPos = m_layout.at(i).top() - offset;
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
+ yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
+ yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
+
+ label->setPos(xPos, yPos);
+ label->setZValue(zValue() + 1);
+ }
+}
+
+#include "moc_barchartitem_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/vertical/bar/barchartitem_p.h b/src/charts/barchart/vertical/bar/barchartitem_p.h
new file mode 100644
index 00000000..09df0dbf
--- /dev/null
+++ b/src/charts/barchart/vertical/bar/barchartitem_p.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 BARCHARTITEM_H
+#define BARCHARTITEM_H
+
+#include "abstractbarchartitem_p.h"
+#include <qstackedbarseries.h>
+#include <QGraphicsItem>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class BarChartItem : public AbstractBarChartItem
+{
+ Q_OBJECT
+public:
+ BarChartItem(QAbstractBarSeries *series, QGraphicsItem* item = 0);
+
+private slots:
+ void handleLabelsPositionChanged();
+ void positionLabels();
+
+private:
+ virtual QVector<QRectF> calculateLayout();
+ void initializeLayout();
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // BARCHARTITEM_H
diff --git a/src/charts/barchart/vertical/bar/qbarseries.cpp b/src/charts/barchart/vertical/bar/qbarseries.cpp
new file mode 100644
index 00000000..3ab2a1ee
--- /dev/null
+++ b/src/charts/barchart/vertical/bar/qbarseries.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qbarseries.h"
+#include "qbarseries_p.h"
+#include "barchartitem_p.h"
+#include "chartdataset_p.h"
+#include "charttheme_p.h"
+#include "qvalueaxis.h"
+#include "qbarcategoryaxis.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QBarSeries
+ \inmodule Qt Charts
+ \brief Series for creating bar chart.
+ \mainclass
+
+ QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
+ as groups, where bars in same category are grouped next to each other. QBarSeries groups the data
+ from sets to categories, which are defined by a QStringList.
+
+ See the \l {BarChart Example} {bar chart example} to learn how to create a grouped bar chart.
+ \image examples_barchart.png
+
+ \sa QBarSet, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries
+*/
+/*!
+ \qmltype BarSeries
+ \instantiates QBarSeries
+ \inqmlmodule QtCharts
+
+ \inherits AbstractBarSeries
+
+ \brief Series for creating bar chart.
+
+ The following QML shows how to create a simple grouped bar chart:
+ \snippet qmlchart/qml/qmlchart/View6.qml 1
+ \beginfloatleft
+ \image examples_qmlchart6.png
+ \endfloat
+ \clearfloat
+*/
+
+/*!
+ Constructs empty QBarSeries.
+ QBarSeries is QObject which is a child of a \a parent.
+*/
+QBarSeries::QBarSeries(QObject *parent)
+ : QAbstractBarSeries(*new QBarSeriesPrivate(this), parent)
+{
+
+}
+
+/*!
+ Returns QAbstractSeries::SeriesTypeBar.
+*/
+QAbstractSeries::SeriesType QBarSeries::type() const
+{
+ return QAbstractSeries::SeriesTypeBar;
+}
+
+/*!
+ Destructor. Removes series from chart.
+*/
+QBarSeries::~QBarSeries()
+{
+ Q_D(QBarSeries);
+ if (d->m_chart)
+ d->m_chart->removeSeries(this);
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) : QAbstractBarSeriesPrivate(q)
+{
+
+}
+
+void QBarSeriesPrivate::initializeDomain()
+{
+ qreal minX(domain()->minX());
+ qreal minY(domain()->minY());
+ qreal maxX(domain()->maxX());
+ qreal maxY(domain()->maxY());
+
+ qreal x = categoryCount();
+ minX = qMin(minX, - (qreal)0.5);
+ minY = qMin(minY, min());
+ maxX = qMax(maxX, x - (qreal)0.5);
+ maxY = qMax(maxY, max());
+
+ domain()->setRange(minX, maxX, minY, maxY);
+}
+
+
+void QBarSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
+{
+ Q_Q(QBarSeries);
+ BarChartItem *bar = new BarChartItem(q,parent);
+ m_item.reset(bar);
+ QAbstractSeriesPrivate::initializeGraphics(parent);
+}
+
+#include "moc_qbarseries.cpp"
+
+QT_CHARTS_END_NAMESPACE
+
diff --git a/src/charts/barchart/vertical/bar/qbarseries.h b/src/charts/barchart/vertical/bar/qbarseries.h
new file mode 100644
index 00000000..d3fefd8a
--- /dev/null
+++ b/src/charts/barchart/vertical/bar/qbarseries.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QBARSERIES_H
+#define QBARSERIES_H
+
+#include <QtCharts/qabstractbarseries.h>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QBarSeriesPrivate;
+
+class QT_CHARTS_EXPORT QBarSeries : public QAbstractBarSeries
+{
+ Q_OBJECT
+public:
+ explicit QBarSeries(QObject *parent = 0);
+ ~QBarSeries();
+ QAbstractSeries::SeriesType type() const;
+
+private:
+ Q_DECLARE_PRIVATE(QBarSeries)
+ Q_DISABLE_COPY(QBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QBARSERIES_H
diff --git a/src/charts/barchart/vertical/bar/qbarseries_p.h b/src/charts/barchart/vertical/bar/qbarseries_p.h
new file mode 100644
index 00000000..c74194d3
--- /dev/null
+++ b/src/charts/barchart/vertical/bar/qbarseries_p.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QBARSERIES_P_H
+#define QBARSERIES_P_H
+
+#include "qabstractbarseries_p.h"
+#include "abstractdomain_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+
+class QBarSeriesPrivate: public QAbstractBarSeriesPrivate
+{
+public:
+ QBarSeriesPrivate(QBarSeries *q);
+ void initializeGraphics(QGraphicsItem* parent);
+ void initializeDomain();
+
+private:
+ Q_DECLARE_PUBLIC(QBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QBARSERIES_P_H
diff --git a/src/charts/barchart/vertical/percent/percentbarchartitem.cpp b/src/charts/barchart/vertical/percent/percentbarchartitem.cpp
new file mode 100644
index 00000000..1e0bbbae
--- /dev/null
+++ b/src/charts/barchart/vertical/percent/percentbarchartitem.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "percentbarchartitem_p.h"
+#include "bar_p.h"
+#include "qabstractbarseries_p.h"
+#include "qbarset.h"
+#include "qbarset_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+PercentBarChartItem::PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
+ AbstractBarChartItem(series, item)
+{
+ connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
+ this, SLOT(handleLabelsPositionChanged()));
+ connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
+}
+
+void PercentBarChartItem::initializeLayout()
+{
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ m_layout.clear();
+ for(int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QRectF rect;
+ QPointF topLeft;
+ QPointF bottomRight;
+
+ if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
+ topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
+ } else {
+ topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
+ }
+
+ if (!m_validData)
+ return;
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ m_layout.append(rect.normalized());
+ }
+ }
+}
+
+QVector<QRectF> PercentBarChartItem::calculateLayout()
+{
+ QVector<QRectF> layout;
+
+ // Use temporary qreals for accuracy
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ for(int category = 0; category < categoryCount; category++) {
+ qreal sum = 0;
+ qreal categorySum = m_series->d_func()->categorySum(category);
+ for (int set = 0; set < setCount; set++) {
+ qreal value = m_series->barSets().at(set)->at(category);
+ QRectF rect;
+ qreal topY = 0;
+ qreal newSum = value + sum;
+ if (newSum > 0)
+ topY = 100 * newSum / categorySum;
+ qreal bottomY = 0;
+ if (sum > 0)
+ bottomY = 100 * sum / categorySum;
+ QPointF topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth/2, topY), m_validData);
+ QPointF bottomRight;
+ if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : domain()->minY()), m_validData);
+ else
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth/2, set ? bottomY : 0), m_validData);
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ layout.append(rect.normalized());
+ sum = newSum;
+ }
+ }
+ return layout;
+}
+
+void PercentBarChartItem::handleUpdatedBars()
+{
+ // Handle changes in pen, brush, labels etc.
+ int categoryCount = m_series->d_func()->categoryCount();
+ int setCount = m_series->count();
+ int itemIndex(0);
+ static const QString valueTag(QLatin1String("@value"));
+
+ for (int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QBarSetPrivate *barSet = m_series->d_func()->barsetAt(set)->d_ptr.data();
+ Bar *bar = m_bars.at(itemIndex);
+ bar->setPen(barSet->m_pen);
+ bar->setBrush(barSet->m_brush);
+ bar->update();
+
+ QGraphicsTextItem *label = m_labels.at(itemIndex);
+ qreal p = m_series->d_func()->percentageAt(set, category) * 100.0;
+ QString vString(presenter()->numberToString(p, 'f', 0));
+ QString valueLabel;
+ if (m_series->labelsFormat().isEmpty()) {
+ vString.append(QStringLiteral("%"));
+ valueLabel = vString;
+ } else {
+ valueLabel = m_series->labelsFormat();
+ valueLabel.replace(valueTag, vString);
+ }
+ label->setHtml(valueLabel);
+ label->setFont(barSet->m_labelFont);
+ label->setDefaultTextColor(barSet->m_labelBrush.color());
+ label->update();
+ itemIndex++;
+ }
+ }
+}
+
+void PercentBarChartItem::handleLabelsPositionChanged()
+{
+ positionLabels();
+}
+
+void PercentBarChartItem::positionLabels()
+{
+ for (int i = 0; i < m_layout.count(); i++) {
+ QGraphicsTextItem *label = m_labels.at(i);
+ qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
+ qreal yPos = 0;
+
+ int offset = m_bars.at(i)->pen().width() / 2 + 2;
+ if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
+ yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
+ yPos = m_layout.at(i).top() - offset;
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
+ yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
+ yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
+
+ label->setPos(xPos, yPos);
+ label->setZValue(zValue() + 1);
+ }
+}
+
+#include "moc_percentbarchartitem_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/vertical/percent/percentbarchartitem_p.h b/src/charts/barchart/vertical/percent/percentbarchartitem_p.h
new file mode 100644
index 00000000..4293d875
--- /dev/null
+++ b/src/charts/barchart/vertical/percent/percentbarchartitem_p.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 PERCENTBARCHARTITEM_H
+#define PERCENTBARCHARTITEM_H
+
+#include "abstractbarchartitem_p.h"
+#include <QGraphicsItem>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QAbstractBarSeries;
+
+class PercentBarChartItem : public AbstractBarChartItem
+{
+ Q_OBJECT
+public:
+ PercentBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item = 0);
+ void handleUpdatedBars();
+
+private slots:
+ void handleLabelsPositionChanged();
+ void positionLabels();
+
+private:
+ virtual QVector<QRectF> calculateLayout();
+ void initializeLayout();
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // PERCENTBARCHARTITEM_H
diff --git a/src/charts/barchart/vertical/percent/qpercentbarseries.cpp b/src/charts/barchart/vertical/percent/qpercentbarseries.cpp
new file mode 100644
index 00000000..7899899b
--- /dev/null
+++ b/src/charts/barchart/vertical/percent/qpercentbarseries.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qpercentbarseries.h"
+#include "qpercentbarseries_p.h"
+#include "percentbarchartitem_p.h"
+#include "chartdataset_p.h"
+#include "charttheme_p.h"
+#include "qvalueaxis.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QPercentBarSeries
+ \inmodule Qt Charts
+ \brief Series for creating percent bar chart.
+ \mainclass
+
+ QPercentBarSeries represents a series of data shown as bars. The purpose of this class is to
+ draw bars as stacks, where each bar is shown as percentage of all bars in that category.
+ QPercentBarSeries groups the data from sets to categories, which are defined by a QStringList.
+ Bars with zero value are not drawn.
+
+ See the \l {PercentbarChart Example} {percent bar chart example} to learn how to create a
+ percent bar chart.
+ \image examples_percentbarchart.png
+
+ \sa QBarSet, QStackedBarSeries, QAbstractBarSeries
+*/
+/*!
+ \qmltype PercentBarSeries
+ \instantiates QPercentBarSeries
+ \inqmlmodule QtCharts
+
+ \inherits AbstractBarSeries
+
+ \brief Series for creating persent bar chart.
+
+ The following QML shows how to create a simple percent bar chart:
+ \snippet qmlchart/qml/qmlchart/View8.qml 1
+ \beginfloatleft
+ \image examples_qmlchart8.png
+ \endfloat
+ \clearfloat
+*/
+
+/*!
+ Constructs empty QPercentBarSeries.
+ QPercentBarSeries is QObject which is a child of a \a parent.
+*/
+QPercentBarSeries::QPercentBarSeries(QObject *parent)
+ : QAbstractBarSeries(*new QPercentBarSeriesPrivate(this), parent)
+{
+}
+
+/*!
+ Destructor. Removes series from chart.
+*/
+QPercentBarSeries::~QPercentBarSeries()
+{
+ Q_D(QPercentBarSeries);
+ if (d->m_chart)
+ d->m_chart->removeSeries(this);
+}
+
+/*!
+ Returns QAbstractSeries::SeriesTypePercentBar.
+*/
+QAbstractSeries::SeriesType QPercentBarSeries::type() const
+{
+ return QAbstractSeries::SeriesTypePercentBar;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QPercentBarSeriesPrivate::QPercentBarSeriesPrivate(QPercentBarSeries *q) : QAbstractBarSeriesPrivate(q)
+{
+
+}
+
+void QPercentBarSeriesPrivate::initializeDomain()
+{
+ qreal minX(domain()->minX());
+ qreal minY(domain()->minY());
+ qreal maxX(domain()->maxX());
+ qreal maxY(domain()->maxY());
+
+ qreal x = categoryCount();
+ minX = qMin(minX, - (qreal)0.5);
+ maxX = qMax(maxX, x - (qreal)0.5);
+ minY = 0;
+ maxY = 100;
+
+ domain()->setRange(minX, maxX, minY, maxY);
+}
+
+
+void QPercentBarSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
+{
+ Q_Q(QPercentBarSeries);
+ PercentBarChartItem *bar = new PercentBarChartItem(q,parent);
+ m_item.reset(bar);
+ QAbstractSeriesPrivate::initializeGraphics(parent);
+}
+
+#include "moc_qpercentbarseries.cpp"
+
+QT_CHARTS_END_NAMESPACE
+
diff --git a/src/charts/barchart/vertical/percent/qpercentbarseries.h b/src/charts/barchart/vertical/percent/qpercentbarseries.h
new file mode 100644
index 00000000..5f9ce140
--- /dev/null
+++ b/src/charts/barchart/vertical/percent/qpercentbarseries.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QPERCENTBARSERIES_H
+#define QPERCENTBARSERIES_H
+
+#include <QStringList>
+#include <QtCharts/qabstractbarseries.h>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QPercentBarSeriesPrivate;
+
+class QT_CHARTS_EXPORT QPercentBarSeries : public QAbstractBarSeries
+{
+ Q_OBJECT
+public:
+ explicit QPercentBarSeries(QObject *parent = 0);
+ ~QPercentBarSeries();
+ QAbstractSeries::SeriesType type() const;
+
+private:
+ Q_DECLARE_PRIVATE(QPercentBarSeries)
+ Q_DISABLE_COPY(QPercentBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QPERCENTBARSERIES_H
diff --git a/src/charts/barchart/vertical/percent/qpercentbarseries_p.h b/src/charts/barchart/vertical/percent/qpercentbarseries_p.h
new file mode 100644
index 00000000..f31c9638
--- /dev/null
+++ b/src/charts/barchart/vertical/percent/qpercentbarseries_p.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QPERCENTBARSERIES_P_H
+#define QPERCENTBARSERIES_P_H
+
+#include "qabstractbarseries_p.h"
+#include "abstractdomain_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+
+class QPercentBarSeriesPrivate: public QAbstractBarSeriesPrivate
+{
+public:
+ QPercentBarSeriesPrivate(QPercentBarSeries *q);
+ void initializeDomain();
+ void initializeGraphics(QGraphicsItem* parent);
+private:
+ Q_DECLARE_PUBLIC(QPercentBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif
diff --git a/src/charts/barchart/vertical/stacked/qstackedbarseries.cpp b/src/charts/barchart/vertical/stacked/qstackedbarseries.cpp
new file mode 100644
index 00000000..7a1946f7
--- /dev/null
+++ b/src/charts/barchart/vertical/stacked/qstackedbarseries.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "qstackedbarseries.h"
+#include "qstackedbarseries_p.h"
+#include "stackedbarchartitem_p.h"
+#include "chartdataset_p.h"
+#include "charttheme_p.h"
+#include "qvalueaxis.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QStackedBarSeries
+ \inmodule Qt Charts
+ \brief Series for creating stacked bar chart.
+ \mainclass
+
+ QStackedBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
+ as stacks, where bars in same category are stacked on top of each other.
+ QStackedBarSeries groups the data from sets to categories, which are defined by QStringList.
+
+ See the \l {StackedbarChart Example} {stacked bar chart example} to learn how to create a stacked bar chart.
+ \image examples_stackedbarchart.png
+
+ \sa QBarSet, QPercentBarSeries, QAbstractBarSeries
+*/
+
+/*!
+ \qmltype StackedBarSeries
+ \instantiates QStackedBarSeries
+ \inqmlmodule QtCharts
+
+ \inherits AbstractBarSeries
+
+ \brief Series for creating stacked bar chart.
+
+ The following QML shows how to create a simple stacked bar chart:
+ \snippet qmlchart/qml/qmlchart/View7.qml 1
+ \beginfloatleft
+ \image examples_qmlchart7.png
+ \endfloat
+ \clearfloat
+*/
+
+/*!
+ Constructs empty QStackedBarSeries.
+ QStackedBarSeries is QObject which is a child of a \a parent.
+*/
+QStackedBarSeries::QStackedBarSeries(QObject *parent)
+ : QAbstractBarSeries(*new QStackedBarSeriesPrivate(this), parent)
+{
+}
+
+/*!
+ Destructor. Removes series from chart.
+*/
+QStackedBarSeries::~QStackedBarSeries()
+{
+ Q_D(QStackedBarSeries);
+ if (d->m_chart)
+ d->m_chart->removeSeries(this);
+}
+/*!
+ Returns QAbstractSeries::SeriesTypeStackedBar.
+*/
+QAbstractSeries::SeriesType QStackedBarSeries::type() const
+{
+ return QAbstractSeries::SeriesTypeStackedBar;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QStackedBarSeries *q) : QAbstractBarSeriesPrivate(q)
+{
+
+}
+
+void QStackedBarSeriesPrivate::initializeDomain()
+{
+ qreal minX(domain()->minX());
+ qreal minY(domain()->minY());
+ qreal maxX(domain()->maxX());
+ qreal maxY(domain()->maxY());
+
+ qreal x = categoryCount();
+ minX = qMin(minX, - (qreal)0.5);
+ minY = qMin(minY, bottom());
+ maxX = qMax(maxX, x - (qreal)0.5);
+ maxY = qMax(maxY, top());
+
+ domain()->setRange(minX, maxX, minY, maxY);
+}
+
+void QStackedBarSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
+{
+ Q_Q(QStackedBarSeries);
+ StackedBarChartItem *bar = new StackedBarChartItem(q,parent);
+ m_item.reset(bar);
+ QAbstractSeriesPrivate::initializeGraphics(parent);
+}
+
+#include "moc_qstackedbarseries.cpp"
+
+QT_CHARTS_END_NAMESPACE
+
diff --git a/src/charts/barchart/vertical/stacked/qstackedbarseries.h b/src/charts/barchart/vertical/stacked/qstackedbarseries.h
new file mode 100644
index 00000000..bab6e174
--- /dev/null
+++ b/src/charts/barchart/vertical/stacked/qstackedbarseries.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 QSTACKEDBARSERIES_H
+#define QSTACKEDBARSERIES_H
+
+#include <QStringList>
+#include <QtCharts/qabstractbarseries.h>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class QStackedBarSeriesPrivate;
+
+class QT_CHARTS_EXPORT QStackedBarSeries : public QAbstractBarSeries
+{
+ Q_OBJECT
+public:
+ explicit QStackedBarSeries(QObject *parent = 0);
+ ~QStackedBarSeries();
+ QAbstractSeries::SeriesType type() const;
+
+private:
+ Q_DECLARE_PRIVATE(QStackedBarSeries)
+ Q_DISABLE_COPY(QStackedBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // QSTACKEDBARSERIES_H
diff --git a/src/charts/barchart/vertical/stacked/qstackedbarseries_p.h b/src/charts/barchart/vertical/stacked/qstackedbarseries_p.h
new file mode 100644
index 00000000..d5cf3c2d
--- /dev/null
+++ b/src/charts/barchart/vertical/stacked/qstackedbarseries_p.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 QSTACKEDBARSERIES_P_H
+#define QSTACKEDBARSERIES_P_H
+
+#include "qabstractbarseries_p.h"
+#include "abstractdomain_p.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+
+class QStackedBarSeriesPrivate: public QAbstractBarSeriesPrivate
+{
+public:
+ QStackedBarSeriesPrivate(QStackedBarSeries *q);
+ void initializeGraphics(QGraphicsItem* parent);
+ void initializeDomain();
+private:
+ Q_DECLARE_PUBLIC(QStackedBarSeries)
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif
diff --git a/src/charts/barchart/vertical/stacked/stackedbarchartitem.cpp b/src/charts/barchart/vertical/stacked/stackedbarchartitem.cpp
new file mode 100644
index 00000000..953bb455
--- /dev/null
+++ b/src/charts/barchart/vertical/stacked/stackedbarchartitem.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 "stackedbarchartitem_p.h"
+#include "bar_p.h"
+#include "qbarset_p.h"
+#include "qabstractbarseries_p.h"
+#include "qbarset.h"
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+StackedBarChartItem::StackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item) :
+ AbstractBarChartItem(series, item)
+{
+ connect(series, SIGNAL(labelsPositionChanged(QAbstractBarSeries::LabelsPosition)),
+ this, SLOT(handleLabelsPositionChanged()));
+ connect(series, SIGNAL(labelsFormatChanged(QString)), this, SLOT(positionLabels()));
+}
+
+void StackedBarChartItem::initializeLayout()
+{
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ m_layout.clear();
+ for(int category = 0; category < categoryCount; category++) {
+ for (int set = 0; set < setCount; set++) {
+ QRectF rect;
+ QPointF topLeft;
+ QPointF bottomRight;
+
+ if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain) {
+ topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, domain()->minY()), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, domain()->minY()), m_validData);
+ } else {
+ topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, 0), m_validData);
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, 0), m_validData);
+ }
+
+ if (!m_validData)
+ return;
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ m_layout.append(rect.normalized());
+ }
+ }
+}
+
+QVector<QRectF> StackedBarChartItem::calculateLayout()
+{
+ QVector<QRectF> layout;
+ // Use temporary qreals for accuracy
+ qreal categoryCount = m_series->d_func()->categoryCount();
+ qreal setCount = m_series->count();
+ qreal barWidth = m_series->d_func()->barWidth();
+
+ for(int category = 0; category < categoryCount; category++) {
+ qreal positiveSum = 0;
+ qreal negativeSum = 0;
+ for (int set = 0; set < setCount; set++) {
+ qreal value = m_series->barSets().at(set)->at(category);
+ QRectF rect;
+ QPointF topLeft;
+ QPointF bottomRight;
+ if (value < 0) {
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + negativeSum), m_validData);
+ if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
+ topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : domain()->minY()), m_validData);
+ else
+ topLeft = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? negativeSum : 0), m_validData);
+ negativeSum += value;
+ } else {
+ topLeft = domain()->calculateGeometryPoint(QPointF(category - barWidth / 2, value + positiveSum), m_validData);
+ if (domain()->type() == AbstractDomain::XLogYDomain || domain()->type() == AbstractDomain::LogXLogYDomain)
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : domain()->minY()), m_validData);
+ else
+ bottomRight = domain()->calculateGeometryPoint(QPointF(category + barWidth / 2, set ? positiveSum : 0), m_validData);
+ positiveSum += value;
+ }
+
+ rect.setTopLeft(topLeft);
+ rect.setBottomRight(bottomRight);
+ layout.append(rect.normalized());
+ }
+ }
+ return layout;
+}
+
+void StackedBarChartItem::handleLabelsPositionChanged()
+{
+ positionLabels();
+}
+
+void StackedBarChartItem::positionLabels()
+{
+ for (int i = 0; i < m_layout.count(); i++) {
+ QGraphicsTextItem *label = m_labels.at(i);
+ qreal xPos = m_layout.at(i).center().x() - label->boundingRect().center().x();
+ qreal yPos = 0;
+
+ int offset = m_bars.at(i)->pen().width() / 2 + 2;
+ if (m_series->labelsPosition() == QAbstractBarSeries::LabelsCenter)
+ yPos = m_layout.at(i).center().y() - label->boundingRect().center().y();
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideEnd)
+ yPos = m_layout.at(i).top() - offset;
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsInsideBase)
+ yPos = m_layout.at(i).bottom() - label->boundingRect().height() + offset;
+ else if (m_series->labelsPosition() == QAbstractBarSeries::LabelsOutsideEnd)
+ yPos = m_layout.at(i).top() - label->boundingRect().height() + offset;
+
+ label->setPos(xPos, yPos);
+ label->setZValue(zValue() + 1);
+ }
+}
+
+#include "moc_stackedbarchartitem_p.cpp"
+
+QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/barchart/vertical/stacked/stackedbarchartitem_p.h b/src/charts/barchart/vertical/stacked/stackedbarchartitem_p.h
new file mode 100644
index 00000000..f2fa6b73
--- /dev/null
+++ b/src/charts/barchart/vertical/stacked/stackedbarchartitem_p.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 Enterprise Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise 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 Qt Enterprise 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 STACKEDBARCHARTITEM_H
+#define STACKEDBARCHARTITEM_H
+
+#include "abstractbarchartitem_p.h"
+#include <qstackedbarseries.h>
+#include <QGraphicsItem>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+class StackedBarChartItem : public AbstractBarChartItem
+{
+ Q_OBJECT
+public:
+ StackedBarChartItem(QAbstractBarSeries *series, QGraphicsItem* item =0);
+
+private slots:
+ void handleLabelsPositionChanged();
+ void positionLabels();
+
+private:
+ virtual QVector<QRectF> calculateLayout();
+ void initializeLayout();
+
+};
+
+QT_CHARTS_END_NAMESPACE
+
+#endif // STACKEDBARCHARTITEM_H