将平面数组转换为分层数组
Convert flat arrays to hierarchical
我在将平面列表转换为分层列表时遇到了一些问题。
我正在尝试从下面的数据中可视化 d3.js 树状图。
每个节点都有 fams
数组中描述的两个子对象。
我在这里发现了一些与我的问题类似的东西,但我无法让它与两个父节点一起工作
这是我要存档的内容https://bl.ocks.org/d3noob/8329404
我希望有人能指出我正确的方向,在此先感谢。
let nodes = [
{ id: 'N001', fam: 'F001' },
{ id: 'N002', fam: 'F002' },
{ id: 'N003', fam: 'F003' },
{ id: 'N004', fam: 'F004' },
{ id: 'N005', fam: 'F005' },
{ id: 'N006', fam: 'F006' },
{ id: 'N007', fam: 'F007' },
{ id: 'N008', fam: 'F008' },
{ id: 'N009', fam: 'F009' },
{ id: 'N010', fam: 'F010' },
{ id: 'N011', fam: 'F011' }
];
let fams = [
{ id: 'F001', p1: 'N002', p2: 'N003' },
{ id: 'F002', p1: 'N004', p2: 'N005' },
{ id: 'F003', p1: 'N006', p2: 'N007' },
{ id: 'F004', p1: 'N008', p2: 'N009' },
{ id: 'F005', p1: 'N010', p2: 'N011' }
];
// Expected output
let finalData = [
{
id: 'N001',
children: [
{
id: 'N002',
fam: 'F002',
children: [
{
id: 'N004',
fam: 'F004',
children: [
{ id: 'N008', fam: 'F008' },
{ id: 'N009', fam: 'F009' }
]
},
{
id: 'N005',
fam: 'F005',
children: [
{ id: 'N010', fam: 'F010' },
{ id: 'N011', fam: 'F011' }
]
}
]
},
{
id: 'N003',
fam: 'F003',
children: [
{ id: 'N006', fam: 'F006' },
{ id: 'N007', fam: 'F007' }
]
}
]
}
];
一个可能的解决方案是循环 nodes
数组以创建一个新的 属性 (parentId
),基于 fams
,它描述父 (null
如果 none):
nodes.forEach(function(d) {
const fam = fams.find(function(e) {
return e.p1 === d.id || e.p2 === d.id
});
d.parentId = fam ? nodes.find(function(e) {
return e.fam === fam.id;
}).id : null;
});
之后,使用 d3.stratify()
创建层次结构将非常简单:
const stratify = d3.stratify()(nodes);
这是演示(使用浏览器的控制台检查结果,而不是 S.O。代码段控制台):
let nodes = [{
id: 'N001',
fam: 'F001'
},
{
id: 'N002',
fam: 'F002'
},
{
id: 'N003',
fam: 'F003'
},
{
id: 'N004',
fam: 'F004'
},
{
id: 'N005',
fam: 'F005'
},
{
id: 'N006',
fam: 'F006'
},
{
id: 'N007',
fam: 'F007'
},
{
id: 'N008',
fam: 'F008'
},
{
id: 'N009',
fam: 'F009'
},
{
id: 'N010',
fam: 'F010'
},
{
id: 'N011',
fam: 'F011'
}
];
let fams = [{
id: 'F001',
p1: 'N002',
p2: 'N003'
},
{
id: 'F002',
p1: 'N004',
p2: 'N005'
},
{
id: 'F003',
p1: 'N006',
p2: 'N007'
},
{
id: 'F004',
p1: 'N008',
p2: 'N009'
},
{
id: 'F005',
p1: 'N010',
p2: 'N011'
}
];
nodes.forEach(function(d) {
const fam = fams.find(function(e) {
return e.p1 === d.id || e.p2 === d.id
});
d.parentId = fam ? nodes.find(function(e) {
return e.fam === fam.id;
}).id : null;
});
const stratify = d3.stratify()(nodes);
console.log(stratify)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
我在将平面列表转换为分层列表时遇到了一些问题。
我正在尝试从下面的数据中可视化 d3.js 树状图。
每个节点都有 fams
数组中描述的两个子对象。
我在这里发现了一些与我的问题类似的东西,但我无法让它与两个父节点一起工作
这是我要存档的内容https://bl.ocks.org/d3noob/8329404
我希望有人能指出我正确的方向,在此先感谢。
let nodes = [
{ id: 'N001', fam: 'F001' },
{ id: 'N002', fam: 'F002' },
{ id: 'N003', fam: 'F003' },
{ id: 'N004', fam: 'F004' },
{ id: 'N005', fam: 'F005' },
{ id: 'N006', fam: 'F006' },
{ id: 'N007', fam: 'F007' },
{ id: 'N008', fam: 'F008' },
{ id: 'N009', fam: 'F009' },
{ id: 'N010', fam: 'F010' },
{ id: 'N011', fam: 'F011' }
];
let fams = [
{ id: 'F001', p1: 'N002', p2: 'N003' },
{ id: 'F002', p1: 'N004', p2: 'N005' },
{ id: 'F003', p1: 'N006', p2: 'N007' },
{ id: 'F004', p1: 'N008', p2: 'N009' },
{ id: 'F005', p1: 'N010', p2: 'N011' }
];
// Expected output
let finalData = [
{
id: 'N001',
children: [
{
id: 'N002',
fam: 'F002',
children: [
{
id: 'N004',
fam: 'F004',
children: [
{ id: 'N008', fam: 'F008' },
{ id: 'N009', fam: 'F009' }
]
},
{
id: 'N005',
fam: 'F005',
children: [
{ id: 'N010', fam: 'F010' },
{ id: 'N011', fam: 'F011' }
]
}
]
},
{
id: 'N003',
fam: 'F003',
children: [
{ id: 'N006', fam: 'F006' },
{ id: 'N007', fam: 'F007' }
]
}
]
}
];
一个可能的解决方案是循环 nodes
数组以创建一个新的 属性 (parentId
),基于 fams
,它描述父 (null
如果 none):
nodes.forEach(function(d) {
const fam = fams.find(function(e) {
return e.p1 === d.id || e.p2 === d.id
});
d.parentId = fam ? nodes.find(function(e) {
return e.fam === fam.id;
}).id : null;
});
之后,使用 d3.stratify()
创建层次结构将非常简单:
const stratify = d3.stratify()(nodes);
这是演示(使用浏览器的控制台检查结果,而不是 S.O。代码段控制台):
let nodes = [{
id: 'N001',
fam: 'F001'
},
{
id: 'N002',
fam: 'F002'
},
{
id: 'N003',
fam: 'F003'
},
{
id: 'N004',
fam: 'F004'
},
{
id: 'N005',
fam: 'F005'
},
{
id: 'N006',
fam: 'F006'
},
{
id: 'N007',
fam: 'F007'
},
{
id: 'N008',
fam: 'F008'
},
{
id: 'N009',
fam: 'F009'
},
{
id: 'N010',
fam: 'F010'
},
{
id: 'N011',
fam: 'F011'
}
];
let fams = [{
id: 'F001',
p1: 'N002',
p2: 'N003'
},
{
id: 'F002',
p1: 'N004',
p2: 'N005'
},
{
id: 'F003',
p1: 'N006',
p2: 'N007'
},
{
id: 'F004',
p1: 'N008',
p2: 'N009'
},
{
id: 'F005',
p1: 'N010',
p2: 'N011'
}
];
nodes.forEach(function(d) {
const fam = fams.find(function(e) {
return e.p1 === d.id || e.p2 === d.id
});
d.parentId = fam ? nodes.find(function(e) {
return e.fam === fam.id;
}).id : null;
});
const stratify = d3.stratify()(nodes);
console.log(stratify)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>