Built with blockbuilder.org
This graph was inspired by a similar one from the CDC
I got help constructing the legend from this post
| license: mit |
Built with blockbuilder.org
This graph was inspired by a similar one from the CDC
I got help constructing the legend from this post
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <style> | |
| html { | |
| font-size: 14px; | |
| } | |
| body { | |
| background-color: lightblue; | |
| position: relative; | |
| } | |
| svg { | |
| position: absolute; | |
| left: calc(50% - 300px); | |
| } | |
| h2 { | |
| text-align: center; | |
| font-size: 1.8rem; | |
| margin-bottom: 5rem; | |
| } | |
| .legend { | |
| font-size: 1rem; | |
| } | |
| rect { | |
| stroke-width: 2; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <script> | |
| const data = [{ | |
| "year": 1999, | |
| "total": 1.6, | |
| "male": 2.1, | |
| "female": 1.1 | |
| }, | |
| { | |
| "year": 2000, | |
| "total": 2.1, | |
| "male": 2.9, | |
| "female": 1.2 | |
| }, | |
| { | |
| "year": 2001, | |
| "total": 2.5, | |
| "male": 3.4, | |
| "female": 1.5 | |
| }, | |
| { | |
| "year": 2002, | |
| "total": 2.9, | |
| "male": 4.0, | |
| "female": 1.7 | |
| }, | |
| { | |
| "year": 2003, | |
| "total": 3.1, | |
| "male": 4.3, | |
| "female": 1.8 | |
| }, | |
| { | |
| "year": 2004, | |
| "total": 3.7, | |
| "male": 5.2, | |
| "female": 2.0 | |
| }, | |
| { | |
| "year": 2005, | |
| "total": 3.5, | |
| "male": 5.0, | |
| "female": 1.9 | |
| }, | |
| { | |
| "year": 2006, | |
| "total": 3.9, | |
| "male": 5.6, | |
| "female": 2.0 | |
| }, | |
| { | |
| "year": 2007, | |
| "total": 4.2, | |
| "male": 6.2, | |
| "female": 2.1 | |
| }, | |
| { | |
| "year": 2008, | |
| "total": 4.2, | |
| "male": 6.1, | |
| "female": 2.1 | |
| }, | |
| { | |
| "year": 2009, | |
| "total": 3.6, | |
| "male": 5.2, | |
| "female": 1.9 | |
| }, | |
| { | |
| "year": 2010, | |
| "total": 3.8, | |
| "male": 5.3, | |
| "female": 2.2 | |
| }, | |
| { | |
| "year": 2011, | |
| "total": 3.8, | |
| "male": 5.4, | |
| "female": 2.2 | |
| }, | |
| { | |
| "year": 2012, | |
| "total": 3.1, | |
| "male": 4.4, | |
| "female": 1.7 | |
| }, | |
| { | |
| "year": 2013, | |
| "total": 3.2, | |
| "male": 4.3, | |
| "female": 2.0 | |
| }, | |
| { | |
| "year": 2014, | |
| "total": 3.1, | |
| "male": 4.0, | |
| "female": 2.2 | |
| }, | |
| { | |
| "year": 2015, | |
| "total": 3.7, | |
| "male": 4.6, | |
| "female": 2.7 | |
| }] | |
| const margin = { top: 20, right: 20, bottom: 20, left: 50 } | |
| const width = 600 | |
| const height = 300 | |
| const innerWidth = width - margin.left - margin.right | |
| const innerHeight = height - margin.top - margin.bottom | |
| const legendRectSize = 18 | |
| const legendSpacing = 4 | |
| d3.select('body') | |
| .append('h2') | |
| .text('Drug Overdose Deaths Among Adolescents Aged 15-19 in the United States: 1999-2015') | |
| const headers = ['male', 'total', 'female'] | |
| const xScale = d3.scaleLinear() | |
| .range([0, innerWidth]) | |
| const yScale = d3.scaleLinear() | |
| .range([innerHeight, 0]) | |
| const svg = d3.select('body') | |
| .append('svg') | |
| .attr('width', width) | |
| .attr('height', height) | |
| const g = svg.append('g') | |
| .attr('transform', `translate(${margin.left},${margin.top})`) | |
| const lineMaker = (gender) => d3.line() | |
| .x(d => xScale(d.year)) | |
| .y(d => yScale(d[gender])) | |
| xScale.domain(d3.extent(data, d => d.year)) | |
| yScale.domain([ | |
| d3.min(data, d => d3.min([d.male, d.female, d.total])), | |
| d3.max(data, d => d3.max([d.male, d.female, d.total])) | |
| ]) | |
| const xAxis = d3.axisBottom() | |
| .scale(xScale) | |
| .ticks(5) | |
| .tickFormat(d => d.toString()) | |
| const yAxis = d3.axisLeft() | |
| .scale(yScale) | |
| .ticks(5) | |
| g.append('g') | |
| .attr('class', 'axis') | |
| .attr('transform', `translate(0,${innerHeight})`) | |
| .call(xAxis) | |
| g.append('g') | |
| .attr('class', 'axis') | |
| .call(yAxis) | |
| .append('text') | |
| .attr('fill', '#000') | |
| .attr('transform', 'rotate(-90)') | |
| .attr('y', 5) | |
| .attr('dy', 10) | |
| .text('Deaths per 100,000 population') | |
| const randomColor = d3.interpolateRgb('purple', 'blue') | |
| g.selectAll('.path') | |
| .data(headers) | |
| .enter() | |
| .append('path') | |
| .attr('d', h => lineMaker(h)(data)) | |
| .attr('stroke', (h, i) => randomColor(i / headers.length)) | |
| .attr('stroke-width', 3) | |
| .attr('fill', 'none') | |
| .attr('data-legend', h => h) | |
| // Legend | |
| const legend = g.selectAll('.legend' | |
| ) | |
| .data(headers) | |
| .enter() | |
| .append('g') | |
| .attr('class', 'legend') | |
| .attr('transform', (d, i) => { | |
| const legend_height = legendRectSize + legendSpacing | |
| return `translate(50,${i * (legend_height)})` | |
| }) | |
| legend.append('rect') | |
| .attr('width', legendRectSize) | |
| .attr('height', legendRectSize) | |
| .style('fill', (d, i) => randomColor(i / headers.length)) | |
| .style('stroke', (d, i) => randomColor(i / headers.length)) | |
| legend.append('text') | |
| .attr('x', legendRectSize + legendSpacing) | |
| .attr('y', legendRectSize - legendSpacing) | |
| .text(d => d) | |
| </script> | |
| </body> |