Custom donut chart using d3.svg.arc().
forked from jdutta's block: Thin Donut Chart
| license: mit |
Custom donut chart using d3.svg.arc().
forked from jdutta's block: Thin Donut Chart
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <link rel="stylesheet" href="thin-donut.css" type="text/css"/> | |
| </head> | |
| <body> | |
| <div id="thin-donut-chart"></div> | |
| </body> | |
| <script src="http://d3js.org/d3.v4.min.js"></script> | |
| <script src="thin-donut.js"></script> | |
| </html> |
| body { | |
| font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
| width: 960px; | |
| height: 500px; | |
| position: relative; | |
| } | |
| #thin-donut-chart { | |
| width: inherit; | |
| height: inherit; | |
| } | |
| .center-label, .bottom-label { | |
| text-anchor: middle; | |
| alignment-baseline: middle; | |
| pointer-events: none; | |
| } | |
| .half-donut .center-label { | |
| alignment-baseline: initial; | |
| } |
| (function () { | |
| var chartConfig = { | |
| width: 200, | |
| height: 200, | |
| color: d3.scaleOrdinal(d3.schemeCategory10), | |
| // See margin convention: http://bl.ocks.org/mbostock/3019563 | |
| margin: { | |
| top: 5, | |
| right: 5, | |
| bottom: 5, | |
| left: 5 | |
| } | |
| }; | |
| function makeRandomData() { | |
| return { | |
| centerLabel: 'hello', | |
| bottomLabel: 'world', | |
| values: [ | |
| {label: 'x', value: Math.random() * 3}, | |
| {label: 'y', value: Math.random() * 10} | |
| ] | |
| }; | |
| } | |
| function init() { | |
| var chartData = makeRandomData(), | |
| chartId = 'thin-donut-chart', | |
| d3ChartEl = d3.select('#' + chartId); | |
| chartConfig.width = parseInt(d3ChartEl.style('width')) || chartConfig.width; | |
| chartConfig.height = parseInt(d3ChartEl.style('height')) || chartConfig.height; | |
| drawChart(chartId, chartData, chartConfig); | |
| } | |
| function drawChart(chartId, chartData, chartConfig) { | |
| var width = chartConfig.width, | |
| height = chartConfig.height, | |
| margin = chartConfig.margin, | |
| radius; | |
| // Adjust for margins | |
| width = width - margin.left - margin.right; | |
| height = height - margin.top - margin.bottom; | |
| radius = Math.min(width, height) / 2; | |
| var thickness = chartConfig.thickness || Math.floor(radius / 5); | |
| var arc = d3.arc() | |
| .outerRadius(radius) | |
| .innerRadius(radius - thickness); | |
| var pieFn = d3.pie() | |
| .sort(null) | |
| .value(function (d) { | |
| return d.value; | |
| }); | |
| var centerLabel = (!!chartData.centerLabel) ? chartData.centerLabel : '', | |
| bottomLabel = (!!chartData.bottomLabel) ? chartData.bottomLabel : ''; | |
| var d3ChartEl = d3.select('#' + chartId); | |
| // Clear any previous chart | |
| d3ChartEl.select('svg').remove(); | |
| var gRoot = d3ChartEl.append('svg') | |
| .attr('width', width + margin.left + margin.right) | |
| .attr('height', height + margin.top + margin.bottom) | |
| .append('g'); | |
| gRoot.attr('transform', 'translate(' + (width / 2 + margin.left) + ',' + (height / 2 + margin.top) + ')'); | |
| var middleCircle = gRoot.append('svg:circle') | |
| .attr('cx', 0) | |
| .attr('cy', 0) | |
| .attr('r', radius) | |
| .style('fill', '#fff'); | |
| var g = gRoot.selectAll('g.arc') | |
| .data(pieFn(chartData.values)) | |
| .enter() | |
| .append('g') | |
| .attr('class', 'arc'); | |
| g.append('svg:path') | |
| .attr('d', arc) | |
| .style('fill', function (d) { | |
| return chartConfig.color(d.data.label); | |
| }) | |
| .attr('data-arc-data', function (d) { | |
| return d.data.value; | |
| }); | |
| gRoot.append('svg:text') | |
| .attr('class', 'center-label') | |
| .text(centerLabel); | |
| } | |
| init(); | |
| })(); |