mirror of
https://github.com/nasa/openmct.git
synced 2025-03-14 16:26:50 +00:00
Merge pull request #1164 from hudsonfoo/open967
[Enhancement] Export plot as PDF, JPG, or PNG
This commit is contained in:
commit
e73bb4ff4a
@ -18,6 +18,8 @@
|
|||||||
"node-uuid": "^1.4.7",
|
"node-uuid": "^1.4.7",
|
||||||
"comma-separated-values": "^3.6.4",
|
"comma-separated-values": "^3.6.4",
|
||||||
"FileSaver.js": "^0.0.2",
|
"FileSaver.js": "^0.0.2",
|
||||||
"zepto": "^1.1.6"
|
"zepto": "^1.1.6",
|
||||||
|
"html2canvas": "^0.4.1",
|
||||||
|
"jspdf": "^1.2.61"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
main.js
8
main.js
@ -28,6 +28,8 @@ requirejs.config({
|
|||||||
"angular-route": "bower_components/angular-route/angular-route.min",
|
"angular-route": "bower_components/angular-route/angular-route.min",
|
||||||
"csv": "bower_components/comma-separated-values/csv.min",
|
"csv": "bower_components/comma-separated-values/csv.min",
|
||||||
"es6-promise": "bower_components/es6-promise/promise.min",
|
"es6-promise": "bower_components/es6-promise/promise.min",
|
||||||
|
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
|
||||||
|
"jsPDF": "bower_components/jspdf/dist/jspdf.min",
|
||||||
"moment": "bower_components/moment/moment",
|
"moment": "bower_components/moment/moment",
|
||||||
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
||||||
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
||||||
@ -43,6 +45,12 @@ requirejs.config({
|
|||||||
"angular-route": {
|
"angular-route": {
|
||||||
"deps": ["angular"]
|
"deps": ["angular"]
|
||||||
},
|
},
|
||||||
|
"html2canvas": {
|
||||||
|
"exports": "html2canvas"
|
||||||
|
},
|
||||||
|
"jsPDF": {
|
||||||
|
"exports": "jsPDF"
|
||||||
|
},
|
||||||
"moment-duration-format": {
|
"moment-duration-format": {
|
||||||
"deps": ["moment"]
|
"deps": ["moment"]
|
||||||
},
|
},
|
||||||
|
@ -25,6 +25,7 @@ define([
|
|||||||
"./src/PlotController",
|
"./src/PlotController",
|
||||||
"./src/policies/PlotViewPolicy",
|
"./src/policies/PlotViewPolicy",
|
||||||
"./src/PlotOptionsController",
|
"./src/PlotOptionsController",
|
||||||
|
"./src/services/ExportImageService",
|
||||||
"text!./res/templates/plot.html",
|
"text!./res/templates/plot.html",
|
||||||
"text!./res/templates/plot-options-browse.html",
|
"text!./res/templates/plot-options-browse.html",
|
||||||
'legacyRegistry'
|
'legacyRegistry'
|
||||||
@ -33,6 +34,7 @@ define([
|
|||||||
PlotController,
|
PlotController,
|
||||||
PlotViewPolicy,
|
PlotViewPolicy,
|
||||||
PlotOptionsController,
|
PlotOptionsController,
|
||||||
|
exportImageService,
|
||||||
plotTemplate,
|
plotTemplate,
|
||||||
plotOptionsBrowseTemplate,
|
plotOptionsBrowseTemplate,
|
||||||
legacyRegistry
|
legacyRegistry
|
||||||
@ -70,6 +72,8 @@ define([
|
|||||||
"implementation": PlotController,
|
"implementation": PlotController,
|
||||||
"depends": [
|
"depends": [
|
||||||
"$scope",
|
"$scope",
|
||||||
|
"$element",
|
||||||
|
"exportImageService",
|
||||||
"telemetryFormatter",
|
"telemetryFormatter",
|
||||||
"telemetryHandler",
|
"telemetryHandler",
|
||||||
"throttle",
|
"throttle",
|
||||||
@ -84,12 +88,30 @@ define([
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"services": [
|
||||||
|
{
|
||||||
|
"key": "exportImageService",
|
||||||
|
"implementation": exportImageService,
|
||||||
|
"depends": [
|
||||||
|
"$q",
|
||||||
|
"$timeout",
|
||||||
|
"$log",
|
||||||
|
"EXPORT_IMAGE_TIMEOUT"
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
"constants": [
|
"constants": [
|
||||||
{
|
{
|
||||||
"key": "PLOT_FIXED_DURATION",
|
"key": "PLOT_FIXED_DURATION",
|
||||||
"value": 900000,
|
"value": 900000,
|
||||||
"priority": "fallback",
|
"priority": "fallback",
|
||||||
"comment": "Fifteen minutes."
|
"comment": "Fifteen minutes."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "EXPORT_IMAGE_TIMEOUT",
|
||||||
|
"value": 500,
|
||||||
|
"priority": "fallback"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"policies": [
|
"policies": [
|
||||||
@ -103,6 +125,38 @@ define([
|
|||||||
"key": "plot-options-browse",
|
"key": "plot-options-browse",
|
||||||
"template": plotOptionsBrowseTemplate
|
"template": plotOptionsBrowseTemplate
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"licenses": [
|
||||||
|
{
|
||||||
|
"name": "FileSaver.js",
|
||||||
|
"version": "0.0.2",
|
||||||
|
"author": "Eli Grey",
|
||||||
|
"description": "File download initiator (for file exports)",
|
||||||
|
"website": "https://github.com/eligrey/FileSaver.js/",
|
||||||
|
"copyright": "Copyright © 2015 Eli Grey.",
|
||||||
|
"license": "license-mit",
|
||||||
|
"link": "https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "html2canvas",
|
||||||
|
"version": "0.4.1",
|
||||||
|
"author": "Niklas von Hertzen",
|
||||||
|
"description": "JavaScript HTML renderer",
|
||||||
|
"website": "https://github.com/niklasvh/html2canvas",
|
||||||
|
"copyright": "Copyright © 2012 Niklas von Hertzen.",
|
||||||
|
"license": "license-mit",
|
||||||
|
"link": "https://github.com/niklasvh/html2canvas/blob/master/LICENSE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "jsPDF",
|
||||||
|
"version": "1.2.61",
|
||||||
|
"author": "James Hall",
|
||||||
|
"description": "JavaScript HTML renderer",
|
||||||
|
"website": "https://github.com/MrRio/jsPDF",
|
||||||
|
"copyright": "Copyright © 2010-2016 James Hall",
|
||||||
|
"license": "license-mit",
|
||||||
|
"link": "https://github.com/MrRio/jsPDF/blob/master/MIT-LICENSE.txt"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -20,7 +20,27 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<span ng-controller="PlotController as plot"
|
<span ng-controller="PlotController as plot"
|
||||||
class="abs holder holder-plot">
|
class="abs holder holder-plot has-control-bar">
|
||||||
|
<div class="l-control-bar" ng-show="!plot.hideExportButtons">
|
||||||
|
<span class="l-btn-set">
|
||||||
|
<a class="s-button t-export icon-download labeled first"
|
||||||
|
ng-click="plot.exportPDF()"
|
||||||
|
title="Export This View's Data as PDF">
|
||||||
|
PDF
|
||||||
|
</a>
|
||||||
|
<a class="s-button t-export labeled"
|
||||||
|
ng-click="plot.exportPNG()"
|
||||||
|
title="Export This View's Data as PNG">
|
||||||
|
PNG
|
||||||
|
</a>
|
||||||
|
<a class="s-button t-export labeled last"
|
||||||
|
ng-click="plot.exportJPG()"
|
||||||
|
title="Export This View's Data as JPG">
|
||||||
|
JPG
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="l-view-section">
|
||||||
<div class="gl-plot"
|
<div class="gl-plot"
|
||||||
ng-style="{ height: 100 / plot.getSubPlots().length + '%'}"
|
ng-style="{ height: 100 / plot.getSubPlots().length + '%'}"
|
||||||
ng-repeat="subplot in plot.getSubPlots()">
|
ng-repeat="subplot in plot.getSubPlots()">
|
||||||
@ -136,4 +156,5 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</span>
|
</span>
|
||||||
|
@ -54,7 +54,8 @@ define(
|
|||||||
* @throws {Error} an error is thrown if WebGL is unavailable.
|
* @throws {Error} an error is thrown if WebGL is unavailable.
|
||||||
*/
|
*/
|
||||||
function GLChart(canvas) {
|
function GLChart(canvas) {
|
||||||
var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"),
|
var gl = canvas.getContext("webgl", { preserveDrawingBuffer: true }) ||
|
||||||
|
canvas.getContext("experimental-webgl", { preserveDrawingBuffer: true }),
|
||||||
vertexShader,
|
vertexShader,
|
||||||
fragmentShader,
|
fragmentShader,
|
||||||
program,
|
program,
|
||||||
|
@ -63,6 +63,8 @@ define(
|
|||||||
*/
|
*/
|
||||||
function PlotController(
|
function PlotController(
|
||||||
$scope,
|
$scope,
|
||||||
|
$element,
|
||||||
|
exportImageService,
|
||||||
telemetryFormatter,
|
telemetryFormatter,
|
||||||
telemetryHandler,
|
telemetryHandler,
|
||||||
throttle,
|
throttle,
|
||||||
@ -246,6 +248,8 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.pending = true;
|
self.pending = true;
|
||||||
|
self.$element = $element;
|
||||||
|
self.exportImageService = exportImageService;
|
||||||
|
|
||||||
// Initialize axes; will get repopulated when telemetry
|
// Initialize axes; will get repopulated when telemetry
|
||||||
// metadata becomes available.
|
// metadata becomes available.
|
||||||
@ -364,6 +368,39 @@ define(
|
|||||||
return this.pending;
|
return this.pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export the plot to PDF
|
||||||
|
*/
|
||||||
|
PlotController.prototype.exportPDF = function () {
|
||||||
|
var self = this;
|
||||||
|
self.hideExportButtons = true;
|
||||||
|
self.exportImageService.exportPDF(self.$element[0], "plot.pdf").finally(function () {
|
||||||
|
self.hideExportButtons = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export the plot to PNG
|
||||||
|
*/
|
||||||
|
PlotController.prototype.exportPNG = function () {
|
||||||
|
var self = this;
|
||||||
|
self.hideExportButtons = true;
|
||||||
|
self.exportImageService.exportPNG(self.$element[0], "plot.png").finally(function () {
|
||||||
|
self.hideExportButtons = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export the plot to JPG
|
||||||
|
*/
|
||||||
|
PlotController.prototype.exportJPG = function () {
|
||||||
|
var self = this;
|
||||||
|
self.hideExportButtons = true;
|
||||||
|
self.exportImageService.exportJPG(self.$element[0], "plot.jpg").finally(function () {
|
||||||
|
self.hideExportButtons = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return PlotController;
|
return PlotController;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
176
platform/features/plot/src/services/ExportImageService.js
Normal file
176
platform/features/plot/src/services/ExportImageService.js
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining ExportImageService. Created by hudsonfoo on 09/02/16
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
"html2canvas",
|
||||||
|
"jsPDF",
|
||||||
|
"saveAs"
|
||||||
|
],
|
||||||
|
function (
|
||||||
|
html2canvas,
|
||||||
|
jsPDF,
|
||||||
|
saveAs
|
||||||
|
) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The export image service will export any HTML node to
|
||||||
|
* PDF, JPG, or PNG.
|
||||||
|
* @param {object} $q
|
||||||
|
* @param {object} $timeout
|
||||||
|
* @param {object} $log
|
||||||
|
* @param {constant} EXPORT_IMAGE_TIMEOUT time in milliseconds before a timeout error is returned
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function ExportImageService($q, $timeout, $log, EXPORT_IMAGE_TIMEOUT, injHtml2Canvas, injJsPDF, injSaveAs, injFileReader) {
|
||||||
|
self.$q = $q;
|
||||||
|
self.$timeout = $timeout;
|
||||||
|
self.$log = $log;
|
||||||
|
self.EXPORT_IMAGE_TIMEOUT = EXPORT_IMAGE_TIMEOUT;
|
||||||
|
self.html2canvas = injHtml2Canvas || html2canvas;
|
||||||
|
self.jsPDF = injJsPDF || jsPDF;
|
||||||
|
self.saveAs = injSaveAs || saveAs;
|
||||||
|
self.reader = injFileReader || new FileReader();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders an HTML element into a base64 encoded image
|
||||||
|
* as a BLOB, PNG, or JPG.
|
||||||
|
* @param {node} element that will be converted to an image
|
||||||
|
* @param {string} type of image to convert the element to
|
||||||
|
* @returns {promise}
|
||||||
|
*/
|
||||||
|
function renderElement(element, type) {
|
||||||
|
var defer = self.$q.defer(),
|
||||||
|
validTypes = ["png", "jpg", "jpeg"],
|
||||||
|
renderTimeout;
|
||||||
|
|
||||||
|
if (validTypes.indexOf(type) === -1) {
|
||||||
|
self.$log.error("Invalid type requested. Try: (" + validTypes.join(",") + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderTimeout = self.$timeout(function () {
|
||||||
|
defer.reject("html2canvas timed out");
|
||||||
|
self.$log.warn("html2canvas timed out");
|
||||||
|
}, self.EXPORT_IMAGE_TIMEOUT);
|
||||||
|
|
||||||
|
try {
|
||||||
|
self.html2canvas(element, {
|
||||||
|
onrendered: function (canvas) {
|
||||||
|
switch (type.toLowerCase()) {
|
||||||
|
case "png":
|
||||||
|
canvas.toBlob(defer.resolve, "image/png");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case "jpg":
|
||||||
|
case "jpeg":
|
||||||
|
canvas.toBlob(defer.resolve, "image/jpeg");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
defer.reject(e);
|
||||||
|
self.$log.warn("html2canvas failed with error: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
defer.promise.finally(renderTimeout.cancel);
|
||||||
|
|
||||||
|
return defer.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* canvas.toBlob() not supported in IE < 10, Opera, and Safari. This polyfill
|
||||||
|
* implements the method in browsers that would not otherwise support it.
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
|
||||||
|
*/
|
||||||
|
function polyfillToBlob() {
|
||||||
|
if (!HTMLCanvasElement.prototype.toBlob) {
|
||||||
|
Object.defineProperty(HTMLCanvasElement.prototype, "toBlob", {
|
||||||
|
value: function (callback, type, quality) {
|
||||||
|
|
||||||
|
var binStr = atob(this.toDataURL(type, quality).split(',')[1]),
|
||||||
|
len = binStr.length,
|
||||||
|
arr = new Uint8Array(len);
|
||||||
|
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
arr[i] = binStr.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(new Blob([arr], {type: type || "image/png"}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a screenshot of a DOM node and exports to PDF.
|
||||||
|
* @param {node} element to be exported
|
||||||
|
* @param {string} filename the exported image
|
||||||
|
* @returns {promise}
|
||||||
|
*/
|
||||||
|
ExportImageService.prototype.exportPDF = function (element, filename) {
|
||||||
|
return renderElement(element, "jpeg").then(function (img) {
|
||||||
|
self.reader.readAsDataURL(img);
|
||||||
|
self.reader.onloadend = function () {
|
||||||
|
var pdf = new self.jsPDF("l", "px", [element.offsetHeight, element.offsetWidth]);
|
||||||
|
pdf.addImage(self.reader.result, "JPEG", 0, 0, element.offsetWidth, element.offsetHeight);
|
||||||
|
pdf.save(filename);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a screenshot of a DOM node and exports to JPG.
|
||||||
|
* @param {node} element to be exported
|
||||||
|
* @param {string} filename the exported image
|
||||||
|
* @returns {promise}
|
||||||
|
*/
|
||||||
|
ExportImageService.prototype.exportJPG = function (element, filename) {
|
||||||
|
return renderElement(element, "jpeg").then(function (img) {
|
||||||
|
self.saveAs(img, filename);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a screenshot of a DOM node and exports to PNG.
|
||||||
|
* @param {node} element to be exported
|
||||||
|
* @param {string} filename the exported image
|
||||||
|
* @returns {promise}
|
||||||
|
*/
|
||||||
|
ExportImageService.prototype.exportPNG = function (element, filename) {
|
||||||
|
return renderElement(element, "png").then(function (img) {
|
||||||
|
self.saveAs(img, filename);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
polyfillToBlob();
|
||||||
|
|
||||||
|
return ExportImageService;
|
||||||
|
}
|
||||||
|
);
|
@ -1,3 +1,5 @@
|
|||||||
|
/*global angular*/
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Open MCT, Copyright (c) 2014-2016, United States Government
|
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
@ -29,6 +31,8 @@ define(
|
|||||||
|
|
||||||
describe("The plot controller", function () {
|
describe("The plot controller", function () {
|
||||||
var mockScope,
|
var mockScope,
|
||||||
|
mockElement,
|
||||||
|
mockExportImageService,
|
||||||
mockFormatter,
|
mockFormatter,
|
||||||
mockHandler,
|
mockHandler,
|
||||||
mockThrottle,
|
mockThrottle,
|
||||||
@ -65,6 +69,11 @@ define(
|
|||||||
"$scope",
|
"$scope",
|
||||||
["$watch", "$on", "$emit"]
|
["$watch", "$on", "$emit"]
|
||||||
);
|
);
|
||||||
|
mockElement = angular.element('<div />');
|
||||||
|
mockExportImageService = jasmine.createSpyObj(
|
||||||
|
"ExportImageService",
|
||||||
|
["exportJPG", "exportPNG", "exportPDF"]
|
||||||
|
);
|
||||||
mockFormatter = jasmine.createSpyObj(
|
mockFormatter = jasmine.createSpyObj(
|
||||||
"formatter",
|
"formatter",
|
||||||
["formatDomainValue", "formatRangeValue"]
|
["formatDomainValue", "formatRangeValue"]
|
||||||
@ -107,6 +116,8 @@ define(
|
|||||||
|
|
||||||
controller = new PlotController(
|
controller = new PlotController(
|
||||||
mockScope,
|
mockScope,
|
||||||
|
mockElement,
|
||||||
|
mockExportImageService,
|
||||||
mockFormatter,
|
mockFormatter,
|
||||||
mockHandler,
|
mockHandler,
|
||||||
mockThrottle
|
mockThrottle
|
||||||
|
141
platform/features/plot/test/services/ExportImageServiceSpec.js
Normal file
141
platform/features/plot/test/services/ExportImageServiceSpec.js
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExportImageServiceSpec. Created by hudsonfoo on 09/03/16.
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
["../../src/services/ExportImageService"],
|
||||||
|
function (ExportImageService) {
|
||||||
|
var mockQ,
|
||||||
|
mockDeferred,
|
||||||
|
mockPromise,
|
||||||
|
mockTimeout,
|
||||||
|
mockLog,
|
||||||
|
mockHtml2Canvas,
|
||||||
|
mockCanvas,
|
||||||
|
mockJsPDF,
|
||||||
|
mockJsPDFSave,
|
||||||
|
mockSaveAs,
|
||||||
|
mockFileReader,
|
||||||
|
mockExportTimeoutConstant,
|
||||||
|
testElement,
|
||||||
|
exportImageService;
|
||||||
|
|
||||||
|
describe("ExportImageService", function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
mockDeferred = jasmine.createSpyObj(
|
||||||
|
"deferred",
|
||||||
|
["reject", "resolve"]
|
||||||
|
);
|
||||||
|
mockPromise = jasmine.createSpyObj(
|
||||||
|
"promise",
|
||||||
|
["then", "finally"]
|
||||||
|
);
|
||||||
|
mockPromise.then = function (callback) {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
mockQ = {
|
||||||
|
"defer": function () {
|
||||||
|
return {
|
||||||
|
"resolve": mockDeferred.resolve,
|
||||||
|
"reject": mockDeferred.reject,
|
||||||
|
"promise": mockPromise
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mockTimeout = function (fn, time) {
|
||||||
|
return {
|
||||||
|
"cancel": function () {}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mockLog = jasmine.createSpyObj(
|
||||||
|
"$log",
|
||||||
|
["warn"]
|
||||||
|
);
|
||||||
|
mockHtml2Canvas = jasmine.createSpy("html2canvas").andCallFake(function (element, opts) {
|
||||||
|
opts.onrendered(mockCanvas);
|
||||||
|
});
|
||||||
|
mockCanvas = jasmine.createSpyObj(
|
||||||
|
"canvas",
|
||||||
|
["toBlob"]
|
||||||
|
);
|
||||||
|
mockJsPDFSave = jasmine.createSpy("jsPDFSave");
|
||||||
|
mockJsPDF = function () {
|
||||||
|
return {
|
||||||
|
"addImage": function () {},
|
||||||
|
"save": mockJsPDFSave
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mockSaveAs = jasmine.createSpy("saveAs");
|
||||||
|
mockFileReader = jasmine.createSpyObj(
|
||||||
|
"FileReader",
|
||||||
|
["readAsDataURL", "onloadend"]
|
||||||
|
);
|
||||||
|
mockExportTimeoutConstant = 0;
|
||||||
|
testElement = {};
|
||||||
|
|
||||||
|
exportImageService = new ExportImageService(
|
||||||
|
mockQ,
|
||||||
|
mockTimeout,
|
||||||
|
mockLog,
|
||||||
|
mockExportTimeoutConstant,
|
||||||
|
mockHtml2Canvas,
|
||||||
|
mockJsPDF,
|
||||||
|
mockSaveAs,
|
||||||
|
mockFileReader
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("runs html2canvas and tries to save a pdf", function () {
|
||||||
|
exportImageService.exportPDF(testElement, "plot.pdf");
|
||||||
|
mockFileReader.onloadend();
|
||||||
|
|
||||||
|
expect(mockHtml2Canvas).toHaveBeenCalledWith(testElement, { onrendered: jasmine.any(Function) });
|
||||||
|
expect(mockCanvas.toBlob).toHaveBeenCalledWith(mockDeferred.resolve, "image/jpeg");
|
||||||
|
expect(mockDeferred.reject).not.toHaveBeenCalled();
|
||||||
|
expect(mockJsPDFSave).toHaveBeenCalled();
|
||||||
|
expect(mockPromise.finally).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("runs html2canvas and tries to save a png", function () {
|
||||||
|
exportImageService.exportPNG(testElement, "plot.png");
|
||||||
|
|
||||||
|
expect(mockHtml2Canvas).toHaveBeenCalledWith(testElement, { onrendered: jasmine.any(Function) });
|
||||||
|
expect(mockCanvas.toBlob).toHaveBeenCalledWith(mockDeferred.resolve, "image/png");
|
||||||
|
expect(mockDeferred.reject).not.toHaveBeenCalled();
|
||||||
|
expect(mockSaveAs).toHaveBeenCalled();
|
||||||
|
expect(mockPromise.finally).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("runs html2canvas and tries to save a jpg", function () {
|
||||||
|
exportImageService.exportJPG(testElement, "plot.png");
|
||||||
|
|
||||||
|
expect(mockHtml2Canvas).toHaveBeenCalledWith(testElement, { onrendered: jasmine.any(Function) });
|
||||||
|
expect(mockCanvas.toBlob).toHaveBeenCalledWith(mockDeferred.resolve, "image/jpeg");
|
||||||
|
expect(mockDeferred.reject).not.toHaveBeenCalled();
|
||||||
|
expect(mockSaveAs).toHaveBeenCalled();
|
||||||
|
expect(mockPromise.finally).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
@ -54,6 +54,8 @@ requirejs.config({
|
|||||||
"angular-route": "bower_components/angular-route/angular-route.min",
|
"angular-route": "bower_components/angular-route/angular-route.min",
|
||||||
"csv": "bower_components/comma-separated-values/csv.min",
|
"csv": "bower_components/comma-separated-values/csv.min",
|
||||||
"es6-promise": "bower_components/es6-promise/promise.min",
|
"es6-promise": "bower_components/es6-promise/promise.min",
|
||||||
|
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
|
||||||
|
"jsPDF": "bower_components/jspdf/dist/jspdf.min",
|
||||||
"moment": "bower_components/moment/moment",
|
"moment": "bower_components/moment/moment",
|
||||||
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
||||||
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user