D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
carlkra
Full window
Github gist
Group Rollup Function
Built with
blockbuilder.org
<!DOCTYPE html> <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