LT-55: Integrating the PDF template with the measurements data
This commit is contained in:
1 parent
dcdd3f3e14
commit
d2dece45f6
6 files changed
+247
-305
No files matched your search
+1
-2
@@ -19,8 +19,7 @@ Template.measurementTableView.onCreated(() => {
|
|||||||
Template.measurementTableView.events({
|
Template.measurementTableView.events({
|
||||||
'click .js-pdf'(event, instance) {
|
'click .js-pdf'(event, instance) {
|
||||||
const { measurementApi, timepointApi } = instance.data;
|
const { measurementApi, timepointApi } = instance.data;
|
||||||
const measurementGroups = instance.data.measurementGroups.get();
|
OHIF.measurements.exportPdf(measurementApi, timepointApi);
|
||||||
OHIF.measurements.exportPdf(measurementGroups, measurementApi, timepointApi);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,187 +1,79 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
// import { $ } from 'meteor/jquery';
|
import { MeasurementReport } from 'meteor/ohif:measurements/client/reports/measurement';
|
||||||
// import jsPDF from 'jspdf';
|
|
||||||
// import html2canvas from 'html2canvas';
|
|
||||||
// import * as pdfMake from 'pdfmake';
|
|
||||||
|
|
||||||
// window.jsPDF = jsPDF;
|
OHIF.measurements.exportPdf = (measurementApi, timepointApi) => {
|
||||||
// window.html2canvas = html2canvas;
|
const currentTimepoint = timepointApi.current();
|
||||||
// window.pdfMake = pdfMake;
|
const { timepointId } = currentTimepoint;
|
||||||
|
const study = ViewerStudies.findOne({
|
||||||
OHIF.measurements.exportPdf = (measurementGroups, measurementApi, timepointApi) => {
|
studyInstanceUid: currentTimepoint.studyInstanceUids[0]
|
||||||
const pdf = new jsPDF('portrait', 'pt', 'a4');
|
});
|
||||||
|
const report = new MeasurementReport({
|
||||||
// Generate the logo
|
header: {
|
||||||
const logoImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAABLZAAAS2QBQlK26QAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAoXSURBVHic7d1LkFTVHcfxbzcDFiAqxCQ8Fc2jFMljTIIaixjLlaAoEktTiYsssnRNUS6SXVwllSULNnERK9lEkUVSeZQxpoIlkGB4mFipRISRATEYGUh0hizOjNQwt2emL+fe29P/76fqX1R1T5/+X87p39y+t6dvi+ktBe4HHgJuA5YDH5vhMcrrNPA2cBjYDewB3m20o2Q18OB43QSsApY02lEsY8AwMATsB54Dfg2czzH4YmA7cBa4aPVUnQOeBq7tOHvVWgXsBD6YpkermTpFet0u6Dh7s/AV4K0e2Bhr+joObOgwh1V5FHg/Q+9WtbUPWNNhDqf1MDDSAxtgza7OA48UzmR+O0i7nU1vszW7GgIGC2eyg9tJu5dNN251V+eBOwvmM6cnemA7re7rBOktW0et8X+XAEdm+mH1rBPArcB7FYy9jnSQ6aoKxlb1XgLuIQXCFPPG/32KdDRXc9MS0u75bysYexcpBDQ33Qi8RvoFP0WLdKrvTeDqGptSfiOkAz9nMo65AdibcTw14zDpNP4UbeABfPH3g0XA5sxjPp55PDVjHbC+6I6JAFB/2JJ5PNdG/yhcG218f9dPcs7lAuDTGcdTswrXRhtYWXMjqk7OuVzOpbNEmvsK10abdBBQ/eE6Lp3ZuVLLMo2j3lD4NzwDlEv514EXr6gdzWQj6dx+t3L91i47zsvAoUw9qNhW4ONdPqbjfJb5hNGurltWt3ZSbm4GMj3/YMnnfzLT86uzV+h+Xg4WDdSuoVlJPcoAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswAkAIzAKTADAApMANACswA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';
|
trial: 'RECIST 1.1',
|
||||||
pdf.addImage(logoImage, 'PNG', 40, 40, 20, 20);
|
patientName: formatPN(study.patientName),
|
||||||
pdf.setFont('Sanchez');
|
mrn: study.patientId,
|
||||||
pdf.setFontSize(14);
|
timepoint: timepointApi.name(currentTimepoint)
|
||||||
pdf.text('Open Health Imaging Foundation', 66, 54);
|
}
|
||||||
|
});
|
||||||
// Header horizontal line
|
|
||||||
pdf.setLineWidth(0.5);
|
|
||||||
pdf.line(30, 64, 565, 64);
|
|
||||||
|
|
||||||
const $element = $('<div></div>').css({
|
const $element = $('<div></div>').css({
|
||||||
border: '1px solid red',
|
height: 800,
|
||||||
height: 1000,
|
|
||||||
left: 0,
|
left: 0,
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
top: 0,
|
top: 0,
|
||||||
width: 1000,
|
visibility: 'hidden',
|
||||||
'z-index': 100000
|
width: 800,
|
||||||
|
'z-index': -1
|
||||||
});
|
});
|
||||||
|
|
||||||
$element.appendTo(document.body);
|
|
||||||
|
|
||||||
const element = $element[0];
|
const element = $element[0];
|
||||||
|
$element.appendTo(document.body);
|
||||||
cornerstone.enable(element, { renderer: 'webgl' });
|
cornerstone.enable(element, { renderer: 'webgl' });
|
||||||
|
|
||||||
const enabledElement = cornerstone.getEnabledElement(element);
|
const enabledElement = cornerstone.getEnabledElement(element);
|
||||||
enabledElement.toolStateManager = cornerstoneTools.newImageIdSpecificToolStateManager();
|
enabledElement.toolStateManager = cornerstoneTools.newImageIdSpecificToolStateManager();
|
||||||
|
|
||||||
const measurements = {
|
const targets = measurementApi.fetch('targets', { timepointId });
|
||||||
targets: [],
|
const nonTargets = measurementApi.fetch('nonTargets', { timepointId });
|
||||||
nonTargets: []
|
const measurements = targets.concat(nonTargets);
|
||||||
};
|
|
||||||
measurementGroups.forEach(measurementGroup => {
|
|
||||||
const { toolGroup, measurementRows } = measurementGroup;
|
|
||||||
measurementRows.forEach(rowItem => {
|
|
||||||
rowItem.entries.forEach(entry => measurements[toolGroup.id].push(entry));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
let i = 0;
|
const iterator = measurements[Symbol.iterator]();
|
||||||
const readMeasurements = toolGroupId => {
|
const printMeasurements = callback => {
|
||||||
measurements[toolGroupId].forEach(measurement => {
|
const current = iterator.next();
|
||||||
setTimeout(() => {
|
if (current.done) {
|
||||||
cornerstone.loadImage(measurement.imageId).then(image => {
|
callback();
|
||||||
cornerstone.displayImage(element, image);
|
return;
|
||||||
cornerstoneTools.addToolState(element, measurement.toolType, measurement);
|
}
|
||||||
cornerstoneTools[measurement.toolType].enable(element);
|
|
||||||
cornerstoneTools.clearToolState(element, measurement.toolType);
|
const measurement = current.value;
|
||||||
});
|
cornerstone.loadImage(measurement.imageId).then(image => {
|
||||||
}, i * 1000);
|
cornerstone.displayImage(element, image);
|
||||||
i++;
|
cornerstoneTools.addToolState(element, measurement.toolType, measurement);
|
||||||
|
cornerstoneTools[measurement.toolType].enable(element);
|
||||||
|
|
||||||
|
let info = measurement.response;
|
||||||
|
if (!info) {
|
||||||
|
info = measurement.longestDiameter;
|
||||||
|
if (measurement.shortestDiameter) {
|
||||||
|
info += ` × ${measurement.shortestDiameter}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
info += ' mm';
|
||||||
|
}
|
||||||
|
|
||||||
|
report.printMeasurement({
|
||||||
|
type: measurement.toolType,
|
||||||
|
number: measurement.measurementNumber,
|
||||||
|
location: measurement.location || '',
|
||||||
|
info,
|
||||||
|
image: enabledElement.canvas.toDataURL()
|
||||||
|
});
|
||||||
|
cornerstoneTools.clearToolState(element, measurement.toolType);
|
||||||
|
|
||||||
|
printMeasurements(callback);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
readMeasurements('targets');
|
printMeasurements(() => {
|
||||||
readMeasurements('nonTargets');
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
$element.remove();
|
$element.remove();
|
||||||
pdf.save('measurements.pdf');
|
report.save('measurements.pdf');
|
||||||
}, i * 1000);
|
|
||||||
};
|
|
||||||
|
|
||||||
// window.exportCanvasToPdf = canvas => {
|
|
||||||
// // only jpeg is supported by jsPDF
|
|
||||||
// const imgData = canvas.toDataURL('image/jpeg', 1.0);
|
|
||||||
// const pdf = new jsPDF();
|
|
||||||
|
|
||||||
// pdf.addImage(imgData, 'JPEG', 0, 0);
|
|
||||||
// pdf.save('download.pdf');
|
|
||||||
// };
|
|
||||||
|
|
||||||
// window.exportActiveViewportToPdf = () => {
|
|
||||||
// const activeViewportElement = getActiveViewportElement();
|
|
||||||
// if (!activeViewportElement) {
|
|
||||||
// console.log('>>>>> No active viewport element');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// console.log('>>>>> activeViewportElement: ', activeViewportElement);
|
|
||||||
// const canvas = $(activeViewportElement).find('canvas').get(0);
|
|
||||||
|
|
||||||
// if (!canvas) {
|
|
||||||
// console.log('>>>>> canvas is not available');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// exportCanvasToPdf(canvas);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Split the data into pages
|
|
||||||
// To make it easier we're going to work with a fixed grid (4R x 2C)
|
|
||||||
const getReportData = data => {
|
|
||||||
const patient = data.patient;
|
|
||||||
const pages = [];
|
|
||||||
let page;
|
|
||||||
|
|
||||||
// Working with ITEMS until we get real data (measurements)
|
|
||||||
const itemsPerPage = 3;
|
|
||||||
data.items.forEach(item => {
|
|
||||||
if (!page || (page.items.length === itemsPerPage)) {
|
|
||||||
page = {
|
|
||||||
width: 595, // points
|
|
||||||
height: 841, // points
|
|
||||||
patient,
|
|
||||||
items: []
|
|
||||||
};
|
|
||||||
|
|
||||||
pages.push(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
page.items.push(item);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return pages;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.exportPdf = (options) => {
|
|
||||||
const pages = getReportData(options.data);
|
|
||||||
const template = Template.measurementsReport;
|
|
||||||
const pdf = new jsPDF('portrait', 'pt', 'a4');
|
|
||||||
let renderedView;
|
|
||||||
|
|
||||||
const parentNode = document.createElement('div');
|
|
||||||
|
|
||||||
const onRendered = (template) => {
|
|
||||||
const printableElement = template.find('.print');
|
|
||||||
const renderOptions = {
|
|
||||||
pagesplit: true
|
|
||||||
};
|
|
||||||
|
|
||||||
document.body.appendChild(parentNode);
|
|
||||||
pdf.addHTML(printableElement, 0, 0, renderOptions, () => {
|
|
||||||
// Blaze.remove(renderedView);
|
|
||||||
// document.body.removeChild(parentNode);
|
|
||||||
pdf.save('html2pdf.pdf');
|
|
||||||
console.log('Done!');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const viewModel = {
|
|
||||||
pages,
|
|
||||||
onRendered
|
|
||||||
};
|
|
||||||
|
|
||||||
renderedView = Blaze.renderWithData(Template['measurementsReport'], viewModel, parentNode);
|
|
||||||
// const html = Blaze.toHTMLWithData(Template['measurementsReport'], pages);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.testExportPdf = () => {
|
|
||||||
const options = {
|
|
||||||
data: {
|
|
||||||
patient: {
|
|
||||||
name: 'Patient name'
|
|
||||||
},
|
|
||||||
// study: {
|
|
||||||
// foo: 'bar'
|
|
||||||
// },
|
|
||||||
// timepoint: {
|
|
||||||
// date: '1/1/1900'
|
|
||||||
// },
|
|
||||||
// measurements: [ ],
|
|
||||||
items: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let i = 0; i < 8; i++) {
|
|
||||||
options.data.items.push('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Praesentium possimus sit alias. Repellendus minus placeat mollitia voluptas quod repellat vero quasi similique dolores minima excepturi, adipisci iusto optio, omnis accusamus. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rerum repudiandae alias praesentium possimus minima sunt velit voluptates maxime labore sequi, quasi cum eos perferendis tempora dolorem obcaecati ut commodi qui.');
|
|
||||||
}
|
|
||||||
|
|
||||||
exportPdf(options);
|
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import jsPDF from 'jspdf';
|
||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
|
||||||
|
export class BaseReport {
|
||||||
|
constructor(options) {
|
||||||
|
const defaultOptions = {
|
||||||
|
width: 595.28,
|
||||||
|
height: 841.89,
|
||||||
|
marginTop: 30,
|
||||||
|
marginLeft: 40,
|
||||||
|
marginRight: 40,
|
||||||
|
marginBottom: 30,
|
||||||
|
showPageNumber: true
|
||||||
|
};
|
||||||
|
|
||||||
|
this.options = _.extend(defaultOptions, options);
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.doc = new jsPDF('portrait', 'pt', [this.options.width, this.options.height]);
|
||||||
|
this.options.width = Math.floor(this.options.width);
|
||||||
|
this.options.height = Math.floor(this.options.height);
|
||||||
|
this.currentPage = 1;
|
||||||
|
this.printStatic();
|
||||||
|
}
|
||||||
|
|
||||||
|
printStatic() {
|
||||||
|
this.x = this.options.marginLeft;
|
||||||
|
this.y = this.options.marginTop;
|
||||||
|
this.printHeader();
|
||||||
|
if (this.options.showPageNumber) {
|
||||||
|
this.printPageNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newPage() {
|
||||||
|
this.doc.addPage();
|
||||||
|
this.currentPage++;
|
||||||
|
this.printStatic();
|
||||||
|
}
|
||||||
|
|
||||||
|
printHeader() {
|
||||||
|
const { marginLeft, marginRight, width } = this.options;
|
||||||
|
const doc = this.doc;
|
||||||
|
let y = this.y;
|
||||||
|
|
||||||
|
// Print the logo strokes
|
||||||
|
doc.setDrawColor(0).setLineWidth(1);
|
||||||
|
doc.roundedRect(marginLeft + 0.5, y + 0.5, 8, 8, 0.5, 0.5, 'D');
|
||||||
|
doc.roundedRect(marginLeft + 11, y + 0.5, 8, 8, 0.5, 0.5, 'D');
|
||||||
|
doc.roundedRect(marginLeft + 0.5, y + 11, 8, 8, 0.5, 0.5, 'D');
|
||||||
|
doc.roundedRect(marginLeft + 11, y + 11, 8, 8, 0.5, 0.5, 'D');
|
||||||
|
|
||||||
|
// Print the logo text
|
||||||
|
doc.setFont('Serif').setFontSize(16).setFontStyle('normal').setTextColor(0);
|
||||||
|
doc.text('Open Health Imaging Foundation', 66, y + 14);
|
||||||
|
y += 24;
|
||||||
|
|
||||||
|
// Print header horizontal line
|
||||||
|
doc.setDrawColor(0).setLineWidth(0.5);
|
||||||
|
doc.line(marginLeft, y, width - marginRight, y);
|
||||||
|
y += 1;
|
||||||
|
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
printPageNumber() {
|
||||||
|
const doc = this.doc;
|
||||||
|
const { marginBottom, marginRight, width, height } = this.options;
|
||||||
|
doc.setFont('Verdana');
|
||||||
|
doc.setFontSize(8);
|
||||||
|
doc.setFontStyle('normal');
|
||||||
|
doc.setTextColor(0);
|
||||||
|
const text = `PAGE ${this.currentPage}`;
|
||||||
|
const size = doc.getTextDimensions(text);
|
||||||
|
doc.text(text, width - marginRight - size.w, height - marginBottom + (size.h / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
save(fileName) {
|
||||||
|
this.doc.save(fileName || 'report.pdf');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
import { BaseReport } from './base';
|
||||||
|
|
||||||
|
export class MeasurementReport extends BaseReport {
|
||||||
|
constructor(options) {
|
||||||
|
super(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
printHeader() {
|
||||||
|
super.printHeader();
|
||||||
|
|
||||||
|
const { marginLeft, marginRight, width, header } = this.options;
|
||||||
|
const doc = this.doc;
|
||||||
|
let y = this.y;
|
||||||
|
|
||||||
|
// don't print the header if not given
|
||||||
|
if (!header) return;
|
||||||
|
|
||||||
|
// Print trial label
|
||||||
|
y += 10;
|
||||||
|
doc.setFont('verdana');
|
||||||
|
doc.setFontSize(8);
|
||||||
|
doc.setFontStyle('bold');
|
||||||
|
doc.setTextColor(255);
|
||||||
|
doc.setFillColor(16);
|
||||||
|
const trialLabel = header.trial;
|
||||||
|
const trialLabelWidth = doc.getTextWidth(trialLabel) + 8;
|
||||||
|
doc.roundedRect(marginLeft, y, trialLabelWidth, 15, 3, 3, 'F');
|
||||||
|
doc.text(trialLabel, marginLeft + 4, y + 10.5);
|
||||||
|
|
||||||
|
// Print patient information
|
||||||
|
doc.setFont('verdana');
|
||||||
|
doc.setFontSize(10);
|
||||||
|
doc.setFontStyle('normal');
|
||||||
|
doc.setTextColor(0);
|
||||||
|
doc.text(`${header.patientName}\t${header.mrn}`, marginLeft + trialLabelWidth + 10, y + 11);
|
||||||
|
y += 25;
|
||||||
|
|
||||||
|
// Print timepoint header
|
||||||
|
doc.setFillColor(229);
|
||||||
|
doc.rect(marginLeft, y, width - marginLeft - marginRight, 18, 'F');
|
||||||
|
doc.setFont('verdana');
|
||||||
|
doc.setFontSize(9);
|
||||||
|
doc.setFontStyle('normal');
|
||||||
|
doc.setTextColor(0);
|
||||||
|
doc.text(header.timepoint.toUpperCase(), marginLeft + 4, y + 12.5);
|
||||||
|
y += 18;
|
||||||
|
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
printMeasurement(measurementData) {
|
||||||
|
const { marginLeft, marginRight, marginBottom, width, height } = this.options;
|
||||||
|
const infoHeight = 28;
|
||||||
|
const rectSize = Math.round((width - marginLeft - marginRight - 3) / 2);
|
||||||
|
const doc = this.doc;
|
||||||
|
let { x, y } = this;
|
||||||
|
const { image, location, info } = measurementData;
|
||||||
|
const type = measurementData.type.toUpperCase();
|
||||||
|
const number = measurementData.number.toString();
|
||||||
|
|
||||||
|
if (y + rectSize + infoHeight > height - marginBottom) {
|
||||||
|
this.newPage();
|
||||||
|
x = this.x;
|
||||||
|
y = this.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the image
|
||||||
|
doc.setFillColor(0);
|
||||||
|
doc.rect(x, y, rectSize, rectSize, 'F');
|
||||||
|
doc.addImage(image, 'JPEG', x + 1, y + 1, rectSize - 2, rectSize - 2);
|
||||||
|
y += rectSize;
|
||||||
|
|
||||||
|
// Print the measurement type
|
||||||
|
doc.setFont('verdana').setFontSize(10).setFontStyle('bold').setTextColor(255);
|
||||||
|
const typeWidth = Math.round(doc.getTextWidth(type));
|
||||||
|
const typeX = x + rectSize - typeWidth;
|
||||||
|
doc.setFillColor(64);
|
||||||
|
doc.rect(typeX - 8, y - 16, typeWidth + 8, 16, 'F');
|
||||||
|
doc.text(type, typeX - 4, y - 5);
|
||||||
|
|
||||||
|
// Print the measurement number
|
||||||
|
doc.setFillColor(224);
|
||||||
|
doc.circle(x + 9, y - 10, 7, 'F');
|
||||||
|
doc.setFont('courier').setTextColor(0);
|
||||||
|
const numberHalfWidth = doc.getTextWidth(number) / 2;
|
||||||
|
doc.text(number, x + 9 - numberHalfWidth, y - 7);
|
||||||
|
|
||||||
|
// Print the measurement location and info
|
||||||
|
doc.setFillColor(240);
|
||||||
|
doc.rect(x, y, rectSize, infoHeight, 'F');
|
||||||
|
doc.setFont('verdana').setFontSize(9);
|
||||||
|
doc.text(location, x + 4, y + 11);
|
||||||
|
doc.setFontStyle('normal');
|
||||||
|
doc.text(info, x + 4, y + 24);
|
||||||
|
y += infoHeight;
|
||||||
|
|
||||||
|
if (x === marginLeft) {
|
||||||
|
this.x = width - marginRight - rectSize;
|
||||||
|
} else {
|
||||||
|
this.x = marginLeft;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>jsPDF</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
|
|
||||||
<script src="pdf.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
const doc = new jsPDF('portrait', 'pt', 'a4');
|
|
||||||
|
|
||||||
// Print the logo
|
|
||||||
doc.setDrawColor(0);
|
|
||||||
doc.setLineWidth(1);
|
|
||||||
doc.roundedRect(40.5, 30.5, 8, 8, 0.5, 0.5, 'D');
|
|
||||||
doc.roundedRect(51, 30.5, 8, 8, 0.5, 0.5, 'D');
|
|
||||||
doc.roundedRect(40.5, 41, 8, 8, 0.5, 0.5, 'D');
|
|
||||||
doc.roundedRect(51, 41, 8, 8, 0.5, 0.5, 'D');
|
|
||||||
doc.text('Open Health Imaging Foundation', 66, 44);
|
|
||||||
|
|
||||||
// Print header horizontal line
|
|
||||||
doc.setDrawColor(0);
|
|
||||||
doc.setLineWidth(0.5);
|
|
||||||
doc.line(40, 54, 555, 54);
|
|
||||||
|
|
||||||
// Print header information
|
|
||||||
doc.setFillColor(16);
|
|
||||||
doc.roundedRect(40, 65, 50, 15, 3, 3, 'F');
|
|
||||||
doc.setFont('Verdana');
|
|
||||||
doc.setFontSize(8);
|
|
||||||
doc.setFontStyle('bold');
|
|
||||||
doc.setTextColor(255);
|
|
||||||
doc.text('RECIST 1.1', 44, 75.5);
|
|
||||||
|
|
||||||
// Print patient information
|
|
||||||
doc.setFont('Verdana');
|
|
||||||
doc.setFontSize(10);
|
|
||||||
doc.setFontStyle('normal');
|
|
||||||
doc.setTextColor(0);
|
|
||||||
doc.text('Ana Goodwin\tMGH 4044827', 110, 76);
|
|
||||||
|
|
||||||
// Print timepoint header
|
|
||||||
doc.setFillColor(229);
|
|
||||||
doc.rect(40, 90, 515, 18, 'F');
|
|
||||||
doc.setFont('Verdana');
|
|
||||||
doc.setFontSize(9);
|
|
||||||
doc.setFontStyle('normal');
|
|
||||||
doc.setTextColor(0);
|
|
||||||
doc.text('FOLLOW-UP 2', 44, 102.5);
|
|
||||||
|
|
||||||
let y = 108;
|
|
||||||
|
|
||||||
// Print a measurements row
|
|
||||||
doc.setFillColor(0);
|
|
||||||
doc.rect(40, y, 256, 256, 'F');
|
|
||||||
doc.rect(299, y, 256, 256, 'F');
|
|
||||||
const image1 = 'data:image/jpeg;base64,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 truncated
|
|
||||||
doc.addImage(image1, 'JPEG', 41, y + 1, 254, 254);
|
|
||||||
const image2 = 'data:image/jpeg;base64,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 truncated
|
|
||||||
doc.addImage(image2, 'JPEG', 300, y + 1, 254, 254);
|
|
||||||
y += 256;
|
|
||||||
doc.setFillColor(64);
|
|
||||||
doc.setFont('Verdana');
|
|
||||||
doc.setFontSize(10);
|
|
||||||
doc.setFontStyle('bold');
|
|
||||||
doc.setTextColor(255);
|
|
||||||
doc.rect(249, y - 16, 47, 16, 'F');
|
|
||||||
doc.rect(508, y - 16, 47, 16, 'F');
|
|
||||||
doc.text('TARGET', 252, y - 5);
|
|
||||||
doc.text('TARGET', 511, y - 5);
|
|
||||||
doc.setFillColor(224);
|
|
||||||
doc.setFont('Courier');
|
|
||||||
doc.setTextColor(0);
|
|
||||||
doc.circle(49, y - 10, 7, 'F');
|
|
||||||
doc.circle(308, y - 10, 7, 'F');
|
|
||||||
doc.text('1', 46.5, y - 7);
|
|
||||||
doc.text('2', 305.5, y - 7);
|
|
||||||
doc.setFillColor(240);
|
|
||||||
doc.rect(40, y, 256, 28, 'F');
|
|
||||||
doc.rect(299, y, 256, 28, 'F');
|
|
||||||
doc.setFont('Verdana');
|
|
||||||
doc.setFontSize(9);
|
|
||||||
doc.text('Lung LUL', 44, y + 11);
|
|
||||||
doc.text('Lymph Node Mediastinal', 303, y + 11);
|
|
||||||
doc.setFontStyle('normal');
|
|
||||||
doc.text('23.8 × 12.9 mm (S:3, I:44)', 44, y + 24);
|
|
||||||
doc.text('17.0 × 28.2 mm (S:3, I:83)', 303, y + 24);
|
|
||||||
y += 28;
|
|
||||||
|
|
||||||
// Print a measurements row
|
|
||||||
doc.setFillColor(0);
|
|
||||||
doc.rect(40, y, 256, 256, 'F');
|
|
||||||
doc.rect(299, y, 256, 256, 'F');
|
|
||||||
const image3 = 'data:image/jpeg;base64,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 truncated
|
|
||||||
doc.addImage(image1, 'JPEG', 41, y + 1, 254, 254);
|
|
||||||
const image4 = 'data:image/jpeg;base64,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 truncated
|
|
||||||
doc.addImage(image2, 'JPEG', 300, y + 1, 254, 254);
|
|
||||||
y += 256;
|
|
||||||
doc.setFillColor(64);
|
|
||||||
doc.setFont('Verdana');
|
|
||||||
doc.setFontSize(10);
|
|
||||||
doc.setFontStyle('bold');
|
|
||||||
doc.setTextColor(255);
|
|
||||||
doc.rect(223, y - 16, 73, 16, 'F');
|
|
||||||
doc.rect(482, y - 16, 73, 16, 'F');
|
|
||||||
doc.text('NON-TARGET', 226, y - 5);
|
|
||||||
doc.text('NON-TARGET', 485, y - 5);
|
|
||||||
doc.setFillColor(224);
|
|
||||||
doc.setFont('Courier');
|
|
||||||
doc.setTextColor(0);
|
|
||||||
doc.circle(49, y - 10, 7, 'F');
|
|
||||||
doc.circle(308, y - 10, 7, 'F');
|
|
||||||
doc.text('1', 46.5, y - 7);
|
|
||||||
doc.text('2', 305.5, y - 7);
|
|
||||||
doc.setFillColor(240);
|
|
||||||
doc.rect(40, y, 256, 28, 'F');
|
|
||||||
doc.rect(299, y, 256, 28, 'F');
|
|
||||||
doc.setFont('Verdana');
|
|
||||||
doc.setFontSize(9);
|
|
||||||
doc.text('Lymph Node Pericardial', 44, y + 11);
|
|
||||||
doc.text('Lymph Node Retrocrural', 303, y + 11);
|
|
||||||
doc.setFontStyle('normal');
|
|
||||||
doc.text('SD (S:3, I:115)', 44, y + 24);
|
|
||||||
doc.text('SD (S:3, I:140)', 303, y + 24);
|
|
||||||
y += 28;
|
|
||||||
|
|
||||||
// Print the page number
|
|
||||||
doc.setFont('Verdana');
|
|
||||||
doc.setFontSize(8);
|
|
||||||
doc.setFontStyle('normal');
|
|
||||||
doc.setTextColor(0);
|
|
||||||
doc.text('PAGE 1', 520, 810);
|
|
||||||
|
|
||||||
doc.output('datauri');
|
|
||||||
Reference in new issue
Block a user