diff --git a/.eslintrc.js b/.eslintrc.js
index b08c42504..72874e116 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -11,7 +11,7 @@ module.exports = {
'SharedArrayBuffer': 'readonly',
},
'parserOptions': {
- 'ecmaVersion': 2018,
+ 'ecmaVersion': 2020,
},
'rules': {
"require-jsdoc" : 0,
diff --git a/apps/dicom-connect/table.js b/apps/dicom-connect/table.js
deleted file mode 100644
index 785cf4542..000000000
--- a/apps/dicom-connect/table.js
+++ /dev/null
@@ -1,357 +0,0 @@
-/**
- * static variables
- */
-
-const sources = [{
- 'name':'j4care',
- 'url':'https://development.j4care.com:11443/dcm4chee-arc/aets/DCM4CHEE/rs'
-
-},{
- 'name': 'google',
- 'url': 'https://dicomwebproxy-bqmq3usc3a-uc.a.run.app/dicomWeb'
-}]
-// const j4careStudiesUrl = 'https://development.j4care.com:11443/dcm4chee-arc/aets/DCM4CHEE/rs'
-// const dicomWebStudiesUrl = 'https://dicomwebproxy-bqmq3usc3a-uc.a.run.app/dicomWeb'
-
-/**
- * global variables
- */
-isAllSeriesSynced = false;
-
-const datatableConfig = {
- scrollX: true,
- lengthMenu: [
- [10, 25, 50, -1],
- [10, 25, 50, 'All']
- ]
-}
-
-
-const page_states = {
- sources: {
- data: [{
- 'name':'j4care',
- 'url':'https://development.j4care.com:11443/dcm4chee-arc/aets/DCM4CHEE/rs'
-
- },{
- 'name': 'google',
- 'url': 'https://dicomwebproxy-bqmq3usc3a-uc.a.run.app/dicomWeb'
- }],
- },
- studies: {
- data: null,
- },
- series: {
- data: null,
- },
- instances: {
- data: null,
- },
- status: 'sources', // 'sources, studies, series, instsances'
-}
-var studies = []
-
-
-
-function getStudies(baseUrl) {
- const url = `${baseUrl}/studies`
- return fetch(url).then(resp=>resp.json());
-}
-
-function getSeries(baseUrl, studyId) {
- const url = `${baseUrl}/studies/${studyId}/series`
- return fetch(url).then(resp=>resp.json());
-}
-
-function getInstances(baseUrl, studyId, seriesId) {
- const url = `${baseUrl}/studies/${studyId}/series/${seriesId}/instances`
- return fetch(url).then(resp=>resp.json());
-}
-
-
-
-
-
-function sanitize(string) {
- string = string || '';
- const map = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- '\'': ''',
- '/': '/',
- };
- const reg = /[&<>"'/]/ig;
- return string.replace(reg, (match) => (map[match]));
-}
-
-
-function initialize() {
- const params = getUrlVars();
- console.log('params')
- console.log(params)
- // store
- const store = new Store('../../data/');
- if(params.status=='studies'&¶ms.source){
- page_states.status = params.status;
- }else if(params.status=='series'&¶ms.source&¶ms.studyId) { // series table
- page_states.status = params.status;
- } else if(params.status=='instances'&¶ms.source&¶ms.studyId&¶ms.seriesId) { // isntasnces table
- page_states.status = params.status;
- }
-
-
-
- //
`;
+ if (modality=='SM') {
+ return `
` + previewBtn + progressIcon + `
`;
+ } else {
+ return `
` + progressIcon + `
`;
+ }
+
+ case 'done':
+ // return url
+
+ return '
' + previewBtn + `
`;
+
+ default:
+
+ return '
';
+ }
+ }
+ datatable = $('#datatable').DataTable({
+ ...datatableConfig,
+ 'data': pageStates[pageStates.status].data,
+ 'columns': [
+ {data: 'status', title: 'Status', render: generateStatus},
+ {data: '0020000E.Value.0', title: 'Series Id', render: generateLink},
+ {data: '00080060.Value.0', title: 'Modality'},
+ {data: 'source', title: 'Source'},
+ {data: 'studyId', title: 'study Id'},
+
+ ],
+ });
+
+ async function checkInterval() {
+ const query = {
+ 'dicom-source-url': src.url,
+ 'study': params.studyId,
+ };
+
+ const slides = await store.findSlide(null, null, params.studyId, null, query);
+ console.log(slides);
+
+ const data = datatable.data();
+
+ for (let i = 0; i < data.length; i++) {
+ const d = data[i];
+ const modality = d['00080060']['Value'][0];
+ const series = d['0020000E']['Value'][0];
+
+ if (modality === 'SM') {
+ const idx = slides.findIndex((slide) => series === slide.series);
+ if (idx !== -1) {
+ d.status = slides[idx].status;
+ d.slideId = slides[idx]._id.$oid;
+ } else {
+ d.status = 'unsync';
+ }
+ }
+
+ if (modality === 'ANN') {
+ let annotationQuery = {
+ 'provenance.image.dicom-source-url': src.url,
+ 'provenance.image.dicom-study': params.studyId,
+ 'provenance.image.dicom-series': series,
+ };
+
+ let annotationCount = await store.countMarks(annotationQuery);
+ console.info('Counted ' + annotationCount[0].count + ' mark objects for ' + series);
+
+ if (annotationCount[0].count > 0) {
+ d.status = 'done';
+ d.slideId = slides[0]._id.$oid;
+ } else {
+ d.status = 'unsync';
+ }
+ }
+ }
+
+ datatable.rows().invalidate().draw();
+
+ const series = pageStates[pageStates.status].data;
+
+ if (series.every((s) => s.status !== 'unsync' && s.status !== 'syncing')) {
+ console.log('clear');
+ clearInterval(updateSeriesStatus);
+ }
+
+ console.log('running');
+ }
+
+ // initialize
+ checkInterval();
+ // update every 10 seconds
+ var updateSeriesStatus = setInterval(checkInterval, 10000);
+ });
+ break;
+ case 'instances':
+ // get source info
+ var idx = sources.findIndex((elt)=>elt.name==params.source);
+ var src = sources[idx];
+ // create breadcrumb for instances
+ const backSeriesUrl = `../dicom-web/table.html?source=${params.source}&status=series&studyId=${params.studyId}`;
+ $('#breadcrumb').append(`
Sources`);
+ $('#breadcrumb').append(`
${src.name}`);
+ $('#breadcrumb').append(`
${params.studyId}`);
+ $('#breadcrumb').append(`
${params.seriesId}`);
+
+
+ getInstances(src.url, params.studyId, params.seriesId).then(function(data) {
+ // add status
+ data.forEach((elt)=>{
+ elt.source=params.source;
+ elt.studyId=params.studyId;
+ elt.seriesId=params.seriesId;
+ });
+ pageStates[pageStates.status].data = data;
+ function generateLink(data, type, row) {
+ const {studyId, seriesId, status}= row;
+ const instanceId = row['00080018']['Value'][0];
+ if (status=='done') return instanceId;
+ return `
${instanceId}`;
+ }
+
+ datatable = $('#datatable').DataTable({
+ ...datatableConfig,
+ 'data': pageStates[pageStates.status].data,
+ 'columns': [
+ {data: '00080018.Value.0', title: 'Instance Id', render: generateLink},
+ {data: 'source', title: 'Source'},
+ {data: 'seriesId', title: 'Series Id'},
+ {data: 'studyId', title: 'Study Id'},
+
+ ],
+ });
+ });
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+$(document).ready(function() {
+ initialize();
+});
+
+
+async function syncSeries(sourceUrl, study, series, modality) {
+ console.log(sourceUrl, study, series, modality);
+ const result = await store.syncSeries('../../', {'source_url': sourceUrl, study, series, modality});
+ console.log('syncSeries:');
+ console.log(result);
+}
+
+function checkSeriesStatus() {
+ const series = pageStates[pageStates.status].data;
+ series.map();
+}
+// table.rows.add( dataset ).draw().
+
diff --git a/apps/viewer/init.js b/apps/viewer/init.js
index e297a591d..6c091f1a4 100644
--- a/apps/viewer/init.js
+++ b/apps/viewer/init.js
@@ -439,7 +439,7 @@ async function initUIcomponents() {
const subToolsOpt = [];
// home
- if (ImgloaderMode == 'iip') {
+ if (ImgloaderMode == 'iip' || $D.params.mode == 'dcmweb') {
subToolsOpt.push({
name: 'home',
icon: 'home', // material icons' name
@@ -450,6 +450,7 @@ async function initUIcomponents() {
callback: goHome,
});
}
+
// pen
subToolsOpt.push({
name: 'annotation',
@@ -470,6 +471,7 @@ async function initUIcomponents() {
callback: drawLabel,
});
+
// magnifier
subToolsOpt.push({
name: 'magnifier',
@@ -522,55 +524,57 @@ async function initUIcomponents() {
callback: toggleMeasurement,
});
}
- // donwload selection
- subToolsOpt.push({
- name: 'download_selection',
- icon: 'get_app', // material icons' name
- title: 'Download Selection',
- type: 'check',
- value: 'download',
- ariaLabel: 'Download selection',
- callback: toggleDownloadSelection,
- });
- // enhance
- subToolsOpt.push({
- name: 'Enhance',
- icon: 'invert_colors',
- title: 'Enhance',
- type: 'dropdown',
- value: 'Enhance',
- ariaLabel: 'Enhance',
- dropdownList: [
- {
- value: 'Histogram Eq',
- title: 'Histogram Equalization',
- icon: 'leaderboard',
- ariaLabel: 'Histogram equalization',
- checked: true,
- },
- {
- value: 'Edge',
- title: 'Edge',
- icon: 'show_chart',
- ariaLabel: 'Edge',
- },
- {
- value: 'Sharpen',
- title: 'Sharpen',
- icon: 'change_history',
- ariaLabel: 'Sharpen',
- },
- {
- value: 'Custom',
- title: 'Custom',
- icon: 'api',
- ariaLabel: 'Custom',
- },
- ],
- callback: enhance,
- });
+ if ($D.params.mode != 'dcmweb') {
+ // donwload selection
+ subToolsOpt.push({
+ name: 'download_selection',
+ icon: 'get_app', // material icons' name
+ title: 'Download Selection',
+ type: 'check',
+ value: 'download',
+ ariaLabel: 'Download selection',
+ callback: toggleDownloadSelection,
+ });
+ // enhance
+ subToolsOpt.push({
+ name: 'Enhance',
+ icon: 'invert_colors',
+ title: 'Enhance',
+ type: 'dropdown',
+ value: 'Enhance',
+ ariaLabel: 'Enhance',
+ dropdownList: [
+ {
+ value: 'Histogram Eq',
+ title: 'Histogram Equalization',
+ icon: 'leaderboard',
+ ariaLabel: 'Histogram equalization',
+ checked: true,
+ },
+ {
+ value: 'Edge',
+ title: 'Edge',
+ icon: 'show_chart',
+ ariaLabel: 'Edge',
+ },
+ {
+ value: 'Sharpen',
+ title: 'Sharpen',
+ icon: 'change_history',
+ ariaLabel: 'Sharpen',
+ },
+ {
+ value: 'Custom',
+ title: 'Custom',
+ icon: 'api',
+ ariaLabel: 'Custom',
+ },
+ ],
+ callback: enhance,
+ });
+ }
// share
- if (ImgloaderMode == 'iip') {
+ if (ImgloaderMode == 'iip' || $D.params.mode == 'dcmweb') {
subToolsOpt.push({
name: 'share',
icon: 'share',
@@ -591,58 +595,61 @@ async function initUIcomponents() {
ariaLabel: 'Side by side viewer',
callback: toggleViewerMode,
});
- // heatmap
- subToolsOpt.push({
- name: 'heatmap',
- icon: 'satellite',
- title: 'Heat Map',
- value: 'heatmap',
- type: 'btn',
- ariaLabel: 'Heat map',
- callback: openHeatmap,
- });
- subToolsOpt.push({
- name: 'labeling',
- icon: 'label',
- title: 'Labeling',
- value: 'labeling',
- type: 'btn',
- ariaLabel: 'Labeling',
- callback: function() {
- window.location.href = `../labeling/labeling.html${window.location.search}`;
- },
- });
- subToolsOpt.push({
- name: 'segment',
- icon: 'timeline',
- type: 'btn',
- value: 'rect',
- title: 'Segment',
- ariaLabel: 'Segment',
- callback: function() {
- if (window.location.search.length > 0) {
- window.location.href =
- '../segment/segment.html' + window.location.search;
- } else {
- window.location.href = '../segment/segment.html';
- }
- },
- });
- subToolsOpt.push({
- name: 'model',
- icon: 'aspect_ratio',
- type: 'btn',
- value: 'rect',
- title: 'Predict',
- ariaLabel: 'Predict',
- callback: function() {
- if (window.location.search.length > 0) {
- window.location.href = '../model/model.html' + window.location.search;
- } else {
- window.location.href = '../model/model.html';
- }
- },
- });
+
+ if ($D.params.mode != 'dcmweb') {
+ // heatmap
+ subToolsOpt.push({
+ name: 'heatmap',
+ icon: 'satellite',
+ title: 'Heat Map',
+ value: 'heatmap',
+ type: 'btn',
+ ariaLabel: 'Heat map',
+ callback: openHeatmap,
+ });
+ subToolsOpt.push({
+ name: 'labeling',
+ icon: 'label',
+ title: 'Labeling',
+ value: 'labeling',
+ type: 'btn',
+ ariaLabel: 'Labeling',
+ callback: function() {
+ window.location.href = `../labeling/labeling.html${window.location.search}`;
+ },
+ });
+ subToolsOpt.push({
+ name: 'segment',
+ icon: 'timeline',
+ type: 'btn',
+ value: 'rect',
+ title: 'Segment',
+ ariaLabel: 'Segment',
+ callback: function() {
+ if (window.location.search.length > 0) {
+ window.location.href =
+ '../segment/segment.html' + window.location.search;
+ } else {
+ window.location.href = '../segment/segment.html';
+ }
+ },
+ });
+ subToolsOpt.push({
+ name: 'model',
+ icon: 'aspect_ratio',
+ type: 'btn',
+ value: 'rect',
+ title: 'Predict',
+ ariaLabel: 'Predict',
+ callback: function() {
+ if (window.location.search.length > 0) {
+ window.location.href = '../model/model.html' + window.location.search;
+ } else {
+ window.location.href = '../model/model.html';
+ }
+ },
+ });
+ }
// -- For Nano borb Start -- //
if (ImgloaderMode == 'imgbox') {
@@ -665,54 +672,57 @@ async function initUIcomponents() {
ariaLabel: 'Load marks',
callback: Store.prototype.LoadMarksFromFile,
});
- }
- // -- For Nano borb End -- //
+ // -- For Nano borb End -- //
- // -- view btn START -- //
- if (!($D.params.data.hasOwnProperty('review') && $D.params.data['review']=='true')) {
+ // -- view btn START -- //
+ if (!($D.params.data.hasOwnProperty('review') && $D.params.data['review']=='true')) {
+ subToolsOpt.push({
+ name: 'review',
+ icon: 'playlist_add_check',
+ title: 'has reviewed',
+ type: 'btn',
+ value: 'review',
+ ariaLabel: 'Has reviewed',
+ callback: updateSlideView,
+ });
+ }
+
+ if ($D.params.mode != 'dcmweb') {
+ // screenshot
+ subToolsOpt.push({
+ name: 'slideCapture',
+ icon: 'camera_enhance',
+ title: 'Slide Capture',
+ type: 'btn',
+ value: 'slCap',
+ ariaLabel: 'Slide capture',
+ callback: captureSlide,
+ });
+ }
+
+ // visualization panel
subToolsOpt.push({
- name: 'review',
- icon: 'playlist_add_check',
- title: 'has reviewed',
+ name: 'visualization',
+ icon: 'auto_graph', // material icons' name
+ title: 'visualization',
+ value: 'visualization',
type: 'btn',
- value: 'review',
- ariaLabel: 'Has reviewed',
- callback: updateSlideView,
+ callback: visualization,
});
- }
- // screenshot
- subToolsOpt.push({
- name: 'slideCapture',
- icon: 'camera_enhance',
- title: 'Slide Capture',
- type: 'btn',
- value: 'slCap',
- ariaLabel: 'Slide capture',
- callback: captureSlide,
- });
-
- // visualization panel
- subToolsOpt.push({
- name: 'visualization',
- icon: 'auto_graph', // material icons' name
- title: 'visualization',
- value: 'visualization',
- type: 'btn',
- callback: visualization,
- });
- subToolsOpt.push({
- name: 'tutorial',
- icon: 'help',
- title: 'Tutorial',
- value: 'tutorial',
- type: 'btn',
- ariaLabel: 'Tutorial',
- callback: function() {
- tour.init();
- tour.start(true);
- },
- });
+ subToolsOpt.push({
+ name: 'tutorial',
+ icon: 'help',
+ title: 'Tutorial',
+ value: 'tutorial',
+ type: 'btn',
+ ariaLabel: 'Tutorial',
+ callback: function() {
+ tour.init();
+ tour.start(true);
+ },
+ });
+ }
// Additional Links handler
function additionalLinksHandler(url, openInNewTab, appendSlide) {
diff --git a/apps/viewer/viewer.html b/apps/viewer/viewer.html
index a15b47214..af65c37a2 100644
--- a/apps/viewer/viewer.html
+++ b/apps/viewer/viewer.html
@@ -380,6 +380,7 @@
+