fix(Segmentation): bump packages to fix segmentation rendering (#3138)

* add test mode

* bump packages

* add reference lines

* update yarn lock

* fix netlify build

* fix num workers

* update year in doc
This commit is contained in:
Alireza 2023-02-03 09:33:28 -05:00 committed by GitHub
parent a2bafaf100
commit 123e3a569b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1172 additions and 43 deletions

View File

@ -45,7 +45,7 @@
"dependencies": {
"@babel/runtime": "7.16.3",
"classnames": "^2.2.6",
"@cornerstonejs/core": "^0.25.0",
"@cornerstonejs/tools": "^0.34.2"
"@cornerstonejs/core": "^0.27.1",
"@cornerstonejs/tools": "^0.36.3"
}
}

View File

@ -43,9 +43,9 @@
},
"dependencies": {
"@babel/runtime": "7.17.9",
"@cornerstonejs/core": "^0.25.0",
"@cornerstonejs/streaming-image-volume-loader": "^0.8.2",
"@cornerstonejs/tools": "^0.34.2",
"@cornerstonejs/core": "^0.27.1",
"@cornerstonejs/streaming-image-volume-loader": "^0.11.2",
"@cornerstonejs/tools": "^0.36.3",
"@kitware/vtk.js": "25.9.0",
"html2canvas": "^1.4.1",
"lodash.debounce": "4.0.8",

View File

@ -32,8 +32,8 @@
"peerDependencies": {
"@ohif/core": "^3.0.0",
"classnames": "^2.2.6",
"@cornerstonejs/core": "^0.25.0",
"@cornerstonejs/tools": "^0.34.2",
"@cornerstonejs/core": "^0.27.1",
"@cornerstonejs/tools": "^0.36.3",
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
"dcmjs": "^0.28.3",
"prop-types": "^15.6.2",

View File

@ -0,0 +1,8 @@
const path = require('path');
const webpackCommon = require('./../../../.webpack/webpack.base.js');
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
module.exports = (env, argv) => {
return webpackCommon(env, argv, { SRC_DIR, DIST_DIR });
};

View File

@ -0,0 +1,50 @@
const webpack = require('webpack');
const { merge } = require('webpack-merge');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const pkg = require('./../package.json');
const webpackCommon = require('./../../../.webpack/webpack.base.js');
const ROOT_DIR = path.join(__dirname, './../');
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
const fileName = 'index.umd.js';
module.exports = (env, argv) => {
const commonConfig = webpackCommon(env, argv, { SRC_DIR, DIST_DIR });
return merge(commonConfig, {
stats: {
colors: true,
hash: true,
timings: true,
assets: true,
chunks: false,
chunkModules: false,
modules: false,
children: false,
warnings: true,
},
optimization: {
minimize: true,
sideEffects: true,
},
output: {
path: ROOT_DIR,
library: 'OHIFExtCornerstone',
libraryTarget: 'umd',
libraryExport: 'default',
filename: pkg.main,
},
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
new MiniCssExtractPlugin({
filename: './dist/[name].css',
chunkFilename: './dist/[id].css',
}),
],
});
};

View File

@ -0,0 +1,20 @@
MIT License
Copyright (c) 2023 Open Health Imaging Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,5 @@
# Test mode
This mode is used to test the basic functionality of the OHIF viewer
in a controlled environment. It is not intended to be used for
development or production.

View File

@ -0,0 +1 @@
module.exports = require('../../babel.config.js');

View File

@ -0,0 +1,50 @@
{
"name": "mode-basic-test-mode",
"version": "0.0.1",
"description": "Basic mode for testing",
"author": "OHIF",
"license": "MIT",
"repository": "OHIF/Viewers",
"main": "dist/index.umd.js",
"module": "src/index.js",
"engines": {
"node": ">=14",
"npm": ">=6",
"yarn": ">=1.16.0"
},
"files": [
"dist",
"README.md"
],
"publishConfig": {
"access": "public"
},
"keywords": [
"ohif-mode"
],
"scripts": {
"dev": "cross-env NODE_ENV=development webpack --config .webpack/webpack.dev.js --watch --debug --output-pathinfo",
"dev:cornerstone": "yarn run dev",
"build": "cross-env NODE_ENV=production webpack --config .webpack/webpack.prod.js",
"build:package": "yarn run build",
"start": "yarn run dev",
"test:unit": "jest --watchAll",
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "^3.0.0",
"@ohif/extension-default": "^3.0.0",
"@ohif/extension-cornerstone": "^3.0.0",
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
"@ohif/extension-dicom-pdf": "^3.0.1",
"@ohif/extension-dicom-video": "^3.0.1",
"@ohif/extension-measurement-tracking": "^3.0.0"
},
"dependencies": {
"@babel/runtime": "7.16.3"
},
"devDependencies": {
"webpack": "^5.50.0",
"webpack-merge": "^5.7.3"
}
}

View File

@ -0,0 +1,5 @@
import packageJson from '../package.json';
const id = packageJson.name;
export { id };

View File

@ -0,0 +1,217 @@
import { hotkeys } from '@ohif/core';
import toolbarButtons from './toolbarButtons.js';
import { id } from './id.js';
import initToolGroups from './initToolGroups.js';
// Allow this mode by excluding non-imaging modalities such as SR, SEG
// Also, SM is not a simple imaging modalities, so exclude it.
const NON_IMAGE_MODALITIES = ['SM', 'ECG', 'SR', 'SEG'];
const ohif = {
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack',
thumbnailList: '@ohif/extension-default.panelModule.seriesList',
};
const tracked = {
measurements:
'@ohif/extension-measurement-tracking.panelModule.trackedMeasurements',
thumbnailList: '@ohif/extension-measurement-tracking.panelModule.seriesList',
viewport:
'@ohif/extension-measurement-tracking.viewportModule.cornerstone-tracked',
};
const dicomsr = {
sopClassHandler:
'@ohif/extension-cornerstone-dicom-sr.sopClassHandlerModule.dicom-sr',
viewport: '@ohif/extension-cornerstone-dicom-sr.viewportModule.dicom-sr',
};
const dicomvideo = {
sopClassHandler:
'@ohif/extension-dicom-video.sopClassHandlerModule.dicom-video',
viewport: '@ohif/extension-dicom-video.viewportModule.dicom-video',
};
const dicompdf = {
sopClassHandler: '@ohif/extension-dicom-pdf.sopClassHandlerModule.dicom-pdf',
viewport: '@ohif/extension-dicom-pdf.viewportModule.dicom-pdf',
};
const dicomSeg = {
sopClassHandler:
'@ohif/extension-cornerstone-dicom-seg.sopClassHandlerModule.dicom-seg',
viewport: '@ohif/extension-cornerstone-dicom-seg.viewportModule.dicom-seg',
panel: '@ohif/extension-cornerstone-dicom-seg.panelModule.panelSegmentation',
};
const extensionDependencies = {
// Can derive the versions at least process.env.from npm_package_version
'@ohif/extension-default': '^3.0.0',
'@ohif/extension-cornerstone': '^3.0.0',
'@ohif/extension-measurement-tracking': '^3.0.0',
'@ohif/extension-cornerstone-dicom-sr': '^3.0.0',
'@ohif/extension-cornerstone-dicom-seg': '^3.0.0',
'@ohif/extension-dicom-pdf': '^3.0.1',
'@ohif/extension-dicom-video': '^3.0.1',
};
function modeFactory() {
return {
// TODO: We're using this as a route segment
// We should not be.
id,
routeName: 'basic-test',
displayName: 'Basic Test Mode',
/**
* Lifecycle hooks
*/
onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
const {
MeasurementService,
ToolBarService,
ToolGroupService,
} = servicesManager.services;
MeasurementService.clearMeasurements();
// Init Default and SR ToolGroups
initToolGroups(extensionManager, ToolGroupService, commandsManager);
let unsubscribe;
const activateTool = () => {
ToolBarService.recordInteraction({
groupId: 'WindowLevel',
itemId: 'WindowLevel',
interactionType: 'tool',
commands: [
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'WindowLevel',
},
context: 'CORNERSTONE',
},
],
});
// We don't need to reset the active tool whenever a viewport is getting
// added to the toolGroup.
unsubscribe();
};
// Since we only have one viewport for the basic cs3d mode and it has
// only one hanging protocol, we can just use the first viewport
({ unsubscribe } = ToolGroupService.subscribe(
ToolGroupService.EVENTS.VIEWPORT_ADDED,
activateTool
));
ToolBarService.init(extensionManager);
ToolBarService.addButtons(toolbarButtons);
ToolBarService.createButtonSection('primary', [
'MeasurementTools',
'Zoom',
'WindowLevel',
'Pan',
'Capture',
'Layout',
'MPR',
'Crosshairs',
'MoreTools',
]);
},
onModeExit: ({ servicesManager }) => {
const {
ToolGroupService,
SyncGroupService,
ToolBarService,
SegmentationService,
CornerstoneViewportService,
} = servicesManager.services;
ToolBarService.reset();
ToolGroupService.destroy();
SyncGroupService.destroy();
SegmentationService.destroy();
CornerstoneViewportService.destroy();
},
validationTags: {
study: [],
series: [],
},
isValidMode: function({ modalities }) {
const modalities_list = modalities.split('\\');
// Exclude non-image modalities
return !!modalities_list.filter(
modality => NON_IMAGE_MODALITIES.indexOf(modality) === -1
).length;
},
routes: [
{
path: 'basic-test',
/*init: ({ servicesManager, extensionManager }) => {
//defaultViewerRouteInit
},*/
layoutTemplate: () => {
return {
id: ohif.layout,
props: {
leftPanels: [tracked.thumbnailList],
rightPanels: [dicomSeg.panel, tracked.measurements],
// rightPanelDefaultClosed: true, // optional prop to start with collapse panels
viewports: [
{
namespace: tracked.viewport,
displaySetsToDisplay: [ohif.sopClassHandler],
},
{
namespace: dicomsr.viewport,
displaySetsToDisplay: [dicomsr.sopClassHandler],
},
{
namespace: dicomvideo.viewport,
displaySetsToDisplay: [dicomvideo.sopClassHandler],
},
{
namespace: dicompdf.viewport,
displaySetsToDisplay: [dicompdf.sopClassHandler],
},
{
namespace: dicomSeg.viewport,
displaySetsToDisplay: [dicomSeg.sopClassHandler],
},
],
},
};
},
},
],
extensions: extensionDependencies,
// Default protocol gets self-registered by default in the init
hangingProtocol: 'default',
// Order is important in sop class handlers when two handlers both use
// the same sop class under different situations. In that case, the more
// general handler needs to come last. For this case, the dicomvideo must
// come first to remove video transfer syntax before ohif uses images
sopClassHandlers: [
dicomvideo.sopClassHandler,
dicomSeg.sopClassHandler,
ohif.sopClassHandler,
dicompdf.sopClassHandler,
dicomsr.sopClassHandler,
],
hotkeys: [...hotkeys.defaults.hotkeyBindings],
};
}
const mode = {
id,
modeFactory,
extensionDependencies,
};
export default mode;

View File

@ -0,0 +1,225 @@
function initDefaultToolGroup(
extensionManager,
ToolGroupService,
commandsManager,
toolGroupId
) {
const utilityModule = extensionManager.getModuleEntry(
'@ohif/extension-cornerstone.utilityModule.tools'
);
const { toolNames, Enums } = utilityModule.exports;
const tools = {
active: [
{
toolName: toolNames.WindowLevel,
bindings: [{ mouseButton: Enums.MouseBindings.Primary }],
},
{
toolName: toolNames.Pan,
bindings: [{ mouseButton: Enums.MouseBindings.Auxiliary }],
},
{
toolName: toolNames.Zoom,
bindings: [{ mouseButton: Enums.MouseBindings.Secondary }],
},
{ toolName: toolNames.StackScrollMouseWheel, bindings: [] },
],
passive: [
{ toolName: toolNames.Length },
{ toolName: toolNames.ArrowAnnotate },
{ toolName: toolNames.Bidirectional },
{ toolName: toolNames.DragProbe },
{ toolName: toolNames.EllipticalROI },
{ toolName: toolNames.RectangleROI },
{ toolName: toolNames.StackScroll },
{ toolName: toolNames.Angle },
{ toolName: toolNames.Magnify },
{ toolName: toolNames.SegmentationDisplay },
],
// enabled
// disabled
disabled: [{ toolName: toolNames.ReferenceLines }],
};
const toolsConfig = {
[toolNames.ArrowAnnotate]: {
getTextCallback: (callback, eventDetails) =>
commandsManager.runCommand('arrowTextCallback', {
callback,
eventDetails,
}),
changeTextCallback: (data, eventDetails, callback) =>
commandsManager.runCommand('arrowTextCallback', {
callback,
data,
eventDetails,
}),
},
};
ToolGroupService.createToolGroupAndAddTools(toolGroupId, tools, toolsConfig);
}
function initSRToolGroup(extensionManager, ToolGroupService, commandsManager) {
const SRUtilityModule = extensionManager.getModuleEntry(
'@ohif/extension-cornerstone-dicom-sr.utilityModule.tools'
);
const CS3DUtilityModule = extensionManager.getModuleEntry(
'@ohif/extension-cornerstone.utilityModule.tools'
);
const { toolNames: SRToolNames } = SRUtilityModule.exports;
const { toolNames, Enums } = CS3DUtilityModule.exports;
const tools = {
active: [
{
toolName: toolNames.WindowLevel,
bindings: [
{
mouseButton: Enums.MouseBindings.Primary,
},
],
},
{
toolName: toolNames.Pan,
bindings: [
{
mouseButton: Enums.MouseBindings.Auxiliary,
},
],
},
{
toolName: toolNames.Zoom,
bindings: [
{
mouseButton: Enums.MouseBindings.Secondary,
},
],
},
{
toolName: toolNames.StackScrollMouseWheel,
bindings: [],
},
],
passive: [
{ toolName: SRToolNames.SRLength },
{ toolName: SRToolNames.SRArrowAnnotate },
{ toolName: SRToolNames.SRBidirectional },
{ toolName: SRToolNames.SREllipticalROI },
],
enabled: [
{
toolName: SRToolNames.DICOMSRDisplay,
bindings: [],
},
],
// disabled
};
const toolsConfig = {
[toolNames.ArrowAnnotate]: {
getTextCallback: (callback, eventDetails) =>
commandsManager.runCommand('arrowTextCallback', {
callback,
eventDetails,
}),
changeTextCallback: (data, eventDetails, callback) =>
commandsManager.runCommand('arrowTextCallback', {
callback,
data,
eventDetails,
}),
},
};
const toolGroupId = 'SRToolGroup';
ToolGroupService.createToolGroupAndAddTools(toolGroupId, tools, toolsConfig);
}
function initMPRToolGroup(extensionManager, ToolGroupService, commandsManager) {
const utilityModule = extensionManager.getModuleEntry(
'@ohif/extension-cornerstone.utilityModule.tools'
);
const { toolNames, Enums } = utilityModule.exports;
const tools = {
active: [
{
toolName: toolNames.WindowLevel,
bindings: [{ mouseButton: Enums.MouseBindings.Primary }],
},
{
toolName: toolNames.Pan,
bindings: [{ mouseButton: Enums.MouseBindings.Auxiliary }],
},
{
toolName: toolNames.Zoom,
bindings: [{ mouseButton: Enums.MouseBindings.Secondary }],
},
{ toolName: toolNames.StackScrollMouseWheel, bindings: [] },
],
passive: [
{ toolName: toolNames.Length },
{ toolName: toolNames.ArrowAnnotate },
{ toolName: toolNames.Bidirectional },
{ toolName: toolNames.DragProbe },
{ toolName: toolNames.EllipticalROI },
{ toolName: toolNames.RectangleROI },
{ toolName: toolNames.StackScroll },
{ toolName: toolNames.Angle },
{ toolName: toolNames.SegmentationDisplay },
],
disabled: [
{ toolName: toolNames.Crosshairs },
{ toolName: toolNames.ReferenceLines },
],
// enabled
// disabled
};
const toolsConfig = {
[toolNames.Crosshairs]: {
viewportIndicators: false,
autoPan: {
enabled: false,
panSize: 10,
},
},
[toolNames.ArrowAnnotate]: {
getTextCallback: (callback, eventDetails) =>
commandsManager.runCommand('arrowTextCallback', {
callback,
eventDetails,
}),
changeTextCallback: (data, eventDetails, callback) =>
commandsManager.runCommand('arrowTextCallback', {
callback,
data,
eventDetails,
}),
},
};
ToolGroupService.createToolGroupAndAddTools('mpr', tools, toolsConfig);
}
function initToolGroups(extensionManager, ToolGroupService, commandsManager) {
initDefaultToolGroup(
extensionManager,
ToolGroupService,
commandsManager,
'default'
);
initSRToolGroup(extensionManager, ToolGroupService, commandsManager);
initMPRToolGroup(extensionManager, ToolGroupService, commandsManager);
}
export default initToolGroups;

View File

@ -0,0 +1,544 @@
// TODO: torn, can either bake this here; or have to create a whole new button type
// Only ways that you can pass in a custom React component for render :l
import {
// ExpandableToolbarButton,
// ListMenu,
WindowLevelMenuItem,
} from '@ohif/ui';
import { defaults } from '@ohif/core';
const { windowLevelPresets } = defaults;
/**
*
* @param {*} type - 'tool' | 'action' | 'toggle'
* @param {*} id
* @param {*} icon
* @param {*} label
*/
function _createButton(type, id, icon, label, commands, tooltip, uiType) {
return {
id,
icon,
label,
type,
commands,
tooltip,
uiType,
};
}
function _createCommands(commandName, toolName, toolGroupIds) {
return toolGroupIds.map(toolGroupId => ({
/* It's a command that is being run when the button is clicked. */
commandName,
commandOptions: {
toolName,
toolGroupId,
},
context: 'CORNERSTONE',
}));
}
const _createActionButton = _createButton.bind(null, 'action');
const _createToggleButton = _createButton.bind(null, 'toggle');
const _createToolButton = _createButton.bind(null, 'tool');
/**
*
* @param {*} preset - preset number (from above import)
* @param {*} title
* @param {*} subtitle
*/
function _createWwwcPreset(preset, title, subtitle) {
return {
id: preset.toString(),
title,
subtitle,
type: 'action',
commands: [
{
commandName: 'setWindowLevel',
commandOptions: {
...windowLevelPresets[preset],
},
context: 'CORNERSTONE',
},
],
};
}
const toolbarButtons = [
// Measurement
{
id: 'MeasurementTools',
type: 'ohif.splitButton',
props: {
groupId: 'MeasurementTools',
isRadio: true, // ?
// Switch?
primary: _createToolButton(
'Length',
'tool-length',
'Length',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'Length',
},
context: 'CORNERSTONE',
},
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'SRLength',
toolGroupId: 'SRToolGroup',
},
// we can use the setToolActive command for this from Cornerstone commandsModule
context: 'CORNERSTONE',
},
],
'Length'
),
secondary: {
icon: 'chevron-down',
label: '',
isActive: true,
tooltip: 'More Measure Tools',
},
items: [
_createToolButton(
'Length',
'tool-length',
'Length',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'Length',
},
context: 'CORNERSTONE',
},
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'SRLength',
toolGroupId: 'SRToolGroup',
},
// we can use the setToolActive command for this from Cornerstone commandsModule
context: 'CORNERSTONE',
},
],
'Length Tool'
),
_createToolButton(
'Bidirectional',
'tool-bidirectional',
'Bidirectional',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'Bidirectional',
},
context: 'CORNERSTONE',
},
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'SRBidirectional',
toolGroupId: 'SRToolGroup',
},
context: 'CORNERSTONE',
},
],
'Bidirectional Tool'
),
_createToolButton(
'ArrowAnnotate',
'tool-annotate',
'Annotation',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'ArrowAnnotate',
},
context: 'CORNERSTONE',
},
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'SRArrowAnnotate',
toolGroupId: 'SRToolGroup',
},
context: 'CORNERSTONE',
},
],
'Arrow Annotate'
),
_createToolButton(
'EllipticalROI',
'tool-elipse',
'Ellipse',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'EllipticalROI',
},
context: 'CORNERSTONE',
},
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'SREllipticalROI',
toolGroupId: 'SRToolGroup',
},
context: 'CORNERSTONE',
},
],
'Ellipse Tool'
),
],
},
},
// Zoom..
{
id: 'Zoom',
type: 'ohif.radioGroup',
props: {
type: 'tool',
icon: 'tool-zoom',
label: 'Zoom',
commands: [
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'Zoom',
},
context: 'CORNERSTONE',
},
],
},
},
// Window Level + Presets...
{
id: 'WindowLevel',
type: 'ohif.splitButton',
props: {
groupId: 'WindowLevel',
primary: _createToolButton(
'WindowLevel',
'tool-window-level',
'Window Level',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'WindowLevel',
},
context: 'CORNERSTONE',
},
],
'Window Level'
),
secondary: {
icon: 'chevron-down',
label: 'W/L Manual',
isActive: true,
tooltip: 'W/L Presets',
},
isAction: true, // ?
renderer: WindowLevelMenuItem,
items: [
_createWwwcPreset(1, 'Soft tissue', '400 / 40'),
_createWwwcPreset(2, 'Lung', '1500 / -600'),
_createWwwcPreset(3, 'Liver', '150 / 90'),
_createWwwcPreset(4, 'Bone', '2500 / 480'),
_createWwwcPreset(5, 'Brain', '80 / 40'),
],
},
},
// Pan...
{
id: 'Pan',
type: 'ohif.radioGroup',
props: {
type: 'tool',
icon: 'tool-move',
label: 'Pan',
commands: [
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'Pan',
},
context: 'CORNERSTONE',
},
],
},
},
{
id: 'Capture',
type: 'ohif.action',
props: {
icon: 'tool-capture',
label: 'Capture',
type: 'action',
commands: [
{
commandName: 'showDownloadViewportModal',
commandOptions: {},
context: 'CORNERSTONE',
},
],
},
},
{
id: 'Layout',
type: 'ohif.layoutSelector',
props: {
rows: 3,
columns: 3,
},
},
{
id: 'MPR',
type: 'ohif.action',
props: {
type: 'toggle',
icon: 'icon-mpr',
label: 'MPR',
commands: [
{
commandName: 'toggleMPR',
commandOptions: {},
context: 'CORNERSTONE',
},
],
},
},
{
id: 'Crosshairs',
type: 'ohif.radioGroup',
props: {
type: 'tool',
icon: 'tool-crosshair',
label: 'Crosshairs',
commands: [
{
commandName: 'setToolActive',
commandOptions: {
toolGroupId: 'mpr',
toolName: 'Crosshairs',
},
context: 'CORNERSTONE',
},
],
},
},
// More...
{
id: 'MoreTools',
type: 'ohif.splitButton',
props: {
isRadio: true, // ?
groupId: 'MoreTools',
primary: _createActionButton(
'Reset',
'tool-reset',
'Reset View',
[
{
commandName: 'resetViewport',
commandOptions: {},
context: 'CORNERSTONE',
},
],
'Reset'
),
secondary: {
icon: 'chevron-down',
label: '',
isActive: true,
tooltip: 'More Tools',
},
items: [
_createActionButton(
'Reset',
'tool-reset',
'Reset View',
[
{
commandName: 'resetViewport',
commandOptions: {},
context: 'CORNERSTONE',
},
],
'Reset'
),
_createActionButton(
'rotate-right',
'tool-rotate-right',
'Rotate Right',
[
{
commandName: 'rotateViewportCW',
commandOptions: {},
context: 'CORNERSTONE',
},
],
'Rotate +90'
),
_createActionButton(
'flip-horizontal',
'tool-flip-horizontal',
'Flip Horizontally',
[
{
commandName: 'flipViewportHorizontal',
commandOptions: {},
context: 'CORNERSTONE',
},
],
'Flip Horizontal'
),
_createToggleButton('StackImageSync', 'link', 'Stack Image Sync', [
{
commandName: 'toggleStackImageSync',
commandOptions: {},
context: 'CORNERSTONE',
},
]),
_createToggleButton(
'ReferenceLines',
'tool-referenceLines', // change this with the new icon
'Reference Lines',
[
{
commandName: 'toggleReferenceLines',
commandOptions: {},
context: 'CORNERSTONE',
},
]
),
_createToolButton(
'StackScroll',
'tool-stack-scroll',
'Stack Scroll',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'StackScroll',
},
context: 'CORNERSTONE',
},
],
'Stack Scroll'
),
_createActionButton(
'invert',
'tool-invert',
'Invert',
[
{
commandName: 'invertViewport',
commandOptions: {},
context: 'CORNERSTONE',
},
],
'Invert Colors'
),
_createToolButton(
'Probe',
'tool-probe',
'Probe',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'DragProbe',
},
context: 'CORNERSTONE',
},
],
'Probe'
),
_createToggleButton(
'cine',
'tool-cine',
'Cine',
[
{
commandName: 'toggleCine',
context: 'CORNERSTONE',
},
],
'Cine'
),
_createToolButton(
'Angle',
'tool-angle',
'Angle',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'Angle',
},
context: 'CORNERSTONE',
},
],
'Angle'
),
_createToolButton(
'Magnify',
'tool-magnify',
'Magnify',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'Magnify',
},
context: 'CORNERSTONE',
},
],
'Magnify'
),
_createToolButton(
'Rectangle',
'tool-rectangle',
'Rectangle',
[
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'RectangleROI',
},
context: 'CORNERSTONE',
},
],
'Rectangle'
),
_createActionButton(
'TagBrowser',
'list-bullets',
'Dicom Tag Browser',
[
{
commandName: 'openDICOMTagViewer',
commandOptions: {},
context: 'DEFAULT',
},
],
'Dicom Tag Browser'
),
],
},
},
];
export default toolbarButtons;

View File

@ -175,7 +175,10 @@ function initMPRToolGroup(extensionManager, ToolGroupService, commandsManager) {
{ toolName: toolNames.Angle },
{ toolName: toolNames.SegmentationDisplay },
],
disabled: [{ toolName: toolNames.Crosshairs }],
disabled: [
{ toolName: toolNames.Crosshairs },
{ toolName: toolNames.ReferenceLines },
],
// enabled
// disabled

View File

@ -66,8 +66,8 @@
"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/plugin-proposal-class-properties": "^7.16.7",
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@babel/plugin-proposal-object-rest-spread": "^7.17.3",
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-arrow-functions": "^7.16.7",
"@babel/plugin-transform-regenerator": "^7.16.7",
@ -93,6 +93,7 @@
"eslint-config-prettier": "^7.2.0",
"eslint-config-react-app": "^6.0.0",
"eslint-plugin-flowtype": "^7.0.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-node": "^11.1.0",

View File

@ -12,7 +12,7 @@
base = ""
build = "yarn run build:viewer:ci"
publish = "dist"
ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF . ../ui/ ../core/ ../i18n/"
ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF . ../ui/ ../core/ ../i18n ../../extensions/ ../../modes"
# NODE_VERSION in root `.nvmrc` takes priority

View File

@ -8,7 +8,8 @@ window.config = {
// helloPage: '@ohif/extension-default.customizationModule.helloPage',
},
showStudyList: true,
maxNumberOfWebWorkers: 4,
// some windows systems have issues with more than 3 web workers
maxNumberOfWebWorkers: 3,
// below flag is for performance reasons, but it might not work for all servers
omitQuotationForMultipartRequest: true,
showLoadingIndicator: true,

View File

@ -2397,36 +2397,28 @@
resolved "https://registry.npmjs.org/@cornerstonejs/codec-openjph/-/codec-openjph-1.0.3.tgz#4c82642e8a6beb0d263f5a263723aec4225e5300"
integrity sha512-PK+9N/JL7ZMGum6OKuReRGGhWXpWjRC9WnltQ6aEzRKEQPMg+3WFiQPZowKCCG1I4whv35DYFRi6wu7RyRaEMQ==
"@cornerstonejs/core@^0.25.0":
version "0.25.0"
resolved "https://registry.npmjs.org/@cornerstonejs/core/-/core-0.25.0.tgz#b392f5526e087c591d5d7ae68782a980aa3488f7"
integrity sha512-MtT3N1+c3apalilsQs8SWaBLD6A0TKo1NLRMY1gFVYfZ9BkyCPlvKxhtgAJthRbr8ME2NMEMs/VjV3/RrFyMVg==
"@cornerstonejs/core@^0.27.1":
version "0.27.1"
resolved "https://registry.npmjs.org/@cornerstonejs/core/-/core-0.27.1.tgz#1c56697cee8071eacfd9b1ee6f59c0fa6071accc"
integrity sha512-RyZicIallTZtr8i1BDkZ3U1JrwPZF7DYj9dj5uwE4WdhoPB+Rp77k5T7BH7gHsNWPyJjPgZwyq+tgV5sdD7zXg==
dependencies:
detect-gpu "^4.0.45"
lodash.clonedeep "4.5.0"
"@cornerstonejs/core@^0.25.1":
version "0.25.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-0.25.1.tgz#7e5c70858018d99417b61965ac606754542f77ad"
integrity sha512-/Ve9qwGyRRK1uUCrefh9cVG3OIaaS9LQoTUk9YMUbsoWxd6JitXh31XVHjlvNtBYGMRVdz+uGPS2zSxq1vi4aA==
"@cornerstonejs/streaming-image-volume-loader@^0.11.2":
version "0.11.2"
resolved "https://registry.npmjs.org/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-0.11.2.tgz#75a8502a381a402a28ca2022f4bd2733eb90427f"
integrity sha512-cFkAKjcIk6V2p3hZ2gpvTGMBmPNrDlg/Ku6CTCqz7D+U6pEQPvct2e42G1tG+Y4MtnYgGpC+oYAeu9Zt/C6XlQ==
dependencies:
detect-gpu "^4.0.45"
lodash.clonedeep "4.5.0"
"@cornerstonejs/core" "^0.27.1"
cornerstone-wado-image-loader "^4.8.0"
"@cornerstonejs/streaming-image-volume-loader@^0.8.2":
version "0.8.2"
resolved "https://registry.npmjs.org/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-0.8.2.tgz#058a591501e7fe7ebbe195695c92d047a288290f"
integrity sha512-50Ihn/tp5GJG7Uu0ZtrjSdS/JRfYIyeuRVAXZKvj2jbjuE2fqf+lgXULPgDKQhKiT7nBy6nb2PEpMRzTH/vlnA==
"@cornerstonejs/tools@^0.36.3":
version "0.36.3"
resolved "https://registry.npmjs.org/@cornerstonejs/tools/-/tools-0.36.3.tgz#22769dbcac57f6811f37376ac45ea1041286d4a0"
integrity sha512-popsYtA5Tvr9u7AoRFASwAr9vdxT3S697sb14clydczbbURAk/vHJw1K70P55BJ38jVx/yaGqfZWObFMWbqPLg==
dependencies:
"@cornerstonejs/core" "^0.25.0"
cornerstone-wado-image-loader "^4.7.0"
"@cornerstonejs/tools@^0.34.2":
version "0.34.2"
resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-0.34.2.tgz#645c97583066a872fd35188153cd21b26625473e"
integrity sha512-rbdQuSXGJ++ARS6eUAkBZi0tjmUKVtad0QPk0SZZXlDC2QAQRyIfq7n7oF2AaIR/0ngarTekUzuIy2nKiaOT+Q==
dependencies:
"@cornerstonejs/core" "^0.25.1"
"@cornerstonejs/core" "^0.27.1"
lodash.clonedeep "4.5.0"
lodash.get "^4.4.2"
@ -9533,10 +9525,10 @@ cornerstone-wado-image-loader@^4.2.1:
dicom-parser "^1.8.9"
pako "^2.0.4"
cornerstone-wado-image-loader@^4.7.0:
version "4.7.0"
resolved "https://registry.npmjs.org/cornerstone-wado-image-loader/-/cornerstone-wado-image-loader-4.7.0.tgz#0b36ea3e8b0f4554234e3fc6db6260e95afea545"
integrity sha512-tq8YhiS4eQ9FmmxSCuoFmntSPzM9rccPq3WkeHbfglAEwmQjRaZMOR9r0MQaT0se/A9hY37q3xRfe9inhK1Ezw==
cornerstone-wado-image-loader@^4.8.0:
version "4.8.0"
resolved "https://registry.npmjs.org/cornerstone-wado-image-loader/-/cornerstone-wado-image-loader-4.8.0.tgz#64237a807227815bd117af839db4c05ab028d5f0"
integrity sha512-pvAAeH9tzL9PZydYOQqRSmIVoWiaxGDdgp0l/U8KafC0UNTiRyB6Sk0pTXTQqvGK2ZnwM4evjSDS9zyD3PxCmg==
dependencies:
"@babel/eslint-parser" "^7.19.1"
"@cornerstonejs/codec-charls" "^0.1.1"
@ -10105,7 +10097,7 @@ cypress-file-upload@^3.5.3:
cypress@^9.5.4:
version "9.7.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.7.0.tgz#bf55b2afd481f7a113ef5604aa8b693564b5e744"
resolved "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz#bf55b2afd481f7a113ef5604aa8b693564b5e744"
integrity sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==
dependencies:
"@cypress/request" "^2.88.10"
@ -11336,6 +11328,13 @@ eslint-module-utils@^2.7.3:
debug "^3.2.7"
find-up "^2.1.0"
eslint-plugin-cypress@^2.12.1:
version "2.12.1"
resolved "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.12.1.tgz#9aeee700708ca8c058e00cdafe215199918c2632"
integrity sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA==
dependencies:
globals "^11.12.0"
eslint-plugin-es@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893"
@ -11704,9 +11703,9 @@ event-stream@=3.3.4:
through "~2.3.1"
eventemitter2@^6.4.3:
version "6.4.5"
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.5.tgz#97380f758ae24ac15df8353e0cc27f8b95644655"
integrity sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==
version "6.4.9"
resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz#41f2750781b4230ed58827bc119d293471ecb125"
integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==
eventemitter3@^3.1.0:
version "3.1.2"
@ -12933,7 +12932,7 @@ global@^4.3.0, global@^4.4.0:
min-document "^2.19.0"
process "^0.11.10"
globals@^11.1.0, globals@^11.7.0:
globals@^11.1.0, globals@^11.12.0, globals@^11.7.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==