mirror of https://github.com/apache/nifi.git
NIFI-2182:
- Ensuring the active thread count is shown. NIFI-2019: - Ensuring correct color of the run status in the From connection label. NIFI-2183: - Removing the DownloadSvg servlet and hidding the download icon until we're able to support save the svg entirely from the client side. This closes #634.
This commit is contained in:
parent
8ab9fca7f8
commit
1e1630cc69
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*/
|
||||
package org.apache.nifi.web.servlet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DownloadSvg extends HttpServlet {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DownloadSvg.class);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param request servlet request
|
||||
* @param response servlet response
|
||||
* @throws ServletException if a servlet-specific error occurs
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
final String svg = request.getParameter("svg");
|
||||
|
||||
// ensure the image markup has been included
|
||||
if (svg == null) {
|
||||
// set the response status
|
||||
response.setContentType("text/plain");
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
|
||||
// write the response message
|
||||
PrintWriter out = response.getWriter();
|
||||
out.println("SVG must be specified.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(svg);
|
||||
}
|
||||
|
||||
String filename = request.getParameter("filename");
|
||||
if (filename == null) {
|
||||
filename = "image.svg";
|
||||
} else if (!filename.endsWith(".svg")) {
|
||||
filename += ".svg";
|
||||
}
|
||||
|
||||
response.setContentType("image/svg+xml");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
|
||||
response.getWriter().print(svg);
|
||||
} catch (final Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
|
||||
// set the response status
|
||||
response.setContentType("text/plain");
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
|
||||
// write the response message
|
||||
PrintWriter out = response.getWriter();
|
||||
out.println("Unable to export image as a SVG.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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" title="Download"></div>
|
||||
<div id="provenance-lineage-downloader" class="hidden" title="Download"></div>
|
||||
<div id="provenance-lineage-closer" title="Close"></div>
|
||||
</div>
|
||||
<div id="provenance-lineage-context-menu"></div>
|
||||
|
|
|
@ -116,16 +116,6 @@
|
|||
<url-pattern>/message</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- servlet to support image downloading -->
|
||||
<servlet>
|
||||
<servlet-name>DownloadSvg</servlet-name>
|
||||
<servlet-class>org.apache.nifi.web.servlet.DownloadSvg</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>DownloadSvg</servlet-name>
|
||||
<url-pattern>/download-svg</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- servlet to login page -->
|
||||
<servlet>
|
||||
<servlet-name>Login</servlet-name>
|
||||
|
|
|
@ -427,11 +427,11 @@ nf.CanvasUtils = (function () {
|
|||
*/
|
||||
activeThreadCount: function (selection, d, setOffset) {
|
||||
// if there is active threads show the count, otherwise hide
|
||||
if (nf.Common.isDefinedAndNotNull(d.status) && d.status.activeThreadCount > 0) {
|
||||
if (nf.Common.isDefinedAndNotNull(d.status) && d.status.aggregateSnapshot.activeThreadCount > 0) {
|
||||
// update the active thread count
|
||||
var activeThreadCount = selection.select('text.active-thread-count')
|
||||
.text(function () {
|
||||
return d.status.activeThreadCount;
|
||||
return d.status.aggregateSnapshot.activeThreadCount;
|
||||
})
|
||||
.style('display', 'block')
|
||||
.each(function () {
|
||||
|
|
|
@ -787,7 +787,7 @@ nf.Connection = (function () {
|
|||
}
|
||||
})
|
||||
.classed('is-missing-port', function () {
|
||||
return d.component.source.exists === true;
|
||||
return d.component.source.exists === false;
|
||||
});
|
||||
} else {
|
||||
// there is no connection from, but check if the name was previous
|
||||
|
|
|
@ -250,7 +250,7 @@ nf.Port = (function () {
|
|||
details.append('text')
|
||||
.attr({
|
||||
'class': 'active-thread-count-icon',
|
||||
'y': 68
|
||||
'y': 43 + offset
|
||||
})
|
||||
.text('\ue83f');
|
||||
|
||||
|
@ -258,7 +258,7 @@ nf.Port = (function () {
|
|||
details.append('text')
|
||||
.attr({
|
||||
'class': 'active-thread-count',
|
||||
'y': 68
|
||||
'y': 43 + offset
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -724,41 +724,6 @@ nf.Common = (function () {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a form inline in order to submit the specified params to the specified URL
|
||||
* using the specified method.
|
||||
*
|
||||
* @param {string} url The URL
|
||||
* @param {object} params An object with the params to include in the submission
|
||||
*/
|
||||
post: function (url, params) {
|
||||
// temporarily override beforeunload
|
||||
var previousBeforeUnload = window.onbeforeunload;
|
||||
window.onbeforeunload = null;
|
||||
|
||||
// create a form for submission
|
||||
var form = $('<form></form>').attr({
|
||||
'method': 'POST',
|
||||
'action': url,
|
||||
'style': 'display: none;'
|
||||
});
|
||||
|
||||
// add each parameter when specified
|
||||
if (nf.Common.isDefinedAndNotNull(params)) {
|
||||
$.each(params, function (name, value) {
|
||||
$('<textarea></textarea>').attr('name', name).val(value).appendTo(form);
|
||||
});
|
||||
}
|
||||
|
||||
// submit the form and clean up
|
||||
form.appendTo('body').submit().remove();
|
||||
|
||||
// restore previous beforeunload if necessary
|
||||
if (previousBeforeUnload !== null) {
|
||||
window.onbeforeunload = previousBeforeUnload;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Formats the specified array as an unordered list. If the array is not an
|
||||
* array, null is returned.
|
||||
|
|
|
@ -1237,67 +1237,69 @@ nf.ProvenanceLineage = (function () {
|
|||
$('#provenance-event-search').show();
|
||||
$('#provenance-lineage').hide();
|
||||
});
|
||||
$('#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
|
||||
});
|
||||
});
|
||||
// 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
|
||||
// });
|
||||
// });
|
||||
|
||||
initLineageQueryDialog();
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue