906 lines
30 KiB
Vue
906 lines
30 KiB
Vue
<template>
|
|
<div ref="dicom-wrapper" class="dicom-wrapper">
|
|
<div ref="dicomViewer" class="dicom-viewer">
|
|
<!-- <div v-for="i in layoutRow" :key="i" class="dicom-row" :style="{height: rowHeight}">
|
|
<div v-for="j in layoutCol" :key="j" class="dicom-item" oncontextmenu="return false">
|
|
<dicom-canvas ref="dicomCanvas" style="width:100%;height:100%" />
|
|
</div>
|
|
</div>-->
|
|
|
|
<div v-show="layoutRow>=1" class="dicom-row" :style="{height: rowHeight}">
|
|
<div
|
|
v-show="layoutRow>=1&&layoutCol>=1"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas0'}"
|
|
data-index="0"
|
|
@click="activateDicomCanvas(0)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas
|
|
ref="dicomCanvas0"
|
|
style="width:100%;height:100%"
|
|
/>
|
|
</div>
|
|
<div
|
|
v-show="layoutRow>=1&&layoutCol>=2"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas1'}"
|
|
data-index="1"
|
|
@click="activateDicomCanvas(1)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas ref="dicomCanvas1" style="width:100%;height:100%" />
|
|
</div>
|
|
<div
|
|
v-show="layoutRow>=1&&layoutCol>=3"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas2'}"
|
|
data-index="2"
|
|
@click="activateDicomCanvas(2)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas ref="dicomCanvas2" style="width:100%;height:100%" />
|
|
</div>
|
|
</div>
|
|
|
|
<div v-show="layoutRow>=2" class="dicom-row" :style="{height: rowHeight}">
|
|
<div
|
|
v-show="layoutRow>=2&&layoutCol>=1"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas3'}"
|
|
data-index="3"
|
|
@click="activateDicomCanvas(3)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas ref="dicomCanvas3" style="width:100%;height:100%" />
|
|
</div>
|
|
<div
|
|
v-show="layoutRow>=2&&layoutCol>=2"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas4'}"
|
|
data-index="4"
|
|
@click="activateDicomCanvas(4)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas ref="dicomCanvas4" style="width:100%;height:100%" />
|
|
</div>
|
|
<div
|
|
v-show="layoutRow>=2&&layoutCol>=3"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas5'}"
|
|
data-index="5"
|
|
@click="activateDicomCanvas(5)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas ref="dicomCanvas5" style="width:100%;height:100%" />
|
|
</div>
|
|
</div>
|
|
|
|
<div v-show="layoutRow==3" class="dicom-row" :style="{height: rowHeight}">
|
|
<div
|
|
v-show="layoutRow==3&&layoutCol>=1"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas6'}"
|
|
data-index="6"
|
|
@click="activateDicomCanvas(6)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas ref="dicomCanvas6" style="width:100%;height:100%" />
|
|
</div>
|
|
<div
|
|
v-show="layoutRow==3&&layoutCol>=2"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas7'}"
|
|
data-index="7"
|
|
@click="activateDicomCanvas(7)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas ref="dicomCanvas7" style="width:100%;height:100%" />
|
|
</div>
|
|
<div
|
|
v-show="layoutRow==3&&layoutCol>=3"
|
|
class="dicom-item"
|
|
:class="{'activeItem':activeItem=='dicomCanvas8'}"
|
|
data-index="8"
|
|
@click="activateDicomCanvas(8)"
|
|
@dblclick="setFullScreen($event)"
|
|
>
|
|
<dicom-canvas ref="dicomCanvas8" style="width:100%;height:100%" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div ref="dicomTools" class="dicom-tools">
|
|
<!-- 布局 -->
|
|
<div class="measureTool-wrapper">
|
|
<div class="sideTool-title">{{ $t('trials:reading:button:layout') }}</div>
|
|
<div class="sideTool-wrapper">
|
|
<label>{{ $t('trials:reading:button:layout') }}:</label>
|
|
<select class="sidetool-select" style="width:90px" @change="changeLayout($event)">
|
|
<option value="1x1" selected>1x1</option>
|
|
<option value="1x2">1x2</option>
|
|
<option value="2x1">2x1</option>
|
|
<option value="2x2">2x2</option>
|
|
<option value="1x3">1x3</option>
|
|
<option value="3x1">3x1</option>
|
|
<option value="2x3">2x3</option>
|
|
<option value="3x2">3x2</option>
|
|
<option value="3x3">3x3</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<!-- 图像变换 -->
|
|
<div class="measureTool-wrapper">
|
|
<div class="sideTool-title">{{ $t('trials:dicom-show:transform') }}</div>
|
|
<div class="sideTool-wrapper">
|
|
<button
|
|
:title="$t('trials:reading:button:wwwc')"
|
|
class="btn-link"
|
|
data-tool="Wwwc"
|
|
@click="setToolActive($event,'Wwwc')"
|
|
>
|
|
<svg-icon icon-class="reverse" style="font-size:20px;" />
|
|
</button>
|
|
<!-- <button
|
|
title="区域调窗"
|
|
class="btn-link"
|
|
data-tool="WwwcRegion"
|
|
@click="setToolActive($event,'WwwcRegion')"
|
|
>
|
|
<svg-icon icon-class="wwwcRegion" style="font-size:20px;" />
|
|
</button> -->
|
|
<button
|
|
:title="$t('trials:reading:button:reverseColor')"
|
|
class="btn-link"
|
|
@click="toggleInvert"
|
|
>
|
|
<svg-icon icon-class="reversecolor" style="font-size:20px;" />
|
|
</button>
|
|
<button :title="$t('trials:reading:button:zoom')" class="btn-link" data-tool="Zoom" @click="setToolActive($event,'Zoom')">
|
|
<svg-icon icon-class="magnifier" style="font-size:20px;" />
|
|
</button>
|
|
<button :title="$t('trials:dicom-show:lens')" class="btn-link" data-tool="Magnify" @click="setToolActive($event,'Magnify')">
|
|
<svg-icon icon-class="zoom" style="font-size:20px;" />
|
|
</button>
|
|
<button :title="$t('trials:reading:button:rotate')" class="btn-link dropdown" data-tool="Rotate">
|
|
<svg-icon icon-class="rotate" style="font-size:20px;" />
|
|
<div class="dropdown-content">
|
|
<div @click.stop="setDicomCanvasRotate(1)">{{ $t('trials:reading:button:rotateDefault') }}</div>
|
|
<div @click.stop="setDicomCanvasRotate(2)">{{ $t('trials:reading:button:rotateHorizontal') }}</div>
|
|
<div @click.stop="setDicomCanvasRotate(3)">{{ $t('trials:reading:button:rotateVertical') }}</div>
|
|
<div @click.stop="setDicomCanvasRotate(4)">{{ $t('trials:reading:button:rotateTurnLeft') }}</div>
|
|
<div @click.stop="setDicomCanvasRotate(5)">{{ $t('trials:reading:button:rotateTurnRight') }}</div>
|
|
</div>
|
|
</button>
|
|
<button :title="$t('trials:reading:button:move')" class="btn-link" data-tool="Pan" @click="setToolActive($event,'Pan')">
|
|
<svg-icon icon-class="move" style="font-size:20px;" />
|
|
</button>
|
|
<button :title="$t('trials:reading:button:fitWindow')" class="btn-link" data-tool="fitToWindow" @click="fitToType($event,'fitToWindow')">
|
|
<svg-icon icon-class="fitToWindow" style="font-size:20px;" />
|
|
</button>
|
|
<button :title="$t('trials:reading:button:fitImage')" class="btn-link" data-tool="fitToImage" @click="fitToType($event,'fitToImage')">
|
|
<svg-icon icon-class="fitToImage" style="font-size:20px;" />
|
|
</button>
|
|
<!-- <button title="旋转" class="btn-link dropdown" data-tool="Rotate" @click="setToolActive($event,'Rotate')"> -->
|
|
|
|
</div>
|
|
</div>
|
|
<!-- 测量标注 -->
|
|
<div class="measureTool-wrapper">
|
|
<div class="sideTool-title">{{ $t('trials:dicom-show:measurementLabeling') }}</div>
|
|
<div class="sideTool-wrapper">
|
|
<!-- 探针 -->
|
|
<button :title="$t('trials:dicom-show:Probe')" class="btn-link" data-tool="Probe" @click="setToolActive($event,'Probe')">
|
|
<svg-icon icon-class="pixel" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 长度测量 -->
|
|
<button :title="$t('trials:dicom-show:Length')" class="btn-link" data-tool="Length" @click="setToolActive($event,'Length')">
|
|
<svg-icon icon-class="length" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 角度测量 -->
|
|
<button :title="$t('trials:dicom-show:Angle')" class="btn-link" data-tool="Angle" @click="setToolActive($event,'Angle')">
|
|
<svg-icon icon-class="angle" style="font-size:20px;" />
|
|
</button>
|
|
<!-- Cobb测量 -->
|
|
<button :title="$t('trials:dicom-show:CobbAngle')" class="btn-link" data-tool="CobbAngle" @click="setToolActive($event,'CobbAngle')">
|
|
<svg-icon icon-class="cobb" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 椭圆测量 -->
|
|
<button :title="$t('trials:dicom-show:EllipticalRoi')" class="btn-link" data-tool="EllipticalRoi" @click="setToolActive($event,'EllipticalRoi')">
|
|
<svg-icon icon-class="oval" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 矩形测量 -->
|
|
<button :title="$t('trials:dicom-show:RectangleRoi')" class="btn-link" data-tool="RectangleRoi" @click="setToolActive($event,'RectangleRoi')">
|
|
<svg-icon icon-class="rectangle" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 多边形标记 -->
|
|
<button :title="$t('trials:dicom-show:FreehandRoi')" class="btn-link" data-tool="FreehandRoi" @click="setToolActive($event,'FreehandRoi')">
|
|
<svg-icon icon-class="polygon" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 十字线 -->
|
|
<button :title="$t('trials:dicom-show:Bidirectional')" class="btn-link" data-tool="Bidirectional" @click="setToolActive($event,'Bidirectional')">
|
|
<svg-icon icon-class="bidirection" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 文字标注 -->
|
|
<button :title="$t('trials:dicom-show:ArrowAnnotate')" class="btn-link" data-tool="ArrowAnnotate" @click="setToolActive($event,'ArrowAnnotate')">
|
|
<svg-icon icon-class="label" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 清除测量和标记 -->
|
|
<button :title="$t('trials:dicom-show:Eraser')" class="btn-link" data-tool="Eraser" @click="setToolActive($event,'Eraser')">
|
|
<svg-icon icon-class="clear" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 截屏 -->
|
|
<button :title="$t('trials:dicom-show:image')" class="btn-link" @click="currentDicomCanvas.saveImage()">
|
|
<svg-icon icon-class="image" style="font-size:20px;" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="measureTool-wrapper">
|
|
<!-- 播放 -->
|
|
<div class="sideTool-title">{{ $t('trials:dicom-show:play') }}</div>
|
|
<div class="sideTool-wrapper">
|
|
<!-- 第一帧 -->
|
|
<button class="btn-link" :title="$t('trials:dicom-show:firstframe')" @click="currentDicomCanvas.scrollPage(-9999)">
|
|
<svg-icon icon-class="firstframe" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 显示上一张影像 -->
|
|
<button class="btn-link" :title="$t('trials:dicom-show:previousframe')" @click="currentDicomCanvas.scrollPage(-1)">
|
|
<svg-icon icon-class="previousframe" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 播放 -->
|
|
<button class="btn-link" :title="$t('trials:dicom-show:play')" @click="clipPlay">
|
|
<svg-icon
|
|
:icon-class="currentDicomCanvas.toolState.clipPlaying ? 'stop' : 'play'"
|
|
style="font-size:20px;"
|
|
/>
|
|
</button>
|
|
<!-- 下一帧 -->
|
|
<button class="btn-link" :title="$t('trials:dicom-show:nextframe')" @click="currentDicomCanvas.scrollPage(1)">
|
|
<svg-icon icon-class="nextframe" style="font-size:20px;" />
|
|
</button>
|
|
<!-- 最后一帧 -->
|
|
<button class="btn-link" :title="$t('trials:dicom-show:lastframe')" @click="currentDicomCanvas.scrollPage(9999)">
|
|
<svg-icon icon-class="lastframe" style="font-size:20px;" />
|
|
</button>
|
|
<select v-model="fps" class="sidetool-select" style="width:60px" @change="setDicomCanvasfps($event)">
|
|
<!-- 默认值 -->
|
|
<option :value="5">5</option>
|
|
<option :value="10">10</option>
|
|
<option :value="15">15</option>
|
|
<option :value="20">20</option>
|
|
<option :value="30">30</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="measureTool-wrapper">
|
|
<!-- 颜色 -->
|
|
<div class="sideTool-title">{{ $t('trials:dicom-show:color') }}</div>
|
|
<div class="sideTool-wrapper">
|
|
<!-- 预设窗位值 -->
|
|
<label>{{ $t('trials:dicom-show:dicomCanvasWwwc') }}:</label>
|
|
<select
|
|
v-model="wwwcList[currentDicomCanvasIndex]"
|
|
class="sidetool-select"
|
|
style="width:100px"
|
|
@change="setDicomCanvasWwwc($event)"
|
|
>
|
|
<!-- 默认值 -->
|
|
<option :value="-1">{{ $t('trials:dicom-show:default') }}</option>
|
|
<!-- 自定义 -->
|
|
<option :value="0">{{ $t('trials:dicom-show:custom') }}</option>
|
|
<!-- 区域窗宽 -->
|
|
<option :value="1" style="border-bottom:1px solid #fff;">{{ $t('trials:reading:button:wwwcRegion') }}</option>
|
|
<option :value="2">
|
|
CT Abdomen
|
|
</option>
|
|
<option :value="3">
|
|
CT Angio
|
|
</option>
|
|
<option :value="4">
|
|
CT Bone
|
|
</option>
|
|
<option :value="5">
|
|
CT Brain
|
|
</option>
|
|
<option :value="6">
|
|
CT Chest
|
|
</option>
|
|
<option :value="7">
|
|
CT Lungs
|
|
</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="sideTool-wrapper">
|
|
<!-- 伪彩色 -->
|
|
<label>{{ $t('trials:dicom-show:pseudocolor') }}:</label>
|
|
<select
|
|
v-model="colorList[currentDicomCanvasIndex]"
|
|
class="sidetool-select"
|
|
style="width:90px"
|
|
@change="setColormap($event)"
|
|
>
|
|
<!-- 默认值 -->
|
|
<option value>{{ $t('trials:dicom-show:default') }}</option>
|
|
<option
|
|
v-for="(item,index) in colormapsList"
|
|
:key="index"
|
|
:value="item.id"
|
|
>{{ item.name }}</option>
|
|
</select>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<el-dialog
|
|
v-if="customWwc.visible"
|
|
:visible.sync="customWwc.visible"
|
|
:close-on-click-modal="false"
|
|
:title="customWwc.title"
|
|
width="400px"
|
|
custom-class="base-dialog-wrapper"
|
|
append-to-body
|
|
>
|
|
<CustomWwwcForm @close="customWwc.visible = false" @setWwwc="setWwwc" />
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import DicomCanvas from './DicomCanvas'
|
|
import CustomWwwcForm from './CustomWwwcForm'
|
|
import * as cornerstone from 'cornerstone-core'
|
|
import * as cornerstoneMath from 'cornerstone-math'
|
|
import * as cornerstoneTools from 'cornerstone-tools'
|
|
import Hammer from 'hammerjs'
|
|
// cornerstone.imageCache.setMaximumSizeBytes(0)
|
|
|
|
cornerstoneTools.external.cornerstone = cornerstone
|
|
cornerstoneTools.external.Hammer = Hammer
|
|
cornerstoneTools.external.cornerstoneMath = cornerstoneMath
|
|
import '@/utils/dialog'
|
|
|
|
export default {
|
|
name: 'DicomsViewer',
|
|
components: {
|
|
DicomCanvas,
|
|
CustomWwwcForm
|
|
},
|
|
data() {
|
|
return {
|
|
activeTool: '',
|
|
activeItem: 'dicomCanvas0',
|
|
layoutRow: 1,
|
|
layoutCol: 1,
|
|
currentDicomCanvasIndex: 0,
|
|
currentDicomCanvas: {
|
|
toolState: {
|
|
clipPlaying: false
|
|
}
|
|
},
|
|
rowHeight: '100%',
|
|
sync: {
|
|
Wwwc: null
|
|
},
|
|
colormapsList: [],
|
|
rotateList: [],
|
|
colorList: [],
|
|
wwwcList: [],
|
|
layout: null,
|
|
seriesList: [],
|
|
customWwc: { visible: false, title: null },
|
|
fps: 15
|
|
}
|
|
},
|
|
mounted() {
|
|
this.customWwc = { visible: false, title: this.$t('DicomViewer:data:customWwc') }
|
|
this.rotateList[0] = '1'
|
|
this.colorList[0] = ''
|
|
this.wwwcList[0] = '-1'
|
|
this.colormapsList = cornerstone.colors.getColormapsList()
|
|
this.currentDicomCanvas = this.$refs['dicomCanvas0']
|
|
},
|
|
|
|
methods: {
|
|
loadImageStack(dicomSeries) {
|
|
this.currentDicomCanvas.toolState.clipPlaying = false
|
|
this.$nextTick(() => {
|
|
this.currentDicomCanvas.loadImageStack(dicomSeries)
|
|
})
|
|
},
|
|
loadOtherImageStack(seriesList) {
|
|
this.$nextTick(() => {
|
|
this.seriesList = seriesList
|
|
const elements = document.querySelectorAll('.dicom-item')
|
|
Array.from(elements).forEach((element, index) => {
|
|
const canvasIndex = element.getAttribute('data-index')
|
|
if (index < seriesList.length && element.style.display !== 'none') {
|
|
this.$refs[`dicomCanvas${canvasIndex}`].loadImageStack(seriesList[index])
|
|
}
|
|
})
|
|
})
|
|
},
|
|
activateDicomCanvas(index) {
|
|
if (index !== this.currentDicomCanvasIndex) {
|
|
this.currentDicomCanvasIndex = index
|
|
this.currentDicomCanvas = this.$refs[`dicomCanvas${index}`]
|
|
this.currentDicomCanvas.tabIndex = 0
|
|
this.activeItem = `dicomCanvas${index}`
|
|
if (this.sync.ReferenceLines) {
|
|
if (this.sync['ReferenceLines']) {
|
|
const elements = this.sync['ReferenceLines'].getSourceElements()
|
|
if (elements.length > 0) {
|
|
this.$refs[`dicomCanvas${index}`].removeTarget(
|
|
this.sync['ReferenceLines']
|
|
)
|
|
this.sync['ReferenceLines'].addTarget(elements[0])
|
|
this.sync['ReferenceLines'].removeSource(elements[0])
|
|
this.$refs[`dicomCanvas${index}`].addSourceElement(
|
|
this.sync['ReferenceLines']
|
|
)
|
|
}
|
|
}
|
|
}
|
|
if (!this.rotateList[this.currentDicomCanvasIndex]) {
|
|
this.rotateList[this.currentDicomCanvasIndex] = '1'
|
|
}
|
|
if (!this.colorList[this.currentDicomCanvasIndex]) {
|
|
this.colorList[this.currentDicomCanvasIndex] = ''
|
|
}
|
|
if (!this.wwwcList[this.currentDicomCanvasIndex]) {
|
|
this.wwwcList[this.currentDicomCanvasIndex] = '-1'
|
|
}
|
|
}
|
|
},
|
|
changeLayout(event) {
|
|
const arr = event.target.value.split('x')
|
|
this.layoutRow = parseInt(arr[0])
|
|
this.layoutCol = parseInt(arr[1])
|
|
this.rowHeight = 100 / this.layoutRow + '%'
|
|
this.$forceUpdate()
|
|
this.$nextTick(() => {
|
|
const elements = document.querySelectorAll('.cornerstone-element')
|
|
Array.from(elements).forEach((element) => {
|
|
cornerstone.enable(element)
|
|
cornerstone.resize(element)
|
|
})
|
|
})
|
|
},
|
|
setFullScreen(e) {
|
|
if (this.layoutRow === 1 && this.layoutCol === 1) return
|
|
if (this.layout) {
|
|
e.currentTarget.classList.remove('dicom-item-fullscreen')
|
|
const arr = this.layout.split('x')
|
|
this.layoutRow = parseInt(arr[0])
|
|
this.layoutCol = parseInt(arr[1])
|
|
this.rowHeight = 100 / this.layoutRow + '%'
|
|
this.$forceUpdate()
|
|
this.$nextTick(() => {
|
|
const elements = document.querySelectorAll('.cornerstone-element')
|
|
Array.from(elements).forEach((element) => {
|
|
cornerstone.enable(element)
|
|
cornerstone.resize(element)
|
|
})
|
|
})
|
|
this.layout = null
|
|
} else {
|
|
this.layout = `${this.layoutRow}x${this.layoutCol}`
|
|
e.currentTarget.classList.add('dicom-item-fullscreen')
|
|
cornerstone.enable(e.currentTarget.children[0])
|
|
cornerstone.resize(e.currentTarget.children[0])
|
|
}
|
|
},
|
|
setToolActive(e, toolName) {
|
|
const elements = document.querySelectorAll('.dicom-item')
|
|
if (e.currentTarget.classList.contains('activeTool')) {
|
|
e.currentTarget.classList.remove('activeTool')
|
|
const scope = this
|
|
Array.from(elements).forEach((element, index) => {
|
|
if (element.style.display !== 'none') {
|
|
scope.$refs[`dicomCanvas${index}`].setToolPassive(toolName)
|
|
}
|
|
})
|
|
} else {
|
|
const toolButtons = document.querySelectorAll('[data-tool]')
|
|
Array.from(toolButtons).forEach((toolBtn) => {
|
|
toolBtn.classList.remove('activeTool')
|
|
})
|
|
e.currentTarget.classList.add('activeTool')
|
|
|
|
const scope = this
|
|
Array.from(elements).forEach((element, index) => {
|
|
if (element.style.display !== 'none') {
|
|
scope.$refs[`dicomCanvas${index}`].setToolActive(toolName)
|
|
}
|
|
})
|
|
}
|
|
},
|
|
setDicomCanvasWwwc(event) {
|
|
this.wwwcList[this.currentDicomCanvasIndex] = event.target.value
|
|
const type = parseInt(event.target.value)
|
|
if (type === -1) {
|
|
// 默认值
|
|
this.currentDicomCanvas.resetWwwc()
|
|
} else if (type === 0) {
|
|
// 自定义
|
|
this.customWwc.visible = true
|
|
} else if (type === 1) {
|
|
// 区域窗宽
|
|
this.currentDicomCanvas.setToolActive('WwwcRegion')
|
|
} else if (type === 2) {
|
|
this.currentDicomCanvas.setWwwc(400, 60)
|
|
} else if (type === 3) {
|
|
this.currentDicomCanvas.setWwwc(600, 300)
|
|
} else if (type === 4) {
|
|
this.currentDicomCanvas.setWwwc(1500, 300)
|
|
} else if (type === 5) {
|
|
this.currentDicomCanvas.setWwwc(80, 40)
|
|
} else if (type === 6) {
|
|
this.currentDicomCanvas.setWwwc(400, 40)
|
|
} else if (type === 7) {
|
|
this.currentDicomCanvas.setWwwc(1500, -400)
|
|
}
|
|
},
|
|
setWwwc(v) {
|
|
this.currentDicomCanvas.setWwwc(v.ww, v.wc)
|
|
this.customWwc.visible = false
|
|
},
|
|
toggleInvert() {
|
|
this.currentDicomCanvas.toggleInvert()
|
|
},
|
|
setDicomCanvasRotate(value) {
|
|
const type = parseInt(value)
|
|
if (type === 1) {
|
|
this.currentDicomCanvas.resetRotate()
|
|
} else if (type === 2) {
|
|
this.currentDicomCanvas.setRotate(true, false, 0, type)
|
|
} else if (type === 3) {
|
|
this.currentDicomCanvas.setRotate(false, true, 0, type)
|
|
} else if (type === 4) {
|
|
this.currentDicomCanvas.setRotate(false, false, -90, type)
|
|
} else if (type === 5) {
|
|
this.currentDicomCanvas.setRotate(false, false, 90, type)
|
|
}
|
|
},
|
|
setColormap(event) {
|
|
this.colorList[this.currentDicomCanvasIndex] = event.target.value
|
|
this.currentDicomCanvas.setColormap(event.target.value)
|
|
},
|
|
setDicomCanvasfps(event) {
|
|
this.currentDicomCanvas.setFps(event.target.value)
|
|
},
|
|
clipPlay() {
|
|
this.currentDicomCanvas.setFps(this.fps)
|
|
this.currentDicomCanvas.toggleClipPlay()
|
|
},
|
|
fitToType(e, type) {
|
|
const toolButtons = document.querySelectorAll('[data-tool]')
|
|
Array.from(toolButtons).forEach((toolBtn) => {
|
|
toolBtn.classList.remove('activeTool')
|
|
})
|
|
e.currentTarget.classList.add('activeTool')
|
|
if (type === 'fitToWindow') {
|
|
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`].fitToWindow()
|
|
} else {
|
|
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`].fitToImage()
|
|
}
|
|
},
|
|
setAnnotationSync(e) {
|
|
if (this.layoutRow * this.layoutCol === 1) {
|
|
return
|
|
}
|
|
this.resetSync('annotationSync')
|
|
let isActive = true
|
|
const toolBtn = e.currentTarget
|
|
if (toolBtn.classList.contains('activeTool')) {
|
|
toolBtn.classList.remove('activeTool')
|
|
isActive = false
|
|
} else {
|
|
toolBtn.classList.add('activeTool')
|
|
}
|
|
if (!this.sync.annotationSync) {
|
|
this.sync.annotationSync = new cornerstoneTools.Synchronizer(
|
|
'cornerstoneimagerendered',
|
|
cornerstoneTools.updateImageSynchronizer
|
|
)
|
|
}
|
|
const scope = this
|
|
const elements = document.querySelectorAll('.dicom-item')
|
|
Array.from(elements).forEach((element, index) => {
|
|
if (element.style.display !== 'none') {
|
|
if (isActive) {
|
|
if (index !== scope.currentDicomCanvasIndex) {
|
|
scope.$refs[`dicomCanvas${index}`].addTargetElement(
|
|
scope.sync['annotationSync']
|
|
)
|
|
} else {
|
|
scope.$refs[`dicomCanvas${index}`].addSourceElement(
|
|
scope.sync['annotationSync']
|
|
)
|
|
}
|
|
scope.$refs[`dicomCanvas${index}`].activeAnnotationSync(
|
|
scope.sync.annotationSync
|
|
)
|
|
} else {
|
|
scope.$refs[`dicomCanvas${index}`].disabledAnnotationSync(
|
|
scope.sync.annotationSync
|
|
)
|
|
}
|
|
}
|
|
})
|
|
if (!isActive) {
|
|
scope.sync.annotationSync = null
|
|
}
|
|
},
|
|
resetSync(prop) {
|
|
for (const key in this.sync) {
|
|
if (key !== prop) {
|
|
if (this.sync[prop]) {
|
|
this.sync[prop] = null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
|
|
.dicom-wrapper {
|
|
display: flex;
|
|
}
|
|
.dicom-wrapper .case-dialog-class {
|
|
position: fixed;
|
|
left: 25%;
|
|
pointer-events: auto;
|
|
display: block;
|
|
overflow: auto;
|
|
}
|
|
|
|
.dicom-wrapper .case-dialog-div{
|
|
pointer-events: none;
|
|
|
|
}
|
|
.dicom-wrapper .case-dialog-class .el-dialog__body{
|
|
max-height:300px;
|
|
overflow-y: auto;
|
|
}
|
|
.dicom-wrapper .el-dialog__header{
|
|
padding: 15px;
|
|
}
|
|
.dicom-wrapper .el-dialog__body{
|
|
padding: 10px 20px;
|
|
}
|
|
.dicom-viewer {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
position: relative;
|
|
}
|
|
.dicom-wrapper .dicom-row {
|
|
display: flex;
|
|
flex-direction: row;
|
|
flex: 1;
|
|
width: 100%;
|
|
}
|
|
.dicom-wrapper .dicom-item {
|
|
position: relative;
|
|
width: 0;
|
|
flex: 1;
|
|
flex-shrink: 1;
|
|
box-sizing: border-box;
|
|
padding: 5px;
|
|
border: 1px solid #c8c8c8;
|
|
}
|
|
.dicom-wrapper .activeItem {
|
|
border: 2px solid chocolate;
|
|
}
|
|
.dicom-item-fullscreen {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 1;
|
|
}
|
|
.dicom-wrapper ::-webkit-scrollbar {
|
|
width: 7px;
|
|
height: 7px;
|
|
}
|
|
.dicom-wrapper ::-webkit-scrollbar-thumb {
|
|
border-radius: 10px;
|
|
background: gray;
|
|
}
|
|
.dicom-wrapper .dicom-tools {
|
|
/* display: flex;
|
|
flex-direction: column; */
|
|
width: 300px;
|
|
height: 100%;
|
|
background-color: #323232;
|
|
margin: 0;
|
|
padding: 0;
|
|
margin-left: 2px;
|
|
/* border: 1px solid blueviolet; */
|
|
color: #d0d0d0;
|
|
font-size: 13px;
|
|
overflow: hidden;
|
|
}
|
|
.dicom-wrapper .measure-wrapper{
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
overflow: hidden;
|
|
|
|
}
|
|
.measure-wrapper .measure-list{
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
}
|
|
.measure-list-header{
|
|
padding: 2px 0px;
|
|
border-bottom: 1px solid gray;
|
|
}
|
|
.measure-wrapper ul{
|
|
margin: 0;
|
|
padding: 0 5px;
|
|
list-style: none;
|
|
}
|
|
.measure-wrapper ul li{
|
|
height: 20px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 5px;
|
|
text-align: center;
|
|
}
|
|
|
|
.measure-wrapper select {
|
|
height: 20px;
|
|
background-color: rgba(0, 0, 0, 0);
|
|
/* color: #323232; */
|
|
border-radius: 4px;
|
|
font-size: 13px;
|
|
color: #606626;
|
|
}
|
|
.measure-wrapper select > option {
|
|
color: #323232;
|
|
}
|
|
/* .measure-wrapper select {
|
|
height: 20px;
|
|
background-color: rgba(0, 0, 0, 0);
|
|
color: #d0d0d0;
|
|
border-radius: 4px;
|
|
}
|
|
.measure-wrapper select > option {
|
|
background-color: #323232;
|
|
} */
|
|
.dicom-canvas {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
border: 1px solid #333333;
|
|
}
|
|
|
|
.dicom-canvas.active {
|
|
border: 1px solid #337ab7;
|
|
}
|
|
.sideTool-title {
|
|
padding: 5px 8px;
|
|
background-color: #525252;
|
|
color: #bebdbd;
|
|
font-size: 14px;
|
|
margin: 4px;
|
|
}
|
|
.sideTool-wrapper {
|
|
border-bottom: 1px solid gray;
|
|
margin: 0px 4px;
|
|
padding: 4px;
|
|
font-size: 12px;
|
|
}
|
|
.sideTool-wrapper .btn {
|
|
font-size: 12px;
|
|
}
|
|
.sidetool-select {
|
|
height: 30px;
|
|
background-color: rgba(0, 0, 0, 0);
|
|
color: #d0d0d0;
|
|
border-radius: 4px;
|
|
}
|
|
.sidetool-select > option {
|
|
background-color: #323232;
|
|
}
|
|
.sideTool-wrapper button.btn-link {
|
|
height: 40px;
|
|
padding: 8px !important;
|
|
border: 1px solid rgba(37, 37, 37, 1);
|
|
margin: 1px 1px;
|
|
}
|
|
.sideTool-wrapper .btn-link {
|
|
display: inline-block;
|
|
height: 40px;
|
|
padding: 8px !important;
|
|
border: 1px solid rgba(37, 37, 37, 1);
|
|
margin: 1px 1px;
|
|
}
|
|
.dicom-wrapper .btn-group {
|
|
position: relative;
|
|
display: inline-block;
|
|
height: 30px;
|
|
padding: 6px 3px;
|
|
vertical-align: middle;
|
|
margin: 1px 1px;
|
|
border-radius: 3px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
color: silver;
|
|
line-height: 20px !important;
|
|
background: rgba(50, 50, 50, 1);
|
|
border: 1px solid rgba(37, 37, 37, 1);
|
|
min-height: 30px;
|
|
}
|
|
.dicom-wrapper .btn-group .btn-left {
|
|
position: relative;
|
|
float: left;
|
|
padding: 1px !important;
|
|
margin-left: 0;
|
|
border-bottom-right-radius: 0;
|
|
border-top-right-radius: 0;
|
|
}
|
|
.dicom-wrapper .activeTool {
|
|
background: #16477b90 !important;
|
|
border: none;
|
|
}
|
|
.dicom-wrapper .btn-link {
|
|
color: #cccccc;
|
|
background-color: #ffffff00;
|
|
cursor: pointer;
|
|
}
|
|
.dicom-wrapper .btn-submit{
|
|
cursor: pointer;
|
|
/* background-color: #eeeeee; */
|
|
background: #eeeeee;
|
|
border: 1px solid #DCDFE6;
|
|
border-radius: 4px;
|
|
color: #606266;
|
|
font-size: 13px;
|
|
}
|
|
|
|
/* .dicom-wrapper .btn-link:hover,
|
|
.dicom-wrapper .btn-link:focus,
|
|
.dicom-wrapper .btn-link:active {
|
|
border-color: transparent;
|
|
background-color: transparent;
|
|
} */
|
|
.dicom-wrapper .iconHover:hover{
|
|
color: red;
|
|
}
|
|
.dicom-wrapper .dropdown {
|
|
position: relative;
|
|
display: inline-block;
|
|
}
|
|
.dicom-wrapper .dropdown-content {
|
|
display: none;
|
|
position: absolute;
|
|
left: 0;
|
|
top: 40px;
|
|
color: #d0d0d0;
|
|
background-color: #323232;
|
|
min-width: 80px;
|
|
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
|
border: 1px solid #4e4e4e;
|
|
padding: 5px;
|
|
}
|
|
.dicom-wrapper .dropdown:hover .dropdown-content {
|
|
display: block;
|
|
}
|
|
.dicom-wrapper .dropdown-content div{
|
|
height: 25px;
|
|
line-height: 25px;
|
|
cursor:point;
|
|
}
|
|
.dicom-wrapper .dropdown-content div:hover{
|
|
background-color: #16477b90;
|
|
}
|
|
|
|
</style>
|