This UI demonstrates the D3 collapsable tree applied to a rowing ladder. In the fully functional app, a user can “schedule” a race between two or more rowers, then “update” a race with the winner. Winners advance to the next round, and racing continues until someone wins the regatta.
Click on a blue bar to collapse or expand the tree. This is a convenient space saver, especially in mobile browsers. This UI demo will detect orientation changes and redraw the rowing ladder into the new browser width.
This is a UI demo only – a fully functional application needs a back-end server with a persistent database.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
<link rel="apple-touch-icon" sizes="114x114" href="pbc-retina.png">
<meta name="apple-touch-fullscreen" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="drawTree.js"></script>
<link rel="stylesheet" href="sculling.css" type="text/css">
<link rel="stylesheet" href="mobile.css" type="text/css">
</head>
<body>
<div id="rowingLogo" role="banner">
<a href=""><img src="pbcoar.gif" width="320" height="47" alt="Rowing Tree"/></a>
</div>
<div class="nav" role="navigation">
<ul>
<li><a href="" class="update">Schedule</a></li>
<li><a href="" class="update">Update</a></li>
</ul>
</div>
<div id="show-rower" class="content scaffold-show" role="main">
<h1>Standings:</h1>
</div>
<div id="chart"></div>
<script>
drawTree(window.innerWidth);
window.addEventListener("orientationchange", function() {
var chartNode = document.getElementById("chart");
while (chartNode.hasChildNodes()) {
chartNode.removeChild(chartNode.lastChild);
}
drawTree(window.innerWidth);
}, false);
</script>
<div class="footer" role="contentinfo"></div>
</body>
</html>
function drawTree(b){function k(a){var e=l.nodes(m);e.forEach(function(c,a){c.x=a*g});var b=n.selectAll("g.node").data(e,function(a){return a.id||(a.id=++q)}),h=b.enter().append("svg:g").attr("class","node").attr("transform",function(c){return"translate("+a.y0+","+a.x0+")"}).style("opacity",1E-6);h.append("svg:rect").attr("y",-g/2).attr("height",g).attr("width",r).style("fill",p).on("click",s);h.append("svg:text").attr("dy",5.5).attr("dx",9.5).text(function(a){return a.name});h.transition().duration(d).attr("transform",
function(a){return"translate("+a.y+","+a.x+")"}).style("opacity",1);b.transition().duration(d).attr("transform",function(a){return"translate("+a.y+","+a.x+")"}).style("opacity",1).select("rect").style("fill-opacity",0.5).style("stroke","#3182bd").style("stroke-width",1.5).style("fill",p);b.exit().transition().duration(d).attr("transform",function(c){return"translate("+a.y+","+a.x+")"}).style("opacity",1E-6).remove();b=n.selectAll("path.link").data(l.links(e),function(a){return a.target.id});b.enter().insert("svg:path",
"g").attr("class","link").attr("d",function(c){c={x:a.x0,y:a.y0};return f({source:c,target:c})}).transition().duration(d).attr("d",f);b.transition().duration(d).attr("d",f);b.exit().transition().duration(d).attr("d",function(c){c={x:a.x,y:a.y};return f({source:c,target:c})}).remove();e.forEach(function(a){a.x0=a.x;a.y0=a.y})}function s(a){console.log("Click -- d: "+a.name+", y: "+a.y+", x: "+a.x);a.children?(a._children=a.children,a.children=null):(a.children=a._children,a._children=null);k(a)}function p(a){return a._children?
"#3182bd":a.children?"#c6dbef":"#fd8d3c"}b||(console.log("WARNING...windowWidth = "+b),b=960);var q=0;b=Math.min(960,b);var g=40,r=0.8*b,d=400,m,l=d3.layout.tree().size([800,100]),f=d3.svg.diagonal().projection(function(a){return[a.y,a.x]}),n=d3.select("#chart").append("svg:svg").attr("width",b).attr("height",800).append("svg:g").attr("transform","translate(20,30)");d3.json("sculling.json",function(a,b){console.log("D3 reading data..err is: "+a+", data: "+b);b.x0=0;b.y0=0;k(m=b)})};
/* Styles for mobile devices */
@media screen and (max-width: 480px) {
.nav {
padding: 0.5em;
}
.nav li {
margin: 0 0.5em 0 0;
padding: 0.25em;
}
/* Hide individual steps in pagination, just have next & previous */
.pagination .step, .pagination .currentStep {
display: none;
}
.pagination .prevLink {
float: left;
}
.pagination .nextLink {
float: right;
}
/* pagination needs to wrap around floated buttons */
.pagination {
overflow: hidden;
}
/* slightly smaller margin around content body */
fieldset,
.property-list {
padding: 0.3em 1em 1em;
}
input, textarea {
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
select, input[type=checkbox], input[type=radio], input[type=submit], input[type=button], input[type=reset] {
width: auto;
}
/* hide all but the first column of list tables */
.scaffold-list td:not(:first-child),
.scaffold-list th:not(:first-child) {
display: none;
}
.scaffold-list thead th {
text-align: center;
}
/* stack form elements */
.fieldcontain {
margin-top: 0.6em;
}
.fieldcontain label,
.fieldcontain .property-label,
.fieldcontain .property-value {
display: block;
float: none;
margin: 0 0 0.25em 0;
text-align: left;
width: auto;
}
.errors ul,
.message p {
margin: 0.5em;
}
.error ul {
margin-left: 0;
}
}
GIF87a�<