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