mirror of https://github.com/apache/nifi.git
NIFI-317:
- Adding support for exporting the lineage graph as SVG. - Removing support to convert to PNG.
This commit is contained in:
parent
b0b14ed10b
commit
4e85e34c31
|
@ -609,18 +609,6 @@
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>batik</groupId>
|
|
||||||
<artifactId>batik-transcoder</artifactId>
|
|
||||||
<version>1.6-1</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>fop</groupId>
|
|
||||||
<artifactId>fop</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
|
|
@ -16,34 +16,24 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.web.servlet;
|
package org.apache.nifi.web.servlet;
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringReader;
|
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
|
|
||||||
import org.apache.batik.transcoder.TranscoderInput;
|
|
||||||
import org.apache.batik.transcoder.TranscoderOutput;
|
|
||||||
import org.apache.batik.transcoder.image.PNGTranscoder;
|
|
||||||
import org.apache.batik.util.XMLResourceDescriptor;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.svg.SVGDocument;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@WebServlet(name = "ConvertSvg", urlPatterns = {"/convert-svg"})
|
@WebServlet(name = "DownloadSvg", urlPatterns = {"/download-svg"})
|
||||||
public class ConvertSvg extends HttpServlet {
|
public class DownloadSvg extends HttpServlet {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ConvertSvg.class);
|
private static final Logger logger = LoggerFactory.getLogger(DownloadSvg.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -54,7 +44,6 @@ public class ConvertSvg extends HttpServlet {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
final String uri = request.getRequestURL().toString();
|
|
||||||
final String rawSvg = request.getParameter("svg");
|
final String rawSvg = request.getParameter("svg");
|
||||||
|
|
||||||
// ensure the image markup has been included
|
// ensure the image markup has been included
|
||||||
|
@ -69,7 +58,6 @@ public class ConvertSvg extends HttpServlet {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputStream bufferedOut = null;
|
|
||||||
try {
|
try {
|
||||||
// get the svg and decode it, +'s need to be converted
|
// get the svg and decode it, +'s need to be converted
|
||||||
final String svg = URLDecoder.decode(rawSvg.replace("+", "%2B"), "UTF-8");
|
final String svg = URLDecoder.decode(rawSvg.replace("+", "%2B"), "UTF-8");
|
||||||
|
@ -80,26 +68,16 @@ public class ConvertSvg extends HttpServlet {
|
||||||
|
|
||||||
String filename = request.getParameter("filename");
|
String filename = request.getParameter("filename");
|
||||||
if (filename == null) {
|
if (filename == null) {
|
||||||
filename = "image.png";
|
filename = "image.svg";
|
||||||
} else if (!filename.endsWith(".png")) {
|
} else if (!filename.endsWith(".svg")) {
|
||||||
filename += ".png";
|
filename += ".svg";
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringReader reader = new StringReader(svg);
|
response.setContentType("image/svg+xml");
|
||||||
final String parser = XMLResourceDescriptor.getXMLParserClassName();
|
|
||||||
final SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
|
|
||||||
final SVGDocument doc = f.createSVGDocument(uri, reader);
|
|
||||||
|
|
||||||
response.setContentType("image/png");
|
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
|
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
|
||||||
bufferedOut = new BufferedOutputStream(response.getOutputStream());
|
response.getWriter().print(svg);
|
||||||
final TranscoderInput transcoderInput = new TranscoderInput(doc);
|
|
||||||
final TranscoderOutput transcoderOutput = new TranscoderOutput(bufferedOut);
|
|
||||||
|
|
||||||
final PNGTranscoder transcoder = new PNGTranscoder();
|
|
||||||
transcoder.transcode(transcoderInput, transcoderOutput);
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
logger.error(e.getMessage(), e);
|
logger.error(e.getMessage(), e);
|
||||||
|
|
||||||
|
@ -109,9 +87,7 @@ public class ConvertSvg extends HttpServlet {
|
||||||
|
|
||||||
// write the response message
|
// write the response message
|
||||||
PrintWriter out = response.getWriter();
|
PrintWriter out = response.getWriter();
|
||||||
out.println("Unable to export image as a PNG.");
|
out.println("Unable to export image as a SVG.");
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(bufferedOut);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,7 +15,9 @@
|
||||||
-->
|
-->
|
||||||
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
||||||
<display-name>nifi</display-name>
|
<display-name>nifi</display-name>
|
||||||
|
|
||||||
<!-- servlet to map to canvas page -->
|
<!-- servlet to map to canvas page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>NiFiCanvas</servlet-name>
|
<servlet-name>NiFiCanvas</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/canvas.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/canvas.jsp</jsp-file>
|
||||||
|
@ -24,7 +26,9 @@
|
||||||
<servlet-name>NiFiCanvas</servlet-name>
|
<servlet-name>NiFiCanvas</servlet-name>
|
||||||
<url-pattern>/canvas</url-pattern>
|
<url-pattern>/canvas</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to map to summary page -->
|
<!-- servlet to map to summary page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>NiFiSummary</servlet-name>
|
<servlet-name>NiFiSummary</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/summary.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/summary.jsp</jsp-file>
|
||||||
|
@ -33,7 +37,9 @@
|
||||||
<servlet-name>NiFiSummary</servlet-name>
|
<servlet-name>NiFiSummary</servlet-name>
|
||||||
<url-pattern>/summary</url-pattern>
|
<url-pattern>/summary</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to map to history page -->
|
<!-- servlet to map to history page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>NiFiHistory</servlet-name>
|
<servlet-name>NiFiHistory</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/history.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/history.jsp</jsp-file>
|
||||||
|
@ -42,7 +48,9 @@
|
||||||
<servlet-name>NiFiHistory</servlet-name>
|
<servlet-name>NiFiHistory</servlet-name>
|
||||||
<url-pattern>/history</url-pattern>
|
<url-pattern>/history</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to map to provenance page -->
|
<!-- servlet to map to provenance page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>NiFiProvenance</servlet-name>
|
<servlet-name>NiFiProvenance</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/provenance.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/provenance.jsp</jsp-file>
|
||||||
|
@ -51,7 +59,9 @@
|
||||||
<servlet-name>NiFiProvenance</servlet-name>
|
<servlet-name>NiFiProvenance</servlet-name>
|
||||||
<url-pattern>/provenance</url-pattern>
|
<url-pattern>/provenance</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to map to counters page -->
|
<!-- servlet to map to counters page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>NiFiCounters</servlet-name>
|
<servlet-name>NiFiCounters</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/counters.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/counters.jsp</jsp-file>
|
||||||
|
@ -60,7 +70,9 @@
|
||||||
<servlet-name>NiFiCounters</servlet-name>
|
<servlet-name>NiFiCounters</servlet-name>
|
||||||
<url-pattern>/counters</url-pattern>
|
<url-pattern>/counters</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to map to templates page -->
|
<!-- servlet to map to templates page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>NiFiTemplates</servlet-name>
|
<servlet-name>NiFiTemplates</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/templates.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/templates.jsp</jsp-file>
|
||||||
|
@ -69,7 +81,9 @@
|
||||||
<servlet-name>NiFiTemplates</servlet-name>
|
<servlet-name>NiFiTemplates</servlet-name>
|
||||||
<url-pattern>/templates</url-pattern>
|
<url-pattern>/templates</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to map to users page -->
|
<!-- servlet to map to users page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>NiFiUsers</servlet-name>
|
<servlet-name>NiFiUsers</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/users.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/users.jsp</jsp-file>
|
||||||
|
@ -78,7 +92,9 @@
|
||||||
<servlet-name>NiFiUsers</servlet-name>
|
<servlet-name>NiFiUsers</servlet-name>
|
||||||
<url-pattern>/users</url-pattern>
|
<url-pattern>/users</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to map to cluster page -->
|
<!-- servlet to map to cluster page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>NiFiCluster</servlet-name>
|
<servlet-name>NiFiCluster</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/cluster.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/cluster.jsp</jsp-file>
|
||||||
|
@ -87,7 +103,9 @@
|
||||||
<servlet-name>NiFiCluster</servlet-name>
|
<servlet-name>NiFiCluster</servlet-name>
|
||||||
<url-pattern>/cluster</url-pattern>
|
<url-pattern>/cluster</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to map to bulletin board page -->
|
<!-- servlet to map to bulletin board page -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>BulletinBoard</servlet-name>
|
<servlet-name>BulletinBoard</servlet-name>
|
||||||
<jsp-file>/WEB-INF/pages/bulletin-board.jsp</jsp-file>
|
<jsp-file>/WEB-INF/pages/bulletin-board.jsp</jsp-file>
|
||||||
|
@ -96,15 +114,18 @@
|
||||||
<servlet-name>BulletinBoard</servlet-name>
|
<servlet-name>BulletinBoard</servlet-name>
|
||||||
<url-pattern>/bulletin-board</url-pattern>
|
<url-pattern>/bulletin-board</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to support image downloading -->
|
<!-- servlet to support image downloading -->
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>ConvertSvg</servlet-name>
|
<servlet-name>DownloadSvg</servlet-name>
|
||||||
<servlet-class>org.apache.nifi.web.servlet.ConvertSvg</servlet-class>
|
<servlet-class>org.apache.nifi.web.servlet.DownloadSvg</servlet-class>
|
||||||
</servlet>
|
</servlet>
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>ConvertSvg</servlet-name>
|
<servlet-name>DownloadSvg</servlet-name>
|
||||||
<url-pattern>/convert-svg</url-pattern>
|
<url-pattern>/download-svg</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<filter>
|
<filter>
|
||||||
<filter-name>IeEdgeHeader</filter-name>
|
<filter-name>IeEdgeHeader</filter-name>
|
||||||
<filter-class>org.apache.nifi.web.filter.IeEdgeHeader</filter-class>
|
<filter-class>org.apache.nifi.web.filter.IeEdgeHeader</filter-class>
|
||||||
|
@ -113,6 +134,7 @@
|
||||||
<filter-name>IeEdgeHeader</filter-name>
|
<filter-name>IeEdgeHeader</filter-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</filter-mapping>
|
</filter-mapping>
|
||||||
|
|
||||||
<welcome-file-list>
|
<welcome-file-list>
|
||||||
<welcome-file>canvas.jsp</welcome-file>
|
<welcome-file>canvas.jsp</welcome-file>
|
||||||
<welcome-file>/WEB-INF/pages/canvas.jsp</welcome-file>
|
<welcome-file>/WEB-INF/pages/canvas.jsp</welcome-file>
|
||||||
|
|
|
@ -531,6 +531,10 @@ nf.ProvenanceLineage = (function () {
|
||||||
var svg = d3.select('#provenance-lineage-container').append('svg:svg')
|
var svg = d3.select('#provenance-lineage-container').append('svg:svg')
|
||||||
.attr('width', width)
|
.attr('width', width)
|
||||||
.attr('height', height)
|
.attr('height', height)
|
||||||
|
.style({
|
||||||
|
'font-family': 'Verdana, Arial, sans-serif',
|
||||||
|
'font-size': '10px'
|
||||||
|
})
|
||||||
.call(lineageZoom)
|
.call(lineageZoom)
|
||||||
.on('dblclick.zoom', null)
|
.on('dblclick.zoom', null)
|
||||||
.on('mousedown', function (d) {
|
.on('mousedown', function (d) {
|
||||||
|
@ -1276,7 +1280,14 @@ nf.ProvenanceLineage = (function () {
|
||||||
return '<g' + before + 'transform="translate(' + x + ',' + y + ')"' + after + '>';
|
return '<g' + before + 'transform="translate(' + x + ',' + y + ')"' + after + '>';
|
||||||
});
|
});
|
||||||
|
|
||||||
nf.Common.submit('POST', './convert-svg', {
|
// 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.submit('POST', './download-svg', {
|
||||||
'filename': 'provenance',
|
'filename': 'provenance',
|
||||||
'svg': encodeURIComponent(svg)
|
'svg': encodeURIComponent(svg)
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue