来自Array数据的D3堆栈图表

时间:2017-11-03 22:25:05

标签: javascript json d3.js

在所有使用D3(v4)生成堆积图表的示例中,我到目前为止看到,输入是一个JSON对象数组,like below

var data = [
  {month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400},
  {month: new Date(2015, 1, 1), apples: 1600, bananas: 1440, cherries: 960, dates: 400},
  {month: new Date(2015, 2, 1), apples:  640, bananas:  960, cherries: 640, dates: 400},
  {month: new Date(2015, 3, 1), apples:  320, bananas:  480, cherries: 640, dates: 400}
];

如果我有一个数组(带有隐式键),我怎么能生成一个堆栈呢?有点像...

var data = {
  "2015, 0, 1": [3840, 1920, 960, 400],
  "2015, 1, 1": [1600, 1440, 960, 400],
  "2015, 2, 1": [ 640,  960, 640, 400],
  "2015, 3, 1": [ 320,  480, 640, 400]
};

这种输入结构的原因是,我必须使用如下所示的数据绘制几个堆栈:

// need to draw one stack per row below
var data = {
  "1": {"A":[100,200], "B":[200,300]},
  "2": {"X":[34,90], "A":[210,90], "C":[56,67]},
  "3": {"B":[50,40], "C":[0,100], "Z":[50,500], "Q":[78,87]},
  "4": {"Z":[40,50]},
  ...
}

2 个答案:

答案 0 :(得分:3)

API很清楚:您必须将数组传递给堆栈生成器。根据它,d3.stack() ......

  

...为给定的数据数组生成一个堆栈,返回一个代表每个系列的数组。 (强调我的)

现在你有一个对象,而不是一个数组。

所以,我认为这里最好的解决方案就是将该对象转换为堆栈生成器所期望的数组结构,您在此问题(第一个数组)中共享。

这只涉及vanilla JavaScript。这是一个例子,故意详细,所以你可以看到步骤:



var data = {
  "2015, 0, 1": [3840, 1920, 960, 400],
  "2015, 1, 1": [1600, 1440, 960, 400],
  "2015, 2, 1": [640, 960, 640, 400],
  "2015, 3, 1": [320, 480, 640, 400]
};

var dataArray = [];

for (var key in data) {
  var obj = {};
  obj.month = key;
  data[key].forEach(function(d, i) {
    obj["value" + i] = d;
  })
  dataArray.push(obj)
}

console.log(dataArray)




它会生成这个数组:

[
    {month: "2015, 0, 1", value0: 3840, value1: 1920, value2: 960, value3: 400},
    {month: "2015, 1, 1", value0: 1600, value1: 1440, value2: 960, value3: 400},
    {month: "2015, 2, 1", value0: 640, value1: 960, value2: 640, value3: 400},
    {month: "2015, 3, 1", value0: 320, value1: 480, value2: 640, value3: 400}
]

你的问题中第一个数组的结构与你的问题相同。

您可以将monthvalue + i更改为您想要的密钥名称。

答案 1 :(得分:0)

当数据是数组时,通过生成包含以下内容的索引的键对象,可以使用数组渲染堆栈条(或其他堆栈表示形式):

const serverData = {
  "2015, 0, 1": [3840, 1920, 960, 400],
  "2015, 1, 1": [1600, 1440, 960, 400],
  "2015, 2, 1": [ 640,  960, 640, 400],
  "2015, 3, 1": [ 320,  480, 640, 400]
};

const serverDataKeys = Object.keys(serverData)
const data = serverDataKeys.map(key => serverData[key]);

/**
data = [
 [3840, 1920, 960, 400],
 [1600, 1440, 960, 400],
 [640, 960, 640, 400],
 [320, 480, 640, 400]
]
*/

const keys = serverData[serverDataKeys[0]].map( (d, index) => index);

/** keys:  [0, 1, 2, 3] */

svg.append('g')
  .selectAll('g')
  .data(d3.stack().keys(keys)(data))
  .enter().append('g')

在以下情况下:

{month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400}

data是整个对象,键是['apples', 'bannanas', 'cherries', 'dates']

使用数组[3840, 1920, 960, 400]时,键应为[0,1,2,3]