D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
allyraza
Full window
Github gist
d3 donut with legend horizontal
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:30px;position:fixed;top:0;right:0;bottom:0;left:0; } </style> </head> <body> <script> class Donut { static get defaults() { return { margin: { top: 15, right: 15, bottom: 30, left: 15 } }; } constructor(config) { this.configure(config); this.init(); } configure(config) { Object.assign(this, Donut.defaults, config); } init() { const { margin, data } = this; const outerWidth = 400; const outerHeight = 300; const width = outerWidth - margin.left - margin.right; const height = outerHeight - margin.top - margin.bottom; const r = Math.min(width, height) / 2; var nodeWidth = (d) => d.getBBox().width; const cScale = d3.scaleOrdinal(d3.schemeCategory20b); const arc = d3.arc() .outerRadius(r) .innerRadius(r - 45) ; const pie = d3.pie() .value(d => d.value) ; const svg = d3.select('body') .append('svg') .style('border', '1px solid #ddd') .attr('width', outerWidth) .attr('height', outerHeight) .append('g') .attr('transform', `translate(${margin.left},${margin.top})`) ; svg.append('g') .attr('class', 'arc') .attr('transform', `translate(${width/2},${height/2})`) .selectAll('path') .data(pie(data)) .enter() .append('path') .attr('d', arc) .style('fill', d => cScale(d.value)) ; const legend = svg.append('g') .attr('class', 'legend') .attr('transform', 'translate(0,0)'); const lg = legend.selectAll('g') .data(data) .enter() .append('g') .attr('transform', (d,i) => `translate(${i * 100},${height + 15})`); lg.append('rect') .style('fill', d => cScale(d.value)) .attr('x', 0) .attr('y', 0) .attr('width', 10) .attr('height', 10); lg.append('text') .style('font-family', 'Georgia') .style('font-size', '13px') .attr('x', 17.5) .attr('y', 10) .text(d => d.label); let offset = 0; lg.attr('transform', function(d, i) { let x = offset; offset += nodeWidth(this) + 10; return `translate(${x},${height + 10})`; }); legend.attr('transform', function() { return `translate(${(width - nodeWidth(this)) / 2},${0})` }); } render() { } } new Donut({ element: 'body', margin: { top: 10, right: 0, bottom: 30, left: 0}, data: [ {label: 'Country', value: 60}, {label: 'City', value: 30}, {label: 'Continent', value: 10}, ] }); </script> </body>
https://d3js.org/d3.v4.min.js