diff options
author | Keith Kyzivat <keith.kyzivat@qt.io> | 2022-11-02 19:30:58 -0400 |
---|---|---|
committer | Keith Kyzivat <keith.kyzivat@qt.io> | 2022-11-11 11:49:12 -0500 |
commit | 189f798b2c44b3a061d8b1275ad03f5e5ef29486 (patch) | |
tree | 10f4ac6814bf8d4055268375599cc3b7c8467bbc | |
parent | 7bb86791791d59909c89072612bc6dbc3a9517e5 (diff) |
Add ability to customize labels for specific points
[ChangeLog][QXYSeries] Add LabelFormat to PointConfiguration,
allowing the user to set a custom label to specific points.
This follows setPointLabelsFormat, allowing the user to substitute the
x position, y position, or index in the label.
Adds @index to formats to allow substituting the index of the point in
the label.
Task-number: QTBUG-89452
Change-Id: If58e50357ca3275f3479b4ade44b789c568564ec
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r-- | examples/charts/CMakeLists.txt | 1 | ||||
-rw-r--r-- | examples/charts/pointconfiguration/CMakeLists.txt | 38 | ||||
-rw-r--r-- | examples/charts/pointconfiguration/chartwindow.cpp | 159 | ||||
-rw-r--r-- | examples/charts/pointconfiguration/chartwindow.h | 36 | ||||
-rw-r--r-- | examples/charts/pointconfiguration/main.cpp | 17 | ||||
-rw-r--r-- | examples/charts/pointconfiguration/pointconfiguration.pro | 12 | ||||
-rw-r--r-- | src/charts/doc/images/examples_pointconfiguration.png | bin | 0 -> 38648 bytes | |||
-rw-r--r-- | src/charts/doc/images/xyseries_point_configuration.png | bin | 25986 -> 23822 bytes | |||
-rw-r--r-- | src/charts/doc/src/examples-pointconfiguration.qdoc | 103 | ||||
-rw-r--r-- | src/charts/xychart/qxyseries.cpp | 63 | ||||
-rw-r--r-- | src/charts/xychart/qxyseries.h | 5 | ||||
-rw-r--r-- | src/charts/xychart/qxyseries_p.h | 5 |
12 files changed, 415 insertions, 24 deletions
diff --git a/examples/charts/CMakeLists.txt b/examples/charts/CMakeLists.txt index cc107889..f630f3c6 100644 --- a/examples/charts/CMakeLists.txt +++ b/examples/charts/CMakeLists.txt @@ -14,6 +14,7 @@ if(QT_FEATURE_charts_line_chart) qt_internal_add_example(logvalueaxis) qt_internal_add_example(modeldata) qt_internal_add_example(zoomlinechart) + qt_internal_add_example(pointconfiguration) endif() if(QT_FEATURE_charts_spline_chart) qt_internal_add_example(dynamicspline) diff --git a/examples/charts/pointconfiguration/CMakeLists.txt b/examples/charts/pointconfiguration/CMakeLists.txt new file mode 100644 index 00000000..5fc8042f --- /dev/null +++ b/examples/charts/pointconfiguration/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.14) +project(pointconfiguration LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/charts/pointconfiguration") + +find_package(Qt6 REQUIRED COMPONENTS Charts Core Gui) + +qt_add_executable(pointconfiguration + chartwindow.cpp + chartwindow.h + main.cpp +) + +set_target_properties(pointconfiguration PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(pointconfiguration PUBLIC + Qt::Charts + Qt::Core + Qt::Gui +) + +install(TARGETS pointconfiguration + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/charts/pointconfiguration/chartwindow.cpp b/examples/charts/pointconfiguration/chartwindow.cpp new file mode 100644 index 00000000..a19c4867 --- /dev/null +++ b/examples/charts/pointconfiguration/chartwindow.cpp @@ -0,0 +1,159 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "chartwindow.h" + +#include <QChart> +#include <QColor> +#include <QGridLayout> +#include <QHBoxLayout> +#include <QIcon> +#include <QLabel> +#include <QLineSeries> +#include <QMainWindow> + +//![1] +ChartWindow::ChartWindow(QWidget *parent) + : QMainWindow(parent) +{ +//![1] + //![2] + setWindowTitle(tr("Chart")); + + m_series = new QLineSeries(this); + m_series->setName(tr("Customized series")); + m_series->setPointsVisible(true); + m_series->append({QPointF(0, 7), QPointF(2, 4), + QPointF(3, 5), QPointF(7, 4), + QPointF(10, 5), QPointF(11, 1), + QPointF(13, 3), QPointF(17, 6), + QPointF(18, 3), QPointF(20, 2)}); + //![2] + + //![3] + QLabel *selectedPointIndexLabel = new QLabel(tr("Selected Point: ")); + m_selectedPointIndexLineEdit = new QLineEdit(); + m_selectedPointIndexLineEdit->setReadOnly(true); + + QLabel *colorLabel = new QLabel(tr("Color: ")); + m_colorCombobox = new QComboBox(); + QStringList colorStrings = {"red", "orange", "yellow", "green", "blue", + "indigo", "violet", "black"}; + QStringList trColorStrings = {tr("red"), tr("orange"), tr("yellow"), + tr("green"), tr("blue"), tr("indigo"), + tr("violet"), tr("black")}; + for (int i = 0; i < colorStrings.size(); i++) + m_colorCombobox->addItem(QIcon(), trColorStrings[i], QColor(colorStrings[i])); + + QLabel *sizeLabel = new QLabel(tr("Size: ")); + m_sizeCombobox = new QComboBox(); + for (auto size : { 2, 3, 4, 6, 8, 10, 12, 15 }) + m_sizeCombobox->addItem(QIcon(), QString::number(size), size); + + QLabel *labelVisibilityLabel = new QLabel(tr("Label Visibility: ")); + m_labelVisibilityCheckbox = new QCheckBox(); + + QLabel *customLabelLabel = new QLabel(tr("Custom Label: ")); + m_customLabelLineEdit = new QLineEdit(); + //![3] + + //![4] + QObject::connect(m_series, &QXYSeries::clicked, m_series, [&](const QPointF &point) { + int index = m_series->points().indexOf(point.toPoint()); + if (index != -1) { + m_series->deselectAllPoints(); + m_series->selectPoint(index); + m_selectedPointIndex = index; + m_selectedPointConfig = m_series->pointConfiguration(index); + const QPointF selectedPoint(m_series->at(index)); + m_selectedPointIndexLineEdit->setText("(" + QString::number(selectedPoint.x()) + ", " + + QString::number(selectedPoint.y()) + ")"); + PointConfigurations config = m_series->pointConfiguration(index); + + QVariant colorVar = config[QXYSeries::PointConfiguration::Color]; + QColor color = colorVar.isValid() ? colorVar.value<QColor>() : m_series->color(); + if (m_colorCombobox->findData(color) < 0) + m_colorCombobox->addItem(color.name(), color); + m_colorCombobox->setCurrentIndex(m_colorCombobox->findData(color)); + + QVariant sizeVar = config[QXYSeries::PointConfiguration::Size]; + qreal size = sizeVar.isValid() ? sizeVar.toReal() : m_series->markerSize(); + if (m_sizeCombobox->findData(size) < 0) + m_sizeCombobox->addItem(QString::number(size), size); + m_sizeCombobox->setCurrentIndex(m_sizeCombobox->findData(size)); + + QVariant labelVisibilityVar = config[QXYSeries::PointConfiguration::LabelVisibility]; + bool labelVisibility = labelVisibilityVar.isValid() ? labelVisibilityVar.toBool() : + m_series->pointLabelsVisible(); + m_labelVisibilityCheckbox->setChecked(labelVisibility); + + QVariant customLabelVar = config[QXYSeries::PointConfiguration::LabelFormat]; + QString customLabel = customLabelVar.isValid() ? customLabelVar.toString() : ""; + m_customLabelLineEdit->setText(customLabel); + } + }); + //![4] + + //![5] + QObject::connect(m_colorCombobox, &QComboBox::activated, m_series, [&](const int index) { + m_selectedPointConfig[QXYSeries::PointConfiguration::Color] = m_colorCombobox->currentData(); + m_series->setPointConfiguration(m_selectedPointIndex, m_selectedPointConfig); + }); + QObject::connect(m_sizeCombobox, &QComboBox::activated, m_series, [&](const int index) { + m_selectedPointConfig[QXYSeries::PointConfiguration::Size] = m_sizeCombobox->currentData(); + m_series->setPointConfiguration(m_selectedPointIndex, m_selectedPointConfig); + }); + QObject::connect(m_labelVisibilityCheckbox, &QAbstractButton::clicked, m_series, [&](const bool checked) { + m_selectedPointConfig[QXYSeries::PointConfiguration::LabelVisibility] = checked; + m_series->setPointConfiguration(m_selectedPointIndex, m_selectedPointConfig); + }); + QObject::connect(m_customLabelLineEdit, &QLineEdit::editingFinished, m_series, [&]() { + m_selectedPointConfig[QXYSeries::PointConfiguration::LabelFormat] = m_customLabelLineEdit->text(); + m_series->setPointConfiguration(m_selectedPointIndex, m_selectedPointConfig); + }); + //![5] + + //![6] + m_chart = new QChart(); + m_chart->addSeries(m_series); + m_chart->createDefaultAxes(); + + m_selectInitialPointConnection = QObject::connect(m_chart, &QChart::geometryChanged, m_chart, [&]() { + m_series->selectPoint(4); + m_series->clicked(m_series->at(m_series->selectedPoints()[0])); + disconnect(m_selectInitialPointConnection); + }); + + QChartView *chartView = new QChartView(m_chart); + chartView->setRenderHint(QPainter::Antialiasing); + + QWidget *controlWidget = new QWidget(this); + QGridLayout *controlLayout = new QGridLayout(controlWidget); + controlLayout->setColumnStretch(1, 1); + + controlLayout->addWidget(selectedPointIndexLabel, 0, 0); + controlLayout->addWidget(m_selectedPointIndexLineEdit, 0, 1); + + controlLayout->addWidget(colorLabel, 1, 0); + controlLayout->addWidget(m_colorCombobox, 1, 1); + + controlLayout->addWidget(sizeLabel, 2, 0); + controlLayout->addWidget(m_sizeCombobox, 2, 1); + + controlLayout->addWidget(labelVisibilityLabel, 3, 0); + controlLayout->addWidget(m_labelVisibilityCheckbox, 3, 1, 1, 2); + + controlLayout->addWidget(customLabelLabel, 4, 0); + controlLayout->addWidget(m_customLabelLineEdit, 4, 1); + + QWidget *mainWidget = new QWidget(this); + QHBoxLayout *mainLayout = new QHBoxLayout(mainWidget); + mainLayout->addWidget(chartView); + mainLayout->setStretch(0, 1); + mainLayout->addWidget(controlWidget); + + setCentralWidget(mainWidget); + //![6] +//![7] +} +//![7] diff --git a/examples/charts/pointconfiguration/chartwindow.h b/examples/charts/pointconfiguration/chartwindow.h new file mode 100644 index 00000000..da01e9ad --- /dev/null +++ b/examples/charts/pointconfiguration/chartwindow.h @@ -0,0 +1,36 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QChartView> +#include <QCheckBox> +#include <QComboBox> +#include <QLineEdit> +#include <QMainWindow> +#include <QXYSeries> + +typedef QHash<QXYSeries::PointConfiguration, QVariant> PointConfigurations; + +//![1] +class ChartWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit ChartWindow(QWidget *parent = nullptr); + ~ChartWindow() {}; + +private: + QChart *m_chart = nullptr; + QXYSeries *m_series = nullptr; + + QMetaObject::Connection m_selectInitialPointConnection; + int m_selectedPointIndex = -1; + PointConfigurations m_selectedPointConfig; + + QLineEdit *m_selectedPointIndexLineEdit = nullptr; + QComboBox *m_colorCombobox = nullptr; + QComboBox *m_sizeCombobox = nullptr; + QCheckBox *m_labelVisibilityCheckbox = nullptr; + QLineEdit *m_customLabelLineEdit = nullptr; +}; +//![1] diff --git a/examples/charts/pointconfiguration/main.cpp b/examples/charts/pointconfiguration/main.cpp new file mode 100644 index 00000000..0279d636 --- /dev/null +++ b/examples/charts/pointconfiguration/main.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "chartwindow.h" + +#include <QApplication> + +//![1] +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + ChartWindow mainWindow; + mainWindow.resize(640, 480); + mainWindow.show(); + return a.exec(); +} +//![1] diff --git a/examples/charts/pointconfiguration/pointconfiguration.pro b/examples/charts/pointconfiguration/pointconfiguration.pro new file mode 100644 index 00000000..b10359d1 --- /dev/null +++ b/examples/charts/pointconfiguration/pointconfiguration.pro @@ -0,0 +1,12 @@ +QT += charts \ + widgets + +SOURCES += \ + chartwindow.cpp + main.cpp + +HEADERS += \ + chartwindow.h + +target.path = $$[QT_INSTALL_EXAMPLES]/charts/pointconfiguration +INSTALLS += target diff --git a/src/charts/doc/images/examples_pointconfiguration.png b/src/charts/doc/images/examples_pointconfiguration.png Binary files differnew file mode 100644 index 00000000..6ee8fca5 --- /dev/null +++ b/src/charts/doc/images/examples_pointconfiguration.png diff --git a/src/charts/doc/images/xyseries_point_configuration.png b/src/charts/doc/images/xyseries_point_configuration.png Binary files differindex 362b898a..abf203a8 100644 --- a/src/charts/doc/images/xyseries_point_configuration.png +++ b/src/charts/doc/images/xyseries_point_configuration.png diff --git a/src/charts/doc/src/examples-pointconfiguration.qdoc b/src/charts/doc/src/examples-pointconfiguration.qdoc new file mode 100644 index 00000000..a061b948 --- /dev/null +++ b/src/charts/doc/src/examples-pointconfiguration.qdoc @@ -0,0 +1,103 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example pointconfiguration + \title Selected Point Configuration Example + \ingroup qtcharts_examples + + \brief This example shows how to modify the configuration of individual points. + + \image examples_pointconfiguration.png + + \section1 Features Demonstrated + In this application you will learn how to: + \list + \li Provide click-selection of points in a series. + \li Override the individual configuration of specific points, configuring: + \list + \li Color + \li Size + \li Visibility of the label + \li Text format of the label + \endlist + \endlist + + \include examples-run.qdocinc + + \section1 Subclass QMainWindow + + We start by creating a subclass of QMainWindow that will contain the chart and controls. + \snippet pointconfiguration/chartwindow.h 1 + And we provide the boilerplate for the constructor implementation: + \snippet pointconfiguration/chartwindow.cpp 1 + \snippet pointconfiguration/chartwindow.cpp 7 + + \section1 Create a Line Series + + Then we create a QLineSeries, giving it a name, making the points visible, and giving it some + points to plot. + \snippet pointconfiguration/chartwindow.cpp 2 + + \section1 Create the Point Configuration Controls + + Now we create some controls to configure the color, size, label visibility, and the label + itself. We create an associated label for each control so the user knows what the control does. + + For the color and size, we use a QComboBox, populating it with a variety of color and size + choices. + + Next we create the final two controls. A Checkbox controls the visibility of the selected + point. The other control is a QLineEdit allowing the user to provide a custom label for the + point. + + Note that we do not set initial values for any of the controls, as a point will always be + selected showing its current settings. + \snippet pointconfiguration/chartwindow.cpp 3 + + \section1 Populate the Controls upon Selecting a Point + + Now that we have the controls, we need to provide the logic that sets the current control values + for the selected point. Note that the whole series value is used if there is no customization + for a selected point. In this case, if the series is set to show blue points, a blue color value + will be shown in the color combobox. + + Upon clicking on the lineseries, we look up the point clicked on, remove the prior point + selection, and then select the point that was clicked on. This visually indicates the selected + point on the chart - making the point larger to indicate its selection. The index of the + current selected point and its \c PointConfigurations are saved to a member variable for later + use. + + The \c PointConfigurations are queried and matching values in the comboboxes are looked up. + Then the current indices of the comboboxes are set accordingly. Similarly for the checkbox and + line edit, the values are looked up from the \c PointConfigurations, and the controls are set + to match them. + \snippet pointconfiguration/chartwindow.cpp 4 + + \section1 Provide the Logic to Configure the Selected Point + + Now that the controls are populated with the current configuration, we need to make them do + something. We connect up their signals to logic that will do the work of configuring the + selected point with the setting chosen. It is a simple matter of setting the + QXYSeries::PointConfiguration value associated with the control to the \c m_selectedPointConfig + \c PointConfigurations member variable, and calling QXYSeries::setPointConfiguration. + \snippet pointconfiguration/chartwindow.cpp 5 + + \section1 Create the Chart and Lay out the Controls + + Finally we create the chart and its view, add the series to the chart, and create the layout + of the window. + As part of this, we connect to the \c geometryChanged signal to catch a signal when the + chart is + first painted. This is so that we can get correct values for the initially selected point. If + we do this earlier, the point values are incorrect. This connection is disconnected after the + first time that it is fired. + \snippet pointconfiguration/chartwindow.cpp 6 + + In \c main.cpp we simply instantiate the \c ChartWindow, resize it, show it, and start the event + loop. + \snippet pointconfiguration/main.cpp 1 + + Now we have a fully functioning application that demonstrates how to customize individual chart + points. +*/ diff --git a/src/charts/xychart/qxyseries.cpp b/src/charts/xychart/qxyseries.cpp index c3b51636..07963e18 100644 --- a/src/charts/xychart/qxyseries.cpp +++ b/src/charts/xychart/qxyseries.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCharts/QXYSeries> @@ -58,8 +58,15 @@ QT_BEGIN_NAMESPACE This enum value can be used to hide or show the label of the point. If used together with QXYSeries::setPointConfiguration, the configuration's value should be boolean. + \value [since 6.5] LabelFormat + This enum value can be used to set custom label text per-point. If used together with + QXYSeries::setPointConfiguration, the configuration's value should be a string. + \note If an empty string is set as the LabelFormat, it will be ignored, and the series + pointLabelsFormat will be used. + \sa pointLabelsFormat \sa setPointConfiguration() + \since 6.2 */ /*! @@ -147,6 +154,8 @@ QT_BEGIN_NAMESPACE QXYSeries supports the following format tags: \table \row + \li @index \li The index in the series of the data point. [since 6.5] + \row \li @xPoint \li The x-coordinate of the data point. \row \li @yPoint \li The y-coordinate of the data point. @@ -157,7 +166,7 @@ QT_BEGIN_NAMESPACE (x, y): \code - series->setPointLabelsFormat("(@xPoint, @yPoint)"); + series->setPointLabelsFormat("@index: (@xPoint, @yPoint)"); \endcode By default, the labels' format is set to \c {@xPoint, @yPoint}. The labels @@ -509,6 +518,11 @@ QT_BEGIN_NAMESPACE */ /*! + \fn void QXYSeries::selectedPointsChanged() + This signal is emitted when the points selection changes. +*/ + +/*! \fn void QXYSeries::lightMarkerChanged(const QImage &lightMarker) This signal is emitted when the light marker image changes to \a lightMarker. \sa QXYSeries::setLightMarker() @@ -775,7 +789,7 @@ void QXYSeries::clearPointsConfiguration(const QXYSeries::PointConfiguration key keys and QVariant values. For example: \code QLineSeries *series = new QLineSeries(); - series->setName("Customized serie"); + series->setName("Customized series"); series->setPointsVisible(true); *series << QPointF(0, 6) << QPointF(2, 4) << QPointF(3, 6) << QPointF(7, 4) << QPointF(10, 5) @@ -793,16 +807,19 @@ void QXYSeries::clearPointsConfiguration(const QXYSeries::PointConfiguration key series->setPointConfiguration(4, conf); - conf.remove(QXYSeries::PointConfiguration::LabelVisibility); + conf.remove(QXYSeries::PointConfiguration::Color); + conf[QXYSeries::PointConfiguration::LabelFormat] = "This Point"; series->setPointConfiguration(6, conf); \endcode - In this example, you can see a default QLineSeries with 10 points - and with changed configuration of two points. Both changed points are - red and visibly bigger than the others with a look derived from series. - By default, points don't have labels, but the point at index 4 has - the label thanks to the QXYSeries::PointConfiguration::LabelVisibility - configuration value. + In this example, you can see a default QLineSeries with 10 points and with changed configuration + of two points. Both changed points are visibly bigger than the others with a look derived from + the series configuration. + By default, points don't have labels, but the point at index 4 has a label thanks to the + QXYSeries::PointConfiguration::LabelVisibility and QXYSeries::PointConfiguration::LabelFormat + configuration values. + The point at index 6 has a custom label \e {This Point} thanks to the + QXYSeries::PointConfiguration::LabelFormat configuration value. Below is an example of a chart created in this way: \image xyseries_point_configuration.png @@ -1805,6 +1822,7 @@ void QXYSeriesPrivate::drawPointLabels(QPainter *painter, const QList<QPointF> & painter->setClipping(false); QList<int> pointsToSkip; + QHash<int, QString> labelFormats; QHash<int, int> offsets; if (!m_pointsConfiguration.isEmpty()) { @@ -1812,14 +1830,16 @@ void QXYSeriesPrivate::drawPointLabels(QPainter *painter, const QList<QPointF> & bool drawLabel = m_pointLabelsVisible; if (m_pointsConfiguration.contains(i)) { const auto &conf = m_pointsConfiguration[i]; - if (conf.contains(QXYSeries::PointConfiguration::LabelVisibility)) { - drawLabel = m_pointsConfiguration - [i][QXYSeries::PointConfiguration::LabelVisibility] - .toBool(); - - if (drawLabel && conf.contains(QXYSeries::PointConfiguration::Size)) - offsets[i] = conf[QXYSeries::PointConfiguration::Size].toReal(); + auto key = QXYSeries::PointConfiguration::LabelVisibility; + if (conf.contains(key)) { + drawLabel = m_pointsConfiguration[i][key].toBool(); + key = QXYSeries::PointConfiguration::Size; + if (drawLabel && conf.contains(key)) + offsets[i] = conf[key].toReal(); } + key = QXYSeries::PointConfiguration::LabelFormat; + if (conf.contains(key) && !conf[key].toString().isEmpty()) + labelFormats[i] = conf[key].toString(); } if (!drawLabel) @@ -1827,19 +1847,21 @@ void QXYSeriesPrivate::drawPointLabels(QPainter *painter, const QList<QPointF> & } } - drawSeriesPointLabels(painter, allPoints, offset, offsets, pointsToSkip); + drawSeriesPointLabels(painter, allPoints, offset, offsets, pointsToSkip, labelFormats); } } void QXYSeriesPrivate::drawSeriesPointLabels(QPainter *painter, const QList<QPointF> &points, const int offset, const QHash<int, int> &offsets, - const QList<int> &indexesToSkip) + const QList<int> &indexesToSkip, + const QHash<int, QString> &labelFormats) { if (points.size() == 0) return; static const QString xPointTag(QLatin1String("@xPoint")); static const QString yPointTag(QLatin1String("@yPoint")); + static const QString indexTag(QLatin1String("@index")); QFont f(m_pointLabelsFont); f.setPixelSize(QFontInfo(m_pointLabelsFont).pixelSize()); @@ -1853,9 +1875,10 @@ void QXYSeriesPrivate::drawSeriesPointLabels(QPainter *painter, const QList<QPoi if (indexesToSkip.contains(i)) continue; - QString pointLabel = m_pointLabelsFormat; + QString pointLabel = labelFormats.contains(i) ? labelFormats[i] : m_pointLabelsFormat; pointLabel.replace(xPointTag, presenter()->numberToString(m_points.at(i).x())); pointLabel.replace(yPointTag, presenter()->numberToString(m_points.at(i).y())); + pointLabel.replace(indexTag, presenter()->numberToString(i)); int currOffset = offset; if (offsets.contains(i)) diff --git a/src/charts/xychart/qxyseries.h b/src/charts/xychart/qxyseries.h index fac75698..23f6bfd7 100644 --- a/src/charts/xychart/qxyseries.h +++ b/src/charts/xychart/qxyseries.h @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QXYSERIES_H @@ -41,7 +41,8 @@ public: Color = 0, Size, Visibility, - LabelVisibility + LabelVisibility, + LabelFormat }; Q_ENUM(PointConfiguration) diff --git a/src/charts/xychart/qxyseries_p.h b/src/charts/xychart/qxyseries_p.h index cbb5aa4e..21408610 100644 --- a/src/charts/xychart/qxyseries_p.h +++ b/src/charts/xychart/qxyseries_p.h @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // W A R N I N G @@ -47,7 +47,8 @@ public: void drawPointLabels(QPainter *painter, const QList<QPointF> &allPoints, const int offset = 0); void drawSeriesPointLabels(QPainter *painter, const QList<QPointF> &points, const int offset = 0, const QHash<int, int> &offsets = {}, - const QList<int> &indexesToSkip = {}); + const QList<int> &indexesToSkip = {}, + const QHash<int, QString> &customLabels = {}); void drawBestFitLine(QPainter *painter, const QRectF &clipRect); QPair<qreal, qreal> bestFitLineEquation(bool &ok) const; |