summaryrefslogtreecommitdiffstats
path: root/src/charts/barchart/abstractbarchartitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/charts/barchart/abstractbarchartitem.cpp')
-rw-r--r--src/charts/barchart/abstractbarchartitem.cpp268
1 files changed, 268 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