D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
abinofbrooklyn
Full window
Github gist
Donut scale
<style type="text/css"> #donut-chart { /* NEW */ height: 500px; margin: 0 auto; /* NEW */ position: relative; /* NEW */ width: 500px; } </style> <script src="https://d3js.org/d3.v4.min.js"></script> <body> <div id="dount-chart"></div> </body> <script> var someData = [{"year":2017,"count":42,"country":"Absurdistan"},{"year":2016,"count":244,"country":"Absurdistan"},{"year":2015,"count":209,"country":"Absurdistan"},{"year":2014,"count":210,"country":"Absurdistan"},{"year":2013,"count":221,"country":"Absurdistan"},{"year":2012,"count":202,"country":"Absurdistan"},{"year":2011,"count":165,"country":"Absurdistan"},{"year":2010,"count":107,"country":"Absurdistan"},{"year":2009,"count":92,"country":"Absurdistan"},{"year":2008,"count":46,"country":"Absurdistan"},{"year":2007,"count":39,"country":"Absurdistan"},{"year":2006,"count":20,"country":"Absurdistan"},{"year":2005,"count":20,"country":"Absurdistan"},{"year":2004,"count":11,"country":"Absurdistan"}] drawChart(someData); function drawChart(data) { console.log(data); data.forEach(function(d) { d.count = +d.count; d.year = +d.year d.enabled = true; }); var year = d3.set(data.map(function(d) { return d.year; })) var size = Object.keys(year).length; var width = 430; var height = 430; var radius = Math.min(width, height) / 2; var donutWidth = 75; var legendSpacing = 4; var legendHeight = radius * 2 - donutWidth * 2 var legendScale = d3.scaleBand() .domain(year.values()) .rangeRound([legendHeight,0]) var legendRectSize = legendScale.bandwidth(); console.log(legendRectSize); var colorScale = d3.scaleOrdinal(d3.schemeCategory20b); var svg = d3.select('#dount-chart') .append('svg') .attr('width', width) .attr('height', height) .append('g') .attr('transform', 'translate(' + (width / 2) + ',' + (height / 2) + ')'); var arc = d3.arc() .innerRadius(radius - donutWidth) .outerRadius(radius); var pie = d3.pie() .value(function(d) { return d.count; }) .sort(null); var tooltip = d3.select('#dount-chart') .append('div') .attr('class', 'tooltip'); tooltip.append('div') .attr('class', 'year'); tooltip.append('div') .attr('class', 'count'); tooltip.append('div') .attr('class', 'percent'); var path = svg.selectAll('path') .data(pie(data)) .enter() .append('path') .attr('d', arc) .attr('fill', function(d, i) { return colorScale(d.data.year); }) .each(function(d) { this._current = d; }); path.on('mouseover', function(d) { var total = d3.sum(data.map(function(d) { return (d.enabled) ? d.count : 0; })); var percent = Math.round(1000 * d.data.count / total) / 10; tooltip.select('.year').html(d.data.year); tooltip.select('.count').html(d.data.count); tooltip.select('.percent').html(percent + '%'); tooltip.style('display', 'block'); }); path.on('mouseout', function() { tooltip.style('display', 'none'); }); var legend = d3.select("svg").append("g") .attr("transform","translate(" +width/2+"," + (radius/2.3 - legendScale.bandwidth()) + ")" ) .selectAll('.legend') .data(colorScale.domain()) .enter() .append('g') .attr('class', 'legend') .attr('transform', function(d, i) { var horz = 0; console.log(i); var vert = legendScale(d); console.log(vert); return 'translate(' + horz + ',' + vert + ')'; }); legend.append('rect') .attr('width', legendRectSize) .attr('height', legendRectSize) .style('fill', colorScale) .style('stroke', colorScale) .on('click', function(year) { var rect = d3.select(this); var enabled = true; var totalEnabled = d3.sum(data.map(function(d) { return (d.enabled) ? 1 : 0; })); if (rect.attr('class') === 'disabled') { rect.attr('class', ''); } else { if (totalEnabled < 2) return; rect.attr('class', 'disabled'); enabled = false; } pie.value(function(d) { if (d.year === year) d.enabled = enabled; return (d.enabled) ? d.count : 0; }); path = path.data(pie(data)); path.transition() .duration(750) .attrTween('d', function(d) { var interpolate = d3.interpolate(this._current, d); this._current = interpolate(0); return function(t) { return arc(interpolate(t)); }; }); }); legend.append('text') .attr('x', legendRectSize + legendSpacing) .attr('y', legendRectSize - legendSpacing) .text(function(d) { return d; }); } </script>
https://d3js.org/d3.v4.min.js