diff options
Diffstat (limited to 'src/charts/areachart')
-rw-r--r-- | src/charts/areachart/areachart.pri | 13 | ||||
-rw-r--r-- | src/charts/areachart/areachartitem.cpp | 262 | ||||
-rw-r--r-- | src/charts/areachart/areachartitem_p.h | 123 | ||||
-rw-r--r-- | src/charts/areachart/qareaseries.cpp | 657 | ||||
-rw-r--r-- | src/charts/areachart/qareaseries.h | 106 | ||||
-rw-r--r-- | src/charts/areachart/qareaseries_p.h | 76 |
6 files changed, 1237 insertions, 0 deletions
diff --git a/src/charts/areachart/areachart.pri b/src/charts/areachart/areachart.pri new file mode 100644 index 00000000..af5fa608 --- /dev/null +++ b/src/charts/areachart/areachart.pri @@ -0,0 +1,13 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +SOURCES += \ + $$PWD/areachartitem.cpp \ + $$PWD/qareaseries.cpp + +PRIVATE_HEADERS += \ + $$PWD/areachartitem_p.h \ + $$PWD/qareaseries_p.h + +PUBLIC_HEADERS += \ + $$PWD/qareaseries.h
\ No newline at end of file diff --git a/src/charts/areachart/areachartitem.cpp b/src/charts/areachart/areachartitem.cpp new file mode 100644 index 00000000..cf2d0e8f --- /dev/null +++ b/src/charts/areachart/areachartitem.cpp @@ -0,0 +1,262 @@ +/**************************************************************************** +** +** 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 "areachartitem_p.h" +#include "qareaseries.h" +#include "qareaseries_p.h" +#include "qlineseries.h" +#include "chartpresenter_p.h" +#include "abstractdomain_p.h" +#include <QPainter> +#include <QGraphicsSceneMouseEvent> +#include <QDebug> + + +QT_CHARTS_BEGIN_NAMESPACE + +AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, QGraphicsItem* item) + : ChartItem(areaSeries->d_func(),item), + m_series(areaSeries), + m_upper(0), + m_lower(0), + m_pointsVisible(false), + m_pointLabelsVisible(false), + m_pointLabelsFormat(areaSeries->pointLabelsFormat()), + m_pointLabelsFont(areaSeries->pointLabelsFont()), + m_pointLabelsColor(areaSeries->pointLabelsColor()) +{ + setAcceptHoverEvents(true); + setZValue(ChartPresenter::LineChartZValue); + if (m_series->upperSeries()) + m_upper = new AreaBoundItem(this, m_series->upperSeries()); + if (m_series->lowerSeries()) + m_lower = new AreaBoundItem(this, m_series->lowerSeries()); + + QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated())); + QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated())); + QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated())); + QObject::connect(this, SIGNAL(clicked(QPointF)), areaSeries, SIGNAL(clicked(QPointF))); + QObject::connect(this, SIGNAL(hovered(QPointF,bool)), areaSeries, SIGNAL(hovered(QPointF,bool))); + QObject::connect(areaSeries, SIGNAL(pointLabelsFormatChanged(QString)), + this, SLOT(handleUpdated())); + QObject::connect(areaSeries, SIGNAL(pointLabelsVisibilityChanged(bool)), + this, SLOT(handleUpdated())); + QObject::connect(areaSeries, SIGNAL(pointLabelsFontChanged(QFont)), + this, SLOT(handleUpdated())); + QObject::connect(areaSeries, SIGNAL(pointLabelsColorChanged(QColor)), + this, SLOT(handleUpdated())); + + handleUpdated(); +} + +AreaChartItem::~AreaChartItem() +{ + delete m_upper; + delete m_lower; +} + +void AreaChartItem::setPresenter(ChartPresenter *presenter) +{ + if (m_upper) + m_upper->setPresenter(presenter); + if (m_lower) { + m_lower->setPresenter(presenter); + } + ChartItem::setPresenter(presenter); +} + +QRectF AreaChartItem::boundingRect() const +{ + return m_rect; +} + +QPainterPath AreaChartItem::shape() const +{ + return m_path; +} + +void AreaChartItem::updatePath() +{ + QPainterPath path; + QRectF rect(QPointF(0,0),domain()->size()); + + path = m_upper->path(); + + if (m_lower) { + // Note: Polarcharts always draw area correctly only when both series have equal width or are + // fully displayed. If one series is partally off-chart, the connecting line between + // the series does not attach to the end of the partially hidden series but to the point + // where it intersects the axis line. The problem is especially noticeable when one of the series + // is entirely off-chart, in which case the connecting line connects two ends of the + // visible series. + // This happens because we get the paths from linechart, which omits off-chart segments. + // To properly fix, linechart would need to provide true full path, in right, left, and the rest + // portions to enable proper clipping. However, combining those to single visually unified area + // would be a nightmare, since they would have to be painted separately. + path.connectPath(m_lower->path().toReversed()); + } else { + QPointF first = path.pointAtPercent(0); + QPointF last = path.pointAtPercent(1); + if (presenter()->chartType() == QChart::ChartTypeCartesian) { + path.lineTo(last.x(), rect.bottom()); + path.lineTo(first.x(), rect.bottom()); + } else { // polar + path.lineTo(rect.center()); + } + } + path.closeSubpath(); + + // Only zoom in if the bounding rect of the path fits inside int limits. QWidget::update() uses + // a region that has to be compatible with QRect. + if (path.boundingRect().height() <= INT_MAX + && path.boundingRect().width() <= INT_MAX) { + prepareGeometryChange(); + m_path = path; + m_rect = path.boundingRect(); + update(); + } +} + +void AreaChartItem::handleUpdated() +{ + setVisible(m_series->isVisible()); + m_pointsVisible = m_series->pointsVisible(); + m_linePen = m_series->pen(); + m_brush = m_series->brush(); + m_pointPen = m_series->pen(); + m_pointPen.setWidthF(2 * m_pointPen.width()); + setOpacity(m_series->opacity()); + m_pointLabelsFormat = m_series->pointLabelsFormat(); + m_pointLabelsVisible = m_series->pointLabelsVisible(); + m_pointLabelsFont = m_series->pointLabelsFont(); + m_pointLabelsColor = m_series->pointLabelsColor(); + update(); +} + +void AreaChartItem::handleDomainUpdated() +{ + if (m_upper) { + AbstractDomain* d = m_upper->domain(); + d->setSize(domain()->size()); + d->setRange(domain()->minX(),domain()->maxX(),domain()->minY(),domain()->maxY()); + m_upper->handleDomainUpdated(); + } + + if (m_lower) { + AbstractDomain* d = m_lower->domain(); + d->setSize(domain()->size()); + d->setRange(domain()->minX(),domain()->maxX(),domain()->minY(),domain()->maxY()); + m_lower->handleDomainUpdated(); + } +} + +void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget) + Q_UNUSED(option) + painter->save(); + painter->setPen(m_linePen); + painter->setBrush(m_brush); + QRectF clipRect = QRectF(QPointF(0, 0), domain()->size()); + if (presenter()->chartType() == QChart::ChartTypePolar) + painter->setClipRegion(QRegion(clipRect.toRect(), QRegion::Ellipse)); + else + painter->setClipRect(clipRect); + painter->drawPath(m_path); + if (m_pointsVisible) { + painter->setPen(m_pointPen); + painter->drawPoints(m_upper->geometryPoints()); + if (m_lower) + painter->drawPoints(m_lower->geometryPoints()); + } + + // Draw series point label + if (m_pointLabelsVisible) { + static const QString xPointTag(QLatin1String("@xPoint")); + static const QString yPointTag(QLatin1String("@yPoint")); + const int labelOffset = 2; + + painter->setFont(m_pointLabelsFont); + painter->setPen(QPen(m_pointLabelsColor)); + QFontMetrics fm(painter->font()); + + QString pointLabel = m_pointLabelsFormat; + + if (m_series->upperSeries()) { + for (int i(0); i < m_series->upperSeries()->count(); i++) { + pointLabel.replace(xPointTag, + presenter()->numberToString(m_series->upperSeries()->at(i).x())); + pointLabel.replace(yPointTag, + presenter()->numberToString(m_series->upperSeries()->at(i).y())); + + // Position text in relation to the point + int pointLabelWidth = fm.width(pointLabel); + QPointF position(m_upper->geometryPoints().at(i)); + position.setX(position.x() - pointLabelWidth / 2); + position.setY(position.y() - m_series->upperSeries()->pen().width() / 2 - labelOffset); + + painter->drawText(position, pointLabel); + } + } + + if (m_series->lowerSeries()) { + for (int i(0); i < m_series->lowerSeries()->count(); i++) { + pointLabel.replace(xPointTag, + presenter()->numberToString(m_series->lowerSeries()->at(i).x())); + pointLabel.replace(yPointTag, + presenter()->numberToString(m_series->lowerSeries()->at(i).y())); + + // Position text in relation to the point + int pointLabelWidth = fm.width(pointLabel); + QPointF position(m_lower->geometryPoints().at(i)); + position.setX(position.x() - pointLabelWidth / 2); + position.setY(position.y() - m_series->lowerSeries()->pen().width() / 2 - labelOffset); + + painter->drawText(position, pointLabel); + } + } + } + + painter->restore(); +} + +void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + emit clicked(m_upper->domain()->calculateDomainPoint(event->pos())); + ChartItem::mousePressEvent(event); +} + +void AreaChartItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + emit hovered(domain()->calculateDomainPoint(event->pos()), true); + event->accept(); +// QGraphicsItem::hoverEnterEvent(event); +} + +void AreaChartItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + emit hovered(domain()->calculateDomainPoint(event->pos()), false); + event->accept(); +// QGraphicsItem::hoverEnterEvent(event); +} + +#include "moc_areachartitem_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/areachart/areachartitem_p.h b/src/charts/areachart/areachartitem_p.h new file mode 100644 index 00000000..5f806af6 --- /dev/null +++ b/src/charts/areachart/areachartitem_p.h @@ -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$ +** +****************************************************************************/ + +// 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 AREACHARTITEM_H +#define AREACHARTITEM_H + +#include "qchartglobal.h" +#include "linechartitem_p.h" +#include "qareaseries.h" +#include <QPen> + +QT_CHARTS_BEGIN_NAMESPACE + +class AreaChartItem; + +class AreaChartItem : public ChartItem +{ + Q_OBJECT +public: + AreaChartItem(QAreaSeries *areaSeries, QGraphicsItem* item = 0); + ~AreaChartItem(); + + //from QGraphicsItem + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + QPainterPath shape() const; + + LineChartItem *upperLineItem() const { return m_upper; } + LineChartItem *lowerLineItem() const { return m_lower; } + + void updatePath(); + + void setPresenter(ChartPresenter *presenter); + QAreaSeries *series() const { return m_series; } + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + +Q_SIGNALS: + void clicked(const QPointF &point); + void hovered(const QPointF &point, bool state); + +public Q_SLOTS: + void handleUpdated(); + void handleDomainUpdated(); + +private: + QAreaSeries *m_series; + LineChartItem *m_upper; + LineChartItem *m_lower; + QPainterPath m_path; + QRectF m_rect; + QPen m_linePen; + QPen m_pointPen; + QBrush m_brush; + bool m_pointsVisible; + + bool m_pointLabelsVisible; + QString m_pointLabelsFormat; + QFont m_pointLabelsFont; + QColor m_pointLabelsColor; + +}; + +class AreaBoundItem : public LineChartItem +{ +public: + AreaBoundItem(AreaChartItem *area, QLineSeries *lineSeries,QGraphicsItem* item = 0) + : LineChartItem(lineSeries, item), m_item(area) + { + // We do not actually want to draw anything from LineChartItem. + // Drawing is done in AreaChartItem only. + setVisible(false); + } + ~AreaBoundItem() {} + + void updateGeometry() + { + // Turn off points drawing from component line chart item, as that + // messes up the fill for area series. + suppressPoints(); + // Component lineseries are not necessarily themselves on the chart, + // so get the chart type for them from area chart. + forceChartType(m_item->series()->chart()->chartType()); + LineChartItem::updateGeometry(); + m_item->updatePath(); + } + +private: + AreaChartItem *m_item; +}; + +QT_CHARTS_END_NAMESPACE + +#endif diff --git a/src/charts/areachart/qareaseries.cpp b/src/charts/areachart/qareaseries.cpp new file mode 100644 index 00000000..e2a2ea2f --- /dev/null +++ b/src/charts/areachart/qareaseries.cpp @@ -0,0 +1,657 @@ +/**************************************************************************** +** +** 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 "qareaseries.h" +#include "qareaseries_p.h" +#include "qlineseries.h" +#include "areachartitem_p.h" +#include "abstractdomain_p.h" +#include "chartdataset_p.h" +#include "charttheme_p.h" +#include "qvalueaxis.h" +#include "qarealegendmarker.h" +#include "qchart_p.h" + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \class QAreaSeries + \inmodule Qt Charts + \brief The QAreaSeries class is used for making area charts. + + \mainclass + + An area chart is used to show quantitative data. It is based on line chart, in the way that area between axis and the line + is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance, + which defines "upper" boundary of the area. "Lower" boundary is defined by default by axis X. Instead of axis X "lower" boundary can be specified by other line. + In that case QAreaSeries should be initiated with two QLineSeries instances. Please note terms "upper" and "lower" boundary can be misleading in cases + where "lower" boundary had bigger values than the "upper" one, however the main point that area between these two boundary lines will be filled. + + See the \l {AreaChart Example} {area chart example} to learn how to create a simple area chart. + \image examples_areachart.png +*/ + +/*! + \qmltype AreaSeries + \instantiates QAreaSeries + \inqmlmodule QtCharts + + \inherits AbstractSeries + + \brief The AreaSeries type is used for making area charts. + + The following QML shows how to create a simple area chart: + \snippet qmlchart/qml/qmlchart/View4.qml 1 + \beginfloatleft + \image examples_qmlchart4.png + \endfloat + \clearfloat +*/ + +/*! + \property QAreaSeries::upperSeries + \brief The upper one of the two line series used to define area series boundaries. +*/ +/*! + \qmlproperty LineSeries AreaSeries::upperSeries + The upper one of the two line series used to define area series boundaries. +*/ + +/*! + \property QAreaSeries::lowerSeries + The lower one of the two line series used to define are series boundaries. Note if + QAreaSeries was constructed without a\ lowerSeries this is null. +*/ +/*! + \qmlproperty LineSeries AreaSeries::lowerSeries + The lower one of the two line series used to define are series boundaries. Note if + AreaSeries was constructed without a\ lowerSeries this is null. +*/ + +/*! + \property QAreaSeries::color + Fill (brush) color of the series. This is a convenience property for modifying the color of brush. + \sa QAreaSeries::brush() +*/ +/*! + \qmlproperty color AreaSeries::color + Fill (brush) color of the series. +*/ + +/*! + \property QAreaSeries::borderColor + Line (pen) color of the series. This is a convenience property for modifying the color of pen. + \sa QAreaSeries::pen() +*/ +/*! + \qmlproperty color AreaSeries::borderColor + Line (pen) color of the series. +*/ + +/*! + \qmlproperty real AreaSeries::borderWidth + The width of the border line. By default the width is 2.0. +*/ + +/*! + \fn QPen QAreaSeries::pen() const + \brief Returns the pen used to draw line for this series. + \sa setPen() +*/ + +/*! + \fn QPen QAreaSeries::brush() const + \brief Returns the brush used to draw line for this series. + \sa setBrush() +*/ + +/*! + \qmlproperty QString AreaSeries::brushFilename + The name of the file used as a brush image for the series. +*/ + +/*! + \fn void QAreaSeries::colorChanged(QColor color) + \brief Signal is emitted when the fill (brush) color has changed to \a color. +*/ +/*! + \qmlsignal AreaSeries::onColorChanged(color color) + Signal is emitted when the fill (brush) color has changed to \a color. +*/ + +/*! + \fn void QAreaSeries::borderColorChanged(QColor color) + \brief Signal is emitted when the line (pen) color has changed to \a color. +*/ +/*! + \qmlsignal AreaSeries::onBorderColorChanged(color color) + Signal is emitted when the line (pen) color has changed to \a color. +*/ + +/*! + \fn void QAreaSeries::clicked(const QPointF& point) + \brief Signal is emitted when user clicks the \a point on area chart. +*/ +/*! + \qmlsignal AreaSeries::onClicked(QPointF point) + Signal is emitted when user clicks the \a point on area chart. +*/ + +/*! + \fn void QAreaSeries::hovered(const QPointF &point, bool state) + This signal is emitted when user has hovered over or away from the series. \a point shows the origin (coordinate) + of the hover event. \a state is true when user has hovered over the series and false when hover has moved away from + the series. +*/ +/*! + \qmlsignal AreaSeries::onHovered(point point, bool state) + This signal is emitted when user has hovered over or away from the series. \a point shows the origin (coordinate) + of the hover event. \a state is true when user has hovered over the series and false when hover has moved away from + the series. +*/ + +/*! + \fn void QAreaSeries::selected() + The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be + implemented by the user of QAreaSeries API. +*/ +/*! + \qmlsignal AreaSeries::onSelected() + The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be + implemented by the user of AreaSeries API. +*/ + +/*! + \fn void QAreaSeriesPrivate::updated() + \brief \internal +*/ + +/*! + \property QAreaSeries::pointLabelsFormat + The \a format used for showing labels with series points. + + QAreaSeries supports the following format tags: + \table + \row + \li @xPoint \li The x value of the data point + \row + \li @yPoint \li The y value of the data point + \endtable + + For example, the following usage of the format tags would produce labels that have the data + point (x, y) shown inside brackets separated by a comma: + \code + series->setPointLabelsFormat("(@xPoint, @yPoint)"); + \endcode + + By default, the labels format is set to '@xPoint, @yPoint'. The labels are shown on the plot + area, labels on the edge of the plot area are cut. If the points are close to each other the + labels may overlap. + + \sa QAreaSeries::pointLabelsVisible, QAreaSeries::pointLabelsFont, QAreaSeries::pointLabelsColor +*/ +/*! + \qmlproperty string AreaSeries::pointLabelsFormat + The \a format used for showing labels with series points. + + \sa QAreaSeries::pointLabelsFormat, pointLabelsVisible, pointLabelsFont, pointLabelsColor +*/ +/*! + \fn void QAreaSeries::pointLabelsFormatChanged(const QString &format) + Signal is emitted when the \a format of data point labels is changed. +*/ +/*! + \qmlsignal AreaSeries::onPointLabelsFormatChanged(string format) + Signal is emitted when the \a format of data point labels is changed. +*/ + +/*! + \property QAreaSeries::pointLabelsVisible + Defines the visibility for data point labels. False by default. + + \sa QAreaSeries::pointLabelsFormat +*/ +/*! + \qmlproperty bool AreaSeries::pointLabelsVisible + Defines the visibility for data point labels. + + \sa pointLabelsFormat +*/ +/*! + \fn void QAreaSeries::pointLabelsVisibilityChanged(bool visible) + The visibility of the data point labels is changed to \a visible. +*/ +/*! + \qmlsignal AreaSeries::onPointLabelsVisibilityChanged(bool visible) + The visibility of the data point labels is changed to \a visible. +*/ + +/*! + \property QAreaSeries::pointLabelsFont + Defines the font used for data point labels. + + \sa QAreaSeries::pointLabelsFormat +*/ +/*! + \qmlproperty font AreaSeries::pointLabelsFont + Defines the font used for data point labels. + + \sa pointLabelsFormat +*/ +/*! + \fn void QAreaSeries::pointLabelsFontChanged(const QFont &font); + The font used for data point labels is changed to \a font. +*/ +/*! + \qmlsignal AreaSeries::onPointLabelsFontChanged(Font font) + The font used for data point labels is changed to \a font. +*/ + +/*! + \property QAreaSeries::pointLabelsColor + Defines the color used for data point labels. By default, the color is the color of the brush + defined in theme for labels. + + \sa QAreaSeries::pointLabelsFormat +*/ +/*! + \qmlproperty font AreaSeries::pointLabelsColor + Defines the color used for data point labels. By default, the color is the color of the brush + defined in theme for labels. + + \sa pointLabelsFormat +*/ +/*! + \fn void QAreaSeries::pointLabelsColorChanged(const QColor &color); + The color used for data point labels is changed to \a color. +*/ +/*! + \qmlsignal AreaSeries::onPointLabelsColorChanged(Color color) + The color used for data point labels is changed to \a color. +*/ + +/*! + Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a + upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead. + When series object is added to QChartView or QChart instance ownerships is transferred. +*/ +QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries) + : QAbstractSeries(*new QAreaSeriesPrivate(upperSeries, lowerSeries, this), upperSeries) +{ +} + +/*! + Constructs area series object without upper or lower series with \a parent object. +*/ +QAreaSeries::QAreaSeries(QObject *parent) + : QAbstractSeries(*new QAreaSeriesPrivate(0, 0, this), parent) +{ +} + +/*! + Destroys the object. +*/ +QAreaSeries::~QAreaSeries() +{ + Q_D(QAreaSeries); + if (d->m_chart) + d->m_chart->removeSeries(this); +} + +/*! + Returns QAbstractSeries::SeriesTypeArea. +*/ +QAbstractSeries::SeriesType QAreaSeries::type() const +{ + return QAbstractSeries::SeriesTypeArea; +} + +/*! + Sets the \a series that is to be used as the area chart upper series. +*/ +void QAreaSeries::setUpperSeries(QLineSeries *series) +{ + Q_D(QAreaSeries); + if (d->m_upperSeries != series) + d->m_upperSeries = series; +} + +QLineSeries *QAreaSeries::upperSeries() const +{ + Q_D(const QAreaSeries); + return d->m_upperSeries; +} + +/*! + Sets the \a series that is to be used as the area chart lower series. +*/ +void QAreaSeries::setLowerSeries(QLineSeries *series) +{ + Q_D(QAreaSeries); + d->m_lowerSeries = series; +} + +QLineSeries *QAreaSeries::lowerSeries() const +{ + Q_D(const QAreaSeries); + return d->m_lowerSeries; +} + +/*! + Sets \a pen used for drawing area outline. +*/ +void QAreaSeries::setPen(const QPen &pen) +{ + Q_D(QAreaSeries); + if (d->m_pen != pen) { + d->m_pen = pen; + emit d->updated(); + } +} + +QPen QAreaSeries::pen() const +{ + Q_D(const QAreaSeries); + if (d->m_pen == QChartPrivate::defaultPen()) + return QPen(); + else + return d->m_pen; +} + +/*! + Sets \a brush used for filling the area. +*/ +void QAreaSeries::setBrush(const QBrush &brush) +{ + Q_D(QAreaSeries); + if (d->m_brush != brush) { + bool emitColorChanged = brush.color() != d->m_brush.color(); + d->m_brush = brush; + emit d->updated(); + if (emitColorChanged) + emit colorChanged(brush.color()); + } +} + +QBrush QAreaSeries::brush() const +{ + Q_D(const QAreaSeries); + if (d->m_brush == QChartPrivate::defaultBrush()) + return QBrush(); + else + return d->m_brush; +} + +void QAreaSeries::setColor(const QColor &color) +{ + QBrush b = brush(); + if (b == QBrush()) + b.setStyle(Qt::SolidPattern); + b.setColor(color); + setBrush(b); +} + +QColor QAreaSeries::color() const +{ + return brush().color(); +} + +void QAreaSeries::setBorderColor(const QColor &color) +{ + QPen p = pen(); + if (p.color() != color) { + p.setColor(color); + setPen(p); + emit borderColorChanged(color); + } +} + +QColor QAreaSeries::borderColor() const +{ + return pen().color(); +} + +/*! + Sets if data points are \a visible and should be drawn on line. +*/ +void QAreaSeries::setPointsVisible(bool visible) +{ + Q_D(QAreaSeries); + if (d->m_pointsVisible != visible) { + d->m_pointsVisible = visible; + emit d->updated(); + } +} + +/*! + Returns if the points are drawn for this series. + \sa setPointsVisible() +*/ +bool QAreaSeries::pointsVisible() const +{ + Q_D(const QAreaSeries); + return d->m_pointsVisible; +} + +void QAreaSeries::setPointLabelsFormat(const QString &format) +{ + Q_D(QAreaSeries); + if (d->m_pointLabelsFormat != format) { + d->m_pointLabelsFormat = format; + emit pointLabelsFormatChanged(format); + } +} + +QString QAreaSeries::pointLabelsFormat() const +{ + Q_D(const QAreaSeries); + return d->m_pointLabelsFormat; +} + +void QAreaSeries::setPointLabelsVisible(bool visible) +{ + Q_D(QAreaSeries); + if (d->m_pointLabelsVisible != visible) { + d->m_pointLabelsVisible = visible; + emit pointLabelsVisibilityChanged(visible); + } +} + +bool QAreaSeries::pointLabelsVisible() const +{ + Q_D(const QAreaSeries); + return d->m_pointLabelsVisible; +} + +void QAreaSeries::setPointLabelsFont(const QFont &font) +{ + Q_D(QAreaSeries); + if (d->m_pointLabelsFont != font) { + d->m_pointLabelsFont = font; + emit pointLabelsFontChanged(font); + } +} + +QFont QAreaSeries::pointLabelsFont() const +{ + Q_D(const QAreaSeries); + return d->m_pointLabelsFont; +} + +void QAreaSeries::setPointLabelsColor(const QColor &color) +{ + Q_D(QAreaSeries); + if (d->m_pointLabelsColor != color) { + d->m_pointLabelsColor = color; + emit pointLabelsColorChanged(color); + } +} + +QColor QAreaSeries::pointLabelsColor() const +{ + Q_D(const QAreaSeries); + if (d->m_pointLabelsColor == QChartPrivate::defaultPen().color()) + return QPen().color(); + else + return d->m_pointLabelsColor; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries, QAreaSeries *q) + : QAbstractSeriesPrivate(q), + m_brush(QChartPrivate::defaultBrush()), + m_pen(QChartPrivate::defaultPen()), + m_upperSeries(upperSeries), + m_lowerSeries(lowerSeries), + m_pointsVisible(false), + m_pointLabelsFormat(QLatin1String("@xPoint, @yPoint")), + m_pointLabelsVisible(false), + m_pointLabelsFont(QChartPrivate::defaultFont()), + m_pointLabelsColor(QChartPrivate::defaultPen().color()) +{ +} + +void QAreaSeriesPrivate::initializeDomain() +{ + Q_Q(QAreaSeries); + + qreal minX(domain()->minX()); + qreal minY(domain()->minY()); + qreal maxX(domain()->maxX()); + qreal maxY(domain()->maxY()); + + QLineSeries *upperSeries = q->upperSeries(); + QLineSeries *lowerSeries = q->lowerSeries(); + + if (upperSeries) { + const QList<QPointF>& points = upperSeries->points(); + + for (int i = 0; i < points.count(); i++) { + qreal x = points[i].x(); + qreal y = points[i].y(); + minX = qMin(minX, x); + minY = qMin(minY, y); + maxX = qMax(maxX, x); + maxY = qMax(maxY, y); + } + } + if (lowerSeries) { + + const QList<QPointF>& points = lowerSeries->points(); + + for (int i = 0; i < points.count(); i++) { + qreal x = points[i].x(); + qreal y = points[i].y(); + minX = qMin(minX, x); + minY = qMin(minY, y); + maxX = qMax(maxX, x); + maxY = qMax(maxY, y); + } + } + + domain()->setRange(minX, maxX, minY, maxY); +} + +void QAreaSeriesPrivate::initializeGraphics(QGraphicsItem* parent) +{ + Q_Q(QAreaSeries); + AreaChartItem *area = new AreaChartItem(q,parent); + m_item.reset(area); + QAbstractSeriesPrivate::initializeGraphics(parent); +} +void QAreaSeriesPrivate::initializeAnimations(QChart::AnimationOptions options) +{ + Q_Q(QAreaSeries); + AreaChartItem *area = static_cast<AreaChartItem *>(m_item.data()); + + if (q->upperSeries() && area->upperLineItem()->animation()) + area->upperLineItem()->animation()->stopAndDestroyLater(); + if (q->lowerSeries() && area->lowerLineItem()->animation()) + area->lowerLineItem()->animation()->stopAndDestroyLater(); + + if (options.testFlag(QChart::SeriesAnimations)) { + area->upperLineItem()->setAnimation(new XYAnimation(area->upperLineItem())); + if (q->lowerSeries()) + area->lowerLineItem()->setAnimation(new XYAnimation(area->lowerLineItem())); + } else { + if (q->upperSeries()) + area->upperLineItem()->setAnimation(0); + if (q->lowerSeries()) + area->lowerLineItem()->setAnimation(0); + } + QAbstractSeriesPrivate::initializeAnimations(options); +} + +QList<QLegendMarker*> QAreaSeriesPrivate::createLegendMarkers(QLegend* legend) +{ + Q_Q(QAreaSeries); + QList<QLegendMarker*> list; + return list << new QAreaLegendMarker(q,legend); +} + + +void QAreaSeriesPrivate::initializeAxes() +{ + +} + +QAbstractAxis::AxisType QAreaSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const +{ + Q_UNUSED(orientation); + return QAbstractAxis::AxisTypeValue; +} + +QAbstractAxis* QAreaSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const +{ + Q_UNUSED(orientation); + return new QValueAxis; +} + +void QAreaSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced) +{ + Q_Q(QAreaSeries); + + const QList<QGradient> gradients = theme->seriesGradients(); + const QList<QColor> colors = theme->seriesColors(); + + if (forced || QChartPrivate::defaultPen() == m_pen) { + QPen pen; + pen.setColor(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0)); + pen.setWidthF(2); + q->setPen(pen); + } + + if (forced || QChartPrivate::defaultBrush() == m_brush) { + QBrush brush(colors.at(index % colors.size())); + q->setBrush(brush); + } + + if (forced || QChartPrivate::defaultPen().color() == m_pointLabelsColor) { + QColor color = theme->labelBrush().color(); + q->setPointLabelsColor(color); + } +} + + +#include "moc_qareaseries.cpp" +#include "moc_qareaseries_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/areachart/qareaseries.h b/src/charts/areachart/qareaseries.h new file mode 100644 index 00000000..cad15c77 --- /dev/null +++ b/src/charts/areachart/qareaseries.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** 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 QAREASERIES_H +#define QAREASERIES_H + +#include <QtCharts/qchartglobal.h> +#include <QtCharts/qabstractseries.h> +#include <QPen> +#include <QBrush> + +QT_CHARTS_BEGIN_NAMESPACE +class QLineSeries; +class QAreaSeriesPrivate; + +class QT_CHARTS_EXPORT QAreaSeries : public QAbstractSeries +{ + Q_OBJECT + Q_PROPERTY(QLineSeries *upperSeries READ upperSeries) + Q_PROPERTY(QLineSeries *lowerSeries READ lowerSeries) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor NOTIFY borderColorChanged) + Q_PROPERTY(QString pointLabelsFormat READ pointLabelsFormat WRITE setPointLabelsFormat NOTIFY pointLabelsFormatChanged) + Q_PROPERTY(bool pointLabelsVisible READ pointLabelsVisible WRITE setPointLabelsVisible NOTIFY pointLabelsVisibilityChanged) + Q_PROPERTY(QFont pointLabelsFont READ pointLabelsFont WRITE setPointLabelsFont NOTIFY pointLabelsFontChanged) + Q_PROPERTY(QColor pointLabelsColor READ pointLabelsColor WRITE setPointLabelsColor NOTIFY pointLabelsColorChanged) + +public: + explicit QAreaSeries(QObject *parent = 0); + explicit QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries = 0); + ~QAreaSeries(); + +public: + QAbstractSeries::SeriesType type() const; + + void setUpperSeries(QLineSeries *series); + QLineSeries *upperSeries() const; + void setLowerSeries(QLineSeries *series); + QLineSeries *lowerSeries() const; + + void setPen(const QPen &pen); + QPen pen() const; + + void setBrush(const QBrush &brush); + QBrush brush() const; + + void setColor(const QColor &color); + QColor color() const; + + void setBorderColor(const QColor &color); + QColor borderColor() const; + + void setPointsVisible(bool visible = true); + bool pointsVisible() const; + + void setPointLabelsFormat(const QString &format); + QString pointLabelsFormat() const; + + void setPointLabelsVisible(bool visible = true); + bool pointLabelsVisible() const; + + void setPointLabelsFont(const QFont &font); + QFont pointLabelsFont() const; + + void setPointLabelsColor(const QColor &color); + QColor pointLabelsColor() const; + +Q_SIGNALS: + void clicked(const QPointF &point); + void hovered(const QPointF &point, bool state); + void selected(); + void colorChanged(QColor color); + void borderColorChanged(QColor color); + void pointLabelsFormatChanged(const QString &format); + void pointLabelsVisibilityChanged(bool visible); + void pointLabelsFontChanged(const QFont &font); + void pointLabelsColorChanged(const QColor &color); + +private: + Q_DECLARE_PRIVATE(QAreaSeries) + Q_DISABLE_COPY(QAreaSeries) + friend class AreaLegendMarker; + friend class AreaChartItem; + friend class QAreaLegendMarkerPrivate; +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QAREASERIES_H diff --git a/src/charts/areachart/qareaseries_p.h b/src/charts/areachart/qareaseries_p.h new file mode 100644 index 00000000..3f6293d3 --- /dev/null +++ b/src/charts/areachart/qareaseries_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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 QAREASERIES_P_H +#define QAREASERIES_P_H + +#include "qabstractseries_p.h" + +QT_CHARTS_BEGIN_NAMESPACE + +class QAreaSeries; + +class QAreaSeriesPrivate: public QAbstractSeriesPrivate +{ + Q_OBJECT + +public: + QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries, QAreaSeries *q); + + void initializeDomain(); + void initializeAxes(); + void initializeGraphics(QGraphicsItem* parent); + void initializeTheme(int index, ChartTheme* theme, bool forced = false); + void initializeAnimations(QChart::AnimationOptions options); + + QList<QLegendMarker *> createLegendMarkers(QLegend *legend); + + QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const; + QAbstractAxis* createDefaultAxis(Qt::Orientation) const; + +Q_SIGNALS: + void updated(); + +protected: + QBrush m_brush; + QPen m_pen; + QLineSeries *m_upperSeries; + QLineSeries *m_lowerSeries; + bool m_pointsVisible; + QString m_pointLabelsFormat; + bool m_pointLabelsVisible; + QFont m_pointLabelsFont; + QColor m_pointLabelsColor; +private: + Q_DECLARE_PUBLIC(QAreaSeries); +}; + +QT_CHARTS_END_NAMESPACE + +#endif |