d3过滤后无法附加完整数据

时间:2019-05-21 02:33:47

标签: javascript d3.js

我有一个简化的项目版本,我将其压缩到以下代码段中:

var margins = {top:20, bottom:300, left:100, right:100};

var height = 600;
var width = 1200;

var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;

var svg = d3.select('body')
    .append('svg')
    .attr('width', totalWidth)
    .attr('height', totalHeight);

var graphGroup = svg.append('g')
    .attr('transform', "translate("+margins.left+","+margins.top+")");

var data = [
  {'manager':'ABC-CA', 'aum':230561804112.86996, 'type':'JV'},
  {'manager':'AEGON-Industrial', 'aum':187676730861.82004, 'type':'JV'},
  {'manager':'AVIC', 'aum':677643221.8599999, 'type':'DM'},
  {'manager':'AXA-SPDB', 'aum':111220010833.66998, 'type':'JV'},
  {'manager':'Baoying', 'aum':26328526612.41, 'type':'DM'},
  {'manager':'Beixin Ruifeng', 'aum':10500065729.3, 'type':'JV'},
  {'manager':'BOB-Scotiabank', 'aum':69159188249.67, 'type':'JV'},
  {'manager':'BOC IM', 'aum':396466612963.73, 'type':'DM'},
  {'manager':'BOCI Securities', 'aum':57940275708.97, 'type':'JV'}
];

  var yExtents = d3.extent(data, function(d) {return d.aum; })

  var xScale = d3.scaleBand()
    .rangeRound([0, width])
    .domain(data.map(function(d) {return d.manager; }));

  var yScale = d3.scaleLinear()
      .range([height,0])
      .domain(yExtents);

  graphGroup.append("g")
      .attr("class", "axis axis--y")
      .attr("transform", "translate(0," + 0 + ")")
      .call(d3.axisRight(yScale))
      .selectAll("text")
      .attr('text-align','right')
      .attr("transform", "translate(-90,0)");

  graphGroup.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(xScale))
      .selectAll("text")
      .attr("transform", "translate(0,0)");


  var bars = graphGroup.selectAll('rect')
    .data(data)
    .enter()
    .append('rect')
    .attr('x', function(d) {return xScale(d.manager); })
    .attr('y', function(d) {return yScale(d.aum); })
    .attr('width', xScale.bandwidth())
    .attr('height', function(d) {return height-yScale(d.aum); })
    .style('fill','#003366');

  d3.select('#rd1').on('click', function() {

    var newData = data;

    bars.data(newData).enter()
        .append('rect');

    bars.transition()
        .duration(750)
        .attr('x', function(d) {return xScale(d.manager); })
        .attr('y', function(d) {return yScale(d.aum); })
        .attr('height', function(d) {return height-yScale(d.aum); })
        .style('fill','#003366');

  });

  d3.select('#rd2').on('click', function() {

    var newData = data.filter(function(d) {return d.type=="JV"});
    bars.data(newData).exit().remove();

    bars.enter()
        .attr('x', function(d) {return xScale(d.manager); })
        .attr('y',height);

    bars.transition()
        .duration(750)
        .attr('x', function(d) {return xScale(d.manager); })
        .attr('y', function(d) {return yScale(d.aum); })
        .attr('height', function(d) {return height-yScale(d.aum); });

  });
<form>
<label class='radio-label'>All <input type="radio" name="level" value="all" checked="checked" id='rd1'></input></label>
<label class='radio-label'>JV <input type="radio" name="level" value="jv" id='rd2'></input></label>
</form>
<script src="https://d3js.org/d3.v5.min.js"></script>

我的目的是当用户单击“ JV”单选按钮时用d.type=='JV'过滤数据,这样就可以了。但是,我对“所有”单选按钮的功能无法正常运行,并且对它进行故障排除已证明是有问题的。 “全部”单选按钮应该再次显示整个数据集,但它仅显示数据集的一部分,因此缺少值,我不知道如何正确设置。

在控制台日志中,console.log(newData.length)是正确的数字:9,但仅附加了5个矩形。

问题

我的输入,更新,退出实现是否有缺陷,如果存在,如何解决,以便在过滤后可以再次完整显示我的数据?

1 个答案:

答案 0 :(得分:4)

var margins = {
  top: 20,
  bottom: 300,
  left: 100,
  right: 100
};

var height = 600;
var width = 1200;

var totalWidth = width + margins.left + margins.right;
var totalHeight = height + margins.top + margins.bottom;

var svg = d3.select('body')
  .append('svg')
  .attr('width', totalWidth)
  .attr('height', totalHeight);

var graphGroup = svg.append('g')
  .attr('transform', "translate(" + margins.left + "," + margins.top + ")");

var data = [{
    'manager': 'ABC-CA',
    'aum': 230561804112.86996,
    'type': 'JV'
  },
  {
    'manager': 'AEGON-Industrial',
    'aum': 187676730861.82004,
    'type': 'JV'
  },
  {
    'manager': 'AVIC',
    'aum': 677643221.8599999,
    'type': 'DM'
  },
  {
    'manager': 'AXA-SPDB',
    'aum': 111220010833.66998,
    'type': 'JV'
  },
  {
    'manager': 'Baoying',
    'aum': 26328526612.41,
    'type': 'DM'
  },
  {
    'manager': 'Beixin Ruifeng',
    'aum': 10500065729.3,
    'type': 'JV'
  },
  {
    'manager': 'BOB-Scotiabank',
    'aum': 69159188249.67,
    'type': 'JV'
  },
  {
    'manager': 'BOC IM',
    'aum': 396466612963.73,
    'type': 'DM'
  },
  {
    'manager': 'BOCI Securities',
    'aum': 57940275708.97,
    'type': 'JV'
  }
];

var yExtents = d3.extent(data, function(d) {
  return d.aum;
})

var xScale = d3.scaleBand()
  .rangeRound([0, width])
  .domain(data.map(function(d) {
    return d.manager;
  }));

var yScale = d3.scaleLinear()
  .range([height, 0])
  .domain(yExtents);

graphGroup.append("g")
  .attr("class", "axis axis--y")
  .attr("transform", "translate(0," + 0 + ")")
  .call(d3.axisRight(yScale))
  .selectAll("text")
  .attr('text-align', 'right')
  .attr("transform", "translate(-90,0)");

graphGroup.append("g")
  .attr("class", "axis axis--x")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(xScale))
  .selectAll("text")
  .attr("transform", "translate(0,0)");

function applyData(newData) {
  var bars = graphGroup
    .selectAll('rect')
    .data(newData);

  bars.exit().remove();

  bars.enter()
    .append('rect')
    .attr('x', function(d) {
      return xScale(d.manager);
    })
    .attr('y', height)    
    .attr('width', xScale.bandwidth())
    .style('fill', '#003366')
    .merge(bars)
    .transition()
    .duration(750)
    .attr('x', function(d) {
      return xScale(d.manager);
    })
    .attr('y', function(d) {
      return yScale(d.aum);
    })
    .attr('height', function(d) {
      return height - yScale(d.aum);
    });
}

d3.select('#rd1').on('click', function() {
  applyData(data);
});

d3.select('#rd2').on('click', function() {

  var newData = data.filter(function(d) {
    return d.type == "JV"
  });
  applyData(newData);

});

applyData(data);
<form>
  <label class='radio-label'>All <input type="radio" name="level" value="all" checked="checked" id='rd1'></input></label>
  <label class='radio-label'>JV <input type="radio" name="level" value="jv" id='rd2'></input></label>
</form>
<script src="https://d3js.org/d3.v5.min.js"></script>

选择是不可变的-您无法在不同的bars调用之间保存和重用data选择。另外,您将在3个地方复制代码-初始数据和每个点击处理程序。我通过将代码提取为一种方法来重构代码。