ohif-viewer/extensions/dicom-sr/src/tools/DICOMSRDisplayTool.js
2020-06-30 18:00:37 +01:00

234 lines
6.1 KiB
JavaScript

import { importInternal, getToolState, toolColors } from 'cornerstone-tools';
import TOOL_NAMES from '../constants/toolNames';
import SCOORD_TYPES from '../constants/scoordTypes';
import id from '../id';
// Cornerstone 3rd party dev kit imports
const draw = importInternal('drawing/draw');
const drawJoinedLines = importInternal('drawing/drawJoinedLines');
const drawCircle = importInternal('drawing/drawCircle');
const drawEllipse = importInternal('drawing/drawEllipse');
const drawHandles = importInternal('drawing/drawHandles');
const getNewContext = importInternal('drawing/getNewContext');
const BaseTool = importInternal('base/BaseTool');
const drawLinkedTextBox = importInternal('drawing/drawLinkedTextBox');
/**
* @class DICOMSRDisplayTool - Renders DICOMSR data in a read only manner (i.e. as an overlay).
* @extends cornerstoneTools.BaseTool
*/
export default class DICOMSRDisplayTool extends BaseTool {
constructor(props = {}) {
const defaultProps = {
mixins: ['enabledOrDisabledBinaryTool'],
name: TOOL_NAMES.DICOM_SR_DISPLAY_TOOL,
};
const initialProps = Object.assign(defaultProps, props);
super(initialProps);
this._module = cornerstoneTools.getModule(id);
}
renderToolData(evt) {
const eventData = evt.detail;
const { element } = eventData;
const module = this._module;
const toolState = getToolState(element, this.name);
if (!toolState) {
return;
}
const trackingUniqueIdentifiersForElement = module.getters.trackingUniqueIdentifiersForElement(
element
);
const {
activeIndex,
trackingUniqueIdentifiers,
} = trackingUniqueIdentifiersForElement;
const activeTrackingUniqueIdentifier =
trackingUniqueIdentifiers[activeIndex];
// Filter toolData to only render the data for the active SR.
const filteredToolData = toolState.data.filter(td =>
trackingUniqueIdentifiers.includes(td.TrackingUniqueIdentifier)
);
for (let i = 0; i < filteredToolData.length; i++) {
const data = filteredToolData[i];
const { renderableData, labels } = data;
const color =
data.TrackingUniqueIdentifier === activeTrackingUniqueIdentifier
? toolColors.getActiveColor()
: toolColors.getToolColor();
const lineWidth = 2;
const options = {
color,
lineWidth,
handleRadius: 6,
};
Object.keys(renderableData).forEach(GraphicType => {
const renderableDataForGraphicType = renderableData[GraphicType];
switch (GraphicType) {
case SCOORD_TYPES.POINT:
case SCOORD_TYPES.MULTIPOINT:
this.renderPointOrMultipoint(
renderableDataForGraphicType,
eventData,
options
);
break;
case SCOORD_TYPES.POLYLINE:
this.renderPolyLine(
renderableDataForGraphicType,
eventData,
options
);
break;
case SCOORD_TYPES.CIRCLE:
this.renderCircle(renderableDataForGraphicType, eventData, options);
break;
case SCOORD_TYPES.ELLIPSE:
this.renderEllipse(
renderableDataForGraphicType,
eventData,
options
);
break;
}
});
const { element } = eventData;
const context = getNewContext(eventData.canvasContext.canvas);
debugger;
const text = _getTextBoxLinesFromLabels(labels);
debugger;
function textBoxAnchorPoints() {
return [{ x: 1000, y: 1000 }];
}
draw(context, context => {
drawLinkedTextBox(
context,
element,
{
active: false,
hasMoved: false,
movesIndependently: false,
drawnIndependently: true,
allowedOutsideImage: true,
hasBoundingBox: true,
x: 256,
y: 256,
},
text,
null,
textBoxAnchorPoints,
color,
lineWidth,
10,
true
);
});
}
}
renderPolyLine(renderableData, eventData, options) {
const { element } = eventData;
const context = getNewContext(eventData.canvasContext.canvas);
renderableData.forEach(points => {
draw(context, context => {
drawJoinedLines(context, element, points[0], points, options);
});
});
}
renderPointOrMultipoint(renderableData, eventData, options) {
const context = getNewContext(eventData.canvasContext.canvas);
renderableData.forEach(points => {
draw(context, context => {
drawHandles(context, eventData, points, options);
});
});
}
renderCircle(renderableData, eventData, options) {
const { element } = eventData;
const context = getNewContext(eventData.canvasContext.canvas);
renderableData.forEach(circle => {
const { center, radius } = circle;
drawCircle(context, element, center, radius, options);
});
}
renderEllipse(renderableData, eventData, options) {
const { element } = eventData;
const context = getNewContext(eventData.canvasContext.canvas);
renderableData.forEach(ellipse => {
const { corner1, corner2 } = ellipse;
drawEllipse(
context,
element,
corner1,
corner2,
options,
'pixel',
0 // TODO -> Work our the initial rotation and add it here so we render appropriately rotated ellipses.
);
});
}
}
function _getTextBoxLinesFromLabels(labels) {
// TODO -> max 2 for now, need a generic solution for this!
const labelLength = Math.min(labels.length, 2);
const lines = [];
for (let i = 0; i < labelLength; i++) {
const labelEntry = labels[i];
lines.push(`${_labelToShorthand(labelEntry.label)}${labelEntry.value}`);
}
return lines;
}
const SHORT_HAND_MAP = {
'Short Axis': 'S ',
'Long Axis': 'L ',
AREA: 'Area ',
Length: '',
};
function _labelToShorthand(label) {
const shortHand = SHORT_HAND_MAP[label];
if (shortHand !== undefined) {
return shortHand;
}
return label;
}