Remove dagre-d3/demo
which breaks the devstack installation
Change-Id: I8a70d421fa29c57a6c5e46ae173f6f2faaadce57 Closes-Bug: 1606783
This commit is contained in:
parent
fec57db018
commit
6b896d5a1d
@ -1,76 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Demo: Arrows</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<style id="css">
|
|
||||||
body {
|
|
||||||
font: 300 14px 'Helvetica Neue', Helvetica;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node rect,
|
|
||||||
.node circle,
|
|
||||||
.node ellipse {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #fff;
|
|
||||||
stroke-width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #333;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1>Dagre D3 Demo: Arrows</h1>
|
|
||||||
|
|
||||||
<svg width=960 height=600><g/></svg>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<p>A sample that shows the different arrows available in dagre-d3.
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script id="js">
|
|
||||||
// Create a new directed graph
|
|
||||||
var g = new dagreD3.graphlib.Graph().setGraph({});
|
|
||||||
|
|
||||||
["normal", "vee"].forEach(function(arrowhead) {
|
|
||||||
g.setNode(arrowhead + "1", { label: " " });
|
|
||||||
g.setNode(arrowhead + "2", { label: " " });
|
|
||||||
g.setEdge(arrowhead + "1", arrowhead + "2", {
|
|
||||||
arrowhead: arrowhead,
|
|
||||||
label: arrowhead
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
inner = svg.select("g");
|
|
||||||
|
|
||||||
// Set up zoom support
|
|
||||||
var zoom = d3.behavior.zoom().on("zoom", function() {
|
|
||||||
inner.attr("transform", "translate(" + d3.event.translate + ")" +
|
|
||||||
"scale(" + d3.event.scale + ")");
|
|
||||||
});
|
|
||||||
svg.call(zoom);
|
|
||||||
|
|
||||||
// Create the renderer
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
|
||||||
render(inner, g);
|
|
||||||
|
|
||||||
// Center the graph
|
|
||||||
var initialScale = 0.75;
|
|
||||||
zoom
|
|
||||||
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
|
|
||||||
.scale(initialScale)
|
|
||||||
.event(svg);
|
|
||||||
svg.attr('height', g.graph().height * initialScale + 40);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="demo.js"></script>
|
|
@ -1,35 +0,0 @@
|
|||||||
body {
|
|
||||||
width: 960px;
|
|
||||||
margin: 0 auto;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 300;
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 3em;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 1.5em;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
section {
|
|
||||||
margin-bottom: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
section p {
|
|
||||||
text-align: justify;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
/*var bodyElem = d3.select('body'),
|
|
||||||
jsElem = d3.select('#js'),
|
|
||||||
jsPanel = bodyElem.append('div').attr('id', 'jsPanel');
|
|
||||||
cssElem = d3.select('#css'),
|
|
||||||
cssPanel = bodyElem.append('div').attr('id', 'cssPanel');
|
|
||||||
|
|
||||||
function setupPanel(panel, elem, title) {
|
|
||||||
panel.append('h2').text(title);
|
|
||||||
return panel.append('pre').append('code').text(elem.html().trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
var jsCode = setupPanel(jsPanel, jsElem, 'JavaScript');
|
|
||||||
var cssCode = setupPanel(cssPanel, cssElem, 'CSS');
|
|
||||||
|
|
||||||
var hljsRoot = 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1';
|
|
||||||
|
|
||||||
bodyElem.append('link')
|
|
||||||
.attr('rel', 'stylesheet')
|
|
||||||
.attr('href', hljsRoot + '/styles/xcode.min.css');
|
|
||||||
bodyElem.append('script')
|
|
||||||
.attr('src', hljsRoot + '/highlight.min.js')
|
|
||||||
.on('load', function() {
|
|
||||||
hljs.highlightBlock(jsCode.node());
|
|
||||||
hljs.highlightBlock(cssCode.node());
|
|
||||||
});
|
|
||||||
*/
|
|
@ -1,99 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Demo: DOM Example</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<h1>Dagre D3 Demo: DOM Example</h1>
|
|
||||||
|
|
||||||
<style id="css">
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path {
|
|
||||||
stroke: #333;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-spacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table td {
|
|
||||||
padding: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table td:first-child {
|
|
||||||
background-color: #afa;
|
|
||||||
border-top: 1px solid #333;
|
|
||||||
border-left: 1px solid #333;
|
|
||||||
border-bottom: 1px solid #333;
|
|
||||||
border-radius: 5px 0 0 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table td:last-child {
|
|
||||||
background-color: #faa;
|
|
||||||
border-top: 1px solid #333;
|
|
||||||
border-right: 1px solid #333;
|
|
||||||
border-bottom: 1px solid #333;
|
|
||||||
border-radius: 0 5px 5px 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<svg width=960 height=600></svg>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<p>A sample showing how to use DOM nodes in a graph. Note that IE does not
|
|
||||||
support this technique.
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script id="js">
|
|
||||||
// Create a new directed graph
|
|
||||||
var g = new dagreD3.graphlib.Graph().setGraph({});
|
|
||||||
|
|
||||||
g.setNode("root", {
|
|
||||||
label: function() {
|
|
||||||
var table = document.createElement("table"),
|
|
||||||
tr = d3.select(table).append("tr");
|
|
||||||
tr.append("td").text("A");
|
|
||||||
tr.append("td").text("B");
|
|
||||||
return table;
|
|
||||||
},
|
|
||||||
padding: 0,
|
|
||||||
rx: 5,
|
|
||||||
ry: 5
|
|
||||||
});
|
|
||||||
g.setNode("A", { label: "A", fill: "#afa" });
|
|
||||||
g.setNode("B", { label: "B", fill: "#faa" });
|
|
||||||
g.setEdge("root", "A", {});
|
|
||||||
g.setEdge("root", "B", {});
|
|
||||||
|
|
||||||
// Create the renderer
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Set up an SVG group so that we can translate the final graph.
|
|
||||||
var svg = d3.select('svg'),
|
|
||||||
svgGroup = svg.append('g');
|
|
||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
|
||||||
render(svgGroup, g);
|
|
||||||
|
|
||||||
// Center the graph
|
|
||||||
var xCenterOffset = (svg.attr('width') - g.graph().width) / 2;
|
|
||||||
svgGroup.attr('transform', 'translate(' + xCenterOffset + ', 20)');
|
|
||||||
svg.attr('height', g.graph().height + 40);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="demo.js"></script>
|
|
@ -1,285 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Renderer Demo</title>
|
|
||||||
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
body {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
|
|
||||||
background: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@-webkit-keyframes flash {
|
|
||||||
0%, 50%, 100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
25%, 75% {
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes flash {
|
|
||||||
0%, 50%, 100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
25%, 75% {
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.warn {
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-fill-mode: both;
|
|
||||||
animation-fill-mode: both;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map text {
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .node rect {
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
stroke: #bbb;
|
|
||||||
fill: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .status {
|
|
||||||
height: 100%;
|
|
||||||
width: 15px;
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
border-top-left-radius: 5px;
|
|
||||||
border-bottom-left-radius: 5px;
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .running .status {
|
|
||||||
background-color: #7f7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .running.warn .status {
|
|
||||||
background-color: #ffed68;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .stopped .status {
|
|
||||||
background-color: #f77;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .warn .queue {
|
|
||||||
color: #f77;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warn {
|
|
||||||
-webkit-animation-name: flash;
|
|
||||||
animation-name: flash;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .consumers {
|
|
||||||
margin-right: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .consumers,
|
|
||||||
.live.map .name {
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .consumers:after {
|
|
||||||
content: "x";
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .queue {
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
width: 130px;
|
|
||||||
height: 20px;
|
|
||||||
font-size: 12px;
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .node g div {
|
|
||||||
width: 200px;
|
|
||||||
height: 40px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .node g div span.consumers {
|
|
||||||
display: inline-block;
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .edgeLabel text {
|
|
||||||
width: 50px;
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.live.map .edgePath path {
|
|
||||||
stroke: #999;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
fill: #999;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="live map">
|
|
||||||
<svg><g/></svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var workers = {
|
|
||||||
"identifier": {
|
|
||||||
"consumers": 2,
|
|
||||||
"count": 20
|
|
||||||
},
|
|
||||||
"lost-and-found": {
|
|
||||||
"consumers": 1,
|
|
||||||
"count": 1,
|
|
||||||
"inputQueue": "identifier",
|
|
||||||
"inputThroughput": 50
|
|
||||||
},
|
|
||||||
"monitor": {
|
|
||||||
"consumers": 1,
|
|
||||||
"count": 0,
|
|
||||||
"inputQueue": "identifier",
|
|
||||||
"inputThroughput": 50
|
|
||||||
},
|
|
||||||
"meta-enricher": {
|
|
||||||
"consumers": 4,
|
|
||||||
"count": 9900,
|
|
||||||
"inputQueue": "identifier",
|
|
||||||
"inputThroughput": 50
|
|
||||||
},
|
|
||||||
"geo-enricher": {
|
|
||||||
"consumers": 2,
|
|
||||||
"count": 1,
|
|
||||||
"inputQueue": "meta-enricher",
|
|
||||||
"inputThroughput": 50
|
|
||||||
},
|
|
||||||
"elasticsearch-writer": {
|
|
||||||
"consumers": 0,
|
|
||||||
"count": 9900,
|
|
||||||
"inputQueue": "geo-enricher",
|
|
||||||
"inputThroughput": 50
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set up zoom support
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
inner = svg.select("g"),
|
|
||||||
zoom = d3.behavior.zoom().on("zoom", function() {
|
|
||||||
inner.attr("transform", "translate(" + d3.event.translate + ")" +
|
|
||||||
"scale(" + d3.event.scale + ")");
|
|
||||||
});
|
|
||||||
svg.call(zoom);
|
|
||||||
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Left-to-right layout
|
|
||||||
var g = new dagreD3.graphlib.Graph();
|
|
||||||
g.setGraph({
|
|
||||||
nodesep: 70,
|
|
||||||
ranksep: 50,
|
|
||||||
rankdir: "LR",
|
|
||||||
marginx: 20,
|
|
||||||
marginy: 20
|
|
||||||
});
|
|
||||||
|
|
||||||
function draw(isUpdate) {
|
|
||||||
for (var id in workers) {
|
|
||||||
var worker = workers[id];
|
|
||||||
var className = worker.consumers ? "running" : "stopped";
|
|
||||||
if (worker.count > 10000) {
|
|
||||||
className += " warn";
|
|
||||||
}
|
|
||||||
var html = "<div>";
|
|
||||||
html += "<span class=status></span>";
|
|
||||||
html += "<span class=consumers>"+worker.consumers+"</span>";
|
|
||||||
html += "<span class=name>"+id+"</span>";
|
|
||||||
html += "<span class=queue><span class=counter>"+worker.count+"</span></span>";
|
|
||||||
html += "</div>";
|
|
||||||
g.setNode(id, {
|
|
||||||
labelType: "html",
|
|
||||||
label: html,
|
|
||||||
rx: 5,
|
|
||||||
ry: 5,
|
|
||||||
padding: 0,
|
|
||||||
class: className
|
|
||||||
});
|
|
||||||
|
|
||||||
if (worker.inputQueue) {
|
|
||||||
g.setEdge(worker.inputQueue, id, {
|
|
||||||
label: worker.inputThroughput + "/s",
|
|
||||||
width: 40
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner.call(render, g);
|
|
||||||
|
|
||||||
// Zoom and scale to fit
|
|
||||||
var zoomScale = zoom.scale();
|
|
||||||
var graphWidth = g.graph().width + 80;
|
|
||||||
var graphHeight = g.graph().height + 40;
|
|
||||||
var width = parseInt(svg.style("width").replace(/px/, ""));
|
|
||||||
var height = parseInt(svg.style("height").replace(/px/, ""));
|
|
||||||
zoomScale = Math.min(width / graphWidth, height / graphHeight);
|
|
||||||
var translate = [(width/2) - ((graphWidth*zoomScale)/2), (height/2) - ((graphHeight*zoomScale)/2)];
|
|
||||||
zoom.translate(translate);
|
|
||||||
zoom.scale(zoomScale);
|
|
||||||
zoom.event(isUpdate ? svg.transition().duration(500) : d3.select("svg"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do some mock queue status updates
|
|
||||||
setInterval(function() {
|
|
||||||
var stoppedWorker1Count = workers["elasticsearch-writer"].count;
|
|
||||||
var stoppedWorker2Count = workers["meta-enricher"].count;
|
|
||||||
for (var id in workers) {
|
|
||||||
workers[id].count = Math.ceil(Math.random() * 3);
|
|
||||||
if (workers[id].inputThroughput) workers[id].inputThroughput = Math.ceil(Math.random() * 250);
|
|
||||||
}
|
|
||||||
workers["elasticsearch-writer"].count = stoppedWorker1Count + Math.ceil(Math.random() * 100);
|
|
||||||
workers["meta-enricher"].count = stoppedWorker2Count + Math.ceil(Math.random() * 100);
|
|
||||||
draw(true);
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
// Do a mock change of worker configuration
|
|
||||||
setInterval(function() {
|
|
||||||
workers["elasticsearch-monitor"] = {
|
|
||||||
"consumers": 0,
|
|
||||||
"count": 0,
|
|
||||||
"inputQueue": "elasticsearch-writer",
|
|
||||||
"inputThroughput": 50
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
draw();
|
|
||||||
</script>
|
|
@ -1,197 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Demo: Tooltip on Hover</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<!-- Pull in JQuery dependencies -->
|
|
||||||
<link rel="stylesheet" href="tipsy.css">
|
|
||||||
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
|
|
||||||
<script src="tipsy.js"></script>
|
|
||||||
|
|
||||||
<h1>Dagre D3 Demo: Tooltip on Hover</h1>
|
|
||||||
|
|
||||||
<style id="css">
|
|
||||||
text {
|
|
||||||
font-weight: 300;
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node rect {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #333;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node text {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This styles the title of the tooltip */
|
|
||||||
.tipsy .name {
|
|
||||||
font-size: 1.5em;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #60b1fc;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This styles the body of the tooltip */
|
|
||||||
.tipsy .description {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<svg width=960 height=600></svg>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<p>The TCP state diagram
|
|
||||||
(<a href="http://www.rfc-editor.org/rfc/rfc793.txt">source: RFC 793</a>) with
|
|
||||||
hover support. Uses <a href="http://bl.ocks.org/ilyabo/1373263">tipsy JS and CSS</a>
|
|
||||||
for the tooltip.
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script id="js">
|
|
||||||
// Create a new directed graph
|
|
||||||
var g = new dagreD3.graphlib.Graph().setGraph({});
|
|
||||||
|
|
||||||
// States and transitions from RFC 793
|
|
||||||
var states = {
|
|
||||||
CLOSED: {
|
|
||||||
description: "represents no connection state at all.",
|
|
||||||
style: "fill: #f77"
|
|
||||||
},
|
|
||||||
|
|
||||||
LISTEN: {
|
|
||||||
description: "represents waiting for a connection request from any " +
|
|
||||||
"remote TCP and port."
|
|
||||||
},
|
|
||||||
|
|
||||||
"SYN SENT": {
|
|
||||||
description: "represents waiting for a matching connection " +
|
|
||||||
"request after having sent a connection request."
|
|
||||||
},
|
|
||||||
|
|
||||||
"SYN RCVD": {
|
|
||||||
description: "represents waiting for a confirming connection " +
|
|
||||||
"request acknowledgment after having both received and sent a " +
|
|
||||||
"connection request."
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
ESTAB: {
|
|
||||||
description: "represents an open connection, data received " +
|
|
||||||
"can be delivered to the user. The normal state for the data " +
|
|
||||||
"transfer phase of the connection.",
|
|
||||||
style: "fill: #7f7"
|
|
||||||
},
|
|
||||||
|
|
||||||
"FINWAIT-1": {
|
|
||||||
description: "represents waiting for a connection termination " +
|
|
||||||
"request from the remote TCP, or an acknowledgment of the " +
|
|
||||||
"connection termination request previously sent."
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
"FINWAIT-2": {
|
|
||||||
description: "represents waiting for a connection termination " +
|
|
||||||
"request from the remote TCP."
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
"CLOSE WAIT": {
|
|
||||||
description: "represents waiting for a connection termination " +
|
|
||||||
"request from the local user."
|
|
||||||
},
|
|
||||||
|
|
||||||
CLOSING: {
|
|
||||||
description: "represents waiting for a connection termination " +
|
|
||||||
"request acknowledgment from the remote TCP."
|
|
||||||
},
|
|
||||||
|
|
||||||
"LAST-ACK": {
|
|
||||||
description: "represents waiting for an acknowledgment of the " +
|
|
||||||
"connection termination request previously sent to the remote " +
|
|
||||||
"TCP (which includes an acknowledgment of its connection " +
|
|
||||||
"termination request)."
|
|
||||||
},
|
|
||||||
|
|
||||||
"TIME WAIT": {
|
|
||||||
description: "represents waiting for enough time to pass to be " +
|
|
||||||
"sure the remote TCP received the acknowledgment of its " +
|
|
||||||
"connection termination request."
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add states to the graph, set labels, and style
|
|
||||||
Object.keys(states).forEach(function(state) {
|
|
||||||
var value = states[state];
|
|
||||||
value.label = state;
|
|
||||||
value.rx = value.ry = 5;
|
|
||||||
g.setNode(state, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up the edges
|
|
||||||
g.setEdge("CLOSED", "LISTEN", { label: "open" });
|
|
||||||
g.setEdge("LISTEN", "SYN RCVD", { label: "rcv SYN" });
|
|
||||||
g.setEdge("LISTEN", "SYN SENT", { label: "send" });
|
|
||||||
g.setEdge("LISTEN", "CLOSED", { label: "close" });
|
|
||||||
g.setEdge("SYN RCVD", "FINWAIT-1", { label: "close" });
|
|
||||||
g.setEdge("SYN RCVD", "ESTAB", { label: "rcv ACK of SYN" });
|
|
||||||
g.setEdge("SYN SENT", "SYN RCVD", { label: "rcv SYN" });
|
|
||||||
g.setEdge("SYN SENT", "ESTAB", { label: "rcv SYN, ACK" });
|
|
||||||
g.setEdge("SYN SENT", "CLOSED", { label: "close" });
|
|
||||||
g.setEdge("ESTAB", "FINWAIT-1", { label: "close" });
|
|
||||||
g.setEdge("ESTAB", "CLOSE WAIT", { label: "rcv FIN" });
|
|
||||||
g.setEdge("FINWAIT-1", "FINWAIT-2", { label: "rcv ACK of FIN" });
|
|
||||||
g.setEdge("FINWAIT-1", "CLOSING", { label: "rcv FIN" });
|
|
||||||
g.setEdge("CLOSE WAIT", "LAST-ACK", { label: "close" });
|
|
||||||
g.setEdge("FINWAIT-2", "TIME WAIT", { label: "rcv FIN" });
|
|
||||||
g.setEdge("CLOSING", "TIME WAIT", { label: "rcv ACK of FIN" });
|
|
||||||
g.setEdge("LAST-ACK", "CLOSED", { label: "rcv ACK of FIN" });
|
|
||||||
g.setEdge("TIME WAIT", "CLOSED", { label: "timeout=2MSL" });
|
|
||||||
|
|
||||||
// Create the renderer
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Set up an SVG group so that we can translate the final graph.
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
inner = svg.append("g");
|
|
||||||
|
|
||||||
// Set up zoom support
|
|
||||||
var zoom = d3.behavior.zoom().on("zoom", function() {
|
|
||||||
inner.attr("transform", "translate(" + d3.event.translate + ")" +
|
|
||||||
"scale(" + d3.event.scale + ")");
|
|
||||||
});
|
|
||||||
svg.call(zoom);
|
|
||||||
|
|
||||||
// Simple function to style the tooltip for the given node.
|
|
||||||
var styleTooltip = function(name, description) {
|
|
||||||
return "<p class='name'>" + name + "</p><p class='description'>" + description + "</p>";
|
|
||||||
};
|
|
||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
|
||||||
render(inner, g);
|
|
||||||
|
|
||||||
inner.selectAll("g.node")
|
|
||||||
.attr("title", function(v) { return styleTooltip(v, g.node(v).description) })
|
|
||||||
.each(function(v) { $(this).tipsy({ gravity: "w", opacity: 1, html: true }); });
|
|
||||||
|
|
||||||
// Center the graph
|
|
||||||
var initialScale = 0.75;
|
|
||||||
zoom
|
|
||||||
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
|
|
||||||
.scale(initialScale)
|
|
||||||
.event(svg);
|
|
||||||
svg.attr('height', g.graph().height * initialScale + 40);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="demo.js"></script>
|
|
@ -1,173 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre Interactive Demo</title>
|
|
||||||
|
|
||||||
<script src="http://d3js.org/d3.v3.js"></script>
|
|
||||||
<script src="http://cpettitt.github.io/project/graphlib-dot/v0.5.2/graphlib-dot.js"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
svg {
|
|
||||||
border: 1px solid #999;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node rect,
|
|
||||||
.node cicrce,
|
|
||||||
.node ellipse {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #fff;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cluster rect {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #000;
|
|
||||||
fill-opacity: 0.1;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path.path {
|
|
||||||
stroke: #333;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
fill: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
h1, h2 {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
margin-top: 1em;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<body onLoad="tryDraw();">
|
|
||||||
|
|
||||||
<h1>Dagre Interactive Demo</h1>
|
|
||||||
|
|
||||||
<h2>Input</h2>
|
|
||||||
|
|
||||||
<form>
|
|
||||||
<label for="inputGraph">Graphviz Definition</label>
|
|
||||||
<textarea id="inputGraph" rows="5" style="display: block" onKeyUp="tryDraw();">
|
|
||||||
/* Example */
|
|
||||||
digraph {
|
|
||||||
/* Note: HTML labels do not work in IE, which lacks support for <foreignObject> tags. */
|
|
||||||
node [rx=5 ry=5 labelStyle="font: 300 14px 'Helvetica Neue', Helvetica"]
|
|
||||||
edge [labelStyle="font: 300 14px 'Helvetica Neue', Helvetica"]
|
|
||||||
A [labelType="html"
|
|
||||||
label="A <span style='font-size:32px'>Big</span> <span style='color:red;'>HTML</span> Source!"];
|
|
||||||
C;
|
|
||||||
E [label="Bold Red Sink" style="fill: #f77; font-weight: bold"];
|
|
||||||
A -> B -> C;
|
|
||||||
B -> D [label="A blue label" labelStyle="fill: #55f; font-weight: bold;"];
|
|
||||||
D -> E [label="A thick red edge" style="stroke: #f77; stroke-width: 2px;" arrowheadStyle="fill: #f77"];
|
|
||||||
C -> E;
|
|
||||||
A -> D [labelType="html" label="A multi-rank <span style='color:blue;'>HTML</span> edge!"];
|
|
||||||
}
|
|
||||||
</textarea>
|
|
||||||
|
|
||||||
<a id="graphLink">Link for this graph</a>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<h2>Graph Visualization</h2>
|
|
||||||
|
|
||||||
<svg width=800 height=600>
|
|
||||||
<g/>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Input related code goes here
|
|
||||||
|
|
||||||
function graphToURL() {
|
|
||||||
var elems = [window.location.protocol, '//',
|
|
||||||
window.location.host,
|
|
||||||
window.location.pathname,
|
|
||||||
'?'];
|
|
||||||
|
|
||||||
var queryParams = [];
|
|
||||||
if (debugAlignment) {
|
|
||||||
queryParams.push('alignment=' + debugAlignment);
|
|
||||||
}
|
|
||||||
queryParams.push('graph=' + encodeURIComponent(inputGraph.value));
|
|
||||||
elems.push(queryParams.join('&'));
|
|
||||||
|
|
||||||
return elems.join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
var inputGraph = document.querySelector("#inputGraph");
|
|
||||||
|
|
||||||
var graphLink = d3.select("#graphLink");
|
|
||||||
|
|
||||||
var oldInputGraphValue;
|
|
||||||
|
|
||||||
var graphRE = /[?&]graph=([^&]+)/;
|
|
||||||
var graphMatch = window.location.search.match(graphRE);
|
|
||||||
if (graphMatch) {
|
|
||||||
inputGraph.value = decodeURIComponent(graphMatch[1]);
|
|
||||||
}
|
|
||||||
var debugAlignmentRE = /[?&]alignment=([^&]+)/;
|
|
||||||
var debugAlignmentMatch = window.location.search.match(debugAlignmentRE);
|
|
||||||
var debugAlignment;
|
|
||||||
if (debugAlignmentMatch) debugAlignment = debugAlignmentMatch[1];
|
|
||||||
|
|
||||||
// Set up zoom support
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
inner = d3.select("svg g"),
|
|
||||||
zoom = d3.behavior.zoom().on("zoom", function() {
|
|
||||||
inner.attr("transform", "translate(" + d3.event.translate + ")" +
|
|
||||||
"scale(" + d3.event.scale + ")");
|
|
||||||
});
|
|
||||||
svg.call(zoom);
|
|
||||||
|
|
||||||
// Create and configure the renderer
|
|
||||||
var render = dagreD3.render();
|
|
||||||
|
|
||||||
function tryDraw() {
|
|
||||||
var g;
|
|
||||||
if (oldInputGraphValue !== inputGraph.value) {
|
|
||||||
inputGraph.setAttribute("class", "");
|
|
||||||
oldInputGraphValue = inputGraph.value;
|
|
||||||
try {
|
|
||||||
g = graphlibDot.read(inputGraph.value);
|
|
||||||
} catch (e) {
|
|
||||||
inputGraph.setAttribute("class", "error");
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save link to new graph
|
|
||||||
graphLink.attr("href", graphToURL());
|
|
||||||
|
|
||||||
// Set margins, if not present
|
|
||||||
if (!g.graph().hasOwnProperty("marginx") &&
|
|
||||||
!g.graph().hasOwnProperty("marginy")) {
|
|
||||||
g.graph().marginx = 20;
|
|
||||||
g.graph().marginy = 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
g.graph().transition = function(selection) {
|
|
||||||
return selection.transition().duration(500);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Render the graph into svg g
|
|
||||||
d3.select("svg g").call(render, g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,105 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Demo: Sentence Tokenization</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<h1>Dagre D3 Demo: Sentence Tokenization</h1>
|
|
||||||
|
|
||||||
<style id="css">
|
|
||||||
/* This sets the color for "TK" nodes to a light blue green. */
|
|
||||||
g.type-TK > rect {
|
|
||||||
fill: #00ffd0;
|
|
||||||
}
|
|
||||||
|
|
||||||
text {
|
|
||||||
font-weight: 300;
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node rect {
|
|
||||||
stroke: #999;
|
|
||||||
fill: #fff;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path {
|
|
||||||
stroke: #333;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<svg id="svg-canvas" width=960 height=600></svg>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<p>An example of visualizing the tokenization of a sentence. This example shows
|
|
||||||
how CSS classes can be applied to a rendered graph.
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script id="js">
|
|
||||||
// Create the input graph
|
|
||||||
var g = new dagreD3.graphlib.Graph()
|
|
||||||
.setGraph({})
|
|
||||||
.setDefaultEdgeLabel(function() { return {}; });
|
|
||||||
|
|
||||||
// Here we"re setting nodeclass, which is used by our custom drawNodes function
|
|
||||||
// below.
|
|
||||||
g.setNode(0, { label: "TOP", class: "type-TOP" });
|
|
||||||
g.setNode(1, { label: "S", class: "type-S" });
|
|
||||||
g.setNode(2, { label: "NP", class: "type-NP" });
|
|
||||||
g.setNode(3, { label: "DT", class: "type-DT" });
|
|
||||||
g.setNode(4, { label: "This", class: "type-TK" });
|
|
||||||
g.setNode(5, { label: "VP", class: "type-VP" });
|
|
||||||
g.setNode(6, { label: "VBZ", class: "type-VBZ" });
|
|
||||||
g.setNode(7, { label: "is", class: "type-TK" });
|
|
||||||
g.setNode(8, { label: "NP", class: "type-NP" });
|
|
||||||
g.setNode(9, { label: "DT", class: "type-DT" });
|
|
||||||
g.setNode(10, { label: "an", class: "type-TK" });
|
|
||||||
g.setNode(11, { label: "NN", class: "type-NN" });
|
|
||||||
g.setNode(12, { label: "example", class: "type-TK" });
|
|
||||||
g.setNode(13, { label: ".", class: "type-." });
|
|
||||||
g.setNode(14, { label: "sentence", class: "type-TK" });
|
|
||||||
|
|
||||||
g.nodes().forEach(function(v) {
|
|
||||||
var node = g.node(v);
|
|
||||||
// Round the corners of the nodes
|
|
||||||
node.rx = node.ry = 5;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up edges, no special attributes.
|
|
||||||
g.setEdge(3, 4);
|
|
||||||
g.setEdge(2, 3);
|
|
||||||
g.setEdge(1, 2);
|
|
||||||
g.setEdge(6, 7);
|
|
||||||
g.setEdge(5, 6);
|
|
||||||
g.setEdge(9, 10);
|
|
||||||
g.setEdge(8, 9);
|
|
||||||
g.setEdge(11,12);
|
|
||||||
g.setEdge(8, 11);
|
|
||||||
g.setEdge(5, 8);
|
|
||||||
g.setEdge(1, 5);
|
|
||||||
g.setEdge(13,14);
|
|
||||||
g.setEdge(1, 13);
|
|
||||||
g.setEdge(0, 1)
|
|
||||||
|
|
||||||
// Create the renderer
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Set up an SVG group so that we can translate the final graph.
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
svgGroup = svg.append("g");
|
|
||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
|
||||||
render(d3.select("svg g"), g);
|
|
||||||
|
|
||||||
// Center the graph
|
|
||||||
var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
|
|
||||||
svgGroup.attr("transform", "translate(" + xCenterOffset + ", 20)");
|
|
||||||
svg.attr("height", g.graph().height + 40);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="demo.js"></script>
|
|
@ -1,71 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Demo: Shapes</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<style id="css">
|
|
||||||
body {
|
|
||||||
font: 300 14px 'Helvetica Neue', Helvetica;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node rect,
|
|
||||||
.node circle,
|
|
||||||
.node ellipse {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #fff;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #333;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1>Dagre D3 Demo: Shapes</h1>
|
|
||||||
|
|
||||||
<svg width=960 height=600><g/></svg>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<p>A sample that shows the different node shapes available in dagre-d3.
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script id="js">
|
|
||||||
// Create a new directed graph
|
|
||||||
var g = new dagreD3.graphlib.Graph().setGraph({});
|
|
||||||
|
|
||||||
g.setNode("rect", { shape: "rect" });
|
|
||||||
g.setNode("circle", { shape: "circle" });
|
|
||||||
g.setNode("ellipse", { shape: "ellipse" });
|
|
||||||
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
inner = svg.select("g");
|
|
||||||
|
|
||||||
// Set up zoom support
|
|
||||||
var zoom = d3.behavior.zoom().on("zoom", function() {
|
|
||||||
inner.attr("transform", "translate(" + d3.event.translate + ")" +
|
|
||||||
"scale(" + d3.event.scale + ")");
|
|
||||||
});
|
|
||||||
svg.call(zoom);
|
|
||||||
|
|
||||||
// Create the renderer
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
|
||||||
render(inner, g);
|
|
||||||
|
|
||||||
// Center the graph
|
|
||||||
var initialScale = 0.75;
|
|
||||||
zoom
|
|
||||||
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
|
|
||||||
.scale(initialScale)
|
|
||||||
.event(svg);
|
|
||||||
svg.attr('height', g.graph().height * initialScale + 40);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="demo.js"></script>
|
|
@ -1,80 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Demo: Style Attributes</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<h1>Dagre D3 Demo: Style Attributes</h1>
|
|
||||||
|
|
||||||
<style id="css">
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path.path {
|
|
||||||
stroke: #333;
|
|
||||||
fill: none;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<svg id="svg" width=960 height=600></svg>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<p>An example showing how styles that are set in the input graph can be applied
|
|
||||||
to nodes, node labels, edges, and edge labels in the rendered graph.
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script id="js">
|
|
||||||
// Create the input graph
|
|
||||||
var g = new dagreD3.graphlib.Graph().setGraph({});
|
|
||||||
|
|
||||||
// Fill node "A" with the color green
|
|
||||||
g.setNode("A", { style: "fill: #afa" });
|
|
||||||
|
|
||||||
// Make the label for node "B" bold
|
|
||||||
g.setNode("B", { labelStyle: "font-weight: bold" });
|
|
||||||
|
|
||||||
// Double the size of the font for node "C"
|
|
||||||
g.setNode("C", { labelStyle: "font-size: 2em" });
|
|
||||||
|
|
||||||
// Make the edge from "A" to "B" red, thick, and dashed
|
|
||||||
g.setEdge("A", "B", {
|
|
||||||
style: "stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;",
|
|
||||||
arrowheadStyle: "fill: #f66"
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make the label for the edge from "C" to "B" italic and underlined
|
|
||||||
g.setEdge("C", "B", {
|
|
||||||
label: "A to C",
|
|
||||||
labelStyle: "font-style: italic; text-decoration: underline;"
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create the renderer
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Set up an SVG group so that we can translate the final graph.
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
inner = svg.append("g");
|
|
||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
|
||||||
render(inner, g);
|
|
||||||
|
|
||||||
// Center the graph
|
|
||||||
var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
|
|
||||||
inner.attr("transform", "translate(" + xCenterOffset + ", 20)");
|
|
||||||
svg.attr("height", g.graph().height + 40);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="demo.js"></script>
|
|
@ -1,105 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Demo: TCP State Diagram</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<style id="css">
|
|
||||||
body {
|
|
||||||
font: 300 14px 'Helvetica Neue', Helvetica;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node rect {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #333;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1>Dagre D3 Demo: TCP State Diagram</h1>
|
|
||||||
|
|
||||||
<svg width=960 height=600><g/></svg>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<p>A sample rendering of a TCP state diagram
|
|
||||||
(<a href="http://www.rfc-editor.org/rfc/rfc793.txt">RFC 793</a>). This example
|
|
||||||
shows how to set custom styles in the input graph and how to set a custom
|
|
||||||
initial zoom.
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script id="js">
|
|
||||||
// Create a new directed graph
|
|
||||||
var g = new dagreD3.graphlib.Graph().setGraph({});
|
|
||||||
|
|
||||||
// States and transitions from RFC 793
|
|
||||||
var states = [ "CLOSED", "LISTEN", "SYN RCVD", "SYN SENT",
|
|
||||||
"ESTAB", "FINWAIT-1", "CLOSE WAIT", "FINWAIT-2",
|
|
||||||
"CLOSING", "LAST-ACK", "TIME WAIT" ];
|
|
||||||
|
|
||||||
// Automatically label each of the nodes
|
|
||||||
states.forEach(function(state) { g.setNode(state, { label: state }); });
|
|
||||||
|
|
||||||
// Set up the edges
|
|
||||||
g.setEdge("CLOSED", "LISTEN", { label: "open" });
|
|
||||||
g.setEdge("LISTEN", "SYN RCVD", { label: "rcv SYN" });
|
|
||||||
g.setEdge("LISTEN", "SYN SENT", { label: "send" });
|
|
||||||
g.setEdge("LISTEN", "CLOSED", { label: "close" });
|
|
||||||
g.setEdge("SYN RCVD", "FINWAIT-1", { label: "close" });
|
|
||||||
g.setEdge("SYN RCVD", "ESTAB", { label: "rcv ACK of SYN" });
|
|
||||||
g.setEdge("SYN SENT", "SYN RCVD", { label: "rcv SYN" });
|
|
||||||
g.setEdge("SYN SENT", "ESTAB", { label: "rcv SYN, ACK" });
|
|
||||||
g.setEdge("SYN SENT", "CLOSED", { label: "close" });
|
|
||||||
g.setEdge("ESTAB", "FINWAIT-1", { label: "close" });
|
|
||||||
g.setEdge("ESTAB", "CLOSE WAIT", { label: "rcv FIN" });
|
|
||||||
g.setEdge("FINWAIT-1", "FINWAIT-2", { label: "rcv ACK of FIN" });
|
|
||||||
g.setEdge("FINWAIT-1", "CLOSING", { label: "rcv FIN" });
|
|
||||||
g.setEdge("CLOSE WAIT", "LAST-ACK", { label: "close" });
|
|
||||||
g.setEdge("FINWAIT-2", "TIME WAIT", { label: "rcv FIN" });
|
|
||||||
g.setEdge("CLOSING", "TIME WAIT", { label: "rcv ACK of FIN" });
|
|
||||||
g.setEdge("LAST-ACK", "CLOSED", { label: "rcv ACK of FIN" });
|
|
||||||
g.setEdge("TIME WAIT", "CLOSED", { label: "timeout=2MSL" });
|
|
||||||
|
|
||||||
// Set some general styles
|
|
||||||
g.nodes().forEach(function(v) {
|
|
||||||
var node = g.node(v);
|
|
||||||
node.rx = node.ry = 5;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add some custom colors based on state
|
|
||||||
g.node('CLOSED').style = "fill: #f77";
|
|
||||||
g.node('ESTAB').style = "fill: #7f7";
|
|
||||||
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
inner = svg.select("g");
|
|
||||||
|
|
||||||
// Set up zoom support
|
|
||||||
var zoom = d3.behavior.zoom().on("zoom", function() {
|
|
||||||
inner.attr("transform", "translate(" + d3.event.translate + ")" +
|
|
||||||
"scale(" + d3.event.scale + ")");
|
|
||||||
});
|
|
||||||
svg.call(zoom);
|
|
||||||
|
|
||||||
// Create the renderer
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
|
||||||
render(inner, g);
|
|
||||||
|
|
||||||
// Center the graph
|
|
||||||
var initialScale = 0.75;
|
|
||||||
zoom
|
|
||||||
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
|
|
||||||
.scale(initialScale)
|
|
||||||
.event(svg);
|
|
||||||
svg.attr('height', g.graph().height * initialScale + 40);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="demo.js"></script>
|
|
@ -1,25 +0,0 @@
|
|||||||
.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; }
|
|
||||||
.tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; }
|
|
||||||
|
|
||||||
/* Rounded corners */
|
|
||||||
.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
|
|
||||||
|
|
||||||
/* Uncomment for shadow */
|
|
||||||
.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }
|
|
||||||
|
|
||||||
.tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
|
|
||||||
|
|
||||||
/* Rules to colour arrows */
|
|
||||||
.tipsy-arrow-n { border-bottom-color: #000; }
|
|
||||||
.tipsy-arrow-s { border-top-color: #000; }
|
|
||||||
.tipsy-arrow-e { border-left-color: #000; }
|
|
||||||
.tipsy-arrow-w { border-right-color: #000; }
|
|
||||||
|
|
||||||
.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
|
|
||||||
.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
|
||||||
.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
|
||||||
.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
|
||||||
.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
|
||||||
.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
|
||||||
.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
|
|
||||||
.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }
|
|
@ -1,288 +0,0 @@
|
|||||||
// tipsy, facebook style tooltips for jquery
|
|
||||||
// version 1.0.0a
|
|
||||||
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
|
|
||||||
// released under the MIT license
|
|
||||||
|
|
||||||
(function($) {
|
|
||||||
|
|
||||||
function maybeCall(thing, ctx) {
|
|
||||||
return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Tipsy(element, options) {
|
|
||||||
this.$element = $(element);
|
|
||||||
this.options = options;
|
|
||||||
this.enabled = true;
|
|
||||||
this.fixTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
Tipsy.prototype = {
|
|
||||||
show: function() {
|
|
||||||
var title = this.getTitle();
|
|
||||||
if (title && this.enabled) {
|
|
||||||
var $tip = this.tip();
|
|
||||||
|
|
||||||
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
|
|
||||||
$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
|
|
||||||
$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);
|
|
||||||
|
|
||||||
var pos = $.extend({}, this.$element.offset(), {
|
|
||||||
width: this.$element[0].offsetWidth || 0,
|
|
||||||
height: this.$element[0].offsetHeight || 0
|
|
||||||
});
|
|
||||||
|
|
||||||
if (typeof this.$element[0].nearestViewportElement == 'object') {
|
|
||||||
// SVG
|
|
||||||
var el = this.$element[0];
|
|
||||||
var rect = el.getBoundingClientRect();
|
|
||||||
pos.width = rect.width;
|
|
||||||
pos.height = rect.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var actualWidth = $tip[0].offsetWidth,
|
|
||||||
actualHeight = $tip[0].offsetHeight,
|
|
||||||
gravity = maybeCall(this.options.gravity, this.$element[0]);
|
|
||||||
|
|
||||||
var tp;
|
|
||||||
switch (gravity.charAt(0)) {
|
|
||||||
case 'n':
|
|
||||||
tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gravity.length == 2) {
|
|
||||||
if (gravity.charAt(1) == 'w') {
|
|
||||||
tp.left = pos.left + pos.width / 2 - 15;
|
|
||||||
} else {
|
|
||||||
tp.left = pos.left + pos.width / 2 - actualWidth + 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$tip.css(tp).addClass('tipsy-' + gravity);
|
|
||||||
$tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
|
|
||||||
if (this.options.className) {
|
|
||||||
$tip.addClass(maybeCall(this.options.className, this.$element[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.fade) {
|
|
||||||
$tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
|
|
||||||
} else {
|
|
||||||
$tip.css({visibility: 'visible', opacity: this.options.opacity});
|
|
||||||
}
|
|
||||||
|
|
||||||
var t = this;
|
|
||||||
var set_hovered = function(set_hover){
|
|
||||||
return function(){
|
|
||||||
t.$tip.stop();
|
|
||||||
t.tipHovered = set_hover;
|
|
||||||
if (!set_hover){
|
|
||||||
if (t.options.delayOut === 0) {
|
|
||||||
t.hide();
|
|
||||||
} else {
|
|
||||||
setTimeout(function() {
|
|
||||||
if (t.hoverState == 'out') t.hide(); }, t.options.delayOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
$tip.hover(set_hovered(true), set_hovered(false));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
hide: function() {
|
|
||||||
if (this.options.fade) {
|
|
||||||
this.tip().stop().fadeOut(function() { $(this).remove(); });
|
|
||||||
} else {
|
|
||||||
this.tip().remove();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
fixTitle: function() {
|
|
||||||
var $e = this.$element;
|
|
||||||
|
|
||||||
if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
|
|
||||||
$e.attr('original-title', $e.attr('title') || '').removeAttr('title');
|
|
||||||
}
|
|
||||||
if (typeof $e.context.nearestViewportElement == 'object'){
|
|
||||||
if ($e.children('title').length){
|
|
||||||
$e.append('<original-title>' + ($e.children('title').text() || '') + '</original-title>')
|
|
||||||
.children('title').remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getTitle: function() {
|
|
||||||
|
|
||||||
var title, $e = this.$element, o = this.options;
|
|
||||||
this.fixTitle();
|
|
||||||
|
|
||||||
if (typeof o.title == 'string') {
|
|
||||||
var title_name = o.title == 'title' ? 'original-title' : o.title;
|
|
||||||
if ($e.children(title_name).length){
|
|
||||||
title = $e.children(title_name).html();
|
|
||||||
} else{
|
|
||||||
title = $e.attr(title_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (typeof o.title == 'function') {
|
|
||||||
title = o.title.call($e[0]);
|
|
||||||
}
|
|
||||||
title = ('' + title).replace(/(^\s*|\s*$)/, "");
|
|
||||||
return title || o.fallback;
|
|
||||||
},
|
|
||||||
|
|
||||||
tip: function() {
|
|
||||||
if (!this.$tip) {
|
|
||||||
this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>');
|
|
||||||
}
|
|
||||||
return this.$tip;
|
|
||||||
},
|
|
||||||
|
|
||||||
validate: function() {
|
|
||||||
if (!this.$element[0].parentNode) {
|
|
||||||
this.hide();
|
|
||||||
this.$element = null;
|
|
||||||
this.options = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
enable: function() { this.enabled = true; },
|
|
||||||
disable: function() { this.enabled = false; },
|
|
||||||
toggleEnabled: function() { this.enabled = !this.enabled; }
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.tipsy = function(options) {
|
|
||||||
|
|
||||||
if (options === true) {
|
|
||||||
return this.data('tipsy');
|
|
||||||
} else if (typeof options == 'string') {
|
|
||||||
var tipsy = this.data('tipsy');
|
|
||||||
if (tipsy) tipsy[options]();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
options = $.extend({}, $.fn.tipsy.defaults, options);
|
|
||||||
|
|
||||||
if (options.hoverlock && options.delayOut === 0) {
|
|
||||||
options.delayOut = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
function get(ele) {
|
|
||||||
var tipsy = $.data(ele, 'tipsy');
|
|
||||||
if (!tipsy) {
|
|
||||||
tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
|
|
||||||
$.data(ele, 'tipsy', tipsy);
|
|
||||||
}
|
|
||||||
return tipsy;
|
|
||||||
}
|
|
||||||
|
|
||||||
function enter() {
|
|
||||||
var tipsy = get(this);
|
|
||||||
tipsy.hoverState = 'in';
|
|
||||||
if (options.delayIn === 0) {
|
|
||||||
tipsy.show();
|
|
||||||
} else {
|
|
||||||
tipsy.fixTitle();
|
|
||||||
setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function leave() {
|
|
||||||
var tipsy = get(this);
|
|
||||||
tipsy.hoverState = 'out';
|
|
||||||
if (options.delayOut === 0) {
|
|
||||||
tipsy.hide();
|
|
||||||
} else {
|
|
||||||
var to = function() {
|
|
||||||
if (!tipsy.tipHovered || !options.hoverlock){
|
|
||||||
if (tipsy.hoverState == 'out') tipsy.hide();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
setTimeout(to, options.delayOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.trigger != 'manual') {
|
|
||||||
var binder = options.live ? 'live' : 'bind',
|
|
||||||
eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
|
|
||||||
eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
|
|
||||||
this[binder](eventIn, enter)[binder](eventOut, leave);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.tipsy.defaults = {
|
|
||||||
className: null,
|
|
||||||
delayIn: 0,
|
|
||||||
delayOut: 0,
|
|
||||||
fade: false,
|
|
||||||
fallback: '',
|
|
||||||
gravity: 'n',
|
|
||||||
html: false,
|
|
||||||
live: false,
|
|
||||||
offset: 0,
|
|
||||||
opacity: 0.8,
|
|
||||||
title: 'title',
|
|
||||||
trigger: 'hover',
|
|
||||||
hoverlock: false
|
|
||||||
};
|
|
||||||
|
|
||||||
// Overwrite this method to provide options on a per-element basis.
|
|
||||||
// For example, you could store the gravity in a 'tipsy-gravity' attribute:
|
|
||||||
// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
|
|
||||||
// (remember - do not modify 'options' in place!)
|
|
||||||
$.fn.tipsy.elementOptions = function(ele, options) {
|
|
||||||
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.tipsy.autoNS = function() {
|
|
||||||
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.tipsy.autoWE = function() {
|
|
||||||
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* yields a closure of the supplied parameters, producing a function that takes
|
|
||||||
* no arguments and is suitable for use as an autogravity function like so:
|
|
||||||
*
|
|
||||||
* @param margin (int) - distance from the viewable region edge that an
|
|
||||||
* element should be before setting its tooltip's gravity to be away
|
|
||||||
* from that edge.
|
|
||||||
* @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
|
|
||||||
* if there are no viewable region edges effecting the tooltip's
|
|
||||||
* gravity. It will try to vary from this minimally, for example,
|
|
||||||
* if 'sw' is preferred and an element is near the right viewable
|
|
||||||
* region edge, but not the top edge, it will set the gravity for
|
|
||||||
* that element's tooltip to be 'se', preserving the southern
|
|
||||||
* component.
|
|
||||||
*/
|
|
||||||
$.fn.tipsy.autoBounds = function(margin, prefer) {
|
|
||||||
return function() {
|
|
||||||
var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
|
|
||||||
boundTop = $(document).scrollTop() + margin,
|
|
||||||
boundLeft = $(document).scrollLeft() + margin,
|
|
||||||
$this = $(this);
|
|
||||||
|
|
||||||
if ($this.offset().top < boundTop) dir.ns = 'n';
|
|
||||||
if ($this.offset().left < boundLeft) dir.ew = 'w';
|
|
||||||
if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
|
|
||||||
if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';
|
|
||||||
|
|
||||||
return dir.ns + (dir.ew ? dir.ew : '');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})(jQuery);
|
|
@ -1,115 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Dagre D3 Demo: User-defined Shapes and Arrows</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="demo.css">
|
|
||||||
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
|
|
||||||
<script src="../build/dagre-d3.js"></script>
|
|
||||||
|
|
||||||
<style id="css">
|
|
||||||
body {
|
|
||||||
font: 300 14px 'Helvetica Neue', Helvetica;
|
|
||||||
}
|
|
||||||
|
|
||||||
.node rect,
|
|
||||||
.node circle,
|
|
||||||
.node ellipse,
|
|
||||||
.node polygon {
|
|
||||||
stroke: #333;
|
|
||||||
fill: #fff;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edgePath path.path {
|
|
||||||
stroke: #333;
|
|
||||||
fill: none;
|
|
||||||
stroke-width: 1.5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1>Dagre D3 Demo: User-defined Shapes and Arrows</h1>
|
|
||||||
|
|
||||||
<svg width=960 height=600><g/></svg>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<p>An example that shows how to create and use user-defined shapes and arrows.
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script id="js">
|
|
||||||
// Create a new directed graph
|
|
||||||
var g = new dagreD3.graphlib.Graph().setGraph({});
|
|
||||||
|
|
||||||
g.setNode("house", { shape: "house", label: "house" });
|
|
||||||
g.setNode("rect", { shape: "rect" });
|
|
||||||
g.setEdge("house", "rect", { arrowhead: "hollowPoint" });
|
|
||||||
|
|
||||||
var svg = d3.select("svg"),
|
|
||||||
inner = svg.select("g");
|
|
||||||
|
|
||||||
// Set up zoom support
|
|
||||||
var zoom = d3.behavior.zoom().on("zoom", function() {
|
|
||||||
inner.attr("transform", "translate(" + d3.event.translate + ")" +
|
|
||||||
"scale(" + d3.event.scale + ")");
|
|
||||||
});
|
|
||||||
svg.call(zoom);
|
|
||||||
|
|
||||||
// Create the renderer
|
|
||||||
var render = new dagreD3.render();
|
|
||||||
|
|
||||||
// Add our custom shape (a house)
|
|
||||||
render.shapes().house = function(parent, bbox, node) {
|
|
||||||
var w = bbox.width,
|
|
||||||
h = bbox.height,
|
|
||||||
points = [
|
|
||||||
{ x: 0, y: 0 },
|
|
||||||
{ x: w, y: 0 },
|
|
||||||
{ x: w, y: -h },
|
|
||||||
{ x: w/2, y: -h * 3/2 },
|
|
||||||
{ x: 0, y: -h }
|
|
||||||
];
|
|
||||||
shapeSvg = parent.insert("polygon", ":first-child")
|
|
||||||
.attr("points", points.map(function(d) { return d.x + "," + d.y; }).join(" "))
|
|
||||||
.attr("transform", "translate(" + (-w/2) + "," + (h * 3/4) + ")");
|
|
||||||
|
|
||||||
node.intersect = function(point) {
|
|
||||||
return dagreD3.intersect.polygon(node, points, point);
|
|
||||||
};
|
|
||||||
|
|
||||||
return shapeSvg;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add our custom arrow (a hollow-point)
|
|
||||||
render.arrows().hollowPoint = function normal(parent, id, edge, type) {
|
|
||||||
var marker = parent.append("marker")
|
|
||||||
.attr("id", id)
|
|
||||||
.attr("viewBox", "0 0 10 10")
|
|
||||||
.attr("refX", 9)
|
|
||||||
.attr("refY", 5)
|
|
||||||
.attr("markerUnits", "strokeWidth")
|
|
||||||
.attr("markerWidth", 8)
|
|
||||||
.attr("markerHeight", 6)
|
|
||||||
.attr("orient", "auto");
|
|
||||||
|
|
||||||
var path = marker.append("path")
|
|
||||||
.attr("d", "M 0 0 L 10 5 L 0 10 z")
|
|
||||||
.style("stroke-width", 1)
|
|
||||||
.style("stroke-dasharray", "1,0")
|
|
||||||
.style("fill", "#fff")
|
|
||||||
.style("stroke", "#333");
|
|
||||||
dagreD3.util.applyStyle(path, edge[type + "Style"]);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
|
||||||
render(inner, g);
|
|
||||||
|
|
||||||
// Center the graph
|
|
||||||
var initialScale = 0.75;
|
|
||||||
zoom
|
|
||||||
.translate([(svg.attr("width") - g.graph().width * initialScale) / 2, 20])
|
|
||||||
.scale(initialScale)
|
|
||||||
.event(svg);
|
|
||||||
svg.attr('height', g.graph().height * initialScale + 40);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="demo.js"></script>
|
|
Loading…
x
Reference in New Issue
Block a user