Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/components/InstrumentPage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ test("toPrecision truncates block if it has precision", () => {
precision: precision,
};
expect(toPrecision(aBlock, originalValue)).toBe(
originalValue.toPrecision(precision),
originalValue.toFixed(precision),
);
});

Expand Down
9 changes: 6 additions & 3 deletions app/components/InstrumentPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import {
IfcPVWSMessage,
IfcPVWSRequest,
} from "@/app/types";
import { findPVByAddress } from "@/app/components/PVutils";
import {
findPVByAddress,
ExponentialOnThresholdFormat,
} from "@/app/components/PVutils";
import CheckToggle from "@/app/components/CheckToggle";

let lastUpdate: string = "";
Expand Down Expand Up @@ -91,8 +94,8 @@ export function toPrecision(
block: IfcBlock,
pvVal: number | string,
): string | number {
return block.precision && typeof pvVal == "number"
? pvVal.toPrecision(block.precision)
return block.precision
? ExponentialOnThresholdFormat(pvVal, block.precision)
: pvVal;
}

Expand Down
121 changes: 121 additions & 0 deletions app/components/PVutils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { IfcPV } from "@/app/types";
import {
findPVByAddress,
findPVByHumanReadableName,
ExponentialOnThresholdFormat,
} from "@/app/components/PVutils";

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

expect(result).toBe(undefined);
});

// Test of ExponentialOnThresholdFormat ported from ibex_gui Java code
test("GIVEN value 0.1 which is above lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(0.1)).toBe("0.100");
});

test("GIVEN negative value 0.1 which is above lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-0.1)).toBe("-0.100");
});

test("GIVEN value 0.01 which is above lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(0.01)).toBe("0.010");
});

test("GIVEN value equal to lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(0.001)).toBe("0.001");
});

test("GIVEN negative value equal to lower threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-0.001)).toBe("-0.001");
});

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", () => {
expect(ExponentialOnThresholdFormat(0.01234)).toBe("0.012");
});

test("GIVEN value above lower threshold with integer part WHEN formatting with precision 5 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(1234.56, 5)).toBe("1234.56000");
});

test("GIVEN value above lower threshold with integer part and extra fractional digits WHEN formatting with precision 3 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(12.5678)).toBe("12.568");
});

test("GIVEN value below lower threshold WHEN formatting with precision 3 THEN exponential notation used", () => {
expect(ExponentialOnThresholdFormat(0.0009)).toBe("9.000E-4");
});

test("GIVEN very small value WHEN formatting with precision 5 THEN exponential notation used", () => {
expect(ExponentialOnThresholdFormat(0.000000001234567, 5)).toBe("1.23457E-9");
});

test("GIVEN very small negative value WHEN formatting with precision 5 THEN exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-0.000000001234567, 5)).toBe(
"-1.23457E-9",
);
});

test("GIVEN value just below higher threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(999999.1234)).toBe("999999.123");
});

test("GIVEN negative value just below higher threshold WHEN formatting with precision 3 THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-999999.1234)).toBe("-999999.123");
});

// TypeScript does not have separate integer/float types - for integers never use exponential so change test a bit
test("GIVEN value equal to higher threshold WHEN formatting with precision 3 THEN exponential notation used", () => {
//expect(ExponentialOnThresholdFormat(1000000)).toBe("1.000E6");
expect(ExponentialOnThresholdFormat(1000000.1)).toBe("1.000E6");
});

test("GIVEN negative value equal to higher threshold WHEN formatting with precision 3 THEN exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-1000000.1)).toBe("-1.000E6");
});

test("GIVEN value above higher threshold WHEN formatting with precision 5 THEN exponential notation used", () => {
//expect(ExponentialOnThresholdFormat(123456789, 5)).toBe("1.23457E8");
expect(ExponentialOnThresholdFormat(123456789.1, 5)).toBe("1.23457E8");
});

test("GIVEN negative value above higher threshold WHEN formatting with precision 5 THEN exponential notation used", () => {
//expect(ExponentialOnThresholdFormat(-123456789, 5)).toBe("-1.23457E8");
expect(ExponentialOnThresholdFormat(-123456789.1, 5)).toBe("-1.23457E8");
});

// TypeScript does not have separate integer/float types - so ignore next two tests.
//it("GIVEN value 0 WHEN formatting THEN no exponential notation used", () => {
// expect(ExponentialOnThresholdFormat(0)).toBe("0.000");
//});
//
//it("GIVEN negative value 0 WHEN formatting THEN no exponential notation used", () => {
// expect(ExponentialOnThresholdFormat(-0)).toBe("0.000");
//});

test("GIVEN integer below higher threshold WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(13)).toBe("13");
});

test("GIVEN negative integer below higher threshold WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-13)).toBe("-13");
});

test("GIVEN integer just below higher threshold WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(999999)).toBe("999999");
});

test("GIVEN integer equal to higher threshold WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(1000000)).toBe("1000000");
});

test("GIVEN negative integer equal to higher threshold WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-1000000)).toBe("-1000000");
});

test("GIVEN integer above higher threshold WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(123456789)).toBe("123456789");
});

test("GIVEN negative integer above higher threshold WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-123456789)).toBe("-123456789");
});

test("GIVEN integer equal to 0 WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(0)).toBe("0");
});

test("GIVEN negative integer equal to 0 WHEN formatting THEN no exponential notation used", () => {
expect(ExponentialOnThresholdFormat(-0)).toBe("0");
});
27 changes: 27 additions & 0 deletions app/components/PVutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,30 @@ export function findPVByAddress(
): IfcPV | undefined {
return arr.find((b: IfcPV) => b.pvaddress == address);
}

/**
* Formats a given PV value input such that above or below a threshold value,
* it uses scientific (exponential) notation, matching behaviour of ibex_gui
*/
export function ExponentialOnThresholdFormat(
value: string | number,
precision: number = 3,
) {
var nValue: number = value == undefined ? NaN : +value;
if (isNaN(nValue)) {
return value;
} else {
if (nValue == 0) {
return "0";
} else if (Number.isInteger(nValue)) {
return nValue.toString();
} else if (Math.abs(nValue) < 0.001 || Math.abs(nValue) >= 1000000) {
return nValue
.toExponential(precision)
.replace("e+", "E")
.replace("e", "E");
} else {
return nValue.toFixed(precision);
}
}
}