阅片页面增加患者信息、检查信息
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
ae2cb2c5fb
commit
64581a3e07
|
|
@ -1,15 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div id="canvas" ref="canvas" v-loading="loading" element-loading-text="Loading..."
|
||||||
id="canvas"
|
element-loading-background="rgba(0, 0, 0, 0.8)" style="position:relative;" class="cornerstone-element"
|
||||||
ref="canvas"
|
@mouseup="sliderMouseup" @contextmenu.prevent="onContextmenu">
|
||||||
v-loading="loading"
|
|
||||||
element-loading-text="Loading..."
|
|
||||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
|
||||||
style="position:relative;"
|
|
||||||
class="cornerstone-element"
|
|
||||||
@mouseup="sliderMouseup"
|
|
||||||
@contextmenu.prevent="onContextmenu"
|
|
||||||
>
|
|
||||||
<!-- 临床数据 -->
|
<!-- 临床数据 -->
|
||||||
<div v-if="stack.isExistsClinicalData" class="info-cd" @click.stop="handleViewCD($event)">
|
<div v-if="stack.isExistsClinicalData" class="info-cd" @click.stop="handleViewCD($event)">
|
||||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:clinicalData')" placement="bottom">
|
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:clinicalData')" placement="bottom">
|
||||||
|
|
@ -18,46 +10,40 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- 切换访视 -->
|
<!-- 切换访视 -->
|
||||||
<div
|
<div v-if="stack.imageRendered && isReadingTaskViewInOrder === 1" class="info-visit"
|
||||||
v-if="stack.imageRendered && isReadingTaskViewInOrder === 1"
|
@dblclick.stop="preventDefault($event)">
|
||||||
class="info-visit"
|
<div class="arrw_div_wrapper"
|
||||||
@dblclick.stop="preventDefault($event)"
|
:style="{ cursor: stack.visitTaskNum <= minVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum <= minVistNum ? '#888' : '#fff' }"
|
||||||
>
|
@click.stop.prevent="toggleSeries($event, -1)" @dblclick.stop="preventDefault($event)">
|
||||||
<div
|
|
||||||
class="arrw_div_wrapper"
|
|
||||||
:style="{cursor:stack.visitTaskNum <= minVistNum?'not-allowed':'pointer',color:stack.visitTaskNum <= minVistNum?'#888':'#fff'}"
|
|
||||||
@click.stop.prevent="toggleSeries($event,-1)"
|
|
||||||
@dblclick.stop="preventDefault($event)"
|
|
||||||
>
|
|
||||||
<i class="el-icon-caret-left" />
|
<i class="el-icon-caret-left" />
|
||||||
</div>
|
</div>
|
||||||
<div class="blind_name_wrapper">
|
<div class="blind_name_wrapper">
|
||||||
{{ stack.taskBlindName }}
|
{{ stack.taskBlindName }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="arrw_div_wrapper"
|
||||||
class="arrw_div_wrapper"
|
:style="{ cursor: stack.visitTaskNum >= maxVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum >= maxVistNum ? '#888' : '#fff' }"
|
||||||
:style="{cursor:stack.visitTaskNum >= maxVistNum?'not-allowed':'pointer',color:stack.visitTaskNum >= maxVistNum?'#888':'#fff'}"
|
@click.stop.prevent="toggleSeries($event, 1)" @dblclick.stop="preventDefault($event)">
|
||||||
@click.stop.prevent="toggleSeries($event,1)"
|
|
||||||
@dblclick.stop="preventDefault($event)"
|
|
||||||
>
|
|
||||||
<i class="el-icon-caret-right" />
|
<i class="el-icon-caret-right" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-series">
|
<div class="info-series">
|
||||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{ stack.taskBlindName }}</h2>
|
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{
|
||||||
|
stack.taskBlindName }}</h2>
|
||||||
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
||||||
<div>Image: #{{ dicomInfo.frame }}</div>
|
<div>Image: #{{ dicomInfo.frame }}</div>
|
||||||
<div>{{ dicomInfo.modality }}</div>
|
<div>{{ dicomInfo.modality }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-image">
|
<div class="info-image">
|
||||||
<div v-show="mousePosition.mo">
|
<div v-show="mousePosition.mo">
|
||||||
Pos: {{ mousePosition.x?mousePosition.x.toFixed(0):'' }}, {{ mousePosition.y?mousePosition.y.toFixed(0):'' }}
|
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) :
|
||||||
|
'' }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
<div
|
||||||
|
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||||
HU: {{ mousePosition.mo }}
|
HU: {{ mousePosition.mo }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
||||||
SUVbw(g/ml): {{ digitPlaces === -1 ?mousePosition.suv.toFixed(3) :mousePosition.suv.toFixed(digitPlaces) }}
|
SUVbw(g/ml): {{ digitPlaces === -1 ? mousePosition.suv.toFixed(3) : mousePosition.suv.toFixed(digitPlaces) }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="mousePosition.mo">
|
<div v-else-if="mousePosition.mo">
|
||||||
Density: {{ mousePosition.mo }}
|
Density: {{ mousePosition.mo }}
|
||||||
|
|
@ -75,14 +61,20 @@
|
||||||
<div class="info-subject">
|
<div class="info-subject">
|
||||||
<div>{{ stack.description }}</div>
|
<div>{{ stack.description }}</div>
|
||||||
<!-- <div>{{ dicomInfo.hospital }}</div> -->
|
<!-- <div>{{ dicomInfo.hospital }}</div> -->
|
||||||
<!-- <div v-show="dicomInfo.pid">{{ dicomInfo.pid }}</div> -->
|
<div v-if="dicomInfo.pid">{{ dicomInfo.pid }}</div>
|
||||||
|
<div v-if="dicomInfo.patientName">{{ dicomInfo.patientName }}</div>
|
||||||
<!-- <div>{{ subjectCode }}</div> -->
|
<!-- <div>{{ subjectCode }}</div> -->
|
||||||
<!-- <div>{{ dicomInfo.sex }} {{ dicomInfo.age }}</div> -->
|
<!-- <div>{{ dicomInfo.sex }} {{ dicomInfo.age }}</div> -->
|
||||||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
<div v-if="dicomInfo.modality">{{ dicomInfo.modality }}</div>
|
||||||
|
<div v-if="dicomInfo.time">{{ dicomInfo.time }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
<div ref="sliderBox" class="my_slider_box"
|
||||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @click.stop.prevent="() => {return}" @mousedown.stop="sliderMousedown($event)" />
|
style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer"
|
||||||
|
@click.stop="goViewer($event)">
|
||||||
|
<div :style="{ top: height + '%' }"
|
||||||
|
style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move"
|
||||||
|
@click.stop.prevent="() => { return }" @mousedown.stop="sliderMousedown($event)" />
|
||||||
</div>
|
</div>
|
||||||
<div style="position: absolute;left: 50%;top: 30px;color: #f44336;transform: translateX(-50%);">
|
<div style="position: absolute;left: 50%;top: 30px;color: #f44336;transform: translateX(-50%);">
|
||||||
{{ markers.top }}
|
{{ markers.top }}
|
||||||
|
|
@ -117,7 +109,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style>
|
<style>
|
||||||
.my_slider_box:after{
|
.my_slider_box:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -20px;
|
bottom: -20px;
|
||||||
|
|
@ -152,6 +144,7 @@ import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/too
|
||||||
import invertOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/invertOrientationString'
|
import invertOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/invertOrientationString'
|
||||||
// import calculateLongestAndShortestDiameters from '@/views/trials/trials-panel/reading/dicoms/tools/Bidirectional/calculateLongestAndShortestDiameters'
|
// import calculateLongestAndShortestDiameters from '@/views/trials/trials-panel/reading/dicoms/tools/Bidirectional/calculateLongestAndShortestDiameters'
|
||||||
import calculateSUV from '@/views/trials/trials-panel/reading/dicoms/tools/calculateSUV'
|
import calculateSUV from '@/views/trials/trials-panel/reading/dicoms/tools/calculateSUV'
|
||||||
|
import { convertBytes } from '@/utils/dicom-character-set'
|
||||||
cornerstoneTools.external.cornerstone = cornerstone
|
cornerstoneTools.external.cornerstone = cornerstone
|
||||||
cornerstoneTools.external.Hammer = Hammer
|
cornerstoneTools.external.Hammer = Hammer
|
||||||
cornerstoneTools.external.cornerstoneMath = cornerstoneMath
|
cornerstoneTools.external.cornerstoneMath = cornerstoneMath
|
||||||
|
|
@ -568,7 +561,7 @@ export default {
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
|
||||||
}).catch(() => {})
|
}).catch(() => { })
|
||||||
e.stopImmediatePropagation()
|
e.stopImmediatePropagation()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
@ -1088,7 +1081,7 @@ export default {
|
||||||
var frame = imageInfo.frame
|
var frame = imageInfo.frame
|
||||||
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
|
||||||
this.stack.instanceId = instanceId
|
this.stack.instanceId = instanceId
|
||||||
|
|
||||||
const element = this.$refs.canvas
|
const element = this.$refs.canvas
|
||||||
cornerstone.enable(element)
|
cornerstone.enable(element)
|
||||||
element.tabIndex = 0
|
element.tabIndex = 0
|
||||||
|
|
@ -1141,7 +1134,7 @@ export default {
|
||||||
|
|
||||||
// const scope = this
|
// const scope = this
|
||||||
Array.from(toolButtons).forEach((toolBtn) => {
|
Array.from(toolButtons).forEach((toolBtn) => {
|
||||||
// Add the tool
|
// Add the tool
|
||||||
const toolName = toolBtn.getAttribute('data-tool')
|
const toolName = toolBtn.getAttribute('data-tool')
|
||||||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||||||
if (apiTool) {
|
if (apiTool) {
|
||||||
|
|
@ -1149,15 +1142,15 @@ export default {
|
||||||
|
|
||||||
if (!toolAlreadyAddedToElement) {
|
if (!toolAlreadyAddedToElement) {
|
||||||
if (toolName === 'Length') {
|
if (toolName === 'Length') {
|
||||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }})
|
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true } })
|
||||||
} else if (toolName === 'Bidirectional') {
|
} else if (toolName === 'Bidirectional') {
|
||||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }})
|
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true } })
|
||||||
} else if (toolName === 'ArrowAnnotate') {
|
} else if (toolName === 'ArrowAnnotate') {
|
||||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||||
} else if (toolName === 'RectangleRoi') {
|
} else if (toolName === 'RectangleRoi') {
|
||||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||||
} else {
|
} else {
|
||||||
cornerstoneTools.addToolForElement(element, apiTool)
|
cornerstoneTools.addToolForElement(element, apiTool)
|
||||||
}
|
}
|
||||||
|
|
@ -1183,10 +1176,10 @@ export default {
|
||||||
mouseButtonMask: 4
|
mouseButtonMask: 4
|
||||||
})
|
})
|
||||||
|
|
||||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||||
// }
|
// }
|
||||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||||
}
|
}
|
||||||
|
|
||||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||||
|
|
@ -1218,9 +1211,24 @@ export default {
|
||||||
ToolStateManager.clearImageIdToolState(imageId)
|
ToolStateManager.clearImageIdToolState(imageId)
|
||||||
e.detail.enabledElement.options = {}
|
e.detail.enabledElement.options = {}
|
||||||
var data = e.detail.image.data
|
var data = e.detail.image.data
|
||||||
|
const patientNameElement = data.elements.x00100010
|
||||||
|
const patientNameBytes = new Uint8Array(
|
||||||
|
data.byteArray.buffer,
|
||||||
|
patientNameElement ? patientNameElement.dataOffset : 0,
|
||||||
|
patientNameElement ? patientNameElement.length : 0
|
||||||
|
)
|
||||||
|
// 解析dicom中字符集字段与解析库不一致 2025.03.04
|
||||||
|
let SpecificCharacterSet = data.string('x00080005')
|
||||||
|
? data.string('x00080005').replace('ISO IR', 'ISO_IR')
|
||||||
|
: ''
|
||||||
|
const patientNameStr = convertBytes(
|
||||||
|
SpecificCharacterSet,
|
||||||
|
patientNameBytes
|
||||||
|
)
|
||||||
this.dicomInfo.hospital = data.string('x00080080')
|
this.dicomInfo.hospital = data.string('x00080080')
|
||||||
// this.dicomInfo.pid = data.string('x00100020')
|
this.dicomInfo.pid = data.string('x00100020')
|
||||||
this.dicomInfo.pid = data.string('x00120040')
|
this.dicomInfo.patientName = patientNameStr
|
||||||
|
// this.dicomInfo.pid = data.string('x00120040')
|
||||||
this.dicomInfo.name = data.string('x00100010')
|
this.dicomInfo.name = data.string('x00100010')
|
||||||
this.dicomInfo.age = data.string('x00101010')
|
this.dicomInfo.age = data.string('x00101010')
|
||||||
this.dicomInfo.sex = data.string('x00100040')
|
this.dicomInfo.sex = data.string('x00100040')
|
||||||
|
|
@ -1231,9 +1239,8 @@ export default {
|
||||||
data.string('x00080030')
|
data.string('x00080030')
|
||||||
)
|
)
|
||||||
this.dicomInfo.series = data.string('x00200011')
|
this.dicomInfo.series = data.string('x00200011')
|
||||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${
|
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length
|
||||||
this.stack.imageIds.length
|
}`
|
||||||
}`
|
|
||||||
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16(
|
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16(
|
||||||
'x00280010'
|
'x00280010'
|
||||||
)}`
|
)}`
|
||||||
|
|
@ -1413,9 +1420,9 @@ export default {
|
||||||
var element = cornerstone.getEnabledElement(this.canvas)
|
var element = cornerstone.getEnabledElement(this.canvas)
|
||||||
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
||||||
const dx =
|
const dx =
|
||||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||||
const dy =
|
const dy =
|
||||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||||
const length = Math.sqrt(dx * dx + dy * dy)
|
const length = Math.sqrt(dx * dx + dy * dy)
|
||||||
|
|
||||||
return length.toFixed(this.digitPlaces)
|
return length.toFixed(this.digitPlaces)
|
||||||
|
|
@ -1429,9 +1436,9 @@ export default {
|
||||||
if (imagePlane) {
|
if (imagePlane) {
|
||||||
return {
|
return {
|
||||||
rowPixelSpacing:
|
rowPixelSpacing:
|
||||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||||
colPixelSpacing:
|
colPixelSpacing:
|
||||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1482,7 +1489,7 @@ export default {
|
||||||
},
|
},
|
||||||
debounce(callback, delay) {
|
debounce(callback, delay) {
|
||||||
let timerId
|
let timerId
|
||||||
return function() {
|
return function () {
|
||||||
clearTimeout(timerId)
|
clearTimeout(timerId)
|
||||||
timerId = setTimeout(() => {
|
timerId = setTimeout(() => {
|
||||||
callback.apply(this, arguments)
|
callback.apply(this, arguments)
|
||||||
|
|
@ -1963,88 +1970,102 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.context-menu-wrapper{
|
.context-menu-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
ul{
|
|
||||||
list-style: none;
|
ul {
|
||||||
margin: 0px;
|
list-style: none;
|
||||||
padding: 0px;
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
background: #343333;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
border: 1px solid #2a2a2a;
|
||||||
|
border-radius: 3px;
|
||||||
|
height: auto;
|
||||||
|
min-height: 50px;
|
||||||
|
line-height: 1.5em;
|
||||||
|
width: 80px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
li {
|
||||||
|
padding: 2px 5px;
|
||||||
|
position: relative;
|
||||||
|
border-bottom: 1px solid #666;
|
||||||
|
|
||||||
|
div {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenu {
|
||||||
|
position: absolute;
|
||||||
|
left: 77px;
|
||||||
|
top: -1px;
|
||||||
background: #343333;
|
background: #343333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin: 0;
|
display: none;
|
||||||
border: 1px solid #2a2a2a;
|
|
||||||
border-radius: 3px;
|
|
||||||
height: auto;
|
|
||||||
min-height: 50px;
|
|
||||||
line-height: 1.5em;
|
|
||||||
width:80px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.menu{
|
|
||||||
li {
|
li {
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
position: relative;
|
|
||||||
border-bottom: 1px solid #666;
|
border-bottom: 1px solid #666;
|
||||||
div{
|
|
||||||
|
div {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.submenu{
|
|
||||||
position: absolute;
|
|
||||||
left: 77px;
|
|
||||||
top: -1px;
|
|
||||||
background: #343333;
|
|
||||||
color: #fff;
|
|
||||||
display: none;
|
|
||||||
li {
|
|
||||||
padding: 2px 5px;
|
|
||||||
border-bottom: 1px solid #666;
|
|
||||||
div{
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
.menu li:hover{
|
|
||||||
background-color: #ff5722;
|
|
||||||
.submenu{
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.menu_active{
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.menu_disabled{
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.info-visit{
|
|
||||||
position: absolute;
|
.menu li:hover {
|
||||||
left:50%;
|
background-color: #ff5722;
|
||||||
top: 5px;
|
|
||||||
transform: translateX(-50%);
|
.submenu {
|
||||||
display: flex;
|
display: block;
|
||||||
flex-direction: row;
|
|
||||||
.arrw_div_wrapper{
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
background-color: #3f3f3f;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 20px;
|
|
||||||
border-radius: 10%;
|
|
||||||
}
|
|
||||||
.blind_name_wrapper{
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
background-color: #00000057;
|
|
||||||
color: #fff;
|
|
||||||
padding:0 10px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.info-cd{
|
|
||||||
|
.menu_active {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu_disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-visit {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 5px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.arrw_div_wrapper {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #3f3f3f;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 20px;
|
||||||
|
border-radius: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blind_name_wrapper {
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
background-color: #00000057;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-cd {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
|
|
@ -2053,6 +2074,7 @@ export default {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-series {
|
.info-series {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
|
|
@ -2062,6 +2084,7 @@ export default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
/* z-index: 1; */
|
/* z-index: 1; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-image {
|
.info-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
|
|
@ -2081,6 +2104,7 @@ export default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
/* z-index: 1; */
|
/* z-index: 1; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-instance {
|
.info-instance {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
|
|
@ -2113,6 +2137,7 @@ export default {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu__item:hover {
|
.menu__item:hover {
|
||||||
color: #ff0000;
|
color: #ff0000;
|
||||||
}
|
}
|
||||||
|
|
@ -2132,11 +2157,12 @@ li:hover {
|
||||||
background-color: #e0e0e2;
|
background-color: #e0e0e2;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg-div {
|
.msg-div {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
background-color: rgba(255, 255, 255, 0.5);
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
color: #000;
|
color: #000;
|
||||||
padding: 5px 20px;
|
padding: 5px 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div id="canvas" ref="canvas" v-loading="loading" element-loading-text="Loading..."
|
||||||
id="canvas"
|
element-loading-background="rgba(0, 0, 0, 0.8)" style="position:relative;" class="cornerstone-element"
|
||||||
ref="canvas"
|
@mouseup="sliderMouseup" @contextmenu.prevent="onContextmenu">
|
||||||
v-loading="loading"
|
|
||||||
element-loading-text="Loading..."
|
|
||||||
element-loading-background="rgba(0, 0, 0, 0.8)"
|
|
||||||
style="position:relative;"
|
|
||||||
class="cornerstone-element"
|
|
||||||
@mouseup="sliderMouseup"
|
|
||||||
@contextmenu.prevent="onContextmenu"
|
|
||||||
>
|
|
||||||
<!-- 临床数据 -->
|
<!-- 临床数据 -->
|
||||||
<div v-if="stack.isExistsClinicalData" class="info-cd" @click.stop="handleViewCD($event)">
|
<div v-if="stack.isExistsClinicalData" class="info-cd" @click.stop="handleViewCD($event)">
|
||||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:clinicalData')" placement="bottom">
|
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:clinicalData')" placement="bottom">
|
||||||
|
|
@ -18,46 +10,40 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- 切换访视 -->
|
<!-- 切换访视 -->
|
||||||
<div
|
<div v-if="stack.imageRendered && isReadingTaskViewInOrder === 1" class="info-visit"
|
||||||
v-if="stack.imageRendered && isReadingTaskViewInOrder === 1"
|
@dblclick.stop="preventDefault($event)">
|
||||||
class="info-visit"
|
<div class="arrw_div_wrapper"
|
||||||
@dblclick.stop="preventDefault($event)"
|
:style="{ cursor: stack.visitTaskNum <= minVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum <= minVistNum ? '#888' : '#fff' }"
|
||||||
>
|
@click.stop.prevent="toggleSeries($event, -1)" @dblclick.stop="preventDefault($event)">
|
||||||
<div
|
|
||||||
class="arrw_div_wrapper"
|
|
||||||
:style="{cursor:stack.visitTaskNum <= minVistNum?'not-allowed':'pointer',color:stack.visitTaskNum <= minVistNum?'#888':'#fff'}"
|
|
||||||
@click.stop.prevent="toggleSeries($event,-1)"
|
|
||||||
@dblclick.stop="preventDefault($event)"
|
|
||||||
>
|
|
||||||
<i class="el-icon-caret-left" />
|
<i class="el-icon-caret-left" />
|
||||||
</div>
|
</div>
|
||||||
<div class="blind_name_wrapper">
|
<div class="blind_name_wrapper">
|
||||||
{{ stack.taskBlindName }}
|
{{ stack.taskBlindName }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="arrw_div_wrapper"
|
||||||
class="arrw_div_wrapper"
|
:style="{ cursor: stack.visitTaskNum >= maxVistNum ? 'not-allowed' : 'pointer', color: stack.visitTaskNum >= maxVistNum ? '#888' : '#fff' }"
|
||||||
:style="{cursor:stack.visitTaskNum >= maxVistNum?'not-allowed':'pointer',color:stack.visitTaskNum >= maxVistNum?'#888':'#fff'}"
|
@click.stop.prevent="toggleSeries($event, 1)" @dblclick.stop="preventDefault($event)">
|
||||||
@click.stop.prevent="toggleSeries($event,1)"
|
|
||||||
@dblclick.stop="preventDefault($event)"
|
|
||||||
>
|
|
||||||
<i class="el-icon-caret-right" />
|
<i class="el-icon-caret-right" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-series">
|
<div class="info-series">
|
||||||
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{ stack.taskBlindName }}</h2>
|
<h2 v-if="isReadingShowSubjectInfo" style="color:#f44336;padding: 5px 0px;margin: 0;">{{ subjectCode }} {{
|
||||||
|
stack.taskBlindName }}</h2>
|
||||||
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
<div v-show="dicomInfo.series">Series: #{{ dicomInfo.series }}</div>
|
||||||
<div>Image: #{{ dicomInfo.frame }}</div>
|
<div>Image: #{{ dicomInfo.frame }}</div>
|
||||||
<div>{{ dicomInfo.modality }}</div>
|
<div>{{ dicomInfo.modality }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-image">
|
<div class="info-image">
|
||||||
<div v-show="mousePosition.mo">
|
<div v-show="mousePosition.mo">
|
||||||
Pos: {{ mousePosition.x?mousePosition.x.toFixed(0):'' }}, {{ mousePosition.y?mousePosition.y.toFixed(0):'' }}
|
Pos: {{ mousePosition.x ? mousePosition.x.toFixed(0) : '' }}, {{ mousePosition.y ? mousePosition.y.toFixed(0) :
|
||||||
|
'' }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
<div
|
||||||
|
v-if="(dicomInfo.modality === 'CT' || dicomInfo.modality === 'DR' || dicomInfo.modality === 'CR') && mousePosition.mo">
|
||||||
HU: {{ mousePosition.mo }}
|
HU: {{ mousePosition.mo }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
<div v-else-if="(dicomInfo.modality === 'PT' && mousePosition.suv)">
|
||||||
SUVbw(g/ml): {{ digitPlaces === -1 ?mousePosition.suv.toFixed(3) :mousePosition.suv.toFixed(digitPlaces) }}
|
SUVbw(g/ml): {{ digitPlaces === -1 ? mousePosition.suv.toFixed(3) : mousePosition.suv.toFixed(digitPlaces) }}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="mousePosition.mo">
|
<div v-else-if="mousePosition.mo">
|
||||||
Density: {{ mousePosition.mo }}
|
Density: {{ mousePosition.mo }}
|
||||||
|
|
@ -75,14 +61,20 @@
|
||||||
<div class="info-subject">
|
<div class="info-subject">
|
||||||
<div>{{ stack.description }}</div>
|
<div>{{ stack.description }}</div>
|
||||||
<!-- <div>{{ dicomInfo.hospital }}</div> -->
|
<!-- <div>{{ dicomInfo.hospital }}</div> -->
|
||||||
<!-- <div v-show="dicomInfo.pid">{{ dicomInfo.pid }}</div> -->
|
<div v-if="dicomInfo.pid">{{ dicomInfo.pid }}</div>
|
||||||
|
<div v-if="dicomInfo.patientName">{{ dicomInfo.patientName }}</div>
|
||||||
<!-- <div>{{ subjectCode }}</div> -->
|
<!-- <div>{{ subjectCode }}</div> -->
|
||||||
<!-- <div>{{ dicomInfo.sex }} {{ dicomInfo.age }}</div> -->
|
<!-- <div>{{ dicomInfo.sex }} {{ dicomInfo.age }}</div> -->
|
||||||
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
<!-- <div v-show="dicomInfo.acc">ACC {{ dicomInfo.acc }}</div> -->
|
||||||
<!-- <div>{{ dicomInfo.time }}</div> -->
|
<div v-if="dicomInfo.modality">{{ dicomInfo.modality }}</div>
|
||||||
|
<div v-if="dicomInfo.time">{{ dicomInfo.time }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="sliderBox" class="my_slider_box" style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer" @click.stop="goViewer($event)">
|
<div ref="sliderBox" class="my_slider_box"
|
||||||
<div :style="{top: height + '%'}" style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move" @click.stop.prevent="() => {return}" @mousedown.stop="sliderMousedown($event)" />
|
style="position: absolute;right: 1px;height: calc(100% - 140px);transform: translateY(-50%);top: calc(50% - 30px);width: 10px;background: #333;cursor: pointer"
|
||||||
|
@click.stop="goViewer($event)">
|
||||||
|
<div :style="{ top: height + '%' }"
|
||||||
|
style="z-index:10;background: #9e9e9e;height: 20px;width: 100%;position: absolute;top: 0;cursor: move"
|
||||||
|
@click.stop.prevent="() => { return }" @mousedown.stop="sliderMousedown($event)" />
|
||||||
</div>
|
</div>
|
||||||
<div style="position: absolute;left: 50%;top: 30px;color: #f44336;transform: translateX(-50%);">
|
<div style="position: absolute;left: 50%;top: 30px;color: #f44336;transform: translateX(-50%);">
|
||||||
{{ markers.top }}
|
{{ markers.top }}
|
||||||
|
|
@ -117,7 +109,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style>
|
<style>
|
||||||
.my_slider_box:after{
|
.my_slider_box:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -20px;
|
bottom: -20px;
|
||||||
|
|
@ -153,6 +145,7 @@ import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/too
|
||||||
import invertOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/invertOrientationString'
|
import invertOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/invertOrientationString'
|
||||||
// import calculateLongestAndShortestDiameters from '@/views/trials/trials-panel/reading/dicoms/tools/Bidirectional/calculateLongestAndShortestDiameters'
|
// import calculateLongestAndShortestDiameters from '@/views/trials/trials-panel/reading/dicoms/tools/Bidirectional/calculateLongestAndShortestDiameters'
|
||||||
import calculateSUV from '@/views/trials/trials-panel/reading/dicoms/tools/calculateSUV'
|
import calculateSUV from '@/views/trials/trials-panel/reading/dicoms/tools/calculateSUV'
|
||||||
|
import { convertBytes } from '@/utils/dicom-character-set'
|
||||||
cornerstoneTools.external.cornerstone = cornerstone
|
cornerstoneTools.external.cornerstone = cornerstone
|
||||||
cornerstoneTools.external.Hammer = Hammer
|
cornerstoneTools.external.Hammer = Hammer
|
||||||
cornerstoneTools.external.cornerstoneMath = cornerstoneMath
|
cornerstoneTools.external.cornerstoneMath = cornerstoneMath
|
||||||
|
|
@ -560,7 +553,7 @@ export default {
|
||||||
mouseDown(e) {
|
mouseDown(e) {
|
||||||
this.image = e.detail.image
|
this.image = e.detail.image
|
||||||
var pointNearTool = this.pointNearTool(e)
|
var pointNearTool = this.pointNearTool(e)
|
||||||
if (pointNearTool) {
|
if (pointNearTool) {
|
||||||
e.stopImmediatePropagation()
|
e.stopImmediatePropagation()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
@ -572,7 +565,7 @@ export default {
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
|
||||||
}).catch(() => {})
|
}).catch(() => { })
|
||||||
e.stopImmediatePropagation()
|
e.stopImmediatePropagation()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
@ -670,7 +663,7 @@ export default {
|
||||||
this.sliderInfo.isMove = false
|
this.sliderInfo.isMove = false
|
||||||
},
|
},
|
||||||
getMeasureData() {
|
getMeasureData() {
|
||||||
console.log('getMeasureData')
|
console.log('getMeasureData')
|
||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId)
|
||||||
this.measureData = this.visitTaskList[idx].MeasureData
|
this.measureData = this.visitTaskList[idx].MeasureData
|
||||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||||
|
|
@ -887,7 +880,7 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
// cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
// cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||||
cornerstoneTools.setToolPassiveForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
cornerstoneTools.setToolPassiveForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
|
||||||
|
|
||||||
}
|
}
|
||||||
if (this.stack.instanceId.includes(data.InstanceId) && ((this.stack.isExistMutiFrames && (data.MeasureData.frame === this.stack.frame) && data.MeasureData) || (!this.stack.isExistMutiFrames && data.MeasureData))) {
|
if (this.stack.instanceId.includes(data.InstanceId) && ((this.stack.isExistMutiFrames && (data.MeasureData.frame === this.stack.frame) && data.MeasureData) || (!this.stack.isExistMutiFrames && data.MeasureData))) {
|
||||||
// console.log('renderMeasuredData', this.stack.frame,data.MeasureData.frame,this.stack.isExistMutiFrames)
|
// console.log('renderMeasuredData', this.stack.frame,data.MeasureData.frame,this.stack.isExistMutiFrames)
|
||||||
|
|
@ -989,32 +982,32 @@ export default {
|
||||||
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === toolState.data[i].uuid)
|
var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === toolState.data[i].uuid)
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
DicomEvent.$emit('setCollapseActive', this.measureData[idx])
|
DicomEvent.$emit('setCollapseActive', this.measureData[idx])
|
||||||
const measureData = {}
|
const measureData = {}
|
||||||
// var markName = this.measureData[idx].OrderMarkName
|
// var markName = this.measureData[idx].OrderMarkName
|
||||||
var markName = this.measureData[idx].MeasureData.data.remark
|
var markName = this.measureData[idx].MeasureData.data.remark
|
||||||
if (this.activeToolName === 'Eraser' && this.disabledMarks.indexOf(markName) === -1) {
|
if (this.activeToolName === 'Eraser' && this.disabledMarks.indexOf(markName) === -1) {
|
||||||
const questionInfo = this.measureData[idx]
|
const questionInfo = this.measureData[idx]
|
||||||
measureData.orderMarkName = markName
|
measureData.orderMarkName = markName
|
||||||
this.$emit('moveMeasureData', { measureData, questionInfo, orderMarkName: markName})
|
this.$emit('moveMeasureData', { measureData, questionInfo, orderMarkName: markName })
|
||||||
}
|
}
|
||||||
if ((this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) && this.activeToolName !== 'Eraser') {
|
if ((this.disabledMarks.indexOf(markName) === -1 || !this.disabledMarks) && this.activeToolName !== 'Eraser') {
|
||||||
const questionInfo = this.measureData[idx]
|
const questionInfo = this.measureData[idx]
|
||||||
const canvas = this.canvas.querySelector('canvas')
|
const canvas = this.canvas.querySelector('canvas')
|
||||||
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
|
||||||
measureData.studyId = this.stack.studyId
|
measureData.studyId = this.stack.studyId
|
||||||
measureData.seriesId = this.stack.seriesId
|
measureData.seriesId = this.stack.seriesId
|
||||||
measureData.instanceId = instanceId
|
measureData.instanceId = instanceId
|
||||||
measureData.frame = this.stack.frame ? this.stack.frame : 0
|
measureData.frame = this.stack.frame ? this.stack.frame : 0
|
||||||
measureData.data = toolState.data[i]
|
measureData.data = toolState.data[i]
|
||||||
measureData.type = toolType
|
measureData.type = toolType
|
||||||
measureData.thick = this.dicomInfo.thick
|
measureData.thick = this.dicomInfo.thick
|
||||||
measureData.location = this.dicomInfo.location
|
measureData.location = this.dicomInfo.location
|
||||||
measureData.ww = Math.round(viewport.voi.windowWidth)
|
measureData.ww = Math.round(viewport.voi.windowWidth)
|
||||||
measureData.wc = Math.round(viewport.voi.windowCenter)
|
measureData.wc = Math.round(viewport.voi.windowCenter)
|
||||||
measureData.data.active = false
|
measureData.data.active = false
|
||||||
this.$emit('modifyMeasureData', { measureData, questionInfo })
|
this.$emit('modifyMeasureData', { measureData, questionInfo })
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1115,7 +1108,7 @@ export default {
|
||||||
const toolButtons = document.querySelectorAll('[data-tool]')
|
const toolButtons = document.querySelectorAll('[data-tool]')
|
||||||
// const scope = this
|
// const scope = this
|
||||||
Array.from(toolButtons).forEach((toolBtn) => {
|
Array.from(toolButtons).forEach((toolBtn) => {
|
||||||
// Add the tool
|
// Add the tool
|
||||||
const toolName = toolBtn.getAttribute('data-tool')
|
const toolName = toolBtn.getAttribute('data-tool')
|
||||||
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
const apiTool = cornerstoneTools[`${toolName}Tool`]
|
||||||
if (apiTool) {
|
if (apiTool) {
|
||||||
|
|
@ -1123,17 +1116,17 @@ export default {
|
||||||
|
|
||||||
if (!toolAlreadyAddedToElement) {
|
if (!toolAlreadyAddedToElement) {
|
||||||
if (toolName === 'Length') {
|
if (toolName === 'Length') {
|
||||||
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }})
|
cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true } })
|
||||||
} else if (toolName === 'Bidirectional') {
|
} else if (toolName === 'Bidirectional') {
|
||||||
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
// cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces })
|
||||||
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
// , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true
|
||||||
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }})
|
cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true } })
|
||||||
} else if (toolName === 'ArrowAnnotate') {
|
} else if (toolName === 'ArrowAnnotate') {
|
||||||
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||||
} else if (toolName === 'RectangleRoi') {
|
} else if (toolName === 'RectangleRoi') {
|
||||||
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }})
|
cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } })
|
||||||
} else if (toolName === 'CircleRoi') {
|
} else if (toolName === 'CircleRoi') {
|
||||||
cornerstoneTools.addToolForElement(element, CircleRoiTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true, showMinMax: true }})
|
cornerstoneTools.addToolForElement(element, CircleRoiTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true, showMinMax: true } })
|
||||||
} else {
|
} else {
|
||||||
cornerstoneTools.addToolForElement(element, apiTool)
|
cornerstoneTools.addToolForElement(element, apiTool)
|
||||||
}
|
}
|
||||||
|
|
@ -1159,10 +1152,10 @@ export default {
|
||||||
mouseButtonMask: 4
|
mouseButtonMask: 4
|
||||||
})
|
})
|
||||||
|
|
||||||
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
// if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) {
|
||||||
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
// cornerstoneTools.addToolForElement(element, OrientationMarkersTool)
|
||||||
// }
|
// }
|
||||||
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
// cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { })
|
||||||
}
|
}
|
||||||
|
|
||||||
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
// cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip'])
|
||||||
|
|
@ -1194,9 +1187,24 @@ export default {
|
||||||
ToolStateManager.clearImageIdToolState(imageId)
|
ToolStateManager.clearImageIdToolState(imageId)
|
||||||
e.detail.enabledElement.options = {}
|
e.detail.enabledElement.options = {}
|
||||||
var data = e.detail.image.data
|
var data = e.detail.image.data
|
||||||
|
const patientNameElement = data.elements.x00100010
|
||||||
|
const patientNameBytes = new Uint8Array(
|
||||||
|
data.byteArray.buffer,
|
||||||
|
patientNameElement ? patientNameElement.dataOffset : 0,
|
||||||
|
patientNameElement ? patientNameElement.length : 0
|
||||||
|
)
|
||||||
|
// 解析dicom中字符集字段与解析库不一致 2025.03.04
|
||||||
|
let SpecificCharacterSet = data.string('x00080005')
|
||||||
|
? data.string('x00080005').replace('ISO IR', 'ISO_IR')
|
||||||
|
: ''
|
||||||
|
const patientNameStr = convertBytes(
|
||||||
|
SpecificCharacterSet,
|
||||||
|
patientNameBytes
|
||||||
|
)
|
||||||
this.dicomInfo.hospital = data.string('x00080080')
|
this.dicomInfo.hospital = data.string('x00080080')
|
||||||
// this.dicomInfo.pid = data.string('x00100020')
|
this.dicomInfo.pid = data.string('x00100020')
|
||||||
this.dicomInfo.pid = data.string('x00120040')
|
this.dicomInfo.patientName = patientNameStr
|
||||||
|
// this.dicomInfo.pid = data.string('x00120040')
|
||||||
this.dicomInfo.name = data.string('x00100010')
|
this.dicomInfo.name = data.string('x00100010')
|
||||||
this.dicomInfo.age = data.string('x00101010')
|
this.dicomInfo.age = data.string('x00101010')
|
||||||
this.dicomInfo.sex = data.string('x00100040')
|
this.dicomInfo.sex = data.string('x00100040')
|
||||||
|
|
@ -1207,9 +1215,8 @@ export default {
|
||||||
data.string('x00080030')
|
data.string('x00080030')
|
||||||
)
|
)
|
||||||
this.dicomInfo.series = data.string('x00200011')
|
this.dicomInfo.series = data.string('x00200011')
|
||||||
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${
|
this.dicomInfo.frame = `${this.stack.currentImageIdIndex + 1}/${this.stack.imageIds.length
|
||||||
this.stack.imageIds.length
|
}`
|
||||||
}`
|
|
||||||
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16(
|
this.dicomInfo.size = `${data.uint16('x00280011')}*${data.uint16(
|
||||||
'x00280010'
|
'x00280010'
|
||||||
)}`
|
)}`
|
||||||
|
|
@ -1390,9 +1397,9 @@ export default {
|
||||||
var element = cornerstone.getEnabledElement(this.canvas)
|
var element = cornerstone.getEnabledElement(this.canvas)
|
||||||
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image)
|
||||||
const dx =
|
const dx =
|
||||||
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
(data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1)
|
||||||
const dy =
|
const dy =
|
||||||
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
(data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1)
|
||||||
const length = Math.sqrt(dx * dx + dy * dy)
|
const length = Math.sqrt(dx * dx + dy * dy)
|
||||||
|
|
||||||
return length.toFixed(this.digitPlaces)
|
return length.toFixed(this.digitPlaces)
|
||||||
|
|
@ -1406,9 +1413,9 @@ export default {
|
||||||
if (imagePlane) {
|
if (imagePlane) {
|
||||||
return {
|
return {
|
||||||
rowPixelSpacing:
|
rowPixelSpacing:
|
||||||
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing,
|
||||||
colPixelSpacing:
|
colPixelSpacing:
|
||||||
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1460,7 +1467,7 @@ export default {
|
||||||
},
|
},
|
||||||
debounce(callback, delay) {
|
debounce(callback, delay) {
|
||||||
let timerId
|
let timerId
|
||||||
return function() {
|
return function () {
|
||||||
clearTimeout(timerId)
|
clearTimeout(timerId)
|
||||||
timerId = setTimeout(() => {
|
timerId = setTimeout(() => {
|
||||||
callback.apply(this, arguments)
|
callback.apply(this, arguments)
|
||||||
|
|
@ -1478,7 +1485,7 @@ export default {
|
||||||
if (imageId) {
|
if (imageId) {
|
||||||
ToolStateManager.clearImageIdToolState(imageId)
|
ToolStateManager.clearImageIdToolState(imageId)
|
||||||
let elements = cornerstone.getEnabledElementsByImageId(imageId)
|
let elements = cornerstone.getEnabledElementsByImageId(imageId)
|
||||||
elements.map(el=>{
|
elements.map(el => {
|
||||||
cornerstone.updateImage(el.element)
|
cornerstone.updateImage(el.element)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1764,7 +1771,7 @@ export default {
|
||||||
this.activeToolName = toolName
|
this.activeToolName = toolName
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
// console.log(cornerstoneTools.isToolActiveForElement(this.canvas, 'Bidirectional'))
|
// console.log(cornerstoneTools.isToolActiveForElement(this.canvas, 'Bidirectional'))
|
||||||
|
|
||||||
if (toolName === 'Zoom') {
|
if (toolName === 'Zoom') {
|
||||||
cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', {
|
cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', {
|
||||||
mouseButtonMask: [1, 2]
|
mouseButtonMask: [1, 2]
|
||||||
|
|
@ -1918,7 +1925,7 @@ export default {
|
||||||
for (const [key, value] of searchParams.entries()) {
|
for (const [key, value] of searchParams.entries()) {
|
||||||
params[key] = value
|
params[key] = value
|
||||||
}
|
}
|
||||||
if (isNaN(params.frame)){
|
if (isNaN(params.frame)) {
|
||||||
params.frame = 0
|
params.frame = 0
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
|
|
@ -1940,88 +1947,102 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.context-menu-wrapper{
|
.context-menu-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
ul{
|
|
||||||
list-style: none;
|
ul {
|
||||||
margin: 0px;
|
list-style: none;
|
||||||
padding: 0px;
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
background: #343333;
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
border: 1px solid #2a2a2a;
|
||||||
|
border-radius: 3px;
|
||||||
|
height: auto;
|
||||||
|
min-height: 50px;
|
||||||
|
line-height: 1.5em;
|
||||||
|
width: 80px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
li {
|
||||||
|
padding: 2px 5px;
|
||||||
|
position: relative;
|
||||||
|
border-bottom: 1px solid #666;
|
||||||
|
|
||||||
|
div {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.submenu {
|
||||||
|
position: absolute;
|
||||||
|
left: 77px;
|
||||||
|
top: -1px;
|
||||||
background: #343333;
|
background: #343333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin: 0;
|
display: none;
|
||||||
border: 1px solid #2a2a2a;
|
|
||||||
border-radius: 3px;
|
|
||||||
height: auto;
|
|
||||||
min-height: 50px;
|
|
||||||
line-height: 1.5em;
|
|
||||||
width:80px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.menu{
|
|
||||||
li {
|
li {
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
position: relative;
|
|
||||||
border-bottom: 1px solid #666;
|
border-bottom: 1px solid #666;
|
||||||
div{
|
|
||||||
|
div {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.submenu{
|
|
||||||
position: absolute;
|
|
||||||
left: 77px;
|
|
||||||
top: -1px;
|
|
||||||
background: #343333;
|
|
||||||
color: #fff;
|
|
||||||
display: none;
|
|
||||||
li {
|
|
||||||
padding: 2px 5px;
|
|
||||||
border-bottom: 1px solid #666;
|
|
||||||
div{
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
.menu li:hover{
|
|
||||||
background-color: #ff5722;
|
|
||||||
.submenu{
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.menu_active{
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.menu_disabled{
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.info-visit{
|
|
||||||
position: absolute;
|
.menu li:hover {
|
||||||
left:50%;
|
background-color: #ff5722;
|
||||||
top: 5px;
|
|
||||||
transform: translateX(-50%);
|
.submenu {
|
||||||
display: flex;
|
display: block;
|
||||||
flex-direction: row;
|
|
||||||
.arrw_div_wrapper{
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
background-color: #3f3f3f;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 20px;
|
|
||||||
border-radius: 10%;
|
|
||||||
}
|
|
||||||
.blind_name_wrapper{
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
background-color: #00000057;
|
|
||||||
color: #fff;
|
|
||||||
padding:0 10px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.info-cd{
|
|
||||||
|
.menu_active {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu_disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-visit {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 5px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.arrw_div_wrapper {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #3f3f3f;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 20px;
|
||||||
|
border-radius: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blind_name_wrapper {
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
background-color: #00000057;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-cd {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
|
|
@ -2030,6 +2051,7 @@ export default {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-series {
|
.info-series {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
|
|
@ -2039,6 +2061,7 @@ export default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
/* z-index: 1; */
|
/* z-index: 1; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-image {
|
.info-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
|
|
@ -2058,6 +2081,7 @@ export default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
/* z-index: 1; */
|
/* z-index: 1; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-instance {
|
.info-instance {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
|
|
@ -2090,6 +2114,7 @@ export default {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu__item:hover {
|
.menu__item:hover {
|
||||||
color: #ff0000;
|
color: #ff0000;
|
||||||
}
|
}
|
||||||
|
|
@ -2109,11 +2134,12 @@ li:hover {
|
||||||
background-color: #e0e0e2;
|
background-color: #e0e0e2;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.msg-div {
|
.msg-div {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
background-color: rgba(255, 255, 255, 0.5);
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
color: #000;
|
color: #000;
|
||||||
padding: 5px 20px;
|
padding: 5px 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue