widgets/Report.js
define([
'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'dojo/_base/lang',
'dojo/_base/array',
'dojo/_base/fx',
'dojo/dom-style',
'dojo/dom-construct',
'dojo/topic',
'dojo/date/locale',
'dojo/number',
'dojo/currency',
'module',
'esri/tasks/PrintTask',
'esri/tasks/PrintTemplate',
'esri/tasks/PrintParameters',
'esri/urlUtils',
// template
'dojo/text!./Report/templates/Report.html',
//i18n
'dojo/i18n!./Report/nls/Report',
// add fake data for testing
//'https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/faker.min.js',
'xstyle/css!./Report/css/Report.css'
], function (
declare,
_WidgetBase,
_TemplatedMixin,
_WidgetsInTemplateMixin,
lang,
array,
fx,
domStyle,
domConstruct,
topic,
locale,
number,
currency,
module,
PrintTask,
PrintTemplate,
PrintParameters,
urlUtils,
template,
i18n
//faker
) {
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
widgetsInTemplate: true,
templateString: template,
baseClass: 'cmvReportWidget',
// i18n
defaultI18n: i18n,
i18n: {},
map: null,
doc: null,
reportLayout: {},
defaultStyles: {
font: {
color: 0,
size: 11,
font: 'helvetica',
style: 'normal'
},
line: {
width: 0.5,
color: 0
},
rectangle: {
lineWidth: 0.5,
lineColor: 0,
fillColor: [255, 255, 255, 0]
}
},
topicID: 'reportWidget',
printTaskURL: '',
fadeInDuration: 100,
fadeOutDuration: 100,
imagePrefix: 'reportImage-',
images: {},
postMixInProperties: function () {
this.inherited(arguments);
this.i18n = this.mixinDeep(this.defaultI18n, this.i18n);
},
postCreate: function () {
this.inherited(arguments);
this.addTopics();
if (!window.jsPDF) {
this.loadJSPDF();
}
this.originalDefaultStyles = this.defaultStyles;
domConstruct.place(this.reportOverlayNode, document.body);
},
addTopics: function () {
this.own(topic.subscribe(this.topicID + '/createReport', lang.hitch(this, 'createReport')));
},
loadJSPDF: function () {
var modulesPath = module.uri.substring(0, module.uri.lastIndexOf('/')) + '/Report/lib';
window.dojoConfig.packages.push({
name: 'jspdf',
main: 'jspdf-1.3.4.min',
location: modulesPath
});
window.dojoConfig.packages.push({
name: 'autotable',
main: 'jspdf.plugin.autotable-2.3.1.min',
location: modulesPath
});
require(window.dojoConfig, [
'autotable'
]);
},
createReport: function (options) {
if (options.feature) {
this.feature = options.feature;
}
if (options.features) {
this.features = options.features;
}
this.defaultStyles = this.originalDefaultStyles;
if (options.defaultStyles) {
this.defaultStyles = options.defaultStyles;
}
if (options.printTaskURL) {
this.printTaskURL = options.printTaskURL;
}
if (options.reportLayout) {
this.reportLayout = options.reportLayout;
}
this.showLoadingMask();
// clear previous images
this.clearImages();
// preload any images
this.preloadImages();
if (this.reportLayout.map) {
if (this.feature && this.feature.geometry && this.feature.geometry.getExtent) {
this.mapExtent = this.map.extent;
if (this.feature.geometry.type === 'point') {
this.map.centerAndZoom(this.feature.geometry, this.map.getMaxZoom() - 5).then(lang.hitch(this, 'printMap'));
} else {
this.map.setExtent(this.feature.geometry.getExtent(), true).then(lang.hitch(this, 'printMap'));
}
} else {
this.mapExtent = null;
this.printMap();
}
} else {
this.checkImages();
}
},
// prints the map
printMap: function () {
var options = lang.clone(this.reportLayout.map);
var printTemplate = new PrintTemplate();
options.dpi = options.dpi || 72;
if (!options.scale) {
options.scale = options.dpi / 72;
}
printTemplate.exportOptions.height = this.converPointToPixel(options.height) * options.scale;
printTemplate.exportOptions.width = this.converPointToPixel(options.width) * options.scale;
printTemplate.exportOptions.dpi = options.dpi;
printTemplate.format = options.format.toUpperCase() || 'PNG32';
printTemplate.layout = 'MAP_ONLY';
printTemplate.preserveScale = options.preserveScale;
var params = new PrintParameters();
params.map = this.map;
params.template = printTemplate;
var printTask = new PrintTask(this.printTaskURL);
printTask.execute(params, lang.hitch(this, 'onPrintComplete'), lang.hitch(this, 'onPrintError'));
},
onPrintError: function (err) {
this.hideLoadingMask();
topic.publish('viewer/handleError', {
error: err
});
topic.publish('growler/growl', {
title: 'Report Failed',
message: 'Could not create a map image for report.',
level: 'error',
timeout: 3000
});
},
onPrintComplete: function (data) {
if (!data.url) {
this.onPrintError('Error, try again');
}
if (this.mapExtent) {
this.map.setExtent(this.mapExtent);
}
this.mapImage = lang.clone(this.reportLayout.map);
this.mapImage.id = this.mapImage.id || this.imagePrefix + 'map';
this.mapImage.url = this.getProxiedUrl(data.url);
this.mapImage.format = this.getMapFormat();
this.loadImage(this.mapImage.id, this.mapImage.url);
},
createPDF: function () {
var options = this.reportLayout;
/* eslint new-cap: 0 */
this.doc = new window.jsPDF(options.layout);
this.docEventID = this.doc.internal.events.subscribe('addPage', lang.hitch(this, 'newPage'));
this.resetFont();
this.resetRectangle();
this.addMetadata();
this.addPageHeaderFooter({
pageNumber: 1
});
// add the map image first
if (this.mapImage && this.images[this.imagePrefix + 'map']) {
this.addImage(this.mapImage);
}
this.addGroupedItems(options);
// clear images
this.clearImages();
this.hideLoadingMask();
this.outputReport();
// reinitialize the doc
this.doc.internal.events.unsubscribe(this.docEventID);
this.doc = new window.jsPDF();
},
outputReport: function () {
var output = this.reportLayout.output,
result = null;
if (output) {
if (output.type === 'print') {
this.doc.autoPrint();
result = this.doc.output('bloburl');
} else if (output.type === 'save') {
result = this.doc.save(output.options);
} else {
result = this.doc.output(output.type);
}
switch (output.type) {
case 'arraybuffer':
break;
case 'blob':
// alternative way to save the file
// must include FileSave: https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js
if (output.options) {
window.saveAs(result, output.options);
}
break;
case 'print':
case 'bloburi':
case 'bloburl':
window.open(result, '_blank');
break;
case 'dataurlnewwindow': // opens a new window
break;
case 'datauri':
case 'dataurl':
break;
case 'datauristring':
case 'dataurlstring':
break;
case 'save': // prompts the user to save
break;
default:
break;
}
// publish the results
if (result) {
topic.publish(this.topicID + '/output', result);
}
}
},
addMetadata: function () {
if (this.reportLayout.metadata) {
this.doc.setProperties(this.reportLayout.metadata);
}
},
newPage: function (pageOptions) {
this.addPageHeaderFooter(pageOptions);
},
addPage: function () {
this.doc.addPage();
},
addPageHeaderFooter: function (pageOptions) {
var options = this.reportLayout;
if (pageOptions.pageNumber === 1) {
if (options.header && options.header.text && !options.header.skipFirst) {
this.addHeader(pageOptions);
}
if (options.footer && !options.footer.skipFirst) {
this.addFooter(pageOptions);
}
} else {
if (options.header && options.header.text && (options.header.eachPage !== false)) {
this.addHeader(pageOptions);
}
if (options.footer && (options.footer.eachPage !== false)) {
this.addFooter(pageOptions);
}
}
},
addHeader: function (pageOptions) {
var options = lang.clone(this.reportLayout.header);
options.pageNumber = pageOptions.pageNumber;
this.addGroupedItems(options);
},
addFooter: function (pageOptions) {
var options = lang.clone(this.reportLayout.footer);
options.pageNumber = pageOptions.pageNumber;
this.addGroupedItems(options);
},
addGroupedItems: function (items) {
var pageNumber = 1;
// you can group items on a per page basis
if (items.pageNumber) {
this.setPage(items.pageNumber);
pageNumber = items.pageNumber;
}
// pages are just like groups of items. do the pages first =
array.forEach(items.pages, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
this.addGroupedItems(item);
}));
// add any attributes
array.forEach(items.attributes, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
this.addAttributes(item);
}));
// add any tables
array.forEach(items.tables, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
if (item.features === true && this.features && this.features.length) {
item.data = array.map(this.features, function (feat) {
return feat.attributes;
});
}
this.addTable(item);
}));
// add any images
array.forEach(items.images, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
this.addImage(item);
}));
// add any shapes
array.forEach(items.shapes, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
this.addShape(item);
}));
// add any text
array.forEach(items.text, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
this.addText(item);
}));
// add any lines
array.forEach(items.lines, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
this.addLine(item);
}));
// add any borders
array.forEach(items.borders, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
this.addBorder(item);
}));
// add any groupedItems. can be nested
array.forEach(items.groupedItems, lang.hitch(this, function (item) {
item.pageNumber = item.pageNumber || pageNumber;
this.addGroupedItems(item);
}));
},
addAttributes: function (attr) {
if (attr.title) {
this.addText(lang.mixin({
left: attr.left + 5,
top: attr.top,
pageNumber: attr.pageNumber
}, attr.title));
}
if (attr.lines) {
array.forEach(attr.lines, lang.hitch(this, function (line) {
this.addLine(lang.mixin({
left: attr.left + 5,
top: attr.top,
pageNumber: attr.pageNumber
}, line));
}));
}
switch (attr.layout) {
case 'stacked':
this.addStackedAttributes(attr);
break;
case 'column':
this.addColumnAttributes(attr);
break;
case 'table':
this.addTable(attr);
break;
case 'fake':
this.addFakeTable(attr);
break;
default:
}
},
addStackedAttributes: function (attr) {
var font = lang.mixin(lang.clone(this.defaultStyles.font), attr.font);
var top = attr.top + 20;
if (attr.pageNumber) {
this.setPage(attr.pageNumber);
}
if (attr.fields) {
var field = null,
left = attr.left + 5, origLeft = left,
len = attr.fields.length;
for (var k = 0; k < len; k++) {
field = attr.fields[k];
left = this.addStackedAttributesLabel(field, font, left, top, attr.pageNumber);
this.addStackedAttributesValue(field, font, left, top, attr.pageNumber);
top += this.doc.internal.getLineHeight();
left = origLeft;
}
if (attr.border) {
this.addStackedAttributesBorder(attr);
}
}
},
addStackedAttributesLabel: function (field, font, left, top, pageNumber) {
var label = field.label;
if (label && label.length > 0) {
label += ':';
font.style = 'bold';
this.setFont(font);
var labelWidth = parseInt(this.doc.getStringUnitWidth(label) * this.doc.internal.getFontSize(), 10) + 5;
this.addText({
text: label,
left: left,
top: top,
font: font,
align: field.labelAlign,
pageNumber: pageNumber
});
left += labelWidth;
}
return left;
},
addStackedAttributesValue: function (field, font, left, top, pageNumber) {
var value = field.value;
if (field.fieldName && this.feature && this.feature.attributes) {
value = this.feature.attributes[field.fieldName];
}
if (!value) {
value = '';
}
if (value && value.length > 0) {
font.style = 'normal';
this.addText({
text: value,
left: left,
top: top,
font: font,
align: field.valueAlign,
pageNumber: pageNumber
});
}
},
addStackedAttributesBorder: function (attr) {
var margins = this.reportLayout.margins;
var width = attr.width || this.doc.internal.pageSize.width - margins.right;
width -= attr.right || 0;
this.addBorder({
left: attr.left,
top: attr.top,
width: width,
height: attr.height,
border: attr.border,
pageNumber: attr.pageNumber
});
},
addColumnAttributes: function (attr) {
if (attr.fields) {
var field = null,
label = null,
value = null,
len = attr.fields.length;
attr.columns = [
{title: 'Label', dataKey: 'label'},
{title: 'Value', dataKey: 'value'}
];
attr.data = [];
for (var k = 0; k < len; k++) {
field = attr.fields[k];
label = field.label;
value = field.value;
if (field.fieldName && this.feature && this.feature.attributes) {
value = this.feature.attributes[field.fieldName];
}
if (!value || (typeof value === 'string' && value.toLowerCase() === 'null')) {
value = '';
}
if (typeof value === 'string') {
value = value.trim();
}
value = this.formatText({
text: value,
format: field.format,
formatOptions: field.formatOptions,
formatter: field.formatter,
attributes: this.feature.attributes
});
attr.data.push({
label: label,
value: value,
styles: field.styles,
rowHeading: field.rowHeading
});
}
attr.options = this.mixinDeep({
theme: 'plain',
styles: {
cellPadding: 5,
valign: 'top', // top, middle, bottom
overflow: 'linebreak' // visible, hidden, ellipsize or linebreak
},
columnStyles: {
label: {
fontStyle: 'bold'
}
},
drawHeaderRow: function () {
// Don't draw header row
return false;
}
}, attr.options);
this.addTable(attr);
}
},
addTable: function (table) {
if (table.columns) {
if (table.pageNumber) {
this.setPage(table.pageNumber);
}
table.options = this.mixinDeep({
drawRow: lang.hitch(this, function (row, data) {
var rowHeading = row.raw.rowHeading;
var rowStyles = row.cells.label.styles;
if (rowHeading) {
var margin = rowHeading.margin || {};
var rowHeight = (rowHeading.height || row.height) + (margin.top || 0);
if (rowHeading.border) {
this.addBorder(this.mixinDeep({
left: data.settings.margin.left,
top: row.y + (margin.top || 0),
width: data.table.width,
height: rowHeight,
fillColor: rowStyles.fillColor,
lineColor: rowStyles.lineColor,
lineWidth: rowStyles.lineWidth
}, rowHeading.border));
}
rowHeading = this.mixinDeep({
left: data.settings.margin.left + data.table.width / 2,
top: row.y + ((rowHeight > row.height) ? rowHeight - data.settings.styles.cellPadding : rowHeight / 2),
styles: {
halign: 'center',
valign: (rowHeight > row.height) ? 'bottom' : 'middle'
}
}, rowHeading);
if (rowHeading.font) {
this.setFont(rowHeading.font);
}
this.doc.autoTableText(rowHeading.text, rowHeading.left, rowHeading.top, rowHeading.styles);
data.cursor.y += rowHeight;
}
})
}, table.options);
if (table.options.addPageContent) {
if (typeof table.options.addPageContent === 'string') {
table.options.addPageContent = lang.hitch(this, this[table.options.addPageContent]);
} else {
table.options.addPageContent = lang.hitch(this, table.options.addPageContent); // anonymous function
}
}
this.doc.autoTable(table.columns, table.data, table.options);
}
},
addText: function (opts) {
opts.text = this.formatText(opts);
this.resetFont();
var font = lang.mixin(lang.clone(this.defaultStyles.font), opts.font);
this.setFont(font);
var width = this.doc.getStringUnitWidth(opts.text) * this.doc.internal.getFontSize();
if (opts.align === 'center' || opts.halign === 'center') {
opts.left -= width / 2;
} else if (opts.align === 'right' || opts.halign === 'right') {
opts.left -= width;
}
if (opts.pageNumber) {
this.setPage(opts.pageNumber);
}
this.doc.text(opts.text, opts.left, opts.top);
this.resetFont();
},
addLine: function (opts) {
this.resetLine();
var line = lang.mixin(lang.clone(this.defaultStyles), opts);
this.setLine(line);
if (opts.pageNumber) {
this.setPage(opts.pageNumber);
}
this.doc.line(opts.left, opts.top, opts.right, opts.bottom);
this.resetLine();
},
addBorder: function (opts) {
this.addRectangle(opts);
},
addRectangle: function (opts) {
this.resetRectangle();
var rect = lang.mixin(lang.clone(this.defaultStyles.rectangle), opts);
this.setRectangle(rect);
if (opts.pageNumber) {
this.setPage(opts.pageNumber);
}
if (opts.left && opts.top && opts.width && opts.height) {
if (opts.fillStyle) {
this.doc.rect(opts.left, opts.top, opts.width, opts.height, opts.fillStyle);
} else {
this.doc.rect(opts.left, opts.top, opts.width, opts.height);
}
}
this.resetRectangle();
},
addSquare: function (opts) {
if (opts.width) {
opts.height = opts.width;
} else if (opts.height) {
opts.width = opts.height;
}
this.addRectangle(opts);
},
addCircle: function (opts) {
if (!opts.width && opts.height) {
opts.width = opts.height;
}
this.resetRectangle();
var rect = lang.mixin(lang.clone(this.defaultStyles.rectangle), opts);
this.setRectangle(rect);
if (opts.pageNumber) {
this.setPage(opts.pageNumber);
}
if (opts.x && opts.y && opts.width) {
if (opts.fillStyle) {
this.doc.circle(opts.x, opts.y, opts.width, opts.fillStyle);
} else {
this.doc.circle(opts.x, opts.y, opts.width);
}
}
this.resetRectangle();
},
addEllipse: function (opts) {
this.resetRectangle();
var rect = lang.mixin(lang.clone(this.defaultStyles.rectangle), opts);
this.setRectangle(rect);
if (opts.pageNumber) {
this.setPage(opts.pageNumber);
}
if (opts.x && opts.y && opts.width && opts.height) {
if (opts.fillStyle) {
this.doc.ellipse(opts.x, opts.y, opts.width, opts.height, opts.fillStyle);
} else {
this.doc.ellipse(opts.x, opts.y, opts.width, opts.height);
}
}
this.resetRectangle();
},
addTriangle: function (opts) {
this.resetRectangle();
var rect = lang.mixin(lang.clone(this.defaultStyles.rectangle), opts);
this.setRectangle(rect);
if (opts.pageNumber) {
this.setPage(opts.pageNumber);
}
if (opts.x1 && opts.y1 && opts.x2 && opts.y2 && opts.x3 && opts.y3) {
if (opts.fillStyle) {
this.doc.triangle(opts.x1, opts.y1, opts.x2, opts.y2, opts.x3, opts.y3, opts.fillStyle);
} else {
this.doc.triangle(opts.x1, opts.y1, opts.x2, opts.y2, opts.x3, opts.y3);
}
}
this.resetRectangle();
},
addImage: function (image) {
var opts = lang.clone(image);
var img = this.images[opts.id];
if (!img || !opts.left || !opts.top) {
return;
}
this.resetRectangle();
if (opts.pageNumber) {
this.setPage(opts.pageNumber);
}
var imgFormat = opts.format || 'PNG';
this.doc.addImage(img, imgFormat, opts.left, opts.top, opts.width, opts.height);
if (opts.border) {
this.addBorder(opts);
}
this.resetRectangle();
},
addShape: function (opts) {
switch (opts.type) {
case 'circle':
this.addCircle(opts);
break;
case 'ellipse':
this.addEllipse(opts);
break;
case 'rectangle':
this.addRectangle(opts);
break;
case 'square':
this.addSquare(opts);
break;
case 'triangle':
this.addTriangle(opts);
break;
default:
}
},
setPage: function (pageNumber) {
pageNumber = pageNumber || 1;
var currPages = this.doc.internal.pages.length - 1; // the jsPDF array is off by one
if (currPages < pageNumber) {
while (currPages < pageNumber) {
this.doc.addPage();
currPages++;
}
}
this.doc.setPage(pageNumber);
},
setFont: function (font) {
if (font) {
if (typeof font.font === 'string') {
this.doc.setFont(font.font);
}
this.setTextColor(font.fontColor || font.textColor || font.color);
var size = font.fontSize || font.size;
if (this.isNumeric(size)) {
this.doc.setFontSize(size);
}
var style = font.fontStyle || font.style;
if (typeof style === 'string') {
this.doc.setFontStyle(style);
}
}
},
resetFont: function () {
this.setFont(this.defaultStyles.font);
},
setLine: function (opts) {
if (opts) {
this.setLineWidth(opts.lineWidth || opts.width);
this.setDrawColor(opts.lineColor || opts.color);
}
},
resetLine: function () {
this.setLine(this.defaultStyles);
},
setRectangle: function (opts) {
if (opts) {
this.setLineWidth(opts.lineWidth || opts.width);
this.setDrawColor(opts.lineColor || opts.color);
this.setFillColor(opts.fillColor);
}
},
resetRectangle: function () {
this.setRectangle(this.defaultStyles.rectangle);
},
setLineWidth: function (width) {
if (this.isNumeric(width)) {
this.doc.setLineWidth(width);
}
},
setTextColor: function (color) {
if ((typeof color !== 'undefined') && (color !== null)) {
if (color instanceof Array) {
if (color.length === 3) {
this.doc.setTextColor(color[0], color[1], color[2]);
} else if (color.length === 4) {
this.doc.setTextColor(color[0], color[1], color[2], color[3]);
}
} else {
this.doc.setTextColor(color, 'normal');
}
}
},
setDrawColor: function (color) {
if ((typeof color !== 'undefined') && (color !== null)) {
if (color instanceof Array) {
if (color.length === 3) {
this.doc.setDrawColor(color[0], color[1], color[2]);
} else if (color.length === 4) {
this.doc.setDrawColor(color[0], color[1], color[2], color[3]);
}
} else {
this.doc.setDrawColor(color);
}
}
},
setFillColor: function (color) {
if ((typeof color !== 'undefined') && (color !== null)) {
if (color instanceof Array) {
if (color.length === 3) {
this.doc.setFillColor(color[0], color[1], color[2]);
} else if (color.length === 4) {
this.doc.setFillColor(color[0], color[1], color[2], color[3]);
}
} else {
this.doc.setFillColor(color);
}
}
},
getMapFormat: function () {
var options = this.mapImage;
var format = options.format || 'png';
format = format.toLowerCase();
if (format.substr(0, 3) === 'png') {
format = 'png';
}
return format;
},
showLoadingMask: function () {
fx.fadeIn({
node: this.reportOverlayNode,
gotoStart: true,
duration: this.fadeInDuration,
onEnd: function (node) {
domStyle.set(node, 'display', 'block');
}
}).play();
},
hideLoadingMask: function () {
fx.fadeOut({
node: this.reportOverlayNode,
gotoStart: true,
duration: this.fadeOutDuration,
onEnd: function (node) {
domStyle.set(node, 'display', 'none');
}
}).play();
},
convertPixelToMilimeter: function (pixels) {
return (pixels * 25.4) / (this.reportLayout.map.dpi || 72);
},
converMilimeterToPixel: function (mm) {
return (mm * (this.reportLayout.map.dpi || 72)) / 25.4;
},
convertPixelToPoint: function (pixels) {
return (pixels * (3 / 4));
},
converPointToPixel: function (points) {
return (points * (4 / 3));
},
isNumeric: function (n) {
return !isNaN(parseFloat(n)) && isFinite(n);
},
formatText: function (opts) {
var text = opts.text,
date = null,
format = opts.format || '';
if (opts.formatter) { // custom formatter?
return opts.formatter(text, opts.attributes);
}
if (typeof text === 'undefined' || text === null) {
switch (format.toLowerCase()) {
case 'date':
text = this.formatDate(new Date());
break;
case 'datetime':
text = this.formatDateTime(new Date());
break;
case 'pagenumber':
text = 'Page ' + opts.pageNumber;
break;
default:
text = '';
break;
}
} else {
switch (format.toLowerCase()) {
case 'date':
date = this.getDateTime(text);
if (date) {
text = this.formatDate(date, opts.formatOptions);
}
break;
case 'datetime':
date = this.getDateTime(text);
if (date) {
text = this.formatDateTime(date, opts.formatOptions);
}
break;
case 'currency':
text = this.formatCurrency(text, opts.formatOptions);
break;
case 'integer':
text = this.formatNumber(text, opts.formatOptions);
break;
case 'double':
text = this.formatSingleDouble(text, opts.formatOptions);
break;
case 'truefalse':
case 'boolean':
text = this.formatBoolean(text);
break;
case 'yesno':
text = this.formatYesNo(text);
break;
default:
break;
}
}
return text;
},
formatDateTime: function (value, formatOptions) {
if (value instanceof Date) {
return locale.format(value, formatOptions || {
formatLength: 'short'
});
}
return '';
},
formatDate: function (value, formatOptions) {
if (value instanceof Date) {
return locale.format(value, formatOptions || {
selector: 'date',
formatLength: 'short'
});
}
return '';
},
formatNumber: function (value, formatOptions) {
if (!isNaN(value)) {
return number.format(value, formatOptions || {
places: 0
});
}
return '';
},
formatSingleDouble: function (value, formatOptions) {
if (!isNaN(value)) {
return number.format(value, formatOptions || {
places: 3
});
}
return '';
},
formatCurrency: function (value, formatOptions) {
if (!isNaN(value)) {
return currency.format(value, formatOptions || {
currency: 'USD'
});
}
return '';
},
formatBoolean: function (value) {
if (!isNaN(value)) {
return (Math.abs(parseInt(value, 10)) === 1) ? 'True' : 'False';
}
return '';
},
formatYesNo: function (value) {
if (!isNaN(value)) {
return (Math.abs(parseInt(value, 10)) === 1) ? 'Yes' : 'No';
}
return '';
},
getDateTime: function (value) {
if (isNaN(value) || value === 0 || value === null || value === '') {
return null;
}
return new Date(value);
},
checkImages: function () {
for (var key in this.images) {
if (!this.images[key]) {
return;
}
}
this.createPDF();
},
preloadImages: function () {
if (this.reportLayout.map) {
this.reportLayout.map.id = this.reportLayout.map.id || this.imagePrefix + 'map';
this.images[this.reportLayout.map.id] = null;
}
array.forEach(this.reportLayout.images, lang.hitch(this, function (image) {
if (!image.id) {
image.id = this.imagePrefix + String(Object.keys(this.images).length);
}
this.images[image.id] = null;
this.loadImage(image.id, image.url);
}));
},
loadImage: function (id, url) {
var blankPNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=';
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = lang.hitch(this, function () {
this.images[id] = img;
this.checkImages();
});
img.onerror = lang.hitch(this, function () {
img.src = blankPNG;
this.images[id] = img;
this.checkImages();
});
img.id = id;
img.src = url;
//resets cache on src of img if it comes back undefined, using a 1x1 blank gif dataURI
if (img.complete || typeof img.complete === 'undefined') {
img.src = blankPNG;
img.src = url;
}
},
clearImages: function () {
for (var key in this.images) {
if (this.images.hasOwnProperty(key)) {
delete this.images[key];
}
}
this.images = [];
this.mapImage = null;
},
/*
convertImgToDataURLviaCanvas: function (url, format, callback) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = lang.hitch(this, callback, img, format); //, callback);
img.src = url;
//resets cache on src of img if it comes back undefined, using a 1x1 blank gif dataURI
if (img.complete || typeof img.complete === 'undefined') {
img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
img.src = url;
}
},
onImageLoad: function (img, format, callback) {
format = format || 'PNG';
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img, 0, 0);
dataURL = canvas.toDataURL(format);
if (callback) {
callback(img);
}
canvas = null;
},
convertFileToDataURLviaFileReader: function (url, callback) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function () {
var reader = new FileReader();
reader.onloadend = function () {
callback(reader.result);
};
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.send();
},
*/
getProxiedUrl: function (url) {
var proxyRule = urlUtils.getProxyRule(url);
if (proxyRule && proxyRule.proxyUrl) {
return proxyRule.proxyUrl + '?' + url;
}
return url;
},
mixinDeep: function (dest, source) {
//Recursively mix the properties of two objects
var empty = {};
for (var name in source) {
if (!(name in dest) || (dest[name] !== source[name] && (!(name in empty) || empty[name] !== source[name]))) {
try {
if (source[name].constructor === Object) {
dest[name] = this.mixinDeep(dest[name], source[name]);
} else {
dest[name] = source[name];
}
} catch (e) {
// Property in destination object not set. Create it and set its value.
dest[name] = source[name];
}
}
}
return dest;
}
/*
// add a table with fake data for demonstration purposes
addFakeTable: function (table) {
var options = {
columns: this.getFakeColumns(),
data: this.getFakeData(30), // enough to fill a page to show multiple pages
options: {
theme: 'grid',
margin: {top: table.top},
styles: {cellPadding: 5},
headerStyles: {rowHeight: 18, fontSize: 11},
bodyStyles: {rowHeight: 15, fontSize: 11, valign: 'middle'}
}
};
table = this.mixinDeep(options, table);
this.addTable(table);
},
// Returns a new array each time to avoid pointer issues
getFakeColumns: function () {
return [
{title: 'ID', dataKey: 'id'},
{title: 'Name', dataKey: 'firstName'},
{title: 'Email', dataKey: 'email'},
{title: 'City', dataKey: 'city'},
{title: 'Country', dataKey: 'country'},
{title: 'Expenses', dataKey: 'expenses'}
];
},
// Uses the faker.js library to get random data.
getFakeData: function (rowCount) {
rowCount = rowCount || 4;
var sentence = faker.lorem.words(12);
var data = [];
for (var j = 1; j <= rowCount; j++) {
data.push({
id: j,
firstName: faker.name.findName(),
email: faker.internet.email(),
country: faker.address.country(),
city: faker.address.city(),
expenses: faker.finance.amount(),
text: this.shuffleSentence(sentence),
text2: this.shuffleSentence(sentence)
});
}
return data;
},
shuffleSentence: function (words) {
words = words || faker.lorem.words(8);
var str = faker.helpers.shuffle(words);
return str.charAt(0).toUpperCase() + str.slice(1);
}
*/
});
});