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 2016/08/23 14:53:55 UTC
nifi git commit: [NIFI-2599] Enhance Status History Dialog. This
closes #894
Repository: nifi
Updated Branches:
refs/heads/master 23350543f -> 3f60eac54
[NIFI-2599] Enhance Status History Dialog. This closes #894
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/3f60eac5
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/3f60eac5
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/3f60eac5
Branch: refs/heads/master
Commit: 3f60eac54413e90e8137471dcd1e50fa6137ef5a
Parents: 2335054
Author: Scott Aslan <sc...@gmail.com>
Authored: Tue Aug 23 10:40:23 2016 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Tue Aug 23 10:53:10 2016 -0400
----------------------------------------------------------------------
.../WEB-INF/partials/status-history-dialog.jsp | 16 +-
.../nifi-web-ui/src/main/webapp/css/header.css | 2 +-
.../src/main/webapp/css/status-history.css | 14 +-
.../main/webapp/js/jquery/modal/jquery.modal.js | 14 +-
.../src/main/webapp/js/nf/nf-status-history.js | 1265 +++++++++---------
.../webapp/js/nf/summary/nf-summary-table.js | 1 +
6 files changed, 641 insertions(+), 671 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/nifi/blob/3f60eac5/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp
index 4b227d0..7daac42 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/status-history-dialog.jsp
@@ -16,16 +16,16 @@
--%>
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<div id="status-history-dialog" class="hidden large-dialog">
+ <div id="status-history-refresh-container">
+ <button id="status-history-refresh-button" class="refresh-button pointer fa fa-refresh" title="Refresh"></button>
+ <div id="status-history-last-refreshed-container" class="last-refreshed-container">
+ Last updated: <span id="status-history-last-refreshed"></span>
+ </div>
+ <div id="status-history-loading-container" class="loading-container"></div>
+ </div>
<div class="dialog-content">
<div id="status-history-details"></div>
- <div id="status-history-refresh-container">
- <button id="status-history-refresh-button" class="refresh-button pointer fa fa-refresh" title="Refresh"></button>
- <div id="status-history-last-refreshed-container" class="last-refreshed-container">
- Last updated: <span id="status-history-last-refreshed"></span>
- </div>
- <div id="status-history-loading-container" class="loading-container"></div>
- <div id="status-history-metric-combo"></div>
- </div>
+ <div id="status-history-metric-combo"></div>
<div id="status-history-container">
<div id="status-history-chart-container"></div>
<div id="status-history-chart-control-container"></div>
http://git-wip-us.apache.org/repos/asf/nifi/blob/3f60eac5/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
index c742c2f..24a370b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/header.css
@@ -190,7 +190,7 @@ md-toolbar.md-small .md-toolbar-tools {
font-style: normal;
font-weight: normal;
font-size: 12px;
- max-width: 250px;
+ max-width: 130px;
text-overflow: ellipsis;
line-height: normal;
overflow: hidden;
http://git-wip-us.apache.org/repos/asf/nifi/blob/3f60eac5/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css
index ac969c2..e421f61 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/status-history.css
@@ -27,9 +27,9 @@
#status-history-refresh-container {
position: absolute;
- top: 0px;
- left: 40%;
- right: 0px;
+ left: 20px;
+ bottom: 20px;
+ z-index: 1;
}
#status-history-loading-container {
@@ -57,6 +57,7 @@
#status-history-metric-combo {
float: right;
+ width: 250px;
}
#status-history-container {
@@ -68,7 +69,6 @@
}
#status-history-chart-container {
- height: 265px;
background-color: #fff;
overflow: hidden;
cursor: default;
@@ -86,6 +86,11 @@
left: 0px;
right: 60%;
bottom: 0px;
+ overflow-y: auto;
+}
+
+#status-history-dialog > .dialog-content {
+ overflow: visible;
}
div.status-history-detail {
@@ -132,7 +137,6 @@ div.legend-entry {
div.legend-label {
font-weight: bold;
- width: 240px;
overflow: hidden;
white-space: nowrap;
line-height: normal;
http://git-wip-us.apache.org/repos/asf/nifi/blob/3f60eac5/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js
index 1e73676..82f8bf6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/modal/jquery.modal.js
@@ -463,13 +463,13 @@
nfDialog.glasspane = glasspane = 'transparent';
}
- //create glass pane overlay
- var modalGlassMarkup = '<div data-nf-dialog-parent="' +
- dialog.attr('id') + '" class="modal-glass" style="background-color: ' + glasspane + ';"></div>';
-
- var modalGlass = $(modalGlassMarkup);
-
- modalGlass.css('z-index', zIndex - 1).appendTo($('body'));
+ if (!$('body').find("[data-nf-dialog-parent='" + dialog.attr('id') + "']").is(':visible')) {
+ //create glass pane overlay
+ $('<div></div>').attr('data-nf-dialog-parent', dialog.attr('id')).addClass("modal-glass").css({
+ "background-color": glasspane,
+ "z-index": zIndex - 1
+ }).appendTo($('body'));
+ }
//persist data attribute
dialog.data('nfDialog', nfDialog);
http://git-wip-us.apache.org/repos/asf/nifi/blob/3f60eac5/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js
index 9a67688..17d40d8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-status-history.js
@@ -233,6 +233,13 @@ nf.StatusHistory = (function () {
}
}
});
+
+ $('#status-history-dialog').modal('show');
+ };
+
+ var getChartMinHeight = function () {
+ return $('#status-history-chart-container').parent().outerHeight() - $('#status-history-chart-control-container').outerHeight() -
+ parseInt($('#status-history-chart-control-container').css('margin-top'), 10);
};
var getChartMaxHeight = function () {
@@ -252,748 +259,698 @@ nf.StatusHistory = (function () {
* Updates the chart with the specified status history and the selected field.
*/
var updateChart = function () {
- var statusHistory = $('#status-history-dialog').data('status-history');
- // get the selected descriptor
- var selectedDescriptor = statusHistory.selectedDescriptor;
+ var statusHistoryDialog = $('#status-history-dialog');
- // remove current details
- $('#status-history-details').empty();
+ if (statusHistoryDialog.is(':visible')) {
+ var statusHistory = statusHistoryDialog.data('status-history');
- // add status history details
- var detailsContainer = buildDetailsContainer('Status History');
- d3.map(statusHistory.details).forEach(function (label, value) {
- addDetailItem(detailsContainer, label, value);
- });
+ // get the selected descriptor
+ var selectedDescriptor = statusHistory.selectedDescriptor;
- var margin = {
- top: 15,
- right: 20,
- bottom: 25,
- left: 75
- };
+ // remove current details
+ $('#status-history-details').empty();
- // -------------
- // prep the data
- // -------------
+ // add status history details
+ var detailsContainer = buildDetailsContainer('Status History');
+ d3.map(statusHistory.details).forEach(function (label, value) {
+ addDetailItem(detailsContainer, label, value);
+ });
- // available colors
- var color = d3.scale.category10();
+ var margin = {
+ top: 15,
+ right: 20,
+ bottom: 25,
+ left: 75
+ };
- // determine the available instances
- var instanceLabels = [];
- $.each(statusHistory.instances, function (_, instance) {
- instanceLabels.push(instance.label);
- });
+ // -------------
+ // prep the data
+ // -------------
- // specify the domain based on the detected instances
- color.domain(instanceLabels);
+ // available colors
+ var color = d3.scale.category10();
- // data for the chart
- var statusData = [];
+ // determine the available instances
+ var instanceLabels = [];
+ $.each(statusHistory.instances, function (_, instance) {
+ instanceLabels.push(instance.label);
+ });
- // go through each instance of this status history
- $.each(statusHistory.instances, function (_, instance) {
- // if this is the first time this instance is being rendered, make it visible
- if (nf.Common.isUndefinedOrNull(instances[instance.id])) {
- instances[instance.id] = true;
- }
+ // specify the domain based on the detected instances
+ color.domain(instanceLabels);
+
+ // data for the chart
+ var statusData = [];
+
+ // go through each instance of this status history
+ $.each(statusHistory.instances, function (_, instance) {
+ // if this is the first time this instance is being rendered, make it visible
+ if (nf.Common.isUndefinedOrNull(instances[instance.id])) {
+ instances[instance.id] = true;
+ }
- // and convert the model
- statusData.push({
- id: instance.id,
- label: instance.label,
- values: $.map(instance.snapshots, function (d) {
- return {
- timestamp: d.timestamp,
- value: d.statusMetrics[selectedDescriptor.field]
- };
- }),
- visible: instances[instance.id] === true
+ // and convert the model
+ statusData.push({
+ id: instance.id,
+ label: instance.label,
+ values: $.map(instance.snapshots, function (d) {
+ return {
+ timestamp: d.timestamp,
+ value: d.statusMetrics[selectedDescriptor.field]
+ };
+ }),
+ visible: instances[instance.id] === true
+ });
});
- });
- // --------------------------
- // custom time axis formatter
- // --------------------------
-
- var customTimeFormat = d3.time.format.multi([
- [':%S.%L', function (d) {
- return d.getMilliseconds();
- }],
- [':%S', function (d) {
- return d.getSeconds();
- }],
- ['%H:%M', function (d) {
- return d.getMinutes();
- }],
- ['%H:%M', function (d) {
- return d.getHours();
- }],
- ['%a %d', function (d) {
- return d.getDay() && d.getDate() !== 1;
- }],
- ['%b %d', function (d) {
- return d.getDate() !== 1;
- }],
- ['%B', function (d) {
- return d.getMonth();
- }],
- ['%Y', function () {
- return true;
- }]
- ]);
-
- // ----------
- // main chart
- // ----------
+ // --------------------------
+ // custom time axis formatter
+ // --------------------------
- var statusHistoryDialog = $('#status-history-dialog');
+ var customTimeFormat = d3.time.format.multi([
+ [':%S.%L', function (d) {
+ return d.getMilliseconds();
+ }],
+ [':%S', function (d) {
+ return d.getSeconds();
+ }],
+ ['%H:%M', function (d) {
+ return d.getMinutes();
+ }],
+ ['%H:%M', function (d) {
+ return d.getHours();
+ }],
+ ['%a %d', function (d) {
+ return d.getDay() && d.getDate() !== 1;
+ }],
+ ['%b %d', function (d) {
+ return d.getDate() !== 1;
+ }],
+ ['%B', function (d) {
+ return d.getMonth();
+ }],
+ ['%Y', function () {
+ return true;
+ }]
+ ]);
+
+ // ----------
+ // main chart
+ // ----------
+
+ // the container for the main chart
+ var chartContainer = $('#status-history-chart-container').empty();
+ if (chartContainer.hasClass('ui-resizable')) {
+ chartContainer.resizable('destroy');
+ chartContainer.removeAttr( "style" );
+ }
- // show/center the dialog if necessary
- if (!statusHistoryDialog.is(':visible')) {
- statusHistoryDialog.modal('show');
- }
+ // calculate the dimensions
+ chartContainer.height(getChartMinHeight());
- // the container for the main chart
- var chartContainer = $('#status-history-chart-container').empty();
- if (chartContainer.hasClass('ui-resizable')) {
- chartContainer.resizable('destroy');
- }
+ // determine the new width/height
+ var width = chartContainer.outerWidth() - margin.left - margin.right;
+ var height = chartContainer.outerHeight() - margin.top - margin.bottom;
- // calculate the dimensions
- var width = chartContainer.parent().outerWidth() - margin.left - margin.right;
- var height = chartContainer.outerHeight() - margin.top - margin.bottom;
+ maxWidth = $('#status-history-container').width();
+ if (width > maxWidth) {
+ width = maxWidth;
+ }
- maxWidth = getChartMaxWidth();
- if (width > maxWidth) {
- width = maxWidth;
- }
+ maxHeight = getChartMaxHeight();
+ if (height > maxHeight) {
+ height = maxHeight;
+ }
- maxHeight = getChartMaxHeight();
- if (height > maxHeight) {
- height = maxHeight;
- }
+ // define the x axis for the main chart
+ var x = d3.time.scale()
+ .range([0, width]);
- // define the x axis for the main chart
- var x = d3.time.scale()
- .range([0, width]);
-
- var xAxis = d3.svg.axis()
- .scale(x)
- .ticks(5)
- .tickFormat(customTimeFormat)
- .orient('bottom');
-
- // define the y axis
- var y = d3.scale.linear()
- .range([height, 0]);
-
- var yAxis = d3.svg.axis()
- .scale(y)
- .tickFormat(formatters[selectedDescriptor.formatter])
- .orient('left');
-
- // status line
- var line = d3.svg.line()
- .interpolate('monotone')
- .x(function (d) {
- return x(d.timestamp);
- })
- .y(function (d) {
- return y(d.value);
- });
+ var xAxis = d3.svg.axis()
+ .scale(x)
+ .ticks(5)
+ .tickFormat(customTimeFormat)
+ .orient('bottom');
- // build the chart svg
- var chartSvg = d3.select('#status-history-chart-container').append('svg')
- .attr('style', 'pointer-events: none;')
- .attr('width', chartContainer.parent().width())
- .attr('height', chartContainer.innerHeight());
- // define a clip the path
- var clipPath = chartSvg.append('defs').append('clipPath')
- .attr('id', 'clip')
- .append('rect')
- .attr('width', width)
- .attr('height', height);
-
- // build the chart
- var chart = chartSvg.append('g')
- .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
-
- // determine the min/max date
- var minDate = d3.min(statusData, function (d) {
- return d3.min(d.values, function (s) {
- return s.timestamp;
- });
- });
- var maxDate = d3.max(statusData, function (d) {
- return d3.max(d.values, function (s) {
- return s.timestamp;
- });
- });
- addDetailItem(detailsContainer, 'Start', nf.Common.formatDateTime(minDate));
- addDetailItem(detailsContainer, 'End', nf.Common.formatDateTime(maxDate));
-
- // determine the x axis range
- x.domain([minDate, maxDate]);
-
- // determine the y axis range
- y.domain([getMinValue(statusData), getMaxValue(statusData)]);
-
- // build the x axis
- chart.append('g')
- .attr('class', 'x axis')
- .attr('transform', 'translate(0, ' + height + ')')
- .call(xAxis);
-
- // build the y axis
- chart.append('g')
- .attr('class', 'y axis')
- .call(yAxis)
- .append('text')
- .attr('transform', 'rotate(-90)')
- .attr('y', 6)
- .attr('dy', '.71em')
- .attr('text-anchor', 'end')
- .text(selectedDescriptor.label);
-
- // build the chart
- var status = chart.selectAll('.status')
- .data(statusData)
- .enter()
- .append('g')
- .attr('clip-path', 'url(#clip)')
- .attr('class', 'status');
-
- // draw the lines
- status.append('path')
- .attr('class', function (d) {
- return 'chart-line chart-line-' + d.id;
- })
- .attr('d', function (d) {
- return line(d.values);
- })
- .attr('stroke', function (d) {
- return color(d.label);
- })
- .classed('hidden', function (d) {
- return d.visible === false;
- })
- .append('title')
- .text(function (d) {
- return d.label;
- });
+ // define the y axis
+ var y = d3.scale.linear()
+ .range([height, 0]);
+
+ var yAxis = d3.svg.axis()
+ .scale(y)
+ .tickFormat(formatters[selectedDescriptor.formatter])
+ .orient('left');
- // draw the control points for each line
- status.each(function (d) {
- // create a group for the control points
- var markGroup = d3.select(this).append('g')
- .attr('class', function () {
- return 'mark-group mark-group-' + d.id;
+
+ // status line
+ var line = d3.svg.line()
+ .interpolate('monotone')
+ .x(function (d) {
+ return x(d.timestamp);
})
- .classed('hidden', function (d) {
- return d.visible === false;
+ .y(function (d) {
+ return y(d.value);
});
- // draw the control points
- markGroup.selectAll('circle.mark')
- .data(d.values)
+ // build the chart svg
+ var chartSvg = d3.select('#status-history-chart-container').append('svg')
+ .attr('style', 'pointer-events: none;')
+ .attr('width', chartContainer.parent().width())
+ .attr('height', chartContainer.innerHeight());
+ // define a clip the path
+ var clipPath = chartSvg.append('defs').append('clipPath')
+ .attr('id', 'clip')
+ .append('rect')
+ .attr('width', width)
+ .attr('height', height);
+
+ // build the chart
+ var chart = chartSvg.append('g')
+ .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
+
+ // determine the min/max date
+ var minDate = d3.min(statusData, function (d) {
+ return d3.min(d.values, function (s) {
+ return s.timestamp;
+ });
+ });
+ var maxDate = d3.max(statusData, function (d) {
+ return d3.max(d.values, function (s) {
+ return s.timestamp;
+ });
+ });
+ addDetailItem(detailsContainer, 'Start', nf.Common.formatDateTime(minDate));
+ addDetailItem(detailsContainer, 'End', nf.Common.formatDateTime(maxDate));
+
+ // determine the x axis range
+ x.domain([minDate, maxDate]);
+
+ // determine the y axis range
+ y.domain([getMinValue(statusData), getMaxValue(statusData)]);
+
+ // build the x axis
+ chart.append('g')
+ .attr('class', 'x axis')
+ .attr('transform', 'translate(0, ' + height + ')')
+ .call(xAxis);
+
+ // build the y axis
+ chart.append('g')
+ .attr('class', 'y axis')
+ .call(yAxis)
+ .append('text')
+ .attr('transform', 'rotate(-90)')
+ .attr('y', 6)
+ .attr('dy', '.71em')
+ .attr('text-anchor', 'end')
+ .text(selectedDescriptor.label);
+
+ // build the chart
+ var status = chart.selectAll('.status')
+ .data(statusData)
.enter()
- .append('circle')
- .attr('style', 'pointer-events: all;')
- .attr('class', 'mark')
- .attr('cx', function (v) {
- return x(v.timestamp);
+ .append('g')
+ .attr('clip-path', 'url(#clip)')
+ .attr('class', 'status');
+
+ // draw the lines
+ status.append('path')
+ .attr('class', function (d) {
+ return 'chart-line chart-line-' + d.id;
})
- .attr('cy', function (v) {
- return y(v.value);
+ .attr('d', function (d) {
+ return line(d.values);
})
- .attr('fill', function () {
+ .attr('stroke', function (d) {
return color(d.label);
})
- .attr('r', 1.5)
+ .classed('hidden', function (d) {
+ return d.visible === false;
+ })
.append('title')
- .text(function (v) {
- return d.label + ' -- ' + formatters[selectedDescriptor.formatter](v.value);
+ .text(function (d) {
+ return d.label;
});
- });
-
- // -------------
- // control chart
- // -------------
-
- // the container for the main chart control
- var chartControlContainer = $('#status-history-chart-control-container').empty();
- var controlHeight = chartControlContainer.innerHeight() - margin.top - margin.bottom;
-
- var xControl = d3.time.scale()
- .range([0, width]);
-
- var xControlAxis = d3.svg.axis()
- .scale(xControl)
- .ticks(5)
- .tickFormat(customTimeFormat)
- .orient('bottom');
-
- var yControl = d3.scale.linear()
- .range([controlHeight, 0]);
-
- var yControlAxis = d3.svg.axis()
- .scale(yControl)
- .tickValues(y.domain())
- .tickFormat(formatters[selectedDescriptor.formatter])
- .orient('left');
-
- // status line
- var controlLine = d3.svg.line()
- .interpolate('monotone')
- .x(function (d) {
- return xControl(d.timestamp);
- })
- .y(function (d) {
- return yControl(d.value);
- });
- // build the svg
- var controlChartSvg = d3.select('#status-history-chart-control-container').append('svg')
- .attr('width', chartContainer.parent().width())
- .attr('height', controlHeight + margin.top + margin.bottom);
-
- // build the control chart
- var control = controlChartSvg.append('g')
- .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
-
- // increase the y domain slightly
- var yControlDomain = y.domain();
- yControlDomain[1] *= 1.04;
-
- // define the domain for the control chart
- xControl.domain(x.domain());
- yControl.domain(yControlDomain);
-
- // build the control x axis
- control.append('g')
- .attr('class', 'x axis')
- .attr('transform', 'translate(0, ' + controlHeight + ')')
- .call(xControlAxis);
-
- // build the control y axis
- control.append('g')
- .attr('class', 'y axis')
- .call(yControlAxis);
-
- // build the control chart
- var controlStatus = control.selectAll('.status')
- .data(statusData)
- .enter()
- .append('g')
- .attr('class', 'status');
-
- // draw the lines
- controlStatus.append('path')
- .attr('class', function (d) {
- return 'chart-line chart-line-' + d.id;
- })
- .attr('d', function (d) {
- return controlLine(d.values);
- })
- .attr('stroke', function (d) {
- return color(d.label);
- })
- .classed('hidden', function (d) {
- return instances[d.id] === false;
- })
- .append('title')
- .text(function (d) {
- return d.label;
+ // draw the control points for each line
+ status.each(function (d) {
+ // create a group for the control points
+ var markGroup = d3.select(this).append('g')
+ .attr('class', function () {
+ return 'mark-group mark-group-' + d.id;
+ })
+ .classed('hidden', function (d) {
+ return d.visible === false;
+ });
+
+ // draw the control points
+ markGroup.selectAll('circle.mark')
+ .data(d.values)
+ .enter()
+ .append('circle')
+ .attr('style', 'pointer-events: all;')
+ .attr('class', 'mark')
+ .attr('cx', function (v) {
+ return x(v.timestamp);
+ })
+ .attr('cy', function (v) {
+ return y(v.value);
+ })
+ .attr('fill', function () {
+ return color(d.label);
+ })
+ .attr('r', 1.5)
+ .append('title')
+ .text(function (v) {
+ return d.label + ' -- ' + formatters[selectedDescriptor.formatter](v.value);
+ });
});
- // -------------------
- // configure the brush
- // -------------------
+ // update the size of the chart
+ chartSvg.attr('width', chartContainer.parent().width())
+ .attr('height', chartContainer.innerHeight());
- /**
- * Updates the axis for the main chart.
- *
- * @param {array} xDomain The new domain for the x axis
- * @param {array} yDomain The new domain for the y axis
- */
- var updateAxes = function (xDomain, yDomain) {
- // update the domain of the main chart
- x.domain(xDomain);
- y.domain(yDomain);
+ // update the size of the clipper
+ clipPath.attr('width', width)
+ .attr('height', height);
- // update the chart lines
- status.selectAll('.chart-line')
- .attr('d', function (d) {
- return line(d.values);
- });
- status.selectAll('circle.mark')
- .attr('cx', function (v) {
- return x(v.timestamp);
- })
- .attr('cy', function (v) {
- return y(v.value);
- })
- .attr('r', function () {
- return brush.empty() ? 1.5 : 4;
- });
+ // update the position of the x axis
+ chart.select('.x.axis').attr('transform', 'translate(0, ' + height + ')');
- // update the x axis
- chart.select('.x.axis').call(xAxis);
- chart.select('.y.axis').call(yAxis);
- };
+ // -------------
+ // control chart
+ // -------------
- /**
- * Handles brush events by updating the main chart according to the context window
- * or the control domain if there is no context window.
- */
- var brushed = function () {
- // determine the new x and y domains
- var xContextDomain, yContextDomain;
- if (brush.empty()) {
- // get the all visible instances
- var visibleInstances = $.grep(statusData, function (d) {
- return d.visible;
- });
+ // the container for the main chart control
+ var chartControlContainer = $('#status-history-chart-control-container').empty();
+ var controlHeight = chartControlContainer.innerHeight() - margin.top - margin.bottom;
- // determine the appropriate y domain
- if (visibleInstances.length === 0) {
- yContextDomain = yControl.domain();
- } else {
- yContextDomain = [
- d3.min(visibleInstances, function (d) {
- return d3.min(d.values, function (s) {
- return s.value;
- });
- }),
- d3.max(visibleInstances, function (d) {
- return d3.max(d.values, function (s) {
- return s.value;
- });
- })
- ];
- }
- xContextDomain = xControl.domain();
+ var xControl = d3.time.scale()
+ .range([0, width]);
- // clear the current extent
- brushExtent = null;
- } else {
- var extent = brush.extent();
- xContextDomain = [extent[0][0], extent[1][0]];
- yContextDomain = [extent[0][1], extent[1][1]];
+ var xControlAxis = d3.svg.axis()
+ .scale(xControl)
+ .ticks(5)
+ .tickFormat(customTimeFormat)
+ .orient('bottom');
- // hold onto the current brush
- brushExtent = extent;
- }
+ var yControl = d3.scale.linear()
+ .range([controlHeight, 0]);
- // update the axes accordingly
- updateAxes(xContextDomain, yContextDomain);
+ var yControlAxis = d3.svg.axis()
+ .scale(yControl)
+ .tickValues(y.domain())
+ .tickFormat(formatters[selectedDescriptor.formatter])
+ .orient('left');
- // update the aggregate statistics according to the new domain
- updateAggregateStatistics();
- };
-
- // build the brush
- var brush = d3.svg.brush()
- .x(xControl)
- .y(yControl)
- .on('brush', brushed);
+ // status line
+ var controlLine = d3.svg.line()
+ .interpolate('monotone')
+ .x(function (d) {
+ return xControl(d.timestamp);
+ })
+ .y(function (d) {
+ return yControl(d.value);
+ });
- // conditionally set the brush extent
- if (nf.Common.isDefinedAndNotNull(brushExtent)) {
- brush = brush.extent(brushExtent);
- }
+ // build the svg
+ var controlChartSvg = d3.select('#status-history-chart-control-container').append('svg')
+ .attr('width', chartContainer.parent().width())
+ .attr('height', controlHeight + margin.top + margin.bottom);
+
+ // build the control chart
+ var control = controlChartSvg.append('g')
+ .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
+
+ // increase the y domain slightly
+ var yControlDomain = y.domain();
+ yControlDomain[1] *= 1.04;
+
+ // define the domain for the control chart
+ xControl.domain(x.domain());
+ yControl.domain(yControlDomain);
+
+ // build the control x axis
+ control.append('g')
+ .attr('class', 'x axis')
+ .attr('transform', 'translate(0, ' + controlHeight + ')')
+ .call(xControlAxis);
+
+ // build the control y axis
+ control.append('g')
+ .attr('class', 'y axis')
+ .call(yControlAxis);
+
+ // build the control chart
+ var controlStatus = control.selectAll('.status')
+ .data(statusData)
+ .enter()
+ .append('g')
+ .attr('class', 'status');
- // context area
- control.append('g')
- .attr('class', 'brush')
- .call(brush);
-
- // add expansion to the extent
- control.select('rect.extent')
- .attr('style', 'pointer-events: all;')
- .on('dblclick', function () {
- if (!brush.empty()) {
- // get the current extent to get the x range
- var extent = brush.extent();
+ // draw the lines
+ controlStatus.append('path')
+ .attr('class', function (d) {
+ return 'chart-line chart-line-' + d.id;
+ })
+ .attr('d', function (d) {
+ return controlLine(d.values);
+ })
+ .attr('stroke', function (d) {
+ return color(d.label);
+ })
+ .classed('hidden', function (d) {
+ return instances[d.id] === false;
+ })
+ .append('title')
+ .text(function (d) {
+ return d.label;
+ });
- // get the y range (this value does not change from the original y domain)
- var yRange = yControl.domain();
+ // -------------------
+ // configure the brush
+ // -------------------
+
+ /**
+ * Updates the axis for the main chart.
+ *
+ * @param {array} xDomain The new domain for the x axis
+ * @param {array} yDomain The new domain for the y axis
+ */
+ var updateAxes = function (xDomain, yDomain) {
+ // update the domain of the main chart
+ x.domain(xDomain);
+ y.domain(yDomain);
- // expand the extent vertically
- brush.extent([[extent[0][0], yRange[0]], [extent[1][0], yRange[1]]]);
+ // update the chart lines
+ status.selectAll('.chart-line')
+ .attr('d', function (d) {
+ return line(d.values);
+ });
+ status.selectAll('circle.mark')
+ .attr('cx', function (v) {
+ return x(v.timestamp);
+ })
+ .attr('cy', function (v) {
+ return y(v.value);
+ })
+ .attr('r', function () {
+ return brush.empty() ? 1.5 : 4;
+ });
+
+ // update the x axis
+ chart.select('.x.axis').call(xAxis);
+ chart.select('.y.axis').call(yAxis);
+ };
+
+ /**
+ * Handles brush events by updating the main chart according to the context window
+ * or the control domain if there is no context window.
+ */
+ var brushed = function () {
+ // determine the new x and y domains
+ var xContextDomain, yContextDomain;
+ if (brush.empty()) {
+ // get the all visible instances
+ var visibleInstances = $.grep(statusData, function (d) {
+ return d.visible;
+ });
+
+ // determine the appropriate y domain
+ if (visibleInstances.length === 0) {
+ yContextDomain = yControl.domain();
+ } else {
+ yContextDomain = [
+ d3.min(visibleInstances, function (d) {
+ return d3.min(d.values, function (s) {
+ return s.value;
+ });
+ }),
+ d3.max(visibleInstances, function (d) {
+ return d3.max(d.values, function (s) {
+ return s.value;
+ });
+ })
+ ];
+ }
+ xContextDomain = xControl.domain();
- // update the brush control
- control.select('.brush').call(brush);
+ // clear the current extent
+ brushExtent = null;
+ } else {
+ var extent = brush.extent();
+ xContextDomain = [extent[0][0], extent[1][0]];
+ yContextDomain = [extent[0][1], extent[1][1]];
- // run the brush to update the axes of the main chart
- brushed();
+ // hold onto the current brush
+ brushExtent = extent;
}
- });
- // --------------------
- // aggregate statistics
- // --------------------
+ // update the axes accordingly
+ updateAxes(xContextDomain, yContextDomain);
- var updateAggregateStatistics = function () {
- // locate the instances that have data points within the current brush
- var withinBrush = $.map(statusData, function (d) {
- var xDomain = x.domain();
- var yDomain = y.domain();
+ // update the aggregate statistics according to the new domain
+ updateAggregateStatistics();
+ };
- // copy to avoid modifying the original
- var copy = $.extend({}, d);
+ // build the brush
+ var brush = d3.svg.brush()
+ .x(xControl)
+ .y(yControl)
+ .on('brush', brushed);
- // update the copy to only include values within the brush
- return $.extend(copy, {
- values: $.grep(d.values, function (s) {
- return s.timestamp.getTime() >= xDomain[0].getTime() && s.timestamp.getTime() <= xDomain[1].getTime() && s.value >= yDomain[0] && s.value <= yDomain[1];
- })
- });
- });
+ // conditionally set the brush extent
+ if (nf.Common.isDefinedAndNotNull(brushExtent)) {
+ brush = brush.extent(brushExtent);
+ }
- // consider visible nodes with data in the brush
- var nodes = $.grep(withinBrush, function (d) {
- return d.id !== config.nifiInstanceId && d.visible && d.values.length > 0;
- });
+ // context area
+ control.append('g')
+ .attr('class', 'brush')
+ .call(brush);
- var nodeMinValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMinValue(nodes));
- var nodeMeanValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMeanValue(nodes));
- var nodeMaxValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMaxValue(nodes));
+ // add expansion to the extent
+ control.select('rect.extent')
+ .attr('style', 'pointer-events: all;')
+ .on('dblclick', function () {
+ if (!brush.empty()) {
+ // get the current extent to get the x range
+ var extent = brush.extent();
- // update the currently displayed min/max/mean
- $('#node-aggregate-statistics').text(nodeMinValue + ' / ' + nodeMaxValue + ' / ' + nodeMeanValue);
+ // get the y range (this value does not change from the original y domain)
+ var yRange = yControl.domain();
- // only consider the cluster with data in the brush
- var cluster = $.grep(withinBrush, function (d) {
- return d.id === config.nifiInstanceId && d.visible && d.values.length > 0;
- });
+ // expand the extent vertically
+ brush.extent([[extent[0][0], yRange[0]], [extent[1][0], yRange[1]]]);
- // determine the cluster values
- var clusterMinValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMinValue(cluster));
- var clusterMeanValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMeanValue(cluster));
- var clusterMaxValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMaxValue(cluster));
+ // update the brush control
+ control.select('.brush').call(brush);
- // update the cluster min/max/mean
- $('#cluster-aggregate-statistics').text(clusterMinValue + ' / ' + clusterMaxValue + ' / ' + clusterMeanValue);
- };
+ // run the brush to update the axes of the main chart
+ brushed();
+ }
+ });
- // ----------------
- // build the legend
- // ----------------
+ // --------------------
+ // aggregate statistics
+ // --------------------
- // identify all nodes and sort
- var nodes = $.grep(statusData, function (status) {
- return status.id !== config.nifiInstanceId;
- }).sort(function (a, b) {
- return a.label < b.label ? -1 : a.label > b.label ? 1 : 0;
- });
+ var updateAggregateStatistics = function () {
+ // locate the instances that have data points within the current brush
+ var withinBrush = $.map(statusData, function (d) {
+ var xDomain = x.domain();
+ var yDomain = y.domain();
+
+ // copy to avoid modifying the original
+ var copy = $.extend({}, d);
- // adds a legend entry for the specified instance
- var addLegendEntry = function (legend, instance) {
- // create the label and the checkbox
- var instanceLabelElement = $('<div></div>').addClass('legend-label').css('color', color(instance.label)).text(instance.label).ellipsis();
- var instanceCheckboxElement = $('<div class="nf-checkbox"></div>').on('click', function () {
- // get the line and the control points for this instance (select all for the line to update control and main charts)
- var chartLine = d3.selectAll('path.chart-line-' + instance.id);
- var markGroup = d3.select('g.mark-group-' + instance.id);
-
- // determine if it was hidden
- var isHidden = markGroup.classed('hidden');
-
- // toggle the visibility
- chartLine.classed('hidden', function () {
- return !isHidden;
+ // update the copy to only include values within the brush
+ return $.extend(copy, {
+ values: $.grep(d.values, function (s) {
+ return s.timestamp.getTime() >= xDomain[0].getTime() && s.timestamp.getTime() <= xDomain[1].getTime() && s.value >= yDomain[0] && s.value <= yDomain[1];
+ })
+ });
});
- markGroup.classed('hidden', function () {
- return !isHidden;
+
+ // consider visible nodes with data in the brush
+ var nodes = $.grep(withinBrush, function (d) {
+ return d.id !== config.nifiInstanceId && d.visible && d.values.length > 0;
});
- // update whether its visible
- instance.visible = isHidden;
+ var nodeMinValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMinValue(nodes));
+ var nodeMeanValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMeanValue(nodes));
+ var nodeMaxValue = nodes.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMaxValue(nodes));
- // record the current status so it persists across refreshes
- instances[instance.id] = instance.visible;
+ // update the currently displayed min/max/mean
+ $('#node-aggregate-statistics').text(nodeMinValue + ' / ' + nodeMaxValue + ' / ' + nodeMeanValue);
- // update the brush
- brushed();
- }).addClass(instance.visible ? 'checkbox-checked' : 'checkbox-unchecked');
+ // only consider the cluster with data in the brush
+ var cluster = $.grep(withinBrush, function (d) {
+ return d.id === config.nifiInstanceId && d.visible && d.values.length > 0;
+ });
- // add the legend entry
- $('<div class="legend-entry"></div>').append(instanceCheckboxElement).append(instanceLabelElement).on('mouseenter', function () {
- d3.selectAll('path.chart-line-' + instance.id).classed('over', true);
- }).on('mouseleave', function () {
- d3.selectAll('path.chart-line-' + instance.id).classed('over', false);
- }).appendTo(legend);
- };
+ // determine the cluster values
+ var clusterMinValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMinValue(cluster));
+ var clusterMeanValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMeanValue(cluster));
+ var clusterMaxValue = cluster.length === 0 ? 'NA' : formatters[selectedDescriptor.formatter](getMaxValue(cluster));
- // get the cluster instance
- var cluster = $.grep(statusData, function (status) {
- return status.id === config.nifiInstanceId;
- });
+ // update the cluster min/max/mean
+ $('#cluster-aggregate-statistics').text(clusterMinValue + ' / ' + clusterMaxValue + ' / ' + clusterMeanValue);
+ };
- // build the cluster container
- var clusterDetailsContainer = buildDetailsContainer('NiFi');
+ // ----------------
+ // build the legend
+ // ----------------
- // add the total cluster values
- addDetailItem(clusterDetailsContainer, 'Min / Max / Mean', '', 'cluster-aggregate-statistics');
+ // identify all nodes and sort
+ var nodes = $.grep(statusData, function (status) {
+ return status.id !== config.nifiInstanceId;
+ }).sort(function (a, b) {
+ return a.label < b.label ? -1 : a.label > b.label ? 1 : 0;
+ });
- // build the cluster legend
- addLegendEntry(clusterDetailsContainer, cluster[0]);
+ // adds a legend entry for the specified instance
+ var addLegendEntry = function (legend, instance) {
+ // create the label and the checkbox
+ var instanceLabelElement = $('<div></div>').addClass('legend-label').css('color', color(instance.label)).text(instance.label).ellipsis();
+ var instanceCheckboxElement = $('<div class="nf-checkbox"></div>').on('click', function () {
+ // get the line and the control points for this instance (select all for the line to update control and main charts)
+ var chartLine = d3.selectAll('path.chart-line-' + instance.id);
+ var markGroup = d3.select('g.mark-group-' + instance.id);
+
+ // determine if it was hidden
+ var isHidden = markGroup.classed('hidden');
+
+ // toggle the visibility
+ chartLine.classed('hidden', function () {
+ return !isHidden;
+ });
+ markGroup.classed('hidden', function () {
+ return !isHidden;
+ });
+
+ // update whether its visible
+ instance.visible = isHidden;
+
+ // record the current status so it persists across refreshes
+ instances[instance.id] = instance.visible;
+
+ // update the brush
+ brushed();
+ }).addClass(instance.visible ? 'checkbox-checked' : 'checkbox-unchecked');
+
+ // add the legend entry
+ $('<div class="legend-entry"></div>').append(instanceCheckboxElement).append(instanceLabelElement).on('mouseenter', function () {
+ d3.selectAll('path.chart-line-' + instance.id).classed('over', true);
+ }).on('mouseleave', function () {
+ d3.selectAll('path.chart-line-' + instance.id).classed('over', false);
+ }).appendTo(legend);
+ };
+
+ // get the cluster instance
+ var cluster = $.grep(statusData, function (status) {
+ return status.id === config.nifiInstanceId;
+ });
- // if there are entries to render
- if (nodes.length > 0) {
// build the cluster container
- var nodeDetailsContainer = buildDetailsContainer('Nodes');
+ var clusterDetailsContainer = buildDetailsContainer('NiFi');
// add the total cluster values
- addDetailItem(nodeDetailsContainer, 'Min / Max / Mean', '', 'node-aggregate-statistics');
+ addDetailItem(clusterDetailsContainer, 'Min / Max / Mean', '', 'cluster-aggregate-statistics');
- // add each legend entry
- $.each(nodes, function (_, instance) {
- addLegendEntry(nodeDetailsContainer, instance);
- });
- }
+ // build the cluster legend
+ addLegendEntry(clusterDetailsContainer, cluster[0]);
- // update the brush
- brushed();
+ // if there are entries to render
+ if (nodes.length > 0) {
+ // build the cluster container
+ var nodeDetailsContainer = buildDetailsContainer('Nodes');
- // ---------------
- // handle resizing
- // ---------------
+ // add the total cluster values
+ addDetailItem(nodeDetailsContainer, 'Min / Max / Mean', '', 'node-aggregate-statistics');
- var maxWidth, maxHeight, resizeExtent, dialog;
- chartContainer.append('<div class="ui-resizable-handle ui-resizable-se"></div>').resizable({
- minWidth: 425,
- minHeight: 150,
- handles: {
- 'se': '.ui-resizable-se'
- },
- start: function (e, ui) {
- // record the current extent so it can be reset on stop
- if (!brush.empty()) {
- resizeExtent = brush.extent();
- }
- },
- resize: function (e, ui) {
- // -----------
- // containment
- // -----------
- dialog = $('#status-history-dialog');
- var nfDialog = {};
- if (nf.Common.isDefinedAndNotNull(dialog.data('nf-dialog'))) {
- nfDialog = dialog.data('nf-dialog');
- }
- nfDialog['min-width'] = (dialog.width()/$(window).width())*100 + '%';
- nfDialog['min-height'] = (dialog.height()/$(window).height())*100 + '%';
- nfDialog.responsive['fullscreen-width'] = dialog.outerWidth() + 'px';
- nfDialog.responsive['fullscreen-height'] = dialog.outerHeight() + 'px';
-
- maxWidth = getChartMaxWidth();
- if (ui.helper.width() > maxWidth) {
- ui.helper.width(maxWidth);
-
- nfDialog.responsive['fullscreen-width'] = $(window).width() + 'px';
- nfDialog['min-width'] = '100%';
- }
-
- maxHeight = getChartMaxHeight();
- if (ui.helper.height() > maxHeight) {
- ui.helper.height(maxHeight);
-
- nfDialog.responsive['fullscreen-height'] = $(window).height() + 'px';
- nfDialog['min-height'] = '100%';
- }
-
- nfDialog['min-width'] = (parseInt(nfDialog['min-width'], 10) >= 100) ? '100%': nfDialog['min-width'];
- nfDialog['min-height'] = (parseInt(nfDialog['min-height'], 10) >= 100) ? '100%': nfDialog['min-height'];
-
- //persist data attribute
- dialog.data('nfDialog', nfDialog);
-
- // ----------------------
- // status history dialog
- // ----------------------
-
- dialog.css('min-width', (chartContainer.outerWidth() + $('#status-history-details').outerWidth() + 40));
- dialog.css('min-height', (chartContainer.outerHeight() +
- $('#status-history-refresh-container').outerHeight() + $('#status-history-chart-control-container').outerHeight() +
- $('.dialog-buttons').outerHeight() + $('.dialog-header').outerHeight() + 40 + 5));
-
- dialog.center();
- },
- stop: function () {
-
- // ----------
- // main chart
- // ----------
-
- // determine the new width/height
- width = chartContainer.outerWidth() - margin.left - margin.right;
- height = chartContainer.outerHeight() - margin.top - margin.bottom;
-
- // update the range
- x.range([0, width]);
- y.range([height, 0]);
-
- // update the size of the chart
- chartSvg.attr('width', chartContainer.parent().width())
- .attr('height', chartContainer.innerHeight());
-
- // update the size of the clipper
- clipPath.attr('width', width)
- .attr('height', height);
-
- // update the position of the x axis
- chart.select('.x.axis').attr('transform', 'translate(0, ' + height + ')');
-
- // -------------
- // control chart
- // -------------
+ // add each legend entry
+ $.each(nodes, function (_, instance) {
+ addLegendEntry(nodeDetailsContainer, instance);
+ });
+ }
- // determine the new width/height
- controlHeight = chartControlContainer.height() - margin.top - margin.bottom;
+ // update the brush
+ brushed();
+
+ // ---------------
+ // handle resizing
+ // ---------------
+
+ var maxWidth, maxHeight, minHeight, resizeExtent, dialog;
+ chartContainer.append('<div class="ui-resizable-handle ui-resizable-se"></div>').resizable({
+ minWidth: 425,
+ minHeight: 150,
+ handles: {
+ 'se': '.ui-resizable-se'
+ },
+ start: function (e, ui) {
+ // record the current extent so it can be reset on stop
+ if (!brush.empty()) {
+ resizeExtent = brush.extent();
+ }
+ },
+ resize: function (e, ui) {
+ // -----------
+ // containment
+ // -----------
+ dialog = $('#status-history-dialog');
+ var nfDialog = {};
+ if (nf.Common.isDefinedAndNotNull(dialog.data('nf-dialog'))) {
+ nfDialog = dialog.data('nf-dialog');
+ }
+ nfDialog['min-width'] = (dialog.width() / $(window).width()) * 100 + '%';
+ nfDialog['min-height'] = (dialog.height() / $(window).height()) * 100 + '%';
+ nfDialog.responsive['fullscreen-width'] = dialog.outerWidth() + 'px';
+ nfDialog.responsive['fullscreen-height'] = dialog.outerHeight() + 'px';
- // update the range
- xControl.range([0, width]);
- yControl.range([controlHeight, 0]);
+ maxWidth = getChartMaxWidth();
+ if (ui.helper.width() > maxWidth) {
+ ui.helper.width(maxWidth);
- // update the size of the control chart
- controlChartSvg.attr('width', chartContainer.parent().width())
- .attr('height', controlHeight + margin.top + margin.bottom);
+ nfDialog.responsive['fullscreen-width'] = $(window).width() + 'px';
+ nfDialog['min-width'] = '100%';
+ }
- // update the chart lines
- controlStatus.selectAll('.chart-line').attr('d', function (d) {
- return controlLine(d.values);
- });
+ maxHeight = getChartMaxHeight();
+ if (ui.helper.height() > maxHeight) {
+ ui.helper.height(maxHeight);
- // update the axes
- control.select('.x.axis').call(xControlAxis);
- control.select('.y.axis').call(yControlAxis);
+ nfDialog.responsive['fullscreen-height'] = $(window).height() + 'px';
+ nfDialog['min-height'] = '100%';
+ }
- // restore the extent if necessary
- if (nf.Common.isDefinedAndNotNull(resizeExtent)) {
- brush.extent(resizeExtent);
- }
+ minHeight = getChartMinHeight();
+ if (ui.helper.height() < minHeight) {
+ ui.helper.height(minHeight);
+ }
- // update the brush
- control.select('.brush').call(brush);
+ nfDialog['min-width'] = (parseInt(nfDialog['min-width'], 10) >= 100) ? '100%' : nfDialog['min-width'];
+ nfDialog['min-height'] = (parseInt(nfDialog['min-height'], 10) >= 100) ? '100%' : nfDialog['min-height'];
- // invoking the brush will trigger appropriate redrawing of the main chart
- brushed();
+ //persist data attribute
+ dialog.data('nfDialog', nfDialog);
- // reset the resize extent
- resizeExtent = null;
+ // ----------------------
+ // status history dialog
+ // ----------------------
- // resize chart container
- chartContainer.width(Math.round( chartContainer.parent().width()));
- chartControlContainer.width(Math.round( chartContainer.parent().width()));
+ dialog.css('min-width', (chartContainer.outerWidth() + $('#status-history-details').outerWidth() + 40));
+ dialog.css('min-height', (chartContainer.outerHeight() +
+ $('#status-history-refresh-container').outerHeight() + $('#status-history-chart-control-container').outerHeight() +
+ $('.dialog-buttons').outerHeight() + $('.dialog-header').outerHeight() + 40 + 5));
- // toggle scrollable style
- nf.Common.toggleScrollable(dialog.find('.dialog-content').get(0));
- }
- });
+ dialog.center();
+ },
+ stop: updateChart
+ });
+ }
};
/**
@@ -1122,9 +1079,17 @@ nf.StatusHistory = (function () {
brushExtent = null;
descriptor = null;
instances = null;
- }
+ },
+ open: updateChart
}
});
+
+ $(window).on('resize', function (e) {
+ if (e.target === window) {
+ updateChart();
+ }
+ nf.Common.toggleScrollable($('#status-history-details').get(0));
+ })
},
/**
http://git-wip-us.apache.org/repos/asf/nifi/blob/3f60eac5/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js
index a43390a..33b8093 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/summary/nf-summary-table.js
@@ -276,6 +276,7 @@ nf.SummaryTable = (function () {
break;
case 'disabled':
classes += ' icon icon-enable-false';
+ break;
case 'invalid':
classes += ' fa fa-warning';
break;