【问题标题】:How to create a stacked barchart using d3?如何使用 d3 创建堆叠条形图?
【发布时间】:2017-07-14 17:45:22
【问题描述】:

我有一个对象数组:

var data = [
  {"ORDER": 1, "apples": 3840, "bananas": 1920, "cherries": 960},
  {"ORDER": 2, "apples": 1600, "bananas": 1440, "cherries": 960},
  {"ORDER": 3, "apples":  640, "bananas":  960, "cherries": 640},
  {"ORDER": 4, "apples":  320, "bananas":  480, "cherries": 640}
];

我想创建一个堆积条形图,以便订单位于 x 轴上,而苹果、香蕉和樱桃的总数位于 y 轴上。 到目前为止,这是我的代码:

x = d3.scaleOrdinal().range([0, w-50])
y = d3.scaleLinear().range([0, h-50])

var stack = d3.stack()
    .keys(["apples", "bananas", "cherries", "dates"])
    .order(d3.stackOrderNone)
    .offset(d3.stackOffsetNone);

var series = stack(data);

 x.domain(series.map(function(d) { return d.Order; }));
 y.domain([0, d3.max(data, function(d) { return d; })]).nice();

g.append("g")
    .selectAll("g")
    .data(d3.stack()(series))
    .enter().append("g")
        .attr("fill", function(d) { return color(d.key); })
    .selectAll("rect")
    .data(function(d) { return d; })
    .enter().append("rect")
        .attr("x", function(d) { return x(d.Order); })
        .attr("y", function(d) { return y(d[1]); })
        .attr("height", function(d) { return y(d[0]) - y(d[1]); })
        .attr("width", x);  

我还将它附加到 svg,但我知道问题出在上面的代码中。关于我做错了什么有什么想法吗?

【问题讨论】:

    标签: javascript d3.js svg bar-chart


    【解决方案1】:

    存在一些问题。

    一,你的图表数据已经准备好堆积在series

    var series = stack(data);
    

    这:d3.stack()(series); 将产生一个空数组:

    var data = [
      {"ORDER": 1, "apples": 3840, "bananas": 1920, "cherries": 960},
      {"ORDER": 2, "apples": 1600, "bananas": 1440, "cherries": 960},
      {"ORDER": 3, "apples":  640, "bananas":  960, "cherries": 640},
      {"ORDER": 4, "apples":  320, "bananas":  480, "cherries": 640}
    ];
    var stack = d3.stack()
        .keys(["apples", "bananas", "cherries"])
        .order(d3.stackOrderNone)
        .offset(d3.stackOffsetNone);
    var series = stack(data);
    console.log(d3.stack()(series));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script>

    再往下:

     .attr("x", function(d) { return x(d.Order); })
    

    这将返回未定义。首先,您的财产是ORDER 而不是Order,其次,如果您在返回之前console.log(d),您会注意到财产订单位于:d.data.ORDER

    这也是你的体重秤的问题:

     x.domain(series.map(function(d) { return d.Order; }));
    

    对于您的 x 比例域,您应该使用您的 data 变量来映射 x 域:x.domain(data.map(function(d) { return d.ORDER; }));


    说到比例,你的宽度最好用scaleBand()(documentation)而不是scaleOrdinal()定义,这将允许你用x.bandwidth()设置宽度。

    最后,还是说到音阶: 对于您的 y 比例,您的域将无法正常工作,如果使用 this bl.ock as an example,您将看到创建的 total 属性将定义域的上端。因此,您需要找到一种方法来获取要为每个ORDER 绘制的所有属性的总数。我使用任意 10 000 作为上限来生成一个工作示例(我也不知道你的颜色函数,所以我只是使用了一个数组):

    var data = [
      {"ORDER": 1, "apples": 3840, "bananas": 1920, "cherries": 960},
      {"ORDER": 2, "apples": 1600, "bananas": 1440, "cherries": 960},
      {"ORDER": 3, "apples":  640, "bananas":  960, "cherries": 640},
      {"ORDER": 4, "apples":  320, "bananas":  480, "cherries": 640}
    ];
    
    var h = 200;
    var w = 200;
    var svg = d3.select('body').append('svg').attr('width',w).attr('height',h);
    var g = svg.append('g');
    
    
    var x = d3.scaleBand().rangeRound([0, w-50]);
    var y = d3.scaleLinear().range([h-50, 0]).domain([0,10000]);
    var color = ['#bae4bc','#7bccc4','#43a2ca'];
    
    var stack = d3.stack()
        .keys(["apples", "bananas", "cherries"])
        .order(d3.stackOrderNone)
        .offset(d3.stackOffsetNone);
        
    var series = stack(data);
    
    x.domain(data.map(function(d) { return d.ORDER; }));
    
    g.append("g")
        .selectAll("g")
        .data(series)
        .enter().append("g")
            .attr("fill", function(d,i) { return color[i]; })
        .selectAll("rect")
        .data(function(d) { return d; })
        .enter().append("rect")
            .attr("x", function(d) { return x(d.data.ORDER); })
            .attr("y", function(d) { return y(d[1]); })
            .attr("height", function(d) { return y(d[0]) - y(d[1]); })
            .attr("width", x.bandwidth());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多