人口金字塔中的过渡效应

时间:2016-01-28 19:33:42

标签: d3.js

我正在研究一个具有更新功能的人口金字塔。

http://bricbracs.com/hh/

当您使用新数据更新它时,您可以看到条形图在水平线上展开和收缩。我想修改过渡效果,以便条形图像这样垂直进入和退出:

http://vis.stanford.edu/jheer/d3/pyramid/shift.html

我一直在关注本教程并修改代码,但到目前为止还没有运气。

https://strongriley.github.io/d3/tutorial/bar-2.html

这是首先在加载时绘制条形图的代码。 (这是男性酒吧组,女性酒吧组是相同的)

leftBarGroup.selectAll('.bar.left')
 .data(data)
 .enter()
 .append('rect')
 .attr('class', 'bar left')
 .attr('y', function(d) { return yScale(d.group); })
 .attr("width", 0)
 .attr("opacity", 0)
 .transition()
 .duration(500)
 .attr('width', function(d) { return xScale(d.male); })
 .attr('height', yScale.rangeBand())  
 .attr("opacity", 1)

以下是更新功能中代码的相应部分,用于更改条形图。

var sel = leftBarGroup.selectAll('.bar.left')  
 .attr('class', 'bar left')
 .data(data) 
 .data(data, function(d) { return d.male; })
 .transition()
 .attr('y',0)
 .duration(500)
 .attr('y', function(d) { return yScale(d.group); })
 .attr('height', yScale.rangeBand())
 .attr('width', function(d) { return xScale(d.male); })
 .attr('height', yScale.rangeBand())

提前致谢。

1 个答案:

答案 0 :(得分:0)

这是在链接示例中重现效果的一种方法。我偏移了杆,然后将它们滑回原位。然后处理顶部和底部的条形略有不同。

注意,我只是在金字塔的男性一侧滑下来,如果你需要帮助,那么请留下我的评论。

  var sel = leftBarGroup.selectAll('.bar.left')
    .attr('class', 'bar left')
    .data(data)
    .data(data, function(d) {
      return d.male;
    })
    // offset y to slide down
    .attr('y', function(d){
      var self = d3.select(this);
      return +self.attr('y') - yScale.rangeBand();
    })
    .transition()
    .duration(500)
    // slide it back into place
    .attr('y', function(d) {
      return yScale(d.group);
    })
    // and set new width
    .attr('width', function(d) {
      return xScale(d.male);
    });

  // for the very top bar
  // not only slide it but "fade it in"
  leftBarGroup.select(':last-child')
    .style('opacity', 0)
    .transition()
    .duration(500)
    .style('opacity', 1)
    .attr('y', function(d) {
      return yScale(d.group);
    });

  // append a fake bar on the bottom
  // to slide and fade out
  leftBarGroup.append('rect')
    .attr('y', function(d) {
        return yScale('0-4');
      })
    .attr('height', yScale.rangeBand())
    .attr('width', function(){
      return leftBarGroup.select(':first-child').attr('width');
    })
    .style('fill', 'steelblue')
    .style('opacity', 0.6)
    .transition()
    .duration(500)
    .attr('y', function(d) {
        return yScale('0-4') + yScale.rangeBand();
      })
    .style('opacity', 0)
    .remove();

<强> EDITS

上升只是扭转逻辑的问题:

var sel = leftBarGroup.selectAll('.bar.left')
    .attr('class', 'bar left')
    .data(data)
    .data(data, function(d) {
      return d.male;
    })
    // offset y to slide up
    .attr('y', function(d){
      var self = d3.select(this);
      return +self.attr('y') + yScale.rangeBand()
    })
    .transition()
    .duration(500)
    // slide it back into place
    .attr('y', function(d) {
      return yScale(d.group);
    })
    // and set new width
    .attr('width', function(d) {
      return xScale(d.male);
    });

  // for the very bottom bar
  // not only slide it but "fade it in"
  leftBarGroup.select(':first-child')
    .style('opacity', 0)
    .transition()
    .duration(500)
    .style('opacity', 1)
    .attr('y', function(d) {
      return yScale(d.group);
    });

  // append a fake bar on the top
  // to slide and fade out
  var w = leftBarGroup.select(':last-child').attr('width');
  leftBarGroup.append('rect')
    .attr('class','fake')
    .attr('y', function(d) {
        return yScale('90+');
      })
    .attr('height', yScale.rangeBand())
    .attr('width', w)
    .style('fill', 'steelblue')
    .style('opacity', 0.6)
    .transition()
    .duration(500)
    .attr('y', function(d) {
        return yScale('90+') - yScale.rangeBand();
      })
    .style('opacity', 0)
    .remove();

更新了代码示例here