[education/labplot] src: Introduced a new value type "Values" to be used for bar and lollipop plots

Alexander Semke <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 09bb261488e678c54fdf2ae76d0c39d7e2d59460 by Alexander Semke.
Committed on 15/08/2026 at 09:33.
Pushed by asemke into branch 'master'.

Introduced a new value type "Values" to be used for bar and lollipop plots
and a couple of other minor fixes related to the formatting of values.

fix #1217

M  +3    -3    src/backend/worksheet/plots/cartesian/BarPlot.cpp
M  +3    -3    src/backend/worksheet/plots/cartesian/LollipopPlot.cpp
M  +1    -1    src/backend/worksheet/plots/cartesian/Value.h
M  +2    -0    src/frontend/dockwidgets/XYCurveDock.cpp
M  +49   -26   src/frontend/widgets/ValueWidget.cpp

https://invent.kde.org/education/labplot/-/commit/09bb261488e678c54fdf2ae76d0c39d7e2d59460

diff --git a/src/backend/worksheet/plots/cartesian/BarPlot.cpp b/src/backend/worksheet/plots/cartesian/BarPlot.cpp
index fd54314bda..b4d27d42af 100644
--- a/src/backend/worksheet/plots/cartesian/BarPlot.cpp
+++ b/src/backend/worksheet/plots/cartesian/BarPlot.cpp
@@ -1112,7 +1112,7 @@ void BarPlotPrivate::updateValues() {
 	const auto& prefix = value->prefix();
 	const auto& suffix = value->suffix();
 	const auto numberLocale = QLocale();
-	if (value->type() == Value::BinEntries) {
+	if (value->type() == Value::Values) {
 		for (int i = 0; i < valuesPointsLogical.count(); ++i) {
 			if (!visiblePoints[i])
 				continue;
@@ -1122,12 +1122,12 @@ void BarPlotPrivate::updateValues() {
 				if (type == BarPlot::Type::Stacked_100_Percent)
 					m_valuesStrings << prefix + numberToString(point.y(), numberLocale, value->numericFormat(), 1) + QLatin1String("%") + suffix;
 				else
-					m_valuesStrings << prefix + numberToString(point.y(), numberLocale) + suffix;
+					m_valuesStrings << prefix + numberToString(point.y(), numberLocale, value->numericFormat(), value->precision()) + suffix;
 			} else {
 				if (type == BarPlot::Type::Stacked_100_Percent)
 					m_valuesStrings << prefix + numberToString(point.x(), numberLocale, value->numericFormat(), 1) + QLatin1String("%") + suffix;
 				else
-					m_valuesStrings << prefix + numberToString(point.x(), numberLocale) + suffix;
+					m_valuesStrings << prefix + numberToString(point.x(), numberLocale, value->numericFormat(), value->precision()) + suffix;
 			}
 		}
 	} else if (value->type() == Value::CustomColumn) {
diff --git a/src/backend/worksheet/plots/cartesian/LollipopPlot.cpp b/src/backend/worksheet/plots/cartesian/LollipopPlot.cpp
index 34a533e69c..046b4f2b50 100644
--- a/src/backend/worksheet/plots/cartesian/LollipopPlot.cpp
+++ b/src/backend/worksheet/plots/cartesian/LollipopPlot.cpp
@@ -712,16 +712,16 @@ void LollipopPlotPrivate::updateValues() {
 	const auto& prefix = value->prefix();
 	const auto& suffix = value->suffix();
 	const auto numberLocale = QLocale();
-	if (value->type() == Value::BinEntries) {
+	if (value->type() == Value::Values) {
 		for (int i = 0; i < m_valuesPointsLogical.count(); ++i) {
 			if (!visiblePoints[i])
 				continue;
 
 			auto& point = m_valuesPointsLogical.at(i);
 			if (orientation == LollipopPlot::Orientation::Vertical)
-				m_valuesStrings << prefix + numberToString(point.y(), numberLocale) + suffix;
+				m_valuesStrings << prefix + numberToString(point.y(), numberLocale, value->numericFormat(), value->precision()) + suffix;
 			else
-				m_valuesStrings << prefix + numberToString(point.x(), numberLocale) + suffix;
+				m_valuesStrings << prefix + numberToString(point.x(), numberLocale, value->numericFormat(), value->precision()) + suffix;
 		}
 	} else if (value->type() == Value::CustomColumn) {
 		const auto* valuesColumn = value->column();
diff --git a/src/backend/worksheet/plots/cartesian/Value.h b/src/backend/worksheet/plots/cartesian/Value.h
index 9284f1ce51..bb3aadced5 100644
--- a/src/backend/worksheet/plots/cartesian/Value.h
+++ b/src/backend/worksheet/plots/cartesian/Value.h
@@ -26,7 +26,7 @@ class Value : public AbstractAspect {
 	Q_OBJECT
 
 public:
-	enum Type { NoValues, BinEntries, CustomColumn, X, Y, XY, XYBracketed };
+	enum Type { NoValues, BinEntries, CustomColumn, X, Y, XY, XYBracketed, Values };
 	enum Position { Above, Under, Left, Right, Center };
 
 	explicit Value(const QString& name);
diff --git a/src/frontend/dockwidgets/XYCurveDock.cpp b/src/frontend/dockwidgets/XYCurveDock.cpp
index edd3c0009a..2439b049d3 100644
--- a/src/frontend/dockwidgets/XYCurveDock.cpp
+++ b/src/frontend/dockwidgets/XYCurveDock.cpp
@@ -376,6 +376,8 @@ void XYCurveDock::setSymbols(const QList<XYCurve*>& curves) {
 	dropLineWidget->setLines(dropLines);
 	errorBarWidget->setErrorBars(errorBars);
 	valueWidget->setValues(values);
+	valueWidget->setXColumn(m_curve->xColumn());
+	valueWidget->setYColumn(m_curve->yColumn());
 }
 
 void XYCurveDock::initGeneralTab() {
diff --git a/src/frontend/widgets/ValueWidget.cpp b/src/frontend/widgets/ValueWidget.cpp
index 263ba80757..ce83037533 100644
--- a/src/frontend/widgets/ValueWidget.cpp
+++ b/src/frontend/widgets/ValueWidget.cpp
@@ -65,8 +65,6 @@ void ValueWidget::setValues(const QList<Value*>& values) {
 	m_values = values;
 	m_value = m_values.first();
 
-	ui.sbDistance->setLocale(QLocale());
-
 	if (!m_aspectModel) {
 		m_aspectModel = new AspectTreeModel(m_value->project());
 		m_aspectModel->enablePlottableColumnsOnly(true);
@@ -118,7 +116,7 @@ void ValueWidget::updateLocale() {
 
 void ValueWidget::retranslateUi() {
 	ui.cbType->clear();
-	if (m_xy) {
+	if (m_xy) { // xy-curve, pareto chart, set via the boolean in the constructor
 		ui.cbType->addItem(i18n("No Values"), static_cast<int>(Value::Type::NoValues));
 		ui.cbType->addItem(QStringLiteral("x"), static_cast<int>(Value::Type::X));
 		ui.cbType->addItem(QStringLiteral("y"), static_cast<int>(Value::Type::Y));
@@ -127,7 +125,10 @@ void ValueWidget::retranslateUi() {
 		ui.cbType->addItem(i18n("Custom Column"), static_cast<int>(Value::Type::CustomColumn));
 	} else {
 		ui.cbType->addItem(i18n("No Values"), static_cast<int>(Value::Type::NoValues));
-		ui.cbType->addItem(i18n("Frequency"), static_cast<int>(Value::Type::BinEntries));
+		if (m_value && m_value->parentAspect()->type() == AspectType::Histogram)
+			ui.cbType->addItem(i18n("Frequency"), static_cast<int>(Value::Type::BinEntries));
+		else // bar plot, lollipop plot
+			ui.cbType->addItem(i18n("Values"), static_cast<int>(Value::Type::Values));
 		ui.cbType->addItem(i18n("Custom Column"), static_cast<int>(Value::Type::CustomColumn));
 	}
 
@@ -210,9 +211,11 @@ void ValueWidget::updateWidgets() {
 		ui.lColumn->hide();
 		cbColumn->hide();
 
-		if (type == Value::Type::BinEntries)
+		if (type == Value::Type::BinEntries) // histogram, integer values for the bin entries only
 			hasInteger = true;
-		else {
+		else if (type == Value::Type::Values) // bar plots
+			hasNumeric = true; // TODO: always numeric or rather check if we have pure int values?
+		else { // xy-related types, determine the actual column mode of the provided columns
 			hasInteger = (m_xColumn && (m_xColumn->columnMode() == AbstractColumn::ColumnMode::Integer || m_xColumn->columnMode() == AbstractColumn::ColumnMode::BigInt))
 			|| (m_yColumn && (m_yColumn->columnMode() == AbstractColumn::ColumnMode::Integer || m_yColumn->columnMode() == AbstractColumn::ColumnMode::BigInt));
 
@@ -411,13 +414,21 @@ void ValueWidget::valueColorChanged(QColor color) {
 //**********************************************************
 void ValueWidget::load() {
 	CONDITIONAL_LOCK_RETURN;
+
+	retranslateUi(); // call this first to re-populate the combobox with the available value types
 	ui.cbType->setCurrentIndex(ui.cbType->findData((int)m_value->type()));
+	updateWidgets(); // call this to update the visibility of widgets dependinging on the selected type
+
 	ui.cbPosition->setCurrentIndex(ui.cbPosition->findData((int)m_value->position()));
 	ui.sbDistance->setValue(Worksheet::convertFromSceneUnits(m_value->distance(), Worksheet::Unit::Point));
 	ui.sbRotation->setValue(m_value->rotationAngle());
 	ui.sbOpacity->setValue(round(m_value->opacity()) * 100.0);
 	cbColumn->setAspect(m_value->column(), m_value->columnPath());
-	this->updateWidgets();
+
+	ui.cbNumericFormat->setCurrentIndex(ui.cbNumericFormat->findData(m_value->numericFormat()));
+	ui.sbPrecision->setValue(m_value->precision());
+	ui.cbDateTimeFormat->setCurrentIndex(ui.cbNumericFormat->findData(m_value->dateTimeFormat()));
+
 	ui.lePrefix->setText(m_value->prefix());
 	ui.leSuffix->setText(m_value->suffix());
 	QFont font = m_value->font();
@@ -427,28 +438,40 @@ void ValueWidget::load() {
 }
 
 void ValueWidget::loadConfig(const KConfigGroup& group) {
-	ui.cbType->setCurrentIndex(ui.cbType->findData(group.readEntry("ValuesType", (int)m_value->type())));
-	ui.cbPosition->setCurrentIndex(ui.cbPosition->findData(group.readEntry("ValuesPosition", (int)m_value->position())));
-	ui.sbDistance->setValue(Worksheet::convertFromSceneUnits(group.readEntry("ValuesDistance", m_value->distance()), Worksheet::Unit::Point));
-	ui.sbRotation->setValue(group.readEntry("ValuesRotation", m_value->rotationAngle()));
-	ui.sbOpacity->setValue(round(group.readEntry("ValuesOpacity", m_value->opacity()) * 100.0));
-	this->updateWidgets();
-	ui.lePrefix->setText(group.readEntry("ValuesPrefix", m_value->prefix()));
-	ui.leSuffix->setText(group.readEntry("ValuesSuffix", m_value->suffix()));
+	CONDITIONAL_LOCK_RETURN;
+
+	retranslateUi(); // call this first to re-populate the combobox with the available value types
+	ui.cbType->setCurrentIndex(ui.cbType->findData(group.readEntry("ValueType", (int)m_value->type())));
+	updateWidgets(); // call this to update the visibility of widgets dependinging on the selected type
+
+	ui.cbPosition->setCurrentIndex(ui.cbPosition->findData(group.readEntry("ValuePosition", (int)m_value->position())));
+	ui.sbDistance->setValue(Worksheet::convertFromSceneUnits(group.readEntry("ValueDistance", m_value->distance()), Worksheet::Unit::Point));
+	ui.sbRotation->setValue(group.readEntry("ValueRotation", m_value->rotationAngle()));
+	ui.sbOpacity->setValue(round(group.readEntry("ValueOpacity", m_value->opacity()) * 100.0));
+
+	ui.cbNumericFormat->setCurrentIndex(ui.cbNumericFormat->findData(group.readEntry("ValueNumericFormat", "f").at(0).toLatin1()));
+	ui.sbPrecision->setValue(group.readEntry("ValuePrecision", m_value->precision()));
+	ui.cbDateTimeFormat->setCurrentIndex(ui.cbDateTimeFormat->findData(group.readEntry("ValueDateTimeFormat", m_value->dateTimeFormat())));
+
+	ui.lePrefix->setText(group.readEntry("ValuePrefix", m_value->prefix()));
+	ui.leSuffix->setText(group.readEntry("ValueSuffix", m_value->suffix()));
 	QFont font = m_value->font();
 	font.setPointSizeF(round(Worksheet::convertFromSceneUnits(font.pointSizeF(), Worksheet::Unit::Point)));
-	ui.kfrFont->setFont(group.readEntry("ValuesFont", font));
-	ui.kcbColor->setColor(group.readEntry("ValuesColor", m_value->color()));
+	ui.kfrFont->setFont(group.readEntry("ValueFont", font));
+	ui.kcbColor->setColor(group.readEntry("ValueColor", m_value->color()));
 }
 
 void ValueWidget::saveConfig(KConfigGroup& group) const {
-	group.writeEntry("ValuesType", ui.cbType->currentData().toInt());
-	group.writeEntry("ValuesPosition", ui.cbPosition->currentData().toInt());
-	group.writeEntry("ValuesDistance", Worksheet::convertToSceneUnits(ui.sbDistance->value(), Worksheet::Unit::Point));
-	group.writeEntry("ValuesRotation", ui.sbRotation->value());
-	group.writeEntry("ValuesOpacity", ui.sbOpacity->value() / 100.0);
-	group.writeEntry("ValuesPrefix", ui.lePrefix->text());
-	group.writeEntry("ValuesSuffix", ui.leSuffix->text());
-	group.writeEntry("ValuesFont", ui.kfrFont->font());
-	group.writeEntry("ValuesColor", ui.kcbColor->color());
+	group.writeEntry("ValueType", ui.cbType->currentData().toInt());
+	group.writeEntry("ValuePosition", ui.cbPosition->currentData().toInt());
+	group.writeEntry("ValueDistance", Worksheet::convertToSceneUnits(ui.sbDistance->value(), Worksheet::Unit::Point));
+	group.writeEntry("ValueRotation", ui.sbRotation->value());
+	group.writeEntry("ValueOpacity", ui.sbOpacity->value() / 100.0);
+	group.writeEntry("ValueNumericFormat", ui.cbNumericFormat->currentData().toString());
+	group.writeEntry("ValuePrecision", ui.sbPrecision->value());
+	group.writeEntry("ValueDateTimeFormat", ui.cbDateTimeFormat->currentData().toString());
+	group.writeEntry("ValuePrefix", ui.lePrefix->text());
+	group.writeEntry("ValueSuffix", ui.leSuffix->text());
+	group.writeEntry("ValueFont", ui.kfrFont->font());
+	group.writeEntry("ValueColor", ui.kcbColor->color());
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.