diff --git a/extensions/default/src/ActionButtons.jsx b/extensions/default/src/ActionButtons.jsx deleted file mode 100644 index 0e3e8a3b6..000000000 --- a/extensions/default/src/ActionButtons.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Button, ButtonGroup, Icon, IconButton } from '@ohif/ui'; - -function ActionButtons() { - return ( - - alert('Export')}> - - - - - - - - ); -} - -export default ActionButtons; diff --git a/extensions/default/src/PanelMeasurementTable.js b/extensions/default/src/PanelMeasurementTable.js index 6da4696fd..cd83598b2 100644 --- a/extensions/default/src/PanelMeasurementTable.js +++ b/extensions/default/src/PanelMeasurementTable.js @@ -1,55 +1,135 @@ -import React from 'react'; -import { StudySummary, MeasurementTable } from '@ohif/ui'; -import ActionButtons from './ActionButtons.jsx'; +import React, { useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import { MeasurementTable } from '@ohif/ui'; +import { DicomMetadataStore } from '@ohif/core'; export default function PanelMeasurementTable({ servicesManager, - commandsManager, + // commandsManager, }) { const { MeasurementService } = servicesManager.services; + const [displayMeasurements, setDisplayMeasurements] = useState([]); - console.log('MeasurementTable rendering!!!!!!!!!!!!!'); + useEffect(() => { + const measurements = MeasurementService.getMeasurements(); + const mappedMeasurements = measurements.map((m, index) => + _mapMeasurementToDisplay(m, index, MeasurementService.VALUE_TYPES) + ); + setDisplayMeasurements(mappedMeasurements); + }, [MeasurementService]); - const descriptionData = { - date: '07-Sep-2010', - modality: 'CT', - description: 'CHEST/ABD/PELVIS W CONTRAST', - }; - - const activeMeasurementItem = 0; - - const measurementTableData = { - title: 'Measurements', - amount: 10, - data: new Array(10).fill({}).map((el, i) => ({ - id: i + 1, - label: 'Label short description', - displayText: '24.0 x 24.0 mm (S:4, I:22)', - isActive: activeMeasurementItem === i + 1, - })), - onClick: id => setActiveMeasurementItem(s => (s === id ? null : id)), - onEdit: id => alert(`Edit: ${id}`), - }; + // const activeMeasurementItem = 0; return ( <>
- {}} onEdit={id => alert(`Edit: ${id}`)} />
-
- -
); } + +PanelMeasurementTable.propTypes = { + servicesManager: PropTypes.shape({ + services: PropTypes.shape({ + MeasurementService: PropTypes.shape({ + getMeasurements: PropTypes.func.isRequired, + VALUE_TYPES: PropTypes.object.isRequired, + }).isRequired, + }).isRequired, + }).isRequired, +}; + +function _mapMeasurementToDisplay(measurement, index, types) { + const { + id, + label, + description, + // Reference IDs + referenceStudyUID, + referenceSeriesUID, + SOPInstanceUID, + } = measurement; + const instance = DicomMetadataStore.getInstance( + referenceStudyUID, + referenceSeriesUID, + SOPInstanceUID + ); + const { PixelSpacing, SeriesNumber, InstanceNumber } = instance; + + return { + id: index + 1, + label: '(empty)', // 'Label short description', + displayText: + _getDisplayText( + measurement, + PixelSpacing, + SeriesNumber, + InstanceNumber, + types + ) || [], + // TODO: handle one layer down + isActive: false, // activeMeasurementItem === i + 1, + }; +} + +function _getDisplayText( + measurement, + pixelSpacing, + seriesNumber, + instanceNumber, + types +) { + const { type, points } = measurement; + const hasPixelSpacing = + pixelSpacing !== undefined && + Array.isArray(pixelSpacing) && + pixelSpacing.length === 2; + const [rowPixelSpacing, colPixelSpacing] = hasPixelSpacing + ? pixelSpacing + : [1, 1]; + const unit = hasPixelSpacing ? 'mm' : 'px'; + + switch (type) { + case types.POLYLINE: { + const { length } = measurement; + const roundedLength = _round(length, 1); + + return [ + `${roundedLength} ${unit} (S:${seriesNumber}, I:${instanceNumber})`, + ]; + } + case types.BIDIRECTIONAL: { + const { shortestDiameter, longestDiameter } = measurement; + const roundedShortestDiameter = _round(shortestDiameter, 1); + const roundedLongestDiameter = _round(longestDiameter, 1); + + return [ + `l: ${roundedLongestDiameter} ${unit} (S:${seriesNumber}, I:${instanceNumber})`, + `s: ${roundedShortestDiameter} ${unit}`, + ]; + } + case types.ELLIPSE: { + const { area } = measurement; + const roundedArea = _round(area, 1); + + return [ + `${roundedArea} ${unit}2 (S:${seriesNumber}, I:${instanceNumber})`, + ]; + } + case types.POINT: { + const { text } = measurement; + return [`${text} (S:${seriesNumber}, I:${instanceNumber})`]; + } + } +} + +function _round(value, decimals) { + return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals); +}