简单堆积的行图

时间:2019-05-06 05:56:34

标签: javascript d3.js

虽然我之前根据How to stack rects respective of previous rect's height?使用let计数器创建了简单的堆叠行/条形图,但是我想看看使用.keys()和{ {1}}个呼叫,就像我们在Bostock's examples之一中看到的那样。这是我最近尝试的一个简单片段:

.stack()
var margins = {top:20, bottom:300, left:30, right:100};

var height = 600;
var width = 900;

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 = [
  {'country':'USA', 'value':.20},
  {'country':'Canada', 'value':.15},
  {'country':'Mexico', 'value':.10}
];

var colorMap = {
  'USA':"#f6d18b",
  'Canada':"#366092",
  'Mexico':"#95b3d7",
  "":"#a6a6a6"
};

var xScale = d3.scaleLinear()
    .range([0,width])
    .domain([0,1]);

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

graphGroup.append('g')
    .selectAll('g')
    .data(d3.stack().keys(colorMap)(data))
    .enter().append('g')
      .style('fill', function(d) {return colorMap[d.country]; })
    .selectAll('rect')
    .data(function(d) {return d; })
    .enter()
    .append('rect')
      .attr('x', function(d) {return xScale(d); })
      .attr('y', 40)
      .attr('width', function(d) {return xScale(d[0]) - xScale(d[1]); });

没有引发错误,我的实现似乎与Bostock的示例相同(保存为我的是一个折线图,他的是一个条形图)。我注意到<script src="https://d3js.org/d3.v5.min.js"></script>需要一个对象,因此我将keys()传递给它-它具有正确的键。

问题

我的colorMap / .keys()的实现出了什么问题?结果应该是一排矩形的矩形,其宽度为数据中的.stack(),如以下所示:

value

1 个答案:

答案 0 :(得分:1)

您对stack()的行为有误解。

首先,您的数据尚未准备好传递给堆栈生成器。在您的数组中,每个对象都是一个数据点,仅描述了国家及其价值。那里没有什么可以堆放的。如果您查看docs,将会看到:

  

[...]返回数组中的每个序列i都与第i个键相对应。每个系列都是点的数组,其中每个点j对应于输入数据中的第j个元素。

每个对象只有两个属性,其中一个是分类的,而不是定量的。因此,您无法堆叠拥有的数据数组。

另一方面,如果您有:

var data = [
  {year: 2016, USA: 0.20, Mexico: 0.10, Canada: 0.15},
  {year: 2016, USA: 0.40, Mexico: 0.04, Canada: 0.45},
  {year: 2016, USA: 0.07, Mexico: 0.19, Canada: 0.17},
  {year: 2016, USA: 0.11, Mexico: 0.30, Canada: 0.18}
];

您可以这样做:

var data = [
  {year: 2016, USA: 0.20, Mexico: 0.10, Canada: 0.15},
  {year: 2016, USA: 0.40, Mexico: 0.04, Canada: 0.45},
  {year: 2016, USA: 0.07, Mexico: 0.19, Canada: 0.17},
  {year: 2016, USA: 0.11, Mexico: 0.30, Canada: 0.18}
];
    
var stack = d3.stack().keys(["USA", "Mexico", "Canada"]);
var stackedData = stack(data);
console.log(stackedData)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

还要注意,keys接受一个函数或一个数组,而不是一个对象。