2016-11-26 54 views
1

我有以下的饼图有一个非常漂亮的转型:确保过渡完成

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


    }); 


}; 

如果更改的选择单选按钮,然后单击该部分未完成其转换的饼图部分,因为我认为它决定需要转到其“开”事件。

如何确保过渡完成? (并且饼图不会执行pac-man模仿)

回答

3
  1. 清除收听开始时的听众。
  2. 安装它时,过渡结束

像这样:

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

+1

(调升),这是极好的。现在丢失的一小部分功能是,当我将鼠标悬停在切片上时,最初呈现视觉效果时,不透明度不会转变为指示光标悬停在其上。在事件'selectAll(“input”)。on(“change”)后面,发生了这种功能返回,即一旦用户点击单选按钮,我可以在某处添加一行代码,这样当视觉初始化时事件到单选按钮被触发,以确保不透明度过渡到位? – whytheq

+1

是的,错过了那个部分,我已经编辑了我的答案,最初需要附加听众(就像以前那样)。稍后改变无线电价值,在转换开始时分离聆听者,转换后聆听者返回。 – Cyril

+0

酷 - 您是否需要在视觉第一次呈现时强制更改代码中的无线电值 - 或仅仅需要添加回我的听众?(...我想问的原因是,有很多代码行,所以只需检查是否添加了任何代码行,我可能会发现,除了在代码段中指定的代码行以上) – whytheq