Skip to content
This repository was archived by the owner on Apr 18, 2024. It is now read-only.

Commit 3116fcb

Browse files
Gondragosmakseqhlomzik
authored
DEV-1373: Fix relations over brushes (#398)
* Add test for relations over brashes * [fix] Fix crash on restoration relations over brushes * [fix] Fix calculating brush bbox after restoration * Fix test code missing * Limit events from resize observer Co-authored-by: Max Tkachenko <[email protected]> Co-authored-by: hlomzik <[email protected]>
1 parent d0fbf45 commit 3116fcb

File tree

5 files changed

+134
-3
lines changed

5 files changed

+134
-3
lines changed

e2e/fragments/AtSidebar.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ module.exports = {
2424
I.dontSee("Regions", this._sideBarLocator);
2525
}
2626
},
27+
seeRelations(count) {
28+
I.see(`Relations (${count})`, this._sideBarLocator);
29+
},
30+
dontSeeRelations() {
31+
I.dontSee(`Relations`, this._sideBarLocator);
32+
},
2733
seeSelectedRegion() {
2834
I.seeElement(this._selectedRegionsLocator);
2935
},
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* global Feature, DataTable, Data, locate, Scenario */
2+
const assert = require("assert");
3+
4+
Feature("Brush relations").tag("@regress");
5+
6+
const IMAGE = "https://user.fm/files/v2-901310d5cb3fa90e0616ca10590bacb3/spacexmoon-800x501.jpg";
7+
8+
const config = `<View>
9+
<Image name="img" value="$image"></Image>
10+
<BrushLabels name="tag" toName="img">
11+
<Label value="Test" background="orange"></Label>
12+
</BrushLabels>
13+
</View>`;
14+
15+
function getPointAtSpiral(t, v , w) {
16+
return { x: v * t * Math.cos(w * t), y: v * t * Math.sin(w * t) };
17+
}
18+
19+
function generateSpiralPoints(x0, y0, R, v , w) {
20+
let t = 1, x, y;
21+
const points = [];
22+
23+
do {
24+
({ x, y } = getPointAtSpiral(t++, v, w));
25+
points.push([x + x0, y + y0]);
26+
} while (x ** 2 + y ** 2 < R ** 2);
27+
return points;
28+
}
29+
30+
Scenario("Brush relations shouldn't crash everything", async ({ I, LabelStudio, AtImageView, AtSidebar, ErrorsCollector }) => {
31+
const params = {
32+
config,
33+
data: { image: IMAGE },
34+
};
35+
36+
I.amOnPage("/");
37+
await ErrorsCollector.run();
38+
LabelStudio.init(params);
39+
AtImageView.waitForImage();
40+
AtSidebar.seeRegions(0);
41+
await AtImageView.lookForStage();
42+
const canvasSize = await AtImageView.getCanvasSize();
43+
const regionsCentralPoints = [];
44+
45+
// create 4 brush regions
46+
for (let i = 0; i < 4; i++) {
47+
// find start position
48+
const x = canvasSize.width / 4 * ((i % 2) * 2 + 1);
49+
const y = canvasSize.height / 4 * ((Math.floor(i / 2) % 2) * 2 + 1);
50+
// generate points in a spiral
51+
const points = generateSpiralPoints(x, y, Math.min(canvasSize.width / 6, canvasSize.height / 6), .4, Math.PI / 18);
52+
53+
// select the brush label
54+
I.pressKey("1");
55+
// draw a brush region
56+
AtImageView.drawThroughPoints(points);
57+
AtSidebar.seeRegions(i+1);
58+
// unselect the region
59+
I.pressKey("u");
60+
// save the central point
61+
regionsCentralPoints.push({ x, y });
62+
}
63+
64+
// Check that we can create a relation between the brush regions
65+
{
66+
// switch to the move tool for easy region selecting
67+
I.pressKey("v");
68+
// select the first region
69+
AtImageView.clickAt(regionsCentralPoints[0].x, regionsCentralPoints[0].y);
70+
// create relation to the second region
71+
I.pressKey(["alt", "r"]);
72+
AtImageView.clickAt(regionsCentralPoints[1].x, regionsCentralPoints[1].y);
73+
// check that the relation has been created
74+
AtSidebar.seeRelations(1);
75+
}
76+
77+
// Check that relations work fine on a brush restoration (from rle)
78+
{
79+
// export annotation
80+
const annotation = await LabelStudio.serialize();
81+
82+
// reload LS with that datalabel studio logo
83+
LabelStudio.init({
84+
...params,
85+
annotations: [{ id: "imported", result: annotation }],
86+
});
87+
88+
AtImageView.waitForImage();
89+
// Check that relation still exist
90+
AtSidebar.seeRelations(1);
91+
92+
// Try to create new relation with restored regions
93+
{
94+
// switch to the move tool for easy region selecting
95+
I.pressKey("v");
96+
// select the third region
97+
AtImageView.clickAt(regionsCentralPoints[2].x, regionsCentralPoints[2].y);
98+
// create relation to the fourth region
99+
I.pressKey(["alt", "r"]);
100+
AtImageView.clickAt(regionsCentralPoints[3].x, regionsCentralPoints[3].y);
101+
// check that the relation has been created
102+
AtSidebar.seeRelations(2);
103+
}
104+
105+
// Check the we didn't get any errors
106+
const errors = await ErrorsCollector.grabErrors();
107+
108+
if (errors.length) {
109+
assert.fail(`Got an error: ${errors[0]}`);
110+
}
111+
}
112+
});

src/common/TimeAgo/TimeAgo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function getNextTick(passedTime = 0) {
2626
}
2727

2828
type TimeAgoProps = React.ComponentPropsWithoutRef<"time"> & {
29-
date: number | string | Date
29+
date: number | string | Date,
3030
}
3131

3232
export const TimeAgo = ({ date, ...rest }: TimeAgoProps) => {

src/components/RelationsOverlay/BoundingBox.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ const _detect = region => {
138138
}
139139
case "brushregion": {
140140
// If there is no imageData we just wait for the next render
141-
return region.imageData && imageRelatedBBox(
141+
const bbox = region.imageData && Geometry.getImageDataBBox(region.imageData.data, region.imageData.width, region.imageData.height);
142+
143+
return bbox && imageRelatedBBox(
142144
region,
143145
Geometry.getImageDataBBox(region.imageData.data, region.imageData.width, region.imageData.height),
144146
);

src/regions/BrushRegion.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,18 @@ const HtxBrushView = ({ item }) => {
525525
highlightedImageRef.current.src = dataUrl;
526526
done = true;
527527
};
528-
}, [item.touches.length, item.strokeColor, item.parent.stageScale, store.annotationStore.selected?.id, item.parent?.zoomingPositionX, item.parent?.zoomingPositionY, item.parent?.stageWidth, item.parent?.stageHeight]);
528+
}, [
529+
item.touches.length,
530+
item.strokeColor,
531+
item.parent.stageScale,
532+
store.annotationStore.selected?.id,
533+
item.parent?.zoomingPositionX,
534+
item.parent?.zoomingPositionY,
535+
item.parent?.stageWidth,
536+
item.parent?.stageHeight,
537+
item.rle,
538+
image,
539+
]);
529540

530541
if (!item.parent) return null;
531542

0 commit comments

Comments
 (0)