Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg { width:100%; height: 100% }
.table th{
text-align:center;
}
.table td{
text-align:center;
}
.table td:first-child{
text-align:left
}
</style>
</head>
<body>
<div class="container">
<div id="page-title">
<h3 id="market-name"></h3>
</div>
<div id="roster"></div>
</div>
<script>
var dateparser = d3.time.format("%m/%d/%Y");
var pctformat = d3.format("%");
var r2precision = d3.format(".2f")
var mformat = d3.format(",");
var months = {0:"Jan", 1:"Feb", 2:"Mar", 3:"Apr", 4:"May", 5:"Jun", 6:"Jul", 7:"Aug", 8:"Sep", 9:"Oct", 10:"Nov", 11:"Dec" };
var data = [];
var columns = ["Period", "Visits", "Bounce Rate", "Avg. Visit Duration" ];
var markets =[];
var table = d3.select("#roster")
.append("table")
.classed("table", true);
var thead = table.append("thead");
var tbody = table.append("tbody");
var marketSelector = d3.select("#page-title")
.append("select")
.attr("id", "market-selector")
.on("change", function() { selectMarket(this.value); });
//start reload
var reload = function () {
d3.csv("data.csv", function(records){
data = records;
data.forEach(function (d) {
d.Date = dateparser.parse(d.Date);
d.Month = d.Date.getMonth();
d.Year = d.Date.getFullYear();
d.Period = d.Year + "-" + (d.Month+1)
d.Visits = +d.Visits;
d.Bounces = +d.Bounces;
d.Pageviews = +d.Pageviews;
d.SPV = +d.SPV;
d.TotalSeconds = +d.TotalSeconds;
if (markets.indexOf(d.Market)<0) {
markets.push(d.Market);
};
});
markets.sort();
selectMarket(markets[0]);
//console.log(data);
//console.log(markets);
});
};
//end reload
//start of redraw function
var redraw = function(roster) {
var nested_data = d3.nest()
.key(function(d) {return d.Period; }).sortKeys(d3.ascending)
.rollup(function(v) {return{
visits:d3.sum(v, function(d) {return d.Visits; }),
BounceRate : d3.sum(v, function(d) {return d.Bounces; })/d3.sum(v, function(d) {return d.Visits; }),
AVD:d3.sum(v, function (d) {return d.TotalSeconds;}) / (d3.sum(v, function(d) {return d.Visits; })-d3.sum(v, function(d) {return d.Bounces; }))/60
};})
.entries(roster);
//console.log(nested_data);
nested_data.forEach(function (d) {
d.Period = months[d.key.split("-").pop() - 1] + "-" + d.key.slice(0,4) ;
d.Visits = mformat(d.values.visits);
d["Bounce Rate"] = pctformat(d.values.BounceRate);
d["Avg. Visit Duration"] = r2precision(d.values.AVD)
});
marketSelector.selectAll("option")
.data(markets)
.enter()
.append("option")
.attr("value", function(d) { return d; })
.text(function(d) { return d; })
.sort(function(a,b) { return d3.ascending(a,b); });
thead.selectAll("tr")
.data([columns])
.enter()
.append("tr")
.selectAll("th")
.data(function(d) { return d; })
.enter()
.append("th")
.on("click", function(d) {
tbody.selectAll("tr")
.sort(function(a,b) {
return (d === 'No')
? d3.ascending(+a[d], +b[d])
: d3.ascending(a[d], b[d])
})
.style("background-color", function(d,i) { return (i%2)? "white":"lightgray"; });
}).text(function(d) { return d; })
;
var rows = tbody.selectAll("tr")
.data(nested_data);
rows.enter()
.append("tr")
.style("background-color", function(d,i) { return (i%2)? "white":"lightgray"; });
rows.exit().remove();
var cells = rows.selectAll("td")
.data(function(row) { return columns.map(function(col) {
return row[col];
});});
cells.enter().append("td");
cells.text(function(d) { return d; });
};
//end of redraw function
var selectMarket = function(marketId) {
var roster = data.filter(function(d) { return d.Market === marketId; });
redraw(roster);
// d3.select("#market-name").text(teams[teamId] + " Roster");
// document.getElementById("market-selector").value = teamId;
};
reload();
</script>
</body>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js