Skip to content

Commit b32391b

Browse files
authored
Merge pull request #3538 from ControlSystemStudio/CSSTUDIO-3425
CSSTUDIO-3425 Support for logarithmic scale in the Linear Meter widget
2 parents d6d8ea4 + 26d5132 commit b32391b

File tree

6 files changed

+138
-30
lines changed

6 files changed

+138
-30
lines changed

app/display/linearmeter/src/main/java/org/csstudio/display/extra/widgets/linearmeter/LinearMeterRepresentation.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ public Pane createJFXNode()
7777
widgetColorToAWTColor(model_widget.propNeedleColor().getValue()),
7878
model_widget.propKnobSize().getValue(),
7979
widgetColorToAWTColor(model_widget.propKnobColor().getValue()),
80-
model_widget.propShowWarnings().getValue());
80+
model_widget.propShowWarnings().getValue(),
81+
model_widget.propLogScale().getValue());
8182
meter.setDisplayMode(model_widget.propDisplayMode().getValue());
8283
meter.setSize(model_widget.propWidth().getValue(),model_widget.propHeight().getValue());
8384
meter.setHorizontal(model_widget.propDisplayHorizontal().getValue());
@@ -108,6 +109,11 @@ protected void registerListeners()
108109
addUntypedWidgetPropertyListener(model_widget.propFont(), layoutChangedListener);
109110
addUntypedWidgetPropertyListener(model_widget.propNeedleColor(), layoutChangedListener);
110111

112+
addWidgetPropertyListener(model_widget.propLogScale(), (property, oldValue, newValue) -> {
113+
meter.setLogScale(newValue);
114+
layoutChanged(null, null, null);
115+
});
116+
111117
addWidgetPropertyListener(model_widget.propShowWarnings(), (property, oldValue, newValue) -> {
112118
meter.setShowWarnings(newValue);
113119
layoutChanged(null, null, null);

app/display/linearmeter/src/main/java/org/csstudio/display/extra/widgets/linearmeter/LinearMeterScale.java

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import org.csstudio.javafx.rtplot.internal.*;
77
import org.csstudio.javafx.rtplot.internal.util.GraphicsUtils;
88

9+
import static org.csstudio.javafx.rtplot.internal.util.Log10.log10;
10+
911

1012
public class LinearMeterScale extends NumericAxis
1113
{
@@ -39,10 +41,12 @@ public LinearMeterScale(PlotPartListener listener,
3941
int height,
4042
boolean horizontal,
4143
double min,
42-
double max)
44+
double max,
45+
boolean isLogarithmic)
4346
{
4447
super("", listener, horizontal, min, max);
4548
super.setBounds(0, 0, width, height);
49+
super.setLogarithmic(isLogarithmic);
4650
isHorizontal = horizontal;
4751
}
4852

@@ -102,26 +106,49 @@ public void paint(Graphics2D gc, Rectangle plot_bounds)
102106
FontMetrics scale_font_fontMetrics = gc.getFontMetrics(scale_font);
103107

104108
for (MajorTick<Double> tick : ticks.getMajorTicks()) {
105-
gc.drawLine((int) ((start_x + this.scale * (tick.getValue() - offset) )),
109+
if (isLogarithmic()) {
110+
gc.drawLine((int) ((start_x + this.scale * (log10(tick.getValue()) - log10(offset)) )),
111+
(int) ((start_y - 0.5 * TICK_LENGTH)),
112+
(int) ((start_x + this.scale * (log10(tick.getValue()) - log10(offset)) )),
113+
(int) ((start_y + 0.5 * TICK_LENGTH)));
114+
drawTickLabel(gc,
115+
(int) ((start_x + this.scale * (log10(tick.getValue()) - log10(offset)) - scale_font_fontMetrics.stringWidth(tick.getLabel())/2)),
116+
(int) (start_y + 0.5 * TICK_LENGTH + 2 + Math.round(Math.ceil((72.0 * (scale_font_fontMetrics.getAscent())) / 96.0))),
117+
tick.getLabel());
118+
}
119+
else {
120+
gc.drawLine((int) ((start_x + this.scale * (tick.getValue() - offset) )),
106121
(int) ((start_y - 0.5 * TICK_LENGTH)),
107122
(int) ((start_x + this.scale * (tick.getValue() - offset) )),
108123
(int) ((start_y + 0.5 * TICK_LENGTH)));
109-
drawTickLabel(gc,
110-
(int) ((start_x + this.scale * (tick.getValue() - offset) - scale_font_fontMetrics.stringWidth(tick.getLabel())/2)),
111-
(int) (start_y + 0.5 * TICK_LENGTH + 2 + Math.round(Math.ceil((72.0 * (scale_font_fontMetrics.getAscent())) / 96.0))),
112-
tick.getLabel());
124+
drawTickLabel(gc,
125+
(int) ((start_x + this.scale * (tick.getValue() - offset) - scale_font_fontMetrics.stringWidth(tick.getLabel())/2)),
126+
(int) (start_y + 0.5 * TICK_LENGTH + 2 + Math.round(Math.ceil((72.0 * (scale_font_fontMetrics.getAscent())) / 96.0))),
127+
tick.getLabel());
128+
}
113129
}
114130
} else {
115-
116131
for (MajorTick<Double> tick : ticks.getMajorTicks()) {
117-
gc.drawLine((int) (start_x - 0.5 * TICK_LENGTH),
132+
if (isLogarithmic()) {
133+
gc.drawLine((int) (start_x - 0.5 * TICK_LENGTH),
134+
(int) (start_y - this.scale * (log10(tick.getValue()) - log10(offset))),
135+
(int) (start_x + 0.5 * TICK_LENGTH),
136+
(int) (start_y - this.scale * (log10(tick.getValue()) - log10(offset))));
137+
drawTickLabel(gc,
138+
(int) (start_x + 4),
139+
(int) (start_y - this.scale * (log10(tick.getValue()) - log10(offset)) + Math.round((72.0 * scale_font.getSize()) / (96.0 * 2.0))),
140+
tick.getLabel());
141+
}
142+
else {
143+
gc.drawLine((int) (start_x - 0.5 * TICK_LENGTH),
118144
(int) (start_y - this.scale * (tick.getValue() - offset)),
119145
(int) (start_x + 0.5 * TICK_LENGTH),
120146
(int) (start_y - this.scale * (tick.getValue() - offset)));
121-
drawTickLabel(gc,
122-
(int) (start_x + 4),
123-
(int) (start_y - this.scale * (tick.getValue() - offset) + Math.round((72.0 * scale_font.getSize()) / (96.0 * 2.0))),
124-
tick.getLabel());
147+
drawTickLabel(gc,
148+
(int) (start_x + 4),
149+
(int) (start_y - this.scale * (tick.getValue() - offset) + Math.round((72.0 * scale_font.getSize()) / (96.0 * 2.0))),
150+
tick.getLabel());
151+
}
125152
}
126153
}
127154

app/display/linearmeter/src/main/java/org/csstudio/display/extra/widgets/linearmeter/LinearMeterWidget.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ public EnumWidgetProperty<RTLinearMeter.DisplayMode> createProperty(Widget widge
160160
}
161161
};
162162

163+
private WidgetProperty<Boolean> logScale;
164+
public static WidgetPropertyDescriptor<Boolean> propLogScale =
165+
newBooleanPropertyDescriptor(WidgetPropertyCategory.DISPLAY, "logScale", Messages.WidgetProperties_LogScale);
166+
163167
public static WidgetPropertyDescriptor<WidgetColor> propNeedleColor =
164168
newColorPropertyDescriptor(WidgetPropertyCategory.MISC, "needle_color", Messages.WidgetProperties_NeedleColor);
165169

@@ -253,6 +257,7 @@ protected void defineProperties(List<WidgetProperty<?>> properties) {
253257
super.defineProperties(properties);
254258

255259
properties.add(display_mode = propDisplayMode.createProperty(this, RTLinearMeter.DisplayMode.NEEDLE));
260+
properties.add(logScale = propLogScale.createProperty(this, false));
256261
properties.add(font = propFont.createProperty(this, WidgetFontService.get(NamedWidgetFonts.DEFAULT)));
257262
properties.add(format = propFormat.createProperty(this, FormatOption.DEFAULT));
258263
properties.add(show_units = propShowUnits.createProperty(this, true));
@@ -439,4 +444,8 @@ public WidgetProperty<RTLinearMeter.DisplayMode> propDisplayMode() {
439444
return display_mode;
440445
}
441446

447+
public WidgetProperty<Boolean> propLogScale() {
448+
return logScale;
449+
}
450+
442451
}

app/display/linearmeter/src/main/java/org/csstudio/display/extra/widgets/linearmeter/RTLinearMeter.java

Lines changed: 81 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
package org.csstudio.display.extra.widgets.linearmeter;
33

44
import static org.csstudio.javafx.rtplot.Activator.logger;
5+
import static org.csstudio.javafx.rtplot.internal.util.Log10.log10;
56

67
import java.awt.BasicStroke;
78
import java.awt.Canvas;
@@ -91,7 +92,8 @@ public RTLinearMeter(double initialValue,
9192
Color needleColor,
9293
int knobSize,
9394
Color knobColor,
94-
boolean showWarnings)
95+
boolean showWarnings,
96+
boolean logScale)
9597
{
9698
if (warningTriangle == null) {
9799
try {
@@ -115,7 +117,8 @@ public RTLinearMeter(double initialValue,
115117
height,
116118
isHorizontal,
117119
min,
118-
max);
120+
max,
121+
logScale);
119122

120123
this.minMaxTolerance = minMaxTolerance;
121124
this.loLo = loLo;
@@ -189,7 +192,8 @@ public void redrawLinearMeterScale() {
189192
linearMeterScale.getBounds().height,
190193
linearMeterScale.isHorizontal(),
191194
linearMeterScale.getValueRange().getLow(),
192-
linearMeterScale.getValueRange().getHigh());
195+
linearMeterScale.getValueRange().getHigh(),
196+
linearMeterScale.isLogarithmic());
193197
linearMeterScale.setHorizontal(isHorizontal);
194198
});
195199
}
@@ -295,6 +299,12 @@ public void setDisplayMode(DisplayMode newDisplayMode) {
295299

296300
private DisplayMode displayMode = DisplayMode.NEEDLE;
297301

302+
public void setLogScale(boolean logScale) {
303+
withWriteLock(() -> {
304+
linearMeterScale.setLogarithmic(logScale);
305+
});
306+
}
307+
298308
private void runOnJavaFXThread(Runnable runnable) {
299309
if (Platform.isFxApplicationThread()) {
300310
runnable.run();
@@ -749,10 +759,20 @@ private Optional<Integer> computeIndicatorPosition(double value) {
749759
}
750760
return withReadLock(() -> {
751761
if (linearMeterScale.isHorizontal()) {
752-
return Optional.of((int) Math.round(marginLeft + pixelsPerScaleUnit * (value - linearMeterScale.getValueRange().getLow())));
762+
if (linearMeterScale.isLogarithmic()) {
763+
return Optional.of((int) Math.round(marginLeft + pixelsPerScaleUnit * (log10(value) - log10(linearMeterScale.getValueRange().getLow()))));
764+
}
765+
else {
766+
return Optional.of((int) Math.round(marginLeft + pixelsPerScaleUnit * (value - linearMeterScale.getValueRange().getLow())));
767+
}
753768
}
754769
else {
755-
return Optional.of((int) Math.round(linearMeterScale.getBounds().height - marginBelow - pixelsPerScaleUnit * (value - linearMeterScale.getValueRange().getLow())));
770+
if (linearMeterScale.isLogarithmic()) {
771+
return Optional.of((int) Math.round(linearMeterScale.getBounds().height - marginBelow - pixelsPerScaleUnit * (log10(value) - log10(linearMeterScale.getValueRange().getLow()))));
772+
}
773+
else {
774+
return Optional.of((int) Math.round(linearMeterScale.getBounds().height - marginBelow - pixelsPerScaleUnit * (value - linearMeterScale.getValueRange().getLow())));
775+
}
756776
}
757777
});
758778
}
@@ -1323,14 +1343,34 @@ private void layout() {
13231343
marginBelow += 1 + fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent();
13241344
}
13251345

1326-
pixelsPerScaleUnit = (linearMeterScale.getBounds().width - marginLeft - marginRight - 1) / (linearMeterScale.getValueRange().getHigh() - linearMeterScale.getValueRange().getLow());
1346+
if (linearMeterScale.isLogarithmic()) {
1347+
pixelsPerScaleUnit = (linearMeterScale.getBounds().width - marginLeft - marginRight - 1) / (log10(linearMeterScale.getValueRange().getHigh()) - log10(linearMeterScale.getValueRange().getLow()));
1348+
}
1349+
else {
1350+
pixelsPerScaleUnit = (linearMeterScale.getBounds().width - marginLeft - marginRight - 1) / (linearMeterScale.getValueRange().getHigh() - linearMeterScale.getValueRange().getLow());
1351+
}
13271352
meterBreadth = Math.round(linearMeterScale.getBounds().height - marginAbove - marginBelow) - 1;
13281353

1329-
double x_loLoRectangle = marginLeft;
1330-
double x_lowRectangle = marginLeft + pixelsPerScaleUnit * (displayedLoLo - linearMeterScale.getValueRange().getLow());
1331-
double x_normalRectangle = marginLeft + pixelsPerScaleUnit * (displayedLow - linearMeterScale.getValueRange().getLow());
1332-
double x_highRectangle = marginLeft + pixelsPerScaleUnit * (displayedHigh - linearMeterScale.getValueRange().getLow());
1333-
double x_hiHiRectangle = marginLeft + pixelsPerScaleUnit * (displayedHiHi - linearMeterScale.getValueRange().getLow());
1354+
double x_loLoRectangle;
1355+
double x_lowRectangle;
1356+
double x_normalRectangle;
1357+
double x_highRectangle;
1358+
double x_hiHiRectangle;
1359+
if (linearMeterScale.isLogarithmic()) {
1360+
x_loLoRectangle = marginLeft;
1361+
x_lowRectangle = marginLeft + pixelsPerScaleUnit * (log10(displayedLoLo) - log10(linearMeterScale.getValueRange().getLow()));
1362+
x_normalRectangle = marginLeft + pixelsPerScaleUnit * (log10(displayedLow) - log10(linearMeterScale.getValueRange().getLow()));
1363+
x_highRectangle = marginLeft + pixelsPerScaleUnit * (log10(displayedHigh) - log10(linearMeterScale.getValueRange().getLow()));
1364+
x_hiHiRectangle = marginLeft + pixelsPerScaleUnit * (log10(displayedHiHi) - log10(linearMeterScale.getValueRange().getLow()));
1365+
}
1366+
else {
1367+
x_loLoRectangle = marginLeft;
1368+
x_lowRectangle = marginLeft + pixelsPerScaleUnit * (displayedLoLo - linearMeterScale.getValueRange().getLow());
1369+
x_normalRectangle = marginLeft + pixelsPerScaleUnit * (displayedLow - linearMeterScale.getValueRange().getLow());
1370+
x_highRectangle = marginLeft + pixelsPerScaleUnit * (displayedHigh - linearMeterScale.getValueRange().getLow());
1371+
x_hiHiRectangle = marginLeft + pixelsPerScaleUnit * (displayedHiHi - linearMeterScale.getValueRange().getLow());
1372+
1373+
}
13341374

13351375
loLoRectangle = new Rectangle((int) Math.round(x_loLoRectangle),
13361376
marginAbove,
@@ -1352,9 +1392,16 @@ private void layout() {
13521392
(int) (Math.round(x_hiHiRectangle) - Math.round(x_highRectangle)),
13531393
meterBreadth);
13541394

1395+
int hihiWidth;
1396+
if (linearMeterScale.isLogarithmic()) {
1397+
hihiWidth = (int) (Math.round(pixelsPerScaleUnit * (log10(linearMeterScale.getValueRange().getHigh()) - log10(displayedHiHi))));
1398+
}
1399+
else {
1400+
hihiWidth = (int) (Math.round(pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedHiHi)));
1401+
}
13551402
hiHiRectangle = new Rectangle((int) Math.round(x_hiHiRectangle),
13561403
marginAbove,
1357-
(int) (Math.round(pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedHiHi))),
1404+
hihiWidth,
13581405
meterBreadth);
13591406
}
13601407
else {
@@ -1381,13 +1428,30 @@ private void layout() {
13811428
marginBelow += 1 + fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent();
13821429
}
13831430

1384-
pixelsPerScaleUnit = (linearMeterScale.getBounds().height - marginAbove - marginBelow - 1) / (linearMeterScale.getValueRange().getHigh() - linearMeterScale.getValueRange().getLow());
1431+
if (linearMeterScale.isLogarithmic()) {
1432+
pixelsPerScaleUnit = (linearMeterScale.getBounds().height - marginAbove - marginBelow - 1) / (log10(linearMeterScale.getValueRange().getHigh()) - log10(linearMeterScale.getValueRange().getLow()));
1433+
}
1434+
else {
1435+
pixelsPerScaleUnit = (linearMeterScale.getBounds().height - marginAbove - marginBelow - 1) / (linearMeterScale.getValueRange().getHigh() - linearMeterScale.getValueRange().getLow());
1436+
}
13851437
meterBreadth = Math.round(linearMeterScale.getBounds().width - marginLeft - marginRight);
13861438

1387-
double y_loLoRectangle = marginAbove + pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedLoLo);
1388-
double y_lowRectangle = marginAbove + pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedLow);
1389-
double y_normalRectangle = marginAbove + pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedHigh);
1390-
double y_highRectangle = marginAbove + pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedHiHi);
1439+
double y_loLoRectangle;
1440+
double y_lowRectangle;
1441+
double y_normalRectangle;
1442+
double y_highRectangle;
1443+
if (linearMeterScale.isLogarithmic()) {
1444+
y_loLoRectangle = marginAbove + pixelsPerScaleUnit * (log10(linearMeterScale.getValueRange().getHigh()) - log10(displayedLoLo));
1445+
y_lowRectangle = marginAbove + pixelsPerScaleUnit * (log10(linearMeterScale.getValueRange().getHigh()) - log10(displayedLow));
1446+
y_normalRectangle = marginAbove + pixelsPerScaleUnit * (log10(linearMeterScale.getValueRange().getHigh()) - log10(displayedHigh));
1447+
y_highRectangle = marginAbove + pixelsPerScaleUnit * (log10(linearMeterScale.getValueRange().getHigh()) - log10(displayedHiHi));
1448+
}
1449+
else {
1450+
y_loLoRectangle = marginAbove + pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedLoLo);
1451+
y_lowRectangle = marginAbove + pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedLow);
1452+
y_normalRectangle = marginAbove + pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedHigh);
1453+
y_highRectangle = marginAbove + pixelsPerScaleUnit * (linearMeterScale.getValueRange().getHigh() - displayedHiHi);
1454+
}
13911455

13921456
loLoRectangle = new Rectangle(marginLeft,
13931457
(int) Math.round(y_loLoRectangle),

app/display/model/src/main/java/org/csstudio/display/builder/model/Messages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ public class Messages
260260
WidgetProperties_LineColor,
261261
WidgetProperties_LineWidth,
262262
WidgetProperties_Locale,
263+
WidgetProperties_LogScale,
263264
WidgetProperties_Macros,
264265
WidgetProperties_MajorTickSpace,
265266
WidgetProperties_MajorTickStepHint,

app/display/model/src/main/resources/org/csstudio/display/builder/model/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ WidgetProperties_LimitsFromPV=Limits from PV
246246
WidgetProperties_LineColor=Line Color
247247
WidgetProperties_LineWidth=Line Width
248248
WidgetProperties_Locale=Locale
249+
WidgetProperties_LogScale=Logarithmic Scale
249250
WidgetProperties_Macros=Macros
250251
WidgetProperties_MajorTickSpace=Major Ticks Space
251252
WidgetProperties_MajorTickStepHint=Major Ticks Pixel Dist.

0 commit comments

Comments
 (0)