summaryrefslogtreecommitdiffstats
path: root/src/charts/candlestickchart/qcandlestickseries.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/charts/candlestickchart/qcandlestickseries.cpp')
-rw-r--r--src/charts/candlestickchart/qcandlestickseries.cpp1138
1 files changed, 1138 insertions, 0 deletions
diff --git a/src/charts/candlestickchart/qcandlestickseries.cpp b/src/charts/candlestickchart/qcandlestickseries.cpp
new file mode 100644
index 00000000..2e04d6cf
--- /dev/null
+++ b/src/charts/candlestickchart/qcandlestickseries.cpp
@@ -0,0 +1,1138 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCharts/QBarCategoryAxis>
+#include <QtCharts/QCandlestickLegendMarker>
+#include <QtCharts/QCandlestickSeries>
+#include <QtCharts/QCandlestickSet>
+#include <QtCharts/QValueAxis>
+#include <QtCore/QDateTime>
+#include <private/candlestickanimation_p.h>
+#include <private/candlestickchartitem_p.h>
+#include <private/chartdataset_p.h>
+#include <private/charttheme_p.h>
+#include <private/qcandlestickseries_p.h>
+#include <private/qcandlestickset_p.h>
+#include <private/qchart_p.h>
+
+QT_CHARTS_BEGIN_NAMESPACE
+
+/*!
+ \class QCandlestickSeries
+ \since 5.8
+ \inmodule Qt Charts
+ \brief Series for creating a candlestick chart.
+
+ QCandlestickSeries represents a series of data shown as candlesticks. The purpose of this class
+ is to act as a container for single candlestick items. Each item is drawn to its own category
+ when using QBarCategoryAxis. QDateTimeAxis and QValueAxis can be used as alternatives to
+ QBarCategoryAxis. In this case, each candlestick item is drawn according to its timestamp value.
+
+ \note The timestamps must be unique within a QCandlestickSeries. When using QBarCategoryAxis,
+ only the first one of the candlestick items sharing a timestamp is drawn. If the chart includes
+ multiple instances of QCandlestickSeries, items from different series sharing a timestamp are
+ drawn to the same category. When using QValueAxis or QDateTimeAxis, candlestick items sharing a
+ timestamp will overlap each other.
+
+ See the \l {Candlestick Chart Example} {candlestick chart example} to learn how to create
+ a candlestick chart.
+ \image examples_candlestickchart.png
+
+ \sa QCandlestickSet, QBarCategoryAxis, QDateTimeAxis, QValueAxis
+*/
+
+/*!
+ \qmltype CandlestickSeries
+ \since 2.2
+ \instantiates QCandlestickSeries
+ \inqmlmodule QtCharts
+ \inherits AbstractSeries
+ \brief Series for creating a candlestick chart.
+
+ CandlestickSeries represents a series of data shown as candlesticks. The purpose of this class
+ is to act as a container for single candlestick items. Each item is drawn to its own category
+ when using BarCategoryAxis. DateTimeAxis and ValueAxis can be used as an alternative to
+ BarCategoryAxis. In this case each candlestick item is drawn according to its timestamp value.
+
+ \note The timestamps must be unique within a CandlestickSeries. When using BarCategoryAxis, only
+ the first one of the candlestick items sharing a timestamp is drawn. If the chart includes
+ multiple instances of CandlestickSeries, items from different series sharing a timestamp are
+ drawn to the same category. When using ValueAxis or DateTimeAxis, candlestick items sharing a
+ timestamp will overlap each other.
+
+ The following QML shows how to create a simple candlestick chart:
+ \code
+ import QtQuick 2.5
+ import QtCharts 2.2
+
+ ChartView {
+ title: "Candlestick Series"
+ width: 400
+ height: 300
+
+ CandlestickSeries {
+ name: "Acme Ltd."
+ increasingColor: "green"
+ decreasingColor: "red"
+
+ CandlestickSet { timestamp: 1435708800000; open: 690; high: 694; low: 599; close: 660 }
+ CandlestickSet { timestamp: 1435795200000; open: 669; high: 669; low: 669; close: 669 }
+ CandlestickSet { timestamp: 1436140800000; open: 485; high: 623; low: 485; close: 600 }
+ CandlestickSet { timestamp: 1436227200000; open: 589; high: 615; low: 377; close: 569 }
+ CandlestickSet { timestamp: 1436313600000; open: 464; high: 464; low: 254; close: 254 }
+ }
+ }
+ \endcode
+
+ \beginfloatleft
+ \image examples_qmlcandlestick.png
+ \endfloat
+ \clearfloat
+
+ \sa CandlestickSet, BarCategoryAxis, DateTimeAxis, ValueAxis
+*/
+
+/*!
+ \property QCandlestickSeries::count
+ \brief The count of sets in series.
+*/
+
+/*!
+ \qmlproperty int CandlestickSeries::count
+ The count of sets in series.
+*/
+
+/*!
+ \property QCandlestickSeries::maximumColumnWidth
+ \brief The maximum width of the candlestick items in pixels. Setting a negative value means
+ there is no maximum width. All negative values are converted to -1.0.
+*/
+
+/*!
+ \qmlproperty qreal CandlestickSeries::maximumColumnWidth
+ \brief The maximum width of the candlestick items in pixels. Setting a negative value means
+ there is no maximum width. All negative values are converted to -1.0.
+*/
+
+/*!
+ \property QCandlestickSeries::minimumColumnWidth
+ \brief The minimum width of the candlestick items in pixels. Setting a negative value means
+ there is no minimum width. All negative values are converted to -1.0.
+*/
+
+/*!
+ \qmlproperty qreal CandlestickSeries::minimumColumnWidth
+ \brief The minimum width of the candlestick items in pixels. Setting a negative value means
+ there is no minimum width. All negative values are converted to -1.0.
+*/
+
+/*!
+ \property QCandlestickSeries::bodyWidth
+ \brief The width of the candlestick items.
+
+ The value signifies the relative width of the candlestick item inside its own slot, in the range
+ 0.0 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
+*/
+
+/*!
+ \qmlproperty qreal CandlestickSeries::bodyWidth
+ \brief The width of the candlestick items.
+
+ The value signifies the relative width of the candlestick item inside its own slot, in the range
+ 0.0 to 1.0. Values outside this range are clamped to 0.0 or 1.0.
+*/
+
+/*!
+ \property QCandlestickSeries::bodyOutlineVisible
+ \brief The visibility of the candlestick body outlines.
+*/
+
+/*!
+ \qmlproperty bool CandlestickSeries::bodyOutlineVisible
+ \brief The visibility of the candlestick body outlines.
+*/
+
+/*!
+ \property QCandlestickSeries::capsWidth
+ \brief The width of the caps.
+
+ The value signifies the relative width of the caps inside its own candlestick, in the range 0.0
+ to 1.0. Values outside this range are clamped to 0.0 or 1.0.
+*/
+
+/*!
+ \qmlproperty qreal CandlestickSeries::capsWidth
+ \brief The width of the caps.
+
+ The value signifies the relative width of the caps inside its own candlestick, in the range 0.0
+ to 1.0. Values outside this range are clamped to 0.0 or 1.0.
+*/
+
+/*!
+ \property QCandlestickSeries::capsVisible
+ \brief The visibility of the caps.
+*/
+
+/*!
+ \qmlproperty bool CandlestickSeries::capsVisible
+ \brief The visibility of the caps.
+*/
+
+/*!
+ \property QCandlestickSeries::increasingColor
+ \brief The color of the increasing candlestick item body. Candlestick is \e increasing when its
+ close value is higher than the open value. By default this property is set to brush color.
+ Default color is used also when the property is set to an invalid color value.
+*/
+
+/*!
+ \qmlproperty QColor CandlestickSeries::increasingColor
+ \brief The color of the increasing candlestick item body. Candlestick is \e increasing when its
+ close value is higher than the open value. By default this property is set to brush color.
+ Default color is used also when the property is set to an invalid color value.
+*/
+
+/*!
+ \property QCandlestickSeries::decreasingColor
+ \brief The color of the decreasing candlestick item body. Candlestick is \e decreasing when its
+ open value is higher than the close value. By default this property is set to brush color with
+ alpha channel set to 128. Default color is used also when the property is set to an invalid
+ color value.
+*/
+
+/*!
+ \qmlproperty QColor CandlestickSeries::decreasingColor
+ \brief The color of the decreasing candlestick item body. Candlestick is \e decreasing when its
+ open value is higher than the close value. By default this property is set to brush color with
+ alpha channel set to 128. Default color is used also when the property is set to an invalid
+ color value.
+*/
+
+/*!
+ \property QCandlestickSeries::brush
+ \brief The brush of the candlestick items.
+*/
+
+/*!
+ \property QCandlestickSeries::pen
+ \brief The pen of the candlestick items.
+*/
+
+/*!
+ \qmlproperty QString CandlestickSeries::brushFilename
+ \brief The name of the file used as a brush for the series.
+*/
+
+/*!
+ \fn void QCandlestickSeries::clicked(QCandlestickSet *set)
+ \brief Emitted when a \a set is clicked (pressed and released) on the chart.
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::clicked(CandlestickSet set)
+ \brief Emitted when a \a set is clicked (pressed and released) on the chart.
+
+ The corresponding signal handler is \c {onClicked}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::hovered(bool status, QCandlestickSet *set)
+ \brief Emitted when there is change in hover \a status over the \a set.
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::hovered(bool status, CandlestickSet set)
+ \brief Emitted when there is change in hover \a status over the \a set.
+
+ The corresponding signal handler is \c {onHovered}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::pressed(QCandlestickSet *set)
+ \brief Emitted when a \a set is pressed on the chart.
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::pressed(CandlestickSet set)
+ \brief Emitted when a \a set is pressed on the chart.
+
+ The corresponding signal handler is \c {onPressed}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::released(QCandlestickSet *set)
+ \brief Emitted when a \a set is released on the chart.
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::released(CandlestickSet set)
+ \brief Emitted when a \a set is released on the chart.
+
+ The corresponding signal handler is \c {onReleased}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::doubleClicked(QCandlestickSet *set)
+ \brief Emitted when a \a set is double-clicked on the chart.
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::doubleClicked(CandlestickSet set)
+ \brief Emitted when a \a set is double-clicked on the chart.
+
+ The corresponding signal handler is \c {onDoubleClicked}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::candlestickSetsAdded(const QList<QCandlestickSet *> &sets)
+ \brief Emitted when new \a sets are added to the series.
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::candlestickSetsAdded(list<CandlestickSet> sets)
+ \brief Emitted when new \a sets are added to the series.
+
+ The corresponding signal handler is \c {onCandlestickSetsAdded}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::candlestickSetsRemoved(const QList<QCandlestickSet *> &sets)
+ \brief Emitted when \a sets are removed from the series.
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::candlestickSetsRemoved(list<CandlestickSet> sets)
+ \brief Emitted when \a sets are removed from the series.
+
+ The corresponding signal handler is \c {onCandlestickSetsRemoved}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::countChanged()
+ \brief Emitted when there is a change in the count of candlestick items in the series.
+ \sa count
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::countChanged()
+ \brief Emitted when there is a change in the count of candlestick items in the series.
+ \sa count
+
+ The corresponding signal handler is \c {onCountChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::maximumColumnWidthChanged()
+ \brief Emitted when there is a change in the maximum column width of candlestick items.
+ \sa maximumColumnWidth
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::maximumColumnWidthChanged()
+ \brief Emitted when there is a change in the maximum column width of candlestick items.
+ \sa maximumColumnWidth
+
+ The corresponding signal handler is \c {onMaximumColumnWidthChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::minimumColumnWidthChanged()
+ \brief Emitted when there is a change in the minimum column width of candlestick items.
+ \sa minimumColumnWidth
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::minimumColumnWidthChanged()
+ \brief Emitted when there is a change in the minimum column width of candlestick items.
+ \sa minimumColumnWidth
+
+ The corresponding signal handler is \c {onMinimumColumnWidthChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::bodyWidthChanged()
+ \brief Emitted when the candlestick item width is changed.
+ \sa bodyWidth
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::bodyWidthChanged()
+ \brief Emitted when the candlestick item width is changed.
+ \sa bodyWidth
+
+ The corresponding signal handler is \c {onBodyWidthChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::bodyOutlineVisibilityChanged()
+ \brief Emitted when the visibility of the candlestick item body outline is changed.
+ \sa bodyOutlineVisible
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::bodyOutlineVisibilityChanged()
+ \brief Emitted when the visibility of the candlestick item body outline is changed.
+ \sa bodyOutlineVisible
+
+ The corresponding signal handler is \c {onBodyOutlineVisibilityChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::capsWidthChanged()
+ \brief Emitted when the candlestick item caps width is changed.
+ \sa capsWidth
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::capsWidthChanged()
+ \brief Emitted when the candlestick item caps width is changed.
+ \sa capsWidth
+
+ The corresponding signal handler is \c {onCapsWidthChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::capsVisibilityChanged()
+ \brief Emitted when the visibility of the candlestick item caps is changed.
+ \sa capsVisible
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::capsVisibilityChanged()
+ \brief Emitted when the visibility of the candlestick item caps is changed.
+ \sa capsVisible
+
+ The corresponding signal handler is \c {onCapsVisibilityChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::increasingColorChanged()
+ \brief Emitted when the candlestick item increasing color is changed.
+ \sa increasingColor
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::increasingColorChanged()
+ \brief Emitted when the candlestick item increasing color is changed.
+ \sa increasingColor
+
+ The corresponding signal handler is \c {onIncreasingColorChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::decreasingColorChanged()
+ \brief Emitted when the candlestick item decreasing color is changed.
+ \sa decreasingColor
+*/
+
+/*!
+ \qmlsignal CandlestickSeries::decreasingColorChanged()
+ \brief Emitted when the candlestick item decreasing color is changed.
+ \sa decreasingColor
+
+ The corresponding signal handler is \c {onDecreasingColorChanged}.
+*/
+
+/*!
+ \fn void QCandlestickSeries::brushChanged()
+ \brief Emitted when the candlestick item brush is changed.
+ \sa brush
+*/
+
+/*!
+ \fn void QCandlestickSeries::penChanged()
+ \brief Emitted when the candlestick item pen is changed.
+ \sa pen
+*/
+
+/*!
+ Constructs an empty QCandlestickSeries. The \a parent is optional.
+*/
+QCandlestickSeries::QCandlestickSeries(QObject *parent)
+ : QAbstractSeries(*new QCandlestickSeriesPrivate(this), parent)
+{
+}
+
+/*!
+ Destroys the series. Removes the series from the chart.
+*/
+QCandlestickSeries::~QCandlestickSeries()
+{
+ Q_D(QCandlestickSeries);
+ if (d->m_chart)
+ d->m_chart->removeSeries(this);
+}
+
+/*!
+ Adds a single set to the series. Takes ownership of the \a set. If the set is \e null or is
+ already in the series, it won't be appended.
+ Returns \c true if appending succeeded, \c false otherwise.
+*/
+bool QCandlestickSeries::append(QCandlestickSet *set)
+{
+ QList<QCandlestickSet *> sets;
+ sets.append(set);
+
+ return append(sets);
+}
+
+/*!
+ Removes a single set from the series.
+ Returns \c true if the \a set is successfully deleted, \c false otherwise.
+*/
+bool QCandlestickSeries::remove(QCandlestickSet *set)
+{
+ QList<QCandlestickSet *> sets;
+ sets.append(set);
+
+ return remove(sets);
+}
+
+/*!
+ Adds a list of sets to the series. Takes ownership of the \a sets. If any of the sets are
+ \e null, already appended to the series, or the list contains duplicated sets, nothing is
+ appended.
+ Returns \c true if all sets were appended successfully, \c false otherwise.
+*/
+bool QCandlestickSeries::append(const QList<QCandlestickSet *> &sets)
+{
+ Q_D(QCandlestickSeries);
+
+ bool success = d->append(sets);
+ if (success) {
+ emit candlestickSetsAdded(sets);
+ emit countChanged();
+ }
+
+ return success;
+}
+
+/*!
+ Removes a list of sets from the series. If any of the \a sets are \e null, already removed from
+ the series, or the list contains duplicated sets, nothing is removed.
+ Returns \c true if all sets were removed successfully, \c false otherwise.
+*/
+bool QCandlestickSeries::remove(const QList<QCandlestickSet *> &sets)
+{
+ Q_D(QCandlestickSeries);
+
+ bool success = d->remove(sets);
+ if (success) {
+ emit candlestickSetsRemoved(sets);
+ emit countChanged();
+ foreach (QCandlestickSet *set, sets)
+ set->deleteLater();
+ }
+
+ return success;
+}
+
+/*!
+ Inserts a set to the series at \a index position. Takes ownership of the \a set. If the set is
+ \e null or already in the series, it won't be appended.
+ Returns \c true if inserting succeeded, \c false otherwise.
+*/
+bool QCandlestickSeries::insert(int index, QCandlestickSet *set)
+{
+ Q_D(QCandlestickSeries);
+
+ bool success = d->insert(index, set);
+ if (success) {
+ QList<QCandlestickSet *> sets;
+ sets.append(set);
+ emit candlestickSetsAdded(sets);
+ emit countChanged();
+ }
+
+ return success;
+}
+
+/*!
+ Takes a single \a set from the series. Does not delete the set object.
+ Returns \c true if take was successful, \c false otherwise.
+ \note The series remains as the set's parent object. You must set the parent object to take full
+ ownership.
+*/
+bool QCandlestickSeries::take(QCandlestickSet *set)
+{
+ Q_D(QCandlestickSeries);
+
+ QList<QCandlestickSet *> sets;
+ sets.append(set);
+
+ bool success = d->remove(sets);
+ if (success) {
+ emit candlestickSetsRemoved(sets);
+ emit countChanged();
+ }
+
+ return success;
+}
+
+/*!
+ Removes all sets from the series, and deletes them.
+*/
+void QCandlestickSeries::clear()
+{
+ Q_D(QCandlestickSeries);
+
+ QList<QCandlestickSet *> sets = candlestickSets();
+
+ bool success = d->remove(sets);
+ if (success) {
+ emit candlestickSetsRemoved(sets);
+ emit countChanged();
+ foreach (QCandlestickSet *set, sets)
+ set->deleteLater();
+ }
+}
+
+/*!
+ Returns the list of sets in the series. Ownership of the sets is unchanged.
+ */
+QList<QCandlestickSet *> QCandlestickSeries::candlestickSets() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_candlestickSets;
+}
+
+/*!
+ Returns the number of the sets in the series.
+*/
+int QCandlestickSeries::count() const
+{
+ return candlestickSets().count();
+}
+
+/*!
+ Returns the type of the series (QAbstractSeries::SeriesTypeCandlestick).
+*/
+QAbstractSeries::SeriesType QCandlestickSeries::type() const
+{
+ return QAbstractSeries::SeriesTypeCandlestick;
+}
+
+void QCandlestickSeries::setMaximumColumnWidth(qreal maximumColumnWidth)
+{
+ Q_D(QCandlestickSeries);
+
+ if (maximumColumnWidth < 0.0 && maximumColumnWidth != -1.0)
+ maximumColumnWidth = -1.0;
+
+ if (d->m_maximumColumnWidth == maximumColumnWidth)
+ return;
+
+ d->m_maximumColumnWidth = maximumColumnWidth;
+
+ emit d->updatedLayout();
+ emit maximumColumnWidthChanged();
+}
+
+qreal QCandlestickSeries::maximumColumnWidth() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_maximumColumnWidth;
+}
+
+void QCandlestickSeries::setMinimumColumnWidth(qreal minimumColumnWidth)
+{
+ Q_D(QCandlestickSeries);
+
+ if (minimumColumnWidth < 0.0 && minimumColumnWidth != -1.0)
+ minimumColumnWidth = -1.0;
+
+ if (d->m_minimumColumnWidth == minimumColumnWidth)
+ return;
+
+ d->m_minimumColumnWidth = minimumColumnWidth;
+
+ d->updatedLayout();
+ emit minimumColumnWidthChanged();
+}
+
+qreal QCandlestickSeries::minimumColumnWidth() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_minimumColumnWidth;
+}
+
+void QCandlestickSeries::setBodyWidth(qreal bodyWidth)
+{
+ Q_D(QCandlestickSeries);
+
+ if (bodyWidth < 0.0)
+ bodyWidth = 0.0;
+ else if (bodyWidth > 1.0)
+ bodyWidth = 1.0;
+
+ if (d->m_bodyWidth == bodyWidth)
+ return;
+
+ d->m_bodyWidth = bodyWidth;
+
+ emit d->updatedLayout();
+ emit bodyWidthChanged();
+}
+
+qreal QCandlestickSeries::bodyWidth() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_bodyWidth;
+}
+
+void QCandlestickSeries::setBodyOutlineVisible(bool bodyOutlineVisible)
+{
+ Q_D(QCandlestickSeries);
+
+ if (d->m_bodyOutlineVisible == bodyOutlineVisible)
+ return;
+
+ d->m_bodyOutlineVisible = bodyOutlineVisible;
+
+ emit d->updated();
+ emit bodyOutlineVisibilityChanged();
+}
+
+bool QCandlestickSeries::bodyOutlineVisible() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_bodyOutlineVisible;
+}
+
+void QCandlestickSeries::setCapsWidth(qreal capsWidth)
+{
+ Q_D(QCandlestickSeries);
+
+ if (capsWidth < 0.0)
+ capsWidth = 0.0;
+ else if (capsWidth > 1.0)
+ capsWidth = 1.0;
+
+ if (d->m_capsWidth == capsWidth)
+ return;
+
+ d->m_capsWidth = capsWidth;
+
+ emit d->updatedLayout();
+ emit capsWidthChanged();
+}
+
+qreal QCandlestickSeries::capsWidth() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_capsWidth;
+}
+
+void QCandlestickSeries::setCapsVisible(bool capsVisible)
+{
+ Q_D(QCandlestickSeries);
+
+ if (d->m_capsVisible == capsVisible)
+ return;
+
+ d->m_capsVisible = capsVisible;
+
+ emit d->updated();
+ emit capsVisibilityChanged();
+}
+
+bool QCandlestickSeries::capsVisible() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_capsVisible;
+}
+
+void QCandlestickSeries::setIncreasingColor(const QColor &increasingColor)
+{
+ Q_D(QCandlestickSeries);
+
+ QColor color;
+ if (increasingColor.isValid()) {
+ color = increasingColor;
+ d->m_customIncreasingColor = true;
+ } else {
+ color = d->m_brush.color();
+ color.setAlpha(128);
+ d->m_customIncreasingColor = false;
+ }
+
+ if (d->m_increasingColor == color)
+ return;
+
+ d->m_increasingColor = color;
+
+ emit d->updated();
+ emit increasingColorChanged();
+}
+
+QColor QCandlestickSeries::increasingColor() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_increasingColor;
+}
+
+void QCandlestickSeries::setDecreasingColor(const QColor &decreasingColor)
+{
+ Q_D(QCandlestickSeries);
+
+ QColor color;
+ if (decreasingColor.isValid()) {
+ color = decreasingColor;
+ d->m_customDecreasingColor = true;
+ } else {
+ color = d->m_brush.color();
+ d->m_customDecreasingColor = false;
+ }
+
+ if (d->m_decreasingColor == color)
+ return;
+
+ d->m_decreasingColor = color;
+
+ emit d->updated();
+ emit decreasingColorChanged();
+}
+
+QColor QCandlestickSeries::decreasingColor() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_decreasingColor;
+}
+
+void QCandlestickSeries::setBrush(const QBrush &brush)
+{
+ Q_D(QCandlestickSeries);
+
+ if (d->m_brush == brush)
+ return;
+
+ d->m_brush = brush;
+ if (!d->m_customIncreasingColor) {
+ QColor color = d->m_brush.color();
+ color.setAlpha(128);
+ if (d->m_increasingColor != color) {
+ d->m_increasingColor = color;
+ emit increasingColorChanged();
+ }
+ }
+ if (!d->m_customDecreasingColor && d->m_decreasingColor != d->m_brush.color()) {
+ d->m_decreasingColor = d->m_brush.color();
+ emit decreasingColorChanged();
+ }
+
+ emit d->updated();
+ emit brushChanged();
+}
+
+QBrush QCandlestickSeries::brush() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_brush;
+}
+
+void QCandlestickSeries::setPen(const QPen &pen)
+{
+ Q_D(QCandlestickSeries);
+
+ if (d->m_pen == pen)
+ return;
+
+ d->m_pen = pen;
+
+ emit d->updated();
+ emit penChanged();
+}
+
+QPen QCandlestickSeries::pen() const
+{
+ Q_D(const QCandlestickSeries);
+
+ return d->m_pen;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QCandlestickSeriesPrivate::QCandlestickSeriesPrivate(QCandlestickSeries *q)
+ : QAbstractSeriesPrivate(q),
+ m_maximumColumnWidth(-1.0),
+ m_minimumColumnWidth(5.0),
+ m_bodyWidth(0.5),
+ m_bodyOutlineVisible(true),
+ m_capsWidth(0.5),
+ m_capsVisible(false),
+ m_increasingColor(QColor(Qt::transparent)),
+ m_decreasingColor(QChartPrivate::defaultBrush().color()),
+ m_customIncreasingColor(false),
+ m_customDecreasingColor(false),
+ m_brush(QChartPrivate::defaultBrush()),
+ m_pen(QChartPrivate::defaultPen()),
+ m_animation(nullptr)
+{
+}
+
+QCandlestickSeriesPrivate::~QCandlestickSeriesPrivate()
+{
+ disconnect(this, 0, 0, 0);
+}
+
+void QCandlestickSeriesPrivate::initializeDomain()
+{
+ qreal minX(domain()->minX());
+ qreal maxX(domain()->maxX());
+ qreal minY(domain()->minY());
+ qreal maxY(domain()->maxY());
+
+ if (m_candlestickSets.count()) {
+ QCandlestickSet *set = m_candlestickSets.first();
+ minX = set->timestamp();
+ maxX = set->timestamp();
+ minY = set->low();
+ maxY = set->high();
+ for (int i = 1; i < m_candlestickSets.count(); ++i) {
+ set = m_candlestickSets.at(i);
+ minX = qMin(minX, qreal(set->timestamp()));
+ maxX = qMax(maxX, qreal(set->timestamp()));
+ minY = qMin(minY, set->low());
+ maxY = qMax(maxY, set->high());
+ }
+ qreal extra = (maxX - minX) / m_candlestickSets.count() / 2;
+ minX = minX - extra;
+ maxX = maxX + extra;
+ }
+
+ domain()->setRange(minX, maxX, minY, maxY);
+}
+
+void QCandlestickSeriesPrivate::initializeAxes()
+{
+ foreach (QAbstractAxis* axis, m_axes) {
+ if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
+ if (axis->orientation() == Qt::Horizontal)
+ populateBarCategories(qobject_cast<QBarCategoryAxis *>(axis));
+ }
+ }
+}
+
+void QCandlestickSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
+{
+ Q_Q(QCandlestickSeries);
+
+ if (forced || QChartPrivate::defaultBrush() == m_brush) {
+ const QList<QGradient> gradients = theme->seriesGradients();
+ const QGradient gradient = gradients.at(index % gradients.size());
+ const QBrush brush(ChartThemeManager::colorAt(gradient, 0.5));
+ q->setBrush(brush);
+ }
+
+ if (forced || QChartPrivate::defaultPen() == m_pen) {
+ QPen pen = theme->outlinePen();
+ pen.setCosmetic(true);
+ q->setPen(pen);
+ }
+}
+
+void QCandlestickSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
+{
+ Q_Q(QCandlestickSeries);
+
+ CandlestickChartItem *item = new CandlestickChartItem(q, parent);
+ m_item.reset(item);
+ QAbstractSeriesPrivate::initializeGraphics(parent);
+
+ if (m_chart) {
+ connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries *)),
+ this, SLOT(handleSeriesChange(QAbstractSeries *)));
+ connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)),
+ this, SLOT(handleSeriesRemove(QAbstractSeries *)));
+
+ item->handleCandlestickSeriesChange();
+ }
+}
+
+void QCandlestickSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration,
+ QEasingCurve &curve)
+{
+ CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
+ Q_ASSERT(item);
+
+ if (item->animation())
+ item->animation()->stopAndDestroyLater();
+
+ if (options.testFlag(QChart::SeriesAnimations))
+ m_animation = new CandlestickAnimation(item, duration, curve);
+ else
+ m_animation = nullptr;
+ item->setAnimation(m_animation);
+
+ QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);
+}
+
+QList<QLegendMarker *> QCandlestickSeriesPrivate::createLegendMarkers(QLegend *legend)
+{
+ Q_Q(QCandlestickSeries);
+
+ QList<QLegendMarker *> list;
+
+ return list << new QCandlestickLegendMarker(q, legend);
+}
+
+QAbstractAxis::AxisType QCandlestickSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
+{
+ if (orientation == Qt::Horizontal)
+ return QAbstractAxis::AxisTypeBarCategory;
+
+ if (orientation == Qt::Vertical)
+ return QAbstractAxis::AxisTypeValue;
+
+ return QAbstractAxis::AxisTypeNoAxis;
+}
+
+QAbstractAxis* QCandlestickSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
+{
+ const QAbstractAxis::AxisType axisType = defaultAxisType(orientation);
+
+ if (axisType == QAbstractAxis::AxisTypeBarCategory)
+ return new QBarCategoryAxis;
+
+ if (axisType == QAbstractAxis::AxisTypeValue)
+ return new QValueAxis;
+
+ return 0; // axisType == QAbstractAxis::AxisTypeNoAxis
+}
+
+bool QCandlestickSeriesPrivate::append(const QList<QCandlestickSet *> &sets)
+{
+ foreach (QCandlestickSet *set, sets) {
+ if ((set == 0) || m_candlestickSets.contains(set) || set->d_ptr->m_series)
+ return false; // Fail if any of the sets is null or is already appended.
+ if (sets.count(set) != 1)
+ return false; // Also fail if the same set occurs more than once in the given list.
+ }
+
+ foreach (QCandlestickSet *set, sets) {
+ m_candlestickSets.append(set);
+ connect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
+ connect(set->d_func(), SIGNAL(updatedCandlestick()), this, SIGNAL(updatedCandlesticks()));
+ set->d_ptr->m_series = this;
+ }
+
+ return true;
+}
+
+bool QCandlestickSeriesPrivate::remove(const QList<QCandlestickSet *> &sets)
+{
+ if (sets.count() == 0)
+ return false;
+
+ foreach (QCandlestickSet *set, sets) {
+ if ((set == 0) || (!m_candlestickSets.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 the same set occurs more than once in the given list.
+ }
+
+ foreach (QCandlestickSet *set, sets) {
+ set->d_ptr->m_series = nullptr;
+ m_candlestickSets.removeOne(set);
+ disconnect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
+ disconnect(set->d_func(), SIGNAL(updatedCandlestick()),this, SIGNAL(updatedCandlesticks()));
+ }
+
+ return true;
+}
+
+bool QCandlestickSeriesPrivate::insert(int index, QCandlestickSet *set)
+{
+ if ((m_candlestickSets.contains(set)) || (set == 0) || set->d_ptr->m_series)
+ return false; // Fail if set is already in list or set is null.
+
+ m_candlestickSets.insert(index, set);
+ connect(set->d_func(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
+ connect(set->d_func(), SIGNAL(updatedCandlestick()), this, SIGNAL(updatedCandlesticks()));
+ set->d_ptr->m_series = this;
+
+ return true;
+}
+
+void QCandlestickSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
+{
+ Q_UNUSED(series);
+
+ if (m_chart) {
+ CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
+ if (item)
+ item->handleCandlestickSeriesChange();
+ }
+}
+
+void QCandlestickSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
+{
+ Q_Q(const QCandlestickSeries);
+
+ QCandlestickSeries *removedSeries = static_cast<QCandlestickSeries *>(series);
+
+ if (q == removedSeries && m_animation) {
+ m_animation->stopAll();
+ disconnect(m_chart->d_ptr->m_dataset, 0, removedSeries->d_func(), 0);
+ }
+
+ if (q != removedSeries) {
+ CandlestickChartItem *item = static_cast<CandlestickChartItem *>(m_item.data());
+ if (item)
+ item->handleCandlestickSeriesChange();
+ }
+}
+
+void QCandlestickSeriesPrivate::populateBarCategories(QBarCategoryAxis *axis)
+{
+ if (axis->categories().isEmpty()) {
+ QStringList categories;
+ for (int i = 0; i < m_candlestickSets.count(); ++i) {
+ const qint64 timestamp = qRound64(m_candlestickSets.at(i)->timestamp());
+ const QString timestampFormat = m_chart->locale().dateTimeFormat(QLocale::ShortFormat);
+ categories << QDateTime::fromMSecsSinceEpoch(timestamp).toString(timestampFormat);
+ }
+ axis->append(categories);
+ }
+}
+
+#include "moc_qcandlestickseries.cpp"
+#include "moc_qcandlestickseries_p.cpp"
+
+QT_CHARTS_END_NAMESPACE