D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
galenburrell
Full window
Github gist
Exercise 6: Line Graphs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Historic Dipsea Results with D3</title> <script type="text/javascript" src="https://d3js.org/d3.v3.js"></script> <style type="text/css"> body { background-color: white; } h1 { font-family: sans-serif; font-size: 24px; margin: 0; } p { font-family: sans-serif; font-size: 14px; margin: 10px 0 0 0; } .linelabel { font-family: sans-serif; font-size: 10px; } .linelabel.fastest { fill:grey; } .linelabel.winner { fill:orange; } svg { background-color: white; } .circle { stroke: none; } .circle.men { fill: steelblue; stroke: steelblue; stroke-width: 0px; } .circle.women { fill: red; stroke: red; stroke-width: 0px; } .circle:hover { stroke-width: 4px; } .line.winner.actual { fill: none; stroke: orange; opacity: 0.5; stroke-width: 1px; } .line.winner.clock { fill: none; stroke: orange; stroke-width: 2px; } .line.fastest.actual { fill: none; stroke: grey; stroke-width: 2px; } .line.fastest.clock { fill: none; stroke: pink; stroke-width: 2px; } .area.winner { fill: orange; opacity: 0.05; stroke: none; } .axis path, .axis line { fill: none; stroke: black; shape-rendering: crispEdges; } .axis text { font-family: sans-serif; font-size: 11px; } .y.axis path, .y.axis line { opacity: 0; } .y.grid { stroke: lightgrey; opacity: 0.5; } .grid path { stroke-width: 0; } </style> </head> <body> <h1>The Dipsea Race</h1> <p>Overall winner and fastest net times by year. In the last 20 years, the fastest runner has not successfully won the race due to the unique age- and gender-handicapping system (represented by the shaded region). Colored dots represent gender of winner. (Source: <a href="https://www.dipsea.org">dipsea.org</a>)</p> <!-- <span id="35" class="p">Top 35 Only </span><span id="1000">All </span><p> --> <script type="text/javascript"> //Set variables var dataset; var dataset_winner = []; var dataset_fastest = []; var svgwidth = 700; var svgheight = 400; var margin = {top: 50, right: 100, bottom: 50, left: 75 }; var w = svgwidth - margin.left - margin.right; var h = svgheight - margin.top - margin.bottom; //Set time formats var yearFormat = d3.time.format("%Y"); var timeFormat = d3.time.format("%X"); //Set scales var xScale = d3.time.scale() .range([ 0, w ]); var yScale = d3.time.scale() .range([ 0, h ]); //Set axis generators var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .ticks(10) .tickFormat(function(d) { return yearFormat(d); }); var yAxis = d3.svg.axis() .scale(yScale) .orient("left") .ticks(8) .tickFormat(function(d) { return timeFormat(d); }); //Configure line generator var line_actual = d3.svg.line() .x(function(d) { return xScale(yearFormat.parse(d.Year)); }) .y(function(d) { return yScale(timeFormat.parse(d.ActualTime)); }); var line_clock = d3.svg.line() .x(function(d) { return xScale(yearFormat.parse(d.Year)); }) .y(function(d) { return yScale(timeFormat.parse(d.ClockTime)); }); var area = d3.svg.area() .x(function(d) { return xScale(yearFormat.parse(d.Year)); }) .y0(function(d) { return yScale(timeFormat.parse(d.ClockTime)); }) .y1(function(d) { return yScale(timeFormat.parse(d.ActualTime)); }); //Create SVG canvas var svg = d3.select("body") .append("svg") .attr("width", svgwidth) .attr("height", svgheight) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); //Load in contents of CSV file d3.csv("dipsea_filtered.csv", function(data) { //Filter data set var years = [ "1996", "1997", "1998", "1999", "2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014" ]; for (var i=0; i < years.length; i++) { var dataset_tmp = data .filter(function(d) { return d.Year == years[i] }); dataset_fastest[i] = { Year: years[i], ActualTime: d3.min(dataset_tmp, function(d) { return d.ActualTime; }) //HeadStart: d3.min(dataset_tmp, function(d) { return d.ActualTime + timeFormat.parse("00:".concat("02").concat(":00")); }) }; } dataset_winner = data .filter(function(d) { return d.Place == 1 }); //Set x and y domain xScale.domain([ d3.min(years, function(d) { return yearFormat.parse(d); }), d3.max(years, function(d) { return yearFormat.parse(d); }) ]); yScale.domain([ d3.max(dataset_winner, function(d) { return timeFormat.parse(d.ActualTime); }), d3.min(dataset_winner, function(d) { return timeFormat.parse("00:00:00"); }) ]); //Lines svg.data([ dataset_winner ]) .append("path") .attr("class", "area winner") .attr("d", area) svg.data([ dataset_fastest ]) .append("path") .attr("class", "line fastest actual") .attr("d", line_actual); svg.data([ dataset_winner ]) .append("path") .attr("class", "line winner actual") .attr("d", line_actual); svg.data([ dataset_winner ]) .append("path") .attr("class", "line winner clock") .attr("d", line_clock); //Line Labels svg.append("text") .attr("transform", "translate(" + ( w + 3 ) + "," + yScale(timeFormat.parse(dataset_fastest[dataset_fastest.length-1].ActualTime)) + ")") .attr("dy", ".35em") .attr("text-anchor", "start") .attr("class", "linelabel fastest") .text("Fastest Time"); svg.append("text") .attr("transform", "translate(" + ( w + 3 ) + "," + yScale(timeFormat.parse(dataset_winner[dataset_winner.length-1].ActualTime)) + ")") .attr("dy", ".35em") .attr("text-anchor", "start") .attr("class", "linelabel winner") .text("Winner's Actual Time"); svg.append("text") .attr("transform", "translate(" + ( w + 3 ) + "," + yScale(timeFormat.parse(dataset_winner[dataset_winner.length-1].ClockTime)) + ")") .attr("dy", ".35em") .attr("text-anchor", "start") .attr("class", "linelabel winner") .text("Winner's Net Time"); //Bind filtered data into rect placeholders var dots = svg.selectAll("circle") .data(dataset_winner) .enter() .append("circle"); //Set attributes of circles dots.attr("cx", function(d) { return xScale(yearFormat.parse(d.Year)); }) .attr("cy", function(d) { return yScale(timeFormat.parse(d.ClockTime)); }) .attr("r", 2) .attr("class", function(d) { if (d.Sex == "M") { return "circle men";}; if (d.Sex == "F") { return "circle women";}; //else { return "circle"; }; }) .append("title") .text(function(d) { return "Sex: " + d.Sex + " Age: " + d.Age + " Head Start : " + d.HeadStart + " minutes"; }); //Append Axis titles svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + h + ")") .call(xAxis) .append("text") .attr("transform", "rotate(0)") .attr("y", 6) .attr("dy", "3em") .attr("dx", w) .style("text-anchor", "end") .style("font-weight", "bold") .text("Year"); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", "-6em") .style("text-anchor", "end") .style("font-weight", "bold") .text("Time"); //Add grid lines var yAxisGrid = yAxis.ticks(8) .tickSize(w,0) .tickFormat("") .orient("right"); svg.append("g") .classed('y', true) .classed('grid', true) .call(yAxisGrid); }); </script> </body> </html>
Modified
http://d3js.org/d3.v3.js
to a secure url
https://d3js.org/d3.v3.js