我一直在研究分段圆环图表应用程序。热衷于增强图表标签,使其与细分市场一起动画。
有没有办法补间标签,以便它们随着弧形动画一起移动。
http://jsfiddle.net/NYEaX/203/
最新代码
var arcGenerator = {
radius: 190,
oldData: "",
init: function(data){
var clone = jQuery.extend(true, {}, data);
var preparedData = this.setData(clone);
this.oldData = preparedData;
this.setup(preparedData);
},
update: function(data){
var clone = jQuery.extend(true, {}, data);
var preparedData = this.setData(clone);
this.animate(preparedData);
this.oldData = preparedData;
},
animate: function(data){
var that = this;
var chart = d3.select(".arcchart");
that.generateArcs(chart, data);
},
setData: function(data){
var diameter = 2 * Math.PI * this.radius;
var localData = new Array();
var oldEndAngle = 0;
var segmentValueSum = 0;
$.each(data[0].segments, function( ri, va) {
segmentValueSum+= va.value;
});
$.each(data[0].segments, function(ri, value) {
var startAngle = oldEndAngle;
var endAngle = startAngle + (value.value/segmentValueSum)*2*Math.PI;
data[0].segments[ri]["startAngle"] = startAngle;
data[0].segments[ri]["endAngle"] = endAngle;
data[0].segments[ri]["index"] = ri;
oldEndAngle = endAngle;
});
localData.push(data[0].segments);
return localData[0];
},
generateArcs: function(chart, data){
var that = this;
//__arc paths
//append previous value to it.
$.each(data, function(index, value) {
if(that.oldData[index] != undefined){
data[index]["previousEndAngle"] = that.oldData[index].endAngle;
}
else{
data[index]["previousEndAngle"] = 0;
}
});
var arcpaths = that.arcpaths.selectAll("path")
.data(data);
arcpaths.enter().append("svg:path")
.attr("class", function(d, i){
return "arcsegments";
})
.style("fill", function(d, i){
return d.color;
})
.transition()
.ease("elastic")
.duration(750)
.attrTween("d", arcTween);
arcpaths.transition()
.ease("elastic")
.style("fill", function(d, i){
return d.color;
})
.duration(750)
.attrTween("d",arcTween);
arcpaths.exit().transition()
.ease("bounce")
.duration(750)
.attrTween("d", arcTween)
.remove();
function arcTween(b) {
var prev = JSON.parse(JSON.stringify(b));
prev.endAngle = b.previousEndAngle;
var i = d3.interpolate(prev, b);
return function(t) {
return that.getArc()(i(t));
};
}
var r = that.radius + 20;
var ir = that.radius - 10;
//__labels
var labels = that.labels.selectAll("text")
.data(data);
labels.enter()
.append("text")
.attr("text-anchor", "middle")
labels
.attr("x", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (ir+((r-ir)/2));
return d.x = Math.cos(a) * (r + 20);
})
.attr("y", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (ir+((r-ir)/2));
return d.y = Math.sin(a) * (r + 20);
})
.text(function(d) {
return d.color;
})
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
})
.transition()
.duration(300)
labels
.transition()
.duration(300)
labels.exit().remove();
//__labels
//__pointers
that.pointers.append("defs").append("marker")
.attr("id", "circ")
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("refX", 3)
.attr("refY", 3)
.append("circle")
.attr("cx", 3)
.attr("cy", 3)
.attr("r", 3);
var pointers = that.pointers.selectAll("path.pointer")
.data(data);
pointers.enter()
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("marker-end", "url(#circ)");
pointers
.attr("d", function(d) {
if(d.cx > d.ox) {
return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
} else {
return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
}
})
.transition()
.duration(300)
pointers
.transition()
.duration(300)
pointers.exit().remove();
//__pointers
},
setup: function(data){
var chart = d3.select("#threshold").append("svg:svg")
.attr("class", "chart")
.attr("width", 520)
.attr("height", 520)
.append("svg:g")
.attr("class", "arcchart")
.attr("transform", "translate(250,250)");
this.arcpaths = chart.append("g")
.attr("class", "arcpaths");
this.labels = chart.append("g")
.attr("class", "labels");
this.pointers = chart.append("g")
.attr("class", "pointer");
this.generateArcs(chart, data);
},
getArc: function(){
var that = this;
var lowThreshold = 5;
var highThreshold = 15
var arc = d3.svg.arc()
.innerRadius(function(d){
if(d.index%2){
return that.radius-highThreshold;
}else{
return that.radius-lowThreshold;
}
})
.outerRadius(function(d){
if(d.index%2){
return that.radius+lowThreshold;
}else{
return that.radius+highThreshold;
}
})
.startAngle(function(d, i){
return d.startAngle;
})
.endAngle(function(d, i){
return d.endAngle;
});
return arc;
}
}
$(document).ready(function() {
var dataCharts = [
{
"data": [
{
"segments": [
{
value: 50,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 23,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 40,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 33,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 45,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 40,
color: "#2c2c2e"
},
{
value: 33,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 33,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 45,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 40,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 23,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 40,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 33,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 45,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 40,
color: "#2c2c2e"
},
{
value: 33,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 33,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 50,
color: "#2c2c2e"
},
{
value: 45,
color: "#2c2c2e"
},
{
value: 10,
color: "#2c2c2e"
},
{
value: 40,
color: "#2c2c2e"
}
]
}
]
},
{
"data": [
{
"segments": [
{
value: 50,
color: "red"
},
{
value: 100,
color: "yellow"
},
{
value: 10,
color: "green"
}
]
}
]
},
{
"data": [
{
"segments": [
{
value: 50,
color: "red"
},
{
value: 50,
color: "brown"
},
{
value: 50,
color: "orange"
},
{
value: 100,
color: "yellow"
},
{
value: 10,
color: "green"
}
]
}
]
}
];
var clone = jQuery.extend(true, {}, dataCharts);
arcGenerator.init(clone[0].data);
$(".testers a").on( "click", function(e) {
e.preventDefault();
var clone = jQuery.extend(true, {}, dataCharts);
var pos = $(this).parent("li").index();
arcGenerator.update(clone[pos].data);
});
});