D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
ohdebby
Full window
Github gist
Paid leave by country
Built with
blockbuilder.org
<!doctype html> <script src="https://d3js.org/d3.v4.min.js"></script> <style type="text/css"> body { font-family: sans-serif; } text { font-size: 16px; fill: #888; } path, line { stroke: #888; stroke-width: 4; fill: none; } </style> <body> </body> <script> // properties var margin = {top: 20, right: 120, bottom: 40, left: 40}; var width = 900 - margin.left - margin.right; var height = 600 - margin.top - margin.bottom; var yscale = d3.scaleLinear(); var xscale = d3.scaleLinear(); var color = d3.scaleOrdinal(d3.schemeCategory20c); // data values in country,year,value format var data_values = []; d3.csv('PaidLeaveOECD.csv', function(data) { var years = data.columns.slice(1).map(function(d) { return +d; }); data.forEach(function(row) { years.forEach(function(year) { data_values.push({ country: row.country, year: year, value: +row[year] }); }); }); var nested = d3.nest() .key(function(d) { return d.country; }) .entries(data_values); // scales yscale .range([height,0]) .domain(d3.extent(data_values.map(function(d) { return d.value; }))); xscale .range([0, width]) .domain(d3.extent(years)); var yaxis = d3.axisLeft() .scale(yscale); var xaxis = d3.axisBottom() .tickFormat(function(d) { return d; }) .scale(xscale); var line = d3.line() .defined(function(d) { return d; }) .x(function(d) { return xscale(d.year); }) .y(function(d) { return yscale(d.value); }); var chart = d3.select("body") .append("div"); var svg = 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] + ')') svg.append("g") .call(yaxis); svg.append("g") .attr("transform", "translate(0," + (height+10) + ")") .call(xaxis); var groups = svg.selectAll(".groups") .data(nested) .enter() .append("g") .attr("class", function(d) { return d.key + "groups"; }); groups.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", function(d) { return color(d.key); }); // groups.append("path") // .attr("class", "invisible hover") // .attr("d", function(d) { return line(d.key); }); //labels groups.append("text") .attr("x", function(d) { return xscale(d.values[d.values.length-1].year);}) .attr("y", function(d) { return yscale(d.values[d.values.length-1].value); }) .attr("alignment-baseline", "middle") .text(function(d) { return d.key; }) .attr("class","label") .style("fill", function(d) { return color(d.key); }) // TEST! // var labels = nested.map(function(d) {return {name: d.key, y:yscale(d.values[d.values.length - 1].value)}}); nested.forEach(function(d) {d.y=yscale(d.values[d.values.length - 1].value)}); // constraint relaxation on labels var alpha = 0.5; var spacing = 12; function relax() { var again = false; nested.forEach(function(a,i) { nested.slice(i+1).forEach(function(b) { var dy = a.y - b.y; if (Math.abs(dy) < spacing) { again = true; var sign = dy > 0 ? 1 : -1; a.y += sign*alpha; b.y -= sign*alpha; } }); }); d3.selectAll(".label") .attr("y", function(d) { return d.y }); if (again) setTimeout(relax,20); }; relax(); // series.selectAll(".hover") // .on("mouseover", function(d,i) { // d3.selectAll(".line") // .style("opacity", 0.12) // .filter(function(p) { return p.country == d.country; }) // .style("opacity", 1) // .style("stroke-width", 2.5); // d3.selectAll(".series text") // .style("opacity", 0) // .filter(function(p) { return p.country == d.country; }) // .style("opacity", 1); // }) // .on("mouseout", function(d,i) { // d3.selectAll(".line") // .style("opacity", 1) // .style("stroke-width", null); // d3.selectAll(".series text") // .style("opacity", 1); // }); }); </script>
https://d3js.org/d3.v4.min.js