summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Kyzivat <keith.kyzivat@qt.io>2022-11-02 19:30:58 -0400
committerKeith Kyzivat <keith.kyzivat@qt.io>2022-11-11 11:49:12 -0500
commit189f798b2c44b3a061d8b1275ad03f5e5ef29486 (patch)
tree10f4ac6814bf8d4055268375599cc3b7c8467bbc
parent7bb86791791d59909c89072612bc6dbc3a9517e5 (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.txt1
-rw-r--r--examples/charts/pointconfiguration/CMakeLists.txt38
-rw-r--r--examples/charts/pointconfiguration/chartwindow.cpp159
-rw-r--r--examples/charts/pointconfiguration/chartwindow.h36
-rw-r--r--examples/charts/pointconfiguration/main.cpp17
-rw-r--r--examples/charts/pointconfiguration/pointconfiguration.pro12
-rw-r--r--src/charts/doc/images/examples_pointconfiguration.pngbin0 -> 38648 bytes
-rw-r--r--src/charts/doc/images/xyseries_point_configuration.pngbin25986 -> 23822 bytes
-rw-r--r--src/charts/doc/src/examples-pointconfiguration.qdoc103
-rw-r--r--src/charts/xychart/qxyseries.cpp63
-rw-r--r--src/charts/xychart/qxyseries.h5
-rw-r--r--src/charts/xychart/qxyseries_p.h5
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
new file mode 100644
index 00000000..6ee8fca5
--- /dev/null
+++ b/src/charts/doc/images/examples_pointconfiguration.png
Binary files differ
diff --git a/src/charts/doc/images/xyseries_point_configuration.png b/src/charts/doc/images/xyseries_point_configuration.png
index 362b898a..abf203a8 100644
--- a/src/charts/doc/images/xyseries_point_configuration.png
+++ b/src/charts/doc/images/xyseries_point_configuration.png
Binary files differ
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;