update readme for recommended nodejs versions (#4389)
[openemr.git] / library / dicom_frame.php
blob0bc9eb20f65f1f97cee24cba5dd96c32fc40b9b3
1 <?php
3 /**
4 * Dicom viewer wrapper script for documents
6 * @package OpenEMR
7 * @link https://www.open-emr.org
8 * @author Victor Kofia <https://kofiav.com> 'Viewer'
9 * @author Jerry Padgett <sjpadgett@gmail.com> 'Viewer wrapper'
10 * @copyright Copyright (c) 2017-2018 Victor Kofia <https://kofiav.com>
11 * @copyright Copyright (c) 2018-2020 Jerry Padgett <sjpadgett@gmail.com>
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 /* Warning: This script wraps the Dicom viewer which is HTML5 compatible only and bootstrap styling
16 * should not be used inside this script due to style conflicts with viewer, namely, hidden class.
19 require_once('../interface/globals.php');
21 use OpenEMR\Core\Header;
22 use OpenEMR\Common\Csrf\CsrfUtils;
24 $web_path = $_REQUEST['web_path'] ?? null;
25 if ($web_path) {
26 $patid = $_REQUEST['patient_id'] ?? null;
27 $docid = isset($_REQUEST['document_id']) ? $_REQUEST['document_id'] : ($_REQUEST['doc_id'] ?? null);
28 $d = new Document(attr($docid));
29 $type = '.dcm';
30 if ($d->get_mimetype() == 'application/dicom+zip') {
31 $type = '.zip';
33 $csrf = attr(CsrfUtils::collectCsrfToken());
34 $state_url = $GLOBALS['web_root'] . "/library/ajax/upload.php";
35 $web_path = attr($web_path) . '&retrieve&patient_id=' . attr_url($patid) . '&document_id=' . attr_url($docid) . '&as_file=false&type=' . attr_url($type);
38 <!DOCTYPE html>
39 <html>
40 <head>
41 <title><?php echo xlt("Dicom Viewer"); ?></title>
43 <?php Header::setupHeader(['dwv', 'i18next', 'i18next-xhr-backend', 'i18next-browser-languagedetector', 'jszip', 'magic-wand', 'konva']); ?>
44 <script type="text/javascript" src="<?php echo $GLOBALS['assets_static_relative']; ?>/flot/dist/es5/jquery.flot.js"></script>
45 <!-- Local (dwv) -->
46 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/browser.js"></script>
47 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/colourMap.js"></script>
48 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/custom.js"></script>
49 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/dropboxLoader.js"></script>
50 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/filter.js"></script>
51 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/generic.js"></script>
52 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/undo.js"></script>
53 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/help.js"></script>
54 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/html.js"></script>
55 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/infoController.js"></script>
56 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/infoOverlay.js"></script>
57 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/loader.js"></script>
58 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/tools.js"></script>
59 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/gui/plot.js"></script>
60 <!-- i18n dwv wrapper -->
61 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/dwv_i18n.js"></script>
62 <!-- Launch the app -->
63 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/dicom_gui.js"></script>
64 <script src="<?php echo $GLOBALS['web_root'] ?>/library/js/dwv/dicom_launcher.js"></script>
65 </head>
66 <style type="text/css">
67 body {
68 background-color: #555;
69 color: #fff;
72 button, input, li, table {
73 margin-top: 0.2em;
76 li button, li input {
77 margin: 0;
80 .container-fluid {
81 display: flex;
82 flex-direction: column;
85 #pageHeader {
86 display: flex;
87 flex-direction: row;
88 justify-content: space-between;
89 padding: .175rem;
92 #pageHeader h1, h2, h3, h5, h6 {
93 margin: 0;
94 color: #fff;
97 #pageHeader a {
98 color: #ddf;
101 #pageHeader .toolbar {
104 #pageMain {
105 display: flex;
106 flex-direction: row;
107 justify-content: center;
110 /* Layers */
111 .layerContainer {
112 position: relative;
113 margin: .625rem;
114 width: 512px;
115 height: 512px;
118 .imageLayer {
119 position: absolute;
122 .drawDiv {
123 position: absolute;
124 pointer-events: none;
127 /* drag&drop */
128 .dropBox {
131 .dropBoxBorder {
132 margin: 20px auto;
133 border: 5px dashed #ccc;
136 .dropBoxBorder.hover {
137 margin: 20px auto;
138 border: 5px dashed #cc0;
141 /* toolbar */
142 .toolList ul {
143 padding: 0;
146 .toolList li {
147 list-style-type: none;
150 /* info */
151 .infoLayer ul {
152 margin: 0;
153 padding: 2px;
154 list-style-type: none;
157 .infoLayer li {
158 margin-top: 0;
161 .infoLayer canvas {
162 margin: 0;
163 padding: 2px;
166 .info {
167 color: #cde;
168 text-shadow: 1px 1px #000;
169 font-size: 80%;
172 .infoc {
173 color: #ff0;
174 text-shadow: 1px 1px #000;
175 font-size: 120%;
178 .infotl {
179 position: absolute;
180 top: 0;
181 left: 0;
182 text-align: left;
183 text-shadow: 0 1px 0 #000;
186 .infotc {
187 position: absolute;
188 top: 0;
189 left: 50%;
190 right: 50%;
191 text-align: center;
192 text-shadow: 0 1px 0 #000;
195 .infotr {
196 position: absolute;
197 top: 0;
198 right: 0;
199 text-align: right;
200 text-shadow: 0 1px 0 #000;
203 .infocl {
204 position: absolute;
205 bottom: 50%;
206 left: 0;
207 text-align: left;
208 text-shadow: 0 1px 0 #000;
211 .infocr {
212 position: absolute;
213 bottom: 50%;
214 right: 2px;
215 text-align: right;
216 text-shadow: 0 1px 0 #000;
219 .infobl {
220 position: absolute;
221 bottom: 0;
222 left: 0;
223 text-align: left;
224 text-shadow: 0 1px 0 #000;
227 .infobc {
228 position: absolute;
229 bottom: 0;
230 left: 50%;
231 right: 50%;
232 text-align: center;
233 text-shadow: 0 1px 0 #000;
236 .infobr {
237 position: absolute;
238 bottom: 0;
239 right: 0;
240 text-align: right;
241 text-shadow: 0 1px 0 #000;
244 .plot {
245 position: absolute;
246 width: 100px;
247 height: 50px;
248 bottom: 15px;
249 right: 0;
252 /* tag list */
253 table.tagsTable {
254 border-collapse: collapse;
255 background-color: #fff;
256 color: #000
259 table.tagsTable thead {
260 background-color: #000;
261 color: #fff
264 table.tagsTable thead th {
265 text-transform: uppercase;
266 font-weight: bold;
267 opacity: 0.9;
270 table.tagsTable tr:nth-child(even) {
271 background-color: #c2c2c2;
274 table.drawsTable {
275 border-collapse: collapse;
278 table.drawsTable td {
279 vertical-align: middle;
282 table.drawsTable thead th {
283 text-transform: uppercase;
284 font-weight: bold;
285 opacity: 0.5;
288 .highlighted {
289 background: #feeeac;
292 .tags {
293 background-color: #fff;
294 color: #000;
295 padding: 1rem 1.25rem;
298 .tags form {
299 width: 45%;
302 /* draw list */
303 .drawList tr:nth-child(even) {
304 background-color: #333;
307 /* history list */
308 div.history {
309 display: none;
312 .history_list {
313 width: 100%;
316 /* help */
317 .help {
318 padding: 1rem 1.25rem;
321 .popup {
322 position: absolute;
323 top: 15%;
324 left: 15%;
325 visibility: hidden;
326 transform: scale(1.05);
327 transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
328 z-index: 1000;
331 #loaderlist.popup {
332 top: 50%;
333 left: 50%;
334 z-index: 1010;
337 .loaderSelect {
338 display: inline;
339 width: 50%;
342 #loaderlist div.popup-content {
343 position: absolute;
344 top: 50%;
345 left: 50%;
346 transform: translate(-50%, -50%);
347 background-color: white;
348 padding: 1rem 1.25rem;
349 width: 24rem;
350 border-radius: 0.5rem;
351 padding-left: .325rem;
354 .lg div.popup-content {
355 position: static;
356 border: 2px solid #fff;
357 width: 75vw;
358 border-radius: 0.5rem;
359 overflow: auto;
360 height: 75vh;
361 background-color: white;
364 #helpPopup div.popup-content {
365 background-color: black;
368 .close-button {
369 background: #ff5d5a;
370 position: absolute;
371 line-height: 1.5rem;
372 text-align: center;
373 right: 20px;
374 width: 1.5rem;
375 height: 1.5rem;
376 cursor: pointer;
377 z-index: 1011;
380 .close-button:hover {
381 background-color: lightcoral;
384 .show-popup {
385 opacity: 1;
386 visibility: visible;
387 transform: scale(1.0);
388 transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
391 #progressbar {
392 width: 0;
393 max-width: 92%;
394 height: 1.25rem;
395 background-color: #4CAF50;
398 #pageHeader h2 em {
399 font-size: 14px;
400 color: red;
403 div.toolList {
404 margin: .325rem 0 .325rem;
406 </style>
407 <body>
408 <!-- DWV -->
409 <div id="dwv" class="container-fluid" src='<?php echo $web_path ?>'>
410 <?php if ($web_path) { ?>
411 <input type="hidden" id="state_url" value='<?php echo $state_url ?>' />
412 <input type="hidden" id="csrf" value='<?php echo $csrf ?>' />
413 <input type="hidden" id="doc_id" value='<?php echo attr($docid) ?>'' />
414 <?php } ?>
415 <div id="pageHeader">
416 <!-- Title -->
417 <h2>DICOM Viewer<span>&nbsp;<em>( Not for Diagnostics )</em></h2>
418 </span>
419 <span class="editspan"></span>
420 <div class="toolbar"></div>
421 </div><!-- /pageHeader -->
422 <div id="pageMain">
423 <!-- get state json data if file -->
424 <div class="openData" title="File">
425 <!-- Open image files -->
426 <div class="popup" id="loaderlist">
427 <div class="popup-content">
428 <span class="close-button" onclick="toggle('loaderlist');">&times;</span>
429 <br />
430 <div class="openData" title="File">
431 <div class="loaderlist"></div>
432 <div id="progressbar"></div>
433 </div>
434 </div>
435 </div>
436 </div>
437 <!-- Toolbox -->
438 <div class="toolList" title="Toolbox"></div>
439 <!-- History -->
440 <div class="history" title="History"></div>
441 <!-- Tags -->
442 <div class="popup lg" id="tagsPopup">
443 <div class="popup-content">
444 <span class="close-button" onclick="toggle('tagsPopup');">&times;</span>
445 <div class="tags" title="Tags">Please load a DICOM study to view image tags.</div>
446 </div>
447 </div>
448 <!-- Help -->
449 <div class="popup lg" id="helpPopup">
450 <div class="popup-content">
451 <span class="close-button" onclick="toggle('helpPopup');">&times;</span>
452 <div class="help" title="Help"></div>
453 </div>
454 </div>
455 <!-- Layer Container -->
456 <div class="layerDialog" title="Image">
457 <div class="layerContainer">
458 <div class="dropBox dropBoxBorder"></div>
459 <canvas class="imageLayer">Only for HTML5 compatible browsers...</canvas>
460 <div class="drawDiv"></div>
461 <div class="infoLayer">
462 <div class="infotl"></div>
463 <div class="infotc"></div>
464 <div class="infotr"></div>
465 <div class="infocl"></div>
466 <div class="infocr"></div>
467 <div class="infobl"></div>
468 <div class="infobc"></div>
469 <div class="infobr" style="bottom: 64px;"></div>
470 <div class="plot"></div>
471 </div><!-- /infoLayer -->
472 </div><!-- /layerContainer -->
473 </div><!-- /layerDialog -->
474 <!-- DrawList -->
475 <div class="drawList" title="Draw list"></div>
476 </div><!-- /pageMain -->
477 </div><!-- /dwv -->
479 </body>
480 </html>