continue consolidating packages, converting various pieces to react

This commit is contained in:
Erik Ziegler 2018-12-13 23:24:39 +01:00
parent 5f30f7bd35
commit 7b66dec163
90 changed files with 350 additions and 485 deletions

View File

@ -31,7 +31,6 @@ ohif:cornerstone
ohif:viewerbase
ohif:study-list
ohif:hanging-protocols
ohif:user-oidc
ohif:measurement-table
fortawesome:fontawesome

View File

@ -68,11 +68,9 @@ ohif:cornerstone@0.0.1
ohif:hanging-protocols@0.0.1
ohif:measurement-table@0.0.1
ohif:measurements@0.0.1
ohif:studies@0.0.1
ohif:study-list@0.0.1
ohif:themes@0.0.1
ohif:themes-common@0.0.1
ohif:user-oidc@0.0.1
ohif:viewerbase@0.0.1
ordered-dict@1.1.0
promise@0.11.2

View File

@ -2,7 +2,8 @@ import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { Route, Switch } from 'react-router-dom';
import { OHIF } from 'meteor/ohif:core';
import Viewer from "./viewer/viewer";
import ViewerRouting from "./ViewerRouting.js";
import IHEInvokeImageDisplay from './IHEInvokeImageDisplay.js';
import './App.css';
const reload = () => window.location.reload();
@ -46,12 +47,24 @@ class App extends Component {
store={this.props.store}
/>
<Route
exact
path="/viewer"
component={Viewer}
path="/viewer/:studyInstanceUids"
component={ViewerRouting}
/*auth={this.props.auth}*/
store={this.props.store}
/>
<Route
path="/study/:studyInstanceUid/series/:seriesInstanceUids"
component={ViewerRouting}
/*auth={this.props.auth}*/
store={this.props.store}
/>
<Route
path="/IHEInvokeImageDisplay"
component={IHEInvokeImageDisplay}
/*auth={this.props.auth}*/
store={this.props.store}
/>
{/*<Route path="/silent-refresh.html" onEnter={reload} />
<Route path="/logout-redirect.html" onEnter={reload} />*/}
<Route render={() =>

View File

@ -0,0 +1,32 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import Viewer from "./viewer/viewer.js";
function IHEInvokeImageDisplay({ match }) {
const requestType = match.params.query.requestType;
let studyInstanceUids;
let displayStudyList = false;
if (requestType === "STUDY") {
studyInstanceUids = match.params.query.studyUID.split(';');
} else if (requestType === "STUDYBASE64") {
const uids = this.params.query.studyUID;
const decodedData = window.atob(uids);
studyInstanceUids = decodedData.split(';');
} else if (requestType === "PATIENT") {
const patientUids = this.params.query.patientID.split(';');
displayStudyList = true
} else {
displayStudyList = true
}
if (displayStudyList) {
return (<StudyList/>);
}
return (
<ViewerFromStudyData studyInstanceUids={studyInstanceUids}/>
);
}
export default IHEInvokeImageDisplay;

View File

@ -0,0 +1,57 @@
import React, {Component} from "react";
import PropTypes from "prop-types";
import Viewer from "./viewer/viewer.js";
import { OHIF } from 'meteor/ohif:core';
class ViewerFromStudyData extends Component {
constructor(props) {
super(props);
this.state = {
studies: null,
error: null
};
}
componentDidMount() {
// TODO: Avoid using timepoints here
//const params = { studyInstanceUids, seriesInstanceUids, timepointId, timepointsFilter={} };
const params = {
studyInstanceUids: this.props.studyInstanceUids,
seriesInstanceUids: this.props.seriesInstanceUids,
}
const promise = OHIF.viewerbase.prepareViewerData(params);
// Render the viewer when the data is ready
promise.then(({ studies, viewerData }) => {
OHIF.viewer.data = viewerData;
this.setState({
studies,
});
}).catch(error => {
this.setState({
error,
});
});
}
render() {
if (this.state.error) {
return (<div>Error: {JSON.stringify(this.state.error)}</div>);
} else if (!this.state.studies) {
return (<div>Loading...</div>);
}
return (
<Viewer studies={this.state.studies}/>
);
}
}
ViewerFromStudyData.propTypes = {
studyInstanceUids: PropTypes.array,
seriesInstanceUids: PropTypes.array
};
export default ViewerFromStudyData;

View File

@ -0,0 +1,23 @@
import React, {Component} from "react";
import PropTypes from "prop-types";
import ViewerFromStudyData from "./ViewerFromStudyData.js";
function ViewerRouting({ match }) {
const { studyInstanceUids, seriesInstanceUids } = match.params;
let studyUIDs;
let seriesUIDs;
if (studyInstanceUids && !seriesInstanceUids) {
studyUIDs = studyInstanceUids.split(';');
} else if (studyInstanceUids && seriesInstanceUids) {
studyUIDs = [match.params.studyInstanceUid];
seriesUIDs = match.params.seriesInstanceUids.split(';');
}
return (
<ViewerFromStudyData studyInstanceUids={studyUIDs} seriesInstanceUids={seriesUIDs}/>
);
}
export default ViewerRouting;

View File

@ -1,7 +1,6 @@
import { Component } from 'react';
import React from 'react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { OHIF } from 'meteor/ohif:core';
import { Viewerbase } from 'meteor/ohif:viewerbase';
import { StudyBrowser } from 'react-viewerbase';

View File

@ -91,7 +91,7 @@ class Viewer extends Component {
OHIF.viewer.StudyMetadataList.removeAll();
OHIF.viewer.data.studyInstanceUids = [];
const studies = this.props.studies;
studies.forEach(study => {
const studyMetadata = new OHIF.metadata.StudyMetadata(study, study.studyInstanceUid);

View File

@ -0,0 +1,6 @@
import { OHIF } from 'meteor/ohif:core';
import classes from './classes/';
OHIF.classes = classes;
export default classes;

View File

@ -1,5 +1,4 @@
import { OHIF } from 'meteor/ohif:core';
import 'meteor/ohif:viewerbase';
// Important metadata classes
const { OHIFError, metadata } = OHIF.viewerbase;

View File

@ -1,7 +1,7 @@
import { Session } from 'meteor/session';
import $ from 'jquery';
import { OHIF } from 'meteor/ohif:core';
import { getInstanceClassDefaultViewport } from '../instanceClassSpecificViewport';
//import { getInstanceClassDefaultViewport } from '../instanceClassSpecificViewport';
// Manage resizing viewports triggered by window resize
export class ResizeViewportManager {
@ -96,12 +96,12 @@ export class ResizeViewportManager {
cornerstone.resize(element, fitToWindow);
if (enabledElement.fitToWindow === false) {
/*if (enabledElement.fitToWindow === false) {
const imageId = enabledElement.image.imageId;
const instance = cornerstone.metaData.get('instance', imageId);
const instanceClassViewport = getInstanceClassDefaultViewport(instance, enabledElement, imageId);
cornerstone.setViewport(element, instanceClassViewport);
}
}*/
}
// Resize each viewport element

View File

@ -4,8 +4,7 @@ import $ from 'jquery';
import _ from 'underscore';
import { OHIF } from 'meteor/ohif:core';
import { OHIFError } from './OHIFError';
import { StackManager } from '../StackManager.js';
import { getImageId } from '../getImageId.js';
//import { getImageId } from '../getImageId.js';
export class StudyPrefetcher {
@ -89,6 +88,8 @@ export class StudyPrefetcher {
const activeViewportIndex = window.store.getState().viewports.activeViewport;
const displaySetInstanceUid = OHIF.viewer.data.loadedSeriesData[activeViewportIndex].displaySetInstanceUid;
const { StackManager } = OHIF.viewerbase;
const stack = StackManager.findStack(displaySetInstanceUid);
if (!stack) {
@ -295,7 +296,7 @@ export class StudyPrefetcher {
getImageIdsFromDisplaySet(displaySet) {
const imageIds = [];
displaySet.images.forEach(image => {
/*displaySet.images.forEach(image => {
const numFrames = image.numFrames;
if (numFrames > 1) {
for (let i = 0; i < numFrames; i++) {
@ -306,9 +307,9 @@ export class StudyPrefetcher {
let imageId = getImageId(image);
imageIds.push(imageId);
}
});
});*/
return imageIds;
return [];//imageIds;
}
filterCachedImageIds(imageIds) {

View File

@ -2,10 +2,68 @@ import MetadataProvider from './MetadataProvider.js';
import CommandsManager from './CommandsManager.js';
import HotkeysContext from './HotkeysContext.js';
import HotkeysManager from './HotkeysManager.js';
import { ImageSet } from './ImageSet';
import { StudyPrefetcher } from './StudyPrefetcher';
import { ResizeViewportManager } from './ResizeViewportManager';
import { StudyLoadingListener } from './StudyLoadingListener';
import { StackLoadingListener } from './StudyLoadingListener';
import { DICOMFileLoadingListener } from './StudyLoadingListener';
import { StudyMetadata } from './metadata/StudyMetadata';
import { SeriesMetadata } from './metadata/SeriesMetadata';
import { InstanceMetadata } from './metadata/InstanceMetadata';
//import { StudySummary } from './metadata/StudySummary';
import { plugins } from './plugins/';
import { TypeSafeCollection } from './TypeSafeCollection';
import { OHIFError } from './OHIFError.js';
//import { StackImagePositionOffsetSynchronizer } from './StackImagePositionOffsetSynchronizer';
import { StudyMetadataSource } from './StudyMetadataSource';
export {
MetadataProvider,
CommandsManager,
HotkeysContext,
HotkeysManager
HotkeysManager,
ImageSet,
StudyPrefetcher,
ResizeViewportManager,
StudyLoadingListener,
StackLoadingListener,
DICOMFileLoadingListener,
StudyMetadata,
SeriesMetadata,
InstanceMetadata,
//StudySummary,
TypeSafeCollection,
OHIFError,
//StackImagePositionOffsetSynchronizer,
StudyMetadataSource
};
const classes = {
MetadataProvider,
CommandsManager,
HotkeysContext,
HotkeysManager,
ImageSet,
StudyPrefetcher,
ResizeViewportManager,
StudyLoadingListener,
StackLoadingListener,
DICOMFileLoadingListener,
StudyMetadata,
SeriesMetadata,
InstanceMetadata,
//StudySummary,
TypeSafeCollection,
OHIFError,
//StackImagePositionOffsetSynchronizer,
StudyMetadataSource
};
export default classes;
//Viewerbase.metadata = { StudyMetadata, SeriesMetadata, InstanceMetadata, StudySummary };
//Viewerbase.plugins = plugins;
// TypeSafeCollection
//Viewerbase.TypeSafeCollection = TypeSafeCollection;

View File

@ -1,5 +1,5 @@
import { Metadata } from './Metadata';
import { OHIFError } from '../OHIFError';
import { OHIFError } from '../OHIFError.js';
/**
* ATTENTION! This class should never depend on StudyMetadata or SeriesMetadata classes as this could
@ -93,7 +93,7 @@ export class InstanceMetadata extends Metadata {
let value = this.getTagValue(tagOrProperty, defaultValue);
if (typeof value !== STRING && typeof value !== UNDEFINED) {
value = value.toString();
value = value.toString();
}
return InstanceMetadata.getIndexedValue(value, index, defaultValue);
@ -108,7 +108,7 @@ export class InstanceMetadata extends Metadata {
value.forEach( (val, idx) => {
value[idx] = parseFloat(val);
});
return value;
}
@ -195,7 +195,7 @@ export class InstanceMetadata extends Metadata {
* Get an value based that can be index based. This function is called by all getters. See above functions.
* - If value is a String and has indexes:
* - If undefined index: returns an array of the split values.
* - If defined index:
* - If defined index:
* - If invalid: returns defaultValue
* - If valid: returns the indexed value
* - If value is not a String, returns default value.

View File

@ -1,7 +1,5 @@
import { Viewerbase } from 'meteor/ohif:viewerbase';
const InstanceMetadata = Viewerbase.metadata.InstanceMetadata;
const DICOMTagDescriptions = Viewerbase.DICOMTagDescriptions;
import { InstanceMetadata } from './InstanceMetadata';
import { DICOMTagDescriptions } from '../../lib/DICOMTagDescriptions.js';
export class OHIFInstanceMetadata extends InstanceMetadata {

View File

@ -1,7 +1,7 @@
import { Viewerbase } from 'meteor/ohif:viewerbase';
import { SeriesMetadata } from './SeriesMetadata';
import { OHIFInstanceMetadata } from './OHIFInstanceMetadata';
export class OHIFSeriesMetadata extends Viewerbase.metadata.SeriesMetadata {
export class OHIFSeriesMetadata extends SeriesMetadata {
/**
* @param {Object} Series object.

View File

@ -1,7 +1,7 @@
import { Viewerbase } from 'meteor/ohif:viewerbase';
import { StudyMetadata } from './StudyMetadata';
import { OHIFSeriesMetadata } from './OHIFSeriesMetadata';
export class OHIFStudyMetadata extends Viewerbase.metadata.StudyMetadata {
export class OHIFStudyMetadata extends StudyMetadata {
/**
* @param {Object} Study object.

View File

@ -1,3 +1,5 @@
import _ from 'underscore';
export class WadoRsMetaDataBuilder {
constructor() {
this.tags = {};

View File

@ -1,8 +1,18 @@
import { StudyMetadata } from './StudyMetadata';
import { SeriesMetadata } from './SeriesMetadata';
import { InstanceMetadata } from './InstanceMetadata';
import { OHIFStudyMetadata } from './OHIFStudyMetadata';
import { OHIFSeriesMetadata } from './OHIFSeriesMetadata';
import { OHIFInstanceMetadata } from './OHIFInstanceMetadata';
import { Metadata } from './Metadata';
import { WadoRsMetaDataBuilder } from './WadoRsMetaDataBuilder';
const metadata = {
Metadata,
WadoRsMetaDataBuilder,
StudyMetadata,
SeriesMetadata,
InstanceMetadata,
OHIFStudyMetadata,
OHIFSeriesMetadata,
OHIFInstanceMetadata

View File

@ -1,3 +1,4 @@
import './studies.js';
import './lib';
import './helpers';
import './commands';
@ -7,6 +8,8 @@ import './ui';
import './header.js';
import './schema.js';
import './utils/';
import './metadata.js';
import './startup.js';
import './classes/';
import './cornerstone.js';
import './classes.js';

View File

@ -1,4 +1,4 @@
// TODO: Deprecate since we have the same thing in dcmjs?
const NUMBER = 'number';
const STRING = 'string';
const REGEX_TAG = /^x[0-9a-fx]{8}$/;

View File

@ -8,3 +8,11 @@ import './user.js';
import './object.js';
import './DICOMWeb/';
import './getCurrentServer.js';
import './DICOMTagDescriptions.js';
import './getStudyBoxData';
import './loadStudy';
import './retrieveStudiesMetadata';
import './retrieveStudyMetadata';
import './searchStudies';
import './parseFloatArray';

View File

@ -1,6 +1,5 @@
import { Meteor } from 'meteor/meteor';
import { OHIF } from 'meteor/ohif:core';
import 'meteor/ohif:viewerbase';
// Define the StudyMetaDataPromises object. This is used as a cache to store study meta data
// promises and prevent unnecessary subsequent calls to the server

View File

@ -1,5 +1,5 @@
import { OHIF } from 'meteor/ohif:core';
import { metadata } from '/client/classes/metadata/';
import metadata from './classes/metadata/';
/**
* Append Metadata namespace to OHIF namespace...

View File

@ -0,0 +1,15 @@
// DICOMWeb instance, study, and metadata retrieval
import Instances from './qido/instances.js';
import Studies from './qido/studies.js';
import RetrieveMetadata from './wado/retrieveMetadata.js';
const WADO = {
RetrieveMetadata
};
const QIDO = {
Studies,
Instances
};
export { QIDO, WADO };

View File

@ -13,6 +13,8 @@ const { DICOMWeb } = OHIF;
* @returns {Array} Series List
*/
function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
const { DICOMWeb } = OHIF;
var seriesMap = {};
var seriesList = [];
@ -67,7 +69,7 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
* @throws ECONNREFUSED
* @returns {{wadoUriRoot: String, studyInstanceUid: String, seriesList: Array}}
*/
OHIF.studies.services.QIDO.Instances = function(server, studyInstanceUid) {
export default function Instances(server, studyInstanceUid) {
// TODO: Are we using this function anywhere?? Can we remove it?
const config = {

View File

@ -88,6 +88,8 @@ function getQIDOQueryParams(filter, serverSupportsQIDOIncludeField) {
* @returns {Array} An array of Study MetaData objects
*/
function resultDataToStudies(resultData) {
const { DICOMWeb } = OHIF;
const studies = [];
if (!resultData || !resultData.length) return;
@ -116,7 +118,7 @@ function resultDataToStudies(resultData) {
return studies;
}
OHIF.studies.services.QIDO.Studies = (server, filter) => {
export default function Studies(server, filter) {
const config = {
url: server.qidoRoot,
headers: OHIF.DICOMWeb.getAuthorizationHeader()

View File

@ -3,7 +3,12 @@ import DICOMwebClient from 'dicomweb-client';
import { parseFloatArray } from '../../lib/parseFloatArray';
const { DICOMWeb } = OHIF;
WADOProxy = {
convertURL: (url, server) => {
// TODO: Remove all WADOProxy stuff from this file
return url;
}
}
/**
* Simple cache schema for retrieved color palettes.
@ -146,6 +151,8 @@ function getPaletteColor(server, instance, tag, lutDescriptor) {
* @returns {String} The ReferenceSOPInstanceUID
*/
async function getPaletteColors(server, instance, lutDescriptor) {
const { DICOMWeb } = OHIF;
let paletteUID = DICOMWeb.getString(instance['00281199']);
return new Promise((resolve, reject) => {
@ -195,6 +202,8 @@ function getFrameIncrementPointer(element) {
}
function getRadiopharmaceuticalInfo(instance) {
const { DICOMWeb } = OHIF;
const modality = DICOMWeb.getString(instance['00080060']);
if (modality !== 'PT') {
@ -225,6 +234,8 @@ function getRadiopharmaceuticalInfo(instance) {
* @returns {{seriesList: Array, patientName: *, patientId: *, accessionNumber: *, studyDate: *, modalities: *, studyDescription: *, imageCount: *, studyInstanceUid: *}}
*/
async function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
const { DICOMWeb } = OHIF;
if (!resultData.length) {
return;
}
@ -362,7 +373,7 @@ async function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
* @param studyInstanceUid
* @returns {Promise}
*/
OHIF.studies.services.WADO.RetrieveMetadata = async function(server, studyInstanceUid) {
async function RetrieveMetadata (server, studyInstanceUid) {
const config = {
url: server.wadoRoot,
headers: OHIF.DICOMWeb.getAuthorizationHeader()
@ -376,3 +387,5 @@ OHIF.studies.services.WADO.RetrieveMetadata = async function(server, studyInstan
return resultDataToStudyMetadata(server, studyInstanceUid, result);
});
};
export default RetrieveMetadata;

View File

@ -0,0 +1,9 @@
import { OHIF } from 'meteor/ohif:core';
import { QIDO, WADO } from './services/';
OHIF.studies = {
services: {
QIDO,
WADO
}
};

View File

@ -3,7 +3,9 @@ Npm.depends({
'jquery.hotkeys': '0.1.0',
loglevel: '1.4.1',
jquery: '3.3.1',
underscore: "1.9.1"
underscore: "1.9.1",
'dicomweb-client': '0.3.2',
'xhr2': '0.1.4'
});
Package.describe({

View File

@ -1,9 +1,9 @@
import Hammer from 'hammerjs';
import cornerstone from 'cornerstone-core/dist/cornerstone.js';
import cornerstoneMath from 'cornerstone-math/dist/cornerstoneMath.js';
import cornerstoneTools from 'cornerstone-tools/dist/cornerstoneTools.js';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoader.js';
import dicomParser from 'dicom-parser'; // Importing from dist breaks instance reference of dicomParser.DataSet class
import cornerstone from 'cornerstone-core';
import cornerstoneMath from 'cornerstone-math';
import cornerstoneTools from 'cornerstone-tools';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import dicomParser from 'dicom-parser';
import * as dcmjs from 'dcmjs/build/dcmjs';
cornerstoneTools.external.Hammer = Hammer;

View File

@ -1,5 +1,4 @@
// OHIF Modules
import { Viewerbase } from 'meteor/ohif:viewerbase';
import { OHIF } from 'meteor/ohif:core';
// Local imports
import { validate } from '../lib/validate.js';
@ -8,7 +7,8 @@ import '../customAttributes';
/**
* Import Constants
*/
const { OHIFError, metadata: { StudySummary, InstanceMetadata } } = Viewerbase;
const { OHIFError } = OHIF.classes;
const { StudySummary, InstanceMetadata } = OHIF.metadata;
/**
* Match a Metadata instance against rules using Validate.js for validation.
@ -53,7 +53,7 @@ const match = (metadataInstance, rules) => {
[attribute]: rule.constraint
};
// Create a single attribute object to be validated, since metadataInstance is an
// Create a single attribute object to be validated, since metadataInstance is an
// instance of Metadata (StudyMetadata, SeriesMetadata or InstanceMetadata)
const attributeValue = customAttributeExists ? metadataInstance.getCustomAttribute(attribute) : metadataInstance.getTagValue(attribute);
const attributeMap = {
@ -112,4 +112,4 @@ const HPMatcher = {
match
};
export { HPMatcher };
export { HPMatcher };

View File

@ -15,7 +15,8 @@ import './customViewportSettings';
* Import Constants
*/
const { OHIFError, metadata: { StudyMetadata, SeriesMetadata, InstanceMetadata, StudySummary } } = OHIF.viewerbase;
const { OHIFError } = OHIF.classes;
const { StudyMetadata, SeriesMetadata, InstanceMetadata, StudySummary } = OHIF.metadata;
// Useful constants
const ABSTRACT_PRIOR_VALUE = 'abstractPriorValue';

View File

@ -29,7 +29,6 @@ Package.onUse(function(api) {
// Our custom packages
api.use('ohif:cornerstone');
api.use('ohif:core');
api.use('ohif:studies');
api.use('ohif:viewerbase');
// Client imports

View File

@ -12,7 +12,7 @@ import './getLocationLabel';
import './getParentToolData';
import './getTimepointName';
import './getToolConfiguration';
import './hangingProtocolCustomizations';
//import './hangingProtocolCustomizations';
import './isNewLesionsMeasurement';
import './isSaveDisabled';
import './MeasurementHandlers';

View File

@ -1 +0,0 @@
require('../imports/client');

View File

@ -1,2 +0,0 @@
import './lib';
import './services';

View File

@ -1,9 +0,0 @@
import { OHIF } from 'meteor/ohif:core';
import { OHIFStudyMetadataSource } from './OHIFStudyMetadataSource';
import { OHIFStudySummary } from './OHIFStudySummary';
OHIF.studies = {};
OHIF.studies.classes = {
OHIFStudyMetadataSource,
OHIFStudySummary
};

View File

@ -1,7 +0,0 @@
import './classes';
import './getStudyBoxData';
import './loadStudy';
import './retrieveStudiesMetadata';
import './retrieveStudyMetadata';
import './searchStudies';
import './parseFloatArray';

View File

@ -1,6 +0,0 @@
import './namespace';
// DICOMWeb instance, study, and metadata retrieval
import './qido/instances.js';
import './qido/studies.js';
import './wado/retrieveMetadata.js';

View File

@ -1,6 +0,0 @@
import { OHIF } from 'meteor/ohif:core';
OHIF.studies.services = {
QIDO: {},
WADO: {}
};

View File

@ -1,31 +0,0 @@
Package.describe({
name: 'ohif:studies',
summary: 'OHIF Studies Library to deal with studies UI, retrieval and manipulation',
version: '0.0.1'
});
Npm.depends({
dimse: '0.0.2',
'dicomweb-client': '0.3.2',
'xhr2': '0.1.4'
});
Package.onUse(function(api) {
api.versionsFrom('1.7');
api.use([
'ecmascript',
'templating',
'stylus',
'http'
]);
// Our custom packages
api.use([
'ohif:core',
'ohif:viewerbase',
]);
// Client imports
api.addFiles('client/main.js', 'client');
});

View File

@ -0,0 +1,9 @@
.StudyList {
height: 100%;
width: 100%;
}
.tempStudyList {
height: 100%;
width: 100%;
}

View File

@ -1,7 +1,6 @@
import { OHIF } from 'meteor/ohif:core';
import 'meteor/ohif:viewerbase';
const { StudyMetadata, StudySummary } = OHIF.viewerbase.metadata;
const { StudyMetadata, StudySummary } = OHIF.metadata;
const PATIENT_ID = 'x00100020';
const STUDY_DATE = 'x00080020';

View File

@ -1,13 +1,13 @@
import { OHIF } from 'meteor/ohif:core';
// Functions
import { getStudyPriors } from './getStudyPriors';
/*import { getStudyPriors } from './getStudyPriors';
import { getStudyPriorsMap } from './getStudyPriorsMap';
OHIF.studylist.functions = {
getStudyPriors,
getStudyPriorsMap
};
};*/
const dblClickOnStudy = data => {
//Router.go('viewerStudies', { studyInstanceUids: data.studyInstanceUid });

View File

@ -26,7 +26,6 @@ Package.onUse(function(api) {
// Our custom packages
api.use('ohif:core', 'client');
api.use('ohif:viewerbase', 'client');
api.use('ohif:studies', 'client');
// Client imports
api.addFiles('client/index.js', 'client');

View File

@ -1,6 +1,7 @@
import { Meteor } from 'meteor/meteor';
import { OHIF } from '../namespace';
import { TypeSafeCollection } from './lib/classes/TypeSafeCollection';
const { TypeSafeCollection } = OHIF.classes;
// Create main Studies collection which will be used across the entire viewer...
const Studies = new TypeSafeCollection();
@ -13,6 +14,3 @@ const StudyMetadataList = new TypeSafeCollection();
// Make it publicly available on "OHIF.viewer" namespace...
OHIF.viewer.StudyMetadataList = StudyMetadataList;
// Subscriptions...
Meteor.subscribe('studyImportStatus');

View File

@ -3,10 +3,10 @@ import { Session } from 'meteor/session';
import { OHIF } from 'meteor/ohif:core';
// Local Modules
import { unloadHandlers } from '../../../lib/unloadHandlers';
import { ResizeViewportManager } from '../../../lib/classes/ResizeViewportManager';
import { LayoutManager } from '../../../lib/classes/LayoutManager';
import { StudyPrefetcher } from '../../../lib/classes/StudyPrefetcher';
import { StudyLoadingListener } from '../../../lib/classes/StudyLoadingListener';
const { StudyLoadingListener, StudyPrefetcher, ResizeViewportManager } = OHIF.classes;
import './ViewerMain.styl';
import { Component } from 'react';

View File

@ -95,10 +95,6 @@ Viewerbase.getStudyMetadata = getStudyMetadata;
* Exported Namespaces (sub-namespaces)
*/
// imageViewerViewportData.*
import { imageViewerViewportData } from './lib/imageViewerViewportData';
Viewerbase.imageViewerViewportData = imageViewerViewportData;
// panelNavigation.*
import { panelNavigation } from './lib/panelNavigation';
Viewerbase.panelNavigation = panelNavigation;
@ -127,10 +123,6 @@ Viewerbase.viewportOverlayUtils = viewportOverlayUtils;
import { viewportUtils } from './lib/viewportUtils';
Viewerbase.viewportUtils = viewportUtils;
// thumbnailDragHandlers.*
import { thumbnailDragHandlers } from './lib/thumbnailDragHandlers';
Viewerbase.thumbnailDragHandlers = thumbnailDragHandlers;
// dialogUtils.*
import { dialogUtils } from './lib/dialogUtils';
Viewerbase.dialogUtils = dialogUtils;
@ -187,67 +179,5 @@ Viewerbase.helpers = helpers;
import { sopClassDictionary } from './lib/sopClassDictionary';
Viewerbase.sopClassDictionary = sopClassDictionary;
// dicomTagDescriptions
import { DICOMTagDescriptions } from './lib/DICOMTagDescriptions';
Viewerbase.DICOMTagDescriptions = DICOMTagDescriptions;
/**
* Exported Classes
*/
// ImageSet
import { ImageSet } from './lib/classes/ImageSet';
Viewerbase.ImageSet = ImageSet;
// LayoutManager
import { LayoutManager } from './lib/classes/LayoutManager';
Viewerbase.LayoutManager = LayoutManager;
// StudyPrefetcher
import { StudyPrefetcher } from './lib/classes/StudyPrefetcher';
Viewerbase.StudyPrefetcher = StudyPrefetcher;
// ResizeViewportManager
import { ResizeViewportManager } from './lib/classes/ResizeViewportManager';
Viewerbase.ResizeViewportManager = ResizeViewportManager;
// StudyLoadingListener
import { StudyLoadingListener } from './lib/classes/StudyLoadingListener';
Viewerbase.StudyLoadingListener = StudyLoadingListener;
// StackLoadingListener
import { StackLoadingListener } from './lib/classes/StudyLoadingListener';
Viewerbase.StackLoadingListener = StackLoadingListener;
// DICOMFileLoadingListener
import { DICOMFileLoadingListener } from './lib/classes/StudyLoadingListener';
Viewerbase.DICOMFileLoadingListener = DICOMFileLoadingListener;
// StudyMetadata, SeriesMetadata, InstanceMetadata
import { StudyMetadata } from './lib/classes/metadata/StudyMetadata';
import { SeriesMetadata } from './lib/classes/metadata/SeriesMetadata';
import { InstanceMetadata } from './lib/classes/metadata/InstanceMetadata';
import { StudySummary } from './lib/classes/metadata/StudySummary';
Viewerbase.metadata = { StudyMetadata, SeriesMetadata, InstanceMetadata, StudySummary };
import { plugins } from './lib/classes/plugins/';
Viewerbase.plugins = plugins;
// TypeSafeCollection
import { TypeSafeCollection } from './lib/classes/TypeSafeCollection';
Viewerbase.TypeSafeCollection = TypeSafeCollection;
// OHIFError
import { OHIFError } from './lib/classes/OHIFError';
Viewerbase.OHIFError = OHIFError;
// StackImagePositionOffsetSynchronizer
import { StackImagePositionOffsetSynchronizer } from './lib/classes/StackImagePositionOffsetSynchronizer';
Viewerbase.StackImagePositionOffsetSynchronizer = StackImagePositionOffsetSynchronizer;
// StudyMetadataSource
import { StudyMetadataSource } from './lib/classes/StudyMetadataSource';
Viewerbase.StudyMetadataSource = StudyMetadataSource;
import redux from './lib/redux/';
Viewerbase.redux = redux;

View File

@ -1,11 +1,13 @@
import { OHIF } from 'meteor/ohif:core';
import { getImageId } from './getImageId';
import { OHIFError } from './classes/OHIFError';
let stackMap = {};
let configuration = {};
const stackUpdatedCallbacks = [];
const { OHIFError } = OHIF.classes;
/**
* Loop through the current series and add metadata to the
* Cornerstone meta data provider. This will be used to fill information

View File

@ -674,3 +674,4 @@ export class LayoutManager {
return this.layoutProps.row !== 1 && this.layoutProps.columns !== 1;
}
}

View File

@ -1,5 +1,4 @@
import { Meteor } from 'meteor/meteor';
import { ImageSet } from './classes/ImageSet';
import { isImage } from './isImage';
import { OHIF } from 'meteor/ohif:core';
@ -11,6 +10,7 @@ const isMultiFrame = instance => {
const makeDisplaySet = (series, instances) => {
const instance = instances[0];
const { ImageSet } = OHIF.classes;
const imageSet = new ImageSet(instances);
const seriesData = series.getData();

View File

@ -1,6 +1,20 @@
import { OHIF } from 'meteor/ohif:core';
import { getWADORSImageUrl } from './getWADORSImageUrl';
function getWADORSImageUrl(instance, frame) {
let wadorsuri = instance.wadorsuri;
if (!wadorsuri) {
return;
}
// We need to sum 1 because WADO-RS frame number is 1-based
frame = (frame || 0) + 1;
// Replaces /frame/1 by /frame/{frame}
wadorsuri = wadorsuri.replace(/(%2Fframes%2F)(\d+)/, `$1${frame}`);
return wadorsuri;
}
/**
* Obtain an imageId for Cornerstone based on the WADO-RS scheme

View File

@ -1,15 +0,0 @@
export function getWADORSImageUrl(instance, frame) {
let wadorsuri = instance.wadorsuri;
if (!wadorsuri) {
return;
}
// We need to sum 1 because WADO-RS frame number is 1-based
frame = (frame || 0) + 1;
// Replaces /frame/1 by /frame/{frame}
wadorsuri = wadorsuri.replace(/(%2Fframes%2F)(\d+)/, `$1${frame}`);
return wadorsuri;
}

View File

@ -1,7 +0,0 @@
export const imageViewerViewportData = {
callbacks: {},
extendData() {
// No-Op function...
}
};

View File

@ -3,7 +3,7 @@ import $ from 'jquery';
import { Random } from 'meteor/random';
import { OHIF } from 'meteor/ohif:core';
import { StudyPrefetcher } from './classes/StudyPrefetcher';
//import { StudyPrefetcher } from './classes/StudyPrefetcher';
import { displayReferenceLines } from './displayReferenceLines';
const PLUGIN_CORNERSTONE = 'cornerstone';
@ -48,7 +48,7 @@ export function setActiveViewport(element) {
// so we can't pass a jQuery object as an argument, otherwise it throws an excepetion
const domElement = $element.find('.imageViewerViewport').get(0);
displayReferenceLines(domElement);
StudyPrefetcher.getInstance().prefetch();
//StudyPrefetcher.getInstance().prefetch();
// @TODO Add this to OHIFAfterActivateViewport handler...
const synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer;

View File

@ -1,4 +1,4 @@
// TODO: Deprecate since we have the same thing in dcmjs?
export const sopClassDictionary = {
ComputedRadiographyImageStorage: "1.2.840.10008.5.1.4.1.1.1",
DigitalXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.1",

View File

@ -1,4 +1,6 @@
import { OHIFError } from './classes/OHIFError';
import { OHIF } from 'meteor/ohif:core';
const { OHIFError } = OHIF.classes;
/**
* Sorts the series and instances inside a study instance by their series

View File

@ -1,255 +0,0 @@
import $ from 'jquery';
import { OHIF } from 'meteor/ohif:core';
const cloneElement = (element, targetId) => {
// Clone the DOM element
const clone = element.cloneNode(true);
// Find any canvas children to clone
const clonedCanvases = $(clone).find('canvas');
clonedCanvases.each((canvasIndex, clonedCanvas) => {
// Draw from the original canvas to the cloned canvas
const context = clonedCanvas.getContext('2d');
const thumbnailCanvas = $(element).find('canvas').get(canvasIndex);
context.drawImage(thumbnailCanvas, 0, 0);
});
// Update the clone with the targetId
clone.id = targetId;
clone.style.visibility = 'hidden';
return clone;
};
const thumbnailDragStartHandler = (event, data) => {
// Prevent any scrolling behaviour normally caused by the original event
event.originalEvent.preventDefault();
// Identify the current study and series index from the thumbnail's DOM position
const targetThumbnail = event.currentTarget;
const $imageThumbnail = $(targetThumbnail);
// Force to hardware acceleration to move element
// if browser supports translate property
const useTransform = OHIF.ui.styleProperty.check('transform', 'translate(1px, 1px)');
// Clone the image thumbnail
const targetId = 'DragClone';
const clone = cloneElement(targetThumbnail, targetId);
const $clone = $(clone);
$clone.addClass('imageThumbnailClone');
// Set pointerEvents to pass through the clone DOM element
// This is necessary in order to identify what is below it
// when using document.elementFromPoint
clone.style.pointerEvents = 'none';
// Append the clone to the body
document.body.appendChild(clone);
// Set the cursor x and y positions from the current touch/mouse coordinates
let cursorX;
let cursorY;
// Handle touchStart cases
if (event.type === 'touchstart') {
cursorX = event.originalEvent.touches[0].pageX;
cursorY = event.originalEvent.touches[0].pageY;
} else {
cursorX = event.pageX;
cursorY = event.pageY;
// Also hook up event handlers for mouse events
const handlers = {};
handlers.mousemove = event => thumbnailDragHandler(event);
handlers.mouseup = event => thumbnailDragEndHandler(event, data, handlers);
$(document).on('mousemove', handlers.mousemove);
$(document).on('mouseup', handlers.mouseup);
}
// This block gets the current offset of the touch/mouse
// relative to the window
//
// i.e. Where did the user grab it from?
const offset = $imageThumbnail.offset();
const { left, top } = offset;
// This difference is saved for later so the element movement looks normal
const diff = {
x: cursorX - left,
y: cursorY - top
};
$clone.data('diff', diff);
$clone.css({
visibility: 'hidden',
'z-index': 100000
});
// This sets the default style properties of the cloned element so it is
// ready to be dragged around the page
if (useTransform) {
const viewerHeight = $('#viewer').height();
const headerHeight = $('.header').outerHeight();
const heightDiff = viewerHeight + headerHeight;
// Save height difference for later to set top position of the element during movement
$clone.data('heightDiff', heightDiff);
const positionX = cursorX - diff.x;
const positionY = cursorY - diff.y - heightDiff;
const translation = `translate(${positionX}px, ${positionY}px)`;
OHIF.ui.styleProperty.set($clone.get(0), 'transform', translation);
} else {
$clone.css({
left: cursorX - diff.x,
position: 'fixed',
top: cursorY - diff.y,
});
}
};
const thumbnailDragHandler = event => {
// Get the touch/mouse coordinates from the event
let cursorX;
let cursorY;
if (event.type === 'touchmove') {
cursorX = event.originalEvent.changedTouches[0].pageX;
cursorY = event.originalEvent.changedTouches[0].pageY;
} else {
cursorX = event.pageX;
cursorY = event.pageY;
}
// Find the clone element and update it's position on the page
const $clone = $('#DragClone');
const diff = $clone.data('diff');
// Force to hardware acceleration to move element
// if browser supports translate property
const useTransform = OHIF.ui.styleProperty.check('transform', 'translate(1px, 1px)');
$clone.css({
visibility: 'visible',
'z-index': 100000
});
// This sets the default style properties of the cloned element so it is
// ready to be dragged around the page
if (useTransform) {
const heightDiff = $clone.data('heightDiff');
const positionX = cursorX - diff.x;
const positionY = cursorY - diff.y - heightDiff;
const translation = `translate(${positionX}px, ${positionY}px)`;
OHIF.ui.styleProperty.set($clone.get(0), 'transform', translation);
} else {
$clone.css({
left: cursorX - diff.x,
position: 'fixed',
top: cursorY - diff.y,
});
}
// Identify the element below the current cursor position
const elemBelow = document.elementFromPoint(cursorX, cursorY);
// If none exists, stop here
if (!elemBelow) {
return;
}
// Remove any current faded effects on viewports
$('.viewportContainer canvas').removeClass('faded');
// Figure out what to do depending on what we're dragging over
const $viewportsDraggedOver = $(elemBelow).parents('.viewportContainer');
if ($viewportsDraggedOver.length) {
// If we're dragging over a non-empty viewport, fade it and change the cursor style
$viewportsDraggedOver.find('canvas').not('.magnifyTool').addClass('faded');
document.body.style.cursor = 'copy';
} else if (elemBelow.classList.contains('viewportContainer') && elemBelow.classList.contains('empty')) {
// If we're dragging over an empty viewport, just change the cursor style
document.body.style.cursor = 'copy';
} else {
// Otherwise, keep the cursor as no-drop style
document.body.style.cursor = 'no-drop';
}
};
const thumbnailDragEndHandler = (event, data, handlers) => {
// Remove the mouse event listeners
if (handlers) {
$(document).off('mousemove', handlers.mousemove);
$(document).off('mouseup', handlers.mouseup);
}
// Reset the cursor style to the default
document.body.style.cursor = 'auto';
// Get the cloned element
const $clone = $('#DragClone');
// If it doesn't exist, stop here
if (!$clone.length) {
return;
}
const offset = $clone.offset();
const { top, left } = offset;
const diff = $clone.data('diff');
// Identify the element below the cloned element position
const elemBelow = document.elementFromPoint(left + diff.x, top + diff.y);
// Remove all cloned elements from the page
$('.imageThumbnailClone').remove();
// Remove any current faded effects on viewports
$('.viewportContainer canvas').removeClass('faded');
// If none exists, stop here
if (!elemBelow) {
return;
}
// Remove any fade effects on the element below
elemBelow.classList.remove('faded');
let element;
const $viewportsDraggedOver = $(elemBelow).closest('.viewportContainer');
if ($viewportsDraggedOver.length) {
// If we're dragging over a non-empty viewport, retrieve it
element = $viewportsDraggedOver.get(0);
} else if (elemBelow.classList.contains('viewportContainer') &&
elemBelow.classList.contains('empty')) {
// If we're dragging over an empty viewport, retrieve that instead
element = elemBelow;
} else {
// Otherwise, stop here
return false;
}
// If there is no stored drag and drop data, stop here
if (!data) {
return false;
}
// Get the dropped viewport index
const viewportIndex = $('.viewportContainer').index(element);
// Rerender the viewport using the dragged thumbnail data
OHIF.viewerbase.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, data);
return false;
};
const thumbnailDragHandlers = {
thumbnailDragEndHandler,
thumbnailDragStartHandler,
thumbnailDragHandler
};
export { thumbnailDragHandlers };

View File

@ -1,6 +1,6 @@
import _ from 'underscore';
import { OHIF } from 'meteor/ohif:core';
import { getWADORSImageId } from './getWADORSImageId';
import { WadoRsMetaDataBuilder } from './classes/metadata/WadoRsMetaDataBuilder';
function getRadiopharmaceuticalInfoMetaData(instance) {
const radiopharmaceuticalInfo = instance.radiopharmaceuticalInfo;
@ -8,6 +8,7 @@ function getRadiopharmaceuticalInfoMetaData(instance) {
if ((instance.modality !== 'PT') || !radiopharmaceuticalInfo) {
return;
}
const { WadoRsMetaDataBuilder } = OHIF.metadata;
return new WadoRsMetaDataBuilder()
.addTag('00181072', radiopharmaceuticalInfo.radiopharmaceuticalStartTime)
@ -17,6 +18,7 @@ function getRadiopharmaceuticalInfoMetaData(instance) {
}
const getWadoRsInstanceMetaData = (study, series, instance) => {
const { WadoRsMetaDataBuilder } = OHIF.metadata;
return new WadoRsMetaDataBuilder()
.addTag('00080016', instance.sopClassUid)
.addTag('00080018', instance.sopInstanceUid)

View File

@ -158,7 +158,7 @@ Package.onUse(function(api) {
api.addFiles('client/components/viewer/studySeriesQuickSwitch/studySeriesQuickSwitch.styl', 'client');
api.addFiles('client/components/viewer/studySeriesQuickSwitch/studySeriesQuickSwitch.js', 'client');
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepoint.html', 'client');
/*api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepoint.html', 'client');
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepoint.styl', 'client');
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepoint.js', 'client');
@ -167,7 +167,7 @@ Package.onUse(function(api) {
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepointBrowser.js', 'client');
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepointStudy.html', 'client');
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js', 'client');
api.addFiles('client/components/viewer/studyTimepointBrowser/studyTimepointStudy.js', 'client');*/
api.addFiles('client/components/viewer/windowLevelPresets/form.html', 'client');
api.addFiles('client/components/viewer/windowLevelPresets/form.js', 'client');