Skip to content

Commit 2b396f0

Browse files
authored
fix: FIT-1327: Correct MultiChannel margin logic to align x-axis (#9296)
Co-authored-by: bmartel <bmartel@users.noreply.github.com>
1 parent a0e4c20 commit 2b396f0

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

web/libs/editor/src/tags/object/TimeSeries/MultiChannel.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ const Model = types
4545
},
4646

4747
get margin() {
48+
// If Y axis is hidden, we don't need to consider it for margin calculation
49+
if (!self.showyaxis) return self.parent?.margin;
50+
4851
const channelsWithYAxis = self.channels.filter((channel) => channel.showaxis && channel.showyaxis);
4952
if (channelsWithYAxis.length > 1) {
5053
return {

web/libs/editor/tests/integration/e2e/timeseries/multichannel.cy.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,46 @@ describe("MultiChannel", () => {
129129
cy.log("Channel visibility toggling works correctly");
130130
});
131131
});
132+
it("should align MultiChannel x-axis with standard Channel", () => {
133+
// Config with one outside channel for comparison and MultiChannel with showYAxis=false
134+
const config = multiChannwlCnfig.replace(
135+
"<MultiChannel>",
136+
'<Channel column="velocity" legend="Standalone"/><MultiChannel showYAxis="false">',
137+
);
138+
139+
cy.log("Initialize MultiChannel TimeSeries for alignment reproduction");
140+
LabelStudio.params().config(config).data(multiChannelSampleData).withResult([]).init();
141+
142+
LabelStudio.waitForObjectsReady();
143+
TimeSeries.waitForReady();
144+
145+
// Verify paths are present
146+
TimeSeries.paths.should("have.length.greaterThan", 0);
147+
148+
// Get the first plot (Sensor A / Standalone)
149+
cy.get(".htx-timeseries-channel:not(.htx-timeseries-multichannel *) path")
150+
.first()
151+
.then(($pathA) => {
152+
const d_A = $pathA.attr("d");
153+
const firstPointA_X = Number.parseFloat(d_A.substring(1).split(",")[0]);
154+
155+
// Get the path for channel inside MultiChannel
156+
cy.get(".htx-timeseries-multichannel path")
157+
.first()
158+
.then(($pathB) => {
159+
const d_B = $pathB.attr("d");
160+
const firstPointB_X = Number.parseFloat(d_B.substring(1).split(",")[0]);
161+
162+
cy.log(`Sensor A First Point X: ${firstPointA_X}`);
163+
cy.log(`Sensor B First Point X: ${firstPointB_X}`);
164+
165+
if (Math.abs(firstPointB_X - firstPointA_X) > 1) {
166+
console.error(`Mismatch! A: ${firstPointA_X}, B: ${firstPointB_X}`);
167+
}
168+
169+
// Tolerance of 1px
170+
expect(firstPointB_X, `Mismatch! A: ${firstPointA_X}, B: ${firstPointB_X}`).to.be.closeTo(firstPointA_X, 1);
171+
});
172+
});
173+
});
132174
});

0 commit comments

Comments
 (0)