Skip to content

Commit 986d52b

Browse files
committed
Add coronal view to the PET-CT overlay example
1 parent 1ccc505 commit 986d52b

2 files changed

Lines changed: 121 additions & 42 deletions

File tree

usage/src/Volume/PET_CT_Overlay.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ input[type=range] {
88

99
input[type=range]::-webkit-slider-runnable-track {
1010
width: 300px;
11-
height: 5px;
11+
height: 3px;
1212
background: #ddd;
1313
border: none;
1414
border-radius: 5px;
@@ -18,11 +18,11 @@ input[type=range]::-webkit-slider-runnable-track {
1818
input[type=range]::-webkit-slider-thumb {
1919
-webkit-appearance: none;
2020
border: none;
21-
height: 15px;
22-
width: 6px;
21+
height: 25px;
22+
width: 8px;
2323
border-radius: 50%;
2424
background: goldenrod;
25-
margin-top: -4px;
25+
margin-top: -10px;
2626
}
2727

2828

@@ -39,7 +39,7 @@ input[type=range][orient='vertical'] {
3939
position: absolute;
4040
zIndex: 1000;
4141
margin: 0;
42-
padding: 0;
42+
padding: 5;
4343
width: 2500%;
4444
height: 0.5em;
4545
transform: translate(-50%, -50%) rotate(-90deg);

usage/src/Volume/PET_CT_Overlay.jsx

Lines changed: 116 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import './PET_CT_Overlay.css';
99
import {
1010
Contexts,
1111
Dataset,
12+
MultiViewRoot,
1213
RegisterDataSet,
1314
ShareDataSetRoot,
1415
SliceRepresentation,
@@ -21,7 +22,10 @@ function Slider(props) {
2122
const onChange = (e) => {
2223
const value = Number(e.currentTarget.value);
2324
props.setValue(value);
24-
setTimeout(view.renderView, 0);
25+
if (props.setCTValue) {
26+
props.setCTValue(value * 4);
27+
}
28+
setTimeout(view?.renderView, 0);
2529
};
2630
return (
2731
<label
@@ -55,7 +59,7 @@ function DropDown(props) {
5559
function onChange(e) {
5660
const value = e.currentTarget.value;
5761
props.setValue(value);
58-
setTimeout(view.renderView, 0);
62+
setTimeout(view?.renderView, 0);
5963
}
6064
return (
6165
<form>
@@ -136,7 +140,9 @@ const loadData = async () => {
136140
ptWebWorkers.terminateWorkers();
137141
ptImageData = vtkITKHelper.convertItkToVtkImage(ptitkImage);
138142
}
139-
loadData.setMaxSlicingValue(ctImageData.getDimensions()[2] - 1);
143+
console.log(ctImageData.getDimensions(), ptImageData.getDimensions());
144+
loadData.setMaxKSlice(ctImageData.getDimensions()[2] - 1);
145+
loadData.setMaxJSlice(ptImageData.getDimensions()[1] - 1);
140146
loadData.setStatusText('');
141147
loader.hidden = 'hidden';
142148
return [ctImageData, ptImageData];
@@ -145,40 +151,45 @@ const loadData = async () => {
145151
function Example(props) {
146152
const [statusText, setStatusText] = useState('Loading data, please wait ...');
147153
const [kSlice, setKSlice] = useState(0);
154+
const [jSlice, setJSlice] = useState(0);
155+
const [ctjSlice, setCTJSlice] = useState(0);
148156
const [colorWindow, setColorWindow] = useState(2048);
149157
const [colorLevel, setColorLevel] = useState(0);
150158
const [colorPreset, setColorPreset] = useState('jet');
151159
const [opacity, setOpacity] = useState(0.4);
152160
const [maxKSlice, setMaxKSlice] = useState(310);
153-
loadData.setMaxSlicingValue = setMaxKSlice;
161+
const [maxJSlice, setMaxJSlice] = useState(110);
162+
loadData.setMaxKSlice = setMaxKSlice;
163+
loadData.setMaxJSlice = setMaxJSlice;
154164
loadData.setStatusText = setStatusText;
155165

156166
useEffect(() => {
157167
loadData().then(([ctData, ptData]) => {
158168
window.ctData = ctData;
159169
window.ptData = ptData;
160170
setKSlice(155);
171+
setJSlice(64);
172+
setCTJSlice(256);
161173
});
162174
}, []);
163175

164176
return (
165-
<div style={{ width: '100%', height: '100%' }}>
177+
<MultiViewRoot>
166178
<ShareDataSetRoot>
167179
<RegisterDataSet id='ctData'>
168180
<Dataset dataset={window.ctData} />
169181
</RegisterDataSet>
170182
<RegisterDataSet id='ptData'>
171183
<Dataset dataset={window.ptData} />
172184
</RegisterDataSet>
173-
<View
174-
id='0'
175-
camera={{
176-
position: [0, 0, 0],
177-
focalPoint: [0, 0, -1],
178-
viewUp: [0, -1, 0],
179-
parallelProjection: true,
185+
<div
186+
style={{
187+
display: 'flex',
188+
flexFlow: 'row',
189+
flexWrap: 'wrap',
190+
width: '100%',
191+
height: '100%',
180192
}}
181-
background={[0, 0, 0]}
182193
>
183194
<label
184195
style={{
@@ -191,14 +202,6 @@ function Example(props) {
191202
>
192203
{statusText}
193204
</label>
194-
<Slider
195-
label='Slice'
196-
max={maxKSlice}
197-
value={kSlice}
198-
setValue={setKSlice}
199-
orient='vertical'
200-
style={{ top: '50%', left: '1%' }}
201-
/>
202205
<Slider
203206
label='Color Level'
204207
max={4095}
@@ -230,27 +233,103 @@ function Example(props) {
230233
style={{ top: '30px', left: '305px' }}
231234
/>
232235
<div className='loader' id='loader' />
233-
<SliceRepresentation
234-
kSlice={kSlice}
235-
property={{
236-
opacity,
236+
<div
237+
style={{
238+
position: 'absolute',
239+
left: '0px',
240+
width: '50%',
241+
height: '100%',
237242
}}
238-
colorMapPreset={colorPreset}
239243
>
240-
<UseDataSet id='ptData' />
241-
</SliceRepresentation>
242-
<SliceRepresentation
243-
kSlice={kSlice}
244-
property={{
245-
colorWindow,
246-
colorLevel,
244+
<View
245+
id='0'
246+
camera={{
247+
position: [0, 0, 0],
248+
focalPoint: [0, 0, -1],
249+
viewUp: [0, -1, 0],
250+
parallelProjection: true,
251+
}}
252+
background={[0, 0, 0]}
253+
>
254+
<Slider
255+
label='Slice'
256+
max={maxKSlice}
257+
value={kSlice}
258+
setValue={setKSlice}
259+
orient='vertical'
260+
style={{ top: '50%', left: '1%' }}
261+
/>
262+
<SliceRepresentation
263+
kSlice={kSlice}
264+
property={{
265+
opacity,
266+
}}
267+
colorMapPreset={colorPreset}
268+
>
269+
<UseDataSet id='ptData' />
270+
</SliceRepresentation>
271+
<SliceRepresentation
272+
kSlice={kSlice}
273+
property={{
274+
colorWindow,
275+
colorLevel,
276+
}}
277+
>
278+
<UseDataSet id='ctData' />
279+
</SliceRepresentation>
280+
</View>
281+
</div>
282+
<div
283+
style={{
284+
position: 'absolute',
285+
left: '50%',
286+
width: '50%',
287+
height: '100%',
247288
}}
248289
>
249-
<UseDataSet id='ctData' />
250-
</SliceRepresentation>
251-
</View>
290+
<View
291+
id='0'
292+
camera={{
293+
position: [0, 0, 0],
294+
focalPoint: [0, -1, 0],
295+
viewUp: [0, 0, 1],
296+
parallelProjection: true,
297+
}}
298+
background={[0, 0, 0]}
299+
>
300+
<Slider
301+
label='Slice'
302+
max={maxJSlice}
303+
value={jSlice}
304+
setValue={setJSlice}
305+
setCTValue={setCTJSlice}
306+
orient='vertical'
307+
style={{ top: '50%', left: '5%' }}
308+
/>
309+
<SliceRepresentation
310+
id='pt'
311+
jSlice={jSlice}
312+
property={{
313+
opacity,
314+
}}
315+
colorMapPreset={colorPreset}
316+
>
317+
<UseDataSet id='ptData' />
318+
</SliceRepresentation>
319+
<SliceRepresentation
320+
jSlice={ctjSlice}
321+
property={{
322+
colorWindow,
323+
colorLevel,
324+
}}
325+
>
326+
<UseDataSet id='ctData' />
327+
</SliceRepresentation>
328+
</View>
329+
</div>
330+
</div>
252331
</ShareDataSetRoot>
253-
</div>
332+
</MultiViewRoot>
254333
);
255334
}
256335

0 commit comments

Comments
 (0)