xxxxxxxxxx
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src='https://cdn.mathjax.org/mathjax/latest/mathjax.js?config=tex-ams-mml_htmlormml'></script>
<style type="text/css">
body {
font-family: futura;
font-size: 10px;
background: #F8F3D4;
}
div {
display: inline-block;
}
h1 {
font-family: futura;
font-size: 10px;
}
/*svg {
stroke: #00B8A9;
}*/
.divisionText {
font-family: futura;
font-size: 12px;
}
.domain {
fill: none;
stroke: #000;
}
.axis line {
stroke: #00B8A9;
stroke-dasharray: 2, 2;
stroke-linecap: "round";
shape-rendering: crispEdges;
}
.teamLines {
fill: none;
stroke: #F6416C;
stroke-width: 2;
}
.teamNames {
font-family: futura;
font-size: 4px;
}
.background-rect {
/*fill: #bfbfbf;*/
fill: #FFDE7D;
opacity: .1;
stroke: #00B8A9;
}
.axis text {
font-family: futura;
font-size: 0.8em;
}
#neighborhoodPopover {
position: absolute;
text-align: center;
padding: 2px;
font-family: futura;
font-size: 12px;
background: #fff;
border: 0px;
border-radius: 8px;
pointer-events: none;
opacity: 0;
}
</style>
<body>
</body>
<script>
var margin = {top: 20, right: 20, bottom: 20, left: 40};
var width = 400 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;
var colorScale = d3.scaleOrdinal(d3.schemeCategory20b);
var parseDate = d3.utcParse("%Y-%m-%d");
d3.csv("games.csv", function(error, data) {
if (error) return console.warn(error);
console.log(data)
data.forEach(function(d) {
d.pct = +d.pct;
d.date_str2 = parseDate(d.date_str2);
d.result = (d.result == "W" ? 1 : 0);
});
var divisionOrder = ['west', "central", 'east'];
var nestedData = d3.nest()
.key(function(d) { return d.league })
.key(function(d) { return d.division })
.sortKeys(function(a, b) { return divisionOrder.indexOf(a) - divisionOrder.indexOf(b)})
.key(function(d) { return d.team; })
.rollup(function(teamValues) {
return {
totalWin: d3.sum(teamValues, function(d) { return d.result }),
values: teamValues
}
})
.sortValues(function(a, b) { return a.value.totalWin - b.value.totalWin })
.entries(data);
console.log(nestedData)
var leagueDivs = d3.select("body").selectAll(".leagueDivs")
.data(nestedData)
.enter().append("div")
.attr("class","leagueDivs")
leagueDivs.append("h1")
.text(function(d) { return d.key; });
var divisionGroups = leagueDivs.selectAll("svg")
.data(function(d) { return d.values })
.enter().append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
divisionGroups.append("rect")
.attr("class", "background-rect")
.attr("width", width)
.attr("height", height)
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
divisionGroups.append("text")
.attr("class","divisionText")
.attr("dy", -5)
.text(function(d) { return d.key.capitalize(); })
var timeScale = d3.scaleUtc()
.domain(d3.extent(data, function(d) { return d.date_str2; }))
.range([0, width]);
var percentScale = d3.scaleLinear()
.domain([0,1])
.range([height, 0]);
var xAxis = d3.axisBottom(timeScale)
.tickSize(-height)
.ticks(20)
.tickPadding(8);
var yAxis = d3.axisLeft(percentScale)
.tickFormat(d3.format(".0%"))
.tickSize(-width)
.tickPadding(8);
divisionGroups.append("g")
.attr("class", "x axis")
.attr("transform","translate(0," + height + ")")
.call(xAxis)
.selectAll(".tick")
.filter(function(d, i) { return i % 5 != 0 })
.select("text")
.remove();
divisionGroups
.append("g")
.attr("class", "y axis")
.call(yAxis)
var teamLineGenerator = d3.line()
.curve(d3.curveBasis)
.x(function(d) { return timeScale(d.date_str2); })
.y(function(d) { return percentScale(d.pct); })
//
var teamOpacityScale = d3.scaleLinear()
.domain([40, 90])
.range([0, 1]);
// var teamOpacityScale = d3.scaleSqrt()
// .domain([40, 90])
// .range([0, .5]);
divisionGroups.selectAll(".teamLines")
.data(function(d) { return d.values })
.enter().append("path")
.attr("class","teamLines")
.style("stroke-opacity", function(d) { return teamOpacityScale(d.value.totalWin); })
.style("stroke-dasharray", function(d,i) {
var dashArrayValue = i*2;
return dashArrayValue
})
.attr("d", function(d) { return teamLineGenerator(d.value.values); })
.on("mouseenter", function(d) {
console.log(d);
d3.select(this)
.style("stroke-width", 1.5)
.style("stroke-dasharray", 0)
d3.select("#neighborhoodPopover")
.transition()
.style("opacity", 1)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px")
.text(function(d) { return d.key; })
})
.on("mouseleave", function(d) {
d3.select(this)
.style("stroke-width", .25)
.style("stroke-dasharray", 1)
d3.select("#neighborhoodPopovercountyText")
.transition()
.style("opacity", 0)
.ease(d3.easeElastic)
});
divisionGroups.selectAll(".teamNames")
.data(function(d) { return d.values })
.enter().append("text")
.attr("class","teamNames")
.text(function(d) { return d.key; })
.attr("x", (width) + 5)
.attr("y", function(d) {
var lastValue = d.value.values[d.value.values.length - 1]
return percentScale(lastValue.pct);
})
d3.selectAll(".east")
.select(".y")
.selectAll("text")
.remove()
d3.selectAll(".central")
.select(".y")
.selectAll("text")
.remove()
});
</script>
Updated missing url https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML to https://cdn.mathjax.org/mathjax/latest/mathjax.js?config=tex-ams-mml_htmlormml
https://d3js.org/d3.v4.min.js
https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML