Skip to content

Commit 14b234a

Browse files
Fix trace and axes properties for XYPlot and legacy opi properties
1 parent 033a746 commit 14b234a

File tree

11 files changed

+219
-290
lines changed

11 files changed

+219
-290
lines changed

src/types/axis.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ describe("Axis", () => {
1515
visible: false,
1616
scaleFont: new Font(20, FontStyle.Italic),
1717
titleFont: new Font(40),
18-
onRight: true
18+
onRight: true,
19+
xAxis: true
1920
};
20-
const axis = new Axis({ xAxis: true, ...testValues });
21+
const axis = new Axis(testValues);
2122

2223
expect(axis).toEqual(testValues);
2324
expect(axis).toBeInstanceOf(Axis);
@@ -37,7 +38,8 @@ describe("Axis", () => {
3738
maximum: 100,
3839
scaleFont: new Font(),
3940
titleFont: new Font(FontStyle.Bold),
40-
onRight: false
41+
onRight: false,
42+
xAxis: false
4143
});
4244
expect(axis).toBeInstanceOf(Axis);
4345
});

src/types/axis.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Color } from "./color";
22
import { Font, FontStyle } from "./font";
33

44
export class Axis {
5+
public xAxis: boolean;
56
public color: Color;
67
public title: string;
78
public showGrid: boolean;
@@ -31,8 +32,10 @@ export class Axis {
3132
maximum = 100,
3233
titleFont = new Font(FontStyle.Bold),
3334
scaleFont = new Font(),
34-
onRight = false
35+
onRight = false,
36+
fromOpi = false
3537
} = {}) {
38+
this.xAxis = xAxis;
3639
this.color = color;
3740
this.title = title || (xAxis ? "X" : "Y");
3841
this.showGrid = showGrid;
@@ -43,7 +46,7 @@ export class Axis {
4346
this.maximum = maximum;
4447
this.titleFont = titleFont;
4548
this.scaleFont = scaleFont;
46-
this.onRight = onRight;
49+
this.onRight = fromOpi ? !onRight : onRight;
4750
}
4851
}
4952

src/types/trace.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ export class Trace {
1212
public visible: boolean;
1313
public yPv: string;
1414
public xPv?: string | null;
15+
public bufferSize?: number;
16+
public plotMode?: number;
17+
public antiAlias?: boolean;
18+
public concatenateData?: boolean;
19+
public updateDelay?: number;
20+
public updateMode?: number;
1521

1622
public constructor({
1723
name = "",
@@ -24,7 +30,14 @@ export class Trace {
2430
pointSize = 1,
2531
visible = true,
2632
xPv = "",
27-
yPv = ""
33+
yPv = "",
34+
fromOpi = false,
35+
antiAlias = true,
36+
bufferSize = 100,
37+
concatenateData = true,
38+
updateDelay = 100,
39+
updateMode = 0,
40+
plotMode = 0
2841
} = {}) {
2942
// xPV property only exists on XYPlot
3043
if (xPv) this.xPv = xPv;
@@ -38,5 +51,13 @@ export class Trace {
3851
this.pointType = pointType;
3952
this.pointSize = pointSize;
4053
this.visible = visible;
54+
if (fromOpi) {
55+
this.antiAlias = antiAlias;
56+
this.bufferSize = bufferSize;
57+
this.concatenateData = concatenateData;
58+
this.updateDelay = updateDelay;
59+
this.updateMode = updateMode;
60+
this.plotMode = plotMode;
61+
}
4162
}
4263
}

src/ui/widgets/EmbeddedDisplay/bobParser.ts

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -254,16 +254,18 @@ function bobParseSymbols(jsonProp: ElementCompact): string[] {
254254
function bobParseTraces(props: any): Trace[] {
255255
const traces: Trace[] = [];
256256
let parsedProps = {};
257-
// If only once trace, we are passed an object instead
258-
// of an array
259-
if (props.trace.length > 1) {
260-
props.trace.forEach((trace: any) => {
261-
parsedProps = bobParseChildProps(trace);
257+
if (props) {
258+
// If only once trace, we are passed an object instead
259+
// of an array
260+
if (props.trace.length > 1) {
261+
props.trace.forEach((trace: any) => {
262+
parsedProps = bobParseChildProps(trace);
263+
traces.push(new Trace(parsedProps));
264+
});
265+
} else {
266+
parsedProps = bobParseChildProps(props.trace);
262267
traces.push(new Trace(parsedProps));
263-
});
264-
} else {
265-
parsedProps = bobParseChildProps(props.trace);
266-
traces.push(new Trace(parsedProps));
268+
}
267269
}
268270
return traces;
269271
}
@@ -276,16 +278,18 @@ function bobParseTraces(props: any): Trace[] {
276278
function bobParseYAxes(props: any): Axis[] {
277279
const axes: Axis[] = [];
278280
let parsedProps = {};
279-
// If only once axis, we are passed an object instead
280-
// of an array
281-
if (props.y_axis.length > 1) {
282-
props.y_axis.forEach((axis: any) => {
283-
parsedProps = bobParseChildProps(axis);
281+
if (props) {
282+
// If only once axis, we are passed an object instead
283+
// of an array
284+
if (props.y_axis.length > 1) {
285+
props.y_axis.forEach((axis: any) => {
286+
parsedProps = bobParseChildProps(axis);
287+
axes.push(new Axis(parsedProps));
288+
});
289+
} else {
290+
parsedProps = bobParseChildProps(props.y_axis);
284291
axes.push(new Axis(parsedProps));
285-
});
286-
} else {
287-
parsedProps = bobParseChildProps(props.y_axis);
288-
axes.push(new Axis(parsedProps));
292+
}
289293
}
290294
return axes;
291295
}
@@ -508,7 +512,7 @@ export function parseBob(
508512
rules: (rules: Rule[]): Rule[] =>
509513
opiParseRules(rules, defaultProtocol, false),
510514
traces: (props: ElementCompact) => bobParseTraces(props["traces"]),
511-
yAxes: (props: ElementCompact) => bobParseYAxes(props["y_axes"])
515+
axes: (props: ElementCompact) => bobParseYAxes(props["y_axes"])
512516
};
513517

514518
const displayWidget = parseWidget(

src/ui/widgets/EmbeddedDisplay/opiParser.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,9 @@ $(trace_0_y_pv_value)</tooltip>
404404
it("parses xygraph widget", (): void => {
405405
const widget = parseOpi(xygraphString, "ca", PREFIX)
406406
.children?.[0] as WidgetDescription;
407-
expect(widget.traces.count).toEqual(1);
408-
expect(widget.axes.count).toEqual(3);
409-
expect(widget.traces.traceOptions[0].bufferSize).toEqual(65536);
410-
expect(widget.axes.axisOptions[2].leftBottomSide).toEqual(false);
407+
expect(widget.traces.length).toEqual(1);
408+
expect(widget.axes.length).toEqual(3);
409+
expect(widget.traces[0].bufferSize).toEqual(65536);
410+
expect(widget.axes[2].onRight).toEqual(true);
411411
});
412412
});

src/ui/widgets/EmbeddedDisplay/opiParser.ts

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import {
1212
AbsolutePosition,
1313
RelativePosition
1414
} from "../../../types/position";
15-
import { Traces, Trace } from "../../../types/traces";
16-
import { Axes, Axis } from "../../../types/axes";
15+
import { Trace } from "../../../types/trace";
16+
import { Axis } from "../../../types/axis";
1717
import {
1818
ComplexParserDict,
1919
ParserDict,
@@ -484,7 +484,7 @@ function opiParseLabelPosition(props: any): string {
484484
* @param props list of props for this element
485485
* @returns a Traces object
486486
*/
487-
function opiParseTraces(props: any): Traces {
487+
function opiParseTraces(props: any): Trace[] {
488488
// Find PV value if it's one of the trace properties
489489
let pvName = opiParseString(props.pv_name);
490490
if (pvName.includes("trace_")) {
@@ -494,10 +494,13 @@ function opiParseTraces(props: any): Traces {
494494
const traces: Trace[] = [];
495495
// Parse all of the 'trace' properties
496496
for (let i = 0; i < count; i++) {
497-
const trace = parseMultipleNamedProps("trace", props, new Trace(i));
497+
const trace = new Trace({
498+
fromOpi: true,
499+
...parseMultipleNamedProps(`trace_${i}`, props)
500+
});
498501
traces.push(trace);
499502
}
500-
return new Traces(count, pvName, traces);
503+
return traces;
501504
}
502505

503506
/**
@@ -506,15 +509,18 @@ function opiParseTraces(props: any): Traces {
506509
* @param props
507510
* @returns an Axes object.
508511
*/
509-
function opiParseAxes(props: any): Axes {
512+
function opiParseAxes(props: any): Axis[] {
510513
const count = opiParseNumber(props.axis_count);
511514
const axes: Axis[] = [];
512515
// Parse all of the 'axis' properties
513516
for (let i = 0; i < count; i++) {
514-
const axis = parseMultipleNamedProps("axis", props, new Axis(i));
517+
const axis = new Axis({
518+
fromOpi: true,
519+
...parseMultipleNamedProps(`axis_${i}`, props)
520+
});
515521
axes.push(axis);
516522
}
517-
return new Axes(count, axes);
523+
return axes;
518524
}
519525

520526
/**
@@ -526,28 +532,24 @@ function opiParseAxes(props: any): Axes {
526532
* @param idx number to search for in prop names
527533
* @returns object containing parsed props
528534
*/
529-
function parseMultipleNamedProps(name: string, props: any, obj: any) {
535+
function parseMultipleNamedProps(name: string, props: any) {
536+
const obj: { [key: string]: any } = {};
530537
// Create keyword string and search for matches
531-
const num = `${name}_${obj.index}_`;
538+
const num = `${name}_`;
532539
const names = Object.getOwnPropertyNames(props);
533540
const newProps = names.filter(s => s.includes(num));
534541
newProps.forEach(item => {
535542
// For each match, convert the name and parse
536-
const newName = snakeCaseToCamelCase(item, num.length, undefined);
543+
const newName = snakeCaseToCamelCase(item, num.length, item.length);
537544
try {
538-
if (newName) {
539-
// Get the type of the property
540-
const match = obj[newName];
541-
if (typeof match === "boolean") {
542-
obj[newName] = opiParseBoolean(props[item]);
543-
} else if (typeof match === "number") {
544-
obj[newName] = opiParseNumber(props[item]);
545-
} else if (typeof match === "string") {
546-
obj[newName] = opiParseString(props[item]);
547-
} else if (match instanceof Color) {
548-
obj[newName] = opiParseColor(props[item]);
549-
} else if (match instanceof Font) {
550-
obj[newName] = opiParseFont(props[item]);
545+
if (newName && OPI_SIMPLE_PARSERS.hasOwnProperty(newName)) {
546+
const [opiPropName, propParser] = OPI_SIMPLE_PARSERS[newName];
547+
obj[newName] = propParser(props[item]);
548+
// Some properties should be passed to more generic names
549+
if (newName === "traceColor" || newName === "axisColor") {
550+
obj.color = opiParseColor(props[opiPropName]);
551+
} else if (newName === "axisTitle") {
552+
obj.title = opiParseString(props[item]);
551553
}
552554
}
553555
} catch {
@@ -718,7 +720,19 @@ export const OPI_SIMPLE_PARSERS: ParserDict = {
718720
resize: ["resize_behaviour", opiParseResizing],
719721
labelsFromPv: ["labels_from_pv", opiParseBoolean],
720722
limitsFromPv: ["limits_from_pv", opiParseBoolean],
721-
format: ["format_type", opiParseNumber]
723+
format: ["format_type", opiParseNumber],
724+
antiAlias: ["anti_alias", opiParseBoolean],
725+
concatenateData: ["concatenate_data", opiParseBoolean],
726+
bufferSize: ["buffer_size", opiParseNumber],
727+
onRight: ["left_bottom_side", opiParseBoolean],
728+
updateMode: ["update_mode", opiParseNumber],
729+
updateDelay: ["update_delay", opiParseNumber],
730+
scaleFormat: ["scale_format", opiParseNumber],
731+
scakeFont: ["scale_font", opiParseFont],
732+
showGrid: ["show_grid", opiParseBoolean],
733+
scaleFont: ["scale_font", opiParseFont],
734+
minimum: ["minimum", opiParseNumber],
735+
maximum: ["maximum", opiParseNumber]
722736
};
723737

724738
/**

src/ui/widgets/StripChart/stripChart.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe("StripChartComponent", () => {
4545
readonly: true,
4646
pvName: "TEST:PV",
4747
traces: [new Trace()],
48-
yAxes: [new Axis()]
48+
axes: [new Axis()]
4949
};
5050

5151
beforeEach(() => {
@@ -70,7 +70,7 @@ describe("StripChartComponent", () => {
7070
new Axis({ color: Color.RED }),
7171
new Axis({ color: Color.BLUE })
7272
];
73-
render(<StripChartComponent {...defaultProps} yAxes={axes} />);
73+
render(<StripChartComponent {...defaultProps} axes={axes} />);
7474

7575
const lineChart = screen.getByTestId("line-chart");
7676
const yAxisData = JSON.parse(lineChart.getAttribute("data-yaxis") ?? "");
@@ -162,7 +162,7 @@ describe("StripChartComponent", () => {
162162

163163
test("applies log scale to y axis", () => {
164164
const axes = [new Axis({ logScale: true })];
165-
render(<StripChartComponent {...defaultProps} yAxes={axes} />);
165+
render(<StripChartComponent {...defaultProps} axes={axes} />);
166166

167167
const lineChart = screen.getByTestId("line-chart");
168168
const yAxisData = JSON.parse(lineChart.getAttribute("data-yaxis") ?? "");

src/ui/widgets/StripChart/stripChart.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import { Box, Typography } from "@mui/material";
1616
import { CurveType, LineChart, XAxis, YAxis } from "@mui/x-charts";
1717
import { Color, Font } from "../../../types";
1818
import { convertStringTimePeriod } from "../utils";
19+
import { Trace } from "../../../types/trace";
20+
import { Axis } from "../../../types/axis";
1921

2022
const MARKER_STYLES: any[] = [
2123
undefined,
@@ -28,7 +30,7 @@ const MARKER_STYLES: any[] = [
2830

2931
const StripChartProps = {
3032
traces: TracesProp,
31-
yAxes: AxesProp,
33+
axes: AxesProp,
3234
start: StringPropOpt,
3335
end: StringPropOpt,
3436
foregroundColor: ColorPropOpt,
@@ -53,8 +55,8 @@ export const StripChartComponent = (
5355
props: StripChartComponentProps
5456
): JSX.Element => {
5557
const {
56-
traces,
57-
yAxes,
58+
traces = [new Trace()],
59+
axes = [new Axis({ xAxis: false })],
5860
value,
5961
title,
6062
titleFont = new Font(),
@@ -99,7 +101,7 @@ export const StripChartComponent = (
99101
}
100102
}, [value, timePeriod]);
101103

102-
const axes: ReadonlyArray<YAxis<any>> = yAxes.map(item => {
104+
const yAxes: ReadonlyArray<YAxis<any>> = axes.map(item => {
103105
const axis = {
104106
width: 45,
105107
id: item.title,
@@ -135,7 +137,7 @@ export const StripChartComponent = (
135137
const series = traces.map(item => {
136138
const trace = {
137139
// If axis is set higher than number of axes, default to zero
138-
id: item.axis <= axes.length - 1 ? axes[item.axis].id : 0,
140+
id: item.axis <= axes.length - 1 ? yAxes[item.axis].id : 0,
139141
data: data.y,
140142
label: item.name,
141143
color: visible ? item.color.toString() : "transparent",
@@ -194,7 +196,7 @@ export const StripChartComponent = (
194196
}
195197
}}
196198
xAxis={xAxis}
197-
yAxis={axes}
199+
yAxis={yAxes}
198200
series={series}
199201
/>
200202
</Box>

0 commit comments

Comments
 (0)