无法对整流器进行排序

时间:2019-05-22 01:26:55

标签: javascript d3.js

我想使用单选按钮,对条形图中的矩形进行排序。源自以下出色的实现:d3 unable to append full data after filtering ,我现在有以下内容:

docker-compose run dev node node_packages/nodemon/bin/nodemon.js -L server.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)");

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.sort(function(x, y){
     return d3.descending(x.aum, y.aum);
  });

  applyData(newData);

});

applyData(data);

尽管未引发任何错误,但排序没有正确应用。似乎只是随机地改组数据。我想要的是将rect按降序重新排序。

问题

是什么导致我的方法无法按降序对数据进行排序?文档表明我没有走错路。我想找出问题的原因。

1 个答案:

答案 0 :(得分:1)

这些是代码中的必要更改:

  1. 每次调用该函数时,您都必须重新计算xScale域:

    xScale.domain(newData.map(function(d) {
        return d.manager;
    }))
    
  2. 您必须再次调用轴生成器:

    graphGroup.select(".axis--x")
        .transition()
        .duration(750)
        .call(d3.axisBottom(xScale))
    
  3. 最后,Array.prototype.sort进行适当排序。这是在修改原始数据数组。因此,您必须复制该原始数组,并对其副本进行排序:

    var newData = JSON.parse(JSON.stringify(data)).sort(//etc...
    

这是您所做的更改(在较小的SVG中)的代码:

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

var height = 300;
var width = 700;

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;
  }))
  .paddingInner(0.2)
  .paddingOuter(0.2);

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) {

  xScale.domain(newData.map(function(d) {
    return d.manager;
  }))

  var bars = graphGroup
    .selectAll('rect')
    .data(newData, function(d) {
      return d.manager;
    });

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

  graphGroup.select(".axis--x")
    .transition()
    .duration(750)
    .call(d3.axisBottom(xScale))
}

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

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

  var newData = JSON.parse(JSON.stringify(data)).sort(function(x, y) {
    return d3.descending(x.aum, y.aum);
  });

  applyData(newData);

});

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