I am looking to develop an arc ring chart. Where each new set of data is displayed as a concentric ring inside the other.
http://jsfiddle.net/NYEaX/101/
I've tried to take a sum of the values in the data, and use this to help develop a proportion algorithm, to ensure each arc never does more than one cycle.
this part manages the concentric ring.
getArc: function(){
var that = this;
var radiusArray = [100, 80];
function getRadiusRing(i){
return that.radius-(i*20);
}
var thickness = 15;
var arc = d3.svg.arc()
.innerRadius(function(d){
return getRadiusRing(d.index);
})
.outerRadius(function(d){
return getRadiusRing(d.index)+thickness;
})
.startAngle(function(d, i){
return d.startAngle;
})
.endAngle(function(d, i){
return d.endAngle;
});
return arc;
}
but I think there is a flaw in the end angle calculations. If you enable more data - the concentric rings although they form correctly have suspicious arc lengths where they wrap around the entire chart?
setData: function(data){
var diameter = 2 * Math.PI * this.radius;
var localData = new Array();
var segmentValueSum = 0;
$.each(data[0].segments, function( ri, va) {
segmentValueSum+= va.value;
});
$.each(data[0].segments, function(ri, value) {
var segmentValue = value.value;
var fraction = segmentValue/segmentValueSum;
var arcBatchLength = fraction*2*Math.PI;
var arcPartition = arcBatchLength;
var startAngle = 0;
var endAngle = ((ri+1)*arcPartition);
data[0].segments[ri]["startAngle"] = startAngle;
data[0].segments[ri]["endAngle"] = endAngle;
data[0].segments[ri]["index"] = ri;
});
localData.push(data[0].segments);
return localData[0];
}
trying to build the chart to look like the following
I've enhanced the chart, but still have issues with the placement and updating of the legend, rings and values. Why is old data remaining? http://jsfiddle.net/NYEaX/123/
if there is more or less data - the labels don't get placed correctly
//draw labels
valueLabels = value_group.selectAll("text.value").data(reversedata)
valueLabels.enter().append("svg:text")
.attr("class", "value")
.attr("transform", function(d) {
var rings = counts;
return "translate("+(that.radius+55)/rings+", 0)";
})
.attr("dx", function(d, i){
return 19*i; })
.attr("dy", function(d, i){
return -5;
})
.attr("text-anchor", function(d){
return "start";
}).text(function(d){
return d.value;
});
valueLabels.transition().duration(300).attrTween("d", arcTween)
valueLabels.exit().remove();
I've made a version where the chart starts from the top - so different orientation. Be good to put this as a variable - maybe have the option to start the chart in 4 different quadrants.
http://jsfiddle.net/NYEaX/364/
I've adjusted
the start angle in set Data
var startAngle = Math.PI*2;
-the label placements
I've managed to fix all the bugs - Here is the final code as a jquery plugin, enjoy
http://jsfiddle.net/NYEaX/165/
Replace
by