确保过渡完成

时间:2016-11-26 16:21:44

标签: javascript d3.js

我有以下饼图,有一个非常好的过渡:

http://plnkr.co/edit/b4uLimUSZzxiPzAkNpBt?p=preview

饼图的代码如下:

function addPieChart(meas, dataFile) {

    var width = 400,
        height = 400,
        radius = Math.min(width, height) / 2.1,
        color = d3.scale.ordinal()
        .range(["#016da9", "#4c96d5"])
        .domain([0, 1]);


    //check if the svg already exists
    var plot = d3.select("#svgPIEChart")
    if (plot.empty()) {
        var vis = d3.select("#pieChart")
            .append("svg") //create the SVG element 
            .attr({
                id: "svgPIEChart"
            })
    } else {
        var vis = d3.select("#svgPIEChart")
        vis.selectAll("*").remove();
    };

    //svg element
    vis.attr({
        //set the width and height of our visualization (these will be attributes of the <svg> tag
        width: width,
        height: height
    });

    //group of the svg element
    var svg = vis
        .append("g")
        .attr({
            'transform': "translate(" + width / 2 + "," + height * .52 + ")"
        });


    var arc = d3.svg.arc()
        .startAngle(function(d) {
            return d.x;
        })
        .endAngle(function(d) {
            return d.x + d.dx;
        })
        .outerRadius(function(d) {
            return (d.y + d.dy) / (radius);
        })
        .innerRadius(function(d) {
            return d.y / (radius);
        });


    d3.text(dataFile, function(text) {
        var csv = d3.csv.parseRows(text);
        var json = buildHierarchy(csv);



        // it seems d3.layout.partition() can be either squares or arcs
        var partition = d3.layout.partition()
            .sort(null)
            .size([2 * Math.PI, radius * radius])
            .value(function(d) {
                return d.Revenue;
            });

        var path = svg.data([json]).selectAll(".theArc")
            .data(partition.nodes)
            .enter()
            .append("path")
            .attr("class", "theArc") //<<<<<<<<<<new jq
            .attr("id", function(d, i) {
                return "theArc_" + i;
            }) //Give each slice a unique ID //<<<<<<<<<<new jq
            .attr("display", function(d) {
                return d.depth ? null : "none";
            })
            .attr("d", arc)
            .style("stroke", "#fff")
            .style("fill", function(d) {
                return color((d.children ? d : d.parent).name);
            })
            .attr("fill-rule", "evenodd")
            .style("opacity", 1)
            .on("mouseover", mouseover) 
            .on("mouseout", mouseout) 
            .on("click", up)
            .each(stash);

        // path.each(stash).on("click", up) 

        //this is a start>>>>>   
        path
            .append("title") //mouseover title showing the figures
            .text(function(d) {
                return d.name + ": " + formatAsShortInteger(d.Revenue);
            });

        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        svg.data([json]).selectAll(".theTxts")
            .data(partition.nodes)
            .enter()
            .append("text")
            .attr("class", "theTxts")
            .attr("dx", 10) //Move the text from the start angle of the arc
            .attr("dy", 15) //Move the text down
            .append("textPath")
            .attr("class", "foo")
            .attr("xlink:href", function(d, i) {
                return "#theArc_" + i;
            })
            .text(function(d) {
                if ((d.name != 'root') && ((d.name != 'B T') || (currentMeasure != 'W'))) {
                    return d.name;
                }
            })
            .on("click", up) //<<<new jq;

        svg.append("text")
            .attr({
                x: "0",
                y: "0",
                'class': "title",
                "id": "titleX",
                'text-anchor': "middle"
            })
            .text(currentMeasure + " split")
            //>>
            .append("tspan")
            .attr({
                dy: "1.1em",
                x: 0,
                'text-anchor': "middle"
            })
            .text("for " + latestMth)
            .attr("class", "title");



        d3.selectAll("input").on("change", function change() {

            value = createValueFunc(this.value);
            currentMeasure = this.value;

            var path2 = svg.data([json]).selectAll(".theArc");
            path2
                .data(partition.value(value).nodes)
                .transition()
                .duration(1500)
                .attrTween("d", arcTween)


            //to update the tooltips  
            svg.selectAll("title")
                .text(function(d) {
                    return d.name + ": " + formatAsShortInteger(value(d));
                });


            svg.selectAll("textPath")
                .text(function(d) {
                    if ((d.name != 'root') && ((d.name != 'B T') || (currentMeasure != 'W'))) {
                        return d.name;
                    }
                });

            // the following deletes what was originally created and then recreates the text
            svg.selectAll("#titleX").remove();
            svg.append("text")
                .attr({
                    x: "0",
                    y: "0",
                    'class': "title",
                    "id": "titleX",
                    'text-anchor': "middle"
                })
                .text(currentMeasure + " split")
                .append("tspan")
                .attr({
                    dy: "1.1em",
                    x: 0,
                    'text-anchor': "middle"
                })
                .text("for " + latestMth)
                .attr("class", "title");


            addProdTitl();
            updateTOPbarChart(currentGrp, currentMeasure, currentColr);
            updateBOTbarChart(currentGrp, currentMeasure, currentColr);

        });



        function mouseover() {
            d3.select(this)
                .transition()
                .duration(200)
                .style("opacity", 0.9);
        };

        function mouseout() {
            d3.select(this)
                .transition()
                .duration(200)
                .style("opacity", 1);
        };


        // update bar chart when user selects piece of the pie chart
        function up(d, i) {

            currentGrp = d.name;

            // (d.children ? d : d.parent).name
            currentColr = color((d.children ? d : d.parent).name); // color(d.name);

            addProdTitl();
            updateTOPbarChart(d.name, currentMeasure, currentColr); //color(d.name));
            updateBOTbarChart(d.name, currentMeasure, currentColr); //color(d.name));

        };


        // Stash the old values for transition.
        function stash(d) {
            d.x0 = d.x;
            d.dx0 = d.dx;
        };

        // Interpolate the arcs in data space.
        function arcTween(a) {
            var i = d3.interpolate({
                x: a.x0,
                dx: a.dx0
            }, a);
            return function(t) {
                var b = i(t);
                a.x0 = b.x;
                a.dx0 = b.dx;
                return arc(b);
            };
        };


    });


};

如果您更改单选按钮的选择,然后单击饼图的某个部分,该部分无法完成其过渡,因为我认为它决定需要继续前进到&#34; on&#34;事件

如何确保转换完成? (并且饼图不会进行模仿)

1 个答案:

答案 0 :(得分:3)

  1. 在tranistion开始时清除你的听众。
  2. 转换结束时附加
  3. 像这样:

     path2
                        .data(partition.value(value).nodes)
                        .transition()
                        .duration(1500)
                        .attrTween("d", arcTween)
                        .each("start", function(){
                          d3.select(this)
                          .on("mouseover", null) //CLEARING the listeners
                          .on("mouseout", null) //CLEARING the listeners
                          .on("click", null) //CLEARING the listeners
                        })
                        .each("end", function(){
                          d3.select(this)
                          .on("mouseover", mouseover) //attaching the listeners
                          .on("mouseout", mouseout) //attaching the listeners
                          .on("click", up) ////attaching the listeners
                        });
    

    工作代码here