This commit is contained in:
Mark Payne 2015-02-13 07:20:19 -05:00
commit bf97094b8c
9 changed files with 172 additions and 70 deletions

View File

@ -14,7 +14,7 @@
-->
# Apache NiFi
Apache NiFi is a dataflow system based on the concepts of flow-based programming. It is currently apart of the Apache Incubator.
Apache NiFi is an easy to use, powerful, and reliable system to process and distribute data. It is currently apart of the Apache Incubator.
## Table of Contents
@ -28,6 +28,10 @@ Apache NiFi is a dataflow system based on the concepts of flow-based programming
follow the directions found there.
- Build nifi. Change directory to 'nifi' and follow the directions found there.
## Documentation
See http://nifi.incubator.apache.org/ for the latest documentation.
## License
Except as otherwise noted this software is licensed under the

View File

@ -28,6 +28,7 @@
<a href="#">Documentation</a>
<ul class="dropdown">
<li><a href="faq.html">FAQ</a></li>
<li><a href="screencasts.html">Screencasts</a></li>
<li><a href="overview.html">NiFi Overview</a></li>
<li><a href="user-guide.html">User Guide</a></li>
<li><a href="developer-guide.html">Developer Guide</a></li>

View File

@ -11,5 +11,40 @@ title: Apache NiFi Screencasts
<div class="medium-space"></div>
<div class="row">
<div class="large-12 columns">
<a href="#" data-reveal-id="toolbar-overview">NiFi Toolbar Overview</a>
<div id="toolbar-overview" class="reveal-modal medium" data-reveal>
<h2>NiFi Toolbar Overview</h2>
<div class="flex-video widescreen" style="display: block;">
<iframe width="560" height="315" src="https://www.youtube.com/embed/LGXRAVUzL4U" frameborder="0" allowfullscreen></iframe>
</div>
<a class="close-reveal-modal">&#215;</a>
</div>
<br/>
<a href="#" data-reveal-id="creating-process-groups">Creating Process Groups</a>
<div id="creating-process-groups" class="reveal-modal medium" data-reveal>
<h2>Creating Process Groups</h2>
<div class="flex-video widescreen" style="display: block;">
<iframe width="560" height="315" src="https://www.youtube.com/embed/hAveiDgDj-8" frameborder="0" allowfullscreen></iframe>
</div>
<a class="close-reveal-modal">&#215;</a>
</div>
<br/>
<a href="#" data-reveal-id="creating-templates">Creating Templates</a>
<div id="creating-templates" class="reveal-modal medium" data-reveal>
<h2>Creating Templates</h2>
<div class="flex-video widescreen" style="display: block;">
<iframe width="560" height="315" src="https://www.youtube.com/embed/PpmL-IMoCnU" frameborder="0" allowfullscreen></iframe>
</div>
<a class="close-reveal-modal">&#215;</a>
</div>
<br/>
<a href="#" data-reveal-id="managing-templates">Managing Templates</a>
<div id="managing-templates" class="reveal-modal medium" data-reveal>
<h2>Managing Templates</h2>
<div class="flex-video widescreen" style="display: block;">
<iframe width="560" height="315" src="https://www.youtube.com/embed/HU5_3PlNmtQ" frameborder="0" allowfullscreen></iframe>
</div>
<a class="close-reveal-modal">&#215;</a>
</div>
</div>
</div>

View File

@ -1065,7 +1065,6 @@ nf.Actions = (function () {
// refresh the birdseye/toolbar
nf.Birdseye.refresh();
nf.CanvasToolbar.refresh();
// remove the original snippet
nf.Snippet.remove(snippet.id).fail(reject);
@ -1078,7 +1077,6 @@ nf.Actions = (function () {
// refresh the birdseye/toolbar
nf.Birdseye.refresh();
nf.CanvasToolbar.refresh();
});
// reject the deferred

View File

@ -373,6 +373,9 @@ nf.CanvasToolbox = (function () {
// show the dialog
$('#new-processor-dialog').modal('show');
// set the focus in the filter field
$('#processor-type-filter').focus();
// adjust the grid canvas now that its been rendered
grid.resizeCanvas();
@ -427,12 +430,11 @@ nf.CanvasToolbox = (function () {
*/
var promptForInputPortName = function (pt) {
var addInputPort = function () {
// hide the dialog
$('#new-port-dialog').modal('hide');
// get the name of the input port and clear the textfield
var portName = $('#new-port-name').val();
$('#new-port-name').val('');
// hide the dialog
$('#new-port-dialog').modal('hide');
// create the input port
createInputPort(portName, pt);
@ -514,12 +516,11 @@ nf.CanvasToolbox = (function () {
*/
var promptForOutputPortName = function (pt) {
var addOutputPort = function () {
// hide the dialog
$('#new-port-dialog').modal('hide');
// get the name of the output port and clear the textfield
var portName = $('#new-port-name').val();
$('#new-port-name').val('');
// hide the dialog
$('#new-port-dialog').modal('hide');
// create the output port
createOutputPort(portName, pt);
@ -641,12 +642,11 @@ nf.CanvasToolbox = (function () {
*/
var promptForRemoteProcessGroupUri = function (pt) {
var addRemoteProcessGroup = function () {
// hide the dialog
$('#new-remote-process-group-dialog').modal('hide');
// get the uri of the controller and clear the textfield
var remoteProcessGroupUri = $('#new-remote-process-group-uri').val();
$('#new-remote-process-group-uri').val('');
// hide the dialog
$('#new-remote-process-group-dialog').modal('hide');
// create the remote process group
createRemoteProcessGroup(remoteProcessGroupUri, pt);
@ -882,7 +882,9 @@ nf.CanvasToolbox = (function () {
nf.Client.setRevision(response.revision);
// add the label to the graph
nf.Label.add(response.label, true);
nf.Graph.add({
'labels': [response.label]
}, true);
// update the birdseye
nf.Birdseye.refresh();
@ -1121,19 +1123,34 @@ nf.CanvasToolbox = (function () {
// configure the new port dialog
$('#new-port-dialog').modal({
headerText: 'Add Port',
overlayBackground: false
overlayBackground: false,
handler: {
close: function () {
$('#new-port-name').val('');
}
}
});
// configure the new process group dialog
$('#new-process-group-dialog').modal({
headerText: 'Add Process Group',
overlayBackground: false
overlayBackground: false,
handler: {
close: function () {
$('#new-process-group-name').val('');
}
}
});
// configure the new remote process group dialog
$('#new-remote-process-group-dialog').modal({
headerText: 'Add Remote Process Group',
overlayBackground: false
overlayBackground: false,
handler: {
close: function () {
$('#new-remote-process-group-uri').val('');
}
}
});
// configure the instantiate template dialog
@ -1162,12 +1179,11 @@ nf.CanvasToolbox = (function () {
promptForGroupName: function (pt) {
return $.Deferred(function (deferred) {
var addGroup = function () {
// hide the dialog
$('#new-process-group-dialog').modal('hide');
// get the name of the group and clear the textfield
var groupName = $('#new-process-group-name').val();
$('#new-process-group-name').val('');
// hide the dialog
$('#new-process-group-dialog').modal('hide');
// create the group and resolve the deferred accordingly
createGroup(groupName, pt).done(function (response) {

View File

@ -393,7 +393,7 @@ nf.CanvasUtils = (function () {
*/
disableImageHref: function (selection) {
selection.on('click.disableImageHref', function () {
if (d3.event.ctrlKey) {
if (d3.event.ctrlKey || d3.event.shiftKey) {
d3.event.preventDefault();
}
});

View File

@ -409,10 +409,10 @@ nf.Canvas = (function () {
// update the selection box
selectionBox.attr(d);
// prevent further propagation (to parents)
d3.event.stopPropagation();
}
// prevent further propagation (to parents)
d3.event.stopPropagation();
}
})
.on('mouseup.selection', function () {
@ -510,12 +510,24 @@ nf.Canvas = (function () {
$(window).on('resize', function () {
updateGraphSize();
}).on('keydown', function (evt) {
var isCtrl = evt.ctrlKey || evt.metaKey;
// consider escape, before checking dialogs
if (!isCtrl && evt.keyCode === 27) {
// esc
nf.Actions.hideDialogs();
evt.preventDefault();
return;
}
// if a dialog is open, disable canvas shortcuts
if ($('.dialog').is(':visible')) {
return;
}
if (evt.ctrlKey || evt.metaKey) {
// handle shortcuts
if (isCtrl) {
if (evt.keyCode === 82) {
// ctrl-r
nf.Actions.reloadStatus();
@ -543,11 +555,6 @@ nf.Canvas = (function () {
// delete
nf.Actions['delete'](nf.CanvasUtils.getSelection());
evt.preventDefault();
} else if (evt.keyCode === 27) {
// esc
nf.Actions.hideDialogs();
evt.preventDefault();
}
}

View File

@ -20,6 +20,21 @@ nf.Connectable = (function () {
var canvas;
var origin;
/**
* Determines if we want to allow adding connections in the current state:
*
* 1) When shift is down, we could be adding components to the current selection.
* 2) When the selection box is visible, we are in the process of moving all the
* components currently selected.
* 3) When the drag selection box is visible, we are in the process or selecting components
* using the selection box.
*
* @returns {boolean}
*/
var allowConnection = function () {
return !d3.event.shiftKey && d3.select('rect.drag-selection').empty() && d3.select('rect.selection').empty();
};
return {
init: function () {
canvas = d3.select('#canvas');
@ -102,17 +117,27 @@ nf.Connectable = (function () {
}).attr('d', function (pathDatum) {
if (!destination.empty() && destination.classed('connectable-destination')) {
var destinationData = destination.datum();
// show the line preview as appropriate
if (pathDatum.sourceId === destinationData.component.id) {
var x = pathDatum.x;
var y = pathDatum.y;
var componentOffset = pathDatum.sourceWidth / 2;
var xOffset = nf.Connection.config.selfLoopXOffset;
var yOffset = nf.Connection.config.selfLoopYOffset;
return 'M' + x + ' ' + y + 'L' + (x + componentOffset + xOffset) + ' ' + (y - yOffset) + 'L' + (x + componentOffset + xOffset) + ' ' + (y + yOffset) + 'Z';
} else {
// get the position on the destination perimeter
var end = nf.CanvasUtils.getPerimeterPoint(pathDatum, {
'x': destinationData.component.position.x,
'y': destinationData.component.position.y,
'width': destinationData.dimensions.width,
'height': destinationData.dimensions.height
});
// get the position on the destination perimeter
var end = nf.CanvasUtils.getPerimeterPoint(pathDatum, {
'x': destinationData.component.position.x,
'y': destinationData.component.position.y,
'width': destinationData.dimensions.width,
'height': destinationData.dimensions.height
});
// direct line between components to provide a 'snap feel'
return 'M' + pathDatum.x + ' ' + pathDatum.y + 'L' + end.x + ' ' + end.y;
// direct line between components to provide a 'snap feel'
return 'M' + pathDatum.x + ' ' + pathDatum.y + 'L' + end.x + ' ' + end.y;
}
} else {
return 'M' + pathDatum.x + ' ' + pathDatum.y + 'L' + d3.event.x + ' ' + d3.event.y;
}
@ -122,57 +147,70 @@ nf.Connectable = (function () {
// stop further propagation
d3.event.sourceEvent.stopPropagation();
// get the add connect img
var addConnect = d3.select(this);
// get the connector, if it the current point is not over a new destination
// the connector will be removed. otherwise it will be removed after the
// connection has been configured/cancelled
var connector = d3.select('path.connector');
var connectorData = connector.datum();
// get the destination
var destination = d3.select('g.connectable-destination');
// we are not over a new destination
if (destination.empty()) {
// get the source to determine if we are still over it
var source = d3.select('#id-' + connectorData.sourceId);
var sourceData = source.datum();
// get the mouse position relative to the source
var position = d3.mouse(source.node());
// if the position is outside the component, remove the add connect img
if (position[0] < 0 || position[0] > sourceData.dimensions.width || position[1] < 0 || position[1] > sourceData.dimensions.height) {
addConnect.remove();
} else {
// reset the add connect img by restoring the position and place in the DOM
addConnect.classed('dragging', false).attr('transform', function () {
return 'translate(' + d.origX + ', ' + d.origY + ')';
});
source.node().appendChild(this);
}
// remove the connector
connector.remove();
} else {
var connectorData = connector.datum();
var destinationData = destination.datum();
// if this is a self loop we need to insert some bend points
if (connectorData.sourceId === destinationData.component.id) {
connector.attr('d', function (pathDatum) {
var x = pathDatum.x;
var y = pathDatum.y;
var componentOffset = pathDatum.sourceWidth / 2;
var xOffset = nf.Connection.config.selfLoopXOffset;
var yOffset = nf.Connection.config.selfLoopYOffset;
return 'M' + x + ' ' + y + 'L' + (x + componentOffset + xOffset) + ' ' + (y - yOffset) + 'L' + (x + componentOffset + xOffset) + ' ' + (y + yOffset) + 'Z';
});
}
// remove the add connect img
addConnect.remove();
// create the connection
var destinationData = destination.datum();
nf.ConnectionConfiguration.createConnection(connectorData.sourceId, destinationData.component.id);
}
// remove this component
d3.select(this).remove();
});
},
activate: function (components) {
components
.on('mouseenter.connectable', function (d) {
if (!d3.event.shiftKey && d3.select('rect.drag-selection').empty()) {
if (allowConnection()) {
var selection = d3.select(this);
// ensure the current component supports connection source
if (nf.CanvasUtils.isValidConnectionSource(selection)) {
// see if theres already a connector rendered
var anyConnector = d3.select('image.add-connect');
if (anyConnector.empty()) {
var addConnect = d3.select('image.add-connect');
if (addConnect.empty()) {
var x = (d.dimensions.width / 2) - 14;
var y = (d.dimensions.height / 2) - 14;
selection.append('image')
.datum({
origX: x,
origY: y
})
.call(connect)
.call(nf.CanvasUtils.disableImageHref)
.attr({
@ -188,17 +226,16 @@ nf.Connectable = (function () {
})
.on('mouseleave.connectable', function () {
// conditionally remove the connector
var connector = d3.select(this).select('image.add-connect');
if (!connector.empty() && !connector.classed('dragging')) {
connector.remove();
var addConnect = d3.select(this).select('image.add-connect');
if (!addConnect.empty() && !addConnect.classed('dragging')) {
addConnect.remove();
}
})
// Using mouseover/out to workaround chrome issue #122746
.on('mouseover.connectable', function () {
// mark that we are hovering when appropriate
var selection = d3.select(this);
selection.classed('hover', function () {
return !d3.event.shiftKey && !selection.classed('hover') && d3.select('rect.drag-selection').empty();
d3.select(this).classed('hover', function () {
return allowConnection();
});
})
.on('mouseout.connection', function () {

View File

@ -67,7 +67,6 @@ nf.Graph = (function () {
// if we are going to select the new components, deselect the previous selection
if (selectAll) {
// deselect the current selection
nf.CanvasUtils.getSelection().classed('selected', false);
}
@ -96,6 +95,11 @@ nf.Graph = (function () {
if (!nf.Common.isEmpty(processGroupContents.connections)) {
nf.Connection.add(processGroupContents.connections, selectAll);
}
// trigger the toolbar to refresh if the selection is changing
if (selectAll) {
nf.CanvasToolbar.refresh();
}
},
/**