424 lines
8.5 KiB
HTML
424 lines
8.5 KiB
HTML
<!doctype html>
|
|
|
|
<meta charset="utf-8">
|
|
<title>Graph Storyboard. Add and Prune Dependencies Algorithm</title>
|
|
|
|
<script src="../dagre-d3.js"></script>
|
|
|
|
<style id="css">
|
|
h1 {
|
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
|
|
margin-top: 0.8em;
|
|
margin-bottom: 0.2em;
|
|
}
|
|
|
|
text {
|
|
font-weight: 300;
|
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.node rect {
|
|
stroke: #333;
|
|
fill: #fff;
|
|
stroke-width: 1.5px;
|
|
}
|
|
|
|
.node polygon {
|
|
stroke: #333;
|
|
fill: #fff;
|
|
stroke-width: 1.5px;
|
|
}
|
|
|
|
.edgePath path.path {
|
|
stroke: #333;
|
|
fill: none;
|
|
stroke-width: 1.5px;
|
|
}
|
|
|
|
div#top-frame {
|
|
height: 350px;
|
|
}
|
|
|
|
div#WBS-frame {
|
|
float: left;
|
|
width: 50%;
|
|
}
|
|
|
|
div#dependencies-frame {
|
|
float: left;
|
|
width: 50%;
|
|
}
|
|
|
|
div#schedule-frame {
|
|
float: none;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// Polyfill for PhantomJS. This can be safely ignored if not using PhantomJS.
|
|
// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
|
|
if (!Function.prototype.bind) {
|
|
Function.prototype.bind = function(oThis) {
|
|
if (typeof this !== 'function') {
|
|
// closest thing possible to the ECMAScript 5
|
|
// internal IsCallable function
|
|
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
|
|
}
|
|
|
|
var aArgs = Array.prototype.slice.call(arguments, 1),
|
|
fToBind = this,
|
|
fNOP = function() {},
|
|
fBound = function() {
|
|
return fToBind.apply(this instanceof fNOP && oThis
|
|
? this
|
|
: oThis,
|
|
aArgs.concat(Array.prototype.slice.call(arguments)));
|
|
};
|
|
|
|
fNOP.prototype = this.prototype;
|
|
fBound.prototype = new fNOP();
|
|
|
|
return fBound;
|
|
};
|
|
}
|
|
</script>
|
|
|
|
<script>
|
|
var dagred3Story = function(svgelement, graphType, interframetime) {
|
|
this.interframetime = interframetime;
|
|
this.lastrenderTime = null;
|
|
this.g = new dagreD3.graphlib.Graph().setGraph({});
|
|
//// Setup animation (if required)
|
|
//this.g.graph().transition = function(selection) {
|
|
// return selection.transition().duration(50);
|
|
//}.bind(this);
|
|
this.g.setDefaultEdgeLabel(function() { return {}; });
|
|
this.g.graph().marginx = 10;
|
|
this.g.graph().marginy = 10;
|
|
switch(graphType) {
|
|
case 'Work Breakdown Structure':
|
|
this.WBS = true;
|
|
this.Schedule = false;
|
|
this.g.graph().ranksep = 30;
|
|
this.g.graph().nodesep = 30;
|
|
break;
|
|
case 'Schedule Network':
|
|
this.Schedule = true;
|
|
this.WBS = false;
|
|
this.g.graph().rankdir = "LR";
|
|
this.g.graph().ranksep = 15;
|
|
this.g.graph().nodesep = 15;
|
|
break;
|
|
default:
|
|
console.log ("graphType of "+x+" is not implemented")
|
|
}
|
|
this.svg = d3.select(svgelement);
|
|
this.inner = this.svg.append("g");
|
|
this.svg.call(d3.behavior.zoom().on("zoom", (function() {
|
|
this.inner.attr("transform", "translate(" + d3.event.translate + ")" +
|
|
"scale(" + d3.event.scale + ")")
|
|
}).bind(this)));
|
|
|
|
this.t = 0;
|
|
|
|
this.dagreD3render = new dagreD3.render();
|
|
};
|
|
|
|
dagred3Story.prototype.animateFrame = function(RenderAfter, Frame) {
|
|
this.t += RenderAfter
|
|
//var that = this;
|
|
setTimeout(function() {
|
|
Frame.forEach(function(x) {
|
|
if (this.Schedule) {
|
|
switch(x[0]) {
|
|
case 'setActivity':
|
|
this.g.setNode(x[1],{})
|
|
break;
|
|
case 'removeNode':
|
|
this.g.removeNode(x[1])
|
|
break;
|
|
case 'setMilestone':
|
|
this.g.setNode(x[1],{ shape: 'diamond', style: "fill: #fff; stroke: #000" })
|
|
break;
|
|
case 'AddCoherenceEdge':
|
|
this.g.setEdge(x[1], x[2], {
|
|
lineInterpolate: 'basis'
|
|
});
|
|
break;
|
|
case 'AddDependencyEdge':
|
|
this.g.setEdge(x[1], x[2], {
|
|
lineInterpolate: 'basis'
|
|
,label: 'added'
|
|
,labeloffset: 5
|
|
,labelpos: 'l'
|
|
});
|
|
break;
|
|
case 'MakeRedundantEdge':
|
|
this.g.setEdge(x[1], x[2], {
|
|
style: "stroke: #aaa; stroke-dasharray: 5, 10;"
|
|
,lineInterpolate: 'basis'
|
|
,arrowheadStyle: "fill: #aaa"
|
|
,labelpos: 'c'
|
|
,label: 'pruned'
|
|
,labelStyle: 'stroke: #aaa'
|
|
});
|
|
break;
|
|
case 'RemoveEdge':
|
|
this.g.removeEdge(x[1], x[2]);
|
|
break;
|
|
default:
|
|
console.log ("Schedule Network element "+x+" is not implemented")
|
|
}
|
|
} else if (this.WBS ) {
|
|
switch(x[0]) {
|
|
case 'setComponent':
|
|
this.g.setNode(x[1],{})
|
|
break;
|
|
case 'AddWBSEdge':
|
|
this.g.setEdge(x[1], x[2], {
|
|
arrowhead: 'undirected'
|
|
});
|
|
break;
|
|
default:
|
|
console.log ("WBS element "+x+" is not implemented")
|
|
}
|
|
}
|
|
}.bind(this))
|
|
|
|
if (this.g) {
|
|
// Render
|
|
this.dagreD3render(this.inner,this.g);
|
|
}
|
|
}.bind(this), this.t)
|
|
};
|
|
|
|
dagred3Story.prototype.animateStory = function(RenderAfter, Story) {
|
|
this.t += RenderAfter
|
|
setTimeout(function() {
|
|
Story.forEach(function(Frame) {
|
|
this.animateFrame(this.interframetime, Frame);
|
|
}.bind(this))
|
|
}.bind(this), this.t)
|
|
};
|
|
|
|
</script>
|
|
|
|
<div id="top-frame">
|
|
<div id="WBS-frame">
|
|
<h1>WBS</h1>
|
|
<svg id="WBS" width=250 height=250></svg>
|
|
</div>
|
|
|
|
<div id="dependencies-frame">
|
|
<h1>Sequencing</h1>
|
|
<svg id="dependencies" width=300 height=250></svg>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="schedule-frame">
|
|
<h1>Coherent Schedule Network</h1>
|
|
<svg id="schedule" width=1150 height=500></svg>
|
|
</div>
|
|
|
|
<script id="js">
|
|
var framedelay = 2000;
|
|
var dependenciesstory = new dagred3Story("#dependencies", "Schedule Network", framedelay);
|
|
dependenciesstory.animateStory(0,
|
|
[
|
|
[
|
|
|
|
],[
|
|
|
|
],[
|
|
|
|
],[
|
|
|
|
]
|
|
,[
|
|
["setActivity", "A.1"]
|
|
,
|
|
["setMilestone", "A.2 Start"]
|
|
,
|
|
["AddDependencyEdge", "A.1", "A.2 Start"]
|
|
],[
|
|
|
|
],[
|
|
|
|
],[
|
|
|
|
],[
|
|
|
|
],[
|
|
["setActivity", "A.2.2"]
|
|
,
|
|
["setActivity", "A.2.3"]
|
|
,
|
|
["AddDependencyEdge", "A.2.2", "A.2.3"]
|
|
],[
|
|
|
|
],[
|
|
|
|
],[
|
|
|
|
],[
|
|
|
|
],[
|
|
["setActivity", "A.2.1"]
|
|
,
|
|
["setActivity", "B"]
|
|
,
|
|
["AddDependencyEdge", "A.2.1", "B"]
|
|
],[
|
|
|
|
],[
|
|
|
|
]
|
|
]);
|
|
|
|
var WBSstory = new dagred3Story("#WBS", "Work Breakdown Structure", framedelay);
|
|
|
|
WBSstory.animateStory(0,
|
|
[
|
|
[
|
|
["setComponent", "Project"]
|
|
],[
|
|
["setComponent", "A"]
|
|
,
|
|
["AddWBSEdge", "Project", "A"]
|
|
,
|
|
["setComponent", "B"]
|
|
,
|
|
["AddWBSEdge", "Project", "B"]
|
|
],[
|
|
["setComponent", "A.1"]
|
|
,
|
|
["AddWBSEdge", "A", "A.1"]
|
|
,
|
|
["setComponent", "A.2"]
|
|
,
|
|
["AddWBSEdge", "A", "A.2"]
|
|
],[
|
|
["setComponent", "A.2.1"]
|
|
,
|
|
["AddWBSEdge", "A.2", "A.2.1"]
|
|
,
|
|
["setComponent", "A.2.2"]
|
|
,
|
|
["AddWBSEdge", "A.2", "A.2.2"]
|
|
,
|
|
["setComponent", "A.2.3"]
|
|
,
|
|
["AddWBSEdge", "A.2", "A.2.3"]
|
|
]
|
|
]);
|
|
|
|
var schedulestory = new dagred3Story("#schedule", "Schedule Network",framedelay);
|
|
|
|
// Create the input graph
|
|
|
|
schedulestory.animateStory(0,
|
|
[
|
|
[
|
|
["setActivity", "Project"]
|
|
],[
|
|
["removeNode", "Project"]
|
|
,
|
|
["setMilestone", "Project Finish"]
|
|
,
|
|
["setMilestone", "Project Start"]
|
|
,
|
|
["setActivity", "A"]
|
|
,
|
|
["setActivity", "B"]
|
|
,
|
|
["AddCoherenceEdge", "Project Start", "A"]
|
|
,
|
|
["AddCoherenceEdge", "Project Start", "B"]
|
|
,
|
|
["AddCoherenceEdge", "A", "Project Finish"]
|
|
,
|
|
["AddCoherenceEdge", "B", "Project Finish"]
|
|
],[
|
|
["removeNode", "A"]
|
|
,
|
|
["setMilestone", "A Start"]
|
|
,
|
|
["setActivity", "A.1"]
|
|
,
|
|
["setActivity", "A.2"]
|
|
,
|
|
["setMilestone", "A Finish"]
|
|
,
|
|
["AddCoherenceEdge", "A Start", "A.1"]
|
|
,
|
|
["AddCoherenceEdge", "A Start", "A.2"]
|
|
,
|
|
["AddCoherenceEdge", "A.1", "A Finish"]
|
|
,
|
|
["AddCoherenceEdge", "A.2", "A Finish"]
|
|
,
|
|
["AddCoherenceEdge", "Project Start", "A Start"]
|
|
,
|
|
["AddCoherenceEdge", "A Finish", "Project Finish"]
|
|
],[
|
|
["removeNode", "A.2"]
|
|
,
|
|
["setMilestone", "A.2 Start"]
|
|
,
|
|
["setActivity", "A.2.1"]
|
|
,
|
|
["setActivity", "A.2.2"]
|
|
,
|
|
["setActivity", "A.2.3"]
|
|
,
|
|
["setMilestone", "A.2 Finish"]
|
|
,
|
|
["AddCoherenceEdge", "A.2 Start", "A.2.1"]
|
|
,
|
|
["AddCoherenceEdge", "A.2 Start", "A.2.2"]
|
|
,
|
|
["AddCoherenceEdge", "A.2 Start", "A.2.3"]
|
|
,
|
|
["AddCoherenceEdge", "A.2.1", "A.2 Finish"]
|
|
,
|
|
["AddCoherenceEdge", "A.2.2", "A.2 Finish"]
|
|
,
|
|
["AddCoherenceEdge", "A.2.3", "A.2 Finish"]
|
|
,
|
|
["AddCoherenceEdge", "A Start", "A.2 Start"]
|
|
,
|
|
["AddCoherenceEdge", "A.2 Finish", "A Finish"]
|
|
]
|
|
,[
|
|
["AddDependencyEdge", "A.1", "A.2 Start"]
|
|
],[
|
|
["MakeRedundantEdge", "A Start", "A.2 Start"]
|
|
],[
|
|
["MakeRedundantEdge", "A.1", "A Finish"]
|
|
],[
|
|
["RemoveEdge", "A Start", "A.2 Start"]
|
|
],[
|
|
["RemoveEdge", "A.1", "A Finish"]
|
|
],[
|
|
["AddDependencyEdge", "A.2.2", "A.2.3"]
|
|
],[
|
|
["MakeRedundantEdge", "A.2 Start", "A.2.3"]
|
|
],[
|
|
["MakeRedundantEdge", "A.2.2", "A.2 Finish"]
|
|
],[
|
|
["RemoveEdge", "A.2 Start", "A.2.3"]
|
|
],[
|
|
["RemoveEdge", "A.2.2", "A.2 Finish"]
|
|
],[
|
|
["AddDependencyEdge", "A.2.1", "B"]
|
|
],[
|
|
["MakeRedundantEdge", "Project Start", "B"]
|
|
],[
|
|
["RemoveEdge", "Project Start", "B"]
|
|
]
|
|
]);
|
|
</script>
|
|
</body>
|
|
</html>
|