OHIF / Viewers

OHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages
https://docs.ohif.org/
MIT License
3.35k stars 3.36k forks source link

[Bug] Overlay does not appear in viewports #4175

Open jmaratt opened 5 months ago

jmaratt commented 5 months ago

Describe the Bug

Adding an overlay using customizationService does not seem to work.

I have followed the examples here closely on the default.js config modified to use a local orthanc server. https://docs.ohif.org/platform/services/ui/customization-service#customizable-viewport-overlay

To make it easier to reproduce I tried it on an unmodified default.js except for adding the examples above with the same unexpected result that the overlay is not added.

Steps to Reproduce

  1. Download repo
  2. yarn install
  3. yarn run dev
  4. Navage to localhost:3000
  5. Open study Walter Phantom (or any other)

The current behavior

Overlay described in customizationService in config file is not added.

The expected behavior

Overlay is added.

OS

Ubuntu 22.04

Node version

v20.11.1

Browser

Chrome 123.0.0

lam0620 commented 5 months ago

I'm having the same issue.

sedghi commented 5 months ago

what have you added as custom overlay that does not work, can you share your edits?

jmaratt commented 5 months ago

I tried the examples on this page: https://docs.ohif.org/platform/services/ui/customization-service

I tried using it connected to a local orthanc server. I verified the dicom images had names etc properly tagged. Demographics also show up correctly in the toolbar right corner. To reduce any variables, I also tried with the default config file with the ohif online pacs. No overlays with either attempt.

Example 1: (to be clear, I just copied just the customizationService part to my config file.)

window.config = {
  //...

  // in the APP_CONFIG file set the top right area to show the patient name
  // using PN: as a prefix when the study has a non-empty patient name.
  customizationService: {
    cornerstoneOverlayTopRight: {
      id: 'cornerstoneOverlayTopRight',
      items: [
        {
          id: 'PatientNameOverlay',
          // Note below that here we are using the customization prototype of
          // `ohif.overlayItem` which was registered to the customization module in
          // `ohif/extension-default` extension.
          customizationType: 'ohif.overlayItem',
          // the following props are passed to the `ohif.overlayItem` prototype
          // which is used to render the overlay item based on the label, color,
          // conditions, etc.
          attribute: 'PatientName',
          label: 'PN:',
          title: 'Patient Name',
          color: 'yellow',
          condition: ({ instance }) =>
            instance &&
            instance.PatientName &&
            instance.PatientName.Alphabetic,
          contentF: ({ instance, formatters: { formatPN } }) =>
            formatPN(instance.PatientName.Alphabetic) +
            ' ' +
            (instance.PatientSex ? '(' + instance.PatientSex + ')' : ''),
        },
      ],
    },
  },

  //...
}

Example 2:

// this is one of the configuration files in `platform/app/public/config/*.js`
window.config = {
  // ...

  customizationService: {
    cornerstoneOverlayTopLeft: {
      id: 'cornerstoneOverlayTopLeft',
      items: [
        {
          id: 'WindowLevel',
          customizationType: 'ohif.overlayItem.windowLevel',
        },
        {
          id: 'PatientName',
          customizationType: 'ohif.overlayItem',
          label: '',
          color: 'green',
          background: 'white',
          condition: ({ instance }) =>
            instance && instance.PatientName && instance.PatientName.Alphabetic,
          contentF: ({ instance, formatters: { formatPN } }) =>
            formatPN(instance.PatientName.Alphabetic) +
            ' ' +
            (instance.PatientSex ? '(' + instance.PatientSex + ')' : ''),
        },
        {
          id: 'Species',
          customizationType: 'ohif.overlayItem',
          label: 'Species:',
          condition: ({ instance }) =>
            instance && instance.PatientSpeciesDescription,
          contentF: ({ instance }) =>
            instance.PatientSpeciesDescription +
            '/' +
            instance.PatientBreedDescription,
        },
        {
          id: 'PID',
          customizationType: 'ohif.overlayItem',
          label: 'PID:',
          title: 'Patient PID',
          condition: ({ instance }) => instance && instance.PatientID,
          contentF: ({ instance }) => instance.PatientID,
        },
        {
          id: 'PatientBirthDate',
          customizationType: 'ohif.overlayItem',
          label: 'DOB:',
          title: "Patient's Date of birth",
          condition: ({ instance }) => instance && instance.PatientBirthDate,
          contentF: ({ instance }) => instance.PatientBirthDate,
        },
        {
          id: 'OtherPid',
          customizationType: 'ohif.overlayItem',
          label: 'Other PID:',
          title: 'Other Patient IDs',
          condition: ({ instance }) => instance && instance.OtherPatientIDs,
          contentF: ({ instance, formatters: { formatPN } }) =>
            formatPN(instance.OtherPatientIDs),
        },
      ],
    },
    cornerstoneOverlayTopRight: {
      id: 'cornerstoneOverlayTopRight',

      items: [
        {
          id: 'InstanceNmber',
          customizationType: 'ohif.overlayItem.instanceNumber',
        },
        {
          id: 'StudyDescription',
          customizationType: 'ohif.overlayItem',
          label: '',
          title: ({ instance }) =>
            instance &&
            instance.StudyDescription &&
            `Study Description: ${instance.StudyDescription}`,
          condition: ({ instance }) => instance && instance.StudyDescription,
          contentF: ({ instance }) => instance.StudyDescription,
        },
        {
          id: 'StudyDate',
          customizationType: 'ohif.overlayItem',
          label: '',
          title: 'Study date',
          condition: ({ instance }) => instance && instance.StudyDate,
          contentF: ({ instance, formatters: { formatDate } }) =>
            formatDate(instance.StudyDate),
        },
        {
          id: 'StudyTime',
          customizationType: 'ohif.overlayItem',
          label: '',
          title: 'Study time',
          condition: ({ instance }) => instance && instance.StudyTime,
          contentF: ({ instance, formatters: { formatTime } }) =>
            formatTime(instance.StudyTime),
        },
      ],
    },
    cornerstoneOverlayBottomLeft: {
      id: 'cornerstoneOverlayBottomLeft',

      items: [
        {
          id: 'SeriesNumber',
          customizationType: 'ohif.overlayItem',
          label: 'Ser:',
          title: 'Series Number',
          condition: ({ instance }) => instance && instance.SeriesNumber,
          contentF: ({ instance }) => instance.SeriesNumber,
        },
        {
          id: 'SliceLocation',
          customizationType: 'ohif.overlayItem',
          label: 'Loc:',
          title: 'Slice Location',
          condition: ({ instance }) => instance && instance.SliceLocation,
          contentF: ({ instance, formatters: { formatNumberPrecision } }) =>
            formatNumberPrecision(instance.SliceLocation, 2) + ' mm',
        },
        {
          id: 'SliceThickness',
          customizationType: 'ohif.overlayItem',
          label: 'Thick:',
          title: 'Slice Thickness',
          condition: ({ instance }) => instance && instance.SliceThickness,
          contentF: ({ instance, formatters: { formatNumberPrecision } }) =>
            formatNumberPrecision(instance.SliceThickness, 2) + ' mm',
        },
      ],
    },
  },

  // ...
}
jmaratt commented 5 months ago

@sedghi I noticed you removed the awaiting reproduction tag. Were you able to confirm the issue? Do you know why it is happening?

Please let me know if there is anything else I can do to help solve it.

sedghi commented 5 months ago

I will revisit the overlay early next week

pwespi commented 4 months ago

There seems to be a new instanceIndex property on the items that is required but not documented. When I add instanceIndex: 0, to my custom items, they show up again.

jmaratt commented 4 months ago

I was also able to make items appear with instanceIndex: 0, added as @pwespi pointed out.

However, there may be another issue with with the examples. When i add instanceIndex: 0, in the items list in example 1, I get the following error in the browser and none of the cornerstone views are rendered. I have to remove attribute: 'PatientName', to make it render. The items in Example 2 work as expected. Both examples are found at: https://docs.ohif.org/platform/services/ui/customization-service/#customizable-viewport-overlay

Context: Grid
Error Message: Objects are not valid as a React child (found: object with keys {Alphabetic}). If you meant to render a collection of children, use an array instead.

Stack Trace
Stack: throwOnInvalidObjectType@http://localhost:3000/app.js:254688:20
createChild@http://localhost:3000/app.js:254926:31
reconcileChildrenArray@http://localhost:3000/app.js:255176:36
reconcileChildren@http://localhost:3000/app.js:258447:44
updateHostComponent@http://localhost:3000/app.js:259089:20
callCallback@http://localhost:3000/app.js:245402:19
dispatchEvent@[native code]
invokeGuardedCallbackDev@http://localhost:3000/app.js:245451:29
invokeGuardedCallback@http://localhost:3000/app.js:245513:36
beginWork$1@http://localhost:3000/app.js:265416:28
performUnitOfWork@http://localhost:3000/app.js:264231:23
workLoopSync@http://localhost:3000/app.js:264159:22
renderRootSync@http://localhost:3000/app.js:264122:19
performSyncWorkOnRoot@http://localhost:3000/app.js:263745:32
@http://localhost:3000/app.js:252784:34
unstable_runWithPriority@http://localhost:3000/app.js:287142:24
flushSyncCallbackQueueImpl@http://localhost:3000/app.js:252779:26
flushSyncCallbackQueue@http://localhost:3000/app.js:252766:29
scheduleUpdateOnFiber@http://localhost:3000/app.js:263345:31
dispatchAction@http://localhost:3000/app.js:257596:26
@http://localhost:3000/extensions_cornerstone_src_Viewport_OHIFCornerstoneViewport_tsx.js:643:22
@http://localhost:3000/app.js:29433:24
forEach@[native code]
_broadcastEvent@http://localhost:3000/app.js:29432:38
@http://localhost:3000/extensions_cornerstone_src_index_tsx.js:8925:27
wayfarer3130 commented 4 months ago

Fixed in https://github.com/OHIF/Viewers/pull/4224