Reference Lines Tool

Setup:

The Reference Lines tool is special in that it is an "Overlay Tool". Which means that it really only has two states: Enabled and Disabled. This tool can be tricky to set up because it requires passing a synchronizer in a synchronizatioContext as an option when first enabling the tool. We attempt to draw a reference line for each of the synchronizer's sourceElements.

The synchronizer, when used with the updateImageSynchronizer function, has the added benefit of triggering redraws on the synchronizer's targetElements when a sourceElement is updated. This is how one element is able to update it's referenceLine in response to a new image on a different element.

// Init cornerstone tools
cornerstoneTools.init()

// ...
// Enable our elements

const scheme = 'wadouri'
const baseUrl = 'https://mypacs.com/dicoms/'

// Create our Stack data
const firstSeries = [
  'image_1.dcm'
]

const secondSeries = [
  'image_11.dcm',
  'image_22.dcm',
  'image_33.dcm',
  'image_44.dcm'
]

const firstStack = {
  currentImageIdIndex: 0,
  imageIds: firstSeries
    .map(seriesImage => `${scheme}:${baseUrl}${seriesImage}`);,
};

const secondStack = {
  currentImageIdIndex: 0,
  imageIds: secondSeries
    .map(seriesImage => `${scheme}:${baseUrl}${seriesImage}`);,
};

// Create the synchronizer
const synchronizer = new cornerstoneTools.Synchronizer(
  // Cornerstone event that should trigger synchronizer
  'cornerstonenewimage',
  // Logic that should run on target elements when event is observed on source elements
  cornerstoneTools.updateImageSynchronizer
)

// Add and activate tools
cornerstoneTools.addTool(cornerstoneTools.StackScrollTool);
cornerstoneTools.addTool(cornerstoneTools.StackScrollMouseWheelTool);
cornerstoneTools.setToolActive('StackScroll', { mouseButtonMask: 1 });
cornerstoneTools.setToolActive('StackScrollMouseWheel', { });

// load images and set the stack
const firstLoadImagePromise = cornerstone.loadImage(firstStack.imageIds[0])
  .then((image) => {
    cornerstone.displayImage(firstElement, image)

    // set the stack as tool state
    synchronizer.add(firstElement)
    cornerstoneTools.addStackStateManager(firstStack, ['stack', 'Crosshairs'])
    cornerstoneTools.addToolState(firstElement, 'stack', firstStack)
  })

const secondLoadImagePromise = cornerstone.loadImage(secondStack.imageIds[0])
  .then((image) => {
    cornerstone.displayImage(secondElement, image)

    // set the stack as tool state
    synchronizer.add(secondElement);
    cornerstoneTools.addStackStateManager(secondElement, ['stack', 'Crosshairs']);
    cornerstoneTools.addToolState(secondElement, 'stack', secondStack);
  })

// After images have loaded, and our sync context has added both elements
Promise.all([firstLoadImagePromise, secondLoadImagePromise])
  .then(() => {
    cornerstoneTools.addTool(cornerstoneTools.ReferenceLinesTool);
    cornerstoneTools.setToolEnabled('ReferenceLines', {
      synchronizationContext: synchronizer,
    });
  });