Skip to content

Commit

Permalink
'Merge' layering code from 'provenance-visualization-feature' branch.
Browse files Browse the repository at this point in the history
  • Loading branch information
sluger committed Jan 28, 2015
1 parent 505b1ea commit e83f5d4
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 74 deletions.
41 changes: 41 additions & 0 deletions refinery/ui/src/js/provvis_decl.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ var provvisDecl = function () {
this.links = d3.map();

this.wfName = "";

this.layer = Object.create(null);
this.aggregation = Object.create(null);
};

Analysis.prototype = Object.create(BaseNode.prototype);
Expand Down Expand Up @@ -261,6 +264,44 @@ var provvisDecl = function () {
Subanalysis.prototype = Object.create(BaseNode.prototype);
Subanalysis.prototype.constructor = Subanalysis;

/**
* Constructor function for the layered node data structure.
*
* @param id
* @param parent
* @param hidden
* @constructor
*/
var LayeredNode = function (id, parent, hidden) {
BaseNode.call(this, id, "layeredNode", parent, hidden);

this.inputs = d3.map();
this.outputs = d3.map();
this.links = d3.map();
};

LayeredNode.prototype = Object.create(BaseNode.prototype);
LayeredNode.prototype.constructor = LayeredNode;

/**
* Constructor function for the aggregated node data structure.
*
* @param id
* @param parent
* @param hidden
* @constructor
*/
var AggregatedNode = function (id, parent, hidden) {
BaseNode.call(this, id, "aggregatedNode", parent, hidden);

this.inputs = d3.map();
this.outputs = d3.map();
this.links = d3.map();
};

AggregatedNode.prototype = Object.create(BaseNode.prototype);
AggregatedNode.prototype.constructor = AggregatedNode;

/**
* Constructor function for the link data structure.
*
Expand Down
1 change: 1 addition & 0 deletions refinery/ui/src/js/provvis_init.js
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ var provvisInit = function () {
/* Temporarily facet node attribute extraction. */
extractFacetNodeAttributesPrivate(solrResponse);

/* Create node attribute list. */
createFacetNodeAttributeList(solrResponse);

/* Create graph. */
Expand Down
164 changes: 91 additions & 73 deletions refinery/ui/src/js/provvis_layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,18 @@ var provvisLayout = function () {
});
};

/**
* Extract and set layered nodes for analysis nodes.
* @param bclgNodes Barcyenter sorted, layered and grouped analysis nodes.
*/
var extractLayeredNodes = function (bclgNodes) {

/* TODO: For each column, for each analysis, check successors.
* If there are at least two analyses sharing the same input files, layer them.
*/

};


/**
* Main layout module function.
Expand Down Expand Up @@ -1124,102 +1136,108 @@ var provvisLayout = function () {
l.l.ts.removed = false;
});

/* SUBANALYSIS LAYOUT. */
reorderSubanalysisNodes(bclgNodes);

} else {
console.log("Error: Graph is not acyclic!");
}

/* TODO: Extract and create layered nodes. */
extractLayeredNodes(bclgNodes);

/* FILES/TOOLS LAYOUT. */
graph.saNodes.forEach(function (san) {
var tsNodes = topSortNodes(san.inputs.values(), san.children.size(), san);

if (tsNodes !== null) {
/* Assign layers. */
layerNodes(tsNodes, san);

/* Group nodes by layer. */
var gNodes = groupNodes(tsNodes);
/* SUBANALYSIS LAYOUT. */
reorderSubanalysisNodes(bclgNodes);

/* TODO: Refine and cleanup. */
/* FILES/TOOLS LAYOUT. */
graph.saNodes.forEach(function (san) {
var tsNodes = topSortNodes(san.inputs.values(), san.children.size(), san);

/* Init rows and visited flag. */
gNodes.forEach(function (gn) {
gn.forEach(function (n, i) {
n.row = i;
n.visited = false;
});
});
if (tsNodes !== null) {
/* Assign layers. */
layerNodes(tsNodes, san);

/* Process layout, for each column. */
gNodes.forEach(function (gn) {
/* Group nodes by layer. */
var gNodes = groupNodes(tsNodes);

/* For each node. */
gn.forEach(function (n) {
/* TODO: Refine and cleanup. */

var succs = n.succs.values().filter(function (s) {
return s.parent === n.parent;
/* Init rows and visited flag. */
gNodes.forEach(function (gn) {
gn.forEach(function (n, i) {
n.row = i;
n.visited = false;
});
});

/* Branch. */
if (succs.length > 1) {
/* Process layout, for each column. */
gNodes.forEach(function (gn) {

/* Successors was visited before? */
var visited = getNumberofVisitedNodesByArray(succs),
rowShift = succs.length / 2;
/* For each node. */
gn.forEach(function (n) {

/* Shift nodes before and after the branch. */
/* But only if there are more than one successor. */
if ((succs.length - visited) > 1) {
shiftNodesByRows(tsNodes, rowShift, n.col, n.row);
shiftNodesByRows(tsNodes, rowShift, n.col, n.row + 1);
}
var succs = n.succs.values().filter(function (s) {
return s.parent === n.parent;
});

var succRow = n.row - rowShift + visited;
succs.forEach(function (sn) {
if (succs.length % 2 === 0 && succRow === n.row) {
succRow++;
}
/* Branch. */
if (succs.length > 1) {

/* Successors was visited before? */
var visited = getNumberofVisitedNodesByArray(succs),
rowShift = succs.length / 2;

if (sn.visited === false) {
sn.row = succRow;
sn.visited = true;
succRow++;
/* Shift nodes before and after the branch. */
/* But only if there are more than one successor. */
if ((succs.length - visited) > 1) {
shiftNodesByRows(tsNodes, rowShift, n.col, n.row);
shiftNodesByRows(tsNodes, rowShift, n.col, n.row + 1);
}
});
} else {
succs.forEach(function (sn) {
sn.row = n.row;
});
}

var succRow = n.row - rowShift + visited;
succs.forEach(function (sn) {
if (succs.length % 2 === 0 && succRow === n.row) {
succRow++;
}

if (sn.visited === false) {
sn.row = succRow;
sn.visited = true;
succRow++;
}
});
} else {
succs.forEach(function (sn) {
sn.row = n.row;
});
}
});
});
});
} else {
console.log("Error: Graph is not acyclic!");
}
});
} else {
console.log("Error: Graph is not acyclic!");
}
});

/* Create workflow grid. */
graph.saNodes.forEach(function (san) {
/* Create workflow grid. */
graph.saNodes.forEach(function (san) {

/* Initialize workflow dimensions. */
san.l.depth = d3.max(san.children.values(), function (n) {
return n.col;
}) + 1;
san.l.width = d3.max(san.children.values(), function (n) {
return n.row;
}) + 1;
/* Initialize workflow dimensions. */
san.l.depth = d3.max(san.children.values(), function (n) {
return n.col;
}) + 1;
san.l.width = d3.max(san.children.values(), function (n) {
return n.row;
}) + 1;

/* Init grid. */
initNodeGrid(san);
/* Init grid. */
initNodeGrid(san);

/* Set grid cells. */
san.children.values().forEach(function (n) {
san.l.grid[n.col][n.row] = n;
/* Set grid cells. */
san.children.values().forEach(function (n) {
san.l.grid[n.col][n.row] = n;
});
});
});

} else {
console.log("Error: Graph is not acyclic!");
}
};

/**
Expand Down
9 changes: 8 additions & 1 deletion refinery/ui/src/js/provvis_render.js
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,7 @@ var provvisRender = function () {
updateLink(d.parent, d.parent.x, d.parent.y);

} else {
/* If the selected subanalysis is the last remaining to collapse, adjust bounding box. */
/* If the selected subanalysis is the last remaining to collapse, adjust bounding box and clippath. */
if (!d.parent.parent.children.values().some(function (san) {
return san.hidden;
})) {
Expand All @@ -1713,6 +1713,13 @@ var provvisRender = function () {
.attr("height", function () {
return anBBoxCoords.y.max - anBBoxCoords.y.min;
});

/* Adjust clippath. */
d3.select("#aBBClipId-"+d.parent.parent.autoId).select("rect")
.attr("width", cell.width - 4)
.attr("height", cell.height - 2)
.attr("rx", cell.width / 3)
.attr("ry", cell.height / 3);
}
/* Update links. */
updateLink(d.parent.parent, d.parent.parent.x, d.parent.parent.y);
Expand Down

0 comments on commit e83f5d4

Please sign in to comment.