LT-55: Integrating the PDF template with the measurements data
This commit is contained in:
parent
dcdd3f3e14
commit
d2dece45f6
@ -19,8 +19,7 @@ Template.measurementTableView.onCreated(() => {
|
||||
Template.measurementTableView.events({
|
||||
'click .js-pdf'(event, instance) {
|
||||
const { measurementApi, timepointApi } = instance.data;
|
||||
const measurementGroups = instance.data.measurementGroups.get();
|
||||
OHIF.measurements.exportPdf(measurementGroups, measurementApi, timepointApi);
|
||||
OHIF.measurements.exportPdf(measurementApi, timepointApi);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -1,187 +1,79 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
// import { $ } from 'meteor/jquery';
|
||||
// import jsPDF from 'jspdf';
|
||||
// import html2canvas from 'html2canvas';
|
||||
// import * as pdfMake from 'pdfmake';
|
||||
import { MeasurementReport } from 'meteor/ohif:measurements/client/reports/measurement';
|
||||
|
||||
// window.jsPDF = jsPDF;
|
||||
// window.html2canvas = html2canvas;
|
||||
// window.pdfMake = pdfMake;
|
||||
|
||||
OHIF.measurements.exportPdf = (measurementGroups, measurementApi, timepointApi) => {
|
||||
const pdf = new jsPDF('portrait', 'pt', 'a4');
|
||||
|
||||
// Generate the logo
|
||||
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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';
|
||||
pdf.addImage(logoImage, 'PNG', 40, 40, 20, 20);
|
||||
pdf.setFont('Sanchez');
|
||||
pdf.setFontSize(14);
|
||||
pdf.text('Open Health Imaging Foundation', 66, 54);
|
||||
|
||||
// Header horizontal line
|
||||
pdf.setLineWidth(0.5);
|
||||
pdf.line(30, 64, 565, 64);
|
||||
OHIF.measurements.exportPdf = (measurementApi, timepointApi) => {
|
||||
const currentTimepoint = timepointApi.current();
|
||||
const { timepointId } = currentTimepoint;
|
||||
const study = ViewerStudies.findOne({
|
||||
studyInstanceUid: currentTimepoint.studyInstanceUids[0]
|
||||
});
|
||||
const report = new MeasurementReport({
|
||||
header: {
|
||||
trial: 'RECIST 1.1',
|
||||
patientName: formatPN(study.patientName),
|
||||
mrn: study.patientId,
|
||||
timepoint: timepointApi.name(currentTimepoint)
|
||||
}
|
||||
});
|
||||
|
||||
const $element = $('<div></div>').css({
|
||||
border: '1px solid red',
|
||||
height: 1000,
|
||||
height: 800,
|
||||
left: 0,
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
width: 1000,
|
||||
'z-index': 100000
|
||||
visibility: 'hidden',
|
||||
width: 800,
|
||||
'z-index': -1
|
||||
});
|
||||
|
||||
$element.appendTo(document.body);
|
||||
|
||||
const element = $element[0];
|
||||
|
||||
$element.appendTo(document.body);
|
||||
cornerstone.enable(element, { renderer: 'webgl' });
|
||||
|
||||
const enabledElement = cornerstone.getEnabledElement(element);
|
||||
enabledElement.toolStateManager = cornerstoneTools.newImageIdSpecificToolStateManager();
|
||||
|
||||
const measurements = {
|
||||
targets: [],
|
||||
nonTargets: []
|
||||
};
|
||||
measurementGroups.forEach(measurementGroup => {
|
||||
const { toolGroup, measurementRows } = measurementGroup;
|
||||
measurementRows.forEach(rowItem => {
|
||||
rowItem.entries.forEach(entry => measurements[toolGroup.id].push(entry));
|
||||
});
|
||||
});
|
||||
const targets = measurementApi.fetch('targets', { timepointId });
|
||||
const nonTargets = measurementApi.fetch('nonTargets', { timepointId });
|
||||
const measurements = targets.concat(nonTargets);
|
||||
|
||||
let i = 0;
|
||||
const readMeasurements = toolGroupId => {
|
||||
measurements[toolGroupId].forEach(measurement => {
|
||||
setTimeout(() => {
|
||||
cornerstone.loadImage(measurement.imageId).then(image => {
|
||||
cornerstone.displayImage(element, image);
|
||||
cornerstoneTools.addToolState(element, measurement.toolType, measurement);
|
||||
cornerstoneTools[measurement.toolType].enable(element);
|
||||
cornerstoneTools.clearToolState(element, measurement.toolType);
|
||||
});
|
||||
}, i * 1000);
|
||||
i++;
|
||||
const iterator = measurements[Symbol.iterator]();
|
||||
const printMeasurements = callback => {
|
||||
const current = iterator.next();
|
||||
if (current.done) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
const measurement = current.value;
|
||||
cornerstone.loadImage(measurement.imageId).then(image => {
|
||||
cornerstone.displayImage(element, image);
|
||||
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');
|
||||
readMeasurements('nonTargets');
|
||||
|
||||
setTimeout(() => {
|
||||
printMeasurements(() => {
|
||||
$element.remove();
|
||||
pdf.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);
|
||||
report.save('measurements.pdf');
|
||||
});
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
83
Packages/ohif-measurements/client/reports/base.js
Normal file
83
Packages/ohif-measurements/client/reports/base.js
Normal file
@ -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');
|
||||
}
|
||||
}
|
||||
104
Packages/ohif-measurements/client/reports/measurement.js
Normal file
104
Packages/ohif-measurements/client/reports/measurement.js
Normal file
@ -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>
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user