Skip to content

Commit a95b709

Browse files
authored
Merge pull request #72 from PytorchConnectomics/simplify-visualize-ui
simplify workflow of upload input and label images, visualize in ng, then segment them
2 parents 45b846a + 327bc15 commit a95b709

File tree

4 files changed

+73
-82
lines changed

4 files changed

+73
-82
lines changed

client/src/components/InputSelector.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ function InputSelector(props) {
4141
>
4242
<Form.Item label='Input Image'>
4343
<Select
44-
allowClear
4544
style={{ width: '100%' }}
46-
placeholder='Please select'
45+
placeholder='Please upload to the left'
4746
onChange={handleImageChange}
4847
value={context.inputImage ? context.inputImage.uid : undefined}
4948
options={context.imageFileList.map((file) => ({
@@ -55,9 +54,8 @@ function InputSelector(props) {
5554
</Form.Item>
5655
<Form.Item label='Input Label'>
5756
<Select
58-
allowClear
5957
style={{ width: '100%' }}
60-
placeholder='Please select'
58+
placeholder='Please upload to the left'
6159
onChange={handleLabelChange}
6260
value={context.inputLabel ? context.inputLabel.uid : undefined}
6361
options={context.labelFileList.map((file) => ({

client/src/views/DataLoader.js

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,40 @@
11
import React, { useContext, useEffect, useState } from 'react'
2-
import { Dragger } from '../components/Dragger'
3-
import { Button, Input, Select, Space, Typography } from 'antd'
4-
import { ArrowRightOutlined } from '@ant-design/icons'
2+
import { Button, Input, Space, Typography, Upload } from 'antd'
3+
import { InboxOutlined, EyeOutlined } from '@ant-design/icons'
54
import { AppContext } from '../contexts/GlobalContext'
65
import './DataLoader.css'
76

87
const { Title } = Typography
98

109
function DataLoader (props) {
1110
const context = useContext(AppContext)
12-
const [currentImage, setCurrentImage] = useState(null)
13-
const [currentLabel, setCurrentLabel] = useState(null)
1411
const [scales, setScales] = useState('30,6,6')
1512
const { fetchNeuroglancerViewer } = props
1613

1714
const handleVisualizeButtonClick = async (event) => {
1815
event.preventDefault()
19-
context.setCurrentImage(currentImage)
20-
context.setCurrentLabel(currentLabel)
2116
fetchNeuroglancerViewer(
22-
currentImage,
23-
currentLabel,
17+
context.currentImage,
18+
context.currentLabel,
2419
scales.split(',').map(Number)
2520
)
2621
}
27-
const handleImageChange = (value) => {
28-
console.log(`selected ${value}`)
29-
setCurrentImage(context.files.find((image) => image.uid === value))
30-
}
31-
const handleLabelChange = (value) => {
32-
console.log(`selected ${value}`)
33-
setCurrentLabel(context.files.find((file) => file.uid === value))
34-
}
22+
23+
const handleImageChange = (info) => {
24+
const { file } = info
25+
if (file) {
26+
context.setInputImage(file)
27+
context.setCurrentImage(file)
28+
}
29+
};
30+
31+
const handleLabelChange = (info) => {
32+
const { file } = info
33+
if (file) {
34+
context.setInputLabel(file)
35+
context.setCurrentLabel(file)
36+
}
37+
};
3538

3639
const handleInputScales = (event) => {
3740
setScales(event.target.value)
@@ -56,36 +59,37 @@ function DataLoader (props) {
5659
align='start'
5760
style={{ margin: '7px', display: 'flex' }}
5861
>
59-
<Dragger />
6062
<Title level={5} style={{ marginBottom: '-5px' }}>
6163
Image
6264
</Title>
63-
<Select
65+
<Upload.Dragger
66+
multiple={false}
67+
maxCount={1}
6468
onChange={handleImageChange}
65-
options={context.imageFileList.map((file) => ({
66-
label: file.name,
67-
value: file.uid
68-
}))}
69-
style={{ width: '185px' }}
70-
placeholder='Select image'
71-
size='middle'
72-
allowClear
73-
/>
69+
>
70+
<p className='ant-upload-drag-icon'>
71+
<InboxOutlined />
72+
</p>
73+
<p className='ant-upload-text'>
74+
Drag image here, or click to upload
75+
</p>
76+
</Upload.Dragger>
7477

7578
<Title level={5} style={{ marginTop: '0px', marginBottom: '-5px' }}>
7679
Label
7780
</Title>
78-
<Select
81+
<Upload.Dragger
82+
multiple={false}
83+
maxCount={1}
7984
onChange={handleLabelChange}
80-
options={context.labelFileList.map((file) => ({
81-
label: file.name,
82-
value: file.uid
83-
}))}
84-
style={{ width: '185px' }}
85-
placeholder='Select label'
86-
size='middle'
87-
allowClear
88-
/>
85+
>
86+
<p className='ant-upload-drag-icon'>
87+
<InboxOutlined />
88+
</p>
89+
<p className='ant-upload-text'>
90+
Drag label here, or click to upload
91+
</p>
92+
</Upload.Dragger>
8993

9094
<Title level={5} style={{ marginTop: '0px', marginBottom: '-5px' }}>
9195
Scales
@@ -99,7 +103,7 @@ function DataLoader (props) {
99103
<Button
100104
type='primary'
101105
onClick={handleVisualizeButtonClick}
102-
icon={<ArrowRightOutlined />}
106+
icon={<EyeOutlined />}
103107
style={{ width: '185px' }}
104108
>
105109
Visualize

client/src/views/Views.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,19 @@ function Views () {
1717
const [isLoading, setIsLoading] = useState(false)
1818
const [isInferring, setIsInferring] = useState(false)
1919
const [isChatOpen, setIsChatOpen] = useState(false)
20-
console.log(viewers)
2120

2221
const onClick = (e) => {
2322
setCurrent(e.key)
2423
}
2524

2625
const items = [
2726
{ label: 'Visualization', key: 'visualization' },
28-
{ label: 'Model Training', key: 'training' },
29-
{ label: 'Model Inference', key: 'inference' },
30-
{ label: 'Tensorboard', key: 'monitoring' }
27+
{ label: 'Model Inference', key: 'inference' }
3128
]
3229

3330
const renderMenu = () => {
3431
if (current === 'visualization') {
35-
return <Visualization viewers={viewers} setViewers={setViewers} />
32+
return <Visualization viewers={viewers} setViewers={setViewers} setCurrent={setCurrent} />
3633
} else if (current === 'training') {
3734
return <ModelTraining />
3835
} else if (current === 'monitoring') {
@@ -54,10 +51,8 @@ function Views () {
5451
const viewerId = currentImage.uid + currentLabel.uid + JSON.stringify(scales)
5552
let updatedViewers = viewers
5653
const exists = viewers.find(
57-
// (viewer) => viewer.key === currentImage.uid + currentLabel.uid
5854
(viewer) => viewer.key === viewerId
5955
)
60-
// console.log(exists, viewers)
6156
if (exists) {
6257
updatedViewers = viewers.filter((viewer) => viewer.key !== viewerId)
6358
}
@@ -67,7 +62,6 @@ function Views () {
6762
scales
6863
)
6964
const newUrl = res.replace(/\/\/[^:/]+/, '//localhost')
70-
console.log('Current Viewer at ', newUrl)
7165

7266
setViewers([
7367
...updatedViewers,

client/src/views/Visualization.js

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import React, { useState } from 'react'
22
import { Button, Tabs, Timeline } from 'antd'
33
import {
4-
ArrowRightOutlined,
5-
DownOutlined,
64
EyeOutlined,
75
InboxOutlined,
8-
ReloadOutlined
6+
ReloadOutlined,
7+
ScissorOutlined
98
} from '@ant-design/icons'
109

1110
function Visualization (props) {
12-
const { viewers, setViewers } = props
11+
const { viewers, setViewers, setCurrent } = props
1312
const [activeKey, setActiveKey] = useState(
1413
viewers.length > 0 ? viewers[0].key : null
1514
) // Store the active tab key
@@ -70,22 +69,32 @@ function Visualization (props) {
7069
onChange={handleChange}
7170
items={viewers.map((viewer) => ({
7271
label: (
73-
<span>
74-
{viewer.title}
75-
<Button
76-
type='link'
77-
icon={<ReloadOutlined />}
78-
onClick={() => refreshViewer(viewer.key)}
79-
/>
80-
72+
<span style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '16px'}}>
73+
<div>
74+
<Button
75+
type='link'
76+
icon={<ReloadOutlined />}
77+
onClick={() => refreshViewer(viewer.key)}
78+
/>
79+
{viewer.title}
80+
</div>
81+
<div style={{ fontColor: 'red' }}>
82+
<Button
83+
type='link'
84+
icon={<ScissorOutlined />}
85+
onClick={() => setCurrent('inference')}
86+
>
87+
Segment it
88+
</Button>
89+
</div>
8190
</span>
8291
),
8392
key: viewer.key,
8493
children: (
8594
<iframe
8695
title='Viewer Display'
8796
width='100%'
88-
height='800'
97+
height='700'
8998
frameBorder='0'
9099
scrolling='no'
91100
src={viewer.viewer}
@@ -101,26 +110,12 @@ function Visualization (props) {
101110
{
102111
children: (
103112
<>
104-
<InboxOutlined /> Upload your files
105-
</>
106-
)
107-
},
108-
{
109-
children: (
110-
<>
111-
Input folder path of file in <EyeOutlined /> preview
112-
</>
113-
)
114-
},
115-
{
116-
children: (
117-
<>
118-
<DownOutlined /> Select your image and label in dropdown menus
113+
<InboxOutlined /> Upload your files to the left
119114
</>
120115
)
121116
},
122117
{
123-
children: 'Input scales of image in z,y,x order'
118+
children: 'Input image scales in z, y, x order (optional)'
124119
},
125120
{
126121
children: (
@@ -129,11 +124,11 @@ function Visualization (props) {
129124
<Button
130125
type='primary'
131126
size='small'
132-
icon={<ArrowRightOutlined />}
127+
icon={<EyeOutlined />}
133128
>
134129
Visualize
135130
</Button>{' '}
136-
button to render image and label in Neuroglancer
131+
to render the image and label with Neuroglancer
137132
</>
138133
)
139134
}

0 commit comments

Comments
 (0)