Skip to content

Commit 3acabf0

Browse files
authored
Merge pull request #22 from KitwareMedical/composition-api
Composition api migration
2 parents ba5cb3c + b6e1435 commit 3acabf0

24 files changed

Lines changed: 4538 additions & 3153 deletions

.eslintrc.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,19 @@ module.exports = {
55
node: true,
66
},
77

8-
extends: [
9-
'plugin:vue/essential',
10-
'@vue/airbnb',
11-
'prettier',
12-
'prettier/vue',
13-
],
8+
extends: ['plugin:vue/essential', '@vue/airbnb', 'prettier', 'prettier/vue'],
149

1510
parserOptions: {
1611
parser: 'babel-eslint',
1712
},
1813

19-
ignorePatterns: [
20-
'src/io/itk-dicom/web-build/**',
21-
],
14+
ignorePatterns: ['src/io/itk-dicom/web-build/**'],
2215

2316
rules: {
2417
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
2518
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
2619
'import/no-named-as-default-member': 'off',
20+
'import/prefer-default-export': 'off',
2721
},
2822

2923
overrides: [

package-lock.json

Lines changed: 3290 additions & 2365 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,43 +12,44 @@
1212
"build:all": "npm run build:dicom && npm run build"
1313
},
1414
"dependencies": {
15-
"core-js": "^3.6.5",
16-
"daikon": "^1.2.42",
17-
"gl-matrix": "^3.3.0",
18-
"itk": "^13.1.1",
19-
"vtk.js": "^14.15.2",
20-
"vue": "^2.6.11",
21-
"vue-notification": "^1.3.20",
22-
"vuetify": "^2.3.4",
23-
"vuex": "^3.5.1"
15+
"@vue/composition-api": "1.0.0-rc.1",
16+
"core-js": "3.8.3",
17+
"daikon": "1.2.42",
18+
"gl-matrix": "3.3.0",
19+
"itk": "13.3.1",
20+
"vtk.js": "16.1.7",
21+
"vue": "2.6.12",
22+
"vue-notification": "1.3.20",
23+
"vuetify": "2.4.3",
24+
"vuex": "3.6.2"
2425
},
2526
"devDependencies": {
26-
"@vue/cli-plugin-babel": "~4.4.6",
27-
"@vue/cli-plugin-eslint": "~4.4.6",
28-
"@vue/cli-plugin-unit-mocha": "^4.4.6",
29-
"@vue/cli-plugin-vuex": "~4.4.6",
30-
"@vue/cli-service": "~4.4.6",
31-
"@vue/eslint-config-airbnb": "^5.1.0",
32-
"@vue/test-utils": "1.0.3",
33-
"babel-eslint": "^10.1.0",
34-
"chai": "^4.1.2",
35-
"chai-as-promised": "^7.1.1",
36-
"eslint": "^7.5.0",
37-
"eslint-config-prettier": "^6.11.0",
38-
"eslint-plugin-import": "^2.22.0",
39-
"eslint-plugin-vue": "^6.2.2",
40-
"lint-staged": "^10.2.11",
41-
"null-loader": "^4.0.0",
42-
"prettier": "^2.0.5",
43-
"sass": "^1.26.10",
44-
"sass-loader": "^9.0.2",
45-
"shader-loader": "^1.3.1",
46-
"sinon": "^9.0.2",
47-
"sinon-chai": "^3.5.0",
48-
"vue-cli-plugin-vuetify": "~2.0.7",
49-
"vue-template-compiler": "^2.6.11",
50-
"vuetify-loader": "^1.6.0",
51-
"worker-loader": "^2.0.0"
27+
"@vue/cli-plugin-babel": "4.5.11",
28+
"@vue/cli-plugin-eslint": "4.5.11",
29+
"@vue/cli-plugin-unit-mocha": "4.5.11",
30+
"@vue/cli-plugin-vuex": "4.5.11",
31+
"@vue/cli-service": "4.5.11",
32+
"@vue/eslint-config-airbnb": "5.3.0",
33+
"@vue/test-utils": "1.1.2",
34+
"babel-eslint": "10.1.0",
35+
"chai": "4.1.2",
36+
"chai-as-promised": "7.1.1",
37+
"eslint": "7.18.0",
38+
"eslint-config-prettier": "7.2.0",
39+
"eslint-plugin-import": "2.22.1",
40+
"eslint-plugin-vue": "7.5.0",
41+
"lint-staged": "10.5.3",
42+
"null-loader": "4.0.1",
43+
"prettier": "2.2.1",
44+
"sass": "1.32.5",
45+
"sass-loader": "10.1.1",
46+
"shader-loader": "1.3.1",
47+
"sinon": "9.2.4",
48+
"sinon-chai": "3.5.0",
49+
"vue-cli-plugin-vuetify": "2.1.0",
50+
"vue-template-compiler": "2.6.12",
51+
"vuetify-loader": "1.7.1",
52+
"worker-loader": "3.0.7"
5253
},
5354
"gitHooks": {
5455
"pre-commit": "lint-staged"

src/App.vue

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,11 @@
130130
<div>
131131
<v-icon size="64">mdi-folder-open</v-icon>
132132
</div>
133-
<div>
134-
Click anywhere here to open files
135-
</div>
133+
<div>Click anywhere here to open files</div>
136134
<div class="mt-8">
137135
<v-icon size="64">mdi-arrow-down-bold</v-icon>
138136
</div>
139-
<div>
140-
Drop your files anywhere here to open
141-
</div>
137+
<div>Drop your files anywhere here to open</div>
142138
</v-card>
143139
</v-row>
144140
</v-col>

src/components/VtkThreeView.vue

Lines changed: 131 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,65 +2,155 @@
22
<div class="vtk-container-wrapper">
33
<div class="vtk-gutter"></div>
44
<div class="vtk-container" :class="active ? 'active' : ''">
5-
<div class="vtk-sub-container" ref="containerParent"></div>
5+
<div class="vtk-sub-container">
6+
<div class="vtk-view" ref="vtkContainer" />
7+
</div>
68
</div>
79
</div>
810
</template>
911

1012
<script>
11-
import { mapGetters } from 'vuex';
13+
import {
14+
ref,
15+
toRefs,
16+
watch,
17+
unref,
18+
reactive,
19+
watchEffect,
20+
computed,
21+
} from '@vue/composition-api';
1222
13-
import VtkViewMixin, { attachResizeObserver } from '@/src/mixins/VtkView';
23+
import {
24+
CommonViewProps,
25+
useVtkView,
26+
useVtkViewCameraOrientation,
27+
giveViewAnnotations,
28+
} from '@/src/composables/view/common';
29+
import { useResizeObserver } from '@/src/composables/resizeObserver';
30+
import { watchScene, watchColorBy } from '@/src/composables/scene';
31+
import { useComputedState } from '@/src/composables/store';
32+
import { useProxyManager } from '@/src/composables/proxyManager';
1433
1534
export default {
1635
name: 'VtkThreeView',
36+
props: CommonViewProps,
37+
setup(props) {
38+
const { viewName, viewType, viewUp, axis, orientation } = toRefs(props);
39+
const vtkContainer = ref(null);
1740
18-
mixins: [VtkViewMixin],
41+
const pxm = useProxyManager();
1942
20-
computed: {
21-
...mapGetters('visualization', [
22-
'boundsWithSpacing',
23-
'baseImageColorPreset',
24-
]),
25-
},
43+
const {
44+
sceneSources,
45+
worldOrientation,
46+
colorBy,
47+
boundsWithSpacing,
48+
baseImageColorPreset,
49+
baseImage,
50+
slices,
51+
windowing,
52+
} = useComputedState({
53+
sceneSources(state, getters) {
54+
const { pipelines } = state.visualization;
55+
return getters.sceneObjectIDs
56+
.filter((id) => id in pipelines)
57+
.map((id) => pipelines[id].last);
58+
},
59+
worldOrientation: (state) => state.visualization.worldOrientation,
60+
colorBy: (state, getters) =>
61+
getters.sceneObjectIDs.map((id) => state.visualization.colorBy[id]),
62+
boundsWithSpacing: (_, getters) =>
63+
getters['visualization/boundsWithSpacing'],
64+
baseImageColorPreset: (_, getters) =>
65+
getters['visualization/baseImageColorPreset'],
66+
baseImage(state) {
67+
const { pipelines } = state.visualization;
68+
const { selectedBaseImage } = state;
69+
if (selectedBaseImage in pipelines) {
70+
return pipelines[selectedBaseImage].last;
71+
}
72+
return null;
73+
},
74+
slices: (state) => state.visualization.slices,
75+
windowing: (state) => state.visualization.windowing,
76+
});
2677
27-
watch: {
28-
sceneSources() {
29-
this.updateOrientation();
30-
this.resetCamera();
31-
},
32-
boundsWithSpacing() {
33-
this.resetCamera();
34-
},
35-
baseImageColorPreset(preset) {
36-
this.setColorPresetAnnotation(preset);
37-
},
38-
},
78+
const spacing = computed(() => worldOrientation.value.spacing);
3979
40-
mounted() {
41-
this.resizeObserver = attachResizeObserver(
42-
this.$refs.containerParent,
43-
this.resizeLater
44-
);
45-
},
80+
const viewRef = useVtkView({
81+
containerRef: vtkContainer,
82+
viewName,
83+
viewType,
84+
});
4685
47-
beforeDestroy() {
48-
this.resizeObserver.unobserve(this.$refs.containerParent);
49-
},
86+
// handle camera orientation
87+
useVtkViewCameraOrientation(viewRef, viewUp, axis, orientation);
5088
51-
methods: {
52-
afterViewMount() {
53-
this.view.setBackground(0.1, 0.2, 0.3);
54-
this.view.setOrientationAxesType('cube');
55-
this.setColorPresetAnnotation(this.baseImageColorPreset);
56-
},
57-
setColorPresetAnnotation(preset) {
58-
if (this.view) {
59-
this.view.setCornerAnnotation('nw', preset || 'No colormap');
89+
useResizeObserver(vtkContainer, () => {
90+
const view = unref(viewRef);
91+
if (view) {
92+
view.resize();
6093
}
61-
},
94+
});
95+
96+
// update scene sources and their colors
97+
watchScene(sceneSources, worldOrientation, viewRef);
98+
watchColorBy(colorBy, sceneSources, viewRef);
99+
100+
// prepare view
101+
watchEffect(() => {
102+
const view = unref(viewRef);
103+
if (view) {
104+
view.setBackground(0.1, 0.2, 0.3);
105+
view.setOrientationAxesType('cube');
106+
}
107+
});
108+
109+
// set wl and slices
110+
watchEffect(() => {
111+
if (viewRef.value && baseImage.value) {
112+
const rep = pxm.getRepresentation(baseImage.value, viewRef.value);
113+
if (rep) {
114+
rep.setXSlice(slices.value.x * spacing.value[0]);
115+
rep.setYSlice(slices.value.y * spacing.value[1]);
116+
rep.setZSlice(slices.value.z * spacing.value[2]);
117+
rep.setWindowWidth(windowing.value.width);
118+
rep.setWindowLevel(windowing.value.level);
119+
}
120+
}
121+
});
122+
123+
// reset camera whenever bounds changes
124+
watch(boundsWithSpacing, () => {
125+
const view = unref(viewRef);
126+
if (view) {
127+
view.resetCamera();
128+
}
129+
});
130+
131+
giveViewAnnotations(
132+
viewRef,
133+
reactive({
134+
nw: baseImageColorPreset,
135+
}),
136+
{
137+
nw: 'No colormap',
138+
}
139+
);
140+
141+
return {
142+
vtkContainer, // dom ref
143+
active: true,
144+
};
62145
},
63146
};
64147
</script>
65148

66149
<style src="@/src/assets/styles/vtk-view.css"></style>
150+
151+
<style scoped>
152+
.vtk-gutter {
153+
display: flex;
154+
flex-flow: column;
155+
}
156+
</style>

0 commit comments

Comments
 (0)