lost-sia 3.2.0-alpha0 → 3.2.0

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.
Files changed (54) hide show
  1. package/dist/Canvas/Canvas.js +1 -1
  2. package/dist/Canvas/LabelInput.js +1 -1
  3. package/dist/Sia.js +1 -1
  4. package/dist/Toolbar/ToolbarItems/ImageToolItems/ImageLabelInput.d.ts +2 -1
  5. package/dist/Toolbar/ToolbarItems/ImageToolItems/ImageLabelInput.js +1 -1
  6. package/dist/Toolbar/ToolbarItems/ImageToolItems/TagLabel.d.ts +2 -1
  7. package/dist/Toolbar/ToolbarItems/ImageToolItems/TagLabel.js +1 -1
  8. package/dist/Toolbar/ToolbarItems/ImageTools.js +1 -1
  9. package/dist/assets/SIA-CoOqcT1a.css +1 -0
  10. package/dist/assets/brand-icons-Cu_C0hZ4.svg +1008 -0
  11. package/dist/assets/brand-icons-F3SPCeH1.woff +0 -0
  12. package/dist/assets/brand-icons-XL9sxUpA.woff2 +0 -0
  13. package/dist/assets/brand-icons-sqJ2Pg7a.eot +0 -0
  14. package/dist/assets/brand-icons-ubhWoxly.ttf +0 -0
  15. package/dist/assets/flags-DOLqOU7Y.png +0 -0
  16. package/dist/assets/icons-BOCtAERH.woff +0 -0
  17. package/dist/assets/icons-CHzK1VD9.eot +0 -0
  18. package/dist/assets/icons-D29ZQHHw.ttf +0 -0
  19. package/dist/assets/icons-Du6TOHnR.woff2 +0 -0
  20. package/dist/assets/icons-RwhydX30.svg +1518 -0
  21. package/dist/assets/node_modules/semantic-ui-css/semantic.min-09YPtVE6.css +1 -0
  22. package/dist/assets/outline-icons-BfdLr8tr.svg +366 -0
  23. package/dist/assets/outline-icons-DD8jm0uy.ttf +0 -0
  24. package/dist/assets/outline-icons-DInHoiqI.woff2 +0 -0
  25. package/dist/assets/outline-icons-LX8adJ4n.eot +0 -0
  26. package/dist/assets/outline-icons-aQ88nltS.woff +0 -0
  27. package/dist/index.d.ts +0 -1
  28. package/dist/index.js +1 -1
  29. package/dist/stories/Canvas/Canvas.stories.d.ts +3 -3
  30. package/dist/stories/Canvas/CanvasWithOffset.stories.d.ts +6 -6
  31. package/dist/stories/Toolbar/ImageTools/TagLabel.stories.d.ts +2 -1
  32. package/package.json +4 -3
  33. package/src/AnnoExampleViewer.jsx +69 -0
  34. package/src/Canvas/Canvas.tsx +45 -17
  35. package/src/Canvas/LabelInput.tsx +11 -9
  36. package/src/InfoBoxes/AnnoDetails.jsx +165 -0
  37. package/src/InfoBoxes/AnnoStats.jsx +106 -0
  38. package/src/InfoBoxes/InfoBox.jsx +76 -0
  39. package/src/InfoBoxes/InfoBoxArea.jsx +152 -0
  40. package/src/InfoBoxes/LabelInfo.jsx +107 -0
  41. package/src/SIA.scss +13 -0
  42. package/src/SIASettingButton.jsx +126 -0
  43. package/src/Sia.tsx +70 -54
  44. package/src/Toolbar/ToolbarItems/ImageToolItems/ImageLabelInput.tsx +74 -24
  45. package/src/Toolbar/ToolbarItems/ImageToolItems/TagLabel.tsx +33 -0
  46. package/src/Toolbar/ToolbarItems/ImageTools.tsx +1 -0
  47. package/src/index.ts +1 -1
  48. package/src/stories/exampleData/exampleExternalAnnotations.ts +22 -22
  49. package/dist/SiaViewer.d.ts +0 -19
  50. package/dist/SiaViewer.js +0 -1
  51. package/dist/assets/SIA-BV1tYu3P.css +0 -1
  52. package/dist/stories/SIA/SiaViewer.stories.d.ts +0 -52
  53. package/src/SiaViewer.tsx +0 -125
  54. package/src/stories/SIA/SiaViewer.stories.tsx +0 -105
@@ -1,4 +1,5 @@
1
- import { useState } from 'react'
1
+ import { useState, useRef, useCallback } from 'react'
2
+ import React from 'react'
2
3
  import {
3
4
  CDropdown,
4
5
  CDropdownMenu,
@@ -11,11 +12,13 @@ import {
11
12
  import { Label } from '../../../types'
12
13
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
13
14
  import { faTag } from '@fortawesome/free-solid-svg-icons'
15
+ import { IconProps } from 'semantic-ui-react'
14
16
  import TagLabel from './TagLabel'
15
17
 
16
18
  type ImageLabelInputProps = {
17
19
  isDisabled: boolean
18
20
  isVisible: boolean
21
+ isFullscreen?: boolean
19
22
  selectedLabelsIds: number[] | undefined
20
23
  possibleLabels: Label[]
21
24
  isMultilabel?: boolean
@@ -25,12 +28,30 @@ type ImageLabelInputProps = {
25
28
  const ImageLabelInput = ({
26
29
  isDisabled,
27
30
  isVisible,
31
+ isFullscreen = false,
28
32
  selectedLabelsIds,
29
33
  possibleLabels,
30
34
  isMultilabel = false,
31
35
  onLabelSelect,
32
36
  }: ImageLabelInputProps) => {
33
37
  const [filter, setFilter] = useState('')
38
+ const tagElRef = useRef<HTMLDivElement | null>(null)
39
+ const tagHandlerRef = useRef<((e: WheelEvent) => void) | null>(null)
40
+ const tagScrollRef = useCallback((el: HTMLDivElement | null) => {
41
+ // cleanup previous listener
42
+ if (tagElRef.current && tagHandlerRef.current) {
43
+ tagElRef.current.removeEventListener('wheel', tagHandlerRef.current)
44
+ }
45
+ tagElRef.current = el
46
+ tagHandlerRef.current = null
47
+ if (!el) return
48
+ const handler = (e: WheelEvent) => {
49
+ e.preventDefault()
50
+ el.scrollLeft += e.deltaY * 0.2
51
+ }
52
+ tagHandlerRef.current = handler
53
+ el.addEventListener('wheel', handler, { passive: false })
54
+ }, [])
34
55
 
35
56
  const filteredLabels: Label[] = possibleLabels.filter((label: Label) =>
36
57
  label.name.toLowerCase().includes(filter.toLowerCase()),
@@ -67,22 +88,41 @@ const ImageLabelInput = ({
67
88
  const renderLabels = () => {
68
89
  if (!selectedLabelsIds || selectedLabelsIds.length === 0)
69
90
  return (
70
- <div style={{ marginTop: 6 }}>
71
- <FontAwesomeIcon icon={faTag} />
91
+ <div>
92
+ <FontAwesomeIcon icon={faTag as IconProps} />
72
93
  </div>
73
94
  )
74
95
 
75
96
  const selectedLabels = getSelectedLabels()
76
- return selectedLabels.map((label: Label) => (
77
- <TagLabel
78
- key={label.name}
79
- name={label.name}
80
- color={label.color}
81
- size={25}
82
- triangleSize={17}
83
- style={{ marginLeft: 1, marginTop: 5 }}
84
- />
85
- ))
97
+ return (
98
+ <div
99
+ ref={tagScrollRef}
100
+ style={
101
+ {
102
+ display: 'flex',
103
+ flexWrap: 'nowrap',
104
+ overflowX: 'auto',
105
+ maxWidth: isFullscreen ? '500px' : '300px',
106
+ alignItems: 'center',
107
+ gap: '10px',
108
+ scrollbarWidth: 'thin',
109
+ } as React.CSSProperties
110
+ }
111
+ className="tag-scroll"
112
+ >
113
+ {selectedLabels.map((label: Label) => (
114
+ <TagLabel
115
+ key={label.name}
116
+ name={label.name}
117
+ color={label.color}
118
+ size={25}
119
+ triangleSize={17}
120
+ style={{ flexShrink: 0 }}
121
+ onRemove={() => updateSelectedLabels(label)}
122
+ />
123
+ ))}
124
+ </div>
125
+ )
86
126
  }
87
127
 
88
128
  return (
@@ -93,12 +133,12 @@ const ImageLabelInput = ({
93
133
  variant="outline"
94
134
  caret={false}
95
135
  color={isDisabled ? 'secondary' : 'primary'}
96
- style={{ paddingTop: 0, paddingBottom: 0 }}
136
+ // style={{ paddingTop: 0, paddingBottom: 0 }}
97
137
  as="div"
98
138
  >
99
139
  {renderLabels()}
100
140
  </CDropdownToggle>
101
- <CDropdownMenu>
141
+ <CDropdownMenu as="div" style={{ padding: 0 }}>
102
142
  <div className="px-3 py-2">
103
143
  <CFormInput
104
144
  placeholder="Filter label..."
@@ -108,15 +148,25 @@ const ImageLabelInput = ({
108
148
  />
109
149
  </div>
110
150
  <CDropdownDivider />
111
- {filteredLabels.length > 0 ? (
112
- filteredLabels.map((label: Label) => (
113
- <CDropdownItem key={label.id} onClick={() => updateSelectedLabels(label)}>
114
- {label.name}
115
- </CDropdownItem>
116
- ))
117
- ) : (
118
- <CDropdownItem disabled>No results</CDropdownItem>
119
- )}
151
+ <div style={{ maxHeight: '200px', overflowY: 'auto' }}>
152
+ {filteredLabels.length > 0 ? (
153
+ filteredLabels.map((label: Label) => {
154
+ const isSelected = selectedLabelsIds?.includes(label.id)
155
+
156
+ return (
157
+ <CDropdownItem
158
+ key={label.id}
159
+ onClick={() => updateSelectedLabels(label)}
160
+ active={isSelected}
161
+ >
162
+ {label.name}
163
+ </CDropdownItem>
164
+ )
165
+ })
166
+ ) : (
167
+ <CDropdownItem disabled>No results</CDropdownItem>
168
+ )}
169
+ </div>
120
170
  </CDropdownMenu>
121
171
  </CDropdown>
122
172
  </CTooltip>
@@ -1,4 +1,7 @@
1
1
  import type { CSSProperties } from 'react'
2
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3
+ import { faXmark } from '@fortawesome/free-solid-svg-icons'
4
+ import { IconProps } from 'semantic-ui-react'
2
5
 
3
6
  type TagLabelProps = {
4
7
  name: string
@@ -7,6 +10,7 @@ type TagLabelProps = {
7
10
  style?: CSSProperties
8
11
  triangleSize?: number
9
12
  onClick?: () => void
13
+ onRemove?: () => void
10
14
  }
11
15
 
12
16
  const TagLabel = ({
@@ -16,6 +20,7 @@ const TagLabel = ({
16
20
  style = {},
17
21
  triangleSize = 22,
18
22
  onClick,
23
+ onRemove,
19
24
  }: TagLabelProps) => {
20
25
  const containerStyle: CSSProperties = {
21
26
  display: 'inline-flex',
@@ -50,6 +55,34 @@ const TagLabel = ({
50
55
  <button style={containerStyle} onClick={onClick}>
51
56
  <span style={triangleStyle} />
52
57
  {name}
58
+ {onRemove && (
59
+ <span
60
+ role="button"
61
+ tabIndex={0}
62
+ onClick={(e) => {
63
+ e.stopPropagation()
64
+ onRemove()
65
+ }}
66
+ onKeyDown={(e) => {
67
+ if (e.key === 'Enter' || e.key === ' ') {
68
+ e.stopPropagation()
69
+ onRemove()
70
+ }
71
+ }}
72
+ style={{
73
+ marginLeft: '6px',
74
+ cursor: 'pointer',
75
+ opacity: 0.6,
76
+ fontSize: `${bodySize * 0.4}px`,
77
+ lineHeight: 1,
78
+ display: 'inline-flex',
79
+ alignItems: 'center',
80
+ }}
81
+ aria-label="Remove tag"
82
+ >
83
+ <FontAwesomeIcon icon={faXmark as IconProps} />
84
+ </span>
85
+ )}
53
86
  </button>
54
87
  )
55
88
  }
@@ -41,6 +41,7 @@ const ImageTools = ({
41
41
  <ImageLabelInput
42
42
  isDisabled={isDisabled}
43
43
  isMultilabel={true}
44
+ isFullscreen={isFullscreen}
44
45
  isVisible={isLabelPopupVisible}
45
46
  selectedLabelsIds={imageLabelIds}
46
47
  possibleLabels={possibleLabels}
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import 'semantic-ui-css/semantic.min.css'
1
2
  import './SIA.scss'
2
3
 
3
4
  // export all type definitions
@@ -5,6 +6,5 @@ export * from './types'
5
6
 
6
7
  export { default as IconButton } from './IconButton'
7
8
  export { default as Sia } from './Sia'
8
- export { default as SiaViewer } from './SiaViewer'
9
9
  export { default as transform } from './utils/transform'
10
10
  export { default as TagLabel } from './Toolbar/ToolbarItems/ImageToolItems/TagLabel'
@@ -37,10 +37,10 @@ const point: ExternalAnnotation[] = [
37
37
  const line: ExternalAnnotation[] = [
38
38
  {
39
39
  coordinates: [
40
- { x: 0.05, y: 0.05 },
41
- { x: 0.2, y: 0.1 },
42
- { x: 0.25, y: 0.1 },
43
- { x: 0.25, y: 0.2 },
40
+ { x: 50, y: 50 },
41
+ { x: 200, y: 100 },
42
+ { x: 250, y: 100 },
43
+ { x: 250, y: 200 },
44
44
  ],
45
45
  labelIds: [5],
46
46
  type: AnnotationTool.Line,
@@ -48,11 +48,11 @@ const line: ExternalAnnotation[] = [
48
48
  },
49
49
  {
50
50
  coordinates: [
51
- { x: 0.26, y: 0.3 },
52
- { x: 0.35, y: 0.33 },
53
- { x: 0.36, y: 0.32 },
54
- { x: 0.37, y: 0.3 },
55
- { x: 0.27, y: 0.25 },
51
+ { x: 259.883, y: 300.424 },
52
+ { x: 350, y: 331.5263919270834 },
53
+ { x: 355, y: 320 },
54
+ { x: 370, y: 300 },
55
+ { x: 270, y: 250 },
56
56
  ],
57
57
  labelIds: [8, 11],
58
58
  type: AnnotationTool.Line,
@@ -63,8 +63,8 @@ const line: ExternalAnnotation[] = [
63
63
  const bbox: ExternalAnnotation[] = [
64
64
  {
65
65
  coordinates: [
66
- { x: 0.05, y: 0.05 },
67
- { x: 0.2, y: 0.2 },
66
+ { x: 50, y: 50 },
67
+ { x: 200, y: 200 },
68
68
  ],
69
69
  labelIds: [5],
70
70
  type: AnnotationTool.BBox,
@@ -72,8 +72,8 @@ const bbox: ExternalAnnotation[] = [
72
72
  },
73
73
  {
74
74
  coordinates: [
75
- { x: 0.25, y: 0.1 },
76
- { x: 0.45, y: 0.15 },
75
+ { x: 250, y: 100 },
76
+ { x: 450, y: 150 },
77
77
  ],
78
78
  labelIds: [8, 11],
79
79
  type: AnnotationTool.BBox,
@@ -84,10 +84,10 @@ const bbox: ExternalAnnotation[] = [
84
84
  const polygon: ExternalAnnotation[] = [
85
85
  {
86
86
  coordinates: [
87
- { x: 0.05, y: 0.05 },
88
- { x: 0.2, y: 0.1 },
89
- { x: 0.25, y: 0.1 },
90
- { x: 0.25, y: 0.2 },
87
+ { x: 50, y: 50 },
88
+ { x: 200, y: 100 },
89
+ { x: 250, y: 100 },
90
+ { x: 250, y: 200 },
91
91
  ],
92
92
  labelIds: [5],
93
93
  status: AnnotationStatus.LOADED,
@@ -95,11 +95,11 @@ const polygon: ExternalAnnotation[] = [
95
95
  },
96
96
  {
97
97
  coordinates: [
98
- { x: 0.26, y: 0.3 },
99
- { x: 0.35, y: 0.33 },
100
- { x: 0.36, y: 0.32 },
101
- { x: 0.37, y: 0.3 },
102
- { x: 0.27, y: 0.25 },
98
+ { x: 259.883, y: 300.424 },
99
+ { x: 350, y: 331.5263919270834 },
100
+ { x: 355, y: 320 },
101
+ { x: 370, y: 300 },
102
+ { x: 270, y: 250 },
103
103
  ],
104
104
  labelIds: [8, 11],
105
105
  status: AnnotationStatus.LOADED,
@@ -1,19 +0,0 @@
1
- import { default as Annotation } from './Annotation/logic/Annotation';
2
- import { ExternalAnnotation, Label, UiConfig } from './types';
3
- type SiaViewerProps = {
4
- image: string;
5
- annotations?: ExternalAnnotation[];
6
- possibleLabels: Label[];
7
- isJunk?: boolean;
8
- uiConfig?: Partial<UiConfig>;
9
- enableZoom?: boolean;
10
- canSelect?: boolean;
11
- onSelectAnnotation?: (annotation?: Annotation) => void;
12
- };
13
- /**
14
- * View-only SIA component. Renders image + annotations without a toolbar and
15
- * blocks all mutations (create / edit / delete / label). Zoom and selection
16
- * can be toggled via props.
17
- */
18
- declare const SiaViewer: ({ image, annotations: propAnnotations, possibleLabels, isJunk, uiConfig: propUiConfig, enableZoom, canSelect, onSelectAnnotation, }: SiaViewerProps) => import("react/jsx-runtime").JSX.Element;
19
- export default SiaViewer;
package/dist/SiaViewer.js DELETED
@@ -1 +0,0 @@
1
- import{jsx as r}from"react/jsx-runtime";import{useState as s,useEffect as c}from"react";import p from"./Canvas/Canvas.js";import N from"./models/AnnotationMode.js";import h from"./models/AnnotationTool.js";const E={canCreate:!1,canEdit:!1,canLabel:!1,canHaveMultipleLabels:!1},f={nodeRadius:4,strokeWidth:4,imageCentered:!1},y={flex:"1 1 auto",minHeight:0,display:"flex",flexDirection:"column"},H=({image:n,annotations:e,possibleLabels:u,isJunk:m=!1,uiConfig:a,enableZoom:A=!0,canSelect:l=!0,onSelectAnnotation:I=()=>{}})=>{const[S,d]=s([]),[T,t]=s(),[C,g]=s(f);return c(()=>{if(n===void 0||e===void 0){d([]),t(void 0);return}let o=0;const v=e.map(i=>({...i,internalId:o++,mode:N.VIEW,selectedNode:1,status:i.status,annoTime:i.annoTime??0}));d(v),t(void 0)},[e,n]),c(()=>{g({...f,...a})},[a]),r("div",{style:y,onWheelCapture:o=>{A||o.stopPropagation()},children:r(p,{annotations:S,annotationSettings:E,image:n,isImageJunk:m,isPolygonSelectionMode:!1,possibleLabels:u,selectedAnnotation:l?T:void 0,selectedAnnoTool:h.Point,uiConfig:C,onAnnoCreated:()=>{},onAnnoChanged:()=>{},onAnnoCreationFinished:()=>{},onAnnoEditing:()=>{},onNotification:()=>{},onRequestNewAnnoId:()=>0,onSelectAnnotation:l?o=>{t(o),I(o)}:()=>{},onSetIsImageJunk:()=>{},onSetSelectedTool:()=>{},onShouldDeleteAnno:()=>{},onTraverseAnnotationHistory:()=>{}})})};export{H as default};
@@ -1 +0,0 @@
1
- .sia-fullscreen{position:fixed;top:0;left:0;z-index:6000;width:100%;height:100%;background-color:#fff}
@@ -1,52 +0,0 @@
1
- import { StoryObj } from '@storybook/react';
2
- export declare const ActionsData: {};
3
- declare const meta: {
4
- title: string;
5
- component: ({ image, annotations: propAnnotations, possibleLabels, isJunk, uiConfig: propUiConfig, enableZoom, canSelect, onSelectAnnotation, }: {
6
- image: string;
7
- annotations?: import('../..').ExternalAnnotation[];
8
- possibleLabels: import('../..').Label[];
9
- isJunk?: boolean;
10
- uiConfig?: Partial<import('../..').UiConfig>;
11
- enableZoom?: boolean;
12
- canSelect?: boolean;
13
- onSelectAnnotation?: (annotation?: import('../../models').Annotation) => void;
14
- }) => import("react/jsx-runtime").JSX.Element;
15
- parameters: {
16
- layout: string;
17
- };
18
- tags: string[];
19
- excludeStories: RegExp;
20
- args: {};
21
- };
22
- export default meta;
23
- type Story = StoryObj<typeof meta>;
24
- /**
25
- * SiaViewer with point annotations. No toolbar, no editing.
26
- * Try clicking annotations to select them and scrolling to zoom.
27
- */
28
- export declare const WithPointAnnotations: Story;
29
- /**
30
- * SiaViewer with bbox annotations.
31
- */
32
- export declare const WithBBoxAnnotations: Story;
33
- /**
34
- * SiaViewer with line annotations.
35
- */
36
- export declare const WithLineAnnotations: Story;
37
- /**
38
- * SiaViewer with polygon annotations.
39
- */
40
- export declare const WithPolygonAnnotations: Story;
41
- /**
42
- * SiaViewer with zoom disabled.
43
- */
44
- export declare const ZoomDisabled: Story;
45
- /**
46
- * SiaViewer with selection disabled. Annotations cannot be clicked.
47
- */
48
- export declare const SelectionDisabled: Story;
49
- /**
50
- * SiaViewer marked as junk.
51
- */
52
- export declare const Junk: Story;
package/src/SiaViewer.tsx DELETED
@@ -1,125 +0,0 @@
1
- import { CSSProperties, useEffect, useState, WheelEvent } from 'react'
2
- import Canvas from './Canvas/Canvas'
3
- import Annotation from './Annotation/logic/Annotation'
4
- import AnnotationMode from './models/AnnotationMode'
5
- import AnnotationTool from './models/AnnotationTool'
6
- import { AnnotationSettings, ExternalAnnotation, Label, UiConfig } from './types'
7
-
8
- type SiaViewerProps = {
9
- image: string
10
- annotations?: ExternalAnnotation[]
11
- possibleLabels: Label[]
12
- isJunk?: boolean
13
- uiConfig?: Partial<UiConfig>
14
- enableZoom?: boolean
15
- canSelect?: boolean
16
- onSelectAnnotation?: (annotation?: Annotation) => void
17
- }
18
-
19
- const VIEW_ANNOTATION_SETTINGS: AnnotationSettings = {
20
- canCreate: false,
21
- canEdit: false,
22
- canLabel: false,
23
- canHaveMultipleLabels: false,
24
- }
25
-
26
- const DEFAULT_UI_CONFIG: UiConfig = {
27
- nodeRadius: 4,
28
- strokeWidth: 4,
29
- imageCentered: false,
30
- }
31
-
32
- const containerStyle: CSSProperties = {
33
- flex: '1 1 auto',
34
- minHeight: 0,
35
- display: 'flex',
36
- flexDirection: 'column',
37
- }
38
-
39
- /**
40
- * View-only SIA component. Renders image + annotations without a toolbar and
41
- * blocks all mutations (create / edit / delete / label). Zoom and selection
42
- * can be toggled via props.
43
- */
44
- const SiaViewer = ({
45
- image,
46
- annotations: propAnnotations,
47
- possibleLabels,
48
- isJunk = false,
49
- uiConfig: propUiConfig,
50
- enableZoom = true,
51
- canSelect = true,
52
- onSelectAnnotation = () => {},
53
- }: SiaViewerProps) => {
54
- const [annotations, setAnnotations] = useState<Annotation[]>([])
55
- const [selectedAnnotation, setSelectedAnnotation] = useState<
56
- Annotation | undefined
57
- >()
58
- const [uiConfig, setUiConfig] = useState<UiConfig>(DEFAULT_UI_CONFIG)
59
-
60
- // (re)initialize annotations whenever the annotations or image prop changes
61
- useEffect(() => {
62
- if (image === undefined || propAnnotations === undefined) {
63
- setAnnotations([])
64
- setSelectedAnnotation(undefined)
65
- return
66
- }
67
-
68
- let internalId = 0
69
- const next: Annotation[] = propAnnotations.map((externalAnno) => ({
70
- ...externalAnno,
71
- internalId: internalId++,
72
- mode: AnnotationMode.VIEW,
73
- selectedNode: 1,
74
- status: externalAnno.status,
75
- annoTime: externalAnno.annoTime ?? 0,
76
- }))
77
-
78
- setAnnotations(next)
79
- setSelectedAnnotation(undefined)
80
- }, [propAnnotations, image])
81
-
82
- useEffect(() => {
83
- setUiConfig({ ...DEFAULT_UI_CONFIG, ...propUiConfig })
84
- }, [propUiConfig])
85
-
86
- const stopZoom = (e: WheelEvent) => {
87
- if (!enableZoom) e.stopPropagation()
88
- }
89
-
90
- return (
91
- <div style={containerStyle} onWheelCapture={stopZoom}>
92
- <Canvas
93
- annotations={annotations}
94
- annotationSettings={VIEW_ANNOTATION_SETTINGS}
95
- image={image}
96
- isImageJunk={isJunk}
97
- isPolygonSelectionMode={false}
98
- possibleLabels={possibleLabels}
99
- selectedAnnotation={canSelect ? selectedAnnotation : undefined}
100
- selectedAnnoTool={AnnotationTool.Point}
101
- uiConfig={uiConfig}
102
- onAnnoCreated={() => {}}
103
- onAnnoChanged={() => {}}
104
- onAnnoCreationFinished={() => {}}
105
- onAnnoEditing={() => {}}
106
- onNotification={() => {}}
107
- onRequestNewAnnoId={() => 0}
108
- onSelectAnnotation={
109
- canSelect
110
- ? (annotation) => {
111
- setSelectedAnnotation(annotation)
112
- onSelectAnnotation(annotation)
113
- }
114
- : () => {}
115
- }
116
- onSetIsImageJunk={() => {}}
117
- onSetSelectedTool={() => {}}
118
- onShouldDeleteAnno={() => {}}
119
- onTraverseAnnotationHistory={() => {}}
120
- />
121
- </div>
122
- )
123
- }
124
-
125
- export default SiaViewer
@@ -1,105 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react'
2
-
3
- import SiaViewer from '../../SiaViewer'
4
-
5
- import exampleImage from '../exampleData/exampleImage'
6
- import exampleLabels from '../exampleData/exampleLabels'
7
- import exampleExternalAnnotations from '../exampleData/exampleExternalAnnotations'
8
-
9
- export const ActionsData = {}
10
-
11
- const meta = {
12
- title: 'Components/SiaViewer',
13
- component: SiaViewer,
14
- parameters: {
15
- layout: 'fullscreen',
16
- },
17
- tags: ['!autodocs'],
18
- excludeStories: /.*Data$/,
19
- args: {
20
- ...ActionsData,
21
- },
22
- } satisfies Meta<typeof SiaViewer>
23
-
24
- export default meta
25
- type Story = StoryObj<typeof meta>
26
-
27
- const defaultArgs = {
28
- ...ActionsData,
29
- image: exampleImage,
30
- possibleLabels: exampleLabels.voc,
31
- }
32
-
33
- /**
34
- * SiaViewer with point annotations. No toolbar, no editing.
35
- * Try clicking annotations to select them and scrolling to zoom.
36
- */
37
- export const WithPointAnnotations: Story = {
38
- args: {
39
- ...defaultArgs,
40
- annotations: exampleExternalAnnotations.point,
41
- },
42
- }
43
-
44
- /**
45
- * SiaViewer with bbox annotations.
46
- */
47
- export const WithBBoxAnnotations: Story = {
48
- args: {
49
- ...defaultArgs,
50
- annotations: exampleExternalAnnotations.bbox,
51
- },
52
- }
53
-
54
- /**
55
- * SiaViewer with line annotations.
56
- */
57
- export const WithLineAnnotations: Story = {
58
- args: {
59
- ...defaultArgs,
60
- annotations: exampleExternalAnnotations.line,
61
- },
62
- }
63
-
64
- /**
65
- * SiaViewer with polygon annotations.
66
- */
67
- export const WithPolygonAnnotations: Story = {
68
- args: {
69
- ...defaultArgs,
70
- annotations: exampleExternalAnnotations.polygon,
71
- },
72
- }
73
-
74
- /**
75
- * SiaViewer with zoom disabled.
76
- */
77
- export const ZoomDisabled: Story = {
78
- args: {
79
- ...defaultArgs,
80
- annotations: exampleExternalAnnotations.polygon,
81
- enableZoom: false,
82
- },
83
- }
84
-
85
- /**
86
- * SiaViewer with selection disabled. Annotations cannot be clicked.
87
- */
88
- export const SelectionDisabled: Story = {
89
- args: {
90
- ...defaultArgs,
91
- annotations: exampleExternalAnnotations.polygon,
92
- canSelect: false,
93
- },
94
- }
95
-
96
- /**
97
- * SiaViewer marked as junk.
98
- */
99
- export const Junk: Story = {
100
- args: {
101
- ...defaultArgs,
102
- annotations: exampleExternalAnnotations.polygon,
103
- isJunk: true,
104
- },
105
- }