You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2017/01/20 21:19:38 UTC
[05/12] nifi git commit: [NIFI-3359] Modularize all of nifi-web-ui
except canvas directory - Removing shell.jsp from summary.jsp. - This closes
#1428
http://git-wip-us.apache.org/repos/asf/nifi/blob/dc934cbb/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 d20737c..ddada58 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
@@ -15,1383 +15,1416 @@
* limitations under the License.
*/
-/* global nf, d3 */
-
-nf.ng.ProvenanceLineage = function () {
+/* global nf, top, define, module, require, exports */
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery',
+ 'd3',
+ 'nf.Common',
+ 'nf.Dialog',
+ 'nf.ErrorHandler'],
+ function ($, d3, common, dialog, errorHandler) {
+ return (nf.ng.ProvenanceLineage = factory($, d3, common, dialog, errorHandler));
+ });
+ } else if (typeof exports === 'object' && typeof module === 'object') {
+ module.exports = (nf.ng.ProvenanceLineage =
+ factory(require('jquery'),
+ require('d3'),
+ require('nf.Common'),
+ require('nf.Dialog'),
+ require('nf.ErrorHandler')));
+ } else {
+ nf.ng.ProvenanceLineage = factory(root.$,
+ root.d3,
+ root.nf.Common,
+ root.nf.Dialog,
+ root.nf.ErrorHandler);
+ }
+}(this, function ($, d3, common, dialog, errorHandler) {
'use strict';
- /**
- * Configuration object used to hold a number of configuration items.
- */
- var config = {
- sliderTickCount: 75,
- urls: {
- lineage: '../nifi-api/provenance/lineage'
- }
- };
+ var mySelf = function () {
+ 'use strict';
- /**
- * Initializes the lineage query dialog.
- */
- var initLineageQueryDialog = function () {
- // initialize the dialog
- $('#lineage-query-dialog').modal({
- scrollableContentStyle: 'scrollable',
- headerText: 'Computing FlowFile lineage...'
- });
- };
+ /**
+ * Configuration object used to hold a number of configuration items.
+ */
+ var config = {
+ sliderTickCount: 75,
+ urls: {
+ lineage: '../nifi-api/provenance/lineage'
+
+ }
+ };
+
+ /**
+ * Initializes the lineage query dialog.
+ */
+ var initLineageQueryDialog = function () {
+ // initialize the dialog
+ $('#lineage-query-dialog').modal({
+ scrollableContentStyle: 'scrollable',
+ headerText: 'Computing FlowFile lineage...'
+ });
+ };
- var downloadSvgFile = function(svgString){
- var link = document.getElementById("image-download-link");
- var downloadSupported = typeof link.download != 'undefined';
- var fileName ='lineage.svg';
+ 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 (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);
+ if (window.navigator.msSaveOrOpenBlob) {
+ window.navigator.msSaveOrOpenBlob(svg, fileName);
+ } else {
+ var url = DOMURL.createObjectURL(svg);
+ link.href = url;
+ link.download = fileName;
+ link.click();
+ }
} else {
- var url = DOMURL.createObjectURL(svg);
- link.href = url;
- link.download = fileName;
- link.click();
+ window.open('data:image/svg+xml;charset=utf-8,' + encodeURI(svgString));
}
- } else {
- window.open('data:image/svg+xml;charset=utf-8,' + encodeURI(svgString));
- }
- };
+ };
- /**
- * Appends the items to the context menu.
- *
- * items = [{class: ..., text: ..., click: function() {...}}, ...]
- *
- * @param {array} items
- */
- var addContextMenuItems = function (items) {
- var contextMenu = $('#provenance-lineage-context-menu');
-
- $.each(items, function (_, item) {
- if (typeof item.click === 'function') {
- var menuItem = $('<div class="context-menu-item"></div>').on('click', item.click).on('mouseenter', function () {
- $(this).addClass('hover');
- }).on('mouseleave', function () {
- $(this).removeClass('hover');
- }).appendTo(contextMenu);
-
- // add the img and the text
- $('<div class="context-menu-item-img"></div>').addClass(item['class']).appendTo(menuItem);
- $('<div class="context-menu-item-text"></div>').text(item['text']).appendTo(menuItem);
- $('<div class="clear"></div>').appendTo(menuItem);
- }
- });
- };
+ /**
+ * Appends the items to the context menu.
+ *
+ * items = [{class: ..., text: ..., click: function() {...}}, ...]
+ *
+ * @param {array} items
+ */
+ var addContextMenuItems = function (items) {
+ var contextMenu = $('#provenance-lineage-context-menu');
+
+ $.each(items, function (_, item) {
+ if (typeof item.click === 'function') {
+ var menuItem = $('<div class="context-menu-item"></div>').on('click', item.click).on('mouseenter', function () {
+ $(this).addClass('hover');
+ }).on('mouseleave', function () {
+ $(this).removeClass('hover');
+ }).appendTo(contextMenu);
+
+ // add the img and the text
+ $('<div class="context-menu-item-img"></div>').addClass(item['class']).appendTo(menuItem);
+ $('<div class="context-menu-item-text"></div>').text(item['text']).appendTo(menuItem);
+ $('<div class="clear"></div>').appendTo(menuItem);
+ }
+ });
+ };
+
+ /**
+ * Submits the specified lineage request.
+ *
+ * @param {type} lineageRequest
+ * @returns {deferred}
+ */
+ var submitLineage = function (lineageRequest) {
+ var lineageEntity = {
+ 'lineage': {
+ 'request': lineageRequest
+ }
+ };
+
+ return $.ajax({
+ type: 'POST',
+ url: config.urls.lineage,
+ data: JSON.stringify(lineageEntity),
+ dataType: 'json',
+ contentType: 'application/json'
+ }).fail(errorHandler.handleAjaxError);
+ };
- /**
- * Submits the specified lineage request.
- *
- * @param {type} lineageRequest
- * @returns {deferred}
- */
- var submitLineage = function (lineageRequest) {
- var lineageEntity = {
- 'lineage': {
- 'request': lineageRequest
+ /**
+ * Gets the specified lineage.
+ *
+ * @param {type} lineage
+ * @returns {deferred}
+ */
+ var getLineage = function (lineage) {
+ var url = lineage.uri;
+ if (common.isDefinedAndNotNull(lineage.request.clusterNodeId)) {
+ url += '?' + $.param({
+ clusterNodeId: lineage.request.clusterNodeId
+ });
}
+
+ return $.ajax({
+ type: 'GET',
+ url: url,
+ dataType: 'json'
+ }).fail(errorHandler.handleAjaxError);
};
- return $.ajax({
- type: 'POST',
- url: config.urls.lineage,
- data: JSON.stringify(lineageEntity),
- dataType: 'json',
- contentType: 'application/json'
- }).fail(nf.Common.handleAjaxError);
- };
+ /**
+ * Cancels the specified lineage.
+ *
+ * @param {type} lineage
+ * @returns {deferred}
+ */
+ var cancelLineage = function (lineage) {
+ var url = lineage.uri;
+ if (common.isDefinedAndNotNull(lineage.request.clusterNodeId)) {
+ url += '?' + $.param({
+ clusterNodeId: lineage.request.clusterNodeId
+ });
+ }
- /**
- * Gets the specified lineage.
- *
- * @param {type} lineage
- * @returns {deferred}
- */
- var getLineage = function (lineage) {
- var url = lineage.uri;
- if (nf.Common.isDefinedAndNotNull(lineage.request.clusterNodeId)) {
- url += '?' + $.param({
- clusterNodeId: lineage.request.clusterNodeId
- });
- }
+ return $.ajax({
+ type: 'DELETE',
+ url: url,
+ dataType: 'json'
+ }).fail(errorHandler.handleAjaxError);
+ };
- return $.ajax({
- type: 'GET',
- url: url,
- dataType: 'json'
- }).fail(nf.Common.handleAjaxError);
- };
+ var DEFAULT_NODE_SPACING = 100;
+ var DEFAULT_LEVEL_DIFFERENCE = 120;
- /**
- * Cancels the specified lineage.
- *
- * @param {type} lineage
- * @returns {deferred}
- */
- var cancelLineage = function (lineage) {
- var url = lineage.uri;
- if (nf.Common.isDefinedAndNotNull(lineage.request.clusterNodeId)) {
- url += '?' + $.param({
- clusterNodeId: lineage.request.clusterNodeId
- });
- }
+ /**
+ * Renders the lineage in the specified results.
+ *
+ * @param {object} lineageResults
+ * @param {integer} eventId
+ * @param {string} clusterNodeId The id of the node in the cluster where this event/flowfile originated
+ */
+ var renderLineage = function (lineageResults, eventId, clusterNodeId, provenanceTableCtrl) {
+ // get the container
+ var lineageContainer = $('#provenance-lineage');
+ var width = lineageContainer.width();
+ var height = lineageContainer.height();
+
+ // record the min/max event time
+ var minMillis;
+ var minTimestamp;
+ var maxMillis;
+
+ // data lookups
+ var nodeLookup = d3.map();
+ var linkLookup = d3.map();
+
+ var locateDescendants = function (nodeIds, descendants, depth) {
+ $.each(nodeIds, function (_, nodeId) {
+ var node = nodeLookup.get(nodeId);
- return $.ajax({
- type: 'DELETE',
- url: url,
- dataType: 'json'
- }).fail(nf.Common.handleAjaxError);
- };
+ var children = [];
+ $.each(node.outgoing, function (_, link) {
+ children.push(link.target.id);
+ descendants.add(link.target.id);
+ });
- var DEFAULT_NODE_SPACING = 100;
- var DEFAULT_LEVEL_DIFFERENCE = 120;
-
- /**
- * Renders the lineage in the specified results.
- *
- * @param {object} lineageResults
- * @param {integer} eventId
- * @param {string} clusterNodeId The id of the node in the cluster where this event/flowfile originated
- */
- var renderLineage = function (lineageResults, eventId, clusterNodeId, provenanceTableCtrl) {
- // get the container
- var lineageContainer = $('#provenance-lineage');
- var width = lineageContainer.width();
- var height = lineageContainer.height();
-
- // record the min/max event time
- var minMillis;
- var minTimestamp;
- var maxMillis;
-
- // data lookups
- var nodeLookup = d3.map();
- var linkLookup = d3.map();
-
- var locateDescendants = function (nodeIds, descendants, depth) {
- $.each(nodeIds, function (_, nodeId) {
- var node = nodeLookup.get(nodeId);
-
- var children = [];
- $.each(node.outgoing, function (_, link) {
- children.push(link.target.id);
- descendants.add(link.target.id);
+ if (common.isUndefined(depth)) {
+ locateDescendants(children, descendants);
+ } else if (depth > 1) {
+ locateDescendants(children, descendants, depth - 1);
+ }
});
+ };
- if (nf.Common.isUndefined(depth)) {
- locateDescendants(children, descendants);
- } else if (depth > 1) {
- locateDescendants(children, descendants, depth - 1);
- }
- });
- };
+ var positionNodes = function (nodeIds, depth, parents, levelDifference) {
+ var immediateSet = d3.set(nodeIds);
+ var childSet = d3.set();
+ var descendantSet = d3.set();
- var positionNodes = function (nodeIds, depth, parents, levelDifference) {
- var immediateSet = d3.set(nodeIds);
- var childSet = d3.set();
- var descendantSet = d3.set();
+ // locate children
+ locateDescendants(nodeIds, childSet, 1);
- // locate children
- locateDescendants(nodeIds, childSet, 1);
+ // locate all descendants (including children)
+ locateDescendants(nodeIds, descendantSet);
- // locate all descendants (including children)
- locateDescendants(nodeIds, descendantSet);
+ // push off processing a node until its deepest point
+ // by removing any descendants from the immediate nodes.
+ // in this case, a link is panning multiple levels
+ descendantSet.forEach(function (d) {
+ immediateSet.remove(d);
+ });
- // push off processing a node until its deepest point
- // by removing any descendants from the immediate nodes.
- // in this case, a link is panning multiple levels
- descendantSet.forEach(function (d) {
- immediateSet.remove(d);
- });
+ // convert the children to an array to ensure consistent
+ // order when performing index of checks below
+ var children = childSet.values().sort(d3.descending);
- // convert the children to an array to ensure consistent
- // order when performing index of checks below
- var children = childSet.values().sort(d3.descending);
+ // convert the immediate to allow for sorting below
+ var immediate = immediateSet.values();
- // convert the immediate to allow for sorting below
- var immediate = immediateSet.values();
+ // attempt to identify fan in/out cases
+ var nodesWithTwoParents = 0;
+ $.each(immediate, function (_, nodeId) {
+ var node = nodeLookup.get(nodeId);
- // attempt to identify fan in/out cases
- var nodesWithTwoParents = 0;
- $.each(immediate, function (_, nodeId) {
- var node = nodeLookup.get(nodeId);
+ // identify fanning cases
+ if (node.incoming.length > 3) {
+ levelDifference = DEFAULT_LEVEL_DIFFERENCE;
+ } else if (node.incoming.length >= 2) {
+ nodesWithTwoParents++;
+ }
+ });
- // identify fanning cases
- if (node.incoming.length > 3) {
+ // increate the level difference if more than two nodes have two or more parents
+ if (nodesWithTwoParents > 2) {
levelDifference = DEFAULT_LEVEL_DIFFERENCE;
- } else if (node.incoming.length >= 2) {
- nodesWithTwoParents++;
}
- });
- // increate the level difference if more than two nodes have two or more parents
- if (nodesWithTwoParents > 2) {
- levelDifference = DEFAULT_LEVEL_DIFFERENCE;
- }
-
- // attempt to sort the nodes to provide an optimum layout
- if (parents.length === 1) {
- immediate = immediate.sort(function (one, two) {
- var oneNode = nodeLookup.get(one);
- var twoNode = nodeLookup.get(two);
-
- // try to order by children
- if (oneNode.outgoing.length > 0 && twoNode.outgoing.length > 0) {
- var oneIndex = children.indexOf(oneNode.outgoing[0].target.id);
- var twoIndex = children.indexOf(twoNode.outgoing[0].target.id);
- if (oneIndex !== twoIndex) {
- return oneIndex - twoIndex;
+ // attempt to sort the nodes to provide an optimum layout
+ if (parents.length === 1) {
+ immediate = immediate.sort(function (one, two) {
+ var oneNode = nodeLookup.get(one);
+ var twoNode = nodeLookup.get(two);
+
+ // try to order by children
+ if (oneNode.outgoing.length > 0 && twoNode.outgoing.length > 0) {
+ var oneIndex = children.indexOf(oneNode.outgoing[0].target.id);
+ var twoIndex = children.indexOf(twoNode.outgoing[0].target.id);
+ if (oneIndex !== twoIndex) {
+ return oneIndex - twoIndex;
+ }
}
- }
- // try to order by parents
- if (oneNode.incoming.length > 0 && twoNode.incoming.length > 0) {
- var oneIndex = oneNode.incoming[0].source.index;
- var twoIndex = twoNode.incoming[0].source.index;
- if (oneIndex !== twoIndex) {
- return oneIndex - twoIndex;
+ // try to order by parents
+ if (oneNode.incoming.length > 0 && twoNode.incoming.length > 0) {
+ var oneIndex = oneNode.incoming[0].source.index;
+ var twoIndex = twoNode.incoming[0].source.index;
+ if (oneIndex !== twoIndex) {
+ return oneIndex - twoIndex;
+ }
}
- }
- // type of node
- if (oneNode.type !== twoNode.type) {
- return oneNode.type > twoNode.type ? 1 : -1;
- }
-
- // type of event
- if (oneNode.eventType !== twoNode.eventType) {
- return oneNode.eventType > twoNode.eventType ? 1 : -1;
- }
+ // type of node
+ if (oneNode.type !== twoNode.type) {
+ return oneNode.type > twoNode.type ? 1 : -1;
+ }
- // timestamp
- return oneNode.millis - twoNode.millis;
- });
- } else if (parents.length > 1) {
- immediate = immediate.sort(function (one, two) {
- var oneNode = nodeLookup.get(one);
- var twoNode = nodeLookup.get(two);
-
- // try to order by parents
- if (oneNode.incoming.length > 0 && twoNode.incoming.length > 0) {
- var oneIndex = oneNode.incoming[0].source.index;
- var twoIndex = twoNode.incoming[0].source.index;
- if (oneIndex !== twoIndex) {
- return oneIndex - twoIndex;
+ // type of event
+ if (oneNode.eventType !== twoNode.eventType) {
+ return oneNode.eventType > twoNode.eventType ? 1 : -1;
}
- }
- // try to order by children
- if (oneNode.outgoing.length > 0 && twoNode.outgoing.length > 0) {
- var oneIndex = children.indexOf(oneNode.outgoing[0].target.id);
- var twoIndex = children.indexOf(twoNode.outgoing[0].target.id);
- if (oneIndex !== twoIndex) {
- return oneIndex - twoIndex;
+ // timestamp
+ return oneNode.millis - twoNode.millis;
+ });
+ } else if (parents.length > 1) {
+ immediate = immediate.sort(function (one, two) {
+ var oneNode = nodeLookup.get(one);
+ var twoNode = nodeLookup.get(two);
+
+ // try to order by parents
+ if (oneNode.incoming.length > 0 && twoNode.incoming.length > 0) {
+ var oneIndex = oneNode.incoming[0].source.index;
+ var twoIndex = twoNode.incoming[0].source.index;
+ if (oneIndex !== twoIndex) {
+ return oneIndex - twoIndex;
+ }
}
- }
- // node type
- if (oneNode.type !== twoNode.type) {
- return oneNode.type > twoNode.type ? 1 : -1;
- }
+ // try to order by children
+ if (oneNode.outgoing.length > 0 && twoNode.outgoing.length > 0) {
+ var oneIndex = children.indexOf(oneNode.outgoing[0].target.id);
+ var twoIndex = children.indexOf(twoNode.outgoing[0].target.id);
+ if (oneIndex !== twoIndex) {
+ return oneIndex - twoIndex;
+ }
+ }
- // event type
- if (oneNode.eventType !== twoNode.eventType) {
- return oneNode.eventType > twoNode.eventType ? 1 : -1;
- }
+ // node type
+ if (oneNode.type !== twoNode.type) {
+ return oneNode.type > twoNode.type ? 1 : -1;
+ }
- // timestamp
- return oneNode.millis - twoNode.millis;
- });
- }
+ // event type
+ if (oneNode.eventType !== twoNode.eventType) {
+ return oneNode.eventType > twoNode.eventType ? 1 : -1;
+ }
- var originX = width / 2;
- if (parents.length > 0) {
- originX = d3.mean(parents, function (parentId) {
- var parent = nodeLookup.get(parentId);
- return parent.x;
- });
- }
+ // timestamp
+ return oneNode.millis - twoNode.millis;
+ });
+ }
- var depthWidth = (immediate.length - 1) * DEFAULT_NODE_SPACING;
- $.each(immediate, function (i, nodeId) {
- var node = nodeLookup.get(nodeId);
+ var originX = width / 2;
+ if (parents.length > 0) {
+ originX = d3.mean(parents, function (parentId) {
+ var parent = nodeLookup.get(parentId);
+ return parent.x;
+ });
+ }
- // set the y position based on the depth
- node.y = levelDifference + depth - 25;
+ var depthWidth = (immediate.length - 1) * DEFAULT_NODE_SPACING;
+ $.each(immediate, function (i, nodeId) {
+ var node = nodeLookup.get(nodeId);
- // ensure the children won't position on top of one another
- // based on the number of parent nodes
- if (immediate.length <= parents.length) {
- if (node.incoming.length === 1) {
- var parent = node.incoming[0].source;
- if (parent.outgoing.length === 1) {
- node.x = parent.x;
+ // set the y position based on the depth
+ node.y = levelDifference + depth - 25;
+
+ // ensure the children won't position on top of one another
+ // based on the number of parent nodes
+ if (immediate.length <= parents.length) {
+ if (node.incoming.length === 1) {
+ var parent = node.incoming[0].source;
+ if (parent.outgoing.length === 1) {
+ node.x = parent.x;
+ return;
+ }
+ } else if (node.incoming.length > 1) {
+ var nodesOnPreviousLevel = $.grep(node.incoming, function (link) {
+ return (node.y - link.source.y) <= DEFAULT_LEVEL_DIFFERENCE;
+ });
+ node.x = d3.mean(nodesOnPreviousLevel, function (link) {
+ return link.source.x;
+ });
return;
}
- } else if (node.incoming.length > 1) {
- var nodesOnPreviousLevel = $.grep(node.incoming, function (link) {
- return (node.y - link.source.y) <= DEFAULT_LEVEL_DIFFERENCE;
- });
- node.x = d3.mean(nodesOnPreviousLevel, function (link) {
- return link.source.x;
- });
- return;
}
- }
- // evenly space the nodes under the origin
- node.x = (i * DEFAULT_NODE_SPACING) + originX - (depthWidth / 2);
- });
+ // evenly space the nodes under the origin
+ node.x = (i * DEFAULT_NODE_SPACING) + originX - (depthWidth / 2);
+ });
- // sort the immediate nodes after positioning by the x coordinate
- // so they can be shifted accordingly if necessary
- var sortedImmediate = immediate.slice().sort(function (one, two) {
- var nodeOne = nodeLookup.get(one);
- var nodeTwo = nodeLookup.get(two);
- return nodeOne.x - nodeTwo.x;
- });
+ // sort the immediate nodes after positioning by the x coordinate
+ // so they can be shifted accordingly if necessary
+ var sortedImmediate = immediate.slice().sort(function (one, two) {
+ var nodeOne = nodeLookup.get(one);
+ var nodeTwo = nodeLookup.get(two);
+ return nodeOne.x - nodeTwo.x;
+ });
- // adjust the x positioning if necessary to avoid positioning on top
- // of one another, only need to consider the x coordinate since the
- // y coordinate will be the same for each node on this row
- for (var i = 0; i < sortedImmediate.length - 1; i++) {
- var first = nodeLookup.get(sortedImmediate[i]);
- var second = nodeLookup.get(sortedImmediate[i + 1]);
- var difference = second.x - first.x;
+ // adjust the x positioning if necessary to avoid positioning on top
+ // of one another, only need to consider the x coordinate since the
+ // y coordinate will be the same for each node on this row
+ for (var i = 0; i < sortedImmediate.length - 1; i++) {
+ var first = nodeLookup.get(sortedImmediate[i]);
+ var second = nodeLookup.get(sortedImmediate[i + 1]);
+ var difference = second.x - first.x;
- if (difference < DEFAULT_NODE_SPACING) {
- second.x += (DEFAULT_NODE_SPACING - difference);
+ if (difference < DEFAULT_NODE_SPACING) {
+ second.x += (DEFAULT_NODE_SPACING - difference);
+ }
}
- }
- // if there are children to position
- if (children.length > 0) {
- var childLevelDifference = DEFAULT_LEVEL_DIFFERENCE / 3;
+ // if there are children to position
+ if (children.length > 0) {
+ var childLevelDifference = DEFAULT_LEVEL_DIFFERENCE / 3;
- // resort the immediate values after each node has been positioned
- immediate = immediate.sort(function (one, two) {
- var oneNode = nodeLookup.get(one);
- var twoNode = nodeLookup.get(two);
- return oneNode.x - twoNode.x;
- });
+ // resort the immediate values after each node has been positioned
+ immediate = immediate.sort(function (one, two) {
+ var oneNode = nodeLookup.get(one);
+ var twoNode = nodeLookup.get(two);
+ return oneNode.x - twoNode.x;
+ });
- // mark each nodes index so subsequent recursive calls can position children accordingly
- var nodesWithTwoChildren = 0;
- $.each(immediate, function (i, nodeId) {
- var node = nodeLookup.get(nodeId);
- node.index = i;
+ // mark each nodes index so subsequent recursive calls can position children accordingly
+ var nodesWithTwoChildren = 0;
+ $.each(immediate, function (i, nodeId) {
+ var node = nodeLookup.get(nodeId);
+ node.index = i;
+
+ // precompute the next level difference since we have easy access to going here
+ if (node.outgoing.length > 3) {
+ childLevelDifference = DEFAULT_LEVEL_DIFFERENCE;
+ } else if (node.outgoing.length >= 2) {
+ nodesWithTwoChildren++;
+ }
+ });
- // precompute the next level difference since we have easy access to going here
- if (node.outgoing.length > 3) {
+ // if there are at least two immediate nodes with two or more children, increase the level difference
+ if (nodesWithTwoChildren > 2) {
childLevelDifference = DEFAULT_LEVEL_DIFFERENCE;
- } else if (node.outgoing.length >= 2) {
- nodesWithTwoChildren++;
}
- });
- // if there are at least two immediate nodes with two or more children, increase the level difference
- if (nodesWithTwoChildren > 2) {
- childLevelDifference = DEFAULT_LEVEL_DIFFERENCE;
+ // position the children
+ positionNodes(children, levelDifference + depth, immediate, childLevelDifference);
}
+ };
- // position the children
- positionNodes(children, levelDifference + depth, immediate, childLevelDifference);
- }
- };
+ var addLineage = function (nodes, links, provenanceTableCtrl) {
+ // add the new nodes
+ $.each(nodes, function (_, node) {
+ if (nodeLookup.has(node.id)) {
+ return;
+ }
- var addLineage = function (nodes, links, provenanceTableCtrl) {
- // add the new nodes
- $.each(nodes, function (_, node) {
- if (nodeLookup.has(node.id)) {
- return;
- }
+ // add values to the node to support rendering
+ $.extend(node, {
+ x: 0,
+ y: 0,
+ visible: true
+ });
- // add values to the node to support rendering
- $.extend(node, {
- x: 0,
- y: 0,
- visible: true
+ // store the node in a lookup
+ nodeLookup.set(node.id, node);
});
- // store the node in a lookup
- nodeLookup.set(node.id, node);
- });
-
- // add the new links
- $.each(links, function (_, link) {
- // create the link object
- var linkObj = {
- id: link.sourceId + '-' + link.targetId,
- source: nodeLookup.get(link.sourceId),
- target: nodeLookup.get(link.targetId),
- flowFileUuid: link.flowFileUuid,
- millis: link.millis,
- visible: true
- };
-
- linkLookup.set(linkObj.id, linkObj);
- });
-
- refresh(provenanceTableCtrl);
- };
+ // add the new links
+ $.each(links, function (_, link) {
+ // create the link object
+ var linkObj = {
+ id: link.sourceId + '-' + link.targetId,
+ source: nodeLookup.get(link.sourceId),
+ target: nodeLookup.get(link.targetId),
+ flowFileUuid: link.flowFileUuid,
+ millis: link.millis,
+ visible: true
+ };
+
+ linkLookup.set(linkObj.id, linkObj);
+ });
- var refresh = function (provenanceTableCtrl) {
- // consider all nodes as starting points
- var startNodes = d3.set(nodeLookup.keys());
+ refresh(provenanceTableCtrl);
+ };
- // go through the nodes to reset their outgoing links
- nodeLookup.forEach(function (id, node) {
- node.outgoing = [];
- node.incoming = [];
+ var refresh = function (provenanceTableCtrl) {
+ // consider all nodes as starting points
+ var startNodes = d3.set(nodeLookup.keys());
- // ensure this event has an event time
- if (nf.Common.isUndefined(minMillis) || minMillis > node.millis) {
- minMillis = node.millis;
- minTimestamp = node.timestamp;
- }
- if (nf.Common.isUndefined(maxMillis) || maxMillis < node.millis) {
- maxMillis = node.millis;
- }
- });
+ // go through the nodes to reset their outgoing links
+ nodeLookup.forEach(function (id, node) {
+ node.outgoing = [];
+ node.incoming = [];
- // go through the links in order to compute the new layout
- linkLookup.forEach(function (id, link) {
- // updating the nodes connections
- link.source.outgoing.push(link);
- link.target.incoming.push(link);
+ // ensure this event has an event time
+ if (common.isUndefined(minMillis) || minMillis > node.millis) {
+ minMillis = node.millis;
+ minTimestamp = node.timestamp;
+ }
+ if (common.isUndefined(maxMillis) || maxMillis < node.millis) {
+ maxMillis = node.millis;
+ }
+ });
- // remove the target from being a potential starting node
- startNodes.remove(link.target.id);
- });
+ // go through the links in order to compute the new layout
+ linkLookup.forEach(function (id, link) {
+ // updating the nodes connections
+ link.source.outgoing.push(link);
+ link.target.incoming.push(link);
- // position the nodes
- positionNodes(startNodes.values(), 1, [], 50);
+ // remove the target from being a potential starting node
+ startNodes.remove(link.target.id);
+ });
- // update the slider min/max/step values
- var step = (maxMillis - minMillis) / config.sliderTickCount;
- slider.slider('option', 'min', minMillis).slider('option', 'max', maxMillis).slider('option', 'step', step).slider('value', maxMillis);
+ // position the nodes
+ positionNodes(startNodes.values(), 1, [], 50);
- // populate the event timeline
- $('#event-time').text(formatEventTime(maxMillis, provenanceTableCtrl));
+ // update the slider min/max/step values
+ var step = (maxMillis - minMillis) / config.sliderTickCount;
+ slider.slider('option', 'min', minMillis).slider('option', 'max', maxMillis).slider('option', 'step', step).slider('value', maxMillis);
- // update the layout
- update(provenanceTableCtrl);
- };
+ // populate the event timeline
+ $('#event-time').text(formatEventTime(maxMillis, provenanceTableCtrl));
- // formats the specified millis
- var formatEventTime = function (millis, provenanceTableCtrl) {
- // get the current user time to properly convert the server time
- var now = new Date();
+ // update the layout
+ update(provenanceTableCtrl);
+ };
- // conver the user offset to millis
- var userTimeOffset = now.getTimezoneOffset() * 60 * 1000;
+ // formats the specified millis
+ var formatEventTime = function (millis, provenanceTableCtrl) {
+ // get the current user time to properly convert the server time
+ var now = new Date();
- // create the proper date by adjusting by the offsets
- var date = new Date(millis + userTimeOffset + provenanceTableCtrl.serverTimeOffset);
- return nf.Common.formatDateTime(date);
- };
+ // conver the user offset to millis
+ var userTimeOffset = now.getTimezoneOffset() * 60 * 1000;
- // handle context menu clicks...
- $('#provenance-lineage-context-menu').on('click', function () {
- $(this).hide().empty();
- });
-
- // handle zoom behavior
- var lineageZoom = d3.behavior.zoom()
- .scaleExtent([0.2, 8])
- .on('zoom', function () {
- d3.select('g.lineage').attr('transform', function () {
- return 'translate(' + d3.event.translate + ') scale(' + d3.event.scale + ')';
- });
- });
-
- // build the svg img
- var svg = d3.select('#provenance-lineage-container').append('svg:svg')
- .attr('width', '100%')
- .attr('height', '100%')
- .call(lineageZoom)
- .on('dblclick.zoom', null)
- .on('mousedown', function (d) {
- // hide the context menu if necessary
- d3.selectAll('circle.context').classed('context', false);
- $('#provenance-lineage-context-menu').hide().empty();
- })
- .on('contextmenu', function () {
- var contextMenu = $('#provenance-lineage-context-menu');
-
- // if there is something to show in the context menu
- if (!contextMenu.is(':empty')) {
- var position = d3.mouse(this);
-
- // show the context menu
- contextMenu.css({
- 'left': position[0] + 'px',
- 'top': position[1] + 'px'
- }).show();
- }
+ // create the proper date by adjusting by the offsets
+ var date = new Date(millis + userTimeOffset + provenanceTableCtrl.serverTimeOffset);
+ return common.formatDateTime(date);
+ };
- // prevent the native default context menu
- d3.event.preventDefault();
+ // handle context menu clicks...
+ $('#provenance-lineage-context-menu').on('click', function () {
+ $(this).hide().empty();
});
- svg.append('rect')
- .attr({
- 'width': '100%',
- 'height': '100%',
- 'fill': '#f9fafb'
- });
+ // handle zoom behavior
+ var lineageZoom = d3.behavior.zoom()
+ .scaleExtent([0.2, 8])
+ .on('zoom', function () {
+ d3.select('g.lineage').attr('transform', function () {
+ return 'translate(' + d3.event.translate + ') scale(' + d3.event.scale + ')';
+ });
+ });
- svg.append('defs').selectAll('marker')
- .data(['FLOWFILE', 'FLOWFILE-SELECTED', 'EVENT', 'EVENT-SELECTED'])
- .enter().append('marker')
- .attr({
- 'id': function (d) {
- return d;
- },
- 'viewBox': '0 -3 6 6',
- 'refX': function (d) {
- if (d.indexOf('FLOWFILE') >= 0) {
- return 16;
- } else {
- return 11;
- }
- },
- 'refY': 0,
- 'markerWidth': 6,
- 'markerHeight': 6,
- 'orient': 'auto',
- 'fill': function (d) {
- if (d.indexOf('SELECTED') >= 0) {
- return '#ba554a';
- } else {
- return '#000000';
+ // build the svg img
+ var svg = d3.select('#provenance-lineage-container').append('svg:svg')
+ .attr('width', '100%')
+ .attr('height', '100%')
+ .call(lineageZoom)
+ .on('dblclick.zoom', null)
+ .on('mousedown', function (d) {
+ // hide the context menu if necessary
+ d3.selectAll('circle.context').classed('context', false);
+ $('#provenance-lineage-context-menu').hide().empty();
+ })
+ .on('contextmenu', function () {
+ var contextMenu = $('#provenance-lineage-context-menu');
+
+ // if there is something to show in the context menu
+ if (!contextMenu.is(':empty')) {
+ var position = d3.mouse(this);
+
+ // show the context menu
+ contextMenu.css({
+ 'left': position[0] + 'px',
+ 'top': position[1] + 'px'
+ }).show();
}
- }
- })
- .append('path')
- .attr('d', 'M0,-3 L6,0 L0,3');
-
- // group everything together
- var lineageContainer = svg.append('g')
- .attr({
- 'transform': 'translate(0, 0) scale(1)',
- 'pointer-events': 'all',
- 'class': 'lineage'
- });
-
- // select the nodes and links
- var nodes = lineageContainer.selectAll('g.node');
- var links = lineageContainer.selectAll('path.link');
-
- var previousMillis = maxMillis;
- var slide = function (event, ui) {
- if (previousMillis > ui.value) {
- // the slider is descending
- // determine the nodes to hide
- var nodesToHide = nodes.filter(function (d) {
- return d.millis > ui.value && d.millis <= previousMillis;
+ // prevent the native default context menu
+ d3.event.preventDefault();
});
- var linksToHide = links.filter(function (d) {
- return d.millis > ui.value && d.millis <= previousMillis;
+
+ svg.append('rect')
+ .attr({
+ 'width': '100%',
+ 'height': '100%',
+ 'fill': '#f9fafb'
});
- // hide applicable nodes and lines
- linksToHide.transition().duration(400).style('opacity', 0);
- nodesToHide.transition().delay(200).duration(400).style('opacity', 0);
- } else {
- // the slider is ascending
+ svg.append('defs').selectAll('marker')
+ .data(['FLOWFILE', 'FLOWFILE-SELECTED', 'EVENT', 'EVENT-SELECTED'])
+ .enter().append('marker')
+ .attr({
+ 'id': function (d) {
+ return d;
+ },
+ 'viewBox': '0 -3 6 6',
+ 'refX': function (d) {
+ if (d.indexOf('FLOWFILE') >= 0) {
+ return 16;
+ } else {
+ return 11;
+ }
+ },
+ 'refY': 0,
+ 'markerWidth': 6,
+ 'markerHeight': 6,
+ 'orient': 'auto',
+ 'fill': function (d) {
+ if (d.indexOf('SELECTED') >= 0) {
+ return '#ba554a';
+ } else {
+ return '#000000';
+ }
+ }
+ })
+ .append('path')
+ .attr('d', 'M0,-3 L6,0 L0,3');
- // determine the nodes to show
- var nodesToShow = nodes.filter(function (d) {
- return d.millis <= ui.value && d.millis > previousMillis;
- });
- var linksToShow = links.filter(function (d) {
- return d.millis <= ui.value && d.millis > previousMillis;
+ // group everything together
+ var lineageContainer = svg.append('g')
+ .attr({
+ 'transform': 'translate(0, 0) scale(1)',
+ 'pointer-events': 'all',
+ 'class': 'lineage'
});
- // show applicable nodes and lines
- nodesToShow.transition().duration(400).style('opacity', 1);
- linksToShow.transition().delay(200).duration(400).style('opacity', 1);
- }
+ // select the nodes and links
+ var nodes = lineageContainer.selectAll('g.node');
+ var links = lineageContainer.selectAll('path.link');
- // update the event time
- $('#event-time').text(formatEventTime(ui.value, provenanceTableCtrl));
+ var previousMillis = maxMillis;
+ var slide = function (event, ui) {
+ if (previousMillis > ui.value) {
+ // the slider is descending
- // update the previous value
- previousMillis = ui.value;
- };
+ // determine the nodes to hide
+ var nodesToHide = nodes.filter(function (d) {
+ return d.millis > ui.value && d.millis <= previousMillis;
+ });
+ var linksToHide = links.filter(function (d) {
+ return d.millis > ui.value && d.millis <= previousMillis;
+ });
- // set up a slider for the showing the timeline of events
- var slider = $('#provenance-lineage-slider').slider({
- min: minMillis,
- max: maxMillis,
- step: (maxMillis - minMillis) / config.sliderTickCount,
- value: maxMillis,
- change: slide,
- slide: slide
- });
-
- // renders flowfile nodes
- var renderFlowFile = function (flowfiles) {
- flowfiles.classed('flowfile', true);
-
- // node
- flowfiles.append('circle')
- .attr({
- 'r': 16,
- 'fill': '#fff',
- 'stroke': '#000',
- 'stroke-width': 1.0
- })
- .on('mousedown', function (d) {
- // empty context menu if necessary
- $('#provenance-lineage-context-menu').hide().empty();
+ // hide applicable nodes and lines
+ linksToHide.transition().duration(400).style('opacity', 0);
+ nodesToHide.transition().delay(200).duration(400).style('opacity', 0);
+ } else {
+ // the slider is ascending
- // prevents the drag event when something other than the
- // left button is clicked
- if (d3.event.button !== 0) {
- d3.event.stopPropagation();
- }
- }, true)
- .on('mouseover', function (d) {
- links.filter(function (linkDatum) {
- return d.id === linkDatum.flowFileUuid;
- })
- .classed('selected', true)
- .attr('marker-end', function (d) {
- return 'url(#' + d.target.type + '-SELECTED)';
- });
- })
- .on('mouseout', function (d) {
- links.filter(function (linkDatum) {
- return d.id === linkDatum.flowFileUuid;
- }).classed('selected', false)
- .attr('marker-end', function (d) {
- return 'url(#' + d.target.type + ')';
- });
- });
+ // determine the nodes to show
+ var nodesToShow = nodes.filter(function (d) {
+ return d.millis <= ui.value && d.millis > previousMillis;
+ });
+ var linksToShow = links.filter(function (d) {
+ return d.millis <= ui.value && d.millis > previousMillis;
+ });
- var icon = flowfiles.append('g')
- .attr({
- 'class': 'flowfile-icon',
- 'transform': function (d) {
- return 'translate(-9,-9)';
- }
- }).append('text')
- .attr({
- 'font-family': 'flowfont',
- 'font-size': '18px',
- 'fill': '#ad9897',
- 'transform': function (d) {
- return 'translate(0,15)';
- }
- })
- .on('mousedown', function (d) {
- // empty context menu if necessary
- $('#provenance-lineage-context-menu').hide().empty();
+ // show applicable nodes and lines
+ nodesToShow.transition().duration(400).style('opacity', 1);
+ linksToShow.transition().delay(200).duration(400).style('opacity', 1);
+ }
- // prevents the drag event when something other than the
- // left button is clicked
- if (d3.event.button !== 0) {
- d3.event.stopPropagation();
- }
- }, true)
- .on('mouseover', function (d) {
- links.filter(function (linkDatum) {
- return d.id === linkDatum.flowFileUuid;
- })
- .classed('selected', true)
- .attr('marker-end', function (d) {
- return 'url(#' + d.target.type + '-SELECTED)';
- });
- })
- .on('mouseout', function (d) {
- links.filter(function (linkDatum) {
- return d.id === linkDatum.flowFileUuid;
- }).classed('selected', false)
- .attr('marker-end', function (d) {
- return 'url(#' + d.target.type + ')';
- });
- })
- .text(function(d) { return '\ue808' });
- };
+ // update the event time
+ $('#event-time').text(formatEventTime(ui.value, provenanceTableCtrl));
- // renders event nodes
- var renderEvent = function (events, provenanceTableCtrl) {
- events
- .classed('event', true)
- .append('circle')
- .classed('selected', function (d) {
- return d.id === eventId;
- })
- .attr({
- 'r': 8,
- 'fill': '#aabbc3',
- 'stroke': '#000',
- 'stroke-width': 1.0,
- 'id': function (d) {
- return 'event-node-' + d.id;
- }
- })
- .on('contextmenu', function (d) {
- // select the current node for a visible cue
- d3.select(this).classed('context', true);
+ // update the previous value
+ previousMillis = ui.value;
+ };
- // empty an previous contents - in case they right click on the
- // node twice without closing the previous context menu
- $('#provenance-lineage-context-menu').hide().empty();
+ // set up a slider for the showing the timeline of events
+ var slider = $('#provenance-lineage-slider').slider({
+ min: minMillis,
+ max: maxMillis,
+ step: (maxMillis - minMillis) / config.sliderTickCount,
+ value: maxMillis,
+ change: slide,
+ slide: slide
+ });
- var menuItems = [{
- 'class': 'lineage-view-event',
- 'text': 'View details',
- 'click': function () {
- provenanceTableCtrl.showEventDetails(d.id, clusterNodeId);
+ // renders flowfile nodes
+ var renderFlowFile = function (flowfiles) {
+ flowfiles.classed('flowfile', true);
+
+ // node
+ flowfiles.append('circle')
+ .attr({
+ 'r': 16,
+ 'fill': '#fff',
+ 'stroke': '#000',
+ 'stroke-width': 1.0
+ })
+ .on('mousedown', function (d) {
+ // empty context menu if necessary
+ $('#provenance-lineage-context-menu').hide().empty();
+
+ // prevents the drag event when something other than the
+ // left button is clicked
+ if (d3.event.button !== 0) {
+ d3.event.stopPropagation();
}
- }];
-
- // if this is a spawn event show appropriate actions
- if (d.eventType === 'SPAWN' || d.eventType === 'CLONE' || d.eventType === 'FORK' || d.eventType === 'JOIN' || d.eventType === 'REPLAY') {
- // starts the lineage expansion process
- var expandLineage = function (lineageRequest) {
- var lineageProgress = $('#lineage-percent-complete');
-
- // add support to cancel outstanding requests - when the button is pressed we
- // could be in one of two stages, 1) waiting to GET the status or 2)
- // in the process of GETting the status. Handle both cases by cancelling
- // the setTimeout (1) and by setting a flag to indicate that a request has
- // been request so we can ignore the results (2).
-
- var cancelled = false;
- var lineage = null;
- var lineageTimer = null;
-
- // update the progress bar value
- provenanceTableCtrl.updateProgress(lineageProgress, 0);
-
- // show the 'searching...' dialog
- $('#lineage-query-dialog').modal('setButtonModel', [{
- buttonText: 'Cancel',
- color: {
- base: '#E3E8EB',
- hover: '#C7D2D7',
- text: '#004849'
- },
- handler: {
- click: function () {
- cancelled = true;
-
- // we are waiting for the next poll attempt
- if (lineageTimer !== null) {
- // cancel it
- clearTimeout(lineageTimer);
-
- // cancel the provenance
- closeDialog();
- }
- }
- }
- }]).modal('show');
+ }, true)
+ .on('mouseover', function (d) {
+ links.filter(function (linkDatum) {
+ return d.id === linkDatum.flowFileUuid;
+ })
+ .classed('selected', true)
+ .attr('marker-end', function (d) {
+ return 'url(#' + d.target.type + '-SELECTED)';
+ });
+ })
+ .on('mouseout', function (d) {
+ links.filter(function (linkDatum) {
+ return d.id === linkDatum.flowFileUuid;
+ }).classed('selected', false)
+ .attr('marker-end', function (d) {
+ return 'url(#' + d.target.type + ')';
+ });
+ });
+ var icon = flowfiles.append('g')
+ .attr({
+ 'class': 'flowfile-icon',
+ 'transform': function (d) {
+ return 'translate(-9,-9)';
+ }
+ }).append('text')
+ .attr({
+ 'font-family': 'flowfont',
+ 'font-size': '18px',
+ 'fill': '#ad9897',
+ 'transform': function (d) {
+ return 'translate(0,15)';
+ }
+ })
+ .on('mousedown', function (d) {
+ // empty context menu if necessary
+ $('#provenance-lineage-context-menu').hide().empty();
+
+ // prevents the drag event when something other than the
+ // left button is clicked
+ if (d3.event.button !== 0) {
+ d3.event.stopPropagation();
+ }
+ }, true)
+ .on('mouseover', function (d) {
+ links.filter(function (linkDatum) {
+ return d.id === linkDatum.flowFileUuid;
+ })
+ .classed('selected', true)
+ .attr('marker-end', function (d) {
+ return 'url(#' + d.target.type + '-SELECTED)';
+ });
+ })
+ .on('mouseout', function (d) {
+ links.filter(function (linkDatum) {
+ return d.id === linkDatum.flowFileUuid;
+ }).classed('selected', false)
+ .attr('marker-end', function (d) {
+ return 'url(#' + d.target.type + ')';
+ });
+ })
+ .text(function (d) {
+ return '\ue808'
+ });
+ };
- // closes the searching dialog and cancels the query on the server
- var closeDialog = function () {
- // cancel the provenance results since we've successfully processed the results
- if (nf.Common.isDefinedAndNotNull(lineage)) {
- cancelLineage(lineage);
- }
+ // renders event nodes
+ var renderEvent = function (events, provenanceTableCtrl) {
+ events
+ .classed('event', true)
+ .append('circle')
+ .classed('selected', function (d) {
+ return d.id === eventId;
+ })
+ .attr({
+ 'r': 8,
+ 'fill': '#aabbc3',
+ 'stroke': '#000',
+ 'stroke-width': 1.0,
+ 'id': function (d) {
+ return 'event-node-' + d.id;
+ }
+ })
+ .on('contextmenu', function (d) {
+ // select the current node for a visible cue
+ d3.select(this).classed('context', true);
- // close the dialog
- $('#lineage-query-dialog').modal('hide');
- };
+ // empty an previous contents - in case they right click on the
+ // node twice without closing the previous context menu
+ $('#provenance-lineage-context-menu').hide().empty();
- // polls for the event lineage
- var pollLineage = function () {
- getLineage(lineage).done(function (response) {
- lineage = response.lineage;
+ var menuItems = [{
+ 'class': 'lineage-view-event',
+ 'text': 'View details',
+ 'click': function () {
+ provenanceTableCtrl.showEventDetails(d.id, clusterNodeId);
+ }
+ }];
+
+ // if this is a spawn event show appropriate actions
+ if (d.eventType === 'SPAWN' || d.eventType === 'CLONE' || d.eventType === 'FORK' || d.eventType === 'JOIN' || d.eventType === 'REPLAY') {
+ // starts the lineage expansion process
+ var expandLineage = function (lineageRequest) {
+ var lineageProgress = $('#lineage-percent-complete');
+
+ // add support to cancel outstanding requests - when the button is pressed we
+ // could be in one of two stages, 1) waiting to GET the status or 2)
+ // in the process of GETting the status. Handle both cases by cancelling
+ // the setTimeout (1) and by setting a flag to indicate that a request has
+ // been request so we can ignore the results (2).
+
+ var cancelled = false;
+ var lineage = null;
+ var lineageTimer = null;
+
+ // update the progress bar value
+ provenanceTableCtrl.updateProgress(lineageProgress, 0);
+
+ // show the 'searching...' dialog
+ $('#lineage-query-dialog').modal('setButtonModel', [{
+ buttonText: 'Cancel',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ cancelled = true;
+
+ // we are waiting for the next poll attempt
+ if (lineageTimer !== null) {
+ // cancel it
+ clearTimeout(lineageTimer);
+
+ // cancel the provenance
+ closeDialog();
+ }
+ }
+ }
+ }]).modal('show');
- // process the lineage
- processLineage();
- }).fail(closeDialog);
- };
- // processes the event lineage
- var processLineage = function () {
- // if the request was cancelled just ignore the current response
- if (cancelled === true) {
- closeDialog();
- return;
- }
+ // closes the searching dialog and cancels the query on the server
+ var closeDialog = function () {
+ // cancel the provenance results since we've successfully processed the results
+ if (common.isDefinedAndNotNull(lineage)) {
+ cancelLineage(lineage);
+ }
- // close the dialog if the results contain an error
- if (!nf.Common.isEmpty(lineage.results.errors)) {
- var errors = lineage.results.errors;
- nf.Dialog.showOkDialog({
- headerText: 'Process Lineage',
- dialogContent: nf.Common.formatUnorderedList(errors)
- });
+ // close the dialog
+ $('#lineage-query-dialog').modal('hide');
+ };
- closeDialog();
- return;
- }
+ // polls for the event lineage
+ var pollLineage = function () {
+ getLineage(lineage).done(function (response) {
+ lineage = response.lineage;
- // update the precent complete
- provenanceTableCtrl.updateProgress(lineageProgress, lineage.percentCompleted);
+ // process the lineage
+ processLineage();
+ }).fail(closeDialog);
+ };
- // process the results if they are finished
- if (lineage.finished === true) {
- var results = lineage.results;
+ // processes the event lineage
+ var processLineage = function () {
+ // if the request was cancelled just ignore the current response
+ if (cancelled === true) {
+ closeDialog();
+ return;
+ }
- // ensure the events haven't aged off
- if (results.nodes.length > 0) {
- // update the lineage graph
- renderEventLineage(results);
- } else {
- // inform the user that no results were found
- nf.Dialog.showOkDialog({
- headerText: 'Lineage Results',
- dialogContent: 'The lineage search has completed successfully but there no results were found. The events may have aged off.'
+ // close the dialog if the results contain an error
+ if (!common.isEmpty(lineage.results.errors)) {
+ var errors = lineage.results.errors;
+ dialog.showOkDialog({
+ headerText: 'Process Lineage',
+ dialogContent: common.formatUnorderedList(errors)
});
- }
- // close the searching.. dialog
- closeDialog();
- } else {
- lineageTimer = setTimeout(function () {
- // clear the timer since we've been invoked
- lineageTimer = null;
+ closeDialog();
+ return;
+ }
- // for the lineage
- pollLineage();
- }, 2000);
- }
- };
+ // update the precent complete
+ provenanceTableCtrl.updateProgress(lineageProgress, lineage.percentCompleted);
+
+ // process the results if they are finished
+ if (lineage.finished === true) {
+ var results = lineage.results;
+
+ // ensure the events haven't aged off
+ if (results.nodes.length > 0) {
+ // update the lineage graph
+ renderEventLineage(results);
+ } else {
+ // inform the user that no results were found
+ dialog.showOkDialog({
+ headerText: 'Lineage Results',
+ dialogContent: 'The lineage search has completed successfully but there no results were found. The events may have aged off.'
+ });
+ }
- // once the query is submitted wait until its finished
- submitLineage(lineageRequest).done(function (response) {
- lineage = response.lineage;
-
- // process the lineage, if its not done computing wait 1 second before checking again
- processLineage(1);
- }).fail(closeDialog);
- };
-
- // handles updating the lineage graph
- var renderEventLineage = function (lineageResults) {
- addLineage(lineageResults.nodes, lineageResults.links, provenanceTableCtrl);
- };
-
- // collapses the lineage for the specified event in the specified direction
- var collapseLineage = function (eventId, provenanceTableCtrl) {
- // get the event in question and collapse in the appropriate direction
- provenanceTableCtrl.getEventDetails(eventId, clusterNodeId).done(function (response) {
- var provenanceEvent = response.provenanceEvent;
- var eventUuid = provenanceEvent.flowFileUuid;
- var eventUuids = d3.set(provenanceEvent.childUuids);
-
- // determines if the specified event should be removable based on if the collapsing is fanning in/out
- var allowEventRemoval = function (fanIn, node) {
- if (fanIn) {
- return node.id !== eventId;
+ // close the searching.. dialog
+ closeDialog();
} else {
- return node.flowFileUuid !== eventUuid && $.inArray(eventUuid, node.parentUuids) === -1;
- }
- };
+ lineageTimer = setTimeout(function () {
+ // clear the timer since we've been invoked
+ lineageTimer = null;
- // determines if the specified link should be removable based on if the collapsing is fanning in/out
- var allowLinkRemoval = function (fanIn, link) {
- if (fanIn) {
- return true;
- } else {
- return link.flowFileUuid !== eventUuid;
+ // for the lineage
+ pollLineage();
+ }, 2000);
}
};
- // the event is fan in if the flowfile uuid is in the children
- var fanIn = $.inArray(eventUuid, provenanceEvent.childUuids) >= 0;
+ // once the query is submitted wait until its finished
+ submitLineage(lineageRequest).done(function (response) {
+ lineage = response.lineage;
- // collapses the specified uuids
- var collapse = function (uuids) {
- var newUuids = false;
+ // process the lineage, if its not done computing wait 1 second before checking again
+ processLineage(1);
+ }).fail(closeDialog);
+ };
- // consider each node for being collapsed
- $.each(nodeLookup.values(), function (_, node) {
- // if this node is in the uuids remove it unless its the original event or is part of this and another lineage
- if (uuids.has(node.flowFileUuid) && allowEventRemoval(fanIn, node)) {
- // remove it from the look lookup
- nodeLookup.remove(node.id);
+ // handles updating the lineage graph
+ var renderEventLineage = function (lineageResults) {
+ addLineage(lineageResults.nodes, lineageResults.links, provenanceTableCtrl);
+ };
- // include all related outgoing flow file uuids
- $.each(node.outgoing, function (_, outgoing) {
- if (!uuids.has(outgoing.flowFileUuid)) {
- uuids.add(outgoing.flowFileUuid);
- newUuids = true;
- }
- });
+ // collapses the lineage for the specified event in the specified direction
+ var collapseLineage = function (eventId, provenanceTableCtrl) {
+ // get the event in question and collapse in the appropriate direction
+ provenanceTableCtrl.getEventDetails(eventId, clusterNodeId).done(function (response) {
+ var provenanceEvent = response.provenanceEvent;
+ var eventUuid = provenanceEvent.flowFileUuid;
+ var eventUuids = d3.set(provenanceEvent.childUuids);
+
+ // determines if the specified event should be removable based on if the collapsing is fanning in/out
+ var allowEventRemoval = function (fanIn, node) {
+ if (fanIn) {
+ return node.id !== eventId;
+ } else {
+ return node.flowFileUuid !== eventUuid && $.inArray(eventUuid, node.parentUuids) === -1;
}
- });
+ };
+
+ // determines if the specified link should be removable based on if the collapsing is fanning in/out
+ var allowLinkRemoval = function (fanIn, link) {
+ if (fanIn) {
+ return true;
+ } else {
+ return link.flowFileUuid !== eventUuid;
+ }
+ };
+
+ // the event is fan in if the flowfile uuid is in the children
+ var fanIn = $.inArray(eventUuid, provenanceEvent.childUuids) >= 0;
+
+ // collapses the specified uuids
+ var collapse = function (uuids) {
+ var newUuids = false;
+
+ // consider each node for being collapsed
+ $.each(nodeLookup.values(), function (_, node) {
+ // if this node is in the uuids remove it unless its the original event or is part of this and another lineage
+ if (uuids.has(node.flowFileUuid) && allowEventRemoval(fanIn, node)) {
+ // remove it from the look lookup
+ nodeLookup.remove(node.id);
+
+ // include all related outgoing flow file uuids
+ $.each(node.outgoing, function (_, outgoing) {
+ if (!uuids.has(outgoing.flowFileUuid)) {
+ uuids.add(outgoing.flowFileUuid);
+ newUuids = true;
+ }
+ });
+ }
+ });
- // update the link data
- $.each(linkLookup.values(), function (_, link) {
- // if this link is in the uuids remove it
- if (uuids.has(link.flowFileUuid) && allowLinkRemoval(fanIn, link)) {
- // remove it from the link lookup
- linkLookup.remove(link.id);
-
- // add a related uuid that needs to be collapse
- var next = link.target;
- if (!uuids.has(next.flowFileUuid)) {
- uuids.add(next.flowFileUuid);
- newUuids = true;
+ // update the link data
+ $.each(linkLookup.values(), function (_, link) {
+ // if this link is in the uuids remove it
+ if (uuids.has(link.flowFileUuid) && allowLinkRemoval(fanIn, link)) {
+ // remove it from the link lookup
+ linkLookup.remove(link.id);
+
+ // add a related uuid that needs to be collapse
+ var next = link.target;
+ if (!uuids.has(next.flowFileUuid)) {
+ uuids.add(next.flowFileUuid);
+ newUuids = true;
+ }
}
+ });
+
+ // collapse any related uuids
+ if (newUuids) {
+ collapse(uuids);
}
- });
+ };
- // collapse any related uuids
- if (newUuids) {
- collapse(uuids);
- }
- };
+ // collapse the specified uuids
+ collapse(eventUuids);
- // collapse the specified uuids
- collapse(eventUuids);
+ // update the layout
+ refresh(provenanceTableCtrl);
+ });
+ };
- // update the layout
- refresh(provenanceTableCtrl);
+ // add menu items
+ menuItems.push({
+ 'class': 'lineage-view-parents',
+ 'text': 'Find parents',
+ 'click': function () {
+ expandLineage({
+ lineageRequestType: 'PARENTS',
+ eventId: d.id,
+ clusterNodeId: clusterNodeId
+ });
+ }
+ }, {
+ 'class': 'lineage-view-children',
+ 'text': 'Expand',
+ 'click': function () {
+ expandLineage({
+ lineageRequestType: 'CHILDREN',
+ eventId: d.id,
+ clusterNodeId: clusterNodeId
+ });
+ }
+ }, {
+ 'class': 'lineage-collapse-children',
+ 'text': 'Collapse',
+ 'click': function () {
+ // collapse the children lineage
+ collapseLineage(d.id, provenanceTableCtrl);
+ }
});
- };
+ }
- // add menu items
- menuItems.push({
- 'class': 'lineage-view-parents',
- 'text': 'Find parents',
- 'click': function () {
- expandLineage({
- lineageRequestType: 'PARENTS',
- eventId: d.id,
- clusterNodeId: clusterNodeId
- });
- }
- }, {
- 'class': 'lineage-view-children',
- 'text': 'Expand',
- 'click': function () {
- expandLineage({
- lin
<TRUNCATED>