D3使堆叠条形图动态化 [英] D3 make stacked bar chart dynamic

查看:488
本文介绍了D3使堆叠条形图动态化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想遵循此示例:或此示例,两者都使用 d3堆栈布局对象来计算堆叠条形的顶部和底部位置。



无论如何进行计算,最终目标是为每个的数据行,其中包含要堆叠的每个值的对象。每个对象需要一个 y0 值表示堆栈中所有以前的值的总和(即,条的底部),并且 y1 表示该条和之前所有条的总和的值(即,条的顶部)。



您只需保存栏的 height ,而不是其中一个值,但堆栈布局会创建y0 / y1结构,因为它很容易与堆叠的区域图形一起使用。区域由线的位置而不是高度定义。


I am trying to follow this example: http://bl.ocks.org/mbostock/3886208

In my application I have to show a stacked bar chart where I can see for example how many different animals specific user bought.

Here is my object:

[["PersonName1", 10, 10],["PersonName2", 4, 16]];

First property is name, second is animal type 1, and third is animal type 2.

I've got stuck in this foreach loop:

data.forEach(function(d) {
    var y0 = 0;
    d.ages = color.domain().map(function(name) {
        return {name: name, y0: y0, y1: y0 += +d[name]};
    });
    d.total = d.ages[d.ages.length - 1].y1;
});

What exactly do the code lines below do?

d.ages = color.domain().map(function(name) {
    return {name: name, y0: y0, y1: y0 += +d[name]};
});

I can't exactly figure out how to do the same thing with my objects.

I've tried to do something like this:

scope.data.forEach(function(d) {
    var y0 = 0;
    d.animals = color.domain().map(function(name) {
        return {name: d[0], y0: y0, y1: y0 += +d[1]};
    });
    d.total = d.animals[d.animals.length - 1].y1;                     
});

But d.animals is always empty.

And i have to use it later on in:

  state.selectAll("rect")
      .data(function(d) { return d.animals; })
     .enter()
      .append("rect")
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.y1); })
      .attr("height", function(d) { return y(d.y0) - y(d.y1); })
      .style("fill", function(d) { return color(d.name); });

Any ideas?

解决方案

That particular bit of code is just a rather confusing way of converting all the values in the row into an array of cumulative values. It depends on the previous line of code, where the domain of the color scale is defined as all the keys from the first data object (i.e., all the column names in the csv file) except for "State". It then maps this array of column names to an array of objects, each of which contains the column name, the total of all previous values (y0), and the new total created by adding the corresponding data value (extracted from the data-row object with data[name]) to the old total. In addition to being assigned to the y1 property of the object in the ages array, the new total is assigned to the y0 variable so that it carries over for mapping the next value in the array.

This wasn't working for you, because your data rows are represented as arrays, not as key:value objects created from reading a csv file. So you aren't able to create an array of column names, and you aren't able to use those names to access the data. You'll have to create the sub-arrays yourself, using array index numbers to access the different data values.

If that's still confusing, I would recommend you look at this or this example, which both use the d3 stack layout object to calculate the top and bottom positions of the stacked bars.

Regardless of how you do the calculation, the end goal is to create a sub-array for each of your data rows, containing objects for each of the values that you want to stack. Each object needs to have a y0 value representing the total of all previous values in the stack (i.e., the bottom of the bar), and a y1 value representing the total of that bar and all the previous ones (i.e., the top of the bar).

You could just save the height of the bar instead of one of these values, but the stack layout creates the y0/y1 structure, since it is easy to use with stacked area graphs. An area is defined by the position of the lines, not by the height.

这篇关于D3使堆叠条形图动态化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆