Fixed bug where root link became clickable. Fix workflow key on results page.

This commit is contained in:
mabashian
2018-11-19 10:39:57 -05:00
parent 4c9a1d6b90
commit 3c510e6344
4 changed files with 83 additions and 85 deletions

View File

@@ -40,42 +40,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
scope.dimensionsSet = false; scope.dimensionsSet = false;
$timeout(function(){ const calcAvailableScreenSpace = () => {
let dimensions = calcAvailableScreenSpace();
windowHeight = dimensions.height;
windowWidth = dimensions.width;
$('.WorkflowMaker-chart').css("height", windowHeight);
scope.dimensionsSet = true;
init();
});
function init() {
line = d3.svg.line()
.x(function (d) {
return d.x;
})
.y(function (d) {
return d.y;
});
zoomObj = d3.behavior.zoom().scaleExtent([0.1, 2]);
baseSvg = d3.select(element[0]).append("svg")
.attr("class", "WorkflowChart-svg")
.call(zoomObj
.on("zoom", naturalZoom)
);
svgGroup = baseSvg.append("g")
.attr("id", "aw-workflow-chart-g")
.attr("transform", "translate(0," + (windowHeight/2 - rootH/2 - startNodeOffsetY) + ")");
}
function calcAvailableScreenSpace() {
let dimensions = {}; let dimensions = {};
if(scope.mode !== 'details') { if(scope.mode !== 'details') {
@@ -97,15 +62,15 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
} }
return dimensions; return dimensions;
} };
// Dagre is going to shift the root node around as nodes are added/removed // Dagre is going to shift the root node around as nodes are added/removed
// This function ensures that the user doesn't experience that // This function ensures that the user doesn't experience that
let normalizeY = ((y) => { const normalizeY = ((y) => {
return y - nodePositionMap[1].y; return y - nodePositionMap[1].y;
}); });
function lineData(d) { const lineData = (d) => {
let sourceX = nodePositionMap[d.source.id].x + (nodePositionMap[d.source.id].width); let sourceX = nodePositionMap[d.source.id].x + (nodePositionMap[d.source.id].width);
let sourceY = normalizeY(nodePositionMap[d.source.id].y) + (nodePositionMap[d.source.id].height/2); let sourceY = normalizeY(nodePositionMap[d.source.id].y) + (nodePositionMap[d.source.id].height/2);
@@ -132,21 +97,21 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
]; ];
return line(points); return line(points);
} };
// TODO: this function is hacky and we need to come up with a better solution // TODO: this function is hacky and we need to come up with a better solution
// see: http://stackoverflow.com/questions/15975440/add-ellipses-to-overflowing-text-in-svg#answer-27723752 // see: http://stackoverflow.com/questions/15975440/add-ellipses-to-overflowing-text-in-svg#answer-27723752
function wrap(text) { const wrap = (text) => {
if(text && text.length > maxNodeTextLength) { if(text && text.length > maxNodeTextLength) {
return text.substring(0,maxNodeTextLength) + '...'; return text.substring(0,maxNodeTextLength) + '...';
} }
else { else {
return text; return text;
} }
} };
function rounded_rect(x, y, w, h, r, tl, tr, bl, br) { const rounded_rect = (x, y, w, h, r, tl, tr, bl, br) => {
var retval; let retval;
retval = "M" + (x + r) + "," + y; retval = "M" + (x + r) + "," + y;
retval += "h" + (w - 2*r); retval += "h" + (w - 2*r);
if (tr) { retval += "a" + r + "," + r + " 0 0 1 " + r + "," + r; } if (tr) { retval += "a" + r + "," + r + " 0 0 1 " + r + "," + r; }
@@ -162,10 +127,10 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
else { retval += "v" + -r; retval += "h" + r; } else { retval += "v" + -r; retval += "h" + r; }
retval += "z"; retval += "z";
return retval; return retval;
} };
// This is the zoom function called by using the mousewheel/click and drag // This is the zoom function called by using the mousewheel/click and drag
function naturalZoom() { const naturalZoom = () => {
let scale = d3.event.scale, let scale = d3.event.scale,
translation = d3.event.translate; translation = d3.event.translate;
@@ -176,10 +141,10 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
scope.workflowZoomed({ scope.workflowZoomed({
zoom: scale zoom: scale
}); });
} };
// This is the zoom that gets called when the user interacts with the manual zoom controls // This is the zoom that gets called when the user interacts with the manual zoom controls
function manualZoom(zoom) { const manualZoom = (zoom) => {
let scale = zoom / 100, let scale = zoom / 100,
translation = zoomObj.translate(), translation = zoomObj.translate(),
origZoom = zoomObj.scale(), origZoom = zoomObj.scale(),
@@ -191,9 +156,9 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
svgGroup.attr("transform", "translate(" + [translateX, translateY + ((windowHeight/2 - rootH/2 - startNodeOffsetY)*scale)] + ")scale(" + scale + ")"); svgGroup.attr("transform", "translate(" + [translateX, translateY + ((windowHeight/2 - rootH/2 - startNodeOffsetY)*scale)] + ")scale(" + scale + ")");
zoomObj.scale(scale); zoomObj.scale(scale);
zoomObj.translate([translateX, translateY]); zoomObj.translate([translateX, translateY]);
} };
function manualPan(direction) { const manualPan = (direction) => {
let scale = zoomObj.scale(), let scale = zoomObj.scale(),
distance = 150 * scale, distance = 150 * scale,
translateX, translateX,
@@ -208,16 +173,16 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
} }
svgGroup.attr("transform", "translate(" + translateX + "," + (translateY + ((windowHeight/2 - rootH/2 - startNodeOffsetY)*scale)) + ")scale(" + scale + ")"); svgGroup.attr("transform", "translate(" + translateX + "," + (translateY + ((windowHeight/2 - rootH/2 - startNodeOffsetY)*scale)) + ")scale(" + scale + ")");
zoomObj.translate([translateX, translateY]); zoomObj.translate([translateX, translateY]);
} };
function resetZoomAndPan() { const resetZoomAndPan = () => {
svgGroup.attr("transform", "translate(0," + (windowHeight/2 - rootH/2 - startNodeOffsetY) + ")scale(" + 1 + ")"); svgGroup.attr("transform", "translate(0," + (windowHeight/2 - rootH/2 - startNodeOffsetY) + ")scale(" + 1 + ")");
// Update the zoomObj // Update the zoomObj
zoomObj.scale(1); zoomObj.scale(1);
zoomObj.translate([0,0]); zoomObj.translate([0,0]);
} };
function zoomToFitChart() { const zoomToFitChart = () => {
let graphDimensions = d3.select('#aw-workflow-chart-g')[0][0].getBoundingClientRect(), let graphDimensions = d3.select('#aw-workflow-chart-g')[0][0].getBoundingClientRect(),
availableScreenSpace = calcAvailableScreenSpace(), availableScreenSpace = calcAvailableScreenSpace(),
currentZoomValue = zoomObj.scale(), currentZoomValue = zoomObj.scale(),
@@ -236,9 +201,9 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
svgGroup.attr("transform", "translate(0," + (windowHeight/2 - (nodeH*scaleToFit/2)) + ")scale(" + scaleToFit + ")"); svgGroup.attr("transform", "translate(0," + (windowHeight/2 - (nodeH*scaleToFit/2)) + ")scale(" + scaleToFit + ")");
zoomObj.translate([0, windowHeight/2 - (nodeH*scaleToFit/2) - ((windowHeight/2 - rootH/2 - startNodeOffsetY)*scaleToFit)]); zoomObj.translate([0, windowHeight/2 - (nodeH*scaleToFit/2) - ((windowHeight/2 - rootH/2 - startNodeOffsetY)*scaleToFit)]);
} };
function update() { const updateGraph = () => {
if(scope.dimensionsSet) { if(scope.dimensionsSet) {
const buildLinkTooltip = (d) => { const buildLinkTooltip = (d) => {
let sourceNode = d3.select(`#node-${d.source.id}`); let sourceNode = d3.select(`#node-${d.source.id}`);
@@ -315,7 +280,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
}); });
}; };
var g = new dagre.graphlib.Graph(); let g = new dagre.graphlib.Graph();
g.setGraph({rankdir: 'LR', nodesep: 30, ranksep: 120}); g.setGraph({rankdir: 'LR', nodesep: 30, ranksep: 120});
@@ -780,7 +745,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
.each(function(d) { .each(function(d) {
if(d.job && d.job.status && (d.job.status === "pending" || d.job.status === "waiting" || d.job.status === "running")) { if(d.job && d.job.status && (d.job.status === "pending" || d.job.status === "waiting" || d.job.status === "running")) {
// Pulse the circle // Pulse the circle
var circle = d3.select(this); let circle = d3.select(this);
(function repeat() { (function repeat() {
circle = circle.transition() circle = circle.transition()
.duration(2000) .duration(2000)
@@ -1267,11 +1232,11 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
if(scope.dimensionsSet) { if(scope.dimensionsSet) {
scope.watchDimensionsSet(); scope.watchDimensionsSet();
scope.watchDimensionsSet = null; scope.watchDimensionsSet = null;
update(); updateGraph();
} }
}); });
} }
} };
function add_node_without_child() { function add_node_without_child() {
this.on("click", function(d) { this.on("click", function(d) {
@@ -1367,7 +1332,7 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
scope.$on('refreshWorkflowChart', function(){ scope.$on('refreshWorkflowChart', function(){
if(scope.graphState) { if(scope.graphState) {
update(); updateGraph();
} }
}); });
@@ -1387,12 +1352,10 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
zoomToFitChart(); zoomToFitChart();
}); });
let clearWatchgraphState = scope.$watch('graphState.arrayOfNodesForChart', function(newVal) { let clearWatchGraphState = scope.$watch('graphState.arrayOfNodesForChart', function(newVal) {
if(newVal) { if(newVal) {
// scope.graphState.arrayOfNodesForChart updateGraph();
clearWatchGraphState();
update();
clearWatchgraphState();
} }
}); });
@@ -1407,6 +1370,37 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
angular.element($window).off('resize', onResize); angular.element($window).off('resize', onResize);
} }
$timeout(() => {
let dimensions = calcAvailableScreenSpace();
windowHeight = dimensions.height;
windowWidth = dimensions.width;
$('.WorkflowMaker-chart').css("height", windowHeight);
scope.dimensionsSet = true;
line = d3.svg.line()
.x(function (d) {
return d.x;
})
.y(function (d) {
return d.y;
});
zoomObj = d3.behavior.zoom().scaleExtent([0.1, 2]);
baseSvg = d3.select(element[0]).append("svg")
.attr("class", "WorkflowChart-svg")
.call(zoomObj
.on("zoom", naturalZoom)
);
svgGroup = baseSvg.append("g")
.attr("id", "aw-workflow-chart-g")
.attr("transform", "translate(0," + (windowHeight/2 - rootH/2 - startNodeOffsetY) + ")");
});
if(scope.mode === 'details') { if(scope.mode === 'details') {
angular.element($window).on('resize', onResize); angular.element($window).on('resize', onResize);
scope.$on('$destroy', cleanUpResize); scope.$on('$destroy', cleanUpResize);

View File

@@ -17,22 +17,6 @@ export default ['templateUrl',
restrict: 'E', restrict: 'E',
link: function(scope) { link: function(scope) {
function init() {
scope.zoom = 100;
$( "#slider" ).slider({
value:100,
min: 10,
max: 200,
step: 10,
slide: function( event, ui ) {
scope.zoom = ui.value;
scope.zoomChart({
zoom: scope.zoom
});
}
});
}
scope.pan = function(direction) { scope.pan = function(direction) {
scope.panChart({ scope.panChart({
direction: direction direction: direction
@@ -70,7 +54,20 @@ export default ['templateUrl',
$("#slider").slider('value',scope.zoom); $("#slider").slider('value',scope.zoom);
}); });
init(); scope.zoom = 100;
$( "#slider" ).slider({
value:100,
min: 10,
max: 200,
step: 10,
slide: function( event, ui ) {
scope.zoom = ui.value;
scope.zoomChart({
zoom: scope.zoom
});
}
});
} }
}; };
} }

View File

@@ -36,7 +36,7 @@ export default ['$scope', 'TemplatesService',
Wait('start'); Wait('start');
TemplatesService.getWorkflowJobTemplateNodes($scope.workflowJobTemplateObj.id, page) TemplatesService.getWorkflowJobTemplateNodes($scope.workflowJobTemplateObj.id, page)
.then(({data}) => { .then(({data}) => {
for (var i = 0; i < data.results.length; i++) { for (let i = 0; i < data.results.length; i++) {
allNodes.push(data.results[i]); allNodes.push(data.results[i]);
} }
if (data.next) { if (data.next) {
@@ -538,11 +538,15 @@ export default ['$scope', 'TemplatesService',
// Add the new links // Add the new links
parents.forEach((parentId) => { parents.forEach((parentId) => {
children.forEach((child) => { children.forEach((child) => {
let source = {
id: parentId
};
if (parentId === 1) { if (parentId === 1) {
child.edgeType = "always"; child.edgeType = "always";
source.isStartNode = true;
} }
$scope.graphState.arrayOfLinksForChart.push({ $scope.graphState.arrayOfLinksForChart.push({
source: {id: parentId}, source,
target: {id: child.id}, target: {id: child.id},
edgeType: child.edgeType edgeType: child.edgeType
}); });

View File

@@ -8,6 +8,9 @@ export default ['workflowData', 'workflowResultsService', 'workflowDataOptions',
let nodeRef; let nodeRef;
var runTimeElapsedTimer = null; var runTimeElapsedTimer = null;
$scope.toggleKey = () => $scope.showKey = !$scope.showKey;
$scope.keyClassList = `{ 'Key-menuIcon--active': showKey }`;
var getLinks = function() { var getLinks = function() {
var getLink = function(key) { var getLink = function(key) {
if(key === 'schedule') { if(key === 'schedule') {