Repository: nifi
Updated Branches:
  refs/heads/master bc005e339 -> 67a47dbea


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.


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/67a47dbe
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/67a47dbe
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/67a47dbe

Branch: refs/heads/master
Commit: 67a47dbead2ea4e06c637bc50c64fbdc2c66a546
Parents: bc005e3
Author: Yolanda M. Davis <[email protected]>
Authored: Wed Aug 31 21:04:49 2016 -0400
Committer: Matt Gilman <[email protected]>
Committed: Wed Sep 14 14:23:46 2016 -0400

----------------------------------------------------------------------
 .../partials/provenance/provenance-content.jsp  |   3 +-
 .../src/main/webapp/css/provenance.css          |   7 +-
 .../main/webapp/images/iconExportLineage.png    | Bin 405 -> 0 bytes
 .../js/nf/provenance/nf-provenance-lineage.js   | 160 ++++++++++++-------
 4 files changed, 105 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/67a47dbe/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/provenance/provenance-content.jsp
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/provenance/provenance-content.jsp
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/provenance/provenance-content.jsp
index 6312f69..79269d8 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/provenance/provenance-content.jsp
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/provenance/provenance-content.jsp
@@ -56,7 +56,7 @@
             <div id="provenance-lineage-loading" 
class="loading-container"></div>
         </div>
         <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>
         <div id="provenance-lineage-context-menu" class="context-menu"></div>
@@ -71,4 +71,5 @@
         </div>
         <div id="provenance-lineage-container"></div>
     </div>
+    <a id="image-download-link" hreflang="image/svg+xml" class="hidden" 
target="_blank"></a>
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi/blob/67a47dbe/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/provenance.css
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/provenance.css
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/provenance.css
index f65011d..d787c4b 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/provenance.css
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/provenance.css
@@ -372,9 +372,11 @@ div.content-detail-value {
     float: left;
     height: 16px;
     width: 16px;
-    background: url("../images/iconExportLineage.png") no-repeat scroll left 
center transparent;
+    font-size: 16px;
+    color: #004849;
     cursor: pointer;
-    margin-right: 2px;
+    margin-right: 4px;
+    margin-top: 2px;
 }
 
 #provenance-lineage-closer {
@@ -385,6 +387,7 @@ div.content-detail-value {
     color: #004849;
     cursor: pointer;
     margin-right: 5px;
+    margin-top: 2px;
 }
 
 #provenance-lineage-slider-container {

http://git-wip-us.apache.org/repos/asf/nifi/blob/67a47dbe/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconExportLineage.png
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconExportLineage.png
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconExportLineage.png
deleted file mode 100755
index 19a4360..0000000
Binary files 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconExportLineage.png
 and /dev/null differ

http://git-wip-us.apache.org/repos/asf/nifi/blob/67a47dbe/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
index 6b038c7..4e15cd2 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
@@ -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.
      *
@@ -1203,68 +1225,82 @@ nf.ng.ProvenanceLineage = function () {
                 $('#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 () {
-            //     var svg = $('#provenance-lineage-container').html();
-            //
-            //     // get the lineage to determine the actual dimensions
-            //     var lineage = $('g.lineage')[0];
-            //     var bbox = lineage.getBBox();
-            //
-            //     // adjust to provide some padding
-            //     var height = bbox.height + 30;
-            //     var width = bbox.width + 30;
-            //     var offsetX = bbox.x - 15;
-            //     var offsetY = bbox.y - 15;
-            //
-            //     // replace the svg height, width with the actual values
-            //     svg = svg.replace(/height=".*?"/, 'height="' + height + 
'"');
-            //     svg = svg.replace(/width=".*?"/, 'width="' + width + '"');
-            //
-            //     // remove any transform applied to the lineage
-            //     svg = svg.replace(/transform=".*?"/, '');
-            //
-            //     // 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) {
-            //         // 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
-            //         if (before.indexOf('link') === -1 && 
after.indexOf('link') === -1) {
-            //             return match;
-            //         }
-            //
-            //         var moveX = parseFloat(rawMoveX) - offsetX;
-            //         var moveY = parseFloat(rawMoveY) - offsetY;
-            //         var lineX = parseFloat(rawLineX) - offsetX;
-            //         var lineY = parseFloat(rawLineY) - offsetY;
-            //         return '<path' + before + 'd="M' + moveX + ',' + moveY 
+ 'L' + lineX + ',' + lineY + '"' + after + '>';
-            //     });
-            //
-            //     // 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) {
-            //         // 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
-            //         // 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) {
-            //             return match;
-            //         }
-            //
-            //         var x = parseFloat(rawX) - offsetX;
-            //         var y = parseFloat(rawY) - offsetY;
-            //         return '<g' + before + 'transform="translate(' + x + 
',' + y + ')"' + after + '>';
-            //     });
-            //
-            //     // namespaces
-            //     svg = svg.replace(/^<svg/, '<svg 
xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink"; 
version="1.1"');
-            //
-            //     // doctype
-            //     svg = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>\n' + svg;
-            //
-            //     // send to server to initiate download... client side only 
support is too browser specific at this point
-            //     nf.Common.post('./download-svg', {
-            //         'filename': 'provenance',
-            //         'svg': svg
-            //     });
-            // });
+             $('#provenance-lineage-downloader').on('click', function () {
+                 var svg = $('#provenance-lineage-container').html();
+
+                 // get the lineage to determine the actual dimensions
+                 var lineage = $('g.lineage')[0];
+                 var bbox = lineage.getBBox();
+
+                 // adjust to provide some padding
+                 var height = bbox.height + 60;
+                 var width = bbox.width + 60;
+                 var offsetX = bbox.x - 15;
+                 var offsetY = bbox.y - 15;
+
+                 // replace the svg height, width with the actual values
+                 svg = svg.replace(/height=".*?"/, 'height="' + height + '"');
+                 svg = svg.replace(/width=".*?"/, 'width="' + width + '"');
+
+                 // remove any transform applied to the lineage
+                 svg = svg.replace(/transform=".*?"/, '');
+
+                 // 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) {
+                     // 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
+                     if (before.indexOf('link') === -1 && 
after.indexOf('link') === -1) {
+                         return match;
+                     }
+
+                     var moveX = parseFloat(rawMoveX) - offsetX;
+                     var moveY = parseFloat(rawMoveY) - offsetY;
+                     var lineX = parseFloat(rawLineX) - offsetX;
+                     var lineY = parseFloat(rawLineY) - offsetY;
+                     return '<path' + before + 'd="M' + moveX + ',' + moveY + 
'L' + lineX + ',' + lineY + '"' + after + '>';
+                 });
+
+                 // 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) {
+                     // 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
+                     // 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) {
+                         return match;
+                     }
+
+                     var x = parseFloat(rawX) - offsetX;
+                     var y = parseFloat(rawY) - offsetY;
+                     return '<g' + before + 'transform="translate(' + x + ',' 
+ y + ')"' + after + '>';
+                 });
+
+                 // namespaces
+                 svg = svg.replace(/<svg ([^>]*)/, function (match) {
+                     var svgString = match;
+                     var nsSVG = ' xmlns="http://www.w3.org/2000/svg";';
+                     var nsXlink = ' 
xmlns:xlink="http://www.w3.org/1999/xlink";';
+                     var version = ' version="1.1"';
+
+                     if (svgString.indexOf(nsSVG) === -1) {
+                         svgString += nsSVG;
+                     }
+
+                     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();
         },

Reply via email to