D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
jadiehm
Full window
Github gist
UConn basketball margin
<!doctype html> <html lang='en-GB'> <head></head> <style> body { font-family: sans-serif; font-size: 16px; line-height: 1.4; display: block; margin: 0; padding: 0; color: #333; -webkit-font-smoothing: antialiased; } a, a:link, a:visited { text-decoration: none; color: #012157; } a:hover { text-decoration: underline; } h1, h2, h3, h4, h5, h6, strong, b { font-family: sans-serif; font-weight: 500; } h3 { font-family: sans-serif; font-size: 26px; font-weight: 900; line-height: 30px; margin: 0 0 5px 0; } p { font-family: sans-serif; font-size: 14px; margin: 0; } /*template styles*/ .gia-chart-wrapper { max-width: 960px; margin: 0 auto; } .gia-source { margin-top: 5px; color: #bdbdbd; padding: 3px 0; font-size: 12px; font-family: sans-serif; } /*chart styles*/ .y.axis line { fill: none; stroke: #dcdcdc; stroke-dasharray: 1px 1px; shape-rendering: crispEdges; stroke-width: 1px; } .tick.g-baseline line { stroke: #333333; stroke-dasharray: 0; stroke-width: 1px; } .axis text { font-family: sans-serif; font-size: 12px; pointer-events: none; fill: #767676; } .y.axis text { text-anchor: start !important; font-size:12px; fill: #767676; } .x.axis line { display: none; } .domain { display: none; } .bar{ fill: #eaeaea; } .g-baseline line { stroke: #333333; stroke-dasharray: 0; stroke-width: 1px; } div.tooltip { position: absolute; text-align: left; padding: 5px; font-family: sans-serif; font-size: 13px; line-height: 16px; pointer-events: none; color: #333333; background-color: #ffffff; border: 1px solid #dcdcdc; } .seasonRect { fill: #f6f6f6; } .label { fill: #333333; text-anchor: middle !important; font-family: sans-serif; font-size: 16px; font-weight: 700; } .added-line { stroke: #e6012a; stroke-width: 2px; } .avg-label { fill: #e6012a; font-family: sans-serif; font-size: 13px; font-weight: 700; text-anchor: start !important; } .highlight { fill: #012157; } .post { fill: #a3c2df; } .logo { width: 50px; float: left; margin-right: 10px; } .headline { width: 100%; } .hed-text { float: left; width: calc(100% - 60px); } .intro { margin-top:5px; } @media(max-width:400px) { h3 { font-size: 22px; line-height: 24px; } .logo { width: 40px; } .hed-text { width: calc(100% - 50px); } } </style> <body> <main> <div class='gia-chart-wrapper'> <div class="headline"> <img class="logo" src="huskies.png"> <div class="hed-text"> <h3>UConn women's basketball winning margin</h3> </div> <p>The Huskies beat their opponents by an average of 38.3 points during the 107-game (and counting) win streak</p> </div> <div class='gia-chart'></div> <div class='gia-source'> Source: <a href="https://www.uconnhuskies.com/sports/w-baskbl/conn-w-baskbl-body.html">UConn Women's Basketball</a> </div> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> <script> //Margin conventions var margin = {top: 35, right: 40, bottom: 60, left: 0}; var widther = d3.select(".gia-chart").node().clientWidth; var width = widther - margin.left - margin.right, height = 450 - margin.top - margin.bottom; //Appends the svg to the chart-container div var svg = d3.select(".gia-chart").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 + ")"); var div = d3.select("body").append("div") .attr("class", "tooltip") .style("opacity", 0); //Creates the xScale var xScale = d3.scale.ordinal() .rangeRoundBands([0, width + 20], 0.2); //Creates the yScale var yScale = d3.scale.linear() .range([height, 0]); //Defines the y axis styles var yAxis = d3.svg.axis() .scale(yScale) .tickSize(-width) .tickPadding(8) .orient("left"); //Loads the data d3.csv("uconn_margin.csv", ready); function ready(err, data) { if (err) throw "error loading data"; //FORMAT data data.forEach(function(d) { d.uconn_advantage = +d.uconn_advantage; d.win_number = +d.win_number; d.game_type = d.game_type; }); //Sets min and max on xScale var xMin = d3.min(data, function(d) { return d.win_number;}); var xMax = d3.max(data, function(d) { return d.win_number;}); var yMin = d3.min(data, function(d) { return d.uconn_advantage;}); var yMax = d3.max(data, function(d) { return d.uconn_advantage;}); //Sets scale domains xScale.domain(data.map(function(d) { return d.win_number; })); yScale.domain([0, yMax]); //Defines the x axis styles var xAxis = d3.svg.axis() .scale(xScale) .tickSize(height) .tickPadding(8) .orient("bottom") .tickValues([10, 20, 30, 40, 50, 60, 70, 80, 90, 100]); //Appends the y axis var yAxisGroup = svg.append("g") .attr("class", "y axis") .call(yAxis) .selectAll("g") .classed("g-baseline", function(d) { return d == 0 }); d3.selectAll(".y.axis text") .attr("transform", "translate(8, -10)"); //Appends the x axis var xAxisGroup = svg.append("g") .attr("class", "x axis") .call(xAxis); //Binds the data to the bars var bar = svg.selectAll(".bar") .data(data) .enter() .append("rect") .attr("class", function(d) { if(d.game_type == "champ") { return "highlight bar"; } else if(d.game_type == "post") { return "post bar"; } else { return "bar"; } }) .attr("x", function(d) { return xScale(d.win_number); }) .attr("width", xScale.rangeBand()) .attr("y", function(d) { return yScale(Math.max(0, d.uconn_advantage)); }) .attr("height", function(d) { return Math.abs(yScale(d.uconn_advantage) - yScale(0)); }) .on("mouseover", function(d) { var right = d3.event.pageX > window.innerWidth / 2; d3.select(this).transition().duration(100).style({'fill': '#012157'}); div.transition(300) .style("opacity", 1); div.html(d.opponent + '<br>' + d.uconn_points + "-" + d.opp_points); var offset = right ? div.node().offsetWidth + 5 : 0; div .style("left", (d3.event.pageX - offset) + "px") .style("top", (d3.event.pageY - 25) + "px") console.log(d.game_type) }) .on("mouseout", function(d) { if(d.game_type == "champ") { d3.select(this).transition().duration(100).style({'fill': '#012157'}); div.transition() .duration(300) .style("opacity", 0); } else if(d.game_type == "post") { d3.select(this).transition().duration(100).style({'fill': '#a3c2df'}); div.transition() .duration(300) .style("opacity", 0); } else { d3.select(this).transition().duration(100).style({'fill': '#eaeaea'}); div.transition() .duration(300) .style("opacity", 0); } }) //Append baseline var baseline = svg.append("line") .attr("x2", function(d) { return width; }) .attr("class", "added-baseline") .attr("y1", yScale(0)) .attr("y2", yScale(0)) .attr("stroke-width", 1) .attr("stroke", "#333333"); //Append average line var average = svg.append("line") .attr("x2", function(d) { return width; }) .attr("class", "added-line") .attr("y1", yScale(38.4)) .attr("y2", yScale(38.4)); //Append labels var averagelabel = svg.append("text") .text("Avg:") .attr("class", "avg-label") .attr("x", width/0.995) .attr("y", height/2.7); var averagelabel2 = svg.append("text") .text("38.4") .attr("class", "avg-label") .attr("x", width/0.995) .attr("y", height/2.4); var season1label = svg.append("text") .text("2014-15") .attr("class", "label") .attr("x", width/4.75) .attr("y", height/0.88); var season2label = svg.append("text") .text("2015-16") .attr("class", "label") .attr("x", width/1.79) .attr("y", height/0.88); var season3label = svg.append("text") .text("2016-17") .attr("class", "label") .attr("x", width/1.16) .attr("y", height/0.88); //RESPONSIVENESS d3.select(window).on("resize", resized); function resized() { //new margin var newMargin = {top: 35, right: 40, bottom: 60, left: 0}; var newWidther = d3.select(".gia-chart").node().clientWidth; var newWidth = newWidther - newMargin.left - newMargin.right; //Change the width of the svg d3.select("svg") .attr("width", newWidth + newMargin.left + newMargin.right); //Change the xScale xScale .rangeRoundBands([0, newWidth + 20], 0.2); //Updates xAxis d3.selectAll(".x.axis") .call(xAxis); //Updates ticks xAxis .scale(xScale) //Update the bars d3.selectAll(".bar") .attr("x", function(d) { return xScale(d.win_number); }) .attr("width", xScale.rangeBand()) //Updates yAxis d3.selectAll(".y.axis") .call(yAxis); yAxis .tickSize(-newWidth); //Updates labels season1label .attr("x", newWidth/4.75) season2label .attr("x", newWidth/1.79) season3label .attr("x", newWidth/1.16) averagelabel .attr("x", newWidth/0.995) averagelabel2 .attr("x", newWidth/0.995) d3.selectAll(".added-line") .attr("x2", function(d) { return newWidth; }) d3.selectAll(".added-baseline") .attr("x2", function(d) { return newWidth; }) }; } </script> </body> </html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js