d3.js分段圆环图

时间:2014-03-09 19:26:04

标签: javascript d3.js charts

我一直在研究分段圆环图表应用程序。热衷于增强图表标签,使其与细分市场一起动画。

有没有办法补间标签,以便它们随着弧形动画一起移动。

http://jsfiddle.net/NYEaX/203/

enter image description here

最新代码

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);           
        });

});

0 个答案:

没有答案