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);
+}