var numberOfBars = 80; create(); function create(){ data = []; for(var x = 0; x < numberOfBars; x ++){ var val1 = Math.random()*100 + 50 data.push({ value1: val1, value2: Math.random()*100 + val1 }) } generateDonut(data) } function generateDonut(data){ var divH = parseInt( d3.select("#chartArea").style("height") ); var divW = parseInt( d3.select("#chartArea").style("width") ); var margin = {top: 10, right: 10, bottom: 10, left: 10}; var w = divW - margin.left - margin.right; h = divH - margin.top - margin.bottom; smallestDim = h < w ? h : w; var outerRadius = smallestDim / 4.5, innerRadius = outerRadius / 2; var pie = d3.layout.pie() .value(function(d){ return 10; }) .padAngle(.010); var arc = d3.svg.arc() .padRadius(outerRadius) //is this line even necessary??? .innerRadius(innerRadius); var coordinates = []; var coordinates2 = []; var svg = d3.select("#chartArea").append("svg") .attr("width", w) .attr("height", h) .append("g") .attr("transform", "translate(" + w / 2 + "," + (h) / 2 + ")"); svg.selectAll("path") .data(pie(data)) .enter().append("path") .each(function(d) { d.outerRadius = innerRadius + d.data.value1 + d.data.value2; //for the coordinates var alpha = (d.startAngle + d.endAngle)/2; var l = d.outerRadius coordinates.push([alpha, l]) coordinates2.push([alpha, l - d.data.value2]) }) .attr("d", arc) .style('fill', 'rgba(128,0,0,.2') //change this value to see where the bars should be .style('stroke', 'none') .on('mouseover', function(d){ console.log(d) d3.select(this).style('stroke', 'orange'); d3.select(this).style('stroke-width', '2px'); var target = 'a' + String((d.startAngle + d.endAngle)/2).replace('.',''); d3.selectAll("." + target).style("stroke-width", "5px") }) .on('mouseout', function(d){ d3.select(this).style('stroke', 'none'); var target = 'a' + String((d.startAngle + d.endAngle)/2).replace('.',''); d3.selectAll("." + target).style("stroke-width", "2.5px") }) drawLines(coordinates, 'maroon', 'outer-bar'); drawLines(coordinates2, 'black', 'inner-bar'); function drawLines(coordinates, colour, group){ coordinates = coordinates.sort(function(a, b){ return a[0] - b[0]; }) for(i in coordinates){ var alpha = coordinates[i][0]; var l = coordinates[i][1]; var x0 = l * Math.sin(alpha); var y0 = l * Math.cos(alpha); //find tangental line var newAngle = alpha + Math.PI/2; var newl = l * Math.PI / numberOfBars; var x2 = x0 + newl * Math.sin(newAngle) var y2 = y0 + newl * Math.cos(newAngle) var x1 = x0 - newl * Math.sin(newAngle) var y1 = y0 - newl * Math.cos(newAngle) var target = 'a' + String(alpha).replace('.',''); svg.append("line") .style("stroke-width", "2.5px") .style("stroke", colour) .attr("class", target + " " + group)//assigning multiple classes .attr("x1", x1) .attr("x2", x2) .attr("y1", -y1) .attr("y2", -y2) .on('mouseover', function(d){ //'d' doesnt reference anything as there is no associated data console.log(this) d3.selectAll('.' + group).style("stroke-width", "5px") }) .on('mouseout', function(d){ d3.selectAll('.' + group).style("stroke-width", "2.5px") }) } } }