NIFI-2251

- Initial commit for client side provenance lineage svg download.
- css styling adjustments, changes for svg replace
- Addressing some style/spacing.
- This closes #982.
This commit is contained in:
Yolanda M. Davis 2016-08-31 21:04:49 -04:00 committed by Matt Gilman
parent bc005e3398
commit 67a47dbead
4 changed files with 105 additions and 65 deletions

View File

@ -56,7 +56,7 @@
<div id="provenance-lineage-loading" class="loading-container"></div> <div id="provenance-lineage-loading" class="loading-container"></div>
</div> </div>
<div id="provenance-lineage-close-container"> <div id="provenance-lineage-close-container">
<div id="provenance-lineage-downloader" class="hidden" title="Download"></div> <div id="provenance-lineage-downloader" class="fa fa-download" title="Download"></div>
<div id="provenance-lineage-closer" class="fa fa-long-arrow-left" title="Go back to event list"></div> <div id="provenance-lineage-closer" class="fa fa-long-arrow-left" title="Go back to event list"></div>
</div> </div>
<div id="provenance-lineage-context-menu" class="context-menu"></div> <div id="provenance-lineage-context-menu" class="context-menu"></div>
@ -71,4 +71,5 @@
</div> </div>
<div id="provenance-lineage-container"></div> <div id="provenance-lineage-container"></div>
</div> </div>
<a id="image-download-link" hreflang="image/svg+xml" class="hidden" target="_blank"></a>
</div> </div>

View File

@ -372,9 +372,11 @@ div.content-detail-value {
float: left; float: left;
height: 16px; height: 16px;
width: 16px; width: 16px;
background: url("../images/iconExportLineage.png") no-repeat scroll left center transparent; font-size: 16px;
color: #004849;
cursor: pointer; cursor: pointer;
margin-right: 2px; margin-right: 4px;
margin-top: 2px;
} }
#provenance-lineage-closer { #provenance-lineage-closer {
@ -385,6 +387,7 @@ div.content-detail-value {
color: #004849; color: #004849;
cursor: pointer; cursor: pointer;
margin-right: 5px; margin-right: 5px;
margin-top: 2px;
} }
#provenance-lineage-slider-container { #provenance-lineage-slider-container {

View File

@ -42,6 +42,28 @@ nf.ng.ProvenanceLineage = function () {
}); });
}; };
var downloadSvgFile = function(svgString){
var link = document.getElementById("image-download-link");
var downloadSupported = typeof link.download != 'undefined';
var fileName ='lineage.svg';
if (downloadSupported) {
var DOMURL = self.URL || self.webkitURL || self;
var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(svg, fileName);
} else {
var url = DOMURL.createObjectURL(svg);
link.href = url;
link.download = fileName;
link.click();
}
} else {
window.open('data:image/svg+xml;charset=utf-8,' + encodeURI(svgString));
}
};
/** /**
* Appends the items to the context menu. * Appends the items to the context menu.
* *
@ -1203,68 +1225,82 @@ nf.ng.ProvenanceLineage = function () {
$('#provenance-table').data('gridInstance').resizeCanvas(); $('#provenance-table').data('gridInstance').resizeCanvas();
}); });
// TODO - restore this as necessary when able to download lineage svg entirely client side $('#provenance-lineage-downloader').on('click', function () {
// $('#provenance-lineage-downloader').on('click', function () { var svg = $('#provenance-lineage-container').html();
// var svg = $('#provenance-lineage-container').html();
// // get the lineage to determine the actual dimensions
// // get the lineage to determine the actual dimensions var lineage = $('g.lineage')[0];
// var lineage = $('g.lineage')[0]; var bbox = lineage.getBBox();
// var bbox = lineage.getBBox();
// // adjust to provide some padding
// // adjust to provide some padding var height = bbox.height + 60;
// var height = bbox.height + 30; var width = bbox.width + 60;
// var width = bbox.width + 30; var offsetX = bbox.x - 15;
// var offsetX = bbox.x - 15; var offsetY = bbox.y - 15;
// var offsetY = bbox.y - 15;
// // replace the svg height, width with the actual values
// // replace the svg height, width with the actual values svg = svg.replace(/height=".*?"/, 'height="' + height + '"');
// svg = svg.replace(/height=".*?"/, 'height="' + height + '"'); svg = svg.replace(/width=".*?"/, 'width="' + width + '"');
// svg = svg.replace(/width=".*?"/, 'width="' + width + '"');
// // remove any transform applied to the lineage
// // remove any transform applied to the lineage svg = svg.replace(/transform=".*?"/, '');
// svg = svg.replace(/transform=".*?"/, '');
// // adjust link positioning based on the offset of the bounding box
// // adjust link positioning based on the offset of the bounding box svg = svg.replace(/<path([^>]*?)d="M[\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?L[\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?"(.*?)>/g, function (match, before, rawMoveX, rawMoveY, rawLineX, rawLineY, after) {
// svg = svg.replace(/<path([^>]*?)d="M[\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?L[\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?"(.*?)>/g, function (match, before, rawMoveX, rawMoveY, rawLineX, rawLineY, after) { // this regex captures the content before and after the d attribute in order to ensure that it contains the link class.
// // this regex captures the content before and after the d attribute in order to ensure that it contains the link class. // within the svg image, there are other paths that are (within markers) that we do not want to offset
// // within the svg image, there are other paths that are (within markers) that we do not want to offset if (before.indexOf('link') === -1 && after.indexOf('link') === -1) {
// if (before.indexOf('link') === -1 && after.indexOf('link') === -1) { return match;
// return match; }
// }
// var moveX = parseFloat(rawMoveX) - offsetX;
// var moveX = parseFloat(rawMoveX) - offsetX; var moveY = parseFloat(rawMoveY) - offsetY;
// var moveY = parseFloat(rawMoveY) - offsetY; var lineX = parseFloat(rawLineX) - offsetX;
// var lineX = parseFloat(rawLineX) - offsetX; var lineY = parseFloat(rawLineY) - offsetY;
// var lineY = parseFloat(rawLineY) - offsetY; return '<path' + before + 'd="M' + moveX + ',' + moveY + 'L' + lineX + ',' + lineY + '"' + after + '>';
// return '<path' + before + 'd="M' + moveX + ',' + moveY + 'L' + lineX + ',' + lineY + '"' + after + '>'; });
// });
// // adjust node positioning based on the offset of the bounding box
// // adjust node positioning based on the offset of the bounding box svg = svg.replace(/<g([^>]*?)transform="translate\([\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?\)"(.*?)>/g, function (match, before, rawX, rawY, after) {
// svg = svg.replace(/<g([^>]*?)transform="translate\([\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?\)"(.*?)>/g, function (match, before, rawX, rawY, after) { // this regex captures the content before and after the transform attribute in order to ensure that it contains the
// // this regex captures the content before and after the transform attribute in order to ensure that it contains the // node class. only node groups are translated with absolute coordinates since all other translated groups fall under
// // node class. only node groups are translated with absolute coordinates since all other translated groups fall under // a parent that is already positioned. this makes their translation relative and not appropriate for this adjustment
// // a parent that is already positioned. this makes their translation relative and not appropriate for this adjustment if (before.indexOf('node') === -1 && after.indexOf('node') === -1) {
// if (before.indexOf('node') === -1 && after.indexOf('node') === -1) { return match;
// return match; }
// }
// var x = parseFloat(rawX) - offsetX;
// var x = parseFloat(rawX) - offsetX; var y = parseFloat(rawY) - offsetY;
// var y = parseFloat(rawY) - offsetY; return '<g' + before + 'transform="translate(' + x + ',' + y + ')"' + after + '>';
// return '<g' + before + 'transform="translate(' + x + ',' + y + ')"' + after + '>'; });
// });
// // namespaces
// // namespaces svg = svg.replace(/<svg ([^>]*)/, function (match) {
// svg = svg.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"'); var svgString = match;
// var nsSVG = ' xmlns="http://www.w3.org/2000/svg"';
// // doctype var nsXlink = ' xmlns:xlink="http://www.w3.org/1999/xlink"';
// svg = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + svg; var version = ' version="1.1"';
//
// // send to server to initiate download... client side only support is too browser specific at this point if (svgString.indexOf(nsSVG) === -1) {
// nf.Common.post('./download-svg', { svgString += nsSVG;
// 'filename': 'provenance', }
// 'svg': svg
// }); if (svgString.indexOf(nsXlink) === -1) {
// }); svgString += nsXlink;
}
if (svgString.indexOf(version) === -1) {
svgString += version;
}
return svgString;
});
// doctype
svg = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + svg;
downloadSvgFile(svg);
});
initLineageQueryDialog(); initLineageQueryDialog();
}, },