/**************************************************************************** ** ** 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 #include #include #include #include #include #include #include #include #include #include #include #include QT_CHARTS_BEGIN_NAMESPACE /*! \class QCandlestickSeries \since 5.8 \inmodule QtCharts \brief The QCandlestickSeries class presents data as candlesticks. This class acts 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 QtCharts 2.2 \instantiates QCandlestickSeries \inqmlmodule QtCharts \inherits AbstractSeries \brief Represents a series of data as candlesticks. The CandlestickSeries type acts 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 */ /*! \qmlproperty AbstractAxis CandlestickSeries::axisX The x-axis used for the series. If you leave both axisX and axisXTop undefined, a value axis is created for the series. \sa axisXTop, ValueAxis */ /*! \qmlproperty AbstractAxis CandlestickSeries::axisY The y-axis used for the series. If you leave both axisY and axisYRight undefined, a value axis is created for the series. \sa axisYRight, ValueAxis */ /*! \qmlproperty AbstractAxis CandlestickSeries::axisXTop The x-axis used for the series, drawn on top of the chart view. \note You can only provide either axisX or axisXTop, not both. \sa axisX */ /*! \qmlproperty AbstractAxis CandlestickSeries::axisYRight The y-axis used for the series, drawn to the right on the chart view. \note You can only provide either axisY or axisYRight, not both. \sa axisY */ /*! \property QCandlestickSeries::count \brief The number of candlestick items in a series. */ /*! \qmlproperty int CandlestickSeries::count The number of candlestick items in a 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 real CandlestickSeries::maximumColumnWidth 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 real CandlestickSeries::minimumColumnWidth 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 relative width of the candlestick item within its own slot, in the range from 0.0 to 1.0. Values outside this range are clamped to 0.0 or 1.0. */ /*! \qmlproperty real CandlestickSeries::bodyWidth The relative width of the candlestick item within its own slot, in the range from 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 outline. */ /*! \qmlproperty bool CandlestickSeries::bodyOutlineVisible The visibility of the candlestick body outlines. */ /*! \property QCandlestickSeries::capsWidth \brief The relative width of the caps within a candlestick, in the range from 0.0 to 1.0. Values outside this range are clamped to 0.0 or 1.0. */ /*! \qmlproperty real CandlestickSeries::capsWidth The relative width of the caps within a candlestick, in the range from 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 The visibility of the caps. */ /*! \property QCandlestickSeries::increasingColor \brief The color of the increasing candlestick item body. A candlestick is \e increasing when its close value is higher than the open value. By default, this property is set to the brush color. The default color is used also when the property is set to an invalid color value. */ /*! \qmlproperty color CandlestickSeries::increasingColor The color of the increasing candlestick item body. A candlestick is \e increasing when its close value is higher than the open value. By default, this property is set to the brush color. The 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. A candlestick is \e decreasing when its open value is higher than the close value. By default, this property is set to the brush color with the alpha channel set to 128. The default color is used also when the property is set to an invalid color value. */ /*! \qmlproperty color CandlestickSeries::decreasingColor The color of the decreasing candlestick item body. A candlestick is \e decreasing when its open value is higher than the close value. By default, this property is set to the brush color with the alpha channel set to 128. The default color is used also when the property is set to an invalid color value. */ /*! \property QCandlestickSeries::brush \brief The brush used to fill the candlestick items. */ /*! \property QCandlestickSeries::pen \brief The pen used to draw the lines of the candlestick items. */ /*! \qmlproperty string CandlestickSeries::brushFilename The name of the file used as a brush image for the series. */ /*! \fn void QCandlestickSeries::clicked(QCandlestickSet *set) This signal is emitted when the candlestick item specified by \a set is clicked on the chart. */ /*! \qmlsignal CandlestickSeries::clicked(CandlestickSet set) This signal is emitted when the candlestick item specified by \a set is clicked on the chart. The corresponding signal handler is \c {onClicked}. */ /*! \fn void QCandlestickSeries::hovered(bool status, QCandlestickSet *set) This signal is emitted when a mouse is hovered over the candlestick item specified by \a set in a chart. When the mouse moves over the item, \a status turns \c true, and when the mouse moves away again, it turns \c false. */ /*! \qmlsignal CandlestickSeries::hovered(bool status, CandlestickSet set) This signal is emitted when a mouse is hovered over the candlestick item specified by \a set in a chart. When the mouse moves over the item, \a status turns \c true, and when the mouse moves away again, it turns \c false. The corresponding signal handler is \c {onHovered}. */ /*! \fn void QCandlestickSeries::pressed(QCandlestickSet *set) This signal is emitted when the user clicks the candlestick item specified by \a set and holds down the mouse button. */ /*! \qmlsignal CandlestickSeries::pressed(CandlestickSet set) This signal is emitted when the user clicks the candlestick item specified by \a set and holds down the mouse button. The corresponding signal handler is \c {onPressed}. */ /*! \fn void QCandlestickSeries::released(QCandlestickSet *set) This signal is emitted when the user releases the mouse press on the candlestick item specified by \a set. */ /*! \qmlsignal CandlestickSeries::released(CandlestickSet set) This signal is emitted when the user releases the mouse press on the candlestick item specified by \a set. The corresponding signal handler is \c {onReleased}. */ /*! \fn void QCandlestickSeries::doubleClicked(QCandlestickSet *set) This signal is emitted when the candlestick item specified by \a set is double-clicked on the chart. */ /*! \qmlsignal CandlestickSeries::doubleClicked(CandlestickSet set) This signal is emitted when the candlestick item specified by \a set is double-clicked on the chart. The corresponding signal handler is \c {onDoubleClicked}. */ /*! \fn void QCandlestickSeries::candlestickSetsAdded(const QList &sets) This signal is emitted when the candlestick items specified by \a sets are added to the series. */ /*! \qmlsignal CandlestickSeries::candlestickSetsAdded(list sets) This signal is emitted when the candlestick items specified by \a sets are added to the series. The corresponding signal handler is \c {onCandlestickSetsAdded}. */ /*! \fn void QCandlestickSeries::candlestickSetsRemoved(const QList &sets) This signal is emitted when the candlestick items specified by \a sets are removed from the series. */ /*! \qmlsignal CandlestickSeries::candlestickSetsRemoved(list sets) This signal is emitted when the candlestick items specified by \a sets are removed from the series. The corresponding signal handler is \c {onCandlestickSetsRemoved}. */ /*! \fn void QCandlestickSeries::countChanged() This signal is emitted when the number of candlestick items in the series changes. \sa count */ /*! \fn void QCandlestickSeries::maximumColumnWidthChanged() This signal is emitted when there is a change in the maximum column width of candlestick items. \sa maximumColumnWidth */ /*! \fn void QCandlestickSeries::minimumColumnWidthChanged() This signal is emitted when there is a change in the minimum column width of candlestick items. \sa minimumColumnWidth */ /*! \fn void QCandlestickSeries::bodyWidthChanged() This signal is emitted when the candlestick item width changes. \sa bodyWidth */ /*! \fn void QCandlestickSeries::bodyOutlineVisibilityChanged() This signal is emitted when the visibility of the candlestick item body outline changes. \sa bodyOutlineVisible */ /*! \fn void QCandlestickSeries::capsWidthChanged() This signal is emitted when the candlestick item caps width changes. \sa capsWidth */ /*! \fn void QCandlestickSeries::capsVisibilityChanged() This signal is emitted when the visibility of the candlestick item caps changes. \sa capsVisible */ /*! \fn void QCandlestickSeries::increasingColorChanged() This signal is emitted when the candlestick item increasing color changes. \sa increasingColor */ /*! \fn void QCandlestickSeries::decreasingColorChanged() This signal is emitted when the candlestick item decreasing color changes. \sa decreasingColor */ /*! \fn void QCandlestickSeries::brushChanged() This signal is emitted when the candlestick item brush changes. \sa brush */ /*! \fn void QCandlestickSeries::penChanged() This signal is emitted when the candlestick item pen changes. \sa pen */ /*! \qmlmethod CandlestickSeries::at(int index) Returns the candlestick item at the position specified by \a index. Returns null if the index is not valid. */ /*! 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); } /*! \qmlmethod CandlestickSeries::append(CandlestickSet set) Adds a single candlestick item specified by \a set to the series and takes ownership of it. If the item is null or it is already in the series, it is not appended. Returns \c true if appending succeeded, \c false otherwise. */ /*! Adds a single candlestick item specified by \a set to the series and takes ownership of it. If the item is null or it is already in the series, it is not appended. Returns \c true if appending succeeded, \c false otherwise. */ bool QCandlestickSeries::append(QCandlestickSet *set) { QList sets; sets.append(set); return append(sets); } /*! \qmlmethod CandlestickSeries::remove(CandlestickSet set) Removes a single candlestick item, specified by \a set, from the series. Returns \c true if the item is successfully deleted, \c false otherwise. */ /*! Removes a single candlestick item, specified by \a set, from the series. Returns \c true if the item is successfully deleted, \c false otherwise. */ bool QCandlestickSeries::remove(QCandlestickSet *set) { QList sets; sets.append(set); return remove(sets); } /*! Adds a list of candlestick items specified by \a sets to the series and takes ownership of it. If any of the items are null, already belong to the series, or appear in the list more than once, nothing is appended. Returns \c true if all items were appended successfully, \c false otherwise. */ bool QCandlestickSeries::append(const QList &sets) { Q_D(QCandlestickSeries); bool success = d->append(sets); if (success) { emit candlestickSetsAdded(sets); emit countChanged(); } return success; } /*! Removes a list of candlestick items specified by \a sets from the series. If any of the items are null, were already removed from the series, or appear in the list more than once, nothing is removed. Returns \c true if all items were removed successfully, \c false otherwise. */ bool QCandlestickSeries::remove(const QList &sets) { Q_D(QCandlestickSeries); bool success = d->remove(sets); if (success) { emit candlestickSetsRemoved(sets); emit countChanged(); foreach (QCandlestickSet *set, sets) set->deleteLater(); } return success; } /*! \qmlmethod CandlestickSeries::insert(int index, CandlestickSet set) Inserts the candlestick item specified by \a set to the series at the position specified by \a index. Takes ownership of the item. If the item is null or already belongs to the series, it is not inserted. Returns \c true if inserting succeeded, \c false otherwise. */ /*! Inserts the candlestick item specified by \a set to the series at the position specified by \a index. Takes ownership of the item. If the item is null or already belongs to the series, it is not inserted. 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 sets; sets.append(set); emit candlestickSetsAdded(sets); emit countChanged(); } return success; } /*! Takes a single candlestick item, specified by \a set, from the series. Does not delete the item. Returns \c true if the take operation was successful, \c false otherwise. \note The series remains the item's parent object. You must set the parent object to take full ownership. */ bool QCandlestickSeries::take(QCandlestickSet *set) { Q_D(QCandlestickSeries); QList sets; sets.append(set); bool success = d->remove(sets); if (success) { emit candlestickSetsRemoved(sets); emit countChanged(); } return success; } /*! \qmlmethod CandlestickSeries::clear() Removes all candlestick items from the series and permanently deletes them. */ /*! Removes all candlestick items from the series and permanently deletes them. */ void QCandlestickSeries::clear() { Q_D(QCandlestickSeries); QList sets = this->sets(); bool success = d->remove(sets); if (success) { emit candlestickSetsRemoved(sets); emit countChanged(); foreach (QCandlestickSet *set, sets) set->deleteLater(); } } /*! Returns the list of candlestick items in the series. Ownership of the items does not change. */ QList QCandlestickSeries::sets() const { Q_D(const QCandlestickSeries); return d->m_sets; } /*! Returns the number of the candlestick items in the series. */ int QCandlestickSeries::count() const { return sets().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_sets.count()) { QCandlestickSet *set = m_sets.first(); minX = set->timestamp(); maxX = set->timestamp(); minY = set->low(); maxY = set->high(); for (int i = 1; i < m_sets.count(); ++i) { set = m_sets.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_sets.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(axis)); } } } void QCandlestickSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced) { Q_Q(QCandlestickSeries); if (forced || QChartPrivate::defaultBrush() == m_brush) { const QList 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(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 QCandlestickSeriesPrivate::createLegendMarkers(QLegend *legend) { Q_Q(QCandlestickSeries); QList 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 &sets) { foreach (QCandlestickSet *set, sets) { if ((set == 0) || m_sets.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_sets.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 &sets) { if (sets.count() == 0) return false; foreach (QCandlestickSet *set, sets) { if ((set == 0) || (!m_sets.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_sets.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_sets.contains(set)) || (set == 0) || set->d_ptr->m_series) return false; // Fail if set is already in list or set is null. m_sets.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(m_item.data()); if (item) item->handleCandlestickSeriesChange(); } } void QCandlestickSeriesPrivate::handleSeriesRemove(QAbstractSeries *series) { Q_Q(const QCandlestickSeries); QCandlestickSeries *removedSeries = static_cast(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(m_item.data()); if (item) item->handleCandlestickSeriesChange(); } } void QCandlestickSeriesPrivate::populateBarCategories(QBarCategoryAxis *axis) { if (axis->categories().isEmpty()) { QStringList categories; for (int i = 0; i < m_sets.count(); ++i) { const qint64 timestamp = qRound64(m_sets.at(i)->timestamp()); const QString timestampFormat = m_chart->locale().dateTimeFormat(QLocale::ShortFormat); categories << QDateTime::fromMSecsSinceEpoch(timestamp).toString(timestampFormat); } axis->append(categories); } } QT_CHARTS_END_NAMESPACE #include "moc_qcandlestickseries.cpp" #include "moc_qcandlestickseries_p.cpp"