From 12a5a08c9cece92312d3eb985d9efa99921995db Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Fri, 3 Apr 2026 09:18:08 +0100 Subject: [PATCH 1/8] Add log scaling property to Meter widget --- .../display/builder/model/widgets/MeterWidget.java | 9 +++++++++ .../javafx/widgets/MeterRepresentation.java | 4 ++++ .../main/java/org/csstudio/javafx/rtplot/RTMeter.java | 7 +++++++ .../csstudio/javafx/rtplot/internal/MeterScale.java | 10 +++++++++- 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java index 9c1613c4f2..7d73fa8e3a 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java @@ -18,6 +18,7 @@ import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propMinimum; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propPrecision; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propShowUnits; +import static org.csstudio.display.builder.model.widgets.plots.PlotWidgetProperties.propLogscale; import java.util.Arrays; import java.util.List; @@ -158,6 +159,7 @@ else if (xml_version.getMajor() < 3) private volatile WidgetProperty limits_from_pv; private volatile WidgetProperty minimum; private volatile WidgetProperty maximum; + private volatile WidgetProperty log_scale; /** Constructor */ public MeterWidget() @@ -195,6 +197,7 @@ protected void defineProperties(final List> properties) properties.add(limits_from_pv = propLimitsFromPV.createProperty(this, true)); properties.add(minimum = propMinimum.createProperty(this, 0.0)); properties.add(maximum = propMaximum.createProperty(this, 100.0)); + properties.add(log_scale = propLogscale.createProperty(this, false)); } /** @return 'foreground_color' property */ @@ -274,4 +277,10 @@ public WidgetProperty propMaximum() { return maximum; } + + /** @return 'log_scale' property */ + public WidgetProperty propLogScale() + { + return log_scale; + } } diff --git a/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/MeterRepresentation.java b/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/MeterRepresentation.java index 713050c254..cae1cf7fb4 100644 --- a/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/MeterRepresentation.java +++ b/app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/MeterRepresentation.java @@ -64,6 +64,7 @@ protected void registerListeners() model_widget.propMaximum().addUntypedPropertyListener(valueListener); model_widget.propShowValue().addUntypedPropertyListener(valueListener); model_widget.runtimePropValue().addUntypedPropertyListener(valueListener); + model_widget.propLogScale().addUntypedPropertyListener(valueListener); valueChanged(null, null, null); } @@ -82,6 +83,7 @@ protected void unregisterListeners() model_widget.propMaximum().removePropertyListener(valueListener); model_widget.propShowValue().removePropertyListener(valueListener); model_widget.runtimePropValue().removePropertyListener(valueListener); + model_widget.propLogScale().removePropertyListener(valueListener); super.unregisterListeners(); } @@ -142,6 +144,8 @@ private void valueChanged(final WidgetProperty property, final Object old_val } else meter.setValue(value, ""); + + meter.setLogScale(model_widget.propLogScale().getValue()); } @Override diff --git a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/RTMeter.java b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/RTMeter.java index 58190a2893..3391e5683b 100644 --- a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/RTMeter.java +++ b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/RTMeter.java @@ -61,6 +61,13 @@ public class RTMeter extends ImageView /** Area of this meter */ protected volatile Rectangle area = new Rectangle(0, 0, 0, 0); + /** @param logscale Use log scale for y-axis? */ + public void setLogScale(final boolean logscale) + { + scale.setLogarithmic(logscale); + requestUpdate(); + } + /** Listener to {@link PlotPart}s (scale), triggering refresh of meter */ protected final PlotPartListener plot_part_listener = new PlotPartListener() { diff --git a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/MeterScale.java b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/MeterScale.java index 9f09be1ff5..1e48c1606b 100644 --- a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/MeterScale.java +++ b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/MeterScale.java @@ -131,7 +131,15 @@ public double getAngle(final double value) if (Double.isFinite(value)) { final AxisRange range = getValueRange(); - return start_angle + (value - range.getLow()) * angle_range / (range.getHigh() - range.getLow()); + if (isLogarithmic()) + { + return start_angle + Math.log10(value/range.getLow()) * angle_range / Math.log10(range.getHigh()/range.getLow()); + } + else + { + return start_angle + (value - range.getLow()) * angle_range / (range.getHigh() - range.getLow()); + } + } else return Double.NaN; From 8246001adfd7c2c47df7cee79a0815d3cd73546f Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Fri, 10 Apr 2026 10:40:12 +0100 Subject: [PATCH 2/8] Update log scale property label to 'Logarithmic Scale' to match similar widgets. --- .../display/builder/model/widgets/MeterWidget.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java index 7d73fa8e3a..9918650b94 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java @@ -18,7 +18,6 @@ import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propMinimum; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propPrecision; import static org.csstudio.display.builder.model.properties.CommonWidgetProperties.propShowUnits; -import static org.csstudio.display.builder.model.widgets.plots.PlotWidgetProperties.propLogscale; import java.util.Arrays; import java.util.List; @@ -146,6 +145,10 @@ else if (xml_version.getMajor() < 3) public static final WidgetPropertyDescriptor propKnobColor = newColorPropertyDescriptor(WidgetPropertyCategory.MISC, "knob_color", Messages.WidgetProperties_KnobColor); + /** Property */ + public static WidgetPropertyDescriptor propLogScale = + newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "logScale", Messages.WidgetProperties_LogScale); + private volatile WidgetProperty foreground; private volatile WidgetProperty background; private volatile WidgetProperty font; @@ -197,7 +200,7 @@ protected void defineProperties(final List> properties) properties.add(limits_from_pv = propLimitsFromPV.createProperty(this, true)); properties.add(minimum = propMinimum.createProperty(this, 0.0)); properties.add(maximum = propMaximum.createProperty(this, 100.0)); - properties.add(log_scale = propLogscale.createProperty(this, false)); + properties.add(log_scale = propLogScale.createProperty(this, false)); } /** @return 'foreground_color' property */ From c864e1d8f9073088612a04f56a6c044f40962779 Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Fri, 10 Apr 2026 10:51:49 +0100 Subject: [PATCH 3/8] Rename logscale prop variable to not conflict with method name --- .../csstudio/display/builder/model/widgets/MeterWidget.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java index 9918650b94..351291f73b 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java @@ -146,7 +146,7 @@ else if (xml_version.getMajor() < 3) newColorPropertyDescriptor(WidgetPropertyCategory.MISC, "knob_color", Messages.WidgetProperties_KnobColor); /** Property */ - public static WidgetPropertyDescriptor propLogScale = + public static WidgetPropertyDescriptor propLogscale = newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "logScale", Messages.WidgetProperties_LogScale); private volatile WidgetProperty foreground; @@ -200,7 +200,7 @@ protected void defineProperties(final List> properties) properties.add(limits_from_pv = propLimitsFromPV.createProperty(this, true)); properties.add(minimum = propMinimum.createProperty(this, 0.0)); properties.add(maximum = propMaximum.createProperty(this, 100.0)); - properties.add(log_scale = propLogScale.createProperty(this, false)); + properties.add(log_scale = propLogscale.createProperty(this, false)); } /** @return 'foreground_color' property */ From 5d488bbeb6414709e475376299a88a742541b173 Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Fri, 10 Apr 2026 10:58:35 +0100 Subject: [PATCH 4/8] Rename logscale prop (again) so it doesn't conflict with method name --- .../csstudio/display/builder/model/widgets/MeterWidget.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java index 351291f73b..009a6092e5 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java @@ -146,7 +146,7 @@ else if (xml_version.getMajor() < 3) newColorPropertyDescriptor(WidgetPropertyCategory.MISC, "knob_color", Messages.WidgetProperties_KnobColor); /** Property */ - public static WidgetPropertyDescriptor propLogscale = + public static WidgetPropertyDescriptor propLogarithmicScale = newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "logScale", Messages.WidgetProperties_LogScale); private volatile WidgetProperty foreground; @@ -200,7 +200,7 @@ protected void defineProperties(final List> properties) properties.add(limits_from_pv = propLimitsFromPV.createProperty(this, true)); properties.add(minimum = propMinimum.createProperty(this, 0.0)); properties.add(maximum = propMaximum.createProperty(this, 100.0)); - properties.add(log_scale = propLogscale.createProperty(this, false)); + properties.add(log_scale = propLogarithmicScale.createProperty(this, false)); } /** @return 'foreground_color' property */ From 4d5f348011e310d77574e2822fcb57144000e570 Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Fri, 10 Apr 2026 11:45:41 +0100 Subject: [PATCH 5/8] Make property a static final constant --- .../org/csstudio/display/builder/model/widgets/MeterWidget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java index 009a6092e5..8ebefb24d8 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java @@ -146,7 +146,7 @@ else if (xml_version.getMajor() < 3) newColorPropertyDescriptor(WidgetPropertyCategory.MISC, "knob_color", Messages.WidgetProperties_KnobColor); /** Property */ - public static WidgetPropertyDescriptor propLogarithmicScale = + public static final WidgetPropertyDescriptor propLogarithmicScale = newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "logScale", Messages.WidgetProperties_LogScale); private volatile WidgetProperty foreground; From c32a194f0b91b236cc30e2e1938f111dd813d8cf Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Mon, 13 Apr 2026 15:35:55 +0100 Subject: [PATCH 6/8] Fix log calculation for Meter widget in case lower limit is 0 Using log10 method will sent it to a huge negative number and not NaN. --- .../java/org/csstudio/javafx/rtplot/internal/MeterScale.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/MeterScale.java b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/MeterScale.java index 1e48c1606b..91c27b8cca 100644 --- a/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/MeterScale.java +++ b/app/rtplot/src/main/java/org/csstudio/javafx/rtplot/internal/MeterScale.java @@ -16,6 +16,8 @@ import org.csstudio.javafx.rtplot.AxisRange; import org.csstudio.javafx.rtplot.internal.util.GraphicsUtils; +import static org.csstudio.javafx.rtplot.internal.util.Log10.log10; + /** 'Round' numeric scale for a meter. * @author Kay Kasemir */ @@ -133,7 +135,7 @@ public double getAngle(final double value) final AxisRange range = getValueRange(); if (isLogarithmic()) { - return start_angle + Math.log10(value/range.getLow()) * angle_range / Math.log10(range.getHigh()/range.getLow()); + return start_angle + (log10(value) - log10(range.getLow())) * angle_range / (log10(range.getHigh()) - log10(range.getLow())); } else { From 8389de4a43a04494098380ecb533aad8e97916d4 Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Tue, 14 Apr 2026 14:38:36 +0100 Subject: [PATCH 7/8] Convert OPI log_scale property to logScale for Meter widget Used when converting widgets in an OPI file to BOB. --- .../csstudio/display/builder/model/widgets/MeterWidget.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java index 8ebefb24d8..446bda2f0f 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java @@ -107,6 +107,10 @@ public boolean configureFromXML(final ModelReader reader, final Widget widget, || !XMLUtil.getChildBoolean(xml, "show_markers").orElse(true)) meter.propShowLimits().setValue(false); + + // Map log_scale property to logScale + XMLUtil.getChildBoolean(xml, "log_scale") + .ifPresent(meter.propLogScale()::setValue); } else if (xml_version.getMajor() < 3) { // Display Builder meter based on 3rd party JFX lib From c46a749b826e837d4a96c80518ae4cf0c8e9a244 Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Tue, 14 Apr 2026 15:19:16 +0100 Subject: [PATCH 8/8] Rename log scale property in Meter widget to log_scale Revert the change to the conversion which is no longer needed. --- .../csstudio/display/builder/model/widgets/MeterWidget.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java index 446bda2f0f..19c48dc43d 100644 --- a/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java +++ b/app/display/model/src/main/java/org/csstudio/display/builder/model/widgets/MeterWidget.java @@ -107,10 +107,6 @@ public boolean configureFromXML(final ModelReader reader, final Widget widget, || !XMLUtil.getChildBoolean(xml, "show_markers").orElse(true)) meter.propShowLimits().setValue(false); - - // Map log_scale property to logScale - XMLUtil.getChildBoolean(xml, "log_scale") - .ifPresent(meter.propLogScale()::setValue); } else if (xml_version.getMajor() < 3) { // Display Builder meter based on 3rd party JFX lib @@ -151,7 +147,7 @@ else if (xml_version.getMajor() < 3) /** Property */ public static final WidgetPropertyDescriptor propLogarithmicScale = - newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "logScale", Messages.WidgetProperties_LogScale); + newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "log_scale", Messages.WidgetProperties_LogScale); private volatile WidgetProperty foreground; private volatile WidgetProperty background;