D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
lmelgar
Full window
Github gist
Dots on Lines
<!DOCTYPE html> <!-- Modification of an example by Scott Murray from Knight D3 course --> <html lang="en"> <head> <meta charset="utf-8"> <title>Line Chart with Multiple Lines</title> <style type="text/css"> @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700); #text_p { max-width: 900px; margin: 0 auto; } h1{ font-family: "Open Sans", sans-serif; font-size: 45px; text-transform: uppercase; font-weight: 700; color: #0099FF; margin-top: 40px; margin-bottom: 15px; } h2 { margin-top: 10px; font-weight: 400; } p { width: 800px; font-family: "Open Sans"; font-size: 18px; font-weight: 100; line-height: 1.7; } #source p { font-size: 13px; margin-bottom: 50px; } a, a:visited { text-decoration: none; color: #0099FF; } a:hover { color: black; } path.line { fill: none; stroke: rgba(0,128,255,0.3); stroke-width: 1px; } .line.unfocused { stroke-opacity: 0.3; } .line.focused { stroke-width: 1.7px; stroke: rgba(0,128,255,1); } /*.axis path, .axis line { fill: none; stroke: black; stroke-width: 1px; }*/ .axis path { display: none; } .axis line { shape-rendering: crispEdges; stroke: rgba(230,230,230,1); } .axis text { font-family: "Open Sans", sans-serif; font-size: 12px; fill: rgba(75,75,75,1); } .axis .minor line { stroke: rgba(189,189,189,1); stroke-dasharray: 1.2,4; } .label { font-family: "Open Sans", sans-serif; font-size: 14px; font-weight: 400; fill: rgba(75,75,75,1); } .tooltip { position: absolute; z-index: 10; } .tooltip p { width: initial; font-family: "Open Sans", sans-serif; line-height: 1.4; color: black; font-size: 13px; background-color: rgba(255,255,255,0.8); border: rgba(230,230,230,1) 1px solid; padding: 5px 7px 5px 7px; } .linelabel { font-family: "Open Sans", sans-serif; font-size: 13px; } strong { font-weight: 600; } </style> </head> <body> <div id="container"> <div id="text_p"> <h1>Infant Mortality under 5 years old since 2000</h1> <p>Although death among children has decreased around the world within the last decade, some countries, like India, keep an alarming infant mortality. This graphic shows the change in infant mortality since 2000 to 2013.</p> <div id="source"> <p>Source: <a href="https://www.who.int/gho/en/">Global Health Observatory (GHO)</a>.</p> </div> </div> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script> <script type="text/javascript"> //Dimensions and padding var width = 1200; var height = 800; var margin = {top: 20, right: 0, bottom: 40, left:260}; //Set up date formatting and years var dateFormat = d3.time.format("Year %Y"); var outFormat = d3.time.format("%Y"); var bycountry = []; //Set up scales var xScale = d3.time.scale() .range([ margin.left, width - margin.right - margin.left ]); var yScale = d3.scale.linear() .range([ margin.top, height - margin.bottom ]); //Configure axis generators var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .ticks(5) .tickFormat(function(d) { return outFormat(d); }) .outerTickSize([0]); var yAxis = d3.svg.axis() .scale(yScale) .orient("right") .ticks(5) .tickSize(width - margin.left - 260); //Configure line generator // each line dataset must have a d.year and a d.amount for this to work. var line = d3.svg.line() .x(function(d) { return xScale(dateFormat.parse(d.Year)); }) .y(function(d) { return yScale(+d.Total); }); var tooltip = d3.select("body") .append("div") .attr("class","tooltip"); //Create the empty SVG image var svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height); //Load data d3.csv("deaths_04yearsold.csv", function(error, data) { var years = ["Year 2000", "Year 2001", "Year 2002", "Year 2003", "Year 2004", "Year 2005", "Year 2006", "Year 2007", "Year 2008", "Year 2009", "Year 2010", "Year 2011", "Year 2012", "Year 2013"]; //Loop once for each row in data var bycountry = d3.nest().key(function (d) { return d.Country; }) .entries(data); console.log(data) console.log(bycountry) //Set scale domains - max and mine of the years xScale.domain( d3.extent(years, function(d) { return dateFormat.parse(d); })); // max of emissions to 0 (reversed, remember) yScale.domain([ d3.max(bycountry, function(d) { return d3.max(d.values, function(d) { return +d.Total; }); }), 0 ]); //Make a group for each country var groups = svg.selectAll("g") .data(bycountry) .enter() .append("g") .attr("class", "lines"); //Within each group, create a new line/path, //binding just the emissions data to each one groups.selectAll("path") .data(function(d) { // because there's a group with data already... return [ d.values ]; // it has to be an array for the line function }) .enter() .append("path") .attr("class", "line") .attr("d", line) .attr("stroke", "#FF0099"); groups.append("text") .datum(function(d) { console.log("Here", {name: d.key, values: d.values[0]}); return {name: d.key, value: d.values[0]}; }) .attr("transform", function(d) { console.log("in transform", d); // error on some with no d.values - American Samoa, for instance. if (d.value) { return "translate(" + xScale(dateFormat.parse(d.value.Year)) + "," + yScale(+d.value.Total) + ")"; } else { return null; } }) .attr("x", 3) .attr("dy", ".30em") .text(function(d) { if (d.value && +d.value.Total > 500000) { return d.name; } }) .attr("class", "linelabel"); var circles = groups.selectAll("circle") .data(function(d) { // because there's a group with data already... return d.values; // NOT an array here. }) .enter() .append("circle"); circles.attr("cx", function(d) { return xScale(dateFormat.parse(d.Year)); }) .attr("cy", function(d) { return yScale(+d.Total); }) .attr("r", 1.5) .attr("fill", "rgba(0,128,255,1)") .style("opacity", 0.3); // this is optional - if you want visible dots or not! //Axes svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + (height - margin.bottom) + ")") .call(xAxis); svg.append("text") .attr("class", "y label") .attr("transform", "translate(" + (margin.left / 1.2) + " ," + (height / 2.3 + margin.top) + ") rotate(-90)") .style("text-anchor", "middle") .attr("dy", "-67") .text("Infant Mortality under 5 years old"); var gy = svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" + margin.left + ",0)") .call(yAxis); gy.selectAll("g").filter(function(d) { return d; }) .classed("minor", true); gy.selectAll("text") .attr("x", -70) .attr("dy", 0); circles .on("mouseover", mouseoverCircleFunc) .on("mousemove", mousemoveCircleFunc) .on("mouseout", mouseoutCircleFunc); function mouseoverCircleFunc(d) { d3.select(this) .transition() .style("opacity", 1) .attr("r", 6); tooltip .style("display", null) // this removes the display none setting from it .html("<p>" + d.Country + "<br>" + d.Year + "<br><strong>Under 5 mortality: " + d3.format(",")(d.Total) + "</strong></p>"); /*d3.selectAll("path.line").classed("unfocused", true); // now undo the unfocus on the current line and set to focused. d3.selectAll(this).select("path.line").classed("unfocused", false).classed("focused", true);*/ } function mousemoveCircleFunc(d) { tooltip .style("top", (d3.event.pageY - 10) + "px" ) .style("left", (d3.event.pageX + 10) + "px"); } function mouseoutCircleFunc(d) { d3.select(this) .transition() .style("opacity", .5) tooltip.style("display", "none"); // this sets it to invisible! /*d3.selectAll("path.line").classed("unfocused", false).classed("focused", false);*/ } d3.selectAll("g.lines") .on("mouseover", mouseoverLinesFunc) .on("mouseout", mouseoutLinesFunc) .on("mousemove", mousemoveLinesFunc); function mouseoverLinesFunc(d) { // line styling: // this is the g element. select it, then the line inside it! //console.log(d, this); d3.selectAll("path.line").classed("unfocused", true); // now undo the unfocus on the current line and set to focused. d3.select(this).select("path.line").classed("unfocused", false).classed("focused", true); /*tooltip .style("display", null) // this removes the display none setting from it .html("<p><b>" + d.key + "</b></p>");*/ } function mouseoutLinesFunc() { // this removes special classes for focusing from all lines. Back to default. d3.selectAll("path.line").classed("unfocused", false).classed("focused", false); /*tooltip.style("display", "none"); // this sets it to invisible!*/ } /*function mouseoverFunc(d) { // line styling: // this is the g element. select it, then the line inside it! //console.log(d, this); d3.selectAll("path.line").classed("unfocused", true); // now undo the unfocus on the current line and set to focused. d3.select(this).select("path.line").classed("unfocused", false).classed("focused", true); } function mouseoutFunc() { // this removes special classes for focusing from all lines. Back to default. d3.selectAll("path.line").classed("unfocused", false).classed("focused", false); }*/ }); </script> </div> </body> </html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js