Skip to content

Commit e71d75d

Browse files
Merge pull request #79 from mducle/pvformattedval
Add formatting of PV values
2 parents e1f03bb + 63fe264 commit e71d75d

File tree

4 files changed

+155
-4
lines changed

4 files changed

+155
-4
lines changed

app/components/InstrumentPage.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ test("toPrecision truncates block if it has precision", () => {
4949
precision: precision,
5050
};
5151
expect(toPrecision(aBlock, originalValue)).toBe(
52-
originalValue.toPrecision(precision),
52+
originalValue.toFixed(precision),
5353
);
5454
});
5555

app/components/InstrumentPage.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import {
1515
IfcPVWSMessage,
1616
IfcPVWSRequest,
1717
} from "@/app/types";
18-
import { findPVByAddress } from "@/app/components/PVutils";
18+
import {
19+
findPVByAddress,
20+
ExponentialOnThresholdFormat,
21+
} from "@/app/components/PVutils";
1922
import CheckToggle from "@/app/components/CheckToggle";
2023

2124
let lastUpdate: string = "";
@@ -91,8 +94,8 @@ export function toPrecision(
9194
block: IfcBlock,
9295
pvVal: number | string,
9396
): string | number {
94-
return block.precision && typeof pvVal == "number"
95-
? pvVal.toPrecision(block.precision)
97+
return block.precision
98+
? ExponentialOnThresholdFormat(pvVal, block.precision)
9699
: pvVal;
97100
}
98101

app/components/PVutils.test.ts

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { IfcPV } from "@/app/types";
22
import {
33
findPVByAddress,
44
findPVByHumanReadableName,
5+
ExponentialOnThresholdFormat,
56
} from "@/app/components/PVutils";
67

78
test("findPVByAddress finds a PV and returns it", () => {
@@ -46,3 +47,123 @@ test("findPVByHumanReadableName does not find a nonexistant PV and returns undef
4647

4748
expect(result).toBe(undefined);
4849
});
50+
51+
// Test of ExponentialOnThresholdFormat ported from ibex_gui Java code
52+
test("GIVEN value 0.1 which is above lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
53+
expect(ExponentialOnThresholdFormat(0.1)).toBe("0.100");
54+
});
55+
56+
test("GIVEN negative value 0.1 which is above lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
57+
expect(ExponentialOnThresholdFormat(-0.1)).toBe("-0.100");
58+
});
59+
60+
test("GIVEN value 0.01 which is above lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
61+
expect(ExponentialOnThresholdFormat(0.01)).toBe("0.010");
62+
});
63+
64+
test("GIVEN value equal to lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
65+
expect(ExponentialOnThresholdFormat(0.001)).toBe("0.001");
66+
});
67+
68+
test("GIVEN negative value equal to lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
69+
expect(ExponentialOnThresholdFormat(-0.001)).toBe("-0.001");
70+
});
71+
72+
test("GIVEN value above lower threshold with extra fractioanl digits WHEN formatting with precision 3 THEN no exponential notation used and some digits are lost", () => {
73+
expect(ExponentialOnThresholdFormat(0.01234)).toBe("0.012");
74+
});
75+
76+
test("GIVEN value above lower threshold with integer part WHEN formatting with precision 5 THEN no exponential notation used", () => {
77+
expect(ExponentialOnThresholdFormat(1234.56, 5)).toBe("1234.56000");
78+
});
79+
80+
test("GIVEN value above lower threshold with integer part and extra fractional digits WHEN formatting with precision 3 THEN no exponential notation used", () => {
81+
expect(ExponentialOnThresholdFormat(12.5678)).toBe("12.568");
82+
});
83+
84+
test("GIVEN value below lower threshold WHEN formatting with precision 3 THEN exponential notation used", () => {
85+
expect(ExponentialOnThresholdFormat(0.0009)).toBe("9.000E-4");
86+
});
87+
88+
test("GIVEN very small value WHEN formatting with precision 5 THEN exponential notation used", () => {
89+
expect(ExponentialOnThresholdFormat(0.000000001234567, 5)).toBe("1.23457E-9");
90+
});
91+
92+
test("GIVEN very small negative value WHEN formatting with precision 5 THEN exponential notation used", () => {
93+
expect(ExponentialOnThresholdFormat(-0.000000001234567, 5)).toBe(
94+
"-1.23457E-9",
95+
);
96+
});
97+
98+
test("GIVEN value just below higher threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
99+
expect(ExponentialOnThresholdFormat(999999.1234)).toBe("999999.123");
100+
});
101+
102+
test("GIVEN negative value just below higher threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
103+
expect(ExponentialOnThresholdFormat(-999999.1234)).toBe("-999999.123");
104+
});
105+
106+
// TypeScript does not have separate integer/float types - for integers never use exponential so change test a bit
107+
test("GIVEN value equal to higher threshold WHEN formatting with precision 3 THEN exponential notation used", () => {
108+
//expect(ExponentialOnThresholdFormat(1000000)).toBe("1.000E6");
109+
expect(ExponentialOnThresholdFormat(1000000.1)).toBe("1.000E6");
110+
});
111+
112+
test("GIVEN negative value equal to higher threshold WHEN formatting with precision 3 THEN exponential notation used", () => {
113+
expect(ExponentialOnThresholdFormat(-1000000.1)).toBe("-1.000E6");
114+
});
115+
116+
test("GIVEN value above higher threshold WHEN formatting with precision 5 THEN exponential notation used", () => {
117+
//expect(ExponentialOnThresholdFormat(123456789, 5)).toBe("1.23457E8");
118+
expect(ExponentialOnThresholdFormat(123456789.1, 5)).toBe("1.23457E8");
119+
});
120+
121+
test("GIVEN negative value above higher threshold WHEN formatting with precision 5 THEN exponential notation used", () => {
122+
//expect(ExponentialOnThresholdFormat(-123456789, 5)).toBe("-1.23457E8");
123+
expect(ExponentialOnThresholdFormat(-123456789.1, 5)).toBe("-1.23457E8");
124+
});
125+
126+
// TypeScript does not have separate integer/float types - so ignore next two tests.
127+
//it("GIVEN value 0 WHEN formatting THEN no exponential notation used", () => {
128+
// expect(ExponentialOnThresholdFormat(0)).toBe("0.000");
129+
//});
130+
//
131+
//it("GIVEN negative value 0 WHEN formatting THEN no exponential notation used", () => {
132+
// expect(ExponentialOnThresholdFormat(-0)).toBe("0.000");
133+
//});
134+
135+
test("GIVEN integer below higher threshold WHEN formatting THEN no exponential notation used", () => {
136+
expect(ExponentialOnThresholdFormat(13)).toBe("13");
137+
});
138+
139+
test("GIVEN negative integer below higher threshold WHEN formatting THEN no exponential notation used", () => {
140+
expect(ExponentialOnThresholdFormat(-13)).toBe("-13");
141+
});
142+
143+
test("GIVEN integer just below higher threshold WHEN formatting THEN no exponential notation used", () => {
144+
expect(ExponentialOnThresholdFormat(999999)).toBe("999999");
145+
});
146+
147+
test("GIVEN integer equal to higher threshold WHEN formatting THEN no exponential notation used", () => {
148+
expect(ExponentialOnThresholdFormat(1000000)).toBe("1000000");
149+
});
150+
151+
test("GIVEN negative integer equal to higher threshold WHEN formatting THEN no exponential notation used", () => {
152+
expect(ExponentialOnThresholdFormat(-1000000)).toBe("-1000000");
153+
});
154+
155+
test("GIVEN integer above higher threshold WHEN formatting THEN no exponential notation used", () => {
156+
expect(ExponentialOnThresholdFormat(123456789)).toBe("123456789");
157+
});
158+
159+
test("GIVEN negative integer above higher threshold WHEN formatting THEN no exponential notation used", () => {
160+
expect(ExponentialOnThresholdFormat(-123456789)).toBe("-123456789");
161+
});
162+
163+
test("GIVEN integer equal to 0 WHEN formatting THEN no exponential notation used", () => {
164+
expect(ExponentialOnThresholdFormat(0)).toBe("0");
165+
});
166+
167+
test("GIVEN negative integer equal to 0 WHEN formatting THEN no exponential notation used", () => {
168+
expect(ExponentialOnThresholdFormat(-0)).toBe("0");
169+
});

app/components/PVutils.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,30 @@ export function findPVByAddress(
1919
): IfcPV | undefined {
2020
return arr.find((b: IfcPV) => b.pvaddress == address);
2121
}
22+
23+
/**
24+
* Formats a given PV value input such that above or below a threshold value,
25+
* it uses scientific (exponential) notation, matching behaviour of ibex_gui
26+
*/
27+
export function ExponentialOnThresholdFormat(
28+
value: string | number,
29+
precision: number = 3,
30+
) {
31+
var nValue: number = value == undefined ? NaN : +value;
32+
if (isNaN(nValue)) {
33+
return value;
34+
} else {
35+
if (nValue == 0) {
36+
return "0";
37+
} else if (Number.isInteger(nValue)) {
38+
return nValue.toString();
39+
} else if (Math.abs(nValue) < 0.001 || Math.abs(nValue) >= 1000000) {
40+
return nValue
41+
.toExponential(precision)
42+
.replace("e+", "E")
43+
.replace("e", "E");
44+
} else {
45+
return nValue.toFixed(precision);
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)