diff options
Diffstat (limited to 'src/charts/boxplotchart/boxwhiskers.cpp')
-rw-r--r-- | src/charts/boxplotchart/boxwhiskers.cpp | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/charts/boxplotchart/boxwhiskers.cpp b/src/charts/boxplotchart/boxwhiskers.cpp new file mode 100644 index 00000000..1e78d127 --- /dev/null +++ b/src/charts/boxplotchart/boxwhiskers.cpp @@ -0,0 +1,194 @@ +/**************************************************************************** + ** + ** 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 "boxwhiskers_p.h" +#include <QPainter> +#include <QWidget> + +QT_CHARTS_BEGIN_NAMESPACE + +BoxWhiskers::BoxWhiskers(QBoxSet *set, AbstractDomain *domain, QGraphicsObject *parent) : + QGraphicsObject(parent), + m_boxSet(set), + m_domain(domain) +{ + setAcceptHoverEvents(true); + setAcceptedMouseButtons(Qt::MouseButtonMask); +} + +BoxWhiskers::~BoxWhiskers() +{ +} + +void BoxWhiskers::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) + emit clicked(m_boxSet); +} + +void BoxWhiskers::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event) + emit hovered(true, m_boxSet); +} + +void BoxWhiskers::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event) + emit hovered(false, m_boxSet); +} + +void BoxWhiskers::setBrush(const QBrush &brush) +{ + m_brush = brush; + m_outlinePen.setColor(m_brush.color()); + update(); +} + +void BoxWhiskers::setPen(const QPen &pen) +{ + qreal widthDiff = pen.widthF() - m_pen.widthF(); + m_boundingRect.adjust(-widthDiff, -widthDiff, widthDiff, widthDiff); + + m_pen = pen; + m_medianPen = pen; + m_medianPen.setCapStyle(Qt::FlatCap); + m_outlinePen = pen; + m_outlinePen.setStyle(Qt::SolidLine); + m_outlinePen.setColor(m_brush.color()); + + update(); +} + +void BoxWhiskers::setBoxWidth(const qreal width) +{ + m_boxWidth = width; +} + +void BoxWhiskers::setLayout(const BoxWhiskersData &data) +{ + m_data = data; + + updateGeometry(m_domain); + update(); +} + +QSizeF BoxWhiskers::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(which) + Q_UNUSED(constraint) + + return QSizeF(); +} + +void BoxWhiskers::setGeometry(const QRectF &rect) +{ + Q_UNUSED(rect) +} + +QRectF BoxWhiskers::boundingRect() const +{ + return m_boundingRect; +} + +void BoxWhiskers::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + painter->save(); + painter->setBrush(m_brush); + painter->setClipRect(parentItem()->boundingRect()); + painter->setPen(m_pen); + painter->drawPath(m_boxPath); + if (!m_boxOutlined) + painter->setPen(m_outlinePen); + painter->drawRect(m_middleBox); + painter->setPen(m_medianPen); + qreal halfLine = m_pen.widthF() / 2.0; + painter->drawLine(QLineF(m_geometryLeft - halfLine, m_geometryMedian, + m_geometryRight + halfLine, m_geometryMedian)); + painter->restore(); +} + +void BoxWhiskers::updateGeometry(AbstractDomain *domain) +{ + m_domain = domain; + + prepareGeometryChange(); + + QPainterPath path; + m_boxPath = path; + m_boundingRect = m_boxPath.boundingRect(); + + qreal columnWidth = 1.0 / m_data.m_seriesCount; + qreal left = ((1.0 - m_boxWidth) / 2.0) * columnWidth + columnWidth * m_data.m_seriesIndex + m_data.m_index - 0.5; + qreal barWidth = m_boxWidth * columnWidth; + + QPointF geometryPoint = m_domain->calculateGeometryPoint(QPointF(left, m_data.m_upperExtreme), m_validData); + if (!m_validData) + return; + m_geometryLeft = geometryPoint.x(); + qreal geometryUpperExtreme = geometryPoint.y(); + geometryPoint = m_domain->calculateGeometryPoint(QPointF(left + barWidth, m_data.m_upperQuartile), m_validData); + if (!m_validData) + return; + m_geometryRight = geometryPoint.x(); + qreal geometryUpperQuartile = geometryPoint.y(); + geometryPoint = m_domain->calculateGeometryPoint(QPointF(left, m_data.m_lowerQuartile), m_validData); + if (!m_validData) + return; + qreal geometryLowerQuartile = geometryPoint.y(); + geometryPoint = m_domain->calculateGeometryPoint(QPointF(left, m_data.m_lowerExtreme), m_validData); + if (!m_validData) + return; + qreal geometryLowerExtreme = geometryPoint.y(); + geometryPoint = m_domain->calculateGeometryPoint(QPointF(left, m_data.m_median), m_validData); + if (!m_validData) + return; + m_geometryMedian = geometryPoint.y(); + + // Upper whisker + path.moveTo(m_geometryLeft, geometryUpperExtreme); + path.lineTo(m_geometryRight, geometryUpperExtreme); + path.moveTo((m_geometryLeft + m_geometryRight) / 2.0, geometryUpperExtreme); + path.lineTo((m_geometryLeft + m_geometryRight) / 2.0, geometryUpperQuartile); + + // Middle Box + m_middleBox.setCoords(m_geometryLeft, geometryUpperQuartile, m_geometryRight, geometryLowerQuartile); + + // Lower whisker + path.moveTo(m_geometryLeft, geometryLowerExtreme); + path.lineTo(m_geometryRight, geometryLowerExtreme); + path.moveTo((m_geometryLeft + m_geometryRight) / 2.0, geometryLowerQuartile); + path.lineTo((m_geometryLeft + m_geometryRight) / 2.0, geometryLowerExtreme); + + path.closeSubpath(); + + m_boxPath = path; + m_boundingRect = m_boxPath.boundingRect(); + + qreal extra = m_pen.widthF(); + m_boundingRect.adjust(-extra, -extra, extra, extra); +} + +#include "moc_boxwhiskers_p.cpp" + +QT_CHARTS_END_NAMESPACE |