lost-sia 1.2.0 → 2.0.0-alpha0

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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/package.json +60 -47
  4. package/src/AnnoExampleViewer.jsx +57 -0
  5. package/src/AnnoLabelInput.jsx +99 -0
  6. package/src/AnnoToolBar.jsx +132 -0
  7. package/src/Annotation/AnnoBar.jsx +148 -0
  8. package/src/Annotation/Annotation.jsx +358 -0
  9. package/src/Annotation/Annotation.scss +47 -0
  10. package/src/Annotation/BBox.jsx +291 -0
  11. package/src/Annotation/Edge.jsx +82 -0
  12. package/src/Annotation/InfSelectionArea.jsx +71 -0
  13. package/src/Annotation/Line.jsx +60 -0
  14. package/src/Annotation/Node.jsx +278 -0
  15. package/src/Annotation/Point.jsx +196 -0
  16. package/src/Annotation/Polygon.jsx +361 -0
  17. package/src/Canvas.jsx +1839 -0
  18. package/src/ImgBar.jsx +123 -0
  19. package/src/InfoBoxes/AnnoDetails.jsx +166 -0
  20. package/src/InfoBoxes/AnnoStats.jsx +104 -0
  21. package/src/InfoBoxes/InfoBox.jsx +78 -0
  22. package/src/InfoBoxes/InfoBoxArea.jsx +155 -0
  23. package/src/InfoBoxes/LabelInfo.jsx +95 -0
  24. package/src/LabelInput.jsx +224 -0
  25. package/src/Prompt.jsx +46 -0
  26. package/src/SIA.scss +10 -0
  27. package/src/SIAFilterButton.jsx +178 -0
  28. package/src/SIASettingButton.jsx +122 -0
  29. package/src/Sia.jsx +485 -0
  30. package/src/SiaPopup.jsx +10 -0
  31. package/src/ToolBar.jsx +399 -0
  32. package/src/Toolbar.css +13 -0
  33. package/src/ToolbarItem.jsx +25 -0
  34. package/src/filterTools.js +3 -0
  35. package/src/index.js +17 -0
  36. package/src/siaDummyData.js +265 -0
  37. package/src/test.js +7 -0
  38. package/src/types/annoStatus.js +4 -0
  39. package/src/types/canvasActions.js +57 -0
  40. package/src/types/cursorstyles.js +3 -0
  41. package/src/types/modes.js +8 -0
  42. package/src/types/notificationType.js +4 -0
  43. package/src/types/toolbarEvents.js +33 -0
  44. package/src/types/tools.js +11 -0
  45. package/src/utils/annoConversion.js +115 -0
  46. package/src/utils/colorlut.js +67 -0
  47. package/src/utils/constraints.js +75 -0
  48. package/src/utils/hist.js +67 -0
  49. package/src/utils/keyActions.js +107 -0
  50. package/src/utils/mouse.js +14 -0
  51. package/src/utils/siaIcons.jsx +95 -0
  52. package/src/utils/transform.js +318 -0
  53. package/src/utils/uiConfig.js +57 -0
  54. package/src/utils/windowViewport.js +35 -0
  55. package/CHANGELOG.md +0 -163
  56. package/dist/index.css +0 -24823
  57. package/dist/index.es.js +0 -10431
  58. package/dist/index.es.js.map +0 -1
  59. package/dist/index.js +0 -10446
  60. package/dist/index.js.map +0 -1
@@ -0,0 +1,358 @@
1
+ import React, { Component } from 'react'
2
+
3
+ import AnnoBar from './AnnoBar'
4
+ import Point from './Point'
5
+ import BBox from './BBox'
6
+ import Line from './Line'
7
+ import Polygon from './Polygon'
8
+ import * as modes from '../types/modes'
9
+ import * as canvasActions from '../types/canvasActions'
10
+ import * as annoStatus from '../types/annoStatus'
11
+ import * as colorlut from '../utils/colorlut'
12
+ import * as constraints from '../utils/constraints'
13
+ import * as transform from '../utils/transform'
14
+ import * as notificationType from '../types/notificationType'
15
+
16
+ class Annotation extends Component {
17
+
18
+ constructor(props) {
19
+ super(props)
20
+ this.state = {
21
+ // mode: modes.VIEW,
22
+ selAreaCss: 'sel-area-off',
23
+ visibility: 'visible',
24
+ anno: undefined
25
+ }
26
+ this.myAnno = React.createRef()
27
+
28
+ }
29
+
30
+ componentWillMount() {
31
+ this.setState({ anno: { ...this.props.data } })
32
+ }
33
+
34
+ componentDidUpdate(prevProps) {
35
+ if (prevProps.data !== this.props.data) {
36
+ this.setState({ anno: { ...this.props.data } })
37
+ }
38
+ if (prevProps.showSingleAnno !== this.props.showSingleAnno) {
39
+ if (this.props.showSingleAnno === undefined) {
40
+ this.setVisible(true)
41
+ } else {
42
+ if (this.props.showSingleAnno !== this.props.data.id) {
43
+ this.setVisible(false)
44
+ } else {
45
+ this.setVisible(true)
46
+ }
47
+ }
48
+ }
49
+ if (this.props.showSingleAnno === undefined) {
50
+ if (this.state.anno.visible !== undefined) {
51
+ if (this.state.anno.visible) {
52
+ this.setVisible(true)
53
+ } else {
54
+ this.setVisible(false)
55
+ }
56
+ }
57
+ }
58
+
59
+ }
60
+
61
+ /*************
62
+ * EVENTS *
63
+ **************/
64
+ onClick(e) {
65
+ e.stopPropagation()
66
+ this.performedAction(this.state.anno, canvasActions.ANNO_SELECTED)
67
+ }
68
+
69
+ onMouseDown(e) {
70
+ e.preventDefault()
71
+ if (this.props.onMouseDown) {
72
+ this.props.onMouseDown(e)
73
+ }
74
+ }
75
+
76
+ onContextMenu(e) {
77
+ e.preventDefault()
78
+ }
79
+
80
+ handleModeChangeRequest(anno, mode) {
81
+ this.setMode(anno, mode)
82
+ }
83
+
84
+ /*************
85
+ * LOGIC *
86
+ *************/
87
+
88
+ /**
89
+ * Trigger callback when this annotation performed an action
90
+ *
91
+ * @param {String} pAction
92
+ */
93
+ performedAction(anno, pAction) {
94
+
95
+ if (this.props.onAction) {
96
+ this.props.onAction(anno, pAction)
97
+ }
98
+ }
99
+
100
+
101
+ notify(messageObj) {
102
+ if (this.props.onNotification) {
103
+ this.props.onNotification(messageObj)
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Handle a performed action from a specific annotation
109
+ *
110
+ * @param {list} annoData - Annotation data that define a box, line,
111
+ * polygon, point
112
+ * @param {string} pAction - The performed action
113
+ * @param {int} selectedNode - The node of the annotation that
114
+ * was selected
115
+ */
116
+ performedAnnoAction(anno, pAction) {
117
+
118
+ switch (pAction) {
119
+ case canvasActions.ANNO_CREATED_FINAL_NODE:
120
+ case canvasActions.ANNO_EDITED:
121
+ case canvasActions.ANNO_MOVED:
122
+ case canvasActions.ANNO_CREATED:
123
+ // Check if annoation is within image bounds
124
+ const corrected = transform.correctAnnotation(anno.data, this.props.svg, this.props.imageOffset)
125
+ let newAnno = { ...anno, data: corrected }
126
+ const area = transform.getArea(corrected, this.props.svg, anno.type, this.props.image)
127
+ if (area !== undefined) {
128
+ if (area < this.props.canvasConfig.annos.minArea) {
129
+ this.notify({
130
+ title: "Annotation to small",
131
+ message: 'Annotation area was ' + Math.round(area) + 'px but needs to be bigger than ' + this.props.canvasConfig.annos.minArea + ' px',
132
+ type: notificationType.WARNING
133
+ })
134
+ // newAnno = {...newAnno, mode: modes.DELETED}
135
+ this.setMode(newAnno, modes.DELETED)
136
+ } else {
137
+ this.performedAction(newAnno, pAction)
138
+ }
139
+ } else {
140
+ this.performedAction(newAnno, pAction)
141
+ }
142
+ break
143
+ default:
144
+ this.performedAction(anno, pAction)
145
+ break
146
+ }
147
+ }
148
+
149
+ setAnnoMode(anno, mode) {
150
+ this.setState({
151
+ anno: {
152
+ ...anno,
153
+ mode: mode
154
+ }
155
+ })
156
+ }
157
+
158
+ setMode(anno, mode) {
159
+ if (anno.mode !== mode) {
160
+ switch (mode) {
161
+ case modes.EDIT_LABEL:
162
+ if (constraints.allowedToLabel(
163
+ this.props.allowedActions,
164
+ anno
165
+ )) {
166
+ this.setAnnoMode(anno, mode)
167
+ }
168
+ break
169
+ case modes.DELETED:
170
+ // if(constraints.allowedToDelete(
171
+ // this.props.allowedActions,
172
+ // anno
173
+ // )){
174
+ this.setAnnoMode(anno, mode)
175
+ const newAnno = {
176
+ ...anno,
177
+ // status: annoStatus.DELETED
178
+ mode: mode.DELETED
179
+ }
180
+ // this.setState({
181
+ // anno: newAnno
182
+ // })
183
+ this.performedAction(newAnno, canvasActions.ANNO_DELETED)
184
+ // }
185
+ break
186
+ case modes.MOVE:
187
+ this.setAnnoMode(anno, mode)
188
+ this.performedAction(anno, canvasActions.ANNO_ENTER_MOVE_MODE)
189
+ break
190
+ case modes.EDIT:
191
+ this.setAnnoMode(anno, mode)
192
+ this.performedAction(anno, canvasActions.ANNO_ENTER_EDIT_MODE)
193
+ break
194
+ default:
195
+ this.setAnnoMode(anno, mode)
196
+ break
197
+ }
198
+ }
199
+ }
200
+
201
+ setVisible(visible) {
202
+ if (visible) {
203
+ if (this.state.visibility !== 'visible') {
204
+ this.setState({ visibility: 'visible' })
205
+ }
206
+ } else {
207
+ if (this.state.visibility !== 'hidden') {
208
+ this.setState({ visibility: 'hidden' })
209
+ }
210
+ }
211
+ }
212
+
213
+ isSelected() {
214
+ if (constraints.allowedToEdit(this.props.allowedActions, this.state.anno)) {
215
+ return this.props.selectedAnno === this.props.data.id
216
+ } else {
217
+ return false
218
+ }
219
+ }
220
+
221
+ getResult() {
222
+ return {
223
+ ...this.state.anno,
224
+ data: this.myAnno.current.state.anno,
225
+ createMode: this.myAnno.current.state.mode === modes.CREATE
226
+ }
227
+ }
228
+
229
+ getLabel(lblId) {
230
+ return this.props.possibleLabels.find(e => {
231
+ return e.id === lblId
232
+ })
233
+ }
234
+
235
+ getColor() {
236
+ if (this.state.anno.labelIds && this.state.anno.labelIds.length > 0) {
237
+ return this.getLabel(this.state.anno.labelIds[0]).color
238
+ }
239
+ else {
240
+ return colorlut.getDefaultColor()
241
+ }
242
+ }
243
+
244
+ getStyle() {
245
+ const color = this.getColor()
246
+ if (this.isSelected()) {
247
+ return {
248
+ stroke: color,
249
+ fill: color,
250
+ strokeWidth: this.props.uiConfig.strokeWidth / this.props.svg.scale,
251
+ r: this.props.uiConfig.nodeRadius / this.props.svg.scale
252
+
253
+ }
254
+ } else {
255
+ return {
256
+ stroke: color,
257
+ fill: color,
258
+ strokeWidth: this.props.uiConfig.strokeWidth / this.props.svg.scale,
259
+ r: this.props.uiConfig.nodeRadius / this.props.svg.scale
260
+ }
261
+ }
262
+ }
263
+
264
+ getCssClass() {
265
+ if (this.isSelected()) {
266
+ return 'selected'
267
+ } else {
268
+ return 'not-selected'
269
+ }
270
+ }
271
+
272
+ /*************
273
+ * RENDERING *
274
+ **************/
275
+ renderAnno() {
276
+ const type = this.props.type
277
+ // const allowedToEdit = constraints.allowedToEditBounds(
278
+ // this.props.allowedActions,
279
+ // this.state.anno
280
+ // )
281
+ switch (type) {
282
+ case 'point':
283
+ return <Point ref={this.myAnno} anno={this.state.anno}
284
+ style={this.getStyle()}
285
+ className={this.getCssClass()}
286
+ isSelected={this.isSelected()}
287
+ svg={this.props.svg}
288
+ onModeChangeRequest={(anno, mode) => this.handleModeChangeRequest(anno, mode)}
289
+ onAction={(anno, pAction) => this.performedAnnoAction(anno, pAction)}
290
+ />
291
+ case 'bBox':
292
+ return <BBox ref={this.myAnno} anno={this.state.anno}
293
+ style={this.getStyle()}
294
+ className={this.getCssClass()}
295
+ onNodeClick={(e, idx) => this.onNodeClick(e, idx)}
296
+ onNodeMouseDown={(e, idx) => this.onNodeMouseDown(e, idx)}
297
+ isSelected={this.isSelected()}
298
+ svg={this.props.svg}
299
+ onModeChangeRequest={(anno, mode) => this.handleModeChangeRequest(anno, mode)}
300
+ onAction={(anno, pAction) => this.performedAnnoAction(anno, pAction)}
301
+ />
302
+ case 'polygon':
303
+ return <Polygon ref={this.myAnno} anno={this.state.anno}
304
+ style={this.getStyle()}
305
+ className={this.getCssClass()}
306
+ onNodeClick={(e, idx) => this.onNodeClick(e, idx)}
307
+ isSelected={this.isSelected()}
308
+ svg={this.props.svg}
309
+ onModeChangeRequest={(anno, mode) => this.handleModeChangeRequest(anno, mode)}
310
+ onAction={(anno, pAction) => this.performedAnnoAction(anno, pAction)}
311
+ />
312
+ case 'line':
313
+ return <Line ref={this.myAnno} anno={this.state.anno}
314
+ style={this.getStyle()}
315
+ className={this.getCssClass()}
316
+ isSelected={this.isSelected()}
317
+ svg={this.props.svg}
318
+ onAction={(anno, pAction) => this.performedAnnoAction(anno, pAction)}
319
+ onModeChangeRequest={(anno, mode) => this.handleModeChangeRequest(anno, mode)}
320
+ />
321
+ default:
322
+ console.error("Wrong annoType for annotations: ",
323
+ this.props.annoType)
324
+ }
325
+ }
326
+
327
+ renderAnnoBar() {
328
+ return <AnnoBar
329
+ anno={this.state.anno}
330
+ mode={this.state.anno.mode}
331
+ possibleLabels={this.props.possibleLabels}
332
+ onClick={e => this.onClick(e)}
333
+ style={this.getStyle()}
334
+ svg={this.props.svg}
335
+ defaultLabel={this.props.defaultLabel}
336
+ />
337
+ }
338
+ render() {
339
+ if (!this.state.anno.data) return null
340
+ if (!this.props.possibleLabels) return null
341
+ if (this.state.anno.status === annoStatus.DELETED) return null
342
+ return (
343
+ <g>
344
+ <g visibility={this.state.visibility}
345
+ onClick={e => this.onClick(e)}
346
+ onMouseDown={e => this.onMouseDown(e)}
347
+ onContextMenu={e => this.onContextMenu(e)}
348
+ >
349
+ {this.renderAnnoBar()}
350
+ {this.renderAnno()}
351
+
352
+ </g>
353
+ </g>
354
+ )
355
+ }
356
+ }
357
+
358
+ export default Annotation
@@ -0,0 +1,47 @@
1
+ //*******************
2
+ //* General styling *
3
+ //*******************
4
+ .sel-area-off{
5
+ fill: none;
6
+ }
7
+
8
+ .sel-area-on{
9
+ fill: blue;
10
+ fill-opacity: 0.001;
11
+ }
12
+
13
+ //**********************
14
+ //* Annotation styling *
15
+ //**********************
16
+ .selected{
17
+ fill-opacity: 0.01;
18
+ cursor: grab;
19
+ }
20
+
21
+ circle.selected{
22
+ fill-opacity: 1.0;
23
+ }
24
+
25
+ .not-selected{
26
+ fill-opacity: 0.3;
27
+ }
28
+
29
+ circle.not-selected{
30
+ fill-opacity: 1.0;
31
+ }
32
+
33
+ //****************
34
+ //* Node styling *
35
+ //****************
36
+ .node-halo-on{
37
+ fill: orange;
38
+ stroke: orange;
39
+ fill-opacity: 0.1;
40
+ stroke-opacity: 0.2;
41
+ cursor: grab;
42
+ }
43
+
44
+ .node-halo-off{
45
+ fill: none;
46
+ stroke: none;
47
+ }
@@ -0,0 +1,291 @@
1
+ import React, {Component} from 'react'
2
+ import './Annotation.scss';
3
+ import * as modes from '../types/modes'
4
+ import * as transform from '../utils/transform'
5
+ import * as canvasActions from '../types/canvasActions'
6
+ import * as mouse from '../utils/mouse'
7
+ import InfSelectionArea from './InfSelectionArea'
8
+ import Node from './Node'
9
+
10
+ class BBox extends Component{
11
+
12
+ /*************
13
+ * LIFECYCLE *
14
+ **************/
15
+ constructor(props){
16
+ super(props)
17
+ this.state = {
18
+ anno: undefined,
19
+ }
20
+ }
21
+
22
+ componentDidMount(prevProps){
23
+ if (this.props.anno.mode === modes.CREATE){
24
+ const data = this.props.anno.data[0]
25
+ const newAnno = {
26
+ ...this.props.anno,
27
+ data: [
28
+ {x: data.x, y: data.y},
29
+ {x: data.x+1, y: data.y},
30
+ {x: data.x+1, y: data.y+1},
31
+ {x: data.x, y: data.y+1}
32
+ ],
33
+ selectedNode: 2
34
+ }
35
+ this.setState({
36
+ anno: newAnno
37
+ })
38
+ // this.performedAction(newAnno, canvasActions.ANNO_START_CREATING)
39
+
40
+ } else {
41
+ this.setState({anno: {...this.props.anno}})
42
+ }
43
+ }
44
+
45
+ componentDidUpdate(prevProps){
46
+ if (prevProps.anno !== this.props.anno){
47
+ this.setState({anno: {...this.props.anno}})
48
+ }
49
+ }
50
+
51
+ /*************
52
+ * EVENTS *
53
+ **************/
54
+ onNodeMouseMove(e, idx){
55
+ switch (this.state.anno.mode){
56
+ case modes.CREATE:
57
+ case modes.EDIT:
58
+ const mousePos = mouse.getMousePosition(e, this.props.svg)
59
+ const idxMinus = idx - 1 < 0 ? 3 : idx -1
60
+ const idxPlus = idx + 1 > 3 ? 0 : idx +1
61
+ let newAnnoData = [...this.state.anno.data]
62
+ if (idx % 2 === 0){
63
+ newAnnoData[idxMinus].x = mousePos.x
64
+ newAnnoData[idx].x = mousePos.x
65
+ newAnnoData[idx].y = mousePos.y
66
+ newAnnoData[idxPlus].y = mousePos.y
67
+ } else {
68
+ newAnnoData[idxMinus].y = mousePos.y
69
+ newAnnoData[idx].x = mousePos.x
70
+ newAnnoData[idx].y = mousePos.y
71
+ newAnnoData[idxPlus].x = mousePos.x
72
+ }
73
+ this.setState({
74
+ anno: {
75
+ ...this.state.anno,
76
+ data: newAnnoData
77
+ }
78
+ })
79
+ break
80
+ default:
81
+ break
82
+ }
83
+ }
84
+
85
+ onNodeMouseDown(e,idx){
86
+ switch(this.state.anno.mode){
87
+ case modes.VIEW:
88
+ if (e.button === 0){
89
+ this.requestModeChange(
90
+ {...this.state.anno, selectedNode:idx},
91
+ modes.EDIT
92
+ )
93
+ }
94
+ break
95
+ default:
96
+ break
97
+ }
98
+ }
99
+
100
+ onNodeMouseUp(e, idx){
101
+ switch(this.state.anno.mode){
102
+ case modes.EDIT:
103
+ if (e.button === 0){
104
+ this.requestModeChange(this.state.anno, modes.VIEW)
105
+ this.performedAction(this.state.anno, canvasActions.ANNO_EDITED)
106
+ }
107
+ break
108
+ case modes.CREATE:
109
+ if (e.button === 2){
110
+ this.requestModeChange(this.state.anno, modes.VIEW)
111
+ this.performedAction(this.state.anno, canvasActions.ANNO_CREATED)
112
+ }
113
+ break
114
+ default:
115
+ break
116
+ }
117
+ }
118
+
119
+ handleNodeMouseLeave(e, idx){
120
+ switch(this.state.anno.mode){
121
+ //if mouse left Canvas in create mode, transit to VIEW mode
122
+ case modes.CREATE:
123
+ this.requestModeChange(this.state.anno, modes.VIEW)
124
+ this.performedAction(this.state.anno, canvasActions.ANNO_CREATED)
125
+ break
126
+ default:
127
+ break
128
+ }
129
+ }
130
+
131
+ /**************
132
+ * ANNO EVENTS *
133
+ ***************/
134
+ onMouseMove(e){
135
+ switch (this.state.anno.mode){
136
+ case modes.MOVE:
137
+ this.move(
138
+ e.movementX/this.props.svg.scale,
139
+ e.movementY/this.props.svg.scale
140
+ )
141
+ break
142
+ default:
143
+ break
144
+ }
145
+ }
146
+
147
+ onMouseUp(e){
148
+ switch (this.state.anno.mode){
149
+ case modes.MOVE:
150
+ if (e.button === 0){
151
+ this.requestModeChange(this.state.anno, modes.VIEW)
152
+ this.performedAction(this.state.anno, canvasActions.ANNO_MOVED)
153
+ }
154
+ break
155
+ default:
156
+ break
157
+ }
158
+ }
159
+
160
+ onMouseDown(e){
161
+ switch (this.state.anno.mode){
162
+ case modes.VIEW:
163
+ if (e.button === 0){
164
+ if (this.props.isSelected){
165
+ this.requestModeChange(this.state.anno, modes.MOVE)
166
+ }
167
+ }
168
+ break
169
+ default:
170
+ break
171
+ }
172
+ }
173
+ /*************
174
+ * LOGIC *
175
+ **************/
176
+ getResult(){
177
+ return this.state.anno
178
+ }
179
+
180
+ requestModeChange(anno, mode){
181
+ this.props.onModeChangeRequest(anno, mode)
182
+ }
183
+
184
+ performedAction(anno, pAction){
185
+ if (this.props.onAction){
186
+ this.props.onAction(anno, pAction)
187
+ }
188
+ }
189
+
190
+ toPolygonStr(data){
191
+ return data.map( (e => {
192
+ return `${e.x},${e.y}`
193
+ })).join(' ')
194
+
195
+ }
196
+
197
+ move(movementX, movementY){
198
+ this.setState({
199
+ anno : {
200
+ ...this.state.anno,
201
+ data: transform.move(this.state.anno.data, movementX, movementY)
202
+ }
203
+ })
204
+ }
205
+
206
+ /*************
207
+ * RENDERING *
208
+ **************/
209
+
210
+ renderPolygon(){
211
+ switch(this.state.anno.mode){
212
+ default:
213
+ return <polygon
214
+ points={this.toPolygonStr(this.state.anno.data)}
215
+ fill='none' stroke="purple"
216
+ style={this.props.style}
217
+ className={this.props.className}
218
+ onMouseDown={e => this.onMouseDown(e)}
219
+ onMouseUp={e => this.onMouseUp(e)}
220
+ />
221
+ }
222
+ }
223
+
224
+ renderNodes(){
225
+ if (!this.props.isSelected) return null
226
+ switch(this.state.anno.mode){
227
+ case modes.MOVE:
228
+ case modes.EDIT_LABEL:
229
+ return null
230
+ case modes.EDIT:
231
+ case modes.CREATE:
232
+ return <Node anno={this.state.anno.data}
233
+ key={this.state.anno.selectedNode}
234
+ idx={this.state.anno.selectedNode}
235
+ style={this.props.style}
236
+ className={this.props.className}
237
+ isSelected={this.props.isSelected}
238
+ mode={this.state.anno.mode}
239
+ svg={this.props.svg}
240
+ onMouseDown={(e, idx) => this.onNodeMouseDown(e,idx)}
241
+ onMouseUp={(e, idx) => this.onNodeMouseUp(e, idx)}
242
+ onMouseMove={(e, idx) => this.onNodeMouseMove(e, idx)}
243
+ onMouseLeave={(e, idx) => this.handleNodeMouseLeave(e, idx)}
244
+ />
245
+ default:
246
+ return this.state.anno.data.map((e, idx) => {
247
+ return <Node anno={this.state.anno.data} idx={idx}
248
+ key={idx} style={this.props.style}
249
+ className={this.props.className}
250
+ isSelected={this.props.isSelected}
251
+ mode={this.state.anno.mode}
252
+ svg={this.props.svg}
253
+ onMouseDown={(e, idx) => this.onNodeMouseDown(e,idx)}
254
+ onMouseUp={(e, idx) => this.onNodeMouseUp(e, idx)}
255
+ onMouseLeave={(e, idx) => this.handleNodeMouseLeave(e, idx)}
256
+ />
257
+ })
258
+ }
259
+ }
260
+
261
+ renderInfSelectionArea(){
262
+ switch (this.state.anno.mode){
263
+ case modes.MOVE:
264
+ return <InfSelectionArea enable={true}
265
+ svg={this.props.svg}
266
+ />
267
+ default:
268
+ return null
269
+ }
270
+ }
271
+
272
+ render(){
273
+ if (this.state.anno){
274
+ return (
275
+ <g
276
+ onMouseMove={e => this.onMouseMove(e)}
277
+ onMouseUp={e => this.onMouseUp(e)}
278
+ onMouseDown={e => this.onMouseDown(e)}
279
+ >
280
+ {this.renderPolygon()}
281
+ {this.renderNodes()}
282
+ {this.renderInfSelectionArea()}
283
+ </g>)
284
+ } else {
285
+ return null
286
+ }
287
+ }
288
+
289
+ }
290
+
291
+ export default BBox;