All files / extensions/cornerstone/src/hooks useMeasurements.ts

86.84% Statements 33/38
47.05% Branches 8/17
90% Functions 9/10
86.48% Lines 32/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101        21x   21x   21x       21x   21x 21x     21x           21x 21x       21x                 21x       21x                                 31x 31x   31x 13x 19x 19x 21x   19x 19x 8x   11x       13x   13x   13x               13x 65x     13x 55x 11x       31x    
import { useState, useEffect } from 'react';
import debounce from 'lodash.debounce';
 
function mapMeasurementToDisplay(measurement, displaySetService) {
  const { referenceSeriesUID } = measurement;
 
  const displaySets = displaySetService.getDisplaySetsForSeries(referenceSeriesUID);
 
  Iif (!displaySets[0]?.instances) {
    throw new Error('The tracked measurements panel should only be tracking "stack" displaySets.');
  }
 
  const { findingSites, finding, label: baseLabel, displayText: baseDisplayText } = measurement;
 
  const firstSite = findingSites?.[0];
  const label = baseLabel || finding?.text || firstSite?.text || '(empty)';
 
  // Initialize displayText with the structure used in Length.ts and CobbAngle.ts
  const displayText = {
    primary: [],
    secondary: baseDisplayText?.secondary || [],
  };
 
  // Add baseDisplayText to primary if it exists
  if (baseDisplayText) {
    displayText.primary.push(...baseDisplayText.primary);
  }
 
  // Add finding sites to primary
  Iif (findingSites) {
    findingSites.forEach(site => {
      Iif (site?.text && site.text !== label) {
        displayText.primary.push(site.text);
      }
    });
  }
 
  // Add finding to primary if it's different from the label
  Iif (finding && finding.text && finding.text !== label) {
    displayText.primary.push(finding.text);
  }
 
  return {
    ...measurement,
    displayText,
    label,
  };
}
 
/**
 * A custom hook that provides mapped measurements based on the given services and filters.
 *
 * @param {Object} servicesManager - The services manager object.
 * @param {Object} options - The options for filtering and mapping measurements.
 * @param {Function} options.measurementFilter - Optional function to filter measurements.
 * @param {Object} options.valueTypes - The value types for mapping measurements.
 * @returns {Array} An array of mapped and filtered measurements.
 */
export function useMeasurements(servicesManager, { measurementFilter }) {
  const { measurementService, displaySetService } = servicesManager.services;
  const [displayMeasurements, setDisplayMeasurements] = useState([]);
 
  useEffect(() => {
    const updateDisplayMeasurements = () => {
      let measurements = measurementService.getMeasurements(measurementFilter);
      const mappedMeasurements = measurements.map(m =>
        mapMeasurementToDisplay(m, displaySetService)
      );
      setDisplayMeasurements(prevMeasurements => {
        if (JSON.stringify(prevMeasurements) !== JSON.stringify(mappedMeasurements)) {
          return mappedMeasurements;
        }
        return prevMeasurements;
      });
    };
 
    const debouncedUpdate = debounce(updateDisplayMeasurements, 100);
 
    updateDisplayMeasurements();
 
    const events = [
      measurementService.EVENTS.MEASUREMENT_ADDED,
      measurementService.EVENTS.RAW_MEASUREMENT_ADDED,
      measurementService.EVENTS.MEASUREMENT_UPDATED,
      measurementService.EVENTS.MEASUREMENT_REMOVED,
      measurementService.EVENTS.MEASUREMENTS_CLEARED,
    ];
 
    const subscriptions = events.map(
      evt => measurementService.subscribe(evt, debouncedUpdate).unsubscribe
    );
 
    return () => {
      subscriptions.forEach(unsub => unsub());
      debouncedUpdate.cancel();
    };
  }, [measurementService, measurementFilter, displaySetService]);
 
  return displayMeasurements;
}