[英]Prepare nested JSON data for D3 stacked bar chart
I have nested JSON data where the first level of keys is activity types (ride, hike, etc.) and the second level is the year. 我有嵌套的JSON数据,其中第一级键是活动类型(骑行,加息等),第二级是年份。 Each year has a value (distance in kilometers). 每年都有一个值(以千米为单位的距离)。 My data structure looks like this: 我的数据结构如下所示:
I want to draw a stacked bar chart like this http://bl.ocks.org/mstanaland/6100713 from my data. 我想从我的数据中绘制一个像http://bl.ocks.org/mstanaland/6100713这样的堆积条形图。 How can I bring my data in a structure which is suitable for a D3 stacked bar chart? 如何将数据放入适合D3堆积条形图的结构中?
This could be done as follows: 这可以按如下方式完成:
const data = [];
myData.forEach(a => a.values.forEach(v => {
const element = data.find(e => e.year === v.key);
if (element) {
element[a.key] = v.values;
} else {
data.push({ year: v.key, [a.key]: v.values });
}
}));
Based on @unminder's answer but just to get every property into the object: 基于@ unminder的答案,但只是为了让每个属性都进入对象:
Stakblitz example: https://stackblitz.com/edit/js-d5sitf Stakblitz示例: https ://stackblitz.com/edit/js-d5sitf
const entryArr = [
{
key: 'ride',
values: [
{ key: '2008', value: 3234 },
{ key: '2009', value: 3234 },
{ key: '2010', value: 5000 },
{ key: '2011', value: 6000 },
{ key: '2012', value: 1456 },
{ key: '2013', value: 2453 }
]
},
{
key: 'hike',
values: [
{ key: '2006', value: 3234 },
{ key: '2009', value: 2420 },
{ key: '2010', value: 4530 },
{ key: '2011', value: 2000 },
{ key: '2012', value: 1900 },
{ key: '2013', value: 3700 }
]
},
{
key: 'walk',
values: [
{ key: '2009', value: 3001 },
{ key: '2010', value: 1090 },
{ key: '2011', value: 2020 },
{ key: '2012', value: 2000 },
{ key: '2013', value: 6000 }
]
}
];
const getKeys = entryArr.map(x => x.key);
const result = [];
entryArr.forEach(a => a.values.forEach(v => {
const element = result.find(e => e.year === v.key);
if (element) {
element[a.key] = v.value;
} else {
const obj = getKeys.reduce((acc, x) => ({ ...acc, year: v.key, [x]: a.key === x ? v.value : '' })
, {});
result.push(obj);
}
}));
console.log(result)
Note: it can be improved using reducers to avoid global variables 注意:可以使用reducers来改进它以避免全局变量
This works good, but when combinations are missing, no entry is made, so it's not true wide data. 这很好用,但是当缺少组合时,不会进行任何输入,因此它不是真正的宽数据。 I achieved it with this code: 我用这段代码实现了它:
// make data long
var flatdata = []
distance_per_year.forEach(function(type) {
type.values.forEach(function(typeYears) {
flatdata.push({
type: type.key,
year: typeYears.key,
distance: typeYears.values,
});
});
});
// Unique activity types
groups = Array.from(new Set(flatdata.map(({ type }) => type)));
years = Array.from(new Set(flatdata.map(({ year }) => year)));
// make wide data with 0 where value is missing
var grouped = years.map(function(d) {
var item = {
year: d
};
groups.forEach(function(e) {
var itemForGroup = flatdata.filter(function(f) {
return f.type === e && f.year === d;
});
if (itemForGroup.length) {
item[e] = Number(itemForGroup[0].distance);
} else {
item[e] = 0;
}
})
return item;
})
This produces first an unnested long dataset first (3 columns), then reshapes it to wide and fills in 0s where distance is missing. 这首先产生一个未经加工的长数据集(3列),然后将其重新整形为宽并填充0,其中距离缺失。
The source are these two questions: Reshape data for D3 stacked bar chart and d3: flatten nested data? 来源是这两个问题: 重塑D3堆积条形图的数据和d3:展平嵌套数据?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.