lost-sia 2.0.1-alpha13 → 2.0.1-alpha14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Annotation/ui/AnnotationComponent.js +1 -1
- package/dist/Annotation/ui/atoms/DaviIcon.d.ts +1 -1
- package/dist/Canvas/Canvas.js +1 -1
- package/dist/IconButton.d.ts +25 -0
- package/dist/IconButton.js +1 -0
- package/dist/Sia.js +1 -1
- package/dist/Toolbar/ToolbarItems/AccessibilityTools.js +1 -1
- package/dist/Toolbar/ToolbarItems/AnnoToolSelector.js +1 -1
- package/dist/Toolbar/ToolbarItems/ImageToolItems/ImageLabelInput.js +1 -1
- package/dist/Toolbar/ToolbarItems/ImageTools.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/models/index.d.ts +1 -1
- package/package.json +3 -2
- package/src/AnnoExampleViewer.jsx +18 -18
- package/src/Annotation/logic/Annotation.ts +24 -24
- package/src/Annotation/ui/AnnotationComponent.tsx +89 -96
- package/src/Annotation/ui/atoms/DaviIcon.tsx +12 -22
- package/src/Annotation/ui/atoms/PolygonArea.tsx +35 -35
- package/src/Annotation/ui/tools/Point.tsx +17 -17
- package/src/Canvas/Canvas.tsx +36 -13
- package/src/Canvas/LabelInput.tsx +27 -34
- package/src/IconButton.tsx +119 -0
- package/src/InfoBoxes/AnnoDetails.jsx +53 -53
- package/src/InfoBoxes/AnnoStats.jsx +41 -41
- package/src/InfoBoxes/InfoBox.jsx +16 -16
- package/src/InfoBoxes/LabelInfo.jsx +30 -30
- package/src/SIASettingButton.jsx +25 -25
- package/src/Sia.tsx +29 -12
- package/src/Toolbar/Toolbar.tsx +25 -25
- package/src/Toolbar/ToolbarItems/AccessibilityTools.tsx +23 -43
- package/src/Toolbar/ToolbarItems/AnnoToolSelector.tsx +53 -43
- package/src/Toolbar/ToolbarItems/ImageToolItems/ImageLabelInput.tsx +71 -71
- package/src/Toolbar/ToolbarItems/ImageToolItems/TagLabel.tsx +24 -24
- package/src/Toolbar/ToolbarItems/ImageTools.tsx +28 -30
- package/src/Toolbar/ToolbarItems/Instructions.tsx +47 -50
- package/src/Toolbar/ToolbarItems/InstructionsModal.tsx +8 -8
- package/src/index.ts +1 -0
- package/src/models/AnnotationMode.ts +1 -1
- package/src/models/AnnotationStatus.ts +1 -1
- package/src/models/AnnotationTool.ts +1 -1
- package/src/models/CanvasAction.ts +1 -1
- package/src/models/Direction.ts +1 -1
- package/src/models/EditorModes.ts +1 -1
- package/src/models/KeyAction.ts +1 -1
- package/src/models/NotificationType.ts +1 -1
- package/src/models/index.ts +6 -12
- package/src/siaDummyData.js +71 -71
- package/src/stories/Button.jsx +11 -15
- package/src/stories/Button.stories.js +17 -17
- package/src/stories/Canvas/CanvasWithOffset.stories.tsx +25 -25
- package/src/stories/FilterDropdown.stories.ts +10 -10
- package/src/stories/Header.jsx +8 -13
- package/src/stories/Header.stories.js +9 -9
- package/src/stories/Page.jsx +21 -26
- package/src/stories/Page.stories.js +14 -14
- package/src/stories/SIA2/DemoWrapper.stories.tsx +22 -22
- package/src/stories/Toolbar/ImageTools/TagLabel.stories.tsx +11 -11
- package/src/stories/Toolbar/Instructions.stories.tsx +11 -11
- package/src/stories/Toolbar/Toolbar.stories.tsx +20 -20
- package/src/stories/siaDummyData.js +71 -71
- package/src/stories/siaDummyData2.ts +72 -72
- package/src/types.ts +47 -47
- package/src/utils/KeyMapper.ts +56 -61
- package/src/utils/TimeUtils.ts +7 -10
- package/src/utils/color.ts +25 -25
- package/src/utils/hist.js +22 -22
- package/src/utils/index.ts +3 -3
- package/src/utils/keyActions.js +81 -81
- package/src/utils/mouse.ts +9 -9
- package/src/utils/transform.ts +66 -72
- package/src/utils/uiConfig.js +19 -22
- package/src/utils/windowViewport.ts +10 -10
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState } from
|
|
1
|
+
import { useState } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
CDropdown,
|
|
4
4
|
CDropdownMenu,
|
|
@@ -7,17 +7,17 @@ import {
|
|
|
7
7
|
CDropdownDivider,
|
|
8
8
|
CDropdownToggle,
|
|
9
9
|
CPopover,
|
|
10
|
-
} from
|
|
11
|
-
import { Label } from
|
|
10
|
+
} from '@coreui/react'
|
|
11
|
+
import { Label } from '../types'
|
|
12
12
|
|
|
13
13
|
type LabelInputProps = {
|
|
14
|
-
defaultLabelId?: number
|
|
15
|
-
isVisible: boolean
|
|
16
|
-
selectedLabelsIds: number[]
|
|
17
|
-
possibleLabels: Label[]
|
|
18
|
-
isMultilabel?: boolean
|
|
19
|
-
onLabelSelect: (selectedLabelIds: number[]) => void
|
|
20
|
-
}
|
|
14
|
+
defaultLabelId?: number
|
|
15
|
+
isVisible: boolean
|
|
16
|
+
selectedLabelsIds: number[]
|
|
17
|
+
possibleLabels: Label[]
|
|
18
|
+
isMultilabel?: boolean
|
|
19
|
+
onLabelSelect: (selectedLabelIds: number[]) => void
|
|
20
|
+
}
|
|
21
21
|
|
|
22
22
|
const LabelInput = ({
|
|
23
23
|
defaultLabelId,
|
|
@@ -27,32 +27,32 @@ const LabelInput = ({
|
|
|
27
27
|
isMultilabel = false,
|
|
28
28
|
onLabelSelect,
|
|
29
29
|
}: LabelInputProps) => {
|
|
30
|
-
const [filter, setFilter] = useState(
|
|
30
|
+
const [filter, setFilter] = useState('')
|
|
31
31
|
|
|
32
32
|
const filteredLabels: Label[] = possibleLabels.filter((label: Label) =>
|
|
33
33
|
label.name.toLowerCase().includes(filter.toLowerCase()),
|
|
34
|
-
)
|
|
34
|
+
)
|
|
35
35
|
|
|
36
36
|
const updateSelectedLabels = (clickedLabel: Label) => {
|
|
37
|
-
let newLabelIds: number[] = []
|
|
37
|
+
let newLabelIds: number[] = []
|
|
38
38
|
|
|
39
39
|
if (isMultilabel) {
|
|
40
|
-
newLabelIds = [...selectedLabelsIds]
|
|
40
|
+
newLabelIds = [...selectedLabelsIds]
|
|
41
41
|
// check if item in list (get its index if so)
|
|
42
|
-
const foundIndex: number = selectedLabelsIds.indexOf(clickedLabel.id)
|
|
42
|
+
const foundIndex: number = selectedLabelsIds.indexOf(clickedLabel.id)
|
|
43
43
|
// add label if not in list, remove label if in list
|
|
44
|
-
if (foundIndex !== -1) newLabelIds.splice(foundIndex, 1)
|
|
45
|
-
else newLabelIds.push(clickedLabel.id)
|
|
44
|
+
if (foundIndex !== -1) newLabelIds.splice(foundIndex, 1)
|
|
45
|
+
else newLabelIds.push(clickedLabel.id)
|
|
46
46
|
}
|
|
47
47
|
// single-label: just replace list with clicked item
|
|
48
|
-
else newLabelIds = [clickedLabel.id]
|
|
48
|
+
else newLabelIds = [clickedLabel.id]
|
|
49
49
|
|
|
50
|
-
onLabelSelect(newLabelIds)
|
|
51
|
-
}
|
|
50
|
+
onLabelSelect(newLabelIds)
|
|
51
|
+
}
|
|
52
52
|
|
|
53
53
|
const defaultLabel: Label | undefined = defaultLabelId
|
|
54
54
|
? possibleLabels.find((label: Label) => label.id === defaultLabelId)
|
|
55
|
-
: undefined
|
|
55
|
+
: undefined
|
|
56
56
|
|
|
57
57
|
return (
|
|
58
58
|
<>
|
|
@@ -63,13 +63,9 @@ const LabelInput = ({
|
|
|
63
63
|
<div style={{ marginLeft: 80 }} />
|
|
64
64
|
</CPopover>
|
|
65
65
|
|
|
66
|
-
<CDropdown
|
|
67
|
-
visible={isVisible}
|
|
68
|
-
autoClose={false}
|
|
69
|
-
style={{ marginTop: -25 }}
|
|
70
|
-
>
|
|
66
|
+
<CDropdown visible={isVisible} autoClose={false} style={{ marginTop: -25 }}>
|
|
71
67
|
{/* this invisible toggle has to be here, othervise the menu is not showing as intended */}
|
|
72
|
-
<CDropdownToggle style={{ display:
|
|
68
|
+
<CDropdownToggle style={{ display: 'none' }} />
|
|
73
69
|
<CDropdownMenu>
|
|
74
70
|
<div className="px-3 py-2">
|
|
75
71
|
<CFormInput
|
|
@@ -82,10 +78,7 @@ const LabelInput = ({
|
|
|
82
78
|
<CDropdownDivider />
|
|
83
79
|
{filteredLabels.length > 0 ? (
|
|
84
80
|
filteredLabels.map((label: Label) => (
|
|
85
|
-
<CDropdownItem
|
|
86
|
-
key={label.id}
|
|
87
|
-
onClick={() => updateSelectedLabels(label)}
|
|
88
|
-
>
|
|
81
|
+
<CDropdownItem key={label.id} onClick={() => updateSelectedLabels(label)}>
|
|
89
82
|
{label.name}
|
|
90
83
|
</CDropdownItem>
|
|
91
84
|
))
|
|
@@ -95,7 +88,7 @@ const LabelInput = ({
|
|
|
95
88
|
</CDropdownMenu>
|
|
96
89
|
</CDropdown>
|
|
97
90
|
</>
|
|
98
|
-
)
|
|
99
|
-
}
|
|
91
|
+
)
|
|
92
|
+
}
|
|
100
93
|
|
|
101
|
-
export default LabelInput
|
|
94
|
+
export default LabelInput
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { faSync, IconDefinition } from '@fortawesome/free-solid-svg-icons'
|
|
2
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
3
|
+
import { CButton, CTooltip } from '@coreui/react'
|
|
4
|
+
import { CSSProperties } from 'react'
|
|
5
|
+
import { SizeProp } from '@fortawesome/fontawesome-svg-core'
|
|
6
|
+
|
|
7
|
+
type IconButtonProps = {
|
|
8
|
+
loadingSize?: SizeProp
|
|
9
|
+
isLoading?: boolean
|
|
10
|
+
margin?: number
|
|
11
|
+
icon?: IconDefinition
|
|
12
|
+
text?: string
|
|
13
|
+
size?: 'sm' | 'lg' | undefined
|
|
14
|
+
isTextLeft?: boolean
|
|
15
|
+
style?: CSSProperties
|
|
16
|
+
id?: string
|
|
17
|
+
type?: 'button' | 'submit' | 'reset' | undefined
|
|
18
|
+
disabled?: boolean
|
|
19
|
+
onClick?: () => void
|
|
20
|
+
className?: string
|
|
21
|
+
color?: string
|
|
22
|
+
isOutline?: boolean
|
|
23
|
+
tooltip?: string
|
|
24
|
+
ttipPlacement?: 'top' | 'left' | 'right' | 'auto' | 'bottom' | undefined
|
|
25
|
+
shape?: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const IconButton = ({
|
|
29
|
+
loadingSize = '1x',
|
|
30
|
+
isLoading = false,
|
|
31
|
+
margin = 5,
|
|
32
|
+
icon,
|
|
33
|
+
text = '',
|
|
34
|
+
size,
|
|
35
|
+
isTextLeft = false,
|
|
36
|
+
style = {},
|
|
37
|
+
id = undefined,
|
|
38
|
+
type = 'button',
|
|
39
|
+
disabled = false,
|
|
40
|
+
onClick,
|
|
41
|
+
className = '',
|
|
42
|
+
color = 'primary',
|
|
43
|
+
isOutline = true,
|
|
44
|
+
tooltip = '',
|
|
45
|
+
ttipPlacement = 'top',
|
|
46
|
+
shape = '',
|
|
47
|
+
}: IconButtonProps) => {
|
|
48
|
+
const iconButtonIcon: IconDefinition | undefined = icon
|
|
49
|
+
|
|
50
|
+
const buttonVariant: 'ghost' | 'outline' | undefined = isOutline ? 'outline' : undefined
|
|
51
|
+
|
|
52
|
+
const renderContent = () => {
|
|
53
|
+
if (isLoading) {
|
|
54
|
+
return (
|
|
55
|
+
<div className="flex justify-center items-center">
|
|
56
|
+
<FontAwesomeIcon
|
|
57
|
+
className="mr-3"
|
|
58
|
+
size={loadingSize || '2x'}
|
|
59
|
+
icon={faSync}
|
|
60
|
+
spin
|
|
61
|
+
/>
|
|
62
|
+
<span className="text-center">Loading</span>
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
const ic =
|
|
67
|
+
iconButtonIcon && iconButtonIcon.iconName && iconButtonIcon.prefix ? (
|
|
68
|
+
<FontAwesomeIcon key="icon" icon={iconButtonIcon} size={loadingSize || '2x'} />
|
|
69
|
+
) : null
|
|
70
|
+
const iconButtonText = text ? (
|
|
71
|
+
<span key="text" style={{ marginLeft: margin, marginRight: margin }}>
|
|
72
|
+
{text}
|
|
73
|
+
</span>
|
|
74
|
+
) : null
|
|
75
|
+
if (isTextLeft) {
|
|
76
|
+
return [iconButtonText, ic]
|
|
77
|
+
}
|
|
78
|
+
return [ic, iconButtonText]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// because visible=false does not seem to work...
|
|
82
|
+
if (tooltip != '') {
|
|
83
|
+
return (
|
|
84
|
+
<CTooltip content={tooltip} placement={ttipPlacement}>
|
|
85
|
+
<CButton
|
|
86
|
+
id={id}
|
|
87
|
+
size={size}
|
|
88
|
+
// type={type}
|
|
89
|
+
className={className}
|
|
90
|
+
style={style}
|
|
91
|
+
variant={buttonVariant}
|
|
92
|
+
disabled={disabled || isLoading}
|
|
93
|
+
onClick={onClick}
|
|
94
|
+
color={disabled || isLoading ? 'secondary' : color}
|
|
95
|
+
shape={shape}
|
|
96
|
+
>
|
|
97
|
+
{renderContent()}
|
|
98
|
+
</CButton>
|
|
99
|
+
</CTooltip>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<CButton
|
|
105
|
+
size={size}
|
|
106
|
+
type={type}
|
|
107
|
+
className={className}
|
|
108
|
+
style={style}
|
|
109
|
+
variant={buttonVariant}
|
|
110
|
+
disabled={disabled || isLoading}
|
|
111
|
+
onClick={onClick}
|
|
112
|
+
color={disabled || isLoading ? 'secondary' : color}
|
|
113
|
+
>
|
|
114
|
+
{renderContent()}
|
|
115
|
+
</CButton>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export default IconButton
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef } from
|
|
2
|
-
import { List, TextArea, Form, Label, Icon } from
|
|
3
|
-
import InfoBox from
|
|
4
|
-
import PopUp from
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react'
|
|
2
|
+
import { List, TextArea, Form, Label, Icon } from 'semantic-ui-react'
|
|
3
|
+
import InfoBox from './InfoBox'
|
|
4
|
+
import PopUp from '../SiaPopup'
|
|
5
5
|
|
|
6
6
|
const AnnoDetails = (props) => {
|
|
7
|
-
const [comment, setComment] = useState(
|
|
8
|
-
const [example, setExample] = useState(false)
|
|
9
|
-
const [showSaveBtn, setShowSaveBtn] = useState(false)
|
|
10
|
-
const tARef = useRef()
|
|
7
|
+
const [comment, setComment] = useState('')
|
|
8
|
+
const [example, setExample] = useState(false)
|
|
9
|
+
const [showSaveBtn, setShowSaveBtn] = useState(false)
|
|
10
|
+
const tARef = useRef()
|
|
11
11
|
useEffect(() => {
|
|
12
12
|
if (props.anno) {
|
|
13
13
|
if (props.anno.comment) {
|
|
14
|
-
setComment(props.anno.comment)
|
|
14
|
+
setComment(props.anno.comment)
|
|
15
15
|
} else {
|
|
16
|
-
setComment(
|
|
16
|
+
setComment('')
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
}, [props.anno])
|
|
19
|
+
}, [props.anno])
|
|
20
20
|
|
|
21
21
|
useEffect(() => {
|
|
22
22
|
if (tARef.current) {
|
|
23
|
-
tARef.current.focus()
|
|
23
|
+
tARef.current.focus()
|
|
24
24
|
}
|
|
25
|
-
}, [props.commentInputTrigger])
|
|
25
|
+
}, [props.commentInputTrigger])
|
|
26
26
|
|
|
27
27
|
const onDismiss = () => {
|
|
28
28
|
if (props.onDismiss) {
|
|
29
|
-
props.onDismiss()
|
|
29
|
+
props.onDismiss()
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
32
|
|
|
33
33
|
const onCommentUpdate = () => {
|
|
34
34
|
if (props.onCommentUpdate) {
|
|
35
|
-
props.onCommentUpdate(comment)
|
|
35
|
+
props.onCommentUpdate(comment)
|
|
36
36
|
}
|
|
37
|
-
setShowSaveBtn(false)
|
|
38
|
-
}
|
|
37
|
+
setShowSaveBtn(false)
|
|
38
|
+
}
|
|
39
39
|
|
|
40
40
|
const onMarkExampleClick = () => {
|
|
41
41
|
// setExample(!example)
|
|
42
42
|
if (props.onMarkExample) {
|
|
43
|
-
props.onMarkExample(props.anno)
|
|
43
|
+
props.onMarkExample(props.anno)
|
|
44
44
|
}
|
|
45
|
-
}
|
|
45
|
+
}
|
|
46
46
|
|
|
47
47
|
const renderSaveBtn = () => {
|
|
48
48
|
if (showSaveBtn) {
|
|
49
|
-
return <Label as="a" corner="right" icon="save" color="red"></Label
|
|
49
|
+
return <Label as="a" corner="right" icon="save" color="red"></Label>
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|
|
52
52
|
|
|
53
53
|
const renderComment = () => {
|
|
54
54
|
return (
|
|
@@ -66,36 +66,36 @@ const AnnoDetails = (props) => {
|
|
|
66
66
|
></TextArea>
|
|
67
67
|
</Form>
|
|
68
68
|
</div>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
71
|
const renderLabels = () => {
|
|
72
72
|
if (props.anno) {
|
|
73
|
-
const selectedLabelIds = props.anno.labelIds
|
|
74
|
-
if (!selectedLabelIds) return
|
|
73
|
+
const selectedLabelIds = props.anno.labelIds
|
|
74
|
+
if (!selectedLabelIds) return 'No Label'
|
|
75
75
|
|
|
76
|
-
let lbls =
|
|
76
|
+
let lbls = ''
|
|
77
77
|
props.anno.labelIds.forEach((lbl, idx) => {
|
|
78
78
|
const labelObject = props.possibleLabels.find((el) => {
|
|
79
|
-
return el.id === lbl
|
|
80
|
-
})
|
|
81
|
-
if (idx > 0) lbls +=
|
|
82
|
-
lbls += labelObject.label
|
|
83
|
-
})
|
|
84
|
-
if (!lbls) return
|
|
85
|
-
return lbls
|
|
79
|
+
return el.id === lbl
|
|
80
|
+
})
|
|
81
|
+
if (idx > 0) lbls += ', '
|
|
82
|
+
lbls += labelObject.label
|
|
83
|
+
})
|
|
84
|
+
if (!lbls) return 'No Label'
|
|
85
|
+
return lbls
|
|
86
86
|
} else {
|
|
87
|
-
return
|
|
87
|
+
return 'No Label'
|
|
88
88
|
}
|
|
89
|
-
}
|
|
89
|
+
}
|
|
90
90
|
|
|
91
91
|
const renderExampleMark = () => {
|
|
92
|
-
if (!props.allowedToMarkExample) return null
|
|
93
|
-
let color =
|
|
94
|
-
let iconName =
|
|
92
|
+
if (!props.allowedToMarkExample) return null
|
|
93
|
+
let color = 'grey'
|
|
94
|
+
let iconName = 'bookmark outline'
|
|
95
95
|
if (props.anno) {
|
|
96
96
|
if (props.anno.isExample) {
|
|
97
|
-
color =
|
|
98
|
-
iconName =
|
|
97
|
+
color = 'yellow'
|
|
98
|
+
iconName = 'bookmark'
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
const mark = (
|
|
@@ -106,19 +106,19 @@ const AnnoDetails = (props) => {
|
|
|
106
106
|
size="medium"
|
|
107
107
|
corner="left"
|
|
108
108
|
onClick={() => {
|
|
109
|
-
onMarkExampleClick()
|
|
109
|
+
onMarkExampleClick()
|
|
110
110
|
}}
|
|
111
111
|
>
|
|
112
112
|
<Icon name={iconName} />
|
|
113
113
|
</Label>
|
|
114
|
-
)
|
|
114
|
+
)
|
|
115
115
|
return (
|
|
116
116
|
<PopUp
|
|
117
117
|
content="Mark this annotation as example for other annotators"
|
|
118
118
|
trigger={mark}
|
|
119
119
|
/>
|
|
120
|
-
)
|
|
121
|
-
}
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
122
|
|
|
123
123
|
const renderDescription = () => {
|
|
124
124
|
if (props.anno) {
|
|
@@ -136,7 +136,7 @@ const AnnoDetails = (props) => {
|
|
|
136
136
|
<List.Item icon="tag" content={renderLabels()} />
|
|
137
137
|
<List.Item
|
|
138
138
|
icon="time"
|
|
139
|
-
content={`${props.anno.annoTime.toLocaleString(
|
|
139
|
+
content={`${props.anno.annoTime.toLocaleString('us', {
|
|
140
140
|
minimumFractionDigits: 2,
|
|
141
141
|
maximumFractionDigits: 2,
|
|
142
142
|
})} seconds`}
|
|
@@ -145,21 +145,21 @@ const AnnoDetails = (props) => {
|
|
|
145
145
|
</List>
|
|
146
146
|
{renderComment()}
|
|
147
147
|
</div>
|
|
148
|
-
)
|
|
148
|
+
)
|
|
149
149
|
} else {
|
|
150
|
-
return
|
|
150
|
+
return 'No annotation selected!'
|
|
151
151
|
}
|
|
152
|
-
}
|
|
152
|
+
}
|
|
153
153
|
|
|
154
154
|
return (
|
|
155
155
|
<InfoBox
|
|
156
|
-
header={
|
|
156
|
+
header={'Annotation Details'}
|
|
157
157
|
content={renderDescription()}
|
|
158
158
|
visible={props.visible}
|
|
159
159
|
defaultPos={props.defaultPos}
|
|
160
160
|
onDismiss={(e) => onDismiss()}
|
|
161
161
|
/>
|
|
162
|
-
)
|
|
163
|
-
}
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
164
|
|
|
165
|
-
export default AnnoDetails
|
|
165
|
+
export default AnnoDetails
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import React, { useState, useEffect } from
|
|
2
|
-
import { List, Label } from
|
|
3
|
-
import InfoBox from
|
|
4
|
-
import * as colorlut from
|
|
1
|
+
import React, { useState, useEffect } from 'react'
|
|
2
|
+
import { List, Label } from 'semantic-ui-react'
|
|
3
|
+
import InfoBox from './InfoBox'
|
|
4
|
+
import * as colorlut from '../utils/color'
|
|
5
5
|
// import actions from '../../../../actions'
|
|
6
6
|
// import * as transform from '../utils/transform'
|
|
7
7
|
// const { siaShowImgBar } = actions
|
|
8
8
|
|
|
9
9
|
const AnnoStats = (props) => {
|
|
10
|
-
const [hideList, setHideList] = useState([])
|
|
10
|
+
const [hideList, setHideList] = useState([])
|
|
11
11
|
|
|
12
12
|
useEffect(() => {
|
|
13
|
-
setHideList([])
|
|
14
|
-
}, [props.imgLoadCount])
|
|
13
|
+
setHideList([])
|
|
14
|
+
}, [props.imgLoadCount])
|
|
15
15
|
|
|
16
16
|
const onDismiss = () => {
|
|
17
17
|
if (props.onDismiss) {
|
|
18
|
-
props.onDismiss()
|
|
18
|
+
props.onDismiss()
|
|
19
19
|
}
|
|
20
|
-
}
|
|
20
|
+
}
|
|
21
21
|
|
|
22
22
|
const onLblClick = (lbl) => {
|
|
23
|
-
let hideLbl = false
|
|
23
|
+
let hideLbl = false
|
|
24
24
|
if (hideList.includes(lbl.id)) {
|
|
25
|
-
setHideList(hideList.filter((e) => e !== lbl.id))
|
|
26
|
-
hideLbl = false
|
|
25
|
+
setHideList(hideList.filter((e) => e !== lbl.id))
|
|
26
|
+
hideLbl = false
|
|
27
27
|
} else {
|
|
28
28
|
// hideList.push(lbl.id)
|
|
29
|
-
setHideList([...hideList, lbl.id])
|
|
30
|
-
hideLbl = true
|
|
29
|
+
setHideList([...hideList, lbl.id])
|
|
30
|
+
hideLbl = true
|
|
31
31
|
}
|
|
32
32
|
if (props.onHideLbl) {
|
|
33
|
-
props.onHideLbl(lbl, hideLbl)
|
|
33
|
+
props.onHideLbl(lbl, hideLbl)
|
|
34
34
|
}
|
|
35
|
-
}
|
|
35
|
+
}
|
|
36
36
|
|
|
37
37
|
const renderRow = (s) => {
|
|
38
|
-
const opacity = hideList.includes(s.id) ? 0.5 : 1.0
|
|
38
|
+
const opacity = hideList.includes(s.id) ? 0.5 : 1.0
|
|
39
39
|
return (
|
|
40
40
|
<List.Item key={s.id}>
|
|
41
41
|
<List.Content>
|
|
@@ -50,57 +50,57 @@ const AnnoStats = (props) => {
|
|
|
50
50
|
</Label>
|
|
51
51
|
</List.Content>
|
|
52
52
|
</List.Item>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
55
|
|
|
56
56
|
const renderRows = () => {
|
|
57
|
-
let stats = {}
|
|
57
|
+
let stats = {}
|
|
58
58
|
props.annos.forEach((a) => {
|
|
59
59
|
// // console.log('render rows', a)
|
|
60
|
-
if (a.status !==
|
|
60
|
+
if (a.status !== 'deleted') {
|
|
61
61
|
a.labelIds.forEach((lblId) => {
|
|
62
62
|
if (lblId in stats) {
|
|
63
|
-
stats[lblId] += 1
|
|
63
|
+
stats[lblId] += 1
|
|
64
64
|
} else {
|
|
65
|
-
stats[lblId] = 1
|
|
65
|
+
stats[lblId] = 1
|
|
66
66
|
}
|
|
67
|
-
})
|
|
67
|
+
})
|
|
68
68
|
if (a.labelIds.length === 0) {
|
|
69
69
|
if ((-1) in stats) {
|
|
70
|
-
stats[-1] += 1
|
|
70
|
+
stats[-1] += 1
|
|
71
71
|
} else {
|
|
72
|
-
stats[-1] = 1
|
|
72
|
+
stats[-1] = 1
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
})
|
|
76
|
+
})
|
|
77
77
|
const res = Object.entries(stats).map(([key, value]) => {
|
|
78
78
|
let lbl = props.possibleLabels.find((e) => {
|
|
79
|
-
return e.id === parseInt(key)
|
|
80
|
-
})
|
|
79
|
+
return e.id === parseInt(key)
|
|
80
|
+
})
|
|
81
81
|
if (!lbl) {
|
|
82
|
-
lbl = { id: -1, label:
|
|
82
|
+
lbl = { id: -1, label: 'No Label', color: colorlut.getDefaultColor() }
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
lbl.amount = value
|
|
85
|
+
lbl.amount = value
|
|
86
86
|
// return renderRow({class:idToLbl[key], amount:value, color:idToColor[key]})
|
|
87
|
-
return renderRow(lbl)
|
|
88
|
-
})
|
|
89
|
-
return res
|
|
90
|
-
}
|
|
87
|
+
return renderRow(lbl)
|
|
88
|
+
})
|
|
89
|
+
return res
|
|
90
|
+
}
|
|
91
91
|
const renderDescription = () => {
|
|
92
|
-
return <List>{renderRows()}</List
|
|
93
|
-
}
|
|
92
|
+
return <List>{renderRows()}</List>
|
|
93
|
+
}
|
|
94
94
|
|
|
95
95
|
return (
|
|
96
96
|
<InfoBox
|
|
97
|
-
header={
|
|
97
|
+
header={'Annotations per Label'}
|
|
98
98
|
content={renderDescription()}
|
|
99
99
|
visible={props.visible}
|
|
100
100
|
defaultPos={props.defaultPos}
|
|
101
101
|
onDismiss={(e) => onDismiss()}
|
|
102
102
|
/>
|
|
103
|
-
)
|
|
104
|
-
}
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
105
|
|
|
106
|
-
export default AnnoStats
|
|
106
|
+
export default AnnoStats
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
import React, { Component } from
|
|
2
|
-
import { Header, Message } from
|
|
3
|
-
import Draggable from
|
|
1
|
+
import React, { Component } from 'react'
|
|
2
|
+
import { Header, Message } from 'semantic-ui-react'
|
|
3
|
+
import Draggable from 'react-draggable'
|
|
4
4
|
|
|
5
5
|
class InfoBox extends Component {
|
|
6
6
|
constructor(props) {
|
|
7
|
-
super(props)
|
|
7
|
+
super(props)
|
|
8
8
|
this.state = {
|
|
9
9
|
style: {
|
|
10
|
-
position:
|
|
10
|
+
position: 'fixed',
|
|
11
11
|
top: 200,
|
|
12
12
|
left: 200,
|
|
13
13
|
width: 250,
|
|
14
14
|
},
|
|
15
|
-
}
|
|
15
|
+
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
componentDidMount() {
|
|
19
|
-
this.updateStyle()
|
|
19
|
+
this.updateStyle()
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
componentDidUpdate(prevProps) {
|
|
23
23
|
if (this.props.defaultPos !== prevProps.defaultPos) {
|
|
24
|
-
this.updateStyle()
|
|
24
|
+
this.updateStyle()
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
handleOnStop(e) {
|
|
29
29
|
if (this.props.onStop) {
|
|
30
|
-
this.props.onStop(e)
|
|
30
|
+
this.props.onStop(e)
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
updateStyle() {
|
|
35
35
|
this.setState({
|
|
36
36
|
style: { ...this.state.style, ...this.props.defaultPos },
|
|
37
|
-
})
|
|
37
|
+
})
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
onDismiss(e) {
|
|
41
41
|
if (this.props.onDismiss) {
|
|
42
|
-
this.props.onDismiss(e)
|
|
42
|
+
this.props.onDismiss(e)
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
render() {
|
|
47
|
-
if (!this.props.visible) return null
|
|
47
|
+
if (!this.props.visible) return null
|
|
48
48
|
return (
|
|
49
49
|
<Draggable handle=".handle" onStop={(e) => this.handleOnStop(e)}>
|
|
50
50
|
<div style={this.state.style}>
|
|
51
51
|
<Message
|
|
52
52
|
style={{ opacity: 0.98 }}
|
|
53
53
|
onDismiss={(e) => {
|
|
54
|
-
this.onDismiss(e)
|
|
54
|
+
this.onDismiss(e)
|
|
55
55
|
}}
|
|
56
56
|
size="small"
|
|
57
57
|
>
|
|
@@ -59,7 +59,7 @@ class InfoBox extends Component {
|
|
|
59
59
|
textAlign="center"
|
|
60
60
|
as="h5"
|
|
61
61
|
className="handle"
|
|
62
|
-
style={{ cursor:
|
|
62
|
+
style={{ cursor: 'grab' }}
|
|
63
63
|
>
|
|
64
64
|
{this.props.header}
|
|
65
65
|
</Header>
|
|
@@ -69,8 +69,8 @@ class InfoBox extends Component {
|
|
|
69
69
|
</Message>
|
|
70
70
|
</div>
|
|
71
71
|
</Draggable>
|
|
72
|
-
)
|
|
72
|
+
)
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export default InfoBox
|
|
76
|
+
export default InfoBox
|