diff options
Diffstat (limited to 'src/chartsqml2/declarativeboxplotseries.cpp')
-rw-r--r-- | src/chartsqml2/declarativeboxplotseries.cpp | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/src/chartsqml2/declarativeboxplotseries.cpp b/src/chartsqml2/declarativeboxplotseries.cpp new file mode 100644 index 00000000..101dab58 --- /dev/null +++ b/src/chartsqml2/declarativeboxplotseries.cpp @@ -0,0 +1,423 @@ +/**************************************************************************** +** +** 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 "declarativebarseries.h" +#include "declarativeboxplotseries.h" +#include "qboxset.h" +#include "qvboxplotmodelmapper.h" + +QT_CHARTS_BEGIN_NAMESPACE + +/*! + \qmltype BoxSet + \instantiates QBoxSet + \inqmlmodule QtCharts + + BoxSet represents one box-and-whiskers item. It takes five values to create a graphical + representation of range and three medians. There are two ways to give the values. The first one + is with constructor or with append method. In these the values have to be given in the following + order: lower extreme, lower quartile, median, upper quartile and upper extreme. The second + method is to create an empty QBoxSet instance and give the values using value specific methods. + \sa BoxPlotSeries +*/ +/*! + \qmlproperty string BoxSet::values + The values on the box-and-whiskers set. +*/ +/*! + \qmlproperty string BoxSet::label + Defines the label of the box-and-whiskers set. +*/ +/*! + \qmlproperty int BoxSet::count + The count of values on the box-and-whiskers set +*/ +/*! + \qmlmethod void BoxSet::at(int index) + Returns the value at \a index position. +*/ +/*! + \qmlmethod void BoxSet::append(qreal value) + Appends new value \a value to the end of set. +*/ +/*! + \qmlmethod void BoxSet::clear() + Sets all values on the set to 0. +*/ +/*! + \qmlmethod void BoxSet::setValue(int index, qreal value) + Sets a new \a value on the \a index position. +*/ +/*! + \qmlsignal BoxSet::onClicked() + This signal is emitted when the user clicks with a mouse on top of box-and-whiskers item. +*/ +/*! + \qmlsignal BoxSet::onHovered(bool status) + The signal is emitted if mouse is hovered on top of box-and-whiskers item. + Parameter \a status is true, if mouse entered on top of the item, and false if mouse left from top of the item. +*/ +/*! + \qmlsignal BoxSet::onPenChanged() + This signal is emitted when the pen of the box-and-whiskers item has changed. +*/ +/*! + \qmlsignal BoxSet::onBrushChanged() + This signal is emitted when the brush of the box-and-whiskers item has changed. +*/ +/*! + \qmlsignal BoxSet::onChangedValues() + This signal is emitted when multiple values have been changed on the box-and-whiskers item. +*/ +/*! + \qmlsignal BoxSet::onChangedValue(int index) + This signal is emitted values the value in the box-and-whiskers item has been modified. + Parameter \a index indicates the position of the modified value. +*/ +/*! + \qmlsignal BoxSet::onCleared() + This signal is emitted when all the values on the set are cleared to 0. +*/ + +/*! + \qmltype BoxPlotSeries + \instantiates QBoxPlotSeries + \inqmlmodule QtCharts + + \inherits AbstractSeries + + BoxPlotSeries represents a series of data shown as box-and-whiskers bars. The purpose of this + class is to act as a container for single box-and-whiskers items. Each item is drawn to own + slot. If chart includes multiple instances of BoxPlotSeries then box-and-whiskers items with the + same index are drawn to same slot. + + The following QML shows how to create a simple box-and-whiskers chart: + \code + import QtQuick 2.0 + import QtCharts 2.0 + + ChartView { + title: "Box Plot series" + width: 400 + height: 300 + theme: ChartView.ChartThemeBrownSand + legend.alignment: Qt.AlignBottom + + BoxPlotSeries { + id: plotSeries + name: "Income" + BoxSet { label: "Jan"; values: [3, 4, 5.1, 6.2, 8.5] } + BoxSet { label: "Feb"; values: [5, 6, 7.5, 8.6, 11.8] } + BoxSet { label: "Mar"; values: [3.2, 5, 5.7, 8, 9.2] } + BoxSet { label: "Apr"; values: [3.8, 5, 6.4, 7, 8] } + BoxSet { label: "May"; values: [4, 5, 5.2, 6, 7] } + } + } + \endcode + + \beginfloatleft + \image examples_qmlboxplot.png + \endfloat + \clearfloat +*/ + +/*! + \qmlmethod BoxPlotSeries::append(string label, VariantList values) + Appends a new box-and-whiskers set with \a label and \a values to the series. + */ +/*! + \qmlmethod BoxPlotSeries::append(BoxSet box) + Appends the \a box to the series. +*/ +/*! + \qmlmethod BoxPlotSeries::insert(int index, string label, VariantList values) + Inserts a new box-and-whiskers set with \a label and \a values at the \a index position. +*/ +/*! + \qmlmethod BoxPlotSeries::remove(QBoxSet boxset) + Removes the \a boxset from the series. +*/ +/*! + \qmlmethod BoxPlotSeries::clear() + Removes all boxsets from the series. Deletes removed sets. +*/ +/*! + \qmlsignal BoxPlotSeries::onClicked(BoxSet boxset); + Signal is emitted when the user clicks the \a boxset on the chart. +*/ +/*! + \qmlsignal BoxPlotSeries::onHovered(bool status, BoxSet boxset); + Signal is emitted when there is change in hover \a status over \a boxset. +*/ +/*! + \qmlsignal BoxPlotSeries::onCountChanged(); + Signal is emitted when there is change in count of box-and-whiskers items in the series. +*/ +/*! + \qmlsignal BoxPlotSeries::onBoxsetsAdded() + Signal is emitted when new box-and-whiskers sets are added to the series. + */ +/*! + \qmlsignal BoxPlotSeries::onBoxsetsRemoved() + Signal is emitted when new box-and-whiskers sets are removed from the series. + */ +/*! + \qmlproperty AbstractAxis BoxPlotSeries::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 BoxPlotSeries::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 BoxPlotSeries::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 BoxPlotSeries::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 +*/ +/*! + \qmlproperty bool BoxPlotSeries::boxOutlineVisible + This property configures the visibility of the middle box outline. +*/ +/*! + \qmlproperty qreal BoxPlotSeries::boxWidth + This property configures the width of the box-and-whiskers item. The value signifies the relative + width of the box-and-whiskers item inside its own slot. The value can between 0.0 and 1.0. Negative values + are clamped to 0.0 and values over 1.0 are clamped to 1.0. +*/ +/*! + \qmlproperty Pen BoxPlotSeries::pen + This property configures the pen of the box-and-whiskers items. +*/ +/*! + \qmlproperty Brush BoxPlotSeries::brush + This property configures the brush of the box-and-whiskers items. +*/ +/*! + \qmlproperty int BoxPlotSeries::count + The count of sets in series. +*/ +/*! + \qmlsignal BoxPlotSeries::onBoxOutlineVisibilityChanged() + Signal is emitted when the middle box outline visibility is changed. + */ +/*! + \qmlsignal BoxPlotSeries::onBoxWidthChanged() + Signal is emitted when the width of the box-and-whiskers item is changed. + */ +/*! + \qmlsignal BoxPlotSeries::onPenChanged() + Signal is emitted when the pen for box-and-whiskers items has changed. +*/ +/*! + \qmlsignal BoxPlotSeries::onBrushChanged() + Signal is emitted when the brush for box-and-whiskers items has changed. +*/ +/*! + \qmlsignal BoxPlotSeries::onClicked(BoxSet boxset) + Signal is emitted when the user clicks the \a boxset on the chart. +*/ +/*! + \qmlsignal BoxPlotSeries::onHovered(bool status, BoxSet boxset) + Signal is emitted when there is change in hover \a status over \a boxset. +*/ +/*! + \qmlsignal BoxPlotSeries::onAxisXChanged(AbstractAxis axis) + Signal is emitted when there is change in X axis. +*/ +/*! + \qmlsignal BoxPlotSeries::onAxisYChanged(AbstractAxis axis) + Signal is emitted when there is change in Y axis. +*/ +/*! + \qmlsignal BoxPlotSeries::onAxisXTopChanged(AbstractAxis axis) + Signal is emitted when there is change in top X axis. +*/ +/*! + \qmlsignal BoxPlotSeries::onAxisYRightChanged(AbstractAxis axis) + Signal is emitted when there is change in Y right axis. +*/ + + +DeclarativeBoxSet::DeclarativeBoxSet(const QString label, QObject *parent) + : QBoxSet(label, parent) +{ + connect(this, SIGNAL(valuesChanged()), this, SIGNAL(changedValues())); + connect(this, SIGNAL(valueChanged(int)), this, SIGNAL(changedValue(int))); + connect(this, SIGNAL(brushChanged()), this, SLOT(handleBrushChanged())); +} + +QVariantList DeclarativeBoxSet::values() +{ + QVariantList values; + for (int i(0); i < 5; i++) + values.append(QVariant(QBoxSet::at(i))); + return values; +} + +void DeclarativeBoxSet::setValues(QVariantList values) +{ + for (int i(0); i < values.count(); i++) { + if (values.at(i).canConvert(QVariant::Double)) + QBoxSet::append(values[i].toDouble()); + } +} + +QString DeclarativeBoxSet::brushFilename() const +{ + return m_brushFilename; +} + +void DeclarativeBoxSet::setBrushFilename(const QString &brushFilename) +{ + QImage brushImage(brushFilename); + if (QBoxSet::brush().textureImage() != brushImage) { + QBrush brush = QBoxSet::brush(); + brush.setTextureImage(brushImage); + QBoxSet::setBrush(brush); + m_brushFilename = brushFilename; + m_brushImage = brushImage; + emit brushFilenameChanged(brushFilename); + } +} + +void DeclarativeBoxSet::handleBrushChanged() +{ + // If the texture image of the brush has changed along the brush + // the brush file name needs to be cleared. + if (!m_brushFilename.isEmpty() && QBoxSet::brush().textureImage() != m_brushImage) { + m_brushFilename.clear(); + emit brushFilenameChanged(QString("")); + } +} + +// ===================================================== + +DeclarativeBoxPlotSeries::DeclarativeBoxPlotSeries(QQuickItem *parent) : + QBoxPlotSeries(parent), + m_axes(new DeclarativeAxes(this)) +{ + connect(m_axes, SIGNAL(axisXChanged(QAbstractAxis*)), this, SIGNAL(axisXChanged(QAbstractAxis*))); + connect(m_axes, SIGNAL(axisYChanged(QAbstractAxis*)), this, SIGNAL(axisYChanged(QAbstractAxis*))); + connect(m_axes, SIGNAL(axisXTopChanged(QAbstractAxis*)), this, SIGNAL(axisXTopChanged(QAbstractAxis*))); + connect(m_axes, SIGNAL(axisYRightChanged(QAbstractAxis*)), this, SIGNAL(axisYRightChanged(QAbstractAxis*))); + connect(this, SIGNAL(hovered(bool, QBoxSet*)), this, SLOT(onHovered(bool, QBoxSet*))); + connect(this, SIGNAL(clicked(QBoxSet*)), this, SLOT(onClicked(QBoxSet*))); + connect(this, SIGNAL(brushChanged()), this, SLOT(handleBrushChanged())); +} + +void DeclarativeBoxPlotSeries::classBegin() +{ +} + +void DeclarativeBoxPlotSeries::componentComplete() +{ + foreach (QObject *child, children()) { + if (qobject_cast<DeclarativeBoxSet *>(child)) { + QBoxPlotSeries::append(qobject_cast<DeclarativeBoxSet *>(child)); + } else if (qobject_cast<QVBoxPlotModelMapper *>(child)) { + QVBoxPlotModelMapper *mapper = qobject_cast<QVBoxPlotModelMapper *>(child); + mapper->setSeries(this); + } + } +} + +QQmlListProperty<QObject> DeclarativeBoxPlotSeries::seriesChildren() +{ + return QQmlListProperty<QObject>(this, 0, &DeclarativeBoxPlotSeries::appendSeriesChildren ,0,0,0); +} + +void DeclarativeBoxPlotSeries::appendSeriesChildren(QQmlListProperty<QObject> *list, QObject *element) +{ + // Empty implementation; the children are parsed in componentComplete instead + Q_UNUSED(list); + Q_UNUSED(element); +} + +DeclarativeBoxSet *DeclarativeBoxPlotSeries::at(int index) +{ + QList<QBoxSet *> setList = boxSets(); + if (index >= 0 && index < setList.count()) + return qobject_cast<DeclarativeBoxSet *>(setList[index]); + + return 0; +} + +DeclarativeBoxSet *DeclarativeBoxPlotSeries::insert(int index, const QString label, QVariantList values) +{ + DeclarativeBoxSet *barset = new DeclarativeBoxSet(label, this); + barset->setValues(values); + if (QBoxPlotSeries::insert(index, barset)) + return barset; + delete barset; + return 0; +} + +void DeclarativeBoxPlotSeries::onHovered(bool status, QBoxSet *boxset) +{ + emit hovered(status, qobject_cast<DeclarativeBoxSet *>(boxset)); +} + +void DeclarativeBoxPlotSeries::onClicked(QBoxSet *boxset) +{ + emit clicked(qobject_cast<DeclarativeBoxSet *>(boxset)); +} + +QString DeclarativeBoxPlotSeries::brushFilename() const +{ + return m_brushFilename; +} + +void DeclarativeBoxPlotSeries::setBrushFilename(const QString &brushFilename) +{ + QImage brushImage(brushFilename); + if (QBoxPlotSeries::brush().textureImage() != brushImage) { + QBrush brush = QBoxPlotSeries::brush(); + brush.setTextureImage(brushImage); + QBoxPlotSeries::setBrush(brush); + m_brushFilename = brushFilename; + m_brushImage = brushImage; + emit brushFilenameChanged(brushFilename); + } +} + +void DeclarativeBoxPlotSeries::handleBrushChanged() +{ + // If the texture image of the brush has changed along the brush + // the brush file name needs to be cleared. + if (!m_brushFilename.isEmpty() && QBoxPlotSeries::brush().textureImage() != m_brushImage) { + m_brushFilename.clear(); + emit brushFilenameChanged(QString("")); + } +} + +#include "moc_declarativeboxplotseries.cpp" + +QT_CHARTS_END_NAMESPACE |