Этот вход (tree-like
структура) должен быть отформатирован в определенный формат, чтобы нарисовать d3 sankey diagram chart
.
let unformattedJson = [
{
"key": "a1",
"value": 30,
"buckets": [
{
"key": "a2",
"value": 10
},
{
"key": "b2",
"value": 20
}
]
},
{
"key": "b1",
"value": 70,
"buckets": [
{
"key": "b2",
"value": 40
},
{
"key": "c2",
"value": 30
}
]
}
]
Ожидаемый вывод, который мне нужно сгенерировать:
{
"nodes": [
{"nodeId":0,"name":"a1"},
{"nodeId":1,"name":"a2"},
{"nodeId":2,"name":"b2"},
{"nodeId":3,"name":"b1"},
{"nodeId":4,"name":"c2"}
],
"links": [
{"source":0,"target":1,"value":10},
{"source":0,"target":2,"value":20},
{"source":3,"target":2,"value":40},
{"source":3,"target":4,"value":30}
]
}
Мой подход к решению.Я сделал две функции для расчета узла и ссылки.Для узлов я сделал рекурсивные функции для получения всех уникальных ключей и назначил id
для каждой клавиши.И я сделал еще одну функцию, чтобы получить все отношения между клавишами.
let makeNodeObj = function(orObj, index){
let obj = {};
obj.nodeId = index;
obj.name = orObj;
return obj;
}
var getUniqueKeys = (old, arr)=>{
let toRet = old;
arr.forEach((data,index)=>{
if(toRet.indexOf(data.key)<0){ //remove duplicates
toRet.push(data.key);
}
if(data.buckets !== undefined && data.buckets.length>0){
getUniqueKeys(toRet, data.buckets);
}
});
return toRet;
}
let uniqueKeys = getUniqueKeys([],unformattedJson);
let nodes = uniqueKeys.map((data,index)=>{
return makeNodeObj(data,index);
});
let getNodeId = function(nodes, key){
let node = nodes.find((data)=>{
return data.name == key
});
return node.nodeId;
}
let links = [];
unformattedJson.map((data)=>{
let sourceId = getNodeId(nodes, data.key);
if(data.buckets.length>0){
data.buckets.map((data2)=>{
let targetId = getNodeId(nodes,data2.key);
let linkObj = {};
linkObj.source = sourceId;
linkObj.target = targetId;
linkObj.value = data2.value;
links.push(linkObj);
})
}
});
console.log({
nodes, links
});
Мое решение будет работать, только если есть только одно углубление уровня.Как этого добиться для нескольких вложенных контейнеров внутри дочернего элемента?