D3 - 为什么这种排序功能不会更新其选择中的所有元素?

时间:2014-12-31 20:21:04

标签: javascript d3.js

我正在制作sorts circle elements (each circle is a planet)的D3视觉效果。有一个可视化功能,为每个行星创建一个圆圈,如下所示:

<g class="planet">
   <circle class="Mercury" r="1.6264266666666667" cy="90" cx="50" fill="#333">
</g>
<g class="planet">
   <circle class="Venus" r="4.034393333333334" cy="90" cx="198.5" fill="#333">
</g>
<g class="planet">
   <circle class="Earth" r="4.252066666666667" cy="90" cx="347" fill="#333">
</g>
...

同样的功能为每个星球创建标签。

我写了第二个函数sort,它将行星/圆圈按降序或升序排列。

    var sort = function(){

        planets
            .sort(function(a, b) {
                if(orderOfAppearance){
                    return d3.descending(a["Equatorial radius (KM)"], b["Equatorial radius (KM)"]);     
                }
                else{
                    return d3.ascending(a["Mean distance from Sun (AU)"], b["Mean distance from Sun (AU)"]);    
                }


            })
            .transition()
            .duration(1500)
            .attr("cx", function(d,i){
                return ((width * 0.99) / radiuses.length) * i + 50; 
            });
            // other stuff... 
    }

sort函数确实正确地对圆进行排序(即它在视觉上是正确的),但是当我检查DOM时,我看到在调用sort之后,所有的圆都被附加到第一个g元素上,而另外7个g元素清空:

<g class="planet">
 <circle class="Jupiter" r="47.661786666666664" cy="90" cx="50" fill="#333">
 <circle class="Saturn" r="40.17809333333334" cy="90" cx="198.5" fill="#333">
 <circle class="Uranus" r="17.03816666666667" cy="90" cx="347" fill="#333">
 <circle class="Neptune" r="16.510906666666667" cy="90" cx="495.5" fill="#333">
 ...
 <circle class="Mercury" r="1.6264266666666667" cy="90" cx="1089.5" fill="#333">
</g>
<g class="planet"></g>
<g class="planet"></g>
...

为什么我的sort函数只选择第一个g元素而不是选择中的所有g元素?行星是一个selectAll(&#34; circle&#34;)选择。

我已将所有内容放入gist here

1 个答案:

答案 0 :(得分:1)

此处的问题是,您的planets选择实际上是circle元素的数组,而不是g元素。要解决此问题,请确保为变量planets分配了g元素,然后附加circles后缀。在排序功能中,您需要更新以对g元素进行排序,然后更新每个元素中的circle

planets = solarSystem.selectAll("g.planet")
    .data(planetaryData)
    .enter()
    .append("g")
    .classed("planet", true);

planets.append("circle")
    .attr({ ...


var sort = function(){

    planets
    .sort(function(a, b) {
          if(orderOfAppearance){
          return d3.descending(a["Equatorial radius (KM)"], b["Equatorial radius (KM)"]);
          }
          else{
          return d3.ascending(a["Mean distance from Sun (AU)"], b["Mean distance from Sun (AU)"]);
          }


          })
    .transition()
    .duration(1500)
    .select("circle")
    .attr("cx", function(d,i){ ...