diff --git a/src/views/trials/trials-panel/reading/dicoms/components/Fusion/PetCt.vue b/src/views/trials/trials-panel/reading/dicoms/components/Fusion/PetCt.vue index cd3230db..a0fdf9e8 100644 --- a/src/views/trials/trials-panel/reading/dicoms/components/Fusion/PetCt.vue +++ b/src/views/trials/trials-panel/reading/dicoms/components/Fusion/PetCt.vue @@ -1654,7 +1654,7 @@ export default { }) }, voiChange(v) { - console.log(this.lastUpper, this.hasVoiChanged, v) + // console.log(this.lastUpper, this.hasVoiChanged, v) if (this.lastUpper === v && this.hasVoiChanged) return; this.lastUpper = v; this.hasVoiChanged = true; @@ -1677,27 +1677,49 @@ export default { this.$refs.colorMap.changeVoi(v) } }, + // async setColorMap(rgbPresetName) { + // this.rgbPresetName = rgbPresetName + // if (this.$refs.FUSION_AXIAL) { + // this.$refs.FUSION_AXIAL.setPreset(this.rgbPresetName) + // this.$refs.FUSION_AXIAL.renderColorBar(this.rgbPresetName) + // } + + // const viewport = getRenderingEngine(renderingEngineId)?.getViewport('FUSION_AXIAL') + // if (!viewport) return + + // const actorEntry = viewport.getActors()?.find(e => String(e.uid || '').includes('PT_VOLUME_ID2')) + // if (!actorEntry?.actor) return + + // const preset = rgbPresetName === 'hsv' ? vtkColorMaps.getPresetByName(rgbPresetName) : getColormap(rgbPresetName) + // const cfun = vtkColorTransferFunction.newInstance() + // const rgbPoints = preset?.RGBPoints + // if (Array.isArray(rgbPoints)) { + // for (let i = 0; i < rgbPoints.length; i += 4) { + // cfun.addRGBPoint(rgbPoints[i], rgbPoints[i + 1], rgbPoints[i + 2], rgbPoints[i + 3]) + // } + // } + // cfun.setMappingRange(0, 5) + // actorEntry.actor.getProperty().setRGBTransferFunction(0, cfun) + + // const ofun = vtkPiecewiseFunction.newInstance() + // ofun.addPoint(0, 0.0) + // ofun.addPoint(0.1, 0.9) + // ofun.addPoint(5, 1.0) + // actorEntry.actor.getProperty().setScalarOpacity(0, ofun) + + // viewport.render() + // }, async setColorMap(rgbPresetName) { this.rgbPresetName = rgbPresetName - let viewports = ['FUSION_AXIAL', 'PT_AXIAL', 'PET_MIP_CORONAL'] + let viewports = ['FUSION_AXIAL'] viewports.map(v => { this.$refs[v] && this.$refs[v].setPreset(this.rgbPresetName) - const renderingEngine = getRenderingEngine(renderingEngineId) - - const viewport = ( - renderingEngine.getViewport(v) - ) - - if (!viewport) return + this.$refs[v] && this.$refs[v].setColorMap(rgbPresetName) - const volumeId = v === 'FUSION_AXIAL' ? ptVolumeId2 : ptVolumeId - viewport.setProperties({ colormap: { name: rgbPresetName } }, volumeId) - viewport.render() }) }, upperRangeChange(v) { - if (this.lastUpper === v) return; - this.lastUpper = v; + if (this.upper === v) return this.upper = v; if (v === 0) { @@ -1918,17 +1940,24 @@ export default { // document.onselectstart = function() { return false }// 解决拖动会选中文字的问题 // document.ondragstart = function() { return false } }, - setWwwc(v) { - // this.changeMapperRange(v.wc, v.ww) - const renderingEngine = getRenderingEngine(renderingEngineId) - let viewportId = this.activeIndex === 1 ? 'CT_AXIAL' : this.activeIndex === 2 ? 'PT_AXIAL' : this.activeIndex === 3 ? 'FUSION_AXIAL' : 'PET_MIP_CORONAL' - const viewport = renderingEngine.getViewport(viewportId) - const lower = v.wc - v.ww / 2 - const upper = v.wc + v.ww / 2 - 1 - viewport.setProperties({ voiRange: { upper: upper, lower: lower } }) - viewport.render() - this.customWwc.visible = false - }, + // setWwwc(v) { + // // this.changeMapperRange(v.wc, v.ww) + // const renderingEngine = getRenderingEngine(renderingEngineId) + // let viewportId = this.activeIndex === 1 ? 'CT_AXIAL' : this.activeIndex === 2 ? 'PT_AXIAL' : this.activeIndex === 3 ? 'FUSION_AXIAL' : 'PET_MIP_CORONAL' + // const viewport = renderingEngine.getViewport(viewportId) + // const lower = v.wc - v.ww / 2 + // const upper = v.wc + v.ww / 2 - 1 + // viewport.setProperties({ voiRange: { upper: upper, lower: lower } }) + // viewport.render() + // if (viewportId !== 'CT_AXIAL') { + // const nextUpper = Math.round(upper) + // this.upper = nextUpper + // if (this.$refs.colorMap) { + // this.$refs.colorMap.changeVoi(nextUpper) + // } + // } + // this.customWwc.visible = false + // }, changeMapperRange(wc, ww) { var lower = wc - ww / 2.0 var upper = wc + ww / 2.0 diff --git a/src/views/trials/trials-panel/reading/dicoms/components/Fusion/Viewport.vue b/src/views/trials/trials-panel/reading/dicoms/components/Fusion/Viewport.vue index 3fee5373..2e38d02c 100644 --- a/src/views/trials/trials-panel/reading/dicoms/components/Fusion/Viewport.vue +++ b/src/views/trials/trials-panel/reading/dicoms/components/Fusion/Viewport.vue @@ -208,7 +208,6 @@ export default { mounted() { const digitPlaces = parseInt(this.$route.query.digitPlaces) this.digitPlaces = digitPlaces === -1 ? 2 : digitPlaces - console.log(toolsUtilities) this.subjectCode = this.$route.query.subjectCode var element = document.getElementById(`viewport${this.index}`) element.addEventListener(VOLUME_NEW_IMAGE, this.handleVolumeNewImage) @@ -346,8 +345,8 @@ export default { upper ) this.imageInfo.wwwc = `${Math.round(windowWidth)}/${Math.round(windowCenter)}` - // 当为PT或融合视口时,触发外部联动 - if (this.index !== 1 && this.index !== 4) { + // 当为PT或融合视口或MIP视口时,触发外部联动 (排除纯CT视口) + if (this.index !== 1) { this.$emit('upperRangeChange', Math.round(upper)) } } @@ -579,6 +578,13 @@ export default { ctx.fillStyle = gradient ctx.fillRect(0, 0, rectWidth, rectHeight) }, + setColorMap(presetName) { + const renderingEngine = getRenderingEngine(this.renderingEngineId) + const viewport = renderingEngine.getViewport(this.viewportId) + let volumeId = `cornerstoneStreamingImageVolume:PT_VOLUME_ID` + viewport.setProperties({ colormap: { name: presetName } }, volumeId) + viewport.render() + }, setWwWc() { let properties = viewport.getProperties() if (this.index === 3) { @@ -594,8 +600,8 @@ export default { upper ) this.imageInfo.wwwc = `${Math.round(windowWidth)}/${Math.round(windowCenter)}` - // 当为PT或融合视口时,触发外部联动 - if (this.index !== 1 && this.index !== 4) { + // 当为PT或融合视口或MIP视口时,触发外部联动 (排除纯CT视口) + if (this.index !== 1) { this.$emit('upperRangeChange', Math.round(upper)) } } diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue index dbb838bd..db172336 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue @@ -757,7 +757,9 @@ export default { }, }, }, - fusionOverlayModality: null + fusionOverlayModality: null, + lastUpper: null, + hasFusionUpperInitialized: false } }, computed: { @@ -3730,11 +3732,14 @@ export default { return pairs.map((p) => p.imageId); }, upperRangeChange(upper) { + if (!this.hasFusionUpperInitialized) { + if (!upper) return + this.hasFusionUpperInitialized = true + } if (this.lastUpper === upper) return; this.lastUpper = upper; if (this.$refs.colorMap) { - this.$refs.colorMap.upper = upper - this.$refs.colorMap.upperRangeChange(upper) + this.$refs.colorMap.changeVoi(upper) } this.voiChange(upper) }, diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/colorMap.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/colorMap.vue index 0660843c..703d6b50 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/colorMap.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/colorMap.vue @@ -74,6 +74,7 @@ export default { rgbPresetName: 'siemens', range: 40, upper: 6, + isSlideMoving: false, } }, mounted() { @@ -86,9 +87,24 @@ export default { this.renderColorMaps() this.upperRangeChange(this.range) this.initSlider() + this.syncSliderPosition() }) }, methods: { + syncSliderPosition(retry = 0) { + var sliderBox = document.getElementById('sliderBox') + var container = document.getElementById('colorBarCanvas') + if (!sliderBox || !container) return + + var maxLeft = container.clientWidth - sliderBox.clientWidth + if (maxLeft <= 0) { + if (retry < 30) { + requestAnimationFrame(() => this.syncSliderPosition(retry + 1)) + } + return + } + this.updateSliderPosition() + }, renderColorMaps() { this.createColorBar(this.rgbPresetName, 'colorBarCanvas', 256, 15) this.colorMaps.forEach((e, index) => { @@ -101,20 +117,25 @@ export default { changeVoi(v) { // 被外部组件调窗同步时调用 if (v === this.upper) return - - // 如果传入的阈值超过了当前输入框设置的最大值,更新 range 为传入值,滑块自动到最右侧 - if (v > this.range) { - this.range = v - this.upper = v - } else { - this.upper = v + + var range = Number(this.range) || 0 + var upper = Number(v) || 0 + if (range <= 0) { + upper = 0 + } else if (upper > range) { + upper = range + } else if (upper < 0) { + upper = 0 } - this.updateSliderPosition() + this.upper = upper + this.syncSliderPosition() }, initSlider() { var slider = document.getElementById('slider') var sliderBox = document.getElementById('sliderBox') var container = document.getElementById('colorBarCanvas') + if (!slider || !sliderBox || !container) return + slider.addEventListener('mousedown', () => { this.isSlideMoving = true }) @@ -123,6 +144,8 @@ export default { var containerWidth = container.clientWidth var sliderWidth = sliderBox.clientWidth var maxLeft = containerWidth - sliderWidth + if (maxLeft <= 0) return + var left = e.clientX - container.getBoundingClientRect().left var position = null position = left @@ -136,10 +159,12 @@ export default { slider.style.left = left + 'px' var positionValue = document.getElementById('slider-position') - var upper = this.range + var upper = Number(this.range) || 0 position = parseInt((position / maxLeft) * upper) + if (position > upper) position = upper + if (position < 0) position = 0 if (this.modality === 'NM') { - positionValue.textContent = Math.round((position / upper) * 100) + '%' + positionValue.textContent = upper > 0 ? Math.round((position / upper) * 100) + '%' : '0%' } else { positionValue.textContent = position } @@ -153,13 +178,28 @@ export default { }, updateSliderPosition() { var sliderBox = document.getElementById('sliderBox') - var colorBarContainer = document.getElementById('colorBar') - if (!sliderBox || !colorBarContainer) return + var container = document.getElementById('colorBarCanvas') + if (!sliderBox || !container) return - var containerWidth = colorBarContainer.clientWidth + var containerWidth = container.clientWidth var sliderWidth = sliderBox.clientWidth var maxLeft = containerWidth - sliderWidth - var left = (this.upper / this.range) * maxLeft + if (maxLeft <= 0) return + + var range = Number(this.range) || 0 + var upper = Number(this.upper) || 0 + if (range <= 0) { + upper = 0 + } else if (upper > range) { + upper = range + } else if (upper < 0) { + upper = 0 + } + if (upper !== this.upper) { + this.upper = upper + } + + var left = range > 0 ? (upper / range) * maxLeft : 0 if (left < 0) { left = 0 } else if (left >= maxLeft) { @@ -167,40 +207,32 @@ export default { } var slider = document.getElementById('slider') if (slider) { - slider.style.left = left + 'px' + slider.style.left = (left + 6) + 'px' } var positionValue = document.getElementById('slider-position') if (positionValue) { if (this.modality === 'NM') { - positionValue.textContent = Math.round((this.upper / this.range) * 100) + '%' + positionValue.textContent = range > 0 ? Math.round((upper / range) * 100) + '%' : '0%' } else { - positionValue.textContent = this.upper + positionValue.textContent = upper } } }, upperRangeChange(v) { - if (v === 0 || v < this.upper) { + if (this.upper === v) return + var nextRange = Number(v) || 0 + if (nextRange <= 0) { + this.upper = 0 + this.updateSliderPosition() + this.voiChange(0) return } - var sliderBox = document.getElementById('sliderBox') - var container = document.getElementById('colorBarCanvas') - var containerWidth = container.clientWidth - var sliderWidth = sliderBox.clientWidth - var maxLeft = containerWidth - sliderWidth - var left = (this.upper / this.range) * maxLeft - if (left < 0) { - left = 6 - } else if (left >= maxLeft) { - left = maxLeft + 6 - } - var slider = document.getElementById('slider') - slider.style.left = left + 'px' - var positionValue = document.getElementById('slider-position') - if (this.modality === 'NM') { - positionValue.textContent = Math.round((this.upper / this.range) * 100) + '%' - } else { - positionValue.textContent = this.upper + this.range = nextRange + if (this.upper > nextRange) { + this.upper = nextRange + this.voiChange(this.upper) } + this.syncSliderPosition() }, createColorBar(rgbPresetName, elId, width, height) { var colorMap = null @@ -247,6 +279,7 @@ export default { init() { this.createColorBar(this.rgbPresetName, 'colorBarCanvas', 256, 15) this.$emit("setColorMap", this.rgbPresetName) + this.syncSliderPosition() } } }