d3.js组条形图不起作用

d3.js group bar chart not working

本文关键字:不起作用 条形图 js d3      更新时间:2023-09-26

这是我的工作jsfiddlehttps://jsfiddle.net/dibyendu/wn6awvbe/。现在这个条形图适用于single value,我的要求是使它成为group bar chart

因此,作为第一步,我必须基于所有值的minmax创建x轴范围。我能够成功地做到这一点。

其次,我尝试创建一个group,并将单个group bars添加到group中。这部分我无法破解。

这是我的代码我已经尝试

var combos = svg.selectAll("g").data(data)
    .enter()
    .append("g")
    .attr({width: 2 * width})
    .attr('height',y.rangeBand()+10)
    ;
combos.selectAll(".bar1")
  .append("rect")
  .attr("class", function(d) { return "bar bar--" + (d.value < 0 ? "negative" : "positive"); })
  .attr("x", function(d) { return x(Math.min(0, d.value)); })
  .attr("y", function(d) { return y(d.name); })
  .attr("width", function(d) { return Math.abs(x(d.value) - x(0)); })
  .attr("height", y.rangeBand());
combos.selectAll(".bar2")
  .append("rect")
  .attr("class", function(d) { return "bar bar--" + (d.value < 0 ? "negative" : "positive"); })
  .attr("x", function(d) { return x(Math.min(0, d.value1)); })
  .attr("y", function(d) { return y(d.name); })
  .attr("width", function(d) { return Math.abs(x(d.value1) - x(0)); })
  .attr("height", y.rangeBand());  

但由于某种原因,它不起作用。我在这里犯了什么错误。感谢您提前提供的帮助。

如果你总是保证每组有2个酒吧,快速解决方法是:

combos
      .append("rect")
      .attr("class", function(d) { return "ba ba--" + (d.value < 0 ? "negative" : "positive"); })
      .attr("x", function(d) { return x(Math.min(0, d.value)); })
      .attr("y", function(d) { return y(d.name); })
      .attr("width", function(d) { return Math.abs(x(d.value) - x(0)); })
      .attr("height", y.rangeBand() / 2); //<-- cut height in half
  combos
      .append("rect")
      .attr("class", function(d) { return "bar bar--" + (d.value < 0 ? "negative" : "positive"); })
      .attr("x", function(d) { return x(Math.min(0, d.value1)); })
      .attr("y", function(d) { return y(d.name) + (y.rangeBand() / 2); }) //<-- offset if from other bar
      .attr("width", function(d) { return Math.abs(x(d.value1) - x(0)); })
      .attr("height", y.rangeBand() / 2); //<-- cut height in 2

更新的小提琴。

评论编辑

如果你想有一个动态的酒吧数量,你真的需要改变你的输入数据。value1:, value2:等是不可行的。快速重构可能使用一组值:

{
  "name": "M1",
  "value": [-45, -13, -10, -8]
},
...

有了这种格式,你可以使用子选择,并真正开始获得一些动态代码:

var combos = svg.selectAll("g").data(data)
  .enter()
  .append("g");    
combos
  .selectAll("rect")
  .data(function(d){
  return d.value.map(function(d1){
    return {
        value: d1,
        name: d.name,
        total: d.value.length,
      };
    })
  })
  .enter()
  .append("rect")
  .attr("class", function(d) { return "ba bar--" + (d.value < 0 ? "negative" : "positive"); })
  .attr("x", function(d) { return x(Math.min(0, d.value)); })
  .attr("y", function(d,i) { return (y(d.name) + (y.rangeBand() / d.total * i)) ; })
  .attr("width", function(d) { return Math.abs(x(d.value) - x(0)); })
  .attr("height", function(d){
    return y.rangeBand() / d.total
   });

新更新的小提琴。